get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 105263,
    "url": "http://patches.dpdk.org/api/patches/105263/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/9264e7c8882285da4980a4dda44d6690cecb5737.1639636621.git.songyl@ramaxel.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": "<9264e7c8882285da4980a4dda44d6690cecb5737.1639636621.git.songyl@ramaxel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/9264e7c8882285da4980a4dda44d6690cecb5737.1639636621.git.songyl@ramaxel.com",
    "date": "2021-12-18T02:51:51",
    "name": "[v1,24/25] net/spnic: support Tx/Rx queue start/stop",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "dadd5780fbaf911023ac2277eb80a3d679e92454",
    "submitter": {
        "id": 2455,
        "url": "http://patches.dpdk.org/api/people/2455/?format=api",
        "name": "Yanling Song",
        "email": "songyl@ramaxel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/9264e7c8882285da4980a4dda44d6690cecb5737.1639636621.git.songyl@ramaxel.com/mbox/",
    "series": [
        {
            "id": 20973,
            "url": "http://patches.dpdk.org/api/series/20973/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=20973",
            "date": "2021-12-18T02:51:28",
            "name": "Net/SPNIC: support SPNIC into DPDK 22.03",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/20973/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/105263/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/105263/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 7DC42A04A4;\n\tSat, 18 Dec 2021 03:55:25 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7E8604270A;\n\tSat, 18 Dec 2021 03:52:55 +0100 (CET)",
            "from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id E8F024013F\n for <dev@dpdk.org>; Sat, 18 Dec 2021 03:52:49 +0100 (CET)",
            "from V12DG1MBS01.ramaxel.local (v12dg1mbs01.ramaxel.local\n [172.26.18.31])\n by VLXDG1SPAM1.ramaxel.com with ESMTPS id 1BI2q3AM010367\n (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);\n Sat, 18 Dec 2021 10:52:04 +0800 (GMT-8)\n (envelope-from songyl@ramaxel.com)",
            "from localhost.localdomain (10.64.9.47) by V12DG1MBS01.ramaxel.local\n (172.26.18.31) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Sat, 18\n Dec 2021 10:52:03 +0800"
        ],
        "From": "Yanling Song <songyl@ramaxel.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<songyl@ramaxel.com>, <yanling.song@linux.dev>, <yanggan@ramaxel.com>,\n <ferruh.yigit@intel.com>",
        "Subject": "[PATCH v1 24/25] net/spnic: support Tx/Rx queue start/stop",
        "Date": "Sat, 18 Dec 2021 10:51:51 +0800",
        "Message-ID": "\n <9264e7c8882285da4980a4dda44d6690cecb5737.1639636621.git.songyl@ramaxel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<cover.1639636621.git.songyl@ramaxel.com>",
        "References": "<cover.1639636621.git.songyl@ramaxel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.9.47]",
        "X-ClientProxiedBy": "V12DG1MBS01.ramaxel.local (172.26.18.31) To\n V12DG1MBS01.ramaxel.local (172.26.18.31)",
        "X-DNSRBL": "",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 1BI2q3AM010367",
        "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": "This commit support starting or stopping a specified Rx/Tx queue\nFor Rx queue:\n    when startting rx queue, mbuf will be allocated and fill rq\nwqe with mbuf info, then add the qid to indirect table of RSS.\nif the first rx queue is started, the valid bit in function table\nwill be setted so that the packets can be received to host.\n    when stopping rx queue, the PMD driver will poll the rx queue\nuntil it is empty and release the mbuf, then the PMD driver will\nremove the qid for RSS indirect table. if the last rx queue is\nstopped, the valid bit in function table will be cleared.\n\nFor Rx queue:\n    when stopping tx queue, the PMD driver will wait until all tx\npackets are sent and then releases all mbuf.\n\nSigned-off-by: Yanling Song <songyl@ramaxel.com>\n---\n drivers/net/spnic/base/spnic_nic_cfg.c |  33 ++++\n drivers/net/spnic/base/spnic_nic_cfg.h |  13 ++\n drivers/net/spnic/spnic_ethdev.c       |  82 +++++++++\n drivers/net/spnic/spnic_rx.c           | 222 +++++++++++++++++++++++++\n drivers/net/spnic/spnic_rx.h           |   4 +\n 5 files changed, 354 insertions(+)",
    "diff": "diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c\nindex ce77b306db..934f11a881 100644\n--- a/drivers/net/spnic/base/spnic_nic_cfg.c\n+++ b/drivers/net/spnic/base/spnic_nic_cfg.c\n@@ -1289,6 +1289,39 @@ int spnic_vf_get_default_cos(void *hwdev, u8 *cos_id)\n \treturn 0;\n }\n \n+int spnic_set_rq_flush(void *hwdev, u16 q_id)\n+{\n+\tstruct spnic_cmd_set_rq_flush *rq_flush_msg = NULL;\n+\tstruct spnic_cmd_buf *cmd_buf = NULL;\n+\tu64 out_param = EIO;\n+\tint err;\n+\n+\tcmd_buf = spnic_alloc_cmd_buf(hwdev);\n+\tif (!cmd_buf) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate cmd buf\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tcmd_buf->size = sizeof(*rq_flush_msg);\n+\n+\trq_flush_msg = cmd_buf->buf;\n+\trq_flush_msg->local_rq_id = q_id;\n+\trq_flush_msg->value = cpu_to_be32(rq_flush_msg->value);\n+\n+\terr = spnic_cmdq_direct_resp(hwdev, SPNIC_MOD_L2NIC,\n+\t\t\t\t     SPNIC_UCODE_CMD_SET_RQ_FLUSH, cmd_buf,\n+\t\t\t\t     &out_param, 0);\n+\tif (err || out_param != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set rq flush, err:%d, out_param: %\"PRIu64\"\",\n+\t\t\t    err, out_param);\n+\t\terr = -EFAULT;\n+\t}\n+\n+\tspnic_free_cmd_buf(cmd_buf);\n+\n+\treturn err;\n+}\n+\n static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,\n \t\t\t\t u16 in_size, void *buf_out, u16 *out_size)\n {\ndiff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h\nindex e5e4ffea4b..e4b4a52d32 100644\n--- a/drivers/net/spnic/base/spnic_nic_cfg.h\n+++ b/drivers/net/spnic/base/spnic_nic_cfg.h\n@@ -1069,6 +1069,19 @@ int spnic_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);\n  */\n int spnic_vf_get_default_cos(void *hwdev, u8 *cos_id);\n \n+/**\n+ * Flush rx queue resource\n+ *\n+ * @param[in] hwdev\n+ *   Device pointer to hwdev\n+ * @param[in] q_id\n+ *   rx queue id\n+ *\n+ * @retval zero : Success\n+ * @retval non-zero : Failure\n+ */\n+int spnic_set_rq_flush(void *hwdev, u16 q_id);\n+\n /**\n  * Get service feature HW supported\n  *\ndiff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c\nindex e4db4afdfd..ff50715120 100644\n--- a/drivers/net/spnic/spnic_ethdev.c\n+++ b/drivers/net/spnic/spnic_ethdev.c\n@@ -993,6 +993,80 @@ static void spnic_deinit_mac_addr(struct rte_eth_dev *eth_dev)\n \tspnic_delete_mc_addr_list(nic_dev);\n }\n \n+static int spnic_dev_rx_queue_start(__rte_unused struct rte_eth_dev *dev,\n+\t\t\t\t     __rte_unused uint16_t rq_id)\n+{\n+\tstruct spnic_rxq *rxq = NULL;\n+\tint rc;\n+\n+\tif (rq_id < dev->data->nb_rx_queues) {\n+\t\trxq = dev->data->rx_queues[rq_id];\n+\n+\t\trc = spnic_start_rq(dev, rxq);\n+\t\tif (rc) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Start rx queue failed, eth_dev:%s, queue_idx:%d\",\n+\t\t\t\t\tdev->data->name, rq_id);\n+\t\t\treturn rc;\n+\t\t}\n+\n+\t\tdev->data->rx_queue_state[rq_id] = RTE_ETH_QUEUE_STATE_STARTED;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int spnic_dev_rx_queue_stop(__rte_unused struct rte_eth_dev *dev,\n+\t\t\t\t    __rte_unused uint16_t rq_id)\n+{\n+\tstruct spnic_rxq *rxq = NULL;\n+\tint rc;\n+\n+\tif (rq_id < dev->data->nb_rx_queues) {\n+\t\trxq = dev->data->rx_queues[rq_id];\n+\n+\t\trc = spnic_stop_rq(dev, rxq);\n+\t\tif (rc) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Stop rx queue failed, eth_dev:%s, queue_idx:%d\",\n+\t\t\t\t\tdev->data->name, rq_id);\n+\t\t\treturn rc;\n+\t\t}\n+\n+\t\tdev->data->rx_queue_state[rq_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int spnic_dev_tx_queue_start(__rte_unused struct rte_eth_dev *dev,\n+\t\t\t\t     __rte_unused uint16_t sq_id)\n+{\n+\tPMD_DRV_LOG(INFO, \"Start tx queue, eth_dev:%s, queue_idx:%d\",\n+\t\t   dev->data->name, sq_id);\n+\tdev->data->tx_queue_state[sq_id] = RTE_ETH_QUEUE_STATE_STARTED;\n+\treturn 0;\n+}\n+\n+static int spnic_dev_tx_queue_stop(__rte_unused struct rte_eth_dev *dev,\n+\t\t\t\t    __rte_unused uint16_t sq_id)\n+{\n+\tstruct spnic_txq *txq = NULL;\n+\tint rc;\n+\n+\tif (sq_id < dev->data->nb_tx_queues) {\n+\t\ttxq = dev->data->tx_queues[sq_id];\n+\t\trc = spnic_stop_sq(txq);\n+\t\tif (rc) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Stop tx queue failed, eth_dev:%s, queue_idx:%d\",\n+\t\t\t\t   dev->data->name, sq_id);\n+\t\t\treturn rc;\n+\t\t}\n+\n+\t\tdev->data->tx_queue_state[sq_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\t}\n+\n+\treturn 0;\n+}\n+\n int spnic_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,\n \t\t\t\t    uint16_t queue_id)\n {\n@@ -2717,6 +2791,10 @@ static const struct eth_dev_ops spnic_pmd_ops = {\n \t.tx_queue_setup                = spnic_tx_queue_setup,\n \t.rx_queue_release              = spnic_rx_queue_release,\n \t.tx_queue_release              = spnic_tx_queue_release,\n+\t.rx_queue_start                = spnic_dev_rx_queue_start,\n+\t.rx_queue_stop                 = spnic_dev_rx_queue_stop,\n+\t.tx_queue_start                = spnic_dev_tx_queue_start,\n+\t.tx_queue_stop                 = spnic_dev_tx_queue_stop,\n \t.rx_queue_intr_enable          = spnic_dev_rx_queue_intr_enable,\n \t.rx_queue_intr_disable         = spnic_dev_rx_queue_intr_disable,\n \t.dev_start                     = spnic_dev_start,\n@@ -2756,6 +2834,10 @@ static const struct eth_dev_ops spnic_pmd_vf_ops = {\n \t.tx_queue_setup                = spnic_tx_queue_setup,\n \t.rx_queue_intr_enable          = spnic_dev_rx_queue_intr_enable,\n \t.rx_queue_intr_disable         = spnic_dev_rx_queue_intr_disable,\n+\t.rx_queue_start                = spnic_dev_rx_queue_start,\n+\t.rx_queue_stop                 = spnic_dev_rx_queue_stop,\n+\t.tx_queue_start                = spnic_dev_tx_queue_start,\n+\t.tx_queue_stop                 = spnic_dev_tx_queue_stop,\n \t.dev_start                     = spnic_dev_start,\n \t.link_update                   = spnic_link_update,\n \t.rx_queue_release              = spnic_rx_queue_release,\ndiff --git a/drivers/net/spnic/spnic_rx.c b/drivers/net/spnic/spnic_rx.c\nindex f990d10be4..cba746df88 100644\n--- a/drivers/net/spnic/spnic_rx.c\n+++ b/drivers/net/spnic/spnic_rx.c\n@@ -486,6 +486,228 @@ void spnic_remove_rq_from_rx_queue_list(struct spnic_nic_dev *nic_dev,\n \tnic_dev->num_rss = rss_queue_count;\n }\n \n+static void spnic_rx_queue_release_mbufs(struct spnic_rxq *rxq)\n+{\n+\tu16 sw_ci, ci_mask, free_wqebbs;\n+\tu16 rx_buf_len;\n+\tu32 status, vlan_len, pkt_len;\n+\tu32 pkt_left_len = 0;\n+\tu32 nr_released = 0;\n+\tstruct spnic_rx_info *rx_info;\n+\tvolatile struct spnic_rq_cqe *rx_cqe;\n+\n+\tsw_ci = spnic_get_rq_local_ci(rxq);\n+\trx_info = &rxq->rx_info[sw_ci];\n+\trx_cqe = &rxq->rx_cqe[sw_ci];\n+\tfree_wqebbs = (u16)(spnic_get_rq_free_wqebb(rxq) + 1);\n+\tstatus = rx_cqe->status;\n+\tci_mask = rxq->q_mask;\n+\n+\twhile (free_wqebbs < rxq->q_depth) {\n+\t\trx_buf_len = rxq->buf_len;\n+\t\tif (pkt_left_len != 0) {\n+\t\t\t/* flush continues jumbo rqe */\n+\t\t\tpkt_left_len = (pkt_left_len <= rx_buf_len) ? 0 :\n+\t\t\t\t       (pkt_left_len - rx_buf_len);\n+\t\t} else if (SPNIC_GET_RX_FLUSH(status)) {\n+\t\t\t/* flush one released rqe */\n+\t\t\tpkt_left_len = 0;\n+\t\t} else if (SPNIC_GET_RX_DONE(status)) {\n+\t\t\t/* flush single packet or  first jumbo rqe */\n+\t\t\tvlan_len = rx_cqe->vlan_len;\n+\t\t\tpkt_len = SPNIC_GET_RX_PKT_LEN(vlan_len);\n+\t\t\tpkt_left_len = (pkt_len <= rx_buf_len) ? 0 :\n+\t\t\t\t       (pkt_len - rx_buf_len);\n+\t\t} else {\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\trte_pktmbuf_free(rx_info->mbuf);\n+\n+\t\trx_info->mbuf = NULL;\n+\t\trx_cqe->status = 0;\n+\t\tnr_released++;\n+\t\tfree_wqebbs++;\n+\n+\t\t/* see next cqe */\n+\t\tsw_ci++;\n+\t\tsw_ci &= ci_mask;\n+\t\trx_info = &rxq->rx_info[sw_ci];\n+\t\trx_cqe = &rxq->rx_cqe[sw_ci];\n+\t\tstatus = rx_cqe->status;\n+\t}\n+\n+\tspnic_update_rq_local_ci(rxq, nr_released);\n+}\n+\n+int spnic_poll_rq_empty(struct spnic_rxq *rxq)\n+{\n+\tunsigned long timeout;\n+\tint free_wqebb;\n+\tint err = -EFAULT;\n+\n+\ttimeout = msecs_to_jiffies(SPNIC_FLUSH_QUEUE_TIMEOUT) + jiffies;\n+\tdo {\n+\t\tfree_wqebb = spnic_get_rq_free_wqebb(rxq) + 1;\n+\t\tif (free_wqebb == rxq->q_depth) {\n+\t\t\terr = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t\tspnic_rx_queue_release_mbufs(rxq);\n+\t\trte_delay_us(1);\n+\t} while (time_before(jiffies, timeout));\n+\n+\treturn err;\n+}\n+\n+void spnic_dump_cqe_status(struct spnic_rxq *rxq, u32 *cqe_done_cnt,\n+\t\t\t    u32 *cqe_hole_cnt, u32 *head_ci,\n+\t\t\t    u32 *head_done)\n+{\n+\tu16 sw_ci;\n+\tu16 avail_pkts = 0;\n+\tu16 hit_done = 0;\n+\tu16 cqe_hole = 0;\n+\tu32 status;\n+\tvolatile struct spnic_rq_cqe *rx_cqe;\n+\n+\tsw_ci = spnic_get_rq_local_ci(rxq);\n+\trx_cqe = &rxq->rx_cqe[sw_ci];\n+\tstatus = rx_cqe->status;\n+\t*head_done = SPNIC_GET_RX_DONE(status);\n+\t*head_ci = sw_ci;\n+\n+\tfor (sw_ci = 0; sw_ci < rxq->q_depth; sw_ci++) {\n+\t\trx_cqe = &rxq->rx_cqe[sw_ci];\n+\n+\t\t/* test current ci is done */\n+\t\tstatus = rx_cqe->status;\n+\t\tif (!SPNIC_GET_RX_DONE(status) ||\n+\t\t    !SPNIC_GET_RX_FLUSH(status)) {\n+\t\t\tif (hit_done) {\n+\t\t\t\tcqe_hole++;\n+\t\t\t\thit_done = 0;\n+\t\t\t}\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tavail_pkts++;\n+\t\thit_done = 1;\n+\t}\n+\n+\t*cqe_done_cnt = avail_pkts;\n+\t*cqe_hole_cnt = cqe_hole;\n+}\n+\n+int spnic_stop_rq(struct rte_eth_dev *eth_dev, struct spnic_rxq *rxq)\n+{\n+\tstruct spnic_nic_dev *nic_dev = rxq->nic_dev;\n+\tu32 cqe_done_cnt = 0;\n+\tu32 cqe_hole_cnt = 0;\n+\tu32 head_ci, head_done;\n+\tint err;\n+\n+\t/* disable rxq intr */\n+\tspnic_dev_rx_queue_intr_disable(eth_dev, rxq->q_id);\n+\n+\t/* lock dev queue switch  */\n+\trte_spinlock_lock(&nic_dev->queue_list_lock);\n+\n+\tspnic_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);\n+\n+\tif (nic_dev->rss_state == SPNIC_RSS_ENABLE) {\n+\t\terr = spnic_refill_indir_rqid(rxq);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Clear rq in indirect table failed, eth_dev:%s, queue_idx:%d\\n\",\n+\t\t\t\t    nic_dev->dev_name, rxq->q_id);\n+\t\t\tspnic_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);\n+\t\t\tgoto set_indir_failed;\n+\t\t}\n+\t}\n+\n+\tif (nic_dev->num_rss == 0) {\n+\t\terr = spnic_set_vport_enable(nic_dev->hwdev, false);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"%s Disable vport failed, rc:%d\",\n+\t\t\t\t    nic_dev->dev_name, err);\n+\t\t\tgoto set_vport_failed;\n+\t\t}\n+\t}\n+\n+\t/* unlock dev queue list switch  */\n+\trte_spinlock_unlock(&nic_dev->queue_list_lock);\n+\n+\t/* Send flush rq cmd to uCode */\n+\terr = spnic_set_rq_flush(nic_dev->hwdev, rxq->q_id);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Flush rq failed, eth_dev:%s, queue_idx:%d\\n\",\n+\t\t\t    nic_dev->dev_name, rxq->q_id);\n+\t\tgoto rq_flush_failed;\n+\t}\n+\n+\terr = spnic_poll_rq_empty(rxq);\n+\tif (err) {\n+\t\tspnic_dump_cqe_status(rxq, &cqe_done_cnt, &cqe_hole_cnt,\n+\t\t\t\t       &head_ci, &head_done);\n+\t\tPMD_DRV_LOG(ERR, \"Poll rq empty timeout, eth_dev:%s, queue_idx:%d, \"\n+\t\t\t    \"mbuf_left:%d, cqe_done:%d, cqe_hole:%d, cqe[%d].done=%d\\n\",\n+\t\t\t    nic_dev->dev_name, rxq->q_id,\n+\t\t\t    rxq->q_depth - spnic_get_rq_free_wqebb(rxq),\n+\t\t\t    cqe_done_cnt, cqe_hole_cnt, head_ci, head_done);\n+\t\tgoto poll_rq_failed;\n+\t}\n+\n+\treturn 0;\n+\n+poll_rq_failed:\n+rq_flush_failed:\n+\trte_spinlock_lock(&nic_dev->queue_list_lock);\n+set_vport_failed:\n+\tspnic_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);\n+\tif (nic_dev->rss_state == SPNIC_RSS_ENABLE)\n+\t\t(void)spnic_refill_indir_rqid(rxq);\n+set_indir_failed:\n+\trte_spinlock_unlock(&nic_dev->queue_list_lock);\n+\tspnic_dev_rx_queue_intr_enable(eth_dev, rxq->q_id);\n+\treturn err;\n+}\n+\n+int spnic_start_rq(struct rte_eth_dev *eth_dev, struct spnic_rxq *rxq)\n+{\n+\tstruct spnic_nic_dev *nic_dev = rxq->nic_dev;\n+\tint err = 0;\n+\n+\t/* lock dev queue switch  */\n+\trte_spinlock_lock(&nic_dev->queue_list_lock);\n+\n+\tspnic_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);\n+\n+\tspnic_rearm_rxq_mbuf(rxq);\n+\n+\tif (nic_dev->rss_state == SPNIC_RSS_ENABLE) {\n+\t\terr = spnic_refill_indir_rqid(rxq);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Refill rq to indrect table failed, eth_dev:%s, queue_idx:%d err:%d\\n\",\n+\t\t\t\t    nic_dev->dev_name, rxq->q_id, err);\n+\t\t\tspnic_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);\n+\t\t}\n+\t}\n+\n+\tif (rxq->nic_dev->num_rss == 1) {\n+\t\terr = spnic_set_vport_enable(nic_dev->hwdev, true);\n+\t\tif (err)\n+\t\t\tPMD_DRV_LOG(ERR, \"%s enable vport failed, err:%d\",\n+\t\t\t\t    nic_dev->dev_name, err);\n+\t}\n+\n+\t/* unlock dev queue list switch  */\n+\trte_spinlock_unlock(&nic_dev->queue_list_lock);\n+\n+\tspnic_dev_rx_queue_intr_enable(eth_dev, rxq->q_id);\n+\n+\treturn err;\n+}\n \n static inline uint64_t spnic_rx_vlan(uint32_t offload_type, uint32_t vlan_len,\n \t\t\t\t      uint16_t *vlan_tci)\ndiff --git a/drivers/net/spnic/spnic_rx.h b/drivers/net/spnic/spnic_rx.h\nindex 5ae4b5f1ab..a876f75595 100644\n--- a/drivers/net/spnic/spnic_rx.h\n+++ b/drivers/net/spnic/spnic_rx.h\n@@ -273,6 +273,10 @@ void spnic_dump_cqe_status(struct spnic_rxq *rxq, u32 *cqe_done_cnt,\n \t\t\t    u32 *cqe_hole_cnt, u32 *head_ci,\n \t\t\t    u32 *head_done);\n \n+int spnic_stop_rq(struct rte_eth_dev *eth_dev, struct spnic_rxq *rxq);\n+\n+int spnic_start_rq(struct rte_eth_dev *eth_dev, struct spnic_rxq *rxq);\n+\n int spnic_start_all_rqs(struct rte_eth_dev *eth_dev);\n \n u16 spnic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, u16 nb_pkts);\n",
    "prefixes": [
        "v1",
        "24/25"
    ]
}