From: Herbert Xu <herbert@gondor.apana.org.au> Date: Thu, 28 May 2009 18:12:26 +1000 Subject: [net] ixgbe: add GRO suppport Message-id: E1M9aiw-0007S1-It@gondolin.me.apana.org.au O-Subject: [PATCH 3/3] ixgbe: Add GRO suppport Bugzilla: 499347 RH-Acked-by: David Miller <davem@redhat.com> RH-Acked-by: Thomas Graf <tgraf@redhat.com> RHEL5 bugzilla 499347 ixgbe: Add GRO suppport Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index c19c161..fbeefda 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -31,7 +31,6 @@ #include <linux/types.h> #include <linux/pci.h> #include <linux/netdevice.h> -#include <linux/inet_lro.h> #include "ixgbe_type.h" #include "ixgbe_common.h" @@ -85,9 +84,6 @@ #define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 #define IXGBE_TX_FLAGS_VLAN_SHIFT 16 -#define IXGBE_MAX_LRO_DESCRIPTORS 8 -#define IXGBE_MAX_LRO_AGGREGATE 32 - /* wrapper around a pointer to a socket buffer, * so a DMA handle can be stored along with the buffer */ struct ixgbe_tx_buffer { @@ -112,6 +108,7 @@ struct ixgbe_queue_stats { }; struct ixgbe_ring { + struct napi_struct napi; void *desc; /* descriptor ring memory */ dma_addr_t dma; /* phys. address of descriptor ring */ unsigned int size; /* length in bytes */ @@ -138,8 +135,6 @@ struct ixgbe_ring { /* cpu for tx queue */ int cpu; - struct net_lro_mgr lro_mgr; - bool lro_used; struct ixgbe_queue_stats stats; u64 v_idx; /* maps directly to the index for this ring in the hardware * vector array, can also be used for finding the bit in EICR @@ -302,10 +297,6 @@ struct ixgbe_adapter { unsigned int tx_ring_count; unsigned int rx_ring_count; - u64 lro_aggregated; - u64 lro_flushed; - u64 lro_no_desc; - u32 link_speed; bool link_up; unsigned long link_check_timeout; diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 0e717d0..c84bfad 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -90,8 +90,6 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"rx_header_split", IXGBE_STAT(rx_hdr_split)}, {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, - {"lro_aggregated", IXGBE_STAT(lro_aggregated)}, - {"lro_flushed", IXGBE_STAT(lro_flushed)}, {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)}, }; @@ -818,15 +816,6 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); int j, k; int i; - u64 aggregated = 0, flushed = 0, no_desc = 0; - for (i = 0; i < adapter->num_rx_queues; i++) { - aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated; - flushed += adapter->rx_ring[i].lro_mgr.stats.flushed; - no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc; - } - adapter->lro_aggregated = aggregated; - adapter->lro_flushed = flushed; - adapter->lro_no_desc = no_desc; ixgbe_update_stats(adapter); 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 3bc6d46..166ae5d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -345,17 +345,15 @@ static void ixgbe_receive_skb(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc) { + struct napi_struct *napi = &ring->napi; bool is_vlan = (status & IXGBE_RXD_STAT_VP); u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); if (skb->ip_summed == CHECKSUM_UNNECESSARY) { if (adapter->vlgrp && is_vlan) - lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb, - adapter->vlgrp, tag, - rx_desc); + vlan_gro_receive(napi, adapter->vlgrp, tag, skb); else - lro_receive_skb(&ring->lro_mgr, skb, rx_desc); - ring->lro_used = true; + napi_gro_receive(napi, skb); } else { if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { if (adapter->vlgrp && is_vlan) @@ -637,10 +635,7 @@ next_desc: staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } - if (rx_ring->lro_used) { - lro_flush_all(&rx_ring->lro_mgr); - rx_ring->lro_used = false; - } + napi_gro_flush(&rx_ring->napi); rx_ring->next_to_clean = i; cleaned_count = IXGBE_DESC_UNUSED(rx_ring); @@ -1566,32 +1561,6 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) } #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 -/** - * ixgbe_get_skb_hdr - helper function for LRO header processing - * @skb: pointer to sk_buff to be added to LRO packet - * @iphdr: pointer to ip header structure - * @tcph: pointer to tcp header structure - * @hdr_flags: pointer to header flags - * @priv: private data - **/ -static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph, - u64 *hdr_flags, void *priv) -{ - union ixgbe_adv_rx_desc *rx_desc = priv; - - /* Verify that this is a valid IPv4 TCP packet */ - if (!((ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_IPV4) && - (ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_TCP))) - return -1; - - /* Set network headers */ - skb_reset_network_header(skb); - skb_set_transport_header(skb, ip_hdrlen(skb)); - *iphdr = ip_hdr(skb); - *tcph = tcp_hdr(skb); - *hdr_flags = LRO_IPV4 | LRO_TCP; - return 0; -} /** * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset @@ -1695,16 +1664,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) adapter->rx_ring[i].head = IXGBE_RDH(j); adapter->rx_ring[i].tail = IXGBE_RDT(j); adapter->rx_ring[i].rx_buf_len = rx_buf_len; - /* Intitial LRO Settings */ - adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE; - adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS; - adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr; - adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID; - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) - adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI; - adapter->rx_ring[i].lro_mgr.dev = adapter->netdev; - adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY; - adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; } /* Program MRQC for the distribution of queues */ @@ -2652,6 +2611,7 @@ static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) { adapter->rx_ring[i].count = adapter->rx_ring_count; adapter->rx_ring[i].queue_index = i; + adapter->rx_ring[i].napi.dev = adapter->netdev; } ixgbe_cache_ring_register(adapter); @@ -2961,12 +2921,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, struct pci_dev *pdev = adapter->pdev; int size; - size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS; - rx_ring->lro_mgr.lro_arr = vmalloc(size); - if (!rx_ring->lro_mgr.lro_arr) - return -ENOMEM; - memset(rx_ring->lro_mgr.lro_arr, 0, size); - size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; rx_ring->rx_buffer_info = vmalloc(size); if (!rx_ring->rx_buffer_info) { @@ -2995,8 +2949,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, return 0; alloc_failed: - vfree(rx_ring->lro_mgr.lro_arr); - rx_ring->lro_mgr.lro_arr = NULL; return -ENOMEM; } @@ -3049,9 +3001,6 @@ void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, { struct pci_dev *pdev = adapter->pdev; - vfree(rx_ring->lro_mgr.lro_arr); - rx_ring->lro_mgr.lro_arr = NULL; - ixgbe_clean_rx_ring(adapter, rx_ring); vfree(rx_ring->rx_buffer_info); @@ -4298,6 +4247,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO6; + netdev->features |= NETIF_F_GRO; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA;