[dpdk-dev,v4,1/3] Add Intel FPGA BUS Lib Code

Message ID 1522512182-182441-2-git-send-email-rosen.xu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Xu, Rosen March 31, 2018, 4:03 p.m. UTC
  Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 config/common_base                          |   5 +
 drivers/bus/Makefile                        |   1 +
 drivers/bus/ifpga/Makefile                  |  33 ++
 drivers/bus/ifpga/ifpga_bus.c               | 517 ++++++++++++++++++++++++++++
 drivers/bus/ifpga/ifpga_common.c            | 141 ++++++++
 drivers/bus/ifpga/ifpga_common.h            |  22 ++
 drivers/bus/ifpga/ifpga_logs.h              |  31 ++
 drivers/bus/ifpga/rte_bus_ifpga.h           | 175 ++++++++++
 drivers/bus/ifpga/rte_bus_ifpga_version.map |   8 +
 mk/rte.app.mk                               |   2 +
 10 files changed, 935 insertions(+)
 create mode 100644 drivers/bus/ifpga/Makefile
 create mode 100644 drivers/bus/ifpga/ifpga_bus.c
 create mode 100644 drivers/bus/ifpga/ifpga_common.c
 create mode 100644 drivers/bus/ifpga/ifpga_common.h
 create mode 100644 drivers/bus/ifpga/ifpga_logs.h
 create mode 100644 drivers/bus/ifpga/rte_bus_ifpga.h
 create mode 100644 drivers/bus/ifpga/rte_bus_ifpga_version.map
  

Comments

Shreyansh Jain April 3, 2018, 9:25 a.m. UTC | #1
Hello Rosen,

On Saturday 31 March 2018 09:33 PM, Rosen Xu wrote:
> Signed-off-by: Rosen Xu <rosen.xu@intel.com>
> ---
>   config/common_base                          |   5 +
>   drivers/bus/Makefile                        |   1 +
>   drivers/bus/ifpga/Makefile                  |  33 ++
>   drivers/bus/ifpga/ifpga_bus.c               | 517 ++++++++++++++++++++++++++++
>   drivers/bus/ifpga/ifpga_common.c            | 141 ++++++++
>   drivers/bus/ifpga/ifpga_common.h            |  22 ++
>   drivers/bus/ifpga/ifpga_logs.h              |  31 ++
>   drivers/bus/ifpga/rte_bus_ifpga.h           | 175 ++++++++++
>   drivers/bus/ifpga/rte_bus_ifpga_version.map |   8 +
>   mk/rte.app.mk                               |   2 +
>   10 files changed, 935 insertions(+)
>   create mode 100644 drivers/bus/ifpga/Makefile
>   create mode 100644 drivers/bus/ifpga/ifpga_bus.c
>   create mode 100644 drivers/bus/ifpga/ifpga_common.c
>   create mode 100644 drivers/bus/ifpga/ifpga_common.h
>   create mode 100644 drivers/bus/ifpga/ifpga_logs.h
>   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga.h
>   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga_version.map
> 
> diff --git a/config/common_base b/config/common_base
> index ad03cf4..49f6b09 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -134,6 +134,11 @@ CONFIG_RTE_LIBRTE_PCI_BUS=y
>   CONFIG_RTE_LIBRTE_VDEV_BUS=y
>   
>   #
> +# Compile the Intel FPGA bus
> +#
> +CONFIG_RTE_LIBRTE_IFPGA_BUS=y
> +
> +#
>   # Compile ARK PMD
>   #
>   CONFIG_RTE_LIBRTE_ARK_PMD=y
> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
> index 7ef2593..55d2dfe 100644
> --- a/drivers/bus/Makefile
> +++ b/drivers/bus/Makefile
> @@ -7,5 +7,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
>   DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
>   DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
>   DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
> +DIRS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga

When I attempted to compile the above using SHARED_LIB=y, this is what I 
got:

--->8---
   LD librte_bus_ifpga.so.1.1
ifpga_bus.o: In function `rte_ifpga_parse':
ifpga_bus.c:(.text+0x2eb): undefined reference to `rte_rawdevs'
ifpga_bus.o: In function `rte_ifpga_scan':
ifpga_bus.c:(.text+0x53e): undefined reference to `rte_kvargs_parse'
ifpga_bus.c:(.text+0x55e): undefined reference to `rte_kvargs_count'
ifpga_bus.c:(.text+0x580): undefined reference to `rte_kvargs_process'
ifpga_bus.c:(.text+0x5e0): undefined reference to `rte_rawdevs'
ifpga_bus.c:(.text+0x746): undefined reference to `rte_kvargs_free'
ifpga_bus.c:(.text+0x7b8): undefined reference to `rte_pci_addr_cmp'
ifpga_bus.c:(.text+0x858): undefined reference to `rte_kvargs_parse'
ifpga_bus.c:(.text+0x878): undefined reference to `rte_kvargs_count'
ifpga_bus.c:(.text+0x89c): undefined reference to `rte_kvargs_process'
ifpga_bus.c:(.text+0x8b8): undefined reference to `rte_kvargs_count'
ifpga_bus.c:(.text+0x8dc): undefined reference to `rte_kvargs_process'
ifpga_bus.c:(.text+0x8f8): undefined reference to `rte_kvargs_count'
ifpga_bus.c:(.text+0x91c): undefined reference to `rte_kvargs_process'
ifpga_bus.c:(.text+0x981): undefined reference to `rte_kvargs_free'
ifpga_common.o: In function `ifpga_pci_addr_cmp':
ifpga_common.c:(.text+0x2c5): undefined reference to 
`rte_eal_compare_pci_addr'
collect2: error: ld returned 1 exit status
/home/shreyansh/build/DPDK/00_dpdk/mk/rte.lib.mk:98: recipe for target 
'librte_bus_ifpga.so.1.1' failed
make[6]: *** [librte_bus_ifpga.so.1.1] Error 1
/home/shreyansh/build/DPDK/00_dpdk/mk/rte.subdir.mk:35: recipe for 
target 'ifpga' failed
make[5]: *** [ifpga] Error 2
--->8---

Essentially, you are dependent on librte_kvargs but you have not 
declared that in your Makefile. Same for lib_rawdev.

>   
>   include $(RTE_SDK)/mk/rte.subdir.mk
> diff --git a/drivers/bus/ifpga/Makefile b/drivers/bus/ifpga/Makefile
> new file mode 100644
> index 0000000..1b569af
> --- /dev/null
> +++ b/drivers/bus/ifpga/Makefile
> @@ -0,0 +1,33 @@
> +# 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 += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +# versioning export map
> +EXPORT_MAP := rte_bus_ifpga_version.map
> +
> +# library version
> +LIBABIVER := 1
> +
> +VPATH += $(SRCDIR)/base
> +
> +SRCS-y += \
> +        ifpga_bus.c \
> +        ifpga_common.c
> +
> +LDLIBS += -lrte_eal
> +
> +#
> +# Export include files
> +#
> +SYMLINK-y-include += rte_bus_ifpga.h
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
> new file mode 100644
> index 0000000..eba2615
> --- /dev/null
> +++ b/drivers/bus/ifpga/ifpga_bus.c
> @@ -0,0 +1,517 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2018 Intel Corporation
> + */
> +

[...]

> +
> +	if (rawdev->dev_ops &&
> +		rawdev->dev_ops->dev_start &&
> +		rawdev->dev_ops->dev_start(rawdev))
> +		goto free_dev;
> +	if (path) {
> +		strncpy(afu_pr_conf.bs_path, path, strlen(path));

strncpy with demarcation based on source is not right. strlen(path) can 
be larger than afu_pr_conf.bs_path

I saw some comment from Gaetan in previous version, if I recall correctly.

> +		if (rawdev->dev_ops->firmware_load &&
> +			rawdev->dev_ops->firmware_load(rawdev,
> +					&afu_pr_conf)){
> +			printf("firmware load error %d\n", ret);
> +			goto free_dev;
> +		}
> +		afu_dev->id.uuid_low  = afu_pr_conf.afu_id.uuid_low;
> +		afu_dev->id.uuid_high = afu_pr_conf.afu_id.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
> +rte_ifpga_scan(void)
> +{

[...]

> +
> +static int
> +ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
> +{
> +	struct rte_afu_driver *drv = NULL;
> +	int rc;
> +
> +	if (afu_dev == NULL)
> +		return -1;
> +
> +	/* Check if a driver is already loaded */
> +	if (afu_dev->driver != NULL)
> +		return 0;
> +
> +	TAILQ_FOREACH(drv, &rte_ifpga_bus.driver_list, next) {
> +		rc = ifpga_probe_one_driver(drv, afu_dev);
> +		if (rc < 0)
> +			/* negative value is an error */
> +			return -1;
> +		if (rc > 0)
> +			/* positive value means driver doesn't support it */
> +			continue;
> +		return 0;
> +	}
> +	return 1;
> +}
> +
> +/*
> + * Scan the content of the PCI bus, and call the probe() function for

I think you are not moving on PCI bus elements. You are looping on 
rte_ifpga_bus.

> + * all registered drivers that have a matching entry in its id_table
> + * for discovered devices.
> + */
> +static int
> +rte_ifpga_probe(void)
> +{
> +	struct rte_ifpga_device *ifpga_dev;
> +	struct rte_afu_device *afu_dev = NULL;
> +	int ret = 0;
> +
> +	TAILQ_FOREACH(ifpga_dev, &rte_ifpga_bus.ifpga_list, next) {
> +		TAILQ_FOREACH(afu_dev, &ifpga_dev->afu_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 0;
> +}
> +

[...]

> diff --git a/drivers/bus/ifpga/ifpga_common.c b/drivers/bus/ifpga/ifpga_common.c
> new file mode 100644
> index 0000000..124ffd2
> --- /dev/null
> +++ b/drivers/bus/ifpga/ifpga_common.c
> @@ -0,0 +1,141 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2018 Intel Corporation
> + */
> +

[...]

> +
> +}
> +int ifpga_get_bdf_arg(const char *key __rte_unused,
> +	const char *value, void *extra_args)
> +{
> +#define MAX_PATH_LEN 1024

Is this max len of a file path or a max len of the value string (BDF).
Can you rename this?

Just a trivial comment, though.

[...]

> diff --git a/drivers/bus/ifpga/ifpga_logs.h b/drivers/bus/ifpga/ifpga_logs.h
> new file mode 100644
> index 0000000..873e0a4
> --- /dev/null
> +++ b/drivers/bus/ifpga/ifpga_logs.h
> @@ -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)

I don't see macro above being used. Would you be using this in later 
patches? (But, i think they might have their own logging definitions).

> +
> +#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_ */
> diff --git a/drivers/bus/ifpga/rte_bus_ifpga.h b/drivers/bus/ifpga/rte_bus_ifpga.h
> new file mode 100644
> index 0000000..e22ab4e
> --- /dev/null
> +++ b/drivers/bus/ifpga/rte_bus_ifpga.h
> @@ -0,0 +1,175 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2018 Intel Corporation
> + */
> +
> +#ifndef _RTE_BUS_IFPGA_H_
> +#define _RTE_BUS_IFPGA_H_
> +
> +/**
> + * @file
> + *
> + * RTE PCI Bus Interface

This is not a "RTE PCI Bus Interface" - It should be AFU/IFPA Bus 
interface file

There are some comments which were given in early versions. Like this 
one. Please do respond to those individually if you are not fixing them.
(Also, it is nice to get acknowledgment of those which are being fixed).

> + */
> +
> +#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_ifpga_device;
> +struct rte_afu_device;
> +struct rte_afu_driver;
> +
> +/** List of Intel FPGA devices */
> +TAILQ_HEAD(rte_ifpga_device_list, rte_ifpga_device);
> +/** List of Intel AFU devices */
> +TAILQ_HEAD(rte_afu_device_list, rte_afu_device);
> +/** List of AFU drivers */
> +TAILQ_HEAD(rte_afu_driver_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_pci_addr pci_addr;
> +	uint64_t uuid_low;
> +	uint64_t uuid_high;
> +	int      port;
> +} __attribute__ ((packed));
> +
> +/**
> + * A structure pr 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];
             ^^^^^^^^^^^
Some stray indentation issue, it seems

> +};
> +
> +#define AFU_PRI_STR_SIZE (PCI_PRI_STR_SIZE + 8)
> +
> +/**
> + * A structure describing a fpga device.
> + */
> +struct rte_ifpga_device {
> +	TAILQ_ENTRY(rte_ifpga_device) next;       /**< Next in device list. */
> +	struct rte_pci_addr pci_addr;
> +	struct rte_rawdev *rdev;
> +	struct rte_afu_device_list afu_list;  /**< List of AFU devices */
> +};
> +
> +/**
> + * 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_ifpga_device *ifpga_dev;    /**< Point ifpga device */
> +	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];
> +						/**< PCI 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)
> +
> +/**
> + * Initialisation function for the driver called during PCI probing.

PCI Probing would have already been done through the PCI bus. I think 
this is probing of the AFU devices (based on the PCI already probed).

> + */
> +typedef int (afu_probe_t)(struct rte_afu_device *);
> +
> +/**
> + * Uninitialisation function for the driver called during hotplugging.
> + */
> +typedef int (afu_remove_t)(struct rte_afu_device *);
> +
> +/**
> + * A structure describing a PCI device.
                               ^^^^
Structure describing an 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. */
> +	uint32_t drv_flags;         /**< Flags contolling handling of device. */
> +};
> +
> +/**
> + * Structure describing the Intel FPGA bus
> + */
> +struct rte_ifpga_bus {
> +	struct rte_bus bus;               /**< Inherit the generic class */
> +	struct rte_ifpga_device_list ifpga_list;  /**< List of FPGA devices */
> +	struct rte_afu_driver_list driver_list;  /**< List of FPGA drivers */
> +};
> +
> +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;
> +}
> +
> +extern struct rte_ifpga_bus rte_ifpga_bus;
> +
> +/**
> + * 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_ */
> diff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map b/drivers/bus/ifpga/rte_bus_ifpga_version.map
> new file mode 100644
> index 0000000..4edc9c0
> --- /dev/null
> +++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map
> @@ -0,0 +1,8 @@
> +DPDK_18.05 {
> +	global:
> +
> +    rte_ifpga_driver_register;
> +    rte_ifpga_driver_unregister;

Should be tab indented

> +
> +	local: *;
> +};

[...]

One suggestion:

I think a lot of comments were provided by Gaetan in the previous 
version. I see some that some of them are still not fixed in this version.

I suggest you individually reply to his comments if you are not going to 
fix, with reason. He put quite an effort to go through your patches.

That would help you track comments as well as not discount a reviewers 
effort.

-
Shreyansh
  
Xu, Rosen April 4, 2018, 1:44 a.m. UTC | #2
Hello Shreyansh,

> -----Original Message-----

> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]

> Sent: Tuesday, April 03, 2018 17:25

> To: Xu, Rosen <rosen.xu@intel.com>

> Cc: dev@dpdk.org; Doherty, Declan <declan.doherty@intel.com>;

> Richardson, Bruce <bruce.richardson@intel.com>; Yigit, Ferruh

> <ferruh.yigit@intel.com>; Ananyev, Konstantin

> <konstantin.ananyev@intel.com>; Zhang, Tianfei <tianfei.zhang@intel.com>;

> Wu, Hao <hao.wu@intel.com>; gaetan.rivet@6wind.com

> Subject: Re: [dpdk-dev] [PATCH v4 1/3] Add Intel FPGA BUS Lib Code

> 

> Hello Rosen,

> 

> On Saturday 31 March 2018 09:33 PM, Rosen Xu wrote:

> > Signed-off-by: Rosen Xu <rosen.xu@intel.com>

> > ---

> >   config/common_base                          |   5 +

> >   drivers/bus/Makefile                        |   1 +

> >   drivers/bus/ifpga/Makefile                  |  33 ++

> >   drivers/bus/ifpga/ifpga_bus.c               | 517

> ++++++++++++++++++++++++++++

> >   drivers/bus/ifpga/ifpga_common.c            | 141 ++++++++

> >   drivers/bus/ifpga/ifpga_common.h            |  22 ++

> >   drivers/bus/ifpga/ifpga_logs.h              |  31 ++

> >   drivers/bus/ifpga/rte_bus_ifpga.h           | 175 ++++++++++

> >   drivers/bus/ifpga/rte_bus_ifpga_version.map |   8 +

> >   mk/rte.app.mk                               |   2 +

> >   10 files changed, 935 insertions(+)

> >   create mode 100644 drivers/bus/ifpga/Makefile

> >   create mode 100644 drivers/bus/ifpga/ifpga_bus.c

> >   create mode 100644 drivers/bus/ifpga/ifpga_common.c

> >   create mode 100644 drivers/bus/ifpga/ifpga_common.h

> >   create mode 100644 drivers/bus/ifpga/ifpga_logs.h

> >   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga.h

> >   create mode 100644 drivers/bus/ifpga/rte_bus_ifpga_version.map

> >

> > diff --git a/config/common_base b/config/common_base index

> > ad03cf4..49f6b09 100644

> > --- a/config/common_base

> > +++ b/config/common_base

> > @@ -134,6 +134,11 @@ CONFIG_RTE_LIBRTE_PCI_BUS=y

> >   CONFIG_RTE_LIBRTE_VDEV_BUS=y

> >

> >   #

> > +# Compile the Intel FPGA bus

> > +#

> > +CONFIG_RTE_LIBRTE_IFPGA_BUS=y

> > +

> > +#

> >   # Compile ARK PMD

> >   #

> >   CONFIG_RTE_LIBRTE_ARK_PMD=y

> > diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index

> > 7ef2593..55d2dfe 100644

> > --- a/drivers/bus/Makefile

> > +++ b/drivers/bus/Makefile

> > @@ -7,5 +7,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa

> >   DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc

> >   DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci

> >   DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev

> > +DIRS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga

> 

> When I attempted to compile the above using SHARED_LIB=y, this is what I

> got:

> 

> --->8---

>    LD librte_bus_ifpga.so.1.1

> ifpga_bus.o: In function `rte_ifpga_parse':

