bnx2x: Return only online tests for MF
authorMerav Sicron <meravs@broadcom.com>
Tue, 19 Jun 2012 07:48:23 +0000 (07:48 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Jun 2012 21:34:34 +0000 (14:34 -0700)
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: Merav Sicron <meravs@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c

index 4335f9f51e6f86966359146a4edeb2613bd671d2..8ee4bfc1b0bb94c0260dd3ff4747b3c8b5a2c4f5 100644 (file)
@@ -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_SHIFT                16
 
-
-#define BNX2X_NUM_TESTS                        8
+#define BNX2X_NUM_TESTS_SF             7
+#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_MAC_LOOPBACK             1
index 68fa902511dcaaa73c6a7db76fcb71841c510248..ed2b49a0c5a540332f17daea3a0ca6bc815e8cca 100644 (file)
@@ -826,7 +826,7 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
                 ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver);
        strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
        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->regdump_len = bnx2x_get_regs_len(dev);
 }
@@ -1533,17 +1533,14 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
        return 0;
 }
 
-static const struct {
-       char string[ETH_GSTRING_LEN];
-} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
-       { "register_test (offline)" },
-       { "memory_test (offline)" },
-       { "int_loopback_test (offline)" },
-       { "ext_loopback_test (offline)" },
-       { "nvram_test (online)" },
-       { "interrupt_test (online)" },
-       { "link_test (online)" },
-       { "idle check (online)" }
+char *bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF] = {
+       "register_test (offline)    ",
+       "memory_test (offline)      ",
+       "int_loopback_test (offline)",
+       "ext_loopback_test (offline)",
+       "nvram_test (online)        ",
+       "interrupt_test (online)    ",
+       "link_test (online)         "
 };
 
 static u32 bnx2x_eee_to_adv(u32 eee_adv)
@@ -2308,6 +2305,8 @@ static void bnx2x_self_test(struct net_device *dev,
 {
        struct bnx2x *bp = netdev_priv(dev);
        u8 is_serdes;
+       int rc;
+
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
                netdev_err(bp->dev,
                           "Handling parity error recovery. Try again later\n");
@@ -2319,17 +2318,18 @@ static void bnx2x_self_test(struct net_device *dev,
           (etest->flags & ETH_TEST_FL_OFFLINE),
           (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;
+       }
 
-       /* 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;
 
-       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);
                u32 val;
                u8 link_up;
@@ -2342,7 +2342,14 @@ static void bnx2x_self_test(struct net_device *dev,
                link_up = bp->link_vars.link_up;
 
                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 */
                bnx2x_wait_for_link(bp, 1, is_serdes);
 
@@ -2370,22 +2377,36 @@ static void bnx2x_self_test(struct net_device *dev,
 
                /* restore input for TX port IF */
                REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val);
-
-               bnx2x_nic_load(bp, LOAD_NORMAL);
+               rc = 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 */
                bnx2x_wait_for_link(bp, link_up, is_serdes);
        }
        if (bnx2x_test_nvram(bp) != 0) {
-               buf[4] = 1;
+               if (!IS_MF(bp))
+                       buf[4] = 1;
+               else
+                       buf[0] = 1;
                etest->flags |= ETH_TEST_FL_FAILED;
        }
        if (bnx2x_test_intr(bp) != 0) {
-               buf[5] = 1;
+               if (!IS_MF(bp))
+                       buf[5] = 1;
+               else
+                       buf[1] = 1;
                etest->flags |= ETH_TEST_FL_FAILED;
        }
 
        if (bnx2x_link_test(bp, is_serdes) != 0) {
-               buf[6] = 1;
+               if (!IS_MF(bp))
+                       buf[6] = 1;
+               else
+                       buf[2] = 1;
                etest->flags |= ETH_TEST_FL_FAILED;
        }
 
@@ -2430,7 +2451,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
                return num_stats;
 
        case ETH_SS_TEST:
-               return BNX2X_NUM_TESTS;
+               return BNX2X_NUM_TESTS(bp);
 
        default:
                return -EINVAL;
@@ -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)
 {
        struct bnx2x *bp = netdev_priv(dev);
-       int i, j, k;
+       int i, j, k, offset, start;
        char queue_name[MAX_QUEUE_NAME_LEN+1];
 
        switch (stringset) {
@@ -2471,7 +2492,17 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
                break;
 
        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;
        }
 }