bus/fslmc: do not log messages if bus not present
[dpdk.git] / drivers / bus / fslmc / fslmc_vfio.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
4  *   Copyright 2016 NXP
5  *
6  */
7
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <sys/types.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <sys/ioctl.h>
16 #include <sys/stat.h>
17 #include <sys/mman.h>
18 #include <sys/vfs.h>
19 #include <libgen.h>
20 #include <dirent.h>
21 #include <sys/eventfd.h>
22
23 #include <eal_filesystem.h>
24 #include <rte_mbuf.h>
25 #include <rte_ethdev_driver.h>
26 #include <rte_malloc.h>
27 #include <rte_memcpy.h>
28 #include <rte_string_fns.h>
29 #include <rte_cycles.h>
30 #include <rte_kvargs.h>
31 #include <rte_dev.h>
32 #include <rte_bus.h>
33 #include <rte_eal_memconfig.h>
34
35 #include "rte_fslmc.h"
36 #include "fslmc_vfio.h"
37 #include "fslmc_logs.h"
38 #include <mc/fsl_dpmng.h>
39
40 #include "portal/dpaa2_hw_pvt.h"
41 #include "portal/dpaa2_hw_dpio.h"
42
43 /** Pathname of FSL-MC devices directory. */
44 #define SYSFS_FSL_MC_DEVICES "/sys/bus/fsl-mc/devices"
45
46 #define FSLMC_CONTAINER_MAX_LEN 8 /**< Of the format dprc.XX */
47
48 /* Number of VFIO containers & groups with in */
49 static struct fslmc_vfio_group vfio_group;
50 static struct fslmc_vfio_container vfio_container;
51 static int container_device_fd;
52 static char *g_container;
53 static uint32_t *msi_intr_vaddr;
54 void *(*rte_mcp_ptr_list);
55
56 static struct rte_dpaa2_object_list dpaa2_obj_list =
57         TAILQ_HEAD_INITIALIZER(dpaa2_obj_list);
58
59 /*register a fslmc bus based dpaa2 driver */
60 void
61 rte_fslmc_object_register(struct rte_dpaa2_object *object)
62 {
63         RTE_VERIFY(object);
64
65         TAILQ_INSERT_TAIL(&dpaa2_obj_list, object, next);
66 }
67
68 int
69 fslmc_get_container_group(int *groupid)
70 {
71         int ret;
72         char *container;
73
74         if (!g_container) {
75                 container = getenv("DPRC");
76                 if (container == NULL) {
77                         DPAA2_BUS_DEBUG("DPAA2: DPRC not available");
78                         return -EINVAL;
79                 }
80
81                 if (strlen(container) >= FSLMC_CONTAINER_MAX_LEN) {
82                         DPAA2_BUS_ERR("Invalid container name: %s", container);
83                         return -1;
84                 }
85
86                 g_container = strdup(container);
87                 if (!g_container) {
88                         DPAA2_BUS_ERR("Mem alloc failure; Container name");
89                         return -ENOMEM;
90                 }
91         }
92
93         /* get group number */
94         ret = rte_vfio_get_group_num(SYSFS_FSL_MC_DEVICES,
95                                      g_container, groupid);
96         if (ret <= 0) {
97                 DPAA2_BUS_ERR("Unable to find %s IOMMU group", g_container);
98                 return -1;
99         }
100
101         DPAA2_BUS_DEBUG("Container: %s has VFIO iommu group id = %d",
102                         g_container, *groupid);
103
104         return 0;
105 }
106
107 static int
108 vfio_connect_container(void)
109 {
110         int fd, ret;
111
112         if (vfio_container.used) {
113                 DPAA2_BUS_DEBUG("No container available");
114                 return -1;
115         }
116
117         /* Try connecting to vfio container if already created */
118         if (!ioctl(vfio_group.fd, VFIO_GROUP_SET_CONTAINER,
119                 &vfio_container.fd)) {
120                 DPAA2_BUS_DEBUG(
121                     "Container pre-exists with FD[0x%x] for this group",
122                     vfio_container.fd);
123                 vfio_group.container = &vfio_container;
124                 return 0;
125         }
126
127         /* Opens main vfio file descriptor which represents the "container" */
128         fd = rte_vfio_get_container_fd();
129         if (fd < 0) {
130                 DPAA2_BUS_ERR("Failed to open VFIO container");
131                 return -errno;
132         }
133
134         /* Check whether support for SMMU type IOMMU present or not */
135         if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
136                 /* Connect group to container */
137                 ret = ioctl(vfio_group.fd, VFIO_GROUP_SET_CONTAINER, &fd);
138                 if (ret) {
139                         DPAA2_BUS_ERR("Failed to setup group container");
140                         close(fd);
141                         return -errno;
142                 }
143
144                 ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
145                 if (ret) {
146                         DPAA2_BUS_ERR("Failed to setup VFIO iommu");
147                         close(fd);
148                         return -errno;
149                 }
150         } else {
151                 DPAA2_BUS_ERR("No supported IOMMU available");
152                 close(fd);
153                 return -EINVAL;
154         }
155
156         vfio_container.used = 1;
157         vfio_container.fd = fd;
158         vfio_container.group = &vfio_group;
159         vfio_group.container = &vfio_container;
160
161         return 0;
162 }
163
164 static int vfio_map_irq_region(struct fslmc_vfio_group *group)
165 {
166         int ret;
167         unsigned long *vaddr = NULL;
168         struct vfio_iommu_type1_dma_map map = {
169                 .argsz = sizeof(map),
170                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
171                 .vaddr = 0x6030000,
172                 .iova = 0x6030000,
173                 .size = 0x1000,
174         };
175
176         vaddr = (unsigned long *)mmap(NULL, 0x1000, PROT_WRITE |
177                 PROT_READ, MAP_SHARED, container_device_fd, 0x6030000);
178         if (vaddr == MAP_FAILED) {
179                 DPAA2_BUS_ERR("Unable to map region (errno = %d)", errno);
180                 return -errno;
181         }
182
183         msi_intr_vaddr = (uint32_t *)((char *)(vaddr) + 64);
184         map.vaddr = (unsigned long)vaddr;
185         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &map);
186         if (ret == 0)
187                 return 0;
188
189         DPAA2_BUS_ERR("Unable to map DMA address (errno = %d)", errno);
190         return -errno;
191 }
192
193 static int fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len);
194 static int fslmc_unmap_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len);
195
196 static void
197 fslmc_memevent_cb(enum rte_mem_event type, const void *addr, size_t len)
198 {
199         struct rte_memseg_list *msl;
200         struct rte_memseg *ms;
201         size_t cur_len = 0, map_len = 0;
202         uint64_t virt_addr;
203         rte_iova_t iova_addr;
204         int ret;
205
206         msl = rte_mem_virt2memseg_list(addr);
207
208         while (cur_len < len) {
209                 const void *va = RTE_PTR_ADD(addr, cur_len);
210
211                 ms = rte_mem_virt2memseg(va, msl);
212                 iova_addr = ms->iova;
213                 virt_addr = ms->addr_64;
214                 map_len = ms->len;
215
216                 DPAA2_BUS_DEBUG("Request for %s, va=%p, "
217                                 "virt_addr=0x%" PRIx64 ", "
218                                 "iova=0x%" PRIx64 ", map_len=%zu",
219                                 type == RTE_MEM_EVENT_ALLOC ?
220                                         "alloc" : "dealloc",
221                                 va, virt_addr, iova_addr, map_len);
222
223                 if (type == RTE_MEM_EVENT_ALLOC)
224                         ret = fslmc_map_dma(virt_addr, iova_addr, map_len);
225                 else
226                         ret = fslmc_unmap_dma(virt_addr, iova_addr, map_len);
227
228                 if (ret != 0) {
229                         DPAA2_BUS_ERR("DMA Mapping/Unmapping failed. "
230                                         "Map=%d, addr=%p, len=%zu, err:(%d)",
231                                         type, va, map_len, ret);
232                         return;
233                 }
234
235                 cur_len += map_len;
236         }
237
238         if (type == RTE_MEM_EVENT_ALLOC)
239                 DPAA2_BUS_DEBUG("Total Mapped: addr=%p, len=%zu",
240                                 addr, len);
241         else
242                 DPAA2_BUS_DEBUG("Total Unmapped: addr=%p, len=%zu",
243                                 addr, len);
244 }
245
246 static int
247 fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr __rte_unused, size_t len)
248 {
249         struct fslmc_vfio_group *group;
250         struct vfio_iommu_type1_dma_map dma_map = {
251                 .argsz = sizeof(struct vfio_iommu_type1_dma_map),
252                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
253         };
254         int ret;
255
256         dma_map.size = len;
257         dma_map.vaddr = vaddr;
258
259 #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
260         dma_map.iova = iovaddr;
261 #else
262         dma_map.iova = dma_map.vaddr;
263 #endif
264
265         /* SET DMA MAP for IOMMU */
266         group = &vfio_group;
267
268         if (!group->container) {
269                 DPAA2_BUS_ERR("Container is not connected ");
270                 return -1;
271         }
272
273         DPAA2_BUS_DEBUG("--> Map address: 0x%"PRIx64", size: %"PRIu64"",
274                         (uint64_t)dma_map.vaddr, (uint64_t)dma_map.size);
275         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &dma_map);
276         if (ret) {
277                 DPAA2_BUS_ERR("VFIO_IOMMU_MAP_DMA API(errno = %d)",
278                                 errno);
279                 return -1;
280         }
281
282         return 0;
283 }
284
285 static int
286 fslmc_unmap_dma(uint64_t vaddr, uint64_t iovaddr __rte_unused, size_t len)
287 {
288         struct fslmc_vfio_group *group;
289         struct vfio_iommu_type1_dma_unmap dma_unmap = {
290                 .argsz = sizeof(struct vfio_iommu_type1_dma_unmap),
291                 .flags = 0,
292         };
293         int ret;
294
295         dma_unmap.size = len;
296         dma_unmap.iova = vaddr;
297
298         /* SET DMA MAP for IOMMU */
299         group = &vfio_group;
300
301         if (!group->container) {
302                 DPAA2_BUS_ERR("Container is not connected ");
303                 return -1;
304         }
305
306         DPAA2_BUS_DEBUG("--> Unmap address: 0x%"PRIx64", size: %"PRIu64"",
307                         (uint64_t)dma_unmap.iova, (uint64_t)dma_unmap.size);
308         ret = ioctl(group->container->fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);
309         if (ret) {
310                 DPAA2_BUS_ERR("VFIO_IOMMU_UNMAP_DMA API(errno = %d)",
311                                 errno);
312                 return -1;
313         }
314
315         return 0;
316 }
317
318 static int
319 fslmc_dmamap_seg(const struct rte_memseg_list *msl __rte_unused,
320                  const struct rte_memseg *ms, void *arg)
321 {
322         int *n_segs = arg;
323         int ret;
324
325         ret = fslmc_map_dma(ms->addr_64, ms->iova, ms->len);
326         if (ret)
327                 DPAA2_BUS_ERR("Unable to VFIO map (addr=%p, len=%zu)",
328                                 ms->addr, ms->len);
329         else
330                 (*n_segs)++;
331
332         return ret;
333 }
334
335 int rte_fslmc_vfio_dmamap(void)
336 {
337         int i = 0, ret;
338         struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
339         rte_rwlock_t *mem_lock = &mcfg->memory_hotplug_lock;
340
341         /* Lock before parsing and registering callback to memory subsystem */
342         rte_rwlock_read_lock(mem_lock);
343
344         if (rte_memseg_walk(fslmc_dmamap_seg, &i) < 0) {
345                 rte_rwlock_read_unlock(mem_lock);
346                 return -1;
347         }
348
349         ret = rte_mem_event_callback_register("fslmc_memevent_clb",
350                                               fslmc_memevent_cb);
351         if (ret && rte_errno == ENOTSUP)
352                 DPAA2_BUS_DEBUG("Memory event callbacks not supported");
353         else if (ret)
354                 DPAA2_BUS_DEBUG("Unable to install memory handler");
355         else
356                 DPAA2_BUS_DEBUG("Installed memory callback handler");
357
358         DPAA2_BUS_DEBUG("Total %d segments found.", i);
359
360         /* TODO - This is a W.A. as VFIO currently does not add the mapping of
361          * the interrupt region to SMMU. This should be removed once the
362          * support is added in the Kernel.
363          */
364         vfio_map_irq_region(&vfio_group);
365
366         /* Existing segments have been mapped and memory callback for hotplug
367          * has been installed.
368          */
369         rte_rwlock_read_unlock(mem_lock);
370
371         return 0;
372 }
373
374 static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
375 {
376         intptr_t v_addr = (intptr_t)MAP_FAILED;
377         int32_t ret, mc_fd;
378
379         struct vfio_device_info d_info = { .argsz = sizeof(d_info) };
380         struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
381
382         /* getting the mcp object's fd*/
383         mc_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, mcp_obj);
384         if (mc_fd < 0) {
385                 DPAA2_BUS_ERR("Error in VFIO get dev %s fd from group %d",
386                               mcp_obj, group->fd);
387                 return v_addr;
388         }
389
390         /* getting device info*/
391         ret = ioctl(mc_fd, VFIO_DEVICE_GET_INFO, &d_info);
392         if (ret < 0) {
393                 DPAA2_BUS_ERR("Error in VFIO getting DEVICE_INFO");
394                 goto MC_FAILURE;
395         }
396
397         /* getting device region info*/
398         ret = ioctl(mc_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
399         if (ret < 0) {
400                 DPAA2_BUS_ERR("Error in VFIO getting REGION_INFO");
401                 goto MC_FAILURE;
402         }
403
404         DPAA2_BUS_DEBUG("Region offset = 0x%"PRIx64"  , region size = %"PRIu64"",
405                         (uint64_t)reg_info.offset, (uint64_t)reg_info.size);
406
407         v_addr = (size_t)mmap(NULL, reg_info.size,
408                 PROT_WRITE | PROT_READ, MAP_SHARED,
409                 mc_fd, reg_info.offset);
410
411 MC_FAILURE:
412         close(mc_fd);
413
414         return v_addr;
415 }
416
417 #define IRQ_SET_BUF_LEN  (sizeof(struct vfio_irq_set) + sizeof(int))
418
419 int rte_dpaa2_intr_enable(struct rte_intr_handle *intr_handle, int index)
420 {
421         int len, ret;
422         char irq_set_buf[IRQ_SET_BUF_LEN];
423         struct vfio_irq_set *irq_set;
424         int *fd_ptr;
425
426         len = sizeof(irq_set_buf);
427
428         irq_set = (struct vfio_irq_set *)irq_set_buf;
429         irq_set->argsz = len;
430         irq_set->count = 1;
431         irq_set->flags =
432                 VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
433         irq_set->index = index;
434         irq_set->start = 0;
435         fd_ptr = (int *)&irq_set->data;
436         *fd_ptr = intr_handle->fd;
437
438         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
439         if (ret) {
440                 DPAA2_BUS_ERR("Error:dpaa2 SET IRQs fd=%d, err = %d(%s)",
441                               intr_handle->fd, errno, strerror(errno));
442                 return ret;
443         }
444
445         return ret;
446 }
447
448 int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
449 {
450         struct vfio_irq_set *irq_set;
451         char irq_set_buf[IRQ_SET_BUF_LEN];
452         int len, ret;
453
454         len = sizeof(struct vfio_irq_set);
455
456         irq_set = (struct vfio_irq_set *)irq_set_buf;
457         irq_set->argsz = len;
458         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
459         irq_set->index = index;
460         irq_set->start = 0;
461         irq_set->count = 0;
462
463         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
464         if (ret)
465                 DPAA2_BUS_ERR(
466                         "Error disabling dpaa2 interrupts for fd %d",
467                         intr_handle->fd);
468
469         return ret;
470 }
471
472 /* set up interrupt support (but not enable interrupts) */
473 int
474 rte_dpaa2_vfio_setup_intr(struct rte_intr_handle *intr_handle,
475                           int vfio_dev_fd,
476                           int num_irqs)
477 {
478         int i, ret;
479
480         /* start from MSI-X interrupt type */
481         for (i = 0; i < num_irqs; i++) {
482                 struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
483                 int fd = -1;
484
485                 irq_info.index = i;
486
487                 ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
488                 if (ret < 0) {
489                         DPAA2_BUS_ERR("Cannot get IRQ(%d) info, error %i (%s)",
490                                       i, errno, strerror(errno));
491                         return -1;
492                 }
493
494                 /* if this vector cannot be used with eventfd,
495                  * fail if we explicitly
496                  * specified interrupt type, otherwise continue
497                  */
498                 if ((irq_info.flags & VFIO_IRQ_INFO_EVENTFD) == 0)
499                         continue;
500
501                 /* set up an eventfd for interrupts */
502                 fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
503                 if (fd < 0) {
504                         DPAA2_BUS_ERR("Cannot set up eventfd, error %i (%s)",
505                                       errno, strerror(errno));
506                         return -1;
507                 }
508
509                 intr_handle->fd = fd;
510                 intr_handle->type = RTE_INTR_HANDLE_VFIO_MSI;
511                 intr_handle->vfio_dev_fd = vfio_dev_fd;
512
513                 return 0;
514         }
515
516         /* if we're here, we haven't found a suitable interrupt vector */
517         return -1;
518 }
519
520 /*
521  * fslmc_process_iodevices for processing only IO (ETH, CRYPTO, and possibly
522  * EVENT) devices.
523  */
524 static int
525 fslmc_process_iodevices(struct rte_dpaa2_device *dev)
526 {
527         int dev_fd;
528         struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
529         struct rte_dpaa2_object *object = NULL;
530
531         dev_fd = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD,
532                        dev->device.name);
533         if (dev_fd <= 0) {
534                 DPAA2_BUS_ERR("Unable to obtain device FD for device:%s",
535                               dev->device.name);
536                 return -1;
537         }
538
539         if (ioctl(dev_fd, VFIO_DEVICE_GET_INFO, &device_info)) {
540                 DPAA2_BUS_ERR("Unable to obtain information for device:%s",
541                               dev->device.name);
542                 return -1;
543         }
544
545         switch (dev->dev_type) {
546         case DPAA2_ETH:
547                 rte_dpaa2_vfio_setup_intr(&dev->intr_handle, dev_fd,
548                                           device_info.num_irqs);
549                 break;
550         case DPAA2_CON:
551         case DPAA2_IO:
552         case DPAA2_CI:
553         case DPAA2_BPOOL:
554                 TAILQ_FOREACH(object, &dpaa2_obj_list, next) {
555                         if (dev->dev_type == object->dev_type)
556                                 object->create(dev_fd, &device_info,
557                                                dev->object_id);
558                         else
559                                 continue;
560                 }
561                 break;
562         default:
563                 break;
564         }
565
566         DPAA2_BUS_DEBUG("Device (%s) abstracted from VFIO",
567                         dev->device.name);
568         return 0;
569 }
570
571 static int
572 fslmc_process_mcp(struct rte_dpaa2_device *dev)
573 {
574         intptr_t v_addr;
575         char *dev_name;
576         struct fsl_mc_io dpmng  = {0};
577         struct mc_version mc_ver_info = {0};
578
579         rte_mcp_ptr_list = malloc(sizeof(void *) * 1);
580         if (!rte_mcp_ptr_list) {
581                 DPAA2_BUS_ERR("Unable to allocate MC portal memory");
582                 return -ENOMEM;
583         }
584
585         dev_name = strdup(dev->device.name);
586         if (!dev_name) {
587                 DPAA2_BUS_ERR("Unable to allocate MC device name memory");
588                 free(rte_mcp_ptr_list);
589                 rte_mcp_ptr_list = NULL;
590                 return -ENOMEM;
591         }
592
593         v_addr = vfio_map_mcp_obj(&vfio_group, dev_name);
594         if (v_addr == (intptr_t)MAP_FAILED) {
595                 DPAA2_BUS_ERR("Error mapping region (errno = %d)", errno);
596                 free(rte_mcp_ptr_list);
597                 rte_mcp_ptr_list = NULL;
598                 return -1;
599         }
600
601         /* check the MC version compatibility */
602         dpmng.regs = (void *)v_addr;
603         if (mc_get_version(&dpmng, CMD_PRI_LOW, &mc_ver_info)) {
604                 DPAA2_BUS_ERR("Unable to obtain MC version");
605                 return -1;
606         }
607
608         if ((mc_ver_info.major != MC_VER_MAJOR) ||
609             (mc_ver_info.minor < MC_VER_MINOR)) {
610                 DPAA2_BUS_ERR("DPAA2 MC version not compatible!"
611                               " Expected %d.%d.x, Detected %d.%d.%d",
612                               MC_VER_MAJOR, MC_VER_MINOR,
613                               mc_ver_info.major, mc_ver_info.minor,
614                               mc_ver_info.revision);
615                 free(rte_mcp_ptr_list);
616                 rte_mcp_ptr_list = NULL;
617                 return -1;
618         }
619         rte_mcp_ptr_list[0] = (void *)v_addr;
620
621         return 0;
622 }
623
624 int
625 fslmc_vfio_process_group(void)
626 {
627         int ret;
628         int found_mportal = 0;
629         struct rte_dpaa2_device *dev, *dev_temp;
630
631         /* Search the MCP as that should be initialized first. */
632         TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
633                 if (dev->dev_type == DPAA2_MPORTAL) {
634                         ret = fslmc_process_mcp(dev);
635                         if (ret) {
636                                 DPAA2_BUS_ERR("Unable to map MC Portal");
637                                 return -1;
638                         }
639                         if (!found_mportal)
640                                 found_mportal = 1;
641
642                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
643                         free(dev);
644                         dev = NULL;
645                         /* Ideally there is only a single dpmcp, but in case
646                          * multiple exists, looping on remaining devices.
647                          */
648                 }
649         }
650
651         /* Cannot continue if there is not even a single mportal */
652         if (!found_mportal) {
653                 DPAA2_BUS_ERR("No MC Portal device found. Not continuing");
654                 return -1;
655         }
656
657         TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
658                 if (!dev)
659                         break;
660
661                 switch (dev->dev_type) {
662                 case DPAA2_ETH:
663                 case DPAA2_CRYPTO:
664                         ret = fslmc_process_iodevices(dev);
665                         if (ret) {
666                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
667                                                 dev->device.name);
668                                 return ret;
669                         }
670                         break;
671                 case DPAA2_CON:
672                 case DPAA2_IO:
673                 case DPAA2_CI:
674                 case DPAA2_BPOOL:
675                         /* Call the object creation routine and remove the
676                          * device entry from device list
677                          */
678                         ret = fslmc_process_iodevices(dev);
679                         if (ret) {
680                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
681                                                 dev->device.name);
682                                 return -1;
683                         }
684
685                         /* This device is not required to be in the DPDK
686                          * exposed device list.
687                          */
688                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
689                         free(dev);
690                         dev = NULL;
691                         break;
692                 case DPAA2_UNKNOWN:
693                 default:
694                         /* Unknown - ignore */
695                         DPAA2_BUS_DEBUG("Found unknown device (%s)",
696                                         dev->device.name);
697                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
698                         free(dev);
699                         dev = NULL;
700                 }
701         }
702
703         return 0;
704 }
705
706 int
707 fslmc_vfio_setup_group(void)
708 {
709         int groupid;
710         int ret;
711         struct vfio_group_status status = { .argsz = sizeof(status) };
712
713         /* if already done once */
714         if (container_device_fd)
715                 return 0;
716
717         ret = fslmc_get_container_group(&groupid);
718         if (ret)
719                 return ret;
720
721         /* In case this group was already opened, continue without any
722          * processing.
723          */
724         if (vfio_group.groupid == groupid) {
725                 DPAA2_BUS_ERR("groupid already exists %d", groupid);
726                 return 0;
727         }
728
729         /* Get the actual group fd */
730         ret = rte_vfio_get_group_fd(groupid);
731         if (ret < 0)
732                 return ret;
733         vfio_group.fd = ret;
734
735         /* Check group viability */
736         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_STATUS, &status);
737         if (ret) {
738                 DPAA2_BUS_ERR("VFIO error getting group status");
739                 close(vfio_group.fd);
740                 rte_vfio_clear_group(vfio_group.fd);
741                 return ret;
742         }
743
744         if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
745                 DPAA2_BUS_ERR("VFIO group not viable");
746                 close(vfio_group.fd);
747                 rte_vfio_clear_group(vfio_group.fd);
748                 return -EPERM;
749         }
750         /* Since Group is VIABLE, Store the groupid */
751         vfio_group.groupid = groupid;
752
753         /* check if group does not have a container yet */
754         if (!(status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
755                 /* Now connect this IOMMU group to given container */
756                 ret = vfio_connect_container();
757                 if (ret) {
758                         DPAA2_BUS_ERR(
759                                 "Error connecting container with groupid %d",
760                                 groupid);
761                         close(vfio_group.fd);
762                         rte_vfio_clear_group(vfio_group.fd);
763                         return ret;
764                 }
765         }
766
767         /* Get Device information */
768         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD, g_container);
769         if (ret < 0) {
770                 DPAA2_BUS_ERR("Error getting device %s fd from group %d",
771                               g_container, vfio_group.groupid);
772                 close(vfio_group.fd);
773                 rte_vfio_clear_group(vfio_group.fd);
774                 return ret;
775         }
776         container_device_fd = ret;
777         DPAA2_BUS_DEBUG("VFIO Container FD is [0x%X]",
778                         container_device_fd);
779
780         return 0;
781 }