Commit 2467ca46 authored by Ben Hutchings's avatar Ben Hutchings Committed by Jeff Garzik

sfc: Cleanup reset code

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: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent bc3c90a2
...@@ -1527,46 +1527,58 @@ static void efx_unregister_netdev(struct efx_nic *efx) ...@@ -1527,46 +1527,58 @@ static void efx_unregister_netdev(struct efx_nic *efx)
* *
**************************************************************************/ **************************************************************************/
/* The final hardware and software finalisation before reset. */ /* Tears down the entire software state and most of the hardware state
static int efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) * before reset. */
static void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{ {
int rc; int rc;
EFX_ASSERT_RESET_SERIALISED(efx); 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); rc = falcon_xmac_get_settings(efx, ecmd);
if (rc) { if (rc)
EFX_ERR(efx, "could not back up PHY settings\n"); EFX_ERR(efx, "could not back up PHY settings\n");
goto fail;
}
efx_fini_channels(efx); efx_fini_channels(efx);
return 0;
fail:
return rc;
} }
/* The first part of software initialisation after a hardware reset /* This function will always ensure that the locks acquired in
* This function does not handle serialisation with the kernel, it * efx_reset_down() are released. A failure return code indicates
* assumes the caller has done this */ * that we were unable to reinitialise the hardware, and the
static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd) * 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; int rc;
efx_init_channels(efx); EFX_ASSERT_RESET_SERIALISED(efx);
/* Restore MAC and PHY settings. */ rc = falcon_init_nic(efx);
rc = falcon_xmac_set_settings(efx, ecmd);
if (rc) { if (rc) {
EFX_ERR(efx, "could not restore PHY settings\n"); EFX_ERR(efx, "failed to initialise NIC\n");
goto fail; ok = false;
} }
return 0; if (ok) {
efx_init_channels(efx);
fail: if (falcon_xmac_set_settings(efx, ecmd))
efx_fini_channels(efx); EFX_ERR(efx, "could not restore PHY settings\n");
}
mutex_unlock(&efx->mac_lock);
if (ok)
efx_start_all(efx);
return rc; return rc;
} }
...@@ -1598,22 +1610,12 @@ static int efx_reset(struct efx_nic *efx) ...@@ -1598,22 +1610,12 @@ static int efx_reset(struct efx_nic *efx)
efx->state = STATE_RESETTING; efx->state = STATE_RESETTING;
EFX_INFO(efx, "resetting (%d)\n", method); EFX_INFO(efx, "resetting (%d)\n", method);
/* The net_dev->get_stats handler is quite slow, and will fail efx_reset_down(efx, &ecmd);
* 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;
rc = falcon_reset_hw(efx, method); rc = falcon_reset_hw(efx, method);
if (rc) { if (rc) {
EFX_ERR(efx, "failed to reset hardware\n"); EFX_ERR(efx, "failed to reset hardware\n");
goto fail2; goto fail;
} }
/* Allow resets to be rescheduled. */ /* Allow resets to be rescheduled. */
...@@ -1625,46 +1627,28 @@ static int efx_reset(struct efx_nic *efx) ...@@ -1625,46 +1627,28 @@ static int efx_reset(struct efx_nic *efx)
* can respond to requests. */ * can respond to requests. */
pci_set_master(efx->pci_dev); 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 */ /* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) { 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; rc = -EIO;
goto fail4; goto fail;
} }
rc = efx_reset_up(efx, &ecmd); rc = efx_reset_up(efx, &ecmd, true);
if (rc) if (rc)
goto fail5; goto disable;
mutex_unlock(&efx->mac_lock);
EFX_LOG(efx, "reset complete\n"); EFX_LOG(efx, "reset complete\n");
efx->state = STATE_RUNNING; efx->state = STATE_RUNNING;
efx_start_all(efx);
unlock_rtnl: unlock_rtnl:
rtnl_unlock(); rtnl_unlock();
return 0; return 0;
fail5: fail:
fail4: efx_reset_up(efx, &ecmd, false);
fail3: disable:
fail2:
fail1:
EFX_ERR(efx, "has been disabled\n"); EFX_ERR(efx, "has been disabled\n");
efx->state = STATE_DISABLED; efx->state = STATE_DISABLED;
mutex_unlock(&efx->mac_lock);
rtnl_unlock(); rtnl_unlock();
efx_unregister_netdev(efx); efx_unregister_netdev(efx);
efx_fini_port(efx); efx_fini_port(efx);
......
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