diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 74 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.h | 2 |
2 files changed, 66 insertions, 10 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index d481b0a99847..482138ec64d2 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -195,6 +195,15 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) | |||
195 | #define TG3_RX_OFFSET(tp) (NET_SKB_PAD) | 195 | #define TG3_RX_OFFSET(tp) (NET_SKB_PAD) |
196 | #endif | 196 | #endif |
197 | 197 | ||
198 | /* This driver uses the new build_skb() API providing a frag as skb->head | ||
199 | * This strategy permits better GRO aggregation, better TCP coalescing, and | ||
200 | * better splice() implementation (avoids a copy from head to a page), at | ||
201 | * minimal memory cost. | ||
202 | * In this 2048 bytes block, we have enough room to store the MTU=1500 frame | ||
203 | * and the struct skb_shared_info. | ||
204 | */ | ||
205 | #define TG3_FRAGSIZE 2048 | ||
206 | |||
198 | /* minimum number of free TX descriptors required to wake up TX process */ | 207 | /* minimum number of free TX descriptors required to wake up TX process */ |
199 | #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) | 208 | #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) |
200 | #define TG3_TX_BD_DMA_MAX_2K 2048 | 209 | #define TG3_TX_BD_DMA_MAX_2K 2048 |
@@ -5617,17 +5626,48 @@ static void tg3_tx(struct tg3_napi *tnapi) | |||
5617 | } | 5626 | } |
5618 | } | 5627 | } |
5619 | 5628 | ||
5629 | static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr) | ||
5630 | { | ||
5631 | void *data; | ||
5632 | |||
5633 | if (tpr->rx_page_size < TG3_FRAGSIZE) { | ||
5634 | struct page *page = alloc_page(GFP_ATOMIC); | ||
5635 | |||
5636 | if (!page) | ||
5637 | return NULL; | ||
5638 | atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count); | ||
5639 | tpr->rx_page_addr = page_address(page); | ||
5640 | tpr->rx_page_size = PAGE_SIZE; | ||
5641 | } | ||
5642 | data = tpr->rx_page_addr; | ||
5643 | tpr->rx_page_addr += TG3_FRAGSIZE; | ||
5644 | tpr->rx_page_size -= TG3_FRAGSIZE; | ||
5645 | return data; | ||
5646 | } | ||
5647 | |||
5648 | static void tg3_frag_free(bool is_frag, void *data) | ||
5649 | { | ||
5650 | if (is_frag) | ||
5651 | put_page(virt_to_head_page(data)); | ||
5652 | else | ||
5653 | kfree(data); | ||
5654 | } | ||
5655 | |||
5620 | static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) | 5656 | static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) |
5621 | { | 5657 | { |
5658 | unsigned int skb_size = SKB_DATA_ALIGN(map_sz + TG3_RX_OFFSET(tp)) + | ||
5659 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | ||
5660 | |||
5622 | if (!ri->data) | 5661 | if (!ri->data) |
5623 | return; | 5662 | return; |
5624 | 5663 | ||
5625 | pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), | 5664 | pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), |
5626 | map_sz, PCI_DMA_FROMDEVICE); | 5665 | map_sz, PCI_DMA_FROMDEVICE); |
5627 | kfree(ri->data); | 5666 | tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data); |
5628 | ri->data = NULL; | 5667 | ri->data = NULL; |
5629 | } | 5668 | } |
5630 | 5669 | ||
5670 | |||
5631 | /* Returns size of skb allocated or < 0 on error. | 5671 | /* Returns size of skb allocated or < 0 on error. |
5632 | * | 5672 | * |
5633 | * We only need to fill in the address because the other members | 5673 | * We only need to fill in the address because the other members |
@@ -5640,7 +5680,8 @@ static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) | |||
5640 | * (to fetch the error flags, vlan tag, checksum, and opaque cookie). | 5680 | * (to fetch the error flags, vlan tag, checksum, and opaque cookie). |
5641 | */ | 5681 | */ |
5642 | static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, | 5682 | static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, |
5643 | u32 opaque_key, u32 dest_idx_unmasked) | 5683 | u32 opaque_key, u32 dest_idx_unmasked, |
5684 | unsigned int *frag_size) | ||
5644 | { | 5685 | { |
5645 | struct tg3_rx_buffer_desc *desc; | 5686 | struct tg3_rx_buffer_desc *desc; |
5646 | struct ring_info *map; | 5687 | struct ring_info *map; |
@@ -5675,7 +5716,13 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, | |||
5675 | */ | 5716 | */ |
5676 | skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) + | 5717 | skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) + |
5677 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | 5718 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
5678 | data = kmalloc(skb_size, GFP_ATOMIC); | 5719 | if (skb_size <= TG3_FRAGSIZE) { |
5720 | data = tg3_frag_alloc(tpr); | ||
5721 | *frag_size = TG3_FRAGSIZE; | ||
5722 | } else { | ||
5723 | data = kmalloc(skb_size, GFP_ATOMIC); | ||
5724 | *frag_size = 0; | ||
5725 | } | ||
5679 | if (!data) | 5726 | if (!data) |
5680 | return -ENOMEM; | 5727 | return -ENOMEM; |
5681 | 5728 | ||
@@ -5683,8 +5730,8 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, | |||
5683 | data + TG3_RX_OFFSET(tp), | 5730 | data + TG3_RX_OFFSET(tp), |
5684 | data_size, | 5731 | data_size, |
5685 | PCI_DMA_FROMDEVICE); | 5732 | PCI_DMA_FROMDEVICE); |
5686 | if (pci_dma_mapping_error(tp->pdev, mapping)) { | 5733 | if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) { |
5687 | kfree(data); | 5734 | tg3_frag_free(skb_size <= TG3_FRAGSIZE, data); |
5688 | return -EIO; | 5735 | return -EIO; |
5689 | } | 5736 | } |
5690 | 5737 | ||
@@ -5835,18 +5882,19 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
5835 | 5882 | ||
5836 | if (len > TG3_RX_COPY_THRESH(tp)) { | 5883 | if (len > TG3_RX_COPY_THRESH(tp)) { |
5837 | int skb_size; | 5884 | int skb_size; |
5885 | unsigned int frag_size; | ||
5838 | 5886 | ||
5839 | skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key, | 5887 | skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key, |
5840 | *post_ptr); | 5888 | *post_ptr, &frag_size); |
5841 | if (skb_size < 0) | 5889 | if (skb_size < 0) |
5842 | goto drop_it; | 5890 | goto drop_it; |
5843 | 5891 | ||
5844 | pci_unmap_single(tp->pdev, dma_addr, skb_size, | 5892 | pci_unmap_single(tp->pdev, dma_addr, skb_size, |
5845 | PCI_DMA_FROMDEVICE); | 5893 | PCI_DMA_FROMDEVICE); |
5846 | 5894 | ||
5847 | skb = build_skb(data, 0); | 5895 | skb = build_skb(data, frag_size); |
5848 | if (!skb) { | 5896 | if (!skb) { |
5849 | kfree(data); | 5897 | tg3_frag_free(frag_size != 0, data); |
5850 | goto drop_it_no_recycle; | 5898 | goto drop_it_no_recycle; |
5851 | } | 5899 | } |
5852 | skb_reserve(skb, TG3_RX_OFFSET(tp)); | 5900 | skb_reserve(skb, TG3_RX_OFFSET(tp)); |
@@ -7279,7 +7327,10 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, | |||
7279 | 7327 | ||
7280 | /* Now allocate fresh SKBs for each rx ring. */ | 7328 | /* Now allocate fresh SKBs for each rx ring. */ |
7281 | for (i = 0; i < tp->rx_pending; i++) { | 7329 | for (i = 0; i < tp->rx_pending; i++) { |
7282 | if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) { | 7330 | unsigned int frag_size; |
7331 | |||
7332 | if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i, | ||
7333 | &frag_size) < 0) { | ||
7283 | netdev_warn(tp->dev, | 7334 | netdev_warn(tp->dev, |
7284 | "Using a smaller RX standard ring. Only " | 7335 | "Using a smaller RX standard ring. Only " |
7285 | "%d out of %d buffers were allocated " | 7336 | "%d out of %d buffers were allocated " |
@@ -7311,7 +7362,10 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, | |||
7311 | } | 7362 | } |
7312 | 7363 | ||
7313 | for (i = 0; i < tp->rx_jumbo_pending; i++) { | 7364 | for (i = 0; i < tp->rx_jumbo_pending; i++) { |
7314 | if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_JUMBO, i) < 0) { | 7365 | unsigned int frag_size; |
7366 | |||
7367 | if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_JUMBO, i, | ||
7368 | &frag_size) < 0) { | ||
7315 | netdev_warn(tp->dev, | 7369 | netdev_warn(tp->dev, |
7316 | "Using a smaller RX jumbo ring. Only %d " | 7370 | "Using a smaller RX jumbo ring. Only %d " |
7317 | "out of %d buffers were allocated " | 7371 | "out of %d buffers were allocated " |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 93865f899a4f..7c855455d937 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -2815,6 +2815,8 @@ struct tg3_rx_prodring_set { | |||
2815 | struct ring_info *rx_jmb_buffers; | 2815 | struct ring_info *rx_jmb_buffers; |
2816 | dma_addr_t rx_std_mapping; | 2816 | dma_addr_t rx_std_mapping; |
2817 | dma_addr_t rx_jmb_mapping; | 2817 | dma_addr_t rx_jmb_mapping; |
2818 | void *rx_page_addr; | ||
2819 | unsigned int rx_page_size; | ||
2818 | }; | 2820 | }; |
2819 | 2821 | ||
2820 | #define TG3_IRQ_MAX_VECS_RSS 5 | 2822 | #define TG3_IRQ_MAX_VECS_RSS 5 |