Commit e8c68c0a authored by Jon Cooper's avatar Jon Cooper Committed by Ben Hutchings

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: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 15acb1ce
...@@ -587,7 +587,7 @@ static void efx_start_datapath(struct efx_nic *efx) ...@@ -587,7 +587,7 @@ static void efx_start_datapath(struct efx_nic *efx)
rx_buf_len = (sizeof(struct efx_rx_page_state) + rx_buf_len = (sizeof(struct efx_rx_page_state) +
NET_IP_ALIGN + efx->rx_dma_len); NET_IP_ALIGN + efx->rx_dma_len);
if (rx_buf_len <= PAGE_SIZE) { if (rx_buf_len <= PAGE_SIZE) {
efx->rx_scatter = false; efx->rx_scatter = efx->type->always_rx_scatter;
efx->rx_buffer_order = 0; efx->rx_buffer_order = 0;
} else if (efx->type->can_rx_scatter) { } else if (efx->type->can_rx_scatter) {
BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES); 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,7 +615,7 @@ static void efx_start_datapath(struct efx_nic *efx)
efx->rx_dma_len, efx->rx_page_buf_step, efx->rx_dma_len, efx->rx_page_buf_step,
efx->rx_bufs_per_page, efx->rx_pages_per_batch); 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) if (efx->rx_scatter != old_rx_scatter)
efx->type->filter_update_rx_scatter(efx); efx->type->filter_update_rx_scatter(efx);
......
...@@ -297,7 +297,8 @@ struct efx_rx_page_state { ...@@ -297,7 +297,8 @@ struct efx_rx_page_state {
* @added_count: Number of buffers added to the receive queue. * @added_count: Number of buffers added to the receive queue.
* @notified_count: Number of buffers given to NIC (<= @added_count). * @notified_count: Number of buffers given to NIC (<= @added_count).
* @removed_count: Number of buffers removed from the receive queue. * @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_ring: The ring to store DMA mapped pages for reuse.
* @page_add: Counter to calculate the write pointer for the recycle ring. * @page_add: Counter to calculate the write pointer for the recycle ring.
* @page_remove: Counter to calculate the read 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 { ...@@ -329,6 +330,7 @@ struct efx_rx_queue {
unsigned int notified_count; unsigned int notified_count;
unsigned int removed_count; unsigned int removed_count;
unsigned int scatter_n; unsigned int scatter_n;
unsigned int scatter_len;
struct page **page_ring; struct page **page_ring;
unsigned int page_add; unsigned int page_add;
unsigned int page_remove; unsigned int page_remove;
...@@ -1023,7 +1025,8 @@ struct efx_mtd_partition { ...@@ -1023,7 +1025,8 @@ struct efx_mtd_partition {
* @rx_prefix_size: Size of RX prefix before packet data * @rx_prefix_size: Size of RX prefix before packet data
* @rx_hash_offset: Offset of RX flow hash within prefix * @rx_hash_offset: Offset of RX flow hash within prefix
* @rx_buffer_padding: Size of padding at end of RX packet * @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 * @max_interrupt_mode: Highest capability interrupt mode supported
* from &enum efx_init_mode. * from &enum efx_init_mode.
* @timer_period_max: Maximum period of interrupt timer (in ticks) * @timer_period_max: Maximum period of interrupt timer (in ticks)
...@@ -1142,6 +1145,7 @@ struct efx_nic_type { ...@@ -1142,6 +1145,7 @@ struct efx_nic_type {
unsigned int rx_hash_offset; unsigned int rx_hash_offset;
unsigned int rx_buffer_padding; unsigned int rx_buffer_padding;
bool can_rx_scatter; bool can_rx_scatter;
bool always_rx_scatter;
unsigned int max_interrupt_mode; unsigned int max_interrupt_mode;
unsigned int timer_period_max; unsigned int timer_period_max;
netdev_features_t offload_features; netdev_features_t offload_features;
......
...@@ -529,8 +529,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, ...@@ -529,8 +529,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
if (!(flags & EFX_RX_PKT_PREFIX_LEN)) if (!(flags & EFX_RX_PKT_PREFIX_LEN))
efx_rx_packet__check_len(rx_queue, rx_buf, len); efx_rx_packet__check_len(rx_queue, rx_buf, len);
} else if (unlikely(n_frags > EFX_RX_MAX_FRAGS) || } else if (unlikely(n_frags > EFX_RX_MAX_FRAGS) ||
unlikely(len <= (n_frags - 1) * EFX_RX_USR_BUF_SIZE) || unlikely(len <= (n_frags - 1) * efx->rx_dma_len) ||
unlikely(len > n_frags * EFX_RX_USR_BUF_SIZE) || unlikely(len > n_frags * efx->rx_dma_len) ||
unlikely(!efx->rx_scatter)) { unlikely(!efx->rx_scatter)) {
/* If this isn't an explicit discard request, either /* If this isn't an explicit discard request, either
* the hardware or the driver is broken. * 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,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); rx_buf = efx_rx_buf_next(rx_queue, rx_buf);
if (--tail_frags == 0) if (--tail_frags == 0)
break; 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); efx_sync_rx_buffer(efx, rx_buf, rx_buf->len);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment