Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 111356
b: refs/heads/master
c: 2467ca4
h: refs/heads/master
v: v3
  • Loading branch information
Ben Hutchings authored and Jeff Garzik committed Sep 3, 2008
1 parent d08e497 commit dd356ec
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc3c90a2b70652b87cde8de65275d6f41d0f24c3
refs/heads/master: 2467ca46b6bb7672ed59fc74ac6780bf10bcd742
98 changes: 41 additions & 57 deletions trunk/drivers/net/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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. */
Expand All @@ -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);
Expand Down

0 comments on commit dd356ec

Please sign in to comment.