Commit f4bd954e authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

sfc: When disabling the NIC, close the device rather than unregistering it

This should reduce user confusion and may also aid recovery (ioctls
will still be available).
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 307505e9
...@@ -1332,6 +1332,8 @@ static int efx_net_open(struct net_device *net_dev) ...@@ -1332,6 +1332,8 @@ static int efx_net_open(struct net_device *net_dev)
EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name, EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name,
raw_smp_processor_id()); raw_smp_processor_id());
if (efx->state == STATE_DISABLED)
return -EIO;
if (efx->phy_mode & PHY_MODE_SPECIAL) if (efx->phy_mode & PHY_MODE_SPECIAL)
return -EBUSY; return -EBUSY;
...@@ -1350,10 +1352,12 @@ static int efx_net_stop(struct net_device *net_dev) ...@@ -1350,10 +1352,12 @@ static int efx_net_stop(struct net_device *net_dev)
EFX_LOG(efx, "closing %s on CPU %d\n", net_dev->name, EFX_LOG(efx, "closing %s on CPU %d\n", net_dev->name,
raw_smp_processor_id()); raw_smp_processor_id());
/* Stop the device and flush all the channels */ if (efx->state != STATE_DISABLED) {
efx_stop_all(efx); /* Stop the device and flush all the channels */
efx_fini_channels(efx); efx_stop_all(efx);
efx_init_channels(efx); efx_fini_channels(efx);
efx_init_channels(efx);
}
return 0; return 0;
} }
...@@ -1685,7 +1689,7 @@ static int efx_reset(struct efx_nic *efx) ...@@ -1685,7 +1689,7 @@ static int efx_reset(struct efx_nic *efx)
{ {
struct ethtool_cmd ecmd; struct ethtool_cmd ecmd;
enum reset_type method = efx->reset_pending; enum reset_type method = efx->reset_pending;
int rc; int rc = 0;
/* Serialise with kernel interfaces */ /* Serialise with kernel interfaces */
rtnl_lock(); rtnl_lock();
...@@ -1694,7 +1698,7 @@ static int efx_reset(struct efx_nic *efx) ...@@ -1694,7 +1698,7 @@ static int efx_reset(struct efx_nic *efx)
* flag set so that efx_pci_probe_main will be retried */ * flag set so that efx_pci_probe_main will be retried */
if (efx->state != STATE_RUNNING) { if (efx->state != STATE_RUNNING) {
EFX_INFO(efx, "scheduled reset quenched. NIC not RUNNING\n"); EFX_INFO(efx, "scheduled reset quenched. NIC not RUNNING\n");
goto unlock_rtnl; goto out_unlock;
} }
EFX_INFO(efx, "resetting (%d)\n", method); EFX_INFO(efx, "resetting (%d)\n", method);
...@@ -1704,7 +1708,7 @@ static int efx_reset(struct efx_nic *efx) ...@@ -1704,7 +1708,7 @@ static int efx_reset(struct efx_nic *efx)
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 fail; goto out_disable;
} }
/* Allow resets to be rescheduled. */ /* Allow resets to be rescheduled. */
...@@ -1718,28 +1722,23 @@ static int efx_reset(struct efx_nic *efx) ...@@ -1718,28 +1722,23 @@ static int efx_reset(struct efx_nic *efx)
/* Leave device stopped if necessary */ /* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) { if (method == RESET_TYPE_DISABLE) {
efx_reset_up(efx, &ecmd, false);
rc = -EIO; rc = -EIO;
goto fail; } else {
rc = efx_reset_up(efx, &ecmd, true);
} }
rc = efx_reset_up(efx, &ecmd, true); out_disable:
if (rc) if (rc) {
goto disable; EFX_ERR(efx, "has been disabled\n");
efx->state = STATE_DISABLED;
EFX_LOG(efx, "reset complete\n"); dev_close(efx->net_dev);
unlock_rtnl: } else {
rtnl_unlock(); EFX_LOG(efx, "reset complete\n");
return 0; }
fail:
efx_reset_up(efx, &ecmd, false);
disable:
EFX_ERR(efx, "has been disabled\n");
efx->state = STATE_DISABLED;
out_unlock:
rtnl_unlock(); rtnl_unlock();
efx_unregister_netdev(efx);
efx_fini_port(efx);
return rc; return rc;
} }
......
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