}
struct ibv_device *
-mlx5_os_get_ibv_device(struct rte_pci_addr *addr)
+mlx5_os_get_ibv_device(const struct rte_pci_addr *addr)
{
int n;
struct ibv_device **ibv_list = mlx5_glue->get_device_list(&n);
__rte_internal
struct ibv_device *
-mlx5_os_get_ibv_device(struct rte_pci_addr *addr);
+mlx5_os_get_ibv_device(const struct rte_pci_addr *addr);
+
+__rte_internal
+struct ibv_device *
+mlx5_os_get_ibv_dev(const struct rte_device *dev);
#endif /* RTE_PMD_MLX5_COMMON_OS_H_ */
#include <sys/mman.h>
#include <inttypes.h>
+#include <rte_errno.h>
+#include <rte_bus_pci.h>
+
+#include "mlx5_common_utils.h"
+#include "mlx5_common_log.h"
+#include "mlx5_common_private.h"
#include "mlx5_autoconf.h"
#include <mlx5_glue.h>
#include <mlx5_common.h>
#include <mlx5_common_mr.h>
+struct ibv_device *
+mlx5_os_get_ibv_dev(const struct rte_device *dev)
+{
+ struct ibv_device *ibv = NULL;
+
+ if (mlx5_dev_is_pci(dev))
+ ibv = mlx5_os_get_ibv_device(&RTE_DEV_TO_PCI_CONST(dev)->addr);
+ if (ibv == NULL) {
+ rte_errno = ENODEV;
+ DRV_LOG(ERR, "Verbs device not found: %s", dev->name);
+ }
+ return ibv;
+}
+
/**
* Register mr. Given protection domain pointer, pointer to addr and length
* register the memory region.
memset(pmd_mr, 0, sizeof(*pmd_mr));
}
}
-
#include <rte_errno.h>
#include <rte_mempool.h>
+#include <rte_class.h>
+#include <rte_malloc.h>
#include "mlx5_common.h"
#include "mlx5_common_os.h"
#include "mlx5_common_log.h"
#include "mlx5_common_pci.h"
+#include "mlx5_common_private.h"
uint8_t haswell_broadwell_cpu;
RTE_LOG_REGISTER_DEFAULT(mlx5_common_logtype, NOTICE)
+/* Head of list of drivers. */
+static TAILQ_HEAD(mlx5_drivers, mlx5_class_driver) drivers_list =
+ TAILQ_HEAD_INITIALIZER(drivers_list);
+
+/* Head of devices. */
+static TAILQ_HEAD(mlx5_devices, mlx5_common_device) devices_list =
+ TAILQ_HEAD_INITIALIZER(devices_list);
+
+static const struct {
+ const char *name;
+ unsigned int drv_class;
+} mlx5_classes[] = {
+ { .name = "vdpa", .drv_class = MLX5_CLASS_VDPA },
+ { .name = "eth", .drv_class = MLX5_CLASS_ETH },
+ /* Keep class "net" for backward compatibility. */
+ { .name = "net", .drv_class = MLX5_CLASS_ETH },
+ { .name = "regex", .drv_class = MLX5_CLASS_REGEX },
+ { .name = "compress", .drv_class = MLX5_CLASS_COMPRESS },
+ { .name = "crypto", .drv_class = MLX5_CLASS_CRYPTO },
+};
+
+static int
+class_name_to_value(const char *class_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < RTE_DIM(mlx5_classes); i++) {
+ if (strcmp(class_name, mlx5_classes[i].name) == 0)
+ return mlx5_classes[i].drv_class;
+ }
+ return -EINVAL;
+}
+
+static struct mlx5_class_driver *
+driver_get(uint32_t class)
+{
+ struct mlx5_class_driver *driver;
+
+ TAILQ_FOREACH(driver, &drivers_list, next) {
+ if ((uint32_t)driver->drv_class == class)
+ return driver;
+ }
+ return NULL;
+}
+
+static int
+devargs_class_handler(__rte_unused const char *key,
+ const char *class_names, void *opaque)
+{
+ int *ret = opaque;
+ int class_val;
+ char *scratch;
+ char *found;
+ char *refstr = NULL;
+
+ *ret = 0;
+ scratch = strdup(class_names);
+ if (scratch == NULL) {
+ *ret = -ENOMEM;
+ return *ret;
+ }
+ found = strtok_r(scratch, ":", &refstr);
+ if (found == NULL)
+ /* Empty string. */
+ goto err;
+ do {
+ /* Extract each individual class name. Multiple
+ * classes can be supplied as class=net:regex:foo:bar.
+ */
+ class_val = class_name_to_value(found);
+ /* Check if its a valid class. */
+ if (class_val < 0) {
+ *ret = -EINVAL;
+ goto err;
+ }
+ *ret |= class_val;
+ found = strtok_r(NULL, ":", &refstr);
+ } while (found != NULL);
+err:
+ free(scratch);
+ if (*ret < 0)
+ DRV_LOG(ERR, "Invalid mlx5 class options: %s.\n", class_names);
+ return *ret;
+}
+
+static int
+parse_class_options(const struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvlist;
+ int ret = 0;
+
+ if (devargs == NULL)
+ return 0;
+ if (devargs->cls != NULL && devargs->cls->name != NULL)
+ /* Global syntax, only one class type. */
+ return class_name_to_value(devargs->cls->name);
+ /* Legacy devargs support multiple classes. */
+ kvlist = rte_kvargs_parse(devargs->args, NULL);
+ if (kvlist == NULL)
+ return 0;
+ rte_kvargs_process(kvlist, RTE_DEVARGS_KEY_CLASS,
+ devargs_class_handler, &ret);
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
+static const unsigned int mlx5_class_invalid_combinations[] = {
+ MLX5_CLASS_ETH | MLX5_CLASS_VDPA,
+ /* New class combination should be added here. */
+};
+
+static int
+is_valid_class_combination(uint32_t user_classes)
+{
+ unsigned int i;
+
+ /* Verify if user specified unsupported combination. */
+ for (i = 0; i < RTE_DIM(mlx5_class_invalid_combinations); i++) {
+ if ((mlx5_class_invalid_combinations[i] & user_classes) ==
+ mlx5_class_invalid_combinations[i])
+ return -EINVAL;
+ }
+ /* Not found any invalid class combination. */
+ return 0;
+}
+
+static bool
+device_class_enabled(const struct mlx5_common_device *device, uint32_t class)
+{
+ return (device->classes_loaded & class) > 0;
+}
+
+static bool
+mlx5_bus_match(const struct mlx5_class_driver *drv,
+ const struct rte_device *dev)
+{
+ if (mlx5_dev_is_pci(dev))
+ return mlx5_dev_pci_match(drv, dev);
+ return true;
+}
+
+static struct mlx5_common_device *
+to_mlx5_device(const struct rte_device *rte_dev)
+{
+ struct mlx5_common_device *dev;
+
+ TAILQ_FOREACH(dev, &devices_list, next) {
+ if (rte_dev == dev->dev)
+ return dev;
+ }
+ return NULL;
+}
+
+static void
+dev_release(struct mlx5_common_device *dev)
+{
+ TAILQ_REMOVE(&devices_list, dev, next);
+ rte_free(dev);
+}
+
+static int
+drivers_remove(struct mlx5_common_device *dev, uint32_t enabled_classes)
+{
+ struct mlx5_class_driver *driver;
+ int local_ret = -ENODEV;
+ unsigned int i = 0;
+ int ret = 0;
+
+ enabled_classes &= dev->classes_loaded;
+ while (enabled_classes) {
+ driver = driver_get(RTE_BIT64(i));
+ if (driver != NULL) {
+ local_ret = driver->remove(dev->dev);
+ if (local_ret == 0)
+ dev->classes_loaded &= ~RTE_BIT64(i);
+ else if (ret == 0)
+ ret = local_ret;
+ }
+ enabled_classes &= ~RTE_BIT64(i);
+ i++;
+ }
+ if (local_ret != 0 && ret == 0)
+ ret = local_ret;
+ return ret;
+}
+
+static int
+drivers_probe(struct mlx5_common_device *dev, uint32_t user_classes)
+{
+ struct mlx5_class_driver *driver;
+ uint32_t enabled_classes = 0;
+ bool already_loaded;
+ int ret;
+
+ TAILQ_FOREACH(driver, &drivers_list, next) {
+ if ((driver->drv_class & user_classes) == 0)
+ continue;
+ if (!mlx5_bus_match(driver, dev->dev))
+ continue;
+ already_loaded = dev->classes_loaded & driver->drv_class;
+ if (already_loaded && driver->probe_again == 0) {
+ DRV_LOG(ERR, "Device %s is already probed",
+ dev->dev->name);
+ ret = -EEXIST;
+ goto probe_err;
+ }
+ ret = driver->probe(dev->dev);
+ if (ret < 0) {
+ DRV_LOG(ERR, "Failed to load driver %s",
+ driver->name);
+ goto probe_err;
+ }
+ enabled_classes |= driver->drv_class;
+ }
+ dev->classes_loaded |= enabled_classes;
+ return 0;
+probe_err:
+ /* Only unload drivers which are enabled which were enabled
+ * in this probe instance.
+ */
+ drivers_remove(dev, enabled_classes);
+ return ret;
+}
+
+int
+mlx5_common_dev_probe(struct rte_device *eal_dev)
+{
+ struct mlx5_common_device *dev;
+ uint32_t classes = 0;
+ bool new_device = false;
+ int ret;
+
+ DRV_LOG(INFO, "probe device \"%s\".", eal_dev->name);
+ ret = parse_class_options(eal_dev->devargs);
+ if (ret < 0) {
+ DRV_LOG(ERR, "Unsupported mlx5 class type: %s",
+ eal_dev->devargs->args);
+ return ret;
+ }
+ classes = ret;
+ if (classes == 0)
+ /* Default to net class. */
+ classes = MLX5_CLASS_ETH;
+ dev = to_mlx5_device(eal_dev);
+ if (!dev) {
+ dev = rte_zmalloc("mlx5_common_device", sizeof(*dev), 0);
+ if (!dev)
+ return -ENOMEM;
+ dev->dev = eal_dev;
+ TAILQ_INSERT_HEAD(&devices_list, dev, next);
+ new_device = true;
+ } else {
+ /* Validate combination here. */
+ ret = is_valid_class_combination(classes |
+ dev->classes_loaded);
+ if (ret != 0) {
+ DRV_LOG(ERR, "Unsupported mlx5 classes combination.");
+ return ret;
+ }
+ }
+ ret = drivers_probe(dev, classes);
+ if (ret)
+ goto class_err;
+ return 0;
+class_err:
+ if (new_device)
+ dev_release(dev);
+ return ret;
+}
+
+int
+mlx5_common_dev_remove(struct rte_device *eal_dev)
+{
+ struct mlx5_common_device *dev;
+ int ret;
+
+ dev = to_mlx5_device(eal_dev);
+ if (!dev)
+ return -ENODEV;
+ /* Matching device found, cleanup and unload drivers. */
+ ret = drivers_remove(dev, dev->classes_loaded);
+ if (ret != 0)
+ dev_release(dev);
+ return ret;
+}
+
+int
+mlx5_common_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova,
+ size_t len)
+{
+ struct mlx5_class_driver *driver = NULL;
+ struct mlx5_class_driver *temp;
+ struct mlx5_common_device *mdev;
+ int ret = -EINVAL;
+
+ mdev = to_mlx5_device(dev);
+ if (!mdev)
+ return -ENODEV;
+ TAILQ_FOREACH(driver, &drivers_list, next) {
+ if (!device_class_enabled(mdev, driver->drv_class) ||
+ driver->dma_map == NULL)
+ continue;
+ ret = driver->dma_map(dev, addr, iova, len);
+ if (ret)
+ goto map_err;
+ }
+ return ret;
+map_err:
+ TAILQ_FOREACH(temp, &drivers_list, next) {
+ if (temp == driver)
+ break;
+ if (device_class_enabled(mdev, temp->drv_class) &&
+ temp->dma_map && temp->dma_unmap)
+ temp->dma_unmap(dev, addr, iova, len);
+ }
+ return ret;
+}
+
+int
+mlx5_common_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
+ size_t len)
+{
+ struct mlx5_class_driver *driver;
+ struct mlx5_common_device *mdev;
+ int local_ret = -EINVAL;
+ int ret = 0;
+
+ mdev = to_mlx5_device(dev);
+ if (!mdev)
+ return -ENODEV;
+ /* There is no unmap error recovery in current implementation. */
+ TAILQ_FOREACH_REVERSE(driver, &drivers_list, mlx5_drivers, next) {
+ if (!device_class_enabled(mdev, driver->drv_class) ||
+ driver->dma_unmap == NULL)
+ continue;
+ local_ret = driver->dma_unmap(dev, addr, iova, len);
+ if (local_ret && (ret == 0))
+ ret = local_ret;
+ }
+ if (local_ret)
+ ret = local_ret;
+ return ret;
+}
+
+void
+mlx5_class_driver_register(struct mlx5_class_driver *driver)
+{
+ mlx5_common_driver_on_register_pci(driver);
+ TAILQ_INSERT_TAIL(&drivers_list, driver, next);
+}
+
+static void mlx5_common_driver_init(void)
+{
+ mlx5_common_pci_init();
+}
+
static bool mlx5_common_initialized;
/**
return;
mlx5_glue_constructor();
- mlx5_common_pci_init();
+ mlx5_common_driver_init();
mlx5_common_initialized = true;
}
exit:
return uar;
}
+
+RTE_PMD_EXPORT_NAME(mlx5_common_driver, __COUNTER__);
__rte_internal
void mlx5_common_init(void);
+/*
+ * Common Driver Interface
+ *
+ * ConnectX common driver supports multiple classes: net, vDPA, regex, crypto
+ * and compress devices. This layer enables creating such multiple classes
+ * on a single device by allowing to bind multiple class-specific device
+ * drivers to attach to the common driver.
+ *
+ * ------------ ------------- -------------- ----------------- ------------
+ * | mlx5 net | | mlx5 vdpa | | mlx5 regex | | mlx5 compress | | mlx5 ... |
+ * | driver | | driver | | driver | | driver | | drivers |
+ * ------------ ------------- -------------- ----------------- ------------
+ * ||
+ * -----------------
+ * | mlx5 |
+ * | common driver |
+ * -----------------
+ * | |
+ * ----------- -----------------
+ * | mlx5 | | mlx5 |
+ * | pci dev | | auxiliary dev |
+ * ----------- -----------------
+ *
+ * - mlx5 PCI bus driver binds to mlx5 PCI devices defined by PCI ID table
+ * of all related devices.
+ * - mlx5 class driver such as net, vDPA, regex defines its specific
+ * PCI ID table and mlx5 bus driver probes matching class drivers.
+ * - mlx5 common driver is central place that validates supported
+ * class combinations.
+ * - mlx5 common driver hides bus difference by resolving device address
+ * from devargs, locating target RDMA device and probing with it.
+ */
+
+/**
+ * Initialization function for the driver called during device probing.
+ */
+typedef int (mlx5_class_driver_probe_t)(struct rte_device *dev);
+
+/**
+ * Uninitialization function for the driver called during hot-unplugging.
+ */
+typedef int (mlx5_class_driver_remove_t)(struct rte_device *dev);
+
+/**
+ * Driver-specific DMA mapping. After a successful call the device
+ * will be able to read/write from/to this segment.
+ *
+ * @param dev
+ * Pointer to the device.
+ * @param addr
+ * Starting virtual address of memory to be mapped.
+ * @param iova
+ * Starting IOVA address of memory to be mapped.
+ * @param len
+ * Length of memory segment being mapped.
+ * @return
+ * - 0 On success.
+ * - Negative value and rte_errno is set otherwise.
+ */
+typedef int (mlx5_class_driver_dma_map_t)(struct rte_device *dev, void *addr,
+ uint64_t iova, size_t len);
+
+/**
+ * Driver-specific DMA un-mapping. After a successful call the device
+ * will not be able to read/write from/to this segment.
+ *
+ * @param dev
+ * Pointer to the device.
+ * @param addr
+ * Starting virtual address of memory to be unmapped.
+ * @param iova
+ * Starting IOVA address of memory to be unmapped.
+ * @param len
+ * Length of memory segment being unmapped.
+ * @return
+ * - 0 On success.
+ * - Negative value and rte_errno is set otherwise.
+ */
+typedef int (mlx5_class_driver_dma_unmap_t)(struct rte_device *dev, void *addr,
+ uint64_t iova, size_t len);
+
+/** Device already probed can be probed again to check for new ports. */
+#define MLX5_DRV_PROBE_AGAIN 0x0004
+
+/**
+ * A structure describing a mlx5 common class driver.
+ */
+struct mlx5_class_driver {
+ TAILQ_ENTRY(mlx5_class_driver) next;
+ enum mlx5_class drv_class; /**< Class of this driver. */
+ const char *name; /**< Driver name. */
+ mlx5_class_driver_probe_t *probe; /**< Device probe function. */
+ mlx5_class_driver_remove_t *remove; /**< Device remove function. */
+ mlx5_class_driver_dma_map_t *dma_map; /**< Device DMA map function. */
+ mlx5_class_driver_dma_unmap_t *dma_unmap;
+ /**< Device DMA unmap function. */
+ const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+ uint32_t probe_again:1;
+ /**< Device already probed can be probed again to check new device. */
+ uint32_t intr_lsc:1; /**< Supports link state interrupt. */
+ uint32_t intr_rmv:1; /**< Supports device remove interrupt. */
+};
+
+/**
+ * Register a mlx5 device driver.
+ *
+ * @param driver
+ * A pointer to a mlx5_driver structure describing the driver
+ * to be registered.
+ */
+__rte_internal
+void
+mlx5_class_driver_register(struct mlx5_class_driver *driver);
+
+/**
+ * Test device is a PCI bus device.
+ *
+ * @param dev
+ * Pointer to device.
+ *
+ * @return
+ * - True on device devargs is a PCI bus device.
+ * - False otherwise.
+ */
+__rte_internal
+bool
+mlx5_dev_is_pci(const struct rte_device *dev);
+
#endif /* RTE_PMD_MLX5_COMMON_H_ */
*/
#include <stdlib.h>
+
#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_errno.h>
#include <rte_class.h>
#include "mlx5_common_log.h"
#include "mlx5_common_pci.h"
+#include "mlx5_common_private.h"
+
+static struct rte_pci_driver mlx5_common_pci_driver;
+
+/********** Legacy PCI bus driver, to be removed ********/
struct mlx5_pci_device {
struct rte_pci_device *pci_dev;
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
-mlx5_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
- struct rte_pci_device *pci_dev)
+mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
{
struct mlx5_pci_device *dev;
uint32_t user_classes = 0;
* 0 on success, the function cannot fail.
*/
static int
-mlx5_common_pci_remove(struct rte_pci_device *pci_dev)
+mlx5_pci_remove(struct rte_pci_device *pci_dev)
{
struct mlx5_pci_device *dev;
int ret;
}
static int
-mlx5_common_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,
- uint64_t iova, size_t len)
+mlx5_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,
+ uint64_t iova, size_t len)
{
struct mlx5_pci_driver *driver = NULL;
struct mlx5_pci_driver *temp;
}
static int
-mlx5_common_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,
- uint64_t iova, size_t len)
+mlx5_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,
+ uint64_t iova, size_t len)
{
struct mlx5_pci_driver *driver;
struct mlx5_pci_device *dev;
.driver = {
.name = MLX5_PCI_DRIVER_NAME,
},
- .probe = mlx5_common_pci_probe,
- .remove = mlx5_common_pci_remove,
- .dma_map = mlx5_common_pci_dma_map,
- .dma_unmap = mlx5_common_pci_dma_unmap,
+ .probe = mlx5_pci_probe,
+ .remove = mlx5_pci_remove,
+ .dma_map = mlx5_pci_dma_map,
+ .dma_unmap = mlx5_pci_dma_unmap,
};
static int
updated_table = calloc(num_ids, sizeof(*updated_table));
if (!updated_table)
return -ENOMEM;
- if (TAILQ_EMPTY(&drv_list)) {
+ if (old_table == NULL) {
/* Copy the first driver's ID table. */
for (id_iter = driver_id_table; id_iter->vendor_id != 0;
id_iter++, i++)
/* Terminate table with empty entry. */
updated_table[i].vendor_id = 0;
mlx5_pci_driver.id_table = updated_table;
+ mlx5_common_pci_driver.id_table = updated_table;
mlx5_pci_id_table = updated_table;
if (old_table)
free(old_table);
TAILQ_INSERT_TAIL(&drv_list, driver, next);
}
+/********** New common PCI bus driver ********/
+
+bool
+mlx5_dev_is_pci(const struct rte_device *dev)
+{
+ return strcmp(dev->bus->name, "pci") == 0;
+}
+
+bool
+mlx5_dev_pci_match(const struct mlx5_class_driver *drv,
+ const struct rte_device *dev)
+{
+ const struct rte_pci_device *pci_dev;
+ const struct rte_pci_id *id_table;
+
+ if (!mlx5_dev_is_pci(dev))
+ return false;
+ pci_dev = RTE_DEV_TO_PCI_CONST(dev);
+ for (id_table = drv->id_table; id_table->vendor_id != 0;
+ id_table++) {
+ /* Check if device's ids match the class driver's ids. */
+ if (id_table->vendor_id != pci_dev->id.vendor_id &&
+ id_table->vendor_id != RTE_PCI_ANY_ID)
+ continue;
+ if (id_table->device_id != pci_dev->id.device_id &&
+ id_table->device_id != RTE_PCI_ANY_ID)
+ continue;
+ if (id_table->subsystem_vendor_id !=
+ pci_dev->id.subsystem_vendor_id &&
+ id_table->subsystem_vendor_id != RTE_PCI_ANY_ID)
+ continue;
+ if (id_table->subsystem_device_id !=
+ pci_dev->id.subsystem_device_id &&
+ id_table->subsystem_device_id != RTE_PCI_ANY_ID)
+ continue;
+ if (id_table->class_id != pci_dev->id.class_id &&
+ id_table->class_id != RTE_CLASS_ANY_ID)
+ continue;
+ return true;
+ }
+ return false;
+}
+
+static int
+mlx5_common_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return mlx5_common_dev_probe(&pci_dev->device);
+}
+
+static int
+mlx5_common_pci_remove(struct rte_pci_device *pci_dev)
+{
+ return mlx5_common_dev_remove(&pci_dev->device);
+}
+
+static int
+mlx5_common_pci_dma_map(struct rte_pci_device *pci_dev, void *addr,
+ uint64_t iova, size_t len)
+{
+ return mlx5_common_dev_dma_map(&pci_dev->device, addr, iova, len);
+}
+
+static int
+mlx5_common_pci_dma_unmap(struct rte_pci_device *pci_dev, void *addr,
+ uint64_t iova, size_t len)
+{
+ return mlx5_common_dev_dma_unmap(&pci_dev->device, addr, iova, len);
+}
+
+void
+mlx5_common_driver_on_register_pci(struct mlx5_class_driver *driver)
+{
+ if (driver->id_table != NULL) {
+ if (pci_ids_table_update(driver->id_table) != 0)
+ return;
+ }
+ if (driver->probe_again)
+ mlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_PROBE_AGAIN;
+ if (driver->intr_lsc)
+ mlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_INTR_LSC;
+ if (driver->intr_rmv)
+ mlx5_common_pci_driver.drv_flags |= RTE_PCI_DRV_INTR_RMV;
+}
+
+static struct rte_pci_driver mlx5_common_pci_driver = {
+ .driver = {
+ .name = MLX5_PCI_DRIVER_NAME,
+ },
+ .probe = mlx5_common_pci_probe,
+ .remove = mlx5_common_pci_remove,
+ .dma_map = mlx5_common_pci_dma_map,
+ .dma_unmap = mlx5_common_pci_dma_unmap,
+};
+
void mlx5_common_pci_init(void)
{
const struct rte_pci_id empty_table[] = {
*/
if (mlx5_pci_id_table == NULL && pci_ids_table_update(empty_table))
return;
- rte_pci_register(&mlx5_pci_driver);
+ rte_pci_register(&mlx5_common_pci_driver);
}
RTE_FINI(mlx5_common_pci_finish)
/* Constructor doesn't register with PCI bus if it failed
* to build the table.
*/
- rte_pci_unregister(&mlx5_pci_driver);
+ rte_pci_unregister(&mlx5_common_pci_driver);
free(mlx5_pci_id_table);
}
}
+
RTE_PMD_EXPORT_NAME(mlx5_common_pci, __COUNTER__);
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef MLX5_COMMON_PRIVATE_H
+#define MLX5_COMMON_PRIVATE_H
+
+#include <rte_pci.h>
+
+#include "mlx5_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Common bus driver: */
+
+struct mlx5_common_device {
+ struct rte_device *dev;
+ TAILQ_ENTRY(mlx5_common_device) next;
+ uint32_t classes_loaded;
+};
+
+int mlx5_common_dev_probe(struct rte_device *eal_dev);
+int mlx5_common_dev_remove(struct rte_device *eal_dev);
+int mlx5_common_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova,
+ size_t len);
+int mlx5_common_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
+ size_t len);
+
+/* Common PCI bus driver: */
+
+void mlx5_common_driver_on_register_pci(struct mlx5_class_driver *driver);
+bool mlx5_dev_pci_match(const struct mlx5_class_driver *drv,
+ const struct rte_device *dev);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* MLX5_COMMON_PRIVATE_H */
#ifndef RTE_PMD_MLX5_COMMON_UTILS_H_
#define RTE_PMD_MLX5_COMMON_UTILS_H_
+#include <rte_rwlock.h>
+
#include "mlx5_common.h"
/************************ mlx5 list *****************************/
haswell_broadwell_cpu;
+ mlx5_class_driver_register;
+
mlx5_common_init;
mlx5_common_verbs_reg_mr; # WINDOWS_NO_EXPORT
mlx5_create_mr_ext;
+ mlx5_dev_is_pci;
mlx5_dev_to_pci_addr; # WINDOWS_NO_EXPORT
mlx5_devx_alloc_uar; # WINDOWS_NO_EXPORT
mlx5_os_alloc_pd;
mlx5_os_dealloc_pd;
mlx5_os_dereg_mr;
+ mlx5_os_get_ibv_dev; # WINDOWS_NO_EXPORT
mlx5_os_get_ibv_device; # WINDOWS_NO_EXPORT
mlx5_os_reg_mr;
mlx5_os_umem_dereg;