diff options
author | Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru> | 2013-11-16 02:02:27 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-12-06 17:27:52 -0500 |
commit | 2ec030144f648a6dd208f95f55ece212f1b72771 (patch) | |
tree | 8652b022a834b23589069b53881f089765a34ae6 /drivers/net/ethernet | |
parent | cd6fe65e923175e4f2e9fb585b1d78c6bf580fc6 (diff) |
sfc: RX buffer allocation takes prefix size into account in IP header alignment
rx_prefix_size is 4-bytes aligned on Falcon/Siena (16 bytes), but it is equal
to 14 on EF10. So, it should be taken into account if arch requires IP header
to be 4-bytes aligned (via NET_IP_ALIGN).
Fixes: 8127d661e77f ('sfc: Add support for Solarflare SFC9100 family')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 6 |
3 files changed, 9 insertions, 4 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 8bd5b485f1bc..fd844b53e385 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -585,7 +585,7 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
585 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | 585 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + |
586 | efx->type->rx_buffer_padding); | 586 | efx->type->rx_buffer_padding); |
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 | efx->rx_ip_align + efx->rx_dma_len); |
589 | if (rx_buf_len <= PAGE_SIZE) { | 589 | if (rx_buf_len <= PAGE_SIZE) { |
590 | efx->rx_scatter = efx->type->always_rx_scatter; | 590 | efx->rx_scatter = efx->type->always_rx_scatter; |
591 | efx->rx_buffer_order = 0; | 591 | efx->rx_buffer_order = 0; |
@@ -2544,6 +2544,8 @@ static int efx_init_struct(struct efx_nic *efx, | |||
2544 | 2544 | ||
2545 | efx->net_dev = net_dev; | 2545 | efx->net_dev = net_dev; |
2546 | efx->rx_prefix_size = efx->type->rx_prefix_size; | 2546 | efx->rx_prefix_size = efx->type->rx_prefix_size; |
2547 | efx->rx_ip_align = | ||
2548 | NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0; | ||
2547 | efx->rx_packet_hash_offset = | 2549 | efx->rx_packet_hash_offset = |
2548 | efx->type->rx_hash_offset - efx->type->rx_prefix_size; | 2550 | efx->type->rx_hash_offset - efx->type->rx_prefix_size; |
2549 | spin_lock_init(&efx->stats_lock); | 2551 | spin_lock_init(&efx->stats_lock); |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b14a717ac3e8..542a0d252ae0 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -683,6 +683,8 @@ struct vfdi_status; | |||
683 | * @n_channels: Number of channels in use | 683 | * @n_channels: Number of channels in use |
684 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) | 684 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) |
685 | * @n_tx_channels: Number of channels used for TX | 685 | * @n_tx_channels: Number of channels used for TX |
686 | * @rx_ip_align: RX DMA address offset to have IP header aligned in | ||
687 | * in accordance with NET_IP_ALIGN | ||
686 | * @rx_dma_len: Current maximum RX DMA length | 688 | * @rx_dma_len: Current maximum RX DMA length |
687 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer | 689 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer |
688 | * @rx_buffer_truesize: Amortised allocation size of an RX buffer, | 690 | * @rx_buffer_truesize: Amortised allocation size of an RX buffer, |
@@ -816,6 +818,7 @@ struct efx_nic { | |||
816 | unsigned rss_spread; | 818 | unsigned rss_spread; |
817 | unsigned tx_channel_offset; | 819 | unsigned tx_channel_offset; |
818 | unsigned n_tx_channels; | 820 | unsigned n_tx_channels; |
821 | unsigned int rx_ip_align; | ||
819 | unsigned int rx_dma_len; | 822 | unsigned int rx_dma_len; |
820 | unsigned int rx_buffer_order; | 823 | unsigned int rx_buffer_order; |
821 | unsigned int rx_buffer_truesize; | 824 | unsigned int rx_buffer_truesize; |
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 8f09e686fc23..42488df1f4ec 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
@@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, | |||
94 | 94 | ||
95 | void efx_rx_config_page_split(struct efx_nic *efx) | 95 | void efx_rx_config_page_split(struct efx_nic *efx) |
96 | { | 96 | { |
97 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN, | 97 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align, |
98 | EFX_RX_BUF_ALIGNMENT); | 98 | EFX_RX_BUF_ALIGNMENT); |
99 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : | 99 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : |
100 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / | 100 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / |
@@ -189,9 +189,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) | |||
189 | do { | 189 | do { |
190 | index = rx_queue->added_count & rx_queue->ptr_mask; | 190 | index = rx_queue->added_count & rx_queue->ptr_mask; |
191 | rx_buf = efx_rx_buffer(rx_queue, index); | 191 | rx_buf = efx_rx_buffer(rx_queue, index); |
192 | rx_buf->dma_addr = dma_addr + NET_IP_ALIGN; | 192 | rx_buf->dma_addr = dma_addr + efx->rx_ip_align; |
193 | rx_buf->page = page; | 193 | rx_buf->page = page; |
194 | rx_buf->page_offset = page_offset + NET_IP_ALIGN; | 194 | rx_buf->page_offset = page_offset + efx->rx_ip_align; |
195 | rx_buf->len = efx->rx_dma_len; | 195 | rx_buf->len = efx->rx_dma_len; |
196 | rx_buf->flags = 0; | 196 | rx_buf->flags = 0; |
197 | ++rx_queue->added_count; | 197 | ++rx_queue->added_count; |