diff options
author | Luca Boccassi <luca.boccassi@gmail.com> | 2017-08-16 18:42:05 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2017-08-16 18:46:04 +0100 |
commit | f239aed5e674965691846e8ce3f187dd47523689 (patch) | |
tree | a153a3125c6e183c73871a8ecaa4b285fed5fbd5 /drivers/bus/fslmc/fslmc_vfio.c | |
parent | bf7567fd2a5b0b28ab724046143c24561d38d015 (diff) |
New upstream version 17.08
Change-Id: I288b50990f52646089d6b1f3aaa6ba2f091a51d7
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Diffstat (limited to 'drivers/bus/fslmc/fslmc_vfio.c')
-rw-r--r-- | drivers/bus/fslmc/fslmc_vfio.c | 165 |
1 files changed, 92 insertions, 73 deletions
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c index 5d4ac67c..45e59277 100644 --- a/drivers/bus/fslmc/fslmc_vfio.c +++ b/drivers/bus/fslmc/fslmc_vfio.c @@ -2,7 +2,7 @@ * BSD LICENSE * * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved. - * Copyright (c) 2016 NXP. All rights reserved. + * Copyright 2016 NXP. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,7 +40,6 @@ #include <errno.h> #include <sys/ioctl.h> #include <sys/stat.h> -#include <sys/types.h> #include <sys/mman.h> #include <sys/vfs.h> #include <libgen.h> @@ -55,7 +54,6 @@ #include <rte_cycles.h> #include <rte_kvargs.h> #include <rte_dev.h> -#include <rte_ethdev.h> #include <rte_bus.h> #include "rte_fslmc.h" @@ -80,6 +78,17 @@ static uint32_t *msi_intr_vaddr; void *(*rte_mcp_ptr_list); static uint32_t mcp_id; static int is_dma_done; +static struct rte_fslmc_object_list fslmc_obj_list = + TAILQ_HEAD_INITIALIZER(fslmc_obj_list); + +/*register a fslmc bus based dpaa2 driver */ +void +rte_fslmc_object_register(struct rte_dpaa2_object *object) +{ + RTE_VERIFY(object); + + TAILQ_INSERT_TAIL(&fslmc_obj_list, object, next); +} static int vfio_connect_container(struct fslmc_vfio_group *vfio_group) { @@ -91,9 +100,9 @@ static int vfio_connect_container(struct fslmc_vfio_group *vfio_group) container = &vfio_containers[i]; if (!ioctl(vfio_group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) { - FSLMC_VFIO_LOG(INFO, "Container pre-exists with" - " FD[0x%x] for this group", - container->fd); + FSLMC_VFIO_LOG(INFO, + "Container pre-exists with FD[0x%x] for this group", + container->fd); vfio_group->container = container; return 0; } @@ -132,7 +141,6 @@ static int vfio_connect_container(struct fslmc_vfio_group *vfio_group) for (i = 0; i < VFIO_MAX_CONTAINERS; i++) { if (vfio_containers[i].used) continue; - FSLMC_VFIO_LOG(DEBUG, "Unused container at index %d", i); container = &vfio_containers[i]; } if (!container) { @@ -178,29 +186,6 @@ static int vfio_map_irq_region(struct fslmc_vfio_group *group) return -errno; } -int vfio_dmamap_mem_region(uint64_t vaddr, - uint64_t iova, - uint64_t size) -{ - struct fslmc_vfio_group *group; - struct vfio_iommu_type1_dma_map dma_map = { - .argsz = sizeof(dma_map), - .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE, - }; - - dma_map.vaddr = vaddr; - dma_map.size = size; - dma_map.iova = iova; - - /* SET DMA MAP for IOMMU */ - group = &vfio_groups[0]; - if (ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &dma_map)) { - FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA (errno = %d)", errno); - return -1; - } - return 0; -} - int rte_fslmc_vfio_dmamap(void) { int ret; @@ -215,17 +200,18 @@ int rte_fslmc_vfio_dmamap(void) if (is_dma_done) return 0; - is_dma_done = 1; - for (i = 0; i < RTE_MAX_MEMSEG; i++) { - memseg = rte_eal_get_physmem_layout(); - if (memseg == NULL) { - FSLMC_VFIO_LOG(ERR, "Cannot get physical layout."); - return -ENODEV; - } + memseg = rte_eal_get_physmem_layout(); + if (memseg == NULL) { + FSLMC_VFIO_LOG(ERR, "Cannot get physical layout."); + return -ENODEV; + } - if (memseg[i].addr == NULL && memseg[i].len == 0) + for (i = 0; i < RTE_MAX_MEMSEG; i++) { + if (memseg[i].addr == NULL && memseg[i].len == 0) { + FSLMC_VFIO_LOG(DEBUG, "Total %d segments found.", i); break; + } dma_map.size = memseg[i].len; dma_map.vaddr = memseg[i].addr_64; @@ -245,16 +231,20 @@ int rte_fslmc_vfio_dmamap(void) FSLMC_VFIO_LOG(DEBUG, "-->Initial SHM Virtual ADDR %llX", dma_map.vaddr); - FSLMC_VFIO_LOG(DEBUG, "-----> DMA size 0x%llX\n", dma_map.size); + FSLMC_VFIO_LOG(DEBUG, "-----> DMA size 0x%llX", dma_map.size); ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &dma_map); if (ret) { - FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA API" - "(errno = %d)", errno); + FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA API(errno = %d)", + errno); return ret; } - FSLMC_VFIO_LOG(DEBUG, "-----> dma_map.vaddr = 0x%llX", - dma_map.vaddr); + } + + /* Verifying that at least single segment is available */ + if (i <= 0) { + FSLMC_VFIO_LOG(ERR, "No Segments found for VFIO Mapping"); + return -1; } /* TODO - This is a W.A. as VFIO currently does not add the mapping of @@ -263,6 +253,8 @@ int rte_fslmc_vfio_dmamap(void) */ vfio_map_irq_region(group); + is_dma_done = 1; + return 0; } @@ -277,8 +269,8 @@ static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj) /* getting the mcp object's fd*/ mc_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, mcp_obj); if (mc_fd < 0) { - FSLMC_VFIO_LOG(ERR, "error in VFIO get device %s fd from group" - " %d", mcp_obj, group->fd); + FSLMC_VFIO_LOG(ERR, "error in VFIO get dev %s fd from group %d", + mcp_obj, group->fd); return v_addr; } @@ -297,7 +289,7 @@ static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj) } FSLMC_VFIO_LOG(DEBUG, "region offset = %llx , region size = %llx", - reg_info.offset, reg_info.size); + reg_info.offset, reg_info.size); v_addr = (uint64_t)mmap(NULL, reg_info.size, PROT_WRITE | PROT_READ, MAP_SHARED, @@ -351,6 +343,40 @@ fslmc_bus_add_device(struct rte_dpaa2_device *dev) } } +#define IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + sizeof(int)) + +int rte_dpaa2_intr_enable(struct rte_intr_handle *intr_handle, + uint32_t index) +{ + struct vfio_irq_set *irq_set; + char irq_set_buf[IRQ_SET_BUF_LEN]; + int *fd_ptr, fd, ret; + + /* Prepare vfio_irq_set structure and SET the IRQ in VFIO */ + /* Give the eventfd to VFIO */ + fd = eventfd(0, 0); + irq_set = (struct vfio_irq_set *)irq_set_buf; + irq_set->argsz = sizeof(irq_set_buf); + irq_set->count = 1; + irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | + VFIO_IRQ_SET_ACTION_TRIGGER; + irq_set->index = index; + irq_set->start = 0; + fd_ptr = (int *)&irq_set->data; + *fd_ptr = fd; + + ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set); + if (ret < 0) { + FSLMC_VFIO_LOG(ERR, "Unable to set IRQ in VFIO, ret: %d\n", + ret); + return -1; + } + + /* Set the FD and update the flags */ + intr_handle->fd = fd; + return 0; +} + /* Following function shall fetch total available list of MC devices * from VFIO container & populate private list of devices and other * data structures @@ -366,14 +392,13 @@ int fslmc_vfio_process_group(void) char path[PATH_MAX]; int64_t v_addr; int ndev_count; - int dpio_count = 0, dpbp_count = 0; struct fslmc_vfio_group *group = &vfio_groups[0]; static int process_once; /* if already done once */ if (process_once) { - FSLMC_VFIO_LOG(DEBUG, "Already scanned once - re-scan " - "not supported"); + FSLMC_VFIO_LOG(DEBUG, + "Already scanned once - re-scan not supported"); return 0; } process_once = 0; @@ -397,8 +422,8 @@ int fslmc_vfio_process_group(void) free(mcp_obj); mcp_obj = malloc(sizeof(dir->d_name)); if (!mcp_obj) { - FSLMC_VFIO_LOG(ERR, "mcp obj:Unable to" - " allocate memory"); + FSLMC_VFIO_LOG(ERR, + "mcp obj:alloc failed"); closedir(d); return -ENOMEM; } @@ -441,8 +466,6 @@ int fslmc_vfio_process_group(void) goto FAILURE; } - FSLMC_VFIO_LOG(DEBUG, "DPAA2 MC has VIR_ADD = %ld", v_addr); - rte_mcp_ptr_list[0] = (void *)v_addr; d = opendir(path); @@ -452,7 +475,6 @@ int fslmc_vfio_process_group(void) } i = 0; - FSLMC_VFIO_LOG(DEBUG, "DPAA2 - Parsing devices:"); /* Parsing each object and initiating them*/ while ((dir = readdir(d)) != NULL) { if (dir->d_type != DT_LNK) @@ -469,14 +491,13 @@ int fslmc_vfio_process_group(void) object_type = strtok(dir->d_name, "."); temp_obj = strtok(NULL, "."); sscanf(temp_obj, "%d", &object_id); - FSLMC_VFIO_LOG(DEBUG, " - %s ", dev_name); /* getting the device fd*/ dev_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, dev_name); if (dev_fd < 0) { - FSLMC_VFIO_LOG(ERR, "VFIO_GROUP_GET_DEVICE_FD error" - " Device fd: %s, Group: %d", - dev_name, group->fd); + FSLMC_VFIO_LOG(ERR, + "GET_DEVICE_FD error fd: %s, Group: %d", + dev_name, group->fd); free(dev_name); goto FAILURE; } @@ -505,22 +526,22 @@ int fslmc_vfio_process_group(void) dev->dev_type = (strcmp(object_type, "dpseci")) ? DPAA2_MC_DPNI_DEVID : DPAA2_MC_DPSECI_DEVID; - FSLMC_VFIO_LOG(DEBUG, "DPAA2: Added [%s-%d]\n", - object_type, object_id); + sprintf(dev->name, "%s.%d", object_type, object_id); + dev->device.name = dev->name; fslmc_bus_add_device(dev); - } - if (!strcmp(object_type, "dpio")) { - ret = dpaa2_create_dpio_device(vdev, - &device_info, + FSLMC_VFIO_LOG(DEBUG, "DPAA2: Added %s", dev->name); + } else { + /* Parse all other objects */ + struct rte_dpaa2_object *object; + + TAILQ_FOREACH(object, &fslmc_obj_list, next) { + if (!strcmp(object_type, object->name)) + object->create(vdev, &device_info, object_id); - if (!ret) - dpio_count++; - } - if (!strcmp(object_type, "dpbp")) { - ret = dpaa2_create_dpbp_device(object_id); - if (!ret) - dpbp_count++; + else + continue; + } } } closedir(d); @@ -529,8 +550,6 @@ int fslmc_vfio_process_group(void) if (ret) FSLMC_VFIO_LOG(DEBUG, "Error in affining qbman swp %d", ret); - FSLMC_VFIO_LOG(DEBUG, "DPAA2: Added dpbp_count = %d dpio_count=%d\n", - dpbp_count, dpio_count); return 0; FAILURE: |