diff options
author | Jon Cooper <jcooper@solarflare.com> | 2013-03-08 10:18:28 +0000 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-29 18:12:12 +0100 |
commit | e8c68c0a09279107b5b239ca6fa7c5839717b7e2 (patch) | |
tree | 27de28a6c05415007eb9d4f7c89aa4667aecf2dc /drivers/net/ethernet/sfc | |
parent | 15acb1cea5d9298eac511b80380183be624fa31c (diff) | |
download | lwn-e8c68c0a09279107b5b239ca6fa7c5839717b7e2.tar.gz lwn-e8c68c0a09279107b5b239ca6fa7c5839717b7e2.zip |
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>
Diffstat (limited to 'drivers/net/ethernet/sfc')
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 8 |
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) rx_buf_len = (sizeof(struct efx_rx_page_state) + NET_IP_ALIGN + efx->rx_dma_len); if (rx_buf_len <= PAGE_SIZE) { - efx->rx_scatter = false; + efx->rx_scatter = efx->type->always_rx_scatter; efx->rx_buffer_order = 0; } else if (efx->type->can_rx_scatter) { BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES); @@ -615,7 +615,7 @@ static void efx_start_datapath(struct efx_nic *efx) efx->rx_dma_len, efx->rx_page_buf_step, efx->rx_bufs_per_page, efx->rx_pages_per_batch); - /* RX filters also have scatter-enabled flags */ + /* RX filters may also have scatter-enabled flags */ if (efx->rx_scatter != old_rx_scatter) efx->type->filter_update_rx_scatter(efx); 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 { * @added_count: Number of buffers added to the receive queue. * @notified_count: Number of buffers given to NIC (<= @added_count). * @removed_count: Number of buffers removed from the receive queue. - * @scatter_n: Number of buffers used by current packet + * @scatter_n: Used by NIC specific receive code. + * @scatter_len: Used by NIC specific receive code. * @page_ring: The ring to store DMA mapped pages for reuse. * @page_add: Counter to calculate the write pointer for the recycle ring. * @page_remove: Counter to calculate the read pointer for the recycle ring. @@ -329,6 +330,7 @@ struct efx_rx_queue { unsigned int notified_count; unsigned int removed_count; unsigned int scatter_n; + unsigned int scatter_len; struct page **page_ring; unsigned int page_add; unsigned int page_remove; @@ -1023,7 +1025,8 @@ struct efx_mtd_partition { * @rx_prefix_size: Size of RX prefix before packet data * @rx_hash_offset: Offset of RX flow hash within prefix * @rx_buffer_padding: Size of padding at end of RX packet - * @can_rx_scatter: NIC is able to scatter packet to multiple buffers + * @can_rx_scatter: NIC is able to scatter packets to multiple buffers + * @always_rx_scatter: NIC will always scatter packets to multiple buffers * @max_interrupt_mode: Highest capability interrupt mode supported * from &enum efx_init_mode. * @timer_period_max: Maximum period of interrupt timer (in ticks) @@ -1142,6 +1145,7 @@ struct efx_nic_type { unsigned int rx_hash_offset; unsigned int rx_buffer_padding; bool can_rx_scatter; + bool always_rx_scatter; unsigned int max_interrupt_mode; unsigned int timer_period_max; 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, if (!(flags & EFX_RX_PKT_PREFIX_LEN)) efx_rx_packet__check_len(rx_queue, rx_buf, len); } else if (unlikely(n_frags > EFX_RX_MAX_FRAGS) || - unlikely(len <= (n_frags - 1) * EFX_RX_USR_BUF_SIZE) || - unlikely(len > n_frags * EFX_RX_USR_BUF_SIZE) || + unlikely(len <= (n_frags - 1) * efx->rx_dma_len) || + unlikely(len > n_frags * efx->rx_dma_len) || unlikely(!efx->rx_scatter)) { /* If this isn't an explicit discard request, either * the hardware or the driver is broken. @@ -581,9 +581,9 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_buf = efx_rx_buf_next(rx_queue, rx_buf); if (--tail_frags == 0) break; - efx_sync_rx_buffer(efx, rx_buf, EFX_RX_USR_BUF_SIZE); + efx_sync_rx_buffer(efx, rx_buf, efx->rx_dma_len); } - rx_buf->len = len - (n_frags - 1) * EFX_RX_USR_BUF_SIZE; + rx_buf->len = len - (n_frags - 1) * efx->rx_dma_len; efx_sync_rx_buffer(efx, rx_buf, rx_buf->len); } |