aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-01-19 00:49:45 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-21 17:34:06 -0500
commit78b6f4ce58d1c85190003840912cc9097cbb8146 (patch)
tree70682230f6f1a271f30b20a496f16ceeef217288 /drivers
parentf3f3abb62ccb1a1c77bcce855c04e12356e6ac95 (diff)
ixgbe: Replace LRO with GRO
This patch makes ixgbe invoke the GRO hooks instead of LRO. As GRO has a compatible external interface to LRO this is a very straightforward replacement. As GRO uses the napi structure to track the held packets, I've modified the code paths involved to pass that along. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/ixgbe/ixgbe.h9
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c11
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c81
4 files changed, 13 insertions, 89 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9fe8cb7d43ac..eccb89770f56 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2444,7 +2444,6 @@ config ENIC
2444config IXGBE 2444config IXGBE
2445 tristate "Intel(R) 10GbE PCI Express adapters support" 2445 tristate "Intel(R) 10GbE PCI Express adapters support"
2446 depends on PCI && INET 2446 depends on PCI && INET
2447 select INET_LRO
2448 ---help--- 2447 ---help---
2449 This driver supports Intel(R) 10GbE PCI Express family of 2448 This driver supports Intel(R) 10GbE PCI Express family of
2450 adapters. For more information on how to identify your adapter, go 2449 adapters. For more information on how to identify your adapter, go
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index e112008f39c1..6ac361a4b8ad 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -31,7 +31,6 @@
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/netdevice.h> 33#include <linux/netdevice.h>
34#include <linux/inet_lro.h>
35#include <linux/aer.h> 34#include <linux/aer.h>
36 35
37#include "ixgbe_type.h" 36#include "ixgbe_type.h"
@@ -88,9 +87,6 @@
88#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000 87#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
89#define IXGBE_TX_FLAGS_VLAN_SHIFT 16 88#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
90 89
91#define IXGBE_MAX_LRO_DESCRIPTORS 8
92#define IXGBE_MAX_LRO_AGGREGATE 32
93
94/* wrapper around a pointer to a socket buffer, 90/* wrapper around a pointer to a socket buffer,
95 * so a DMA handle can be stored along with the buffer */ 91 * so a DMA handle can be stored along with the buffer */
96struct ixgbe_tx_buffer { 92struct ixgbe_tx_buffer {
@@ -142,8 +138,6 @@ struct ixgbe_ring {
142 /* cpu for tx queue */ 138 /* cpu for tx queue */
143 int cpu; 139 int cpu;
144#endif 140#endif
145 struct net_lro_mgr lro_mgr;
146 bool lro_used;
147 struct ixgbe_queue_stats stats; 141 struct ixgbe_queue_stats stats;
148 u16 v_idx; /* maps directly to the index for this ring in the hardware 142 u16 v_idx; /* maps directly to the index for this ring in the hardware
149 * vector array, can also be used for finding the bit in EICR 143 * vector array, can also be used for finding the bit in EICR
@@ -301,9 +295,6 @@ struct ixgbe_adapter {
301 295
302 unsigned long state; 296 unsigned long state;
303 u64 tx_busy; 297 u64 tx_busy;
304 u64 lro_aggregated;
305 u64 lro_flushed;
306 u64 lro_no_desc;
307 unsigned int tx_ring_count; 298 unsigned int tx_ring_count;
308 unsigned int rx_ring_count; 299 unsigned int rx_ring_count;
309 300
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 67f87a79154d..4f6b5dfc78a2 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -89,8 +89,6 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
89 {"rx_header_split", IXGBE_STAT(rx_hdr_split)}, 89 {"rx_header_split", IXGBE_STAT(rx_hdr_split)},
90 {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, 90 {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
91 {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, 91 {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
92 {"lro_aggregated", IXGBE_STAT(lro_aggregated)},
93 {"lro_flushed", IXGBE_STAT(lro_flushed)},
94}; 92};
95 93
96#define IXGBE_QUEUE_STATS_LEN \ 94#define IXGBE_QUEUE_STATS_LEN \
@@ -808,15 +806,6 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
808 int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); 806 int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
809 int j, k; 807 int j, k;
810 int i; 808 int i;
811 u64 aggregated = 0, flushed = 0, no_desc = 0;
812 for (i = 0; i < adapter->num_rx_queues; i++) {
813 aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
814 flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
815 no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
816 }
817 adapter->lro_aggregated = aggregated;
818 adapter->lro_flushed = flushed;
819 adapter->lro_no_desc = no_desc;
820 809
821 ixgbe_update_stats(adapter); 810 ixgbe_update_stats(adapter);
822 for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { 811 for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 7489094bbbc8..f7b592eff68e 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -403,23 +403,20 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
403 * @rx_ring: rx descriptor ring (for a specific queue) to setup 403 * @rx_ring: rx descriptor ring (for a specific queue) to setup
404 * @rx_desc: rx descriptor 404 * @rx_desc: rx descriptor
405 **/ 405 **/
406static void ixgbe_receive_skb(struct ixgbe_adapter *adapter, 406static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
407 struct sk_buff *skb, u8 status, 407 struct sk_buff *skb, u8 status,
408 struct ixgbe_ring *ring,
409 union ixgbe_adv_rx_desc *rx_desc) 408 union ixgbe_adv_rx_desc *rx_desc)
410{ 409{
410 struct ixgbe_adapter *adapter = q_vector->adapter;
411 struct napi_struct *napi = &q_vector->napi;
411 bool is_vlan = (status & IXGBE_RXD_STAT_VP); 412 bool is_vlan = (status & IXGBE_RXD_STAT_VP);
412 u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); 413 u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
413 414
414 if (adapter->netdev->features & NETIF_F_LRO && 415 if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
415 skb->ip_summed == CHECKSUM_UNNECESSARY) {
416 if (adapter->vlgrp && is_vlan && (tag != 0)) 416 if (adapter->vlgrp && is_vlan && (tag != 0))
417 lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb, 417 vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
418 adapter->vlgrp, tag,
419 rx_desc);
420 else 418 else
421 lro_receive_skb(&ring->lro_mgr, skb, rx_desc); 419 napi_gro_receive(napi, skb);
422 ring->lro_used = true;
423 } else { 420 } else {
424 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { 421 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
425 if (adapter->vlgrp && is_vlan && (tag != 0)) 422 if (adapter->vlgrp && is_vlan && (tag != 0))
@@ -574,10 +571,11 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
574 return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; 571 return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
575} 572}
576 573
577static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, 574static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
578 struct ixgbe_ring *rx_ring, 575 struct ixgbe_ring *rx_ring,
579 int *work_done, int work_to_do) 576 int *work_done, int work_to_do)
580{ 577{
578 struct ixgbe_adapter *adapter = q_vector->adapter;
581 struct pci_dev *pdev = adapter->pdev; 579 struct pci_dev *pdev = adapter->pdev;
582 union ixgbe_adv_rx_desc *rx_desc, *next_rxd; 580 union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
583 struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; 581 struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -678,7 +676,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
678 total_rx_packets++; 676 total_rx_packets++;
679 677
680 skb->protocol = eth_type_trans(skb, adapter->netdev); 678 skb->protocol = eth_type_trans(skb, adapter->netdev);
681 ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc); 679 ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
682 680
683next_desc: 681next_desc:
684 rx_desc->wb.upper.status_error = 0; 682 rx_desc->wb.upper.status_error = 0;
@@ -696,11 +694,6 @@ next_desc:
696 staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 694 staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
697 } 695 }
698 696
699 if (rx_ring->lro_used) {
700 lro_flush_all(&rx_ring->lro_mgr);
701 rx_ring->lro_used = false;
702 }
703
704 rx_ring->next_to_clean = i; 697 rx_ring->next_to_clean = i;
705 cleaned_count = IXGBE_DESC_UNUSED(rx_ring); 698 cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
706 699
@@ -1052,7 +1045,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
1052 ixgbe_update_rx_dca(adapter, rx_ring); 1045 ixgbe_update_rx_dca(adapter, rx_ring);
1053#endif 1046#endif
1054 1047
1055 ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget); 1048 ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
1056 1049
1057 /* If all Rx work done, exit the polling mode */ 1050 /* If all Rx work done, exit the polling mode */
1058 if (work_done < budget) { 1051 if (work_done < budget) {
@@ -1095,7 +1088,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
1095 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) 1088 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
1096 ixgbe_update_rx_dca(adapter, rx_ring); 1089 ixgbe_update_rx_dca(adapter, rx_ring);
1097#endif 1090#endif
1098 ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget); 1091 ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
1099 enable_mask |= rx_ring->v_idx; 1092 enable_mask |= rx_ring->v_idx;
1100 r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, 1093 r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
1101 r_idx + 1); 1094 r_idx + 1);
@@ -1568,33 +1561,6 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
1568 IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl); 1561 IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
1569} 1562}
1570 1563
1571/**
1572 * ixgbe_get_skb_hdr - helper function for LRO header processing
1573 * @skb: pointer to sk_buff to be added to LRO packet
1574 * @iphdr: pointer to ip header structure
1575 * @tcph: pointer to tcp header structure
1576 * @hdr_flags: pointer to header flags
1577 * @priv: private data
1578 **/
1579static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
1580 u64 *hdr_flags, void *priv)
1581{
1582 union ixgbe_adv_rx_desc *rx_desc = priv;
1583
1584 /* Verify that this is a valid IPv4 TCP packet */
1585 if (!((ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_IPV4) &&
1586 (ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_TCP)))
1587 return -1;
1588
1589 /* Set network headers */
1590 skb_reset_network_header(skb);
1591 skb_set_transport_header(skb, ip_hdrlen(skb));
1592 *iphdr = ip_hdr(skb);
1593 *tcph = tcp_hdr(skb);
1594 *hdr_flags = LRO_IPV4 | LRO_TCP;
1595 return 0;
1596}
1597
1598#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \ 1564#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
1599 (((S) & (PAGE_SIZE - 1)) ? 1 : 0)) 1565 (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
1600 1566
@@ -1666,16 +1632,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
1666 adapter->rx_ring[i].head = IXGBE_RDH(j); 1632 adapter->rx_ring[i].head = IXGBE_RDH(j);
1667 adapter->rx_ring[i].tail = IXGBE_RDT(j); 1633 adapter->rx_ring[i].tail = IXGBE_RDT(j);
1668 adapter->rx_ring[i].rx_buf_len = rx_buf_len; 1634 adapter->rx_ring[i].rx_buf_len = rx_buf_len;
1669 /* Intitial LRO Settings */
1670 adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
1671 adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
1672 adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
1673 adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
1674 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
1675 adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
1676 adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
1677 adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
1678 adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
1679 1635
1680 ixgbe_configure_srrctl(adapter, j); 1636 ixgbe_configure_srrctl(adapter, j);
1681 } 1637 }
@@ -2310,7 +2266,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
2310#endif 2266#endif
2311 2267
2312 tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); 2268 tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
2313 ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget); 2269 ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
2314 2270
2315 if (tx_cleaned) 2271 if (tx_cleaned)
2316 work_done = budget; 2272 work_done = budget;
@@ -2926,12 +2882,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
2926 struct pci_dev *pdev = adapter->pdev; 2882 struct pci_dev *pdev = adapter->pdev;
2927 int size; 2883 int size;
2928 2884
2929 size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
2930 rx_ring->lro_mgr.lro_arr = vmalloc(size);
2931 if (!rx_ring->lro_mgr.lro_arr)
2932 return -ENOMEM;
2933 memset(rx_ring->lro_mgr.lro_arr, 0, size);
2934
2935 size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; 2885 size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
2936 rx_ring->rx_buffer_info = vmalloc(size); 2886 rx_ring->rx_buffer_info = vmalloc(size);
2937 if (!rx_ring->rx_buffer_info) { 2887 if (!rx_ring->rx_buffer_info) {
@@ -2960,8 +2910,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
2960 return 0; 2910 return 0;
2961 2911
2962alloc_failed: 2912alloc_failed:
2963 vfree(rx_ring->lro_mgr.lro_arr);
2964 rx_ring->lro_mgr.lro_arr = NULL;
2965 return -ENOMEM; 2913 return -ENOMEM;
2966} 2914}
2967 2915
@@ -3039,9 +2987,6 @@ void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
3039{ 2987{
3040 struct pci_dev *pdev = adapter->pdev; 2988 struct pci_dev *pdev = adapter->pdev;
3041 2989
3042 vfree(rx_ring->lro_mgr.lro_arr);
3043 rx_ring->lro_mgr.lro_arr = NULL;
3044
3045 ixgbe_clean_rx_ring(adapter, rx_ring); 2990 ixgbe_clean_rx_ring(adapter, rx_ring);
3046 2991
3047 vfree(rx_ring->rx_buffer_info); 2992 vfree(rx_ring->rx_buffer_info);
@@ -4141,7 +4086,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
4141 netdev->features |= NETIF_F_IPV6_CSUM; 4086 netdev->features |= NETIF_F_IPV6_CSUM;
4142 netdev->features |= NETIF_F_TSO; 4087 netdev->features |= NETIF_F_TSO;
4143 netdev->features |= NETIF_F_TSO6; 4088 netdev->features |= NETIF_F_TSO6;
4144 netdev->features |= NETIF_F_LRO; 4089 netdev->features |= NETIF_F_GRO;
4145 4090
4146 netdev->vlan_features |= NETIF_F_TSO; 4091 netdev->vlan_features |= NETIF_F_TSO;
4147 netdev->vlan_features |= NETIF_F_TSO6; 4092 netdev->vlan_features |= NETIF_F_TSO6;