From: Michael Chan Date: Sun, 5 Aug 2018 20:51:48 +0000 (-0400) Subject: bnxt_en: Add external loopback test to ethtool selftest. X-Git-Tag: v4.19-rc1~140^2~134^2~10 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=55fd0cf320c3051f8dcb88c07ddd1e4c54b82cba;p=linux.git bnxt_en: Add external loopback test to ethtool selftest. Add code to detect firmware support for external loopback and the extra test entry for external loopback. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index c612d74451a7..d9fc905c5996 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6337,6 +6337,10 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) & PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK; } + if (resp->flags & PORT_PHY_QCAPS_RESP_FLAGS_EXTERNAL_LPBK_SUPPORTED) { + if (bp->test_info) + bp->test_info->flags |= BNXT_TEST_FL_EXT_LPBK; + } if (resp->supported_speeds_auto_mode) link_info->support_auto_speeds = le16_to_cpu(resp->supported_speeds_auto_mode); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 3b5a55ce11ea..0d49fe015ba9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -990,6 +990,8 @@ struct bnxt_led_info { struct bnxt_test_info { u8 offline_mask; + u8 flags; +#define BNXT_TEST_FL_EXT_LPBK 0x1 u16 timeout; char string[BNXT_MAX_TEST][ETH_GSTRING_LEN]; }; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 1f626afb2118..9517633f947a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -2397,7 +2397,7 @@ static int bnxt_disable_an_for_lpbk(struct bnxt *bp, return rc; } -static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable) +static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable, bool ext) { struct hwrm_port_phy_cfg_input req = {0}; @@ -2405,7 +2405,10 @@ static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable) if (enable) { bnxt_disable_an_for_lpbk(bp, &req); - req.lpbk = PORT_PHY_CFG_REQ_LPBK_LOCAL; + if (ext) + req.lpbk = PORT_PHY_CFG_REQ_LPBK_EXTERNAL; + else + req.lpbk = PORT_PHY_CFG_REQ_LPBK_LOCAL; } else { req.lpbk = PORT_PHY_CFG_REQ_LPBK_NONE; } @@ -2538,15 +2541,17 @@ static int bnxt_run_fw_tests(struct bnxt *bp, u8 test_mask, u8 *test_results) return rc; } -#define BNXT_DRV_TESTS 3 +#define BNXT_DRV_TESTS 4 #define BNXT_MACLPBK_TEST_IDX (bp->num_tests - BNXT_DRV_TESTS) #define BNXT_PHYLPBK_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 1) -#define BNXT_IRQ_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 2) +#define BNXT_EXTLPBK_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 2) +#define BNXT_IRQ_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 3) static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) { struct bnxt *bp = netdev_priv(dev); + bool do_ext_lpbk = false; bool offline = false; u8 test_results = 0; u8 test_mask = 0; @@ -2560,6 +2565,10 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, return; } + if ((etest->flags & ETH_TEST_FL_EXTERNAL_LB) && + (bp->test_info->flags & BNXT_TEST_FL_EXT_LPBK)) + do_ext_lpbk = true; + if (etest->flags & ETH_TEST_FL_OFFLINE) { if (bp->pf.active_vfs) { etest->flags |= ETH_TEST_FL_FAILED; @@ -2600,13 +2609,22 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, buf[BNXT_MACLPBK_TEST_IDX] = 0; bnxt_hwrm_mac_loopback(bp, false); - bnxt_hwrm_phy_loopback(bp, true); + bnxt_hwrm_phy_loopback(bp, true, false); msleep(1000); if (bnxt_run_loopback(bp)) { buf[BNXT_PHYLPBK_TEST_IDX] = 1; etest->flags |= ETH_TEST_FL_FAILED; } - bnxt_hwrm_phy_loopback(bp, false); + if (do_ext_lpbk) { + etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE; + bnxt_hwrm_phy_loopback(bp, true, true); + msleep(1000); + if (bnxt_run_loopback(bp)) { + buf[BNXT_EXTLPBK_TEST_IDX] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + } + bnxt_hwrm_phy_loopback(bp, false, false); bnxt_half_close_nic(bp); bnxt_open_nic(bp, false, true); } @@ -2707,6 +2725,8 @@ void bnxt_ethtool_init(struct bnxt *bp) strcpy(str, "Mac loopback test (offline)"); } else if (i == BNXT_PHYLPBK_TEST_IDX) { strcpy(str, "Phy loopback test (offline)"); + } else if (i == BNXT_EXTLPBK_TEST_IDX) { + strcpy(str, "Ext loopback test (offline)"); } else if (i == BNXT_IRQ_TEST_IDX) { strcpy(str, "Interrupt_test (offline)"); } else {