From a7d529ae2158b5300e4aa16c21f1828bc864449b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 24 Jun 2011 20:46:31 +0100 Subject: sfc: Allow resets to be upgraded; use atomic ops for safety Currently an attempt to schedule any reset is ignored if a reset is already pending. This ignores the relative scopes - if the requested reset is greater in scope then the scheduled reset should be upgraded accordingly. There are also some race conditions which could lead to a reset request being lost. Deal with them by using atomic operations on a bitmask. This also makes tests on reset_pending easier to get right. Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e8d5f03a89fe..c422eb2ce60a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -645,7 +645,7 @@ struct efx_filter_state; * @irq_rx_moderation: IRQ moderation time for RX event queues * @msg_enable: Log message enable flags * @state: Device state flag. Serialised by the rtnl_lock. - * @reset_pending: Pending reset method (normally RESET_TYPE_NONE) + * @reset_pending: Bitmask for pending resets * @tx_queue: TX DMA queues * @rx_queue: RX DMA queues * @channel: Channels @@ -728,7 +728,7 @@ struct efx_nic { u32 msg_enable; enum nic_state state; - enum reset_type reset_pending; + unsigned long reset_pending; struct efx_channel *channel[EFX_MAX_CHANNELS]; char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6]; -- cgit v1.2.3 From 0e2a9c7cb941db993f481cdd6a99d70a302053e0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 24 Jun 2011 20:50:07 +0100 Subject: 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 --- drivers/net/sfc/net_driver.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index c422eb2ce60a..4597066741f1 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -828,6 +828,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @init: Initialise the controller * @fini: Shut down the controller * @monitor: Periodic function for polling link state and hardware monitor + * @map_reset_reason: Map ethtool reset reason to a reset method + * @map_reset_flags: Map ethtool reset flags to a reset method, if possible * @reset: Reset the controller hardware and possibly the PHY. This will * be called while the controller is uninitialised. * @probe_port: Probe the MAC and PHY @@ -865,8 +867,6 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @rx_dc_base: Base address in SRAM of RX queue descriptor caches * @offload_features: net_device feature flags for protocol offload * features implemented in hardware - * @reset_world_flags: Flags for additional components covered by - * reset method RESET_TYPE_WORLD */ struct efx_nic_type { int (*probe)(struct efx_nic *efx); @@ -874,6 +874,8 @@ struct efx_nic_type { int (*init)(struct efx_nic *efx); void (*fini)(struct efx_nic *efx); void (*monitor)(struct efx_nic *efx); + enum reset_type (*map_reset_reason)(enum reset_type reason); + int (*map_reset_flags)(u32 *flags); int (*reset)(struct efx_nic *efx, enum reset_type method); int (*probe_port)(struct efx_nic *efx); void (*remove_port)(struct efx_nic *efx); @@ -908,7 +910,6 @@ struct efx_nic_type { unsigned int tx_dc_base; unsigned int rx_dc_base; u32 offload_features; - u32 reset_world_flags; }; /************************************************************************** -- cgit v1.2.3