sfc: Refactor queue teardown sequence to allow for EF10 flush behaviour
Currently efx_stop_datapath() will try to flush our DMA queues (if DMA is enabled), then finalise software and hardware state for each queue. However, for EF10 we must ask the MC to finalise each queue, which implicitly starts flushing it, and then wait for the flush events. We therefore need to delegate more of this to the NIC type. Combine all the hardware operations into a new NIC-type operation efx_nic_type::fini_dmaq, and call this before tearing down the software state and buffers for all the DMA queues. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
@@ -640,7 +640,6 @@ static void efx_stop_datapath(struct efx_nic *efx)
|
||||
struct efx_channel *channel;
|
||||
struct efx_tx_queue *tx_queue;
|
||||
struct efx_rx_queue *rx_queue;
|
||||
struct pci_dev *dev = efx->pci_dev;
|
||||
int rc;
|
||||
|
||||
EFX_ASSERT_RESET_SERIALISED(efx);
|
||||
@@ -652,26 +651,6 @@ static void efx_stop_datapath(struct efx_nic *efx)
|
||||
rx_queue->refill_enabled = false;
|
||||
}
|
||||
|
||||
/* Only perform flush if dma is enabled */
|
||||
if (dev->is_busmaster && efx->state != STATE_RECOVERY) {
|
||||
rc = efx_nic_flush_queues(efx);
|
||||
|
||||
if (rc && EFX_WORKAROUND_7803(efx)) {
|
||||
/* Schedule a reset to recover from the flush failure. The
|
||||
* descriptor caches reference memory we're about to free,
|
||||
* but falcon_reconfigure_mac_wrapper() won't reconnect
|
||||
* the MACs because of the pending reset. */
|
||||
netif_err(efx, drv, efx->net_dev,
|
||||
"Resetting to recover from flush failure\n");
|
||||
efx_schedule_reset(efx, RESET_TYPE_ALL);
|
||||
} else if (rc) {
|
||||
netif_err(efx, drv, efx->net_dev, "failed to flush queues\n");
|
||||
} else {
|
||||
netif_dbg(efx, drv, efx->net_dev,
|
||||
"successfully flushed all queues\n");
|
||||
}
|
||||
}
|
||||
|
||||
efx_for_each_channel(channel, efx) {
|
||||
/* RX packet processing is pipelined, so wait for the
|
||||
* NAPI handler to complete. At least event queue 0
|
||||
@@ -683,7 +662,26 @@ static void efx_stop_datapath(struct efx_nic *efx)
|
||||
efx_stop_eventq(channel);
|
||||
efx_start_eventq(channel);
|
||||
}
|
||||
}
|
||||
|
||||
rc = efx->type->fini_dmaq(efx);
|
||||
if (rc && EFX_WORKAROUND_7803(efx)) {
|
||||
/* Schedule a reset to recover from the flush failure. The
|
||||
* descriptor caches reference memory we're about to free,
|
||||
* but falcon_reconfigure_mac_wrapper() won't reconnect
|
||||
* the MACs because of the pending reset.
|
||||
*/
|
||||
netif_err(efx, drv, efx->net_dev,
|
||||
"Resetting to recover from flush failure\n");
|
||||
efx_schedule_reset(efx, RESET_TYPE_ALL);
|
||||
} else if (rc) {
|
||||
netif_err(efx, drv, efx->net_dev, "failed to flush queues\n");
|
||||
} else {
|
||||
netif_dbg(efx, drv, efx->net_dev,
|
||||
"successfully flushed all queues\n");
|
||||
}
|
||||
|
||||
efx_for_each_channel(channel, efx) {
|
||||
efx_for_each_channel_rx_queue(rx_queue, channel)
|
||||
efx_fini_rx_queue(rx_queue);
|
||||
efx_for_each_possible_channel_tx_queue(tx_queue, channel)
|
||||
|
||||
Reference in New Issue
Block a user