[PATCH v6 08/26] net/spnic: add hardware info initialization
From: Yanling Song <hidden>
Date: 2021-12-30 06:10:10
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
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 <redacted> --- 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..ac76b2632e
--- /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 spnic_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..5003d048e6
--- /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 spnic_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 3b2373e027..cf4328a04b 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 7e348c3139..9dc4fdc2d6 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 secondary 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 2f25c0d0d3..3bb8a3c31f 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 4b4c4311eb..9cde0a122f 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 = spnic_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.32.0