bus/ifpga: add Intel FPGA bus library

Defined FPGA-BUS for Acceleration Drivers of AFUs

1. FPGA PCI Scan (1st Scan) follows DPDK UIO/VFIO PCI Scan Process,
probe Intel FPGA Rawdev Driver, it will be covered in following patches.

2. AFU Scan(2nd Scan) bind DPDK driver to FPGA Partial-Bitstream.
This scan is trigged by hotplug of IFPGA Rawdev probe, in this scan
the AFUs will be created and their drivers are also probed.

This patch will introduce rte_afu_device which describe the AFU device
listed in the FPGA-BUS.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Reviewed-by: Qi Zhang <qi.z.zhang@intel.com>
This commit is contained in:
Rosen Xu 2018-05-11 16:31:29 +08:00 committed by Thomas Monjalon
parent e0d88a394e
commit 05fa3d4a65
14 changed files with 819 additions and 1 deletions

View File

@ -401,6 +401,10 @@ F: drivers/mempool/bucket/
Bus Drivers
-----------
Intel FPGA bus
M: Rosen Xu <rosen.xu@intel.com>
F: drivers/bus/ifpga/
NXP buses
M: Hemant Agrawal <hemant.agrawal@nxp.com>
M: Shreyansh Jain <shreyansh.jain@nxp.com>

View File

@ -138,6 +138,11 @@ CONFIG_RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS=n
#
CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
#
# Compile the Intel FPGA bus
#
CONFIG_RTE_LIBRTE_IFPGA_BUS=y
#
# Compile PCI bus driver
#

View File

@ -171,6 +171,12 @@ New Features
enqueue/dequeue crypto operations to/from cryptodev as events scheduled
by an event device.
* **Added Ifpga Bus, a generic Intel FPGA Bus library.**
The Ifpga Bus library provides support for integrating any Intel FPGA device with
the DPDK framework. It provides Intel FPGA Partial Bit Stream AFU (Accelerated
Function Unit) scan and drivers probe.
* **Added DPAA2 QDMA Driver (in rawdev).**
The DPAA2 QDMA is an implementation of the rawdev API, that provide means

View File

@ -7,6 +7,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
ifeq ($(CONFIG_RTE_EAL_VFIO),y)
DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
endif
DIRS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga
DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev

View File

@ -0,0 +1,32 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
LIB = librte_bus_ifpga.a
CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
LDLIBS += -lrte_eal
LDLIBS += -lrte_rawdev
LDLIBS += -lrte_kvargs
# versioning export map
EXPORT_MAP := rte_bus_ifpga_version.map
# library version
LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga_bus.c
SRCS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga_common.c
#
# Export include files
#
SYMLINK-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)-include += rte_bus_ifpga.h
include $(RTE_SDK)/mk/rte.lib.mk

View File

