|
@@ -554,7 +554,7 @@ rx_ring_summary:
|
|
|
16, 1,
|
|
|
page_address(buffer_info->page) +
|
|
|
buffer_info->page_offset,
|
|
|
- IGB_RX_BUFSZ, true);
|
|
|
+ igb_rx_bufsz(rx_ring), true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -3746,7 +3746,10 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
|
|
|
|
|
|
/* set descriptor configuration */
|
|
|
srrctl = IGB_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
|
|
|
- srrctl |= IGB_RX_BUFSZ >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
|
|
+ if (ring_uses_large_buffer(ring))
|
|
|
+ srrctl |= IGB_RXBUFFER_3072 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
|
|
+ else
|
|
|
+ srrctl |= IGB_RXBUFFER_2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
|
|
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
|
|
|
if (hw->mac.type >= e1000_82580)
|
|
|
srrctl |= E1000_SRRCTL_TIMESTAMP;
|
|
@@ -3776,6 +3779,23 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
|
|
|
wr32(E1000_RXDCTL(reg_idx), rxdctl);
|
|
|
}
|
|
|
|
|
|
+static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
|
|
|
+ struct igb_ring *rx_ring)
|
|
|
+{
|
|
|
+ /* set build_skb and buffer size flags */
|
|
|
+ clear_ring_uses_large_buffer(rx_ring);
|
|
|
+
|
|
|
+ if (adapter->flags & IGB_FLAG_RX_LEGACY)
|
|
|
+ return;
|
|
|
+
|
|
|
+#if (PAGE_SIZE < 8192)
|
|
|
+ if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
|
|
|
+ return;
|
|
|
+
|
|
|
+ set_ring_uses_large_buffer(rx_ring);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* igb_configure_rx - Configure receive Unit after Reset
|
|
|
* @adapter: board private structure
|
|
@@ -3793,8 +3813,12 @@ static void igb_configure_rx(struct igb_adapter *adapter)
|
|
|
/* Setup the HW Rx Head and Tail Descriptor Pointers and
|
|
|
* the Base and Length of the Rx Descriptor Ring
|
|
|
*/
|
|
|
- for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
- igb_configure_rx_ring(adapter, adapter->rx_ring[i]);
|
|
|
+ for (i = 0; i < adapter->num_rx_queues; i++) {
|
|
|
+ struct igb_ring *rx_ring = adapter->rx_ring[i];
|
|
|
+
|
|
|
+ igb_set_rx_buffer_len(adapter, rx_ring);
|
|
|
+ igb_configure_rx_ring(adapter, rx_ring);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3969,13 +3993,13 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring)
|
|
|
dma_sync_single_range_for_cpu(rx_ring->dev,
|
|
|
buffer_info->dma,
|
|
|
buffer_info->page_offset,
|
|
|
- IGB_RX_BUFSZ,
|
|
|
+ igb_rx_bufsz(rx_ring),
|
|
|
DMA_FROM_DEVICE);
|
|
|
|
|
|
/* free resources associated with mapping */
|
|
|
dma_unmap_page_attrs(rx_ring->dev,
|
|
|
buffer_info->dma,
|
|
|
- PAGE_SIZE,
|
|
|
+ igb_rx_pg_size(rx_ring),
|
|
|
DMA_FROM_DEVICE,
|
|
|
IGB_RX_DMA_ATTR);
|
|
|
__page_frag_cache_drain(buffer_info->page,
|
|
@@ -6870,7 +6894,7 @@ static inline bool igb_page_is_reserved(struct page *page)
|
|
|
|
|
|
static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
|
|
|
struct page *page,
|
|
|
- unsigned int truesize)
|
|
|
+ const unsigned int truesize)
|
|
|
{
|
|
|
unsigned int pagecnt_bias = rx_buffer->pagecnt_bias--;
|
|
|
|
|
@@ -6884,12 +6908,14 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
|
|
|
return false;
|
|
|
|
|
|
/* flip page offset to other buffer */
|
|
|
- rx_buffer->page_offset ^= IGB_RX_BUFSZ;
|
|
|
+ rx_buffer->page_offset ^= truesize;
|
|
|
#else
|
|
|
/* move offset up to the next cache line */
|
|
|
rx_buffer->page_offset += truesize;
|
|
|
+#define IGB_LAST_OFFSET \
|
|
|
+ (SKB_WITH_OVERHEAD(PAGE_SIZE) - IGB_RXBUFFER_2048)
|
|
|
|
|
|
- if (rx_buffer->page_offset > (PAGE_SIZE - IGB_RX_BUFSZ))
|
|
|
+ if (rx_buffer->page_offset > IGB_LAST_OFFSET)
|
|
|
return false;
|
|
|
#endif
|
|
|
|
|
@@ -6929,7 +6955,7 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring,
|
|
|
struct page *page = rx_buffer->page;
|
|
|
void *va = page_address(page) + rx_buffer->page_offset;
|
|
|
#if (PAGE_SIZE < 8192)
|
|
|
- unsigned int truesize = IGB_RX_BUFSZ;
|
|
|
+ unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
|
|
|
#else
|
|
|
unsigned int truesize = SKB_DATA_ALIGN(size);
|
|
|
#endif
|
|
@@ -7025,7 +7051,7 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
|
|
|
* any references we are holding to it
|
|
|
*/
|
|
|
dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma,
|
|
|
- PAGE_SIZE, DMA_FROM_DEVICE,
|
|
|
+ igb_rx_pg_size(rx_ring), DMA_FROM_DEVICE,
|
|
|
IGB_RX_DMA_ATTR);
|
|
|
__page_frag_cache_drain(page, rx_buffer->pagecnt_bias);
|
|
|
}
|
|
@@ -7278,21 +7304,23 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
|
|
|
return true;
|
|
|
|
|
|
/* alloc new page for storage */
|
|
|
- page = dev_alloc_page();
|
|
|
+ page = dev_alloc_pages(igb_rx_pg_order(rx_ring));
|
|
|
if (unlikely(!page)) {
|
|
|
rx_ring->rx_stats.alloc_failed++;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/* map page for use */
|
|
|
- dma = dma_map_page_attrs(rx_ring->dev, page, 0, PAGE_SIZE,
|
|
|
- DMA_FROM_DEVICE, IGB_RX_DMA_ATTR);
|
|
|
+ dma = dma_map_page_attrs(rx_ring->dev, page, 0,
|
|
|
+ igb_rx_pg_size(rx_ring),
|
|
|
+ DMA_FROM_DEVICE,
|
|
|
+ IGB_RX_DMA_ATTR);
|
|
|
|
|
|
/* if mapping failed free memory back to system since
|
|
|
* there isn't much point in holding memory we can't use
|
|
|
*/
|
|
|
if (dma_mapping_error(rx_ring->dev, dma)) {
|
|
|
- __free_page(page);
|
|
|
+ __free_pages(page, igb_rx_pg_order(rx_ring));
|
|
|
|
|
|
rx_ring->rx_stats.alloc_failed++;
|
|
|
return false;
|
|
@@ -7315,6 +7343,7 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
|
|
|
union e1000_adv_rx_desc *rx_desc;
|
|
|
struct igb_rx_buffer *bi;
|
|
|
u16 i = rx_ring->next_to_use;
|
|
|
+ u16 bufsz;
|
|
|
|
|
|
/* nothing to do */
|
|
|
if (!cleaned_count)
|
|
@@ -7324,14 +7353,15 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
|
|
|
bi = &rx_ring->rx_buffer_info[i];
|
|
|
i -= rx_ring->count;
|
|
|
|
|
|
+ bufsz = igb_rx_bufsz(rx_ring);
|
|
|
+
|
|
|
do {
|
|
|
if (!igb_alloc_mapped_page(rx_ring, bi))
|
|
|
break;
|
|
|
|
|
|
/* sync the buffer for use by the device */
|
|
|
dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
|
|
|
- bi->page_offset,
|
|
|
- IGB_RX_BUFSZ,
|
|
|
+ bi->page_offset, bufsz,
|
|
|
DMA_FROM_DEVICE);
|
|
|
|
|
|
/* Refresh the desc even if buffer_addrs didn't change
|