get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 55700,
    "url": "http://patches.dpdk.org/api/patches/55700/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190630180609.36705-25-jerinj@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": "<20190630180609.36705-25-jerinj@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190630180609.36705-25-jerinj@marvell.com",
    "date": "2019-06-30T18:05:36",
    "name": "[v2,24/57] net/octeontx2: enable Tx through traffic manager",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "32ef16413ef2ab5a7d795f53d16e57ee723f3333",
    "submitter": {
        "id": 1188,
        "url": "http://patches.dpdk.org/api/people/1188/?format=api",
        "name": "Jerin Jacob Kollanukkaran",
        "email": "jerinj@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/20190630180609.36705-25-jerinj@marvell.com/mbox/",
    "series": [
        {
            "id": 5236,
            "url": "http://patches.dpdk.org/api/series/5236/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5236",
            "date": "2019-06-30T18:05:12",
            "name": "OCTEON TX2 Ethdev driver",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/5236/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/55700/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/55700/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id AF3F51BA9A;\n\tSun, 30 Jun 2019 20:08:25 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n\t[67.231.148.174]) by dpdk.org (Postfix) with ESMTP id 0B3621B965\n\tfor <dev@dpdk.org>; Sun, 30 Jun 2019 20:07:48 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n\tby mx0a-0016f401.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id\n\tx5UI73OH028454 for <dev@dpdk.org>; Sun, 30 Jun 2019 11:07:48 -0700",
            "from sc-exch02.marvell.com ([199.233.58.182])\n\tby mx0a-0016f401.pphosted.com with ESMTP id 2te5bn4ghw-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n\tfor <dev@dpdk.org>; Sun, 30 Jun 2019 11:07:48 -0700",
            "from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH02.marvell.com\n\t(10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1367.3;\n\tSun, 30 Jun 2019 11:07:46 -0700",
            "from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com\n\t(10.93.176.81) with Microsoft SMTP Server id 15.0.1367.3 via Frontend\n\tTransport; Sun, 30 Jun 2019 11:07:46 -0700",
            "from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14])\n\tby maili.marvell.com (Postfix) with ESMTP id 1A3313F703F;\n\tSun, 30 Jun 2019 11:07:44 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n\th=from : to : cc :\n\tsubject : date : message-id : in-reply-to : references : mime-version\n\t: content-transfer-encoding : content-type; s=pfpt0818;\n\tbh=TdoGfIVJlz6ICFHYT72X/PH4rFpLvgwIzTV2dNaQKPY=;\n\tb=mqTPbXd0TTa9gJaVOwNDG8yVZBN1R86ml6L5RpZOLhmHEYp4rSa9M9yovghRZp9ZOJB7\n\t6qopEnVvjycvxxyTDtWcAniQcX54UUuxpw2EOHfl7/oKGIwybz8y71qII4mtd9I+R+re\n\ttlTpbv9Hw9++5rq2P8Dz+pNiRE95OuZVbTTza24B/3mDJoICAQzryPsMsO6VdZBUFbrB\n\tOPJzhm0Y3qBXxZbIUwwb7LYo+nRoxygOkgxFI/GfTVJZNgDNXOeHgAD3Yg4fQMwGCdOv\n\trxCyAufOb/LlnJMutiWNfmEMD/IRGEIMEqV4cS0DITgbrasW7quVUshRIaAdYZmObCQ8\n\tWw== ",
        "From": "<jerinj@marvell.com>",
        "To": "<dev@dpdk.org>, Jerin Jacob <jerinj@marvell.com>, Nithin Dabilpuram\n\t<ndabilpuram@marvell.com>, Kiran Kumar K <kirankumark@marvell.com>",
        "CC": "Krzysztof Kanas <kkanas@marvell.com>, Vamsi Attunuru\n\t<vattunuru@marvell.com>",
        "Date": "Sun, 30 Jun 2019 23:35:36 +0530",
        "Message-ID": "<20190630180609.36705-25-jerinj@marvell.com>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20190630180609.36705-1-jerinj@marvell.com>",
        "References": "<20190602152434.23996-1-jerinj@marvell.com>\n\t<20190630180609.36705-1-jerinj@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10434:, ,\n\tdefinitions=2019-06-30_08:, , signatures=0",
        "Subject": "[dpdk-dev] [PATCH v2 24/57] net/octeontx2: enable Tx through\n\ttraffic manager",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Krzysztof Kanas <kkanas@marvell.com>\n\nThis patch enables pkt transmit through traffic manager\nhierarchy by clearing software XOFF on the nodes and linking\ntx queues to corresponding leaf nodes.\nIt also adds support to start and stop tx queue using\ntraffic manager.\n\nSigned-off-by: Krzysztof Kanas <kkanas@marvell.com>\nSigned-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>\nSigned-off-by: Vamsi Attunuru <vattunuru@marvell.com>\n---\n drivers/net/octeontx2/otx2_ethdev.c |  75 ++++++-\n drivers/net/octeontx2/otx2_tm.c     | 296 +++++++++++++++++++++++++++-\n drivers/net/octeontx2/otx2_tm.h     |   4 +\n 3 files changed, 370 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c\nindex 899865749..62b1e3d14 100644\n--- a/drivers/net/octeontx2/otx2_ethdev.c\n+++ b/drivers/net/octeontx2/otx2_ethdev.c\n@@ -120,6 +120,32 @@ nix_lf_free(struct otx2_eth_dev *dev)\n \treturn otx2_mbox_process(mbox);\n }\n \n+int\n+otx2_cgx_rxtx_start(struct otx2_eth_dev *dev)\n+{\n+\tstruct otx2_mbox *mbox = dev->mbox;\n+\n+\tif (otx2_dev_is_vf(dev))\n+\t\treturn 0;\n+\n+\totx2_mbox_alloc_msg_cgx_start_rxtx(mbox);\n+\n+\treturn otx2_mbox_process(mbox);\n+}\n+\n+int\n+otx2_cgx_rxtx_stop(struct otx2_eth_dev *dev)\n+{\n+\tstruct otx2_mbox *mbox = dev->mbox;\n+\n+\tif (otx2_dev_is_vf(dev))\n+\t\treturn 0;\n+\n+\totx2_mbox_alloc_msg_cgx_stop_rxtx(mbox);\n+\n+\treturn otx2_mbox_process(mbox);\n+}\n+\n static inline void\n nix_rx_queue_reset(struct otx2_eth_rxq *rxq)\n {\n@@ -461,16 +487,27 @@ nix_sq_init(struct otx2_eth_txq *txq)\n \tstruct otx2_eth_dev *dev = txq->dev;\n \tstruct otx2_mbox *mbox = dev->mbox;\n \tstruct nix_aq_enq_req *sq;\n+\tuint32_t rr_quantum;\n+\tuint16_t smq;\n+\tint rc;\n \n \tif (txq->sqb_pool->pool_id == 0)\n \t\treturn -EINVAL;\n \n+\trc = otx2_nix_tm_get_leaf_data(dev, txq->sq, &rr_quantum, &smq);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to get sq->smq(leaf node), rc=%d\", rc);\n+\t\treturn rc;\n+\t}\n+\n \tsq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);\n \tsq->qidx = txq->sq;\n \tsq->ctype = NIX_AQ_CTYPE_SQ;\n \tsq->op = NIX_AQ_INSTOP_INIT;\n \tsq->sq.max_sqe_size = nix_sq_max_sqe_sz(txq);\n \n+\tsq->sq.smq = smq;\n+\tsq->sq.smq_rr_quantum = rr_quantum;\n \tsq->sq.default_chan = dev->tx_chan_base;\n \tsq->sq.sqe_stype = NIX_STYPE_STF;\n \tsq->sq.ena = 1;\n@@ -692,12 +729,18 @@ static void\n otx2_nix_tx_queue_release(void *_txq)\n {\n \tstruct otx2_eth_txq *txq = _txq;\n+\tstruct rte_eth_dev *eth_dev;\n \n \tif (!txq)\n \t\treturn;\n \n+\teth_dev = txq->dev->eth_dev;\n+\n \totx2_nix_dbg(\"Releasing txq %u\", txq->sq);\n \n+\t/* Flush and disable tm */\n+\totx2_nix_tm_sw_xoff(txq, eth_dev->data->dev_started);\n+\n \t/* Free sqb's and disable sq */\n \tnix_sq_uninit(txq);\n \n@@ -1123,24 +1166,52 @@ int\n otx2_nix_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx)\n {\n \tstruct rte_eth_dev_data *data = eth_dev->data;\n+\tstruct otx2_eth_txq *txq;\n+\tint rc = -EINVAL;\n+\n+\ttxq = eth_dev->data->tx_queues[qidx];\n \n \tif (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED)\n \t\treturn 0;\n \n+\trc = otx2_nix_sq_sqb_aura_fc(txq, true);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to enable sqb aura fc, txq=%u, rc=%d\",\n+\t\t\t qidx, rc);\n+\t\tgoto done;\n+\t}\n+\n \tdata->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;\n-\treturn 0;\n+\n+done:\n+\treturn rc;\n }\n \n int\n otx2_nix_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)\n {\n \tstruct rte_eth_dev_data *data = eth_dev->data;\n+\tstruct otx2_eth_txq *txq;\n+\tint rc;\n+\n+\ttxq = eth_dev->data->tx_queues[qidx];\n \n \tif (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED)\n \t\treturn 0;\n \n+\ttxq->fc_cache_pkts = 0;\n+\n+\trc = otx2_nix_sq_sqb_aura_fc(txq, false);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to disable sqb aura fc, txq=%u, rc=%d\",\n+\t\t\t qidx, rc);\n+\t\tgoto done;\n+\t}\n+\n \tdata->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;\n-\treturn 0;\n+\n+done:\n+\treturn rc;\n }\n \n static int\ndiff --git a/drivers/net/octeontx2/otx2_tm.c b/drivers/net/octeontx2/otx2_tm.c\nindex c6154e4d4..246920695 100644\n--- a/drivers/net/octeontx2/otx2_tm.c\n+++ b/drivers/net/octeontx2/otx2_tm.c\n@@ -676,6 +676,224 @@ nix_tm_clear_shaper_profiles(struct otx2_eth_dev *dev)\n \treturn 0;\n }\n \n+static int\n+nix_smq_xoff(struct otx2_eth_dev *dev, uint16_t smq, bool enable)\n+{\n+\tstruct otx2_mbox *mbox = dev->mbox;\n+\tstruct nix_txschq_config *req;\n+\n+\treq = otx2_mbox_alloc_msg_nix_txschq_cfg(mbox);\n+\treq->lvl = NIX_TXSCH_LVL_SMQ;\n+\treq->num_regs = 1;\n+\n+\treq->reg[0] = NIX_AF_SMQX_CFG(smq);\n+\t/* Unmodified fields */\n+\treq->regval[0] = ((uint64_t)NIX_MAX_VTAG_INS << 36) |\n+\t\t\t\t(NIX_MAX_HW_FRS << 8) | NIX_MIN_HW_FRS;\n+\n+\tif (enable)\n+\t\treq->regval[0] |= BIT_ULL(50) | BIT_ULL(49);\n+\telse\n+\t\treq->regval[0] |= 0;\n+\n+\treturn otx2_mbox_process(mbox);\n+}\n+\n+int\n+otx2_nix_sq_sqb_aura_fc(void *__txq, bool enable)\n+{\n+\tstruct otx2_eth_txq *txq = __txq;\n+\tstruct npa_aq_enq_req *req;\n+\tstruct npa_aq_enq_rsp *rsp;\n+\tstruct otx2_npa_lf *lf;\n+\tstruct otx2_mbox *mbox;\n+\tuint64_t aura_handle;\n+\tint rc;\n+\n+\tlf = otx2_npa_lf_obj_get();\n+\tif (!lf)\n+\t\treturn -EFAULT;\n+\tmbox = lf->mbox;\n+\t/* Set/clear sqb aura fc_ena */\n+\taura_handle = txq->sqb_pool->pool_id;\n+\treq = otx2_mbox_alloc_msg_npa_aq_enq(mbox);\n+\n+\treq->aura_id = npa_lf_aura_handle_to_aura(aura_handle);\n+\treq->ctype = NPA_AQ_CTYPE_AURA;\n+\treq->op = NPA_AQ_INSTOP_WRITE;\n+\t/* Below is not needed for aura writes but AF driver needs it */\n+\t/* AF will translate to associated poolctx */\n+\treq->aura.pool_addr = req->aura_id;\n+\n+\treq->aura.fc_ena = enable;\n+\treq->aura_mask.fc_ena = 1;\n+\n+\trc = otx2_mbox_process(mbox);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Read back npa aura ctx */\n+\treq = otx2_mbox_alloc_msg_npa_aq_enq(mbox);\n+\n+\treq->aura_id = npa_lf_aura_handle_to_aura(aura_handle);\n+\treq->ctype = NPA_AQ_CTYPE_AURA;\n+\treq->op = NPA_AQ_INSTOP_READ;\n+\n+\trc = otx2_mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Init when enabled as there might be no triggers */\n+\tif (enable)\n+\t\t*(volatile uint64_t *)txq->fc_mem = rsp->aura.count;\n+\telse\n+\t\t*(volatile uint64_t *)txq->fc_mem = txq->nb_sqb_bufs;\n+\t/* Sync write barrier */\n+\trte_wmb();\n+\n+\treturn 0;\n+}\n+\n+static void\n+nix_txq_flush_sq_spin(struct otx2_eth_txq *txq)\n+{\n+\tuint16_t sqb_cnt, head_off, tail_off;\n+\tstruct otx2_eth_dev *dev = txq->dev;\n+\tuint16_t sq = txq->sq;\n+\tuint64_t reg, val;\n+\tint64_t *regaddr;\n+\n+\twhile (true) {\n+\t\treg = ((uint64_t)sq << 32);\n+\t\tregaddr = (int64_t *)(dev->base + NIX_LF_SQ_OP_PKTS);\n+\t\tval = otx2_atomic64_add_nosync(reg, regaddr);\n+\n+\t\tregaddr = (int64_t *)(dev->base + NIX_LF_SQ_OP_STATUS);\n+\t\tval = otx2_atomic64_add_nosync(reg, regaddr);\n+\t\tsqb_cnt = val & 0xFFFF;\n+\t\thead_off = (val >> 20) & 0x3F;\n+\t\ttail_off = (val >> 28) & 0x3F;\n+\n+\t\t/* SQ reached quiescent state */\n+\t\tif (sqb_cnt <= 1 && head_off == tail_off &&\n+\t\t    (*txq->fc_mem == txq->nb_sqb_bufs)) {\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\trte_pause();\n+\t}\n+}\n+\n+int\n+otx2_nix_tm_sw_xoff(void *__txq, bool dev_started)\n+{\n+\tstruct otx2_eth_txq *txq = __txq;\n+\tstruct otx2_eth_dev *dev = txq->dev;\n+\tstruct otx2_mbox *mbox = dev->mbox;\n+\tstruct nix_aq_enq_req *req;\n+\tstruct nix_aq_enq_rsp *rsp;\n+\tuint16_t smq;\n+\tint rc;\n+\n+\t/* Get smq from sq */\n+\treq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);\n+\treq->qidx = txq->sq;\n+\treq->ctype = NIX_AQ_CTYPE_SQ;\n+\treq->op = NIX_AQ_INSTOP_READ;\n+\trc = otx2_mbox_process_msg(mbox, (void *)&rsp);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to get smq, rc=%d\", rc);\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* Check if sq is enabled */\n+\tif (!rsp->sq.ena)\n+\t\treturn 0;\n+\n+\tsmq = rsp->sq.smq;\n+\n+\t/* Enable CGX RXTX to drain pkts */\n+\tif (!dev_started) {\n+\t\trc = otx2_cgx_rxtx_start(dev);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\trc = otx2_nix_sq_sqb_aura_fc(txq, false);\n+\tif (rc < 0) {\n+\t\totx2_err(\"Failed to disable sqb aura fc, rc=%d\", rc);\n+\t\tgoto cleanup;\n+\t}\n+\n+\t/* Disable smq xoff for case it was enabled earlier */\n+\trc = nix_smq_xoff(dev, smq, false);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to enable smq for sq %u, rc=%d\", txq->sq, rc);\n+\t\tgoto cleanup;\n+\t}\n+\n+\t/* Wait for sq entries to be flushed */\n+\tnix_txq_flush_sq_spin(txq);\n+\n+\t/* Flush and enable smq xoff */\n+\trc = nix_smq_xoff(dev, smq, true);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to disable smq for sq %u, rc=%d\", txq->sq, rc);\n+\t\treturn rc;\n+\t}\n+\n+cleanup:\n+\t/* Restore cgx state */\n+\tif (!dev_started)\n+\t\trc |= otx2_cgx_rxtx_stop(dev);\n+\n+\treturn rc;\n+}\n+\n+static int\n+nix_tm_sw_xon(struct otx2_eth_txq *txq,\n+\t      uint16_t smq, uint32_t rr_quantum)\n+{\n+\tstruct otx2_eth_dev *dev = txq->dev;\n+\tstruct otx2_mbox *mbox = dev->mbox;\n+\tstruct nix_aq_enq_req *req;\n+\tint rc;\n+\n+\totx2_tm_dbg(\"Enabling sq(%u)->smq(%u), rr_quantum %u\",\n+\t\t    txq->sq, txq->sq, rr_quantum);\n+\t/* Set smq from sq */\n+\treq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);\n+\treq->qidx = txq->sq;\n+\treq->ctype = NIX_AQ_CTYPE_SQ;\n+\treq->op = NIX_AQ_INSTOP_WRITE;\n+\treq->sq.smq = smq;\n+\treq->sq.smq_rr_quantum = rr_quantum;\n+\treq->sq_mask.smq = ~req->sq_mask.smq;\n+\treq->sq_mask.smq_rr_quantum = ~req->sq_mask.smq_rr_quantum;\n+\n+\trc = otx2_mbox_process(mbox);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to set smq, rc=%d\", rc);\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* Enable sqb_aura fc */\n+\trc = otx2_nix_sq_sqb_aura_fc(txq, true);\n+\tif (rc < 0) {\n+\t\totx2_err(\"Failed to enable sqb aura fc, rc=%d\", rc);\n+\t\treturn rc;\n+\t}\n+\n+\t/* Disable smq xoff */\n+\trc = nix_smq_xoff(dev, smq, false);\n+\tif (rc) {\n+\t\totx2_err(\"Failed to enable smq for sq %u\", txq->sq);\n+\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n nix_tm_free_resources(struct otx2_eth_dev *dev, uint32_t flags_mask,\n \t\t      uint32_t flags, bool hw_only)\n@@ -929,10 +1147,11 @@ static int\n nix_tm_alloc_resources(struct rte_eth_dev *eth_dev, bool xmit_enable)\n {\n \tstruct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);\n+\tstruct otx2_nix_tm_node *tm_node;\n+\tuint16_t sq, smq, rr_quantum;\n+\tstruct otx2_eth_txq *txq;\n \tint rc;\n \n-\tRTE_SET_USED(xmit_enable);\n-\n \tnix_tm_update_parent_info(dev);\n \n \trc = nix_tm_send_txsch_alloc_msg(dev);\n@@ -947,7 +1166,43 @@ nix_tm_alloc_resources(struct rte_eth_dev *eth_dev, bool xmit_enable)\n \t\treturn rc;\n \t}\n \n-\treturn 0;\n+\t/* Enable xmit as all the topology is ready */\n+\tTAILQ_FOREACH(tm_node, &dev->node_list, node) {\n+\t\tif (tm_node->flags & NIX_TM_NODE_ENABLED)\n+\t\t\tcontinue;\n+\n+\t\t/* Enable xmit on sq */\n+\t\tif (tm_node->level_id != OTX2_TM_LVL_QUEUE) {\n+\t\t\ttm_node->flags |= NIX_TM_NODE_ENABLED;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Don't enable SMQ or mark as enable */\n+\t\tif (!xmit_enable)\n+\t\t\tcontinue;\n+\n+\t\tsq = tm_node->id;\n+\t\tif (sq > eth_dev->data->nb_tx_queues) {\n+\t\t\trc = -EFAULT;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\ttxq = eth_dev->data->tx_queues[sq];\n+\n+\t\tsmq = tm_node->parent->hw_id;\n+\t\trr_quantum = (tm_node->weight *\n+\t\t\t      NIX_TM_RR_QUANTUM_MAX) / MAX_SCHED_WEIGHT;\n+\n+\t\trc = nix_tm_sw_xon(txq, smq, rr_quantum);\n+\t\tif (rc)\n+\t\t\tbreak;\n+\t\ttm_node->flags |= NIX_TM_NODE_ENABLED;\n+\t}\n+\n+\tif (rc)\n+\t\totx2_err(\"TM failed to enable xmit on sq %u, rc=%d\", sq, rc);\n+\n+\treturn rc;\n }\n \n static int\n@@ -1104,3 +1359,38 @@ otx2_nix_tm_fini(struct rte_eth_dev *eth_dev)\n \tdev->tm_flags = 0;\n \treturn 0;\n }\n+\n+int\n+otx2_nix_tm_get_leaf_data(struct otx2_eth_dev *dev, uint16_t sq,\n+\t\t\t  uint32_t *rr_quantum, uint16_t *smq)\n+{\n+\tstruct otx2_nix_tm_node *tm_node;\n+\tint rc;\n+\n+\t/* 0..sq_cnt-1 are leaf nodes */\n+\tif (sq >= dev->tm_leaf_cnt)\n+\t\treturn -EINVAL;\n+\n+\t/* Search for internal node first */\n+\ttm_node = nix_tm_node_search(dev, sq, false);\n+\tif (!tm_node)\n+\t\ttm_node = nix_tm_node_search(dev, sq, true);\n+\n+\t/* Check if we found a valid leaf node */\n+\tif (!tm_node || tm_node->level_id != OTX2_TM_LVL_QUEUE ||\n+\t    !tm_node->parent || tm_node->parent->hw_id == UINT32_MAX) {\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* Get SMQ Id of leaf node's parent */\n+\t*smq = tm_node->parent->hw_id;\n+\t*rr_quantum = (tm_node->weight * NIX_TM_RR_QUANTUM_MAX)\n+\t\t/ MAX_SCHED_WEIGHT;\n+\n+\trc = nix_smq_xoff(dev, *smq, false);\n+\tif (rc)\n+\t\treturn rc;\n+\ttm_node->flags |= NIX_TM_NODE_ENABLED;\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/octeontx2/otx2_tm.h b/drivers/net/octeontx2/otx2_tm.h\nindex af1bb1862..2a009eece 100644\n--- a/drivers/net/octeontx2/otx2_tm.h\n+++ b/drivers/net/octeontx2/otx2_tm.h\n@@ -16,6 +16,10 @@ struct otx2_eth_dev;\n void otx2_nix_tm_conf_init(struct rte_eth_dev *eth_dev);\n int otx2_nix_tm_init_default(struct rte_eth_dev *eth_dev);\n int otx2_nix_tm_fini(struct rte_eth_dev *eth_dev);\n+int otx2_nix_tm_get_leaf_data(struct otx2_eth_dev *dev, uint16_t sq,\n+\t\t\t      uint32_t *rr_quantum, uint16_t *smq);\n+int otx2_nix_tm_sw_xoff(void *_txq, bool dev_started);\n+int otx2_nix_sq_sqb_aura_fc(void *_txq, bool enable);\n \n struct otx2_nix_tm_node {\n \tTAILQ_ENTRY(otx2_nix_tm_node) node;\n",
    "prefixes": [
        "v2",
        "24/57"
    ]
}