i40e: fix pf reset after offline test
authorShannon Nelson <shannon.nelson@intel.com>
Tue, 26 Nov 2013 10:49:12 +0000 (10:49 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 16 Dec 2013 08:48:46 +0000 (00:48 -0800)
When the ethtool testing starts it sets the I40E_TESTING state
bit, which blocks new netdev opens so that things don't get
confused, while the testing might be messing with register and
other things.  Unfortunately, that was keeping the PF resets
after the register test from working correctly because the netdev
would not get reopened.  This patch reorders the tests to put the
register test last as it is the only one that needs a reset, and
we wait to trigger the reset until after we clear the
I40E_TESTING bit.

Change-Id: Ieaa18d74264250ac336b0656b490125ee8a22d2a
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_ethtool.c

index eb34375..9c380a8 100644 (file)
@@ -748,7 +748,6 @@ static int i40e_reg_test(struct net_device *netdev, u64 *data)
        netif_info(pf, hw, netdev, "register test\n");
        *data = i40e_diag_reg_test(&pf->hw);
 
-       i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
        return *data;
 }
 
@@ -796,20 +795,18 @@ static void i40e_diag_test(struct net_device *netdev,
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_pf *pf = np->vsi->back;
 
-       set_bit(__I40E_TESTING, &pf->state);
        if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
                /* Offline tests */
                netif_info(pf, drv, netdev, "offline testing starting\n");
 
+               set_bit(__I40E_TESTING, &pf->state);
+
                /* Link test performed before hardware reset
                 * so autoneg doesn't interfere with test result
                 */
                if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
                        eth_test->flags |= ETH_TEST_FL_FAILED;
 
-               if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
-                       eth_test->flags |= ETH_TEST_FL_FAILED;
-
                if (i40e_eeprom_test(netdev, &data[I40E_ETH_TEST_EEPROM]))
                        eth_test->flags |= ETH_TEST_FL_FAILED;
 
@@ -819,6 +816,12 @@ static void i40e_diag_test(struct net_device *netdev,
                if (i40e_loopback_test(netdev, &data[I40E_ETH_TEST_LOOPBACK]))
                        eth_test->flags |= ETH_TEST_FL_FAILED;
 
+               /* run reg test last, a reset is required after it */
+               if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               clear_bit(__I40E_TESTING, &pf->state);
+               i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
        } else {
                /* Online tests */
                netif_info(pf, drv, netdev, "online testing starting\n");
@@ -832,7 +835,6 @@ static void i40e_diag_test(struct net_device *netdev,
                data[I40E_ETH_TEST_INTR] = 0;
                data[I40E_ETH_TEST_LOOPBACK] = 0;
        }
-       clear_bit(__I40E_TESTING, &pf->state);
 
        netif_info(pf, drv, netdev, "testing finished\n");
 }