Commit cf2c1df6 authored by Merav Sicron's avatar Merav Sicron Committed by David S. Miller

bnx2x: Return only online tests for MF

1. In multi-function device, show only the online tests in self-test results as
   only these test are performed (offline tests cannot be performed as they may
   corrupt the traffic of other functions on the same physical port). Note that
   multi-function mode cannot change while the driver is up.
2. Check result code in NIC load and act accordingly.
Signed-off-by: default avatarMerav Sicron <meravs@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8970b2e4
...@@ -1900,8 +1900,10 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, ...@@ -1900,8 +1900,10 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PCICFG_LINK_SPEED 0xf0000 #define PCICFG_LINK_SPEED 0xf0000
#define PCICFG_LINK_SPEED_SHIFT 16 #define PCICFG_LINK_SPEED_SHIFT 16
#define BNX2X_NUM_TESTS_SF 7
#define BNX2X_NUM_TESTS 8 #define BNX2X_NUM_TESTS_MF 3
#define BNX2X_NUM_TESTS(bp) (IS_MF(bp) ? BNX2X_NUM_TESTS_MF : \
BNX2X_NUM_TESTS_SF)
#define BNX2X_PHY_LOOPBACK 0 #define BNX2X_PHY_LOOPBACK 0
#define BNX2X_MAC_LOOPBACK 1 #define BNX2X_MAC_LOOPBACK 1
......
...@@ -826,7 +826,7 @@ static void bnx2x_get_drvinfo(struct net_device *dev, ...@@ -826,7 +826,7 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver); ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver);
strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
info->n_stats = BNX2X_NUM_STATS; info->n_stats = BNX2X_NUM_STATS;
info->testinfo_len = BNX2X_NUM_TESTS; info->testinfo_len = BNX2X_NUM_TESTS(bp);
info->eedump_len = bp->common.flash_size; info->eedump_len = bp->common.flash_size;
info->regdump_len = bnx2x_get_regs_len(dev); info->regdump_len = bnx2x_get_regs_len(dev);
} }
...@@ -1533,17 +1533,14 @@ static int bnx2x_set_pauseparam(struct net_device *dev, ...@@ -1533,17 +1533,14 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
return 0; return 0;
} }
static const struct { char *bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF] = {
char string[ETH_GSTRING_LEN]; "register_test (offline) ",
} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { "memory_test (offline) ",
{ "register_test (offline)" }, "int_loopback_test (offline)",
{ "memory_test (offline)" }, "ext_loopback_test (offline)",
{ "int_loopback_test (offline)" }, "nvram_test (online) ",
{ "ext_loopback_test (offline)" }, "interrupt_test (online) ",
{ "nvram_test (online)" }, "link_test (online) "
{ "interrupt_test (online)" },
{ "link_test (online)" },
{ "idle check (online)" }
}; };
static u32 bnx2x_eee_to_adv(u32 eee_adv) static u32 bnx2x_eee_to_adv(u32 eee_adv)
...@@ -2308,6 +2305,8 @@ static void bnx2x_self_test(struct net_device *dev, ...@@ -2308,6 +2305,8 @@ static void bnx2x_self_test(struct net_device *dev,
{ {
struct bnx2x *bp = netdev_priv(dev); struct bnx2x *bp = netdev_priv(dev);
u8 is_serdes; u8 is_serdes;
int rc;
if (bp->recovery_state != BNX2X_RECOVERY_DONE) { if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
netdev_err(bp->dev, netdev_err(bp->dev,
"Handling parity error recovery. Try again later\n"); "Handling parity error recovery. Try again later\n");
...@@ -2319,17 +2318,18 @@ static void bnx2x_self_test(struct net_device *dev, ...@@ -2319,17 +2318,18 @@ static void bnx2x_self_test(struct net_device *dev,
(etest->flags & ETH_TEST_FL_OFFLINE), (etest->flags & ETH_TEST_FL_OFFLINE),
(etest->flags & ETH_TEST_FL_EXTERNAL_LB)>>2); (etest->flags & ETH_TEST_FL_EXTERNAL_LB)>>2);
memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS); memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp));
if (!netif_running(dev)) if (!netif_running(dev)) {
DP(BNX2X_MSG_ETHTOOL,
"Can't perform self-test when interface is down\n");
return; return;
}
/* offline tests are not supported in MF mode */
if (IS_MF(bp))
etest->flags &= ~ETH_TEST_FL_OFFLINE;
is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0;
if (etest->flags & ETH_TEST_FL_OFFLINE) { /* offline tests are not supported in MF mode */
if ((etest->flags & ETH_TEST_FL_OFFLINE) && !IS_MF(bp)) {
int port = BP_PORT(bp); int port = BP_PORT(bp);
u32 val; u32 val;
u8 link_up; u8 link_up;
...@@ -2342,7 +2342,14 @@ static void bnx2x_self_test(struct net_device *dev, ...@@ -2342,7 +2342,14 @@ static void bnx2x_self_test(struct net_device *dev,
link_up = bp->link_vars.link_up; link_up = bp->link_vars.link_up;
bnx2x_nic_unload(bp, UNLOAD_NORMAL); bnx2x_nic_unload(bp, UNLOAD_NORMAL);
bnx2x_nic_load(bp, LOAD_DIAG); rc = bnx2x_nic_load(bp, LOAD_DIAG);
if (rc) {
etest->flags |= ETH_TEST_FL_FAILED;
DP(BNX2X_MSG_ETHTOOL,
"Can't perform self-test, nic_load (for offline) failed\n");
return;
}
/* wait until link state is restored */ /* wait until link state is restored */
bnx2x_wait_for_link(bp, 1, is_serdes); bnx2x_wait_for_link(bp, 1, is_serdes);
...@@ -2370,22 +2377,36 @@ static void bnx2x_self_test(struct net_device *dev, ...@@ -2370,22 +2377,36 @@ static void bnx2x_self_test(struct net_device *dev,
/* restore input for TX port IF */ /* restore input for TX port IF */
REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val); REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val);
rc = bnx2x_nic_load(bp, LOAD_NORMAL);
bnx2x_nic_load(bp, LOAD_NORMAL); if (rc) {
etest->flags |= ETH_TEST_FL_FAILED;
DP(BNX2X_MSG_ETHTOOL,
"Can't perform self-test, nic_load (for online) failed\n");
return;
}
/* wait until link state is restored */ /* wait until link state is restored */
bnx2x_wait_for_link(bp, link_up, is_serdes); bnx2x_wait_for_link(bp, link_up, is_serdes);
} }
if (bnx2x_test_nvram(bp) != 0) { if (bnx2x_test_nvram(bp) != 0) {
if (!IS_MF(bp))
buf[4] = 1; buf[4] = 1;
else
buf[0] = 1;
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
} }
if (bnx2x_test_intr(bp) != 0) { if (bnx2x_test_intr(bp) != 0) {
if (!IS_MF(bp))
buf[5] = 1; buf[5] = 1;
else
buf[1] = 1;
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
} }
if (bnx2x_link_test(bp, is_serdes) != 0) { if (bnx2x_link_test(bp, is_serdes) != 0) {
if (!IS_MF(bp))
buf[6] = 1; buf[6] = 1;
else
buf[2] = 1;
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
} }
...@@ -2430,7 +2451,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) ...@@ -2430,7 +2451,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
return num_stats; return num_stats;
case ETH_SS_TEST: case ETH_SS_TEST:
return BNX2X_NUM_TESTS; return BNX2X_NUM_TESTS(bp);
default: default:
return -EINVAL; return -EINVAL;
...@@ -2440,7 +2461,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) ...@@ -2440,7 +2461,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{ {
struct bnx2x *bp = netdev_priv(dev); struct bnx2x *bp = netdev_priv(dev);
int i, j, k; int i, j, k, offset, start;
char queue_name[MAX_QUEUE_NAME_LEN+1]; char queue_name[MAX_QUEUE_NAME_LEN+1];
switch (stringset) { switch (stringset) {
...@@ -2471,7 +2492,17 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) ...@@ -2471,7 +2492,17 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
break; break;
case ETH_SS_TEST: case ETH_SS_TEST:
memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr)); /* First 4 tests cannot be done in MF mode */
if (!IS_MF(bp))
start = 0;
else
start = 4;
for (i = 0, j = start; j < (start + BNX2X_NUM_TESTS(bp));
i++, j++) {
offset = sprintf(buf+32*i, "%s",
bnx2x_tests_str_arr[j]);
*(buf+offset) = '\0';
}
break; break;
} }
} }
......
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