get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 119343,
    "url": "https://patches.dpdk.org/api/patches/119343/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20221031083346.16558-4-beilei.xing@intel.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": "<20221031083346.16558-4-beilei.xing@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20221031083346.16558-4-beilei.xing@intel.com",
    "date": "2022-10-31T08:33:31",
    "name": "[v18,03/18] net/idpf: add Tx queue setup",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a4a7c09a21fd1edbb6ded50667d444f94acbef6a",
    "submitter": {
        "id": 410,
        "url": "https://patches.dpdk.org/api/people/410/?format=api",
        "name": "Xing, Beilei",
        "email": "beilei.xing@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20221031083346.16558-4-beilei.xing@intel.com/mbox/",
    "series": [
        {
            "id": 25492,
            "url": "https://patches.dpdk.org/api/series/25492/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=25492",
            "date": "2022-10-31T08:33:28",
            "name": "add support for idpf PMD in DPDK",
            "version": 18,
            "mbox": "https://patches.dpdk.org/series/25492/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/119343/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/119343/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 244C7A00C2;\n\tMon, 31 Oct 2022 10:04:37 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 653C540DF7;\n\tMon, 31 Oct 2022 10:04:24 +0100 (CET)",
            "from mga06.intel.com (mga06b.intel.com [134.134.136.31])\n by mails.dpdk.org (Postfix) with ESMTP id C73D040695\n for <dev@dpdk.org>; Mon, 31 Oct 2022 10:04:17 +0100 (CET)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 31 Oct 2022 02:04:04 -0700",
            "from dpdk-beileix-3.sh.intel.com ([10.67.110.253])\n by fmsmga006.fm.intel.com with ESMTP; 31 Oct 2022 02:04:02 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1667207058; x=1698743058;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=JtJChglb7ZQh5DYYyPAikSdTxyAHIJ4ZdFhu6Z9wMA4=;\n b=CRYDtvN4vFfXJnsJGrlwmfiRxCMrqR1z/GmyhIgKFGt0fHE/HTrnZfat\n UnoI4Gn9l4yPBmsMAKo+27PYTaUPkrq8Rhu6i5oeTT+VI/odwxvY8y6Ld\n v5COuKMTiuRd6xZvy55b8ZSIC/Xuhhu2+HZ1QhW7yny5ht2hc/CoH3wm4\n Z+Z1qVgpM9LGhvSGABZM3E9RSIfe6qeaif5Iw53jQ0jFRfOl7pLyizOkM\n 3prUrpgdGgWdnbSv9SYSlkrbYuaQ5SdZn1KmgLVv3Gr+z6bxgy0kBIi/c\n Jt67L6ZhS/LOEu/4NTWUCgrPcrBGSgsuQ+EiqiFVD9dndqhS74x7eRYXi A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10516\"; a=\"370926272\"",
            "E=Sophos;i=\"5.95,227,1661842800\"; d=\"scan'208\";a=\"370926272\"",
            "E=McAfee;i=\"6500,9779,10516\"; a=\"878664790\"",
            "E=Sophos;i=\"5.95,227,1661842800\"; d=\"scan'208\";a=\"878664790\""
        ],
        "X-ExtLoop1": "1",
        "From": "beilei.xing@intel.com",
        "To": "jingjing.wu@intel.com,\n\tbeilei.xing@intel.com",
        "Cc": "dev@dpdk.org, Junfeng Guo <junfeng.guo@intel.com>,\n Xiaoyun Li <xiaoyun.li@intel.com>",
        "Subject": "[PATCH v18 03/18] net/idpf: add Tx queue setup",
        "Date": "Mon, 31 Oct 2022 08:33:31 +0000",
        "Message-Id": "<20221031083346.16558-4-beilei.xing@intel.com>",
        "X-Mailer": "git-send-email 2.26.2",
        "In-Reply-To": "<20221031083346.16558-1-beilei.xing@intel.com>",
        "References": "<20221031051556.98549-1-beilei.xing@intel.com>\n <20221031083346.16558-1-beilei.xing@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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"
    },
    "content": "From: Junfeng Guo <junfeng.guo@intel.com>\n\nAdd support for tx_queue_setup ops.\n\nIn the single queue model, the same descriptor queue is used by SW to\npost buffer descriptors to HW and by HW to post completed descriptors\nto SW.\n\nIn the split queue model, \"RX buffer queues\" are used to pass\ndescriptor buffers from SW to HW while Rx queues are used only to\npass the descriptor completions, that is, descriptors that point\nto completed buffers, from HW to SW. This is contrary to the single\nqueue model in which Rx queues are used for both purposes.\n\nSigned-off-by: Beilei Xing <beilei.xing@intel.com>\nSigned-off-by: Xiaoyun Li <xiaoyun.li@intel.com>\nSigned-off-by: Junfeng Guo <junfeng.guo@intel.com>\n---\n drivers/net/idpf/idpf_ethdev.c |  13 ++\n drivers/net/idpf/idpf_rxtx.c   | 364 +++++++++++++++++++++++++++++++++\n drivers/net/idpf/idpf_rxtx.h   |  70 +++++++\n drivers/net/idpf/meson.build   |   1 +\n 4 files changed, 448 insertions(+)\n create mode 100644 drivers/net/idpf/idpf_rxtx.c\n create mode 100644 drivers/net/idpf/idpf_rxtx.h",
    "diff": "diff --git a/drivers/net/idpf/idpf_ethdev.c b/drivers/net/idpf/idpf_ethdev.c\nindex 035f563275..54f20d30ca 100644\n--- a/drivers/net/idpf/idpf_ethdev.c\n+++ b/drivers/net/idpf/idpf_ethdev.c\n@@ -11,6 +11,7 @@\n #include <errno.h>\n \n #include \"idpf_ethdev.h\"\n+#include \"idpf_rxtx.h\"\n \n #define IDPF_TX_SINGLE_Q\t\"tx_single\"\n #define IDPF_RX_SINGLE_Q\t\"rx_single\"\n@@ -42,6 +43,17 @@ idpf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \tdev_info->max_mtu = dev_info->max_rx_pktlen - IDPF_ETH_OVERHEAD;\n \tdev_info->min_mtu = RTE_ETHER_MIN_MTU;\n \n+\tdev_info->default_txconf = (struct rte_eth_txconf) {\n+\t\t.tx_free_thresh = IDPF_DEFAULT_TX_FREE_THRESH,\n+\t\t.tx_rs_thresh = IDPF_DEFAULT_TX_RS_THRESH,\n+\t};\n+\n+\tdev_info->tx_desc_lim = (struct rte_eth_desc_lim) {\n+\t\t.nb_max = IDPF_MAX_RING_DESC,\n+\t\t.nb_min = IDPF_MIN_RING_DESC,\n+\t\t.nb_align = IDPF_ALIGN_RING_DESC,\n+\t};\n+\n \treturn 0;\n }\n \n@@ -631,6 +643,7 @@ idpf_adapter_init(struct rte_pci_device *pci_dev, struct idpf_adapter *adapter)\n static const struct eth_dev_ops idpf_eth_dev_ops = {\n \t.dev_configure\t\t\t= idpf_dev_configure,\n \t.dev_close\t\t\t= idpf_dev_close,\n+\t.tx_queue_setup\t\t\t= idpf_tx_queue_setup,\n \t.dev_infos_get\t\t\t= idpf_dev_info_get,\n };\n \ndiff --git a/drivers/net/idpf/idpf_rxtx.c b/drivers/net/idpf/idpf_rxtx.c\nnew file mode 100644\nindex 0000000000..4afa0a2560\n--- /dev/null\n+++ b/drivers/net/idpf/idpf_rxtx.c\n@@ -0,0 +1,364 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Intel Corporation\n+ */\n+\n+#include <ethdev_driver.h>\n+#include <rte_net.h>\n+\n+#include \"idpf_ethdev.h\"\n+#include \"idpf_rxtx.h\"\n+\n+static int\n+check_tx_thresh(uint16_t nb_desc, uint16_t tx_rs_thresh,\n+\t\tuint16_t tx_free_thresh)\n+{\n+\t/* TX descriptors will have their RS bit set after tx_rs_thresh\n+\t * descriptors have been used. The TX descriptor ring will be cleaned\n+\t * after tx_free_thresh descriptors are used or if the number of\n+\t * descriptors required to transmit a packet is greater than the\n+\t * number of free TX descriptors.\n+\t *\n+\t * The following constraints must be satisfied:\n+\t *  - tx_rs_thresh must be less than the size of the ring minus 2.\n+\t *  - tx_free_thresh must be less than the size of the ring minus 3.\n+\t *  - tx_rs_thresh must be less than or equal to tx_free_thresh.\n+\t *  - tx_rs_thresh must be a divisor of the ring size.\n+\t *\n+\t * One descriptor in the TX ring is used as a sentinel to avoid a H/W\n+\t * race condition, hence the maximum threshold constraints. When set\n+\t * to zero use default values.\n+\t */\n+\tif (tx_rs_thresh >= (nb_desc - 2)) {\n+\t\tPMD_INIT_LOG(ERR, \"tx_rs_thresh (%u) must be less than the \"\n+\t\t\t     \"number of TX descriptors (%u) minus 2\",\n+\t\t\t     tx_rs_thresh, nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (tx_free_thresh >= (nb_desc - 3)) {\n+\t\tPMD_INIT_LOG(ERR, \"tx_free_thresh (%u) must be less than the \"\n+\t\t\t     \"number of TX descriptors (%u) minus 3.\",\n+\t\t\t     tx_free_thresh, nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (tx_rs_thresh > tx_free_thresh) {\n+\t\tPMD_INIT_LOG(ERR, \"tx_rs_thresh (%u) must be less than or \"\n+\t\t\t     \"equal to tx_free_thresh (%u).\",\n+\t\t\t     tx_rs_thresh, tx_free_thresh);\n+\t\treturn -EINVAL;\n+\t}\n+\tif ((nb_desc % tx_rs_thresh) != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"tx_rs_thresh (%u) must be a divisor of the \"\n+\t\t\t     \"number of TX descriptors (%u).\",\n+\t\t\t     tx_rs_thresh, nb_desc);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+reset_split_tx_descq(struct idpf_tx_queue *txq)\n+{\n+\tstruct idpf_tx_entry *txe;\n+\tuint32_t i, size;\n+\tuint16_t prev;\n+\n+\tif (txq == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Pointer to txq is NULL\");\n+\t\treturn;\n+\t}\n+\n+\tsize = sizeof(struct idpf_flex_tx_sched_desc) * txq->nb_tx_desc;\n+\tfor (i = 0; i < size; i++)\n+\t\t((volatile char *)txq->desc_ring)[i] = 0;\n+\n+\ttxe = txq->sw_ring;\n+\tprev = (uint16_t)(txq->sw_nb_desc - 1);\n+\tfor (i = 0; i < txq->sw_nb_desc; i++) {\n+\t\ttxe[i].mbuf = NULL;\n+\t\ttxe[i].last_id = i;\n+\t\ttxe[prev].next_id = i;\n+\t\tprev = i;\n+\t}\n+\n+\ttxq->tx_tail = 0;\n+\ttxq->nb_used = 0;\n+\n+\t/* Use this as next to clean for split desc queue */\n+\ttxq->last_desc_cleaned = 0;\n+\ttxq->sw_tail = 0;\n+\ttxq->nb_free = txq->nb_tx_desc - 1;\n+}\n+\n+static void\n+reset_split_tx_complq(struct idpf_tx_queue *cq)\n+{\n+\tuint32_t i, size;\n+\n+\tif (cq == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Pointer to complq is NULL\");\n+\t\treturn;\n+\t}\n+\n+\tsize = sizeof(struct idpf_splitq_tx_compl_desc) * cq->nb_tx_desc;\n+\tfor (i = 0; i < size; i++)\n+\t\t((volatile char *)cq->compl_ring)[i] = 0;\n+\n+\tcq->tx_tail = 0;\n+\tcq->expected_gen_id = 1;\n+}\n+\n+static void\n+reset_single_tx_queue(struct idpf_tx_queue *txq)\n+{\n+\tstruct idpf_tx_entry *txe;\n+\tuint32_t i, size;\n+\tuint16_t prev;\n+\n+\tif (txq == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Pointer to txq is NULL\");\n+\t\treturn;\n+\t}\n+\n+\ttxe = txq->sw_ring;\n+\tsize = sizeof(struct idpf_flex_tx_desc) * txq->nb_tx_desc;\n+\tfor (i = 0; i < size; i++)\n+\t\t((volatile char *)txq->tx_ring)[i] = 0;\n+\n+\tprev = (uint16_t)(txq->nb_tx_desc - 1);\n+\tfor (i = 0; i < txq->nb_tx_desc; i++) {\n+\t\ttxq->tx_ring[i].qw1.cmd_dtype =\n+\t\t\trte_cpu_to_le_16(IDPF_TX_DESC_DTYPE_DESC_DONE);\n+\t\ttxe[i].mbuf =  NULL;\n+\t\ttxe[i].last_id = i;\n+\t\ttxe[prev].next_id = i;\n+\t\tprev = i;\n+\t}\n+\n+\ttxq->tx_tail = 0;\n+\ttxq->nb_used = 0;\n+\n+\ttxq->last_desc_cleaned = txq->nb_tx_desc - 1;\n+\ttxq->nb_free = txq->nb_tx_desc - 1;\n+\n+\ttxq->next_dd = txq->rs_thresh - 1;\n+\ttxq->next_rs = txq->rs_thresh - 1;\n+}\n+\n+static int\n+idpf_tx_split_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\t  uint16_t nb_desc, unsigned int socket_id,\n+\t\t\t  const struct rte_eth_txconf *tx_conf)\n+{\n+\tstruct idpf_vport *vport = dev->data->dev_private;\n+\tstruct idpf_adapter *adapter = vport->adapter;\n+\tuint16_t tx_rs_thresh, tx_free_thresh;\n+\tstruct idpf_hw *hw = &adapter->hw;\n+\tstruct idpf_tx_queue *txq, *cq;\n+\tconst struct rte_memzone *mz;\n+\tuint32_t ring_size;\n+\tuint64_t offloads;\n+\tint ret;\n+\n+\toffloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;\n+\n+\ttx_rs_thresh = (uint16_t)((tx_conf->tx_rs_thresh != 0) ?\n+\t\ttx_conf->tx_rs_thresh : IDPF_DEFAULT_TX_RS_THRESH);\n+\ttx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh != 0) ?\n+\t\ttx_conf->tx_free_thresh : IDPF_DEFAULT_TX_FREE_THRESH);\n+\tif (check_tx_thresh(nb_desc, tx_rs_thresh, tx_free_thresh) != 0)\n+\t\treturn -EINVAL;\n+\n+\t/* Allocate the TX queue data structure. */\n+\ttxq = rte_zmalloc_socket(\"idpf split txq\",\n+\t\t\t\t sizeof(struct idpf_tx_queue),\n+\t\t\t\t RTE_CACHE_LINE_SIZE,\n+\t\t\t\t socket_id);\n+\tif (txq == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for tx queue structure\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\ttxq->nb_tx_desc = nb_desc;\n+\ttxq->rs_thresh = tx_rs_thresh;\n+\ttxq->free_thresh = tx_free_thresh;\n+\ttxq->queue_id = vport->chunks_info.tx_start_qid + queue_idx;\n+\ttxq->port_id = dev->data->port_id;\n+\ttxq->offloads = offloads;\n+\n+\t/* Allocate software ring */\n+\ttxq->sw_nb_desc = 2 * nb_desc;\n+\ttxq->sw_ring =\n+\t\trte_zmalloc_socket(\"idpf split tx sw ring\",\n+\t\t\t\t   sizeof(struct idpf_tx_entry) *\n+\t\t\t\t   txq->sw_nb_desc,\n+\t\t\t\t   RTE_CACHE_LINE_SIZE,\n+\t\t\t\t   socket_id);\n+\tif (txq->sw_ring == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for SW TX ring\");\n+\t\tret = -ENOMEM;\n+\t\tgoto err_txq_sw_ring;\n+\t}\n+\n+\t/* Allocate TX hardware ring descriptors. */\n+\tring_size = sizeof(struct idpf_flex_tx_sched_desc) * txq->nb_tx_desc;\n+\tring_size = RTE_ALIGN(ring_size, IDPF_DMA_MEM_ALIGN);\n+\tmz = rte_eth_dma_zone_reserve(dev, \"split_tx_ring\", queue_idx,\n+\t\t\t\t      ring_size, IDPF_RING_BASE_ALIGN,\n+\t\t\t\t      socket_id);\n+\tif (mz == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to reserve DMA memory for TX\");\n+\t\tret = -ENOMEM;\n+\t\tgoto err_txq_mz;\n+\t}\n+\ttxq->tx_ring_phys_addr = mz->iova;\n+\ttxq->desc_ring = mz->addr;\n+\n+\ttxq->mz = mz;\n+\treset_split_tx_descq(txq);\n+\ttxq->qtx_tail = hw->hw_addr + (vport->chunks_info.tx_qtail_start +\n+\t\t\tqueue_idx * vport->chunks_info.tx_qtail_spacing);\n+\n+\t/* Allocate the TX completion queue data structure. */\n+\ttxq->complq = rte_zmalloc_socket(\"idpf splitq cq\",\n+\t\t\t\t\t sizeof(struct idpf_tx_queue),\n+\t\t\t\t\t RTE_CACHE_LINE_SIZE,\n+\t\t\t\t\t socket_id);\n+\tcq = txq->complq;\n+\tif (cq == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for tx queue structure\");\n+\t\tret = -ENOMEM;\n+\t\tgoto err_cq;\n+\t}\n+\tcq->nb_tx_desc = 2 * nb_desc;\n+\tcq->queue_id = vport->chunks_info.tx_compl_start_qid + queue_idx;\n+\tcq->port_id = dev->data->port_id;\n+\tcq->txqs = dev->data->tx_queues;\n+\tcq->tx_start_qid = vport->chunks_info.tx_start_qid;\n+\n+\tring_size = sizeof(struct idpf_splitq_tx_compl_desc) * cq->nb_tx_desc;\n+\tring_size = RTE_ALIGN(ring_size, IDPF_DMA_MEM_ALIGN);\n+\tmz = rte_eth_dma_zone_reserve(dev, \"tx_split_compl_ring\", queue_idx,\n+\t\t\t\t      ring_size, IDPF_RING_BASE_ALIGN,\n+\t\t\t\t      socket_id);\n+\tif (mz == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to reserve DMA memory for TX completion queue\");\n+\t\tret = -ENOMEM;\n+\t\tgoto err_cq_mz;\n+\t}\n+\tcq->tx_ring_phys_addr = mz->iova;\n+\tcq->compl_ring = mz->addr;\n+\tcq->mz = mz;\n+\treset_split_tx_complq(cq);\n+\n+\ttxq->q_set = true;\n+\tdev->data->tx_queues[queue_idx] = txq;\n+\n+\treturn 0;\n+\n+err_cq_mz:\n+\trte_free(cq);\n+err_cq:\n+\trte_memzone_free(txq->mz);\n+err_txq_mz:\n+\trte_free(txq->sw_ring);\n+err_txq_sw_ring:\n+\trte_free(txq);\n+\n+\treturn ret;\n+}\n+\n+static int\n+idpf_tx_single_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\t   uint16_t nb_desc, unsigned int socket_id,\n+\t\t\t   const struct rte_eth_txconf *tx_conf)\n+{\n+\tstruct idpf_vport *vport = dev->data->dev_private;\n+\tstruct idpf_adapter *adapter = vport->adapter;\n+\tuint16_t tx_rs_thresh, tx_free_thresh;\n+\tstruct idpf_hw *hw = &adapter->hw;\n+\tconst struct rte_memzone *mz;\n+\tstruct idpf_tx_queue *txq;\n+\tuint32_t ring_size;\n+\tuint64_t offloads;\n+\n+\toffloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;\n+\n+\ttx_rs_thresh = (uint16_t)((tx_conf->tx_rs_thresh > 0) ?\n+\t\ttx_conf->tx_rs_thresh : IDPF_DEFAULT_TX_RS_THRESH);\n+\ttx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh > 0) ?\n+\t\ttx_conf->tx_free_thresh : IDPF_DEFAULT_TX_FREE_THRESH);\n+\tif (check_tx_thresh(nb_desc, tx_rs_thresh, tx_free_thresh) != 0)\n+\t\treturn -EINVAL;\n+\n+\t/* Allocate the TX queue data structure. */\n+\ttxq = rte_zmalloc_socket(\"idpf txq\",\n+\t\t\t\t sizeof(struct idpf_tx_queue),\n+\t\t\t\t RTE_CACHE_LINE_SIZE,\n+\t\t\t\t socket_id);\n+\tif (txq == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for tx queue structure\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* TODO: vlan offload */\n+\n+\ttxq->nb_tx_desc = nb_desc;\n+\ttxq->rs_thresh = tx_rs_thresh;\n+\ttxq->free_thresh = tx_free_thresh;\n+\ttxq->queue_id = vport->chunks_info.tx_start_qid + queue_idx;\n+\ttxq->port_id = dev->data->port_id;\n+\ttxq->offloads = offloads;\n+\n+\t/* Allocate software ring */\n+\ttxq->sw_ring =\n+\t\trte_zmalloc_socket(\"idpf tx sw ring\",\n+\t\t\t\t   sizeof(struct idpf_tx_entry) * nb_desc,\n+\t\t\t\t   RTE_CACHE_LINE_SIZE,\n+\t\t\t\t   socket_id);\n+\tif (txq->sw_ring == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for SW TX ring\");\n+\t\trte_free(txq);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Allocate TX hardware ring descriptors. */\n+\tring_size = sizeof(struct idpf_flex_tx_desc) * nb_desc;\n+\tring_size = RTE_ALIGN(ring_size, IDPF_DMA_MEM_ALIGN);\n+\tmz = rte_eth_dma_zone_reserve(dev, \"tx_ring\", queue_idx,\n+\t\t\t\t      ring_size, IDPF_RING_BASE_ALIGN,\n+\t\t\t\t      socket_id);\n+\tif (mz == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to reserve DMA memory for TX\");\n+\t\trte_free(txq->sw_ring);\n+\t\trte_free(txq);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\ttxq->tx_ring_phys_addr = mz->iova;\n+\ttxq->tx_ring = mz->addr;\n+\n+\ttxq->mz = mz;\n+\treset_single_tx_queue(txq);\n+\ttxq->q_set = true;\n+\tdev->data->tx_queues[queue_idx] = txq;\n+\ttxq->qtx_tail = hw->hw_addr + (vport->chunks_info.tx_qtail_start +\n+\t\t\tqueue_idx * vport->chunks_info.tx_qtail_spacing);\n+\n+\treturn 0;\n+}\n+\n+int\n+idpf_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t    uint16_t nb_desc, unsigned int socket_id,\n+\t\t    const struct rte_eth_txconf *tx_conf)\n+{\n+\tstruct idpf_vport *vport = dev->data->dev_private;\n+\n+\tif (vport->txq_model == VIRTCHNL2_QUEUE_MODEL_SINGLE)\n+\t\treturn idpf_tx_single_queue_setup(dev, queue_idx, nb_desc,\n+\t\t\t\t\t\t  socket_id, tx_conf);\n+\telse\n+\t\treturn idpf_tx_split_queue_setup(dev, queue_idx, nb_desc,\n+\t\t\t\t\t\t socket_id, tx_conf);\n+}\ndiff --git a/drivers/net/idpf/idpf_rxtx.h b/drivers/net/idpf/idpf_rxtx.h\nnew file mode 100644\nindex 0000000000..c7ba15b058\n--- /dev/null\n+++ b/drivers/net/idpf/idpf_rxtx.h\n@@ -0,0 +1,70 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Intel Corporation\n+ */\n+\n+#ifndef _IDPF_RXTX_H_\n+#define _IDPF_RXTX_H_\n+\n+#include \"idpf_ethdev.h\"\n+\n+/* In QLEN must be whole number of 32 descriptors. */\n+#define IDPF_ALIGN_RING_DESC\t32\n+#define IDPF_MIN_RING_DESC\t32\n+#define IDPF_MAX_RING_DESC\t4096\n+#define IDPF_DMA_MEM_ALIGN\t4096\n+/* Base address of the HW descriptor ring should be 128B aligned. */\n+#define IDPF_RING_BASE_ALIGN\t128\n+\n+#define IDPF_DEFAULT_TX_RS_THRESH\t32\n+#define IDPF_DEFAULT_TX_FREE_THRESH\t32\n+\n+struct idpf_tx_entry {\n+\tstruct rte_mbuf *mbuf;\n+\tuint16_t next_id;\n+\tuint16_t last_id;\n+};\n+\n+/* Structure associated with each TX queue. */\n+struct idpf_tx_queue {\n+\tconst struct rte_memzone *mz;\t\t/* memzone for Tx ring */\n+\tvolatile struct idpf_flex_tx_desc *tx_ring;\t/* Tx ring virtual address */\n+\tvolatile union {\n+\t\tstruct idpf_flex_tx_sched_desc *desc_ring;\n+\t\tstruct idpf_splitq_tx_compl_desc *compl_ring;\n+\t};\n+\tuint64_t tx_ring_phys_addr;\t\t/* Tx ring DMA address */\n+\tstruct idpf_tx_entry *sw_ring;\t\t/* address array of SW ring */\n+\n+\tuint16_t nb_tx_desc;\t\t/* ring length */\n+\tuint16_t tx_tail;\t\t/* current value of tail */\n+\tvolatile uint8_t *qtx_tail;\t/* register address of tail */\n+\t/* number of used desc since RS bit set */\n+\tuint16_t nb_used;\n+\tuint16_t nb_free;\n+\tuint16_t last_desc_cleaned;\t/* last desc have been cleaned*/\n+\tuint16_t free_thresh;\n+\tuint16_t rs_thresh;\n+\n+\tuint16_t port_id;\n+\tuint16_t queue_id;\n+\tuint64_t offloads;\n+\tuint16_t next_dd;\t/* next to set RS, for VPMD */\n+\tuint16_t next_rs;\t/* next to check DD,  for VPMD */\n+\n+\tbool q_set;\t\t/* if tx queue has been configured */\n+\tbool q_started;\t\t/* if tx queue has been started */\n+\n+\t/* only valid for split queue mode */\n+\tuint16_t sw_nb_desc;\n+\tuint16_t sw_tail;\n+\tvoid **txqs;\n+\tuint32_t tx_start_qid;\n+\tuint8_t expected_gen_id;\n+\tstruct idpf_tx_queue *complq;\n+};\n+\n+int idpf_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\tuint16_t nb_desc, unsigned int socket_id,\n+\t\t\tconst struct rte_eth_txconf *tx_conf);\n+\n+#endif /* _IDPF_RXTX_H_ */\ndiff --git a/drivers/net/idpf/meson.build b/drivers/net/idpf/meson.build\nindex ecf73355c3..b632b76656 100644\n--- a/drivers/net/idpf/meson.build\n+++ b/drivers/net/idpf/meson.build\n@@ -11,5 +11,6 @@ deps += ['common_idpf']\n \n sources = files(\n     'idpf_ethdev.c',\n+    'idpf_rxtx.c',\n     'idpf_vchnl.c',\n )\n",
    "prefixes": [
        "v18",
        "03/18"
    ]
}