Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/610655/?format=api
{ "id": 610655, "url": "http://patchwork.ozlabs.org/api/patches/610655/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20160414211931.14141.18864.stgit@ahduyck-xeon-server/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20160414211931.14141.18864.stgit@ahduyck-xeon-server>", "list_archive_url": null, "date": "2016-04-14T21:19:31", "name": "[next-queue,v2,2/3] ixgbe/ixgbevf: Add support for GSO partial", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "250ad7406044b1456b00499d199c81d9cbf6e73c", "submitter": { "id": 67293, "url": "http://patchwork.ozlabs.org/api/people/67293/?format=api", "name": "Alexander Duyck", "email": "aduyck@mirantis.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20160414211931.14141.18864.stgit@ahduyck-xeon-server/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/610655/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/610655/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@lists.osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Received": [ "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ozlabs.org (Postfix) with ESMTP id 3qmD8H3LVlz9sDC\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 15 Apr 2016 07:19:43 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id C372A89A5F;\n\tThu, 14 Apr 2016 21:19:42 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id k+g8VD9RxhX2; Thu, 14 Apr 2016 21:19:41 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 1A6FF8A521;\n\tThu, 14 Apr 2016 21:19:41 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id AF0A61C0DF4\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:39 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id A9D8C869AA\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:39 +0000 (UTC)", "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 6c8HjOg94Emu for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:38 +0000 (UTC)", "from mail-pa0-f49.google.com (mail-pa0-f49.google.com\n\t[209.85.220.49])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id 60EDE869A9\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:38 +0000 (UTC)", "by mail-pa0-f49.google.com with SMTP id fs9so29512316pac.2\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 14:19:38 -0700 (PDT)", "from [192.168.1.144] (static-50-53-29-36.bvtn.or.frontiernet.net.\n\t[50.53.29.36]) by smtp.gmail.com with ESMTPSA id\n\t62sm59934035pfk.83.2016.04.14.14.19.37\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 14 Apr 2016 14:19:37 -0700 (PDT)" ], "Authentication-Results": "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=mirantis.com header.i=@mirantis.com\n\theader.b=T8HDY6Gy; dkim-atps=neutral", "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "from auto-whitelisted by SQLgrey-1.7.6", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=mirantis.com;\n\ts=google; \n\th=subject:from:to:date:message-id:in-reply-to:references:user-agent\n\t:mime-version:content-transfer-encoding;\n\tbh=BMwcE62YiszZKmBUPw9W3nFoJWYguiUZNhRRrwCHyMQ=;\n\tb=T8HDY6GyFuYVpwZd+abcmOw4NFQ8NPQGB2kllWSOh+bX4+JkBu7ntkKJjMxyQ6fd/K\n\t/qshct0b7+9ROhqZTJSdMGRy3slv5dWBvYOS97JeeiH5tUUL/a0Un4vZGURTyhWCFPED\n\tUH/vTOmNKWK4Df/6b6k0NOXQJ6s2EARnoM4cE=", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:subject:from:to:date:message-id:in-reply-to\n\t:references:user-agent:mime-version:content-transfer-encoding;\n\tbh=BMwcE62YiszZKmBUPw9W3nFoJWYguiUZNhRRrwCHyMQ=;\n\tb=FDV/cclpHLAenin5ap83jY77H/nSNU8L1s+1nLZ1a3jcqVZLs17LfK4+gokut45l02\n\tVwh3nwMCgEXzegRmKVvPH5tLObcdhiMCeQcHbSwnR5iha/N4URlXt+7LJqD+BolxclS8\n\taG8aAX5DGe0Ocbczztqbt8wmwqm0pwHy4iJc8z8VKYLD1EbWCRj6w3uaT3uBObIWAsWD\n\tv9sU7c62U2YS2cYFFJSw83tqL/sG021Q9OzgEo6Bb6Z2Vl9pbHiePULLV1F5yZLbgGNl\n\tMqpf43a+HqPE1Z6MuGqQ0nT/19Ajt4oNra45omfYvApVMJzVlW5R5bv3scIn0hvGiSQX\n\tnMJw==", "X-Gm-Message-State": "AOPr4FW9x2lRcaYTIGD2qAz+kuJ02Aex30j5UlvWACZw1F7YnxoFpArvVj5WaDN6TtCenJSp", "X-Received": "by 10.66.160.168 with SMTP id xl8mr24357935pab.132.1460668778042;\n\tThu, 14 Apr 2016 14:19:38 -0700 (PDT)", "From": "Alexander Duyck <aduyck@mirantis.com>", "To": "intel-wired-lan@lists.osuosl.org, jeffrey.t.kirsher@intel.com,\n\talexander.duyck@gmail.com", "Date": "Thu, 14 Apr 2016 17:19:31 -0400", "Message-ID": "<20160414211931.14141.18864.stgit@ahduyck-xeon-server>", "In-Reply-To": "<20160414210725.14141.25917.stgit@ahduyck-xeon-server>", "References": "<20160414210725.14141.25917.stgit@ahduyck-xeon-server>", "User-Agent": "StGit/0.17.1-dirty", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [next-queue PATCH v2 2/3] ixgbe/ixgbevf: Add\n\tsupport for GSO partial", "X-BeenThere": "intel-wired-lan@lists.osuosl.org", "X-Mailman-Version": "2.1.18-1", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.lists.osuosl.org>", "List-Unsubscribe": "<http://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@lists.osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@lists.osuosl.org?subject=help>", "List-Subscribe": "<http://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@lists.osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@lists.osuosl.org>" }, "content": "This patch adds support for partial GSO segmentation in the case of\ntunnels. Specifically with this change the driver an perform segmenation\nas long as the frame either has IPv6 inner headers, or we are allowed to\nmangle the IP IDs on the inner header. This is needed because we will not\nbe modifying any fields from the start of the start of the outer transport\nheader to the start of the inner transport header as we are treating them\nlike they are just a block of IP options.\n\nSigned-off-by: Alexander Duyck <aduyck@mirantis.com>\n---\n drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 133 ++++++++++++++-------\n drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 129 +++++++++++++++-----\n 2 files changed, 180 insertions(+), 82 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\nindex d70746f85cab..baee3c139ad0 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n@@ -7255,9 +7255,18 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,\n \t\t struct ixgbe_tx_buffer *first,\n \t\t u8 *hdr_len)\n {\n+\tu32 vlan_macip_lens, type_tucmd, mss_l4len_idx;\n \tstruct sk_buff *skb = first->skb;\n-\tu32 vlan_macip_lens, type_tucmd;\n-\tu32 mss_l4len_idx, l4len;\n+\tunion {\n+\t\tstruct iphdr *v4;\n+\t\tstruct ipv6hdr *v6;\n+\t\tunsigned char *hdr;\n+\t} ip;\n+\tunion {\n+\t\tstruct tcphdr *tcp;\n+\t\tunsigned char *hdr;\n+\t} l4;\n+\tu32 paylen, l4_offset;\n \tint err;\n \n \tif (skb->ip_summed != CHECKSUM_PARTIAL)\n@@ -7270,46 +7279,52 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,\n \tif (err < 0)\n \t\treturn err;\n \n+\tip.hdr = skb_network_header(skb);\n+\tl4.hdr = skb_checksum_start(skb);\n+\n \t/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */\n \ttype_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;\n \n-\tif (first->protocol == htons(ETH_P_IP)) {\n-\t\tstruct iphdr *iph = ip_hdr(skb);\n-\t\tiph->tot_len = 0;\n-\t\tiph->check = 0;\n-\t\ttcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,\n-\t\t\t\t\t\t\t iph->daddr, 0,\n-\t\t\t\t\t\t\t IPPROTO_TCP,\n-\t\t\t\t\t\t\t 0);\n+\t/* initialize outer IP header fields */\n+\tif (ip.v4->version == 4) {\n+\t\t/* IP header will have to cancel out any data that\n+\t\t * is not a part of the outer IP header\n+\t\t */\n+\t\tip.v4->check = csum_fold(csum_add(lco_csum(skb),\n+\t\t\t\t\t\t csum_unfold(l4.tcp->check)));\n \t\ttype_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;\n+\n+\t\tip.v4->tot_len = 0;\n \t\tfirst->tx_flags |= IXGBE_TX_FLAGS_TSO |\n \t\t\t\t IXGBE_TX_FLAGS_CSUM |\n \t\t\t\t IXGBE_TX_FLAGS_IPV4;\n-\t} else if (skb_is_gso_v6(skb)) {\n-\t\tipv6_hdr(skb)->payload_len = 0;\n-\t\ttcp_hdr(skb)->check =\n-\t\t ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,\n-\t\t\t\t &ipv6_hdr(skb)->daddr,\n-\t\t\t\t 0, IPPROTO_TCP, 0);\n+\t} else {\n+\t\tip.v6->payload_len = 0;\n \t\tfirst->tx_flags |= IXGBE_TX_FLAGS_TSO |\n \t\t\t\t IXGBE_TX_FLAGS_CSUM;\n \t}\n \n-\t/* compute header lengths */\n-\tl4len = tcp_hdrlen(skb);\n-\t*hdr_len = skb_transport_offset(skb) + l4len;\n+\t/* determine offset of inner transport header */\n+\tl4_offset = l4.hdr - skb->data;\n+\n+\t/* compute length of segmentation header */\n+\t*hdr_len = (l4.tcp->doff * 4) + l4_offset;\n+\n+\t/* remove payload length from inner checksum */\n+\tpaylen = skb->len - l4_offset;\n+\tcsum_replace_by_diff(&l4.tcp->check, htonl(paylen));\n \n \t/* update gso size and bytecount with header size */\n \tfirst->gso_segs = skb_shinfo(skb)->gso_segs;\n \tfirst->bytecount += (first->gso_segs - 1) * *hdr_len;\n \n \t/* mss_l4len_id: use 0 as index for TSO */\n-\tmss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT;\n+\tmss_l4len_idx = (*hdr_len - l4_offset) << IXGBE_ADVTXD_L4LEN_SHIFT;\n \tmss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;\n \n \t/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */\n-\tvlan_macip_lens = skb_network_header_len(skb);\n-\tvlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;\n+\tvlan_macip_lens = l4.hdr - ip.hdr;\n+\tvlan_macip_lens |= (ip.hdr - skb->data) << IXGBE_ADVTXD_MACLEN_SHIFT;\n \tvlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;\n \n \tixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd,\n@@ -8966,17 +8981,36 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)\n \tkfree(fwd_adapter);\n }\n \n-#define IXGBE_MAX_TUNNEL_HDR_LEN 80\n+#define IXGBE_MAX_MAC_HDR_LEN\t\t127\n+#define IXGBE_MAX_NETWORK_HDR_LEN\t511\n+\n static netdev_features_t\n ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,\n \t\t netdev_features_t features)\n {\n-\tif (!skb->encapsulation)\n-\t\treturn features;\n-\n-\tif (unlikely(skb_inner_mac_header(skb) - skb_transport_header(skb) >\n-\t\t IXGBE_MAX_TUNNEL_HDR_LEN))\n-\t\treturn features & ~NETIF_F_CSUM_MASK;\n+\tunsigned int network_hdr_len, mac_hdr_len;\n+\n+\t/* Make certain the headers can be described by a context descriptor */\n+\tmac_hdr_len = skb_network_header(skb) - skb->data;\n+\tif (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN))\n+\t\treturn features & ~(NETIF_F_HW_CSUM |\n+\t\t\t\t NETIF_F_SCTP_CRC |\n+\t\t\t\t NETIF_F_HW_VLAN_CTAG_TX |\n+\t\t\t\t NETIF_F_TSO |\n+\t\t\t\t NETIF_F_TSO6);\n+\n+\tnetwork_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);\n+\tif (unlikely(network_hdr_len > IXGBE_MAX_NETWORK_HDR_LEN))\n+\t\treturn features & ~(NETIF_F_HW_CSUM |\n+\t\t\t\t NETIF_F_SCTP_CRC |\n+\t\t\t\t NETIF_F_TSO |\n+\t\t\t\t NETIF_F_TSO6);\n+\n+\t/* We can only support IPV4 TSO in tunnels if we can mangle the\n+\t * inner IP ID field, so strip TSO if MANGLEID is not supported.\n+\t */\n+\tif (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID))\n+\t\tfeatures &= ~NETIF_F_TSO;\n \n \treturn features;\n }\n@@ -9343,31 +9377,44 @@ skip_sriov:\n \t\t\t NETIF_F_TSO6 |\n \t\t\t NETIF_F_RXHASH |\n \t\t\t NETIF_F_RXCSUM |\n-\t\t\t NETIF_F_HW_CSUM |\n-\t\t\t NETIF_F_HW_VLAN_CTAG_TX |\n-\t\t\t NETIF_F_HW_VLAN_CTAG_RX |\n-\t\t\t NETIF_F_HW_VLAN_CTAG_FILTER;\n+\t\t\t NETIF_F_HW_CSUM;\n+\n+#define IXGBE_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \\\n+\t\t\t\t NETIF_F_GSO_GRE_CSUM | \\\n+\t\t\t\t NETIF_F_GSO_IPIP | \\\n+\t\t\t\t NETIF_F_GSO_SIT | \\\n+\t\t\t\t NETIF_F_GSO_UDP_TUNNEL | \\\n+\t\t\t\t NETIF_F_GSO_UDP_TUNNEL_CSUM)\n+\n+\tnetdev->gso_partial_features = IXGBE_GSO_PARTIAL_FEATURES;\n+\tnetdev->features |= NETIF_F_GSO_PARTIAL |\n+\t\t\t IXGBE_GSO_PARTIAL_FEATURES;\n \n \tif (hw->mac.type >= ixgbe_mac_82599EB)\n \t\tnetdev->features |= NETIF_F_SCTP_CRC;\n \n \t/* copy netdev features into list of user selectable features */\n-\tnetdev->hw_features |= netdev->features;\n-\tnetdev->hw_features |= NETIF_F_RXALL |\n+\tnetdev->hw_features |= netdev->features |\n+\t\t\t NETIF_F_HW_VLAN_CTAG_RX |\n+\t\t\t NETIF_F_HW_VLAN_CTAG_TX |\n+\t\t\t NETIF_F_RXALL |\n \t\t\t NETIF_F_HW_L2FW_DOFFLOAD;\n \n \tif (hw->mac.type >= ixgbe_mac_82599EB)\n \t\tnetdev->hw_features |= NETIF_F_NTUPLE |\n \t\t\t\t NETIF_F_HW_TC;\n \n-\tnetdev->vlan_features |= NETIF_F_SG |\n-\t\t\t\t NETIF_F_TSO |\n-\t\t\t\t NETIF_F_TSO6 |\n-\t\t\t\t NETIF_F_HW_CSUM |\n-\t\t\t\t NETIF_F_SCTP_CRC;\n+\tif (pci_using_dac)\n+\t\tnetdev->features |= NETIF_F_HIGHDMA;\n+\n+\t/* set this bit last since it cannot be part of vlan_features */\n+\tnetdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |\n+\t\t\t NETIF_F_HW_VLAN_CTAG_RX |\n+\t\t\t NETIF_F_HW_VLAN_CTAG_TX;\n \n+\tnetdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;\n+\tnetdev->hw_enc_features |= netdev->vlan_features;\n \tnetdev->mpls_features |= NETIF_F_HW_CSUM;\n-\tnetdev->hw_enc_features |= NETIF_F_HW_CSUM;\n \n \tnetdev->priv_flags |= IFF_UNICAST_FLT;\n \tnetdev->priv_flags |= IFF_SUPP_NOFCS;\n@@ -9398,10 +9445,6 @@ skip_sriov:\n \t\t\t\t\t NETIF_F_FCOE_MTU;\n \t}\n #endif /* IXGBE_FCOE */\n-\tif (pci_using_dac) {\n-\t\tnetdev->features |= NETIF_F_HIGHDMA;\n-\t\tnetdev->vlan_features |= NETIF_F_HIGHDMA;\n-\t}\n \n \tif (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)\n \t\tnetdev->hw_features |= NETIF_F_LRO;\ndiff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c\nindex e4e6060e6197..eb91922bcb19 100644\n--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c\n+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c\n@@ -3272,9 +3272,18 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,\n \t\t struct ixgbevf_tx_buffer *first,\n \t\t u8 *hdr_len)\n {\n+\tu32 vlan_macip_lens, type_tucmd, mss_l4len_idx;\n \tstruct sk_buff *skb = first->skb;\n-\tu32 vlan_macip_lens, type_tucmd;\n-\tu32 mss_l4len_idx, l4len;\n+\tunion {\n+\t\tstruct iphdr *v4;\n+\t\tstruct ipv6hdr *v6;\n+\t\tunsigned char *hdr;\n+\t} ip;\n+\tunion {\n+\t\tstruct tcphdr *tcp;\n+\t\tunsigned char *hdr;\n+\t} l4;\n+\tu32 paylen, l4_offset;\n \tint err;\n \n \tif (skb->ip_summed != CHECKSUM_PARTIAL)\n@@ -3287,49 +3296,53 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,\n \tif (err < 0)\n \t\treturn err;\n \n+\tip.hdr = skb_network_header(skb);\n+\tl4.hdr = skb_checksum_start(skb);\n+\n \t/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */\n \ttype_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;\n \n-\tif (first->protocol == htons(ETH_P_IP)) {\n-\t\tstruct iphdr *iph = ip_hdr(skb);\n-\n-\t\tiph->tot_len = 0;\n-\t\tiph->check = 0;\n-\t\ttcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,\n-\t\t\t\t\t\t\t iph->daddr, 0,\n-\t\t\t\t\t\t\t IPPROTO_TCP,\n-\t\t\t\t\t\t\t 0);\n+\t/* initialize outer IP header fields */\n+\tif (ip.v4->version == 4) {\n+\t\t/* IP header will have to cancel out any data that\n+\t\t * is not a part of the outer IP header\n+\t\t */\n+\t\tip.v4->check = csum_fold(csum_add(lco_csum(skb),\n+\t\t\t\t\t\t csum_unfold(l4.tcp->check)));\n \t\ttype_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;\n+\n+\t\tip.v4->tot_len = 0;\n \t\tfirst->tx_flags |= IXGBE_TX_FLAGS_TSO |\n \t\t\t\t IXGBE_TX_FLAGS_CSUM |\n \t\t\t\t IXGBE_TX_FLAGS_IPV4;\n-\t} else if (skb_is_gso_v6(skb)) {\n-\t\tipv6_hdr(skb)->payload_len = 0;\n-\t\ttcp_hdr(skb)->check =\n-\t\t ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,\n-\t\t\t\t &ipv6_hdr(skb)->daddr,\n-\t\t\t\t 0, IPPROTO_TCP, 0);\n+\t} else {\n+\t\tip.v6->payload_len = 0;\n \t\tfirst->tx_flags |= IXGBE_TX_FLAGS_TSO |\n \t\t\t\t IXGBE_TX_FLAGS_CSUM;\n \t}\n \n-\t/* compute header lengths */\n-\tl4len = tcp_hdrlen(skb);\n-\t*hdr_len += l4len;\n-\t*hdr_len = skb_transport_offset(skb) + l4len;\n+\t/* determine offset of inner transport header */\n+\tl4_offset = l4.hdr - skb->data;\n+\n+\t/* compute length of segmentation header */\n+\t*hdr_len = (l4.tcp->doff * 4) + l4_offset;\n \n-\t/* update GSO size and bytecount with header size */\n+\t/* remove payload length from inner checksum */\n+\tpaylen = skb->len - l4_offset;\n+\tcsum_replace_by_diff(&l4.tcp->check, htonl(paylen));\n+\n+\t/* update gso size and bytecount with header size */\n \tfirst->gso_segs = skb_shinfo(skb)->gso_segs;\n \tfirst->bytecount += (first->gso_segs - 1) * *hdr_len;\n \n \t/* mss_l4len_id: use 1 as index for TSO */\n-\tmss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT;\n+\tmss_l4len_idx = (*hdr_len - l4_offset) << IXGBE_ADVTXD_L4LEN_SHIFT;\n \tmss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;\n \tmss_l4len_idx |= (1u << IXGBE_ADVTXD_IDX_SHIFT);\n \n \t/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */\n-\tvlan_macip_lens = skb_network_header_len(skb);\n-\tvlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;\n+\tvlan_macip_lens = l4.hdr - ip.hdr;\n+\tvlan_macip_lens |= (ip.hdr - skb->data) << IXGBE_ADVTXD_MACLEN_SHIFT;\n \tvlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;\n \n \tixgbevf_tx_ctxtdesc(tx_ring, vlan_macip_lens,\n@@ -3870,6 +3883,40 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,\n \treturn stats;\n }\n \n+#define IXGBEVF_MAX_MAC_HDR_LEN\t\t127\n+#define IXGBEVF_MAX_NETWORK_HDR_LEN\t511\n+\n+static netdev_features_t\n+ixgbevf_features_check(struct sk_buff *skb, struct net_device *dev,\n+\t\t netdev_features_t features)\n+{\n+\tunsigned int network_hdr_len, mac_hdr_len;\n+\n+\t/* Make certain the headers can be described by a context descriptor */\n+\tmac_hdr_len = skb_network_header(skb) - skb->data;\n+\tif (unlikely(mac_hdr_len > IXGBEVF_MAX_MAC_HDR_LEN))\n+\t\treturn features & ~(NETIF_F_HW_CSUM |\n+\t\t\t\t NETIF_F_SCTP_CRC |\n+\t\t\t\t NETIF_F_HW_VLAN_CTAG_TX |\n+\t\t\t\t NETIF_F_TSO |\n+\t\t\t\t NETIF_F_TSO6);\n+\n+\tnetwork_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);\n+\tif (unlikely(network_hdr_len > IXGBEVF_MAX_NETWORK_HDR_LEN))\n+\t\treturn features & ~(NETIF_F_HW_CSUM |\n+\t\t\t\t NETIF_F_SCTP_CRC |\n+\t\t\t\t NETIF_F_TSO |\n+\t\t\t\t NETIF_F_TSO6);\n+\n+\t/* We can only support IPV4 TSO in tunnels if we can mangle the\n+\t * inner IP ID field, so strip TSO if MANGLEID is not supported.\n+\t */\n+\tif (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID))\n+\t\tfeatures &= ~NETIF_F_TSO;\n+\n+\treturn features;\n+}\n+\n static const struct net_device_ops ixgbevf_netdev_ops = {\n \t.ndo_open\t\t= ixgbevf_open,\n \t.ndo_stop\t\t= ixgbevf_close,\n@@ -3888,7 +3935,7 @@ static const struct net_device_ops ixgbevf_netdev_ops = {\n #ifdef CONFIG_NET_POLL_CONTROLLER\n \t.ndo_poll_controller\t= ixgbevf_netpoll,\n #endif\n-\t.ndo_features_check\t= passthru_features_check,\n+\t.ndo_features_check\t= ixgbevf_features_check,\n };\n \n static void ixgbevf_assign_netdev_ops(struct net_device *dev)\n@@ -3999,23 +4046,31 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\n \t\t\t NETIF_F_HW_CSUM |\n \t\t\t NETIF_F_SCTP_CRC;\n \n-\tnetdev->features = netdev->hw_features |\n-\t\t\t NETIF_F_HW_VLAN_CTAG_TX |\n-\t\t\t NETIF_F_HW_VLAN_CTAG_RX |\n-\t\t\t NETIF_F_HW_VLAN_CTAG_FILTER;\n+#define IXGBEVF_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \\\n+\t\t\t\t NETIF_F_GSO_GRE_CSUM | \\\n+\t\t\t\t NETIF_F_GSO_IPIP | \\\n+\t\t\t\t NETIF_F_GSO_SIT | \\\n+\t\t\t\t NETIF_F_GSO_UDP_TUNNEL | \\\n+\t\t\t\t NETIF_F_GSO_UDP_TUNNEL_CSUM)\n \n-\tnetdev->vlan_features |= NETIF_F_SG |\n-\t\t\t\t NETIF_F_TSO |\n-\t\t\t\t NETIF_F_TSO6 |\n-\t\t\t\t NETIF_F_HW_CSUM |\n-\t\t\t\t NETIF_F_SCTP_CRC;\n+\tnetdev->gso_partial_features = IXGBEVF_GSO_PARTIAL_FEATURES;\n+\tnetdev->hw_features |= NETIF_F_GSO_PARTIAL |\n+\t\t\t IXGBEVF_GSO_PARTIAL_FEATURES;\n \n-\tnetdev->mpls_features |= NETIF_F_HW_CSUM;\n-\tnetdev->hw_enc_features |= NETIF_F_HW_CSUM;\n+\tnetdev->features = netdev->hw_features;\n \n \tif (pci_using_dac)\n \t\tnetdev->features |= NETIF_F_HIGHDMA;\n \n+\tnetdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;\n+\tnetdev->mpls_features |= NETIF_F_HW_CSUM;\n+\tnetdev->hw_enc_features |= netdev->vlan_features;\n+\n+\t/* set this bit last since it cannot be part of vlan_features */\n+\tnetdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |\n+\t\t\t NETIF_F_HW_VLAN_CTAG_RX |\n+\t\t\t NETIF_F_HW_VLAN_CTAG_TX;\n+\n \tnetdev->priv_flags |= IFF_UNICAST_FLT;\n \n \tif (IXGBE_REMOVED(hw->hw_addr)) {\n", "prefixes": [ "next-queue", "v2", "2/3" ] }