aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>2008-06-18 18:32:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-06-24 23:06:19 -0400
commit177db6ffd0599430a2ab63045e88fc4031f42420 (patch)
tree1c1e0b71a9589628e8b2abd82c213e1e7d1cc34b
parent8f85cd7fefa3d01c4e05aac1cb198733336cf44b (diff)
ixgbe: add LRO support
Support for in-kernel LRO with the ability to enable/disable via ethtool based on comments from Ben Hutchings. Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/net/Kconfig3
-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.c111
4 files changed, 112 insertions, 22 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9df3a1d9731..23be317003b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2471,7 +2471,8 @@ config EHEA
2471 2471
2472config IXGBE 2472config IXGBE
2473 tristate "Intel(R) 10GbE PCI Express adapters support" 2473 tristate "Intel(R) 10GbE PCI Express adapters support"
2474 depends on PCI 2474 depends on PCI && INET
2475 select INET_LRO
2475 ---help--- 2476 ---help---
2476 This driver supports Intel(R) 10GbE PCI Express family of 2477 This driver supports Intel(R) 10GbE PCI Express family of
2477 adapters. For more information on how to identify your adapter, go 2478 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 d98113472a8..956914a5028 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -32,6 +32,7 @@
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/netdevice.h> 34#include <linux/netdevice.h>
35#include <linux/inet_lro.h>
35 36
36#include "ixgbe_type.h" 37#include "ixgbe_type.h"
37#include "ixgbe_common.h" 38#include "ixgbe_common.h"
@@ -100,6 +101,9 @@
100#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 101#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
101#define IXGBE_TX_FLAGS_VLAN_SHIFT 16 102#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
102 103
104#define IXGBE_MAX_LRO_DESCRIPTORS 8
105#define IXGBE_MAX_LRO_AGGREGATE 32
106
103/* wrapper around a pointer to a socket buffer, 107/* wrapper around a pointer to a socket buffer,
104 * so a DMA handle can be stored along with the buffer */ 108 * so a DMA handle can be stored along with the buffer */
105struct ixgbe_tx_buffer { 109struct ixgbe_tx_buffer {
@@ -150,6 +154,8 @@ struct ixgbe_ring {
150 /* cpu for tx queue */ 154 /* cpu for tx queue */
151 int cpu; 155 int cpu;
152#endif 156#endif
157 struct net_lro_mgr lro_mgr;
158 bool lro_used;
153 struct ixgbe_queue_stats stats; 159 struct ixgbe_queue_stats stats;
154 u8 v_idx; /* maps directly to the index for this ring in the hardware 160 u8 v_idx; /* maps directly to the index for this ring in the hardware
155 * vector array, can also be used for finding the bit in EICR 161 * vector array, can also be used for finding the bit in EICR
@@ -287,6 +293,9 @@ struct ixgbe_adapter {
287 293
288 unsigned long state; 294 unsigned long state;
289 u64 tx_busy; 295 u64 tx_busy;
296 u64 lro_aggregated;
297 u64 lro_flushed;
298 u64 lro_no_desc;
290}; 299};
291 300
292enum ixbge_state_t { 301enum ixbge_state_t {
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 4e463778bcf..12990b1fe7e 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -90,6 +90,8 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
90 {"rx_header_split", IXGBE_STAT(rx_hdr_split)}, 90 {"rx_header_split", IXGBE_STAT(rx_hdr_split)},
91 {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, 91 {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
92 {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, 92 {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
93 {"lro_aggregated", IXGBE_STAT(lro_aggregated)},
94 {"lro_flushed", IXGBE_STAT(lro_flushed)},
93}; 95};
94 96
95#define IXGBE_QUEUE_STATS_LEN \ 97#define IXGBE_QUEUE_STATS_LEN \
@@ -787,6 +789,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
787 int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); 789 int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
788 int j, k; 790 int j, k;
789 int i; 791 int i;
792 u64 aggregated = 0, flushed = 0, no_desc = 0;
790 793
791 ixgbe_update_stats(adapter); 794 ixgbe_update_stats(adapter);
792 for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { 795 for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
@@ -801,11 +804,17 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
801 i += k; 804 i += k;
802 } 805 }
803 for (j = 0; j < adapter->num_rx_queues; j++) { 806 for (j = 0; j < adapter->num_rx_queues; j++) {
807 aggregated += adapter->rx_ring[j].lro_mgr.stats.aggregated;
808 flushed += adapter->rx_ring[j].lro_mgr.stats.flushed;
809 no_desc += adapter->rx_ring[j].lro_mgr.stats.no_desc;
804 queue_stat = (u64 *)&adapter->rx_ring[j].stats; 810 queue_stat = (u64 *)&adapter->rx_ring[j].stats;
805 for (k = 0; k < stat_count; k++) 811 for (k = 0; k < stat_count; k++)
806 data[i + k] = queue_stat[k]; 812 data[i + k] = queue_stat[k];
807 i += k; 813 i += k;
808 } 814 }
815 adapter->lro_aggregated = aggregated;
816 adapter->lro_flushed = flushed;
817 adapter->lro_no_desc = no_desc;
809} 818}
810 819
811static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, 820static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
@@ -973,6 +982,8 @@ static struct ethtool_ops ixgbe_ethtool_ops = {
973 .get_ethtool_stats = ixgbe_get_ethtool_stats, 982 .get_ethtool_stats = ixgbe_get_ethtool_stats,
974 .get_coalesce = ixgbe_get_coalesce, 983 .get_coalesce = ixgbe_get_coalesce,
975 .set_coalesce = ixgbe_set_coalesce, 984 .set_coalesce = ixgbe_set_coalesce,
985 .get_flags = ethtool_op_get_flags,
986 .set_flags = ethtool_op_set_flags,
976}; 987};
977 988
978void ixgbe_set_ethtool_ops(struct net_device *netdev) 989void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 0d37c9025be..f429c9a4754 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -389,24 +389,39 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
389 * ixgbe_receive_skb - Send a completed packet up the stack 389 * ixgbe_receive_skb - Send a completed packet up the stack
390 * @adapter: board private structure 390 * @adapter: board private structure
391 * @skb: packet to send up 391 * @skb: packet to send up
392 * @is_vlan: packet has a VLAN tag 392 * @status: hardware indication of status of receive
393 * @tag: VLAN tag from descriptor 393 * @rx_ring: rx descriptor ring (for a specific queue) to setup
394 * @rx_desc: rx descriptor
394 **/ 395 **/
395static void ixgbe_receive_skb(struct ixgbe_adapter *adapter, 396static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
396 struct sk_buff *skb, bool is_vlan, 397 struct sk_buff *skb, u8 status,
397 u16 tag) 398 struct ixgbe_ring *ring,
399 union ixgbe_adv_rx_desc *rx_desc)
398{ 400{
399 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { 401 bool is_vlan = (status & IXGBE_RXD_STAT_VP);
400 if (adapter->vlgrp && is_vlan) 402 u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
401 vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
402 else
403 netif_receive_skb(skb);
404 } else {
405 403
404 if (adapter->netdev->features & NETIF_F_LRO &&
405 skb->ip_summed == CHECKSUM_UNNECESSARY) {
406 if (adapter->vlgrp && is_vlan) 406 if (adapter->vlgrp && is_vlan)
407 vlan_hwaccel_rx(skb, adapter->vlgrp, tag); 407 lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
408 adapter->vlgrp, tag,
409 rx_desc);
408 else 410 else
409 netif_rx(skb); 411 lro_receive_skb(&ring->lro_mgr, skb, rx_desc);
412 ring->lro_used = true;
413 } else {
414 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
415 if (adapter->vlgrp && is_vlan)
416 vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
417 else
418 netif_receive_skb(skb);
419 } else {
420 if (adapter->vlgrp && is_vlan)
421 vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
422 else
423 netif_rx(skb);
424 }
410 } 425 }
411} 426}
412 427
@@ -546,8 +561,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
546 struct sk_buff *skb; 561 struct sk_buff *skb;
547 unsigned int i; 562 unsigned int i;
548 u32 upper_len, len, staterr; 563 u32 upper_len, len, staterr;
549 u16 hdr_info, vlan_tag; 564 u16 hdr_info;
550 bool is_vlan, cleaned = false; 565 bool cleaned = false;
551 int cleaned_count = 0; 566 int cleaned_count = 0;
552 unsigned int total_rx_bytes = 0, total_rx_packets = 0; 567 unsigned int total_rx_bytes = 0, total_rx_packets = 0;
553 568
@@ -556,8 +571,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
556 rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); 571 rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
557 staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 572 staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
558 rx_buffer_info = &rx_ring->rx_buffer_info[i]; 573 rx_buffer_info = &rx_ring->rx_buffer_info[i];
559 is_vlan = (staterr & IXGBE_RXD_STAT_VP);
560 vlan_tag = le16_to_cpu(rx_desc->wb.upper.vlan);
561 574
562 while (staterr & IXGBE_RXD_STAT_DD) { 575 while (staterr & IXGBE_RXD_STAT_DD) {
563 if (*work_done >= work_to_do) 576 if (*work_done >= work_to_do)
@@ -635,7 +648,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
635 total_rx_packets++; 648 total_rx_packets++;
636 649
637 skb->protocol = eth_type_trans(skb, netdev); 650 skb->protocol = eth_type_trans(skb, netdev);
638 ixgbe_receive_skb(adapter, skb, is_vlan, vlan_tag); 651 ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
639 netdev->last_rx = jiffies; 652 netdev->last_rx = jiffies;
640 653
641next_desc: 654next_desc:
@@ -652,8 +665,11 @@ next_desc:
652 rx_buffer_info = next_buffer; 665 rx_buffer_info = next_buffer;
653 666
654 staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 667 staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
655 is_vlan = (staterr & IXGBE_RXD_STAT_VP); 668 }
656 vlan_tag = le16_to_cpu(rx_desc->wb.upper.vlan); 669
670 if (rx_ring->lro_used) {
671 lro_flush_all(&rx_ring->lro_mgr);
672 rx_ring->lro_used = false;
657 } 673 }
658 674
659 rx_ring->next_to_clean = i; 675 rx_ring->next_to_clean = i;
@@ -1382,6 +1398,33 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
1382 1398
1383#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 1399#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
1384/** 1400/**
1401 * ixgbe_get_skb_hdr - helper function for LRO header processing
1402 * @skb: pointer to sk_buff to be added to LRO packet
1403 * @iphdr: pointer to tcp header structure
1404 * @tcph: pointer to tcp header structure
1405 * @hdr_flags: pointer to header flags
1406 * @priv: private data
1407 **/
1408static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
1409 u64 *hdr_flags, void *priv)
1410{
1411 union ixgbe_adv_rx_desc *rx_desc = priv;
1412
1413 /* Verify that this is a valid IPv4 TCP packet */
1414 if (!(rx_desc->wb.lower.lo_dword.pkt_info &
1415 (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)))
1416 return -1;
1417
1418 /* Set network headers */
1419 skb_reset_network_header(skb);
1420 skb_set_transport_header(skb, ip_hdrlen(skb));
1421 *iphdr = ip_hdr(skb);
1422 *tcph = tcp_hdr(skb);
1423 *hdr_flags = LRO_IPV4 | LRO_TCP;
1424 return 0;
1425}
1426
1427/**
1385 * ixgbe_configure_rx - Configure 8254x Receive Unit after Reset 1428 * ixgbe_configure_rx - Configure 8254x Receive Unit after Reset
1386 * @adapter: board private structure 1429 * @adapter: board private structure
1387 * 1430 *
@@ -1470,6 +1513,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
1470 adapter->rx_ring[i].tail = IXGBE_RDT(i); 1513 adapter->rx_ring[i].tail = IXGBE_RDT(i);
1471 } 1514 }
1472 1515
1516 /* Intitial LRO Settings */
1517 adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
1518 adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
1519 adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
1520 adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
1521 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
1522 adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
1523 adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
1524 adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
1525 adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
1526
1473 if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { 1527 if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
1474 /* Fill out redirection table */ 1528 /* Fill out redirection table */
1475 for (i = 0, j = 0; i < 128; i++, j++) { 1529 for (i = 0, j = 0; i < 128; i++, j++) {
@@ -2489,12 +2543,18 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
2489 struct pci_dev *pdev = adapter->pdev; 2543 struct pci_dev *pdev = adapter->pdev;
2490 int size; 2544 int size;
2491 2545
2546 size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
2547 rxdr->lro_mgr.lro_arr = vmalloc(size);
2548 if (!rxdr->lro_mgr.lro_arr)
2549 return -ENOMEM;
2550 memset(rxdr->lro_mgr.lro_arr, 0, size);
2551
2492 size = sizeof(struct ixgbe_rx_buffer) * rxdr->count; 2552 size = sizeof(struct ixgbe_rx_buffer) * rxdr->count;
2493 rxdr->rx_buffer_info = vmalloc(size); 2553 rxdr->rx_buffer_info = vmalloc(size);
2494 if (!rxdr->rx_buffer_info) { 2554 if (!rxdr->rx_buffer_info) {
2495 DPRINTK(PROBE, ERR, 2555 DPRINTK(PROBE, ERR,
2496 "vmalloc allocation failed for the rx desc ring\n"); 2556 "vmalloc allocation failed for the rx desc ring\n");
2497 return -ENOMEM; 2557 goto alloc_failed;
2498 } 2558 }
2499 memset(rxdr->rx_buffer_info, 0, size); 2559 memset(rxdr->rx_buffer_info, 0, size);
2500 2560
@@ -2508,13 +2568,18 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
2508 DPRINTK(PROBE, ERR, 2568 DPRINTK(PROBE, ERR,
2509 "Memory allocation failed for the rx desc ring\n"); 2569 "Memory allocation failed for the rx desc ring\n");
2510 vfree(rxdr->rx_buffer_info); 2570 vfree(rxdr->rx_buffer_info);
2511 return -ENOMEM; 2571 goto alloc_failed;
2512 } 2572 }
2513 2573
2514 rxdr->next_to_clean = 0; 2574 rxdr->next_to_clean = 0;
2515 rxdr->next_to_use = 0; 2575 rxdr->next_to_use = 0;
2516 2576
2517 return 0; 2577 return 0;
2578
2579alloc_failed:
2580 vfree(rxdr->lro_mgr.lro_arr);
2581 rxdr->lro_mgr.lro_arr = NULL;
2582 return -ENOMEM;
2518} 2583}
2519 2584
2520/** 2585/**
@@ -2565,6 +2630,9 @@ static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
2565{ 2630{
2566 struct pci_dev *pdev = adapter->pdev; 2631 struct pci_dev *pdev = adapter->pdev;
2567 2632
2633 vfree(rx_ring->lro_mgr.lro_arr);
2634 rx_ring->lro_mgr.lro_arr = NULL;
2635
2568 ixgbe_clean_rx_ring(adapter, rx_ring); 2636 ixgbe_clean_rx_ring(adapter, rx_ring);
2569 2637
2570 vfree(rx_ring->rx_buffer_info); 2638 vfree(rx_ring->rx_buffer_info);
@@ -3517,6 +3585,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
3517 NETIF_F_HW_VLAN_RX | 3585 NETIF_F_HW_VLAN_RX |
3518 NETIF_F_HW_VLAN_FILTER; 3586 NETIF_F_HW_VLAN_FILTER;
3519 3587
3588 netdev->features |= NETIF_F_LRO;
3520 netdev->features |= NETIF_F_TSO; 3589 netdev->features |= NETIF_F_TSO;
3521 netdev->features |= NETIF_F_TSO6; 3590 netdev->features |= NETIF_F_TSO6;
3522 3591