diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-01-19 00:49:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-21 17:34:06 -0500 |
commit | 78b6f4ce58d1c85190003840912cc9097cbb8146 (patch) | |
tree | 70682230f6f1a271f30b20a496f16ceeef217288 /drivers | |
parent | f3f3abb62ccb1a1c77bcce855c04e12356e6ac95 (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 9 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 11 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 81 |
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 | |||
2444 | config IXGBE | 2444 | config 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 */ |
96 | struct ixgbe_tx_buffer { | 92 | struct 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 | **/ |
406 | static void ixgbe_receive_skb(struct ixgbe_adapter *adapter, | 406 | static 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 | ||
577 | static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, | 574 | static 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 | ||
683 | next_desc: | 681 | next_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 | **/ | ||
1579 | static 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 | ||
2962 | alloc_failed: | 2912 | alloc_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; |