get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 105247,
    "url": "http://patches.dpdk.org/api/patches/105247/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/3ecfdd9a47d781a308db1f67c19c8840c620c0f0.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": "<3ecfdd9a47d781a308db1f67c19c8840c620c0f0.1639636621.git.songyl@ramaxel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/3ecfdd9a47d781a308db1f67c19c8840c620c0f0.1639636621.git.songyl@ramaxel.com",
    "date": "2021-12-18T02:51:35",
    "name": "[v1,08/25] net/spnic: add hardware info initialization",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5de776cc7b78edac7d291ab4dd2e43e03ed061d0",
    "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/3ecfdd9a47d781a308db1f67c19c8840c620c0f0.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/105247/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/105247/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 487A5A04A4;\n\tSat, 18 Dec 2021 03:53:20 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7C2E34116A;\n\tSat, 18 Dec 2021 03:52:31 +0100 (CET)",
            "from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id B5F0441172\n for <dev@dpdk.org>; Sat, 18 Dec 2021 03:52:28 +0100 (CET)",
            "from V12DG1MBS01.ramaxel.local (v12dg1mbs01.ramaxel.local\n [172.26.18.31])\n by VLXDG1SPAM1.ramaxel.com with ESMTPS id 1BI2q088010338\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:51:59 +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 08/25] net/spnic: add hardware info initialization",
        "Date": "Sat, 18 Dec 2021 10:51:35 +0800",
        "Message-ID": "\n <3ecfdd9a47d781a308db1f67c19c8840c620c0f0.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 1BI2q088010338",
        "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 commits add hardware info initialization, including\nthat device capability initialization, common feature\nnegotiation, and two interfaces spnic_get_board_info(),\nspnic_get_mgmt_version() to get hardware info and\nfirmware version.\n\nSigned-off-by: Yanling Song <songyl@ramaxel.com>\n---\n drivers/net/spnic/base/meson.build     |   3 +-\n drivers/net/spnic/base/spnic_hw_cfg.c  | 157 +++++++++++++++++++++++++\n drivers/net/spnic/base/spnic_hw_cfg.h  | 117 ++++++++++++++++++\n drivers/net/spnic/base/spnic_hw_comm.c | 121 +++++++++++++++++++\n drivers/net/spnic/base/spnic_hw_comm.h |  22 ++++\n drivers/net/spnic/base/spnic_hwdev.c   |  70 +++++++++++\n drivers/net/spnic/base/spnic_hwdev.h   |   5 +\n drivers/net/spnic/base/spnic_mbox.c    |   8 ++\n 8 files changed, 502 insertions(+), 1 deletion(-)\n create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.c\n create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.h",
    "diff": "diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build\nindex da6d6ee4a2..77a56ca41e 100644\n--- a/drivers/net/spnic/base/meson.build\n+++ b/drivers/net/spnic/base/meson.build\n@@ -10,7 +10,8 @@ sources = [\n \t'spnic_nic_event.c',\n \t'spnic_cmdq.c',\n \t'spnic_hw_comm.c',\n-\t'spnic_wq.c'\n+\t'spnic_wq.c',\n+\t'spnic_hw_cfg.c'\n ]\n \n extra_flags = []\ndiff --git a/drivers/net/spnic/base/spnic_hw_cfg.c b/drivers/net/spnic/base/spnic_hw_cfg.c\nnew file mode 100644\nindex 0000000000..e8856ce9fe\n--- /dev/null\n+++ b/drivers/net/spnic/base/spnic_hw_cfg.c\n@@ -0,0 +1,157 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#include \"spnic_compat.h\"\n+#include \"spnic_mgmt.h\"\n+#include \"spnic_mbox.h\"\n+#include \"spnic_hwdev.h\"\n+#include \"spnic_hwif.h\"\n+#include \"spnic_hw_cfg.h\"\n+\n+static void parse_pub_res_cap(struct service_cap *cap,\n+\t\t\t      struct spnic_cfg_cmd_dev_cap *dev_cap,\n+\t\t\t      enum func_type type)\n+{\n+\tcap->host_id = dev_cap->host_id;\n+\tcap->ep_id = dev_cap->ep_id;\n+\tcap->er_id = dev_cap->er_id;\n+\tcap->port_id = dev_cap->port_id;\n+\n+\tcap->svc_type = dev_cap->svc_cap_en;\n+\tcap->chip_svc_type = cap->svc_type;\n+\n+\tcap->cos_valid_bitmap = dev_cap->valid_cos_bitmap;\n+\tcap->flexq_en = dev_cap->flexq_en;\n+\n+\tcap->host_total_function = dev_cap->host_total_func;\n+\tcap->max_vf = 0;\n+\tif (type == TYPE_PF || type == TYPE_PPF) {\n+\t\tcap->max_vf = dev_cap->max_vf;\n+\t\tcap->pf_num = dev_cap->host_pf_num;\n+\t\tcap->pf_id_start = dev_cap->pf_id_start;\n+\t\tcap->vf_num = dev_cap->host_vf_num;\n+\t\tcap->vf_id_start = dev_cap->vf_id_start;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"Get public resource capability: \");\n+\tPMD_DRV_LOG(INFO, \"host_id: 0x%x, ep_id: 0x%x, er_id: 0x%x, \"\n+\t\t    \"port_id: 0x%x\",\n+\t\t    cap->host_id, cap->ep_id, cap->er_id, cap->port_id);\n+\tPMD_DRV_LOG(INFO, \"host_total_function: 0x%x, max_vf: 0x%x\",\n+\t\t    cap->host_total_function, cap->max_vf);\n+\tPMD_DRV_LOG(INFO, \"host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\",\n+\t\t    cap->pf_num, cap->pf_id_start,\n+\t\t    cap->vf_num, cap->vf_id_start);\n+}\n+\n+static void parse_l2nic_res_cap(struct service_cap *cap,\n+\t\t\t\tstruct spnic_cfg_cmd_dev_cap *dev_cap)\n+{\n+\tstruct nic_service_cap *nic_cap = &cap->nic_cap;\n+\n+\tnic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;\n+\tnic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;\n+\n+\tPMD_DRV_LOG(INFO, \"L2nic resource capbility, max_sqs: 0x%x, \"\n+\t\t    \"max_rqs: 0x%x\",\n+\t\t    nic_cap->max_sqs, nic_cap->max_rqs);\n+}\n+\n+static void parse_dev_cap(struct spnic_hwdev *dev,\n+\t\t\t  struct spnic_cfg_cmd_dev_cap *dev_cap,\n+\t\t\t  enum func_type type)\n+{\n+\tstruct service_cap *cap = &dev->cfg_mgmt->svc_cap;\n+\n+\tparse_pub_res_cap(cap, dev_cap, type);\n+\n+\tif (IS_NIC_TYPE(dev))\n+\t\tparse_l2nic_res_cap(cap, dev_cap);\n+}\n+\n+static int get_cap_from_fw(struct spnic_hwdev *hwdev, enum func_type type)\n+{\n+\tstruct spnic_cfg_cmd_dev_cap dev_cap;\n+\tu16 out_len = sizeof(dev_cap);\n+\tint err;\n+\n+\tmemset(&dev_cap, 0, sizeof(dev_cap));\n+\tdev_cap.func_id = spnic_global_func_id(hwdev);\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_CFGM,\n+\t\t\t\t     SPNIC_CFG_CMD_GET_DEV_CAP,\n+\t\t\t\t     &dev_cap, sizeof(dev_cap),\n+\t\t\t\t     &dev_cap, &out_len, 0);\n+\tif (err || dev_cap.status || !out_len) {\n+\t\tPMD_DRV_LOG(ERR, \"Get capability from FW failed, err: %d, \"\n+\t\t\t    \"status: 0x%x, out size: 0x%x\",\n+\t\t\t    err, dev_cap.status, out_len);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tparse_dev_cap(hwdev, &dev_cap, type);\n+\treturn 0;\n+}\n+\n+static int get_dev_cap(struct spnic_hwdev *hwdev)\n+{\n+\tenum func_type type = SPNIC_FUNC_TYPE(hwdev);\n+\n+\tswitch (type) {\n+\tcase TYPE_PF:\n+\tcase TYPE_PPF:\n+\tcase TYPE_VF:\n+\t\tif (get_cap_from_fw(hwdev, type) != 0)\n+\t\t\treturn -EFAULT;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported PCIe function type: %d\", type);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int cfg_mbx_vf_proc_msg(void *hwdev, __rte_unused void *pri_handle, u16 cmd,\n+\t\t\t__rte_unused void *buf_in, __rte_unused u16 in_size,\n+\t\t\t__rte_unused void *buf_out, __rte_unused u16 *out_size)\n+{\n+\tstruct spnic_hwdev *dev = hwdev;\n+\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\tPMD_DRV_LOG(WARNING,\n+\t\t    \"Unsupported cfg mbox vf event %d to process\", cmd);\n+\n+\treturn 0;\n+}\n+\n+int spnic_init_capability(void *dev)\n+{\n+\tstruct spnic_hwdev *hwdev = (struct spnic_hwdev *)dev;\n+\tstruct cfg_mgmt_info *cfg_mgmt = NULL;\n+\tint err;\n+\n+\tcfg_mgmt = rte_zmalloc(\"cfg_mgmt\", sizeof(*cfg_mgmt),\n+\t\t\t       SPNIC_MEM_ALLOC_ALIGN_MIN);\n+\tif (!cfg_mgmt)\n+\t\treturn -ENOMEM;\n+\n+\tmemset(cfg_mgmt, 0, sizeof(struct cfg_mgmt_info));\n+\thwdev->cfg_mgmt = cfg_mgmt;\n+\tcfg_mgmt->hwdev = hwdev;\n+\n+\terr = get_dev_cap(hwdev);\n+\tif (err) {\n+\t\trte_free(cfg_mgmt);\n+\t\thwdev->cfg_mgmt = NULL;\n+\t}\n+\n+\treturn err;\n+}\n+\n+void spnic_free_capability(void *dev)\n+{\n+\trte_free(((struct spnic_hwdev *)dev)->cfg_mgmt);\n+}\ndiff --git a/drivers/net/spnic/base/spnic_hw_cfg.h b/drivers/net/spnic/base/spnic_hw_cfg.h\nnew file mode 100644\nindex 0000000000..1b1b598726\n--- /dev/null\n+++ b/drivers/net/spnic/base/spnic_hw_cfg.h\n@@ -0,0 +1,117 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#ifndef _SPNIC_HW_CFG_H_\n+#define _SPNIC_HW_CFG_H_\n+\n+#define CFG_MAX_CMD_TIMEOUT\t30000 /* ms */\n+\n+#define K_UNIT              BIT(10)\n+#define M_UNIT              BIT(20)\n+#define G_UNIT              BIT(30)\n+\n+/* Number of PFs and VFs */\n+#define HOST_PF_NUM\t\t4\n+#define HOST_VF_NUM\t\t0\n+#define HOST_OQID_MASK_VAL\t2\n+\n+#define L2NIC_SQ_DEPTH      (4 * K_UNIT)\n+#define L2NIC_RQ_DEPTH      (4 * K_UNIT)\n+\n+enum intr_type {\n+\tINTR_TYPE_MSIX,\n+\tINTR_TYPE_MSI,\n+\tINTR_TYPE_INT,\n+\tINTR_TYPE_NONE\n+};\n+\n+/* Service type relates define */\n+enum cfg_svc_type_en {\n+\tCFG_SVC_NIC_BIT0 = (1 << 0)\n+};\n+\n+struct nic_service_cap {\n+\tu16 max_sqs;\n+\tu16 max_rqs;\n+};\n+\n+/* Device capability */\n+struct service_cap {\n+\tenum cfg_svc_type_en svc_type; /* User input service type */\n+\tenum cfg_svc_type_en chip_svc_type; /* HW supported service type */\n+\n+\tu8 host_id;\n+\tu8 ep_id;\n+\tu8 er_id;\t/* PF/VF's ER */\n+\tu8 port_id;\t/* PF/VF's physical port */\n+\n+\tu16 host_total_function;\n+\tu8 pf_num;\n+\tu8 pf_id_start;\n+\tu16 vf_num;\t/* max numbers of vf in current host */\n+\tu16 vf_id_start;\n+\n+\tu8 flexq_en;\n+\tu8 cos_valid_bitmap;\n+\tu16 max_vf;\t/* max VF number that PF supported */\n+\n+\tstruct nic_service_cap nic_cap; /* NIC capability */\n+};\n+\n+struct cfg_mgmt_info {\n+\tvoid *hwdev;\n+\tstruct service_cap svc_cap;\n+};\n+\n+enum spnic_cfg_cmd {\n+\tSPNIC_CFG_CMD_GET_DEV_CAP = 0,\n+};\n+\n+struct spnic_cfg_cmd_dev_cap {\n+\tu8 status;\n+\tu8 version;\n+\tu8 rsvd0[6];\n+\n+\tu16 func_id;\n+\tu16 rsvd1;\n+\n+\t/* Public resource */\n+\tu8 host_id;\n+\tu8 ep_id;\n+\tu8 er_id;\n+\tu8 port_id;\n+\n+\tu16 host_total_func;\n+\tu8 host_pf_num;\n+\tu8 pf_id_start;\n+\tu16 host_vf_num;\n+\tu16 vf_id_start;\n+\tu32 rsvd_host;\n+\n+\tu16 svc_cap_en;\n+\tu16 max_vf;\n+\tu8 flexq_en;\n+\tu8 valid_cos_bitmap;\n+\t/* Reserved for func_valid_cos_bitmap */\n+\tu16 rsvd_cos;\n+\n+\tu32 rsvd[11];\n+\n+\t/* l2nic */\n+\tu16 nic_max_sq_id;\n+\tu16 nic_max_rq_id;\n+\tu32 rsvd_nic[3];\n+\n+\tu32 rsvd_glb[60];\n+};\n+\n+#define IS_NIC_TYPE(dev) \\\n+\t(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SVC_NIC_BIT0)\n+\n+int spnic_init_capability(void *dev);\n+void spnic_free_capability(void *dev);\n+\n+int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in,\n+\t\t\tu16 in_size, void *buf_out, u16 *out_size);\n+#endif /* _SPNIC_HW_CFG_H_ */\ndiff --git a/drivers/net/spnic/base/spnic_hw_comm.c b/drivers/net/spnic/base/spnic_hw_comm.c\nindex 48730ce7fe..5cb607cf03 100644\n--- a/drivers/net/spnic/base/spnic_hw_comm.c\n+++ b/drivers/net/spnic/base/spnic_hw_comm.c\n@@ -192,6 +192,31 @@ int spnic_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size)\n \treturn 0;\n }\n \n+int spnic_func_reset(void *hwdev, u64 reset_flag)\n+{\n+\tstruct spnic_reset func_reset;\n+\tstruct spnic_hwif *hwif = ((struct spnic_hwdev *)hwdev)->hwif;\n+\tu16 out_size = sizeof(func_reset);\n+\tint err = 0;\n+\n+\tPMD_DRV_LOG(INFO, \"Function is reset\");\n+\n+\tmemset(&func_reset, 0, sizeof(func_reset));\n+\tfunc_reset.func_id = SPNIC_HWIF_GLOBAL_IDX(hwif);\n+\tfunc_reset.reset_flag = reset_flag;\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM, MGMT_CMD_FUNC_RESET,\n+\t\t\t\t     &func_reset, sizeof(func_reset),\n+\t\t\t\t     &func_reset, &out_size, 0);\n+\tif (err || !out_size || func_reset.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Reset func resources failed, err: %d, \"\n+\t\t\t    \"status: 0x%x, out_size: 0x%x\",\n+\t\t\t    err, func_reset.status, out_size);\n+\t\treturn -EIO;\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;\n@@ -261,3 +286,99 @@ int spnic_set_dma_attr_tbl(struct spnic_hwdev *hwdev, u32 entry_idx, u8 st,\n \n \treturn 0;\n }\n+\n+int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len)\n+{\n+\tstruct spnic_cmd_get_fw_version fw_ver;\n+\tu16 out_size = sizeof(fw_ver);\n+\tint err;\n+\n+\tif (!hwdev || !mgmt_ver)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&fw_ver, 0, sizeof(fw_ver));\n+\tfw_ver.fw_type = SPNIC_FW_VER_TYPE_MPU;\n+\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM,\n+\t\t\t\t     MGMT_CMD_GET_FW_VERSION,\n+\t\t\t\t     &fw_ver, sizeof(fw_ver), &fw_ver,\n+\t\t\t\t     &out_size, 0);\n+\tif (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, fw_ver.status)) {\n+\t\tPMD_DRV_LOG(ERR, \"Get mgmt version failed, err: %d, status: 0x%x, out size: 0x%x\",\n+\t\t\t    err, fw_ver.status, out_size);\n+\t\treturn -EIO;\n+\t}\n+\n+\tsnprintf(mgmt_ver, max_mgmt_len, \"%s\", fw_ver.ver);\n+\n+\treturn 0;\n+}\n+\n+int spnic_get_board_info(void *hwdev, struct spnic_board_info *info)\n+{\n+\tstruct spnic_cmd_board_info board_info;\n+\tu16 out_size = sizeof(board_info);\n+\tint err;\n+\n+\tif (!hwdev || !info)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&board_info, 0, sizeof(board_info));\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM,\n+\t\t\t\t     MGMT_CMD_GET_BOARD_INFO,\n+\t\t\t\t     &board_info, sizeof(board_info),\n+\t\t\t\t     &board_info, &out_size, 0);\n+\tif (err || board_info.status || !out_size) {\n+\t\tPMD_DRV_LOG(ERR, \"Get board info failed, err: %d, status: 0x%x, out size: 0x%x\",\n+\t\t\t    err, board_info.status, out_size);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tmemcpy(info, &board_info.info, sizeof(*info));\n+\n+\treturn 0;\n+}\n+\n+static int spnic_comm_features_nego(void *hwdev, u8 opcode, u64 *s_feature,\n+\t\t\t\t     u16 size)\n+{\n+\tstruct comm_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 == MGMT_MSG_CMD_OP_SET)\n+\t\tmemcpy(feature_nego.s_feature, s_feature, (size * sizeof(u64)));\n+\n+\terr = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM,\n+\t\t\t\t     MGMT_CMD_FEATURE_NEGO,\n+\t\t\t\t     &feature_nego, sizeof(feature_nego),\n+\t\t\t\t     &feature_nego, &out_size, 0);\n+\tif (err || !out_size || feature_nego.head.status) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to negotiate feature, err: %d, status: 0x%x, out size: 0x%x\\n\",\n+\t\t\terr, feature_nego.head.status, out_size);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (opcode == MGMT_MSG_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_comm_features(void *hwdev, u64 *s_feature, u16 size)\n+{\n+\treturn spnic_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_GET, s_feature,\n+\t\t\t\t\t size);\n+}\n+\n+int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size)\n+{\n+\treturn spnic_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_SET, s_feature,\n+\t\t\t\t\t size);\n+}\ndiff --git a/drivers/net/spnic/base/spnic_hw_comm.h b/drivers/net/spnic/base/spnic_hw_comm.h\nindex c905f49b7a..207f0aaeae 100644\n--- a/drivers/net/spnic/base/spnic_hw_comm.h\n+++ b/drivers/net/spnic/base/spnic_hw_comm.h\n@@ -96,6 +96,18 @@ enum spnic_fw_ver_type {\n \tSPNIC_FW_VER_TYPE_CFG,\n };\n \n+#define MGMT_MSG_CMD_OP_SET\t1\n+#define MGMT_MSG_CMD_OP_GET\t0\n+\n+struct comm_cmd_feature_nego {\n+\tstruct mgmt_msg_head 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 struct comm_cmd_dma_attr_config {\n \tstruct mgmt_msg_head head;\n \n@@ -162,6 +174,12 @@ struct interrupt_info {\n \tu8 resend_timer_cfg;\n };\n \n+int spnic_func_reset(void *hwdev, u64 reset_flag);\n+\n+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_get_interrupt_cfg(void *dev, struct interrupt_info *info);\n \n int spnic_set_interrupt_cfg(void *dev, struct interrupt_info info);\n@@ -170,6 +188,10 @@ 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_get_comm_features(void *hwdev, u64 *s_feature, u16 size);\n+\n+int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size);\n+\n int spnic_set_dma_attr_tbl(struct spnic_hwdev *hwdev, u32 entry_idx, u8 st,\n \t\t\t   u8 at, u8 ph, u8 no_snooping, u8 tph_en);\n \ndiff --git a/drivers/net/spnic/base/spnic_hwdev.c b/drivers/net/spnic/base/spnic_hwdev.c\nindex 00b3b41d97..bd5b1d57cb 100644\n--- a/drivers/net/spnic/base/spnic_hwdev.c\n+++ b/drivers/net/spnic/base/spnic_hwdev.c\n@@ -11,6 +11,7 @@\n #include \"spnic_mbox.h\"\n #include \"spnic_wq.h\"\n #include \"spnic_cmdq.h\"\n+#include \"spnic_hw_cfg.h\"\n #include \"spnic_hwdev.h\"\n #include \"spnic_hw_comm.h\"\n \n@@ -283,6 +284,35 @@ static void spnic_comm_cmdqs_free(struct spnic_hwdev *hwdev)\n \tspnic_cmdqs_free(hwdev);\n }\n \n+static void spnic_sync_mgmt_func_state(struct spnic_hwdev *hwdev)\n+{\n+\tspnic_set_pf_status(hwdev->hwif, SPNIC_PF_STATUS_ACTIVE_FLAG);\n+}\n+\n+static int __get_func_misc_info(struct spnic_hwdev *hwdev)\n+{\n+\tint err;\n+\n+\terr = spnic_get_board_info(hwdev, &hwdev->board_info);\n+\tif (err) {\n+\t\t/* For the PF/VF of slave host, return error */\n+\t\tif (spnic_pcie_itf_id(hwdev))\n+\t\t\treturn err;\n+\n+\t\tmemset(&hwdev->board_info, 0xff,\n+\t\t       sizeof(struct spnic_board_info));\n+\t}\n+\n+\terr = spnic_get_mgmt_version(hwdev, hwdev->mgmt_ver,\n+\t\t\tSPNIC_MGMT_VERSION_MAX_LEN);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Get mgmt cpu version failed\");\n+\t\treturn err;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int init_mgmt_channel(struct spnic_hwdev *hwdev)\n {\n \tint err;\n@@ -375,15 +405,31 @@ static int spnic_init_comm_ch(struct spnic_hwdev *hwdev)\n \t\treturn err;\n \t}\n \n+\terr = __get_func_misc_info(hwdev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Get function msic information failed\");\n+\t\tgoto get_func_info_err;\n+\t}\n+\n+\terr = spnic_func_reset(hwdev, SPNIC_NIC_RES | SPNIC_COMM_RES);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Reset function failed\");\n+\t\tgoto func_reset_err;\n+\t}\n+\n \terr = init_cmdqs_channel(hwdev);\n \tif (err) {\n \t\tPMD_DRV_LOG(ERR, \"Init cmdq channel failed\");\n \t\tgoto init_cmdqs_channel_err;\n \t}\n \n+\tspnic_sync_mgmt_func_state(hwdev);\n+\n \treturn 0;\n \n init_cmdqs_channel_err:\n+func_reset_err:\n+get_func_info_err:\n \tfree_mgmt_channel(hwdev);\n \n \treturn err;\n@@ -391,11 +437,14 @@ static int spnic_init_comm_ch(struct spnic_hwdev *hwdev)\n \n static void spnic_uninit_comm_ch(struct spnic_hwdev *hwdev)\n {\n+\tspnic_set_pf_status(hwdev->hwif, SPNIC_PF_STATUS_INIT);\n+\n \tspnic_comm_cmdqs_free(hwdev);\n \n \tif (SPNIC_FUNC_TYPE(hwdev) != TYPE_VF)\n \t\tspnic_set_wq_page_size(hwdev, spnic_global_func_id(hwdev),\n \t\t\t\t\tSPNIC_HW_WQ_PAGE_SIZE);\n+\n \tfree_mgmt_channel(hwdev);\n }\n \n@@ -423,8 +472,27 @@ int spnic_init_hwdev(struct spnic_hwdev *hwdev)\n \t\tgoto init_comm_ch_err;\n \t}\n \n+\terr = spnic_init_capability(hwdev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Init capability failed\");\n+\t\tgoto init_cap_err;\n+\t}\n+\n+\terr = spnic_set_comm_features(hwdev, hwdev->features,\n+\t\t\t\t       MAX_FEATURE_QWORD);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set comm features\\n\");\n+\t\tgoto set_feature_err;\n+\t}\n+\n \treturn 0;\n \n+set_feature_err:\n+\tspnic_free_capability(hwdev);\n+\n+init_cap_err:\n+\tspnic_uninit_comm_ch(hwdev);\n+\n init_comm_ch_err:\n \tspnic_free_hwif(hwdev);\n \n@@ -436,6 +504,8 @@ int spnic_init_hwdev(struct spnic_hwdev *hwdev)\n \n void spnic_free_hwdev(struct spnic_hwdev *hwdev)\n {\n+\tspnic_free_capability(hwdev);\n+\n \tspnic_uninit_comm_ch(hwdev);\n \n \tspnic_free_hwif(hwdev);\ndiff --git a/drivers/net/spnic/base/spnic_hwdev.h b/drivers/net/spnic/base/spnic_hwdev.h\nindex 3b055dd732..d9dce12764 100644\n--- a/drivers/net/spnic/base/spnic_hwdev.h\n+++ b/drivers/net/spnic/base/spnic_hwdev.h\n@@ -100,6 +100,7 @@ struct spnic_board_info {\n \tu32 cfg_addr;\n };\n \n+#define MAX_FEATURE_QWORD\t4\n struct spnic_hwdev {\n \tvoid *dev_handle; /* Pointer to spnic_nic_dev */\n \tvoid *pci_dev; /* Pointer to rte_pci_device */\n@@ -117,7 +118,11 @@ struct spnic_hwdev {\n \n \tstruct spnic_msg_pf_to_mgmt *pf_to_mgmt;\n \tu8 *chip_fault_stats;\n+\n \tstruct spnic_hw_stats hw_stats;\n+\tstruct spnic_board_info board_info;\n+\tchar mgmt_ver[MGMT_VERSION_MAX_LEN];\n+\tu64 features[MAX_FEATURE_QWORD];\n \n \tu16 max_vfs;\n \tu16 link_status;\ndiff --git a/drivers/net/spnic/base/spnic_mbox.c b/drivers/net/spnic/base/spnic_mbox.c\nindex 5c39e307be..cdb7d31e8c 100644\n--- a/drivers/net/spnic/base/spnic_mbox.c\n+++ b/drivers/net/spnic/base/spnic_mbox.c\n@@ -10,6 +10,7 @@\n #include \"spnic_mgmt.h\"\n #include \"spnic_hwif.h\"\n #include \"spnic_eqs.h\"\n+#include \"spnic_hw_cfg.h\"\n #include \"spnic_mbox.h\"\n #include \"spnic_nic_event.h\"\n \n@@ -150,6 +151,13 @@ static int recv_vf_mbox_handler(struct spnic_mbox *func_to_func,\n \t\t\t\t\t     recv_mbox->mbox_len,\n \t\t\t\t\t     buf_out, out_size);\n \t\tbreak;\n+\tcase SPNIC_MOD_CFGM:\n+\t\terr = cfg_mbx_vf_proc_msg(func_to_func->hwdev,\n+\t\t\t\t\t  func_to_func->hwdev->cfg_mgmt,\n+\t\t\t\t\t  recv_mbox->cmd, recv_mbox->mbox,\n+\t\t\t\t\t  recv_mbox->mbox_len,\n+\t\t\t\t\t  buf_out, out_size);\n+\t\tbreak;\n \tcase SPNIC_MOD_L2NIC:\n \t\terr = spnic_vf_event_handler(func_to_func->hwdev,\n \t\t\t\t\t     func_to_func->hwdev->cfg_mgmt,\n",
    "prefixes": [
        "v1",
        "08/25"
    ]
}