aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Cooper <jcooper@solarflare.com>2013-03-08 05:18:28 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-08-29 13:12:12 -0400
commite8c68c0a09279107b5b239ca6fa7c5839717b7e2 (patch)
tree27de28a6c05415007eb9d4f7c89aa4667aecf2dc
parent15acb1cea5d9298eac511b80380183be624fa31c (diff)
sfc: Prepare for RX scatter on EF10
RX DMA scatter is always enabled on EF10. Adjust the common RX completion handling to allow for this. RX completion events on EF10 include the length used from a single descriptor, not the cumulative length used. Add a field to struct efx_rx_queue to hold the cumulative length. [bwh: Also fix a related comment] Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/efx.c4
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h8
-rw-r--r--drivers/net/ethernet/sfc/rx.c8
3 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index aec62139420e..b4832230d744 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -587,7 +587,7 @@ static void efx_start_datapath(struct efx_nic *efx)
587 rx_buf_len = (sizeof(struct efx_rx_page_state) + 587 rx_buf_len = (sizeof(struct efx_rx_page_state) +
588 NET_IP_ALIGN + efx->rx_dma_len); 588 NET_IP_ALIGN + efx->rx_dma_len);
589 if (rx_buf_len <= PAGE_SIZE) { 589 if (rx_buf_len <= PAGE_SIZE) {
590 efx->rx_scatter = false; 590 efx->rx_scatter = efx->type->always_rx_scatter;
591 efx->rx_buffer_order = 0; 591 efx->rx_buffer_order = 0;
592 } else if (efx->type->can_rx_scatter) { 592 } else if (efx->type->can_rx_scatter) {
593 BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES); 593 BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES);
@@ -615,7 +615,7 @@ static void efx_start_datapath(struct efx_nic *efx)
615 efx->rx_dma_len, efx->rx_page_buf_step, 615 efx->rx_dma_len, efx->rx_page_buf_step,
616 efx->rx_bufs_per_page, efx->rx_pages_per_batch); 616 efx->rx_bufs_per_page, efx->rx_pages_per_batch);
617 617
618 /* RX filters also have scatter-enabled flags */ 618 /* RX filters may also have scatter-enabled flags */
619 if (efx->rx_scatter != old_rx_scatter) 619 if (efx->rx_scatter != old_rx_scatter)
620 efx->type->filter_update_rx_scatter(efx); 620 efx->type->filter_update_rx_scatter(efx);
621 621
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 89974f739bb6..5341c76b1d02 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -297,7 +297,8 @@ struct efx_rx_page_state {
297 * @added_count: Number of buffers added to the receive queue. 297 * @added_count: Number of buffers added to the receive queue.
298 * @notified_count: Number of buffers given to NIC (<= @added_count). 298 * @notified_count: Number of buffers given to NIC (<= @added_count).
299 * @removed_count: Number of buffers removed from the receive queue. 299 * @removed_count: Number of buffers removed from the receive queue.
300 * @scatter_n: Number of buffers used by current packet 300 * @scatter_n: Used by NIC specific receive code.
301 * @scatter_len: Used by NIC specific receive code.
301 * @page_ring: The ring to store DMA mapped pages for reuse. 302 * @page_ring: The ring to store DMA mapped pages for reuse.
302 * @page_add: Counter to calculate the write pointer for the recycle ring. 303 * @page_add: Counter to calculate the write pointer for the recycle ring.
303 * @page_remove: Counter to calculate the read pointer for the recycle ring. 304 * @page_remove: Counter to calculate the read pointer for the recycle ring.
@@ -329,6 +330,7 @@ struct efx_rx_queue {
329 unsigned int notified_count; 330 unsigned int notified_count;
330 unsigned int removed_count; 331 unsigned int removed_count;
331 unsigned int scatter_n; 332 unsigned int scatter_n;
333 unsigned int scatter_len;
332 struct page **page_ring; 334 struct page **page_ring;
333 unsigned int page_add; 335 unsigned int page_add;
334 unsigned int page_remove; 336 unsigned int page_remove;
@@ -1023,7 +1025,8 @@ struct efx_mtd_partition {
1023 * @rx_prefix_size: Size of RX prefix before packet data 1025 * @rx_prefix_size: Size of RX prefix before packet data
1024 * @rx_hash_offset: Offset of RX flow hash within prefix 1026 * @rx_hash_offset: Offset of RX flow hash within prefix
1025 * @rx_buffer_padding: Size of padding at end of RX packet 1027 * @rx_buffer_padding: Size of padding at end of RX packet
1026 * @can_rx_scatter: NIC is able to scatter packet to multiple buffers 1028 * @can_rx_scatter: NIC is able to scatter packets to multiple buffers
1029 * @always_rx_scatter: NIC will always scatter packets to multiple buffers
1027 * @max_interrupt_mode: Highest capability interrupt mode supported 1030 * @max_interrupt_mode: Highest capability interrupt mode supported
1028 * from &enum efx_init_mode. 1031 * from &enum efx_init_mode.
1029 * @timer_period_max: Maximum period of interrupt timer (in ticks) 1032 * @timer_period_max: Maximum period of interrupt timer (in ticks)
@@ -1142,6 +1145,7 @@ struct efx_nic_type {
1142 unsigned int rx_hash_offset; 1145 unsigned int rx_hash_offset;
1143 unsigned int rx_buffer_padding; 1146 unsigned int rx_buffer_padding;
1144 bool can_rx_scatter; 1147 bool can_rx_scatter;
1148 bool always_rx_scatter;
1145 unsigned int max_interrupt_mode; 1149 unsigned int max_interrupt_mode;
1146 unsigned int timer_period_max; 1150 unsigned int timer_period_max;
1147 netdev_features_t offload_features; 1151 netdev_features_t offload_features;
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 81eab21effe9..8c13dd8fa4dc 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -529,8 +529,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
529 if (!(flags & EFX_RX_PKT_PREFIX_LEN)) 529 if (!(flags & EFX_RX_PKT_PREFIX_LEN))
530 efx_rx_packet__check_len(rx_queue, rx_buf, len); 530 efx_rx_packet__check_len(rx_queue, rx_buf, len);
531 } else if (unlikely(n_frags > EFX_RX_MAX_FRAGS) || 531 } else if (unlikely(n_frags > EFX_RX_MAX_FRAGS) ||
532 unlikely(len <= (n_frags - 1) * EFX_RX_USR_BUF_SIZE) || 532 unlikely(len <= (n_frags - 1) * efx->rx_dma_len) ||
533 unlikely(len > n_frags * EFX_RX_USR_BUF_SIZE) || 533 unlikely(len > n_frags * efx->rx_dma_len) ||
534 unlikely(!efx->rx_scatter)) { 534 unlikely(!efx->rx_scatter)) {
535 /* If this isn't an explicit discard request, either 535 /* If this isn't an explicit discard request, either
536 * the hardware or the driver is broken. 536 * the hardware or the driver is broken.
@@ -581,9 +581,9 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
581 rx_buf = efx_rx_buf_next(rx_queue, rx_buf); 581 rx_buf = efx_rx_buf_next(rx_queue, rx_buf);
582 if (--tail_frags == 0) 582 if (--tail_frags == 0)
583 break; 583 break;
584 efx_sync_rx_buffer(efx, rx_buf, EFX_RX_USR_BUF_SIZE); 584 efx_sync_rx_buffer(efx, rx_buf, efx->rx_dma_len);
585 } 585 }
586 rx_buf->len = len - (n_frags - 1) * EFX_RX_USR_BUF_SIZE; 586 rx_buf->len = len - (n_frags - 1) * efx->rx_dma_len;
587 efx_sync_rx_buffer(efx, rx_buf, rx_buf->len); 587 efx_sync_rx_buffer(efx, rx_buf, rx_buf->len);
588 } 588 }
589 589