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