Merge branch 'net-hns3-add-support-ethtool-extended-link-state'
Guangbin Huang says: ==================== net: hns3: add support ethtool extended link state This series adds support for ethtool extended link state in the HNS3 ethernet driver to add one additional information for user to know why a link is not up. ==================== Link: https://lore.kernel.org/r/1629080129-46507-1-git-send-email-huangguangbin2@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
fd04ed1ca3
@ -595,6 +595,14 @@ Link extended substates:
|
|||||||
that is not formally
|
that is not formally
|
||||||
supported, which led to
|
supported, which led to
|
||||||
signal integrity issues
|
signal integrity issues
|
||||||
|
|
||||||
|
``ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST`` The external clock signal for
|
||||||
|
SerDes is too weak or
|
||||||
|
unavailable.
|
||||||
|
|
||||||
|
``ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS`` The received signal for
|
||||||
|
SerDes is too weak because
|
||||||
|
analog loss of signal.
|
||||||
================================================================= =============================
|
================================================================= =============================
|
||||||
|
|
||||||
Cable issue substates:
|
Cable issue substates:
|
||||||
|
@ -718,6 +718,8 @@ struct hnae3_ae_ops {
|
|||||||
u32 nsec, u32 sec);
|
u32 nsec, u32 sec);
|
||||||
int (*get_ts_info)(struct hnae3_handle *handle,
|
int (*get_ts_info)(struct hnae3_handle *handle,
|
||||||
struct ethtool_ts_info *info);
|
struct ethtool_ts_info *info);
|
||||||
|
int (*get_link_diagnosis_info)(struct hnae3_handle *handle,
|
||||||
|
u32 *status_code);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hnae3_dcb_ops {
|
struct hnae3_dcb_ops {
|
||||||
|
@ -7,21 +7,7 @@
|
|||||||
#include <linux/sfp.h>
|
#include <linux/sfp.h>
|
||||||
|
|
||||||
#include "hns3_enet.h"
|
#include "hns3_enet.h"
|
||||||
|
#include "hns3_ethtool.h"
|
||||||
struct hns3_stats {
|
|
||||||
char stats_string[ETH_GSTRING_LEN];
|
|
||||||
int stats_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hns3_sfp_type {
|
|
||||||
u8 type;
|
|
||||||
u8 ext_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hns3_pflag_desc {
|
|
||||||
char name[ETH_GSTRING_LEN];
|
|
||||||
void (*handler)(struct net_device *netdev, bool enable);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tqp related stats */
|
/* tqp related stats */
|
||||||
#define HNS3_TQP_STAT(_string, _member) { \
|
#define HNS3_TQP_STAT(_string, _member) { \
|
||||||
@ -1725,6 +1711,71 @@ static int hns3_get_ts_info(struct net_device *netdev,
|
|||||||
return ethtool_op_get_ts_info(netdev, info);
|
return ethtool_op_get_ts_info(netdev, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct hns3_ethtool_link_ext_state_mapping
|
||||||
|
hns3_link_ext_state_map[] = {
|
||||||
|
{1, ETHTOOL_LINK_EXT_STATE_AUTONEG,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD},
|
||||||
|
{2, ETHTOOL_LINK_EXT_STATE_AUTONEG,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED},
|
||||||
|
|
||||||
|
{256, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT},
|
||||||
|
{257, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY},
|
||||||
|
{512, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT},
|
||||||
|
|
||||||
|
{513, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK},
|
||||||
|
{514, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED},
|
||||||
|
{515, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED},
|
||||||
|
|
||||||
|
{768, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS},
|
||||||
|
{769, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST},
|
||||||
|
{770, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS},
|
||||||
|
|
||||||
|
{1024, ETHTOOL_LINK_EXT_STATE_NO_CABLE, 0},
|
||||||
|
{1025, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
|
||||||
|
|
||||||
|
{1026, ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int hns3_get_link_ext_state(struct net_device *netdev,
|
||||||
|
struct ethtool_link_ext_state_info *info)
|
||||||
|
{
|
||||||
|
const struct hns3_ethtool_link_ext_state_mapping *map;
|
||||||
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||||
|
u32 status_code, i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (netif_carrier_ok(netdev))
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
if (!h->ae_algo->ops->get_link_diagnosis_info)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
ret = h->ae_algo->ops->get_link_diagnosis_info(h, &status_code);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(hns3_link_ext_state_map); i++) {
|
||||||
|
map = &hns3_link_ext_state_map[i];
|
||||||
|
if (map->status_code == status_code) {
|
||||||
|
info->link_ext_state = map->link_ext_state;
|
||||||
|
info->__link_ext_substate = map->link_ext_substate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENODATA;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops hns3vf_ethtool_ops = {
|
static const struct ethtool_ops hns3vf_ethtool_ops = {
|
||||||
.supported_coalesce_params = HNS3_ETHTOOL_COALESCE,
|
.supported_coalesce_params = HNS3_ETHTOOL_COALESCE,
|
||||||
.get_drvinfo = hns3_get_drvinfo,
|
.get_drvinfo = hns3_get_drvinfo,
|
||||||
@ -1796,6 +1847,7 @@ static const struct ethtool_ops hns3_ethtool_ops = {
|
|||||||
.get_tunable = hns3_get_tunable,
|
.get_tunable = hns3_get_tunable,
|
||||||
.set_tunable = hns3_set_tunable,
|
.set_tunable = hns3_set_tunable,
|
||||||
.reset = hns3_set_reset,
|
.reset = hns3_set_reset,
|
||||||
|
.get_link_ext_state = hns3_get_link_ext_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
void hns3_ethtool_set_ops(struct net_device *netdev)
|
void hns3_ethtool_set_ops(struct net_device *netdev)
|
||||||
|
31
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.h
Normal file
31
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
// Copyright (c) 2021 Hisilicon Limited.
|
||||||
|
|
||||||
|
#ifndef __HNS3_ETHTOOL_H
|
||||||
|
#define __HNS3_ETHTOOL_H
|
||||||
|
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
struct hns3_stats {
|
||||||
|
char stats_string[ETH_GSTRING_LEN];
|
||||||
|
int stats_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hns3_sfp_type {
|
||||||
|
u8 type;
|
||||||
|
u8 ext_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hns3_pflag_desc {
|
||||||
|
char name[ETH_GSTRING_LEN];
|
||||||
|
void (*handler)(struct net_device *netdev, bool enable);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hns3_ethtool_link_ext_state_mapping {
|
||||||
|
u32 status_code;
|
||||||
|
enum ethtool_link_ext_state link_ext_state;
|
||||||
|
u8 link_ext_substate;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -316,6 +316,9 @@ enum hclge_opcode_type {
|
|||||||
/* PHY command */
|
/* PHY command */
|
||||||
HCLGE_OPC_PHY_LINK_KSETTING = 0x7025,
|
HCLGE_OPC_PHY_LINK_KSETTING = 0x7025,
|
||||||
HCLGE_OPC_PHY_REG = 0x7026,
|
HCLGE_OPC_PHY_REG = 0x7026,
|
||||||
|
|
||||||
|
/* Query link diagnosis info command */
|
||||||
|
HCLGE_OPC_QUERY_LINK_DIAGNOSIS = 0x702A,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HCLGE_TQP_REG_OFFSET 0x80000
|
#define HCLGE_TQP_REG_OFFSET 0x80000
|
||||||
|
@ -12843,6 +12843,29 @@ static int hclge_get_module_eeprom(struct hnae3_handle *handle, u32 offset,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hclge_get_link_diagnosis_info(struct hnae3_handle *handle,
|
||||||
|
u32 *status_code)
|
||||||
|
{
|
||||||
|
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||||
|
struct hclge_dev *hdev = vport->back;
|
||||||
|
struct hclge_desc desc;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_LINK_DIAGNOSIS, true);
|
||||||
|
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"failed to query link diagnosis info, ret = %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*status_code = le32_to_cpu(desc.data[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct hnae3_ae_ops hclge_ops = {
|
static const struct hnae3_ae_ops hclge_ops = {
|
||||||
.init_ae_dev = hclge_init_ae_dev,
|
.init_ae_dev = hclge_init_ae_dev,
|
||||||
.uninit_ae_dev = hclge_uninit_ae_dev,
|
.uninit_ae_dev = hclge_uninit_ae_dev,
|
||||||
@ -12943,6 +12966,7 @@ static const struct hnae3_ae_ops hclge_ops = {
|
|||||||
.set_tx_hwts_info = hclge_ptp_set_tx_info,
|
.set_tx_hwts_info = hclge_ptp_set_tx_info,
|
||||||
.get_rx_hwts = hclge_ptp_get_rx_hwts,
|
.get_rx_hwts = hclge_ptp_get_rx_hwts,
|
||||||
.get_ts_info = hclge_ptp_get_ts_info,
|
.get_ts_info = hclge_ptp_get_ts_info,
|
||||||
|
.get_link_diagnosis_info = hclge_get_link_diagnosis_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hnae3_ae_algo ae_algo = {
|
static struct hnae3_ae_algo ae_algo = {
|
||||||
|
@ -639,6 +639,8 @@ enum ethtool_link_ext_substate_link_logical_mismatch {
|
|||||||
enum ethtool_link_ext_substate_bad_signal_integrity {
|
enum ethtool_link_ext_substate_bad_signal_integrity {
|
||||||
ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 1,
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 1,
|
||||||
ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE,
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST,
|
||||||
|
ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* More information in addition to ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE. */
|
/* More information in addition to ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE. */
|
||||||
|
Loading…
Reference in New Issue
Block a user