> ifpga_bus.c:(.text+0x2eb): undefined reference to `rte_rawdevs'

> ifpga_bus.o: In function `rte_ifpga_scan':

> ifpga_bus.c:(.text+0x53e): undefined reference to `rte_kvargs_parse'

> ifpga_bus.c:(.text+0x55e): undefined reference to `rte_kvargs_count'

> ifpga_bus.c:(.text+0x580): undefined reference to `rte_kvargs_process'

> ifpga_bus.c:(.text+0x5e0): undefined reference to `rte_rawdevs'

> ifpga_bus.c:(.text+0x746): undefined reference to `rte_kvargs_free'

> ifpga_bus.c:(.text+0x7b8): undefined reference to `rte_pci_addr_cmp'

> ifpga_bus.c:(.text+0x858): undefined reference to `rte_kvargs_parse'

> ifpga_bus.c:(.text+0x878): undefined reference to `rte_kvargs_count'

> ifpga_bus.c:(.text+0x89c): undefined reference to `rte_kvargs_process'

> ifpga_bus.c:(.text+0x8b8): undefined reference to `rte_kvargs_count'

> ifpga_bus.c:(.text+0x8dc): undefined reference to `rte_kvargs_process'

> ifpga_bus.c:(.text+0x8f8): undefined reference to `rte_kvargs_count'

