Commit 55fd0cf3 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

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: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e795892e
...@@ -6337,6 +6337,10 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) ...@@ -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) & bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK; 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) if (resp->supported_speeds_auto_mode)
link_info->support_auto_speeds = link_info->support_auto_speeds =
le16_to_cpu(resp->supported_speeds_auto_mode); le16_to_cpu(resp->supported_speeds_auto_mode);
......
...@@ -990,6 +990,8 @@ struct bnxt_led_info { ...@@ -990,6 +990,8 @@ struct bnxt_led_info {
struct bnxt_test_info { struct bnxt_test_info {
u8 offline_mask; u8 offline_mask;
u8 flags;
#define BNXT_TEST_FL_EXT_LPBK 0x1
u16 timeout; u16 timeout;
char string[BNXT_MAX_TEST][ETH_GSTRING_LEN]; char string[BNXT_MAX_TEST][ETH_GSTRING_LEN];
}; };
......
...@@ -2397,7 +2397,7 @@ static int bnxt_disable_an_for_lpbk(struct bnxt *bp, ...@@ -2397,7 +2397,7 @@ static int bnxt_disable_an_for_lpbk(struct bnxt *bp,
return rc; 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}; struct hwrm_port_phy_cfg_input req = {0};
...@@ -2405,7 +2405,10 @@ static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable) ...@@ -2405,7 +2405,10 @@ static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable)
if (enable) { if (enable) {
bnxt_disable_an_for_lpbk(bp, &req); 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 { } else {
req.lpbk = PORT_PHY_CFG_REQ_LPBK_NONE; 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) ...@@ -2538,15 +2541,17 @@ static int bnxt_run_fw_tests(struct bnxt *bp, u8 test_mask, u8 *test_results)
return rc; 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_MACLPBK_TEST_IDX (bp->num_tests - BNXT_DRV_TESTS)
#define BNXT_PHYLPBK_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 1) #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, static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
u64 *buf) u64 *buf)
{ {
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
bool do_ext_lpbk = false;
bool offline = false; bool offline = false;
u8 test_results = 0; u8 test_results = 0;
u8 test_mask = 0; u8 test_mask = 0;
...@@ -2560,6 +2565,10 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, ...@@ -2560,6 +2565,10 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
return; 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 (etest->flags & ETH_TEST_FL_OFFLINE) {
if (bp->pf.active_vfs) { if (bp->pf.active_vfs) {
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
...@@ -2600,13 +2609,22 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, ...@@ -2600,13 +2609,22 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
buf[BNXT_MACLPBK_TEST_IDX] = 0; buf[BNXT_MACLPBK_TEST_IDX] = 0;
bnxt_hwrm_mac_loopback(bp, false); bnxt_hwrm_mac_loopback(bp, false);
bnxt_hwrm_phy_loopback(bp, true); bnxt_hwrm_phy_loopback(bp, true, false);
msleep(1000); msleep(1000);
if (bnxt_run_loopback(bp)) { if (bnxt_run_loopback(bp)) {
buf[BNXT_PHYLPBK_TEST_IDX] = 1; buf[BNXT_PHYLPBK_TEST_IDX] = 1;
etest->flags |= ETH_TEST_FL_FAILED; 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_half_close_nic(bp);
bnxt_open_nic(bp, false, true); bnxt_open_nic(bp, false, true);
} }
...@@ -2707,6 +2725,8 @@ void bnxt_ethtool_init(struct bnxt *bp) ...@@ -2707,6 +2725,8 @@ void bnxt_ethtool_init(struct bnxt *bp)
strcpy(str, "Mac loopback test (offline)"); strcpy(str, "Mac loopback test (offline)");
} else if (i == BNXT_PHYLPBK_TEST_IDX) { } else if (i == BNXT_PHYLPBK_TEST_IDX) {
strcpy(str, "Phy loopback test (offline)"); 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) { } else if (i == BNXT_IRQ_TEST_IDX) {
strcpy(str, "Interrupt_test (offline)"); strcpy(str, "Interrupt_test (offline)");
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment