diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2013-05-27 11:52:54 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-21 14:48:54 -0400 |
commit | d8aec745ddaf278ba187d7712c1becc5ffd0f7da (patch) | |
tree | 6f6f9c650a0eeb74d933bed7b032dd4554ca24b1 /drivers | |
parent | 1840667a851efb5f719d2c76b235c172104722e8 (diff) |
sfc: Stop RX refill before flushing RX queues
rx_queue::enabled guards refill, so rename it to reflect that. Clear
it at the start of the queue teardown process rather than waiting for
the RX queue to be flushed.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 8 |
4 files changed, 13 insertions, 9 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index a7818d1c2415..ee9242cf5fd7 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -248,8 +248,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) | |||
248 | efx_channel_get_rx_queue(channel); | 248 | efx_channel_get_rx_queue(channel); |
249 | 249 | ||
250 | efx_rx_flush_packet(channel); | 250 | efx_rx_flush_packet(channel); |
251 | if (rx_queue->enabled) | 251 | efx_fast_push_rx_descriptors(rx_queue); |
252 | efx_fast_push_rx_descriptors(rx_queue); | ||
253 | } | 252 | } |
254 | 253 | ||
255 | return spent; | 254 | return spent; |
@@ -647,6 +646,12 @@ static void efx_stop_datapath(struct efx_nic *efx) | |||
647 | EFX_ASSERT_RESET_SERIALISED(efx); | 646 | EFX_ASSERT_RESET_SERIALISED(efx); |
648 | BUG_ON(efx->port_enabled); | 647 | BUG_ON(efx->port_enabled); |
649 | 648 | ||
649 | /* Stop RX refill */ | ||
650 | efx_for_each_channel(channel, efx) { | ||
651 | efx_for_each_channel_rx_queue(rx_queue, channel) | ||
652 | rx_queue->refill_enabled = false; | ||
653 | } | ||
654 | |||
650 | /* Only perform flush if dma is enabled */ | 655 | /* Only perform flush if dma is enabled */ |
651 | if (dev->is_busmaster && efx->state != STATE_RECOVERY) { | 656 | if (dev->is_busmaster && efx->state != STATE_RECOVERY) { |
652 | rc = efx_nic_flush_queues(efx); | 657 | rc = efx_nic_flush_queues(efx); |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 7c9637203ea0..c9f798913f39 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -286,7 +286,7 @@ struct efx_rx_page_state { | |||
286 | * @buffer: The software buffer ring | 286 | * @buffer: The software buffer ring |
287 | * @rxd: The hardware descriptor ring | 287 | * @rxd: The hardware descriptor ring |
288 | * @ptr_mask: The size of the ring minus 1. | 288 | * @ptr_mask: The size of the ring minus 1. |
289 | * @enabled: Receive queue enabled indicator. | 289 | * @refill_enabled: Enable refill whenever fill level is low |
290 | * @flush_pending: Set when a RX flush is pending. Has the same lifetime as | 290 | * @flush_pending: Set when a RX flush is pending. Has the same lifetime as |
291 | * @rxq_flush_pending. | 291 | * @rxq_flush_pending. |
292 | * @added_count: Number of buffers added to the receive queue. | 292 | * @added_count: Number of buffers added to the receive queue. |
@@ -317,7 +317,7 @@ struct efx_rx_queue { | |||
317 | struct efx_rx_buffer *buffer; | 317 | struct efx_rx_buffer *buffer; |
318 | struct efx_special_buffer rxd; | 318 | struct efx_special_buffer rxd; |
319 | unsigned int ptr_mask; | 319 | unsigned int ptr_mask; |
320 | bool enabled; | 320 | bool refill_enabled; |
321 | bool flush_pending; | 321 | bool flush_pending; |
322 | 322 | ||
323 | unsigned int added_count; | 323 | unsigned int added_count; |
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 2d0a584e1af2..deb0ee04fe70 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c | |||
@@ -1204,7 +1204,6 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event) | |||
1204 | * queue. Refill it here */ | 1204 | * queue. Refill it here */ |
1205 | efx_fast_push_rx_descriptors(rx_queue); | 1205 | efx_fast_push_rx_descriptors(rx_queue); |
1206 | } else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) { | 1206 | } else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) { |
1207 | rx_queue->enabled = false; | ||
1208 | efx_handle_drain_event(channel); | 1207 | efx_handle_drain_event(channel); |
1209 | } else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) { | 1208 | } else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) { |
1210 | efx_handle_drain_event(channel); | 1209 | efx_handle_drain_event(channel); |
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 6af9cfda50fb..8b482dee4eb0 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
@@ -326,6 +326,9 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) | |||
326 | unsigned int fill_level, batch_size; | 326 | unsigned int fill_level, batch_size; |
327 | int space, rc = 0; | 327 | int space, rc = 0; |
328 | 328 | ||
329 | if (!rx_queue->refill_enabled) | ||
330 | return; | ||
331 | |||
329 | /* Calculate current fill level, and exit if we don't need to fill */ | 332 | /* Calculate current fill level, and exit if we don't need to fill */ |
330 | fill_level = (rx_queue->added_count - rx_queue->removed_count); | 333 | fill_level = (rx_queue->added_count - rx_queue->removed_count); |
331 | EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries); | 334 | EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries); |
@@ -738,9 +741,9 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) | |||
738 | 741 | ||
739 | rx_queue->max_fill = max_fill; | 742 | rx_queue->max_fill = max_fill; |
740 | rx_queue->fast_fill_trigger = trigger; | 743 | rx_queue->fast_fill_trigger = trigger; |
744 | rx_queue->refill_enabled = true; | ||
741 | 745 | ||
742 | /* Set up RX descriptor ring */ | 746 | /* Set up RX descriptor ring */ |
743 | rx_queue->enabled = true; | ||
744 | efx_nic_init_rx(rx_queue); | 747 | efx_nic_init_rx(rx_queue); |
745 | } | 748 | } |
746 | 749 | ||
@@ -753,9 +756,6 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) | |||
753 | netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, | 756 | netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, |
754 | "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); | 757 | "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); |
755 | 758 | ||
756 | /* A flush failure might have left rx_queue->enabled */ | ||
757 | rx_queue->enabled = false; | ||
758 | |||
759 | del_timer_sync(&rx_queue->slow_fill); | 759 | del_timer_sync(&rx_queue->slow_fill); |
760 | efx_nic_fini_rx(rx_queue); | 760 | efx_nic_fini_rx(rx_queue); |
761 | 761 | ||