@ -0,0 +1,464 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <rte_errno.h>
#include <rte_bus.h>
#include <rte_per_lcore.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_common.h>
#include <rte_devargs.h>
#include <rte_kvargs.h>
#include <rte_alarm.h>
#include "rte_rawdev.h"
#include "rte_rawdev_pmd.h"
#include "rte_bus_ifpga.h"
#include "ifpga_logs.h"
#include "ifpga_common.h"
int ifpga_bus_logtype;
/* Forward declaration to access Intel FPGA bus
* on which iFPGA devices are connected
*/
static struct rte_bus rte_ifpga_bus;
static struct ifpga_afu_dev_list ifpga_afu_dev_list =
TAILQ_HEAD_INITIALIZER(ifpga_afu_dev_list);
static struct ifpga_afu_drv_list ifpga_afu_drv_list =
TAILQ_HEAD_INITIALIZER(ifpga_afu_drv_list);
/* register a ifpga bus based driver */
void rte_ifpga_driver_register(struct rte_afu_driver *driver)
{
RTE_VERIFY(driver);
TAILQ_INSERT_TAIL(&ifpga_afu_drv_list, driver, next);
}
/* un-register a fpga bus based driver */
void rte_ifpga_driver_unregister(struct rte_afu_driver *driver)
{
TAILQ_REMOVE(&ifpga_afu_drv_list, driver, next);
}
static struct rte_afu_device *
ifpga_find_afu_dev(const struct rte_rawdev *rdev,
const struct rte_afu_id *afu_id)
{
struct rte_afu_device *afu_dev = NULL;
TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
if (afu_dev &&
afu_dev->rawdev == rdev &&
!ifpga_afu_id_cmp(&afu_dev->id, afu_id))
return afu_dev;
}
return NULL;
}
static const char * const valid_args[] = {
#define IFPGA_ARG_NAME "ifpga"
IFPGA_ARG_NAME,
#define IFPGA_ARG_PORT "port"
IFPGA_ARG_PORT,
#define IFPGA_AFU_BTS "afu_bts"
IFPGA_AFU_BTS,
NULL
};
/*
* Scan the content of the FPGA bus, and the devices in the devices
* list
*/
static struct rte_afu_device *
ifpga_scan_one(struct rte_rawdev *rawdev,
struct rte_devargs *devargs)
{
struct rte_kvargs *kvlist = NULL;
struct rte_afu_device *afu_dev = NULL;
struct rte_afu_pr_conf afu_pr_conf;
int ret = 0;
char *path = NULL;
memset(&afu_pr_conf, 0, sizeof(struct rte_afu_pr_conf));
kvlist = rte_kvargs_parse(devargs->args, valid_args);
if (!kvlist) {
IFPGA_BUS_ERR("error when parsing param");
goto end;
}
if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT,
&rte_ifpga_get_integer32_arg, &afu_pr_conf.afu_id.port) < 0) {
IFPGA_BUS_ERR("error to parse %s",
IFPGA_ARG_PORT);
goto end;
}
} else {
IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
IFPGA_ARG_PORT);
goto end;
}
if (rte_kvargs_count(kvlist, IFPGA_AFU_BTS) == 1) {
if (rte_kvargs_process(kvlist, IFPGA_AFU_BTS,
&rte_ifpga_get_string_arg, &path) < 0) {
IFPGA_BUS_ERR("Failed to parse %s",
IFPGA_AFU_BTS);
goto end;
}
} else {
IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
IFPGA_AFU_BTS);
goto end;
}
afu_pr_conf.afu_id.uuid.uuid_low = 0;
afu_pr_conf.afu_id.uuid.uuid_high = 0;
afu_pr_conf.pr_enable = path?1:0;
if (ifpga_find_afu_dev(rawdev, &afu_pr_conf.afu_id))
goto end;
afu_dev = calloc(1, sizeof(*afu_dev));
if (!afu_dev)
goto end;
afu_dev->device.devargs = devargs;
afu_dev->device.numa_node = SOCKET_ID_ANY;
afu_dev->device.name = devargs->name;
afu_dev->rawdev = rawdev;
afu_dev->id.uuid.uuid_low = 0;
afu_dev->id.uuid.uuid_high = 0;
afu_dev->id.port = afu_pr_conf.afu_id.port;
if (rawdev->dev_ops && rawdev->dev_ops->dev_info_get)
rawdev->dev_ops->dev_info_get(rawdev, afu_dev);
if (rawdev->dev_ops &&
rawdev->dev_ops->dev_start &&
rawdev->dev_ops->dev_start(rawdev))
goto free_dev;
strncpy(afu_pr_conf.bs_path, path, sizeof(afu_pr_conf.bs_path));
if (rawdev->dev_ops->firmware_load &&
rawdev->dev_ops->firmware_load(rawdev,
&afu_pr_conf)){
IFPGA_BUS_ERR("firmware load error %d\n", ret);
goto free_dev;
}
afu_dev->id.uuid.uuid_low = afu_pr_conf.afu_id.uuid.uuid_low;
afu_dev->id.uuid.uuid_high = afu_pr_conf.afu_id.uuid.uuid_high;
return afu_dev;
free_dev:
free(afu_dev);
end:
if (kvlist)
rte_kvargs_free(kvlist);
if (path)
free(path);
return NULL;
}
/*
* Scan the content of the FPGA bus, and the devices in the devices
* list
*/
static int
ifpga_scan(void)
{
struct rte_devargs *devargs;
struct rte_kvargs *kvlist = NULL;
struct rte_rawdev *rawdev = NULL;
char *name = NULL;
char name1[RTE_RAWDEV_NAME_MAX_LEN];
struct rte_afu_device *afu_dev = NULL;
/* for FPGA devices we scan the devargs_list populated via cmdline */
RTE_EAL_DEVARGS_FOREACH(IFPGA_ARG_NAME, devargs) {
if (devargs->bus != &rte_ifpga_bus)
continue;
kvlist = rte_kvargs_parse(devargs->args, valid_args);
if (!kvlist) {
IFPGA_BUS_ERR("error when parsing param");
goto end;
}
if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
&rte_ifpga_get_string_arg, &name) < 0) {
IFPGA_BUS_ERR("error to parse %s",
IFPGA_ARG_NAME);
goto end;
}
} else {
IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
IFPGA_ARG_NAME);
goto end;
}
memset(name1, 0, sizeof(name1));
snprintf(name1, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
rawdev = rte_rawdev_pmd_get_named_dev(name1);
if (!rawdev)
goto end;
afu_dev = ifpga_scan_one(rawdev, devargs);
if (afu_dev != NULL)
TAILQ_INSERT_TAIL(&ifpga_afu_dev_list, afu_dev, next);
}
end:
if (kvlist)
rte_kvargs_free(kvlist);
if (name)
free(name);
return 0;
}
/*
* Match the AFU Driver and AFU Device using the ID Table
*/
static int
rte_afu_match(const struct rte_afu_driver *afu_drv,
const struct rte_afu_device *afu_dev)
{
const struct rte_afu_uuid *id_table;
for (id_table = afu_drv->id_table;
((id_table->uuid_low != 0) && (id_table->uuid_high != 0));
id_table++) {
/* check if device's identifiers match the driver's ones */
if ((id_table->uuid_low != afu_dev->id.uuid.uuid_low) ||
id_table->uuid_high !=
afu_dev->id.uuid.uuid_high)
continue;
return 1;
}
return 0;
}
static int
ifpga_probe_one_driver(struct rte_afu_driver *drv,
struct rte_afu_device *afu_dev)
{
int ret;
if (!rte_afu_match(drv, afu_dev))
/* Match of device and driver failed */
return 1;
/* reference driver structure */
afu_dev->driver = drv;
afu_dev->device.driver = &drv->driver;
/* call the driver probe() function */
ret = drv->probe(afu_dev);
if (ret) {
afu_dev->driver = NULL;
afu_dev->device.driver = NULL;
}
return ret;
}
static int
ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
{
struct rte_afu_driver *drv = NULL;
int ret = 0;
if (afu_dev == NULL)
return -1;
/* Check if a driver is already loaded */
if (afu_dev->driver != NULL)
return 0;
TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
if (ifpga_probe_one_driver(drv, afu_dev)) {
ret = -1;
break;
}
}
return ret;
}
/*
* Scan the content of the Intel FPGA bus, and call the probe() function for
* all registered drivers that have a matching entry in its id_table
* for discovered devices.
*/
static int
ifpga_probe(void)
{
struct rte_afu_device *afu_dev = NULL;
int ret = 0;
TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
if (afu_dev->device.driver)
continue;
ret = ifpga_probe_all_drivers(afu_dev);
if (ret < 0)
IFPGA_BUS_ERR("failed to initialize %s device\n",
rte_ifpga_device_name(afu_dev));
}
return ret;
}
static int
ifpga_plug(struct rte_device *dev)
{
return ifpga_probe_all_drivers(RTE_DEV_TO_AFU(dev));
}
static int
ifpga_remove_driver(struct rte_afu_device *afu_dev)
{
const char *name;
const struct rte_afu_driver *driver;
name = rte_ifpga_device_name(afu_dev);
if (!afu_dev->device.driver) {
IFPGA_BUS_DEBUG("no driver attach to device %s\n", name);
return 1;
}
driver = RTE_DRV_TO_AFU_CONST(afu_dev->device.driver);
return driver->remove(afu_dev);
}
static int
ifpga_unplug(struct rte_device *dev)
{
struct rte_afu_device *afu_dev = NULL;
struct rte_devargs *devargs = NULL;
int ret;
if (dev == NULL)
return -EINVAL;
afu_dev = RTE_DEV_TO_AFU(dev);
if (!dev)
return -ENOENT;
devargs = dev->devargs;
ret = ifpga_remove_driver(afu_dev);
if (ret)
return ret;
TAILQ_REMOVE(&ifpga_afu_dev_list, afu_dev, next);
rte_devargs_remove(devargs->bus->name, devargs->name);
free(afu_dev);
return 0;
}
static struct rte_device *
ifpga_find_device(const struct rte_device *start,
rte_dev_cmp_t cmp, const void *data)
{
struct rte_afu_device *afu_dev;
TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
if (start && &afu_dev->device == start) {
start = NULL;
continue;
}
if (cmp(&afu_dev->device, data) == 0)
return &afu_dev->device;
}
return NULL;
}
static int
ifpga_parse(const char *name, void *addr)
{
int *out = addr;
struct rte_rawdev *rawdev = NULL;
char rawdev_name[RTE_RAWDEV_NAME_MAX_LEN];
char *c1 = NULL;
char *c2 = NULL;
int port = IFPGA_BUS_DEV_PORT_MAX;
char str_port[8];
int str_port_len = 0;
int ret;
memset(str_port, 0, 8);
c1 = strchr(name, '|');
if (c1 != NULL) {
str_port_len = c1 - name;
c2 = c1 + 1;
}
if (str_port_len < 8 &&
str_port_len > 0) {
memcpy(str_port, name, str_port_len);
ret = sscanf(str_port, "%d", &port);
if (ret == -1)
return 0;
}
memset(rawdev_name, 0, sizeof(rawdev_name));
snprintf(rawdev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", c2);
rawdev = rte_rawdev_pmd_get_named_dev(rawdev_name);
if ((port < IFPGA_BUS_DEV_PORT_MAX) &&
rawdev &&
(addr != NULL))
*out = port;
if ((port < IFPGA_BUS_DEV_PORT_MAX) &&
rawdev)
return 0;
else
return 1;
}
static struct rte_bus rte_ifpga_bus = {
.scan = ifpga_scan,
.probe = ifpga_probe,
.find_device = ifpga_find_device,
.plug = ifpga_plug,
.unplug = ifpga_unplug,
.parse = ifpga_parse,
};
RTE_REGISTER_BUS(IFPGA_BUS_NAME, rte_ifpga_bus);
RTE_INIT(ifpga_init_log)
{
ifpga_bus_logtype = rte_log_register("bus.ifpga");
if (ifpga_bus_logtype >= 0)
rte_log_set_level(ifpga_bus_logtype, RTE_LOG_NOTICE);
}

View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <rte_errno.h>
#include <rte_bus.h>
#include <rte_per_lcore.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_common.h>
#include <rte_devargs.h>
#include <rte_kvargs.h>
#include <rte_alarm.h>
#include "rte_bus_ifpga.h"
#include "ifpga_logs.h"
#include "ifpga_common.h"
int rte_ifpga_get_string_arg(const char *key __rte_unused,
const char *value, void *extra_args)
{
if (!value || !extra_args)
return -EINVAL;
*(char **)extra_args = strdup(value);
if (!*(char **)extra_args)
return -ENOMEM;
return 0;
}
int rte_ifpga_get_integer32_arg(const char *key __rte_unused,
const char *value, void *extra_args)
{
if (!value || !extra_args)
return -EINVAL;
*(int *)extra_args = strtoull(value, NULL, 0);
return 0;
}
int ifpga_get_integer64_arg(const char *key __rte_unused,
const char *value, void *extra_args)
{
if (!value || !extra_args)
return -EINVAL;
*(uint64_t *)extra_args = strtoull(value, NULL, 0);
return 0;
}
int ifpga_get_unsigned_long(const char *str, int base)
{
unsigned long num;
char *end = NULL;
errno = 0;
num = strtoul(str, &end, base);
if ((str[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
return -1;
return num;
}
int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0,
const struct rte_afu_id *afu_id1)
{
if ((afu_id0->uuid.uuid_low == afu_id1->uuid.uuid_low) &&
(afu_id0->uuid.uuid_high == afu_id1->uuid.uuid_high) &&
(afu_id0->port == afu_id1->port)) {
return 0;
} else
return 1;
}

View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#ifndef _IFPGA_COMMON_H_
#define _IFPGA_COMMON_H_
int rte_ifpga_get_string_arg(const char *key __rte_unused,
const char *value, void *extra_args);
int rte_ifpga_get_integer32_arg(const char *key __rte_unused,
const char *value, void *extra_args);
int ifpga_get_integer64_arg(const char *key __rte_unused,
const char *value, void *extra_args);
int ifpga_get_unsigned_long(const char *str, int base);
int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0,
const struct rte_afu_id *afu_id1);
#endif /* _IFPGA_COMMON_H_ */

View File

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#ifndef _IFPGA_LOGS_H_
#define _IFPGA_LOGS_H_
#include <rte_log.h>
extern int ifpga_bus_logtype;
#define IFPGA_LOG(level, fmt, args...) \
rte_log(RTE_LOG_ ## level, ifpga_bus_logtype, "%s(): " fmt "\n", \
__func__, ##args)
#define IFPGA_BUS_LOG(level, fmt, args...) \
rte_log(RTE_LOG_ ## level, ifpga_bus_logtype, "%s(): " fmt "\n", \
__func__, ##args)
#define IFPGA_BUS_FUNC_TRACE() IFPGA_BUS_LOG(DEBUG, ">>")
#define IFPGA_BUS_DEBUG(fmt, args...) \
IFPGA_BUS_LOG(DEBUG, fmt, ## args)
#define IFPGA_BUS_INFO(fmt, args...) \
IFPGA_BUS_LOG(INFO, fmt, ## args)
#define IFPGA_BUS_ERR(fmt, args...) \
IFPGA_BUS_LOG(ERR, fmt, ## args)
#define IFPGA_BUS_WARN(fmt, args...) \
IFPGA_BUS_LOG(WARNING, fmt, ## args)
#endif /* _IFPGA_BUS_LOGS_H_ */

View File

@ -0,0 +1,8 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2018 Intel Corporation
deps += ['pci', 'kvargs', 'rawdev']
install_headers('rte_bus_ifpga.h')
sources = files('ifpga_common.c', 'ifpga_bus.c')
allow_experimental_apis = true

View File

@ -0,0 +1,150 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#ifndef _RTE_BUS_IFPGA_H_
#define _RTE_BUS_IFPGA_H_
/**
* @file
*
* RTE Intel FPGA Bus Interface
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_bus.h>
#include <rte_pci.h>
/** Name of Intel FPGA Bus */
#define IFPGA_BUS_NAME ifpga
/* Forward declarations */
struct rte_afu_device;
struct rte_afu_driver;
/** Double linked list of Intel FPGA AFU device. */
TAILQ_HEAD(ifpga_afu_dev_list, rte_afu_device);
/** Double linked list of Intel FPGA AFU device drivers. */
TAILQ_HEAD(ifpga_afu_drv_list, rte_afu_driver);
#define IFPGA_BUS_BITSTREAM_PATH_MAX_LEN 256
struct rte_afu_uuid {
uint64_t uuid_low;
uint64_t uuid_high;
} __attribute__ ((packed));
#define IFPGA_BUS_DEV_PORT_MAX 4
/**
* A structure describing an ID for a AFU driver. Each driver provides a
* table of these IDs for each device that it supports.
*/
struct rte_afu_id {
struct rte_afu_uuid uuid;
int port; /**< port number */
} __attribute__ ((packed));
/**
* A structure PR (Partial Reconfiguration) configuration AFU driver.
*/
struct rte_afu_pr_conf {
struct rte_afu_id afu_id;
int pr_enable;
char bs_path[IFPGA_BUS_BITSTREAM_PATH_MAX_LEN];
};
#define AFU_PRI_STR_SIZE (PCI_PRI_STR_SIZE + 8)
/**
* A structure describing a AFU device.
*/
struct rte_afu_device {
TAILQ_ENTRY(rte_afu_device) next; /**< Next in device list. */
struct rte_device device; /**< Inherit core device */
struct rte_rawdev *rawdev; /**< Point Rawdev */
struct rte_afu_id id; /**< AFU id within FPGA. */
uint32_t num_region; /**< number of regions found */
struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
/**< AFU Memory Resource */
struct rte_intr_handle intr_handle; /**< Interrupt handle */
struct rte_afu_driver *driver; /**< Associated driver */
char path[IFPGA_BUS_BITSTREAM_PATH_MAX_LEN];
} __attribute__ ((packed));
/**
* @internal
* Helper macro for drivers that need to convert to struct rte_afu_device.
*/
#define RTE_DEV_TO_AFU(ptr) \
container_of(ptr, struct rte_afu_device, device)
#define RTE_DRV_TO_AFU_CONST(ptr) \
container_of(ptr, const struct rte_afu_driver, driver)
/**
* Initialization function for the driver called during FPGA BUS probing.
*/
typedef int (afu_probe_t)(struct rte_afu_device *);
/**
* Uninitialization function for the driver called during hotplugging.
*/
typedef int (afu_remove_t)(struct rte_afu_device *);
/**
* A structure describing a AFU device.
*/
struct rte_afu_driver {
TAILQ_ENTRY(rte_afu_driver) next; /**< Next afu driver. */
struct rte_driver driver; /**< Inherit core driver. */
afu_probe_t *probe; /**< Device Probe function. */
afu_remove_t *remove; /**< Device Remove function. */
const struct rte_afu_uuid *id_table; /**< AFU uuid within FPGA. */
};
static inline const char *
rte_ifpga_device_name(const struct rte_afu_device *afu)
{
if (afu && afu->device.name)
return afu->device.name;
return NULL;
}
/**
* Register a ifpga afu device driver.
*
* @param driver
* A pointer to a rte_afu_driver structure describing the driver
* to be registered.
*/
void rte_ifpga_driver_register(struct rte_afu_driver *driver);
/**
* Unregister a ifpga afu device driver.
*
* @param driver
* A pointer to a rte_afu_driver structure describing the driver
* to be unregistered.
*/
void rte_ifpga_driver_unregister(struct rte_afu_driver *driver);
#define RTE_PMD_REGISTER_AFU(nm, afudrv)\
RTE_INIT(afudrvinitfn_ ##afudrv);\
static const char *afudrvinit_ ## nm ## _alias;\
static void afudrvinitfn_ ##afudrv(void)\
{\
(afudrv).driver.name = RTE_STR(nm);\
(afudrv).driver.alias = afudrvinit_ ## nm ## _alias;\
rte_ifpga_driver_register(&afudrv);\
} \
RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
#define RTE_PMD_REGISTER_AFU_ALIAS(nm, alias)\
static const char *afudrvinit_ ## nm ## _alias = RTE_STR(alias)
#endif /* _RTE_BUS_IFPGA_H_ */

View File

@ -0,0 +1,10 @@
DPDK_18.05 {
global:
rte_ifpga_get_integer32_arg;
rte_ifpga_get_string_arg;
rte_ifpga_driver_register;
rte_ifpga_driver_unregister;
local: *;
};

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
drivers = ['dpaa', 'fslmc', 'pci', 'vdev']
drivers = ['dpaa', 'fslmc', 'ifpga', 'pci', 'vdev']
std_deps = ['eal']
config_flag_fmt = 'RTE_LIBRTE_@0@_BUS'
driver_name_fmt = 'rte_bus_@0@'

View File

@ -261,6 +261,7 @@ ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += -lrte_pmd_dpaa2_cmdif
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
_LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += -lrte_bus_ifpga
endif # CONFIG_RTE_LIBRTE_RAWDEV