1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Huawei Technologies Co., Ltd 3 */ 4 5 #include "hinic_compat.h" 6 #include "hinic_pmd_hwdev.h" 7 #include "hinic_pmd_hwif.h" 8 #include "hinic_pmd_mgmt.h" 9 #include "hinic_pmd_eqs.h" 10 #include "hinic_pmd_cfg.h" 11 12 bool hinic_support_nic(struct hinic_hwdev *hwdev, struct nic_service_cap *cap) 13 { 14 if (!IS_NIC_TYPE(hwdev)) 15 return false; 16 17 if (cap) 18 memcpy(cap, &hwdev->cfg_mgmt->svc_cap.nic_cap, sizeof(*cap)); 19 20 return true; 21 } 22 23 static void hinic_parse_shared_res_cap(struct service_cap *cap, 24 struct hinic_dev_cap *dev_cap, 25 __rte_unused enum func_type type) 26 { 27 struct host_shared_resource_cap *shared_cap = &cap->shared_res_cap; 28 29 shared_cap->host_pctxs = dev_cap->host_pctx_num; 30 31 if (dev_cap->host_sf_en) 32 cap->sf_en = true; 33 else 34 cap->sf_en = false; 35 36 shared_cap->host_cctxs = dev_cap->host_ccxt_num; 37 shared_cap->host_scqs = dev_cap->host_scq_num; 38 shared_cap->host_srqs = dev_cap->host_srq_num; 39 shared_cap->host_mpts = dev_cap->host_mpt_num; 40 41 PMD_DRV_LOG(INFO, "Get share resource capability:"); 42 PMD_DRV_LOG(INFO, "host_pctxs: 0x%x, host_cctxs: 0x%x, host_scqs: 0x%x, host_srqs: 0x%x, host_mpts: 0x%x", 43 shared_cap->host_pctxs, shared_cap->host_cctxs, 44 shared_cap->host_scqs, shared_cap->host_srqs, 45 shared_cap->host_mpts); 46 } 47 48 static void hinic_parse_l2nic_res_cap(struct service_cap *cap, 49 struct hinic_dev_cap *dev_cap, 50 enum func_type type) 51 { 52 struct nic_service_cap *nic_cap = &cap->nic_cap; 53 54 if (type == TYPE_PF || type == TYPE_PPF) { 55 nic_cap->max_sqs = dev_cap->nic_max_sq + 1; 56 nic_cap->max_rqs = dev_cap->nic_max_rq + 1; 57 nic_cap->vf_max_sqs = dev_cap->nic_vf_max_sq + 1; 58 nic_cap->vf_max_rqs = dev_cap->nic_vf_max_rq + 1; 59 } else { 60 nic_cap->max_sqs = dev_cap->nic_max_sq; 61 nic_cap->max_rqs = dev_cap->nic_max_rq; 62 nic_cap->vf_max_sqs = 0; 63 nic_cap->vf_max_rqs = 0; 64 } 65 66 if (dev_cap->nic_lro_en) 67 nic_cap->lro_en = true; 68 else 69 nic_cap->lro_en = false; 70 71 nic_cap->lro_sz = dev_cap->nic_lro_sz; 72 nic_cap->tso_sz = dev_cap->nic_tso_sz; 73 74 PMD_DRV_LOG(INFO, "Get l2nic resource capability:"); 75 PMD_DRV_LOG(INFO, "max_sqs: 0x%x, max_rqs: 0x%x, vf_max_sqs: 0x%x, vf_max_rqs: 0x%x", 76 nic_cap->max_sqs, nic_cap->max_rqs, 77 nic_cap->vf_max_sqs, nic_cap->vf_max_rqs); 78 } 79 80 u16 hinic_func_max_qnum(void *hwdev) 81 { 82 struct hinic_hwdev *dev = hwdev; 83 84 return dev->cfg_mgmt->svc_cap.max_sqs; 85 } 86 87 int init_cfg_mgmt(struct hinic_hwdev *hwdev) 88 { 89 struct cfg_mgmt_info *cfg_mgmt; 90 91 cfg_mgmt = kzalloc(sizeof(*cfg_mgmt), GFP_KERNEL); 92 if (!cfg_mgmt) 93 return -ENOMEM; 94 95 hwdev->cfg_mgmt = cfg_mgmt; 96 cfg_mgmt->hwdev = hwdev; 97 98 return 0; 99 } 100 101 void free_cfg_mgmt(struct hinic_hwdev *hwdev) 102 { 103 kfree(hwdev->cfg_mgmt); 104 hwdev->cfg_mgmt = NULL; 105 } 106 107 static void hinic_parse_pub_res_cap(struct service_cap *cap, 108 struct hinic_dev_cap *dev_cap, 109 enum func_type type) 110 { 111 cap->host_id = dev_cap->host_id; 112 cap->ep_id = dev_cap->ep_id; 113 cap->max_cos_id = dev_cap->max_cos_id; 114 cap->er_id = dev_cap->er_id; 115 cap->port_id = dev_cap->port_id; 116 117 if (type == TYPE_PF || type == TYPE_PPF) { 118 cap->max_vf = dev_cap->max_vf; 119 cap->pf_num = dev_cap->pf_num; 120 cap->pf_id_start = dev_cap->pf_id_start; 121 cap->vf_num = dev_cap->vf_num; 122 cap->vf_id_start = dev_cap->vf_id_start; 123 cap->max_sqs = dev_cap->nic_max_sq + 1; 124 cap->max_rqs = dev_cap->nic_max_rq + 1; 125 } 126 127 cap->chip_svc_type = CFG_SVC_NIC_BIT0; 128 cap->host_total_function = dev_cap->host_total_func; 129 cap->host_oq_id_mask_val = dev_cap->host_oq_id_mask_val; 130 131 PMD_DRV_LOG(INFO, "Get public resource capability:"); 132 PMD_DRV_LOG(INFO, "host_id: 0x%x, ep_id: 0x%x, intr_type: 0x%x, max_cos_id: 0x%x, er_id: 0x%x, port_id: 0x%x", 133 cap->host_id, cap->ep_id, cap->intr_chip_en, 134 cap->max_cos_id, cap->er_id, cap->port_id); 135 PMD_DRV_LOG(INFO, "host_total_function: 0x%x, host_oq_id_mask_val: 0x%x, max_vf: 0x%x", 136 cap->host_total_function, cap->host_oq_id_mask_val, 137 cap->max_vf); 138 PMD_DRV_LOG(INFO, "pf_num: 0x%x, pf_id_start: 0x%x, vf_num: 0x%x, vf_id_start: 0x%x", 139 cap->pf_num, cap->pf_id_start, 140 cap->vf_num, cap->vf_id_start); 141 } 142 143 static void parse_dev_cap(struct hinic_hwdev *dev, 144 struct hinic_dev_cap *dev_cap, 145 enum func_type type) 146 { 147 struct service_cap *cap = &dev->cfg_mgmt->svc_cap; 148 149 /* Public resource */ 150 hinic_parse_pub_res_cap(cap, dev_cap, type); 151 152 /* PPF managed dynamic resource */ 153 if (type == TYPE_PPF) 154 hinic_parse_shared_res_cap(cap, dev_cap, type); 155 156 /* L2 NIC resource */ 157 if (IS_NIC_TYPE(dev)) 158 hinic_parse_l2nic_res_cap(cap, dev_cap, type); 159 } 160 161 static int get_cap_from_fw(struct hinic_hwdev *dev, enum func_type type) 162 { 163 int err; 164 u16 in_len, out_len; 165 struct hinic_dev_cap dev_cap; 166 167 memset(&dev_cap, 0, sizeof(dev_cap)); 168 in_len = sizeof(dev_cap); 169 out_len = in_len; 170 dev_cap.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; 171 err = hinic_msg_to_mgmt_sync(dev, HINIC_MOD_CFGM, HINIC_CFG_NIC_CAP, 172 &dev_cap, in_len, &dev_cap, &out_len, 0); 173 if (err || dev_cap.mgmt_msg_head.status || !out_len) { 174 PMD_DRV_LOG(ERR, "Get capability from FW failed, err: %d, status: %d, out_len: %d", 175 err, dev_cap.mgmt_msg_head.status, out_len); 176 return -EFAULT; 177 } 178 179 parse_dev_cap(dev, &dev_cap, type); 180 return 0; 181 } 182 183 static int get_dev_cap(struct hinic_hwdev *dev) 184 { 185 int err; 186 enum func_type type = HINIC_FUNC_TYPE(dev); 187 188 switch (type) { 189 case TYPE_PF: 190 case TYPE_PPF: 191 err = get_cap_from_fw(dev, type); 192 if (err) { 193 PMD_DRV_LOG(ERR, "Get PF/PPF capability failed"); 194 return err; 195 } 196 break; 197 default: 198 PMD_DRV_LOG(ERR, "Unsupported PCI function type"); 199 return -EINVAL; 200 } 201 202 return 0; 203 } 204 205 int hinic_init_capability(struct hinic_hwdev *hwdev) 206 { 207 return get_dev_cap(hwdev); 208 } 209