diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-06-24 20:50:07 +0100 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2011-06-25 00:43:48 +0100 |
commit | 0e2a9c7cb941db993f481cdd6a99d70a302053e0 (patch) | |
tree | 1b71555f2b37dfcc10d7471c96a3de56293a1f84 /drivers/net/sfc/ethtool.c | |
parent | a7d529ae2158b5300e4aa16c21f1828bc864449b (diff) | |
download | linux-0e2a9c7cb941db993f481cdd6a99d70a302053e0.tar.gz linux-0e2a9c7cb941db993f481cdd6a99d70a302053e0.tar.bz2 linux-0e2a9c7cb941db993f481cdd6a99d70a302053e0.zip |
sfc: Fix mapping of reset reasons and flags to methods
There are certain hardware bugs that may occur on Falcon during normal
operation, that require a reset to recover from. We try to minimise
disruption by keeping the PHY running, following a reset sequence
labelled as 'invisible'.
Siena does not suffer from these hardware bugs, so we have not
implemented an 'invisible' reset sequence. However, if a similar
error does occur (due to a hardware fault or software bug) then the
code shared with Falcon will wrongly assume that the PHY is not being
reset.
Since the mapping of reset reasons (internal) and flags (ethtool) to
methods must differ significantly between NIC types, move it into
per-NIC-type functions (replacing the insufficient reset_world_flags
field).
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/sfc/ethtool.c')
-rw-r--r-- | drivers/net/sfc/ethtool.c | 27 |
1 files changed, 5 insertions, 22 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index d229027dc363..bc4643af6dd1 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -796,30 +796,13 @@ static int efx_ethtool_set_wol(struct net_device *net_dev, static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) { struct efx_nic *efx = netdev_priv(net_dev); - enum reset_type method; - enum { - ETH_RESET_EFX_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER | - ETH_RESET_OFFLOAD | ETH_RESET_MAC) - }; - - /* Check for minimal reset flags */ - if ((*flags & ETH_RESET_EFX_INVISIBLE) != ETH_RESET_EFX_INVISIBLE) - return -EINVAL; - *flags ^= ETH_RESET_EFX_INVISIBLE; - method = RESET_TYPE_INVISIBLE; - - if (*flags & ETH_RESET_PHY) { - *flags ^= ETH_RESET_PHY; - method = RESET_TYPE_ALL; - } + int rc; - if ((*flags & efx->type->reset_world_flags) == - efx->type->reset_world_flags) { - *flags ^= efx->type->reset_world_flags; - method = RESET_TYPE_WORLD; - } + rc = efx->type->map_reset_flags(flags); + if (rc < 0) + return rc; - return efx_reset(efx, method); + return efx_reset(efx, rc); } static int |