raw/ifpga: add Intel FPGA bus rawdev driver

Add Intel FPGA BUS Rawdev Driver which is based on
librte_rawdev library.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Yanglong Wu <yanglong.wu@intel.com>
Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Reviewed-by: Qi Zhang <qi.z.zhang@intel.com>
This commit is contained in:
Rosen Xu 2018-05-11 16:31:31 +08:00 committed by Thomas Monjalon
parent 56bb54ea1b
commit ef1e8ede3d
13 changed files with 844 additions and 2 deletions

View File

@ -881,8 +881,10 @@ Rawdev Drivers
--------------
Intel FPGA
M: Rosen Xu <rosen.xu@intel.com>
M: Tianfei zhang <tianfei.zhang@intel.com>
F: drivers/raw/ifpga_rawdev/
F: doc/guides/rawdevs/ifpga_rawdev.rst
NXP DPAA2 QDMA
M: Nipun Gupta <nipun.gupta@nxp.com>

View File

@ -649,6 +649,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
# Compile PMD for Intel FPGA raw device
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
#
# Compile librte_ring
#

View File

@ -0,0 +1,112 @@
.. SPDX-License-Identifier: BSD-3-Clause
Copyright(c) 2018 Intel Corporation.
IFPGA Rawdev Driver
======================
FPGA is used more and more widely in Cloud and NFV, one primary reason is
that FPGA not only provides ASIC performance but also it's more flexible
than ASIC.
FPGA uses Partial Reconfigure (PR) Parts of Bit Stream to achieve its
flexibility. That means one FPGA Device Bit Stream is divided into many Parts
of Bit Stream(each Part of Bit Stream is defined as AFU-Accelerated Function
Unit), and each AFU is a hardware acceleration unit which can be dynamically
reloaded respectively.
By PR (Partial Reconfiguration) AFUs, one FPGA resources can be time-shared by
different users. FPGA hot upgrade and fault tolerance can be provided easily.
The SW IFPGA Rawdev Driver (**ifpga_rawdev**) provides a Rawdev driver
that utilizes Intel FPGA Software Stack OPAE(Open Programmable Acceleration
Engine) for FPGA management.
Implementation details
----------------------
Each instance of IFPGA Rawdev Driver is probed by Intel FpgaDev. In coordination
with OPAE share code IFPGA Rawdev Driver provides common FPGA management ops
for FPGA operation, OPAE provides all following operations:
- FPGA PR (Partial Reconfiguration) management
- FPGA AFUs Identifying
- FPGA Thermal Management
- FPGA Power Management
- FPGA Performance reporting
- FPGA Remote Debug
All configuration parameters are taken by vdev_ifpga_cfg driver. Besides
configuration, vdev_ifpga_cfg driver also hot plugs in IFPGA Bus.
All of the AFUs of one FPGA may share same PCI BDF and AFUs scan depend on
IFPGA Rawdev Driver so IFPGA Bus takes AFU device scan and AFU drivers probe.
All AFU device driver bind to AFU device by its UUID (Universally Unique
Identifier).
To avoid unnecessary code duplication and ensure maximum performance,
handling of AFU devices is left to different PMDs; all the design as
summarized by the following block diagram::
+---------------------------------------------------------------+
| Application(s) |
+----------------------------.----------------------------------+
|
|
+----------------------------'----------------------------------+
| DPDK Framework (APIs) |
+----------|------------|--------.---------------------|--------+
/ \ |
/ \ |
+-------'-------+ +-------'-------+ +--------'--------+
| Eth PMD | | Crypto PMD | | |
+-------.-------+ +-------.-------+ | |
| | | |
| | | |
+-------'-------+ +-------'-------+ | IFPGA |
| Eth AFU Dev | |Crypto AFU Dev | | Rawdev Driver |
+-------.-------+ +-------.-------+ |(OPAE Share Code)|
| | | |
| | Rawdev | |
+-------'------------------'-------+ Ops | |
| IFPGA Bus | -------->| |
+-----------------.----------------+ +--------.--------+
| |
Hot-plugin -->| |
| |
+-----------------'------------------+ +--------'--------+
| vdev_ifpga_cfg driver | | Intel FpgaDev |
+------------------------------------+ +-----------------+
Build options
-------------
- ``CONFIG_RTE_LIBRTE_IFPGA_BUS`` (default ``y``)
Toggle compilation of IFPGA Bus library.
- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
Toggle compilation of the ``ifpga_rawdev`` driver.
Run-time parameters
-------------------
This driver is invoked automatically in systems added with Intel FPGA,
but PR and IFPGA Bus scan is trigged by command line using
``--vdev 'ifpga_rawdev_cfg`` EAL option.
The following device parameters are supported:
- ``ifpga`` [string]
Provide a specific Intel FPGA device PCI BDF. Can be provided multiple
times for additional instances.
- ``port`` [int]
Each FPGA can provide many channels to PR AFU by software, each channels
is identified by this parameter.
- ``afu_bts`` [string]
If null, the AFU Bit Stream has been PR in FPGA, if not forces PR and
identifies AFU Bit Stream file.

