Use mailbox to get device capability for initializing driver capability. Co-developed-by: Zhu Yikai Signed-off-by: Zhu Yikai Signed-off-by: Fan Gong --- .../ethernet/huawei/hinic3/hinic3_hw_cfg.c | 66 +++++++++++++++++++ .../ethernet/huawei/hinic3/hinic3_hw_cfg.h | 1 + .../ethernet/huawei/hinic3/hinic3_hw_intf.h | 42 ++++++++++++ .../net/ethernet/huawei/hinic3/hinic3_hwdev.c | 6 ++ 4 files changed, 115 insertions(+) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c index 8db5e2c9ff10..7827c1f626db 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c @@ -8,6 +8,67 @@ #include "hinic3_hwif.h" #include "hinic3_mbox.h" +#define HINIC3_CFG_MAX_QP 256 + +static void hinic3_parse_pub_res_cap(struct hinic3_hwdev *hwdev, + struct hinic3_dev_cap *cap, + const struct cfg_cmd_dev_cap *dev_cap, + enum hinic3_func_type type) +{ + cap->port_id = dev_cap->port_id; + cap->supp_svcs_bitmap = dev_cap->svc_cap_en; +} + +static void hinic3_parse_l2nic_res_cap(struct hinic3_hwdev *hwdev, + struct hinic3_dev_cap *cap, + const struct cfg_cmd_dev_cap *dev_cap, + enum hinic3_func_type type) +{ + struct hinic3_nic_service_cap *nic_svc_cap = &cap->nic_svc_cap; + + nic_svc_cap->max_sqs = min(dev_cap->nic_max_sq_id + 1, + HINIC3_CFG_MAX_QP); +} + +static void hinic3_parse_dev_cap(struct hinic3_hwdev *hwdev, + const struct cfg_cmd_dev_cap *dev_cap, + enum hinic3_func_type type) +{ + struct hinic3_dev_cap *cap = &hwdev->cfg_mgmt->cap; + + /* Public resource */ + hinic3_parse_pub_res_cap(hwdev, cap, dev_cap, type); + + /* L2 NIC resource */ + if (hinic3_support_nic(hwdev)) + hinic3_parse_l2nic_res_cap(hwdev, cap, dev_cap, type); +} + +static int get_cap_from_fw(struct hinic3_hwdev *hwdev, + enum hinic3_func_type type) +{ + struct mgmt_msg_params msg_params = {}; + struct cfg_cmd_dev_cap dev_cap = {}; + int err; + + dev_cap.func_id = hinic3_global_func_id(hwdev); + + mgmt_msg_params_init_default(&msg_params, &dev_cap, sizeof(dev_cap)); + + err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_CFGM, + CFG_CMD_GET_DEV_CAP, &msg_params); + if (err || dev_cap.head.status) { + dev_err(hwdev->dev, + "Failed to get capability from FW, err: %d, status: 0x%x\n", + err, dev_cap.head.status); + return -EIO; + } + + hinic3_parse_dev_cap(hwdev, &dev_cap, type); + + return 0; +} + static int hinic3_init_irq_info(struct hinic3_hwdev *hwdev) { struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt; @@ -153,6 +214,11 @@ void hinic3_free_irq(struct hinic3_hwdev *hwdev, u32 irq_id) mutex_unlock(&irq_info->irq_mutex); } +int hinic3_init_capability(struct hinic3_hwdev *hwdev) +{ + return get_cap_from_fw(hwdev, HINIC3_FUNC_TYPE_VF); +} + bool hinic3_support_nic(struct hinic3_hwdev *hwdev) { return hwdev->cfg_mgmt->cap.supp_svcs_bitmap & diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h index 5978cbd56fb2..58806199bf54 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h @@ -49,6 +49,7 @@ int hinic3_alloc_irqs(struct hinic3_hwdev *hwdev, u16 num, struct msix_entry *alloc_arr, u16 *act_num); void hinic3_free_irq(struct hinic3_hwdev *hwdev, u32 irq_id); +int hinic3_init_capability(struct hinic3_hwdev *hwdev); bool hinic3_support_nic(struct hinic3_hwdev *hwdev); u16 hinic3_func_max_qnum(struct hinic3_hwdev *hwdev); u8 hinic3_physical_port_id(struct hinic3_hwdev *hwdev); diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_intf.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_intf.h index b5695dda8fe5..87b43a123edb 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_intf.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_intf.h @@ -51,6 +51,48 @@ static inline void mgmt_msg_params_init_default(struct mgmt_msg_params *msg_para msg_params->timeout_ms = 0; } +enum cfg_cmd { + CFG_CMD_GET_DEV_CAP = 0, +}; + +/* Device capabilities, defined by hw */ +struct cfg_cmd_dev_cap { + struct mgmt_msg_head head; + + u16 func_id; + u16 rsvd1; + + /* Public resources */ + 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; + u8 host_oq_id_mask_val; + u8 timer_en; + u8 host_valid_bitmap; + u8 rsvd_host; + + u16 svc_cap_en; + u16 max_vf; + u8 flexq_en; + u8 valid_cos_bitmap; + u8 port_cos_valid_bitmap; + u8 rsvd2[45]; + + /* l2nic */ + u16 nic_max_sq_id; + u16 nic_max_rq_id; + u16 nic_default_num_queues; + + u8 rsvd3[250]; +}; + /* COMM Commands between Driver to fw */ enum comm_cmd { /* Commands for clearing FLR and resources */ diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c index c2327c34a47b..258e96ac9b76 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c @@ -479,6 +479,12 @@ int hinic3_init_hwdev(struct pci_dev *pdev) goto err_free_cfg_mgmt; } + err = hinic3_init_capability(hwdev); + if (err) { + dev_err(hwdev->dev, "Failed to init capability\n"); + goto err_uninit_comm_ch; + } + err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD); if (err) { -- 2.43.0