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