View File

@ -13,3 +13,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev

View File

@ -177,6 +177,14 @@ New Features
the DPDK framework. It provides Intel FPGA Partial Bit Stream AFU (Accelerated
Function Unit) scan and drivers probe.
* **Added IFPGA (Intel FPGA) Rawdev Driver.**
Added a new Rawdev driver called IFPGA(Intel FPGA) Rawdev Driver, which cooperates
with OPAE (Open Programmable Acceleration Engine) share code provides common FPGA
management ops for FPGA operation.
See the :doc:`../rawdevs/ifpga_rawdev` programmer's guide for more details.
* **Added DPAA2 QDMA Driver (in rawdev).**
The DPAA2 QDMA is an implementation of the rawdev API, that provide means

View File

@ -9,5 +9,6 @@ ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk

View File

@ -0,0 +1,36 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
LIB = librte_pmd_ifpga_rawdev.a
CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga_rawdev
LDLIBS += -lrte_eal
LDLIBS += -lrte_rawdev
LDLIBS += -lrte_bus_vdev
LDLIBS += -lrte_kvargs
LDLIBS += -lrte_bus_pci
LDLIBS += -lrte_bus_ifpga
EXPORT_MAP := rte_pmd_ifpga_rawdev_version.map
LIBABIVER := 1
VPATH += $(SRCDIR)/base
include $(RTE_SDK)/drivers/raw/ifpga_rawdev/base/Makefile
#
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev.c
include $(RTE_SDK)/mk/rte.lib.mk

View File