> ifpga_bus.c:(.text+0x91c): undefined reference to `rte_kvargs_process'

> ifpga_bus.c:(.text+0x981): undefined reference to `rte_kvargs_free'

> ifpga_common.o: In function `ifpga_pci_addr_cmp':

> ifpga_common.c:(.text+0x2c5): undefined reference to

> `rte_eal_compare_pci_addr'

> collect2: error: ld returned 1 exit status

> /home/shreyansh/build/DPDK/00_dpdk/mk/rte.lib.mk:98: recipe for target

> 'librte_bus_ifpga.so.1.1' failed

> make[6]: *** [librte_bus_ifpga.so.1.1] Error 1

> /home/shreyansh/build/DPDK/00_dpdk/mk/rte.subdir.mk:35: recipe for

> target 'ifpga' failed

> make[5]: *** [ifpga] Error 2

> --->8---


I have fixed it to modify Makefile in my PATCH v5.

> Essentially, you are dependent on librte_kvargs but you have not declared

> that in your Makefile. Same for lib_rawdev.


I have declared it in my PATCH v5.

> >

> >   include $(RTE_SDK)/mk/rte.subdir.mk

> > diff --git a/drivers/bus/ifpga/Makefile b/drivers/bus/ifpga/Makefile

> > new file mode 100644 index 0000000..1b569af

> > --- /dev/null

> > +++ b/drivers/bus/ifpga/Makefile

> > @@ -0,0 +1,33 @@

> > +# 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 += -O3

> > +CFLAGS += $(WERROR_FLAGS)

> > +

> > +# versioning export map

> > +EXPORT_MAP := rte_bus_ifpga_version.map

> > +

> > +# library version

> > +LIBABIVER := 1

> > +

> > +VPATH += $(SRCDIR)/base

> > +

> > +SRCS-y += \

> > +        ifpga_bus.c \

> > +        ifpga_common.c

> > +

> > +LDLIBS += -lrte_eal

> > +

> > +#

> > +# Export include files

> > +#

> > +SYMLINK-y-include += rte_bus_ifpga.h

> > +

> > +include $(RTE_SDK)/mk/rte.lib.mk

> > diff --git a/drivers/bus/ifpga/ifpga_bus.c

> > b/drivers/bus/ifpga/ifpga_bus.c new file mode 100644 index

> > 0000000..eba2615

> > --- /dev/null

> > +++ b/drivers/bus/ifpga/ifpga_bus.c

> > @@ -0,0 +1,517 @@

> > +/* SPDX-License-Identifier: BSD-3-Clause

> > + * Copyright(c) 2010-2018 Intel Corporation  */

> > +

> 

> [...]

> 

> > +

> > +	if (rawdev->dev_ops &&

> > +		rawdev->dev_ops->dev_start &&

> > +		rawdev->dev_ops->dev_start(rawdev))

> > +		goto free_dev;

