get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 105249,
    "url": "http://patches.dpdk.org/api/patches/105249/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/73fd0a0bc343762104bd3b8279838ef8e0ee1726.1639636621.git.songyl@ramaxel.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": "<73fd0a0bc343762104bd3b8279838ef8e0ee1726.1639636621.git.songyl@ramaxel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/73fd0a0bc343762104bd3b8279838ef8e0ee1726.1639636621.git.songyl@ramaxel.com",
    "date": "2021-12-18T02:51:38",
    "name": "[v1,11/25] net/spnic: add queue pairs context initialization",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "99f3e187a5658a85b3dee9c7a6721a42f252ddb4",
    "submitter": {
        "id": 2455,
        "url": "http://patches.dpdk.org/api/people/2455/?format=api",
        "name": "Yanling Song",
        "email": "songyl@ramaxel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/73fd0a0bc343762104bd3b8279838ef8e0ee1726.1639636621.git.songyl@ramaxel.com/mbox/",
    "series": [
        {
            "id": 20973,
            "url": "http://patches.dpdk.org/api/series/20973/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=20973",
            "date": "2021-12-18T02:51:28",
            "name": "Net/SPNIC: support SPNIC into DPDK 22.03",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/20973/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/105249/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/105249/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 09926A04A4;\n\tSat, 18 Dec 2021 03:53:38 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id CF64841182;\n\tSat, 18 Dec 2021 03:52:35 +0100 (CET)",
            "from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id CA9F6411C9\n for <dev@dpdk.org>; Sat, 18 Dec 2021 03:52:33 +0100 (CET)",
            "from V12DG1MBS01.ramaxel.local (v12dg1mbs01.ramaxel.local\n [172.26.18.31])\n by VLXDG1SPAM1.ramaxel.com with ESMTPS id 1BI2q0mJ010341\n (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);\n Sat, 18 Dec 2021 10:52:00 +0800 (GMT-8)\n (envelope-from songyl@ramaxel.com)",
            "from localhost.localdomain (10.64.9.47) by V12DG1MBS01.ramaxel.local\n (172.26.18.31) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Sat, 18\n Dec 2021 10:52:00 +0800"
        ],
        "From": "Yanling Song <songyl@ramaxel.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<songyl@ramaxel.com>, <yanling.song@linux.dev>, <yanggan@ramaxel.com>,\n <ferruh.yigit@intel.com>",
        "Subject": "[PATCH v1 11/25] net/spnic: add queue pairs context initialization",
        "Date": "Sat, 18 Dec 2021 10:51:38 +0800",
        "Message-ID": "\n <73fd0a0bc343762104bd3b8279838ef8e0ee1726.1639636621.git.songyl@ramaxel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<cover.1639636621.git.songyl@ramaxel.com>",
        "References": "<cover.1639636621.git.songyl@ramaxel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.9.47]",
        "X-ClientProxiedBy": "V12DG1MBS01.ramaxel.local (172.26.18.31) To\n V12DG1MBS01.ramaxel.local (172.26.18.31)",
        "X-DNSRBL": "",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 1BI2q0mJ010341",
        "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": "This patch adds the initialization of Tx/Rx queues\ncontext and negotiation of NIC features.\n\nSigned-off-by: Yanling Song <songyl@ramaxel.com>\n---\n drivers/net/spnic/base/spnic_hw_comm.c | 101 ++++\n drivers/net/spnic/base/spnic_hw_comm.h |   6 +\n drivers/net/spnic/base/spnic_nic_cfg.c |  76 +++\n drivers/net/spnic/base/spnic_nic_cfg.h |  65 ++-\n drivers/net/spnic/meson.build          |   3 +-\n drivers/net/spnic/spnic_ethdev.c       |  57 +-\n drivers/net/spnic/spnic_io.c           | 738 +++++++++++++++++++++++++\n drivers/net/spnic/spnic_io.h           | 154 ++++++\n drivers/net/spnic/spnic_rx.h           | 113 ++++\n drivers/net/spnic/spnic_tx.h           |  62 +++\n 10 files changed, 1370 insertions(+), 5 deletions(-)\n create mode 100644 drivers/net/spnic/spnic_io.c\n create mode 100644 drivers/net/spnic/spnic_io.h\n create mode 100644 drivers/net/spnic/spnic_rx.h\n create mode 100644 drivers/net/spnic/spnic_tx.h",
    "diff": "diff --git a/drivers/net/spnic/base/spnic_hw_comm.c b/drivers/net/spnic/base/spnic_hw_comm.c\nindex 5cb607cf03..1c751f2403 100644\n--- a/drivers/net/spnic/base/spnic_hw_comm.c\n+++ b/drivers/net/spnic/base/spnic_hw_comm.c\n@@ -217,6 +217,107 @@ int spnic_func_reset(void *hwdev, u64 reset_flag)\n \treturn 0;\n }\n \n+int spnic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz)\n+{\n+\tu32 i, num_hw_types, best_match_sz;\n+\n+\tif (unlikely(!match_sz || rx_buf_sz < SPNIC_RX_BUF_SIZE_32B))\n+\t\treturn -EINVAL;\n+\n+\tif (rx_buf_sz >= SPNIC_RX_BUF_SIZE_16K) {\n+\t\tbest_match_sz =  SPNIC_RX_BUF_SIZE_16K;\n+\t\tgoto size_matched;\n+\t}\n+\n+\tnum_hw_types = sizeof(spnic_hw_rx_buf_size) /\n+\t\tsizeof(spnic_hw_rx_buf_size[0]);\n+\tbest_match_sz = spnic_hw_rx_buf_size[0];\n+\tfor (i = 0; i < num_hw_types; i++) {\n+\t\tif (rx_buf_sz == spnic_hw_rx_buf_size[i]) {\n+\t\t\tbest_match_sz = spnic_hw_rx_buf_size[i];\n+\t\t\tbreak;\n+\t\t} else if (rx_buf_sz < spnic_hw_rx_buf_size[i]) {\n+\t\t\tbreak;\n+\t\t}\n+\t\tbest_match_sz = spnic_hw_rx_buf_size[i];\n+\t}\n+\n+size_matched:\n+\t*match_sz = best_match_sz;\n+\n+\treturn 0;\n+}\n+\n+static u16 get_hw_rx_buf_size(u32 rx_buf_sz)\n+{\n+\tu16 num_hw_types = sizeof(spnic_hw_rx_buf_size) /\n+\t\t\t   sizeof(spnic_hw_rx_buf_size[0]);\n+\tu16 i;\n+\n+\tfor (i = 0; i < num_hw_types; i++) {\n+\t\tif (spnic_hw_rx_buf_size[i] == rx_buf_sz)\n+\t\t\treturn i;\n+\t}\n+\n+\tPMD_DRV_LOG(WARNING, \"Chip can't support rx buf size of %d\", rx_buf_sz);\n+\n+\treturn DEFAULT_RX_BUF_SIZE; /* Default 2K */\n+}\n+\n+int spnic_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz)\n+{\n+\tstruct spnic_cmd_root_ctxt root_ctxt;\n+\tu16 out_size = sizeof(root_ctxt);\n+\tint err;\n+\n+\tif (!hwdev)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&root_ctxt, 0, sizeof(root_ctxt));\n+\troot_ctxt.func_idx = spnic_global_func_id(hwdev);\n+\troot_ctxt.set_cmdq_depth = 0;\n+\troot_ctxt.cmdq_depth = 0;\n+\troot_ctxt.lro_en = 1;\n+\troot_ctxt.rq_depth  = (u16)ilog2(rq_depth);\n+\troot_ctxt.rx_buf_sz = get_hw_rx_buf_size(rx_buf_sz);\n+\troot_ctxt.sq_depth  = (u16)ilog2(sq_depth);\n+\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM, MGMT_CMD_SET_VAT,\n+\t\t\t\t     &root_ctxt, sizeof(root_ctxt),\n+\t\t\t\t     &root_ctxt, &out_size, 0);\n+\tif (err || !out_size || root_ctxt.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Set root context failed, err: %d, status: 0x%x, out_size: 0x%x\",\n+\t\t\t    err, root_ctxt.status, out_size);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int spnic_clean_root_ctxt(void *hwdev)\n+{\n+\tstruct spnic_cmd_root_ctxt root_ctxt;\n+\tu16 out_size = sizeof(root_ctxt);\n+\tint err;\n+\n+\tif (!hwdev)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&root_ctxt, 0, sizeof(root_ctxt));\n+\troot_ctxt.func_idx = spnic_global_func_id(hwdev);\n+\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM, MGMT_CMD_SET_VAT,\n+\t\t\t\t     &root_ctxt, sizeof(root_ctxt),\n+\t\t\t\t     &root_ctxt, &out_size, 0);\n+\tif (err || !out_size || root_ctxt.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Clean root context failed, err: %d, status: 0x%x, out_size: 0x%x\",\n+\t\t\t    err, root_ctxt.status, out_size);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth)\n {\n \tstruct spnic_cmd_root_ctxt root_ctxt;\ndiff --git a/drivers/net/spnic/base/spnic_hw_comm.h b/drivers/net/spnic/base/spnic_hw_comm.h\nindex 207f0aaeae..f960fbb53f 100644\n--- a/drivers/net/spnic/base/spnic_hw_comm.h\n+++ b/drivers/net/spnic/base/spnic_hw_comm.h\n@@ -180,6 +180,10 @@ int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len);\n \n int spnic_get_board_info(void *hwdev, struct spnic_board_info *info);\n \n+int spnic_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz);\n+\n+int spnic_clean_root_ctxt(void *hwdev);\n+\n int spnic_get_interrupt_cfg(void *dev, struct interrupt_info *info);\n \n int spnic_set_interrupt_cfg(void *dev, struct interrupt_info info);\n@@ -188,6 +192,8 @@ int spnic_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size);\n \n int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth);\n \n+int spnic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz);\n+\n int spnic_get_comm_features(void *hwdev, u64 *s_feature, u16 size);\n \n int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size);\ndiff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c\nindex 886aaea384..25d98d67dd 100644\n--- a/drivers/net/spnic/base/spnic_nic_cfg.c\n+++ b/drivers/net/spnic/base/spnic_nic_cfg.c\n@@ -75,6 +75,42 @@ int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,\n \t\t\t\t      in_size, buf_out, out_size, 0);\n }\n \n+int spnic_set_ci_table(void *hwdev, struct spnic_sq_attr *attr)\n+{\n+\tstruct spnic_cmd_cons_idx_attr cons_idx_attr;\n+\tu16 out_size = sizeof(cons_idx_attr);\n+\tint err;\n+\n+\tif (!hwdev || !attr)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&cons_idx_attr, 0, sizeof(cons_idx_attr));\n+\tcons_idx_attr.func_idx = spnic_global_func_id(hwdev);\n+\tcons_idx_attr.dma_attr_off  = attr->dma_attr_off;\n+\tcons_idx_attr.pending_limit = attr->pending_limit;\n+\tcons_idx_attr.coalescing_time  = attr->coalescing_time;\n+\n+\tif (attr->intr_en) {\n+\t\tcons_idx_attr.intr_en = attr->intr_en;\n+\t\tcons_idx_attr.intr_idx = attr->intr_idx;\n+\t}\n+\n+\tcons_idx_attr.l2nic_sqn = attr->l2nic_sqn;\n+\tcons_idx_attr.ci_addr = attr->ci_dma_base;\n+\n+\terr = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_SQ_CI_ATTR_SET,\n+\t\t\t\t     &cons_idx_attr, sizeof(cons_idx_attr),\n+\t\t\t\t     &cons_idx_attr, &out_size);\n+\tif (err || !out_size || cons_idx_attr.msg_head.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Set ci attribute table failed, err: %d, \"\n+\t\t\t    \"status: 0x%x, out_size: 0x%x\",\n+\t\t\t    err, cons_idx_attr.msg_head.status, out_size);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int spnic_check_mac_info(u8 status, u16 vlan_id)\n {\n \tif ((status && status != SPNIC_MGMT_STATUS_EXIST &&\n@@ -406,6 +442,46 @@ int spnic_set_port_mtu(void *hwdev, u16 new_mtu)\n \t\t\t\t\t&func_tbl_cfg);\n }\n \n+static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)\n+{\n+\tstruct spnic_cmd_feature_nego feature_nego;\n+\tu16 out_size = sizeof(feature_nego);\n+\tint err;\n+\n+\tif (!hwdev || !s_feature || size > MAX_FEATURE_QWORD)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&feature_nego, 0, sizeof(feature_nego));\n+\tfeature_nego.func_id = spnic_global_func_id(hwdev);\n+\tfeature_nego.opcode = opcode;\n+\tif (opcode == SPNIC_CMD_OP_SET)\n+\t\tmemcpy(feature_nego.s_feature, s_feature, size * sizeof(u64));\n+\n+\terr = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_FEATURE_NEGO,\n+\t\t\t\t     &feature_nego, sizeof(feature_nego),\n+\t\t\t\t     &feature_nego, &out_size);\n+\tif (err || !out_size || feature_nego.msg_head.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to negotiate nic feature, err:%d, status: 0x%x, out_size: 0x%x\\n\",\n+\t\t\t    err, feature_nego.msg_head.status, out_size);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (opcode == SPNIC_CMD_OP_GET)\n+\t\tmemcpy(s_feature, feature_nego.s_feature, size * sizeof(u64));\n+\n+\treturn 0;\n+}\n+\n+int spnic_get_feature_from_hw(void *hwdev, u64 *s_feature, u16 size)\n+{\n+\treturn nic_feature_nego(hwdev, SPNIC_CMD_OP_GET, s_feature, size);\n+}\n+\n+int spnic_set_feature_to_hw(void *hwdev, u64 *s_feature, u16 size)\n+{\n+\treturn nic_feature_nego(hwdev, SPNIC_CMD_OP_SET, s_feature, size);\n+}\n+\n static int spnic_vf_func_init(void *hwdev)\n {\n \tstruct spnic_cmd_register_vf register_info;\ndiff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h\nindex 98cad645d2..ce9792f8ee 100644\n--- a/drivers/net/spnic/base/spnic_nic_cfg.h\n+++ b/drivers/net/spnic/base/spnic_nic_cfg.h\n@@ -36,6 +36,15 @@\n #define SPNIC_MGMT_STATUS_EXIST\t\t0x6\n #define CHECK_IPSU_15BIT\t\t0x8000\n \n+struct spnic_cmd_feature_nego {\n+\tstruct mgmt_msg_head msg_head;\n+\n+\tu16 func_id;\n+\tu8 opcode;\t/* 1: set, 0: get */\n+\tu8 rsvd;\n+\tu64 s_feature[MAX_FEATURE_QWORD];\n+};\n+\n /* Structures for port info */\n struct nic_port_info {\n \tu8 port_type;\n@@ -69,6 +78,30 @@ enum nic_speed_level {\n \tLINK_SPEED_LEVELS,\n };\n \n+struct spnic_sq_attr {\n+\tu8 dma_attr_off;\n+\tu8 pending_limit;\n+\tu8 coalescing_time;\n+\tu8 intr_en;\n+\tu16 intr_idx;\n+\tu32 l2nic_sqn;\n+\tu64 ci_dma_base;\n+};\n+\n+struct spnic_cmd_cons_idx_attr {\n+\tstruct mgmt_msg_head msg_head;\n+\n+\tu16 func_idx;\n+\tu8 dma_attr_off;\n+\tu8 pending_limit;\n+\tu8 coalescing_time;\n+\tu8 intr_en;\n+\tu16 intr_idx;\n+\tu32 l2nic_sqn;\n+\tu32 rsvd;\n+\tu64 ci_addr;\n+};\n+\n struct spnic_port_mac_set {\n \tstruct mgmt_msg_head msg_head;\n \n@@ -88,7 +121,6 @@ struct spnic_port_mac_update {\n \tu16 rsvd2;\n \tu8 new_mac[ETH_ALEN];\n };\n-\n struct spnic_cmd_port_info {\n \tstruct mgmt_msg_head msg_head;\n \n@@ -193,6 +225,9 @@ struct spnic_cmd_set_func_tbl {\n \tstruct spnic_func_tbl_cfg tbl_cfg;\n };\n \n+#define SPNIC_CMD_OP_GET\t0\n+#define SPNIC_CMD_OP_SET\t1\n+\n enum {\n \tSPNIC_IFLA_VF_LINK_STATE_AUTO,\t/* Link state of the uplink */\n \tSPNIC_IFLA_VF_LINK_STATE_ENABLE, /* Link always up */\n@@ -223,6 +258,8 @@ struct spnic_cmd_register_vf {\n int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,\n \t\t\t   void *buf_out, u16 *out_size);\n \n+int spnic_set_ci_table(void *hwdev, struct spnic_sq_attr *attr);\n+\n /**\n  * Update MAC address to hardware\n  *\n@@ -390,4 +427,30 @@ int spnic_init_function_table(void *hwdev, u16 rx_buff_len);\n  * @retval non-zero : Failure\n  */\n int spnic_vf_get_default_cos(void *hwdev, u8 *cos_id);\n+\n+/**\n+ * Get service feature HW supported\n+ *\n+ * @param[in] dev\n+ *   Device pointer to hwdev\n+ * @param[in] size\n+ *   s_feature's array size\n+ * @param[out] s_feature\n+ *   s_feature HW supported\n+ * @retval zero: Success\n+ * @retval non-zero: Failure\n+ */\n+int spnic_get_feature_from_hw(void *hwdev, u64 *s_feature, u16 size);\n+\n+/**\n+ * Set service feature driver supported to hardware\n+ *\n+ * @param[in] dev\n+ *   Device pointer to hwdev\n+ *\n+ * @retval zero: Success\n+ * @retval non-zero: Failure\n+ */\n+int spnic_set_feature_to_hw(void *hwdev, u64 *s_feature, u16 size);\n+\n #endif /* _SPNIC_NIC_CFG_H_ */\ndiff --git a/drivers/net/spnic/meson.build b/drivers/net/spnic/meson.build\nindex 042d2fe6e1..20d5151a8d 100644\n--- a/drivers/net/spnic/meson.build\n+++ b/drivers/net/spnic/meson.build\n@@ -6,6 +6,7 @@ objs = [base_objs]\n \n sources = files(\n \t'spnic_ethdev.c',\n-\t)\n+\t'spnic_io.c',\n+)\n \n includes += include_directories('base')\ndiff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c\nindex 7f73e70df1..4205ab43a4 100644\n--- a/drivers/net/spnic/spnic_ethdev.c\n+++ b/drivers/net/spnic/spnic_ethdev.c\n@@ -22,14 +22,25 @@\n #include \"base/spnic_hw_comm.h\"\n #include \"base/spnic_nic_cfg.h\"\n #include \"base/spnic_nic_event.h\"\n+#include \"spnic_io.h\"\n+#include \"spnic_tx.h\"\n+#include \"spnic_rx.h\"\n #include \"spnic_ethdev.h\"\n \n /* Driver-specific log messages type */\n int spnic_logtype;\n \n+#define SPNIC_DEFAULT_RX_FREE_THRESH\t32\n+#define SPNIC_DEFAULT_TX_FREE_THRESH\t32\n+\n #define SPNIC_MAX_UC_MAC_ADDRS\t\t128\n #define SPNIC_MAX_MC_MAC_ADDRS\t\t128\n \n+#define SPNIC_MAX_QUEUE_DEPTH\t\t16384\n+#define SPNIC_MIN_QUEUE_DEPTH\t\t128\n+#define SPNIC_TXD_ALIGN\t\t\t1\n+#define SPNIC_RXD_ALIGN\t\t\t1\n+\n /**\n  * Deinit mac_vlan table in hardware.\n  *\n@@ -219,6 +230,7 @@ static void spnic_deinit_sw_rxtxqs(struct spnic_nic_dev *nic_dev)\n static int spnic_dev_start(struct rte_eth_dev *eth_dev)\n {\n \tstruct spnic_nic_dev *nic_dev;\n+\tu64 nic_features;\n \tint err;\n \n \tnic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n@@ -230,6 +242,26 @@ static int spnic_dev_start(struct rte_eth_dev *eth_dev)\n \t\tgoto init_func_tbl_fail;\n \t}\n \n+\tnic_features = spnic_get_driver_feature(nic_dev->hwdev);\n+\tnic_features &= DEFAULT_DRV_FEATURE;\n+\tspnic_update_driver_feature(nic_dev->hwdev, nic_features);\n+\n+\terr = spnic_set_feature_to_hw(nic_dev->hwdev, &nic_dev->feature_cap, 1);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set nic features to hardware, err %d\\n\",\n+\t\t\t    err);\n+\t\tgoto get_feature_err;\n+\t}\n+\n+\n+\t/* Init txq and rxq context */\n+\terr = spnic_init_qp_ctxts(nic_dev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Init qp context failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_qp_fail;\n+\t}\n+\n \t/* Set default mtu */\n \terr = spnic_set_port_mtu(nic_dev->hwdev, nic_dev->mtu_size);\n \tif (err) {\n@@ -238,7 +270,6 @@ static int spnic_dev_start(struct rte_eth_dev *eth_dev)\n \t\tgoto set_mtu_fail;\n \t}\n \n-\n \t/* Update eth_dev link status */\n \tif (eth_dev->data->dev_conf.intr_conf.lsc != 0)\n \t\t(void)spnic_link_update(eth_dev, 0);\n@@ -248,6 +279,10 @@ static int spnic_dev_start(struct rte_eth_dev *eth_dev)\n \treturn 0;\n \n set_mtu_fail:\n+\tspnic_free_qp_ctxts(nic_dev->hwdev);\n+\n+init_qp_fail:\n+get_feature_err:\n init_func_tbl_fail:\n \n \treturn err;\n@@ -278,6 +313,9 @@ static int spnic_dev_stop(struct rte_eth_dev *dev)\n \tmemset(&link, 0, sizeof(link));\n \t(void)rte_eth_linkstatus_set(dev, &link);\n \n+\t/* Clean root context */\n+\tspnic_free_qp_ctxts(nic_dev->hwdev);\n+\n \treturn 0;\n }\n \n@@ -290,7 +328,7 @@ static int spnic_dev_stop(struct rte_eth_dev *dev)\n static int spnic_dev_close(struct rte_eth_dev *eth_dev)\n {\n \tstruct spnic_nic_dev *nic_dev =\n-\t\tSPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n+\tSPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);\n \n \tif (rte_bit_relaxed_test_and_set32(SPNIC_DEV_CLOSE, &nic_dev->dev_status)) {\n \t\tPMD_DRV_LOG(WARNING, \"Device %s already closed\",\n@@ -306,7 +344,6 @@ static int spnic_dev_close(struct rte_eth_dev *eth_dev)\n \n \trte_bit_relaxed_clear32(SPNIC_DEV_INTR_EN, &nic_dev->dev_status);\n \n-\n \t/* Destroy rx mode mutex */\n \tspnic_mutex_destroy(&nic_dev->rx_mode_mutex);\n \n@@ -736,6 +773,12 @@ static int spnic_func_init(struct rte_eth_dev *eth_dev)\n \t\tgoto init_hwdev_fail;\n \t}\n \n+\tif (!spnic_support_nic(nic_dev->hwdev)) {\n+\t\tPMD_DRV_LOG(ERR, \"Hw of %s don't support nic\\n\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto init_hwdev_fail;\n+\t}\n+\n \tnic_dev->max_sqs = spnic_func_max_sqs(nic_dev->hwdev);\n \tnic_dev->max_rqs = spnic_func_max_rqs(nic_dev->hwdev);\n \n@@ -751,6 +794,13 @@ static int spnic_func_init(struct rte_eth_dev *eth_dev)\n \t\tgoto init_nic_hwdev_fail;\n \t}\n \n+\terr = spnic_get_feature_from_hw(nic_dev->hwdev, &nic_dev->feature_cap, 1);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Get nic feature from hardware failed, dev_name: %s\",\n+\t\t\t    eth_dev->data->name);\n+\t\tgoto get_cap_fail;\n+\t}\n+\n \terr = spnic_init_sw_rxtxqs(nic_dev);\n \tif (err) {\n \t\tPMD_DRV_LOG(ERR, \"Init sw rxqs or txqs failed, dev_name: %s\",\n@@ -792,6 +842,7 @@ static int spnic_func_init(struct rte_eth_dev *eth_dev)\n init_sw_rxtxqs_fail:\n \tspnic_free_nic_hwdev(nic_dev->hwdev);\n \n+get_cap_fail:\n init_nic_hwdev_fail:\n \tspnic_free_hwdev(nic_dev->hwdev);\n \teth_dev->dev_ops = NULL;\ndiff --git a/drivers/net/spnic/spnic_io.c b/drivers/net/spnic/spnic_io.c\nnew file mode 100644\nindex 0000000000..b4358f530a\n--- /dev/null\n+++ b/drivers/net/spnic/spnic_io.c\n@@ -0,0 +1,738 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#include <rte_io.h>\n+#include <rte_pci.h>\n+#include <rte_bus_pci.h>\n+#include <ethdev_pci.h>\n+#include <rte_mbuf.h>\n+#include <rte_malloc.h>\n+#include <rte_memcpy.h>\n+#include <rte_mempool.h>\n+#include <rte_errno.h>\n+#include <rte_ether.h>\n+#include <rte_ethdev_core.h>\n+#include <ethdev_driver.h>\n+\n+#include \"base/spnic_compat.h\"\n+#include \"base/spnic_cmd.h\"\n+#include \"base/spnic_wq.h\"\n+#include \"base/spnic_mgmt.h\"\n+#include \"base/spnic_cmdq.h\"\n+#include \"base/spnic_hwdev.h\"\n+#include \"base/spnic_hw_comm.h\"\n+#include \"base/spnic_nic_cfg.h\"\n+#include \"base/spnic_hw_cfg.h\"\n+#include \"spnic_io.h\"\n+#include \"spnic_tx.h\"\n+#include \"spnic_rx.h\"\n+#include \"spnic_ethdev.h\"\n+\n+#define SPNIC_DEAULT_TX_CI_PENDING_LIMIT\t0\n+#define SPNIC_DEAULT_TX_CI_COALESCING_TIME\t0\n+#define SPNIC_DEAULT_DROP_THD_ON\t\t0xFFFF\n+#define SPNIC_DEAULT_DROP_THD_OFF\t\t0\n+\n+#define WQ_PREFETCH_MAX\t\t\t4\n+#define WQ_PREFETCH_MIN\t\t\t1\n+#define WQ_PREFETCH_THRESHOLD\t\t256\n+\n+#define SPNIC_Q_CTXT_MAX\t\t31\n+\n+enum spnic_qp_ctxt_type {\n+\tSPNIC_QP_CTXT_TYPE_SQ,\n+\tSPNIC_QP_CTXT_TYPE_RQ,\n+};\n+\n+struct spnic_qp_ctxt_header {\n+\tu16 num_queues;\n+\tu16 queue_type;\n+\tu16 start_qid;\n+\tu16 rsvd;\n+};\n+\n+struct spnic_sq_ctxt {\n+\tu32 ci_pi;\n+\tu32 drop_mode_sp;\n+\tu32 wq_pfn_hi_owner;\n+\tu32 wq_pfn_lo;\n+\n+\tu32 rsvd0;\n+\tu32 pkt_drop_thd;\n+\tu32 global_sq_id;\n+\tu32 vlan_ceq_attr;\n+\n+\tu32 pref_cache;\n+\tu32 pref_ci_owner;\n+\tu32 pref_wq_pfn_hi_ci;\n+\tu32 pref_wq_pfn_lo;\n+\n+\tu32 rsvd8;\n+\tu32 rsvd9;\n+\tu32 wq_block_pfn_hi;\n+\tu32 wq_block_pfn_lo;\n+};\n+\n+struct spnic_rq_ctxt {\n+\tu32 ci_pi;\n+\tu32 ceq_attr;\n+\tu32 wq_pfn_hi_type_owner;\n+\tu32 wq_pfn_lo;\n+\n+\tu32 rsvd[3];\n+\tu32 cqe_sge_len;\n+\n+\tu32 pref_cache;\n+\tu32 pref_ci_owner;\n+\tu32 pref_wq_pfn_hi_ci;\n+\tu32 pref_wq_pfn_lo;\n+\n+\tu32 pi_paddr_hi;\n+\tu32 pi_paddr_lo;\n+\tu32 wq_block_pfn_hi;\n+\tu32 wq_block_pfn_lo;\n+};\n+\n+struct spnic_sq_ctxt_block {\n+\tstruct spnic_qp_ctxt_header cmdq_hdr;\n+\tstruct spnic_sq_ctxt sq_ctxt[SPNIC_Q_CTXT_MAX];\n+};\n+\n+struct spnic_rq_ctxt_block {\n+\tstruct spnic_qp_ctxt_header cmdq_hdr;\n+\tstruct spnic_rq_ctxt rq_ctxt[SPNIC_Q_CTXT_MAX];\n+};\n+\n+struct spnic_clean_queue_ctxt {\n+\tstruct spnic_qp_ctxt_header cmdq_hdr;\n+\tu32 rsvd;\n+};\n+\n+#define SQ_CTXT_SIZE(num_sqs)\t((u16)(sizeof(struct spnic_qp_ctxt_header) \\\n+\t\t\t\t+ (num_sqs) * sizeof(struct spnic_sq_ctxt)))\n+\n+#define RQ_CTXT_SIZE(num_rqs)\t((u16)(sizeof(struct spnic_qp_ctxt_header) \\\n+\t\t\t\t+ (num_rqs) * sizeof(struct spnic_rq_ctxt)))\n+\n+#define CI_IDX_HIGH_SHIFH\t\t\t\t12\n+\n+#define CI_HIGN_IDX(val)\t\t((val) >> CI_IDX_HIGH_SHIFH)\n+\n+#define SQ_CTXT_PI_IDX_SHIFT\t\t\t\t0\n+#define SQ_CTXT_CI_IDX_SHIFT\t\t\t\t16\n+\n+#define SQ_CTXT_PI_IDX_MASK\t\t\t\t0xFFFFU\n+#define SQ_CTXT_CI_IDX_MASK\t\t\t\t0xFFFFU\n+\n+#define SQ_CTXT_CI_PI_SET(val, member)\t\t\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_##member##_SHIFT)\n+\n+#define SQ_CTXT_MODE_SP_FLAG_SHIFT\t\t\t0\n+#define SQ_CTXT_MODE_PKT_DROP_SHIFT\t\t\t1\n+\n+#define SQ_CTXT_MODE_SP_FLAG_MASK\t\t\t0x1U\n+#define SQ_CTXT_MODE_PKT_DROP_MASK\t\t\t0x1U\n+\n+#define SQ_CTXT_MODE_SET(val, member)\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_MODE_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_MODE_##member##_SHIFT)\n+\n+#define SQ_CTXT_WQ_PAGE_HI_PFN_SHIFT\t\t\t0\n+#define SQ_CTXT_WQ_PAGE_OWNER_SHIFT\t\t\t23\n+\n+#define SQ_CTXT_WQ_PAGE_HI_PFN_MASK\t\t\t0xFFFFFU\n+#define SQ_CTXT_WQ_PAGE_OWNER_MASK\t\t\t0x1U\n+\n+#define SQ_CTXT_WQ_PAGE_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_WQ_PAGE_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_WQ_PAGE_##member##_SHIFT)\n+\n+#define SQ_CTXT_PKT_DROP_THD_ON_SHIFT\t\t\t0\n+#define SQ_CTXT_PKT_DROP_THD_OFF_SHIFT\t\t\t16\n+\n+#define SQ_CTXT_PKT_DROP_THD_ON_MASK\t\t\t0xFFFFU\n+#define SQ_CTXT_PKT_DROP_THD_OFF_MASK\t\t\t0xFFFFU\n+\n+#define SQ_CTXT_PKT_DROP_THD_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_PKT_DROP_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_PKT_DROP_##member##_SHIFT)\n+\n+#define SQ_CTXT_GLOBAL_SQ_ID_SHIFT\t\t\t0\n+\n+#define SQ_CTXT_GLOBAL_SQ_ID_MASK\t\t\t0x1FFFU\n+\n+#define SQ_CTXT_GLOBAL_QUEUE_ID_SET(val, member)\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_##member##_SHIFT)\n+\n+\n+#define SQ_CTXT_VLAN_TAG_SHIFT\t\t\t\t0\n+#define SQ_CTXT_VLAN_TYPE_SEL_SHIFT\t\t\t16\n+#define SQ_CTXT_VLAN_INSERT_MODE_SHIFT\t\t\t19\n+#define SQ_CTXT_VLAN_CEQ_EN_SHIFT\t\t\t23\n+\n+#define SQ_CTXT_VLAN_TAG_MASK\t\t\t\t0xFFFFU\n+#define SQ_CTXT_VLAN_TYPE_SEL_MASK\t\t\t0x7U\n+#define SQ_CTXT_VLAN_INSERT_MODE_MASK\t\t\t0x3U\n+#define SQ_CTXT_VLAN_CEQ_EN_MASK\t\t\t0x1U\n+\n+#define SQ_CTXT_VLAN_CEQ_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_VLAN_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_VLAN_##member##_SHIFT)\n+\n+#define SQ_CTXT_PREF_CACHE_THRESHOLD_SHIFT\t\t0\n+#define SQ_CTXT_PREF_CACHE_MAX_SHIFT\t\t\t14\n+#define SQ_CTXT_PREF_CACHE_MIN_SHIFT\t\t\t25\n+\n+#define SQ_CTXT_PREF_CACHE_THRESHOLD_MASK\t\t0x3FFFU\n+#define SQ_CTXT_PREF_CACHE_MAX_MASK\t\t\t0x7FFU\n+#define SQ_CTXT_PREF_CACHE_MIN_MASK\t\t\t0x7FU\n+\n+#define SQ_CTXT_PREF_CI_HI_SHIFT\t\t\t0\n+#define SQ_CTXT_PREF_OWNER_SHIFT\t\t\t4\n+\n+#define SQ_CTXT_PREF_CI_HI_MASK\t\t\t\t0xFU\n+#define SQ_CTXT_PREF_OWNER_MASK\t\t\t\t0x1U\n+\n+#define SQ_CTXT_PREF_WQ_PFN_HI_SHIFT\t\t\t0\n+#define SQ_CTXT_PREF_CI_LOW_SHIFT\t\t\t20\n+\n+#define SQ_CTXT_PREF_WQ_PFN_HI_MASK\t\t\t0xFFFFFU\n+#define SQ_CTXT_PREF_CI_LOW_MASK\t\t\t0xFFFU\n+\n+#define SQ_CTXT_PREF_SET(val, member)\t\t\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_PREF_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_PREF_##member##_SHIFT)\n+\n+#define SQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT\t\t\t0\n+\n+#define SQ_CTXT_WQ_BLOCK_PFN_HI_MASK\t\t\t0x7FFFFFU\n+\n+#define SQ_CTXT_WQ_BLOCK_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tSQ_CTXT_WQ_BLOCK_##member##_MASK) \\\n+\t\t\t\t\t<< SQ_CTXT_WQ_BLOCK_##member##_SHIFT)\n+\n+#define RQ_CTXT_PI_IDX_SHIFT\t\t\t\t0\n+#define RQ_CTXT_CI_IDX_SHIFT\t\t\t\t16\n+\n+#define RQ_CTXT_PI_IDX_MASK\t\t\t\t0xFFFFU\n+#define RQ_CTXT_CI_IDX_MASK\t\t\t\t0xFFFFU\n+\n+#define RQ_CTXT_CI_PI_SET(val, member)\t\t\t(((val) & \\\n+\t\t\t\t\tRQ_CTXT_##member##_MASK) \\\n+\t\t\t\t\t<< RQ_CTXT_##member##_SHIFT)\n+\n+#define RQ_CTXT_CEQ_ATTR_INTR_SHIFT\t\t\t21\n+#define RQ_CTXT_CEQ_ATTR_INTR_ARM_SHIFT\t\t\t30\n+#define RQ_CTXT_CEQ_ATTR_EN_SHIFT\t\t\t31\n+\n+#define RQ_CTXT_CEQ_ATTR_INTR_MASK\t\t\t0x3FFU\n+#define RQ_CTXT_CEQ_ATTR_INTR_ARM_MASK\t\t\t0x1U\n+#define RQ_CTXT_CEQ_ATTR_EN_MASK\t\t\t0x1U\n+\n+#define RQ_CTXT_CEQ_ATTR_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tRQ_CTXT_CEQ_ATTR_##member##_MASK) \\\n+\t\t\t\t\t<< RQ_CTXT_CEQ_ATTR_##member##_SHIFT)\n+\n+#define RQ_CTXT_WQ_PAGE_HI_PFN_SHIFT\t\t\t0\n+#define RQ_CTXT_WQ_PAGE_WQE_TYPE_SHIFT\t\t\t28\n+#define RQ_CTXT_WQ_PAGE_OWNER_SHIFT\t\t\t31\n+\n+#define RQ_CTXT_WQ_PAGE_HI_PFN_MASK\t\t\t0xFFFFFU\n+#define RQ_CTXT_WQ_PAGE_WQE_TYPE_MASK\t\t\t0x3U\n+#define RQ_CTXT_WQ_PAGE_OWNER_MASK\t\t\t0x1U\n+\n+#define RQ_CTXT_WQ_PAGE_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tRQ_CTXT_WQ_PAGE_##member##_MASK) << \\\n+\t\t\t\t\tRQ_CTXT_WQ_PAGE_##member##_SHIFT)\n+\n+#define RQ_CTXT_CQE_LEN_SHIFT\t\t\t\t28\n+\n+#define RQ_CTXT_CQE_LEN_MASK\t\t\t\t0x3U\n+\n+#define RQ_CTXT_CQE_LEN_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tRQ_CTXT_##member##_MASK) << \\\n+\t\t\t\t\tRQ_CTXT_##member##_SHIFT)\n+\n+#define RQ_CTXT_PREF_CACHE_THRESHOLD_SHIFT\t\t0\n+#define RQ_CTXT_PREF_CACHE_MAX_SHIFT\t\t\t14\n+#define RQ_CTXT_PREF_CACHE_MIN_SHIFT\t\t\t25\n+\n+#define RQ_CTXT_PREF_CACHE_THRESHOLD_MASK\t\t0x3FFFU\n+#define RQ_CTXT_PREF_CACHE_MAX_MASK\t\t\t0x7FFU\n+#define RQ_CTXT_PREF_CACHE_MIN_MASK\t\t\t0x7FU\n+\n+#define RQ_CTXT_PREF_CI_HI_SHIFT\t\t\t0\n+#define RQ_CTXT_PREF_OWNER_SHIFT\t\t\t4\n+\n+#define RQ_CTXT_PREF_CI_HI_MASK\t\t\t\t0xFU\n+#define RQ_CTXT_PREF_OWNER_MASK\t\t\t\t0x1U\n+\n+#define RQ_CTXT_PREF_WQ_PFN_HI_SHIFT\t\t\t0\n+#define RQ_CTXT_PREF_CI_LOW_SHIFT\t\t\t20\n+\n+#define RQ_CTXT_PREF_WQ_PFN_HI_MASK\t\t\t0xFFFFFU\n+#define RQ_CTXT_PREF_CI_LOW_MASK\t\t\t0xFFFU\n+\n+#define RQ_CTXT_PREF_SET(val, member)\t\t\t(((val) & \\\n+\t\t\t\t\tRQ_CTXT_PREF_##member##_MASK) << \\\n+\t\t\t\t\tRQ_CTXT_PREF_##member##_SHIFT)\n+\n+#define RQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT\t\t\t0\n+\n+#define RQ_CTXT_WQ_BLOCK_PFN_HI_MASK\t\t\t0x7FFFFFU\n+\n+#define RQ_CTXT_WQ_BLOCK_SET(val, member)\t\t(((val) & \\\n+\t\t\t\t\tRQ_CTXT_WQ_BLOCK_##member##_MASK) << \\\n+\t\t\t\t\tRQ_CTXT_WQ_BLOCK_##member##_SHIFT)\n+\n+#define SIZE_16BYTES(size)\t\t(RTE_ALIGN((size), 16) >> 4)\n+\n+#define\tWQ_PAGE_PFN_SHIFT\t\t\t\t12\n+#define\tWQ_BLOCK_PFN_SHIFT\t\t\t\t9\n+\n+#define WQ_PAGE_PFN(page_addr)\t\t((page_addr) >> WQ_PAGE_PFN_SHIFT)\n+#define WQ_BLOCK_PFN(page_addr)\t\t((page_addr) >> WQ_BLOCK_PFN_SHIFT)\n+\n+static void\n+spnic_qp_prepare_cmdq_header(struct spnic_qp_ctxt_header *qp_ctxt_hdr,\n+\t\t\t     enum spnic_qp_ctxt_type ctxt_type,\n+\t\t\t     u16 num_queues, u16 q_id)\n+{\n+\tqp_ctxt_hdr->queue_type = ctxt_type;\n+\tqp_ctxt_hdr->num_queues = num_queues;\n+\tqp_ctxt_hdr->start_qid = q_id;\n+\tqp_ctxt_hdr->rsvd = 0;\n+\n+\tspnic_cpu_to_be32(qp_ctxt_hdr, sizeof(*qp_ctxt_hdr));\n+}\n+\n+static void spnic_sq_prepare_ctxt(struct spnic_txq *sq, u16 sq_id,\n+\t\t\t\t  struct spnic_sq_ctxt *sq_ctxt)\n+{\n+\tu64 wq_page_addr;\n+\tu64 wq_page_pfn, wq_block_pfn;\n+\tu32 wq_page_pfn_hi, wq_page_pfn_lo;\n+\tu32 wq_block_pfn_hi, wq_block_pfn_lo;\n+\tu16 pi_start, ci_start;\n+\n+\tci_start = sq->cons_idx & sq->q_mask;\n+\tpi_start = sq->prod_idx & sq->q_mask;\n+\n+\t/* Read the first page from hardware table */\n+\twq_page_addr = sq->queue_buf_paddr;\n+\n+\twq_page_pfn = WQ_PAGE_PFN(wq_page_addr);\n+\twq_page_pfn_hi = upper_32_bits(wq_page_pfn);\n+\twq_page_pfn_lo = lower_32_bits(wq_page_pfn);\n+\n+\t/* Use 0-level CLA */\n+\twq_block_pfn = WQ_BLOCK_PFN(wq_page_addr);\n+\twq_block_pfn_hi = upper_32_bits(wq_block_pfn);\n+\twq_block_pfn_lo = lower_32_bits(wq_block_pfn);\n+\n+\tsq_ctxt->ci_pi = SQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |\n+\t\t\t SQ_CTXT_CI_PI_SET(pi_start, PI_IDX);\n+\n+\tsq_ctxt->drop_mode_sp = SQ_CTXT_MODE_SET(0, SP_FLAG) |\n+\t\t\t\tSQ_CTXT_MODE_SET(0, PKT_DROP);\n+\n+\tsq_ctxt->wq_pfn_hi_owner = SQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |\n+\t\t\t\t   SQ_CTXT_WQ_PAGE_SET(1, OWNER);\n+\n+\tsq_ctxt->wq_pfn_lo = wq_page_pfn_lo;\n+\n+\tsq_ctxt->pkt_drop_thd =\n+\t\tSQ_CTXT_PKT_DROP_THD_SET(SPNIC_DEAULT_DROP_THD_ON, THD_ON) |\n+\t\tSQ_CTXT_PKT_DROP_THD_SET(SPNIC_DEAULT_DROP_THD_OFF, THD_OFF);\n+\n+\tsq_ctxt->global_sq_id =\n+\t\tSQ_CTXT_GLOBAL_QUEUE_ID_SET(sq_id, GLOBAL_SQ_ID);\n+\n+\t/* Insert c-vlan in default */\n+\tsq_ctxt->vlan_ceq_attr = SQ_CTXT_VLAN_CEQ_SET(0, CEQ_EN) |\n+\t\t\t\t SQ_CTXT_VLAN_CEQ_SET(1, INSERT_MODE);\n+\n+\tsq_ctxt->rsvd0 = 0;\n+\n+\tsq_ctxt->pref_cache = SQ_CTXT_PREF_SET(WQ_PREFETCH_MIN, CACHE_MIN) |\n+\t\t\t      SQ_CTXT_PREF_SET(WQ_PREFETCH_MAX, CACHE_MAX) |\n+\t\t\t      SQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD,\n+\t\t\t\t\t       CACHE_THRESHOLD);\n+\n+\tsq_ctxt->pref_ci_owner =\n+\t\tSQ_CTXT_PREF_SET(CI_HIGN_IDX(ci_start), CI_HI) |\n+\t\tSQ_CTXT_PREF_SET(1, OWNER);\n+\n+\tsq_ctxt->pref_wq_pfn_hi_ci =\n+\t\tSQ_CTXT_PREF_SET(ci_start, CI_LOW) |\n+\t\tSQ_CTXT_PREF_SET(wq_page_pfn_hi, WQ_PFN_HI);\n+\n+\tsq_ctxt->pref_wq_pfn_lo = wq_page_pfn_lo;\n+\n+\tsq_ctxt->wq_block_pfn_hi =\n+\t\tSQ_CTXT_WQ_BLOCK_SET(wq_block_pfn_hi, PFN_HI);\n+\n+\tsq_ctxt->wq_block_pfn_lo = wq_block_pfn_lo;\n+\n+\tspnic_cpu_to_be32(sq_ctxt, sizeof(*sq_ctxt));\n+}\n+\n+static void spnic_rq_prepare_ctxt(struct spnic_rxq *rq,\n+\t\t\t\t  struct spnic_rq_ctxt *rq_ctxt)\n+{\n+\tu64 wq_page_addr;\n+\tu64 wq_page_pfn, wq_block_pfn;\n+\tu32 wq_page_pfn_hi, wq_page_pfn_lo;\n+\tu32 wq_block_pfn_hi, wq_block_pfn_lo;\n+\tu16 pi_start, ci_start;\n+\tu16 wqe_type = rq->wqebb_shift - SPNIC_RQ_WQEBB_SHIFT;\n+\tu8 intr_disable;\n+\n+\t/* RQ depth is in unit of 8 Bytes */\n+\tci_start = (u16)((rq->cons_idx & rq->q_mask) << wqe_type);\n+\tpi_start = (u16)((rq->prod_idx & rq->q_mask) << wqe_type);\n+\n+\t/* Read the first page from hardware table */\n+\twq_page_addr = rq->queue_buf_paddr;\n+\n+\twq_page_pfn = WQ_PAGE_PFN(wq_page_addr);\n+\twq_page_pfn_hi = upper_32_bits(wq_page_pfn);\n+\twq_page_pfn_lo = lower_32_bits(wq_page_pfn);\n+\n+\t/* Use 0-level CLA */\n+\twq_block_pfn = WQ_BLOCK_PFN(wq_page_addr);\n+\n+\twq_block_pfn_hi = upper_32_bits(wq_block_pfn);\n+\twq_block_pfn_lo = lower_32_bits(wq_block_pfn);\n+\n+\trq_ctxt->ci_pi = RQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |\n+\t\t\t RQ_CTXT_CI_PI_SET(pi_start, PI_IDX);\n+\n+\tintr_disable = rq->dp_intr_en ? 0 : 1;\n+\trq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(intr_disable, EN) |\n+\t\t\t    RQ_CTXT_CEQ_ATTR_SET(0, INTR_ARM) |\n+\t\t\t    RQ_CTXT_CEQ_ATTR_SET(rq->msix_entry_idx, INTR);\n+\n+\t/* Use 32Byte WQE with SGE for CQE in default */\n+\trq_ctxt->wq_pfn_hi_type_owner =\n+\t\tRQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |\n+\t\tRQ_CTXT_WQ_PAGE_SET(1, OWNER);\n+\n+\tswitch (wqe_type) {\n+\tcase SPNIC_EXTEND_RQ_WQE:\n+\t\t/* Use 32Byte WQE with SGE for CQE */\n+\t\trq_ctxt->wq_pfn_hi_type_owner |=\n+\t\t\tRQ_CTXT_WQ_PAGE_SET(0, WQE_TYPE);\n+\t\tbreak;\n+\tcase SPNIC_NORMAL_RQ_WQE:\n+\t\t/* Use 16Byte WQE with 32Bytes SGE for CQE */\n+\t\trq_ctxt->wq_pfn_hi_type_owner |=\n+\t\t\tRQ_CTXT_WQ_PAGE_SET(2, WQE_TYPE);\n+\t\trq_ctxt->cqe_sge_len = RQ_CTXT_CQE_LEN_SET(1, CQE_LEN);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(INFO, \"Invalid rq wqe type: %u\", wqe_type);\n+\t}\n+\n+\trq_ctxt->wq_pfn_lo = wq_page_pfn_lo;\n+\n+\trq_ctxt->pref_cache =\n+\t\tRQ_CTXT_PREF_SET(WQ_PREFETCH_MIN, CACHE_MIN) |\n+\t\tRQ_CTXT_PREF_SET(WQ_PREFETCH_MAX, CACHE_MAX) |\n+\t\tRQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);\n+\n+\trq_ctxt->pref_ci_owner =\n+\t\tRQ_CTXT_PREF_SET(CI_HIGN_IDX(ci_start), CI_HI) |\n+\t\tRQ_CTXT_PREF_SET(1, OWNER);\n+\n+\trq_ctxt->pref_wq_pfn_hi_ci =\n+\t\tRQ_CTXT_PREF_SET(wq_page_pfn_hi, WQ_PFN_HI) |\n+\t\tRQ_CTXT_PREF_SET(ci_start, CI_LOW);\n+\n+\trq_ctxt->pref_wq_pfn_lo = wq_page_pfn_lo;\n+\n+\trq_ctxt->pi_paddr_hi = upper_32_bits(rq->pi_dma_addr);\n+\trq_ctxt->pi_paddr_lo = lower_32_bits(rq->pi_dma_addr);\n+\n+\trq_ctxt->wq_block_pfn_hi =\n+\t\tRQ_CTXT_WQ_BLOCK_SET(wq_block_pfn_hi, PFN_HI);\n+\n+\trq_ctxt->wq_block_pfn_lo = wq_block_pfn_lo;\n+\n+\tspnic_cpu_to_be32(rq_ctxt, sizeof(*rq_ctxt));\n+}\n+\n+static int init_sq_ctxts(struct spnic_nic_dev *nic_dev)\n+{\n+\tstruct spnic_sq_ctxt_block *sq_ctxt_block = NULL;\n+\tstruct spnic_sq_ctxt *sq_ctxt = NULL;\n+\tstruct spnic_cmd_buf *cmd_buf = NULL;\n+\tstruct spnic_txq *sq = NULL;\n+\tu64 out_param = 0;\n+\tu16 q_id, curr_id, max_ctxts, i;\n+\tint err = 0;\n+\n+\tcmd_buf = spnic_alloc_cmd_buf(nic_dev->hwdev);\n+\tif (!cmd_buf) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cmd buf for sq ctx failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tq_id = 0;\n+\twhile (q_id < nic_dev->num_sqs) {\n+\t\tsq_ctxt_block = cmd_buf->buf;\n+\t\tsq_ctxt = sq_ctxt_block->sq_ctxt;\n+\n+\t\tmax_ctxts = (nic_dev->num_sqs - q_id) > SPNIC_Q_CTXT_MAX ?\n+\t\t\t     SPNIC_Q_CTXT_MAX : (nic_dev->num_sqs - q_id);\n+\n+\t\tspnic_qp_prepare_cmdq_header(&sq_ctxt_block->cmdq_hdr,\n+\t\t\t\t\t      SPNIC_QP_CTXT_TYPE_SQ,\n+\t\t\t\t\t      max_ctxts, q_id);\n+\n+\t\tfor (i = 0; i < max_ctxts; i++) {\n+\t\t\tcurr_id = q_id + i;\n+\t\t\tsq = nic_dev->txqs[curr_id];\n+\t\t\tspnic_sq_prepare_ctxt(sq, curr_id, &sq_ctxt[i]);\n+\t\t}\n+\n+\t\tcmd_buf->size = SQ_CTXT_SIZE(max_ctxts);\n+\t\terr = spnic_cmdq_direct_resp(nic_dev->hwdev, SPNIC_MOD_L2NIC,\n+\t\t\t\t\t      SPNIC_UCODE_CMD_MODIFY_QUEUE_CTX,\n+\t\t\t\t\t      cmd_buf, &out_param, 0);\n+\t\tif (err || out_param != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Set SQ ctxts failed, \"\n+\t\t\t\t    \"err: %d, out_param: %\"PRIu64\"\",\n+\t\t\t\t    err, out_param);\n+\n+\t\t\terr = -EFAULT;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tq_id += max_ctxts;\n+\t}\n+\n+\tspnic_free_cmd_buf(cmd_buf);\n+\treturn err;\n+}\n+\n+static int init_rq_ctxts(struct spnic_nic_dev *nic_dev)\n+{\n+\tstruct spnic_rq_ctxt_block *rq_ctxt_block = NULL;\n+\tstruct spnic_rq_ctxt *rq_ctxt = NULL;\n+\tstruct spnic_cmd_buf *cmd_buf = NULL;\n+\tstruct spnic_rxq *rq = NULL;\n+\tu64 out_param = 0;\n+\tu16 q_id, curr_id, max_ctxts, i;\n+\tint err = 0;\n+\n+\tcmd_buf = spnic_alloc_cmd_buf(nic_dev->hwdev);\n+\tif (!cmd_buf) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cmd buf for rq ctx failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tq_id = 0;\n+\twhile (q_id < nic_dev->num_rqs) {\n+\t\trq_ctxt_block = cmd_buf->buf;\n+\t\trq_ctxt = rq_ctxt_block->rq_ctxt;\n+\n+\t\tmax_ctxts = (nic_dev->num_rqs - q_id) > SPNIC_Q_CTXT_MAX ?\n+\t\t\t    SPNIC_Q_CTXT_MAX : (nic_dev->num_rqs - q_id);\n+\n+\t\tspnic_qp_prepare_cmdq_header(&rq_ctxt_block->cmdq_hdr,\n+\t\t\t\t\t      SPNIC_QP_CTXT_TYPE_RQ, max_ctxts,\n+\t\t\t\t\t      q_id);\n+\n+\t\tfor (i = 0; i < max_ctxts; i++) {\n+\t\t\tcurr_id = q_id + i;\n+\t\t\trq = nic_dev->rxqs[curr_id];\n+\n+\t\t\tspnic_rq_prepare_ctxt(rq, &rq_ctxt[i]);\n+\t\t}\n+\n+\t\tcmd_buf->size = RQ_CTXT_SIZE(max_ctxts);\n+\t\terr = spnic_cmdq_direct_resp(nic_dev->hwdev, SPNIC_MOD_L2NIC,\n+\t\t\t\t\t      SPNIC_UCODE_CMD_MODIFY_QUEUE_CTX,\n+\t\t\t\t\t      cmd_buf, &out_param, 0);\n+\t\tif (err || out_param != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Set RQ ctxts failed, \"\n+\t\t\t\t    \"err: %d, out_param: %\"PRIu64\"\",\n+\t\t\t\t    err, out_param);\n+\t\t\terr = -EFAULT;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tq_id += max_ctxts;\n+\t}\n+\n+\tspnic_free_cmd_buf(cmd_buf);\n+\treturn err;\n+}\n+\n+static int clean_queue_offload_ctxt(struct spnic_nic_dev *nic_dev,\n+\t\t\t\t    enum spnic_qp_ctxt_type ctxt_type)\n+{\n+\tstruct spnic_clean_queue_ctxt *ctxt_block = NULL;\n+\tstruct spnic_cmd_buf *cmd_buf;\n+\tu64 out_param = 0;\n+\tint err;\n+\n+\tcmd_buf = spnic_alloc_cmd_buf(nic_dev->hwdev);\n+\tif (!cmd_buf) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate cmd buf for LRO/TSO space failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tctxt_block = cmd_buf->buf;\n+\tctxt_block->cmdq_hdr.num_queues = nic_dev->max_sqs;\n+\tctxt_block->cmdq_hdr.queue_type = ctxt_type;\n+\tctxt_block->cmdq_hdr.start_qid = 0;\n+\n+\tspnic_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));\n+\n+\tcmd_buf->size = sizeof(*ctxt_block);\n+\n+\terr = spnic_cmdq_direct_resp(nic_dev->hwdev, SPNIC_MOD_L2NIC,\n+\t\t\t\t      SPNIC_UCODE_CMD_CLEAN_QUEUE_CONTEXT,\n+\t\t\t\t      cmd_buf, &out_param, 0);\n+\tif ((err) || (out_param)) {\n+\t\tPMD_DRV_LOG(ERR, \"Clean queue offload ctxts failed, \"\n+\t\t\t    \"err: %d, out_param: %\"PRIu64\"\", err, out_param);\n+\t\terr = -EFAULT;\n+\t}\n+\n+\tspnic_free_cmd_buf(cmd_buf);\n+\treturn err;\n+}\n+\n+static int clean_qp_offload_ctxt(struct spnic_nic_dev *nic_dev)\n+{\n+\t/* Clean LRO/TSO context space */\n+\treturn (clean_queue_offload_ctxt(nic_dev, SPNIC_QP_CTXT_TYPE_SQ) ||\n+\t\tclean_queue_offload_ctxt(nic_dev, SPNIC_QP_CTXT_TYPE_RQ));\n+}\n+\n+void spnic_get_func_rx_buf_size(void *dev)\n+{\n+\tstruct spnic_nic_dev *nic_dev = (struct spnic_nic_dev *)dev;\n+\tstruct spnic_rxq *rxq = NULL;\n+\tu16 q_id;\n+\tu16 buf_size = 0;\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_rqs; 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->rx_buff_len = buf_size;\n+}\n+\n+/* Init qps ctxt and set sq ci attr and arm all sq */\n+int spnic_init_qp_ctxts(void *dev)\n+{\n+\tstruct spnic_nic_dev *nic_dev = NULL;\n+\tstruct spnic_hwdev *hwdev = NULL;\n+\tstruct spnic_sq_attr sq_attr;\n+\tu32 rq_depth;\n+\tu16 q_id;\n+\tint err;\n+\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\tnic_dev = (struct spnic_nic_dev *)dev;\n+\thwdev = nic_dev->hwdev;\n+\n+\terr = init_sq_ctxts(nic_dev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Init SQ ctxts failed\");\n+\t\treturn err;\n+\t}\n+\n+\terr = init_rq_ctxts(nic_dev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Init RQ ctxts failed\");\n+\t\treturn err;\n+\t}\n+\n+\terr = clean_qp_offload_ctxt(nic_dev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Clean qp offload ctxts failed\");\n+\t\treturn err;\n+\t}\n+\n+\trq_depth = ((u32)nic_dev->rxqs[0]->q_depth) <<\n+\t\t   nic_dev->rxqs[0]->wqe_type;\n+\terr = spnic_set_root_ctxt(hwdev, rq_depth, nic_dev->txqs[0]->q_depth,\n+\t\t\t\t   nic_dev->rx_buff_len);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Set root context failed\");\n+\t\treturn err;\n+\t}\n+\n+\tfor (q_id = 0; q_id < nic_dev->num_sqs; q_id++) {\n+\t\tsq_attr.ci_dma_base = nic_dev->txqs[q_id]->ci_dma_base >> 2;\n+\t\tsq_attr.pending_limit = SPNIC_DEAULT_TX_CI_PENDING_LIMIT;\n+\t\tsq_attr.coalescing_time = SPNIC_DEAULT_TX_CI_COALESCING_TIME;\n+\t\tsq_attr.intr_en = 0;\n+\t\tsq_attr.intr_idx = 0; /* Tx doesn't need intr */\n+\t\tsq_attr.l2nic_sqn = q_id;\n+\t\tsq_attr.dma_attr_off = 0;\n+\t\terr = spnic_set_ci_table(hwdev, &sq_attr);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Set ci table failed\");\n+\t\t\tgoto set_cons_idx_table_err;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+set_cons_idx_table_err:\n+\tspnic_clean_root_ctxt(hwdev);\n+\treturn err;\n+}\n+\n+void spnic_free_qp_ctxts(void *hwdev)\n+{\n+\tif (!hwdev)\n+\t\treturn;\n+\n+\tspnic_clean_root_ctxt(hwdev);\n+}\n+\n+void spnic_update_driver_feature(void *dev, u64 s_feature)\n+{\n+\tstruct spnic_nic_dev *nic_dev = NULL;\n+\n+\tif (!dev)\n+\t\treturn;\n+\n+\tnic_dev = (struct spnic_nic_dev *)dev;\n+\tnic_dev->feature_cap = s_feature;\n+\n+\tPMD_DRV_LOG(INFO, \"Update nic feature to %\"PRIu64\"\\n\",\n+\t\t    nic_dev->feature_cap);\n+}\n+\n+u64 spnic_get_driver_feature(void *dev)\n+{\n+\tstruct spnic_nic_dev *nic_dev = NULL;\n+\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\tnic_dev = (struct spnic_nic_dev *)dev;\n+\n+\treturn nic_dev->feature_cap;\n+}\ndiff --git a/drivers/net/spnic/spnic_io.h b/drivers/net/spnic/spnic_io.h\nnew file mode 100644\nindex 0000000000..c59b2f42ec\n--- /dev/null\n+++ b/drivers/net/spnic/spnic_io.h\n@@ -0,0 +1,154 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#ifndef _SPNIC_IO_H_\n+#define _SPNIC_IO_H_\n+\n+#define SPNIC_SQ_WQEBB_SHIFT\t\t\t4\n+#define SPNIC_RQ_WQEBB_SHIFT\t\t\t3\n+\n+#define SPNIC_SQ_WQEBB_SIZE\tBIT(SPNIC_SQ_WQEBB_SHIFT)\n+#define SPNIC_CQE_SIZE_SHIFT\t\t\t4\n+\n+/* Ci addr should RTE_CACHE_SIZE(64B) alignment for performance */\n+#define SPNIC_CI_Q_ADDR_SIZE\t\t\t64\n+\n+#define CI_TABLE_SIZE(num_qps, pg_sz)\t\\\n+\t\t\t(RTE_ALIGN((num_qps) * SPNIC_CI_Q_ADDR_SIZE, pg_sz))\n+\n+#define SPNIC_CI_VADDR(base_addr, q_id)\t((u8 *)(base_addr) + \\\n+\t\t\t\t\t\t(q_id) * SPNIC_CI_Q_ADDR_SIZE)\n+\n+#define SPNIC_CI_PADDR(base_paddr, q_id)\t((base_paddr) + \\\n+\t\t\t\t\t\t(q_id) * SPNIC_CI_Q_ADDR_SIZE)\n+\n+enum spnic_rq_wqe_type {\n+\tSPNIC_COMPACT_RQ_WQE,\n+\tSPNIC_NORMAL_RQ_WQE,\n+\tSPNIC_EXTEND_RQ_WQE,\n+};\n+\n+enum spnic_queue_type {\n+\tSPNIC_SQ,\n+\tSPNIC_RQ,\n+\tSPNIC_MAX_QUEUE_TYPE\n+};\n+\n+/* Doorbell info */\n+struct spnic_db {\n+\tu32 db_info;\n+\tu32 pi_hi;\n+};\n+\n+#define DB_INFO_QID_SHIFT\t\t\t0\n+#define DB_INFO_NON_FILTER_SHIFT\t\t22\n+#define DB_INFO_CFLAG_SHIFT\t\t\t23\n+#define DB_INFO_COS_SHIFT\t\t\t24\n+#define DB_INFO_TYPE_SHIFT\t\t\t27\n+\n+#define DB_INFO_QID_MASK\t\t\t0x1FFFU\n+#define DB_INFO_NON_FILTER_MASK\t\t\t0x1U\n+#define DB_INFO_CFLAG_MASK\t\t\t0x1U\n+#define DB_INFO_COS_MASK\t\t\t0x7U\n+#define DB_INFO_TYPE_MASK\t\t\t0x1FU\n+#define DB_INFO_SET(val, member)\t\t(((u32)(val) & \\\n+\t\t\t\t\tDB_INFO_##member##_MASK) << \\\n+\t\t\t\t\tDB_INFO_##member##_SHIFT)\n+\n+#define DB_PI_LOW_MASK\t0xFFU\n+#define DB_PI_HIGH_MASK\t0xFFU\n+#define DB_PI_LOW(pi)\t((pi) & DB_PI_LOW_MASK)\n+#define DB_PI_HI_SHIFT\t8\n+#define DB_PI_HIGH(pi)\t(((pi) >> DB_PI_HI_SHIFT) & DB_PI_HIGH_MASK)\n+#define DB_INFO_UPPER_32(val) (((u64)val) << 32)\n+\n+#define DB_ADDR(db_addr, pi)\t((u64 *)(db_addr) + DB_PI_LOW(pi))\n+#define SRC_TYPE\t\t1\n+\n+/* Cflag data path */\n+#define SQ_CFLAG_DP\t\t0\n+#define RQ_CFLAG_DP\t\t1\n+\n+#define MASKED_QUEUE_IDX(queue, idx) ((idx) & (queue)->q_mask)\n+\n+#define\tNIC_WQE_ADDR(queue, idx) ((void *)((u64)((queue)->queue_buf_vaddr) + \\\n+\t\t\t\t       ((idx) << (queue)->wqebb_shift)))\n+\n+#define SPNIC_FLUSH_QUEUE_TIMEOUT\t3000\n+\n+/**\n+ * Write send queue doorbell\n+ *\n+ * @param[in] db_addr\n+ *   Doorbell address\n+ * @param[in] q_id\n+ *   Send queue id\n+ * @param[in] cos\n+ *   Send queue cos\n+ * @param[in] cflag\n+ *   Cflag data path\n+ * @param[in] pi\n+ *   Send queue pi\n+ */\n+static inline void spnic_write_db(void *db_addr, u16 q_id, int cos, u8 cflag,\n+\t\t\t\t  u16 pi)\n+{\n+\tu64 db;\n+\n+\t/* Hardware will do endianness coverting */\n+\tdb = DB_PI_HIGH(pi);\n+\tdb = DB_INFO_UPPER_32(db) | DB_INFO_SET(SRC_TYPE, TYPE) |\n+\t     DB_INFO_SET(cflag, CFLAG) | DB_INFO_SET(cos, COS) |\n+\t     DB_INFO_SET(q_id, QID);\n+\n+\trte_wmb(); /* Write all before the doorbell */\n+\n+\trte_write64(*((u64 *)&db), DB_ADDR(db_addr, pi));\n+}\n+\n+void spnic_get_func_rx_buf_size(void *dev);\n+\n+/**\n+ * Init queue pair context\n+ *\n+ * @param[in] dev\n+ *   Device pointer to nic device\n+ *\n+ * @retval zero: Success\n+ * @retval non-zero: Failure\n+ */\n+int spnic_init_qp_ctxts(void *dev);\n+\n+/**\n+ * Free queue pair context\n+ *\n+ * @param[in] hwdev\n+ *   Device pointer to hwdev\n+ */\n+void spnic_free_qp_ctxts(void *hwdev);\n+\n+/**\n+ * Update service feature driver supported\n+ *\n+ * @param[in] dev\n+ *   Device pointer to nic device\n+ * @param[out] s_feature\n+ *   s_feature driver supported\n+ * @retval zero: Success\n+ * @retval non-zero: Failure\n+ */\n+void spnic_update_driver_feature(void *dev, u64 s_feature);\n+\n+/**\n+ * Get service feature driver supported\n+ *\n+ * @param[in] dev\n+ *   Device pointer to nic device\n+ * @param[out] s_feature\n+ *   s_feature driver supported\n+ * @retval zero: Success\n+ * @retval non-zero: Failure\n+ */\n+u64 spnic_get_driver_feature(void *dev);\n+#endif /* _SPNIC_IO_H_ */\ndiff --git a/drivers/net/spnic/spnic_rx.h b/drivers/net/spnic/spnic_rx.h\nnew file mode 100644\nindex 0000000000..b2f0052533\n--- /dev/null\n+++ b/drivers/net/spnic/spnic_rx.h\n@@ -0,0 +1,113 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#ifndef _SPNIC_RX_H_\n+#define _SPNIC_RX_H_\n+\n+struct spnic_rxq_stats {\n+\tu64 packets;\n+\tu64 bytes;\n+\tu64 errors;\n+\tu64 csum_errors;\n+\tu64 other_errors;\n+\tu64 unlock_bp;\n+\tu64 dropped;\n+\n+\tu64 rx_nombuf;\n+\tu64 rx_discards;\n+\tu64 burst_pkts;\n+};\n+\n+struct spnic_rq_cqe {\n+\tu32 status;\n+\tu32 vlan_len;\n+\n+\tu32 offload_type;\n+\tu32 hash_val;\n+\tu32 xid;\n+\tu32 decrypt_info;\n+\tu32 rsvd6;\n+\tu32 pkt_info;\n+};\n+\n+/*\n+ * Attention: please do not add any member in spnic_rx_info because rxq bulk\n+ * rearm mode will write mbuf in rx_info\n+ */\n+struct spnic_rx_info {\n+\tstruct rte_mbuf *mbuf;\n+};\n+\n+struct spnic_sge_sect {\n+\tstruct spnic_sge sge;\n+\tu32 rsvd;\n+};\n+\n+struct spnic_rq_extend_wqe {\n+\tstruct spnic_sge_sect buf_desc;\n+\tstruct spnic_sge_sect cqe_sect;\n+};\n+\n+struct spnic_rq_normal_wqe {\n+\tu32 buf_hi_addr;\n+\tu32 buf_lo_addr;\n+\tu32 cqe_hi_addr;\n+\tu32 cqe_lo_addr;\n+};\n+\n+struct spnic_rq_wqe {\n+\tunion {\n+\t\tstruct spnic_rq_normal_wqe normal_wqe;\n+\t\tstruct spnic_rq_extend_wqe extend_wqe;\n+\t};\n+};\n+\n+struct spnic_rxq {\n+\tstruct spnic_nic_dev *nic_dev;\n+\n+\tu16 q_id;\n+\tu16 q_depth;\n+\tu16 q_mask;\n+\tu16 buf_len;\n+\n+\tu32 rx_buff_shift;\n+\n+\tu16 rx_free_thresh;\n+\tu16 rxinfo_align_end;\n+\tu16 wqebb_shift;\n+\tu16 wqebb_size;\n+\n+\tu16 wqe_type;\n+\tu16 cons_idx;\n+\tu16 prod_idx;\n+\tu16 delta;\n+\n+\tu16 next_to_update;\n+\tu16 port_id;\n+\n+\tconst struct rte_memzone *rq_mz;\n+\tvoid *queue_buf_vaddr; /* Rq dma info */\n+\trte_iova_t queue_buf_paddr;\n+\n+\tconst struct rte_memzone *pi_mz;\n+\tu16 *pi_virt_addr;\n+\tvoid *db_addr;\n+\trte_iova_t pi_dma_addr;\n+\n+\tstruct spnic_rx_info *rx_info;\n+\tstruct spnic_rq_cqe *rx_cqe;\n+\tstruct rte_mempool *mb_pool;\n+\n+\tconst struct rte_memzone *cqe_mz;\n+\trte_iova_t cqe_start_paddr;\n+\tvoid *cqe_start_vaddr;\n+\tu8 dp_intr_en;\n+\tu16 msix_entry_idx;\n+\n+\tunsigned long status;\n+\n+\tstruct spnic_rxq_stats\trxq_stats;\n+} __rte_cache_aligned;\n+\n+#endif /* _SPNIC_RX_H_ */\ndiff --git a/drivers/net/spnic/spnic_tx.h b/drivers/net/spnic/spnic_tx.h\nnew file mode 100644\nindex 0000000000..7528b27bd9\n--- /dev/null\n+++ b/drivers/net/spnic/spnic_tx.h\n@@ -0,0 +1,62 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#ifndef _SPNIC_TX_H_\n+#define _SPNIC_TX_H_\n+\n+/* Txq info */\n+struct spnic_txq_stats {\n+\tu64 packets;\n+\tu64 bytes;\n+\tu64 tx_busy;\n+\tu64 off_errs;\n+\tu64 burst_pkts;\n+\tu64 sge_len0;\n+\tu64 mbuf_null;\n+\tu64 cpy_pkts;\n+\tu64 sge_len_too_large;\n+};\n+\n+struct spnic_tx_info {\n+\tstruct rte_mbuf *mbuf;\n+\tstruct rte_mbuf *cpy_mbuf;\n+\tint wqebb_cnt;\n+};\n+\n+struct spnic_txq {\n+\tstruct spnic_nic_dev *nic_dev;\n+\n+\tu16 q_id;\n+\tu16 q_depth;\n+\tu16 q_mask;\n+\tu16 wqebb_size;\n+\n+\tu16 wqebb_shift;\n+\tu16 cons_idx;\n+\tu16 prod_idx;\n+\n+\tu16 tx_free_thresh;\n+\tu16 owner; /* Used for sq */\n+\n+\tvoid *db_addr;\n+\n+\tstruct spnic_tx_info *tx_info;\n+\n+\tconst struct rte_memzone *sq_mz;\n+\tvoid *queue_buf_vaddr;\n+\trte_iova_t queue_buf_paddr; /* Sq dma info */\n+\n+\tconst struct rte_memzone *ci_mz;\n+\tvoid *ci_vaddr_base;\n+\trte_iova_t ci_dma_base;\n+\n+\tu64 sq_head_addr;\n+\tu64 sq_bot_sge_addr;\n+\n+\tu32 cos;\n+\n+\tstruct spnic_txq_stats txq_stats;\n+} __rte_cache_aligned;\n+\n+#endif /* _SPNIC_TX_H_ */\n",
    "prefixes": [
        "v1",
        "11/25"
    ]
}