get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 88460,
    "url": "https://patches.dpdk.org/api/patches/88460/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210304090728.26166-2-kalesh-anakkur.purayil@broadcom.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": "<20210304090728.26166-2-kalesh-anakkur.purayil@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210304090728.26166-2-kalesh-anakkur.purayil@broadcom.com",
    "date": "2021-03-04T09:07:26",
    "name": "[1/3] net/bnxt: check flush status during ring free",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "8e1fd058aa35444d35b90a11bea551d1dc70259d",
    "submitter": {
        "id": 1479,
        "url": "https://patches.dpdk.org/api/people/1479/?format=api",
        "name": "Kalesh A P",
        "email": "kalesh-anakkur.purayil@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "https://patches.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210304090728.26166-2-kalesh-anakkur.purayil@broadcom.com/mbox/",
    "series": [
        {
            "id": 15488,
            "url": "https://patches.dpdk.org/api/series/15488/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=15488",
            "date": "2021-03-04T09:07:25",
            "name": "bnxt fixes",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/15488/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/88460/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/88460/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 A7276A0561;\n\tThu,  4 Mar 2021 09:45:19 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 71D904069B;\n\tThu,  4 Mar 2021 09:45:14 +0100 (CET)",
            "from relay.smtp-ext.broadcom.com (lpdvacalvio01.broadcom.com\n [192.19.229.182])\n by mails.dpdk.org (Postfix) with ESMTP id DBE9C40147\n for <dev@dpdk.org>; Thu,  4 Mar 2021 09:45:12 +0100 (CET)",
            "from dhcp-10-123-153-22.dhcp.broadcom.net\n (bgccx-dev-host-lnx2.bec.broadcom.net [10.123.153.22])\n by relay.smtp-ext.broadcom.com (Postfix) with ESMTP id 2E30D7A52;\n Thu,  4 Mar 2021 00:45:10 -0800 (PST)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 relay.smtp-ext.broadcom.com 2E30D7A52",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com;\n s=dkimrelay; t=1614847512;\n bh=kywByYhmNrhUup+Qs7wxveeMVtswWsOTgAyCn4j/szQ=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=dQ6JjAk43B9JC6HLZGNSUY4adW3q1OboXGuM5lqZqnXeWp/cOXZlJN6T/uGmhVIrU\n /udjBzQYAM5/j/Vgogkd/W7u+v5z3InaQI3B+261uOmYA0VuUM9Pk0NHmLTOfvo+Yu\n dvyCZG60PJfy/I/m5betoCi0BxD/3lxfGrYny4/g=",
        "From": "Kalesh A P <kalesh-anakkur.purayil@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com,\n\tajit.khaparde@broadcom.com",
        "Date": "Thu,  4 Mar 2021 14:37:26 +0530",
        "Message-Id": "<20210304090728.26166-2-kalesh-anakkur.purayil@broadcom.com>",
        "X-Mailer": "git-send-email 2.10.1",
        "In-Reply-To": "<20210304090728.26166-1-kalesh-anakkur.purayil@broadcom.com>",
        "References": "<20210304090728.26166-1-kalesh-anakkur.purayil@broadcom.com>",
        "Subject": "[dpdk-dev] [PATCH 1/3] net/bnxt: check flush status during ring free",
        "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: Ajit Khaparde <ajit.khaparde@broadcom.com>\n\nWhen host SW issues a HWRM_RING_FREE for Tx/Rx/AGG ring in HW,\nthe FW flushes the BDs associated with the ring and performs other\ncleanup in the HW. The host software should ideally check for an\nindication from the FW indicating this step has been completed\nsuccessfully to avoid unexpected errors during cleanup.\n\nThe FW issues a HWRM_DONE response to the RING_FREE request on\nthe corresponding CQ ring. Poll the CQs during cleanup and\nensure the HWRM_FREE command is completed not just based on the\nvalue of valid bit but also the HWRM_DONE response for the ring.\n\nIf the HWRM_DONE response is not seen, force the cleanup to\ncomplete just based on the valid bit.\n\nSigned-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\nReviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>\n---\n drivers/net/bnxt/bnxt_hwrm.c | 128 ++++++++++++++++++++++++++++++++++++++++---\n drivers/net/bnxt/bnxt_hwrm.h |   3 +-\n drivers/net/bnxt/bnxt_rxr.c  |  36 +++++++++++-\n drivers/net/bnxt/bnxt_rxr.h  |   1 +\n drivers/net/bnxt/bnxt_txr.c  |  36 ++++++++++++\n drivers/net/bnxt/bnxt_txr.h  |   1 +\n 6 files changed, 196 insertions(+), 9 deletions(-)",
    "diff": "diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c\nindex 0b5318e..02b0a21 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.c\n+++ b/drivers/net/bnxt/bnxt_hwrm.c\n@@ -75,6 +75,82 @@ static void bnxt_hwrm_set_pg_attr(struct bnxt_ring_mem_info *rmem,\n \t}\n }\n \n+static struct bnxt_cp_ring_info*\n+bnxt_get_ring_info_by_id(struct bnxt *bp, uint16_t rid, uint16_t type)\n+{\n+\tstruct bnxt_cp_ring_info *cp_ring = NULL;\n+\tuint16_t i;\n+\n+\tswitch (type) {\n+\tcase HWRM_RING_FREE_INPUT_RING_TYPE_RX:\n+\tcase HWRM_RING_FREE_INPUT_RING_TYPE_RX_AGG:\n+\t\t/* FALLTHROUGH */\n+\t\tfor (i = 0; i < bp->rx_cp_nr_rings; i++) {\n+\t\t\tstruct bnxt_rx_queue *rxq = bp->rx_queues[i];\n+\n+\t\t\tif (rxq->cp_ring->cp_ring_struct->fw_ring_id ==\n+\t\t\t    rte_cpu_to_le_16(rid)) {\n+\t\t\t\treturn rxq->cp_ring;\n+\t\t\t}\n+\t\t}\n+\t\tbreak;\n+\tcase HWRM_RING_FREE_INPUT_RING_TYPE_TX:\n+\t\tfor (i = 0; i < bp->tx_cp_nr_rings; i++) {\n+\t\t\tstruct bnxt_tx_queue *txq = bp->tx_queues[i];\n+\n+\t\t\tif (txq->cp_ring->cp_ring_struct->fw_ring_id ==\n+\t\t\t    rte_cpu_to_le_16(rid)) {\n+\t\t\t\treturn txq->cp_ring;\n+\t\t\t}\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\treturn cp_ring;\n+\t}\n+\treturn cp_ring;\n+}\n+\n+/* Complete a sweep of the CQ ring for the corresponding Tx/Rx/AGG ring.\n+ * If the CMPL_BASE_TYPE_HWRM_DONE is not encountered by the last pass,\n+ * before timeout, we force the done bit for the cleanup to proceed.\n+ * Also if cpr is null, do nothing.. The HWRM command is  not for a\n+ * Tx/Rx/AGG ring cleanup.\n+ */\n+static int\n+bnxt_check_cq_hwrm_done(struct bnxt_cp_ring_info *cpr,\n+\t\t\tbool tx, bool rx, bool timeout)\n+{\n+\tint done = 0;\n+\n+\tif (cpr != NULL) {\n+\t\tif (tx)\n+\t\t\tdone = bnxt_flush_tx_cmp(cpr);\n+\n+\t\tif (rx)\n+\t\t\tdone = bnxt_flush_rx_cmp(cpr);\n+\n+\t\tif (done)\n+\t\t\tPMD_DRV_LOG(DEBUG, \"HWRM DONE for %s ring\\n\",\n+\t\t\t\t    rx ? \"Rx\" : \"Tx\");\n+\n+\t\t/* We are about to timeout and still haven't seen the\n+\t\t * HWRM done for the Ring free. Force the cleanup.\n+\t\t */\n+\t\tif (!done && timeout) {\n+\t\t\tdone = 1;\n+\t\t\tPMD_DRV_LOG(DEBUG, \"Timing out for %s ring\\n\",\n+\t\t\t\t    rx ? \"Rx\" : \"Tx\");\n+\t\t}\n+\t} else {\n+\t\t/* This HWRM command is not for a Tx/Rx/AGG ring cleanup.\n+\t\t * Otherwise the cpr would have been valid. So do nothing.\n+\t\t */\n+\t\tdone = 1;\n+\t}\n+\n+\treturn done;\n+}\n+\n /*\n  * HWRM Functions (sent to HWRM)\n  * These are named bnxt_hwrm_*() and return 0 on success or -110 if the\n@@ -97,6 +173,9 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg,\n \t\tGRCPF_REG_KONG_CHANNEL_OFFSET : GRCPF_REG_CHIMP_CHANNEL_OFFSET;\n \tuint16_t mb_trigger_offset = use_kong_mb ?\n \t\tGRCPF_REG_KONG_COMM_TRIGGER : GRCPF_REG_CHIMP_COMM_TRIGGER;\n+\tstruct bnxt_cp_ring_info *cpr = NULL;\n+\tbool is_rx = false;\n+\tbool is_tx = false;\n \tuint32_t timeout;\n \n \t/* Do not send HWRM commands to firmware in error state */\n@@ -153,14 +232,42 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg,\n \t */\n \trte_io_mb();\n \n+\t/* Check ring flush is done.\n+\t * This is valid only for Tx and Rx rings (including AGG rings).\n+\t * The Tx and Rx rings should be freed once the HW confirms all\n+\t * the internal buffers and BDs associated with the rings are\n+\t * consumed and the corresponding DMA is handled.\n+\t */\n+\tif (rte_cpu_to_le_16(req->cmpl_ring) != INVALID_HW_RING_ID) {\n+\t\t/* Check if the TxCQ matches. If that fails check if RxCQ\n+\t\t * matches. And if neither match, is_rx = false, is_tx = false.\n+\t\t */\n+\t\tcpr = bnxt_get_ring_info_by_id(bp, req->cmpl_ring,\n+\t\t\t\t\t       HWRM_RING_FREE_INPUT_RING_TYPE_TX);\n+\t\tif (cpr == NULL) {\n+\t\t\t/* Not a TxCQ. Check if the RxCQ matches. */\n+\t\t\tcpr =\n+\t\t\tbnxt_get_ring_info_by_id(bp, req->cmpl_ring,\n+\t\t\t\t\t\t HWRM_RING_FREE_INPUT_RING_TYPE_RX);\n+\t\t\tif (cpr != NULL)\n+\t\t\t\tis_rx = true;\n+\t\t} else {\n+\t\t\tis_tx = true;\n+\t\t}\n+\t}\n+\n \t/* Poll for the valid bit */\n \tfor (i = 0; i < timeout; i++) {\n+\t\tint done;\n+\n+\t\tdone = bnxt_check_cq_hwrm_done(cpr, is_tx, is_rx,\n+\t\t\t\t\t       i == timeout - 1);\n \t\t/* Sanity check on the resp->resp_len */\n \t\trte_io_rmb();\n \t\tif (resp->resp_len && resp->resp_len <= bp->max_resp_len) {\n \t\t\t/* Last byte of resp contains the valid key */\n \t\t\tvalid = (uint8_t *)resp + resp->resp_len - 1;\n-\t\t\tif (*valid == HWRM_RESP_VALID_KEY)\n+\t\t\tif (*valid == HWRM_RESP_VALID_KEY && done)\n \t\t\t\tbreak;\n \t\t}\n \t\trte_delay_us(1);\n@@ -1672,7 +1779,8 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,\n }\n \n int bnxt_hwrm_ring_free(struct bnxt *bp,\n-\t\t\tstruct bnxt_ring *ring, uint32_t ring_type)\n+\t\t\tstruct bnxt_ring *ring, uint32_t ring_type,\n+\t\t\tuint16_t cp_ring_id)\n {\n \tint rc;\n \tstruct hwrm_ring_free_input req = {.req_type = 0 };\n@@ -1682,6 +1790,7 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,\n \n \treq.ring_type = ring_type;\n \treq.ring_id = rte_cpu_to_le_16(ring->fw_ring_id);\n+\treq.cmpl_ring = rte_cpu_to_le_16(cp_ring_id);\n \n \trc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);\n \n@@ -2541,7 +2650,8 @@ void bnxt_free_nq_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)\n \tstruct bnxt_ring *cp_ring = cpr->cp_ring_struct;\n \n \tbnxt_hwrm_ring_free(bp, cp_ring,\n-\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_NQ);\n+\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_NQ,\n+\t\t\t    INVALID_HW_RING_ID);\n \tcp_ring->fw_ring_id = INVALID_HW_RING_ID;\n \tmemset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *\n \t\t\t\t     sizeof(*cpr->cp_desc_ring));\n@@ -2554,7 +2664,8 @@ void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)\n \tstruct bnxt_ring *cp_ring = cpr->cp_ring_struct;\n \n \tbnxt_hwrm_ring_free(bp, cp_ring,\n-\t\t\tHWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL);\n+\t\t\tHWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL,\n+\t\t\tINVALID_HW_RING_ID);\n \tcp_ring->fw_ring_id = INVALID_HW_RING_ID;\n \tmemset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *\n \t\t\tsizeof(*cpr->cp_desc_ring));\n@@ -2571,7 +2682,8 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)\n \n \tif (ring->fw_ring_id != INVALID_HW_RING_ID) {\n \t\tbnxt_hwrm_ring_free(bp, ring,\n-\t\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_RX);\n+\t\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_RX,\n+\t\t\t\t    cpr->cp_ring_struct->fw_ring_id);\n \t\tring->fw_ring_id = INVALID_HW_RING_ID;\n \t\tif (BNXT_HAS_RING_GRPS(bp))\n \t\t\tbp->grp_info[queue_index].rx_fw_ring_id =\n@@ -2582,7 +2694,8 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)\n \t\tbnxt_hwrm_ring_free(bp, ring,\n \t\t\t\t    BNXT_CHIP_P5(bp) ?\n \t\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_RX_AGG :\n-\t\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_RX);\n+\t\t\t\t    HWRM_RING_FREE_INPUT_RING_TYPE_RX,\n+\t\t\t\t    cpr->cp_ring_struct->fw_ring_id);\n \t\tif (BNXT_HAS_RING_GRPS(bp))\n \t\t\tbp->grp_info[queue_index].ag_fw_ring_id =\n \t\t\t\t\t\t\tINVALID_HW_RING_ID;\n@@ -2607,7 +2720,8 @@ bnxt_free_all_hwrm_rings(struct bnxt *bp)\n \n \t\tif (ring->fw_ring_id != INVALID_HW_RING_ID) {\n \t\t\tbnxt_hwrm_ring_free(bp, ring,\n-\t\t\t\t\tHWRM_RING_FREE_INPUT_RING_TYPE_TX);\n+\t\t\t\t\tHWRM_RING_FREE_INPUT_RING_TYPE_TX,\n+\t\t\t\t\tcpr->cp_ring_struct->fw_ring_id);\n \t\t\tring->fw_ring_id = INVALID_HW_RING_ID;\n \t\t\tmemset(txr->tx_desc_ring, 0,\n \t\t\t\t\ttxr->tx_ring_struct->ring_size *\ndiff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h\nindex 785e321..3d05acf 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.h\n+++ b/drivers/net/bnxt/bnxt_hwrm.h\n@@ -162,7 +162,8 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,\n \t\t\t uint32_t stats_ctx_id, uint32_t cmpl_ring_id,\n \t\t\t uint16_t tx_cosq_id);\n int bnxt_hwrm_ring_free(struct bnxt *bp,\n-\t\t\tstruct bnxt_ring *ring, uint32_t ring_type);\n+\t\t\tstruct bnxt_ring *ring, uint32_t ring_type,\n+\t\t\tuint16_t cp_ring_id);\n int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx);\n int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned int idx);\n \ndiff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c\nindex 30d22b7..c72545a 100644\n--- a/drivers/net/bnxt/bnxt_rxr.c\n+++ b/drivers/net/bnxt/bnxt_rxr.c\n@@ -991,7 +991,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\t\t\t\tcpr->cp_ring_struct->ring_mask,\n \t\t\t\t\tcpr->valid);\n \n-\t\tif ((CMP_TYPE(rxcmp) >= CMPL_BASE_TYPE_RX_TPA_START_V2) &&\n+\t\tif (CMP_TYPE(rxcmp) == CMPL_BASE_TYPE_HWRM_DONE) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Rx flush done\\n\");\n+\t\t} else if ((CMP_TYPE(rxcmp) >= CMPL_BASE_TYPE_RX_TPA_START_V2) &&\n \t\t     (CMP_TYPE(rxcmp) <= RX_TPA_V2_ABUF_CMPL_TYPE_RX_TPA_AGG)) {\n \t\t\trc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);\n \t\t\tif (!rc)\n@@ -1291,3 +1293,35 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)\n \n \treturn 0;\n }\n+\n+/* Sweep the Rx completion queue till HWRM_DONE for ring flush is received.\n+ * The mbufs will not be freed in this call.\n+ * They will be freed during ring free as a part of mem cleanup.\n+ */\n+int bnxt_flush_rx_cmp(struct bnxt_cp_ring_info *cpr)\n+{\n+\tstruct bnxt_ring *cp_ring_struct = cpr->cp_ring_struct;\n+\tuint32_t ring_mask = cp_ring_struct->ring_mask;\n+\tuint32_t raw_cons = cpr->cp_raw_cons;\n+\tstruct rx_pkt_cmpl *rxcmp;\n+\tuint32_t nb_rx = 0;\n+\tuint32_t cons;\n+\n+\tdo {\n+\t\tcons = RING_CMP(cpr->cp_ring_struct, raw_cons);\n+\t\trxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];\n+\n+\t\tif (CMP_TYPE(rxcmp) == CMPL_BASE_TYPE_HWRM_DONE)\n+\t\t\treturn 1;\n+\n+\t\traw_cons = NEXT_RAW_CMP(raw_cons);\n+\t\tnb_rx++;\n+\t} while (nb_rx < ring_mask);\n+\n+\tcpr->cp_raw_cons = raw_cons;\n+\n+\t/* Ring the completion queue doorbell. */\n+\tbnxt_db_cq(cpr);\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h\nindex 06d1084..a6fdd77 100644\n--- a/drivers/net/bnxt/bnxt_rxr.h\n+++ b/drivers/net/bnxt/bnxt_rxr.h\n@@ -100,6 +100,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id);\n int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);\n int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);\n int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);\n+int bnxt_flush_rx_cmp(struct bnxt_cp_ring_info *cpr);\n \n #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)\n uint16_t bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,\ndiff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c\nindex 2810906..01db0cc 100644\n--- a/drivers/net/bnxt/bnxt_txr.c\n+++ b/drivers/net/bnxt/bnxt_txr.c\n@@ -569,3 +569,39 @@ int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)\n \n \treturn 0;\n }\n+\n+/* Sweep the Tx completion queue till HWRM_DONE for ring flush is received.\n+ * The mbufs will not be freed in this call.\n+ * They will be freed during ring free as a part of mem cleanup.\n+ */\n+int bnxt_flush_tx_cmp(struct bnxt_cp_ring_info *cpr)\n+{\n+\tuint32_t raw_cons = cpr->cp_raw_cons;\n+\tuint32_t cons;\n+\tuint32_t nb_tx_pkts = 0;\n+\tstruct tx_cmpl *txcmp;\n+\tstruct cmpl_base *cp_desc_ring = cpr->cp_desc_ring;\n+\tstruct bnxt_ring *cp_ring_struct = cpr->cp_ring_struct;\n+\tuint32_t ring_mask = cp_ring_struct->ring_mask;\n+\tuint32_t opaque = 0;\n+\n+\tdo {\n+\t\tcons = RING_CMPL(ring_mask, raw_cons);\n+\t\ttxcmp = (struct tx_cmpl *)&cp_desc_ring[cons];\n+\n+\t\topaque = rte_cpu_to_le_32(txcmp->opaque);\n+\t\traw_cons = NEXT_RAW_CMP(raw_cons);\n+\n+\t\tif (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)\n+\t\t\tnb_tx_pkts += opaque;\n+\t\telse if (CMP_TYPE(txcmp) == HWRM_CMPL_TYPE_HWRM_DONE)\n+\t\t\treturn 1;\n+\t} while (nb_tx_pkts < ring_mask);\n+\n+\tif (nb_tx_pkts) {\n+\t\tcpr->cp_raw_cons = raw_cons;\n+\t\tbnxt_db_cq(cpr);\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h\nindex 281a3e2..91e10db 100644\n--- a/drivers/net/bnxt/bnxt_txr.h\n+++ b/drivers/net/bnxt/bnxt_txr.h\n@@ -56,6 +56,7 @@ uint16_t bnxt_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,\n \n int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);\n int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);\n+int bnxt_flush_tx_cmp(struct bnxt_cp_ring_info *cpr);\n \n #define PKT_TX_OIP_IIP_TCP_UDP_CKSUM\t(PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \\\n \t\t\t\t\tPKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)\n",
    "prefixes": [
        "1/3"
    ]
}