> > +	if (path) {

> > +		strncpy(afu_pr_conf.bs_path, path, strlen(path));

> 

> strncpy with demarcation based on source is not right. strlen(path) can be

> larger than afu_pr_conf.bs_path


I have changed to destination string in PATCH v5.

> I saw some comment from Gaetan in previous version, if I recall correctly.

> 

> > +		if (rawdev->dev_ops->firmware_load &&

> > +			rawdev->dev_ops->firmware_load(rawdev,

> > +					&afu_pr_conf)){

> > +			printf("firmware load error %d\n", ret);

> > +			goto free_dev;

> > +		}

> > +		afu_dev->id.uuid_low  = afu_pr_conf.afu_id.uuid_low;

> > +		afu_dev->id.uuid_high = afu_pr_conf.afu_id.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

> > +rte_ifpga_scan(void)

> > +{

> 

> [...]

> 

> > +

> > +static int

> > +ifpga_probe_all_drivers(struct rte_afu_device *afu_dev) {

> > +	struct rte_afu_driver *drv = NULL;

> > +	int rc;

> > +

> > +	if (afu_dev == NULL)

> > +		return -1;

> > +

> > +	/* Check if a driver is already loaded */

> > +	if (afu_dev->driver != NULL)

> > +		return 0;

> > +

> > +	TAILQ_FOREACH(drv, &rte_ifpga_bus.driver_list, next) {

> > +		rc = ifpga_probe_one_driver(drv, afu_dev);

> > +		if (rc < 0)

> > +			/* negative value is an error */

> > +			return -1;

> > +		if (rc > 0)

> > +			/* positive value means driver doesn't support it */

> > +			continue;

> > +		return 0;

> > +	}

> > +	return 1;

> > +}

> > +

> > +/*

> > + * Scan the content of the PCI bus, and call the probe() function for

> 

> I think you are not moving on PCI bus elements. You are looping on

> rte_ifpga_bus.


I have modified all PCI bus elements to FPGA BUS in my PATCH v5.
 
> > + * all registered drivers that have a matching entry in its id_table

> > + * for discovered devices.

> > + */

> > +static int

> > +rte_ifpga_probe(void)

> > +{

> > +	struct rte_ifpga_device *ifpga_dev;

> > +	struct rte_afu_device *afu_dev = NULL;

> > +	int ret = 0;

> > +

> > +	TAILQ_FOREACH(ifpga_dev, &rte_ifpga_bus.ifpga_list, next) {

> > +		TAILQ_FOREACH(afu_dev, &ifpga_dev->afu_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 0;

> > +}

> > +

> 

> [...]

> 

> > diff --git a/drivers/bus/ifpga/ifpga_common.c

> > b/drivers/bus/ifpga/ifpga_common.c

> > new file mode 100644

> > index 0000000..124ffd2

> > --- /dev/null

> > +++ b/drivers/bus/ifpga/ifpga_common.c

> > @@ -0,0 +1,141 @@

> > +/* SPDX-License-Identifier: BSD-3-Clause

> > + * Copyright(c) 2010-2018 Intel Corporation  */

> > +

> 

> [...]

> 

> > +

> > +}

> > +int ifpga_get_bdf_arg(const char *key __rte_unused,

> > +	const char *value, void *extra_args) { #define MAX_PATH_LEN 1024

> 

> Is this max len of a file path or a max len of the value string (BDF).

> Can you rename this?


I will rename it to IFPGA_MAX_BDF_LEN in my PATCH v5.

> Just a trivial comment, though.

> 

> [...]

> 

> > diff --git a/drivers/bus/ifpga/ifpga_logs.h

> > b/drivers/bus/ifpga/ifpga_logs.h new file mode 100644 index

> > 0000000..873e0a4

> > --- /dev/null

> > +++ b/drivers/bus/ifpga/ifpga_logs.h

> > @@ -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)

> 

> I don't see macro above being used. Would you be using this in later patches?

> (But, i think they might have their own logging definitions).


Yes, they will be used in later patches.
For FPGA BUS is a common module, so we need to provide all macros will be used.
 
> > +

> > +#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_ */

> > diff --git a/drivers/bus/ifpga/rte_bus_ifpga.h

> > b/drivers/bus/ifpga/rte_bus_ifpga.h

> > new file mode 100644

> > index 0000000..e22ab4e

> > --- /dev/null

> > +++ b/drivers/bus/ifpga/rte_bus_ifpga.h

> > @@ -0,0 +1,175 @@

> > +/* SPDX-License-Identifier: BSD-3-Clause

> > + * Copyright(c) 2010-2018 Intel Corporation  */

> > +

> > +#ifndef _RTE_BUS_IFPGA_H_

> > +#define _RTE_BUS_IFPGA_H_

> > +

> > +/**

> > + * @file

> > + *

> > + * RTE PCI Bus Interface

> 

> This is not a "RTE PCI Bus Interface" - It should be AFU/IFPA Bus interface file


I will modify it in PATCH v5.
 
> There are some comments which were given in early versions. Like this one.

> Please do respond to those individually if you are not fixing them.

> (Also, it is nice to get acknowledgment of those which are being fixed).


I have fix those comments and I also will reply it to those individually.
 
> > + */

> > +

> > +#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_ifpga_device;

> > +struct rte_afu_device;

> > +struct rte_afu_driver;

> > +

> > +/** List of Intel FPGA devices */

> > +TAILQ_HEAD(rte_ifpga_device_list, rte_ifpga_device);

> > +/** List of Intel AFU devices */

> > +TAILQ_HEAD(rte_afu_device_list, rte_afu_device);

> > +/** List of AFU drivers */

> > +TAILQ_HEAD(rte_afu_driver_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_pci_addr pci_addr;

> > +	uint64_t uuid_low;

> > +	uint64_t uuid_high;

> > +	int      port;

> > +} __attribute__ ((packed));

> > +

> > +/**

> > + * A structure pr 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];

>              ^^^^^^^^^^^

> Some stray indentation issue, it seems


Do you means to change it  to:
char bs_path[IFPGA_BUS_BITSTREAM_PATH_MAX_LEN];?
If so I have fixed it in my PATCH v5.

> > +};

> > +

> > +#define AFU_PRI_STR_SIZE (PCI_PRI_STR_SIZE + 8)

> > +

> > +/**

> > + * A structure describing a fpga device.

> > + */

> > +struct rte_ifpga_device {

> > +	TAILQ_ENTRY(rte_ifpga_device) next;       /**< Next in device list. */

> > +	struct rte_pci_addr pci_addr;

> > +	struct rte_rawdev *rdev;

> > +	struct rte_afu_device_list afu_list;  /**< List of AFU devices */ };

> > +

> > +/**

> > + * 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_ifpga_device *ifpga_dev;    /**< Point ifpga device */

> > +	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];

> > +						/**< PCI 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)

> > +

> > +/**

> > + * Initialisation function for the driver called during PCI probing.

> 

> PCI Probing would have already been done through the PCI bus. I think this is

> probing of the AFU devices (based on the PCI already probed).


rte_ifpga_plug()/rte_ifpga_unplug() will use this macro.
 
> > + */

> > +typedef int (afu_probe_t)(struct rte_afu_device *);

> > +

> > +/**

> > + * Uninitialisation function for the driver called during hotplugging.

> > + */

> > +typedef int (afu_remove_t)(struct rte_afu_device *);

> > +

> > +/**

> > + * A structure describing a PCI device.

>                                ^^^^

> Structure describing an AFU device.


Yes, it should be AFU device, and I have fixed it in my PATCH v5.

> > + */

> > +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. */

> > +	uint32_t drv_flags;         /**< Flags contolling handling of device. */

> > +};

> > +

> > +/**

> > + * Structure describing the Intel FPGA bus  */ struct rte_ifpga_bus {

> > +	struct rte_bus bus;               /**< Inherit the generic class */

> > +	struct rte_ifpga_device_list ifpga_list;  /**< List of FPGA devices */

> > +	struct rte_afu_driver_list driver_list;  /**< List of FPGA drivers

> > +*/ };

> > +

> > +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;

> > +}

