xref: /dpdk/drivers/raw/ifpga/ifpga_rawdev.c (revision 7f12dfdc)
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, const char *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 	if (buffer_size <= 0) {
300 		ret = -EINVAL;
301 		goto close_fd;
302 	}
303 
304 	IFPGA_RAWDEV_PMD_INFO("bitstream file size: %zu\n", buffer_size);
305 	buffer = rte_malloc(NULL, buffer_size, 0);
306 	if (!buffer) {
307 		ret = -ENOMEM;
308 		goto close_fd;
309 	}
310 
311 	/*read the raw data*/
312 	if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) {
313 		ret = -EINVAL;
314 		goto free_buffer;
315 	}
316 
317 	/*do PR now*/
318 	ret = fpga_pr(rawdev, port_id, buffer, buffer_size, &pr_error);
319 	IFPGA_RAWDEV_PMD_INFO("downloading to device port %d....%s.\n", port_id,
320 		ret ? "failed" : "success");
321 	if (ret) {
322 		ret = -EINVAL;
323 		goto free_buffer;
324 	}
325 
326 free_buffer:
327 	if (buffer)
328 		rte_free(buffer);
329 close_fd:
330 	close(file_fd);
331 	file_fd = 0;
332 	return ret;
333 }
334 
335 static int
336 ifpga_rawdev_pr(struct rte_rawdev *dev,
337 	rte_rawdev_obj_t pr_conf)
338 {
339 	struct opae_adapter *adapter;
340 	struct rte_afu_pr_conf *afu_pr_conf;
341 	int ret;
342 	struct uuid uuid;
343 	struct opae_accelerator *acc;
344 
345 	IFPGA_RAWDEV_PMD_FUNC_TRACE();
346 
347 	adapter = ifpga_rawdev_get_priv(dev);
348 	if (!adapter)
349 		return -ENODEV;
350 
351 	if (!pr_conf)
352 		return -EINVAL;
353 
354 	afu_pr_conf = pr_conf;
355 
356 	if (afu_pr_conf->pr_enable) {
357 		ret = rte_fpga_do_pr(dev,
358 				afu_pr_conf->afu_id.port,
359 				afu_pr_conf->bs_path);
360 		if (ret) {
361 			IFPGA_RAWDEV_PMD_ERR("do pr error %d\n", ret);
362 			return ret;
363 		}
364 	}
365 
366 	acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
367 	if (!acc)
368 		return -ENODEV;
369 
370 	ret = opae_acc_get_uuid(acc, &uuid);
371 	if (ret)
372 		return ret;
373 
374 	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
375 	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
376 
377 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
378 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
379 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
380 
381 	return 0;
382 }
383 
384 static int
385 ifpga_rawdev_get_attr(struct rte_rawdev *dev,
386 	const char *attr_name, uint64_t *attr_value)
387 {
388 	struct opae_adapter *adapter;
389 	struct opae_manager *mgr;
390 	struct opae_retimer_info opae_rtm_info;
391 	struct opae_retimer_status opae_rtm_status;
392 	struct opae_eth_group_info opae_eth_grp_info;
393 	struct opae_eth_group_region_info opae_eth_grp_reg_info;
394 	int eth_group_num = 0;
395 	uint64_t port_link_bitmap = 0, port_link_bit;
396 	uint32_t i, j, p, q;
397 
398 #define MAX_PORT_PER_RETIMER    4
399 
400 	IFPGA_RAWDEV_PMD_FUNC_TRACE();
401 
402 	if (!dev || !attr_name || !attr_value) {
403 		IFPGA_RAWDEV_PMD_ERR("Invalid arguments for getting attributes");
404 		return -1;
405 	}
406 
407 	adapter = ifpga_rawdev_get_priv(dev);
408 	if (!adapter) {
409 		IFPGA_RAWDEV_PMD_ERR("Adapter of dev %s is NULL", dev->name);
410 		return -1;
411 	}
412 
413 	mgr = opae_adapter_get_mgr(adapter);
414 	if (!mgr) {
415 		IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL");
416 		return -1;
417 	}
418 
419 	/* currently, eth_group_num is always 2 */
420 	eth_group_num = opae_manager_get_eth_group_nums(mgr);
421 	if (eth_group_num < 0)
422 		return -1;
423 
424 	if (!strcmp(attr_name, "LineSideBaseMAC")) {
425 		/* Currently FPGA not implement, so just set all zeros*/
426 		*attr_value = (uint64_t)0;
427 		return 0;
428 	}
429 	if (!strcmp(attr_name, "LineSideMACType")) {
430 		/* eth_group 0 on FPGA connect to LineSide */
431 		if (opae_manager_get_eth_group_info(mgr, 0,
432 			&opae_eth_grp_info))
433 			return -1;
434 		switch (opae_eth_grp_info.speed) {
435 		case ETH_SPEED_10G:
436 			*attr_value =
437 			(uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI);
438 			break;
439 		case ETH_SPEED_25G:
440 			*attr_value =
441 			(uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI);
442 			break;
443 		default:
444 			*attr_value =
445 			(uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_UNKNOWN);
446 			break;
447 		}
448 		return 0;
449 	}
450 	if (!strcmp(attr_name, "LineSideLinkSpeed")) {
451 		if (opae_manager_get_retimer_status(mgr, &opae_rtm_status))
452 			return -1;
453 		switch (opae_rtm_status.speed) {
454 		case MXD_1GB:
455 			*attr_value =
456 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
457 			break;
458 		case MXD_2_5GB:
459 			*attr_value =
460 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
461 			break;
462 		case MXD_5GB:
463 			*attr_value =
464 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
465 			break;
466 		case MXD_10GB:
467 			*attr_value =
468 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_10GB);
469 			break;
470 		case MXD_25GB:
471 			*attr_value =
472 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_25GB);
473 			break;
474 		case MXD_40GB:
475 			*attr_value =
476 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_40GB);
477 			break;
478 		case MXD_100GB:
479 			*attr_value =
480 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
481 			break;
482 		case MXD_SPEED_UNKNOWN:
483 			*attr_value =
484 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
485 			break;
486 		default:
487 			*attr_value =
488 				(uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN);
489 			break;
490 		}
491 		return 0;
492 	}
493 	if (!strcmp(attr_name, "LineSideLinkRetimerNum")) {
494 		if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
495 			return -1;
496 		*attr_value = (uint64_t)(opae_rtm_info.nums_retimer);
497 		return 0;
498 	}
499 	if (!strcmp(attr_name, "LineSideLinkPortNum")) {
500 		if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
501 			return -1;
502 		uint64_t tmp = (uint64_t)opae_rtm_info.ports_per_retimer *
503 					(uint64_t)opae_rtm_info.nums_retimer;
504 		*attr_value = tmp;
505 		return 0;
506 	}
507 	if (!strcmp(attr_name, "LineSideLinkStatus")) {
508 		if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
509 			return -1;
510 		if (opae_manager_get_retimer_status(mgr, &opae_rtm_status))
511 			return -1;
512 		(*attr_value) = 0;
513 		q = 0;
514 		port_link_bitmap = (uint64_t)(opae_rtm_status.line_link_bitmap);
515 		for (i = 0; i < opae_rtm_info.nums_retimer; i++) {
516 			p = i * MAX_PORT_PER_RETIMER;
517 			for (j = 0; j < opae_rtm_info.ports_per_retimer; j++) {
518 				port_link_bit = 0;
519 				IFPGA_BIT_SET(port_link_bit, (p+j));
520 				port_link_bit &= port_link_bitmap;
521 				if (port_link_bit)
522 					IFPGA_BIT_SET((*attr_value), q);
523 				q++;
524 			}
525 		}
526 		return 0;
527 	}
528 	if (!strcmp(attr_name, "LineSideBARIndex")) {
529 		/* eth_group 0 on FPGA connect to LineSide */
530 		if (opae_manager_get_eth_group_region_info(mgr, 0,
531 			&opae_eth_grp_reg_info))
532 			return -1;
533 		*attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx;
534 		return 0;
535 	}
536 	if (!strcmp(attr_name, "NICSideMACType")) {
537 		/* eth_group 1 on FPGA connect to NicSide */
538 		if (opae_manager_get_eth_group_info(mgr, 1,
539 			&opae_eth_grp_info))
540 			return -1;
541 		*attr_value = (uint64_t)(opae_eth_grp_info.speed);
542 		return 0;
543 	}
544 	if (!strcmp(attr_name, "NICSideLinkSpeed")) {
545 		/* eth_group 1 on FPGA connect to NicSide */
546 		if (opae_manager_get_eth_group_info(mgr, 1,
547 			&opae_eth_grp_info))
548 			return -1;
549 		*attr_value = (uint64_t)(opae_eth_grp_info.speed);
550 		return 0;
551 	}
552 	if (!strcmp(attr_name, "NICSideLinkPortNum")) {
553 		if (opae_manager_get_retimer_info(mgr, &opae_rtm_info))
554 			return -1;
555 		uint64_t tmp = (uint64_t)opae_rtm_info.nums_fvl *
556 					(uint64_t)opae_rtm_info.ports_per_fvl;
557 		*attr_value = tmp;
558 		return 0;
559 	}
560 	if (!strcmp(attr_name, "NICSideLinkStatus"))
561 		return 0;
562 	if (!strcmp(attr_name, "NICSideBARIndex")) {
563 		/* eth_group 1 on FPGA connect to NicSide */
564 		if (opae_manager_get_eth_group_region_info(mgr, 1,
565 			&opae_eth_grp_reg_info))
566 			return -1;
567 		*attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx;
568 		return 0;
569 	}
570 
571 	IFPGA_RAWDEV_PMD_ERR("%s not support", attr_name);
572 	return -1;
573 }
574 
575 static const struct rte_rawdev_ops ifpga_rawdev_ops = {
576 	.dev_info_get = ifpga_rawdev_info_get,
577 	.dev_configure = ifpga_rawdev_configure,
578 	.dev_start = ifpga_rawdev_start,
579 	.dev_stop = ifpga_rawdev_stop,
580 	.dev_close = ifpga_rawdev_close,
581 	.dev_reset = ifpga_rawdev_reset,
582 
583 	.queue_def_conf = NULL,
584 	.queue_setup = NULL,
585 	.queue_release = NULL,
586 
587 	.attr_get = ifpga_rawdev_get_attr,
588 	.attr_set = NULL,
589 
590 	.enqueue_bufs = NULL,
591 	.dequeue_bufs = NULL,
592 
593 	.dump = NULL,
594 
595 	.xstats_get = NULL,
596 	.xstats_get_names = NULL,
597 	.xstats_get_by_name = NULL,
598 	.xstats_reset = NULL,
599 
600 	.firmware_status_get = NULL,
601 	.firmware_version_get = NULL,
602 	.firmware_load = ifpga_rawdev_pr,
603 	.firmware_unload = NULL,
604 
605 	.dev_selftest = NULL,
606 };
607 
608 static int
609 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
610 			int socket_id)
611 {
612 	int ret = 0;
613 	struct rte_rawdev *rawdev = NULL;
614 	struct opae_adapter *adapter = NULL;
615 	struct opae_manager *mgr = NULL;
616 	struct opae_adapter_data_pci *data = NULL;
617 	char name[RTE_RAWDEV_NAME_MAX_LEN];
618 	int i;
619 
620 	if (!pci_dev) {
621 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
622 		ret = -EINVAL;
623 		goto cleanup;
624 	}
625 
626 	memset(name, 0, sizeof(name));
627 	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
628 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
629 
630 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
631 
632 	/* Allocate device structure */
633 	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct opae_adapter),
634 					 socket_id);
635 	if (rawdev == NULL) {
636 		IFPGA_RAWDEV_PMD_ERR("Unable to allocate rawdevice");
637 		ret = -EINVAL;
638 		goto cleanup;
639 	}
640 
641 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
642 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
643 	if (!data) {
644 		ret = -ENOMEM;
645 		goto cleanup;
646 	}
647 
648 	/* init opae_adapter_data_pci for device specific information */
649 	for (i = 0; i < PCI_MAX_RESOURCE; i++) {
650 		data->region[i].phys_addr = pci_dev->mem_resource[i].phys_addr;
651 		data->region[i].len = pci_dev->mem_resource[i].len;
652 		data->region[i].addr = pci_dev->mem_resource[i].addr;
653 	}
654 	data->device_id = pci_dev->id.device_id;
655 	data->vendor_id = pci_dev->id.vendor_id;
656 
657 	adapter = rawdev->dev_private;
658 	/* create a opae_adapter based on above device data */
659 	ret = opae_adapter_init(adapter, pci_dev->device.name, data);
660 	if (ret) {
661 		ret = -ENOMEM;
662 		goto free_adapter_data;
663 	}
664 
665 	rawdev->dev_ops = &ifpga_rawdev_ops;
666 	rawdev->device = &pci_dev->device;
667 	rawdev->driver_name = pci_dev->driver->driver.name;
668 
669 	/* must enumerate the adapter before use it */
670 	ret = opae_adapter_enumerate(adapter);
671 	if (ret)
672 		goto free_adapter_data;
673 
674 	/* get opae_manager to rawdev */
675 	mgr = opae_adapter_get_mgr(adapter);
676 	if (mgr) {
677 		/* PF function */
678 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
679 	}
680 
681 	return ret;
682 
683 free_adapter_data:
684 	if (data)
685 		opae_adapter_data_free(data);
686 cleanup:
687 	if (rawdev)
688 		rte_rawdev_pmd_release(rawdev);
689 
690 	return ret;
691 }
692 
693 static int
694 ifpga_rawdev_destroy(struct rte_pci_device *pci_dev)
695 {
696 	int ret;
697 	struct rte_rawdev *rawdev;
698 	char name[RTE_RAWDEV_NAME_MAX_LEN];
699 	struct opae_adapter *adapter;
700 
701 	if (!pci_dev) {
702 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
703 		ret = -EINVAL;
704 		return ret;
705 	}
706 
707 	memset(name, 0, sizeof(name));
708 	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
709 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
710 
711 	IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d",
712 		name, rte_socket_id());
713 
714 	rawdev = rte_rawdev_pmd_get_named_dev(name);
715 	if (!rawdev) {
716 		IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name);
717 		return -EINVAL;
718 	}
719 
720 	adapter = ifpga_rawdev_get_priv(rawdev);
721 	if (!adapter)
722 		return -ENODEV;
723 
724 	opae_adapter_data_free(adapter->data);
725 	opae_adapter_free(adapter);
726 
727 	/* rte_rawdev_close is called by pmd_release */
728 	ret = rte_rawdev_pmd_release(rawdev);
729 	if (ret)
730 		IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed");
731 
732 	return ret;
733 }
734 
735 static int
736 ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
737 	struct rte_pci_device *pci_dev)
738 {
739 	IFPGA_RAWDEV_PMD_FUNC_TRACE();
740 	return ifpga_rawdev_create(pci_dev, rte_socket_id());
741 }
742 
743 static int
744 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
745 {
746 	return ifpga_rawdev_destroy(pci_dev);
747 }
748 
749 static struct rte_pci_driver rte_ifpga_rawdev_pmd = {
750 	.id_table  = pci_ifpga_map,
751 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
752 	.probe     = ifpga_rawdev_pci_probe,
753 	.remove    = ifpga_rawdev_pci_remove,
754 };
755 
756 RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd);
757 RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd);
758 RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci");
759 
760 RTE_INIT(ifpga_rawdev_init_log)
761 {
762 	ifpga_rawdev_logtype = rte_log_register("driver.raw.init");
763 	if (ifpga_rawdev_logtype >= 0)
764 		rte_log_set_level(ifpga_rawdev_logtype, RTE_LOG_NOTICE);
765 }
766 
767 static const char * const valid_args[] = {
768 #define IFPGA_ARG_NAME         "ifpga"
769 	IFPGA_ARG_NAME,
770 #define IFPGA_ARG_PORT         "port"
771 	IFPGA_ARG_PORT,
772 #define IFPGA_AFU_BTS          "afu_bts"
773 	IFPGA_AFU_BTS,
774 	NULL
775 };
776 
777 static int
778 ifpga_cfg_probe(struct rte_vdev_device *dev)
779 {
780 	struct rte_devargs *devargs;
781 	struct rte_kvargs *kvlist = NULL;
782 	int port;
783 	char *name = NULL;
784 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
785 	int ret = -1;
786 
787 	devargs = dev->device.devargs;
788 
789 	kvlist = rte_kvargs_parse(devargs->args, valid_args);
790 	if (!kvlist) {
791 		IFPGA_RAWDEV_PMD_LOG(ERR, "error when parsing param");
792 		goto end;
793 	}
794 
795 	if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
796 		if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
797 				       &rte_ifpga_get_string_arg, &name) < 0) {
798 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
799 				     IFPGA_ARG_NAME);
800 			goto end;
801 		}
802 	} else {
803 		IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
804 			  IFPGA_ARG_NAME);
805 		goto end;
806 	}
807 
808 	if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
809 		if (rte_kvargs_process(kvlist,
810 			IFPGA_ARG_PORT,
811 			&rte_ifpga_get_integer32_arg,
812 			&port) < 0) {
813 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
814 				IFPGA_ARG_PORT);
815 			goto end;
816 		}
817 	} else {
818 		IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
819 			  IFPGA_ARG_PORT);
820 		goto end;
821 	}
822 
823 	memset(dev_name, 0, sizeof(dev_name));
824 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
825 	port, name);
826 
827 	ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME),
828 			dev_name, devargs->args);
829 end:
830 	if (kvlist)
831 		rte_kvargs_free(kvlist);
832 	if (name)
833 		free(name);
834 
835 	return ret;
836 }
837 
838 static int
839 ifpga_cfg_remove(struct rte_vdev_device *vdev)
840 {
841 	IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p",
842 		vdev);
843 
844 	return 0;
845 }
846 
847 static struct rte_vdev_driver ifpga_cfg_driver = {
848 	.probe = ifpga_cfg_probe,
849 	.remove = ifpga_cfg_remove,
850 };
851 
852 RTE_PMD_REGISTER_VDEV(ifpga_rawdev_cfg, ifpga_cfg_driver);
853 RTE_PMD_REGISTER_ALIAS(ifpga_rawdev_cfg, ifpga_cfg);
854 RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg,
855 	"ifpga=<string> "
856 	"port=<int> "
857 	"afu_bts=<path>");
858