This commits add hardware info initialization, including
that device capability initialization, common feature
negotiation, and two interfaces spnic_get_board_info(),
spnic_get_mgmt_version() to get hardware info and
firmware version.

Signed-off-by: Yanling Song <son...@ramaxel.com>
---
 drivers/net/spnic/base/meson.build     |   3 +-
 drivers/net/spnic/base/spnic_hw_cfg.c  | 157 +++++++++++++++++++++++++
 drivers/net/spnic/base/spnic_hw_cfg.h  | 117 ++++++++++++++++++
 drivers/net/spnic/base/spnic_hw_comm.c | 121 +++++++++++++++++++
 drivers/net/spnic/base/spnic_hw_comm.h |  22 ++++
 drivers/net/spnic/base/spnic_hwdev.c   |  70 +++++++++++
 drivers/net/spnic/base/spnic_hwdev.h   |   5 +
 drivers/net/spnic/base/spnic_mbox.c    |   8 ++
 8 files changed, 502 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.c
 create mode 100644 drivers/net/spnic/base/spnic_hw_cfg.h

diff --git a/drivers/net/spnic/base/meson.build 
b/drivers/net/spnic/base/meson.build
index da6d6ee4a2..77a56ca41e 100644
--- a/drivers/net/spnic/base/meson.build
+++ b/drivers/net/spnic/base/meson.build
@@ -10,7 +10,8 @@ sources = [
        'spnic_nic_event.c',
        'spnic_cmdq.c',
        'spnic_hw_comm.c',
-       'spnic_wq.c'
+       'spnic_wq.c',
+       'spnic_hw_cfg.c'
 ]
 
 extra_flags = []
