get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 99391,
    "url": "http://patches.dpdk.org/api/patches/99391/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1632291108-28780-8-git-send-email-skoteshwar@marvell.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": "<1632291108-28780-8-git-send-email-skoteshwar@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1632291108-28780-8-git-send-email-skoteshwar@marvell.com",
    "date": "2021-09-22T06:11:47",
    "name": "[v3,7/8] net/cnxk: TM capabilities and queue rate limit handlers",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "f1deb42ca84bcbd7b4ec16d6ca2399fe700c42e2",
    "submitter": {
        "id": 2009,
        "url": "http://patches.dpdk.org/api/people/2009/?format=api",
        "name": "Satha Koteswara Rao Kottidi",
        "email": "skoteshwar@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1632291108-28780-8-git-send-email-skoteshwar@marvell.com/mbox/",
    "series": [
        {
            "id": 19067,
            "url": "http://patches.dpdk.org/api/series/19067/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=19067",
            "date": "2021-09-22T06:11:40",
            "name": "Add TM Support for CN9K and CN10K",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/19067/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/99391/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/99391/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 2072FA0C45;\n\tWed, 22 Sep 2021 08:12:42 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 3CF0D41192;\n\tWed, 22 Sep 2021 08:12:34 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 907B541184\n for <dev@dpdk.org>; Wed, 22 Sep 2021 08:12:27 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18LLFpF2022454\n for <dev@dpdk.org>; Tue, 21 Sep 2021 23:12:25 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com with ESMTP id 3b7q5dhe7g-5\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Tue, 21 Sep 2021 23:12:25 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.18;\n Tue, 21 Sep 2021 23:12:15 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend\n Transport; Tue, 21 Sep 2021 23:12:16 -0700",
            "from cavium.marvell.com (cavium.marvell.com [10.28.34.244])\n by maili.marvell.com (Postfix) with ESMTP id 4E69E3F7078;\n Tue, 21 Sep 2021 23:12:14 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-type; s=pfpt0220; bh=EmRHFkZht9aM0FxYYuQuaWtAWRvm2r48kUn+b+z/8hw=;\n b=ipxrD2EJ27uGAm2GMNrczfMcLkiNt17Ub+auBp7M2FmoXzNFDg6SXEiVu7+GLSvUX4V8\n ia+ZnfxGpGZlnZ8KGfL95JuvthOe0xsJfs7DoJ/Zev6NFcNc6KzAVMD9s7HzLUT/kXBE\n bO+aBywVqXbRxL9YI6CpkWQ8mZkjzFwWTtwDn4RuFB4MpfiShDh2yl83sg0NMhYhf3xv\n vjaXUMF6VNJFTTUbBglGaZanAq9qxtR6vAlXRw86ssabBEcll1/bMCvAVeMgsaPJnu3w\n UZq23BOG//Y0K7HPTscsmPQDpDxbC88P8PkNyOd1gqUamJjy5Ak6GKg25SGAFhWcFYe7 SQ==",
        "From": "<skoteshwar@marvell.com>",
        "To": "Nithin Dabilpuram <ndabilpuram@marvell.com>, Kiran Kumar K\n <kirankumark@marvell.com>, Sunil Kumar Kori <skori@marvell.com>, Satha Rao\n <skoteshwar@marvell.com>",
        "CC": "<dev@dpdk.org>",
        "Date": "Wed, 22 Sep 2021 02:11:47 -0400",
        "Message-ID": "<1632291108-28780-8-git-send-email-skoteshwar@marvell.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1632291108-28780-1-git-send-email-skoteshwar@marvell.com>",
        "References": "<1630516236-10526-1-git-send-email-skoteshwar@marvell.com>\n <1632291108-28780-1-git-send-email-skoteshwar@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "yAmU61Sss6DgqlfZxQPl2LAuPjfk1bGb",
        "X-Proofpoint-ORIG-GUID": "yAmU61Sss6DgqlfZxQPl2LAuPjfk1bGb",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.391,FMLib:17.0.607.475\n definitions=2021-09-22_01,2021-09-20_01,2020-04-07_01",
        "Subject": "[dpdk-dev] [PATCH v3 7/8] net/cnxk: TM capabilities and queue rate\n limit handlers",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Satha Rao <skoteshwar@marvell.com>\n\nInitial version of TM implementation added basic infrastructure,\nTM node_get, capabilities operations and rate limit queue operation.\n\nSigned-off-by: Satha Rao <skoteshwar@marvell.com>\nAcked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>\n---\n drivers/net/cnxk/cnxk_ethdev.c |   2 +\n drivers/net/cnxk/cnxk_ethdev.h |   3 +\n drivers/net/cnxk/cnxk_tm.c     | 322 +++++++++++++++++++++++++++++++++\n drivers/net/cnxk/cnxk_tm.h     |  18 ++\n drivers/net/cnxk/meson.build   |   1 +\n 5 files changed, 346 insertions(+)\n create mode 100644 drivers/net/cnxk/cnxk_tm.c\n create mode 100644 drivers/net/cnxk/cnxk_tm.h",
    "diff": "diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c\nindex 7152dcd002..8629193d50 100644\n--- a/drivers/net/cnxk/cnxk_ethdev.c\n+++ b/drivers/net/cnxk/cnxk_ethdev.c\n@@ -1276,6 +1276,8 @@ struct eth_dev_ops cnxk_eth_dev_ops = {\n \t.rss_hash_update = cnxk_nix_rss_hash_update,\n \t.rss_hash_conf_get = cnxk_nix_rss_hash_conf_get,\n \t.set_mc_addr_list = cnxk_nix_mc_addr_list_configure,\n+\t.set_queue_rate_limit = cnxk_nix_tm_set_queue_rate_limit,\n+\t.tm_ops_get = cnxk_nix_tm_ops_get,\n };\n \n static int\ndiff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h\nindex 27920c84f2..10e05e6b5e 100644\n--- a/drivers/net/cnxk/cnxk_ethdev.h\n+++ b/drivers/net/cnxk/cnxk_ethdev.h\n@@ -330,6 +330,9 @@ int cnxk_nix_tsc_convert(struct cnxk_eth_dev *dev);\n int cnxk_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock);\n \n uint64_t cnxk_nix_rxq_mbuf_setup(struct cnxk_eth_dev *dev);\n+int cnxk_nix_tm_ops_get(struct rte_eth_dev *eth_dev, void *ops);\n+int cnxk_nix_tm_set_queue_rate_limit(struct rte_eth_dev *eth_dev,\n+\t\t\t\t     uint16_t queue_idx, uint16_t tx_rate);\n \n /* RSS */\n uint32_t cnxk_rss_ethdev_to_nix(struct cnxk_eth_dev *dev, uint64_t ethdev_rss,\ndiff --git a/drivers/net/cnxk/cnxk_tm.c b/drivers/net/cnxk/cnxk_tm.c\nnew file mode 100644\nindex 0000000000..87fd8bec92\n--- /dev/null\n+++ b/drivers/net/cnxk/cnxk_tm.c\n@@ -0,0 +1,322 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2021 Marvell.\n+ */\n+#include <cnxk_ethdev.h>\n+#include <cnxk_tm.h>\n+#include <cnxk_utils.h>\n+\n+static int\n+cnxk_nix_tm_node_type_get(struct rte_eth_dev *eth_dev, uint32_t node_id,\n+\t\t\t  int *is_leaf, struct rte_tm_error *error)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct roc_nix *nix = &dev->nix;\n+\tstruct roc_nix_tm_node *node;\n+\n+\tif (is_leaf == NULL) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tnode = roc_nix_tm_node_get(nix, node_id);\n+\tif (node_id == RTE_TM_NODE_ID_NULL || !node) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (roc_nix_tm_lvl_is_leaf(nix, node->lvl))\n+\t\t*is_leaf = true;\n+\telse\n+\t\t*is_leaf = false;\n+\n+\treturn 0;\n+}\n+\n+static int\n+cnxk_nix_tm_capa_get(struct rte_eth_dev *eth_dev,\n+\t\t     struct rte_tm_capabilities *cap,\n+\t\t     struct rte_tm_error *error)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tint rc, max_nr_nodes = 0, i, n_lvl;\n+\tstruct roc_nix *nix = &dev->nix;\n+\tuint16_t schq[ROC_TM_LVL_MAX];\n+\n+\tmemset(cap, 0, sizeof(*cap));\n+\n+\trc = roc_nix_tm_rsrc_count(nix, schq);\n+\tif (rc) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\terror->message = \"unexpected fatal error\";\n+\t\treturn rc;\n+\t}\n+\n+\tfor (i = 0; i < NIX_TXSCH_LVL_TL1; i++)\n+\t\tmax_nr_nodes += schq[i];\n+\n+\tcap->n_nodes_max = max_nr_nodes + dev->nb_txq;\n+\n+\tn_lvl = roc_nix_tm_lvl_cnt_get(nix);\n+\t/* Consider leaf level */\n+\tcap->n_levels_max = n_lvl + 1;\n+\tcap->non_leaf_nodes_identical = 1;\n+\tcap->leaf_nodes_identical = 1;\n+\n+\t/* Shaper Capabilities */\n+\tcap->shaper_private_n_max = max_nr_nodes;\n+\tcap->shaper_n_max = max_nr_nodes;\n+\tcap->shaper_private_dual_rate_n_max = max_nr_nodes;\n+\tcap->shaper_private_rate_min = NIX_TM_MIN_SHAPER_RATE / 8;\n+\tcap->shaper_private_rate_max = NIX_TM_MAX_SHAPER_RATE / 8;\n+\tcap->shaper_private_packet_mode_supported = 1;\n+\tcap->shaper_private_byte_mode_supported = 1;\n+\tcap->shaper_pkt_length_adjust_min = NIX_TM_LENGTH_ADJUST_MIN;\n+\tcap->shaper_pkt_length_adjust_max = NIX_TM_LENGTH_ADJUST_MAX;\n+\n+\t/* Schedule Capabilities */\n+\tcap->sched_n_children_max = schq[n_lvl - 1];\n+\tcap->sched_sp_n_priorities_max = NIX_TM_TLX_SP_PRIO_MAX;\n+\tcap->sched_wfq_n_children_per_group_max = cap->sched_n_children_max;\n+\tcap->sched_wfq_n_groups_max = 1;\n+\tcap->sched_wfq_weight_max = roc_nix_tm_max_sched_wt_get();\n+\tcap->sched_wfq_packet_mode_supported = 1;\n+\tcap->sched_wfq_byte_mode_supported = 1;\n+\n+\tcap->dynamic_update_mask = RTE_TM_UPDATE_NODE_PARENT_KEEP_LEVEL |\n+\t\t\t\t   RTE_TM_UPDATE_NODE_SUSPEND_RESUME;\n+\tcap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES |\n+\t\t\t  RTE_TM_STATS_N_PKTS_RED_DROPPED |\n+\t\t\t  RTE_TM_STATS_N_BYTES_RED_DROPPED;\n+\n+\tfor (i = 0; i < RTE_COLORS; i++) {\n+\t\tcap->mark_vlan_dei_supported[i] = false;\n+\t\tcap->mark_ip_ecn_tcp_supported[i] = false;\n+\t\tcap->mark_ip_dscp_supported[i] = false;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+cnxk_nix_tm_level_capa_get(struct rte_eth_dev *eth_dev, uint32_t lvl,\n+\t\t\t   struct rte_tm_level_capabilities *cap,\n+\t\t\t   struct rte_tm_error *error)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct roc_nix *nix = &dev->nix;\n+\tuint16_t schq[ROC_TM_LVL_MAX];\n+\tint rc, n_lvl;\n+\n+\tmemset(cap, 0, sizeof(*cap));\n+\n+\trc = roc_nix_tm_rsrc_count(nix, schq);\n+\tif (rc) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\terror->message = \"unexpected fatal error\";\n+\t\treturn rc;\n+\t}\n+\n+\tn_lvl = roc_nix_tm_lvl_cnt_get(nix);\n+\n+\tif (roc_nix_tm_lvl_is_leaf(nix, lvl)) {\n+\t\t/* Leaf */\n+\t\tcap->n_nodes_max = dev->nb_txq;\n+\t\tcap->n_nodes_leaf_max = dev->nb_txq;\n+\t\tcap->leaf_nodes_identical = 1;\n+\t\tcap->leaf.stats_mask =\n+\t\t\tRTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;\n+\n+\t} else if (lvl == ROC_TM_LVL_ROOT) {\n+\t\t/* Root node, a.k.a. TL2(vf)/TL1(pf) */\n+\t\tcap->n_nodes_max = 1;\n+\t\tcap->n_nodes_nonleaf_max = 1;\n+\t\tcap->non_leaf_nodes_identical = 1;\n+\n+\t\tcap->nonleaf.shaper_private_supported = true;\n+\t\tcap->nonleaf.shaper_private_dual_rate_supported =\n+\t\t\troc_nix_tm_lvl_have_link_access(nix, lvl) ? false :\n+\t\t\t\t\t\t\t\t    true;\n+\t\tcap->nonleaf.shaper_private_rate_min =\n+\t\t\tNIX_TM_MIN_SHAPER_RATE / 8;\n+\t\tcap->nonleaf.shaper_private_rate_max =\n+\t\t\tNIX_TM_MAX_SHAPER_RATE / 8;\n+\t\tcap->nonleaf.shaper_private_packet_mode_supported = 1;\n+\t\tcap->nonleaf.shaper_private_byte_mode_supported = 1;\n+\n+\t\tcap->nonleaf.sched_n_children_max = schq[lvl];\n+\t\tcap->nonleaf.sched_sp_n_priorities_max =\n+\t\t\troc_nix_tm_max_prio(nix, lvl) + 1;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 1;\n+\t\tcap->nonleaf.sched_wfq_weight_max =\n+\t\t\troc_nix_tm_max_sched_wt_get();\n+\t\tcap->nonleaf.sched_wfq_packet_mode_supported = 1;\n+\t\tcap->nonleaf.sched_wfq_byte_mode_supported = 1;\n+\n+\t\tif (roc_nix_tm_lvl_have_link_access(nix, lvl))\n+\t\t\tcap->nonleaf.stats_mask =\n+\t\t\t\tRTE_TM_STATS_N_PKTS_RED_DROPPED |\n+\t\t\t\tRTE_TM_STATS_N_BYTES_RED_DROPPED;\n+\t} else if (lvl < ROC_TM_LVL_MAX) {\n+\t\t/* TL2, TL3, TL4, MDQ */\n+\t\tcap->n_nodes_max = schq[lvl];\n+\t\tcap->n_nodes_nonleaf_max = cap->n_nodes_max;\n+\t\tcap->non_leaf_nodes_identical = 1;\n+\n+\t\tcap->nonleaf.shaper_private_supported = true;\n+\t\tcap->nonleaf.shaper_private_dual_rate_supported = true;\n+\t\tcap->nonleaf.shaper_private_rate_min =\n+\t\t\tNIX_TM_MIN_SHAPER_RATE / 8;\n+\t\tcap->nonleaf.shaper_private_rate_max =\n+\t\t\tNIX_TM_MAX_SHAPER_RATE / 8;\n+\t\tcap->nonleaf.shaper_private_packet_mode_supported = 1;\n+\t\tcap->nonleaf.shaper_private_byte_mode_supported = 1;\n+\n+\t\t/* MDQ doesn't support Strict Priority */\n+\t\tif ((int)lvl == (n_lvl - 1))\n+\t\t\tcap->nonleaf.sched_n_children_max = dev->nb_txq;\n+\t\telse\n+\t\t\tcap->nonleaf.sched_n_children_max = schq[lvl - 1];\n+\t\tcap->nonleaf.sched_sp_n_priorities_max =\n+\t\t\troc_nix_tm_max_prio(nix, lvl) + 1;\n+\t\tcap->nonleaf.sched_wfq_n_groups_max = 1;\n+\t\tcap->nonleaf.sched_wfq_weight_max =\n+\t\t\troc_nix_tm_max_sched_wt_get();\n+\t\tcap->nonleaf.sched_wfq_packet_mode_supported = 1;\n+\t\tcap->nonleaf.sched_wfq_byte_mode_supported = 1;\n+\t} else {\n+\t\t/* unsupported level */\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\treturn rc;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+cnxk_nix_tm_node_capa_get(struct rte_eth_dev *eth_dev, uint32_t node_id,\n+\t\t\t  struct rte_tm_node_capabilities *cap,\n+\t\t\t  struct rte_tm_error *error)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tstruct cnxk_nix_tm_node *tm_node;\n+\tstruct roc_nix *nix = &dev->nix;\n+\tuint16_t schq[ROC_TM_LVL_MAX];\n+\tint rc, n_lvl, lvl;\n+\n+\tmemset(cap, 0, sizeof(*cap));\n+\n+\ttm_node = (struct cnxk_nix_tm_node *)roc_nix_tm_node_get(nix, node_id);\n+\tif (!tm_node) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_NODE_ID;\n+\t\terror->message = \"no such node\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tlvl = tm_node->nix_node.lvl;\n+\tn_lvl = roc_nix_tm_lvl_cnt_get(nix);\n+\n+\t/* Leaf node */\n+\tif (roc_nix_tm_lvl_is_leaf(nix, lvl)) {\n+\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;\n+\t\treturn 0;\n+\t}\n+\n+\trc = roc_nix_tm_rsrc_count(nix, schq);\n+\tif (rc) {\n+\t\terror->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;\n+\t\terror->message = \"unexpected fatal error\";\n+\t\treturn rc;\n+\t}\n+\n+\t/* Non Leaf Shaper */\n+\tcap->shaper_private_supported = true;\n+\tcap->shaper_private_rate_min = NIX_TM_MIN_SHAPER_RATE / 8;\n+\tcap->shaper_private_rate_max = NIX_TM_MAX_SHAPER_RATE / 8;\n+\tcap->shaper_private_packet_mode_supported = 1;\n+\tcap->shaper_private_byte_mode_supported = 1;\n+\n+\t/* Non Leaf Scheduler */\n+\tif (lvl == (n_lvl - 1))\n+\t\tcap->nonleaf.sched_n_children_max = dev->nb_txq;\n+\telse\n+\t\tcap->nonleaf.sched_n_children_max = schq[lvl - 1];\n+\n+\tcap->nonleaf.sched_sp_n_priorities_max =\n+\t\troc_nix_tm_max_prio(nix, lvl) + 1;\n+\tcap->nonleaf.sched_wfq_n_children_per_group_max =\n+\t\tcap->nonleaf.sched_n_children_max;\n+\tcap->nonleaf.sched_wfq_n_groups_max = 1;\n+\tcap->nonleaf.sched_wfq_weight_max = roc_nix_tm_max_sched_wt_get();\n+\tcap->nonleaf.sched_wfq_packet_mode_supported = 1;\n+\tcap->nonleaf.sched_wfq_byte_mode_supported = 1;\n+\n+\tcap->shaper_private_dual_rate_supported = true;\n+\tif (roc_nix_tm_lvl_have_link_access(nix, lvl)) {\n+\t\tcap->shaper_private_dual_rate_supported = false;\n+\t\tcap->stats_mask = RTE_TM_STATS_N_PKTS_RED_DROPPED |\n+\t\t\t\t  RTE_TM_STATS_N_BYTES_RED_DROPPED;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+const struct rte_tm_ops cnxk_tm_ops = {\n+\t.node_type_get = cnxk_nix_tm_node_type_get,\n+\t.capabilities_get = cnxk_nix_tm_capa_get,\n+\t.level_capabilities_get = cnxk_nix_tm_level_capa_get,\n+\t.node_capabilities_get = cnxk_nix_tm_node_capa_get,\n+};\n+\n+int\n+cnxk_nix_tm_ops_get(struct rte_eth_dev *eth_dev __rte_unused, void *arg)\n+{\n+\tif (!arg)\n+\t\treturn -EINVAL;\n+\n+\t/* Check for supported revisions */\n+\tif (roc_model_is_cn96_ax() || roc_model_is_cn95_a0())\n+\t\treturn -EINVAL;\n+\n+\t*(const void **)arg = &cnxk_tm_ops;\n+\n+\treturn 0;\n+}\n+\n+int\n+cnxk_nix_tm_set_queue_rate_limit(struct rte_eth_dev *eth_dev,\n+\t\t\t\t uint16_t queue_idx, uint16_t tx_rate_mbps)\n+{\n+\tstruct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);\n+\tuint64_t tx_rate = tx_rate_mbps * (uint64_t)1E6;\n+\tstruct roc_nix *nix = &dev->nix;\n+\tint rc = -EINVAL;\n+\n+\t/* Check for supported revisions */\n+\tif (roc_model_is_cn96_ax() || roc_model_is_cn95_a0())\n+\t\tgoto exit;\n+\n+\tif (queue_idx >= eth_dev->data->nb_tx_queues)\n+\t\tgoto exit;\n+\n+\tif ((roc_nix_tm_tree_type_get(nix) != ROC_NIX_TM_RLIMIT) &&\n+\t    eth_dev->data->nb_tx_queues > 1) {\n+\t\t/*\n+\t\t * Disable xmit will be enabled when\n+\t\t * new topology is available.\n+\t\t */\n+\t\trc = roc_nix_tm_hierarchy_disable(nix);\n+\t\tif (rc)\n+\t\t\tgoto exit;\n+\n+\t\trc = roc_nix_tm_prepare_rate_limited_tree(nix);\n+\t\tif (rc)\n+\t\t\tgoto exit;\n+\n+\t\trc = roc_nix_tm_hierarchy_enable(nix, ROC_NIX_TM_RLIMIT, true);\n+\t\tif (rc)\n+\t\t\tgoto exit;\n+\t}\n+\n+\treturn roc_nix_tm_rlimit_sq(nix, queue_idx, tx_rate);\n+exit:\n+\treturn rc;\n+}\ndiff --git a/drivers/net/cnxk/cnxk_tm.h b/drivers/net/cnxk/cnxk_tm.h\nnew file mode 100644\nindex 0000000000..f7470c2634\n--- /dev/null\n+++ b/drivers/net/cnxk/cnxk_tm.h\n@@ -0,0 +1,18 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2021 Marvell.\n+ */\n+#ifndef __CNXK_TM_H__\n+#define __CNXK_TM_H__\n+\n+#include <stdbool.h>\n+\n+#include <rte_tm_driver.h>\n+\n+#include \"roc_api.h\"\n+\n+struct cnxk_nix_tm_node {\n+\tstruct roc_nix_tm_node nix_node;\n+\tstruct rte_tm_node_params params;\n+};\n+\n+#endif /* __CNXK_TM_H__ */\ndiff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build\nindex d4cdd1744a..1e86144755 100644\n--- a/drivers/net/cnxk/meson.build\n+++ b/drivers/net/cnxk/meson.build\n@@ -17,6 +17,7 @@ sources = files(\n         'cnxk_ptp.c',\n         'cnxk_rte_flow.c',\n         'cnxk_stats.c',\n+        'cnxk_tm.c',\n )\n \n # CN9K\n",
    "prefixes": [
        "v3",
        "7/8"
    ]
}