]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / drivers / raw / ifpga_rawdev / ifpga_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
3 */
4
5 #include <string.h>
6 #include <dirent.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <fcntl.h>
11 #include <rte_log.h>
12 #include <rte_bus.h>
13 #include <rte_eal_memconfig.h>
14 #include <rte_malloc.h>
15 #include <rte_devargs.h>
16 #include <rte_memcpy.h>
17 #include <rte_pci.h>
18 #include <rte_bus_pci.h>
19 #include <rte_kvargs.h>
20 #include <rte_alarm.h>
21
22 #include <rte_errno.h>
23 #include <rte_per_lcore.h>
24 #include <rte_memory.h>
25 #include <rte_memzone.h>
26 #include <rte_eal.h>
27 #include <rte_common.h>
28 #include <rte_bus_vdev.h>
29
30 #include "base/opae_hw_api.h"
31 #include "rte_rawdev.h"
32 #include "rte_rawdev_pmd.h"
33 #include "rte_bus_ifpga.h"
34 #include "ifpga_common.h"
35 #include "ifpga_logs.h"
36 #include "ifpga_rawdev.h"
37 #include "ipn3ke_rawdev_api.h"
38
39 int ifpga_rawdev_logtype;
40
41 #define PCI_VENDOR_ID_INTEL 0x8086
42 /* PCI Device ID */
43 #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
44 #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
45 #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
46 #define PCIE_DEVICE_ID_PAC_N3000 0x0B30
47 /* VF Device */
48 #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
49 #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
50 #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
51 #define PCIE_DEVICE_ID_VF_PAC_N3000 0x0B31
52 #define RTE_MAX_RAW_DEVICE 10
53
54 static const struct rte_pci_id pci_ifpga_map[] = {
55 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X) },
56 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X) },
57 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X) },
58 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X) },
59 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X) },
60 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X) },
61 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PAC_N3000),},
62 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_PAC_N3000),},
63 { .vendor_id = 0, /* sentinel */ },
64 };
65
66 static int
67 ifpga_fill_afu_dev(struct opae_accelerator *acc,
68 struct rte_afu_device *afu_dev)
69 {
70 struct rte_mem_resource *res = afu_dev->mem_resource;
71 struct opae_acc_region_info region_info;
72 struct opae_acc_info info;
73 unsigned long i;
74 int ret;
75
76 ret = opae_acc_get_info(acc, &info);
77 if (ret)
78 return ret;
79
80 if (info.num_regions > PCI_MAX_RESOURCE)
81 return -EFAULT;
82
83 afu_dev->num_region = info.num_regions;
84
85 for (i = 0; i < info.num_regions; i++) {
86 region_info.index = i;
87 ret = opae_acc_get_region_info(acc, &region_info);
88 if (ret)
89 return ret;
90
91 if ((region_info.flags & ACC_REGION_MMIO) &&
92 (region_info.flags & ACC_REGION_READ) &&
93 (region_info.flags & ACC_REGION_WRITE)) {
94 res[i].phys_addr = region_info.phys_addr;
95 res[i].len = region_info.len;
96 res[i].addr = region_info.addr;
97 } else
98 return -EFAULT;
99 }
100
101 return 0;
102 }
103
104 static void
105 ifpga_rawdev_info_get(struct rte_rawdev *dev,
106 rte_rawdev_obj_t dev_info)
107 {
108 struct opae_adapter *adapter;
109 struct opae_accelerator *acc;
110 struct rte_afu_device *afu_dev;
111 struct opae_manager *mgr = NULL;
112 struct opae_eth_group_region_info opae_lside_eth_info;
113 struct opae_eth_group_region_info opae_nside_eth_info;
114 int lside_bar_idx, nside_bar_idx;
115
116 IFPGA_RAWDEV_PMD_FUNC_TRACE();
117
118 if (!dev_info) {
119 IFPGA_RAWDEV_PMD_ERR("Invalid request");
120 return;
121 }
122
123 adapter = ifpga_rawdev_get_priv(dev);
124 if (!adapter)
125 return;
126
127 afu_dev = dev_info;
128 afu_dev->rawdev = dev;
129
130 /* find opae_accelerator and fill info into afu_device */
131 opae_adapter_for_each_acc(adapter, acc) {
132 if (acc->index != afu_dev->id.port)
133 continue;
134
135 if (ifpga_fill_afu_dev(acc, afu_dev)) {
136 IFPGA_RAWDEV_PMD_ERR("cannot get info\n");
137 return;
138 }
139 }
140
141 /* get opae_manager to rawdev */
142 mgr = opae_adapter_get_mgr(adapter);
143 if (mgr) {
144 /* get LineSide BAR Index */
145 if (opae_manager_get_eth_group_region_info(mgr, 0,
146 &opae_lside_eth_info)) {
147 return;
148 }
149 lside_bar_idx = opae_lside_eth_info.mem_idx;
150
151 /* get NICSide BAR Index */
152 if (opae_manager_get_eth_group_region_info(mgr, 1,
153 &opae_nside_eth_info)) {
154 return;
155 }
156 nside_bar_idx = opae_nside_eth_info.mem_idx;
157
158 if (lside_bar_idx >= PCI_MAX_RESOURCE ||
159 nside_bar_idx >= PCI_MAX_RESOURCE ||
160 lside_bar_idx == nside_bar_idx)
161 return;
162
163 /* fill LineSide BAR Index */
164 afu_dev->mem_resource[lside_bar_idx].phys_addr =
165 opae_lside_eth_info.phys_addr;
166 afu_dev->mem_resource[lside_bar_idx].len =
167 opae_lside_eth_info.len;
168 afu_dev->mem_resource[lside_bar_idx].addr =
169 opae_lside_eth_info.addr;
170
171 /* fill NICSide BAR Index */
172 afu_dev->mem_resource[nside_bar_idx].phys_addr =
173 opae_nside_eth_info.phys_addr;
174 afu_dev->mem_resource[nside_bar_idx].len =
175 opae_nside_eth_info.len;
176 afu_dev->mem_resource[nside_bar_idx].addr =
177 opae_nside_eth_info.addr;
178 }
179 }
180
181 static int
182 ifpga_rawdev_configure(const struct rte_rawdev *dev,
183 rte_rawdev_obj_t config)
184 {
185 IFPGA_RAWDEV_PMD_FUNC_TRACE();
186
187 RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
188
189 return config ? 0 : 1;
190 }
191
192 static int
193 ifpga_rawdev_start(struct rte_rawdev *dev)
194 {
195 int ret = 0;
196 struct opae_adapter *adapter;
197
198 IFPGA_RAWDEV_PMD_FUNC_TRACE();
199
200 RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
201
202 adapter = ifpga_rawdev_get_priv(dev);
203 if (!adapter)
204 return -ENODEV;
205
206 return ret;
207 }
208
209 static void
210 ifpga_rawdev_stop(struct rte_rawdev *dev)
211 {
212 dev->started = 0;
213 }
214
215 static int
216 ifpga_rawdev_close(struct rte_rawdev *dev)
217 {
218 return dev ? 0:1;
219 }
220
221 static int
222 ifpga_rawdev_reset(struct rte_rawdev *dev)
223 {
224 return dev ? 0:1;
225 }
226
227 static int
228 fpga_pr(struct rte_rawdev *raw_dev, u32 port_id, u64 *buffer, u32 size,
229 u64 *status)
230 {
231
232 struct opae_adapter *adapter;
233 struct opae_manager *mgr;
234 struct opae_accelerator *acc;
235 struct opae_bridge *br;
236 int ret;
237
238 adapter = ifpga_rawdev_get_priv(raw_dev);
239 if (!adapter)
240 return -ENODEV;
241
242 mgr = opae_adapter_get_mgr(adapter);
243 if (!mgr)
244 return -ENODEV;
245
246 acc = opae_adapter_get_acc(adapter, port_id);
247 if (!acc)
248 return -ENODEV;
249
250 br = opae_acc_get_br(acc);
251 if (!br)
252 return -ENODEV;
253
254 ret = opae_manager_flash(mgr, port_id, buffer, size, status);
255 if (ret) {
256 IFPGA_RAWDEV_PMD_ERR("%s pr error %d\n", __func__, ret);
257 return ret;
258 }
259
260 ret = opae_bridge_reset(br);
261 if (ret) {
262 IFPGA_RAWDEV_PMD_ERR("%s reset port:%d error %d\n",
263 __func__, port_id, ret);
264 return ret;
265 }
266
267 return ret;
268 }
269
270 static int
271 rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id,
272 const char *file_name)
273 {
274 struct stat file_stat;
275 int file_fd;
276 int ret = 0;
277 ssize_t buffer_size;
278 void *buffer;
279 u64 pr_error;
280
281 if (!file_name)
282 return -EINVAL;
283
284 file_fd = open(file_name, O_RDONLY);
285 if (file_fd < 0) {
286 IFPGA_RAWDEV_PMD_ERR("%s: open file error: %s\n",
287 __func__, file_name);
288 IFPGA_RAWDEV_PMD_ERR("Message : %s\n", strerror(errno));
289 return -EINVAL;
290 }
291 ret = stat(file_name, &file_stat);
292 if (ret) {
293 IFPGA_RAWDEV_PMD_ERR("stat on bitstream file failed: %s\n",
294 file_name);
295 ret = -EINVAL;
296 goto close_fd;
297 }
298 buffer_size = file_stat.st_size;
299 IFPGA_RAWDEV_PMD_INFO("bitstream file size: %zu\n", buffer_size);
300 buffer = rte_malloc(NULL, buffer_size, 0);
301 if (!buffer) {
302 ret = -ENOMEM;
303 goto close_fd;
304 }
305
306 /*read the raw data*/
307 if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) {
308 ret = -EINVAL;
309 goto free_buffer;
310 }
311
312 /*do PR now*/
313 ret = fpga_pr(rawdev, port_id, buffer, buffer_size, &pr_error);
314 IFPGA_RAWDEV_PMD_INFO("downloading to device port %d....%s.\n", port_id,
315 ret ? "failed" : "success");
316 if (ret) {
317 ret = -EINVAL;
318 goto free_buffer;
319 }
320
321 free_buffer:
322 if (buffer)
323 rte_free(buffer);
324 close_fd:
325 close(file_fd);
326 file_fd = 0;
327 return ret;
328 }
329
330 static int
331 ifpga_rawdev_pr(struct rte_rawdev *dev,
332 rte_rawdev_obj_t pr_conf)
333 {
334 struct opae_adapter *adapter;
335 struct rte_afu_pr_conf *afu_pr_conf;
336 int ret;
337 struct uuid uuid;
338 struct opae_accelerator *acc;
339
340 IFPGA_RAWDEV_PMD_FUNC_TRACE();
341
342 adapter = ifpga_rawdev_get_priv(dev);
343 if (!adapter)
344 return -ENODEV;
345
346 if (!pr_conf)
347 return -EINVAL;
348
349 afu_pr_conf = pr_conf;
350
351 if (afu_pr_conf->pr_enable) {
352 ret = rte_fpga_do_pr(dev,
353 afu_pr_conf->afu_id.port,
354 afu_pr_conf->bs_path);
355 if (ret) {
356 IFPGA_RAWDEV_PMD_ERR("do pr error %d\n", ret);
357 return ret;
358 }
359 }
360
361 acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
362 if (!acc)
363 return -ENODEV;
364
365 ret = opae_acc_get_uuid(acc, &uuid);
366 if (ret)
367 return ret;
368
369 memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
370 memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
371
372 IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
373 (unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
374 (unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
375
376 return 0;
377 }
378
379 static int
380 ifpga_rawdev_get_attr(struct rte_rawdev *dev,
381 const char *attr_name, uint64_t *attr_value)
382 {
383 struct opae_adapter *adapter;
384 struct opae_manager *mgr;
385 struct opae_retimer_info opae_rtm_info;
386 struct opae_retimer_status opae_rtm_status;
387 struct opae_eth_group_info opae_eth_grp_info;
388 struct opae_eth_group_region_info opae_eth_grp_reg_info;
389 int eth_group_num = 0;
390 uint64_t port_link_bitmap = 0, port_link_bit;
391 uint32_t i, j, p, q;
392
393 #define MAX_PORT_PER_RETIMER 4
394
395 IFPGA_RAWDEV_PMD_FUNC_TRACE();
396
397 if (!dev || !attr_name || !attr_value) {
398 IFPGA_RAWDEV_PMD_ERR("Invalid arguments for getting attributes");
399 return -1;
400 }
401
402 adapter = ifpga_rawdev_get_priv(dev);
403 if (!adapter) {
404 IFPGA_RAWDEV_PMD_ERR("Adapter of dev %s is NULL", dev->name);
405 return -1;
406 }
407
408 mgr = opae_adapter_get_mgr(adapter);
409 if (!mgr) {
410 IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL");
411 return -1;
412 }
413
414 /* currently, eth_group_num is always 2 */
415 eth_group_num = opae_manager_get_eth_group_nums(mgr);
416 if (eth_group_num < 0)
417 return -1;
418
419 if (!strcmp(attr_name, "LineSideBaseMAC")) {
420 /* Currently FPGA not implement, so just set all zeros*/
421 *attr_value = (uint64_t)0;
422 return 0;
423 }
424 if (!strcmp(attr_name, "LineSideMACType")) {
425 /* eth_group 0 on FPGA connect to LineSide */
426 if (opae_manager_get_eth_group_info(mgr, 0,
427 &opae_eth_grp_info))
428 return -1;
429 switch (opae_eth_grp_info.speed) {
430 case ETH_SPEED_10G:
431 *attr_value =
432 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI);
433 break;
434 case ETH_SPEED_25G:
435 *attr_value =
436 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI);
437 break;
438 default:
439 *attr_value =
440 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_UNKNOWN);
441 break;
442 }
443 return 0;
444 }
445 if (!strcmp(attr_name, "LineSideLinkSpeed")) {
446 if (opae_manager_get_retimer_status(mgr, &opae_rtm_status))
447 return -1;
448 switch (opae_rtm_status.speed) {
449 case MXD_1GB:
450 *attr_value =
451 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
452 break;
453 case MXD_2_5GB:
454 *attr_value =
455 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
456 break;
457 case MXD_5GB:
458 *attr_value =
459 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
460 break;
461 case MXD_10GB:
462 *attr_value =
463 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_10GB);
464 break;
465 case MXD_25GB:
466 *attr_value =
467 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_25GB);
468 break;
469 case MXD_40GB:
470 *attr_value =
471 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_40GB);
472 break;
473 case MXD_100GB:
474 *attr_value =
475 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
476 break;
477 case MXD_SPEED_UNKNOWN:
478 *attr_value =
479 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
480 break;
481 default:
482 *attr_value =
483 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
484 break;
485 }
486 return 0;
487 }
488 if (!strcmp(attr_name, "LineSideLinkRetimerNum")) {
489 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
490 return -1;
491 *attr_value = (uint64_t)(opae_rtm_info.nums_retimer);
492 return 0;
493 }
494 if (!strcmp(attr_name, "LineSideLinkPortNum")) {
495 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
496 return -1;
497 uint64_t tmp = opae_rtm_info.ports_per_retimer *
498 opae_rtm_info.nums_retimer;
499 *attr_value = tmp;
500 return 0;
501 }
502 if (!strcmp(attr_name, "LineSideLinkStatus")) {
503 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
504 return -1;
505 if (opae_manager_get_retimer_status(mgr, &opae_rtm_status))
506 return -1;
507 (*attr_value) = 0;
508 q = 0;
509 port_link_bitmap = (uint64_t)(opae_rtm_status.line_link_bitmap);
510 for (i = 0; i < opae_rtm_info.nums_retimer; i++) {
511 p = i * MAX_PORT_PER_RETIMER;
512 for (j = 0; j < opae_rtm_info.ports_per_retimer; j++) {
513 port_link_bit = 0;
514 IFPGA_BIT_SET(port_link_bit, (p+j));
515 port_link_bit &= port_link_bitmap;
516 if (port_link_bit)
517 IFPGA_BIT_SET((*attr_value), q);
518 q++;
519 }
520 }
521 return 0;
522 }
523 if (!strcmp(attr_name, "LineSideBARIndex")) {
524 /* eth_group 0 on FPGA connect to LineSide */
525 if (opae_manager_get_eth_group_region_info(mgr, 0,
526 &opae_eth_grp_reg_info))
527 return -1;
528 *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx;
529 return 0;
530 }
531 if (!strcmp(attr_name, "NICSideMACType")) {
532 /* eth_group 1 on FPGA connect to NicSide */
533 if (opae_manager_get_eth_group_info(mgr, 1,
534 &opae_eth_grp_info))
535 return -1;
536 *attr_value = (uint64_t)(opae_eth_grp_info.speed);
537 return 0;
538 }
539 if (!strcmp(attr_name, "NICSideLinkSpeed")) {
540 /* eth_group 1 on FPGA connect to NicSide */
541 if (opae_manager_get_eth_group_info(mgr, 1,
542 &opae_eth_grp_info))
543 return -1;
544 *attr_value = (uint64_t)(opae_eth_grp_info.speed);
545 return 0;
546 }
547 if (!strcmp(attr_name, "NICSideLinkPortNum")) {
548 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
549 return -1;
550 uint64_t tmp = opae_rtm_info.nums_fvl *
551 opae_rtm_info.ports_per_fvl;
552 *attr_value = tmp;
553 return 0;
554 }
555 if (!strcmp(attr_name, "NICSideLinkStatus"))
556 return 0;
557 if (!strcmp(attr_name, "NICSideBARIndex")) {
558 /* eth_group 1 on FPGA connect to NicSide */
559 if (opae_manager_get_eth_group_region_info(mgr, 1,
560 &opae_eth_grp_reg_info))
561 return -1;
562 *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx;
563 return 0;
564 }
565
566 IFPGA_RAWDEV_PMD_ERR("%s not support", attr_name);
567 return -1;
568 }
569
570 static const struct rte_rawdev_ops ifpga_rawdev_ops = {
571 .dev_info_get = ifpga_rawdev_info_get,
572 .dev_configure = ifpga_rawdev_configure,
573 .dev_start = ifpga_rawdev_start,
574 .dev_stop = ifpga_rawdev_stop,
575 .dev_close = ifpga_rawdev_close,
576 .dev_reset = ifpga_rawdev_reset,
577
578 .queue_def_conf = NULL,
579 .queue_setup = NULL,
580 .queue_release = NULL,
581
582 .attr_get = ifpga_rawdev_get_attr,
583 .attr_set = NULL,
584
585 .enqueue_bufs = NULL,
586 .dequeue_bufs = NULL,
587
588 .dump = NULL,
589
590 .xstats_get = NULL,
591 .xstats_get_names = NULL,
592 .xstats_get_by_name = NULL,
593 .xstats_reset = NULL,
594
595 .firmware_status_get = NULL,
596 .firmware_version_get = NULL,
597 .firmware_load = ifpga_rawdev_pr,
598 .firmware_unload = NULL,
599
600 .dev_selftest = NULL,
601 };
602
603 static int
604 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
605 int socket_id)
606 {
607 int ret = 0;
608 struct rte_rawdev *rawdev = NULL;
609 struct opae_adapter *adapter = NULL;
610 struct opae_manager *mgr = NULL;
611 struct opae_adapter_data_pci *data = NULL;
612 char name[RTE_RAWDEV_NAME_MAX_LEN];
613 int i;
614
615 if (!pci_dev) {
616 IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
617 ret = -EINVAL;
618 goto cleanup;
619 }
620
621 memset(name, 0, sizeof(name));
622 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
623 pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
624
625 IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
626
627 /* Allocate device structure */
628 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct opae_adapter),
629 socket_id);
630 if (rawdev == NULL) {
631 IFPGA_RAWDEV_PMD_ERR("Unable to allocate rawdevice");
632 ret = -EINVAL;
633 goto cleanup;
634 }
635
636 /* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
637 data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
638 if (!data) {
639 ret = -ENOMEM;
640 goto cleanup;
641 }
642
643 /* init opae_adapter_data_pci for device specific information */
644 for (i = 0; i < PCI_MAX_RESOURCE; i++) {
645 data->region[i].phys_addr = pci_dev->mem_resource[i].phys_addr;
646 data->region[i].len = pci_dev->mem_resource[i].len;
647 data->region[i].addr = pci_dev->mem_resource[i].addr;
648 }
649 data->device_id = pci_dev->id.device_id;
650 data->vendor_id = pci_dev->id.vendor_id;
651
652 adapter = rawdev->dev_private;
653 /* create a opae_adapter based on above device data */
654 ret = opae_adapter_init(adapter, pci_dev->device.name, data);
655 if (ret) {
656 ret = -ENOMEM;
657 goto free_adapter_data;
658 }
659
660 rawdev->dev_ops = &ifpga_rawdev_ops;
661 rawdev->device = &pci_dev->device;
662 rawdev->driver_name = pci_dev->driver->driver.name;
663
664 /* must enumerate the adapter before use it */
665 ret = opae_adapter_enumerate(adapter);
666 if (ret)
667 goto free_adapter_data;
668
669 /* get opae_manager to rawdev */
670 mgr = opae_adapter_get_mgr(adapter);
671 if (mgr) {
672 /* PF function */
673 IFPGA_RAWDEV_PMD_INFO("this is a PF function");
674 }
675
676 return ret;
677
678 free_adapter_data:
679 if (data)
680 opae_adapter_data_free(data);
681 cleanup:
682 if (rawdev)
683 rte_rawdev_pmd_release(rawdev);
684
685 return ret;
686 }
687
688 static int
689 ifpga_rawdev_destroy(struct rte_pci_device *pci_dev)
690 {
691 int ret;
692 struct rte_rawdev *rawdev;
693 char name[RTE_RAWDEV_NAME_MAX_LEN];
694 struct opae_adapter *adapter;
695
696 if (!pci_dev) {
697 IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
698 ret = -EINVAL;
699 return ret;
700 }
701
702 memset(name, 0, sizeof(name));
703 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
704 pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
705
706 IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d",
707 name, rte_socket_id());
708
709 rawdev = rte_rawdev_pmd_get_named_dev(name);
710 if (!rawdev) {
711 IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name);
712 return -EINVAL;
713 }
714
715 adapter = ifpga_rawdev_get_priv(rawdev);
716 if (!adapter)
717 return -ENODEV;
718
719 opae_adapter_data_free(adapter->data);
720 opae_adapter_free(adapter);
721
722 /* rte_rawdev_close is called by pmd_release */
723 ret = rte_rawdev_pmd_release(rawdev);
724 if (ret)
725 IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed");
726
727 return ret;
728 }
729
730 static int
731 ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
732 struct rte_pci_device *pci_dev)
733 {
734 IFPGA_RAWDEV_PMD_FUNC_TRACE();
735 return ifpga_rawdev_create(pci_dev, rte_socket_id());
736 }
737
738 static int
739 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
740 {
741 return ifpga_rawdev_destroy(pci_dev);
742 }
743
744 static struct rte_pci_driver rte_ifpga_rawdev_pmd = {
745 .id_table = pci_ifpga_map,
746 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
747 .probe = ifpga_rawdev_pci_probe,
748 .remove = ifpga_rawdev_pci_remove,
749 };
750
751 RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd);
752 RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd);
753 RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci");
754
755 RTE_INIT(ifpga_rawdev_init_log)
756 {
757 ifpga_rawdev_logtype = rte_log_register("driver.raw.init");
758 if (ifpga_rawdev_logtype >= 0)
759 rte_log_set_level(ifpga_rawdev_logtype, RTE_LOG_NOTICE);
760 }
761
762 static const char * const valid_args[] = {
763 #define IFPGA_ARG_NAME "ifpga"
764 IFPGA_ARG_NAME,
765 #define IFPGA_ARG_PORT "port"
766 IFPGA_ARG_PORT,
767 #define IFPGA_AFU_BTS "afu_bts"
768 IFPGA_AFU_BTS,
769 NULL
770 };
771
772 static int
773 ifpga_cfg_probe(struct rte_vdev_device *dev)
774 {
775 struct rte_devargs *devargs;
776 struct rte_kvargs *kvlist = NULL;
777 int port;
778 char *name = NULL;
779 char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
780 int ret = -1;
781
782 devargs = dev->device.devargs;
783
784 kvlist = rte_kvargs_parse(devargs->args, valid_args);
785 if (!kvlist) {
786 IFPGA_RAWDEV_PMD_LOG(ERR, "error when parsing param");
787 goto end;
788 }
789
790 if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
791 if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
792 &rte_ifpga_get_string_arg, &name) < 0) {
793 IFPGA_RAWDEV_PMD_ERR("error to parse %s",
794 IFPGA_ARG_NAME);
795 goto end;
796 }
797 } else {
798 IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
799 IFPGA_ARG_NAME);
800 goto end;
801 }
802
803 if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
804 if (rte_kvargs_process(kvlist,
805 IFPGA_ARG_PORT,
806 &rte_ifpga_get_integer32_arg,
807 &port) < 0) {
808 IFPGA_RAWDEV_PMD_ERR("error to parse %s",
809 IFPGA_ARG_PORT);
810 goto end;
811 }
812 } else {
813 IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
814 IFPGA_ARG_PORT);
815 goto end;
816 }
817
818 memset(dev_name, 0, sizeof(dev_name));
819 snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
820 port, name);
821
822 ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME),
823 dev_name, devargs->args);
824 end:
825 if (kvlist)
826 rte_kvargs_free(kvlist);
827 if (name)
828 free(name);
829
830 return ret;
831 }
832
833 static int
834 ifpga_cfg_remove(struct rte_vdev_device *vdev)
835 {
836 IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p",
837 vdev);
838
839 return 0;
840 }
841
842 static struct rte_vdev_driver ifpga_cfg_driver = {
843 .probe = ifpga_cfg_probe,
844 .remove = ifpga_cfg_remove,
845 };
846
847 RTE_PMD_REGISTER_VDEV(ifpga_rawdev_cfg, ifpga_cfg_driver);
848 RTE_PMD_REGISTER_ALIAS(ifpga_rawdev_cfg, ifpga_cfg);
849 RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg,
850 "ifpga=<string> "
851 "port=<int> "
852 "afu_bts=<path>");