diff --git a/drivers/net/spnic/base/spnic_hw_cfg.c 
b/drivers/net/spnic/base/spnic_hw_cfg.c
new file mode 100644
index 0000000000..e8856ce9fe
--- /dev/null
+++ b/drivers/net/spnic/base/spnic_hw_cfg.c
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#include "spnic_compat.h"
+#include "spnic_mgmt.h"
+#include "spnic_mbox.h"
+#include "spnic_hwdev.h"
+#include "spnic_hwif.h"
+#include "spnic_hw_cfg.h"
+
+static void parse_pub_res_cap(struct service_cap *cap,
+                             struct spnic_cfg_cmd_dev_cap *dev_cap,
+                             enum func_type type)
+{
+       cap->host_id = dev_cap->host_id;
+       cap->ep_id = dev_cap->ep_id;
+       cap->er_id = dev_cap->er_id;
+       cap->port_id = dev_cap->port_id;
+
+       cap->svc_type = dev_cap->svc_cap_en;
+       cap->chip_svc_type = cap->svc_type;
+
+       cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap;
+       cap->flexq_en = dev_cap->flexq_en;
+
+       cap->host_total_function = dev_cap->host_total_func;
+       cap->max_vf = 0;
+       if (type == TYPE_PF || type == TYPE_PPF) {
+               cap->max_vf = dev_cap->max_vf;
+               cap->pf_num = dev_cap->host_pf_num;
+               cap->pf_id_start = dev_cap->pf_id_start;
+               cap->vf_num = dev_cap->host_vf_num;
+               cap->vf_id_start = dev_cap->vf_id_start;
+       }
+
+       PMD_DRV_LOG(INFO, "Get public resource capability: ");
+       PMD_DRV_LOG(INFO, "host_id: 0x%x, ep_id: 0x%x, er_id: 0x%x, "
+                   "port_id: 0x%x",
+                   cap->host_id, cap->ep_id, cap->er_id, cap->port_id);
+       PMD_DRV_LOG(INFO, "host_total_function: 0x%x, max_vf: 0x%x",
+                   cap->host_total_function, cap->max_vf);
+       PMD_DRV_LOG(INFO, "host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 
0x%x, vf_id_start: 0x%x",
+                   cap->pf_num, cap->pf_id_start,
+                   cap->vf_num, cap->vf_id_start);
+}
+
+static void parse_l2nic_res_cap(struct service_cap *cap,
+                               struct spnic_cfg_cmd_dev_cap *dev_cap)
+{
+       struct nic_service_cap *nic_cap = &cap->nic_cap;
+
+       nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
+       nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
+
+       PMD_DRV_LOG(INFO, "L2nic resource capbility, max_sqs: 0x%x, "
+                   "max_rqs: 0x%x",
+                   nic_cap->max_sqs, nic_cap->max_rqs);
+}
+
+static void parse_dev_cap(struct spnic_hwdev *dev,
+                         struct spnic_cfg_cmd_dev_cap *dev_cap,
+                         enum func_type type)
+{
+       struct service_cap *cap = &dev->cfg_mgmt->svc_cap;
+
+       parse_pub_res_cap(cap, dev_cap, type);
+
+       if (IS_NIC_TYPE(dev))
+               parse_l2nic_res_cap(cap, dev_cap);
+}
+
+static int get_cap_from_fw(struct spnic_hwdev *hwdev, enum func_type type)
+{
+       struct spnic_cfg_cmd_dev_cap dev_cap;
+       u16 out_len = sizeof(dev_cap);
+       int err;
+
+       memset(&dev_cap, 0, sizeof(dev_cap));
+       dev_cap.func_id = spnic_global_func_id(hwdev);
+       err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_CFGM,
+                                    SPNIC_CFG_CMD_GET_DEV_CAP,
+                                    &dev_cap, sizeof(dev_cap),
+                                    &dev_cap, &out_len, 0);
+       if (err || dev_cap.status || !out_len) {
+               PMD_DRV_LOG(ERR, "Get capability from FW failed, err: %d, "
+                           "status: 0x%x, out size: 0x%x",
+                           err, dev_cap.status, out_len);
+               return -EFAULT;
+       }
+
+       parse_dev_cap(hwdev, &dev_cap, type);
+       return 0;
+}
+
+static int get_dev_cap(struct spnic_hwdev *hwdev)
+{
+       enum func_type type = SPNIC_FUNC_TYPE(hwdev);
+
+       switch (type) {
+       case TYPE_PF:
+       case TYPE_PPF:
+       case TYPE_VF:
+               if (get_cap_from_fw(hwdev, type) != 0)
+                       return -EFAULT;
+               break;
+       default:
+               PMD_DRV_LOG(ERR, "Unsupported PCIe function type: %d", type);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int cfg_mbx_vf_proc_msg(void *hwdev, __rte_unused void *pri_handle, u16 cmd,
+                       __rte_unused void *buf_in, __rte_unused u16 in_size,
+                       __rte_unused void *buf_out, __rte_unused u16 *out_size)
+{
+       struct spnic_hwdev *dev = hwdev;
+
+       if (!dev)
+               return -EINVAL;
+
+       PMD_DRV_LOG(WARNING,
+                   "Unsupported cfg mbox vf event %d to process", cmd);
+
+       return 0;
+}
+
+int spnic_init_capability(void *dev)
+{
+       struct spnic_hwdev *hwdev = (struct spnic_hwdev *)dev;
+       struct cfg_mgmt_info *cfg_mgmt = NULL;
+       int err;
+
+       cfg_mgmt = rte_zmalloc("cfg_mgmt", sizeof(*cfg_mgmt),
+                              SPNIC_MEM_ALLOC_ALIGN_MIN);
+       if (!cfg_mgmt)
+               return -ENOMEM;
+
+       memset(cfg_mgmt, 0, sizeof(struct cfg_mgmt_info));
+       hwdev->cfg_mgmt = cfg_mgmt;
+       cfg_mgmt->hwdev = hwdev;
+
+       err = get_dev_cap(hwdev);
+       if (err) {
+               rte_free(cfg_mgmt);
+               hwdev->cfg_mgmt = NULL;
+       }
+
+       return err;
+}
+
+void spnic_free_capability(void *dev)
+{
+       rte_free(((struct spnic_hwdev *)dev)->cfg_mgmt);
+}
diff --git a/drivers/net/spnic/base/spnic_hw_cfg.h 
b/drivers/net/spnic/base/spnic_hw_cfg.h
new file mode 100644
index 0000000000..1b1b598726
--- /dev/null
+++ b/drivers/net/spnic/base/spnic_hw_cfg.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd
+ */
+
+#ifndef _SPNIC_HW_CFG_H_
+#define _SPNIC_HW_CFG_H_
+
+#define CFG_MAX_CMD_TIMEOUT    30000 /* ms */
+
+#define K_UNIT              BIT(10)
+#define M_UNIT              BIT(20)
+#define G_UNIT              BIT(30)
+
+/* Number of PFs and VFs */
+#define HOST_PF_NUM            4
+#define HOST_VF_NUM            0
+#define HOST_OQID_MASK_VAL     2
+
+#define L2NIC_SQ_DEPTH      (4 * K_UNIT)
+#define L2NIC_RQ_DEPTH      (4 * K_UNIT)
+
+enum intr_type {
+       INTR_TYPE_MSIX,
+       INTR_TYPE_MSI,
+       INTR_TYPE_INT,
+       INTR_TYPE_NONE
+};
+
+/* Service type relates define */
+enum cfg_svc_type_en {
+       CFG_SVC_NIC_BIT0 = (1 << 0)
+};
+
+struct nic_service_cap {
+       u16 max_sqs;
+       u16 max_rqs;
+};
+
+/* Device capability */
+struct service_cap {
+       enum cfg_svc_type_en svc_type; /* User input service type */
+       enum cfg_svc_type_en chip_svc_type; /* HW supported service type */
+
+       u8 host_id;
+       u8 ep_id;
+       u8 er_id;       /* PF/VF's ER */
+       u8 port_id;     /* PF/VF's physical port */
+
+       u16 host_total_function;
+       u8 pf_num;
+       u8 pf_id_start;
+       u16 vf_num;     /* max numbers of vf in current host */
+       u16 vf_id_start;
+
+       u8 flexq_en;
+       u8 cos_valid_bitmap;
+       u16 max_vf;     /* max VF number that PF supported */
+
+       struct nic_service_cap nic_cap; /* NIC capability */
+};
+
+struct cfg_mgmt_info {
+       void *hwdev;
+       struct service_cap svc_cap;
+};
+
+enum spnic_cfg_cmd {
+       SPNIC_CFG_CMD_GET_DEV_CAP = 0,
+};
+
+struct spnic_cfg_cmd_dev_cap {
+       u8 status;
+       u8 version;
+       u8 rsvd0[6];
+
+       u16 func_id;
+       u16 rsvd1;
+
+       /* Public resource */
+       u8 host_id;
+       u8 ep_id;
+       u8 er_id;
+       u8 port_id;
+
+       u16 host_total_func;
+       u8 host_pf_num;
+       u8 pf_id_start;
+       u16 host_vf_num;
+       u16 vf_id_start;
+       u32 rsvd_host;
+
+       u16 svc_cap_en;
+       u16 max_vf;
+       u8 flexq_en;
+       u8 valid_cos_bitmap;
+       /* Reserved for func_valid_cos_bitmap */
+       u16 rsvd_cos;
+
+       u32 rsvd[11];
+
+       /* l2nic */
+       u16 nic_max_sq_id;
+       u16 nic_max_rq_id;
+       u32 rsvd_nic[3];
+
+       u32 rsvd_glb[60];
+};
+
+#define IS_NIC_TYPE(dev) \
+       (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SVC_NIC_BIT0)
+
+int spnic_init_capability(void *dev);
+void spnic_free_capability(void *dev);
+
+int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in,
+                       u16 in_size, void *buf_out, u16 *out_size);
+#endif /* _SPNIC_HW_CFG_H_ */
diff --git a/drivers/net/spnic/base/spnic_hw_comm.c 
b/drivers/net/spnic/base/spnic_hw_comm.c
index 48730ce7fe..5cb607cf03 100644
--- a/drivers/net/spnic/base/spnic_hw_comm.c
+++ b/drivers/net/spnic/base/spnic_hw_comm.c
@@ -192,6 +192,31 @@ int spnic_set_wq_page_size(void *hwdev, u16 func_idx, u32 
page_size)
        return 0;
 }
 
