41be1a205cfba99f244e510ae0b80529925a40d6
[dpdk.git] / 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>");