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: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
bc3c90a2b7
commit
2467ca46b6
1 changed files with 41 additions and 57 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue