[dpdk-dev,11/32] net/dpaa2: add dpaa2 vfio support

Message ID 1480875447-23680-12-git-send-email-hemant.agrawal@nxp.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
checkpatch/checkpatch warning coding style issues

Commit Message

Hemant Agrawal Dec. 4, 2016, 6:17 p.m. UTC
  Add support for using VFIO for dpaa2 based fsl-mc bus.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa2/Makefile     |   1 +
 drivers/net/dpaa2/dpaa2_bus.c  |  15 +-
 drivers/net/dpaa2/dpaa2_vfio.c | 451 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/dpaa2/dpaa2_vfio.h |  74 +++++++
 4 files changed, 540 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/dpaa2/dpaa2_vfio.c
 create mode 100644 drivers/net/dpaa2/dpaa2_vfio.h
  

Comments

Thomas Monjalon Dec. 6, 2016, 9:04 p.m. UTC | #1
2016-12-04 23:47, Hemant Agrawal:
> Add support for using VFIO for dpaa2 based fsl-mc bus.

Why do we need so much special code for interfacing VFIO on fsl-mc?
Can you reuse some code from EAL VFIO?
  
Hemant Agrawal Dec. 7, 2016, 7 a.m. UTC | #2
On 12/7/2016 2:34 AM, Thomas Monjalon wrote:
> 2016-12-04 23:47, Hemant Agrawal:
>> Add support for using VFIO for dpaa2 based fsl-mc bus.
>
> Why do we need so much special code for interfacing VFIO on fsl-mc?
> Can you reuse some code from EAL VFIO?
>

fsl-mc VFIO scans the objects.  So, it is slightly different.

Even though I have tried to minimize changes and re-use the code from 
EAL VFIO. It is still refactoring work, which we will take up little later.
  
Thomas Monjalon Dec. 7, 2016, 8:38 a.m. UTC | #3
2016-12-07 12:30, Hemant Agrawal:
> On 12/7/2016 2:34 AM, Thomas Monjalon wrote:
> > 2016-12-04 23:47, Hemant Agrawal:
> >> Add support for using VFIO for dpaa2 based fsl-mc bus.
> >
> > Why do we need so much special code for interfacing VFIO on fsl-mc?
> > Can you reuse some code from EAL VFIO?
> >
> 
> fsl-mc VFIO scans the objects.  So, it is slightly different.
> 
> Even though I have tried to minimize changes and re-use the code from 
> EAL VFIO. It is still refactoring work, which we will take up little later.

Do you mean you could re-use some EAL code but do not want to do it now?
It sounds like something heard too many times earlier (from others).
The experience tells we must not wait to do things right.
  
Hemant Agrawal Dec. 7, 2016, 10:04 a.m. UTC | #4
On 12/7/2016 2:08 PM, Thomas Monjalon wrote:
> 2016-12-07 12:30, Hemant Agrawal:
>> On 12/7/2016 2:34 AM, Thomas Monjalon wrote:
>>> 2016-12-04 23:47, Hemant Agrawal:
>>>> Add support for using VFIO for dpaa2 based fsl-mc bus.
>>>
>>> Why do we need so much special code for interfacing VFIO on fsl-mc?
>>> Can you reuse some code from EAL VFIO?
>>>
>>
>> fsl-mc VFIO scans the objects.  So, it is slightly different.
>>
>> Even though I have tried to minimize changes and re-use the code from
>> EAL VFIO. It is still refactoring work, which we will take up little later.
>
> Do you mean you could re-use some EAL code but do not want to do it now?
> It sounds like something heard too many times earlier (from others).
> The experience tells we must not wait to do things right.
>
I meant that I was able to use some of the EAL VFIO functions. There are 
some changes which I am planning to propose in eal vfio and in our driver.

I will do it in subsequent patchsets of current series shortly.
  

Patch

diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
index a99ce22..ab17143 100644
--- a/drivers/net/dpaa2/Makefile
+++ b/drivers/net/dpaa2/Makefile
@@ -49,6 +49,7 @@  EXPORT_MAP := rte_pmd_dpaa2_version.map
 LIBABIVER := 1
 
 
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_vfio.c
 # Interfaces with DPDK
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_bus.c
 
diff --git a/drivers/net/dpaa2/dpaa2_bus.c b/drivers/net/dpaa2/dpaa2_bus.c
index 571066c..fa88599 100644
--- a/drivers/net/dpaa2/dpaa2_bus.c
+++ b/drivers/net/dpaa2/dpaa2_bus.c
@@ -44,6 +44,10 @@ 
 
 #include "eal_filesystem.h"
 #include "eal_private.h"