> > +

> > +extern struct rte_ifpga_bus rte_ifpga_bus;

> > +

> > +/**

> > + * 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_ */

> > diff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map

> > b/drivers/bus/ifpga/rte_bus_ifpga_version.map

> > new file mode 100644

> > index 0000000..4edc9c0

> > --- /dev/null

> > +++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map

> > @@ -0,0 +1,8 @@

> > +DPDK_18.05 {

> > +	global:

> > +

> > +    rte_ifpga_driver_register;

> > +    rte_ifpga_driver_unregister;

> 

> Should be tab indented


Yes, I will fix them.

> > +

> > +	local: *;

> > +};

> 

> [...]

> 

> One suggestion:

> 

> I think a lot of comments were provided by Gaetan in the previous version. I

> see some that some of them are still not fixed in this version.

> 

> I suggest you individually reply to his comments if you are not going to fix,

> with reason. He put quite an effort to go through your patches.

> 

> That would help you track comments as well as not discount a reviewers

> effort.


OK, I will individually reply to Gaetan's comments.

> -

> Shreyansh
  

Patch

diff --git a/config/common_base b/config/common_base
index ad03cf4..49f6b09 100644
--- a/config/common_base
+++ b/config/common_base
@@ -134,6 +134,11 @@  CONFIG_RTE_LIBRTE_PCI_BUS=y
 CONFIG_RTE_LIBRTE_VDEV_BUS=y
 
 #
+# Compile the Intel FPGA bus
+#
+CONFIG_RTE_LIBRTE_IFPGA_BUS=y
+
+#
 # Compile ARK PMD
 #
 CONFIG_RTE_LIBRTE_ARK_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 7ef2593..55d2dfe 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -7,5 +7,6 @@  DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
 DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
