get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 63410,
    "url": "http://patches.dpdk.org/api/patches/63410/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20191130105816.13675-2-xavier.huwei@foxmail.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": "<20191130105816.13675-2-xavier.huwei@foxmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20191130105816.13675-2-xavier.huwei@foxmail.com",
    "date": "2019-11-30T10:58:08",
    "name": "[1/9] net/hns3: support Rx interrupt",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0b5e9fbb57ec137ad27acd3f962d45fe118c5684",
    "submitter": {
        "id": 1526,
        "url": "http://patches.dpdk.org/api/people/1526/?format=api",
        "name": "Wei Hu (Xavier)",
        "email": "xavier.huwei@foxmail.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20191130105816.13675-2-xavier.huwei@foxmail.com/mbox/",
    "series": [
        {
            "id": 7695,
            "url": "http://patches.dpdk.org/api/series/7695/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=7695",
            "date": "2019-11-30T10:58:07",
            "name": "updates for hns3 PMD driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/7695/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/63410/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/63410/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1482CA04F0;\n\tSat, 30 Nov 2019 11:59:17 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 35E814CA7;\n\tSat, 30 Nov 2019 11:59:00 +0100 (CET)",
            "from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56])\n by dpdk.org (Postfix) with ESMTP id C43CB2BD3\n for <dev@dpdk.org>; Sat, 30 Nov 2019 11:58:54 +0100 (CET)",
            "from localhost.localdomain (unknown [114.119.4.74])\n by esmtp4.qq.com (ESMTP) with\n id ; Sat, 30 Nov 2019 18:58:30 +0800 (CST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=foxmail.com;\n s=s201512; t=1575111513;\n bh=L4QfQ8uy3T094UaXyAKauu+tSesnR1jzBkewOtiTm1o=;\n h=From:To:Subject:Date:Message-Id:MIME-Version;\n b=NWkN6OhbIzOqXPuoAKQpRc0MhxaRYX4gKFrZfsDTAxDiPUY3G+Wd5dDr9u2CzXiwA\n Z/pROO7IJpSMYK22YGo4MYF1L/BfRwZchY2FqOq7Lwnhpy2YToaYi/vkZYabxHsFhB\n dEME0akR2AA/RcNMh3zDj4xaXX59p+KDre3C3yzk=",
        "X-QQ-mid": "esmtp2t1575111511ta3y3c5ba",
        "X-QQ-SSF": "B100000000000020E5120000000000T",
        "X-QQ-FEAT": "ECcPpPTfzVCRl5j8V0N4GJPYQSJ2YRvZAF6jjc8l+RkMEn1wAaqdk94VJbTwy\n 2lqx2XnNcEX3sSBe8cy9uxeMdnQ6jgKJBaHVK7ujdTL9ds5kax4hPfXDcUq56p56BUAbH68\n ZNniGOgcSRroPnEfYPN2Rzkw+7/RVZr2TK9IPPsJ1TqnrHLgWrdH/v3oPbrqWmhihnEtIot\n QoxSRNKlxVDmRjphoLJG79gc8We65jM9TCSFDu+fkZnqq3/jqat9aJroPcnYibLPydq4VWe\n 4shVU85rEBDJmyspu4CqjpaIyrOUqt1uPiZiNhzv/1x068",
        "X-QQ-GoodBg": "0",
        "From": "\"Wei Hu (Xavier)\" <xavier.huwei@foxmail.com>",
        "To": "dev@dpdk.org",
        "Cc": "huwei87@hisilicon.com,\n\txavier.huwei@foxmail.com",
        "Date": "Sat, 30 Nov 2019 18:58:08 +0800",
        "Message-Id": "<20191130105816.13675-2-xavier.huwei@foxmail.com>",
        "X-Mailer": "git-send-email 2.23.0",
        "In-Reply-To": "<20191130105816.13675-1-xavier.huwei@foxmail.com>",
        "References": "<20191130105816.13675-1-xavier.huwei@foxmail.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-QQ-SENDSIZE": "520",
        "Feedback-ID": "esmtp:foxmail.com:bgforeign:bgforeign11",
        "X-QQ-Bgrelay": "1",
        "Subject": "[dpdk-dev] [PATCH 1/9] net/hns3: support Rx interrupt",
        "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 <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: Hao Chen <chenhao164@huawei.com>\n\nThis patch supports of receive packets through interrupt mode for hns3\nPF/VF driver. The following ops functions should be implemented defined\nin struct eth_dev_ops:\nrx_queue_intr_enable\nrx_queue_intr_disable\nrx_queue_count\n\nSigned-off-by: Hao Chen <chenhao164@huawei.com>\nSigned-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>\n---\n doc/guides/nics/features/hns3.ini    |   1 +\n doc/guides/nics/features/hns3_vf.ini |   1 +\n drivers/net/hns3/hns3_cmd.h          |  28 +++++\n drivers/net/hns3/hns3_ethdev.c       | 160 ++++++++++++++++++++++++--\n drivers/net/hns3/hns3_ethdev_vf.c    | 166 ++++++++++++++++++++++++---\n drivers/net/hns3/hns3_mbx.h          |  13 +++\n drivers/net/hns3/hns3_regs.h         |   3 +\n drivers/net/hns3/hns3_rxtx.c         |  51 ++++++++\n drivers/net/hns3/hns3_rxtx.h         |   4 +\n 9 files changed, 405 insertions(+), 22 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini\nindex 6df789ed1..cd5c08a9d 100644\n--- a/doc/guides/nics/features/hns3.ini\n+++ b/doc/guides/nics/features/hns3.ini\n@@ -5,6 +5,7 @@\n ;\n [Features]\n Link status          = Y\n+Rx interrupt         = Y\n MTU update           = Y\n Jumbo frame          = Y\n Promiscuous mode     = Y\ndiff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini\nindex 41497c4c2..fd00ac3e2 100644\n--- a/doc/guides/nics/features/hns3_vf.ini\n+++ b/doc/guides/nics/features/hns3_vf.ini\n@@ -5,6 +5,7 @@\n ;\n [Features]\n Link status          = Y\n+Rx interrupt         = Y\n MTU update           = Y\n Jumbo frame          = Y\n Unicast MAC filter   = Y\ndiff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h\nindex be0ecbe86..897dc1420 100644\n--- a/drivers/net/hns3/hns3_cmd.h\n+++ b/drivers/net/hns3/hns3_cmd.h\n@@ -209,6 +209,10 @@ enum hns3_opcode_type {\n \t/* SFP command */\n \tHNS3_OPC_SFP_GET_SPEED          = 0x7104,\n \n+\t/* Interrupts commands */\n+\tHNS3_OPC_ADD_RING_TO_VECTOR\t= 0x1503,\n+\tHNS3_OPC_DEL_RING_TO_VECTOR\t= 0x1504,\n+\n \t/* Error INT commands */\n \tHNS3_QUERY_MSIX_INT_STS_BD_NUM          = 0x1513,\n \tHNS3_QUERY_CLEAR_ALL_MPF_MSIX_INT       = 0x1514,\n@@ -673,6 +677,30 @@ struct hns3_tqp_map_cmd {\n \tuint8_t rsv[18];\n };\n \n+#define HNS3_RING_TYPE_B\t0\n+#define HNS3_RING_TYPE_TX\t0\n+#define HNS3_RING_TYPE_RX\t1\n+#define HNS3_RING_GL_IDX_S\t0\n+#define HNS3_RING_GL_IDX_M\tGENMASK(1, 0)\n+#define HNS3_RING_GL_RX\t\t0\n+#define HNS3_RING_GL_TX\t\t1\n+\n+#define HNS3_VECTOR_ELEMENTS_PER_CMD\t10\n+\n+#define HNS3_INT_TYPE_S\t\t0\n+#define HNS3_INT_TYPE_M\t\tGENMASK(1, 0)\n+#define HNS3_TQP_ID_S\t\t2\n+#define HNS3_TQP_ID_M\t\tGENMASK(12, 2)\n+#define HNS3_INT_GL_IDX_S\t13\n+#define HNS3_INT_GL_IDX_M\tGENMASK(14, 13)\n+struct hns3_ctrl_vector_chain_cmd {\n+\tuint8_t int_vector_id;\n+\tuint8_t int_cause_num;\n+\tuint16_t tqp_type_and_id[HNS3_VECTOR_ELEMENTS_PER_CMD];\n+\tuint8_t vfid;\n+\tuint8_t rsv;\n+};\n+\n struct hns3_config_max_frm_size_cmd {\n \tuint16_t max_frm_size;\n \tuint8_t min_frm_size;\ndiff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c\nindex 72315718a..bf0ab458f 100644\n--- a/drivers/net/hns3/hns3_ethdev.c\n+++ b/drivers/net/hns3/hns3_ethdev.c\n@@ -2021,6 +2021,40 @@ hns3_check_dcb_cfg(struct rte_eth_dev *dev)\n \treturn hns3_check_mq_mode(dev);\n }\n \n+static int\n+hns3_bind_ring_with_vector(struct rte_eth_dev *dev, uint8_t vector_id,\n+\t\t\t   bool mmap, uint16_t queue_id)\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct hns3_cmd_desc desc;\n+\tstruct hns3_ctrl_vector_chain_cmd *req =\n+\t\t(struct hns3_ctrl_vector_chain_cmd *)desc.data;\n+\tenum hns3_cmd_status status;\n+\tenum hns3_opcode_type op;\n+\tuint16_t tqp_type_and_id = 0;\n+\n+\top = mmap ? HNS3_OPC_ADD_RING_TO_VECTOR : HNS3_OPC_DEL_RING_TO_VECTOR;\n+\thns3_cmd_setup_basic_desc(&desc, op, false);\n+\treq->int_vector_id = vector_id;\n+\n+\thns3_set_field(tqp_type_and_id, HNS3_INT_TYPE_M, HNS3_INT_TYPE_S,\n+\t\t       HNS3_RING_TYPE_RX);\n+\thns3_set_field(tqp_type_and_id, HNS3_TQP_ID_M, HNS3_TQP_ID_S, queue_id);\n+\thns3_set_field(tqp_type_and_id, HNS3_INT_GL_IDX_M, HNS3_INT_GL_IDX_S,\n+\t\t       HNS3_RING_GL_RX);\n+\treq->tqp_type_and_id[0] = rte_cpu_to_le_16(tqp_type_and_id);\n+\n+\treq->int_cause_num = 1;\n+\tstatus = hns3_cmd_send(hw, &desc, 1);\n+\tif (status) {\n+\t\thns3_err(hw, \"Map TQP %d fail, vector_id is %d, status is %d.\",\n+\t\t\t queue_id, vector_id, status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n hns3_dev_configure(struct rte_eth_dev *dev)\n {\n@@ -4020,15 +4054,83 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue)\n }\n \n static int\n-hns3_dev_start(struct rte_eth_dev *eth_dev)\n+hns3_map_rx_interrupt(struct rte_eth_dev *dev)\n {\n-\tstruct hns3_adapter *hns = eth_dev->data->dev_private;\n-\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint32_t intr_vector;\n+\tuint8_t base = 0;\n+\tuint8_t vec = 0;\n+\tuint16_t q_id;\n \tint ret;\n \n+\tif (dev->data->dev_conf.intr_conf.rxq == 0)\n+\t\treturn 0;\n+\n+\t/* disable uio/vfio intr/eventfd mapping */\n+\trte_intr_disable(intr_handle);\n+\n+\t/* check and configure queue intr-vector mapping */\n+\tif (rte_intr_cap_multiple(intr_handle) ||\n+\t    !RTE_ETH_DEV_SRIOV(dev).active) {\n+\t\tintr_vector = dev->data->nb_rx_queues;\n+\t\t/* creates event fd for each intr vector when MSIX is used */\n+\t\tif (rte_intr_efd_enable(intr_handle, intr_vector))\n+\t\t\treturn -EINVAL;\n+\t}\n+\tif (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {\n+\t\tintr_handle->intr_vec =\n+\t\t\trte_zmalloc(\"intr_vec\",\n+\t\t\t\t    dev->data->nb_rx_queues * sizeof(int), 0);\n+\t\tif (intr_handle->intr_vec == NULL) {\n+\t\t\thns3_err(hw, \"Failed to allocate %d rx_queues\"\n+\t\t\t\t     \" intr_vec\", dev->data->nb_rx_queues);\n+\t\t\tret = -ENOMEM;\n+\t\t\tgoto alloc_intr_vec_error;\n+\t\t}\n+\t}\n+\n+\tif (rte_intr_allow_others(intr_handle)) {\n+\t\tvec = RTE_INTR_VEC_RXTX_OFFSET;\n+\t\tbase = RTE_INTR_VEC_RXTX_OFFSET;\n+\t}\n+\tif (rte_intr_dp_is_en(intr_handle)) {\n+\t\tfor (q_id = 0; q_id < dev->data->nb_rx_queues; q_id++) {\n+\t\t\tret = hns3_bind_ring_with_vector(dev, vec, true, q_id);\n+\t\t\tif (ret)\n+\t\t\t\tgoto bind_vector_error;\n+\t\t\tintr_handle->intr_vec[q_id] = vec;\n+\t\t\tif (vec < base + intr_handle->nb_efd - 1)\n+\t\t\t\tvec++;\n+\t\t}\n+\t}\n+\trte_intr_enable(intr_handle);\n+\treturn 0;\n+\n+bind_vector_error:\n+\trte_intr_efd_disable(intr_handle);\n+\tif (intr_handle->intr_vec) {\n+\t\tfree(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+\treturn ret;\n+alloc_intr_vec_error:\n+\trte_intr_efd_disable(intr_handle);\n+\treturn ret;\n+}\n+\n+static int\n+hns3_dev_start(struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tint ret = 0;\n+\n \tPMD_INIT_FUNC_TRACE();\n \tif (rte_atomic16_read(&hw->reset.resetting))\n \t\treturn -EBUSY;\n+\n \trte_spinlock_lock(&hw->lock);\n \thw->adapter_state = HNS3_NIC_STARTING;\n \n@@ -4041,8 +4143,12 @@ hns3_dev_start(struct rte_eth_dev *eth_dev)\n \n \thw->adapter_state = HNS3_NIC_STARTED;\n \trte_spinlock_unlock(&hw->lock);\n-\thns3_set_rxtx_function(eth_dev);\n-\thns3_mp_req_start_rxtx(eth_dev);\n+\n+\tret = hns3_map_rx_interrupt(dev);\n+\tif (ret)\n+\t\treturn ret;\n+\thns3_set_rxtx_function(dev);\n+\thns3_mp_req_start_rxtx(dev);\n \n \thns3_info(hw, \"hns3 dev start successful!\");\n \treturn 0;\n@@ -4070,18 +4176,50 @@ hns3_do_stop(struct hns3_adapter *hns)\n }\n \n static void\n-hns3_dev_stop(struct rte_eth_dev *eth_dev)\n+hns3_unmap_rx_interrupt(struct rte_eth_dev *dev)\n {\n-\tstruct hns3_adapter *hns = eth_dev->data->dev_private;\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n+\tuint8_t base = 0;\n+\tuint8_t vec = 0;\n+\tuint16_t q_id;\n+\n+\tif (dev->data->dev_conf.intr_conf.rxq == 0)\n+\t\treturn;\n+\n+\t/* unmap the ring with vector */\n+\tif (rte_intr_allow_others(intr_handle)) {\n+\t\tvec = RTE_INTR_VEC_RXTX_OFFSET;\n+\t\tbase = RTE_INTR_VEC_RXTX_OFFSET;\n+\t}\n+\tif (rte_intr_dp_is_en(intr_handle)) {\n+\t\tfor (q_id = 0; q_id < dev->data->nb_rx_queues; q_id++) {\n+\t\t\t(void)hns3_bind_ring_with_vector(dev, vec, false, q_id);\n+\t\t\tif (vec < base + intr_handle->nb_efd - 1)\n+\t\t\t\tvec++;\n+\t\t}\n+\t}\n+\t/* Clean datapath event and queue/vec mapping */\n+\trte_intr_efd_disable(intr_handle);\n+\tif (intr_handle->intr_vec) {\n+\t\trte_free(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+}\n+\n+static void\n+hns3_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n \tstruct hns3_hw *hw = &hns->hw;\n \n \tPMD_INIT_FUNC_TRACE();\n \n \thw->adapter_state = HNS3_NIC_STOPPING;\n-\thns3_set_rxtx_function(eth_dev);\n+\thns3_set_rxtx_function(dev);\n \trte_wmb();\n \t/* Disable datapath on secondary process. */\n-\thns3_mp_req_stop_rxtx(eth_dev);\n+\thns3_mp_req_stop_rxtx(dev);\n \t/* Prevent crashes when queues are still in use. */\n \trte_delay_ms(hw->tqps_num);\n \n@@ -4092,6 +4230,7 @@ hns3_dev_stop(struct rte_eth_dev *eth_dev)\n \t\thw->adapter_state = HNS3_NIC_CONFIGURED;\n \t}\n \trte_spinlock_unlock(&hw->lock);\n+\thns3_unmap_rx_interrupt(dev);\n }\n \n static void\n@@ -4748,6 +4887,9 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {\n \t.tx_queue_setup         = hns3_tx_queue_setup,\n \t.rx_queue_release       = hns3_dev_rx_queue_release,\n \t.tx_queue_release       = hns3_dev_tx_queue_release,\n+\t.rx_queue_intr_enable   = hns3_dev_rx_queue_intr_enable,\n+\t.rx_queue_intr_disable  = hns3_dev_rx_queue_intr_disable,\n+\t.rx_queue_count         = hns3_dev_rx_queue_count,\n \t.dev_configure          = hns3_dev_configure,\n \t.flow_ctrl_get          = hns3_flow_ctrl_get,\n \t.flow_ctrl_set          = hns3_flow_ctrl_set,\ndiff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c\nindex b1736e73a..9b6bc83e4 100644\n--- a/drivers/net/hns3/hns3_ethdev_vf.c\n+++ b/drivers/net/hns3/hns3_ethdev_vf.c\n@@ -1208,6 +1208,36 @@ hns3vf_uninit_vf(struct rte_eth_dev *eth_dev)\n \thw->io_base = NULL;\n }\n \n+static int\n+hns3vf_bind_ring_with_vector(struct rte_eth_dev *dev, uint8_t vector_id,\n+\t\t\t     bool mmap, uint16_t queue_id)\n+\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct hns3_vf_bind_vector_msg bind_msg;\n+\tuint16_t code;\n+\tint ret;\n+\n+\tmemset(&bind_msg, 0, sizeof(bind_msg));\n+\tcode = mmap ? HNS3_MBX_MAP_RING_TO_VECTOR :\n+\t\tHNS3_MBX_UNMAP_RING_TO_VECTOR;\n+\tbind_msg.vector_id = vector_id;\n+\tbind_msg.ring_num = 1;\n+\tbind_msg.param[0].ring_type = HNS3_RING_TYPE_RX;\n+\tbind_msg.param[0].tqp_index = queue_id;\n+\tbind_msg.param[0].int_gl_index = HNS3_RING_GL_RX;\n+\n+\tret = hns3_send_mbx_msg(hw, code, 0, (uint8_t *)&bind_msg,\n+\t\t\t\tsizeof(bind_msg), false, NULL, 0);\n+\tif (ret) {\n+\t\thns3_err(hw, \"Map TQP %d fail, vector_id is %d, ret is %d.\",\n+\t\t\t queue_id, vector_id, ret);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n hns3vf_do_stop(struct hns3_adapter *hns)\n {\n@@ -1225,18 +1255,51 @@ hns3vf_do_stop(struct hns3_adapter *hns)\n }\n \n static void\n-hns3vf_dev_stop(struct rte_eth_dev *eth_dev)\n+hns3vf_unmap_rx_interrupt(struct rte_eth_dev *dev)\n {\n-\tstruct hns3_adapter *hns = eth_dev->data->dev_private;\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n+\tuint8_t base = 0;\n+\tuint8_t vec = 0;\n+\tuint16_t q_id;\n+\n+\tif (dev->data->dev_conf.intr_conf.rxq == 0)\n+\t\treturn;\n+\n+\t/* unmap the ring with vector */\n+\tif (rte_intr_allow_others(intr_handle)) {\n+\t\tvec = RTE_INTR_VEC_RXTX_OFFSET;\n+\t\tbase = RTE_INTR_VEC_RXTX_OFFSET;\n+\t}\n+\tif (rte_intr_dp_is_en(intr_handle)) {\n+\t\tfor (q_id = 0; q_id < dev->data->nb_rx_queues; q_id++) {\n+\t\t\t(void)hns3vf_bind_ring_with_vector(dev, vec, false,\n+\t\t\t\t\t\t\t   q_id);\n+\t\t\tif (vec < base + intr_handle->nb_efd - 1)\n+\t\t\t\tvec++;\n+\t\t}\n+\t}\n+\t/* Clean datapath event and queue/vec mapping */\n+\trte_intr_efd_disable(intr_handle);\n+\tif (intr_handle->intr_vec) {\n+\t\trte_free(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+}\n+\n+static void\n+hns3vf_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n \tstruct hns3_hw *hw = &hns->hw;\n \n \tPMD_INIT_FUNC_TRACE();\n \n \thw->adapter_state = HNS3_NIC_STOPPING;\n-\thns3_set_rxtx_function(eth_dev);\n+\thns3_set_rxtx_function(dev);\n \trte_wmb();\n \t/* Disable datapath on secondary process. */\n-\thns3_mp_req_stop_rxtx(eth_dev);\n+\thns3_mp_req_stop_rxtx(dev);\n \t/* Prevent crashes when queues are still in use. */\n \trte_delay_ms(hw->tqps_num);\n \n@@ -1246,8 +1309,10 @@ hns3vf_dev_stop(struct rte_eth_dev *eth_dev)\n \t\thns3_dev_release_mbufs(hns);\n \t\thw->adapter_state = HNS3_NIC_CONFIGURED;\n \t}\n-\trte_eal_alarm_cancel(hns3vf_service_handler, eth_dev);\n+\trte_eal_alarm_cancel(hns3vf_service_handler, dev);\n \trte_spinlock_unlock(&hw->lock);\n+\n+\thns3vf_unmap_rx_interrupt(dev);\n }\n \n static void\n@@ -1329,15 +1394,84 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue)\n }\n \n static int\n-hns3vf_dev_start(struct rte_eth_dev *eth_dev)\n+hns3vf_map_rx_interrupt(struct rte_eth_dev *dev)\n {\n-\tstruct hns3_adapter *hns = eth_dev->data->dev_private;\n-\tstruct hns3_hw *hw = &hns->hw;\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint32_t intr_vector;\n+\tuint8_t base = 0;\n+\tuint8_t vec = 0;\n+\tuint16_t q_id;\n \tint ret;\n \n+\tif (dev->data->dev_conf.intr_conf.rxq == 0)\n+\t\treturn 0;\n+\n+\t/* disable uio/vfio intr/eventfd mapping */\n+\trte_intr_disable(intr_handle);\n+\n+\t/* check and configure queue intr-vector mapping */\n+\tif (rte_intr_cap_multiple(intr_handle) ||\n+\t\t!RTE_ETH_DEV_SRIOV(dev).active) {\n+\t\tintr_vector = dev->data->nb_rx_queues;\n+\t\t/* It creates event fd for each intr vector when MSIX is used */\n+\t\tif (rte_intr_efd_enable(intr_handle, intr_vector))\n+\t\t\treturn -EINVAL;\n+\t}\n+\tif (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {\n+\t\tintr_handle->intr_vec =\n+\t\t\trte_zmalloc(\"intr_vec\",\n+\t\t\t\t    dev->data->nb_rx_queues * sizeof(int), 0);\n+\t\tif (intr_handle->intr_vec == NULL) {\n+\t\t\thns3_err(hw, \"Failed to allocate %d rx_queues\"\n+\t\t\t\t     \" intr_vec\", dev->data->nb_rx_queues);\n+\t\t\tret = -ENOMEM;\n+\t\t\tgoto vf_alloc_intr_vec_error;\n+\t\t}\n+\t}\n+\n+\tif (rte_intr_allow_others(intr_handle)) {\n+\t\tvec = RTE_INTR_VEC_RXTX_OFFSET;\n+\t\tbase = RTE_INTR_VEC_RXTX_OFFSET;\n+\t}\n+\tif (rte_intr_dp_is_en(intr_handle)) {\n+\t\tfor (q_id = 0; q_id < dev->data->nb_rx_queues; q_id++) {\n+\t\t\tret = hns3vf_bind_ring_with_vector(dev, vec, true,\n+\t\t\t\t\t\t\t   q_id);\n+\t\t\tif (ret)\n+\t\t\t\tgoto vf_bind_vector_error;\n+\t\t\tintr_handle->intr_vec[q_id] = vec;\n+\t\t\tif (vec < base + intr_handle->nb_efd - 1)\n+\t\t\t\tvec++;\n+\t\t}\n+\t}\n+\trte_intr_enable(intr_handle);\n+\treturn 0;\n+\n+vf_bind_vector_error:\n+\trte_intr_efd_disable(intr_handle);\n+\tif (intr_handle->intr_vec) {\n+\t\tfree(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+\treturn ret;\n+vf_alloc_intr_vec_error:\n+\trte_intr_efd_disable(intr_handle);\n+\treturn ret;\n+}\n+\n+static int\n+hns3vf_dev_start(struct rte_eth_dev *dev)\n+{\n+\tstruct hns3_adapter *hns = dev->data->dev_private;\n+\tstruct hns3_hw *hw = &hns->hw;\n+\tint ret = 0;\n+\n \tPMD_INIT_FUNC_TRACE();\n \tif (rte_atomic16_read(&hw->reset.resetting))\n \t\treturn -EBUSY;\n+\n \trte_spinlock_lock(&hw->lock);\n \thw->adapter_state = HNS3_NIC_STARTING;\n \tret = hns3vf_do_start(hns, true);\n@@ -1348,11 +1482,14 @@ hns3vf_dev_start(struct rte_eth_dev *eth_dev)\n \t}\n \thw->adapter_state = HNS3_NIC_STARTED;\n \trte_spinlock_unlock(&hw->lock);\n-\thns3_set_rxtx_function(eth_dev);\n-\thns3_mp_req_start_rxtx(eth_dev);\n-\trte_eal_alarm_set(HNS3VF_SERVICE_INTERVAL, hns3vf_service_handler,\n-\t\t\t  eth_dev);\n-\treturn 0;\n+\n+\tret = hns3vf_map_rx_interrupt(dev);\n+\tif (ret)\n+\t\treturn ret;\n+\thns3_set_rxtx_function(dev);\n+\thns3_mp_req_start_rxtx(dev);\n+\trte_eal_alarm_set(HNS3VF_SERVICE_INTERVAL, hns3vf_service_handler, dev);\n+\treturn ret;\n }\n \n static bool\n@@ -1685,6 +1822,9 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {\n \t.tx_queue_setup     = hns3_tx_queue_setup,\n \t.rx_queue_release   = hns3_dev_rx_queue_release,\n \t.tx_queue_release   = hns3_dev_tx_queue_release,\n+\t.rx_queue_intr_enable   = hns3_dev_rx_queue_intr_enable,\n+\t.rx_queue_intr_disable  = hns3_dev_rx_queue_intr_disable,\n+\t.rx_queue_count         = hns3_dev_rx_queue_count,\n \t.dev_configure      = hns3vf_dev_configure,\n \t.mac_addr_add       = hns3vf_add_mac_addr,\n \t.mac_addr_remove    = hns3vf_remove_mac_addr,\ndiff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h\nindex 01eddb845..d1a6bfead 100644\n--- a/drivers/net/hns3/hns3_mbx.h\n+++ b/drivers/net/hns3/hns3_mbx.h\n@@ -104,6 +104,19 @@ struct hns3_mbx_pf_to_vf_cmd {\n \tuint16_t msg[8];\n };\n \n+struct hns3_ring_chain_param {\n+\tuint8_t ring_type;\n+\tuint8_t tqp_index;\n+\tuint8_t int_gl_index;\n+};\n+\n+#define HNS3_MBX_MAX_RING_CHAIN_PARAM_NUM\t4\n+struct hns3_vf_bind_vector_msg {\n+\tuint8_t vector_id;\n+\tuint8_t ring_num;\n+\tstruct hns3_ring_chain_param param[HNS3_MBX_MAX_RING_CHAIN_PARAM_NUM];\n+};\n+\n struct hns3_vf_rst_cmd {\n \tuint8_t dest_vfid;\n \tuint8_t vf_rst;\ndiff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h\nindex 2f5faafe1..42581df67 100644\n--- a/drivers/net/hns3/hns3_regs.h\n+++ b/drivers/net/hns3/hns3_regs.h\n@@ -83,6 +83,9 @@\n \n #define HNS3_RING_EN_B\t\t\t\t0\n \n+#define HNS3_VECTOR_REG_OFFSET\t\t\t0x4\n+#define HNS3_VECTOR_VF_OFFSET\t\t\t0x100000\n+\n #define HNS3_TQP_REG_OFFSET\t\t\t0x80000\n #define HNS3_TQP_REG_SIZE\t\t\t0x200\n \ndiff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c\nindex 816644713..e7f0c8fc9 100644\n--- a/drivers/net/hns3/hns3_rxtx.c\n+++ b/drivers/net/hns3/hns3_rxtx.c\n@@ -395,6 +395,57 @@ hns3_reset_all_queues(struct hns3_adapter *hns)\n \treturn 0;\n }\n \n+uint32_t\n+hns3_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n+{\n+\tstruct hns3_rx_queue *rxq;\n+\n+\trxq = dev->data->rx_queues[rx_queue_id];\n+\n+\treturn rxq->nb_rx_desc - rxq->nb_rx_hold;\n+}\n+\n+void\n+hns3_tqp_intr_enable(struct hns3_hw *hw, uint16_t tpq_int_num, bool en)\n+{\n+\tuint32_t addr, value;\n+\n+\taddr = HNS3_TQP_INTR_CTRL_REG + tpq_int_num * HNS3_VECTOR_REG_OFFSET;\n+\tvalue = en ? 1 : 0;\n+\n+\thns3_write_dev(hw, addr, value);\n+}\n+\n+int\n+hns3_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)\n+{\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = &pci_dev->intr_handle;\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\tif (dev->data->dev_conf.intr_conf.rxq == 0)\n+\t\treturn -ENOTSUP;\n+\n+\t/* enable the vectors */\n+\thns3_tqp_intr_enable(hw, queue_id, true);\n+\n+\treturn rte_intr_ack(intr_handle);\n+}\n+\n+int\n+hns3_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)\n+{\n+\tstruct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\tif (dev->data->dev_conf.intr_conf.rxq == 0)\n+\t\treturn -ENOTSUP;\n+\n+\t/* disable the vectors */\n+\thns3_tqp_intr_enable(hw, queue_id, false);\n+\n+\treturn 0;\n+}\n+\n static int\n hns3_dev_rx_queue_start(struct hns3_adapter *hns, uint16_t idx)\n {\ndiff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h\nindex daf51f409..60c3f414b 100644\n--- a/drivers/net/hns3/hns3_rxtx.h\n+++ b/drivers/net/hns3/hns3_rxtx.h\n@@ -295,6 +295,9 @@ void hns3_dev_rx_queue_release(void *queue);\n void hns3_dev_tx_queue_release(void *queue);\n void hns3_free_all_queues(struct rte_eth_dev *dev);\n int hns3_reset_all_queues(struct hns3_adapter *hns);\n+uint32_t hns3_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id);\n+int hns3_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);\n+int hns3_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);\n int hns3_start_queues(struct hns3_adapter *hns, bool reset_queue);\n int hns3_stop_queues(struct hns3_adapter *hns, bool reset_queue);\n void hns3_dev_release_mbufs(struct hns3_adapter *hns);\n@@ -311,4 +314,5 @@ uint16_t hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\tuint16_t nb_pkts);\n const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev);\n void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev);\n+void hns3_tqp_intr_enable(struct hns3_hw *hw, uint16_t tpq_int_num, bool en);\n #endif /* _HNS3_RXTX_H_ */\n",
    "prefixes": [
        "1/9"
    ]
}