get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 55450,
    "url": "http://patches.dpdk.org/api/patches/55450/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/7fa10989c16b60f45f7cbf64a2cbba2174d26b57.1561620219.git.xuanziyang2@huawei.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": "<7fa10989c16b60f45f7cbf64a2cbba2174d26b57.1561620219.git.xuanziyang2@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/7fa10989c16b60f45f7cbf64a2cbba2174d26b57.1561620219.git.xuanziyang2@huawei.com",
    "date": "2019-06-27T08:18:47",
    "name": "[v6,12/15] net/hinic: add device initailization",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "136ec132edb54d788faf06e3248e3c34d09d9de3",
    "submitter": {
        "id": 1321,
        "url": "http://patches.dpdk.org/api/people/1321/?format=api",
        "name": "Ziyang Xuan",
        "email": "xuanziyang2@huawei.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/7fa10989c16b60f45f7cbf64a2cbba2174d26b57.1561620219.git.xuanziyang2@huawei.com/mbox/",
    "series": [
        {
            "id": 5191,
            "url": "http://patches.dpdk.org/api/series/5191/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5191",
            "date": "2019-06-27T08:10:12",
            "name": "A new net PMD - hinic",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/5191/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/55450/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/55450/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 A576A2BE5;\n\tThu, 27 Jun 2019 10:07:02 +0200 (CEST)",
            "from huawei.com (szxga06-in.huawei.com [45.249.212.32])\n\tby dpdk.org (Postfix) with ESMTP id 299262B98\n\tfor <dev@dpdk.org>; Thu, 27 Jun 2019 10:07:00 +0200 (CEST)",
            "from DGGEMS410-HUB.china.huawei.com (unknown [172.30.72.59])\n\tby Forcepoint Email with ESMTP id C2456D7966EAD36238D2\n\tfor <dev@dpdk.org>; Thu, 27 Jun 2019 16:06:58 +0800 (CST)",
            "from tester_149.localdomain (10.175.119.39) by\n\tDGGEMS410-HUB.china.huawei.com (10.3.19.210) with Microsoft SMTP\n\tServer id 14.3.439.0; Thu, 27 Jun 2019 16:06:49 +0800"
        ],
        "From": "Ziyang Xuan <xuanziyang2@huawei.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@intel.com>, <cloud.wangxiaoyun@huawei.com>,\n\t<shahar.belkar@huawei.com>, <luoxianjun@huawei.com>,\n\t<tanya.brokhman@huawei.com>, Ziyang Xuan <xuanziyang2@huawei.com>",
        "Date": "Thu, 27 Jun 2019 16:18:47 +0800",
        "Message-ID": "<7fa10989c16b60f45f7cbf64a2cbba2174d26b57.1561620219.git.xuanziyang2@huawei.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<cover.1561620219.git.xuanziyang2@huawei.com>",
        "References": "<cover.1561620219.git.xuanziyang2@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.175.119.39]",
        "X-CFilter-Loop": "Reflected",
        "Subject": "[dpdk-dev] [PATCH v6 12/15] net/hinic: add device initailization",
        "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": "Add device initialization function codes.\n\nSigned-off-by: Ziyang Xuan <xuanziyang2@huawei.com>\n---\n drivers/net/hinic/Makefile           |   2 +\n drivers/net/hinic/hinic_pmd_ethdev.c | 700 ++++++++++++++++++++++++++-\n drivers/net/hinic/hinic_pmd_rx.c     | 178 +++++++\n drivers/net/hinic/hinic_pmd_rx.h     | 128 +++++\n drivers/net/hinic/hinic_pmd_tx.c     |  92 ++++\n drivers/net/hinic/hinic_pmd_tx.h     | 143 ++++++\n drivers/net/hinic/meson.build        |   2 +\n 7 files changed, 1241 insertions(+), 4 deletions(-)\n create mode 100644 drivers/net/hinic/hinic_pmd_rx.c\n create mode 100644 drivers/net/hinic/hinic_pmd_rx.h\n create mode 100644 drivers/net/hinic/hinic_pmd_tx.c\n create mode 100644 drivers/net/hinic/hinic_pmd_tx.h",
    "diff": "diff --git a/drivers/net/hinic/Makefile b/drivers/net/hinic/Makefile\nindex 8b7475b59..df7871b05 100644\n--- a/drivers/net/hinic/Makefile\n+++ b/drivers/net/hinic/Makefile\n@@ -42,5 +42,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_nicio.c\n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_wq.c\n \n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_ethdev.c\n+SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_rx.c\n+SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_tx.c\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c\nindex 2491b7a38..f984465ed 100644\n--- a/drivers/net/hinic/hinic_pmd_ethdev.c\n+++ b/drivers/net/hinic/hinic_pmd_ethdev.c\n@@ -5,13 +5,24 @@\n #include <rte_pci.h>\n #include <rte_bus_pci.h>\n #include <rte_ethdev_pci.h>\n+#include <rte_mbuf.h>\n #include <rte_malloc.h>\n #include <rte_memcpy.h>\n+#include <rte_mempool.h>\n+#include <rte_errno.h>\n \n #include \"base/hinic_compat.h\"\n #include \"base/hinic_pmd_hwdev.h\"\n+#include \"base/hinic_pmd_hwif.h\"\n+#include \"base/hinic_pmd_wq.h\"\n+#include \"base/hinic_pmd_cfg.h\"\n+#include \"base/hinic_pmd_mgmt.h\"\n+#include \"base/hinic_pmd_cmdq.h\"\n #include \"base/hinic_pmd_niccfg.h\"\n+#include \"base/hinic_pmd_nicio.h\"\n #include \"hinic_pmd_ethdev.h\"\n+#include \"hinic_pmd_tx.h\"\n+#include \"hinic_pmd_rx.h\"\n \n /* Vendor ID used by Huawei devices */\n #define HINIC_HUAWEI_VENDOR_ID\t\t0x19E5\n@@ -22,6 +33,13 @@\n #define HINIC_DEV_ID_MEZZ_40GE\t\t0x020D\n #define HINIC_DEV_ID_MEZZ_100GE\t\t0x0205\n \n+#define HINIC_SERVICE_MODE_NIC\t\t2\n+\n+#define HINIC_INTR_CB_UNREG_MAX_RETRIES\t\t10\n+\n+#define DEFAULT_BASE_COS\t\t4\n+#define NR_MAX_COS\t\t\t8\n+\n #define HINIC_MIN_RX_BUF_SIZE\t\t1024\n #define HINIC_MAX_MAC_ADDRS\t\t1\n \n@@ -40,6 +58,91 @@ static const struct rte_eth_desc_lim hinic_tx_desc_lim = {\n \t.nb_align = HINIC_TXD_ALIGN,\n };\n \n+/**\n+ * Interrupt handler triggered by NIC  for handling\n+ * specific event.\n+ *\n+ * @param: The address of parameter (struct rte_eth_dev *) regsitered before.\n+ **/\n+static void hinic_dev_interrupt_handler(void *param)\n+{\n+\tstruct rte_eth_dev *dev = param;\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\n+\tif (!hinic_test_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status)) {\n+\t\tPMD_DRV_LOG(WARNING, \"Device's interrupt is disabled, ignore interrupt event, dev_name: %s, port_id: %d\",\n+\t\t\t    nic_dev->proc_dev_name, dev->data->port_id);\n+\t\treturn;\n+\t}\n+\n+\t/* aeq0 msg handler */\n+\thinic_dev_handle_aeq_event(nic_dev->hwdev, param);\n+}\n+\n+/**\n+ * Ethernet device configuration.\n+ *\n+ * Prepare the driver for a given number of TX and RX queues, mtu size\n+ * and configure RSS.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int hinic_dev_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev;\n+\tstruct hinic_nic_io *nic_io;\n+\tint err;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tnic_io = nic_dev->hwdev->nic_io;\n+\n+\tnic_dev->num_sq =  dev->data->nb_tx_queues;\n+\tnic_dev->num_rq = dev->data->nb_rx_queues;\n+\n+\tnic_io->num_sqs =  dev->data->nb_tx_queues;\n+\tnic_io->num_rqs = dev->data->nb_rx_queues;\n+\n+\t/* queue pair is max_num(sq, rq) */\n+\tnic_dev->num_qps = (nic_dev->num_sq > nic_dev->num_rq) ?\n+\t\t\tnic_dev->num_sq : nic_dev->num_rq;\n+\tnic_io->num_qps = nic_dev->num_qps;\n+\n+\tif (nic_dev->num_qps > nic_io->max_qps) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Queue number out of range, get queue_num:%d, max_queue_num:%d\",\n+\t\t\tnic_dev->num_qps, nic_io->max_qps);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* mtu size is 256~9600 */\n+\tif (dev->data->dev_conf.rxmode.max_rx_pkt_len < HINIC_MIN_FRAME_SIZE ||\n+\t    dev->data->dev_conf.rxmode.max_rx_pkt_len >\n+\t    HINIC_MAX_JUMBO_FRAME_SIZE) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Max rx pkt len out of range, get max_rx_pkt_len:%d, \"\n+\t\t\t\"expect between %d and %d\",\n+\t\t\tdev->data->dev_conf.rxmode.max_rx_pkt_len,\n+\t\t\tHINIC_MIN_FRAME_SIZE, HINIC_MAX_JUMBO_FRAME_SIZE);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tnic_dev->mtu_size =\n+\t\tHINIC_PKTLEN_TO_MTU(dev->data->dev_conf.rxmode.max_rx_pkt_len);\n+\n+\t/* rss template */\n+\terr = hinic_config_mq_mode(dev, TRUE);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Config multi-queue failed\");\n+\t\treturn err;\n+\t}\n+\n+\treturn HINIC_OK;\n+}\n+\n /**\n  * Get link speed from NIC.\n  *\n@@ -128,27 +231,618 @@ hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)\n \n \tinfo->hash_key_size = HINIC_RSS_KEY_SIZE;\n \tinfo->reta_size = HINIC_RSS_INDIR_SIZE;\n+\tinfo->flow_type_rss_offloads = HINIC_RSS_OFFLOAD_ALL;\n \tinfo->rx_desc_lim = hinic_rx_desc_lim;\n \tinfo->tx_desc_lim = hinic_tx_desc_lim;\n }\n \n-static int hinic_func_init(__rte_unused struct rte_eth_dev *eth_dev)\n+static void hinic_free_all_rq(struct hinic_nic_dev *nic_dev)\n+{\n+\tu16 q_id;\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_rq; q_id++)\n+\t\thinic_destroy_rq(nic_dev->hwdev, q_id);\n+}\n+\n+static void hinic_free_all_sq(struct hinic_nic_dev *nic_dev)\n+{\n+\tu16 q_id;\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_sq; q_id++)\n+\t\thinic_destroy_sq(nic_dev->hwdev, q_id);\n+}\n+\n+static void hinic_disable_interrupt(struct rte_eth_dev *dev)\n {\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tint ret, retries = 0;\n+\n+\thinic_clear_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status);\n+\n+\t/* disable msix interrupt in hardware */\n+\thinic_set_msix_state(nic_dev->hwdev, 0, HINIC_MSIX_DISABLE);\n+\n+\t/* disable rte interrupt */\n+\tret = rte_intr_disable(&pci_dev->intr_handle);\n+\tif (ret)\n+\t\tPMD_DRV_LOG(ERR, \"Disable intr failed: %d\", ret);\n+\n+\tdo {\n+\t\tret =\n+\t\trte_intr_callback_unregister(&pci_dev->intr_handle,\n+\t\t\t\t\t     hinic_dev_interrupt_handler, dev);\n+\t\tif (ret >= 0) {\n+\t\t\tbreak;\n+\t\t} else if (ret == -EAGAIN) {\n+\t\t\trte_delay_ms(100);\n+\t\t\tretries++;\n+\t\t} else {\n+\t\t\tPMD_DRV_LOG(ERR, \"intr callback unregister failed: %d\",\n+\t\t\t\t    ret);\n+\t\t\tbreak;\n+\t\t}\n+\t} while (retries < HINIC_INTR_CB_UNREG_MAX_RETRIES);\n+\n+\tif (retries == HINIC_INTR_CB_UNREG_MAX_RETRIES)\n+\t\tPMD_DRV_LOG(ERR, \"Unregister intr callback failed after %d retries\",\n+\t\t\t    retries);\n+}\n+\n+/**\n+ * Init mac_vlan table in NIC.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success and stats is filled,\n+ *   negative error value otherwise.\n+ */\n+static int hinic_init_mac_addr(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev =\n+\t\t\t\tHINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\tuint8_t addr_bytes[RTE_ETHER_ADDR_LEN];\n+\tu16 func_id = 0;\n+\tint rc = 0;\n+\n+\trc = hinic_get_default_mac(nic_dev->hwdev, addr_bytes);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tmemmove(eth_dev->data->mac_addrs->addr_bytes,\n+\t\taddr_bytes, RTE_ETHER_ADDR_LEN);\n+\n+\tfunc_id = hinic_global_func_id(nic_dev->hwdev);\n+\trc = hinic_set_mac(nic_dev->hwdev, eth_dev->data->mac_addrs->addr_bytes,\n+\t\t\t   0, func_id);\n+\tif (rc && rc != HINIC_PF_SET_VF_ALREADY)\n+\t\treturn rc;\n+\n \treturn 0;\n }\n \n+/**\n+ * Deinit mac_vlan table in NIC.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success and stats is filled,\n+ *   negative error value otherwise.\n+ */\n+static void hinic_deinit_mac_addr(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev =\n+\t\t\t\tHINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\tint rc;\n+\tu16 func_id = 0;\n+\n+\tif (rte_is_zero_ether_addr(eth_dev->data->mac_addrs))\n+\t\treturn;\n+\n+\tfunc_id = hinic_global_func_id(nic_dev->hwdev);\n+\trc = hinic_del_mac(nic_dev->hwdev,\n+\t\t\t   eth_dev->data->mac_addrs->addr_bytes,\n+\t\t\t   0, func_id);\n+\tif (rc && rc != HINIC_PF_SET_VF_ALREADY)\n+\t\tPMD_DRV_LOG(ERR, \"Delete mac table failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+}\n+\n+static int hinic_set_default_pause_feature(struct hinic_nic_dev *nic_dev)\n+{\n+\tstruct nic_pause_config pause_config = {0};\n+\n+\tpause_config.auto_neg = 0;\n+\tpause_config.rx_pause = HINIC_DEFAUT_PAUSE_CONFIG;\n+\tpause_config.tx_pause = HINIC_DEFAUT_PAUSE_CONFIG;\n+\n+\treturn hinic_set_pause_config(nic_dev->hwdev, pause_config);\n+}\n+\n+static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev)\n+{\n+\tu8 up_tc[HINIC_DCB_UP_MAX] = {0};\n+\tu8 up_pgid[HINIC_DCB_UP_MAX] = {0};\n+\tu8 up_bw[HINIC_DCB_UP_MAX] = {0};\n+\tu8 pg_bw[HINIC_DCB_UP_MAX] = {0};\n+\tu8 up_strict[HINIC_DCB_UP_MAX] = {0};\n+\tint i = 0;\n+\n+\tpg_bw[0] = 100;\n+\tfor (i = 0; i < HINIC_DCB_UP_MAX; i++)\n+\t\tup_bw[i] = 100;\n+\n+\treturn hinic_dcb_set_ets(nic_dev->hwdev, up_tc, pg_bw,\n+\t\t\t\t\tup_pgid, up_bw, up_strict);\n+}\n+\n+static void hinic_init_default_cos(struct hinic_nic_dev *nic_dev)\n+{\n+\tnic_dev->default_cos =\n+\t\t\t(hinic_global_func_id(nic_dev->hwdev) +\n+\t\t\t DEFAULT_BASE_COS) % NR_MAX_COS;\n+}\n+\n+static int hinic_set_default_hw_feature(struct hinic_nic_dev *nic_dev)\n+{\n+\tint err;\n+\n+\thinic_init_default_cos(nic_dev);\n+\n+\t/* Restore DCB configure to default status */\n+\terr = hinic_set_default_dcb_feature(nic_dev);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* disable LRO */\n+\terr = hinic_set_rx_lro(nic_dev->hwdev, 0, 0, (u8)0);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* Set pause enable, and up will disable pfc. */\n+\terr = hinic_set_default_pause_feature(nic_dev);\n+\tif (err)\n+\t\treturn err;\n+\n+\terr = hinic_reset_port_link_cfg(nic_dev->hwdev);\n+\tif (err)\n+\t\treturn err;\n+\n+\terr = hinic_set_link_status_follow(nic_dev->hwdev,\n+\t\t\t\t\t   HINIC_LINK_FOLLOW_PORT);\n+\tif (err == HINIC_MGMT_CMD_UNSUPPORTED)\n+\t\tPMD_DRV_LOG(WARNING, \"Don't support to set link status follow phy port status\");\n+\telse if (err)\n+\t\treturn err;\n+\n+\treturn hinic_set_anti_attack(nic_dev->hwdev, true);\n+}\n+\n+static int32_t hinic_card_workmode_check(struct hinic_nic_dev *nic_dev)\n+{\n+\tstruct hinic_board_info info = { 0 };\n+\tint rc;\n+\n+\trc = hinic_get_board_info(nic_dev->hwdev, &info);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\treturn (info.service_mode == HINIC_SERVICE_MODE_NIC ? HINIC_OK :\n+\t\t\t\t\t\tHINIC_ERROR);\n+}\n+\n+static int hinic_copy_mempool_init(struct hinic_nic_dev *nic_dev)\n+{\n+\tnic_dev->cpy_mpool = rte_mempool_lookup(nic_dev->proc_dev_name);\n+\tif (nic_dev->cpy_mpool == NULL) {\n+\t\tnic_dev->cpy_mpool =\n+\t\trte_pktmbuf_pool_create(nic_dev->proc_dev_name,\n+\t\t\t\t\tHINIC_COPY_MEMPOOL_DEPTH,\n+\t\t\t\t\tRTE_CACHE_LINE_SIZE, 0,\n+\t\t\t\t\tHINIC_COPY_MBUF_SIZE,\n+\t\t\t\t\trte_socket_id());\n+\t\tif (!nic_dev->cpy_mpool) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Create copy mempool failed, errno: %d, dev_name: %s\",\n+\t\t\t\t    rte_errno, nic_dev->proc_dev_name);\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void hinic_copy_mempool_uninit(struct hinic_nic_dev *nic_dev)\n+{\n+\tif (nic_dev->cpy_mpool != NULL)\n+\t\trte_mempool_free(nic_dev->cpy_mpool);\n+}\n+\n+static int hinic_init_sw_rxtxqs(struct hinic_nic_dev *nic_dev)\n+{\n+\tu32 txq_size;\n+\tu32 rxq_size;\n+\n+\t/* allocate software txq array */\n+\ttxq_size = nic_dev->nic_cap.max_sqs * sizeof(*nic_dev->txqs);\n+\tnic_dev->txqs = kzalloc_aligned(txq_size, GFP_KERNEL);\n+\tif (!nic_dev->txqs) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate txqs failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* allocate software rxq array */\n+\trxq_size = nic_dev->nic_cap.max_rqs * sizeof(*nic_dev->rxqs);\n+\tnic_dev->rxqs = kzalloc_aligned(rxq_size, GFP_KERNEL);\n+\tif (!nic_dev->rxqs) {\n+\t\t/* free txqs */\n+\t\tkfree(nic_dev->txqs);\n+\t\tnic_dev->txqs = NULL;\n+\n+\t\tPMD_DRV_LOG(ERR, \"Allocate rxqs failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\treturn HINIC_OK;\n+}\n+\n+static void hinic_deinit_sw_rxtxqs(struct hinic_nic_dev *nic_dev)\n+{\n+\tkfree(nic_dev->txqs);\n+\tnic_dev->txqs = NULL;\n+\n+\tkfree(nic_dev->rxqs);\n+\tnic_dev->rxqs = NULL;\n+}\n+\n+static int hinic_nic_dev_create(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev =\n+\t\t\t\tHINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\tint rc;\n+\n+\tnic_dev->hwdev = rte_zmalloc(\"hinic_hwdev\", sizeof(*nic_dev->hwdev),\n+\t\t\t\t     RTE_CACHE_LINE_SIZE);\n+\tif (!nic_dev->hwdev) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate hinic hwdev memory failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\treturn -ENOMEM;\n+\t}\n+\tnic_dev->hwdev->pcidev_hdl = RTE_ETH_DEV_TO_PCI(eth_dev);\n+\n+\t/* init osdep*/\n+\trc = hinic_osdep_init(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize os_dep failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_osdep_fail;\n+\t}\n+\n+\t/* init_hwif */\n+\trc = hinic_hwif_res_init(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize hwif failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_hwif_fail;\n+\t}\n+\n+\t/* init_cfg_mgmt */\n+\trc = init_cfg_mgmt(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize cfg_mgmt failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_cfgmgnt_fail;\n+\t}\n+\n+\t/* init_aeqs */\n+\trc = hinic_comm_aeqs_init(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize aeqs failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_aeqs_fail;\n+\t}\n+\n+\t/* init_pf_to_mgnt */\n+\trc = hinic_comm_pf_to_mgmt_init(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize pf_to_mgmt failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_pf_to_mgmt_fail;\n+\t}\n+\n+\trc = hinic_card_workmode_check(nic_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Check card workmode failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto workmode_check_fail;\n+\t}\n+\n+\t/* do l2nic reset to make chip clear */\n+\trc = hinic_l2nic_reset(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Do l2nic reset failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto l2nic_reset_fail;\n+\t}\n+\n+\t/* init dma and aeq msix attribute table */\n+\t(void)hinic_init_attr_table(nic_dev->hwdev);\n+\n+\t/* init_cmdqs */\n+\trc = hinic_comm_cmdqs_init(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize cmdq failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_cmdq_fail;\n+\t}\n+\n+\t/* set hardware state active */\n+\trc = hinic_activate_hwdev_state(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize resources state failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_resources_state_fail;\n+\t}\n+\n+\t/* init_capability */\n+\trc = hinic_init_capability(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize capability failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_cap_fail;\n+\t}\n+\n+\t/* get nic capability */\n+\tif (!hinic_support_nic(nic_dev->hwdev, &nic_dev->nic_cap))\n+\t\tgoto nic_check_fail;\n+\n+\t/* init root cla and function table */\n+\trc = hinic_init_nicio(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize nic_io failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_nicio_fail;\n+\t}\n+\n+\t/* init_software_txrxq */\n+\trc = hinic_init_sw_rxtxqs(nic_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize sw_rxtxqs failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_sw_rxtxqs_fail;\n+\t}\n+\n+\trc = hinic_copy_mempool_init(nic_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Create copy mempool failed, dev_name: %s\",\n+\t\t\t eth_dev->data->name);\n+\t\tgoto init_mpool_fail;\n+\t}\n+\n+\t/* set hardware feature to default status */\n+\trc = hinic_set_default_hw_feature(nic_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize hardware default features failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto set_default_hw_feature_fail;\n+\t}\n+\n+\treturn 0;\n+\n+set_default_hw_feature_fail:\n+\thinic_copy_mempool_uninit(nic_dev);\n+\n+init_mpool_fail:\n+\thinic_deinit_sw_rxtxqs(nic_dev);\n+\n+init_sw_rxtxqs_fail:\n+\thinic_deinit_nicio(nic_dev->hwdev);\n+\n+nic_check_fail:\n+init_nicio_fail:\n+init_cap_fail:\n+\thinic_deactivate_hwdev_state(nic_dev->hwdev);\n+\n+init_resources_state_fail:\n+\thinic_comm_cmdqs_free(nic_dev->hwdev);\n+\n+init_cmdq_fail:\n+l2nic_reset_fail:\n+workmode_check_fail:\n+\thinic_comm_pf_to_mgmt_free(nic_dev->hwdev);\n+\n+init_pf_to_mgmt_fail:\n+\thinic_comm_aeqs_free(nic_dev->hwdev);\n+\n+init_aeqs_fail:\n+\tfree_cfg_mgmt(nic_dev->hwdev);\n+\n+init_cfgmgnt_fail:\n+\thinic_hwif_res_free(nic_dev->hwdev);\n+\n+init_hwif_fail:\n+\thinic_osdep_deinit(nic_dev->hwdev);\n+\n+init_osdep_fail:\n+\trte_free(nic_dev->hwdev);\n+\tnic_dev->hwdev = NULL;\n+\n+\treturn rc;\n+}\n+\n+static void hinic_nic_dev_destroy(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev =\n+\t\t\tHINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\n+\t(void)hinic_set_link_status_follow(nic_dev->hwdev,\n+\t\t\t\t\t   HINIC_LINK_FOLLOW_DEFAULT);\n+\thinic_copy_mempool_uninit(nic_dev);\n+\thinic_deinit_sw_rxtxqs(nic_dev);\n+\thinic_deinit_nicio(nic_dev->hwdev);\n+\thinic_deactivate_hwdev_state(nic_dev->hwdev);\n+\thinic_comm_cmdqs_free(nic_dev->hwdev);\n+\thinic_comm_pf_to_mgmt_free(nic_dev->hwdev);\n+\thinic_comm_aeqs_free(nic_dev->hwdev);\n+\tfree_cfg_mgmt(nic_dev->hwdev);\n+\thinic_hwif_res_free(nic_dev->hwdev);\n+\thinic_osdep_deinit(nic_dev->hwdev);\n+\trte_free(nic_dev->hwdev);\n+\tnic_dev->hwdev = NULL;\n+}\n+\n+static int hinic_func_init(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct rte_pci_device *pci_dev;\n+\tstruct rte_ether_addr *eth_addr;\n+\tstruct hinic_nic_dev *nic_dev;\n+\tint rc;\n+\n+\tpci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n+\n+\t/* EAL is SECONDARY and eth_dev is already created */\n+\tif (rte_eal_process_type() != RTE_PROC_PRIMARY) {\n+\t\trc = rte_intr_callback_register(&pci_dev->intr_handle,\n+\t\t\t\t\t\thinic_dev_interrupt_handler,\n+\t\t\t\t\t\t(void *)eth_dev);\n+\t\tif (rc)\n+\t\t\tPMD_DRV_LOG(ERR, \"Initialize %s failed in secondary process\",\n+\t\t\t\t    eth_dev->data->name);\n+\n+\t\treturn rc;\n+\t}\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\tmemset(nic_dev, 0, sizeof(*nic_dev));\n+\n+\tsnprintf(nic_dev->proc_dev_name,\n+\t\t sizeof(nic_dev->proc_dev_name),\n+\t\t \"hinic-%.4x:%.2x:%.2x.%x\",\n+\t\t pci_dev->addr.domain, pci_dev->addr.bus,\n+\t\t pci_dev->addr.devid, pci_dev->addr.function);\n+\n+\t/* alloc mac_addrs */\n+\teth_addr = rte_zmalloc(\"hinic_mac\", sizeof(*eth_addr), 0);\n+\tif (!eth_addr) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate ethernet addresses' memory failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\trc = -ENOMEM;\n+\t\tgoto eth_addr_fail;\n+\t}\n+\teth_dev->data->mac_addrs = eth_addr;\n+\n+\t/*\n+\t * Pass the information to the rte_eth_dev_close() that it should also\n+\t * release the private port resources.\n+\t */\n+\teth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;\n+\n+\t/* create hardware nic_device */\n+\trc = hinic_nic_dev_create(eth_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Create nic device failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto create_nic_dev_fail;\n+\t}\n+\n+\trc = hinic_init_mac_addr(eth_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize mac table failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_mac_fail;\n+\t}\n+\n+\t/* register callback func to eal lib */\n+\trc = rte_intr_callback_register(&pci_dev->intr_handle,\n+\t\t\t\t\thinic_dev_interrupt_handler,\n+\t\t\t\t\t(void *)eth_dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Register rte interrupt callback failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto reg_intr_cb_fail;\n+\t}\n+\n+\t/* enable uio/vfio intr/eventfd mapping */\n+\trc = rte_intr_enable(&pci_dev->intr_handle);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Enable rte interrupt failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto enable_intr_fail;\n+\t}\n+\thinic_set_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status);\n+\n+\thinic_set_bit(HINIC_DEV_INIT, &nic_dev->dev_status);\n+\tPMD_DRV_LOG(INFO, \"Initialize %s in primary successfully\",\n+\t\t    eth_dev->data->name);\n+\n+\treturn 0;\n+\n+enable_intr_fail:\n+\t(void)rte_intr_callback_unregister(&pci_dev->intr_handle,\n+\t\t\t\t\t   hinic_dev_interrupt_handler,\n+\t\t\t\t\t   (void *)eth_dev);\n+\n+reg_intr_cb_fail:\n+\thinic_deinit_mac_addr(eth_dev);\n+\n+init_mac_fail:\n+\thinic_nic_dev_destroy(eth_dev);\n+\n+create_nic_dev_fail:\n+\trte_free(eth_addr);\n+\teth_dev->data->mac_addrs = NULL;\n+\n+eth_addr_fail:\n+\tPMD_DRV_LOG(ERR, \"Initialize %s in primary failed\",\n+\t\t    eth_dev->data->name);\n+\treturn rc;\n+}\n+\n /**\n  * DPDK callback to close the device.\n  *\n  * @param dev\n  *   Pointer to Ethernet device structure.\n  */\n-static void hinic_dev_close(__rte_unused struct rte_eth_dev *dev)\n+static void hinic_dev_close(struct rte_eth_dev *dev)\n {\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\n+\tif (hinic_test_and_set_bit(HINIC_DEV_CLOSE, &nic_dev->dev_status)) {\n+\t\tPMD_DRV_LOG(WARNING, \"Device %s already closed\",\n+\t\t\t    dev->data->name);\n+\t\treturn;\n+\t}\n+\n+\t/* rx_cqe, rx_info */\n+\thinic_free_all_rx_resources(dev);\n+\n+\t/* tx_info */\n+\thinic_free_all_tx_resources(dev);\n+\n+\t/* free wq, pi_dma_addr */\n+\thinic_free_all_rq(nic_dev);\n+\n+\t/* free wq, db_addr */\n+\thinic_free_all_sq(nic_dev);\n+\n+\t/* deinit mac vlan tbl */\n+\thinic_deinit_mac_addr(dev);\n+\n+\t/* disable hardware and uio interrupt */\n+\thinic_disable_interrupt(dev);\n+\n+\t/* deinit nic hardware device */\n+\thinic_nic_dev_destroy(dev);\n }\n \n static const struct eth_dev_ops hinic_pmd_ops = {\n+\t.dev_configure                 = hinic_dev_configure,\n \t.dev_infos_get                 = hinic_dev_infos_get,\n+\t.dev_close                     = hinic_dev_close,\n };\n \n static int hinic_dev_init(struct rte_eth_dev *eth_dev)\n@@ -182,8 +876,6 @@ static int hinic_dev_uninit(struct rte_eth_dev *dev)\n \thinic_dev_close(dev);\n \n \tdev->dev_ops = NULL;\n-\tdev->rx_pkt_burst = NULL;\n-\tdev->tx_pkt_burst = NULL;\n \n \trte_free(dev->data->mac_addrs);\n \tdev->data->mac_addrs = NULL;\ndiff --git a/drivers/net/hinic/hinic_pmd_rx.c b/drivers/net/hinic/hinic_pmd_rx.c\nnew file mode 100644\nindex 000000000..f384901ca\n--- /dev/null\n+++ b/drivers/net/hinic/hinic_pmd_rx.c\n@@ -0,0 +1,178 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include <rte_ether.h>\n+#include <rte_mbuf.h>\n+\n+#include \"base/hinic_compat.h\"\n+#include \"base/hinic_pmd_hwdev.h\"\n+#include \"base/hinic_pmd_wq.h\"\n+#include \"base/hinic_pmd_niccfg.h\"\n+#include \"base/hinic_pmd_nicio.h\"\n+#include \"hinic_pmd_ethdev.h\"\n+#include \"hinic_pmd_rx.h\"\n+\n+\n+void hinic_destroy_rq(struct hinic_hwdev *hwdev, u16 q_id)\n+{\n+\tstruct hinic_nic_io *nic_io = hwdev->nic_io;\n+\tstruct hinic_qp *qp = &nic_io->qps[q_id];\n+\tstruct hinic_rq *rq = &qp->rq;\n+\n+\tif (qp->rq.wq == NULL)\n+\t\treturn;\n+\n+\tdma_free_coherent_volatile(hwdev, HINIC_PAGE_SIZE,\n+\t\t\t\t   (volatile void *)rq->pi_virt_addr,\n+\t\t\t\t   rq->pi_dma_addr);\n+\thinic_wq_free(nic_io->hwdev, qp->rq.wq);\n+\tqp->rq.wq = NULL;\n+}\n+\n+static void hinic_rx_free_cqe(struct hinic_rxq *rxq)\n+{\n+\tsize_t cqe_mem_size;\n+\n+\tcqe_mem_size = sizeof(struct hinic_rq_cqe) * rxq->q_depth;\n+\tdma_free_coherent(rxq->nic_dev->hwdev, cqe_mem_size,\n+\t\t\t  rxq->cqe_start_vaddr, rxq->cqe_start_paddr);\n+\trxq->cqe_start_vaddr = NULL;\n+}\n+\n+void hinic_free_rx_resources(struct hinic_rxq *rxq)\n+{\n+\tif (rxq->rx_info == NULL)\n+\t\treturn;\n+\n+\thinic_rx_free_cqe(rxq);\n+\tkfree(rxq->rx_info);\n+\trxq->rx_info = NULL;\n+}\n+\n+void hinic_free_all_rx_resources(struct rte_eth_dev *eth_dev)\n+{\n+\tu16 q_id;\n+\tstruct hinic_nic_dev *nic_dev =\n+\t\t\t\tHINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_rq; q_id++) {\n+\t\teth_dev->data->rx_queues[q_id] = NULL;\n+\n+\t\tif (nic_dev->rxqs[q_id] == NULL)\n+\t\t\tcontinue;\n+\n+\t\thinic_free_all_rx_skbs(nic_dev->rxqs[q_id]);\n+\t\thinic_free_rx_resources(nic_dev->rxqs[q_id]);\n+\t\tkfree(nic_dev->rxqs[q_id]);\n+\t\tnic_dev->rxqs[q_id] = NULL;\n+\t}\n+}\n+\n+static void\n+hinic_add_rq_to_rx_queue_list(struct hinic_nic_dev *nic_dev, u16 queue_id)\n+{\n+\tu8 rss_queue_count = nic_dev->num_rss;\n+\n+\tRTE_ASSERT(rss_queue_count <= (RTE_DIM(nic_dev->rx_queue_list) - 1));\n+\n+\tnic_dev->rx_queue_list[rss_queue_count] = queue_id;\n+\tnic_dev->num_rss++;\n+}\n+\n+/**\n+ * hinic_setup_num_qps - determine num_qps from rss_tmpl_id\n+ * @nic_dev: pointer to the private ethernet device\n+ * Return: 0 on Success, error code otherwise.\n+ **/\n+static int hinic_setup_num_qps(struct hinic_nic_dev *nic_dev)\n+{\n+\tint err, i;\n+\n+\tif (!(nic_dev->flags & ETH_MQ_RX_RSS_FLAG)) {\n+\t\tnic_dev->flags &= ~ETH_MQ_RX_RSS_FLAG;\n+\t\tnic_dev->num_rss = 0;\n+\t\tif (nic_dev->num_rq > 1) {\n+\t\t\t/* get rss template id */\n+\t\t\terr = hinic_rss_template_alloc(nic_dev->hwdev,\n+\t\t\t\t\t\t       &nic_dev->rss_tmpl_idx);\n+\t\t\tif (err) {\n+\t\t\t\tPMD_DRV_LOG(WARNING, \"Alloc rss template failed\");\n+\t\t\t\treturn err;\n+\t\t\t}\n+\t\t\tnic_dev->flags |= ETH_MQ_RX_RSS_FLAG;\n+\t\t\tfor (i = 0; i < nic_dev->num_rq; i++)\n+\t\t\t\thinic_add_rq_to_rx_queue_list(nic_dev, i);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void hinic_destroy_num_qps(struct hinic_nic_dev *nic_dev)\n+{\n+\tif (nic_dev->flags & ETH_MQ_RX_RSS_FLAG) {\n+\t\tif (hinic_rss_template_free(nic_dev->hwdev,\n+\t\t\t\t\t    nic_dev->rss_tmpl_idx))\n+\t\t\tPMD_DRV_LOG(WARNING, \"Free rss template failed\");\n+\n+\t\tnic_dev->flags &= ~ETH_MQ_RX_RSS_FLAG;\n+\t}\n+}\n+\n+static int hinic_config_mq_rx_rss(struct hinic_nic_dev *nic_dev, bool on)\n+{\n+\tint ret = 0;\n+\n+\tif (on) {\n+\t\tret = hinic_setup_num_qps(nic_dev);\n+\t\tif (ret)\n+\t\t\tPMD_DRV_LOG(ERR, \"Setup num_qps failed\");\n+\t} else {\n+\t\thinic_destroy_num_qps(nic_dev);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int hinic_config_mq_mode(struct rte_eth_dev *dev, bool on)\n+{\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tstruct rte_eth_conf *dev_conf = &dev->data->dev_conf;\n+\tint ret = 0;\n+\n+\tswitch (dev_conf->rxmode.mq_mode) {\n+\tcase ETH_MQ_RX_RSS:\n+\t\tret = hinic_config_mq_rx_rss(nic_dev, on);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+void hinic_free_all_rx_skbs(struct hinic_rxq *rxq)\n+{\n+\tstruct hinic_nic_dev *nic_dev = rxq->nic_dev;\n+\tstruct hinic_rx_info *rx_info;\n+\tint free_wqebbs =\n+\t\thinic_get_rq_free_wqebbs(nic_dev->hwdev, rxq->q_id) + 1;\n+\tvolatile struct hinic_rq_cqe *rx_cqe;\n+\tu16 ci;\n+\n+\twhile (free_wqebbs++ < rxq->q_depth) {\n+\t\tci = hinic_get_rq_local_ci(nic_dev->hwdev, rxq->q_id);\n+\n+\t\trx_cqe = &rxq->rx_cqe[ci];\n+\n+\t\t/* clear done bit */\n+\t\trx_cqe->status = 0;\n+\n+\t\trx_info = &rxq->rx_info[ci];\n+\t\trte_pktmbuf_free(rx_info->mbuf);\n+\t\trx_info->mbuf = NULL;\n+\n+\t\thinic_update_rq_local_ci(nic_dev->hwdev, rxq->q_id, 1);\n+\t}\n+}\ndiff --git a/drivers/net/hinic/hinic_pmd_rx.h b/drivers/net/hinic/hinic_pmd_rx.h\nnew file mode 100644\nindex 000000000..fe2735bac\n--- /dev/null\n+++ b/drivers/net/hinic/hinic_pmd_rx.h\n@@ -0,0 +1,128 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_RX_H_\n+#define _HINIC_PMD_RX_H_\n+\n+#define HINIC_DEFAULT_RX_FREE_THRESH\t32\n+\n+#define HINIC_RSS_OFFLOAD_ALL ( \\\n+\tETH_RSS_IPV4 | \\\n+\tETH_RSS_FRAG_IPV4 |\\\n+\tETH_RSS_NONFRAG_IPV4_TCP | \\\n+\tETH_RSS_NONFRAG_IPV4_UDP | \\\n+\tETH_RSS_IPV6 | \\\n+\tETH_RSS_FRAG_IPV6 | \\\n+\tETH_RSS_NONFRAG_IPV6_TCP | \\\n+\tETH_RSS_NONFRAG_IPV6_UDP | \\\n+\tETH_RSS_IPV6_EX | \\\n+\tETH_RSS_IPV6_TCP_EX | \\\n+\tETH_RSS_IPV6_UDP_EX)\n+\n+enum rq_completion_fmt {\n+\tRQ_COMPLETE_SGE = 1\n+};\n+\n+struct hinic_rq_ctrl {\n+\tu32\tctrl_fmt;\n+};\n+\n+struct hinic_rq_cqe {\n+\tu32 status;\n+\tu32 vlan_len;\n+\tu32 offload_type;\n+\tu32 rss_hash;\n+\n+\tu32 rsvd[4];\n+};\n+\n+struct hinic_rq_cqe_sect {\n+\tstruct hinic_sge\tsge;\n+\tu32\t\t\trsvd;\n+};\n+\n+struct hinic_rq_bufdesc {\n+\tu32\taddr_high;\n+\tu32\taddr_low;\n+};\n+\n+struct hinic_rq_wqe {\n+\tstruct hinic_rq_ctrl\t\tctrl;\n+\tu32\t\t\t\trsvd;\n+\tstruct hinic_rq_cqe_sect\tcqe_sect;\n+\tstruct hinic_rq_bufdesc\t\tbuf_desc;\n+};\n+\n+struct hinic_rxq_stats {\n+\tu64 packets;\n+\tu64 bytes;\n+\tu64 rx_nombuf;\n+\tu64 errors;\n+\tu64 rx_discards;\n+\tu64 burst_pkts;\n+};\n+\n+/* Attention, Do not add any member in hinic_rx_info\n+ * as rxq bulk rearm mode will write mbuf in rx_info\n+ */\n+struct hinic_rx_info {\n+\tstruct rte_mbuf *mbuf;\n+};\n+\n+struct hinic_rxq {\n+\tstruct hinic_wq *wq;\n+\tvolatile u16 *pi_virt_addr;\n+\n+\tu16 port_id;\n+\tu16 q_id;\n+\tu16 q_depth;\n+\tu16 buf_len;\n+\n+\tu16 rx_free_thresh;\n+\tu16 rxinfo_align_end;\n+\n+\tunsigned long status;\n+\tstruct hinic_rxq_stats rxq_stats;\n+\n+\tstruct hinic_nic_dev *nic_dev;\n+\n+\tstruct hinic_rx_info\t*rx_info;\n+\tvolatile struct hinic_rq_cqe *rx_cqe;\n+\n+\tdma_addr_t cqe_start_paddr;\n+\tvoid *cqe_start_vaddr;\n+\tstruct rte_mempool *mb_pool;\n+};\n+\n+int hinic_setup_rx_resources(struct hinic_rxq *rxq);\n+\n+void hinic_free_all_rx_resources(struct rte_eth_dev *eth_dev);\n+\n+void hinic_free_all_rx_mbuf(struct rte_eth_dev *eth_dev);\n+\n+void hinic_free_rx_resources(struct hinic_rxq *rxq);\n+\n+u16 hinic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, u16 nb_pkts);\n+\n+void hinic_free_all_rx_skbs(struct hinic_rxq *rxq);\n+\n+void hinic_rx_alloc_pkts(struct hinic_rxq *rxq);\n+\n+void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats);\n+\n+void hinic_rxq_stats_reset(struct hinic_rxq *rxq);\n+\n+int hinic_config_mq_mode(struct rte_eth_dev *dev, bool on);\n+\n+int hinic_rx_configure(struct rte_eth_dev *dev);\n+\n+void hinic_rx_remove_configure(struct rte_eth_dev *dev);\n+\n+void hinic_get_func_rx_buf_size(struct hinic_nic_dev *nic_dev);\n+\n+int hinic_create_rq(struct hinic_hwdev *hwdev, u16 q_id, u16 rq_depth);\n+\n+void hinic_destroy_rq(struct hinic_hwdev *hwdev, u16 q_id);\n+\n+#endif /* _HINIC_PMD_RX_H_ */\ndiff --git a/drivers/net/hinic/hinic_pmd_tx.c b/drivers/net/hinic/hinic_pmd_tx.c\nnew file mode 100644\nindex 000000000..79c5f9822\n--- /dev/null\n+++ b/drivers/net/hinic/hinic_pmd_tx.c\n@@ -0,0 +1,92 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include <rte_mbuf.h>\n+#include <rte_tcp.h>\n+#include <rte_sctp.h>\n+#include <rte_udp.h>\n+#include <rte_ip.h>\n+\n+#include \"base/hinic_compat.h\"\n+#include \"base/hinic_pmd_hwdev.h\"\n+#include \"base/hinic_pmd_hwif.h\"\n+#include \"base/hinic_pmd_wq.h\"\n+#include \"base/hinic_pmd_nicio.h\"\n+#include \"hinic_pmd_ethdev.h\"\n+#include \"hinic_pmd_tx.h\"\n+\n+\n+void hinic_free_all_tx_skbs(struct hinic_txq *txq)\n+{\n+\tu16 ci;\n+\tstruct hinic_nic_dev *nic_dev = txq->nic_dev;\n+\tstruct hinic_tx_info *tx_info;\n+\tint free_wqebbs = hinic_get_sq_free_wqebbs(nic_dev->hwdev,\n+\t\t\t\t\t\t   txq->q_id) + 1;\n+\n+\twhile (free_wqebbs < txq->q_depth) {\n+\t\tci = hinic_get_sq_local_ci(nic_dev->hwdev, txq->q_id);\n+\n+\t\ttx_info = &txq->tx_info[ci];\n+\n+\t\tif (unlikely(tx_info->cpy_mbuf != NULL)) {\n+\t\t\trte_pktmbuf_free(tx_info->cpy_mbuf);\n+\t\t\ttx_info->cpy_mbuf = NULL;\n+\t\t}\n+\n+\t\trte_pktmbuf_free(tx_info->mbuf);\n+\t\thinic_update_sq_local_ci(nic_dev->hwdev, txq->q_id,\n+\t\t\t\t\t tx_info->wqebb_cnt);\n+\n+\t\tfree_wqebbs += tx_info->wqebb_cnt;\n+\t\ttx_info->mbuf = NULL;\n+\t}\n+}\n+\n+void hinic_free_all_tx_resources(struct rte_eth_dev *eth_dev)\n+{\n+\tu16 q_id;\n+\tstruct hinic_nic_dev *nic_dev =\n+\t\t\t\tHINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_sq; q_id++) {\n+\t\teth_dev->data->tx_queues[q_id] = NULL;\n+\n+\t\tif (nic_dev->txqs[q_id] == NULL)\n+\t\t\tcontinue;\n+\n+\t\t/* stop tx queue free tx mbuf */\n+\t\thinic_free_all_tx_skbs(nic_dev->txqs[q_id]);\n+\t\thinic_free_tx_resources(nic_dev->txqs[q_id]);\n+\n+\t\t/* free txq */\n+\t\tkfree(nic_dev->txqs[q_id]);\n+\t\tnic_dev->txqs[q_id] = NULL;\n+\t}\n+}\n+\n+void hinic_free_tx_resources(struct hinic_txq *txq)\n+{\n+\tif (txq->tx_info == NULL)\n+\t\treturn;\n+\n+\tkfree(txq->tx_info);\n+\ttxq->tx_info = NULL;\n+}\n+\n+void hinic_destroy_sq(struct hinic_hwdev *hwdev, u16 q_id)\n+{\n+\tstruct hinic_nic_io *nic_io;\n+\tstruct hinic_qp *qp;\n+\n+\tnic_io = hwdev->nic_io;\n+\tqp = &nic_io->qps[q_id];\n+\n+\tif (qp->sq.wq == NULL)\n+\t\treturn;\n+\n+\thinic_free_db_addr(nic_io->hwdev, qp->sq.db_addr);\n+\thinic_wq_free(nic_io->hwdev, qp->sq.wq);\n+\tqp->sq.wq = NULL;\n+}\ndiff --git a/drivers/net/hinic/hinic_pmd_tx.h b/drivers/net/hinic/hinic_pmd_tx.h\nnew file mode 100644\nindex 000000000..8b361cf9f\n--- /dev/null\n+++ b/drivers/net/hinic/hinic_pmd_tx.h\n@@ -0,0 +1,143 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_TX_H_\n+#define _HINIC_PMD_TX_H_\n+\n+#define HINIC_DEFAULT_TX_FREE_THRESH\t32\n+#define HINIC_MAX_TX_FREE_BULK\t\t64\n+\n+#define HINIC_GET_WQ_HEAD(txq)\t\t((txq)->wq->queue_buf_vaddr)\n+\n+#define HINIC_GET_WQ_TAIL(txq)\t\t\\\n+\t\t((txq)->wq->queue_buf_vaddr + (txq)->wq->wq_buf_size)\n+\n+#define HINIC_TX_CKSUM_OFFLOAD_MASK (\t\\\n+\t\tPKT_TX_IP_CKSUM |\t\\\n+\t\tPKT_TX_TCP_CKSUM |\t\\\n+\t\tPKT_TX_UDP_CKSUM |      \\\n+\t\tPKT_TX_SCTP_CKSUM |\t\\\n+\t\tPKT_TX_OUTER_IP_CKSUM |\t\\\n+\t\tPKT_TX_TCP_SEG)\n+\n+enum sq_wqe_type {\n+\tSQ_NORMAL_WQE = 0,\n+};\n+\n+/* tx offload info */\n+struct hinic_tx_offload_info {\n+\tu8 outer_l2_len;\n+\tu8 outer_l3_type;\n+\tu8 outer_l3_len;\n+\n+\tu8 inner_l2_len;\n+\tu8 inner_l3_type;\n+\tu8 inner_l3_len;\n+\n+\tu8 tunnel_length;\n+\tu8 tunnel_type;\n+\tu8 inner_l4_type;\n+\tu8 inner_l4_len;\n+\n+\tu8 payload_offset;\n+\tu8 inner_l4_tcp_udp;\n+};\n+\n+/* tx sge info */\n+struct hinic_wqe_info {\n+\tu16 pi;\n+\tu16 owner;\n+\tu16 around;\n+\tu16 seq_wqebbs;\n+\tu16 sge_cnt;\n+\tu16 cpy_mbuf_cnt;\n+};\n+\n+struct hinic_sq_ctrl {\n+\tu32\tctrl_fmt;\n+\tu32\tqueue_info;\n+};\n+\n+struct hinic_sq_task {\n+\tu32\t\tpkt_info0;\n+\tu32\t\tpkt_info1;\n+\tu32\t\tpkt_info2;\n+\tu32\t\tufo_v6_identify;\n+\tu32\t\tpkt_info4;\n+\tu32\t\trsvd5;\n+};\n+\n+struct hinic_sq_bufdesc {\n+\tstruct hinic_sge sge;\n+\tu32\trsvd;\n+};\n+\n+struct hinic_sq_wqe {\n+\t/* sq wqe control section */\n+\tstruct hinic_sq_ctrl\t\tctrl;\n+\n+\t/* sq task control section */\n+\tstruct hinic_sq_task\t\ttask;\n+\n+\t/* sq sge section start address, 1~127 sges */\n+\tstruct hinic_sq_bufdesc     buf_descs[0];\n+};\n+\n+struct hinic_txq_stats {\n+\tu64 packets;\n+\tu64 bytes;\n+\tu64 rl_drop;\n+\tu64 tx_busy;\n+\tu64 off_errs;\n+\tu64 cpy_pkts;\n+\tu64 burst_pkts;\n+};\n+\n+struct hinic_tx_info {\n+\tstruct rte_mbuf *mbuf;\n+\tint wqebb_cnt;\n+\tstruct rte_mbuf *cpy_mbuf;\n+};\n+\n+struct hinic_txq {\n+\t/* cacheline0 */\n+\tstruct hinic_nic_dev *nic_dev;\n+\tstruct hinic_wq *wq;\n+\tstruct hinic_sq *sq;\n+\tvolatile u16 *cons_idx_addr;\n+\tstruct hinic_tx_info *tx_info;\n+\n+\tu16 tx_free_thresh;\n+\tu16 port_id;\n+\tu16 q_id;\n+\tu16 q_depth;\n+\tu32 cos;\n+\n+\t/* cacheline1 */\n+\tstruct hinic_txq_stats txq_stats;\n+\tu64 sq_head_addr;\n+\tu64 sq_bot_sge_addr;\n+};\n+\n+int hinic_setup_tx_resources(struct hinic_txq *txq);\n+\n+void hinic_free_all_tx_resources(struct rte_eth_dev *eth_dev);\n+\n+void hinic_free_all_tx_mbuf(struct rte_eth_dev *eth_dev);\n+\n+void hinic_free_tx_resources(struct hinic_txq *txq);\n+\n+u16 hinic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, u16 nb_pkts);\n+\n+void hinic_free_all_tx_skbs(struct hinic_txq *txq);\n+\n+void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats);\n+\n+void hinic_txq_stats_reset(struct hinic_txq *txq);\n+\n+int hinic_create_sq(struct hinic_hwdev *hwdev, u16 q_id, u16 sq_depth);\n+\n+void hinic_destroy_sq(struct hinic_hwdev *hwdev, u16 q_id);\n+\n+#endif /* _HINIC_PMD_TX_H_ */\ndiff --git a/drivers/net/hinic/meson.build b/drivers/net/hinic/meson.build\nindex d1c3ecc77..87c8d163e 100644\n--- a/drivers/net/hinic/meson.build\n+++ b/drivers/net/hinic/meson.build\n@@ -6,6 +6,8 @@ objs = [base_objs]\n \n sources = files(\n \t'hinic_pmd_ethdev.c',\n+\t'hinic_pmd_rx.c',\n+\t'hinic_pmd_tx.c',\n \t)\n \n includes += include_directories('base')\n",
    "prefixes": [
        "v6",
        "12/15"
    ]
}