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
@ -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)
|
|||||||
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)
|
|||||||
* 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user