Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/567914/?format=api
{ "id": 567914, "url": "http://patchwork.ozlabs.org/api/patches/567914/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20160115044203.24270.75723.stgit@localhost.localdomain/", "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": "<20160115044203.24270.75723.stgit@localhost.localdomain>", "list_archive_url": null, "date": "2016-01-15T04:42:03", "name": "[next,2/3] i40e: Refactor Tx checksum offload", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": false, "hash": "492bba28ae2cf07d192a885115987ed11c2c17db", "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/20160115044203.24270.75723.stgit@localhost.localdomain/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/567914/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/567914/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 C256A14032F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 15 Jan 2016 15:42:11 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 2471A917A9;\n\tFri, 15 Jan 2016 04:42:10 +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 C+3VHfTDU5k9; Fri, 15 Jan 2016 04:42:08 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id C9A819176A;\n\tFri, 15 Jan 2016 04:42:08 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id 769D91BFA5C\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 04:42:08 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 6EA2B8B094\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 04:42:08 +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 QqO62v-Hx1C2 for <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 04:42:04 +0000 (UTC)", "from mail-pf0-f179.google.com (mail-pf0-f179.google.com\n\t[209.85.192.179])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id 5CBE98B06D\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 04:42:04 +0000 (UTC)", "by mail-pf0-f179.google.com with SMTP id q63so114671254pfb.1\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Jan 2016 20:42:04 -0800 (PST)", "from localhost.localdomain\n\t(static-50-53-29-36.bvtn.or.frontiernet.net. [50.53.29.36])\n\tby smtp.gmail.com with ESMTPSA id\n\tq136sm12519169pfq.66.2016.01.14.20.42.03\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 14 Jan 2016 20:42:03 -0800 (PST)" ], "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=eJm1gEXV; 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:cc:date:message-id:in-reply-to:references\n\t:user-agent:mime-version:content-type:content-transfer-encoding;\n\tbh=ym47k9SGAmmDcnvaYZjYS1GzaM55ShgttTI/RpmpwCE=;\n\tb=eJm1gEXVXKtIRiwNY/r2iAHiNcQ1WGHgipkd2CGu4UoHytZ2cL0V3K23kr1GSnjjon\n\t+JBOqlfI0vyJHYrlYxxUFW+dEyOxgZeGvpQETvNOiY5PsmHs1QgiVVvJC3Bwgr6gC/Mt\n\tN59sh+mdVQZYvKT7ooyZKN+H+hS9ug5Q32pXo=", "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:cc:date:message-id:in-reply-to\n\t:references:user-agent:mime-version:content-type\n\t:content-transfer-encoding;\n\tbh=ym47k9SGAmmDcnvaYZjYS1GzaM55ShgttTI/RpmpwCE=;\n\tb=gmCf0DROAB2Ciy4ldGL4uPr1S3ZTaOVD0jbAIMWoAETbWzvsdncj/Kf+wmx6lCQWIx\n\t/0GGGoUD2cjqRm5eXGPMk42hryec3Y9FE3xNrCeVPieAUm2YU2b7sdeUNkJjib7DegD9\n\taXX9DD2MKoGfBgQ/v4WxDWS9CJhEzpLD6/GL41ENtnPFmdBSJ4zqK4GJuVUi7ZSsX8BT\n\tXJaZMNvi1DhI7oM5trSDFPWyx2SeHXwliy6cw8pXkUKsQLKG3fkLSj3R/HBzmOJFcUhj\n\tAcTqUhCGPAsVsfU7NZbppfZpiVxkOipmWTDUlmUedGxBav8+BkOr0ehMXDngiPBdWWSs\n\tD4Sw==", "X-Gm-Message-State": "ALoCoQk2p8ZrDcXDARy0c/zuGXCAK+K3YjPTnkLdWFZbiGD2dsT3yiYXV+a1FWeHKMp3So6FWd/CiK4cP8F/jZcK00Dmivu/qA==", "X-Received": "by 10.98.42.81 with SMTP id q78mr11745861pfq.142.1452832924063; \n\tThu, 14 Jan 2016 20:42:04 -0800 (PST)", "From": "Alexander Duyck <aduyck@mirantis.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Thu, 14 Jan 2016 20:42:03 -0800", "Message-ID": "<20160115044203.24270.75723.stgit@localhost.localdomain>", "In-Reply-To": "<20160115043921.24270.62791.stgit@localhost.localdomain>", "References": "<20160115043921.24270.62791.stgit@localhost.localdomain>", "User-Agent": "StGit/0.17.1-dirty", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [next PATCH 2/3] i40e: Refactor Tx checksum\n\toffload", "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 is meant to clean up a number of bugs in the Tx checksum offload\nfor the i40e driver. The main issues all tend to be in the area of IPv6.\n\n1. IPv6 tunnel offloads not advertised\n2. IPv6 extension headers not skipped\n3. Use of iphdr(skb)->protocol in checksum path for IPv6\n4. Tx flags not reset when going from V6 to V4 for offloads\n\nSpecifically this driver was not offloading IPv6 under a number of\ncircumstances, and in some cases such as IPv4 over an IPv6 based VXLAN\ntunnel it would fail outright to send any valid data.\n\nSigned-off-by: Alexander Duyck <aduyck@mirantis.com>\n---\n drivers/net/ethernet/intel/i40e/i40e_main.c | 2 \n drivers/net/ethernet/intel/i40e/i40e_txrx.c | 193 ++++++++++++++++-----------\n 2 files changed, 115 insertions(+), 80 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c\nindex c21ad853d72f..a15ab5fd3bd7 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_main.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c\n@@ -9017,7 +9017,9 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)\n \tnp->vsi = vsi;\n \n \tnetdev->hw_enc_features |= NETIF_F_IP_CSUM\t |\n+\t\t\t\t NETIF_F_IPV6_CSUM\t |\n \t\t\t\t NETIF_F_TSO\t\t |\n+\t\t\t\t NETIF_F_TSO6\t\t |\n \t\t\t\t NETIF_F_TSO_ECN\t |\n \t\t\t\t NETIF_F_GSO_GRE\t |\n \t\t\t\t NETIF_F_GSO_UDP_TUNNEL |\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex ac2fa7b02e94..60005356e65b 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -2337,122 +2337,152 @@ no_timestamp:\n * @tx_ring: Tx descriptor ring\n * @cd_tunneling: ptr to context desc bits\n **/\n-static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,\n-\t\t\t\tu32 *td_cmd, u32 *td_offset,\n-\t\t\t\tstruct i40e_ring *tx_ring,\n-\t\t\t\tu32 *cd_tunneling)\n+static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,\n+\t\t\t u32 *td_cmd, u32 *td_offset,\n+\t\t\t struct i40e_ring *tx_ring,\n+\t\t\t u32 *cd_tunneling)\n {\n-\tstruct ipv6hdr *this_ipv6_hdr;\n-\tunsigned int this_tcp_hdrlen;\n-\tstruct iphdr *this_ip_hdr;\n-\tu32 network_hdr_len;\n-\tu8 l4_hdr = 0;\n-\tstruct udphdr *oudph;\n-\tstruct iphdr *oiph;\n-\tu32 l4_tunnel = 0;\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\tstruct udphdr *udp;\n+\t\tunsigned char *hdr;\n+\t} l4;\n+\tunsigned char *exthdr;\n+\tu32 offset, cmd = 0, tunnel = 0;\n+\t__be16 frag_off;\n+\tu8 l4_proto = 0;\n+\n+\tip.hdr = skb_network_header(skb);\n+\tl4.hdr = skb_transport_header(skb);\n+\n+\t/* words in MACLEN + dwords in IPLEN + dwords in L4Len */\n+\toffset = ((ip.hdr - skb->data) / 2) <<\n+\t\t I40E_TX_DESC_LENGTH_MACLEN_SHIFT;\n \n \tif (skb->encapsulation) {\n-\t\tswitch (ip_hdr(skb)->protocol) {\n+\t\t/* define outer network header type */\n+\t\tif (*tx_flags & I40E_TX_FLAGS_IPV4) {\n+\t\t\ttunnel |= (*tx_flags & I40E_TX_FLAGS_TSO) ?\n+\t\t\t\t I40E_TX_CTX_EXT_IP_IPV4 :\n+\t\t\t\t I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;\n+\n+\t\t\tl4_proto = ip.v4->protocol;\n+\t\t} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {\n+\t\t\ttunnel |= I40E_TX_CTX_EXT_IP_IPV6;\n+\n+\t\t\texthdr = ip.hdr + sizeof(*ip.v6);\n+\t\t\tl4_proto = ip.v6->nexthdr;\n+\t\t\tif (l4.hdr != exthdr)\n+\t\t\t\tipv6_skip_exthdr(skb, exthdr - skb->data,\n+\t\t\t\t\t\t &l4_proto, &frag_off);\n+\t\t}\n+\n+\t\t/* compute outer L3 header size */\n+\t\ttunnel |= ((l4.hdr - ip.hdr) / 4) <<\n+\t\t\t I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;\n+\n+\t\t/* switch IP header pointer from outer to inner header */\n+\t\tip.hdr = skb_inner_network_header(skb);\n+\n+\t\t/* define outer transport */\n+\t\tswitch (l4_proto) {\n \t\tcase IPPROTO_UDP:\n-\t\t\toudph = udp_hdr(skb);\n-\t\t\toiph = ip_hdr(skb);\n-\t\t\tl4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;\n+\t\t\ttunnel |= I40E_TXD_CTX_UDP_TUNNELING;\n \t\t\t*tx_flags |= I40E_TX_FLAGS_TUNNEL;\n \t\t\tbreak;\n \t\tcase IPPROTO_GRE:\n-\t\t\tl4_tunnel = I40E_TXD_CTX_GRE_TUNNELING;\n+\t\t\ttunnel |= I40E_TXD_CTX_GRE_TUNNELING;\n \t\t\t*tx_flags |= I40E_TX_FLAGS_TUNNEL;\n \t\t\tbreak;\n \t\tdefault:\n-\t\t\treturn;\n-\t\t}\n-\t\tnetwork_hdr_len = skb_inner_network_header_len(skb);\n-\t\tthis_ip_hdr = inner_ip_hdr(skb);\n-\t\tthis_ipv6_hdr = inner_ipv6_hdr(skb);\n-\t\tthis_tcp_hdrlen = inner_tcp_hdrlen(skb);\n+\t\t\tif (*tx_flags & I40E_TX_FLAGS_TSO)\n+\t\t\t\treturn -1;\n \n-\t\tif (*tx_flags & I40E_TX_FLAGS_IPV4) {\n-\t\t\tif (*tx_flags & I40E_TX_FLAGS_TSO) {\n-\t\t\t\t*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV4;\n-\t\t\t} else {\n-\t\t\t\t*cd_tunneling |=\n-\t\t\t\t\t I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;\n-\t\t\t}\n-\t\t} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {\n-\t\t\t*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6;\n+\t\t\tskb_checksum_help(skb);\n+\t\t\treturn 0;\n \t\t}\n \n-\t\t/* Now set the ctx descriptor fields */\n-\t\t*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<\n-\t\t\t\t I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |\n-\t\t\t\t l4_tunnel |\n-\t\t\t\t ((skb_inner_network_offset(skb) -\n-\t\t\t\t\tskb_transport_offset(skb)) >> 1) <<\n-\t\t\t\t I40E_TXD_CTX_QW0_NATLEN_SHIFT;\n-\t\tif (this_ip_hdr->version == 6) {\n-\t\t\t*tx_flags &= ~I40E_TX_FLAGS_IPV4;\n-\t\t\t*tx_flags |= I40E_TX_FLAGS_IPV6;\n-\t\t}\n+\t\t/* compute tunnel header size */\n+\t\ttunnel |= ((ip.hdr - l4.hdr) / 2) <<\n+\t\t\t I40E_TXD_CTX_QW0_NATLEN_SHIFT;\n+\n+\t\t/* switch L4 header pointer from outer to inner */\n+\t\tl4.hdr = skb_inner_transport_header(skb);\n+\n \t\t/* indicate if we need to offload outer UDP header */\n \t\tif ((*tx_flags & I40E_TX_FLAGS_TSO) &&\n \t\t (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))\n-\t\t\t*cd_tunneling |= I40E_TXD_CTX_QW0_L4T_CS_MASK;\n+\t\t\ttunnel |= I40E_TXD_CTX_QW0_L4T_CS_MASK;\n \n-\t} else {\n-\t\tnetwork_hdr_len = skb_network_header_len(skb);\n-\t\tthis_ip_hdr = ip_hdr(skb);\n-\t\tthis_ipv6_hdr = ipv6_hdr(skb);\n-\t\tthis_tcp_hdrlen = tcp_hdrlen(skb);\n+\t\t/* reset type as we transition from outer to inner headers */\n+\t\t*tx_flags &= ~(I40E_TX_FLAGS_IPV4 | I40E_TX_FLAGS_IPV6);\n+\t\tif (ip.v4->version == 4)\n+\t\t\t*tx_flags |= I40E_TX_FLAGS_IPV4;\n+\t\tif (ip.v6->version == 6)\n+\t\t\t*tx_flags |= I40E_TX_FLAGS_IPV6;\n+\n+\t\t/* record tunnel offload values */\n+\t\t*cd_tunneling |= tunnel;\n \t}\n \n \t/* Enable IP checksum offloads */\n \tif (*tx_flags & I40E_TX_FLAGS_IPV4) {\n-\t\tl4_hdr = this_ip_hdr->protocol;\n \t\t/* the stack computes the IP header already, the only time we\n \t\t * need the hardware to recompute it is in the case of TSO.\n \t\t */\n-\t\tif (*tx_flags & I40E_TX_FLAGS_TSO) {\n-\t\t\t*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4_CSUM;\n-\t\t} else {\n-\t\t\t*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;\n-\t\t}\n-\t\t/* Now set the td_offset for IP header length */\n-\t\t*td_offset = (network_hdr_len >> 2) <<\n-\t\t\t I40E_TX_DESC_LENGTH_IPLEN_SHIFT;\n+\t\tcmd |= (*tx_flags & I40E_TX_FLAGS_TSO) ?\n+\t\t I40E_TX_DESC_CMD_IIPT_IPV4_CSUM :\n+\t\t I40E_TX_DESC_CMD_IIPT_IPV4;\n+\n+\t\tl4_proto = ip.v4->protocol;\n \t} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {\n-\t\tl4_hdr = this_ipv6_hdr->nexthdr;\n-\t\t*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;\n-\t\t/* Now set the td_offset for IP header length */\n-\t\t*td_offset = (network_hdr_len >> 2) <<\n-\t\t\t I40E_TX_DESC_LENGTH_IPLEN_SHIFT;\n+\t\tcmd |= I40E_TX_DESC_CMD_IIPT_IPV6;\n+\n+\t\texthdr = ip.hdr + sizeof(*ip.v6);\n+\t\tl4_proto = ip.v6->nexthdr;\n+\t\tif (l4.hdr != exthdr)\n+\t\t\tipv6_skip_exthdr(skb, exthdr - skb->data,\n+\t\t\t\t\t &l4_proto, &frag_off);\n \t}\n-\t/* words in MACLEN + dwords in IPLEN + dwords in L4Len */\n-\t*td_offset |= (skb_network_offset(skb) >> 1) <<\n-\t\t I40E_TX_DESC_LENGTH_MACLEN_SHIFT;\n+\n+\t/* Now set the td_offset for IP header length */\n+\toffset |= ((l4.hdr - ip.hdr) / 4) << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;\n \n \t/* Enable L4 checksum offloads */\n-\tswitch (l4_hdr) {\n+\tswitch (l4_proto) {\n \tcase IPPROTO_TCP:\n \t\t/* enable checksum offloads */\n-\t\t*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;\n-\t\t*td_offset |= (this_tcp_hdrlen >> 2) <<\n-\t\t\t I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;\n+\t\tcmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;\n+\t\toffset |= l4.tcp->doff << I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;\n \t\tbreak;\n \tcase IPPROTO_SCTP:\n \t\t/* enable SCTP checksum offload */\n-\t\t*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_SCTP;\n-\t\t*td_offset |= (sizeof(struct sctphdr) >> 2) <<\n-\t\t\t I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;\n+\t\tcmd |= I40E_TX_DESC_CMD_L4T_EOFT_SCTP;\n+\t\toffset |= (sizeof(struct sctphdr) >> 2) <<\n+\t\t\t I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;\n \t\tbreak;\n \tcase IPPROTO_UDP:\n \t\t/* enable UDP checksum offload */\n-\t\t*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_UDP;\n-\t\t*td_offset |= (sizeof(struct udphdr) >> 2) <<\n-\t\t\t I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;\n+\t\tcmd |= I40E_TX_DESC_CMD_L4T_EOFT_UDP;\n+\t\toffset |= (sizeof(struct udphdr) >> 2) <<\n+\t\t\t I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;\n \t\tbreak;\n \tdefault:\n-\t\tbreak;\n+\t\tif (*tx_flags & I40E_TX_FLAGS_TSO)\n+\t\t\treturn -1;\n+\t\tskb_checksum_help(skb);\n+\t\treturn 0;\n \t}\n+\n+\t*td_cmd |= cmd;\n+\t*td_offset |= offset;\n+\n+\treturn 1;\n }\n \n /**\n@@ -2890,10 +2920,13 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,\n \n \t/* Always offload the checksum, since it's in the data descriptor */\n \tif (skb->ip_summed == CHECKSUM_PARTIAL) {\n-\t\ttx_flags |= I40E_TX_FLAGS_CSUM;\n+\t\ttso = i40e_tx_enable_csum(skb, &tx_flags, &td_cmd, &td_offset,\n+\t\t\t\t\t tx_ring, &cd_tunneling);\n+\t\tif (tso < 0)\n+\t\t\tgoto out_drop;\n+\t\telse if (tso)\n+\t\t\ttx_flags |= I40E_TX_FLAGS_CSUM;\n \n-\t\ti40e_tx_enable_csum(skb, &tx_flags, &td_cmd, &td_offset,\n-\t\t\t\t tx_ring, &cd_tunneling);\n \t}\n \n \ti40e_create_tx_ctx(tx_ring, cd_type_cmd_tso_mss,\n", "prefixes": [ "next", "2/3" ] }