+DIRS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/ifpga/Makefile b/drivers/bus/ifpga/Makefile
new file mode 100644
index 0000000..1b569af
--- /dev/null
+++ b/drivers/bus/ifpga/Makefile
@@ -0,0 +1,33 @@ 
+# 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 += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# versioning export map
+EXPORT_MAP := rte_bus_ifpga_version.map
+
+# library version
+LIBABIVER := 1
+
+VPATH += $(SRCDIR)/base
+
+SRCS-y += \
+        ifpga_bus.c \
+        ifpga_common.c
+
+LDLIBS += -lrte_eal
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_bus_ifpga.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
new file mode 100644
index 0000000..eba2615
--- /dev/null
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -0,0 +1,517 @@ 
+/* 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_pci.h>
+#include <rte_bus_pci.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;
+
+/* register a ifpga bus based driver */
+void rte_ifpga_driver_register(struct rte_afu_driver *driver)
+{
+	RTE_VERIFY(driver);
+
+	TAILQ_INSERT_TAIL(&rte_ifpga_bus.driver_list, driver, next);
+}
+
+/* un-register a fpga bus based driver */
+void rte_ifpga_driver_unregister(struct rte_afu_driver *driver)
+{
+	TAILQ_REMOVE(&rte_ifpga_bus.driver_list, driver, next);
+}
+
+static struct rte_ifpga_device *
+ifpga_find_ifpga_dev(const struct rte_pci_addr *pci_addr)
+{
+	struct rte_ifpga_device *ifpga_dev = NULL;
+
+	TAILQ_FOREACH(ifpga_dev, &rte_ifpga_bus.ifpga_list, next) {
+		if (!rte_pci_addr_cmp(&ifpga_dev->pci_addr, pci_addr))
+			return ifpga_dev;
+	}
+	return NULL;
+}
+
+static struct rte_afu_device *
+ifpga_find_afu_dev(const struct rte_ifpga_device *ifpga_dev,
+	const struct rte_afu_id *afu_id)
+{
+	struct rte_afu_device *afu_dev = NULL;
+
+	TAILQ_FOREACH(afu_dev, &ifpga_dev->afu_list, next) {
+		if (!ifpga_afu_id_cmp(&afu_dev->id, afu_id))
+			return afu_dev;
+	}
+	return NULL;
+}
+
+static const char * const valid_args[] = {
+#define IFPGA_ARG_BDF          "bdf"
+	IFPGA_ARG_BDF,
+#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 *
+rte_ifpga_scan_one(struct rte_devargs *devargs,
+	struct rte_ifpga_device *ifpga_dev)
+{
+	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct rte_afu_device *afu_dev = NULL;
+	struct rte_afu_pr_conf afu_pr_conf;
+	int ret = 0;
+	char *path = NULL;
+
+	memset((char *)(&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_BDF) == 1) {
+		if (rte_kvargs_process(kvlist, IFPGA_ARG_BDF,
+			&ifpga_get_bdf_arg, &afu_pr_conf.afu_id.pci_addr) < 0) {
+			IFPGA_BUS_ERR("error to parse %s", IFPGA_ARG_BDF);
+			goto end;
+		}
+	} else {
+		IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
+			IFPGA_ARG_BDF);
+		goto end;
+	}
+
+	if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
+		if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT,
+		&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,
+				       &ifpga_get_string_arg, &path) < 0) {
+			IFPGA_BUS_ERR("error 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_low = 0;
+	afu_pr_conf.afu_id.uuid_high = 0;
+	afu_pr_conf.pr_enable = path?1:0;
+
+	rawdev = ifpga_dev->rdev;
+	if (ifpga_find_afu_dev(ifpga_dev, &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.pci_addr.domain = afu_pr_conf.afu_id.pci_addr.domain;
+	afu_dev->id.pci_addr.bus = afu_pr_conf.afu_id.pci_addr.bus;
+	afu_dev->id.pci_addr.devid = afu_pr_conf.afu_id.pci_addr.devid;
+	afu_dev->id.pci_addr.function = afu_pr_conf.afu_id.pci_addr.function;
+	afu_dev->id.uuid_low  = 0;
+	afu_dev->id.uuid_high = 0;
+	afu_dev->id.port      = afu_pr_conf.afu_id.port;
+	afu_dev->ifpga_dev    = ifpga_dev;
+
+	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;
+	if (path) {
+		strncpy(afu_pr_conf.bs_path, path, strlen(path));
+		if (rawdev->dev_ops->firmware_load &&
+			rawdev->dev_ops->firmware_load(rawdev,
+					&afu_pr_conf)){
+			printf("firmware load error %d\n", ret);
+			goto free_dev;
+		}
+		afu_dev->id.uuid_low  = afu_pr_conf.afu_id.uuid_low;
+		afu_dev->id.uuid_high = afu_pr_conf.afu_id.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
+rte_ifpga_scan(void)
+{
+	struct rte_ifpga_device *ifpga_dev;
+	struct rte_devargs *devargs;
+	struct rte_kvargs *kvlist = NULL;
+	struct rte_pci_addr pci_addr;
+	struct rte_rawdev *rawdev = NULL;
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+	struct rte_afu_device *afu_dev = NULL;
+
+	/* for FPGA devices we scan the devargs_list populated via cmdline */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != &rte_ifpga_bus.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_BDF) == 1) {
+			if (rte_kvargs_process(kvlist, IFPGA_ARG_BDF,
+				&ifpga_get_bdf_arg, &pci_addr) < 0) {
+				IFPGA_BUS_ERR("error to parse %s",
+					IFPGA_ARG_BDF);
+				goto end;
+			}
+		} else {
+			IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
+				IFPGA_ARG_BDF);
+			goto end;
+		}
+
+		memset(name, 0, sizeof(name));
+		snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%x:%x",
+		pci_addr.bus, pci_addr.devid, pci_addr.function);
+
+		rawdev = rte_rawdev_pmd_get_named_dev(name);
+		if (!rawdev)
+			goto end;
+
+		if (ifpga_find_ifpga_dev(&pci_addr))
+			continue;
+
+		ifpga_dev = calloc(1, sizeof(*ifpga_dev));
+		if (!ifpga_dev)
+			goto end;
+
+		ifpga_dev->pci_addr.domain   = pci_addr.domain;
+		ifpga_dev->pci_addr.bus      = pci_addr.bus;
+		ifpga_dev->pci_addr.devid    = pci_addr.devid;
+		ifpga_dev->pci_addr.function = pci_addr.function;
+		ifpga_dev->rdev = rawdev;
+		TAILQ_INIT(&ifpga_dev->afu_list);
+
+		TAILQ_INSERT_TAIL(&rte_ifpga_bus.ifpga_list, ifpga_dev, next);
+		afu_dev = rte_ifpga_scan_one(devargs, ifpga_dev);
+		if (afu_dev != NULL)
+			TAILQ_INSERT_TAIL(&ifpga_dev->afu_list, afu_dev, next);
+	}
+
+end:
+	if (kvlist)
+		rte_kvargs_free(kvlist);
+
+	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_low) ||
+				(id_table->uuid_high != afu_dev->id.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 positive value if driver doesn't support this device */
+	return 0;
+}
+
+static int
+ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
+{
+	struct rte_afu_driver *drv = NULL;
+	int rc;
+
+	if (afu_dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (afu_dev->driver != NULL)
+		return 0;
+
+	TAILQ_FOREACH(drv, &rte_ifpga_bus.driver_list, next) {
+		rc = ifpga_probe_one_driver(drv, afu_dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+static int
+rte_ifpga_probe(void)
+{
+	struct rte_ifpga_device *ifpga_dev;
+	struct rte_afu_device *afu_dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(ifpga_dev, &rte_ifpga_bus.ifpga_list, next) {
+		TAILQ_FOREACH(afu_dev, &ifpga_dev->afu_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 0;
+}
+
+static int
+rte_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 = container_of(afu_dev->device.driver,
+		const struct rte_afu_driver,
+		driver);
+	return driver->remove(afu_dev);
+}
+
+static int
+rte_ifpga_unplug(struct rte_device *dev)
+{
+	struct rte_ifpga_device *ifpga_dev = NULL;
+	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;
+
+	ifpga_dev = afu_dev->ifpga_dev;
+	devargs = dev->devargs;
+
+	ret = ifpga_remove_driver(afu_dev);
+	if (ret)
+		return ret;
+
+	TAILQ_REMOVE(&ifpga_dev->afu_list, afu_dev, next);
+
+	TAILQ_REMOVE(&devargs_list, devargs, next);
+
+	free(devargs->args);
+	free(devargs);
+	free(afu_dev);
+	return 0;
+
+}
+
+static struct rte_device *
+rte_ifpga_find_device(const struct rte_device *start,
+	rte_dev_cmp_t cmp, const void *data)
+{
+	struct rte_ifpga_device *ifpga_dev;
+	struct rte_afu_device *afu_dev;
+
+	TAILQ_FOREACH(ifpga_dev, &rte_ifpga_bus.ifpga_list, next) {
+		TAILQ_FOREACH(afu_dev, &ifpga_dev->afu_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
+rte_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, *c2 = NULL;
+	int      port = IFPGA_BUS_DEV_PORT_MAX;
+	char str_port[8];
+	int str_port_len = 0;
+
+	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);
+		sscanf(str_port, "%d", &port);
+	}
+
+	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;
+}
+
+struct rte_ifpga_bus rte_ifpga_bus = {
+	 .bus = {
+		 .scan        = rte_ifpga_scan,
+		 .probe       = rte_ifpga_probe,
+		 .find_device = rte_ifpga_find_device,
+	     .plug        = rte_ifpga_plug,
+	     .unplug      = rte_ifpga_unplug,
+	     .parse       = rte_ifpga_parse,
+	 },
+	.ifpga_list  = TAILQ_HEAD_INITIALIZER(rte_ifpga_bus.ifpga_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_ifpga_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(IFPGA_BUS_NAME, rte_ifpga_bus.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);
+}
+
diff --git a/drivers/bus/ifpga/ifpga_common.c b/drivers/bus/ifpga/ifpga_common.c
new file mode 100644
index 0000000..124ffd2
--- /dev/null
+++ b/drivers/bus/ifpga/ifpga_common.c
@@ -0,0 +1,141 @@ 
+/* 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_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_kvargs.h>
+#include <rte_alarm.h>
+
+#include "rte_bus_ifpga.h"
+#include "ifpga_logs.h"
+#include "ifpga_common.h"
+
+int 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 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_get_bdf_arg(const char *key __rte_unused,
+	const char *value, void *extra_args)
+{
+#define MAX_PATH_LEN 1024
+	struct rte_pci_addr *addr;
+	int num[4];
+	char str[MAX_PATH_LEN];
+	int i, j;
+
+	if (!value || !extra_args)
+		return -EINVAL;
+
+	addr = (struct rte_pci_addr *)extra_args;
+	strcpy(str, value);
+	memset(num, 0, 4 * sizeof(num[0]));
+	i = strlen(str) - 1;
+	j = 3;
+	while (i > 0 && j >= 0) {
+		while ((str[i - 1] != ':' && str[i - 1] != '.') && i > 0)
+			i--;
+		num[j--] = ifpga_get_unsigned_long(&str[i], 16);
+		i--;
+		if (i >= 0)
+			str[i] = '\0';
+	}
+	addr->domain = num[0];
+	addr->bus = num[1];
+	addr->devid = num[2];
+	addr->function = num[3];
+	printf("[%s]: bdf %04d:%02d:%02d.%02d\n",
+			__func__,
+			addr->domain,
+			addr->bus,
+			addr->devid,
+			addr->function);
+
+	return 0;
+}
+
+int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0,
+	const struct rte_afu_id *afu_id1)
+{
+	if ((afu_id0->pci_addr.bus       == afu_id1->pci_addr.bus) &&
+		(afu_id0->pci_addr.devid     == afu_id1->pci_addr.devid) &&
+		(afu_id0->pci_addr.function  == afu_id1->pci_addr.function) &&
+		(afu_id0->uuid_low           == afu_id1->uuid_low) &&
+		(afu_id0->uuid_high          == afu_id1->uuid_high) &&
+		(afu_id0->port               == afu_id1->port)) {
+		return 0;
+	} else
+		return 1;
+}
+int ifpga_pci_addr_cmp(const struct rte_device *dev,
+	const void *_pci_addr)
+{
+	struct rte_pci_device *pdev;
+	const struct rte_pci_addr *paddr = _pci_addr;
+
+	pdev = RTE_DEV_TO_PCI(*(struct rte_device **)(void *)&dev);
+	return rte_eal_compare_pci_addr(&pdev->addr, paddr);
+}
diff --git a/drivers/bus/ifpga/ifpga_common.h b/drivers/bus/ifpga/ifpga_common.h
new file mode 100644
index 0000000..1c85bd3
--- /dev/null
+++ b/drivers/bus/ifpga/ifpga_common.h
@@ -0,0 +1,22 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _IFPGA_COMMON_H_
+#define _IFPGA_COMMON_H_
+
+int ifpga_get_string_arg(const char *key __rte_unused,
+	const char *value, void *extra_args);
+int 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_get_bdf_arg(const char *key __rte_unused,
+	const char *value, void *extra_args);
+int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0,
+	const struct rte_afu_id *afu_id1);
+int ifpga_pci_addr_cmp(const struct rte_device *dev,
+	const void *_pci_addr);
+
+#endif /* _IFPGA_COMMON_H_ */
diff --git a/drivers/bus/ifpga/ifpga_logs.h b/drivers/bus/ifpga/ifpga_logs.h
new file mode 100644
index 0000000..873e0a4
--- /dev/null
+++ b/drivers/bus/ifpga/ifpga_logs.h
@@ -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_ */
diff --git a/drivers/bus/ifpga/rte_bus_ifpga.h b/drivers/bus/ifpga/rte_bus_ifpga.h
new file mode 100644
index 0000000..e22ab4e
--- /dev/null
+++ b/drivers/bus/ifpga/rte_bus_ifpga.h
@@ -0,0 +1,175 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _RTE_BUS_IFPGA_H_
+#define _RTE_BUS_IFPGA_H_
+
+/**
+ * @file
+ *
+ * RTE PCI 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_ifpga_device;
+struct rte_afu_device;
+struct rte_afu_driver;
+
+/** List of Intel FPGA devices */
+TAILQ_HEAD(rte_ifpga_device_list, rte_ifpga_device);
+/** List of Intel AFU devices */
+TAILQ_HEAD(rte_afu_device_list, rte_afu_device);
+/** List of AFU drivers */
+TAILQ_HEAD(rte_afu_driver_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_pci_addr pci_addr;
+	uint64_t uuid_low;
+	uint64_t uuid_high;
+	int      port;
+} __attribute__ ((packed));
+
+/**
+ * A structure pr 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 fpga device.
+ */
+struct rte_ifpga_device {
+	TAILQ_ENTRY(rte_ifpga_device) next;       /**< Next in device list. */
+	struct rte_pci_addr pci_addr;
+	struct rte_rawdev *rdev;
+	struct rte_afu_device_list afu_list;  /**< List of AFU devices */
+};
+
+/**
+ * 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_ifpga_device *ifpga_dev;    /**< Point ifpga device */
+	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];
+						/**< PCI 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)
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (afu_probe_t)(struct rte_afu_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (afu_remove_t)(struct rte_afu_device *);
+
+/**
+ * A structure describing a PCI 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. */
+	uint32_t drv_flags;         /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the Intel FPGA bus
+ */
+struct rte_ifpga_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_ifpga_device_list ifpga_list;  /**< List of FPGA devices */
+	struct rte_afu_driver_list driver_list;  /**< List of FPGA drivers */
+};
+
+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;
+}
+
+extern struct rte_ifpga_bus rte_ifpga_bus;
+
+/**
+ * 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_ */
diff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map b/drivers/bus/ifpga/rte_bus_ifpga_version.map
new file mode 100644
index 0000000..4edc9c0
--- /dev/null
+++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map
@@ -0,0 +1,8 @@ 
+DPDK_18.05 {
+	global:
+
+    rte_ifpga_driver_register;
+    rte_ifpga_driver_unregister;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 3eb41d1..929c3d8 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -107,6 +107,8 @@  _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
 _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
+
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif