remove useless include of EAL memory config header
[dpdk.git] / drivers / raw / ifpga / 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_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>");