get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1408,
    "url": "https://patches.dpdk.org/api/patches/1408/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1416524335-22753-12-git-send-email-olivier.matz@6wind.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1416524335-22753-12-git-send-email-olivier.matz@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1416524335-22753-12-git-send-email-olivier.matz@6wind.com",
    "date": "2014-11-20T22:58:53",
    "name": "[dpdk-dev,v3,11/13] ixgbe: support TCP segmentation offload",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "664291500f7dbf3f6a48cc6ae967dbefa3edd2c1",
    "submitter": {
        "id": 8,
        "url": "https://patches.dpdk.org/api/people/8/?format=api",
        "name": "Olivier Matz",
        "email": "olivier.matz@6wind.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1416524335-22753-12-git-send-email-olivier.matz@6wind.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/1408/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/1408/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 7D3A37FE6;\n\tThu, 20 Nov 2014 23:48:54 +0100 (CET)",
            "from mail-wg0-f45.google.com (mail-wg0-f45.google.com\n\t[74.125.82.45]) by dpdk.org (Postfix) with ESMTP id 34E647F40\n\tfor <dev@dpdk.org>; Thu, 20 Nov 2014 23:48:44 +0100 (CET)",
            "by mail-wg0-f45.google.com with SMTP id b13so5081517wgh.4\n\tfor <dev@dpdk.org>; Thu, 20 Nov 2014 14:59:16 -0800 (PST)",
            "from glumotte.dev.6wind.com (guy78-3-82-239-227-177.fbx.proxad.net.\n\t[82.239.227.177]) by mx.google.com with ESMTPSA id\n\tcz3sm5380581wjb.23.2014.11.20.14.59.14 for <multiple recipients>\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tThu, 20 Nov 2014 14:59:15 -0800 (PST)"
        ],
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=F7ih4xj9OnccKlg+c3+VlKXZsvB86ys48zghyNkyZZs=;\n\tb=mcNzjRJjKArfDT24OKoTJ7v7YvG187lBDDmdsNHeX4BrvJrJu+E4Zx9vgQHmakYh8T\n\tPEAlWqNEwT8oGnlqiFyDC3VlQHou+wngY6gXQxLCjTmc5u3/8yqYnxCGXKAi3uh1vHbR\n\twgJZ3vw4XzjuDTn2MPMeBFr7B99CcszH8gMbbA/pGUmy3V714cVIvZ5YfUDIPTPtsNgV\n\t0uv1HhkQj6cv0EJSV9dg/w+iI5xRCLAJ7IbLCM619Gh0NOqXtDeF6YDbHnIXU7wV7qTq\n\tEZMSYEaLygcdRrePUQrRYTfjqzSPCDasdoVrHSxff6wJ3PM0gvt0mVtOecrQzCYJXBae\n\tgDow==",
        "X-Gm-Message-State": "ALoCoQn/oCansELEWA9gLab/ZZm3fEn2vuo+NVR9QFvvjrGmpwZhtpjDtowWMqXZETElKVO+EUeX",
        "X-Received": "by 10.194.235.193 with SMTP id uo1mr1149635wjc.105.1416524356088;\n\tThu, 20 Nov 2014 14:59:16 -0800 (PST)",
        "From": "Olivier Matz <olivier.matz@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Thu, 20 Nov 2014 23:58:53 +0100",
        "Message-Id": "<1416524335-22753-12-git-send-email-olivier.matz@6wind.com>",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1416524335-22753-1-git-send-email-olivier.matz@6wind.com>",
        "References": "<1415984609-2484-1-git-send-email-olivier.matz@6wind.com>\n\t<1416524335-22753-1-git-send-email-olivier.matz@6wind.com>",
        "Cc": "jigsaw@gmail.com",
        "Subject": "[dpdk-dev] [PATCH v3 11/13] ixgbe: support TCP segmentation offload",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Implement TSO (TCP segmentation offload) in ixgbe driver. The driver is\nnow able to use PKT_TX_TCP_SEG mbuf flag and mbuf hardware offload infos\n(l2_len, l3_len, l4_len, tso_segsz) to configure the hardware support of\nTCP segmentation.\n\nIn ixgbe, when doing TSO, the IP length must not be included in the TCP\npseudo header checksum. A new function ixgbe_fix_tcp_phdr_cksum() is\nused to fix the pseudo header checksum of the packet before giving it to\nthe hardware.\n\nIn the patch, the tx_desc_cksum_flags_to_olinfo() and\ntx_desc_ol_flags_to_cmdtype() functions have been reworked to make them\nclearer. This should not impact performance as gcc (version 4.8 in my\ncase) is smart enough to convert the tests into a code that does not\ncontain any branch instruction.\n\nSigned-off-by: Olivier Matz <olivier.matz@6wind.com>\nAcked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>\n---\n lib/librte_pmd_ixgbe/ixgbe_ethdev.c |   3 +-\n lib/librte_pmd_ixgbe/ixgbe_rxtx.c   | 170 ++++++++++++++++++++++--------------\n lib/librte_pmd_ixgbe/ixgbe_rxtx.h   |  19 ++--\n 3 files changed, 118 insertions(+), 74 deletions(-)",
    "diff": "diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\nindex 2eb609c..2c2ecc0 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n@@ -1964,7 +1964,8 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \t\tDEV_TX_OFFLOAD_IPV4_CKSUM  |\n \t\tDEV_TX_OFFLOAD_UDP_CKSUM   |\n \t\tDEV_TX_OFFLOAD_TCP_CKSUM   |\n-\t\tDEV_TX_OFFLOAD_SCTP_CKSUM;\n+\t\tDEV_TX_OFFLOAD_SCTP_CKSUM  |\n+\t\tDEV_TX_OFFLOAD_TCP_TSO;\n \n \tdev_info->default_rxconf = (struct rte_eth_rxconf) {\n \t\t\t.rx_thresh = {\ndiff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c\nindex 2df3385..63216fa 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c\n+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c\n@@ -2,6 +2,7 @@\n  *   BSD LICENSE\n  *\n  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+ *   Copyright 2014 6WIND S.A.\n  *   All rights reserved.\n  *\n  *   Redistribution and use in source and binary forms, with or without\n@@ -94,7 +95,8 @@\n #define IXGBE_TX_OFFLOAD_MASK (\t\t\t \\\n \t\tPKT_TX_VLAN_PKT |\t\t \\\n \t\tPKT_TX_IP_CKSUM |\t\t \\\n-\t\tPKT_TX_L4_MASK)\n+\t\tPKT_TX_L4_MASK |\t\t \\\n+\t\tPKT_TX_TCP_SEG)\n \n static inline struct rte_mbuf *\n rte_rxmbuf_alloc(struct rte_mempool *mp)\n@@ -363,59 +365,84 @@ ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,\n static inline void\n ixgbe_set_xmit_ctx(struct igb_tx_queue* txq,\n \t\tvolatile struct ixgbe_adv_tx_context_desc *ctx_txd,\n-\t\tuint64_t ol_flags, uint32_t vlan_macip_lens)\n+\t\tuint64_t ol_flags, union ixgbe_tx_offload tx_offload)\n {\n \tuint32_t type_tucmd_mlhl;\n-\tuint32_t mss_l4len_idx;\n+\tuint32_t mss_l4len_idx = 0;\n \tuint32_t ctx_idx;\n-\tuint32_t cmp_mask;\n+\tuint32_t vlan_macip_lens;\n+\tunion ixgbe_tx_offload tx_offload_mask;\n \n \tctx_idx = txq->ctx_curr;\n-\tcmp_mask = 0;\n+\ttx_offload_mask.data = 0;\n \ttype_tucmd_mlhl = 0;\n \n+\t/* Specify which HW CTX to upload. */\n+\tmss_l4len_idx |= (ctx_idx << IXGBE_ADVTXD_IDX_SHIFT);\n+\n \tif (ol_flags & PKT_TX_VLAN_PKT) {\n-\t\tcmp_mask |= TX_VLAN_CMP_MASK;\n+\t\ttx_offload_mask.vlan_tci = ~0;\n \t}\n \n-\tif (ol_flags & PKT_TX_IP_CKSUM) {\n-\t\ttype_tucmd_mlhl = IXGBE_ADVTXD_TUCMD_IPV4;\n-\t\tcmp_mask |= TX_MACIP_LEN_CMP_MASK;\n-\t}\n+\t/* check if TCP segmentation required for this packet */\n+\tif (ol_flags & PKT_TX_TCP_SEG) {\n+\t\t/* implies IP cksum and TCP cksum */\n+\t\ttype_tucmd_mlhl = IXGBE_ADVTXD_TUCMD_IPV4 |\n+\t\t\tIXGBE_ADVTXD_TUCMD_L4T_TCP |\n+\t\t\tIXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;\n+\n+\t\ttx_offload_mask.l2_len = ~0;\n+\t\ttx_offload_mask.l3_len = ~0;\n+\t\ttx_offload_mask.l4_len = ~0;\n+\t\ttx_offload_mask.tso_segsz = ~0;\n+\t\tmss_l4len_idx |= tx_offload.tso_segsz << IXGBE_ADVTXD_MSS_SHIFT;\n+\t\tmss_l4len_idx |= tx_offload.l4_len << IXGBE_ADVTXD_L4LEN_SHIFT;\n+\t} else { /* no TSO, check if hardware checksum is needed */\n+\t\tif (ol_flags & PKT_TX_IP_CKSUM) {\n+\t\t\ttype_tucmd_mlhl = IXGBE_ADVTXD_TUCMD_IPV4;\n+\t\t\ttx_offload_mask.l2_len = ~0;\n+\t\t\ttx_offload_mask.l3_len = ~0;\n+\t\t}\n \n-\t/* Specify which HW CTX to upload. */\n-\tmss_l4len_idx = (ctx_idx << IXGBE_ADVTXD_IDX_SHIFT);\n-\tswitch (ol_flags & PKT_TX_L4_MASK) {\n-\tcase PKT_TX_UDP_CKSUM:\n-\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP |\n+\t\tswitch (ol_flags & PKT_TX_L4_MASK) {\n+\t\tcase PKT_TX_UDP_CKSUM:\n+\t\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP |\n \t\t\t\tIXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;\n-\t\tmss_l4len_idx |= sizeof(struct udp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;\n-\t\tcmp_mask |= TX_MACIP_LEN_CMP_MASK;\n-\t\tbreak;\n-\tcase PKT_TX_TCP_CKSUM:\n-\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP |\n+\t\t\tmss_l4len_idx |= sizeof(struct udp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;\n+\t\t\ttx_offload_mask.l2_len = ~0;\n+\t\t\ttx_offload_mask.l3_len = ~0;\n+\t\t\tbreak;\n+\t\tcase PKT_TX_TCP_CKSUM:\n+\t\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP |\n \t\t\t\tIXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;\n-\t\tmss_l4len_idx |= sizeof(struct tcp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;\n-\t\tcmp_mask |= TX_MACIP_LEN_CMP_MASK;\n-\t\tbreak;\n-\tcase PKT_TX_SCTP_CKSUM:\n-\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP |\n+\t\t\tmss_l4len_idx |= sizeof(struct tcp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;\n+\t\t\ttx_offload_mask.l2_len = ~0;\n+\t\t\ttx_offload_mask.l3_len = ~0;\n+\t\t\ttx_offload_mask.l4_len = ~0;\n+\t\t\tbreak;\n+\t\tcase PKT_TX_SCTP_CKSUM:\n+\t\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP |\n \t\t\t\tIXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;\n-\t\tmss_l4len_idx |= sizeof(struct sctp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;\n-\t\tcmp_mask |= TX_MACIP_LEN_CMP_MASK;\n-\t\tbreak;\n-\tdefault:\n-\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_RSV |\n+\t\t\tmss_l4len_idx |= sizeof(struct sctp_hdr) << IXGBE_ADVTXD_L4LEN_SHIFT;\n+\t\t\ttx_offload_mask.l2_len = ~0;\n+\t\t\ttx_offload_mask.l3_len = ~0;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\ttype_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_RSV |\n \t\t\t\tIXGBE_ADVTXD_DTYP_CTXT | IXGBE_ADVTXD_DCMD_DEXT;\n-\t\tbreak;\n+\t\t\tbreak;\n+\t\t}\n \t}\n \n \ttxq->ctx_cache[ctx_idx].flags = ol_flags;\n-\ttxq->ctx_cache[ctx_idx].cmp_mask = cmp_mask;\n-\ttxq->ctx_cache[ctx_idx].vlan_macip_lens.data =\n-\t\tvlan_macip_lens & cmp_mask;\n+\ttxq->ctx_cache[ctx_idx].tx_offload.data  =\n+\t\ttx_offload_mask.data & tx_offload.data;\n+\ttxq->ctx_cache[ctx_idx].tx_offload_mask    = tx_offload_mask;\n \n \tctx_txd->type_tucmd_mlhl = rte_cpu_to_le_32(type_tucmd_mlhl);\n+\tvlan_macip_lens = tx_offload.l3_len;\n+\tvlan_macip_lens |= (tx_offload.l2_len << IXGBE_ADVTXD_MACLEN_SHIFT);\n+\tvlan_macip_lens |= ((uint32_t)tx_offload.vlan_tci << IXGBE_ADVTXD_VLAN_SHIFT);\n \tctx_txd->vlan_macip_lens = rte_cpu_to_le_32(vlan_macip_lens);\n \tctx_txd->mss_l4len_idx   = rte_cpu_to_le_32(mss_l4len_idx);\n \tctx_txd->seqnum_seed     = 0;\n@@ -427,20 +454,20 @@ ixgbe_set_xmit_ctx(struct igb_tx_queue* txq,\n  */\n static inline uint32_t\n what_advctx_update(struct igb_tx_queue *txq, uint64_t flags,\n-\t\tuint32_t vlan_macip_lens)\n+\t\tunion ixgbe_tx_offload tx_offload)\n {\n \t/* If match with the current used context */\n \tif (likely((txq->ctx_cache[txq->ctx_curr].flags == flags) &&\n-\t\t(txq->ctx_cache[txq->ctx_curr].vlan_macip_lens.data ==\n-\t\t(txq->ctx_cache[txq->ctx_curr].cmp_mask & vlan_macip_lens)))) {\n+\t\t(txq->ctx_cache[txq->ctx_curr].tx_offload.data ==\n+\t\t(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)))) {\n \t\t\treturn txq->ctx_curr;\n \t}\n \n \t/* What if match with the next context  */\n \ttxq->ctx_curr ^= 1;\n \tif (likely((txq->ctx_cache[txq->ctx_curr].flags == flags) &&\n-\t\t(txq->ctx_cache[txq->ctx_curr].vlan_macip_lens.data ==\n-\t\t(txq->ctx_cache[txq->ctx_curr].cmp_mask & vlan_macip_lens)))) {\n+\t\t(txq->ctx_cache[txq->ctx_curr].tx_offload.data ==\n+\t\t(txq->ctx_cache[txq->ctx_curr].tx_offload_mask.data & tx_offload.data)))) {\n \t\t\treturn txq->ctx_curr;\n \t}\n \n@@ -451,20 +478,25 @@ what_advctx_update(struct igb_tx_queue *txq, uint64_t flags,\n static inline uint32_t\n tx_desc_cksum_flags_to_olinfo(uint64_t ol_flags)\n {\n-\tstatic const uint32_t l4_olinfo[2] = {0, IXGBE_ADVTXD_POPTS_TXSM};\n-\tstatic const uint32_t l3_olinfo[2] = {0, IXGBE_ADVTXD_POPTS_IXSM};\n-\tuint32_t tmp;\n-\n-\ttmp  = l4_olinfo[(ol_flags & PKT_TX_L4_MASK)  != PKT_TX_L4_NO_CKSUM];\n-\ttmp |= l3_olinfo[(ol_flags & PKT_TX_IP_CKSUM) != 0];\n+\tuint32_t tmp = 0;\n+\tif ((ol_flags & PKT_TX_L4_MASK) != PKT_TX_L4_NO_CKSUM)\n+\t\ttmp |= IXGBE_ADVTXD_POPTS_TXSM;\n+\tif (ol_flags & PKT_TX_IP_CKSUM)\n+\t\ttmp |= IXGBE_ADVTXD_POPTS_IXSM;\n+\tif (ol_flags & PKT_TX_TCP_SEG)\n+\t\ttmp |= IXGBE_ADVTXD_POPTS_TXSM;\n \treturn tmp;\n }\n \n static inline uint32_t\n-tx_desc_vlan_flags_to_cmdtype(uint64_t ol_flags)\n+tx_desc_ol_flags_to_cmdtype(uint64_t ol_flags)\n {\n-\tstatic const uint32_t vlan_cmd[2] = {0, IXGBE_ADVTXD_DCMD_VLE};\n-\treturn vlan_cmd[(ol_flags & PKT_TX_VLAN_PKT) != 0];\n+\tuint32_t cmdtype = 0;\n+\tif (ol_flags & PKT_TX_VLAN_PKT)\n+\t\tcmdtype |= IXGBE_ADVTXD_DCMD_VLE;\n+\tif (ol_flags & PKT_TX_TCP_SEG)\n+\t\tcmdtype |= IXGBE_ADVTXD_DCMD_TSE;\n+\treturn cmdtype;\n }\n \n /* Default RS bit threshold values */\n@@ -545,14 +577,6 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \tvolatile union ixgbe_adv_tx_desc *txd;\n \tstruct rte_mbuf     *tx_pkt;\n \tstruct rte_mbuf     *m_seg;\n-\tunion ixgbe_vlan_macip vlan_macip_lens;\n-\tunion {\n-\t\tuint16_t u16;\n-\t\tstruct {\n-\t\t\tuint16_t l3_len:9;\n-\t\t\tuint16_t l2_len:7;\n-\t\t};\n-\t} l2_l3_len;\n \tuint64_t buf_dma_addr;\n \tuint32_t olinfo_status;\n \tuint32_t cmd_type_len;\n@@ -566,6 +590,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \tuint64_t tx_ol_req;\n \tuint32_t ctx = 0;\n \tuint32_t new_ctx;\n+\tunion ixgbe_tx_offload tx_offload = { .data = 0 };\n \n \ttxq = tx_queue;\n \tsw_ring = txq->sw_ring;\n@@ -595,14 +620,15 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t/* If hardware offload required */\n \t\ttx_ol_req = ol_flags & IXGBE_TX_OFFLOAD_MASK;\n \t\tif (tx_ol_req) {\n-\t\t\tl2_l3_len.l2_len = tx_pkt->l2_len;\n-\t\t\tl2_l3_len.l3_len = tx_pkt->l3_len;\n-\t\t\tvlan_macip_lens.f.vlan_tci = tx_pkt->vlan_tci;\n-\t\t\tvlan_macip_lens.f.l2_l3_len = l2_l3_len.u16;\n+\t\t\ttx_offload.l2_len = tx_pkt->l2_len;\n+\t\t\ttx_offload.l3_len = tx_pkt->l3_len;\n+\t\t\ttx_offload.l4_len = tx_pkt->l4_len;\n+\t\t\ttx_offload.vlan_tci = tx_pkt->vlan_tci;\n+\t\t\ttx_offload.tso_segsz = tx_pkt->tso_segsz;\n \n \t\t\t/* If new context need be built or reuse the exist ctx. */\n \t\t\tctx = what_advctx_update(txq, tx_ol_req,\n-\t\t\t\tvlan_macip_lens.data);\n+\t\t\t\ttx_offload);\n \t\t\t/* Only allocate context descriptor if required*/\n \t\t\tnew_ctx = (ctx == IXGBE_CTX_NUM);\n \t\t\tctx = txq->ctx_curr;\n@@ -717,13 +743,22 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t */\n \t\tcmd_type_len = IXGBE_ADVTXD_DTYP_DATA |\n \t\t\tIXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT;\n-\t\tolinfo_status = (pkt_len << IXGBE_ADVTXD_PAYLEN_SHIFT);\n+\n #ifdef RTE_LIBRTE_IEEE1588\n \t\tif (ol_flags & PKT_TX_IEEE1588_TMST)\n \t\t\tcmd_type_len |= IXGBE_ADVTXD_MAC_1588;\n #endif\n \n+\t\tolinfo_status = 0;\n \t\tif (tx_ol_req) {\n+\n+\t\t\tif (ol_flags & PKT_TX_TCP_SEG) {\n+\t\t\t\t/* when TSO is on, paylen in descriptor is the\n+\t\t\t\t * not the packet len but the tcp payload len */\n+\t\t\t\tpkt_len -= (tx_offload.l2_len +\n+\t\t\t\t\ttx_offload.l3_len + tx_offload.l4_len);\n+\t\t\t}\n+\n \t\t\t/*\n \t\t\t * Setup the TX Advanced Context Descriptor if required\n \t\t\t */\n@@ -744,7 +779,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\t\t}\n \n \t\t\t\tixgbe_set_xmit_ctx(txq, ctx_txd, tx_ol_req,\n-\t\t\t\t    vlan_macip_lens.data);\n+\t\t\t\t\ttx_offload);\n \n \t\t\t\ttxe->last_id = tx_last;\n \t\t\t\ttx_id = txe->next_id;\n@@ -756,11 +791,13 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\t * This path will go through\n \t\t\t * whatever new/reuse the context descriptor\n \t\t\t */\n-\t\t\tcmd_type_len  |= tx_desc_vlan_flags_to_cmdtype(ol_flags);\n+\t\t\tcmd_type_len  |= tx_desc_ol_flags_to_cmdtype(ol_flags);\n \t\t\tolinfo_status |= tx_desc_cksum_flags_to_olinfo(ol_flags);\n \t\t\tolinfo_status |= ctx << IXGBE_ADVTXD_IDX_SHIFT;\n \t\t}\n \n+\t\tolinfo_status |= (pkt_len << IXGBE_ADVTXD_PAYLEN_SHIFT);\n+\n \t\tm_seg = tx_pkt;\n \t\tdo {\n \t\t\ttxd = &txr[tx_id];\n@@ -3611,9 +3648,10 @@ ixgbe_dev_tx_init(struct rte_eth_dev *dev)\n \tPMD_INIT_FUNC_TRACE();\n \thw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n-\t/* Enable TX CRC (checksum offload requirement) */\n+\t/* Enable TX CRC (checksum offload requirement) and hw padding\n+\t * (TSO requirement) */\n \thlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);\n-\thlreg0 |= IXGBE_HLREG0_TXCRCEN;\n+\thlreg0 |= (IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_TXPADEN);\n \tIXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);\n \n \t/* Setup the Base and Length of the Tx Descriptor Rings */\ndiff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.h b/lib/librte_pmd_ixgbe/ixgbe_rxtx.h\nindex eb89715..13099af 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.h\n+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.h\n@@ -145,13 +145,16 @@ enum ixgbe_advctx_num {\n };\n \n /** Offload features */\n-union ixgbe_vlan_macip {\n-\tuint32_t data;\n+union ixgbe_tx_offload {\n+\tuint64_t data;\n \tstruct {\n-\t\tuint16_t l2_l3_len; /**< combined 9-bit l3, 7-bit l2 lengths */\n-\t\tuint16_t vlan_tci;\n+\t\tuint64_t l2_len:7; /**< L2 (MAC) Header Length. */\n+\t\tuint64_t l3_len:9; /**< L3 (IP) Header Length. */\n+\t\tuint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */\n+\t\tuint64_t tso_segsz:16; /**< TCP TSO segment size */\n+\t\tuint64_t vlan_tci:16;\n \t\t/**< VLAN Tag Control Identifier (CPU order). */\n-\t} f;\n+\t};\n };\n \n /*\n@@ -170,8 +173,10 @@ union ixgbe_vlan_macip {\n \n struct ixgbe_advctx_info {\n \tuint64_t flags;           /**< ol_flags for context build. */\n-\tuint32_t cmp_mask;        /**< compare mask for vlan_macip_lens */\n-\tunion ixgbe_vlan_macip vlan_macip_lens; /**< vlan, mac ip length. */\n+\t/**< tx offload: vlan, tso, l2-l3-l4 lengths. */\n+\tunion ixgbe_tx_offload tx_offload;\n+\t/** compare mask for tx offload. */\n+\tunion ixgbe_tx_offload tx_offload_mask;\n };\n \n /**\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "11/13"
    ]
}