+int spnic_func_reset(void *hwdev, u64 reset_flag)
+{
+       struct spnic_reset func_reset;
+       struct spnic_hwif *hwif = ((struct spnic_hwdev *)hwdev)->hwif;
+       u16 out_size = sizeof(func_reset);
+       int err = 0;
+
+       PMD_DRV_LOG(INFO, "Function is reset");
+
+       memset(&func_reset, 0, sizeof(func_reset));
+       func_reset.func_id = SPNIC_HWIF_GLOBAL_IDX(hwif);
+       func_reset.reset_flag = reset_flag;
+       err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM, MGMT_CMD_FUNC_RESET,
+                                    &func_reset, sizeof(func_reset),
+                                    &func_reset, &out_size, 0);
+       if (err || !out_size || func_reset.status) {
+               PMD_DRV_LOG(ERR, "Reset func resources failed, err: %d, "
+                           "status: 0x%x, out_size: 0x%x",
+                           err, func_reset.status, out_size);
+               return -EIO;
+       }
+
+       return 0;
+}
+
 int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth)
 {
        struct spnic_cmd_root_ctxt root_ctxt;
@@ -261,3 +286,99 @@ int spnic_set_dma_attr_tbl(struct spnic_hwdev *hwdev, u32 
entry_idx, u8 st,
 
        return 0;
 }
+
+int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len)
+{
+       struct spnic_cmd_get_fw_version fw_ver;
+       u16 out_size = sizeof(fw_ver);
+       int err;
+
+       if (!hwdev || !mgmt_ver)
+               return -EINVAL;
+
+       memset(&fw_ver, 0, sizeof(fw_ver));
+       fw_ver.fw_type = SPNIC_FW_VER_TYPE_MPU;
+
+       err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM,
+                                    MGMT_CMD_GET_FW_VERSION,
+                                    &fw_ver, sizeof(fw_ver), &fw_ver,
+                                    &out_size, 0);
+       if (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, fw_ver.status)) {
+               PMD_DRV_LOG(ERR, "Get mgmt version failed, err: %d, status: 
0x%x, out size: 0x%x",
+                           err, fw_ver.status, out_size);
+               return -EIO;
+       }
+
+       snprintf(mgmt_ver, max_mgmt_len, "%s", fw_ver.ver);
+
+       return 0;
+}
+
+int spnic_get_board_info(void *hwdev, struct spnic_board_info *info)
+{
+       struct spnic_cmd_board_info board_info;
+       u16 out_size = sizeof(board_info);
+       int err;
+
+       if (!hwdev || !info)
+               return -EINVAL;
+
+       memset(&board_info, 0, sizeof(board_info));
+       err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM,
+                                    MGMT_CMD_GET_BOARD_INFO,
+                                    &board_info, sizeof(board_info),
+                                    &board_info, &out_size, 0);
+       if (err || board_info.status || !out_size) {
+               PMD_DRV_LOG(ERR, "Get board info failed, err: %d, status: 0x%x, 
out size: 0x%x",
+                           err, board_info.status, out_size);
+               return -EFAULT;
+       }
+
+       memcpy(info, &board_info.info, sizeof(*info));
+
+       return 0;
+}
+
+static int spnic_comm_features_nego(void *hwdev, u8 opcode, u64 *s_feature,
+                                    u16 size)
+{
+       struct comm_cmd_feature_nego feature_nego;
+       u16 out_size = sizeof(feature_nego);
+       int err;
+
+       if (!hwdev || !s_feature || size > MAX_FEATURE_QWORD)
+               return -EINVAL;
+
+       memset(&feature_nego, 0, sizeof(feature_nego));
+       feature_nego.func_id = spnic_global_func_id(hwdev);
+       feature_nego.opcode = opcode;
+       if (opcode == MGMT_MSG_CMD_OP_SET)
+               memcpy(feature_nego.s_feature, s_feature, (size * sizeof(u64)));
+
+       err = spnic_msg_to_mgmt_sync(hwdev, SPNIC_MOD_COMM,
+                                    MGMT_CMD_FEATURE_NEGO,
+                                    &feature_nego, sizeof(feature_nego),
+                                    &feature_nego, &out_size, 0);
+       if (err || !out_size || feature_nego.head.status) {
+               PMD_DRV_LOG(ERR, "Failed to negotiate feature, err: %d, status: 
0x%x, out size: 0x%x\n",
+                       err, feature_nego.head.status, out_size);
+               return -EINVAL;
+       }
+
+       if (opcode == MGMT_MSG_CMD_OP_GET)
+               memcpy(s_feature, feature_nego.s_feature, (size * sizeof(u64)));
+
+       return 0;
+}
+
+int spnic_get_comm_features(void *hwdev, u64 *s_feature, u16 size)
+{
+       return spnic_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_GET, s_feature,
+                                        size);
+}
+
+int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size)
+{
+       return spnic_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_SET, s_feature,
+                                        size);
+}
diff --git a/drivers/net/spnic/base/spnic_hw_comm.h 
b/drivers/net/spnic/base/spnic_hw_comm.h
index c905f49b7a..207f0aaeae 100644
--- a/drivers/net/spnic/base/spnic_hw_comm.h
+++ b/drivers/net/spnic/base/spnic_hw_comm.h
@@ -96,6 +96,18 @@ enum spnic_fw_ver_type {
        SPNIC_FW_VER_TYPE_CFG,
 };
 