@ -0,0 +1,619 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <rte_log.h>
#include <rte_bus.h>
#include <rte_eal_memconfig.h>
#include <rte_malloc.h>
#include <rte_devargs.h>
#include <rte_memcpy.h>
#include <rte_pci.h>
#include <rte_bus_pci.h>
#include <rte_kvargs.h>
#include <rte_alarm.h>
#include <rte_errno.h>
#include <rte_per_lcore.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_common.h>
#include <rte_bus_vdev.h>
#include "base/opae_hw_api.h"
#include "rte_rawdev.h"
#include "rte_rawdev_pmd.h"
#include "rte_bus_ifpga.h"
#include "ifpga_common.h"
#include "ifpga_logs.h"
#include "ifpga_rawdev.h"
int ifpga_rawdev_logtype;
#define PCI_VENDOR_ID_INTEL 0x8086
/* PCI Device ID */
#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
/* VF Device */
#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
#define RTE_MAX_RAW_DEVICE 10
static const struct rte_pci_id pci_ifpga_map[] = {
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X) },
{ .vendor_id = 0, /* sentinel */ },
};
static int
ifpga_fill_afu_dev(struct opae_accelerator *acc,
struct rte_afu_device *afu_dev)
{
struct rte_mem_resource *res = afu_dev->mem_resource;
struct opae_acc_region_info region_info;
struct opae_acc_info info;
unsigned long i;
int ret;
ret = opae_acc_get_info(acc, &info);
if (ret)
return ret;
if (info.num_regions > PCI_MAX_RESOURCE)
return -EFAULT;
afu_dev->num_region = info.num_regions;
for (i = 0; i < info.num_regions; i++) {
region_info.index = i;
ret = opae_acc_get_region_info(acc, &region_info);
if (ret)
return ret;
if ((region_info.flags & ACC_REGION_MMIO) &&
(region_info.flags & ACC_REGION_READ) &&
(region_info.flags & ACC_REGION_WRITE)) {
res[i].phys_addr = region_info.phys_addr;
res[i].len = region_info.len;
res[i].addr = region_info.addr;
} else
return -EFAULT;
}
return 0;
}
static void
ifpga_rawdev_info_get(struct rte_rawdev *dev,
rte_rawdev_obj_t dev_info)
{
struct opae_adapter *adapter;
struct opae_accelerator *acc;
struct rte_afu_device *afu_dev;
IFPGA_RAWDEV_PMD_FUNC_TRACE();
if (!dev_info) {
IFPGA_RAWDEV_PMD_ERR("Invalid request");
return;
}
adapter = ifpga_rawdev_get_priv(dev);
if (!adapter)
return;
afu_dev = dev_info;
afu_dev->rawdev = dev;
/* find opae_accelerator and fill info into afu_device */
opae_adapter_for_each_acc(adapter, acc) {
if (acc->index != afu_dev->id.port)
continue;
if (ifpga_fill_afu_dev(acc, afu_dev)) {
IFPGA_RAWDEV_PMD_ERR("cannot get info\n");
return;
}
}
}
static int
ifpga_rawdev_configure(const struct rte_rawdev *dev,
rte_rawdev_obj_t config)
{
IFPGA_RAWDEV_PMD_FUNC_TRACE();
RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
return config ? 0 : 1;
}
static int
ifpga_rawdev_start(struct rte_rawdev *dev)
{
int ret = 0;
struct opae_adapter *adapter;
IFPGA_RAWDEV_PMD_FUNC_TRACE();
RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
adapter = ifpga_rawdev_get_priv(dev);
if (!adapter)
return -ENODEV;
return ret;
}
static void
ifpga_rawdev_stop(struct rte_rawdev *dev)
{
dev->started = 0;
}
static int
ifpga_rawdev_close(struct rte_rawdev *dev)
{
return dev ? 0:1;
}
static int
ifpga_rawdev_reset(struct rte_rawdev *dev)
{
return dev ? 0:1;
}
static int
fpga_pr(struct rte_rawdev *raw_dev, u32 port_id, u64 *buffer, u32 size,
u64 *status)
{
struct opae_adapter *adapter;
struct opae_manager *mgr;
struct opae_accelerator *acc;
struct opae_bridge *br;
int ret;
adapter = ifpga_rawdev_get_priv(raw_dev);
if (!adapter)
return -ENODEV;
mgr = opae_adapter_get_mgr(adapter);
if (!mgr)
return -ENODEV;
acc = opae_adapter_get_acc(adapter, port_id);
if (!acc)
return -ENODEV;
br = opae_acc_get_br(acc);
if (!br)
return -ENODEV;
ret = opae_manager_flash(mgr, port_id, buffer, size, status);
if (ret) {
IFPGA_RAWDEV_PMD_ERR("%s pr error %d\n", __func__, ret);
return ret;
}
ret = opae_bridge_reset(br);
if (ret) {
IFPGA_RAWDEV_PMD_ERR("%s reset port:%d error %d\n",
__func__, port_id, ret);
return ret;
}
return ret;
}
static int
rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id,
const char *file_name)
{
struct stat file_stat;
int file_fd;
int ret = 0;
ssize_t buffer_size;
void *buffer;
u64 pr_error;
if (!file_name)
return -EINVAL;
file_fd = open(file_name, O_RDONLY);
if (file_fd < 0) {
IFPGA_RAWDEV_PMD_ERR("%s: open file error: %s\n",
__func__, file_name);
IFPGA_RAWDEV_PMD_ERR("Message : %s\n", strerror(errno));
return -EINVAL;
}
ret = stat(file_name, &file_stat);
if (ret) {
IFPGA_RAWDEV_PMD_ERR("stat on bitstream file failed: %s\n",
file_name);
return -EINVAL;
}
buffer_size = file_stat.st_size;
IFPGA_RAWDEV_PMD_INFO("bitstream file size: %zu\n", buffer_size);
buffer = rte_malloc(NULL, buffer_size, 0);
if (!buffer) {
ret = -ENOMEM;
goto close_fd;
}
/*read the raw data*/
if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) {
ret = -EINVAL;
goto free_buffer;
}
/*do PR now*/
ret = fpga_pr(rawdev, port_id, buffer, buffer_size, &pr_error);
IFPGA_RAWDEV_PMD_INFO("downloading to device port %d....%s.\n", port_id,
ret ? "failed" : "success");
if (ret) {
ret = -EINVAL;
goto free_buffer;
}
free_buffer:
if (buffer)
rte_free(buffer);
close_fd:
close(file_fd);
file_fd = 0;
return ret;
}
static int
ifpga_rawdev_pr(struct rte_rawdev *dev,
rte_rawdev_obj_t pr_conf)
{
struct opae_adapter *adapter;
struct rte_afu_pr_conf *afu_pr_conf;
int ret;
struct uuid uuid;
struct opae_accelerator *acc;
IFPGA_RAWDEV_PMD_FUNC_TRACE();
adapter = ifpga_rawdev_get_priv(dev);
if (!adapter)
return -ENODEV;
if (!pr_conf)
return -EINVAL;
afu_pr_conf = pr_conf;
if (afu_pr_conf->pr_enable) {
ret = rte_fpga_do_pr(dev,
afu_pr_conf->afu_id.port,
afu_pr_conf->bs_path);
if (ret) {
IFPGA_RAWDEV_PMD_ERR("do pr error %d\n", ret);
return ret;
}
}
acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
if (!acc)
return -ENODEV;
ret = opae_acc_get_uuid(acc, &uuid);
if (ret)
return ret;
memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
(unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
return 0;
}
static const struct rte_rawdev_ops ifpga_rawdev_ops = {
.dev_info_get = ifpga_rawdev_info_get,
.dev_configure = ifpga_rawdev_configure,
.dev_start = ifpga_rawdev_start,
.dev_stop = ifpga_rawdev_stop,
.dev_close = ifpga_rawdev_close,
.dev_reset = ifpga_rawdev_reset,
.queue_def_conf = NULL,
.queue_setup = NULL,
.queue_release = NULL,
.attr_get = NULL,
.attr_set = NULL,
.enqueue_bufs = NULL,
.dequeue_bufs = NULL,
.dump = NULL,
.xstats_get = NULL,
.xstats_get_names = NULL,
.xstats_get_by_name = NULL,
.xstats_reset = NULL,
.firmware_status_get = NULL,
.firmware_version_get = NULL,
.firmware_load = ifpga_rawdev_pr,
.firmware_unload = NULL,
.dev_selftest = NULL,
};
static int
ifpga_rawdev_create(struct rte_pci_device *pci_dev,
int socket_id)
{
int ret = 0;
struct rte_rawdev *rawdev = NULL;
struct opae_adapter *adapter = NULL;
struct opae_manager *mgr = NULL;
struct opae_adapter_data_pci *data = NULL;
char name[RTE_RAWDEV_NAME_MAX_LEN];
int i;
if (!pci_dev) {
IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
ret = -EINVAL;
goto cleanup;
}
memset(name, 0, sizeof(name));
snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
/* Allocate device structure */
rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct opae_adapter),
socket_id);
if (rawdev == NULL) {
IFPGA_RAWDEV_PMD_ERR("Unable to allocate rawdevice");
ret = -EINVAL;
goto cleanup;
}
/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
if (!data) {
ret = -ENOMEM;
goto cleanup;
}
/* init opae_adapter_data_pci for device specific information */
for (i = 0; i < PCI_MAX_RESOURCE; i++) {
data->region[i].phys_addr = pci_dev->mem_resource[i].phys_addr;
data->region[i].len = pci_dev->mem_resource[i].len;
data->region[i].addr = pci_dev->mem_resource[i].addr;
}
data->device_id = pci_dev->id.device_id;
data->vendor_id = pci_dev->id.vendor_id;
/* create a opae_adapter based on above device data */
adapter = opae_adapter_alloc(pci_dev->device.name, data);
if (!adapter) {
ret = -ENOMEM;
goto free_adapter_data;
}
rawdev->dev_ops = &ifpga_rawdev_ops;
rawdev->device = &pci_dev->device;
rawdev->driver_name = pci_dev->device.driver->name;
rawdev->dev_private = adapter;
/* must enumerate the adapter before use it */
ret = opae_adapter_enumerate(adapter);
if (ret)
goto free_adapter;
/* get opae_manager to rawdev */
mgr = opae_adapter_get_mgr(adapter);
if (mgr) {
/* PF function */
IFPGA_RAWDEV_PMD_INFO("this is a PF function");
}
return ret;
free_adapter:
if (adapter)
opae_adapter_free(adapter);
free_adapter_data:
if (data)
opae_adapter_data_free(data);
cleanup:
if (rawdev)
rte_rawdev_pmd_release(rawdev);
return ret;
}
static int
ifpga_rawdev_destroy(struct rte_pci_device *pci_dev)
{
int ret;
struct rte_rawdev *rawdev;
char name[RTE_RAWDEV_NAME_MAX_LEN];
struct opae_adapter *adapter;
if (!pci_dev) {
IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
ret = -EINVAL;
return ret;
}
memset(name, 0, sizeof(name));
snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d",
name, rte_socket_id());
rawdev = rte_rawdev_pmd_get_named_dev(name);
if (!rawdev) {
IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name);
return -EINVAL;
}
adapter = ifpga_rawdev_get_priv(rawdev);
if (!adapter)
return -ENODEV;
opae_adapter_data_free(adapter->data);
opae_adapter_free(adapter);
/* rte_rawdev_close is called by pmd_release */
ret = rte_rawdev_pmd_release(rawdev);
if (ret)
IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed");
return ret;
}
static int
ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
IFPGA_RAWDEV_PMD_FUNC_TRACE();
return ifpga_rawdev_create(pci_dev, rte_socket_id());
}
static int
ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
{
return ifpga_rawdev_destroy(pci_dev);
}
static struct rte_pci_driver rte_ifpga_rawdev_pmd = {
.id_table = pci_ifpga_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = ifpga_rawdev_pci_probe,
.remove = ifpga_rawdev_pci_remove,
};
RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd);
RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd);
RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci");
RTE_INIT(ifpga_rawdev_init_log);
static void
ifpga_rawdev_init_log(void)
{
ifpga_rawdev_logtype = rte_log_register("driver.raw.init");
if (ifpga_rawdev_logtype >= 0)
rte_log_set_level(ifpga_rawdev_logtype, RTE_LOG_NOTICE);
}
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
};
static int
ifpga_cfg_probe(struct rte_vdev_device *dev)
{
struct rte_devargs *devargs;
struct rte_kvargs *kvlist = NULL;
int port;
char *name = NULL;
char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
devargs = dev->device.devargs;
kvlist = rte_kvargs_parse(devargs->args, valid_args);
if (!kvlist) {
IFPGA_RAWDEV_PMD_LOG(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_RAWDEV_PMD_ERR("error to parse %s",
IFPGA_ARG_NAME);
goto end;
}
} else {
IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
IFPGA_ARG_NAME);
goto end;
}
if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
if (rte_kvargs_process(kvlist,
IFPGA_ARG_PORT,
&rte_ifpga_get_integer32_arg,
&port) < 0) {
IFPGA_RAWDEV_PMD_ERR("error to parse %s",
IFPGA_ARG_PORT);
goto end;
}
} else {
IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus",
IFPGA_ARG_PORT);
goto end;
}
memset(dev_name, 0, sizeof(dev_name));
snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
port, name);
rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME),
dev_name, devargs->args);
end:
if (kvlist)
rte_kvargs_free(kvlist);
if (name)
free(name);
return 0;
}
static int
ifpga_cfg_remove(struct rte_vdev_device *vdev)
{
IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p",
vdev);
return 0;
}
static struct rte_vdev_driver ifpga_cfg_driver = {
.probe = ifpga_cfg_probe,
.remove = ifpga_cfg_remove,
};
RTE_PMD_REGISTER_VDEV(ifpga_rawdev_cfg, ifpga_cfg_driver);
RTE_PMD_REGISTER_ALIAS(ifpga_rawdev_cfg, ifpga_cfg);
RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg,
"ifpga=<string> "
"port=<int> "
"afu_bts=<path>");

