sfc: RX buffer allocation takes prefix size into account in IP header alignment
authorAndrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
Sat, 16 Nov 2013 07:02:27 +0000 (11:02 +0400)
committerBen Hutchings <bhutchings@solarflare.com>
Fri, 6 Dec 2013 22:27:52 +0000 (22:27 +0000)
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>
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx.c

index 8bd5b485f1bc1fef2bb76548abb9e8fda20414e0..fd844b53e38565cffa3e267fe0229f01f522a0d6 100644 (file)
@@ -585,7 +585,7 @@ static void efx_start_datapath(struct efx_nic *efx)
                           EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
                           efx->type->rx_buffer_padding);
        rx_buf_len = (sizeof(struct efx_rx_page_state) +
-                     NET_IP_ALIGN + efx->rx_dma_len);
+                     efx->rx_ip_align + efx->rx_dma_len);
        if (rx_buf_len <= PAGE_SIZE) {
                efx->rx_scatter = efx->type->always_rx_scatter;
                efx->rx_buffer_order = 0;
@@ -2544,6 +2544,8 @@ static int efx_init_struct(struct efx_nic *efx,
 
        efx->net_dev = net_dev;
        efx->rx_prefix_size = efx->type->rx_prefix_size;
+       efx->rx_ip_align =
+               NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
        efx->rx_packet_hash_offset =
                efx->type->rx_hash_offset - efx->type->rx_prefix_size;
        spin_lock_init(&efx->stats_lock);
index b14a717ac3e8d95099b5d2648be590e138bc9e61..542a0d252ae0c25f6c60167c1ec9dba3943ba3d8 100644 (file)
@@ -683,6 +683,8 @@ struct vfdi_status;
  * @n_channels: Number of channels in use
  * @n_rx_channels: Number of channels used for RX (= number of RX queues)
  * @n_tx_channels: Number of channels used for TX
+ * @rx_ip_align: RX DMA address offset to have IP header aligned in
+ *     in accordance with NET_IP_ALIGN
  * @rx_dma_len: Current maximum RX DMA length
  * @rx_buffer_order: Order (log2) of number of pages for each RX buffer
  * @rx_buffer_truesize: Amortised allocation size of an RX buffer,
@@ -816,6 +818,7 @@ struct efx_nic {
        unsigned rss_spread;
        unsigned tx_channel_offset;
        unsigned n_tx_channels;
+       unsigned int rx_ip_align;
        unsigned int rx_dma_len;
        unsigned int rx_buffer_order;
        unsigned int rx_buffer_truesize;
index 8f09e686fc2392a80f56610c78a61c6374b4a410..42488df1f4ec2af02feb9a46c408168b6a7dabec 100644 (file)
@@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx,
 
 void efx_rx_config_page_split(struct efx_nic *efx)
 {
-       efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
+       efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align,
                                      EFX_RX_BUF_ALIGNMENT);
        efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
                ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
@@ -189,9 +189,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
                do {
                        index = rx_queue->added_count & rx_queue->ptr_mask;
                        rx_buf = efx_rx_buffer(rx_queue, index);
-                       rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
+                       rx_buf->dma_addr = dma_addr + efx->rx_ip_align;
                        rx_buf->page = page;
-                       rx_buf->page_offset = page_offset + NET_IP_ALIGN;
+                       rx_buf->page_offset = page_offset + efx->rx_ip_align;
                        rx_buf->len = efx->rx_dma_len;
                        rx_buf->flags = 0;
                        ++rx_queue->added_count;