get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130794,
    "url": "https://patches.dpdk.org/api/patches/130794/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230829075829.208413-10-wanry@3snic.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20230829075829.208413-10-wanry@3snic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230829075829.208413-10-wanry@3snic.com",
    "date": "2023-08-29T07:58:06",
    "name": "[09/32] net/sssnic/base: add control queue",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ee15eeca0f86c8e89bc3f126d2a62ae635d2f0d6",
    "submitter": {
        "id": 3119,
        "url": "https://patches.dpdk.org/api/people/3119/?format=api",
        "name": "Renyong Wan",
        "email": "wanry@3snic.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230829075829.208413-10-wanry@3snic.com/mbox/",
    "series": [
        {
            "id": 29358,
            "url": "https://patches.dpdk.org/api/series/29358/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29358",
            "date": "2023-08-29T07:57:57",
            "name": "Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/29358/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/130794/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/130794/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 31A5B41F53;\n\tTue, 29 Aug 2023 10:00:06 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 332FF4029F;\n\tTue, 29 Aug 2023 09:59:40 +0200 (CEST)",
            "from VLXDG1SPAM1.ramaxel.com (email.ramaxel.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id 24B1A402B1\n for <dev@dpdk.org>; Tue, 29 Aug 2023 09:59:36 +0200 (CEST)",
            "from V12DG1MBS03.ramaxel.local ([172.26.18.33])\n by VLXDG1SPAM1.ramaxel.com with ESMTP id 37T7wrM8080563;\n Tue, 29 Aug 2023 15:58:59 +0800 (GMT-8)\n (envelope-from wanry@3snic.com)",
            "from localhost.localdomain (10.64.136.151) by\n V12DG1MBS03.ramaxel.local (172.26.18.33) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id\n 15.1.2375.17; Tue, 29 Aug 2023 15:58:40 +0800"
        ],
        "From": "<wanry@3snic.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@amd.com>, Renyong Wan <wanry@3snic.com>, Steven Song\n <steven.song@3snic.com>",
        "Subject": "[PATCH 09/32] net/sssnic/base: add control queue",
        "Date": "Tue, 29 Aug 2023 15:58:06 +0800",
        "Message-ID": "<20230829075829.208413-10-wanry@3snic.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230829075829.208413-1-wanry@3snic.com>",
        "References": "<20230829075829.208413-1-wanry@3snic.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "7bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.136.151]",
        "X-ClientProxiedBy": "V12DG1MBS03.ramaxel.local (172.26.18.33) To\n V12DG1MBS03.ramaxel.local (172.26.18.33)",
        "X-DNSRBL": "",
        "X-SPAM-SOURCE-CHECK": "pass",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 37T7wrM8080563",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Renyong Wan <wanry@3snic.com>\n\nControl queue is used for communication between driver and datapath code\nof firmware.\n\nSigned-off-by: Steven Song <steven.song@3snic.com>\nSigned-off-by: Renyong Wan <wanry@3snic.com>\n---\n drivers/net/sssnic/base/meson.build    |   2 +\n drivers/net/sssnic/base/sssnic_api.c   | 102 +++++\n drivers/net/sssnic/base/sssnic_api.h   |  23 ++\n drivers/net/sssnic/base/sssnic_cmd.h   | 114 ++++++\n drivers/net/sssnic/base/sssnic_ctrlq.c | 519 +++++++++++++++++++++++++\n drivers/net/sssnic/base/sssnic_ctrlq.h |  58 +++\n drivers/net/sssnic/base/sssnic_hw.c    | 149 +++++++\n drivers/net/sssnic/base/sssnic_hw.h    |   8 +\n 8 files changed, 975 insertions(+)\n create mode 100644 drivers/net/sssnic/base/sssnic_api.c\n create mode 100644 drivers/net/sssnic/base/sssnic_api.h\n create mode 100644 drivers/net/sssnic/base/sssnic_cmd.h\n create mode 100644 drivers/net/sssnic/base/sssnic_ctrlq.c\n create mode 100644 drivers/net/sssnic/base/sssnic_ctrlq.h",
    "diff": "diff --git a/drivers/net/sssnic/base/meson.build b/drivers/net/sssnic/base/meson.build\nindex 7c23a82ff3..e93ca7b24b 100644\n--- a/drivers/net/sssnic/base/meson.build\n+++ b/drivers/net/sssnic/base/meson.build\n@@ -7,6 +7,8 @@ sources = [\n         'sssnic_msg.c',\n         'sssnic_mbox.c',\n         'sssnic_workq.c',\n+        'sssnic_ctrlq.c',\n+        'sssnic_api.c',\n ]\n \n c_args = cflags\ndiff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c\nnew file mode 100644\nindex 0000000000..51a59f0f25\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_api.c\n@@ -0,0 +1,102 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#include <rte_byteorder.h>\n+#include <rte_common.h>\n+#include <rte_malloc.h>\n+#include <rte_mbuf.h>\n+\n+#include \"../sssnic_log.h\"\n+#include \"sssnic_hw.h\"\n+#include \"sssnic_cmd.h\"\n+#include \"sssnic_mbox.h\"\n+#include \"sssnic_api.h\"\n+\n+int\n+sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,\n+\tstruct sssnic_msix_attr *attr)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_msix_ctrl_cmd cmd;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_GET;\n+\tcmd.idx = msix_idx;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_MSIX_CTRL_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to MSIX_CTRL_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\tattr->lli_credit = cmd.lli_credit;\n+\tattr->lli_timer = cmd.lli_timer;\n+\tattr->pending_limit = cmd.pending_count;\n+\tattr->coalescing_timer = cmd.coalescing_timer;\n+\tattr->resend_timer = cmd.resend_timer;\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_msix_attr_set(struct sssnic_hw *hw, uint16_t msix_idx,\n+\tstruct sssnic_msix_attr *attr)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_msix_ctrl_cmd cmd;\n+\tstruct sssnic_msix_attr tmp;\n+\tuint32_t cmd_len;\n+\n+\tret = sssnic_msix_attr_get(hw, msix_idx, &tmp);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get interrupt configuration\");\n+\t\treturn ret;\n+\t}\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd.idx = msix_idx;\n+\tcmd.lli_credit = tmp.lli_credit;\n+\tcmd.lli_timer = tmp.lli_timer;\n+\tcmd.pending_count = tmp.pending_limit;\n+\tcmd.coalescing_timer = tmp.coalescing_timer;\n+\tcmd.resend_timer = tmp.resend_timer;\n+\tif (attr->lli_set != 0) {\n+\t\tcmd.lli_credit = attr->lli_credit;\n+\t\tcmd.lli_timer = attr->lli_timer;\n+\t}\n+\tif (attr->coalescing_set != 0) {\n+\t\tcmd.pending_count = attr->pending_limit;\n+\t\tcmd.coalescing_timer = attr->coalescing_timer;\n+\t\tcmd.resend_timer = attr->resend_timer;\n+\t}\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_MSIX_CTRL_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to MSIX_CTRL_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h\nnew file mode 100644\nindex 0000000000..3d54eb826a\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_api.h\n@@ -0,0 +1,23 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_API_H_\n+#define _SSSNIC_API_H_\n+\n+struct sssnic_msix_attr {\n+\tuint32_t lli_set;\n+\tuint32_t coalescing_set;\n+\tuint8_t lli_credit;\n+\tuint8_t lli_timer;\n+\tuint8_t pending_limit;\n+\tuint8_t coalescing_timer;\n+\tuint8_t resend_timer;\n+};\n+\n+int sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,\n+\tstruct sssnic_msix_attr *attr);\n+int sssnic_msix_attr_set(struct sssnic_hw *hw, uint16_t msix_idx,\n+\tstruct sssnic_msix_attr *attr);\n+\n+#endif /* _SSSNIC_API_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_cmd.h b/drivers/net/sssnic/base/sssnic_cmd.h\nnew file mode 100644\nindex 0000000000..ee9f536ac2\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_cmd.h\n@@ -0,0 +1,114 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_CMD_H_\n+#define _SSSNIC_CMD_H_\n+\n+#define SSSNIC_CMD_OPCODE_SET 1\n+#define SSSNIC_CMD_OPCODE_GET 0\n+\n+enum sssnic_mgmt_cmd_id {\n+\tSSSNIC_RESET_FUNC_CMD = 0,\n+\tSSSNIC_SET_CTRLQ_CTX_CMD = 20,\n+\tSSSNIC_SET_ROOT_CTX_CMD = 21,\n+\tSSSNIC_PAGESIZE_CFG_CMD = 22,\n+\tSSSNIC_MSIX_CTRL_CMD = 23,\n+\tSSSNIC_SET_DMA_ATTR_CMD = 25,\n+\tSSSNIC_GET_FW_VERSION_CMD = 60,\n+};\n+\n+struct sssnic_cmd_common {\n+\tuint8_t status;\n+\tuint8_t version;\n+\tuint8_t resvd[6];\n+};\n+\n+struct sssnic_set_ctrlq_ctx_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t func_id;\n+\t/* CtrlQ ID, here always is 0 */\n+\tuint8_t qid;\n+\tuint8_t resvd[5];\n+\tunion {\n+\t\tuint64_t data[2];\n+\t\tstruct {\n+\t\t\t/* Page frame number*/\n+\t\t\tuint64_t pfn : 52;\n+\t\t\tuint64_t resvd0 : 4;\n+\t\t\t/* Completion event queue ID*/\n+\t\t\tuint64_t eq_id : 5;\n+\t\t\t/* Interrupt enable indication */\n+\t\t\tuint64_t informed : 1;\n+\t\t\t/* Completion event queue enable indication */\n+\t\t\tuint64_t eq_en : 1;\n+\t\t\t/* Entries wrapped indication */\n+\t\t\tuint64_t wrapped : 1;\n+\t\t\tuint64_t block_pfn : 52;\n+\t\t\tuint64_t start_ci : 12;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_dma_attr_set_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t func_id;\n+\tuint8_t idx;\n+\tuint8_t st;\n+\tuint8_t at;\n+\tuint8_t ph;\n+\tuint8_t no_snooping;\n+\tuint8_t tph;\n+\tuint32_t resvd0;\n+};\n+\n+struct sssnic_func_reset_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t func_id;\n+\tuint16_t resvd[3];\n+\t/* Mask of reource to be reset */\n+\tuint64_t res_mask;\n+};\n+\n+struct sssnic_root_ctx_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t func_id;\n+\t/* set ctrlq depth enable */\n+\tuint8_t set_ctrlq_depth;\n+\t/* real depth is 2^ctrlq_depth */\n+\tuint8_t ctrlq_depth;\n+\tuint16_t rx_buf;\n+\tuint8_t lro_enable;\n+\tuint8_t resvd0;\n+\tuint16_t txq_depth;\n+\tuint16_t rxq_depth;\n+\tuint64_t resvd1;\n+};\n+\n+struct sssnic_pagesize_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t func_id;\n+\t/* SSSNIC_CMD_OPCODE_xx */\n+\tuint8_t opcode;\n+\t/* real size is (2^pagesz)*4KB */\n+\tuint8_t pagesz;\n+\tuint32_t resvd0;\n+};\n+\n+struct sssnic_msix_ctrl_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t func_id;\n+\t/* SSSNIC_CMD_OPCODE_xx */\n+\tuint8_t opcode;\n+\tuint8_t resvd0;\n+\t/* MSIX index */\n+\tuint16_t idx;\n+\tuint8_t pending_count;\n+\tuint8_t coalescing_timer;\n+\tuint8_t resend_timer;\n+\tuint8_t lli_timer;\n+\tuint8_t lli_credit;\n+\tuint8_t resvd1[5];\n+};\n+\n+#endif /* _SSSNIC_CMD_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_ctrlq.c b/drivers/net/sssnic/base/sssnic_ctrlq.c\nnew file mode 100644\nindex 0000000000..75cd25f441\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_ctrlq.c\n@@ -0,0 +1,519 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#include <rte_byteorder.h>\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_malloc.h>\n+#include <rte_mbuf.h>\n+\n+#include \"../sssnic_log.h\"\n+#include \"sssnic_hw.h\"\n+#include \"sssnic_reg.h\"\n+#include \"sssnic_cmd.h\"\n+#include \"sssnic_mbox.h\"\n+#include \"sssnic_ctrlq.h\"\n+\n+#define SSSNIC_CTRLQ_DOORBELL_OFFSET 0\n+#define SSSNIC_CTRLQ_BUF_SIZE 4096\n+#define SSSNIC_CTRLQ_ENTRY_SIZE 64\n+#define SSSNIC_CTRLQ_DEPTH 64\n+\n+#define SSSNIC_CTRLQ_RESP_TIMEOUT 5000 /* Default response timeout */\n+\n+enum sssnic_ctrlq_response_fmt {\n+\t/* return result and write it back into corresponding field of ctrlq entry */\n+\tSSSNIC_CTRLQ_RESPONSE_RESULT,\n+\t/* return data write it into DMA memory that usually is pktmbuf*/\n+\tSSSNIC_CTRLQ_RESPONSE_DATA,\n+};\n+\n+struct sssnic_ctrlq_entry_desc_section {\n+\tunion {\n+\t\tuint32_t dword;\n+\t\tstruct {\n+\t\t\t/* buffer section length, always 2*/\n+\t\t\tuint32_t buf_sec_len : 8;\n+\t\t\tuint32_t resvd0 : 7;\n+\t\t\t/* response fmt, 0:result 1:data */\n+\t\t\tuint32_t resp_fmt : 1;\n+\t\t\tuint32_t resvd1 : 6;\n+\t\t\t/* buffer data format,always 0 */\n+\t\t\tuint32_t buf_fmt : 1;\n+\t\t\t/* always 1 */\n+\t\t\tuint32_t need_resp : 1;\n+\t\t\tuint32_t resvd2 : 3;\n+\t\t\t/* response section length, always 3 */\n+\t\t\tuint32_t resp_sec_len : 2;\n+\t\t\t/* control section length, always 1 */\n+\t\t\tuint32_t ctrl_sec_len : 2;\n+\t\t\t/* wrapped bit */\n+\t\t\tuint32_t wrapped : 1;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_ctrlq_entry_status_section {\n+\tunion {\n+\t\tuint32_t dword;\n+\t\tstruct {\n+\t\t\t/* status value, usually it  saves error code */\n+\t\t\tuint32_t value : 31;\n+\t\t\tuint32_t resvd0 : 1;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_ctrlq_entry_ctrl_section {\n+\tunion {\n+\t\tuint32_t dword;\n+\t\tstruct {\n+\t\t\t/* producer index*/\n+\t\t\tuint32_t pi : 16;\n+\t\t\t/* command ID */\n+\t\t\tuint32_t cmd : 8;\n+\t\t\t/* hardware module */\n+\t\t\tuint32_t module : 5;\n+\t\t\tuint32_t resvd0 : 2;\n+\t\t\t/* Indication of command done */\n+\t\t\tuint32_t done : 1;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_ctrlq_entry_response_section {\n+\tunion {\n+\t\tstruct {\n+\t\t\tuint32_t hi_addr;\n+\t\t\tuint32_t lo_addr;\n+\t\t\tuint32_t len;\n+\t\t\tuint32_t resvd0;\n+\t\t} data;\n+\t\tstruct {\n+\t\t\tuint64_t value;\n+\t\t\tuint64_t resvd0;\n+\t\t} result;\n+\t};\n+};\n+\n+struct sssnic_ctrlq_entry_buf_section {\n+\tstruct {\n+\t\tuint32_t hi_addr;\n+\t\tuint32_t lo_addr;\n+\t\tuint32_t len;\n+\t\tuint32_t resvd0;\n+\t} sge;\n+\tuint64_t resvd0[2];\n+};\n+\n+/* Hardware format of control queue entry */\n+struct sssnic_ctrlq_entry {\n+\tunion {\n+\t\tuint32_t dword[16];\n+\t\tstruct {\n+\t\t\tstruct sssnic_ctrlq_entry_desc_section desc;\n+\t\t\tuint32_t resvd0;\n+\t\t\tstruct sssnic_ctrlq_entry_status_section status;\n+\t\t\tstruct sssnic_ctrlq_entry_ctrl_section ctrl;\n+\t\t\tstruct sssnic_ctrlq_entry_response_section response;\n+\t\t\tstruct sssnic_ctrlq_entry_buf_section buf;\n+\t\t};\n+\t};\n+};\n+\n+/* Hardware format of control queue doorbell */\n+struct sssnic_ctrlq_doorbell {\n+\tunion {\n+\t\tuint64_t u64;\n+\t\tstruct {\n+\t\t\tuint64_t resvd0 : 23;\n+\t\t\t/* ctrlq type is always 1*/\n+\t\t\tuint64_t qtype : 1;\n+\t\t\t/* cltrq id is always 0*/\n+\t\t\tuint64_t qid : 3;\n+\t\t\tuint64_t resvd1 : 5;\n+\t\t\t/* most significant byte of pi*/\n+\t\t\tuint64_t pi_msb : 8;\n+\t\t\tuint64_t resvd2 : 24;\n+\t\t};\n+\t};\n+};\n+static int\n+sssnic_ctrlq_wait_response(struct sssnic_ctrlq *ctrlq, int *err_code,\n+\tuint32_t timeout_ms)\n+{\n+\tstruct sssnic_ctrlq_entry *entry;\n+\tstruct sssnic_workq *workq;\n+\tuint64_t end;\n+\tint done = 0;\n+\n+\tworkq = ctrlq->workq;\n+\tentry = (struct sssnic_ctrlq_entry *)sssnic_workq_peek(workq);\n+\tif (entry == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Not found executing ctrlq command\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (timeout_ms == 0)\n+\t\ttimeout_ms = SSSNIC_CTRLQ_RESP_TIMEOUT;\n+\tend = rte_get_timer_cycles() + rte_get_timer_hz() * timeout_ms / 1000;\n+\tdo {\n+\t\tdone = entry->ctrl.done;\n+\t\tif (done)\n+\t\t\tbreak;\n+\t\trte_delay_us(1);\n+\t} while (((long)(rte_get_timer_cycles() - end)) < 0);\n+\n+\tif (!done) {\n+\t\tPMD_DRV_LOG(ERR, \"Waiting ctrlq response timeout, ci=%u\",\n+\t\t\tworkq->ci);\n+\t\treturn -ETIMEDOUT;\n+\t}\n+\tif (err_code)\n+\t\t*err_code = entry->status.value;\n+\tsssnic_workq_consume(workq, 1, NULL);\n+\treturn 0;\n+}\n+\n+static void\n+sssnic_ctrlq_doorbell_ring(struct sssnic_ctrlq *ctrlq, uint16_t next_pi)\n+{\n+\tstruct sssnic_ctrlq_doorbell db;\n+\n+\tdb.u64 = 0;\n+\tdb.qtype = 1;\n+\tdb.qid = 0;\n+\tdb.pi_msb = (next_pi >> 8) & 0xff;\n+\trte_wmb();\n+\trte_write64(db.u64, ctrlq->doorbell + ((next_pi & 0xff) << 3));\n+}\n+\n+static void\n+sssnic_ctrlq_entry_init(struct sssnic_ctrlq_entry *entry, struct rte_mbuf *mbuf,\n+\tstruct sssnic_ctrlq_cmd *cmd, uint16_t pi, uint16_t wrapped)\n+{\n+\tstruct sssnic_ctrlq_entry tmp_entry;\n+\tvoid *buf_addr;\n+\trte_iova_t buf_iova;\n+\n+\t/* Fill the temporary ctrlq entry */\n+\tmemset(&tmp_entry, 0, sizeof(tmp_entry));\n+\ttmp_entry.desc.buf_fmt = 0;\n+\ttmp_entry.desc.buf_sec_len = 2;\n+\ttmp_entry.desc.need_resp = 1;\n+\ttmp_entry.desc.resp_sec_len = 3;\n+\ttmp_entry.desc.ctrl_sec_len = 1;\n+\ttmp_entry.desc.wrapped = wrapped;\n+\n+\ttmp_entry.status.value = 0;\n+\n+\ttmp_entry.ctrl.cmd = cmd->cmd;\n+\ttmp_entry.ctrl.pi = pi;\n+\ttmp_entry.ctrl.module = cmd->module;\n+\ttmp_entry.ctrl.done = 0;\n+\n+\tbuf_iova = rte_mbuf_data_iova(mbuf);\n+\tif (cmd->mbuf == NULL && cmd->data != NULL) {\n+\t\t/* cmd data is not allocated in mbuf*/\n+\t\tbuf_addr = rte_pktmbuf_mtod(mbuf, void *);\n+\t\trte_memcpy(buf_addr, cmd->data, cmd->data_len);\n+\t}\n+\ttmp_entry.buf.sge.hi_addr = (uint32_t)((buf_iova >> 16) >> 16);\n+\ttmp_entry.buf.sge.lo_addr = (uint32_t)buf_iova;\n+\ttmp_entry.buf.sge.len = cmd->data_len;\n+\n+\tif (cmd->response_len == 0) {\n+\t\ttmp_entry.desc.resp_fmt = SSSNIC_CTRLQ_RESPONSE_RESULT;\n+\t\ttmp_entry.response.result.value = 0;\n+\t} else {\n+\t\ttmp_entry.desc.resp_fmt = SSSNIC_CTRLQ_RESPONSE_DATA;\n+\t\t/* response sge shares cmd mbuf */\n+\t\ttmp_entry.response.data.hi_addr =\n+\t\t\t(uint32_t)((buf_iova >> 16) >> 16);\n+\t\ttmp_entry.response.data.lo_addr = (uint32_t)buf_iova;\n+\t\ttmp_entry.response.data.len = SSSNIC_CTRLQ_MBUF_SIZE;\n+\t}\n+\n+\t/* write temporary entry to real ctrlq entry\n+\t * the first 64bits must be copied last\n+\t */\n+\trte_memcpy(((uint8_t *)entry) + sizeof(uint64_t),\n+\t\t((uint8_t *)&tmp_entry) + sizeof(uint64_t),\n+\t\tSSSNIC_CTRLQ_ENTRY_SIZE - sizeof(sizeof(uint64_t)));\n+\trte_wmb();\n+\t*((uint64_t *)entry) = *((uint64_t *)&tmp_entry);\n+}\n+\n+static int\n+sssnic_ctrlq_cmd_exec_internal(struct sssnic_ctrlq *ctrlq,\n+\tstruct sssnic_ctrlq_cmd *cmd, uint32_t timeout_ms)\n+{\n+\tstruct rte_mbuf *mbuf;\n+\tstruct sssnic_ctrlq_entry *entry;\n+\tstruct sssnic_workq *workq;\n+\tuint16_t pi; /* current pi */\n+\tuint16_t next_pi;\n+\tuint16_t wrapped;\n+\tint ret;\n+\tint err_code;\n+\n+\t/* Allocate cmd mbuf */\n+\tif (cmd->mbuf == NULL) {\n+\t\tmbuf = rte_pktmbuf_alloc(ctrlq->mbuf_pool);\n+\t\tif (mbuf == NULL) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Could not alloc mbuf for ctrlq cmd\");\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t} else {\n+\t\tmbuf = cmd->mbuf;\n+\t}\n+\n+\t/* allocate ctrlq entry */\n+\tworkq = ctrlq->workq;\n+\twrapped = ctrlq->wrapped;\n+\tentry = (struct sssnic_ctrlq_entry *)sssnic_workq_produce(workq, 1,\n+\t\t&pi);\n+\tif (entry == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"No enough control queue entry\");\n+\t\tret = -EBUSY;\n+\t\tgoto out;\n+\t}\n+\t/* workq->pi will be the next pi, the next pi could not exceed workq\n+\t * depth else must recalculate next pi, and reverse wrapped bit.\n+\t */\n+\tif (workq->pi >= workq->num_entries) {\n+\t\tctrlq->wrapped = !ctrlq->wrapped;\n+\t\tworkq->pi -= workq->num_entries;\n+\t}\n+\tnext_pi = workq->pi;\n+\n+\t/* fill ctrlq entry */\n+\tsssnic_ctrlq_entry_init(entry, mbuf, cmd, pi, wrapped);\n+\n+\t/* Ring doorbell */\n+\tsssnic_ctrlq_doorbell_ring(ctrlq, next_pi);\n+\n+\t/* Wait response */\n+\tret = sssnic_ctrlq_wait_response(ctrlq, &err_code, timeout_ms);\n+\tif (ret != 0)\n+\t\tgoto out;\n+\n+\tif (err_code) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Found error while control queue command executing, error code:%x.\",\n+\t\t\terr_code);\n+\t\tret = err_code;\n+\t\tgoto out;\n+\t}\n+\n+\tif (cmd->response_len == 0) {\n+\t\tcmd->result = entry->response.result.value;\n+\t} else if ((cmd->mbuf != NULL && cmd->response_data != cmd->data) ||\n+\t\t   cmd->mbuf == NULL) {\n+\t\t/* cmd data may be as same as response data if mbuf is not null */\n+\t\trte_memcpy(cmd->response_data, rte_pktmbuf_mtod(mbuf, void *),\n+\t\t\tcmd->response_len);\n+\t}\n+out:\n+\tif (cmd->mbuf == NULL)\n+\t\trte_pktmbuf_free(mbuf);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ctrlq_cmd_exec(struct sssnic_hw *hw, struct sssnic_ctrlq_cmd *cmd,\n+\tuint32_t timeout_ms)\n+{\n+\tint ret;\n+\tstruct sssnic_ctrlq *ctrlq;\n+\n+\tif (hw == NULL || hw->ctrlq == NULL || cmd == NULL ||\n+\t\t(cmd->response_len != 0 && cmd->response_data == NULL)) {\n+\t\tPMD_DRV_LOG(ERR, \"Bad parameter to execute ctrlq command\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tSSSNIC_DEBUG(\"module=%u, cmd=%u, data=%p, data_len=%u, response_len=%u\",\n+\t\tcmd->module, cmd->cmd, cmd->data, cmd->data_len,\n+\t\tcmd->response_len);\n+\n+\tctrlq = hw->ctrlq;\n+\trte_spinlock_lock(&ctrlq->lock);\n+\tret = sssnic_ctrlq_cmd_exec_internal(ctrlq, cmd, timeout_ms);\n+\trte_spinlock_unlock(&ctrlq->lock);\n+\n+\treturn ret;\n+}\n+\n+static int\n+sssnic_ctrlq_depth_set(struct sssnic_hw *hw, uint32_t depth)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_root_ctx_cmd cmd;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.set_ctrlq_depth = 1;\n+\tcmd.ctrlq_depth = (uint8_t)rte_log2_u32(depth);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_SET_ROOT_CTX_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tif (!cmd_len || cmd.common.status) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SET_ROOT_CTX_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_ctrlq_ctx_setup(struct sssnic_ctrlq *ctrlq)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_set_ctrlq_ctx_cmd cmd;\n+\tuint32_t cmd_len;\n+\tstruct sssnic_hw *hw = ctrlq->hw;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.qid = 0;\n+\tcmd.pfn = ctrlq->workq->buf_phyaddr / RTE_PGSIZE_4K;\n+\tcmd.wrapped = !!ctrlq->wrapped;\n+\tcmd.start_ci = 0;\n+\tcmd.block_pfn = cmd.pfn;\n+\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_SET_CTRLQ_CTX_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send SSSNIC_SET_CTRLQ_CTX_CMD\");\n+\t\treturn ret;\n+\t}\n+\treturn 0;\n+}\n+\n+struct sssnic_ctrlq_cmd *\n+sssnic_ctrlq_cmd_alloc(struct sssnic_hw *hw)\n+{\n+\tstruct sssnic_ctrlq_cmd *cmd;\n+\n+\tcmd = rte_zmalloc(NULL, sizeof(struct sssnic_ctrlq_cmd), 0);\n+\tif (cmd == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate sssnic_ctrlq_cmd\");\n+\t\treturn NULL;\n+\t}\n+\n+\tcmd->mbuf = rte_pktmbuf_alloc(hw->ctrlq->mbuf_pool);\n+\tif (cmd->mbuf == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate sssnic_ctrlq_cmd mbuf\");\n+\t\trte_free(cmd);\n+\t\treturn NULL;\n+\t}\n+\n+\tcmd->data = rte_pktmbuf_mtod(cmd->mbuf, void *);\n+\tcmd->response_data = cmd->data;\n+\n+\treturn cmd;\n+}\n+\n+void\n+sssnic_ctrlq_cmd_destroy(__rte_unused struct sssnic_hw *hw,\n+\tstruct sssnic_ctrlq_cmd *cmd)\n+{\n+\tif (cmd != NULL) {\n+\t\tif (cmd->mbuf != NULL)\n+\t\t\trte_pktmbuf_free(cmd->mbuf);\n+\n+\t\trte_free(cmd);\n+\t}\n+}\n+\n+int\n+sssnic_ctrlq_init(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_ctrlq *ctrlq;\n+\tchar m_name[RTE_MEMPOOL_NAMESIZE];\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tctrlq = rte_zmalloc(NULL, sizeof(struct sssnic_ctrlq), 0);\n+\tif (ctrlq == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memory for ctrlq\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tctrlq->hw = hw;\n+\trte_spinlock_init(&ctrlq->lock);\n+\tctrlq->doorbell = hw->db_base_addr + SSSNIC_CTRLQ_DOORBELL_OFFSET;\n+\n+\tsnprintf(m_name, sizeof(m_name), \"sssnic%u_ctrlq_wq\",\n+\t\tSSSNIC_ETH_PORT_ID(hw));\n+\tctrlq->workq = sssnic_workq_new(m_name, rte_socket_id(),\n+\t\tSSSNIC_CTRLQ_ENTRY_SIZE, SSSNIC_CTRLQ_DEPTH);\n+\tif (ctrlq->workq == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc work queue for ctrlq\");\n+\t\tret = -ENOMEM;\n+\t\tgoto new_workq_fail;\n+\t}\n+\tctrlq->wrapped = 1;\n+\n+\tsnprintf(m_name, sizeof(m_name), \"sssnic%u_ctrlq_mbuf\",\n+\t\tSSSNIC_ETH_PORT_ID(hw));\n+\tctrlq->mbuf_pool = rte_pktmbuf_pool_create(m_name, SSSNIC_CTRLQ_DEPTH,\n+\t\t0, 0, SSSNIC_CTRLQ_MBUF_SIZE, rte_socket_id());\n+\tif (ctrlq->mbuf_pool == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc mbuf for %s\", m_name);\n+\t\tret = -ENOMEM;\n+\t\tgoto alloc_mbuf_fail;\n+\t}\n+\n+\tret = sssnic_ctrlq_ctx_setup(ctrlq);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup control queue context\");\n+\t\tgoto setup_ctrlq_ctx_fail;\n+\t}\n+\n+\tret = sssnic_ctrlq_depth_set(hw, SSSNIC_CTRLQ_DEPTH);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize control queue depth\");\n+\t\tgoto setup_ctrlq_ctx_fail;\n+\t}\n+\n+\thw->ctrlq = ctrlq;\n+\n+\treturn 0;\n+\n+setup_ctrlq_ctx_fail:\n+\trte_mempool_free(ctrlq->mbuf_pool);\n+alloc_mbuf_fail:\n+\tsssnic_workq_destroy(ctrlq->workq);\n+new_workq_fail:\n+\trte_free(ctrlq);\n+\treturn ret;\n+}\n+\n+void\n+sssnic_ctrlq_shutdown(struct sssnic_hw *hw)\n+{\n+\tstruct sssnic_ctrlq *ctrlq;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tif (hw == NULL || hw->ctrlq == NULL)\n+\t\treturn;\n+\tctrlq = hw->ctrlq;\n+\trte_mempool_free(ctrlq->mbuf_pool);\n+\tsssnic_workq_destroy(ctrlq->workq);\n+\trte_free(ctrlq);\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_ctrlq.h b/drivers/net/sssnic/base/sssnic_ctrlq.h\nnew file mode 100644\nindex 0000000000..61b182e9f4\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_ctrlq.h\n@@ -0,0 +1,58 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_CTRLQ_H_\n+#define _SSSNIC_CTRLQ_H_\n+\n+#include \"sssnic_workq.h\"\n+\n+#define SSSNIC_CTRLQ_MBUF_SIZE 2048\n+#define SSSNIC_CTRLQ_MAX_CMD_DATA_LEN                                          \\\n+\t(SSSNIC_CTRLQ_MBUF_SIZE - RTE_PKTMBUF_HEADROOM)\n+\n+struct sssnic_ctrlq_cmd {\n+\tuint32_t module;\n+\t/* Command ID */\n+\tuint32_t cmd;\n+\t/* Command data */\n+\tvoid *data;\n+\t/* mbuf is just used for dynamic allocation of ctrlq cmd,\n+\t * cmd data will point to mbuf data to reduce data copying\n+\t * as well as response_data.\n+\t */\n+\tstruct rte_mbuf *mbuf;\n+\tunion {\n+\t\t/* response data buffer */\n+\t\tvoid *response_data;\n+\t\t/* result of command executing */\n+\t\tuint64_t result;\n+\t};\n+\t/* command data length */\n+\tuint32_t data_len;\n+\t/* length of response data buffer, return result of command\n+\t * if response_len=0, else return response_data\n+\t */\n+\tuint32_t response_len;\n+};\n+\n+struct sssnic_ctrlq {\n+\tstruct sssnic_hw *hw;\n+\tstruct sssnic_workq *workq;\n+\tstruct rte_mempool *mbuf_pool;\n+\tuint8_t *doorbell;\n+\tuint32_t wrapped;\n+\tuint32_t resvd0;\n+\trte_spinlock_t lock;\n+};\n+\n+struct sssnic_ctrlq_cmd *sssnic_ctrlq_cmd_alloc(struct sssnic_hw *hw);\n+void sssnic_ctrlq_cmd_destroy(__rte_unused struct sssnic_hw *hw,\n+\tstruct sssnic_ctrlq_cmd *cmd);\n+\n+int sssnic_ctrlq_cmd_exec(struct sssnic_hw *hw, struct sssnic_ctrlq_cmd *cmd,\n+\tuint32_t timeout_ms);\n+int sssnic_ctrlq_init(struct sssnic_hw *hw);\n+void sssnic_ctrlq_shutdown(struct sssnic_hw *hw);\n+\n+#endif /* _SSSNIC_CTRLQ_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_hw.c b/drivers/net/sssnic/base/sssnic_hw.c\nindex ff527b2c7f..4ca75208af 100644\n--- a/drivers/net/sssnic/base/sssnic_hw.c\n+++ b/drivers/net/sssnic/base/sssnic_hw.c\n@@ -9,9 +9,12 @@\n #include \"../sssnic_log.h\"\n #include \"sssnic_hw.h\"\n #include \"sssnic_reg.h\"\n+#include \"sssnic_cmd.h\"\n+#include \"sssnic_api.h\"\n #include \"sssnic_eventq.h\"\n #include \"sssnic_msg.h\"\n #include \"sssnic_mbox.h\"\n+#include \"sssnic_ctrlq.h\"\n \n static int\n wait_for_sssnic_hw_ready(struct sssnic_hw *hw)\n@@ -140,6 +143,116 @@ sssnic_pf_status_set(struct sssnic_hw *hw, enum sssnic_pf_status status)\n \tsssnic_cfg_reg_write(hw, SSSNIC_ATTR6_REG, reg.u32);\n }\n \n+static int\n+sssnic_dma_attr_init(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_dma_attr_set_cmd cmd;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_SET_DMA_ATTR_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SET_DMA_ATTR_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_func_reset(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_func_reset_cmd cmd;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.res_mask = RTE_BIT64(0) | RTE_BIT64(1) | RTE_BIT64(2) |\n+\t\t       RTE_BIT64(10) | RTE_BIT64(12) | RTE_BIT64(13);\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_RESET_FUNC_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to RESET_FUNC_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_pagesize_set(struct sssnic_hw *hw, uint32_t pagesize)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_pagesize_cmd cmd;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.pagesz = (uint8_t)rte_log2_u32(pagesize >> 12);\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_PAGESIZE_CFG_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to PAGESIZE_CFG_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* Only initialize msix 0 attributes */\n+static int\n+sssnic_msix_attr_init(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_msix_attr attr;\n+\n+\tattr.lli_set = 0;\n+\tattr.coalescing_set = 1;\n+\tattr.pending_limit = 0;\n+\tattr.coalescing_timer = 0xff;\n+\tattr.resend_timer = 0x7;\n+\n+\tret = sssnic_msix_attr_set(hw, 0, &attr);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set msix0 attributes.\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n sssnic_base_init(struct sssnic_hw *hw)\n {\n@@ -217,8 +330,42 @@ sssnic_hw_init(struct sssnic_hw *hw)\n \t\tgoto mbox_init_fail;\n \t}\n \n+\tret = sssnic_func_reset(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to reset function resources\");\n+\t\tgoto mbox_init_fail;\n+\t}\n+\n+\tret = sssnic_dma_attr_init(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize DMA attributes\");\n+\t\tgoto mbox_init_fail;\n+\t}\n+\n+\tret = sssnic_msix_attr_init(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize msix attributes\");\n+\t\tgoto mbox_init_fail;\n+\t}\n+\n+\tret = sssnic_pagesize_set(hw, 0x100000);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set page size to 0x100000\");\n+\t\tgoto mbox_init_fail;\n+\t}\n+\n+\tret = sssnic_ctrlq_init(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize control queue\");\n+\t\tgoto ctrlq_init_fail;\n+\t}\n+\n+\tsssnic_pf_status_set(hw, SSSNIC_PF_STATUS_ACTIVE);\n+\n \treturn -EINVAL;\n \n+ctrlq_init_fail:\n+\tsssnic_mbox_shutdown(hw);\n mbox_init_fail:\n \tsssnic_eventq_all_shutdown(hw);\n eventq_init_fail:\n@@ -231,6 +378,8 @@ sssnic_hw_shutdown(struct sssnic_hw *hw)\n {\n \tPMD_INIT_FUNC_TRACE();\n \n+\tsssnic_pf_status_set(hw, SSSNIC_PF_STATUS_INIT);\n+\tsssnic_ctrlq_shutdown(hw);\n \tsssnic_mbox_shutdown(hw);\n \tsssnic_eventq_all_shutdown(hw);\n \tsssnic_msg_inbox_shutdown(hw);\ndiff --git a/drivers/net/sssnic/base/sssnic_hw.h b/drivers/net/sssnic/base/sssnic_hw.h\nindex 41e65f5880..c1b9539015 100644\n--- a/drivers/net/sssnic/base/sssnic_hw.h\n+++ b/drivers/net/sssnic/base/sssnic_hw.h\n@@ -54,6 +54,7 @@ struct sssnic_hw {\n \tstruct sssnic_eventq *eventqs;\n \tstruct sssnic_msg_inbox *msg_inbox;\n \tstruct sssnic_mbox *mbox;\n+\tstruct sssnic_ctrlq *ctrlq;\n \tuint8_t num_eventqs;\n \tuint16_t eth_port_id;\n };\n@@ -64,6 +65,13 @@ struct sssnic_hw {\n #define SSSNIC_FUNC_TYPE(hw) ((hw)->attr.func_type)\n #define SSSNIC_AF_FUNC_IDX(hw) ((hw)->attr.af_idx)\n \n+enum sssnic_module {\n+\tSSSNIC_COMM_MODULE = 0,\n+\tSSSNIC_LAN_MODULE = 1,\n+\tSSSNIC_CFG_MODULE = 7,\n+\tSSSNIC_NETIF_MODULE = 14,\n+};\n+\n int sssnic_hw_init(struct sssnic_hw *hw);\n void sssnic_hw_shutdown(struct sssnic_hw *hw);\n void sssnic_msix_state_set(struct sssnic_hw *hw, uint16_t msix_id, int state);\n",
    "prefixes": [
        "09/32"
    ]
}