net/hinic/base: add hardware operation
[dpdk.git] / drivers / net / hinic / base / hinic_pmd_cfg.c
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 }