bnxt_en: Add external loopback test to ethtool selftest.
authorMichael Chan <michael.chan@broadcom.com>
Sun, 5 Aug 2018 20:51:48 +0000 (16:51 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 6 Aug 2018 00:08:25 +0000 (17:08 -0700)
Add code to detect firmware support for external loopback and the extra
test entry for external loopback.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index c612d74451a7fa1730c9e66fa33344f37e844683..d9fc905c599670a51ed191a84cecf5510cc3cfae 100644 (file)
@@ -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);
index 3b5a55ce11eaa66b3b6584d306566836d8732976..0d49fe015ba90cf269d68337bafa566cf38ba1fb 100644 (file)
@@ -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];
 };
index 1f626afb211876169884a4fdcd6d245e0a1d3f73..9517633f947a1d794184fafcd426db9dc6659fb4 100644 (file)
@@ -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 {