@@ -168,6 +168,11 @@ CONFIG_RTE_LIBRTE_COMMON_DPAAX=n
#
CONFIG_RTE_LIBRTE_IFPGA_BUS=y
+#
+# Compile the mdev bus
+#
+CONFIG_RTE_LIBRTE_MDEV_BUS=n
+
#
# Compile PCI bus driver
#
@@ -25,6 +25,7 @@ CONFIG_RTE_LIBRTE_AVP_PMD=y
CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD=y
CONFIG_RTE_LIBRTE_NFP_PMD=y
CONFIG_RTE_LIBRTE_POWER=y
+CONFIG_RTE_LIBRTE_MDEV_BUS=y
CONFIG_RTE_VIRTIO_USER=y
CONFIG_RTE_PROC_INFO=y
@@ -8,6 +8,7 @@ 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_MDEV_BUS) += mdev
DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev
DIRS-$(CONFIG_RTE_LIBRTE_VMBUS) += vmbus
new file mode 100644
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bus_mdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -I$(SRCDIR)
+
+# versioning export map
+EXPORT_MAP := rte_bus_mdev_version.map
+
+# library version
+LIBABIVER := 1
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_FREEBSD),)
+$(error "Mdev bus not implemented for BSD yet")
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/mdev/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)/eal
+
+LDLIBS += -lrte_eal
+
+include $(RTE_SDK)/drivers/bus/mdev/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_MDEV_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_MDEV_BUS) += mdev.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_MDEV_BUS)-include += rte_bus_mdev.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
new file mode 100644
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+SRCS += mdev.c
+
+CFLAGS += -D_GNU_SOURCE
new file mode 100644
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus_mdev.h>
+
+#include "eal_filesystem.h"
+
+#include "private.h"
+
+static int
+mdev_scan_one(const char *dirname, const rte_uuid_t addr)
+{
+ struct rte_mdev_device *mdev;
+ char device_api[PATH_MAX];
+ char filename[PATH_MAX];
+ char *ptr;
+
+ mdev = malloc(sizeof(*mdev));
+ if (mdev == NULL)
+ return -1;
+
+ memset(mdev, 0, sizeof(*mdev));
+ mdev->device.bus = &rte_mdev_bus.bus;
+ rte_uuid_copy(mdev->addr, addr);
+
+ /* get device_api */
+ snprintf(filename, sizeof(filename), "%s/mdev_type/device_api",
+ dirname);
+ if (rte_eal_parse_sysfs_str(filename, device_api,
+ sizeof(device_api)) < 0) {
+ free(mdev);
+ return -1;
+ }
+
+ ptr = strchr(device_api, '\n');
+ if (ptr != NULL)
+ *ptr = '\0';
+
+ mdev_name_set(mdev);
+
+ if (strcmp(device_api, "vfio-pci") == 0) {
+ /* device api */
+ mdev->dev_api = RTE_MDEV_DEV_API_VFIO_PCI;
+
+ if (TAILQ_EMPTY(&rte_mdev_bus.device_list))
+ rte_mdev_add_device(mdev);
+ else {
+ struct rte_mdev_device *dev;
+ int ret;
+
+ TAILQ_FOREACH(dev, &rte_mdev_bus.device_list, next) {
+ ret = rte_uuid_compare(mdev->addr, dev->addr);
+ if (ret > 0)
+ continue;
+
+ if (ret < 0)
+ rte_mdev_insert_device(dev, mdev);
+ else /* already registered */
+ free(mdev);
+
+ return 0;
+ }
+
+ rte_mdev_add_device(mdev);
+ }
+ } else {
+ RTE_LOG(DEBUG, EAL, "%s(): mdev device_api %s is not supported\n",
+ __func__, device_api);
+ }
+
+ return 0;
+}
+
+/*
+ * Scan the content of the mdev bus, and the devices in the devices
+ * list
+ */
+int
+rte_mdev_scan(void)
+{
+ struct dirent *e;
+ DIR *dir;
+ char dirname[PATH_MAX];
+ rte_uuid_t addr;
+
+ dir = opendir(rte_mdev_get_sysfs_path());
+ if (dir == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ while ((e = readdir(dir)) != NULL) {
+ if (e->d_name[0] == '.')
+ continue;
+
+ if (rte_uuid_parse(e->d_name, addr) != 0)
+ continue;
+
+ snprintf(dirname, sizeof(dirname), "%s/%s",
+ rte_mdev_get_sysfs_path(), e->d_name);
+
+ if (mdev_scan_one(dirname, addr) < 0)
+ goto error;
+ }
+ closedir(dir);
+ return 0;
+
+error:
+ closedir(dir);
+ return -1;
+}
new file mode 100644
@@ -0,0 +1,310 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 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 <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_uuid.h>
+#include <rte_bus_mdev.h>
+
+#include "private.h"
+
+#define SYSFS_MDEV_DEVICES "/sys/bus/mdev/devices"
+
+const char *rte_mdev_get_sysfs_path(void)
+{
+ const char *path = NULL;
+
+ path = getenv("SYSFS_MDEV_DEVICES");
+ if (path == NULL)
+ return SYSFS_MDEV_DEVICES;
+
+ return path;
+}
+
+static void
+rte_mdev_device_name(const rte_uuid_t addr, char *output, size_t size)
+{
+ RTE_VERIFY(size >= RTE_UUID_STRLEN);
+ rte_uuid_unparse(addr, output, size);
+}
+
+static struct rte_devargs *
+mdev_devargs_lookup(struct rte_mdev_device *dev)
+{
+ struct rte_devargs *devargs;
+ rte_uuid_t addr;
+
+ RTE_EAL_DEVARGS_FOREACH("mdev", devargs) {
+ devargs->bus->parse(devargs->name, addr);
+ if (!rte_uuid_compare(dev->addr, addr))
+ return devargs;
+ }
+ return NULL;
+}
+
+void
+mdev_name_set(struct rte_mdev_device *dev)
+{
+ struct rte_devargs *devargs;
+
+ /* Each device has its internal, canonical name set. */
+ rte_mdev_device_name(dev->addr, dev->name, sizeof(dev->name));
+ devargs = mdev_devargs_lookup(dev);
+ dev->device.devargs = devargs;
+ /* In blacklist mode, if the device is not blacklisted, no
+ * rte_devargs exists for it.
+ */
+ if (devargs != NULL)
+ /* If an rte_devargs exists, the generic rte_device uses the
+ * given name as its name.
+ */
+ dev->device.name = dev->device.devargs->name;
+ else
+ /* Otherwise, it uses the internal, canonical form. */
+ dev->device.name = dev->name;
+}
+
+void
+rte_mdev_register(struct rte_mdev_driver *driver)
+{
+ TAILQ_INSERT_TAIL(&rte_mdev_bus.driver_list, driver, next);
+ driver->bus = &rte_mdev_bus;
+}
+
+void
+rte_mdev_unregister(struct rte_mdev_driver *driver)
+{
+ TAILQ_REMOVE(&rte_mdev_bus.driver_list, driver, next);
+ driver->bus = NULL;
+}
+
+void
+rte_mdev_add_device(struct rte_mdev_device *mdev)
+{
+ TAILQ_INSERT_TAIL(&rte_mdev_bus.device_list, mdev, next);
+}
+
+void
+rte_mdev_insert_device(struct rte_mdev_device *exist_mdev,
+ struct rte_mdev_device *new_mdev)
+{
+ TAILQ_INSERT_BEFORE(exist_mdev, new_mdev, next);
+}
+
+void
+rte_mdev_remove_device(struct rte_mdev_device *mdev)
+{
+ TAILQ_REMOVE(&rte_mdev_bus.device_list, mdev, next);
+}
+
+static struct rte_device *
+mdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+ const void *data)
+{
+ const struct rte_mdev_device *pstart;
+ struct rte_mdev_device *pdev;
+
+ if (start != NULL) {
+ pstart = RTE_DEV_TO_MDEV_CONST(start);
+ pdev = TAILQ_NEXT(pstart, next);
+ } else {
+ pdev = TAILQ_FIRST(&rte_mdev_bus.device_list);
+ }
+ while (pdev != NULL) {
+ if (cmp(&pdev->device, data) == 0)
+ return &pdev->device;
+ pdev = TAILQ_NEXT(pdev, next);
+ }
+ return NULL;
+}
+
+int
+rte_mdev_match(const struct rte_mdev_driver *mdev_drv,
+ const struct rte_mdev_device *mdev_dev)
+{
+ if (mdev_drv->dev_api == mdev_dev->dev_api)
+ return 1;
+
+ return 0;
+}
+
+static int
+rte_mdev_probe_one_driver(struct rte_mdev_driver *dr,
+ struct rte_mdev_device *dev)
+{
+ int ret;
+
+ if (dr == NULL || dev == NULL)
+ return -EINVAL;
+
+ /* no initialization when blacklisted, return without error */
+ if (dev->device.devargs != NULL &&
+ dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
+ RTE_LOG(INFO, EAL, "Device is blacklisted, not initializing\n");
+ return 1;
+ }
+
+ /* The device is not blacklisted; Check if driver supports it */
+ if (!rte_mdev_match(dr, dev)) {
+ /* Match of device and driver failed */
+ return 1;
+ }
+
+ /* reference driver structure */
+ dev->driver = dr;
+
+ /* call the driver probe() function */
+ ret = dr->probe(dr, dev);
+ if (ret != 0)
+ dev->driver = NULL;
+
+ return ret;
+}
+
+static int
+mdev_probe_all_drivers(struct rte_mdev_device *dev)
+{
+ struct rte_mdev_driver *dr = NULL;
+ int rc = 0;
+
+ if (dev == NULL)
+ return -1;
+
+ /* Check if a driver is already loaded */
+ if (dev->driver != NULL)
+ return 0;
+
+ FOREACH_DRIVER_ON_MDEV_BUS(dr) {
+ rc = rte_mdev_probe_one_driver(dr, 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;
+}
+
+int
+rte_mdev_probe(void)
+{
+ struct rte_mdev_device *mdev = NULL;
+ size_t probed = 0, failed = 0;
+ struct rte_devargs *devargs;
+ int probe_all = 0;
+ int ret = 0;
+
+ if (rte_mdev_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+ probe_all = 1;
+
+ FOREACH_DEVICE_ON_MDEV_BUS(mdev) {
+ probed++;
+
+ devargs = mdev->device.devargs;
+ /* probe all or only whitelisted devices */
+ if (probe_all)
+ ret = mdev_probe_all_drivers(mdev);
+ else if (devargs != NULL &&
+ devargs->policy == RTE_DEV_WHITELISTED)
+ ret = mdev_probe_all_drivers(mdev);
+ if (ret < 0) {
+ char name[RTE_UUID_STRLEN];
+ rte_uuid_unparse(mdev->addr, name, sizeof(name));
+ RTE_LOG(ERR, EAL, "Requested device %s cannot be used\n",
+ name);
+ rte_errno = errno;
+ failed++;
+ ret = 0;
+ }
+ }
+
+ return (probed && probed == failed) ? -1 : 0;
+}
+
+static int
+mdev_plug(struct rte_device *dev)
+{
+ return mdev_probe_all_drivers(RTE_DEV_TO_MDEV(dev));
+}
+
+static int
+rte_mdev_detach_dev(struct rte_mdev_device *dev)
+{
+ struct rte_mdev_driver *dr;
+ int ret = 0;
+
+ if (dev == NULL)
+ return -EINVAL;
+
+ dr = dev->driver;
+
+ if (dr->remove) {
+ ret = dr->remove(dev);
+ if (ret != 0)
+ return ret;
+ }
+
+ /* clear driver structure */
+ dev->driver = NULL;
+
+ return 0;
+}
+
+static int
+mdev_unplug(struct rte_device *dev)
+{
+ struct rte_mdev_device *pmdev;
+ int ret;
+
+ pmdev = RTE_DEV_TO_MDEV(dev);
+ ret = rte_mdev_detach_dev(pmdev);
+ if (ret == 0) {
+ rte_mdev_remove_device(pmdev);
+ free(pmdev);
+ }
+ return ret;
+}
+
+static int
+mdev_parse(const char *name, void *addr)
+{
+ rte_uuid_t uuid;
+ int parse;
+
+ parse = (rte_uuid_parse(name, uuid) == 0);
+ if (parse && addr != NULL)
+ rte_uuid_copy(addr, uuid);
+ return parse == false;
+}
+
+struct rte_mdev_bus rte_mdev_bus = {
+ .bus = {
+ .scan = rte_mdev_scan,
+ .probe = rte_mdev_probe,
+ .find_device = mdev_find_device,
+ .plug = mdev_plug,
+ .unplug = mdev_unplug,
+ .parse = mdev_parse,
+ },
+ .device_list = TAILQ_HEAD_INITIALIZER(rte_mdev_bus.device_list),
+ .driver_list = TAILQ_HEAD_INITIALIZER(rte_mdev_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(mdev, rte_mdev_bus.bus);
new file mode 100644
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+version = 1
+allow_experimental_apis = true
+install_headers('rte_bus_mdev.h')
+sources = files('mdev.c')
+
+if host_machine.system() == 'linux'
+ sources += files('linux/mdev.c')
+ includes += include_directories('linux')
+ cflags += ['-D_GNU_SOURCE']
+else
+ build = false
+endif
new file mode 100644
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _MDEV_PRIVATE_H_
+#define _MDEV_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_bus_mdev.h>
+
+struct rte_mdev_driver;
+struct rte_mdev_device;
+
+extern struct rte_mdev_bus rte_mdev_bus;
+
+/**
+ * Probe the mdev bus.
+ *
+ * @return
+ * - 0 on success.
+ * - !0 on error.
+ */
+int rte_mdev_probe(void);
+
+/**
+ * Scan the content of the mdev bus, and the devices in the devices
+ * list.
+ *
+ * @return
+ * 0 on success, negative on error
+ */
+int rte_mdev_scan(void);
+
+/**
+ * Set the name of a mdev device.
+ */
+void mdev_name_set(struct rte_mdev_device *dev);
+
+/**
+ * Add a mdev device to the mdev bus (append to mdev device list). This function
+ * also updates the bus references of the mdev device (and the generic device
+ * object embedded within.
+ *
+ * @param mdev
+ * mdev device to add
+ * @return void
+ */
+void rte_mdev_add_device(struct rte_mdev_device *mdev);
+
+/**
+ * Insert a mdev device in the mdev bus at a particular location in the device
+ * list. It also updates the mdev bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_mdev
+ * existing mdev device in mdev bus
+ * @param new_mdev
+ * mdev device to be added before exist_mdev
+ * @return void
+ */
+void rte_mdev_insert_device(struct rte_mdev_device *exist_mdev,
+ struct rte_mdev_device *new_mdev);
+
+/**
+ * Remove a mdev device from the mdev bus. This sets to NULL the bus references
+ * in the mdev device object as well as the generic device object.
+ *
+ * @param mdev_device
+ * mdev device to be removed from mdev bus
+ * @return void
+ */
+void rte_mdev_remove_device(struct rte_mdev_device *mdev_device);
+
+/**
+ * Match the mdev driver and device using mdev device_api.
+ *
+ * @param mdev_drv
+ * mdev driver from which device_api would be extracted
+ * @param mdev_dev
+ * mdev device to match against the driver
+ * @return
+ * 1 for successful match
+ * 0 for unsuccessful match
+ */
+int
+rte_mdev_match(const struct rte_mdev_driver *mdev_drv,
+ const struct rte_mdev_device *mdev_dev);
+
+#endif /* _MDEV_PRIVATE_H_ */
new file mode 100644
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _RTE_BUS_MDEV_H_
+#define _RTE_BUS_MDEV_H_
+
+/**
+ * @file
+ *
+ * RTE Mdev Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_uuid.h>
+#include <rte_bus.h>
+
+struct rte_devargs;
+
+enum rte_mdev_device_api {
+ RTE_MDEV_DEV_API_VFIO_PCI = 0,
+ RTE_MDEV_DEV_API_MAX,
+};
+
+struct rte_mdev_bus;
+struct rte_mdev_driver;
+struct rte_mdev_device;
+
+/** Pathname of mdev devices directory. */
+const char * __rte_experimental rte_mdev_get_sysfs_path(void);
+
+/**
+ * Register a mdev driver.
+ *
+ * @param driver
+ * A pointer to a rte_mdev_driver structure describing the driver
+ * to be registered.
+ */
+void __rte_experimental rte_mdev_register(struct rte_mdev_driver *driver);
+
+#define RTE_MDEV_REGISTER_DRIVER(nm, mdev_drv) \
+RTE_INIT(mdevinitfn_ ##nm) \
+{ \
+ (mdev_drv).driver.name = RTE_STR(nm); \
+ rte_mdev_register(&mdev_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a mdev driver.
+ *
+ * @param driver
+ * A pointer to a rte_mdev_driver structure describing the driver
+ * to be unregistered.
+ */
+void __rte_experimental rte_mdev_unregister(struct rte_mdev_driver *driver);
+
+/**
+ * Initialisation function for the driver called during mdev probing.
+ */
+typedef int (mdev_probe_t)(struct rte_mdev_driver *, struct rte_mdev_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (mdev_remove_t)(struct rte_mdev_device *);
+
+/**
+ * A structure describing a mdev driver.
+ */
+struct rte_mdev_driver {
+ TAILQ_ENTRY(rte_mdev_driver) next; /**< Next in list. */
+ struct rte_driver driver; /**< Inherit core driver. */
+ struct rte_mdev_bus *bus; /**< Mdev bus reference. */
+ mdev_probe_t *probe; /**< Device probe function. */
+ mdev_remove_t *remove; /**< Device remove function. */
+ enum rte_mdev_device_api dev_api; /**< Device API. */
+};
+
+/**
+ * A structure describing a mdev device.
+ */
+struct rte_mdev_device {
+ TAILQ_ENTRY(rte_mdev_device) next; /**< Next mdev device. */
+ struct rte_device device; /**< Inherit core device. */
+ enum rte_mdev_device_api dev_api; /**< Device API. */
+ struct rte_mdev_driver *driver; /**< Associated driver. */
+ rte_uuid_t addr; /**< Location. */
+ char name[RTE_UUID_STRLEN]; /**< Location (ASCII). */
+ void *private; /**< Driver-specific data. */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_mdev_device.
+ */
+#define RTE_DEV_TO_MDEV(ptr) container_of(ptr, struct rte_mdev_device, device)
+
+#define RTE_DEV_TO_MDEV_CONST(ptr) \
+ container_of(ptr, const struct rte_mdev_device, device)
+
+/** List of mdev devices */
+TAILQ_HEAD(rte_mdev_device_list, rte_mdev_device);
+/** List of mdev drivers */
+TAILQ_HEAD(rte_mdev_driver_list, rte_mdev_driver);
+
+/**
+ * Structure describing the mdev bus
+ */
+struct rte_mdev_bus {
+ struct rte_bus bus; /**< Inherit the generic class */
+ struct rte_mdev_device_list device_list; /**< List of mdev devices */
+ struct rte_mdev_driver_list driver_list; /**< List of mdev drivers */
+};
+
+/* Mdev Bus iterators */
+#define FOREACH_DEVICE_ON_MDEV_BUS(p) \
+ TAILQ_FOREACH(p, &(rte_mdev_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_MDEV_BUS(p) \
+ TAILQ_FOREACH(p, &(rte_mdev_bus.driver_list), next)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_MDEV_H_ */
new file mode 100644
@@ -0,0 +1,12 @@
+DPDK_19.05 {
+
+ local: *;
+};
+
+EXPERIMENTAL {
+ global:
+
+ rte_mdev_get_sysfs_path;
+ rte_mdev_register;
+ rte_mdev_unregister;
+};
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-drivers = ['dpaa', 'fslmc', 'ifpga', 'pci', 'vdev', 'vmbus']
+drivers = ['dpaa', 'fslmc', 'ifpga', 'mdev', 'pci', 'vdev', 'vmbus']
std_deps = ['eal']
config_flag_fmt = 'RTE_LIBRTE_@0@_BUS'
driver_name_fmt = 'rte_bus_@0@'
@@ -123,6 +123,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_FSLMC_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_COMMON_DPAAX) += -lrte_common_dpaax
endif
+_LDLIBS-$(CONFIG_RTE_LIBRTE_MDEV_BUS) += -lrte_bus_mdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += -lrte_bus_pci
_LDLIBS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += -lrte_bus_vdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += -lrte_bus_dpaa