1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2021 Intel Corporation
3 */
4
5 #include <rte_pci.h>
6 #include <bus_pci_driver.h>
7 #include <rte_rawdev.h>
8 #include <rte_rawdev_pmd.h>
9 #include "rte_pmd_ifpga.h"
10 #include "ifpga_rawdev.h"
11 #include "base/ifpga_api.h"
12 #include "base/ifpga_sec_mgr.h"
13
14
15 int
rte_pmd_ifpga_get_dev_id(const char * pci_addr,uint16_t * dev_id)16 rte_pmd_ifpga_get_dev_id(const char *pci_addr, uint16_t *dev_id)
17 {
18 struct rte_pci_addr addr;
19 struct rte_rawdev *rdev = NULL;
20 char rdev_name[RTE_RAWDEV_NAME_MAX_LEN] = {0};
21
22 if (!pci_addr || !dev_id) {
23 IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid.");
24 return -EINVAL;
25 }
26
27 if (strnlen(pci_addr, PCI_PRI_STR_SIZE) == PCI_PRI_STR_SIZE) {
28 IFPGA_RAWDEV_PMD_ERR("PCI address is too long.");
29 return -EINVAL;
30 }
31
32 if (rte_pci_addr_parse(pci_addr, &addr)) {
33 IFPGA_RAWDEV_PMD_ERR("PCI address %s is invalid.", pci_addr);
34 return -EINVAL;
35 }
36
37 snprintf(rdev_name, RTE_RAWDEV_NAME_MAX_LEN, IFPGA_RAWDEV_NAME_FMT,
38 addr.bus, addr.devid, addr.function);
39 rdev = rte_rawdev_pmd_get_named_dev(rdev_name);
40 if (!rdev) {
41 IFPGA_RAWDEV_PMD_DEBUG("%s is not probed by ifpga driver.",
42 pci_addr);
43 return -ENODEV;
44 }
45 *dev_id = rdev->dev_id;
46
47 return 0;
48 }
49
50 static struct rte_rawdev *
get_rte_rawdev(uint16_t dev_id)51 get_rte_rawdev(uint16_t dev_id)
52 {
53 struct rte_rawdev *dev = NULL;
54
55 if (dev_id >= RTE_RAWDEV_MAX_DEVS)
56 return NULL;
57
58 dev = &rte_rawdevs[dev_id];
59 if (dev->attached == RTE_RAWDEV_ATTACHED)
60 return dev;
61
62 return NULL;
63 }
64
65 static struct opae_adapter *
get_opae_adapter(uint16_t dev_id)66 get_opae_adapter(uint16_t dev_id)
67 {
68 struct rte_rawdev *dev = NULL;
69 struct opae_adapter *adapter = NULL;
70
71 dev = get_rte_rawdev(dev_id);
72 if (!dev) {
73 IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
74 return NULL;
75 }
76
77 adapter = ifpga_rawdev_get_priv(dev);
78 if (!adapter) {
79 IFPGA_RAWDEV_PMD_ERR("Adapter is not registered.");
80 return NULL;
81 }
82
83 return adapter;
84 }
85
86 static opae_share_data *
get_share_data(struct opae_adapter * adapter)87 get_share_data(struct opae_adapter *adapter)
88 {
89 opae_share_data *sd = NULL;
90
91 if (!adapter)
92 return NULL;
93
94 sd = (opae_share_data *)adapter->shm.ptr;
95 if (!sd) {
96 IFPGA_RAWDEV_PMD_ERR("Share data is not initialized.");
97 return NULL;
98 }
99
100 return sd;
101 }
102
103 int
rte_pmd_ifpga_get_rsu_status(uint16_t dev_id,uint32_t * stat,uint32_t * prog)104 rte_pmd_ifpga_get_rsu_status(uint16_t dev_id, uint32_t *stat, uint32_t *prog)
105 {
106 struct opae_adapter *adapter = NULL;
107 opae_share_data *sd = NULL;
108
109 adapter = get_opae_adapter(dev_id);
110 if (!adapter)
111 return -ENODEV;
112
113 sd = get_share_data(adapter);
114 if (!sd)
115 return -ENOMEM;
116
117 if (stat)
118 *stat = IFPGA_RSU_GET_STAT(sd->rsu_stat);
119 if (prog)
120 *prog = IFPGA_RSU_GET_PROG(sd->rsu_stat);
121
122 return 0;
123 }
124
125 int
rte_pmd_ifpga_set_rsu_status(uint16_t dev_id,uint32_t stat,uint32_t prog)126 rte_pmd_ifpga_set_rsu_status(uint16_t dev_id, uint32_t stat, uint32_t prog)
127 {
128 struct opae_adapter *adapter = NULL;
129 opae_share_data *sd = NULL;
130
131 adapter = get_opae_adapter(dev_id);
132 if (!adapter)
133 return -ENODEV;
134
135 sd = get_share_data(adapter);
136 if (!sd)
137 return -ENOMEM;
138
139 sd->rsu_stat = IFPGA_RSU_STATUS(stat, prog);
140
141 return 0;
142 }
143
144 static int
ifpga_is_rebooting(struct opae_adapter * adapter)145 ifpga_is_rebooting(struct opae_adapter *adapter)
146 {
147 opae_share_data *sd = NULL;
148
149 sd = get_share_data(adapter);
150 if (!sd)
151 return 1;
152
153 if (IFPGA_RSU_GET_STAT(sd->rsu_stat) == IFPGA_RSU_REBOOT) {
154 IFPGA_RAWDEV_PMD_WARN("Reboot is in progress.");
155 return 1;
156 }
157
158 return 0;
159 }
160
161 static int
get_common_property(struct opae_adapter * adapter,rte_pmd_ifpga_common_prop * prop)162 get_common_property(struct opae_adapter *adapter,
163 rte_pmd_ifpga_common_prop *prop)
164 {
165 struct ifpga_fme_hw *fme = NULL;
166 struct opae_board_info *info = NULL;
167 struct feature_prop fp;
168 struct uuid pr_id;
169 int ret = 0;
170
171 if (!adapter || !prop)
172 return -EINVAL;
173
174 if (!adapter->mgr || !adapter->mgr->data) {
175 IFPGA_RAWDEV_PMD_ERR("Manager is not registered.");
176 return -ENODEV;
177 }
178
179 fme = adapter->mgr->data;
180 fp.feature_id = FME_FEATURE_ID_HEADER;
181 fp.prop_id = FME_HDR_PROP_PORTS_NUM;
182 ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
183 if (ret) {
184 IFPGA_RAWDEV_PMD_ERR("Failed to get port number.");
185 return ret;
186 }
187 prop->num_ports = fp.data;
188
189 fp.prop_id = FME_HDR_PROP_BITSTREAM_ID;
190 ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
191 if (ret) {
192 IFPGA_RAWDEV_PMD_ERR("Failed to get bitstream ID.");
193 return ret;
194 }
195 prop->bitstream_id = fp.data;
196
197 fp.prop_id = FME_HDR_PROP_BITSTREAM_METADATA;
198 ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
199 if (ret) {
200 IFPGA_RAWDEV_PMD_ERR("Failed to get bitstream metadata.");
201 return ret;
202 }
203 prop->bitstream_metadata = fp.data;
204
205 ret = opae_mgr_get_uuid(adapter->mgr, &pr_id);
206 if (ret) {
207 IFPGA_RAWDEV_PMD_ERR("Failed to get PR ID.");
208 return ret;
209 }
210 memcpy(prop->pr_id.b, pr_id.b, sizeof(rte_pmd_ifpga_uuid));
211
212 ret = opae_mgr_get_board_info(adapter->mgr, &info);
213 if (ret) {
214 IFPGA_RAWDEV_PMD_ERR("Failed to get board info.");
215 return ret;
216 }
217 prop->boot_page = info->boot_page;
218 prop->bmc_version = info->max10_version;
219 prop->bmc_nios_version = info->nios_fw_version;
220
221 return 0;
222 }
223
224 static int
get_port_property(struct opae_adapter * adapter,uint16_t port,rte_pmd_ifpga_port_prop * prop)225 get_port_property(struct opae_adapter *adapter, uint16_t port,
226 rte_pmd_ifpga_port_prop *prop)
227 {
228 struct ifpga_fme_hw *fme = NULL;
229 struct feature_prop fp;
230 struct opae_accelerator *acc = NULL;
231 struct uuid afu_id;
232 int ret = 0;
233
234 if (!adapter || !prop)
235 return -EINVAL;
236
237 if (!adapter->mgr || !adapter->mgr->data) {
238 IFPGA_RAWDEV_PMD_ERR("Manager is not registered.");
239 return -ENODEV;
240 }
241
242 fme = adapter->mgr->data;
243 fp.feature_id = FME_FEATURE_ID_HEADER;
244 fp.prop_id = FME_HDR_PROP_PORT_TYPE;
245 fp.data = port;
246 fp.data <<= 32;
247 ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
248 if (ret)
249 return ret;
250 prop->type = fp.data & 0xffffffff;
251
252 if (prop->type == 0) {
253 acc = opae_adapter_get_acc(adapter, port);
254 ret = opae_acc_get_uuid(acc, &afu_id);
255 if (ret) {
256 IFPGA_RAWDEV_PMD_ERR("Failed to get port%u AFU ID.",
257 port);
258 return ret;
259 }
260 memcpy(prop->afu_id.b, afu_id.b, sizeof(rte_pmd_ifpga_uuid));
261 }
262
263 return 0;
264 }
265
266 int
rte_pmd_ifpga_get_property(uint16_t dev_id,rte_pmd_ifpga_prop * prop)267 rte_pmd_ifpga_get_property(uint16_t dev_id, rte_pmd_ifpga_prop *prop)
268 {
269 struct opae_adapter *adapter = NULL;
270 uint32_t i = 0;
271 int ret = 0;
272
273 adapter = get_opae_adapter(dev_id);
274 if (!adapter)
275 return -ENODEV;
276
277 opae_adapter_lock(adapter, -1);
278 if (ifpga_is_rebooting(adapter)) {
279 ret = -EBUSY;
280 goto unlock_dev;
281 }
282
283 ret = get_common_property(adapter, &prop->common);
284 if (ret) {
285 ret = -EIO;
286 goto unlock_dev;
287 }
288
289 for (i = 0; i < prop->common.num_ports; i++) {
290 ret = get_port_property(adapter, i, &prop->port[i]);
291 if (ret) {
292 ret = -EIO;
293 break;
294 }
295 }
296
297 unlock_dev:
298 opae_adapter_unlock(adapter);
299 return ret;
300 }
301
302 int
rte_pmd_ifpga_get_phy_info(uint16_t dev_id,rte_pmd_ifpga_phy_info * info)303 rte_pmd_ifpga_get_phy_info(uint16_t dev_id, rte_pmd_ifpga_phy_info *info)
304 {
305 struct opae_adapter *adapter = NULL;
306 struct opae_retimer_info rtm_info;
307 struct opae_retimer_status rtm_status;
308 int ret = 0;
309
310 adapter = get_opae_adapter(dev_id);
311 if (!adapter)
312 return -ENODEV;
313
314 opae_adapter_lock(adapter, -1);
315 if (ifpga_is_rebooting(adapter)) {
316 ret = -EBUSY;
317 goto unlock_dev;
318 }
319
320 ret = opae_manager_get_retimer_info(adapter->mgr, &rtm_info);
321 if (ret) {
322 IFPGA_RAWDEV_PMD_ERR("Failed to get retimer info.");
323 ret = -EIO;
324 goto unlock_dev;
325 }
326 info->num_retimers = rtm_info.nums_retimer;
327
328 ret = opae_manager_get_retimer_status(adapter->mgr, &rtm_status);
329 if (ret) {
330 IFPGA_RAWDEV_PMD_ERR("Failed to get retimer status.");
331 ret = -EIO;
332 goto unlock_dev;
333 }
334 info->link_speed = rtm_status.speed;
335 info->link_status = rtm_status.line_link_bitmap;
336
337 unlock_dev:
338 opae_adapter_unlock(adapter);
339 return ret;
340 }
341
342 int
rte_pmd_ifpga_update_flash(uint16_t dev_id,const char * image,uint64_t * status)343 rte_pmd_ifpga_update_flash(uint16_t dev_id, const char *image,
344 uint64_t *status)
345 {
346 struct opae_adapter *adapter = NULL;
347
348 adapter = get_opae_adapter(dev_id);
349 if (!adapter)
350 return -ENODEV;
351
352 return opae_mgr_update_flash(adapter->mgr, image, status);
353 }
354
355 int
rte_pmd_ifpga_stop_update(uint16_t dev_id,int force)356 rte_pmd_ifpga_stop_update(uint16_t dev_id, int force)
357 {
358 struct opae_adapter *adapter = NULL;
359
360 adapter = get_opae_adapter(dev_id);
361 if (!adapter)
362 return -ENODEV;
363
364 return opae_mgr_stop_flash_update(adapter->mgr, force);
365 }
366
367 int
rte_pmd_ifpga_reboot_try(uint16_t dev_id)368 rte_pmd_ifpga_reboot_try(uint16_t dev_id)
369 {
370 struct opae_adapter *adapter = NULL;
371 opae_share_data *sd = NULL;
372
373 adapter = get_opae_adapter(dev_id);
374 if (!adapter)
375 return -ENODEV;
376
377 sd = get_share_data(adapter);
378 if (!sd)
379 return -ENOMEM;
380
381 opae_adapter_lock(adapter, -1);
382 if (IFPGA_RSU_GET_STAT(sd->rsu_stat) != IFPGA_RSU_IDLE) {
383 opae_adapter_unlock(adapter);
384 IFPGA_RAWDEV_PMD_WARN("Update or reboot is in progress.");
385 return -EBUSY;
386 }
387 sd->rsu_stat = IFPGA_RSU_STATUS(IFPGA_RSU_REBOOT, 0);
388 opae_adapter_unlock(adapter);
389
390 return 0;
391 }
392
393 int
rte_pmd_ifpga_reload(uint16_t dev_id,int type,int page)394 rte_pmd_ifpga_reload(uint16_t dev_id, int type, int page)
395 {
396 struct opae_adapter *adapter = NULL;
397
398 adapter = get_opae_adapter(dev_id);
399 if (!adapter)
400 return -ENODEV;
401
402 return opae_mgr_reload(adapter->mgr, type, page);
403 }
404
405 int
rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id,int port,const char * file)406 rte_pmd_ifpga_partial_reconfigure(uint16_t dev_id, int port, const char *file)
407 {
408 struct rte_rawdev *dev = NULL;
409
410 dev = get_rte_rawdev(dev_id);
411 if (!dev) {
412 IFPGA_RAWDEV_PMD_ERR("Device ID %u is invalid.", dev_id);
413 return -EINVAL;
414 }
415
416 return ifpga_rawdev_partial_reconfigure(dev, port, file);
417 }
418
419 void
rte_pmd_ifpga_cleanup(void)420 rte_pmd_ifpga_cleanup(void)
421 {
422 ifpga_rawdev_cleanup();
423 }
424