View File

@ -0,0 +1,37 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2018 Intel Corporation
*/
#ifndef _IFPGA_RAWDEV_H_
#define _IFPGA_RAWDEV_H_
extern int ifpga_rawdev_logtype;
#define IFPGA_RAWDEV_PMD_LOG(level, fmt, args...) \
rte_log(RTE_LOG_ ## level, ifpga_rawdev_logtype, "ifgpa: " fmt, \
##args)
#define IFPGA_RAWDEV_PMD_FUNC_TRACE() IFPGA_RAWDEV_PMD_LOG(DEBUG, ">>")
#define IFPGA_RAWDEV_PMD_DEBUG(fmt, args...) \
IFPGA_RAWDEV_PMD_LOG(DEBUG, fmt, ## args)
#define IFPGA_RAWDEV_PMD_INFO(fmt, args...) \
IFPGA_RAWDEV_PMD_LOG(INFO, fmt, ## args)
#define IFPGA_RAWDEV_PMD_ERR(fmt, args...) \
IFPGA_RAWDEV_PMD_LOG(ERR, fmt, ## args)
#define IFPGA_RAWDEV_PMD_WARN(fmt, args...) \
IFPGA_RAWDEV_PMD_LOG(WARNING, fmt, ## args)
enum ifpga_rawdev_device_state {
IFPGA_IDLE,
IFPGA_READY,
IFPGA_ERROR
};
static inline struct opae_adapter *
ifpga_rawdev_get_priv(const struct rte_rawdev *rawdev)
{
return rawdev->dev_private;
}
#endif /* _IFPGA_RAWDEV_H_ */

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018 Intel Corporation
version = 1
subdir('base')
objs = [base_objs]
deps += ['rawdev', 'pci', 'bus_pci', 'kvargs',
'bus_vdev', 'bus_ifpga']
sources = files('ifpga_rawdev.c')
includes += include_directories('base')
allow_experimental_apis = true

View File

@ -0,0 +1,4 @@
DPDK_18.05 {
local: *;
};

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma']
drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'

View File

@ -262,9 +262,11 @@ _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
ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
_LDLIBS-y += --no-whole-archive