get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 55451,
    "url": "http://patches.dpdk.org/api/patches/55451/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/130199f8f58fd9be36485bfe6e94c26a6f106fe9.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": "<130199f8f58fd9be36485bfe6e94c26a6f106fe9.1561620219.git.xuanziyang2@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/130199f8f58fd9be36485bfe6e94c26a6f106fe9.1561620219.git.xuanziyang2@huawei.com",
    "date": "2019-06-27T08:19:19",
    "name": "[v6,13/15] net/hinic: add start stop close queue ops",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "32b37cde7a1f60c037f807998cad74d21b142731",
    "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/130199f8f58fd9be36485bfe6e94c26a6f106fe9.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/55451/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/55451/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 79A902BB5;\n\tThu, 27 Jun 2019 10:07:30 +0200 (CEST)",
            "from huawei.com (szxga07-in.huawei.com [45.249.212.35])\n\tby dpdk.org (Postfix) with ESMTP id 223342BB5\n\tfor <dev@dpdk.org>; Thu, 27 Jun 2019 10:07:29 +0200 (CEST)",
            "from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.60])\n\tby Forcepoint Email with ESMTP id D539C42F85AE02665E80\n\tfor <dev@dpdk.org>; Thu, 27 Jun 2019 16:07:27 +0800 (CST)",
            "from tester_149.localdomain (10.175.119.39) by\n\tDGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP\n\tServer id 14.3.439.0; Thu, 27 Jun 2019 16:07:20 +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:19:19 +0800",
        "Message-ID": "<130199f8f58fd9be36485bfe6e94c26a6f106fe9.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 13/15] net/hinic: add start stop close queue\n\tops",
        "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 dev_start, dev_stop, link_update, queue_setup, queue_release\nrelated function codes.\n\nSigned-off-by: Ziyang Xuan <xuanziyang2@huawei.com>\n---\n drivers/net/hinic/hinic_pmd_ethdev.c | 684 +++++++++++++++++++++++++++\n drivers/net/hinic/hinic_pmd_rx.c     | 420 ++++++++++++++++\n drivers/net/hinic/hinic_pmd_tx.c     |  68 +++\n 3 files changed, 1172 insertions(+)",
    "diff": "diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c\nindex f984465ed..eeb4227fa 100644\n--- a/drivers/net/hinic/hinic_pmd_ethdev.c\n+++ b/drivers/net/hinic/hinic_pmd_ethdev.c\n@@ -58,6 +58,7 @@ static const struct rte_eth_desc_lim hinic_tx_desc_lim = {\n \t.nb_align = HINIC_TXD_ALIGN,\n };\n \n+\n /**\n  * Interrupt handler triggered by NIC  for handling\n  * specific event.\n@@ -143,6 +144,311 @@ static int hinic_dev_configure(struct rte_eth_dev *dev)\n \treturn HINIC_OK;\n }\n \n+/**\n+ * DPDK callback to create the receive queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param queue_idx\n+ *   RX queue index.\n+ * @param nb_desc\n+ *   Number of descriptors for receive queue.\n+ * @param socket_id\n+ *   NUMA socket on which memory must be allocated.\n+ * @param rx_conf\n+ *   Thresholds parameters (unused_).\n+ * @param mp\n+ *   Memory pool for buffer allocations.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int hinic_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\t uint16_t nb_desc, unsigned int socket_id,\n+\t\t\t __rte_unused const struct rte_eth_rxconf *rx_conf,\n+\t\t\t struct rte_mempool *mp)\n+{\n+\tint rc;\n+\tstruct hinic_nic_dev *nic_dev;\n+\tstruct hinic_hwdev *hwdev;\n+\tstruct hinic_rxq *rxq;\n+\tu16 rq_depth, rx_free_thresh;\n+\tu32 buf_size;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\thwdev = nic_dev->hwdev;\n+\n+\t/* queue depth must be power of 2, otherwise will be aligned up */\n+\trq_depth = (nb_desc & (nb_desc - 1)) ?\n+\t\t((u16)(1U << (ilog2(nb_desc) + 1))) : nb_desc;\n+\n+\t/*\n+\t * Validate number of receive descriptors.\n+\t * It must not exceed hardware maximum and minimum.\n+\t */\n+\tif (rq_depth > HINIC_MAX_QUEUE_DEPTH ||\n+\t\trq_depth < HINIC_MIN_QUEUE_DEPTH) {\n+\t\tPMD_DRV_LOG(ERR, \"RX queue depth is out of range from %d to %d, (nb_desc=%d, q_depth=%d, port=%d queue=%d)\",\n+\t\t\t    HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH,\n+\t\t\t    (int)nb_desc, (int)rq_depth,\n+\t\t\t    (int)dev->data->port_id, (int)queue_idx);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * The RX descriptor ring will be cleaned after rxq->rx_free_thresh\n+\t * descriptors are used or if the number of descriptors required\n+\t * to transmit a packet is greater than the number of free RX\n+\t * descriptors.\n+\t * The following constraints must be satisfied:\n+\t *  rx_free_thresh must be greater than 0.\n+\t *  rx_free_thresh must be less than the size of the ring minus 1.\n+\t * When set to zero use default values.\n+\t */\n+\trx_free_thresh = (u16)((rx_conf->rx_free_thresh) ?\n+\t\t\trx_conf->rx_free_thresh : HINIC_DEFAULT_RX_FREE_THRESH);\n+\tif (rx_free_thresh >= (rq_depth - 1)) {\n+\t\tPMD_DRV_LOG(ERR, \"rx_free_thresh must be less than the number of RX descriptors minus 1. (rx_free_thresh=%u port=%d queue=%d)\",\n+\t\t\t    (unsigned int)rx_free_thresh,\n+\t\t\t    (int)dev->data->port_id,\n+\t\t\t    (int)queue_idx);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trxq = rte_zmalloc_socket(\"hinic_rx_queue\", sizeof(struct hinic_rxq),\n+\t\t\t\t RTE_CACHE_LINE_SIZE, socket_id);\n+\tif (!rxq) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate rxq[%d] failed, dev_name: %s\",\n+\t\t\t    queue_idx, dev->data->name);\n+\t\treturn -ENOMEM;\n+\t}\n+\tnic_dev->rxqs[queue_idx] = rxq;\n+\n+\t/* alloc rx sq hw wqepage*/\n+\trc = hinic_create_rq(hwdev, queue_idx, rq_depth);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Create rxq[%d] failed, dev_name: %s, rq_depth: %d\",\n+\t\t\t    queue_idx, dev->data->name, rq_depth);\n+\t\tgoto ceate_rq_fail;\n+\t}\n+\n+\t/* mbuf pool must be assigned before setup rx resources */\n+\trxq->mb_pool = mp;\n+\n+\trc =\n+\thinic_convert_rx_buf_size(rte_pktmbuf_data_room_size(rxq->mb_pool) -\n+\t\t\t\t  RTE_PKTMBUF_HEADROOM, &buf_size);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Adjust buf size failed, dev_name: %s\",\n+\t\t\t    dev->data->name);\n+\t\tgoto adjust_bufsize_fail;\n+\t}\n+\n+\t/* rx queue info, rearm control */\n+\trxq->wq = &hwdev->nic_io->rq_wq[queue_idx];\n+\trxq->pi_virt_addr = hwdev->nic_io->qps[queue_idx].rq.pi_virt_addr;\n+\trxq->nic_dev = nic_dev;\n+\trxq->q_id = queue_idx;\n+\trxq->q_depth = rq_depth;\n+\trxq->buf_len = (u16)buf_size;\n+\trxq->rx_free_thresh = rx_free_thresh;\n+\n+\t/* the last point cant do mbuf rearm in bulk */\n+\trxq->rxinfo_align_end = rxq->q_depth - rxq->rx_free_thresh;\n+\n+\t/* device port identifier */\n+\trxq->port_id = dev->data->port_id;\n+\n+\t/* alloc rx_cqe and prepare rq_wqe */\n+\trc = hinic_setup_rx_resources(rxq);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Setup rxq[%d] rx_resources failed, dev_name:%s\",\n+\t\t\t    queue_idx, dev->data->name);\n+\t\tgoto setup_rx_res_err;\n+\t}\n+\n+\t/* record nic_dev rxq in rte_eth rx_queues */\n+\tdev->data->rx_queues[queue_idx] = rxq;\n+\n+\treturn 0;\n+\n+setup_rx_res_err:\n+adjust_bufsize_fail:\n+\thinic_destroy_rq(hwdev, queue_idx);\n+\n+ceate_rq_fail:\n+\trte_free(rxq);\n+\n+\treturn rc;\n+}\n+\n+static void hinic_reset_rx_queue(struct rte_eth_dev *dev)\n+{\n+\tstruct hinic_rxq *rxq;\n+\tstruct hinic_nic_dev *nic_dev;\n+\tint q_id = 0;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_rq; q_id++) {\n+\t\trxq = dev->data->rx_queues[q_id];\n+\n+\t\trxq->wq->cons_idx = 0;\n+\t\trxq->wq->prod_idx = 0;\n+\t\trxq->wq->delta = rxq->q_depth;\n+\t\trxq->wq->mask = rxq->q_depth - 1;\n+\n+\t\t/* alloc mbuf to rq */\n+\t\thinic_rx_alloc_pkts(rxq);\n+\t}\n+}\n+\n+/**\n+ * DPDK callback to configure the transmit queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param queue_idx\n+ *   Transmit queue index.\n+ * @param nb_desc\n+ *   Number of descriptors for transmit queue.\n+ * @param socket_id\n+ *   NUMA socket on which memory must be allocated.\n+ * @param tx_conf\n+ *   Tx queue configuration parameters.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+static int hinic_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\t uint16_t nb_desc, unsigned int socket_id,\n+\t\t\t __rte_unused const struct rte_eth_txconf *tx_conf)\n+{\n+\tint rc;\n+\tstruct hinic_nic_dev *nic_dev;\n+\tstruct hinic_hwdev *hwdev;\n+\tstruct hinic_txq *txq;\n+\tu16 sq_depth, tx_free_thresh;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\thwdev = nic_dev->hwdev;\n+\n+\t/* queue depth must be power of 2, otherwise will be aligned up */\n+\tsq_depth = (nb_desc & (nb_desc - 1)) ?\n+\t\t\t((u16)(1U << (ilog2(nb_desc) + 1))) : nb_desc;\n+\n+\t/*\n+\t * Validate number of transmit descriptors.\n+\t * It must not exceed hardware maximum and minimum.\n+\t */\n+\tif (sq_depth > HINIC_MAX_QUEUE_DEPTH ||\n+\t\tsq_depth < HINIC_MIN_QUEUE_DEPTH) {\n+\t\tPMD_DRV_LOG(ERR, \"TX queue depth is out of range from %d to %d, (nb_desc=%d, q_depth=%d, port=%d queue=%d)\",\n+\t\t\t  HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH,\n+\t\t\t  (int)nb_desc, (int)sq_depth,\n+\t\t\t  (int)dev->data->port_id, (int)queue_idx);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * The TX descriptor ring will be cleaned after txq->tx_free_thresh\n+\t * descriptors are used or if the number of descriptors required\n+\t * to transmit a packet is greater than the number of free TX\n+\t * descriptors.\n+\t * The following constraints must be satisfied:\n+\t *  tx_free_thresh must be greater than 0.\n+\t *  tx_free_thresh must be less than the size of the ring minus 1.\n+\t * When set to zero use default values.\n+\t */\n+\ttx_free_thresh = (u16)((tx_conf->tx_free_thresh) ?\n+\t\t\ttx_conf->tx_free_thresh : HINIC_DEFAULT_TX_FREE_THRESH);\n+\tif (tx_free_thresh >= (sq_depth - 1)) {\n+\t\tPMD_DRV_LOG(ERR, \"tx_free_thresh must be less than the number of TX descriptors minus 1. (tx_free_thresh=%u port=%d queue=%d)\",\n+\t\t\t(unsigned int)tx_free_thresh, (int)dev->data->port_id,\n+\t\t\t(int)queue_idx);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttxq = rte_zmalloc_socket(\"hinic_tx_queue\", sizeof(struct hinic_txq),\n+\t\t\t\t RTE_CACHE_LINE_SIZE, socket_id);\n+\tif (!txq) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate txq[%d] failed, dev_name: %s\",\n+\t\t\t    queue_idx, dev->data->name);\n+\t\treturn -ENOMEM;\n+\t}\n+\tnic_dev->txqs[queue_idx] = txq;\n+\n+\t/* alloc tx sq hw wqepage */\n+\trc = hinic_create_sq(hwdev, queue_idx, sq_depth);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Create txq[%d] failed, dev_name: %s, sq_depth: %d\",\n+\t\t\t    queue_idx, dev->data->name, sq_depth);\n+\t\tgoto create_sq_fail;\n+\t}\n+\n+\ttxq->q_id = queue_idx;\n+\ttxq->q_depth = sq_depth;\n+\ttxq->port_id = dev->data->port_id;\n+\ttxq->tx_free_thresh = tx_free_thresh;\n+\ttxq->nic_dev = nic_dev;\n+\ttxq->wq = &hwdev->nic_io->sq_wq[queue_idx];\n+\ttxq->sq = &hwdev->nic_io->qps[queue_idx].sq;\n+\ttxq->cons_idx_addr = hwdev->nic_io->qps[queue_idx].sq.cons_idx_addr;\n+\ttxq->sq_head_addr = HINIC_GET_WQ_HEAD(txq);\n+\ttxq->sq_bot_sge_addr = HINIC_GET_WQ_TAIL(txq) -\n+\t\t\t\t\tsizeof(struct hinic_sq_bufdesc);\n+\ttxq->cos = nic_dev->default_cos;\n+\n+\t/* alloc software txinfo */\n+\trc = hinic_setup_tx_resources(txq);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Setup txq[%d] tx_resources failed, dev_name: %s\",\n+\t\t\t    queue_idx, dev->data->name);\n+\t\tgoto setup_tx_res_fail;\n+\t}\n+\n+\t/* record nic_dev txq in rte_eth tx_queues */\n+\tdev->data->tx_queues[queue_idx] = txq;\n+\n+\treturn HINIC_OK;\n+\n+setup_tx_res_fail:\n+\thinic_destroy_sq(hwdev, queue_idx);\n+\n+create_sq_fail:\n+\trte_free(txq);\n+\n+\treturn rc;\n+}\n+\n+static void hinic_reset_tx_queue(struct rte_eth_dev *dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev;\n+\tstruct hinic_txq *txq;\n+\tstruct hinic_nic_io *nic_io;\n+\tstruct hinic_hwdev *hwdev;\n+\tvolatile u32 *ci_addr;\n+\tint q_id = 0;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\thwdev = nic_dev->hwdev;\n+\tnic_io = hwdev->nic_io;\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_sq; q_id++) {\n+\t\ttxq = dev->data->tx_queues[q_id];\n+\n+\t\ttxq->wq->cons_idx = 0;\n+\t\ttxq->wq->prod_idx = 0;\n+\t\ttxq->wq->delta = txq->q_depth;\n+\t\ttxq->wq->mask  = txq->q_depth - 1;\n+\n+\t\t/*clear hardware ci*/\n+\t\tci_addr = (volatile u32 *)HINIC_CI_VADDR(nic_io->ci_vaddr_base,\n+\t\t\t\t\t\t\tq_id);\n+\t\t*ci_addr = 0;\n+\t}\n+}\n+\n /**\n  * Get link speed from NIC.\n  *\n@@ -236,6 +542,301 @@ hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)\n \tinfo->tx_desc_lim = hinic_tx_desc_lim;\n }\n \n+static int hinic_config_rx_mode(struct hinic_nic_dev *nic_dev, u32 rx_mode_ctrl)\n+{\n+\tint err;\n+\n+\terr = hinic_set_rx_mode(nic_dev->hwdev, rx_mode_ctrl);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set rx mode\");\n+\t\treturn -EINVAL;\n+\t}\n+\tnic_dev->rx_mode_status = rx_mode_ctrl;\n+\n+\treturn 0;\n+}\n+\n+\n+static int hinic_rxtx_configure(struct rte_eth_dev *dev)\n+{\n+\tint err;\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\n+\t/* rx configure, if rss enable, need to init default configuration */\n+\terr = hinic_rx_configure(dev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Configure rss failed\");\n+\t\treturn err;\n+\t}\n+\n+\t/* rx mode init */\n+\terr = hinic_config_rx_mode(nic_dev, HINIC_DEFAULT_RX_MODE);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Configure rx_mode:0x%x failed\",\n+\t\t\tHINIC_DEFAULT_RX_MODE);\n+\t\tgoto set_rx_mode_fail;\n+\t}\n+\n+\treturn HINIC_OK;\n+\n+set_rx_mode_fail:\n+\thinic_rx_remove_configure(dev);\n+\n+\treturn err;\n+}\n+\n+static void hinic_remove_rxtx_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\n+\t(void)hinic_config_rx_mode(nic_dev, 0);\n+\thinic_rx_remove_configure(dev);\n+}\n+\n+static int hinic_priv_get_dev_link_status(struct hinic_nic_dev *nic_dev,\n+\t\t\t\t\t  struct rte_eth_link *link)\n+{\n+\tint rc;\n+\tu8 port_link_status = 0;\n+\tstruct nic_port_info port_link_info;\n+\tstruct hinic_hwdev *nic_hwdev = nic_dev->hwdev;\n+\tuint32_t port_speed[LINK_SPEED_MAX] = {ETH_SPEED_NUM_10M,\n+\t\t\t\t\tETH_SPEED_NUM_100M, ETH_SPEED_NUM_1G,\n+\t\t\t\t\tETH_SPEED_NUM_10G, ETH_SPEED_NUM_25G,\n+\t\t\t\t\tETH_SPEED_NUM_40G, ETH_SPEED_NUM_100G};\n+\n+\trc = hinic_get_link_status(nic_hwdev, &port_link_status);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (!port_link_status) {\n+\t\tlink->link_status = ETH_LINK_DOWN;\n+\t\tlink->link_speed = 0;\n+\t\tlink->link_duplex = ETH_LINK_HALF_DUPLEX;\n+\t\tlink->link_autoneg = ETH_LINK_FIXED;\n+\t\treturn HINIC_OK;\n+\t}\n+\n+\tmemset(&port_link_info, 0, sizeof(port_link_info));\n+\trc = hinic_get_port_info(nic_hwdev, &port_link_info);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tlink->link_speed = port_speed[port_link_info.speed % LINK_SPEED_MAX];\n+\tlink->link_duplex = port_link_info.duplex;\n+\tlink->link_autoneg = port_link_info.autoneg_state;\n+\tlink->link_status = port_link_status;\n+\n+\treturn HINIC_OK;\n+}\n+\n+/**\n+ * DPDK callback to retrieve physical link information.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param wait_to_complete\n+ *   Wait for request completion.\n+ *\n+ * @return\n+ *   0 link status changed, -1 link status not changed\n+ */\n+static int hinic_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n+{\n+#define CHECK_INTERVAL 10  /* 10ms */\n+#define MAX_REPEAT_TIME 100  /* 1s (100 * 10ms) in total */\n+\tint rc = HINIC_OK;\n+\tstruct rte_eth_link link;\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tunsigned int rep_cnt = MAX_REPEAT_TIME;\n+\n+\tmemset(&link, 0, sizeof(link));\n+\tdo {\n+\t\t/* Get link status information from hardware */\n+\t\trc = hinic_priv_get_dev_link_status(nic_dev, &link);\n+\t\tif (rc != HINIC_OK) {\n+\t\t\tlink.link_speed = ETH_SPEED_NUM_NONE;\n+\t\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n+\t\t\tPMD_DRV_LOG(ERR, \"Get link status failed\");\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tif (!wait_to_complete || link.link_status)\n+\t\t\tbreak;\n+\n+\t\trte_delay_ms(CHECK_INTERVAL);\n+\t} while (rep_cnt--);\n+\n+out:\n+\trc = rte_eth_linkstatus_set(dev, &link);\n+\treturn rc;\n+}\n+\n+/**\n+ * DPDK callback to start the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value on failure.\n+ */\n+static int hinic_dev_start(struct rte_eth_dev *dev)\n+{\n+\tint rc;\n+\tchar *name;\n+\tstruct hinic_nic_dev *nic_dev;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tname = dev->data->name;\n+\n+\t/* reset rx and tx queue */\n+\thinic_reset_rx_queue(dev);\n+\thinic_reset_tx_queue(dev);\n+\n+\t/* get func rx buf size */\n+\thinic_get_func_rx_buf_size(nic_dev);\n+\n+\t/* init txq and rxq context */\n+\trc = hinic_init_qp_ctxts(nic_dev->hwdev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Initialize qp context failed, dev_name:%s\",\n+\t\t\t    name);\n+\t\tgoto init_qp_fail;\n+\t}\n+\n+\t/* rss template */\n+\trc = hinic_config_mq_mode(dev, TRUE);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Configure mq mode failed, dev_name: %s\",\n+\t\t\t    name);\n+\t\tgoto cfg_mq_mode_fail;\n+\t}\n+\n+\t/* set default mtu */\n+\trc = hinic_set_port_mtu(nic_dev->hwdev, nic_dev->mtu_size);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Set mtu_size[%d] failed, dev_name: %s\",\n+\t\t\t    nic_dev->mtu_size, name);\n+\t\tgoto set_mtu_fail;\n+\t}\n+\n+\t/* configure rss rx_mode and other rx or tx default feature */\n+\trc = hinic_rxtx_configure(dev);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Configure tx and rx failed, dev_name: %s\",\n+\t\t\t    name);\n+\t\tgoto cfg_rxtx_fail;\n+\t}\n+\n+\t/* open virtual port and ready to start packet receiving */\n+\trc = hinic_set_vport_enable(nic_dev->hwdev, true);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Enable vport failed, dev_name:%s\", name);\n+\t\tgoto en_vport_fail;\n+\t}\n+\n+\t/* open physical port and start packet receiving */\n+\trc = hinic_set_port_enable(nic_dev->hwdev, true);\n+\tif (rc) {\n+\t\tPMD_DRV_LOG(ERR, \"Enable physical port failed, dev_name:%s\",\n+\t\t\t    name);\n+\t\tgoto en_port_fail;\n+\t}\n+\n+\t/* update eth_dev link status */\n+\tif (dev->data->dev_conf.intr_conf.lsc != 0)\n+\t\t(void)hinic_link_update(dev, 0);\n+\n+\thinic_set_bit(HINIC_DEV_START, &nic_dev->dev_status);\n+\n+\treturn 0;\n+\n+en_port_fail:\n+\t(void)hinic_set_vport_enable(nic_dev->hwdev, false);\n+\n+en_vport_fail:\n+\t/* Flush tx && rx chip resources in case of set vport fake fail */\n+\t(void)hinic_flush_qp_res(nic_dev->hwdev);\n+\trte_delay_ms(100);\n+\n+\thinic_remove_rxtx_configure(dev);\n+\n+cfg_rxtx_fail:\n+set_mtu_fail:\n+cfg_mq_mode_fail:\n+\thinic_free_qp_ctxts(nic_dev->hwdev);\n+\n+init_qp_fail:\n+\thinic_free_all_rx_mbuf(dev);\n+\thinic_free_all_tx_mbuf(dev);\n+\n+\treturn rc;\n+}\n+\n+/**\n+ * DPDK callback to release the receive queue.\n+ *\n+ * @param queue\n+ *   Generic receive queue pointer.\n+ */\n+static void hinic_rx_queue_release(void *queue)\n+{\n+\tstruct hinic_rxq *rxq = queue;\n+\tstruct hinic_nic_dev *nic_dev;\n+\n+\tif (!rxq) {\n+\t\tPMD_DRV_LOG(WARNING, \"Rxq is null when release\");\n+\t\treturn;\n+\t}\n+\tnic_dev = rxq->nic_dev;\n+\n+\t/* free rxq_pkt mbuf */\n+\thinic_free_all_rx_skbs(rxq);\n+\n+\t/* free rxq_cqe, rxq_info */\n+\thinic_free_rx_resources(rxq);\n+\n+\t/* free root rq wq */\n+\thinic_destroy_rq(nic_dev->hwdev, rxq->q_id);\n+\n+\tnic_dev->rxqs[rxq->q_id] = NULL;\n+\n+\t/* free rxq */\n+\trte_free(rxq);\n+}\n+\n+/**\n+ * DPDK callback to release the transmit queue.\n+ *\n+ * @param queue\n+ *   Generic transmit queue pointer.\n+ */\n+static void hinic_tx_queue_release(void *queue)\n+{\n+\tstruct hinic_txq *txq = queue;\n+\tstruct hinic_nic_dev *nic_dev;\n+\n+\tif (!txq) {\n+\t\tPMD_DRV_LOG(WARNING, \"Txq is null when release\");\n+\t\treturn;\n+\t}\n+\tnic_dev = txq->nic_dev;\n+\n+\t/* free txq_pkt mbuf */\n+\thinic_free_all_tx_skbs(txq);\n+\n+\t/* free txq_info */\n+\thinic_free_tx_resources(txq);\n+\n+\t/* free root sq wq */\n+\thinic_destroy_sq(nic_dev->hwdev, txq->q_id);\n+\tnic_dev->txqs[txq->q_id] = NULL;\n+\n+\t/* free txq */\n+\trte_free(txq);\n+}\n+\n static void hinic_free_all_rq(struct hinic_nic_dev *nic_dev)\n {\n \tu16 q_id;\n@@ -252,6 +853,61 @@ static void hinic_free_all_sq(struct hinic_nic_dev *nic_dev)\n \t\thinic_destroy_sq(nic_dev->hwdev, q_id);\n }\n \n+/**\n+ * DPDK callback to stop the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ */\n+static void hinic_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tint rc;\n+\tchar *name;\n+\tuint16_t port_id;\n+\tstruct hinic_nic_dev *nic_dev;\n+\tstruct rte_eth_link link;\n+\n+\tnic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tname = dev->data->name;\n+\tport_id = dev->data->port_id;\n+\n+\tif (!hinic_test_and_clear_bit(HINIC_DEV_START, &nic_dev->dev_status)) {\n+\t\tPMD_DRV_LOG(INFO, \"Device %s already stopped\", name);\n+\t\treturn;\n+\t}\n+\n+\t/* just stop phy port and vport */\n+\trc = hinic_set_port_enable(nic_dev->hwdev, false);\n+\tif (rc)\n+\t\tPMD_DRV_LOG(WARNING, \"Disable phy port failed, error: %d, dev_name:%s, port_id:%d\",\n+\t\t\t  rc, name, port_id);\n+\n+\trc = hinic_set_vport_enable(nic_dev->hwdev, false);\n+\tif (rc)\n+\t\tPMD_DRV_LOG(WARNING, \"Disable vport failed, error: %d, dev_name:%s, port_id:%d\",\n+\t\t\t  rc, name, port_id);\n+\n+\t/* Clear recorded link status */\n+\tmemset(&link, 0, sizeof(link));\n+\t(void)rte_eth_linkstatus_set(dev, &link);\n+\n+\t/* flush pending io request */\n+\trc = hinic_rx_tx_flush(nic_dev->hwdev);\n+\tif (rc)\n+\t\tPMD_DRV_LOG(WARNING, \"Flush pending io failed, error: %d, dev_name: %s, port_id: %d\",\n+\t\t\t    rc, name, port_id);\n+\n+\t/* clean rss table and rx_mode */\n+\thinic_remove_rxtx_configure(dev);\n+\n+\t/* clean root context */\n+\thinic_free_qp_ctxts(nic_dev->hwdev);\n+\n+\t/* free mbuf */\n+\thinic_free_all_rx_mbuf(dev);\n+\thinic_free_all_tx_mbuf(dev);\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@@ -289,6 +945,21 @@ static void hinic_disable_interrupt(struct rte_eth_dev *dev)\n \t\t\t    retries);\n }\n \n+static void hinic_gen_random_mac_addr(struct rte_ether_addr *mac_addr)\n+{\n+\tuint64_t random_value;\n+\n+\t/* Set Organizationally Unique Identifier (OUI) prefix */\n+\tmac_addr->addr_bytes[0] = 0x00;\n+\tmac_addr->addr_bytes[1] = 0x09;\n+\tmac_addr->addr_bytes[2] = 0xC0;\n+\t/* Force indication of locally assigned MAC address. */\n+\tmac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;\n+\t/* Generate the last 3 bytes of the MAC address with a random number. */\n+\trandom_value = rte_rand();\n+\tmemcpy(&mac_addr->addr_bytes[3], &random_value, 3);\n+}\n+\n /**\n  * Init mac_vlan table in NIC.\n  *\n@@ -314,6 +985,9 @@ static int hinic_init_mac_addr(struct rte_eth_dev *eth_dev)\n \tmemmove(eth_dev->data->mac_addrs->addr_bytes,\n \t\taddr_bytes, RTE_ETHER_ADDR_LEN);\n \n+\tif (rte_is_zero_ether_addr(eth_dev->data->mac_addrs))\n+\t\thinic_gen_random_mac_addr(eth_dev->data->mac_addrs);\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@@ -817,6 +1491,9 @@ static void hinic_dev_close(struct rte_eth_dev *dev)\n \t\treturn;\n \t}\n \n+\t/* stop device first */\n+\thinic_dev_stop(dev);\n+\n \t/* rx_cqe, rx_info */\n \thinic_free_all_rx_resources(dev);\n \n@@ -842,6 +1519,13 @@ static void hinic_dev_close(struct rte_eth_dev *dev)\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.rx_queue_setup                = hinic_rx_queue_setup,\n+\t.tx_queue_setup                = hinic_tx_queue_setup,\n+\t.dev_start                     = hinic_dev_start,\n+\t.link_update                   = hinic_link_update,\n+\t.rx_queue_release              = hinic_rx_queue_release,\n+\t.tx_queue_release              = hinic_tx_queue_release,\n+\t.dev_stop                      = hinic_dev_stop,\n \t.dev_close                     = hinic_dev_close,\n };\n \ndiff --git a/drivers/net/hinic/hinic_pmd_rx.c b/drivers/net/hinic/hinic_pmd_rx.c\nindex f384901ca..592a889f0 100644\n--- a/drivers/net/hinic/hinic_pmd_rx.c\n+++ b/drivers/net/hinic/hinic_pmd_rx.c\n@@ -13,6 +13,110 @@\n #include \"hinic_pmd_ethdev.h\"\n #include \"hinic_pmd_rx.h\"\n \n+/* rxq wq operations */\n+#define HINIC_GET_RQ_WQE_MASK(rxq)\t\\\n+\t((rxq)->wq->mask)\n+\n+#define HINIC_GET_RQ_LOCAL_CI(rxq)\t\\\n+\t(((rxq)->wq->cons_idx) & HINIC_GET_RQ_WQE_MASK(rxq))\n+\n+#define HINIC_GET_RQ_LOCAL_PI(rxq)\t\\\n+\t(((rxq)->wq->prod_idx) & HINIC_GET_RQ_WQE_MASK(rxq))\n+\n+#define HINIC_UPDATE_RQ_LOCAL_CI(rxq, wqebb_cnt)\t\\\n+\tdo {\t\t\t\t\t\t\\\n+\t\t(rxq)->wq->cons_idx += (wqebb_cnt);\t\\\n+\t\t(rxq)->wq->delta += (wqebb_cnt);\t\\\n+\t} while (0)\n+\n+#define HINIC_UPDATE_RQ_HW_PI(rxq, pi)\t\\\n+\t(*((rxq)->pi_virt_addr) =\t\\\n+\t\tcpu_to_be16((pi) & HINIC_GET_RQ_WQE_MASK(rxq)))\n+\n+#define HINIC_GET_RQ_FREE_WQEBBS(rxq)\t((rxq)->wq->delta - 1)\n+\n+#define HINIC_RX_CSUM_OFFLOAD_EN\t0xFFF\n+\n+/* RQ_CTRL */\n+#define\tRQ_CTRL_BUFDESC_SECT_LEN_SHIFT\t\t0\n+#define\tRQ_CTRL_COMPLETE_FORMAT_SHIFT\t\t15\n+#define RQ_CTRL_COMPLETE_LEN_SHIFT\t\t27\n+#define RQ_CTRL_LEN_SHIFT\t\t\t29\n+\n+#define\tRQ_CTRL_BUFDESC_SECT_LEN_MASK\t\t0xFFU\n+#define\tRQ_CTRL_COMPLETE_FORMAT_MASK\t\t0x1U\n+#define RQ_CTRL_COMPLETE_LEN_MASK\t\t0x3U\n+#define RQ_CTRL_LEN_MASK\t\t\t0x3U\n+\n+#define RQ_CTRL_SET(val, member)\t\t\\\n+\t(((val) & RQ_CTRL_##member##_MASK) << RQ_CTRL_##member##_SHIFT)\n+\n+#define RQ_CTRL_GET(val, member)\t\t\\\n+\t(((val) >> RQ_CTRL_##member##_SHIFT) & RQ_CTRL_##member##_MASK)\n+\n+#define RQ_CTRL_CLEAR(val, member)\t\t\\\n+\t((val) & (~(RQ_CTRL_##member##_MASK << RQ_CTRL_##member##_SHIFT)))\n+\n+\n+void hinic_get_func_rx_buf_size(struct hinic_nic_dev *nic_dev)\n+{\n+\tstruct hinic_rxq *rxq;\n+\tu16 q_id;\n+\tu16 buf_size = 0;\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_rq; q_id++) {\n+\t\trxq = nic_dev->rxqs[q_id];\n+\n+\t\tif (rxq == NULL)\n+\t\t\tcontinue;\n+\n+\t\tif (q_id == 0)\n+\t\t\tbuf_size = rxq->buf_len;\n+\n+\t\tbuf_size = buf_size > rxq->buf_len ? rxq->buf_len : buf_size;\n+\t}\n+\n+\tnic_dev->hwdev->nic_io->rq_buf_size = buf_size;\n+}\n+\n+int hinic_create_rq(struct hinic_hwdev *hwdev, u16 q_id, u16 rq_depth)\n+{\n+\tint err;\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+\t/* in case of hardware still generate interrupt, do not use msix 0 */\n+\trq->msix_entry_idx = 1;\n+\trq->q_id = q_id;\n+\trq->rq_depth = rq_depth;\n+\tnic_io->rq_depth = rq_depth;\n+\n+\terr = hinic_wq_allocate(hwdev, &nic_io->rq_wq[q_id],\n+\t\t\t\tHINIC_RQ_WQEBB_SHIFT, nic_io->rq_depth);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate WQ for RQ\");\n+\t\treturn err;\n+\t}\n+\trq->wq = &nic_io->rq_wq[q_id];\n+\n+\trq->pi_virt_addr =\n+\t\t(volatile u16 *)dma_zalloc_coherent(hwdev, HINIC_PAGE_SIZE,\n+\t\t\t\t\t\t    &rq->pi_dma_addr,\n+\t\t\t\t\t\t    GFP_KERNEL);\n+\tif (!rq->pi_virt_addr) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate rq pi virt addr\");\n+\t\terr = -ENOMEM;\n+\t\tgoto rq_pi_alloc_err;\n+\t}\n+\n+\treturn HINIC_OK;\n+\n+rq_pi_alloc_err:\n+\thinic_wq_free(hwdev, &nic_io->rq_wq[q_id]);\n+\n+\treturn err;\n+}\n \n void hinic_destroy_rq(struct hinic_hwdev *hwdev, u16 q_id)\n {\n@@ -30,6 +134,48 @@ void hinic_destroy_rq(struct hinic_hwdev *hwdev, u16 q_id)\n \tqp->rq.wq = NULL;\n }\n \n+static void\n+hinic_prepare_rq_wqe(void *wqe, __rte_unused u16 pi, dma_addr_t buf_addr,\n+\t\t\tdma_addr_t cqe_dma)\n+{\n+\tstruct hinic_rq_wqe *rq_wqe = wqe;\n+\tstruct hinic_rq_ctrl *ctrl = &rq_wqe->ctrl;\n+\tstruct hinic_rq_cqe_sect *cqe_sect = &rq_wqe->cqe_sect;\n+\tstruct hinic_rq_bufdesc *buf_desc = &rq_wqe->buf_desc;\n+\tu32 rq_ceq_len = sizeof(struct hinic_rq_cqe);\n+\n+\tctrl->ctrl_fmt =\n+\t\tRQ_CTRL_SET(SIZE_8BYTES(sizeof(*ctrl)),  LEN) |\n+\t\tRQ_CTRL_SET(SIZE_8BYTES(sizeof(*cqe_sect)), COMPLETE_LEN) |\n+\t\tRQ_CTRL_SET(SIZE_8BYTES(sizeof(*buf_desc)), BUFDESC_SECT_LEN) |\n+\t\tRQ_CTRL_SET(RQ_COMPLETE_SGE, COMPLETE_FORMAT);\n+\n+\thinic_set_sge(&cqe_sect->sge, cqe_dma, rq_ceq_len);\n+\n+\tbuf_desc->addr_high = upper_32_bits(buf_addr);\n+\tbuf_desc->addr_low = lower_32_bits(buf_addr);\n+}\n+\n+static int hinic_rx_alloc_cqe(struct hinic_rxq *rxq)\n+{\n+\tsize_t cqe_mem_size;\n+\n+\t/* allocate continuous cqe memory for saving number of memory zone */\n+\tcqe_mem_size = sizeof(struct hinic_rq_cqe) * rxq->q_depth;\n+\trxq->cqe_start_vaddr =\n+\t\tdma_zalloc_coherent(rxq->nic_dev->hwdev,\n+\t\t\t\t    cqe_mem_size, &rxq->cqe_start_paddr,\n+\t\t\t\t    GFP_KERNEL);\n+\tif (!rxq->cqe_start_vaddr) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cqe dma memory failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\trxq->rx_cqe = (struct hinic_rq_cqe *)rxq->cqe_start_vaddr;\n+\n+\treturn HINIC_OK;\n+}\n+\n static void hinic_rx_free_cqe(struct hinic_rxq *rxq)\n {\n \tsize_t cqe_mem_size;\n@@ -40,6 +186,70 @@ static void hinic_rx_free_cqe(struct hinic_rxq *rxq)\n \trxq->cqe_start_vaddr = NULL;\n }\n \n+static int hinic_rx_fill_wqe(struct hinic_rxq *rxq)\n+{\n+\tstruct hinic_nic_dev *nic_dev = rxq->nic_dev;\n+\tstruct hinic_rq_wqe *rq_wqe;\n+\tdma_addr_t buf_dma_addr, cqe_dma_addr;\n+\tu16 pi = 0;\n+\tint i;\n+\n+\tbuf_dma_addr = 0;\n+\tcqe_dma_addr = rxq->cqe_start_paddr;\n+\tfor (i = 0; i < rxq->q_depth; i++) {\n+\t\trq_wqe = hinic_get_rq_wqe(nic_dev->hwdev, rxq->q_id, &pi);\n+\t\tif (!rq_wqe) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Get rq wqe failed\");\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\thinic_prepare_rq_wqe(rq_wqe, pi, buf_dma_addr, cqe_dma_addr);\n+\t\tcqe_dma_addr +=  sizeof(struct hinic_rq_cqe);\n+\n+\t\thinic_cpu_to_be32(rq_wqe, sizeof(struct hinic_rq_wqe));\n+\t}\n+\n+\thinic_return_rq_wqe(nic_dev->hwdev, rxq->q_id, i);\n+\n+\treturn i;\n+}\n+\n+/* alloc cqe and prepare rqe */\n+int hinic_setup_rx_resources(struct hinic_rxq *rxq)\n+{\n+\tu64 rx_info_sz;\n+\tint err, pkts;\n+\n+\trx_info_sz = rxq->q_depth * sizeof(*rxq->rx_info);\n+\trxq->rx_info = kzalloc_aligned(rx_info_sz, GFP_KERNEL);\n+\tif (!rxq->rx_info)\n+\t\treturn -ENOMEM;\n+\n+\terr = hinic_rx_alloc_cqe(rxq);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate rx cqe failed\");\n+\t\tgoto rx_cqe_err;\n+\t}\n+\n+\tpkts = hinic_rx_fill_wqe(rxq);\n+\tif (pkts != rxq->q_depth) {\n+\t\tPMD_DRV_LOG(ERR, \"Fill rx wqe failed\");\n+\t\terr = -ENOMEM;\n+\t\tgoto rx_fill_err;\n+\t}\n+\n+\treturn 0;\n+\n+rx_fill_err:\n+\thinic_rx_free_cqe(rxq);\n+\n+rx_cqe_err:\n+\tkfree(rxq->rx_info);\n+\trxq->rx_info = NULL;\n+\n+\treturn err;\n+}\n+\n void hinic_free_rx_resources(struct hinic_rxq *rxq)\n {\n \tif (rxq->rx_info == NULL)\n@@ -69,6 +279,112 @@ void hinic_free_all_rx_resources(struct rte_eth_dev *eth_dev)\n \t}\n }\n \n+void hinic_free_all_rx_mbuf(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+\tu16 q_id;\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_rq; q_id++)\n+\t\thinic_free_all_rx_skbs(nic_dev->rxqs[q_id]);\n+}\n+\n+static void hinic_rss_deinit(struct hinic_nic_dev *nic_dev)\n+{\n+\tu8 prio_tc[HINIC_DCB_UP_MAX] = {0};\n+\t(void)hinic_rss_cfg(nic_dev->hwdev, 0,\n+\t\t\t    nic_dev->rss_tmpl_idx, 0, prio_tc);\n+}\n+\n+static int hinic_rss_key_init(struct hinic_nic_dev *nic_dev,\n+\t\t\t      struct rte_eth_rss_conf *rss_conf)\n+{\n+\tu8 default_rss_key[HINIC_RSS_KEY_SIZE] = {\n+\t\t\t 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,\n+\t\t\t 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,\n+\t\t\t 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,\n+\t\t\t 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,\n+\t\t\t 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa};\n+\tu8 hashkey[HINIC_RSS_KEY_SIZE] = {0};\n+\tu8 tmpl_idx = nic_dev->rss_tmpl_idx;\n+\n+\tif (rss_conf->rss_key == NULL)\n+\t\tmemcpy(hashkey, default_rss_key, HINIC_RSS_KEY_SIZE);\n+\telse\n+\t\tmemcpy(hashkey, rss_conf->rss_key, rss_conf->rss_key_len);\n+\n+\treturn hinic_rss_set_template_tbl(nic_dev->hwdev, tmpl_idx, hashkey);\n+}\n+\n+static void hinic_fill_rss_type(struct nic_rss_type *rss_type,\n+\t\t\t\tstruct rte_eth_rss_conf *rss_conf)\n+{\n+\tu64 rss_hf = rss_conf->rss_hf;\n+\n+\trss_type->ipv4 = (rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4)) ? 1 : 0;\n+\trss_type->tcp_ipv4 = (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0;\n+\trss_type->ipv6 = (rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6)) ? 1 : 0;\n+\trss_type->ipv6_ext = (rss_hf & ETH_RSS_IPV6_EX) ? 1 : 0;\n+\trss_type->tcp_ipv6 = (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0;\n+\trss_type->tcp_ipv6_ext = (rss_hf & ETH_RSS_IPV6_TCP_EX) ? 1 : 0;\n+\trss_type->udp_ipv4 = (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0;\n+\trss_type->udp_ipv6 = (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0;\n+}\n+\n+static void hinic_fillout_indir_tbl(struct hinic_nic_dev *nic_dev, u32 *indir)\n+{\n+\tu8 rss_queue_count = nic_dev->num_rss;\n+\tint i = 0, j;\n+\n+\tif (rss_queue_count == 0) {\n+\t\t/* delete q_id from indir tbl */\n+\t\tfor (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)\n+\t\t\tindir[i] = 0xFF;\t/* Invalid value in indir tbl */\n+\t} else {\n+\t\twhile (i < HINIC_RSS_INDIR_SIZE)\n+\t\t\tfor (j = 0; (j < rss_queue_count) &&\n+\t\t\t     (i < HINIC_RSS_INDIR_SIZE); j++)\n+\t\t\t\tindir[i++] = nic_dev->rx_queue_list[j];\n+\t}\n+}\n+\n+static int hinic_rss_init(struct hinic_nic_dev *nic_dev,\n+\t\t\t  __attribute__((unused)) u8 *rq2iq_map,\n+\t\t\t  struct rte_eth_rss_conf *rss_conf)\n+{\n+\tu32 indir_tbl[HINIC_RSS_INDIR_SIZE] = {0};\n+\tstruct nic_rss_type rss_type = {0};\n+\tu8 prio_tc[HINIC_DCB_UP_MAX] = {0};\n+\tu8 tmpl_idx = 0xFF, num_tc = 0;\n+\tint err;\n+\n+\ttmpl_idx = nic_dev->rss_tmpl_idx;\n+\n+\terr = hinic_rss_key_init(nic_dev, rss_conf);\n+\tif (err)\n+\t\treturn err;\n+\n+\tif (!nic_dev->rss_indir_flag) {\n+\t\thinic_fillout_indir_tbl(nic_dev, indir_tbl);\n+\t\terr = hinic_rss_set_indir_tbl(nic_dev->hwdev, tmpl_idx,\n+\t\t\t\t\t      indir_tbl);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\n+\thinic_fill_rss_type(&rss_type, rss_conf);\n+\terr = hinic_set_rss_type(nic_dev->hwdev, tmpl_idx, rss_type);\n+\tif (err)\n+\t\treturn err;\n+\n+\terr = hinic_rss_set_hash_engine(nic_dev->hwdev, tmpl_idx,\n+\t\t\t\t\tHINIC_RSS_HASH_ENGINE_TYPE_TOEP);\n+\tif (err)\n+\t\treturn err;\n+\n+\treturn hinic_rss_cfg(nic_dev->hwdev, 1, tmpl_idx, num_tc, prio_tc);\n+}\n+\n static void\n hinic_add_rq_to_rx_queue_list(struct hinic_nic_dev *nic_dev, u16 queue_id)\n {\n@@ -152,6 +468,56 @@ int hinic_config_mq_mode(struct rte_eth_dev *dev, bool on)\n \treturn ret;\n }\n \n+int hinic_rx_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\tstruct rte_eth_rss_conf rss_conf =\n+\t\tdev->data->dev_conf.rx_adv_conf.rss_conf;\n+\tu32 csum_en = 0;\n+\tint err;\n+\n+\tif (nic_dev->flags & ETH_MQ_RX_RSS_FLAG) {\n+\t\tif (rss_conf.rss_hf == 0) {\n+\t\t\trss_conf.rss_hf = HINIC_RSS_OFFLOAD_ALL;\n+\t\t} else if ((rss_conf.rss_hf & HINIC_RSS_OFFLOAD_ALL) == 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Do not support rss offload all\");\n+\t\t\tgoto rss_config_err;\n+\t\t}\n+\n+\t\terr = hinic_rss_init(nic_dev, NULL, &rss_conf);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Init rss failed\");\n+\t\t\tgoto rss_config_err;\n+\t\t}\n+\t}\n+\n+\t/* Enable both L3/L4 rx checksum offload */\n+\tif (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_CHECKSUM)\n+\t\tcsum_en = HINIC_RX_CSUM_OFFLOAD_EN;\n+\n+\terr = hinic_set_rx_csum_offload(nic_dev->hwdev, csum_en);\n+\tif (err)\n+\t\tgoto rx_csum_ofl_err;\n+\n+\treturn 0;\n+\n+rx_csum_ofl_err:\n+rss_config_err:\n+\thinic_destroy_num_qps(nic_dev);\n+\n+\treturn HINIC_ERROR;\n+}\n+\n+void hinic_rx_remove_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);\n+\n+\tif (nic_dev->flags & ETH_MQ_RX_RSS_FLAG) {\n+\t\thinic_rss_deinit(nic_dev);\n+\t\thinic_destroy_num_qps(nic_dev);\n+\t}\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@@ -176,3 +542,57 @@ void hinic_free_all_rx_skbs(struct hinic_rxq *rxq)\n \t\thinic_update_rq_local_ci(nic_dev->hwdev, rxq->q_id, 1);\n \t}\n }\n+\n+static struct rte_mbuf *hinic_rx_alloc_mbuf(struct hinic_rxq *rxq,\n+\t\t\t\t\tdma_addr_t *dma_addr)\n+{\n+\tstruct rte_mbuf *mbuf;\n+\n+\tmbuf = rte_mbuf_raw_alloc(rxq->mb_pool);\n+\tif (unlikely(!mbuf))\n+\t\treturn NULL;\n+\n+\t*dma_addr = rte_mbuf_data_iova_default(mbuf);\n+\n+\treturn mbuf;\n+}\n+\n+void hinic_rx_alloc_pkts(struct hinic_rxq *rxq)\n+{\n+\tstruct hinic_nic_dev *nic_dev = rxq->nic_dev;\n+\tstruct hinic_rq_wqe *rq_wqe;\n+\tstruct hinic_rx_info *rx_info;\n+\tstruct rte_mbuf *mb;\n+\tdma_addr_t dma_addr;\n+\tu16 pi = 0;\n+\tint i, free_wqebbs;\n+\n+\tfree_wqebbs = HINIC_GET_RQ_FREE_WQEBBS(rxq);\n+\tfor (i = 0; i < free_wqebbs; i++) {\n+\t\tmb = hinic_rx_alloc_mbuf(rxq, &dma_addr);\n+\t\tif (unlikely(!mb)) {\n+\t\t\trxq->rxq_stats.rx_nombuf++;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\trq_wqe = hinic_get_rq_wqe(nic_dev->hwdev, rxq->q_id, &pi);\n+\t\tif (unlikely(!rq_wqe)) {\n+\t\t\trte_pktmbuf_free(mb);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* fill buffer address only */\n+\t\trq_wqe->buf_desc.addr_high =\n+\t\t\t\tcpu_to_be32(upper_32_bits(dma_addr));\n+\t\trq_wqe->buf_desc.addr_low =\n+\t\t\t\tcpu_to_be32(lower_32_bits(dma_addr));\n+\n+\t\trx_info = &rxq->rx_info[pi];\n+\t\trx_info->mbuf = mb;\n+\t}\n+\n+\tif (likely(i > 0)) {\n+\t\trte_wmb();\n+\t\tHINIC_UPDATE_RQ_HW_PI(rxq, pi + 1);\n+\t}\n+}\ndiff --git a/drivers/net/hinic/hinic_pmd_tx.c b/drivers/net/hinic/hinic_pmd_tx.c\nindex 79c5f9822..854b94dc5 100644\n--- a/drivers/net/hinic/hinic_pmd_tx.c\n+++ b/drivers/net/hinic/hinic_pmd_tx.c\n@@ -66,6 +66,29 @@ void hinic_free_all_tx_resources(struct rte_eth_dev *eth_dev)\n \t}\n }\n \n+void hinic_free_all_tx_mbuf(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\t/* stop tx queue free tx mbuf */\n+\t\thinic_free_all_tx_skbs(nic_dev->txqs[q_id]);\n+}\n+\n+int hinic_setup_tx_resources(struct hinic_txq *txq)\n+{\n+\tu64 tx_info_sz;\n+\n+\ttx_info_sz = txq->q_depth * sizeof(*txq->tx_info);\n+\ttxq->tx_info = kzalloc_aligned(tx_info_sz, GFP_KERNEL);\n+\tif (!txq->tx_info)\n+\t\treturn -ENOMEM;\n+\n+\treturn HINIC_OK;\n+}\n+\n void hinic_free_tx_resources(struct hinic_txq *txq)\n {\n \tif (txq->tx_info == NULL)\n@@ -75,6 +98,51 @@ void hinic_free_tx_resources(struct hinic_txq *txq)\n \ttxq->tx_info = NULL;\n }\n \n+int hinic_create_sq(struct hinic_hwdev *hwdev, u16 q_id, u16 sq_depth)\n+{\n+\tint err;\n+\tstruct hinic_nic_io *nic_io = hwdev->nic_io;\n+\tstruct hinic_qp *qp = &nic_io->qps[q_id];\n+\tstruct hinic_sq *sq = &qp->sq;\n+\tvoid __iomem *db_addr;\n+\tvolatile u32 *ci_addr;\n+\n+\tsq->sq_depth = sq_depth;\n+\tnic_io->sq_depth = sq_depth;\n+\n+\t/* alloc wq */\n+\terr = hinic_wq_allocate(nic_io->hwdev, &nic_io->sq_wq[q_id],\n+\t\t\t\tHINIC_SQ_WQEBB_SHIFT, nic_io->sq_depth);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate WQ for SQ\");\n+\t\treturn err;\n+\t}\n+\n+\t/* alloc sq doorbell space */\n+\terr = hinic_alloc_db_addr(nic_io->hwdev, &db_addr);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to init db addr\");\n+\t\tgoto alloc_db_err;\n+\t}\n+\n+\t/* clear hardware ci */\n+\tci_addr = (volatile u32 *)HINIC_CI_VADDR(nic_io->ci_vaddr_base, q_id);\n+\t*ci_addr = 0;\n+\n+\tsq->q_id = q_id;\n+\tsq->wq = &nic_io->sq_wq[q_id];\n+\tsq->owner = 1;\n+\tsq->cons_idx_addr = (volatile u16 *)ci_addr;\n+\tsq->db_addr = db_addr;\n+\n+\treturn HINIC_OK;\n+\n+alloc_db_err:\n+\thinic_wq_free(nic_io->hwdev, &nic_io->sq_wq[q_id]);\n+\n+\treturn err;\n+}\n+\n void hinic_destroy_sq(struct hinic_hwdev *hwdev, u16 q_id)\n {\n \tstruct hinic_nic_io *nic_io;\n",
    "prefixes": [
        "v6",
        "13/15"
    ]
}