sfc: Cleanup reset code
authorBen Hutchings <bhutchings@solarflare.com>
Mon, 1 Sep 2008 11:48:50 +0000 (12:48 +0100)
committerJeff Garzik <jgarzik@redhat.com>
Wed, 3 Sep 2008 13:53:48 +0000 (09:53 -0400)
Move more code from efx_reset() into efx_reset_down() and efx_reset_up().

Stop propagating MAC/PHY setting failures from efx_reset_down() and
efx_reset_up() as these should not be fatal.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/net/sfc/efx.c

index f226dcf18c7d1cd374ef5aa73f8ecda7c87c6f02..f34dbf2c5b69376dbbe752de27c9b68888eb556b 100644 (file)
@@ -1527,46 +1527,58 @@ static void efx_unregister_netdev(struct efx_nic *efx)
  *
  **************************************************************************/
 
-/* The final hardware and software finalisation before reset. */
-static int efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+/* Tears down the entire software state and most of the hardware state
+ * before reset.  */
+static void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
        int rc;
 
        EFX_ASSERT_RESET_SERIALISED(efx);
 
+       /* The net_dev->get_stats handler is quite slow, and will fail
+        * if a fetch is pending over reset. Serialise against it. */
+       spin_lock(&efx->stats_lock);
+       spin_unlock(&efx->stats_lock);
+
+       efx_stop_all(efx);
+       mutex_lock(&efx->mac_lock);
+
        rc = falcon_xmac_get_settings(efx, ecmd);
-       if (rc) {
+       if (rc)
                EFX_ERR(efx, "could not back up PHY settings\n");
-               goto fail;
-       }
 
        efx_fini_channels(efx);
-       return 0;
-
- fail:
-       return rc;
 }
 
-/* The first part of software initialisation after a hardware reset
- * This function does not handle serialisation with the kernel, it
- * assumes the caller has done this */
-static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+/* This function will always ensure that the locks acquired in
+ * efx_reset_down() are released. A failure return code indicates
+ * that we were unable to reinitialise the hardware, and the
+ * driver should be disabled. If ok is false, then the rx and tx
+ * engines are not restarted, pending a RESET_DISABLE. */
+static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
+                       bool ok)
 {
        int rc;
 
-       efx_init_channels(efx);
+       EFX_ASSERT_RESET_SERIALISED(efx);
 
-       /* Restore MAC and PHY settings. */
-       rc = falcon_xmac_set_settings(efx, ecmd);
+       rc = falcon_init_nic(efx);
        if (rc) {
-               EFX_ERR(efx, "could not restore PHY settings\n");
-               goto fail;
+               EFX_ERR(efx, "failed to initialise NIC\n");
+               ok = false;
        }
 
-       return 0;
+       if (ok) {
+               efx_init_channels(efx);
 
- fail:
-       efx_fini_channels(efx);
+               if (falcon_xmac_set_settings(efx, ecmd))
+                       EFX_ERR(efx, "could not restore PHY settings\n");
+       }
+
+       mutex_unlock(&efx->mac_lock);
+
+       if (ok)
+               efx_start_all(efx);
        return rc;
 }
 
@@ -1598,22 +1610,12 @@ static int efx_reset(struct efx_nic *efx)
        efx->state = STATE_RESETTING;
        EFX_INFO(efx, "resetting (%d)\n", method);
 
-       /* The net_dev->get_stats handler is quite slow, and will fail
-        * if a fetch is pending over reset. Serialise against it. */
-       spin_lock(&efx->stats_lock);
-       spin_unlock(&efx->stats_lock);
-
-       efx_stop_all(efx);
-       mutex_lock(&efx->mac_lock);
-
-       rc = efx_reset_down(efx, &ecmd);
-       if (rc)
-               goto fail1;
+       efx_reset_down(efx, &ecmd);
 
        rc = falcon_reset_hw(efx, method);
        if (rc) {
                EFX_ERR(efx, "failed to reset hardware\n");
-               goto fail2;
+               goto fail;
        }
 
        /* Allow resets to be rescheduled. */
@@ -1625,46 +1627,28 @@ static int efx_reset(struct efx_nic *efx)
         * can respond to requests. */
        pci_set_master(efx->pci_dev);
 
-       /* Reinitialise device. This is appropriate in the RESET_TYPE_DISABLE
-        * case so the driver can talk to external SRAM */
-       rc = falcon_init_nic(efx);
-       if (rc) {
-               EFX_ERR(efx, "failed to initialise NIC\n");
-               goto fail3;
-       }
-
        /* Leave device stopped if necessary */
        if (method == RESET_TYPE_DISABLE) {
-               /* Reinitialise the device anyway so the driver unload sequence
-                * can talk to the external SRAM */
-               falcon_init_nic(efx);
                rc = -EIO;
-               goto fail4;
+               goto fail;
        }
 
-       rc = efx_reset_up(efx, &ecmd);
+       rc = efx_reset_up(efx, &ecmd, true);
        if (rc)
-               goto fail5;
+               goto disable;
 
-       mutex_unlock(&efx->mac_lock);
        EFX_LOG(efx, "reset complete\n");
-
        efx->state = STATE_RUNNING;
-       efx_start_all(efx);
-
  unlock_rtnl:
        rtnl_unlock();
        return 0;
 
- fail5:
- fail4:
- fail3:
- fail2:
- fail1:
+ fail:
+       efx_reset_up(efx, &ecmd, false);
+ disable:
        EFX_ERR(efx, "has been disabled\n");
        efx->state = STATE_DISABLED;
 
-       mutex_unlock(&efx->mac_lock);
        rtnl_unlock();
        efx_unregister_netdev(efx);
        efx_fini_port(efx);