+#define MGMT_MSG_CMD_OP_SET    1
+#define MGMT_MSG_CMD_OP_GET    0
+
+struct comm_cmd_feature_nego {
+       struct mgmt_msg_head head;
+
+       u16 func_id;
+       u8 opcode;      /* 1: set, 0: get */
+       u8 rsvd;
+       u64 s_feature[MAX_FEATURE_QWORD];
+};
+
 struct comm_cmd_dma_attr_config {
        struct mgmt_msg_head head;
 
@@ -162,6 +174,12 @@ struct interrupt_info {
        u8 resend_timer_cfg;
 };
 
+int spnic_func_reset(void *hwdev, u64 reset_flag);
+
+int spnic_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len);
+
+int spnic_get_board_info(void *hwdev, struct spnic_board_info *info);
+
 int spnic_get_interrupt_cfg(void *dev, struct interrupt_info *info);
 
 int spnic_set_interrupt_cfg(void *dev, struct interrupt_info info);
@@ -170,6 +188,10 @@ int spnic_set_wq_page_size(void *hwdev, u16 func_idx, u32 
page_size);
 
 int spnic_set_cmdq_depth(void *hwdev, u16 cmdq_depth);
 
+int spnic_get_comm_features(void *hwdev, u64 *s_feature, u16 size);
+
+int spnic_set_comm_features(void *hwdev, u64 *s_feature, u16 size);
+
 int spnic_set_dma_attr_tbl(struct spnic_hwdev *hwdev, u32 entry_idx, u8 st,
                           u8 at, u8 ph, u8 no_snooping, u8 tph_en);
 
