get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 66399,
    "url": "http://patches.dpdk.org/api/patches/66399/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200309093243.63204-2-huwei013@chinasoftinc.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<20200309093243.63204-2-huwei013@chinasoftinc.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200309093243.63204-2-huwei013@chinasoftinc.com",
    "date": "2020-03-09T09:32:39",
    "name": "[v2,1/5] net/hns3: support TCP segment offload",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "61faaecd8bb63ca0f392c32d31b3f028e17f9a2d",
    "submitter": {
        "id": 1537,
        "url": "http://patches.dpdk.org/api/people/1537/?format=api",
        "name": "Wei Hu (Xavier)",
        "email": "huwei013@chinasoftinc.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200309093243.63204-2-huwei013@chinasoftinc.com/mbox/",
    "series": [
        {
            "id": 8836,
            "url": "http://patches.dpdk.org/api/series/8836/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8836",
            "date": "2020-03-09T09:32:39",
            "name": "misc updates and fixes for hns3 PMD driver",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/8836/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/66399/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/66399/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id CA90DA052E;\n\tMon,  9 Mar 2020 10:33:23 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id E3F751C00F;\n\tMon,  9 Mar 2020 10:33:22 +0100 (CET)",
            "from incedge.chinasoftinc.com (unknown [114.113.233.8])\n by dpdk.org (Postfix) with ESMTP id D74BC1C00E\n for <dev@dpdk.org>; Mon,  9 Mar 2020 10:33:20 +0100 (CET)",
            "from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by\n incedge.chinasoftinc.com with ESMTP id yWwzi5GXcCIk9btP (version=TLSv1\n cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for <dev@dpdk.org>;\n Mon, 09 Mar 2020 17:32:49 +0800 (CST)",
            "from localhost.localdomain (114.119.4.74) by INCCAS001.ito.icss\n (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Mon, 9 Mar 2020\n 17:32:48 +0800"
        ],
        "X-ASG-Debug-ID": "1583746368-0a3dd1404a03530002-TfluYd",
        "X-Barracuda-Envelope-From": "huwei013@chinasoftinc.com",
        "X-Barracuda-RBL-Trusted-Forwarder": [
            "10.168.0.51",
            "10.168.0.60"
        ],
        "X-ASG-Whitelist": "Client",
        "From": "\"Wei Hu (Xavier)\" <huwei013@chinasoftinc.com>",
        "To": "<dev@dpdk.org>",
        "Date": "Mon, 9 Mar 2020 17:32:39 +0800",
        "X-ASG-Orig-Subj": "[PATCH v2 1/5] net/hns3: support TCP segment offload",
        "Message-ID": "<20200309093243.63204-2-huwei013@chinasoftinc.com>",
        "X-Mailer": "git-send-email 2.23.0",
        "In-Reply-To": "<20200309093243.63204-1-huwei013@chinasoftinc.com>",
        "References": "<20200309093243.63204-1-huwei013@chinasoftinc.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[114.119.4.74]",
        "X-Barracuda-Connect": "inccas001.ito.icss[10.168.0.51]",
        "X-Barracuda-Start-Time": "1583746368",
        "X-Barracuda-Encrypted": "ECDHE-RSA-AES256-SHA",
        "X-Barracuda-URL": "https://incspam.chinasofti.com:443/cgi-mod/mark.cgi",
        "X-Virus-Scanned": "by bsmtpd at chinasoftinc.com",
        "X-Barracuda-Scan-Msg-Size": "13856",
        "Subject": "[dpdk-dev] [PATCH v2 1/5] net/hns3: support TCP segment offload",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Hongbo Zheng <zhenghongbo3@huawei.com>\n\nThis patch adds TCP segment offload support for hns3 PMD driver.\n\nSigned-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>\nSigned-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>\n---\n doc/guides/nics/features/hns3.ini    |   1 +\n doc/guides/nics/features/hns3_vf.ini |   1 +\n doc/guides/nics/hns3.rst             |   1 +\n drivers/net/hns3/hns3_ethdev.c       |   4 +\n drivers/net/hns3/hns3_ethdev.h       |   6 +-\n drivers/net/hns3/hns3_ethdev_vf.c    |   4 +\n drivers/net/hns3/hns3_rxtx.c         | 258 +++++++++++++++++++++++++--\n 7 files changed, 259 insertions(+), 16 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini\nindex cd5c08a9d..c3a8544bc 100644\n--- a/doc/guides/nics/features/hns3.ini\n+++ b/doc/guides/nics/features/hns3.ini\n@@ -8,6 +8,7 @@ Link status          = Y\n Rx interrupt         = Y\n MTU update           = Y\n Jumbo frame          = Y\n+TSO                  = Y\n Promiscuous mode     = Y\n Allmulticast mode    = Y\n Unicast MAC filter   = Y\ndiff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini\nindex fd00ac3e2..e4e77380f 100644\n--- a/doc/guides/nics/features/hns3_vf.ini\n+++ b/doc/guides/nics/features/hns3_vf.ini\n@@ -8,6 +8,7 @@ Link status          = Y\n Rx interrupt         = Y\n MTU update           = Y\n Jumbo frame          = Y\n+TSO                  = Y\n Unicast MAC filter   = Y\n Multicast MAC filter = Y\n RSS hash             = Y\ndiff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst\nindex 8d19f4851..05dbe4174 100644\n--- a/doc/guides/nics/hns3.rst\n+++ b/doc/guides/nics/hns3.rst\n@@ -17,6 +17,7 @@ Features of the HNS3 PMD are:\n - Receive Side Scaling (RSS)\n - Packet type information\n - Checksum offload\n+- TSO offload\n - Promiscuous mode\n - Multicast mode\n - Port hardware statistics\ndiff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c\nindex 918fbe076..d4751d478 100644\n--- a/drivers/net/hns3/hns3_ethdev.c\n+++ b/drivers/net/hns3/hns3_ethdev.c\n@@ -2256,6 +2256,10 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)\n \t\t\t\t DEV_TX_OFFLOAD_VLAN_INSERT |\n \t\t\t\t DEV_TX_OFFLOAD_QINQ_INSERT |\n \t\t\t\t DEV_TX_OFFLOAD_MULTI_SEGS |\n+\t\t\t\t DEV_TX_OFFLOAD_TCP_TSO |\n+\t\t\t\t DEV_TX_OFFLOAD_VXLAN_TNL_TSO |\n+\t\t\t\t DEV_TX_OFFLOAD_GRE_TNL_TSO |\n+\t\t\t\t DEV_TX_OFFLOAD_GENEVE_TNL_TSO |\n \t\t\t\t info->tx_queue_offload_capa);\n \n \tinfo->rx_desc_lim = (struct rte_eth_desc_lim) {\ndiff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h\nindex d4a03065f..c7625119a 100644\n--- a/drivers/net/hns3/hns3_ethdev.h\n+++ b/drivers/net/hns3/hns3_ethdev.h\n@@ -31,10 +31,14 @@\n #define HNS3_MC_MACADDR_NUM\t\t128\n \n #define HNS3_MAX_BD_SIZE\t\t65535\n-#define HNS3_MAX_TX_BD_PER_PKT\t\t8\n+#define HNS3_MAX_NON_TSO_BD_PER_PKT\t8\n+#define HNS3_MAX_TSO_BD_PER_PKT\t\t63\n #define HNS3_MAX_FRAME_LEN\t\t9728\n #define HNS3_VLAN_TAG_SIZE\t\t4\n #define HNS3_DEFAULT_RX_BUF_LEN\t\t2048\n+#define HNS3_MAX_BD_PAYLEN\t\t(1024 * 1024 - 1)\n+#define HNS3_MAX_TSO_HDR_SIZE\t\t512\n+#define HNS3_MAX_TSO_HDR_BD_NUM\t\t3\n \n #define HNS3_ETH_OVERHEAD \\\n \t(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + HNS3_VLAN_TAG_SIZE * 2)\ndiff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c\nindex 505525eba..7b776ad13 100644\n--- a/drivers/net/hns3/hns3_ethdev_vf.c\n+++ b/drivers/net/hns3/hns3_ethdev_vf.c\n@@ -592,6 +592,10 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)\n \t\t\t\t DEV_TX_OFFLOAD_VLAN_INSERT |\n \t\t\t\t DEV_TX_OFFLOAD_QINQ_INSERT |\n \t\t\t\t DEV_TX_OFFLOAD_MULTI_SEGS |\n+\t\t\t\t DEV_TX_OFFLOAD_TCP_TSO |\n+\t\t\t\t DEV_TX_OFFLOAD_VXLAN_TNL_TSO |\n+\t\t\t\t DEV_TX_OFFLOAD_GRE_TNL_TSO |\n+\t\t\t\t DEV_TX_OFFLOAD_GENEVE_TNL_TSO |\n \t\t\t\t info->tx_queue_offload_capa);\n \n \tinfo->rx_desc_lim = (struct rte_eth_desc_lim) {\ndiff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c\nindex 03ebda658..aaccf7ef2 100644\n--- a/drivers/net/hns3/hns3_rxtx.c\n+++ b/drivers/net/hns3/hns3_rxtx.c\n@@ -1704,6 +1704,78 @@ hns3_tx_free_useless_buffer(struct hns3_tx_queue *txq)\n \ttxq->tx_bd_ready   = tx_bd_ready;\n }\n \n+static int\n+hns3_tso_proc_tunnel(struct hns3_desc *desc, uint64_t ol_flags,\n+\t\t     struct rte_mbuf *rxm, uint8_t *l2_len)\n+{\n+\tuint64_t tun_flags;\n+\tuint8_t ol4_len;\n+\tuint32_t otmp;\n+\n+\ttun_flags = ol_flags & PKT_TX_TUNNEL_MASK;\n+\tif (tun_flags == 0)\n+\t\treturn 0;\n+\n+\totmp = rte_le_to_cpu_32(desc->tx.ol_type_vlan_len_msec);\n+\tswitch (tun_flags) {\n+\tcase PKT_TX_TUNNEL_GENEVE:\n+\tcase PKT_TX_TUNNEL_VXLAN:\n+\t\t*l2_len = rxm->l2_len - RTE_ETHER_VXLAN_HLEN;\n+\t\tbreak;\n+\tcase PKT_TX_TUNNEL_GRE:\n+\t\t/*\n+\t\t * OL4 header size, defined in 4 Bytes, it contains outer\n+\t\t * L4(GRE) length and tunneling length.\n+\t\t */\n+\t\tol4_len = hns3_get_field(otmp, HNS3_TXD_L4LEN_M,\n+\t\t\t\t\t HNS3_TXD_L4LEN_S);\n+\t\t*l2_len = rxm->l2_len - (ol4_len << HNS3_L4_LEN_UNIT);\n+\t\tbreak;\n+\tdefault:\n+\t\t/* For non UDP / GRE tunneling, drop the tunnel packet */\n+\t\treturn -EINVAL;\n+\t}\n+\thns3_set_field(otmp, HNS3_TXD_L2LEN_M, HNS3_TXD_L2LEN_S,\n+\t\t       rxm->outer_l2_len >> HNS3_L2_LEN_UNIT);\n+\tdesc->tx.ol_type_vlan_len_msec = rte_cpu_to_le_32(otmp);\n+\n+\treturn 0;\n+}\n+\n+static void\n+hns3_set_tso(struct hns3_desc *desc,\n+\t     uint64_t ol_flags, struct rte_mbuf *rxm)\n+{\n+\tuint32_t paylen, hdr_len;\n+\tuint32_t tmp;\n+\tuint8_t l2_len = rxm->l2_len;\n+\n+\tif (!(ol_flags & PKT_TX_TCP_SEG))\n+\t\treturn;\n+\n+\tif (hns3_tso_proc_tunnel(desc, ol_flags, rxm, &l2_len))\n+\t\treturn;\n+\n+\thdr_len = rxm->l2_len + rxm->l3_len + rxm->l4_len;\n+\thdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?\n+\t\t    rxm->outer_l2_len + rxm->outer_l3_len : 0;\n+\tpaylen = rxm->pkt_len - hdr_len;\n+\tif (paylen <= rxm->tso_segsz)\n+\t\treturn;\n+\n+\ttmp = rte_le_to_cpu_32(desc->tx.type_cs_vlan_tso_len);\n+\thns3_set_bit(tmp, HNS3_TXD_TSO_B, 1);\n+\thns3_set_bit(tmp, HNS3_TXD_L3CS_B, 1);\n+\thns3_set_field(tmp, HNS3_TXD_L4T_M, HNS3_TXD_L4T_S, HNS3_L4T_TCP);\n+\thns3_set_bit(tmp, HNS3_TXD_L4CS_B, 1);\n+\thns3_set_field(tmp, HNS3_TXD_L4LEN_M, HNS3_TXD_L4LEN_S,\n+\t\t       sizeof(struct rte_tcp_hdr) >> HNS3_L4_LEN_UNIT);\n+\thns3_set_field(tmp, HNS3_TXD_L2LEN_M, HNS3_TXD_L2LEN_S,\n+\t\t       l2_len >> HNS3_L2_LEN_UNIT);\n+\tdesc->tx.type_cs_vlan_tso_len = rte_cpu_to_le_32(tmp);\n+\tdesc->tx.mss = rte_cpu_to_le_16(rxm->tso_segsz);\n+}\n+\n static void\n fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,\n \t  bool first, int offset)\n@@ -1711,9 +1783,9 @@ fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,\n \tstruct hns3_desc *tx_ring = txq->tx_ring;\n \tstruct hns3_desc *desc = &tx_ring[tx_desc_id];\n \tuint8_t frag_end = rxm->next == NULL ? 1 : 0;\n+\tuint64_t ol_flags = rxm->ol_flags;\n \tuint16_t size = rxm->data_len;\n \tuint16_t rrcfv = 0;\n-\tuint64_t ol_flags = rxm->ol_flags;\n \tuint32_t hdr_len;\n \tuint32_t paylen;\n \tuint32_t tmp;\n@@ -1728,6 +1800,7 @@ fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,\n \t\t\t   rxm->outer_l2_len + rxm->outer_l3_len : 0;\n \t\tpaylen = rxm->pkt_len - hdr_len;\n \t\tdesc->tx.paylen = rte_cpu_to_le_32(paylen);\n+\t\thns3_set_tso(desc, ol_flags, rxm);\n \t}\n \n \thns3_set_bit(rrcfv, HNS3_TXD_FE_B, frag_end);\n@@ -2041,6 +2114,136 @@ hns3_txd_enable_checksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,\n \tdesc->tx.type_cs_vlan_tso_len |= rte_cpu_to_le_32(value);\n }\n \n+static bool\n+hns3_pkt_need_linearized(struct rte_mbuf *tx_pkts, uint32_t bd_num)\n+{\n+\tstruct rte_mbuf *m_first = tx_pkts;\n+\tstruct rte_mbuf *m_last = tx_pkts;\n+\tuint32_t tot_len = 0;\n+\tuint32_t hdr_len;\n+\tuint32_t i;\n+\n+\t/*\n+\t * Hardware requires that the sum of the data length of every 8\n+\t * consecutive buffers is greater than MSS in hns3 network engine.\n+\t * We simplify it by ensuring pkt_headlen + the first 8 consecutive\n+\t * frags greater than gso header len + mss, and the remaining 7\n+\t * consecutive frags greater than MSS except the last 7 frags.\n+\t */\n+\tif (bd_num <= HNS3_MAX_NON_TSO_BD_PER_PKT)\n+\t\treturn false;\n+\n+\tfor (i = 0; m_last && i < HNS3_MAX_NON_TSO_BD_PER_PKT - 1;\n+\t     i++, m_last = m_last->next)\n+\t\ttot_len += m_last->data_len;\n+\n+\tif (!m_last)\n+\t\treturn true;\n+\n+\t/* ensure the first 8 frags is greater than mss + header */\n+\thdr_len = tx_pkts->l2_len + tx_pkts->l3_len + tx_pkts->l4_len;\n+\thdr_len += (tx_pkts->ol_flags & PKT_TX_TUNNEL_MASK) ?\n+\t\t   tx_pkts->outer_l2_len + tx_pkts->outer_l3_len : 0;\n+\tif (tot_len + m_last->data_len < tx_pkts->tso_segsz + hdr_len)\n+\t\treturn true;\n+\n+\t/*\n+\t * ensure the sum of the data length of every 7 consecutive buffer\n+\t * is greater than mss except the last one.\n+\t */\n+\tfor (i = 0; m_last && i < bd_num - HNS3_MAX_NON_TSO_BD_PER_PKT; i++) {\n+\t\ttot_len -= m_first->data_len;\n+\t\ttot_len += m_last->data_len;\n+\n+\t\tif (tot_len < tx_pkts->tso_segsz)\n+\t\t\treturn true;\n+\n+\t\tm_first = m_first->next;\n+\t\tm_last = m_last->next;\n+\t}\n+\n+\treturn false;\n+}\n+\n+static void\n+hns3_outer_header_cksum_prepare(struct rte_mbuf *m)\n+{\n+\tuint64_t ol_flags = m->ol_flags;\n+\tstruct rte_ipv4_hdr *ipv4_hdr;\n+\tstruct rte_udp_hdr *udp_hdr;\n+\tuint32_t paylen, hdr_len;\n+\n+\tif (!(ol_flags & (PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IPV6)))\n+\t\treturn;\n+\n+\tif (ol_flags & PKT_TX_IPV4) {\n+\t\tipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,\n+\t\t\t\t\t\t   m->outer_l2_len);\n+\n+\t\tif (ol_flags & PKT_TX_IP_CKSUM)\n+\t\t\tipv4_hdr->hdr_checksum = 0;\n+\t}\n+\n+\tif ((ol_flags & PKT_TX_L4_MASK) == PKT_TX_UDP_CKSUM &&\n+\t    ol_flags & PKT_TX_TCP_SEG) {\n+\t\thdr_len = m->l2_len + m->l3_len + m->l4_len;\n+\t\thdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?\n+\t\t\t\tm->outer_l2_len + m->outer_l3_len : 0;\n+\t\tpaylen = m->pkt_len - hdr_len;\n+\t\tif (paylen <= m->tso_segsz)\n+\t\t\treturn;\n+\t\tudp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,\n+\t\t\t\t\t\t  m->outer_l2_len +\n+\t\t\t\t\t\t  m->outer_l3_len);\n+\t\tudp_hdr->dgram_cksum = 0;\n+\t}\n+}\n+\n+static inline bool\n+hns3_pkt_is_tso(struct rte_mbuf *m)\n+{\n+\treturn (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG);\n+}\n+\n+static int\n+hns3_check_tso_pkt_valid(struct rte_mbuf *m)\n+{\n+\tuint32_t tmp_data_len_sum = 0;\n+\tuint16_t nb_buf = m->nb_segs;\n+\tuint32_t paylen, hdr_len;\n+\tstruct rte_mbuf *m_seg;\n+\tint i;\n+\n+\tif (nb_buf > HNS3_MAX_TSO_BD_PER_PKT)\n+\t\treturn -EINVAL;\n+\n+\thdr_len = m->l2_len + m->l3_len + m->l4_len;\n+\thdr_len += (m->ol_flags & PKT_TX_TUNNEL_MASK) ?\n+\t\t\tm->outer_l2_len + m->outer_l3_len : 0;\n+\tif (hdr_len > HNS3_MAX_TSO_HDR_SIZE)\n+\t\treturn -EINVAL;\n+\n+\tpaylen = m->pkt_len - hdr_len;\n+\tif (paylen > HNS3_MAX_BD_PAYLEN)\n+\t\treturn -EINVAL;\n+\n+\t/*\n+\t * The TSO header (include outer and inner L2, L3 and L4 header)\n+\t * should be provided by three descriptors in maximum in hns3 network\n+\t * engine.\n+\t */\n+\tm_seg = m;\n+\tfor (i = 0; m_seg != NULL && i < HNS3_MAX_TSO_HDR_BD_NUM && i < nb_buf;\n+\t     i++, m_seg = m_seg->next) {\n+\t\ttmp_data_len_sum += m_seg->data_len;\n+\t}\n+\n+\tif (hdr_len > tmp_data_len_sum)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n uint16_t\n hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,\n \t       uint16_t nb_pkts)\n@@ -2058,6 +2261,13 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\treturn i;\n \t\t}\n \n+\t\tif (hns3_pkt_is_tso(m) &&\n+\t\t    (hns3_pkt_need_linearized(m, m->nb_segs) ||\n+\t\t     hns3_check_tso_pkt_valid(m))) {\n+\t\t\trte_errno = EINVAL;\n+\t\t\treturn i;\n+\t\t}\n+\n #ifdef RTE_LIBRTE_ETHDEV_DEBUG\n \t\tret = rte_validate_tx_offload(m);\n \t\tif (ret != 0) {\n@@ -2070,6 +2280,8 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\trte_errno = -ret;\n \t\t\treturn i;\n \t\t}\n+\n+\t\thns3_outer_header_cksum_prepare(m);\n \t}\n \n \treturn i;\n@@ -2093,13 +2305,39 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,\n \treturn 0;\n }\n \n+static int\n+hns3_check_non_tso_pkt(uint16_t nb_buf, struct rte_mbuf **m_seg,\n+\t\t      struct rte_mbuf *tx_pkt, struct hns3_tx_queue *txq)\n+{\n+\tstruct rte_mbuf *new_pkt;\n+\tint ret;\n+\n+\tif (hns3_pkt_is_tso(*m_seg))\n+\t\treturn 0;\n+\n+\t/*\n+\t * If packet length is greater than HNS3_MAX_FRAME_LEN\n+\t * driver support, the packet will be ignored.\n+\t */\n+\tif (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN))\n+\t\treturn -EINVAL;\n+\n+\tif (unlikely(nb_buf > HNS3_MAX_NON_TSO_BD_PER_PKT)) {\n+\t\tret = hns3_reassemble_tx_pkts(txq, tx_pkt, &new_pkt);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\t*m_seg = new_pkt;\n+\t}\n+\n+\treturn 0;\n+}\n+\n uint16_t\n hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n {\n \tstruct rte_net_hdr_lens hdr_lens = {0};\n \tstruct hns3_tx_queue *txq = tx_queue;\n \tstruct hns3_entry *tx_bak_pkt;\n-\tstruct rte_mbuf *new_pkt;\n \tstruct rte_mbuf *tx_pkt;\n \tstruct rte_mbuf *m_seg;\n \tuint32_t nb_hold = 0;\n@@ -2131,13 +2369,6 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n \t\t\tgoto end_of_tx;\n \t\t}\n \n-\t\t/*\n-\t\t * If packet length is greater than HNS3_MAX_FRAME_LEN\n-\t\t * driver support, the packet will be ignored.\n-\t\t */\n-\t\tif (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN))\n-\t\t\tbreak;\n-\n \t\t/*\n \t\t * If packet length is less than minimum packet size, driver\n \t\t * need to pad it.\n@@ -2156,12 +2387,9 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n \t\t}\n \n \t\tm_seg = tx_pkt;\n-\t\tif (unlikely(nb_buf > HNS3_MAX_TX_BD_PER_PKT)) {\n-\t\t\tif (hns3_reassemble_tx_pkts(txq, tx_pkt, &new_pkt))\n-\t\t\t\tgoto end_of_tx;\n-\t\t\tm_seg = new_pkt;\n-\t\t\tnb_buf = m_seg->nb_segs;\n-\t\t}\n+\n+\t\tif (hns3_check_non_tso_pkt(nb_buf, &m_seg, tx_pkt, txq))\n+\t\t\tgoto end_of_tx;\n \n \t\tif (hns3_parse_cksum(txq, tx_next_use, m_seg, &hdr_lens))\n \t\t\tgoto end_of_tx;\n",
    "prefixes": [
        "v2",
        "1/5"
    ]
}