+#include "dpaa2_vfio.h"
+
+#define DPAA2_BUS_LOG(level, fmt, args...) \
+	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
 
 void
 rte_dpaa2_register(struct rte_dpaa2_driver *driver)
@@ -79,8 +83,17 @@  int rte_dpaa2_probe(struct rte_driver *driver __rte_unused,
 	return 0;
 }
 
-int rte_dpaa2_scan(struct rte_bus *bus_d __rte_unused)
+int rte_dpaa2_scan(struct rte_bus *bus_d)
 {
+	if (dpaa2_vfio_setup_group()) {
+		DPAA2_BUS_LOG(ERR, "DPAA2: Unable to setup VFIO");
+		return -1;
+	}
+	if (dpaa2_vfio_process_group(bus_d)) {
+		DPAA2_BUS_LOG(ERR, "DPAA2: Unable to setup devices");
+		return -1;
+	}
+	RTE_LOG(INFO, PMD, "DPAA2: Device setup completed\n");
 	return 0;
 }
 
diff --git a/drivers/net/dpaa2/dpaa2_vfio.c b/drivers/net/dpaa2/dpaa2_vfio.c
new file mode 100644
index 0000000..e7e33d3
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_vfio.c
@@ -0,0 +1,451 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ *   Copyright (c) 2016 NXP. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#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>
+#include <dirent.h>
+#include <sys/eventfd.h>
+
+#include <eal_filesystem.h>
+#include <eal_private.h>
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_string_fns.h>
+#include <rte_cycles.h>
+#include <rte_kvargs.h>
+#include <rte_dev.h>
+#include <rte_ethdev.h>
+#include <rte_bus.h>
+#include <rte_dpaa2.h>
+
+#include "dpaa2_vfio.h"
+#define VFIO_MAX_CONTAINERS	1
+
+#define DPAA2_VFIO_LOG(level, fmt, args...) \
+	RTE_LOG(level, EAL, "%s(): " fmt "\n", __func__, ##args)
+
+/** Pathname of FSL-MC devices directory. */
+#define SYSFS_DPAA2_MC_DEVICES "/sys/bus/fsl-mc/devices"
+
+/* Number of VFIO containers & groups with in */
+static struct dpaa2_vfio_group vfio_groups[VFIO_MAX_GRP];
+static struct dpaa2_vfio_container vfio_containers[VFIO_MAX_CONTAINERS];
+static int container_device_fd;
+void *(*mcp_ptr_list);
+static uint32_t mcp_id;
+
+static int vfio_connect_container(struct dpaa2_vfio_group *vfio_group)
+{
+	struct dpaa2_vfio_container *container;
+	int i, fd, ret;
+
+	/* Try connecting to vfio container if already created */
+	for (i = 0; i < VFIO_MAX_CONTAINERS; i++) {
+		container = &vfio_containers[i];
+		if (!ioctl(vfio_group->fd, VFIO_GROUP_SET_CONTAINER,
+			   &container->fd)) {
+			DPAA2_VFIO_LOG(INFO, " Container pre-exists with"
+				    " FD[0x%x] for this group",
+				    container->fd);
+			vfio_group->container = container;
+			return 0;
+		}
+	}
+
+	/* Opens main vfio file descriptor which represents the "container" */
+	fd = vfio_get_container_fd();
+	if (fd < 0) {
+		DPAA2_VFIO_LOG(ERR, " Failed to open VFIO container");
+		return -errno;
+	}
+
+	/* Check whether support for SMMU type IOMMU present or not */
+	if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
+		/* Connect group to container */
+		ret = ioctl(vfio_group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
+		if (ret) {
+			DPAA2_VFIO_LOG(ERR, "Failed to setup group container");
+			close(fd);
+			return -errno;
+		}
+
+		ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
+		if (ret) {
+			DPAA2_VFIO_LOG(ERR, "Failed to setup VFIO iommu");
+			close(fd);
+			return -errno;
+		}
+	} else {
+		DPAA2_VFIO_LOG(ERR, " No supported IOMMU available");
+		close(fd);
+		return -EINVAL;
+	}
+
+	container = NULL;
+	for (i = 0; i < VFIO_MAX_CONTAINERS; i++) {
+		if (vfio_containers[i].used)
+			continue;
+		DPAA2_VFIO_LOG(DEBUG, " Unused container at index %d", i);
+		container = &vfio_containers[i];
+	}
+	if (!container) {
+		DPAA2_VFIO_LOG(ERR, " No free container found");
+		close(fd);
+		return -ENOMEM;
+	}
+
+	container->used = 1;
+	container->fd = fd;
+	container->group_list[container->index] = vfio_group;
+	vfio_group->container = container;
+	container->index++;
+	return 0;
+}
+
+static int64_t vfio_map_mcp_obj(struct dpaa2_vfio_group *group, char *mcp_obj)
+{
+	int64_t v_addr = (int64_t)MAP_FAILED;
+	int32_t ret, mc_fd;
+
+	struct vfio_device_info d_info = { .argsz = sizeof(d_info) };
+	struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
+
+	/* getting the mcp object's fd*/
+	mc_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, mcp_obj);
+	if (mc_fd < 0) {
+		DPAA2_VFIO_LOG(ERR, "VFIO error get device %s fd from group"
+			    " %d", mcp_obj, group->fd);
+		return v_addr;
+	}
+
+	/* getting device info*/
+	ret = ioctl(mc_fd, VFIO_DEVICE_GET_INFO, &d_info);
+	if (ret < 0) {
+		DPAA2_VFIO_LOG(ERR, "VFIO error getting DEVICE_INFO");
+		goto MC_FAILURE;
+	}
+
+	/* getting device region info*/
+	ret = ioctl(mc_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
+	if (ret < 0) {
+		DPAA2_VFIO_LOG(ERR, " VFIO error getting REGION_INFO");
+		goto MC_FAILURE;
+	}
+
+	DPAA2_VFIO_LOG(DEBUG, " region offset = %llx  , region size = %llx",
+		     reg_info.offset, reg_info.size);
+
+	v_addr = (uint64_t)mmap(NULL, reg_info.size,
+		PROT_WRITE | PROT_READ, MAP_SHARED,
+		mc_fd, reg_info.offset);
+
+MC_FAILURE:
+	close(mc_fd);
+
+	return v_addr;
+}
+
+/* Following function shall fetch total available list of MC devices
+ * from VFIO container & populate private list of devices and other
+ * data structures
+ */
+int dpaa2_vfio_process_group(struct rte_bus *bus __rte_unused)
+{
+	struct dpaa2_vfio_device *vdev;
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char *temp_obj, *object_type __rte_unused, *mcp_obj, *dev_name;
+	int32_t object_id, i, dev_fd;
+	DIR *d;
+	struct dirent *dir;
+	char path[PATH_MAX];
+	int64_t v_addr;
+	int ndev_count;
+	struct dpaa2_vfio_group *group = &vfio_groups[0];
+	static int process_once;
+
+	/* if already done once */
+	if (process_once) {
+		DPAA2_VFIO_LOG(DEBUG, "\n %s - Already scanned once - re-scan "
+			    "not supported", __func__);
+		return 0;
+	}
+	process_once = 0;
+
+	sprintf(path, "/sys/kernel/iommu_groups/%d/devices", group->groupid);
+
+	d = opendir(path);
+	if (!d) {
+		DPAA2_VFIO_LOG(ERR, "Unable to open directory %s", path);
+		return -1;
+	}
+
+	/*Counting the number of devices in a group and getting the mcp ID*/
+	ndev_count = 0;
+	mcp_obj = NULL;
+	while ((dir = readdir(d)) != NULL) {
+		if (dir->d_type == DT_LNK) {
+			ndev_count++;
+			if (!strncmp("dpmcp", dir->d_name, 5)) {
+				if (mcp_obj)
+					free(mcp_obj);
+				mcp_obj = malloc(sizeof(dir->d_name));
+				if (!mcp_obj) {
+					DPAA2_VFIO_LOG(ERR, "Unable to"
+						    " allocate memory");
+					return -ENOMEM;
+				}
+				strcpy(mcp_obj, dir->d_name);
+				temp_obj = strtok(dir->d_name, ".");
+				temp_obj = strtok(NULL, ".");
+				sscanf(temp_obj, "%d", &mcp_id);
+			}
+		}
+	}
+	closedir(d);
+
+	if (!mcp_obj) {
+		DPAA2_VFIO_LOG(ERR, "DPAA2 MCP Object not Found");
+		return -ENODEV;
+	}
+	RTE_LOG(INFO, PMD, "Total devices in container = %d, MCP ID = %d\n",
+		     ndev_count, mcp_id);
+
+	/* Allocate the memory depends upon number of objects in a group*/
+	group->vfio_device = (struct dpaa2_vfio_device *)malloc(ndev_count *
+			     sizeof(struct dpaa2_vfio_device));
+	if (!(group->vfio_device)) {
+		DPAA2_VFIO_LOG(ERR, " Unable to allocate memory\n");
+		free(mcp_obj);
+		return -ENOMEM;
+	}
+
+	/* Allocate memory for MC Portal list */
+	mcp_ptr_list = malloc(sizeof(void *) * 1);
+	if (!mcp_ptr_list) {
+		DPAA2_VFIO_LOG(ERR, " Unable to allocate memory!");
+		free(mcp_obj);
+		goto FAILURE;
+	}
+
+	v_addr = vfio_map_mcp_obj(group, mcp_obj);
+	free(mcp_obj);
+	if (v_addr == (int64_t)MAP_FAILED) {
+		DPAA2_VFIO_LOG(ERR, " Error mapping region (err = %d)", errno);
+		goto FAILURE;
+	}
+
+	DPAA2_VFIO_LOG(DEBUG, " DPAA2 MC has VIR_ADD = 0x%ld", v_addr);
+
+	mcp_ptr_list[0] = (void *)v_addr;
+
+	d = opendir(path);
+	if (!d) {
+		DPAA2_VFIO_LOG(ERR, " Unable to open %s Directory", path);
+		goto FAILURE;
+	}
+
+	i = 0;
+	DPAA2_VFIO_LOG(DEBUG, "DPAA2 - Parsing devices:");
+	/* Parsing each object and initiating them*/
+	while ((dir = readdir(d)) != NULL) {
+		if (dir->d_type != DT_LNK)
+			continue;
+		if (!strncmp("dprc", dir->d_name, 4) ||
+		    !strncmp("dpmcp", dir->d_name, 5))
+			continue;
+		dev_name = malloc(sizeof(dir->d_name));
+		if (!dev_name) {
+			DPAA2_VFIO_LOG(ERR, " Unable to allocate memory");
+			goto FAILURE;
+		}
+		strcpy(dev_name, dir->d_name);
+		object_type = strtok(dir->d_name, ".");
+		temp_obj = strtok(NULL, ".");
+		sscanf(temp_obj, "%d", &object_id);
+		DPAA2_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) {
+			DPAA2_VFIO_LOG(ERR, " VFIO_GROUP_GET_DEVICE_FD error"
+				    " Device fd: %s, Group: %d",
+				    dev_name, group->fd);
+			free(dev_name);
+			goto FAILURE;
+		}
+
+		free(dev_name);
+		vdev = &group->vfio_device[group->object_index++];
+		vdev->fd = dev_fd;
+		vdev->index = i;
+		i++;
+		/* Get Device inofrmation */
+		if (ioctl(vdev->fd, VFIO_DEVICE_GET_INFO, &device_info)) {
+			DPAA2_VFIO_LOG(ERR, "DPAA2 VFIO_DEVICE_GET_INFO fail");
+			goto FAILURE;
+		}
+	}
+	closedir(d);
+
+	return 0;
+
+FAILURE:
+	free(group->vfio_device);
+	group->vfio_device = NULL;
+	return -1;
+}
+
+
+int dpaa2_vfio_setup_group(void)
+{
+	char path[PATH_MAX];
+	char iommu_group_path[PATH_MAX], *group_name;
+	struct dpaa2_vfio_group *group = NULL;
+	struct stat st;
+	int groupid;
+	int ret, len, i;
+	char *container;
+	struct vfio_group_status status = { .argsz = sizeof(status) };
+
+	/* if already done once */
+	if (container_device_fd)
+		return 0;
+
+	container = getenv("DPRC");
+
+	if (container == NULL) {
+		DPAA2_VFIO_LOG(ERR, " VFIO container not set in env DPRC");
+		return -1;
+	}
+	RTE_LOG(INFO, PMD, "DPAA2: Processing Container = %s\n", container);
+	snprintf(path, sizeof(path), "%s/%s",
+		 SYSFS_DPAA2_MC_DEVICES, container);
+
+	/* Check whether fsl-mc container exists or not */
+	DPAA2_VFIO_LOG(DEBUG, " container device path = %s", path);
+	if (stat(path, &st) < 0) {
+		DPAA2_VFIO_LOG(ERR, "vfio: Error (%d) getting FSL-MC device (%s)",
+			     errno,  path);
+		return -errno;
+	}
+
+	/* DPRC container exists. Now checkout the IOMMU Group */
+	strncat(path, "/iommu_group", sizeof(path) - strlen(path) - 1);
+
+	len = readlink(path, iommu_group_path, PATH_MAX);
+	if (len == -1) {
+		DPAA2_VFIO_LOG(ERR, " vfio: error no iommu_group for device");
+		DPAA2_VFIO_LOG(ERR, "   %s: len = %d, errno = %d",
+			     path, len, errno);
+		return -errno;
+	}
+
+	iommu_group_path[len] = 0;
+	group_name = basename(iommu_group_path);
+	if (sscanf(group_name, "%d", &groupid) != 1) {
+		DPAA2_VFIO_LOG(ERR, " VFIO error reading %s", path);
+		return -errno;
+	}
+
+	DPAA2_VFIO_LOG(DEBUG, " VFIO iommu group id = %d", groupid);
+
+	/* Check if group already exists */
+	for (i = 0; i < VFIO_MAX_GRP; i++) {
+		group = &vfio_groups[i];
+		if (group->groupid == groupid) {
+			DPAA2_VFIO_LOG(ERR, " groupid already exists %d",
+				     groupid);
+			return 0;
+		}
+	}
+
+	/* Open the VFIO file corresponding to the IOMMU group */
+	snprintf(path, sizeof(path), "/dev/vfio/%d", groupid);
+
+	group->fd = open(path, O_RDWR);
+	if (group->fd < 0) {
+		DPAA2_VFIO_LOG(ERR, " VFIO error opening %s", path);
+		return -1;
+	}
+
+	/* Test & Verify that group is VIABLE & AVAILABLE */
+	if (ioctl(group->fd, VFIO_GROUP_GET_STATUS, &status)) {
+		DPAA2_VFIO_LOG(ERR, " VFIO error getting group status");
+		close(group->fd);
+		return -1;
+	}
+	if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
+		DPAA2_VFIO_LOG(ERR, " VFIO group not viable");
+		close(group->fd);
+		return -1;
+	}
+	/* Since Group is VIABLE, Store the groupid */
+	group->groupid = groupid;
+
+	/* check if group does not have a container yet */
+	if (!(status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
+		/* Now connect this IOMMU group to given container */
+		if (vfio_connect_container(group)) {
+			DPAA2_VFIO_LOG(ERR, "VFIO error connecting container"
+				       " with groupid %d", groupid);
+			close(group->fd);
+			return -1;
+		}
+	}
+
+	/* Get Device information */
+	ret = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, container);
+	if (ret < 0) {
+		DPAA2_VFIO_LOG(ERR, " VFIO error getting device %s fd from"
+			       " group  %d", container, group->groupid);
+		return ret;
+	}
+	container_device_fd = ret;
+	DPAA2_VFIO_LOG(DEBUG, " VFIO Container FD is [0x%X]",
+		     container_device_fd);
+
+	return 0;
+}
diff --git a/drivers/net/dpaa2/dpaa2_vfio.h b/drivers/net/dpaa2/dpaa2_vfio.h
new file mode 100644
index 0000000..2a866ed
--- /dev/null
+++ b/drivers/net/dpaa2/dpaa2_vfio.h
@@ -0,0 +1,74 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
+ *   Copyright (c) 2016 NXP. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Freescale Semiconductor, Inc nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DPAA2_VFIO_H_
+#define _DPAA2_VFIO_H_
+
+#include "eal_vfio.h"
+
+#define DPAA2_VENDOR_ID		0x1957
+#define DPAA2_MC_DPNI_DEVID	7
+#define DPAA2_MC_DPSECI_DEVID	3
+
+#define VFIO_MAX_GRP 1
+
+typedef struct dpaa2_vfio_device {
+	int fd; /* dpaa2_mc root container device ?? */
+	int index; /*index of child object */
+	struct dpaa2_vfio_device *child; /* Child object */
+} dpaa2_vfio_device;
+
+typedef struct dpaa2_vfio_group {
+	int fd; /* /dev/vfio/"groupid" */
+	int groupid;
+	struct dpaa2_vfio_container *container;
+	int object_index;
+	struct dpaa2_vfio_device *vfio_device;
+} dpaa2_vfio_group;
+
+typedef struct dpaa2_vfio_container {
+	int fd; /* /dev/vfio/vfio */
+	int used;
+	int index; /* index in group list */
+	struct dpaa2_vfio_group *group_list[VFIO_MAX_GRP];
+} dpaa2_vfio_container;
+
+int vfio_dmamap_mem_region(
+	uint64_t vaddr,
+	uint64_t iova,
+	uint64_t size);
+
+int dpaa2_vfio_setup_group(void);
+int dpaa2_vfio_process_group(struct rte_bus *bus);
+
+#endif /* _DPAA2_VFIO_H_ */