diff --git a/drivers/net/spnic/base/spnic_hwdev.c 
b/drivers/net/spnic/base/spnic_hwdev.c
index 00b3b41d97..bd5b1d57cb 100644
--- a/drivers/net/spnic/base/spnic_hwdev.c
+++ b/drivers/net/spnic/base/spnic_hwdev.c
@@ -11,6 +11,7 @@
 #include "spnic_mbox.h"
 #include "spnic_wq.h"
 #include "spnic_cmdq.h"
+#include "spnic_hw_cfg.h"
 #include "spnic_hwdev.h"
 #include "spnic_hw_comm.h"
 
@@ -283,6 +284,35 @@ static void spnic_comm_cmdqs_free(struct spnic_hwdev 
*hwdev)
        spnic_cmdqs_free(hwdev);
 }
 
+static void spnic_sync_mgmt_func_state(struct spnic_hwdev *hwdev)
+{
+       spnic_set_pf_status(hwdev->hwif, SPNIC_PF_STATUS_ACTIVE_FLAG);
+}
+
+static int __get_func_misc_info(struct spnic_hwdev *hwdev)
+{
+       int err;
+
+       err = spnic_get_board_info(hwdev, &hwdev->board_info);
+       if (err) {
+               /* For the PF/VF of slave host, return error */
+               if (spnic_pcie_itf_id(hwdev))
+                       return err;
+
+               memset(&hwdev->board_info, 0xff,
+                      sizeof(struct spnic_board_info));
+       }
+
+       err = spnic_get_mgmt_version(hwdev, hwdev->mgmt_ver,
+                       SPNIC_MGMT_VERSION_MAX_LEN);
+       if (err) {
+               PMD_DRV_LOG(ERR, "Get mgmt cpu version failed");
+               return err;
+       }
+
+       return 0;
+}
+
 static int init_mgmt_channel(struct spnic_hwdev *hwdev)
 {
        int err;
@@ -375,15 +405,31 @@ static int spnic_init_comm_ch(struct spnic_hwdev *hwdev)
                return err;
        }
 
+       err = __get_func_misc_info(hwdev);
+       if (err) {
+               PMD_DRV_LOG(ERR, "Get function msic information failed");
+               goto get_func_info_err;
+       }
+
+       err = spnic_func_reset(hwdev, SPNIC_NIC_RES | SPNIC_COMM_RES);
+       if (err) {
+               PMD_DRV_LOG(ERR, "Reset function failed");
+               goto func_reset_err;
+       }
+
        err = init_cmdqs_channel(hwdev);
        if (err) {
                PMD_DRV_LOG(ERR, "Init cmdq channel failed");
                goto init_cmdqs_channel_err;
        }
 
+       spnic_sync_mgmt_func_state(hwdev);
+
        return 0;
 
 init_cmdqs_channel_err:
+func_reset_err:
+get_func_info_err:
        free_mgmt_channel(hwdev);
 
        return err;
