sfc: SFT9001: Include non-breaking cable diagnostics in online self-tests
authorBen Hutchings <bhutchings@solarflare.com>
Fri, 27 Feb 2009 13:04:07 +0000 (13:04 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Mar 2009 11:15:02 +0000 (03:15 -0800)
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sfc/tenxpress.c

index 5b0f45166628161e6a225b39137d336e50266d93..23583ba2e7eb9d28ff356f7c0e44517e22c49b4c 100644 (file)
@@ -679,12 +679,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 {
        struct ethtool_cmd ecmd;
        int phy_id = efx->mii.phy_id;
-       int rc = 0, rc2, i, res_reg;
+       int rc = 0, rc2, i, ctrl_reg, res_reg;
 
-       if (!(flags & ETH_TEST_FL_OFFLINE))
-               return 0;
-
-       efx->phy_op->get_settings(efx, &ecmd);
+       if (flags & ETH_TEST_FL_OFFLINE)
+               efx->phy_op->get_settings(efx, &ecmd);
 
        /* Initialise cable diagnostic results to unknown failure */
        for (i = 1; i < 9; ++i)
@@ -692,18 +690,22 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 
        /* Run cable diagnostics; wait up to 5 seconds for them to complete.
         * A cable fault is not a self-test failure, but a timeout is. */
+       ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
+                   (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+       if (flags & ETH_TEST_FL_OFFLINE) {
+               /* Break the link in order to run full diagnostics.  We
+                * must reset the PHY to resume normal service. */
+               ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
+       }
        mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                           PMA_PMD_CDIAG_CTRL_REG,
-                           (1 << CDIAG_CTRL_IMMED_LBN) |
-                           (1 << CDIAG_CTRL_BRK_LINK_LBN) |
-                           (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+                           PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
        i = 0;
        while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
                                  PMA_PMD_CDIAG_CTRL_REG) &
               (1 << CDIAG_CTRL_IN_PROG_LBN)) {
                if (++i == 50) {
                        rc = -ETIMEDOUT;
-                       goto reset;
+                       goto out;
                }
                msleep(100);
        }
@@ -728,17 +730,18 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
                        results[5 + i] = len_reg;
        }
 
-       /* We must reset to exit cable diagnostic mode.  The BIST will
-        * also run when we do this. */
-reset:
-       rc2 = tenxpress_special_reset(efx);
-       results[0] = rc2 ? -1 : 1;
-       if (!rc)
-               rc = rc2;
-
-       rc2 = efx->phy_op->set_settings(efx, &ecmd);
-       if (!rc)
-               rc = rc2;
+out:
+       if (flags & ETH_TEST_FL_OFFLINE) {
+               /* Reset, running the BIST and then resuming normal service. */
+               rc2 = tenxpress_special_reset(efx);
+               results[0] = rc2 ? -1 : 1;
+               if (!rc)
+                       rc = rc2;
+
+               rc2 = efx->phy_op->set_settings(efx, &ecmd);
+               if (!rc)
+                       rc = rc2;
+       }
 
        return rc;
 }