diff options
author | Jakub Kicinski <kuba@kernel.org> | 2021-08-17 01:12:15 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-08-17 01:12:16 +0300 |
commit | fd04ed1ca37f3f0767b8e42b32fcc078f99e6193 (patch) | |
tree | 7cfa1584bf38a0b9b601a165c0a471b0b969244f /drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | |
parent | 1b3f78df6a80932d7deb0155d8b0871e8d3e4bca (diff) | |
parent | f5c2b9f0fc078308a88de807d60cd4e352a165fc (diff) | |
download | linux-fd04ed1ca37f3f0767b8e42b32fcc078f99e6193.tar.xz |
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>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 82 |
1 files changed, 67 insertions, 15 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index c8f09b07185e..835105015763 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -7,21 +7,7 @@ #include <linux/sfp.h> #include "hns3_enet.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); -}; +#include "hns3_ethtool.h" /* tqp related stats */ #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); } +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 = { .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, .get_drvinfo = hns3_get_drvinfo, @@ -1796,6 +1847,7 @@ static const struct ethtool_ops hns3_ethtool_ops = { .get_tunable = hns3_get_tunable, .set_tunable = hns3_set_tunable, .reset = hns3_set_reset, + .get_link_ext_state = hns3_get_link_ext_state, }; void hns3_ethtool_set_ops(struct net_device *netdev) |