@@ -391,11 +437,14 @@ static int spnic_init_comm_ch(struct spnic_hwdev *hwdev)
 
 static void spnic_uninit_comm_ch(struct spnic_hwdev *hwdev)
 {
+       spnic_set_pf_status(hwdev->hwif, SPNIC_PF_STATUS_INIT);
+
        spnic_comm_cmdqs_free(hwdev);
 
        if (SPNIC_FUNC_TYPE(hwdev) != TYPE_VF)
                spnic_set_wq_page_size(hwdev, spnic_global_func_id(hwdev),
                                        SPNIC_HW_WQ_PAGE_SIZE);
+
        free_mgmt_channel(hwdev);
 }
 
@@ -423,8 +472,27 @@ int spnic_init_hwdev(struct spnic_hwdev *hwdev)
                goto init_comm_ch_err;
        }
 
+       err = spnic_init_capability(hwdev);
+       if (err) {
+               PMD_DRV_LOG(ERR, "Init capability failed");
+               goto init_cap_err;
+       }
+
+       err = spnic_set_comm_features(hwdev, hwdev->features,
+                                      MAX_FEATURE_QWORD);
+       if (err) {
+               PMD_DRV_LOG(ERR, "Failed to set comm features\n");
+               goto set_feature_err;
+       }
+
        return 0;
 
+set_feature_err:
+       spnic_free_capability(hwdev);
+
+init_cap_err:
+       spnic_uninit_comm_ch(hwdev);
+
 init_comm_ch_err:
        spnic_free_hwif(hwdev);
 
@@ -436,6 +504,8 @@ int spnic_init_hwdev(struct spnic_hwdev *hwdev)
 
 void spnic_free_hwdev(struct spnic_hwdev *hwdev)
 {
+       spnic_free_capability(hwdev);
+
        spnic_uninit_comm_ch(hwdev);
 
        spnic_free_hwif(hwdev);
diff --git a/drivers/net/spnic/base/spnic_hwdev.h 
b/drivers/net/spnic/base/spnic_hwdev.h
index 3b055dd732..d9dce12764 100644
--- a/drivers/net/spnic/base/spnic_hwdev.h
+++ b/drivers/net/spnic/base/spnic_hwdev.h
@@ -100,6 +100,7 @@ struct spnic_board_info {
        u32 cfg_addr;
 };
 
+#define MAX_FEATURE_QWORD      4
 struct spnic_hwdev {
        void *dev_handle; /* Pointer to spnic_nic_dev */
        void *pci_dev; /* Pointer to rte_pci_device */
@@ -117,7 +118,11 @@ struct spnic_hwdev {
 
        struct spnic_msg_pf_to_mgmt *pf_to_mgmt;
        u8 *chip_fault_stats;
+
        struct spnic_hw_stats hw_stats;
+       struct spnic_board_info board_info;
+       char mgmt_ver[MGMT_VERSION_MAX_LEN];
+       u64 features[MAX_FEATURE_QWORD];
 
        u16 max_vfs;
        u16 link_status;
diff --git a/drivers/net/spnic/base/spnic_mbox.c 
b/drivers/net/spnic/base/spnic_mbox.c
index 5c39e307be..cdb7d31e8c 100644
--- a/drivers/net/spnic/base/spnic_mbox.c
+++ b/drivers/net/spnic/base/spnic_mbox.c
@@ -10,6 +10,7 @@
 #include "spnic_mgmt.h"
 #include "spnic_hwif.h"
 #include "spnic_eqs.h"
+#include "spnic_hw_cfg.h"
 #include "spnic_mbox.h"
 #include "spnic_nic_event.h"
 
@@ -150,6 +151,13 @@ static int recv_vf_mbox_handler(struct spnic_mbox 
*func_to_func,
                                             recv_mbox->mbox_len,
                                             buf_out, out_size);
                break;
+       case SPNIC_MOD_CFGM:
+               err = cfg_mbx_vf_proc_msg(func_to_func->hwdev,
+                                         func_to_func->hwdev->cfg_mgmt,
+                                         recv_mbox->cmd, recv_mbox->mbox,
+                                         recv_mbox->mbox_len,
+                                         buf_out, out_size);
+               break;
        case SPNIC_MOD_L2NIC:
                err = spnic_vf_event_handler(func_to_func->hwdev,
                                             func_to_func->hwdev->cfg_mgmt,
-- 
2.27.0

Reply via email to