get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/610656/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 610656,
    "url": "http://patchwork.ozlabs.org/api/patches/610656/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20160414211938.14141.76178.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": "<20160414211938.14141.76178.stgit@ahduyck-xeon-server>",
    "list_archive_url": null,
    "date": "2016-04-14T21:19:38",
    "name": "[next-queue,v2,3/3] igb/igbvf: Add support for GSO partial",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "8a3ce18d48b41594dec39f1b918a36e8292cdbd1",
    "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/20160414211938.14141.76178.stgit@ahduyck-xeon-server/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/610656/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/610656/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 3qmD8P5kGwz9sDC\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 15 Apr 2016 07:19:49 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 168728A521;\n\tThu, 14 Apr 2016 21:19:49 +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 JzMoWrD32qdl; Thu, 14 Apr 2016 21:19:47 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 63B0E89A5F;\n\tThu, 14 Apr 2016 21:19:47 +0000 (UTC)",
            "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ash.osuosl.org (Postfix) with ESMTP id BA6E71C0DF4\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:45 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id B30398A801\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:45 +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 uvikrk73mtnz for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:44 +0000 (UTC)",
            "from mail-pa0-f44.google.com (mail-pa0-f44.google.com\n\t[209.85.220.44])\n\tby whitealder.osuosl.org (Postfix) with ESMTPS id 84E1489A5F\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 21:19:44 +0000 (UTC)",
            "by mail-pa0-f44.google.com with SMTP id zm5so48353191pac.0\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Apr 2016 14:19:44 -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\tu2sm59987276pfi.26.2016.04.14.14.19.43\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 14 Apr 2016 14:19:43 -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=SYKnwg7q; 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=dwPe1PxWQg1nmlGzfuR3/drofa0XHPmak9FPy7UD0EY=;\n\tb=SYKnwg7qe52Czg+xaBc63GN2UYi8nPYv3TEXAvmaqo9ZsGgP9oBSe/YHVeMlFIZ63f\n\t/78mafTztADCFPordtxf7IuHxvb/7+tNMzfZIgdDJZq3X0Utchd8gzeutM3NOkmN2QZb\n\tfWVMGYs9bmEDy4O0yXODDTFMo2Tjt61BrZxBM=",
        "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=dwPe1PxWQg1nmlGzfuR3/drofa0XHPmak9FPy7UD0EY=;\n\tb=hCihnUFG8PK5w42vY0b41KZg7Q+HS4OBLcNVMt4ibTKV0s0rMjQlPuNlw9OjXIR0JX\n\tM2wDCGE8kGwqP7jsKPR473X5g0wikxJeXdYLMOZGGwZRH2iuUlgbUkQKi8N9Rw9xBHtu\n\tuiOisWcuXVRuDoA+Z9kHArfYJDve2AZE2DiMahSRLfbX7JB8278WVvmBvGXps/hwxArP\n\t2AlciN6/0Tu3LNThQEWHbGv6FG6k7vPJiG+Lym0MprrHs4yujZYml6FIpWbodFZ52C0x\n\tkhQz+tsdyRfVK25vvpsG7q6ODbG5FXBTQqgv2nZehSDF36D3BLGMODQUYWXdMhBTjafV\n\ttpTw==",
        "X-Gm-Message-State": "AOPr4FX1p8WwlVA08byCGvmnatWR7cmqIbX4BeDGHmo7aeVRrXm5vKeo5QvOoVtOJ9xGjG1x",
        "X-Received": "by 10.66.218.161 with SMTP id ph1mr24009591pac.83.1460668784207; \n\tThu, 14 Apr 2016 14:19:44 -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:38 -0400",
        "Message-ID": "<20160414211938.14141.76178.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 3/3] igb/igbvf: Add support\n\tfor 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/igb/igb_main.c |  137 +++++++++++++++-------\n drivers/net/ethernet/intel/igbvf/netdev.c |  182 +++++++++++++++++------------\n 2 files changed, 203 insertions(+), 116 deletions(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c\nindex 3d58b3268182..f1c18f141d3e 100644\n--- a/drivers/net/ethernet/intel/igb/igb_main.c\n+++ b/drivers/net/ethernet/intel/igb/igb_main.c\n@@ -2087,6 +2087,40 @@ static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],\n \treturn ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, flags);\n }\n \n+#define IGB_MAX_MAC_HDR_LEN\t127\n+#define IGB_MAX_NETWORK_HDR_LEN\t511\n+\n+static netdev_features_t\n+igb_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 > IGB_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 >  IGB_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 igb_netdev_ops = {\n \t.ndo_open\t\t= igb_open,\n \t.ndo_stop\t\t= igb_close,\n@@ -2111,7 +2145,7 @@ static const struct net_device_ops igb_netdev_ops = {\n \t.ndo_fix_features\t= igb_fix_features,\n \t.ndo_set_features\t= igb_set_features,\n \t.ndo_fdb_add\t\t= igb_ndo_fdb_add,\n-\t.ndo_features_check\t= passthru_features_check,\n+\t.ndo_features_check\t= igb_features_check,\n };\n \n /**\n@@ -2377,38 +2411,43 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\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_RX |\n-\t\t\t    NETIF_F_HW_VLAN_CTAG_TX;\n+\t\t\t    NETIF_F_HW_CSUM;\n \n \tif (hw->mac.type >= e1000_82576)\n \t\tnetdev->features |= NETIF_F_SCTP_CRC;\n \n+#define IGB_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 = IGB_GSO_PARTIAL_FEATURES;\n+\tnetdev->features |= NETIF_F_GSO_PARTIAL | IGB_GSO_PARTIAL_FEATURES;\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 \n \tif (hw->mac.type >= e1000_i350)\n \t\tnetdev->hw_features |= NETIF_F_NTUPLE;\n \n-\t/* set this bit last since it cannot be part of hw_features */\n-\tnetdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;\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+\tnetdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;\n \tnetdev->mpls_features |= NETIF_F_HW_CSUM;\n-\tnetdev->hw_enc_features |= NETIF_F_HW_CSUM;\n+\tnetdev->hw_enc_features |= netdev->vlan_features;\n \n-\tnetdev->priv_flags |= IFF_SUPP_NOFCS;\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-\tif (pci_using_dac) {\n-\t\tnetdev->features |= NETIF_F_HIGHDMA;\n-\t\tnetdev->vlan_features |= NETIF_F_HIGHDMA;\n-\t}\n+\tnetdev->priv_flags |= IFF_SUPP_NOFCS;\n \n \tnetdev->priv_flags |= IFF_UNICAST_FLT;\n \n@@ -4842,9 +4881,18 @@ static int igb_tso(struct igb_ring *tx_ring,\n \t\t   struct igb_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@@ -4857,45 +4905,52 @@ static int igb_tso(struct igb_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 = E1000_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 |= E1000_ADVTXD_TUCMD_IPV4;\n+\n+\t\tip.v4->tot_len = 0;\n \t\tfirst->tx_flags |= IGB_TX_FLAGS_TSO |\n \t\t\t\t   IGB_TX_FLAGS_CSUM |\n \t\t\t\t   IGB_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 = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,\n-\t\t\t\t\t\t       &ipv6_hdr(skb)->daddr,\n-\t\t\t\t\t\t       0, IPPROTO_TCP, 0);\n+\t} else {\n+\t\tip.v6->payload_len = 0;\n \t\tfirst->tx_flags |= IGB_TX_FLAGS_TSO |\n \t\t\t\t   IGB_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 IDX */\n-\tmss_l4len_idx = l4len << E1000_ADVTXD_L4LEN_SHIFT;\n+\tmss_l4len_idx = (*hdr_len - l4_offset) << E1000_ADVTXD_L4LEN_SHIFT;\n \tmss_l4len_idx |= skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT;\n \n \t/* VLAN MACLEN IPLEN */\n-\tvlan_macip_lens = skb_network_header_len(skb);\n-\tvlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT;\n+\tvlan_macip_lens = l4.hdr - ip.hdr;\n+\tvlan_macip_lens |= (ip.hdr - skb->data) << E1000_ADVTXD_MACLEN_SHIFT;\n \tvlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK;\n \n \tigb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);\ndiff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c\nindex 57894a80c469..322a2d7828a5 100644\n--- a/drivers/net/ethernet/intel/igbvf/netdev.c\n+++ b/drivers/net/ethernet/intel/igbvf/netdev.c\n@@ -1931,83 +1931,74 @@ static void igbvf_tx_ctxtdesc(struct igbvf_ring *tx_ring, u32 vlan_macip_lens,\n \tbuffer_info->dma = 0;\n }\n \n-static int igbvf_tso(struct igbvf_adapter *adapter,\n-\t\t     struct igbvf_ring *tx_ring,\n-\t\t     struct sk_buff *skb, u32 tx_flags, u8 *hdr_len,\n-\t\t     __be16 protocol)\n-{\n-\tstruct e1000_adv_tx_context_desc *context_desc;\n-\tstruct igbvf_buffer *buffer_info;\n-\tu32 info = 0, tu_cmd = 0;\n-\tu32 mss_l4len_idx, l4len;\n-\tunsigned int i;\n+static int igbvf_tso(struct igbvf_ring *tx_ring,\n+\t\t     struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)\n+{\n+\tu32 vlan_macip_lens, type_tucmd, mss_l4len_idx;\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-\t*hdr_len = 0;\n+\tif (skb->ip_summed != CHECKSUM_PARTIAL)\n+\t\treturn 0;\n+\n+\tif (!skb_is_gso(skb))\n+\t\treturn 0;\n \n \terr = skb_cow_head(skb, 0);\n-\tif (err < 0) {\n-\t\tdev_err(&adapter->pdev->dev, \"igbvf_tso returning an error\\n\");\n+\tif (err < 0)\n \t\treturn err;\n-\t}\n \n-\tl4len = tcp_hdrlen(skb);\n-\t*hdr_len += l4len;\n-\n-\tif (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} else if (skb_is_gso_v6(skb)) {\n-\t\tipv6_hdr(skb)->payload_len = 0;\n-\t\ttcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,\n-\t\t\t\t\t\t       &ipv6_hdr(skb)->daddr,\n-\t\t\t\t\t\t       0, IPPROTO_TCP, 0);\n-\t}\n+\tip.hdr = skb_network_header(skb);\n+\tl4.hdr = skb_checksum_start(skb);\n \n-\ti = tx_ring->next_to_use;\n+\t/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */\n+\ttype_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;\n \n-\tbuffer_info = &tx_ring->buffer_info[i];\n-\tcontext_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);\n-\t/* VLAN MACLEN IPLEN */\n-\tif (tx_flags & IGBVF_TX_FLAGS_VLAN)\n-\t\tinfo |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);\n-\tinfo |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);\n-\t*hdr_len += skb_network_offset(skb);\n-\tinfo |= (skb_transport_header(skb) - skb_network_header(skb));\n-\t*hdr_len += (skb_transport_header(skb) - skb_network_header(skb));\n-\tcontext_desc->vlan_macip_lens = cpu_to_le32(info);\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 |= E1000_ADVTXD_TUCMD_IPV4;\n \n-\t/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */\n-\ttu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);\n+\t\tip.v4->tot_len = 0;\n+\t} else {\n+\t\tip.v6->payload_len = 0;\n+\t}\n \n-\tif (protocol == htons(ETH_P_IP))\n-\t\ttu_cmd |= E1000_ADVTXD_TUCMD_IPV4;\n-\ttu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;\n+\t/* determine offset of inner transport header */\n+\tl4_offset = l4.hdr - skb->data;\n \n-\tcontext_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);\n+\t/* compute length of segmentation header */\n+\t*hdr_len = (l4.tcp->doff * 4) + l4_offset;\n \n-\t/* MSS L4LEN IDX */\n-\tmss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);\n-\tmss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);\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-\tcontext_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);\n-\tcontext_desc->seqnum_seed = 0;\n+\t/* MSS L4LEN IDX */\n+\tmss_l4len_idx = (*hdr_len - l4_offset) << E1000_ADVTXD_L4LEN_SHIFT;\n+\tmss_l4len_idx |= skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT;\n \n-\tbuffer_info->time_stamp = jiffies;\n-\tbuffer_info->dma = 0;\n-\ti++;\n-\tif (i == tx_ring->count)\n-\t\ti = 0;\n+\t/* VLAN MACLEN IPLEN */\n+\tvlan_macip_lens = l4.hdr - ip.hdr;\n+\tvlan_macip_lens |= (ip.hdr - skb->data) << E1000_ADVTXD_MACLEN_SHIFT;\n+\tvlan_macip_lens |= tx_flags & IGBVF_TX_FLAGS_VLAN_MASK;\n \n-\ttx_ring->next_to_use = i;\n+\tigbvf_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);\n \n-\treturn true;\n+\treturn 1;\n }\n \n static inline bool igbvf_ipv6_csum_is_sctp(struct sk_buff *skb)\n@@ -2269,8 +2260,7 @@ static netdev_tx_t igbvf_xmit_frame_ring_adv(struct sk_buff *skb,\n \n \tfirst = tx_ring->next_to_use;\n \n-\ttso = skb_is_gso(skb) ?\n-\t\tigbvf_tso(adapter, tx_ring, skb, tx_flags, &hdr_len, protocol) : 0;\n+\ttso = igbvf_tso(tx_ring, skb, tx_flags, &hdr_len);\n \tif (unlikely(tso < 0)) {\n \t\tdev_kfree_skb_any(skb);\n \t\treturn NETDEV_TX_OK;\n@@ -2613,6 +2603,40 @@ static int igbvf_set_features(struct net_device *netdev,\n \treturn 0;\n }\n \n+#define IGBVF_MAX_MAC_HDR_LEN\t\t127\n+#define IGBVF_MAX_NETWORK_HDR_LEN\t511\n+\n+static netdev_features_t\n+igbvf_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 > IGBVF_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 >  IGBVF_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 igbvf_netdev_ops = {\n \t.ndo_open\t\t= igbvf_open,\n \t.ndo_stop\t\t= igbvf_close,\n@@ -2629,7 +2653,7 @@ static const struct net_device_ops igbvf_netdev_ops = {\n \t.ndo_poll_controller\t= igbvf_netpoll,\n #endif\n \t.ndo_set_features\t= igbvf_set_features,\n-\t.ndo_features_check\t= passthru_features_check,\n+\t.ndo_features_check\t= igbvf_features_check,\n };\n \n /**\n@@ -2737,22 +2761,30 @@ static int igbvf_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 IGBVF_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 = IGBVF_GSO_PARTIAL_FEATURES;\n+\tnetdev->hw_features |= NETIF_F_GSO_PARTIAL |\n+\t\t\t       IGBVF_GSO_PARTIAL_FEATURES;\n+\n+\tnetdev->features = netdev->hw_features;\n \n \tif (pci_using_dac)\n \t\tnetdev->features |= NETIF_F_HIGHDMA;\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-\n+\tnetdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;\n \tnetdev->mpls_features |= NETIF_F_HW_CSUM;\n-\tnetdev->hw_enc_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 \t/*reset the controller to put the device in a known good state */\n \terr = hw->mac.ops.reset_hw(hw);\n",
    "prefixes": [
        "next-queue",
        "v2",
        "3/3"
    ]
}