get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 55015,
    "url": "http://patches.dpdk.org/api/patches/55015/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/a36ff199bd7345071acd78fc3997c6d67665fba1.1560958308.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": "<a36ff199bd7345071acd78fc3997c6d67665fba1.1560958308.git.xuanziyang2@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/a36ff199bd7345071acd78fc3997c6d67665fba1.1560958308.git.xuanziyang2@huawei.com",
    "date": "2019-06-19T15:55:13",
    "name": "[v5,04/15] net/hinic/base: add support for cmdq mechanism",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "9a7cdb0924f9b132c24c3c97f5e87a183584f388",
    "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/a36ff199bd7345071acd78fc3997c6d67665fba1.1560958308.git.xuanziyang2@huawei.com/mbox/",
    "series": [
        {
            "id": 5084,
            "url": "http://patches.dpdk.org/api/series/5084/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5084",
            "date": "2019-06-19T15:45:20",
            "name": "A new net PMD - hinic",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/5084/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/55015/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/55015/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 0503B1D0D3;\n\tWed, 19 Jun 2019 17:43:41 +0200 (CEST)",
            "from huawei.com (szxga05-in.huawei.com [45.249.212.191])\n\tby dpdk.org (Postfix) with ESMTP id EE9E41D0EE\n\tfor <dev@dpdk.org>; Wed, 19 Jun 2019 17:43:22 +0200 (CEST)",
            "from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.58])\n\tby Forcepoint Email with ESMTP id 28E76C0149B6148F98D2\n\tfor <dev@dpdk.org>; Wed, 19 Jun 2019 23:43:19 +0800 (CST)",
            "from tester_149.localdomain (10.175.119.39) by\n\tDGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP\n\tServer id 14.3.439.0; Wed, 19 Jun 2019 23:43:12 +0800"
        ],
        "From": "Ziyang Xuan <xuanziyang2@huawei.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@intel.com>, <cloud.wangxiaoyun@huawei.com>,\n\t<zhouguoyang@huawei.com>, <shahar.belkar@huawei.com>,\n\t<luoxianjun@huawei.com>, Ziyang Xuan <xuanziyang2@huawei.com>",
        "Date": "Wed, 19 Jun 2019 23:55:13 +0800",
        "Message-ID": "<a36ff199bd7345071acd78fc3997c6d67665fba1.1560958308.git.xuanziyang2@huawei.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<cover.1560958308.git.xuanziyang2@huawei.com>",
        "References": "<cover.1560958308.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 v5 04/15] net/hinic/base: add support for cmdq\n\tmechanism",
        "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": "Micocode is named ucode in Hi1822. Its main responsibility is data\ntransmission and reception. But it can also handle some administration\nworks. It uses cmdq mechanism. This patch introduces data structures,\ninitialization, interfaces, and commands sending functions of cmdq.\n\nSigned-off-by: Ziyang Xuan <xuanziyang2@huawei.com>\n---\n drivers/net/hinic/base/hinic_pmd_cmdq.c | 849 ++++++++++++++++++++++++\n drivers/net/hinic/base/hinic_pmd_cmdq.h | 242 +++++++\n 2 files changed, 1091 insertions(+)\n create mode 100644 drivers/net/hinic/base/hinic_pmd_cmdq.c\n create mode 100644 drivers/net/hinic/base/hinic_pmd_cmdq.h",
    "diff": "diff --git a/drivers/net/hinic/base/hinic_pmd_cmdq.c b/drivers/net/hinic/base/hinic_pmd_cmdq.c\nnew file mode 100644\nindex 000000000..eb8de24d6\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_cmdq.c\n@@ -0,0 +1,849 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include \"hinic_compat.h\"\n+#include \"hinic_pmd_hwdev.h\"\n+#include \"hinic_pmd_hwif.h\"\n+#include \"hinic_pmd_wq.h\"\n+#include \"hinic_pmd_mgmt.h\"\n+#include \"hinic_pmd_cmdq.h\"\n+\n+#define CMDQ_CMD_TIMEOUT\t\t\t\t5000 /* millisecond */\n+\n+#define UPPER_8_BITS(data)\t\t\t\t(((data) >> 8) & 0xFF)\n+#define LOWER_8_BITS(data)\t\t\t\t((data) & 0xFF)\n+\n+#define CMDQ_DB_INFO_HI_PROD_IDX_SHIFT\t\t\t0\n+#define CMDQ_DB_INFO_QUEUE_TYPE_SHIFT\t\t\t23\n+#define CMDQ_DB_INFO_CMDQ_TYPE_SHIFT\t\t\t24\n+#define CMDQ_DB_INFO_SRC_TYPE_SHIFT\t\t\t27\n+\n+#define CMDQ_DB_INFO_HI_PROD_IDX_MASK\t\t\t0xFFU\n+#define CMDQ_DB_INFO_QUEUE_TYPE_MASK\t\t\t0x1U\n+#define CMDQ_DB_INFO_CMDQ_TYPE_MASK\t\t\t0x7U\n+#define CMDQ_DB_INFO_SRC_TYPE_MASK\t\t\t0x1FU\n+\n+#define CMDQ_DB_INFO_SET(val, member)\t\t\\\n+\t(((val) & CMDQ_DB_INFO_##member##_MASK) <<\t\\\n+\t\tCMDQ_DB_INFO_##member##_SHIFT)\n+\n+#define CMDQ_CTRL_PI_SHIFT\t\t\t\t0\n+#define CMDQ_CTRL_CMD_SHIFT\t\t\t\t16\n+#define CMDQ_CTRL_MOD_SHIFT\t\t\t\t24\n+#define CMDQ_CTRL_ACK_TYPE_SHIFT\t\t\t29\n+#define CMDQ_CTRL_HW_BUSY_BIT_SHIFT\t\t\t31\n+\n+#define CMDQ_CTRL_PI_MASK\t\t\t\t0xFFFFU\n+#define CMDQ_CTRL_CMD_MASK\t\t\t\t0xFFU\n+#define CMDQ_CTRL_MOD_MASK\t\t\t\t0x1FU\n+#define CMDQ_CTRL_ACK_TYPE_MASK\t\t\t\t0x3U\n+#define CMDQ_CTRL_HW_BUSY_BIT_MASK\t\t\t0x1U\n+\n+#define CMDQ_CTRL_SET(val, member)\t\t\\\n+\t(((val) & CMDQ_CTRL_##member##_MASK) << CMDQ_CTRL_##member##_SHIFT)\n+\n+#define CMDQ_CTRL_GET(val, member)\t\t\\\n+\t(((val) >> CMDQ_CTRL_##member##_SHIFT) & CMDQ_CTRL_##member##_MASK)\n+\n+#define CMDQ_WQE_HEADER_BUFDESC_LEN_SHIFT\t\t0\n+#define CMDQ_WQE_HEADER_COMPLETE_FMT_SHIFT\t\t15\n+#define CMDQ_WQE_HEADER_DATA_FMT_SHIFT\t\t\t22\n+#define CMDQ_WQE_HEADER_COMPLETE_REQ_SHIFT\t\t23\n+#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_SHIFT\t\t27\n+#define CMDQ_WQE_HEADER_CTRL_LEN_SHIFT\t\t\t29\n+#define CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT\t\t31\n+\n+#define CMDQ_WQE_HEADER_BUFDESC_LEN_MASK\t\t0xFFU\n+#define CMDQ_WQE_HEADER_COMPLETE_FMT_MASK\t\t0x1U\n+#define CMDQ_WQE_HEADER_DATA_FMT_MASK\t\t\t0x1U\n+#define CMDQ_WQE_HEADER_COMPLETE_REQ_MASK\t\t0x1U\n+#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_MASK\t\t0x3U\n+#define CMDQ_WQE_HEADER_CTRL_LEN_MASK\t\t\t0x3U\n+#define CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK\t\t0x1U\n+\n+#define CMDQ_WQE_HEADER_SET(val, member)\t\\\n+\t(((val) & CMDQ_WQE_HEADER_##member##_MASK) <<\t\\\n+\t\tCMDQ_WQE_HEADER_##member##_SHIFT)\n+\n+#define CMDQ_WQE_HEADER_GET(val, member)\t\\\n+\t(((val) >> CMDQ_WQE_HEADER_##member##_SHIFT) &\t\\\n+\t\tCMDQ_WQE_HEADER_##member##_MASK)\n+\n+#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT\t\t0\n+#define CMDQ_CTXT_EQ_ID_SHIFT\t\t\t\t56\n+#define CMDQ_CTXT_CEQ_ARM_SHIFT\t\t\t\t61\n+#define CMDQ_CTXT_CEQ_EN_SHIFT\t\t\t\t62\n+#define CMDQ_CTXT_HW_BUSY_BIT_SHIFT\t\t\t63\n+\n+#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK\t\t0xFFFFFFFFFFFFF\n+#define CMDQ_CTXT_EQ_ID_MASK\t\t\t\t0x1F\n+#define CMDQ_CTXT_CEQ_ARM_MASK\t\t\t\t0x1\n+#define CMDQ_CTXT_CEQ_EN_MASK\t\t\t\t0x1\n+#define CMDQ_CTXT_HW_BUSY_BIT_MASK\t\t\t0x1\n+\n+#define CMDQ_CTXT_PAGE_INFO_SET(val, member)\t\t\\\n+\t(((u64)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)\n+\n+#define CMDQ_CTXT_PAGE_INFO_CLEAR(val, member)\t\t\\\n+\t((val) & (~((u64)CMDQ_CTXT_##member##_MASK <<\t\\\n+\t\tCMDQ_CTXT_##member##_SHIFT)))\n+\n+#define CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT\t\t\t0\n+#define CMDQ_CTXT_CI_SHIFT\t\t\t\t52\n+\n+#define CMDQ_CTXT_WQ_BLOCK_PFN_MASK\t\t\t0xFFFFFFFFFFFFF\n+#define CMDQ_CTXT_CI_MASK\t\t\t\t0xFFF\n+\n+#define CMDQ_CTXT_BLOCK_INFO_SET(val, member)\t\t\\\n+\t(((u64)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)\n+\n+#define SAVED_DATA_ARM_SHIFT\t\t\t31\n+\n+#define SAVED_DATA_ARM_MASK\t\t\t0x1U\n+\n+#define SAVED_DATA_SET(val, member)\t\t\\\n+\t(((val) & SAVED_DATA_##member##_MASK) << SAVED_DATA_##member##_SHIFT)\n+\n+#define SAVED_DATA_CLEAR(val, member)\t\t\\\n+\t((val) & (~(SAVED_DATA_##member##_MASK << SAVED_DATA_##member##_SHIFT)))\n+\n+#define WQE_ERRCODE_VAL_SHIFT\t\t\t20\n+\n+#define WQE_ERRCODE_VAL_MASK\t\t\t0xF\n+\n+#define WQE_ERRCODE_GET(val, member)\t\t\\\n+\t(((val) >> WQE_ERRCODE_##member##_SHIFT) & WQE_ERRCODE_##member##_MASK)\n+\n+#define WQE_COMPLETED(ctrl_info)\tCMDQ_CTRL_GET(ctrl_info, HW_BUSY_BIT)\n+\n+#define WQE_HEADER(wqe)\t\t((struct hinic_cmdq_header *)(wqe))\n+\n+#define CMDQ_DB_PI_OFF(pi)\t\t(((u16)LOWER_8_BITS(pi)) << 3)\n+\n+#define CMDQ_DB_ADDR(db_base, pi)\t\\\n+\t(((u8 *)(db_base) + HINIC_DB_OFF) + CMDQ_DB_PI_OFF(pi))\n+\n+#define CMDQ_PFN(addr, page_size)\t((addr) >> (ilog2(page_size)))\n+\n+#define FIRST_DATA_TO_WRITE_LAST\tsizeof(u64)\n+\n+#define WQE_LCMD_SIZE\t\t64\n+#define WQE_SCMD_SIZE\t\t64\n+\n+#define COMPLETE_LEN\t\t3\n+\n+#define CMDQ_WQEBB_SIZE\t\t64\n+#define CMDQ_WQEBB_SHIFT\t6\n+\n+#define CMDQ_WQE_SIZE\t\t64\n+\n+#define HINIC_CMDQ_WQ_BUF_SIZE\t4096\n+\n+#define WQE_NUM_WQEBBS(wqe_size, wq)\t\\\n+\t((u16)(ALIGN((u32)(wqe_size), (wq)->wqebb_size) / (wq)->wqebb_size))\n+\n+#define cmdq_to_cmdqs(cmdq)\tcontainer_of((cmdq) - (cmdq)->cmdq_type, \\\n+\t\t\t\tstruct hinic_cmdqs, cmdq[0])\n+\n+#define WAIT_CMDQ_ENABLE_TIMEOUT\t300\n+\n+\n+static void cmdq_init_queue_ctxt(struct hinic_cmdq *cmdq,\n+\t\t\t\t struct hinic_cmdq_ctxt *cmdq_ctxt);\n+static void hinic_cmdqs_free(struct hinic_hwdev *hwdev);\n+\n+bool hinic_cmdq_idle(struct hinic_cmdq *cmdq)\n+{\n+\tstruct hinic_wq *wq = cmdq->wq;\n+\n+\treturn ((wq->delta) == wq->q_depth ? true : false);\n+}\n+\n+struct hinic_cmd_buf *hinic_alloc_cmd_buf(void *hwdev)\n+{\n+\tstruct hinic_cmdqs *cmdqs = ((struct hinic_hwdev *)hwdev)->cmdqs;\n+\tstruct hinic_cmd_buf *cmd_buf;\n+\n+\tcmd_buf = kzalloc(sizeof(*cmd_buf), GFP_KERNEL);\n+\tif (!cmd_buf) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cmd buffer failed\");\n+\t\treturn NULL;\n+\t}\n+\n+\tcmd_buf->buf = pci_pool_alloc(cmdqs->cmd_buf_pool, GFP_KERNEL,\n+\t\t\t\t      &cmd_buf->dma_addr);\n+\tif (!cmd_buf->buf) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cmd from the pool failed\");\n+\t\tgoto alloc_pci_buf_err;\n+\t}\n+\n+\treturn cmd_buf;\n+\n+alloc_pci_buf_err:\n+\tkfree(cmd_buf);\n+\treturn NULL;\n+}\n+\n+void hinic_free_cmd_buf(void *hwdev, struct hinic_cmd_buf *cmd_buf)\n+{\n+\tstruct hinic_cmdqs *cmdqs = ((struct hinic_hwdev *)hwdev)->cmdqs;\n+\n+\tpci_pool_free(cmdqs->cmd_buf_pool, cmd_buf->buf, cmd_buf->dma_addr);\n+\tkfree(cmd_buf);\n+}\n+\n+static u32 cmdq_wqe_size(enum cmdq_wqe_type wqe_type)\n+{\n+\tu32 wqe_size = 0;\n+\n+\tswitch (wqe_type) {\n+\tcase WQE_LCMD_TYPE:\n+\t\twqe_size = WQE_LCMD_SIZE;\n+\t\tbreak;\n+\tcase WQE_SCMD_TYPE:\n+\t\twqe_size = WQE_SCMD_SIZE;\n+\t\tbreak;\n+\t}\n+\n+\treturn wqe_size;\n+}\n+\n+static int cmdq_get_wqe_size(enum bufdesc_len len)\n+{\n+\tint wqe_size = 0;\n+\n+\tswitch (len) {\n+\tcase BUFDESC_LCMD_LEN:\n+\t\twqe_size = WQE_LCMD_SIZE;\n+\t\tbreak;\n+\tcase BUFDESC_SCMD_LEN:\n+\t\twqe_size = WQE_SCMD_SIZE;\n+\t\tbreak;\n+\t}\n+\n+\treturn wqe_size;\n+}\n+\n+static void cmdq_set_completion(struct hinic_cmdq_completion *complete,\n+\t\t\t\t\tstruct hinic_cmd_buf *buf_out)\n+{\n+\tstruct hinic_sge_resp *sge_resp = &complete->sge_resp;\n+\n+\thinic_set_sge(&sge_resp->sge, buf_out->dma_addr,\n+\t\t      HINIC_CMDQ_BUF_SIZE);\n+}\n+\n+static void cmdq_set_lcmd_bufdesc(struct hinic_cmdq_wqe_lcmd *wqe,\n+\t\t\t\t\tstruct hinic_cmd_buf *buf_in)\n+{\n+\thinic_set_sge(&wqe->buf_desc.sge, buf_in->dma_addr, buf_in->size);\n+}\n+\n+static void cmdq_fill_db(struct hinic_cmdq_db *db,\n+\t\t\tenum hinic_cmdq_type cmdq_type, u16 prod_idx)\n+{\n+\tdb->db_info = CMDQ_DB_INFO_SET(UPPER_8_BITS(prod_idx), HI_PROD_IDX) |\n+\t\t\tCMDQ_DB_INFO_SET(HINIC_DB_CMDQ_TYPE, QUEUE_TYPE) |\n+\t\t\tCMDQ_DB_INFO_SET(cmdq_type, CMDQ_TYPE)\t\t|\n+\t\t\tCMDQ_DB_INFO_SET(HINIC_DB_SRC_CMDQ_TYPE, SRC_TYPE);\n+}\n+\n+static void cmdq_set_db(struct hinic_cmdq *cmdq,\n+\t\t\tenum hinic_cmdq_type cmdq_type, u16 prod_idx)\n+{\n+\tstruct hinic_cmdq_db db;\n+\n+\tcmdq_fill_db(&db, cmdq_type, prod_idx);\n+\n+\t/* The data that is written to HW should be in Big Endian Format */\n+\tdb.db_info = cpu_to_be32(db.db_info);\n+\n+\trte_wmb();\t/* write all before the doorbell */\n+\n+\twritel(db.db_info, CMDQ_DB_ADDR(cmdq->db_base, prod_idx));\n+}\n+\n+static void cmdq_wqe_fill(void *dst, void *src)\n+{\n+\tmemcpy((u8 *)dst + FIRST_DATA_TO_WRITE_LAST,\n+\t       (u8 *)src + FIRST_DATA_TO_WRITE_LAST,\n+\t       CMDQ_WQE_SIZE - FIRST_DATA_TO_WRITE_LAST);\n+\n+\trte_wmb();/* The first 8 bytes should be written last */\n+\n+\t*(u64 *)dst = *(u64 *)src;\n+}\n+\n+static void cmdq_prepare_wqe_ctrl(struct hinic_cmdq_wqe *wqe, int wrapped,\n+\t\t\t\t  enum hinic_ack_type ack_type,\n+\t\t\t\t  enum hinic_mod_type mod, u8 cmd, u16 prod_idx,\n+\t\t\t\t  enum completion_format complete_format,\n+\t\t\t\t  enum data_format local_data_format,\n+\t\t\t\t  enum bufdesc_len buf_len)\n+{\n+\tstruct hinic_ctrl *ctrl;\n+\tenum ctrl_sect_len ctrl_len;\n+\tstruct hinic_cmdq_wqe_lcmd *wqe_lcmd;\n+\tstruct hinic_cmdq_wqe_scmd *wqe_scmd;\n+\tu32 saved_data = WQE_HEADER(wqe)->saved_data;\n+\n+\tif (local_data_format == DATA_SGE) {\n+\t\twqe_lcmd = &wqe->wqe_lcmd;\n+\n+\t\twqe_lcmd->status.status_info = 0;\n+\t\tctrl = &wqe_lcmd->ctrl;\n+\t\tctrl_len = CTRL_SECT_LEN;\n+\t} else {\n+\t\twqe_scmd = &wqe->inline_wqe.wqe_scmd;\n+\n+\t\twqe_scmd->status.status_info = 0;\n+\t\tctrl = &wqe_scmd->ctrl;\n+\t\tctrl_len = CTRL_DIRECT_SECT_LEN;\n+\t}\n+\n+\tctrl->ctrl_info = CMDQ_CTRL_SET(prod_idx, PI)\t\t|\n+\t\t\tCMDQ_CTRL_SET(cmd, CMD)\t\t\t|\n+\t\t\tCMDQ_CTRL_SET(mod, MOD)\t\t\t|\n+\t\t\tCMDQ_CTRL_SET(ack_type, ACK_TYPE);\n+\n+\tWQE_HEADER(wqe)->header_info =\n+\t\tCMDQ_WQE_HEADER_SET(buf_len, BUFDESC_LEN) |\n+\t\tCMDQ_WQE_HEADER_SET(complete_format, COMPLETE_FMT) |\n+\t\tCMDQ_WQE_HEADER_SET(local_data_format, DATA_FMT)\t|\n+\t\tCMDQ_WQE_HEADER_SET(CEQ_SET, COMPLETE_REQ)\t|\n+\t\tCMDQ_WQE_HEADER_SET(COMPLETE_LEN, COMPLETE_SECT_LEN) |\n+\t\tCMDQ_WQE_HEADER_SET(ctrl_len, CTRL_LEN)\t\t|\n+\t\tCMDQ_WQE_HEADER_SET((u32)wrapped, HW_BUSY_BIT);\n+\n+\tif (cmd == CMDQ_SET_ARM_CMD && mod == HINIC_MOD_COMM) {\n+\t\tsaved_data &= SAVED_DATA_CLEAR(saved_data, ARM);\n+\t\tWQE_HEADER(wqe)->saved_data = saved_data |\n+\t\t\t\t\t\tSAVED_DATA_SET(1, ARM);\n+\t} else {\n+\t\tsaved_data &= SAVED_DATA_CLEAR(saved_data, ARM);\n+\t\tWQE_HEADER(wqe)->saved_data = saved_data;\n+\t}\n+}\n+\n+static void cmdq_set_lcmd_wqe(struct hinic_cmdq_wqe *wqe,\n+\t\t\t      enum cmdq_cmd_type cmd_type,\n+\t\t\t      struct hinic_cmd_buf *buf_in,\n+\t\t\t      struct hinic_cmd_buf *buf_out, int wrapped,\n+\t\t\t      enum hinic_ack_type ack_type,\n+\t\t\t      enum hinic_mod_type mod, u8 cmd, u16 prod_idx)\n+{\n+\tstruct hinic_cmdq_wqe_lcmd *wqe_lcmd = &wqe->wqe_lcmd;\n+\tenum completion_format complete_format = COMPLETE_DIRECT;\n+\n+\tswitch (cmd_type) {\n+\tcase SYNC_CMD_SGE_RESP:\n+\t\tif (buf_out) {\n+\t\t\tcomplete_format = COMPLETE_SGE;\n+\t\t\tcmdq_set_completion(&wqe_lcmd->completion, buf_out);\n+\t\t}\n+\t\tbreak;\n+\tcase SYNC_CMD_DIRECT_RESP:\n+\t\tcomplete_format = COMPLETE_DIRECT;\n+\t\twqe_lcmd->completion.direct_resp = 0;\n+\t\tbreak;\n+\tcase ASYNC_CMD:\n+\t\tcomplete_format = COMPLETE_DIRECT;\n+\t\twqe_lcmd->completion.direct_resp = 0;\n+\n+\t\twqe_lcmd->buf_desc.saved_async_buf = (u64)(buf_in);\n+\t\tbreak;\n+\t}\n+\n+\tcmdq_prepare_wqe_ctrl(wqe, wrapped, ack_type, mod, cmd,\n+\t\t\t      prod_idx, complete_format, DATA_SGE,\n+\t\t\t      BUFDESC_LCMD_LEN);\n+\n+\tcmdq_set_lcmd_bufdesc(wqe_lcmd, buf_in);\n+}\n+\n+static int cmdq_params_valid(struct hinic_cmd_buf *buf_in)\n+{\n+\tif (buf_in->size > HINIC_CMDQ_MAX_DATA_SIZE) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid CMDQ buffer size\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int wait_cmdqs_enable(struct hinic_cmdqs *cmdqs)\n+{\n+\tunsigned long end;\n+\n+\tend = jiffies + msecs_to_jiffies(WAIT_CMDQ_ENABLE_TIMEOUT);\n+\tdo {\n+\t\tif (cmdqs->status & HINIC_CMDQ_ENABLE)\n+\t\t\treturn 0;\n+\n+\t} while (time_before(jiffies, end));\n+\n+\treturn -EBUSY;\n+}\n+\n+static void cmdq_update_errcode(struct hinic_cmdq *cmdq, u16 prod_idx,\n+\t\t\t\tint errcode)\n+{\n+\tcmdq->errcode[prod_idx] = errcode;\n+}\n+\n+static void clear_wqe_complete_bit(struct hinic_cmdq *cmdq,\n+\t\t\t\t   struct hinic_cmdq_wqe *wqe)\n+{\n+\tstruct hinic_cmdq_wqe_lcmd *wqe_lcmd;\n+\tstruct hinic_cmdq_inline_wqe *inline_wqe;\n+\tstruct hinic_cmdq_wqe_scmd *wqe_scmd;\n+\tstruct hinic_ctrl *ctrl;\n+\tu32 header_info = be32_to_cpu(WQE_HEADER(wqe)->header_info);\n+\tint buf_len = CMDQ_WQE_HEADER_GET(header_info, BUFDESC_LEN);\n+\tint wqe_size = cmdq_get_wqe_size(buf_len);\n+\tu16 num_wqebbs;\n+\n+\tif (wqe_size == WQE_LCMD_SIZE) {\n+\t\twqe_lcmd = &wqe->wqe_lcmd;\n+\t\tctrl = &wqe_lcmd->ctrl;\n+\t} else {\n+\t\tinline_wqe = &wqe->inline_wqe;\n+\t\twqe_scmd = &inline_wqe->wqe_scmd;\n+\t\tctrl = &wqe_scmd->ctrl;\n+\t}\n+\n+\t/* clear HW busy bit */\n+\tctrl->ctrl_info = 0;\n+\n+\trte_wmb();\t/* verify wqe is clear */\n+\n+\tnum_wqebbs = WQE_NUM_WQEBBS(wqe_size, cmdq->wq);\n+\thinic_put_wqe(cmdq->wq, num_wqebbs);\n+}\n+\n+static int hinic_set_cmdq_ctxts(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_cmdqs *cmdqs = hwdev->cmdqs;\n+\tstruct hinic_cmdq_ctxt *cmdq_ctxt;\n+\tenum hinic_cmdq_type cmdq_type;\n+\tu16 in_size;\n+\tint err;\n+\n+\tcmdq_type = HINIC_CMDQ_SYNC;\n+\tfor (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {\n+\t\tcmdq_ctxt = &cmdqs->cmdq[cmdq_type].cmdq_ctxt;\n+\t\tcmdq_ctxt->resp_aeq_num = HINIC_AEQ1;\n+\t\tin_size = sizeof(*cmdq_ctxt);\n+\t\terr = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t\t     HINIC_MGMT_CMD_CMDQ_CTXT_SET,\n+\t\t\t\t\t     cmdq_ctxt, in_size, NULL,\n+\t\t\t\t\t     NULL, 0);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Set cmdq ctxt failed\");\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\t}\n+\n+\tcmdqs->status |= HINIC_CMDQ_ENABLE;\n+\n+\treturn 0;\n+}\n+\n+void hinic_comm_cmdqs_free(struct hinic_hwdev *hwdev)\n+{\n+\thinic_cmdqs_free(hwdev);\n+}\n+\n+int hinic_reinit_cmdq_ctxts(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_cmdqs *cmdqs = hwdev->cmdqs;\n+\tenum hinic_cmdq_type cmdq_type;\n+\n+\tcmdq_type = HINIC_CMDQ_SYNC;\n+\tfor (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {\n+\t\tcmdqs->cmdq[cmdq_type].wrapped = 1;\n+\t\thinic_wq_wqe_pg_clear(cmdqs->cmdq[cmdq_type].wq);\n+\t}\n+\n+\treturn hinic_set_cmdq_ctxts(hwdev);\n+}\n+\n+static int init_cmdq(struct hinic_cmdq *cmdq, struct hinic_hwdev *hwdev,\n+\t\t     struct hinic_wq *wq, enum hinic_cmdq_type q_type)\n+{\n+\tvoid __iomem *db_base;\n+\tint err = 0;\n+\tsize_t errcode_size;\n+\tsize_t cmd_infos_size;\n+\n+\tcmdq->wq = wq;\n+\tcmdq->cmdq_type = q_type;\n+\tcmdq->wrapped = 1;\n+\n+\tspin_lock_init(&cmdq->cmdq_lock);\n+\n+\terrcode_size = wq->q_depth * sizeof(*cmdq->errcode);\n+\tcmdq->errcode = kzalloc(errcode_size, GFP_KERNEL);\n+\tif (!cmdq->errcode) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate errcode for cmdq failed\");\n+\t\tspin_lock_deinit(&cmdq->cmdq_lock);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tcmd_infos_size = wq->q_depth * sizeof(*cmdq->cmd_infos);\n+\tcmdq->cmd_infos = kzalloc(cmd_infos_size, GFP_KERNEL);\n+\tif (!cmdq->cmd_infos) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate errcode for cmdq failed\");\n+\t\terr = -ENOMEM;\n+\t\tgoto cmd_infos_err;\n+\t}\n+\n+\terr = hinic_alloc_db_addr(hwdev, &db_base);\n+\tif (err)\n+\t\tgoto alloc_db_err;\n+\n+\tcmdq->db_base = (u8 *)db_base;\n+\treturn 0;\n+\n+alloc_db_err:\n+\tkfree(cmdq->cmd_infos);\n+\n+cmd_infos_err:\n+\tkfree(cmdq->errcode);\n+\tspin_lock_deinit(&cmdq->cmdq_lock);\n+\n+\treturn err;\n+}\n+\n+static void free_cmdq(struct hinic_hwdev *hwdev, struct hinic_cmdq *cmdq)\n+{\n+\thinic_free_db_addr(hwdev, cmdq->db_base);\n+\tkfree(cmdq->cmd_infos);\n+\tkfree(cmdq->errcode);\n+\tspin_lock_deinit(&cmdq->cmdq_lock);\n+}\n+\n+static int hinic_cmdqs_init(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_cmdqs *cmdqs;\n+\tstruct hinic_cmdq_ctxt *cmdq_ctxt;\n+\tenum hinic_cmdq_type type, cmdq_type;\n+\tsize_t saved_wqs_size;\n+\tint err;\n+\n+\tcmdqs = kzalloc(sizeof(*cmdqs), GFP_KERNEL);\n+\tif (!cmdqs)\n+\t\treturn -ENOMEM;\n+\n+\thwdev->cmdqs = cmdqs;\n+\tcmdqs->hwdev = hwdev;\n+\n+\tsaved_wqs_size = HINIC_MAX_CMDQ_TYPES * sizeof(struct hinic_wq);\n+\tcmdqs->saved_wqs = kzalloc(saved_wqs_size, GFP_KERNEL);\n+\tif (!cmdqs->saved_wqs) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate saved wqs failed\");\n+\t\terr = -ENOMEM;\n+\t\tgoto alloc_wqs_err;\n+\t}\n+\n+\tcmdqs->cmd_buf_pool = dma_pool_create(\"hinic_cmdq\", hwdev,\n+\t\t\t\t\t      HINIC_CMDQ_BUF_SIZE,\n+\t\t\t\t\t      HINIC_CMDQ_BUF_SIZE, 0ULL);\n+\tif (!cmdqs->cmd_buf_pool) {\n+\t\tPMD_DRV_LOG(ERR, \"Create cmdq buffer pool failed\");\n+\t\terr = -ENOMEM;\n+\t\tgoto pool_create_err;\n+\t}\n+\n+\terr = hinic_cmdq_alloc(cmdqs->saved_wqs, hwdev,\n+\t\t\t       HINIC_MAX_CMDQ_TYPES, HINIC_CMDQ_WQ_BUF_SIZE,\n+\t\t\t       CMDQ_WQEBB_SHIFT, HINIC_CMDQ_DEPTH);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cmdq failed\");\n+\t\tgoto cmdq_alloc_err;\n+\t}\n+\n+\tcmdq_type = HINIC_CMDQ_SYNC;\n+\tfor (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {\n+\t\terr = init_cmdq(&cmdqs->cmdq[cmdq_type], hwdev,\n+\t\t\t\t&cmdqs->saved_wqs[cmdq_type], cmdq_type);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Initialize cmdq failed\");\n+\t\t\tgoto init_cmdq_err;\n+\t\t}\n+\n+\t\tcmdq_ctxt = &cmdqs->cmdq[cmdq_type].cmdq_ctxt;\n+\t\tcmdq_init_queue_ctxt(&cmdqs->cmdq[cmdq_type], cmdq_ctxt);\n+\t}\n+\n+\terr = hinic_set_cmdq_ctxts(hwdev);\n+\tif (err)\n+\t\tgoto init_cmdq_err;\n+\n+\treturn 0;\n+\n+init_cmdq_err:\n+\ttype = HINIC_CMDQ_SYNC;\n+\tfor ( ; type < cmdq_type; type++)\n+\t\tfree_cmdq(hwdev, &cmdqs->cmdq[type]);\n+\n+\thinic_cmdq_free(hwdev, cmdqs->saved_wqs, HINIC_MAX_CMDQ_TYPES);\n+\n+cmdq_alloc_err:\n+\tdma_pool_destroy(cmdqs->cmd_buf_pool);\n+\n+pool_create_err:\n+\tkfree(cmdqs->saved_wqs);\n+\n+alloc_wqs_err:\n+\tkfree(cmdqs);\n+\n+\treturn err;\n+}\n+\n+static void hinic_cmdqs_free(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_cmdqs *cmdqs = hwdev->cmdqs;\n+\tenum hinic_cmdq_type cmdq_type = HINIC_CMDQ_SYNC;\n+\n+\tcmdqs->status &= ~HINIC_CMDQ_ENABLE;\n+\n+\tfor ( ; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++)\n+\t\tfree_cmdq(cmdqs->hwdev, &cmdqs->cmdq[cmdq_type]);\n+\n+\thinic_cmdq_free(hwdev, cmdqs->saved_wqs,\n+\t\t\tHINIC_MAX_CMDQ_TYPES);\n+\n+\tdma_pool_destroy(cmdqs->cmd_buf_pool);\n+\n+\tkfree(cmdqs->saved_wqs);\n+\n+\tkfree(cmdqs);\n+}\n+\n+static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth)\n+{\n+\tstruct hinic_root_ctxt root_ctxt;\n+\n+\tmemset(&root_ctxt, 0, sizeof(root_ctxt));\n+\troot_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;\n+\troot_ctxt.func_idx = hinic_global_func_id(hwdev);\n+\troot_ctxt.ppf_idx = hinic_ppf_idx(hwdev);\n+\troot_ctxt.set_cmdq_depth = 1;\n+\troot_ctxt.cmdq_depth = (u8)ilog2(cmdq_depth);\n+\treturn hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,\n+\t\t\t\t      HINIC_MGMT_CMD_VAT_SET,\n+\t\t\t\t      &root_ctxt, sizeof(root_ctxt),\n+\t\t\t\t      NULL, NULL, 0);\n+}\n+\n+int hinic_comm_cmdqs_init(struct hinic_hwdev *hwdev)\n+{\n+\tint err;\n+\n+\terr = hinic_cmdqs_init(hwdev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Init cmd queues failed\");\n+\t\treturn err;\n+\t}\n+\n+\terr = hinic_set_cmdq_depth(hwdev, HINIC_CMDQ_DEPTH);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Set cmdq depth failed\");\n+\t\tgoto set_cmdq_depth_err;\n+\t}\n+\n+\treturn 0;\n+\n+set_cmdq_depth_err:\n+\thinic_cmdqs_free(hwdev);\n+\n+\treturn err;\n+}\n+\n+static void cmdq_init_queue_ctxt(struct hinic_cmdq *cmdq,\n+\t\t\t\t struct hinic_cmdq_ctxt *cmdq_ctxt)\n+{\n+\tstruct hinic_cmdqs *cmdqs = (struct hinic_cmdqs *)cmdq_to_cmdqs(cmdq);\n+\tstruct hinic_hwdev *hwdev = cmdqs->hwdev;\n+\tstruct hinic_wq *wq = cmdq->wq;\n+\tstruct hinic_cmdq_ctxt_info *ctxt_info = &cmdq_ctxt->ctxt_info;\n+\tu64 wq_first_page_paddr, pfn;\n+\n+\tu16 start_ci = (u16)(wq->cons_idx);\n+\n+\t/* The data in the HW is in Big Endian Format */\n+\twq_first_page_paddr = wq->queue_buf_paddr;\n+\n+\tpfn = CMDQ_PFN(wq_first_page_paddr, HINIC_PAGE_SIZE);\n+\tctxt_info->curr_wqe_page_pfn =\n+\t\tCMDQ_CTXT_PAGE_INFO_SET(1, HW_BUSY_BIT) |\n+\t\tCMDQ_CTXT_PAGE_INFO_SET(1, CEQ_EN)\t|\n+\t\tCMDQ_CTXT_PAGE_INFO_SET(0, CEQ_ARM)\t|\n+\t\tCMDQ_CTXT_PAGE_INFO_SET(HINIC_CEQ_ID_CMDQ, EQ_ID) |\n+\t\tCMDQ_CTXT_PAGE_INFO_SET(pfn, CURR_WQE_PAGE_PFN);\n+\n+\tctxt_info->wq_block_pfn = CMDQ_CTXT_BLOCK_INFO_SET(start_ci, CI) |\n+\t\t\t\tCMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN);\n+\tcmdq_ctxt->func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif);\n+\tcmdq_ctxt->ppf_idx  = HINIC_HWIF_PPF_IDX(hwdev->hwif);\n+\tcmdq_ctxt->cmdq_id  = cmdq->cmdq_type;\n+}\n+\n+static int hinic_cmdq_poll_msg(struct hinic_cmdq *cmdq, u32 timeout)\n+{\n+\tstruct hinic_cmdq_wqe *wqe;\n+\tstruct hinic_cmdq_wqe_lcmd *wqe_lcmd;\n+\tstruct hinic_ctrl *ctrl;\n+\tstruct hinic_cmdq_cmd_info *cmd_info;\n+\tu32 status_info, ctrl_info;\n+\tu16 ci;\n+\tint errcode;\n+\tunsigned long end;\n+\tint done = 0;\n+\tint rc = 0;\n+\n+\twqe = hinic_read_wqe(cmdq->wq, 1, &ci);\n+\tif (wqe == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"No outstanding cmdq msg\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tcmd_info = &cmdq->cmd_infos[ci];\n+\t/* this cmd has not been filled and send to hw, or get TMO msg ack*/\n+\tif (cmd_info->cmd_type == HINIC_CMD_TYPE_NONE) {\n+\t\tPMD_DRV_LOG(ERR, \"Cmdq msg has not been filled and send to hw, or get TMO msg ack. cmdq ci: %u\",\n+\t\t\t    ci);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* only arm bit is using scmd wqe, the wqe is lcmd */\n+\twqe_lcmd = &wqe->wqe_lcmd;\n+\tctrl = &wqe_lcmd->ctrl;\n+\tend = jiffies + msecs_to_jiffies(timeout);\n+\tdo {\n+\t\tctrl_info = be32_to_cpu((ctrl)->ctrl_info);\n+\t\tif (WQE_COMPLETED(ctrl_info)) {\n+\t\t\tdone = 1;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\trte_delay_ms(1);\n+\t} while (time_before(jiffies, end));\n+\n+\tif (done) {\n+\t\tstatus_info = be32_to_cpu(wqe_lcmd->status.status_info);\n+\t\terrcode = WQE_ERRCODE_GET(status_info, VAL);\n+\t\tcmdq_update_errcode(cmdq, ci, errcode);\n+\t\tclear_wqe_complete_bit(cmdq, wqe);\n+\t\trc = 0;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Poll cmdq msg time out, ci: %u\", ci);\n+\t\trc = -ETIMEDOUT;\n+\t}\n+\n+\t/* set this cmd invalid */\n+\tcmd_info->cmd_type = HINIC_CMD_TYPE_NONE;\n+\n+\treturn rc;\n+}\n+\n+static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,\n+\t\t\t\t     enum hinic_ack_type ack_type,\n+\t\t\t\t     enum hinic_mod_type mod, u8 cmd,\n+\t\t\t\t     struct hinic_cmd_buf *buf_in,\n+\t\t\t\t     u64 *out_param, u32 timeout)\n+{\n+\tstruct hinic_wq *wq = cmdq->wq;\n+\tstruct hinic_cmdq_wqe *curr_wqe, wqe;\n+\tstruct hinic_cmdq_wqe_lcmd *wqe_lcmd;\n+\tu16 curr_prod_idx, next_prod_idx, num_wqebbs;\n+\tint wrapped;\n+\tu32 timeo, wqe_size;\n+\tint err;\n+\n+\twqe_size = cmdq_wqe_size(WQE_LCMD_TYPE);\n+\tnum_wqebbs = WQE_NUM_WQEBBS(wqe_size, wq);\n+\n+\t/* Keep wrapped and doorbell index correct. */\n+\tspin_lock(&cmdq->cmdq_lock);\n+\n+\tcurr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx);\n+\tif (!curr_wqe) {\n+\t\terr = -EBUSY;\n+\t\tgoto cmdq_unlock;\n+\t}\n+\n+\tmemset(&wqe, 0, sizeof(wqe));\n+\twrapped = cmdq->wrapped;\n+\n+\tnext_prod_idx = curr_prod_idx + num_wqebbs;\n+\tif (next_prod_idx >= wq->q_depth) {\n+\t\tcmdq->wrapped = !cmdq->wrapped;\n+\t\tnext_prod_idx -= wq->q_depth;\n+\t}\n+\n+\tcmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL,\n+\t\t\t  wrapped, ack_type, mod, cmd, curr_prod_idx);\n+\n+\t/* The data that is written to HW should be in Big Endian Format */\n+\thinic_cpu_to_be32(&wqe, wqe_size);\n+\n+\t/* CMDQ WQE is not shadow, therefore wqe will be written to wq */\n+\tcmdq_wqe_fill(curr_wqe, &wqe);\n+\n+\tcmdq->cmd_infos[curr_prod_idx].cmd_type = HINIC_CMD_TYPE_NORMAL;\n+\n+\tcmdq_set_db(cmdq, HINIC_CMDQ_SYNC, next_prod_idx);\n+\n+\ttimeo = msecs_to_jiffies(timeout ? timeout : CMDQ_CMD_TIMEOUT);\n+\terr = hinic_cmdq_poll_msg(cmdq, timeo);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Cmdq poll msg ack failed, prod idx: 0x%x\",\n+\t\t\tcurr_prod_idx);\n+\t\terr = -ETIMEDOUT;\n+\t\tgoto cmdq_unlock;\n+\t}\n+\n+\trte_smp_rmb();\t/* read error code after completion */\n+\n+\tif (out_param) {\n+\t\twqe_lcmd = &curr_wqe->wqe_lcmd;\n+\t\t*out_param = cpu_to_be64(wqe_lcmd->completion.direct_resp);\n+\t}\n+\n+\tif (cmdq->errcode[curr_prod_idx] > 1) {\n+\t\terr = cmdq->errcode[curr_prod_idx];\n+\t\tgoto cmdq_unlock;\n+\t}\n+\n+cmdq_unlock:\n+\tspin_unlock(&cmdq->cmdq_lock);\n+\n+\treturn err;\n+}\n+\n+int hinic_cmdq_direct_resp(void *hwdev, enum hinic_ack_type ack_type,\n+\t\t\t   enum hinic_mod_type mod, u8 cmd,\n+\t\t\t   struct hinic_cmd_buf *buf_in,\n+\t\t\t   u64 *out_param, u32 timeout)\n+{\n+\tstruct hinic_cmdqs *cmdqs = ((struct hinic_hwdev *)hwdev)->cmdqs;\n+\tint err = cmdq_params_valid(buf_in);\n+\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid CMDQ parameters\");\n+\t\treturn err;\n+\t}\n+\n+\terr = wait_cmdqs_enable(cmdqs);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Cmdq is disable\");\n+\t\treturn err;\n+\t}\n+\n+\treturn cmdq_sync_cmd_direct_resp(&cmdqs->cmdq[HINIC_CMDQ_SYNC],\n+\t\t\t\t\t ack_type, mod, cmd, buf_in,\n+\t\t\t\t\t out_param, timeout);\n+}\ndiff --git a/drivers/net/hinic/base/hinic_pmd_cmdq.h b/drivers/net/hinic/base/hinic_pmd_cmdq.h\nnew file mode 100644\nindex 000000000..da939e16f\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_cmdq.h\n@@ -0,0 +1,242 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_CMDQ_H_\n+#define _HINIC_PMD_CMDQ_H_\n+\n+#define HINIC_DB_OFF\t\t\t0x00000800\n+\n+#define HINIC_SCMD_DATA_LEN\t\t16\n+\n+/* hiovs pmd use 64, kernel l2nic use 4096 */\n+#define\tHINIC_CMDQ_DEPTH\t\t64\n+\n+#define\tHINIC_CMDQ_BUF_SIZE\t\t2048U\n+#define HINIC_CMDQ_BUF_HW_RSVD\t\t8\n+#define HINIC_CMDQ_MAX_DATA_SIZE\t(HINIC_CMDQ_BUF_SIZE\t\\\n+\t\t\t\t\t - HINIC_CMDQ_BUF_HW_RSVD)\n+\n+#define\tHINIC_CEQ_ID_CMDQ\t\t0\n+\n+enum cmdq_scmd_type {\n+\tCMDQ_SET_ARM_CMD = 2,\n+};\n+\n+enum cmdq_wqe_type {\n+\tWQE_LCMD_TYPE,\n+\tWQE_SCMD_TYPE,\n+};\n+\n+enum ctrl_sect_len {\n+\tCTRL_SECT_LEN = 1,\n+\tCTRL_DIRECT_SECT_LEN = 2,\n+};\n+\n+enum bufdesc_len {\n+\tBUFDESC_LCMD_LEN = 2,\n+\tBUFDESC_SCMD_LEN = 3,\n+};\n+\n+enum data_format {\n+\tDATA_SGE,\n+};\n+\n+enum completion_format {\n+\tCOMPLETE_DIRECT,\n+\tCOMPLETE_SGE,\n+};\n+\n+enum completion_request {\n+\tCEQ_SET = 1,\n+};\n+\n+enum cmdq_cmd_type {\n+\tSYNC_CMD_DIRECT_RESP,\n+\tSYNC_CMD_SGE_RESP,\n+\tASYNC_CMD,\n+};\n+\n+enum hinic_cmdq_type {\n+\tHINIC_CMDQ_SYNC,\n+\tHINIC_CMDQ_ASYNC,\n+\tHINIC_MAX_CMDQ_TYPES,\n+};\n+\n+enum hinic_db_src_type {\n+\tHINIC_DB_SRC_CMDQ_TYPE,\n+\tHINIC_DB_SRC_L2NIC_SQ_TYPE,\n+};\n+\n+enum hinic_cmdq_db_type {\n+\tHINIC_DB_SQ_RQ_TYPE,\n+\tHINIC_DB_CMDQ_TYPE,\n+};\n+\n+/* CMDQ WQE CTRLS */\n+struct hinic_cmdq_header {\n+\tu32\theader_info;\n+\tu32\tsaved_data;\n+};\n+\n+struct hinic_scmd_bufdesc {\n+\tu32\tbuf_len;\n+\tu32\trsvd;\n+\tu8\tdata[HINIC_SCMD_DATA_LEN];\n+};\n+\n+struct hinic_lcmd_bufdesc {\n+\tstruct hinic_sge\tsge;\n+\tu32\t\t\trsvd1;\n+\tu64\t\t\tsaved_async_buf;\n+\tu64\t\t\trsvd3;\n+};\n+\n+struct hinic_cmdq_db {\n+\tu32\tdb_info;\n+\tu32\trsvd;\n+};\n+\n+struct hinic_status {\n+\tu32 status_info;\n+};\n+\n+struct hinic_ctrl {\n+\tu32 ctrl_info;\n+};\n+\n+struct hinic_sge_resp {\n+\tstruct hinic_sge sge;\n+\tu32\t\trsvd;\n+};\n+\n+struct hinic_cmdq_completion {\n+\t/* HW Format */\n+\tunion {\n+\t\tstruct hinic_sge_resp\tsge_resp;\n+\t\tu64\t\t\tdirect_resp;\n+\t};\n+};\n+\n+struct hinic_cmdq_wqe_scmd {\n+\tstruct hinic_cmdq_header\theader;\n+\tstruct hinic_cmdq_db\t\tdb;\n+\tstruct hinic_status\t\tstatus;\n+\tstruct hinic_ctrl\t\tctrl;\n+\tstruct hinic_cmdq_completion\tcompletion;\n+\tstruct hinic_scmd_bufdesc\tbuf_desc;\n+};\n+\n+struct hinic_cmdq_wqe_lcmd {\n+\tstruct hinic_cmdq_header\theader;\n+\tstruct hinic_status\t\tstatus;\n+\tstruct hinic_ctrl\t\tctrl;\n+\tstruct hinic_cmdq_completion\tcompletion;\n+\tstruct hinic_lcmd_bufdesc\tbuf_desc;\n+};\n+\n+struct hinic_cmdq_inline_wqe {\n+\tstruct hinic_cmdq_wqe_scmd\twqe_scmd;\n+};\n+\n+struct hinic_cmdq_wqe {\n+\t/* HW Format */\n+\tunion{\n+\t\tstruct hinic_cmdq_inline_wqe\tinline_wqe;\n+\t\tstruct hinic_cmdq_wqe_lcmd\twqe_lcmd;\n+\t};\n+};\n+\n+struct hinic_cmdq_ctxt_info {\n+\tu64\tcurr_wqe_page_pfn;\n+\tu64\twq_block_pfn;\n+};\n+\n+/* New interface */\n+struct hinic_cmdq_ctxt {\n+\tu8\tstatus;\n+\tu8\tversion;\n+\tu8\tresp_aeq_num;\n+\tu8\trsvd0[5];\n+\n+\tu16\tfunc_idx;\n+\tu8\tcmdq_id;\n+\tu8\tppf_idx;\n+\n+\tu8\trsvd1[4];\n+\n+\tstruct hinic_cmdq_ctxt_info ctxt_info;\n+};\n+\n+enum hinic_cmdq_status {\n+\tHINIC_CMDQ_ENABLE = BIT(0),\n+};\n+\n+enum hinic_cmdq_cmd_type {\n+\tHINIC_CMD_TYPE_NONE,\n+\tHINIC_CMD_TYPE_SET_ARM,\n+\tHINIC_CMD_TYPE_NORMAL,\n+};\n+\n+struct hinic_cmdq_cmd_info {\n+\tenum hinic_cmdq_cmd_type cmd_type;\n+};\n+\n+struct hinic_cmdq {\n+\tstruct hinic_wq\t\t\t*wq;\n+\n+\tenum hinic_cmdq_type\t\tcmdq_type;\n+\tint\t\t\t\twrapped;\n+\n+\thinic_spinlock_t\t\tcmdq_lock;\n+\n+\tint\t\t\t\t*errcode;\n+\n+\t/* doorbell area */\n+\tu8 __iomem\t\t\t*db_base;\n+\n+\tstruct hinic_cmdq_ctxt\t\tcmdq_ctxt;\n+\n+\tstruct hinic_cmdq_cmd_info\t*cmd_infos;\n+};\n+\n+struct hinic_cmdqs {\n+\tstruct hinic_hwdev\t\t*hwdev;\n+\n+\tstruct pci_pool\t\t\t*cmd_buf_pool;\n+\n+\tstruct hinic_wq\t\t\t*saved_wqs;\n+\n+\tstruct hinic_cmdq\t\tcmdq[HINIC_MAX_CMDQ_TYPES];\n+\n+\tu32\t\t\t\tstatus;\n+};\n+\n+struct hinic_cmd_buf {\n+\tvoid\t\t*buf;\n+\tdma_addr_t\tdma_addr;\n+\tstruct rte_mbuf *mbuf;\n+\tu16\t\tsize;\n+};\n+\n+int hinic_reinit_cmdq_ctxts(struct hinic_hwdev *hwdev);\n+\n+bool hinic_cmdq_idle(struct hinic_cmdq *cmdq);\n+\n+struct hinic_cmd_buf *hinic_alloc_cmd_buf(void *hwdev);\n+\n+void hinic_free_cmd_buf(void *hwdev, struct hinic_cmd_buf *cmd_buf);\n+\n+/* PF/VF send cmd to ucode by cmdq, and return if success.\n+ * timeout=0, use default timeout.\n+ */\n+int hinic_cmdq_direct_resp(void *hwdev, enum hinic_ack_type ack_type,\n+\t\t\t   enum hinic_mod_type mod, u8 cmd,\n+\t\t\t   struct hinic_cmd_buf *buf_in,\n+\t\t\t   u64 *out_param, u32 timeout);\n+\n+int hinic_comm_cmdqs_init(struct hinic_hwdev *hwdev);\n+\n+void hinic_comm_cmdqs_free(struct hinic_hwdev *hwdev);\n+\n+#endif /* _HINIC_PMD_CMDQ_H_ */\n",
    "prefixes": [
        "v5",
        "04/15"
    ]
}