diff --git a/lib/env_dpdk/22.11/bus_driver.h b/lib/env_dpdk/22.11/bus_driver.h new file mode 100644 index 000000000..b5295776b --- /dev/null +++ b/lib/env_dpdk/22.11/bus_driver.h @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Red Hat, Inc. + */ + +#ifndef BUS_DRIVER_H +#define BUS_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rte_bus.h" +#include +#include "rte_dev.h" +#include +#include + +struct rte_devargs; +struct rte_device; + +/** Double linked list of buses */ +RTE_TAILQ_HEAD(rte_bus_list, rte_bus); + +/** + * Bus specific scan for devices attached on the bus. + * For each bus object, the scan would be responsible for finding devices and + * adding them to its private device list. + * + * A bus should mandatorily implement this method. + * + * @return + * 0 for successful scan + * <0 for unsuccessful scan with error value + */ +typedef int (*rte_bus_scan_t)(void); + +/** + * Implementation specific probe function which is responsible for linking + * devices on that bus with applicable drivers. + * + * This is called while iterating over each registered bus. + * + * @return + * 0 for successful probe + * !0 for any error while probing + */ +typedef int (*rte_bus_probe_t)(void); + +/** + * Device iterator to find a device on a bus. + * + * This function returns an rte_device if one of those held by the bus + * matches the data passed as parameter. + * + * If the comparison function returns zero this function should stop iterating + * over any more devices. To continue a search the device of a previous search + * can be passed via the start parameter. + * + * @param cmp + * Comparison function. + * + * @param data + * Data to compare each device against. + * + * @param start + * starting point for the iteration + * + * @return + * The first device matching the data, NULL if none exists. + */ +typedef struct rte_device * +(*rte_bus_find_device_t)(const struct rte_device *start, rte_dev_cmp_t cmp, + const void *data); + +/** + * Implementation specific probe function which is responsible for linking + * devices on that bus with applicable drivers. + * + * @param dev + * Device pointer that was returned by a previous call to find_device. + * + * @return + * 0 on success. + * !0 on error. + */ +typedef int (*rte_bus_plug_t)(struct rte_device *dev); + +/** + * Implementation specific remove function which is responsible for unlinking + * devices on that bus from assigned driver. + * + * @param dev + * Device pointer that was returned by a previous call to find_device. + * + * @return + * 0 on success. + * !0 on error. + */ +typedef int (*rte_bus_unplug_t)(struct rte_device *dev); + +/** + * Bus specific parsing function. + * Validates the syntax used in the textual representation of a device, + * If the syntax is valid and ``addr`` is not NULL, writes the bus-specific + * device representation to ``addr``. + * + * @param[in] name + * device textual description + * + * @param[out] addr + * device information location address, into which parsed info + * should be written. If NULL, nothing should be written, which + * is not an error. + * + * @return + * 0 if parsing was successful. + * !0 for any error. + */ +typedef int (*rte_bus_parse_t)(const char *name, void *addr); + +/** + * Parse bus part of the device arguments. + * + * The field name of the struct rte_devargs will be set. + * + * @param da + * Pointer to the devargs to parse. + * + * @return + * 0 on successful parsing, otherwise rte_errno is set. + * -EINVAL: on parsing error. + * -ENODEV: if no key matching a device argument is specified. + * -E2BIG: device name is too long. + */ +typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da); + +/** + * Device level DMA map function. + * After a successful call, the memory segment will be mapped to the + * given device. + * + * @param dev + * Device pointer. + * @param addr + * Virtual address to map. + * @param iova + * IOVA address to map. + * @param len + * Length of the memory segment being mapped. + * + * @return + * 0 if mapping was successful. + * Negative value and rte_errno is set otherwise. + */ +typedef int (*rte_dev_dma_map_t)(struct rte_device *dev, void *addr, + uint64_t iova, size_t len); + +/** + * Device level DMA unmap function. + * After a successful call, the memory segment will no longer be + * accessible by the given device. + * + * @param dev + * Device pointer. + * @param addr + * Virtual address to unmap. + * @param iova + * IOVA address to unmap. + * @param len + * Length of the memory segment being mapped. + * + * @return + * 0 if un-mapping was successful. + * Negative value and rte_errno is set otherwise. + */ +typedef int (*rte_dev_dma_unmap_t)(struct rte_device *dev, void *addr, + uint64_t iova, size_t len); + +/** + * Implement a specific hot-unplug handler, which is responsible for + * handle the failure when device be hot-unplugged. When the event of + * hot-unplug be detected, it could call this function to handle + * the hot-unplug failure and avoid app crash. + * @param dev + * Pointer of the device structure. + * + * @return + * 0 on success. + * !0 on error. + */ +typedef int (*rte_bus_hot_unplug_handler_t)(struct rte_device *dev); + +/** + * Implement a specific sigbus handler, which is responsible for handling + * the sigbus error which is either original memory error, or specific memory + * error that caused of device be hot-unplugged. When sigbus error be captured, + * it could call this function to handle sigbus error. + * @param failure_addr + * Pointer of the fault address of the sigbus error. + * + * @return + * 0 for success handle the sigbus for hot-unplug. + * 1 for not process it, because it is a generic sigbus error. + * -1 for failed to handle the sigbus for hot-unplug. + */ +typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr); + +/** + * Implementation specific cleanup function which is responsible for cleaning up + * devices on that bus with applicable drivers. + * + * This is called while iterating over each registered bus. + * + * @return + * 0 for successful cleanup + * !0 for any error during cleanup + */ +typedef int (*rte_bus_cleanup_t)(void); + +/** + * Bus scan policies + */ +enum rte_bus_scan_mode { + RTE_BUS_SCAN_UNDEFINED, + RTE_BUS_SCAN_ALLOWLIST, + RTE_BUS_SCAN_BLOCKLIST, +}; + +/** + * A structure used to configure bus operations. + */ +struct rte_bus_conf { + enum rte_bus_scan_mode scan_mode; /**< Scan policy. */ +}; + + +/** + * Get common iommu class of the all the devices on the bus. The bus may + * check that those devices are attached to iommu driver. + * If no devices are attached to the bus. The bus may return with don't care + * (_DC) value. + * Otherwise, The bus will return appropriate _pa or _va iova mode. + * + * @return + * enum rte_iova_mode value. + */ +typedef enum rte_iova_mode (*rte_bus_get_iommu_class_t)(void); + +/** + * A structure describing a generic bus. + */ +struct rte_bus { + RTE_TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */ + const char *name; /**< Name of the bus */ + rte_bus_scan_t scan; /**< Scan for devices attached to bus */ + rte_bus_probe_t probe; /**< Probe devices on bus */ + rte_bus_find_device_t find_device; /**< Find a device on the bus */ + rte_bus_plug_t plug; /**< Probe single device for drivers */ + rte_bus_unplug_t unplug; /**< Remove single device from driver */ + rte_bus_parse_t parse; /**< Parse a device name */ + rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */ + rte_dev_dma_map_t dma_map; /**< DMA map for device in the bus */ + rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */ + struct rte_bus_conf conf; /**< Bus configuration */ + rte_bus_get_iommu_class_t get_iommu_class; /**< Get iommu class */ + rte_dev_iterate_t dev_iterate; /**< Device iterator. */ + rte_bus_hot_unplug_handler_t hot_unplug_handler; + /**< handle hot-unplug failure on the bus */ + rte_bus_sigbus_handler_t sigbus_handler; + /**< handle sigbus error on the bus */ + rte_bus_cleanup_t cleanup; /**< Cleanup devices on bus */ +}; + +/** + * Register a Bus handler. + * + * @param bus + * A pointer to a rte_bus structure describing the bus + * to be registered. + */ +__rte_internal +void rte_bus_register(struct rte_bus *bus); + +/** + * Helper for Bus registration. + * The constructor has higher priority than PMD constructors. + */ +#define RTE_REGISTER_BUS(nm, bus) \ +RTE_INIT_PRIO(businitfn_ ##nm, BUS) \ +{\ + (bus).name = RTE_STR(nm);\ + rte_bus_register(&bus); \ +} + +/** + * Unregister a Bus handler. + * + * @param bus + * A pointer to a rte_bus structure describing the bus + * to be unregistered. + */ +__rte_internal +void rte_bus_unregister(struct rte_bus *bus); + +#ifdef __cplusplus +} +#endif + +#endif /* BUS_DRIVER_H */ diff --git a/lib/env_dpdk/22.11/bus_pci_driver.h b/lib/env_dpdk/22.11/bus_pci_driver.h new file mode 100644 index 000000000..0a5fffb19 --- /dev/null +++ b/lib/env_dpdk/22.11/bus_pci_driver.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation. + * Copyright 2013-2014 6WIND S.A. + */ + +#ifndef BUS_PCI_DRIVER_H +#define BUS_PCI_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rte_bus_pci.h" +#include "dev_driver.h" +#include + +/** Pathname of PCI devices directory. */ +__rte_internal +const char *rte_pci_get_sysfs_path(void); + +enum rte_pci_kernel_driver { + RTE_PCI_KDRV_UNKNOWN = 0, /* may be misc UIO or bifurcated driver */ + RTE_PCI_KDRV_IGB_UIO, /* igb_uio for Linux */ + RTE_PCI_KDRV_VFIO, /* VFIO for Linux */ + RTE_PCI_KDRV_UIO_GENERIC, /* uio_pci_generic for Linux */ + RTE_PCI_KDRV_NIC_UIO, /* nic_uio for FreeBSD */ + RTE_PCI_KDRV_NONE, /* no attached driver */ + RTE_PCI_KDRV_NET_UIO, /* NetUIO for Windows */ +}; + +/** + * A structure describing a PCI device. + */ +struct rte_pci_device { + RTE_TAILQ_ENTRY(rte_pci_device) next; /**< Next probed PCI device. */ + struct rte_device device; /**< Inherit core device */ + struct rte_pci_addr addr; /**< PCI location. */ + struct rte_pci_id id; /**< PCI ID. */ + struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE]; + /**< PCI Memory Resource */ + struct rte_intr_handle *intr_handle; /**< Interrupt handle */ + struct rte_pci_driver *driver; /**< PCI driver used in probing */ + uint16_t max_vfs; /**< sriov enable if not zero */ + enum rte_pci_kernel_driver kdrv; /**< Kernel driver passthrough */ + char name[PCI_PRI_STR_SIZE+1]; /**< PCI location (ASCII) */ + char *bus_info; /**< PCI bus specific info */ + struct rte_intr_handle *vfio_req_intr_handle; + /**< Handler of VFIO request interrupt */ +}; + +/** + * @internal + * Helper macro for drivers that need to convert to struct rte_pci_device. + */ +#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device) + +#define RTE_DEV_TO_PCI_CONST(ptr) \ + container_of(ptr, const struct rte_pci_device, device) + +#define RTE_ETH_DEV_TO_PCI(eth_dev) RTE_DEV_TO_PCI((eth_dev)->device) + +#ifdef __cplusplus +/** C++ macro used to help building up tables of device IDs */ +#define RTE_PCI_DEVICE(vend, dev) \ + RTE_CLASS_ANY_ID, \ + (vend), \ + (dev), \ + RTE_PCI_ANY_ID, \ + RTE_PCI_ANY_ID +#else +/** Macro used to help building up tables of device IDs */ +#define RTE_PCI_DEVICE(vend, dev) \ + .class_id = RTE_CLASS_ANY_ID, \ + .vendor_id = (vend), \ + .device_id = (dev), \ + .subsystem_vendor_id = RTE_PCI_ANY_ID, \ + .subsystem_device_id = RTE_PCI_ANY_ID +#endif + +/** + * Initialisation function for the driver called during PCI probing. + */ +typedef int (rte_pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *); + +/** + * Uninitialisation function for the driver called during hotplugging. + */ +typedef int (rte_pci_remove_t)(struct rte_pci_device *); + +/** + * 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 PCI 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 (pci_dma_map_t)(struct rte_pci_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 PCI 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 (pci_dma_unmap_t)(struct rte_pci_device *dev, void *addr, + uint64_t iova, size_t len); + +/** + * A structure describing a PCI driver. + */ +struct rte_pci_driver { + RTE_TAILQ_ENTRY(rte_pci_driver) next; /**< Next in list. */ + struct rte_driver driver; /**< Inherit core driver. */ + rte_pci_probe_t *probe; /**< Device probe function. */ + rte_pci_remove_t *remove; /**< Device remove function. */ + pci_dma_map_t *dma_map; /**< device dma map function. */ + pci_dma_unmap_t *dma_unmap; /**< device dma unmap function. */ + const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */ + uint32_t drv_flags; /**< Flags RTE_PCI_DRV_*. */ +}; + +/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */ +#define RTE_PCI_DRV_NEED_MAPPING 0x0001 +/** Device needs PCI BAR mapping with enabled write combining (wc) */ +#define RTE_PCI_DRV_WC_ACTIVATE 0x0002 +/** Device already probed can be probed again to check for new ports. */ +#define RTE_PCI_DRV_PROBE_AGAIN 0x0004 +/** Device driver supports link state interrupt */ +#define RTE_PCI_DRV_INTR_LSC 0x0008 +/** Device driver supports device removal interrupt */ +#define RTE_PCI_DRV_INTR_RMV 0x0010 +/** Device driver needs to keep mapped resources if unsupported dev detected */ +#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020 +/** Device driver needs IOVA as VA and cannot work with IOVA as PA */ +#define RTE_PCI_DRV_NEED_IOVA_AS_VA 0x0040 + +/** + * Register a PCI driver. + * + * @param driver + * A pointer to a rte_pci_driver structure describing the driver + * to be registered. + */ +__rte_internal +void rte_pci_register(struct rte_pci_driver *driver); + +/** Helper for PCI device registration from driver (eth, crypto) instance */ +#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \ +RTE_INIT(pciinitfn_ ##nm) \ +{\ + (pci_drv).driver.name = RTE_STR(nm);\ + rte_pci_register(&pci_drv); \ +} \ +RTE_PMD_EXPORT_NAME(nm, __COUNTER__) + +/** + * Unregister a PCI driver. + * + * @param driver + * A pointer to a rte_pci_driver structure describing the driver + * to be unregistered. + */ +__rte_internal +void rte_pci_unregister(struct rte_pci_driver *driver); + +/* + * A structure used to access io resources for a pci device. + * rte_pci_ioport is arch, os, driver specific, and should not be used outside + * of pci ioport api. + */ +struct rte_pci_ioport { + struct rte_pci_device *dev; + uint64_t base; + uint64_t len; /* only filled for memory mapped ports */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* BUS_PCI_DRIVER_H */ diff --git a/lib/env_dpdk/22.11/dev_driver.h b/lib/env_dpdk/22.11/dev_driver.h new file mode 100644 index 000000000..05fc06e12 --- /dev/null +++ b/lib/env_dpdk/22.11/dev_driver.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Red Hat, Inc. + */ + +#ifndef DEV_DRIVER_H +#define DEV_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "rte_dev.h" + +/** + * A structure describing a device driver. + */ +struct rte_driver { + RTE_TAILQ_ENTRY(rte_driver) next; /**< Next in list. */ + const char *name; /**< Driver name. */ + const char *alias; /**< Driver alias. */ +}; + +/** + * A structure describing a generic device. + */ +struct rte_device { + RTE_TAILQ_ENTRY(rte_device) next; /**< Next device */ + const char *name; /**< Device name */ + const char *bus_info; /**< Device bus specific information */ + const struct rte_driver *driver; /**< Driver assigned after probing */ + const struct rte_bus *bus; /**< Bus handle assigned on scan */ + int numa_node; /**< NUMA node connection */ + struct rte_devargs *devargs; /**< Arguments for latest probing */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* DEV_DRIVER_H */ diff --git a/lib/env_dpdk/22.11/rte_bus.h b/lib/env_dpdk/22.11/rte_bus.h new file mode 100644 index 000000000..dfe756fb1 --- /dev/null +++ b/lib/env_dpdk/22.11/rte_bus.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2016 NXP + */ + +#ifndef _RTE_BUS_H_ +#define _RTE_BUS_H_ + +/** + * @file + * + * DPDK device bus interface + * + * This file exposes API and interfaces for bus abstraction + * over the devices and drivers in EAL. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +struct rte_bus; +struct rte_device; + +/** + * Retrieve a bus name. + * + * @param bus + * A pointer to a rte_bus structure. + * @return + * A pointer to the bus name string. + */ +const char *rte_bus_name(const struct rte_bus *bus); + +/** + * Scan all the buses. + * + * @return + * 0 in case of success in scanning all buses + * !0 in case of failure to scan + */ +int rte_bus_scan(void); + +/** + * For each device on the buses, perform a driver 'match' and call the + * driver-specific probe for device initialization. + * + * @return + * 0 for successful match/probe + * !0 otherwise + */ +int rte_bus_probe(void); + +/** + * Dump information of all the buses registered with EAL. + * + * @param f + * A valid and open output stream handle + */ +void rte_bus_dump(FILE *f); + +/** + * Bus comparison function. + * + * @param bus + * Bus under test. + * + * @param data + * Data to compare against. + * + * @return + * 0 if the bus matches the data. + * !0 if the bus does not match. + * <0 if ordering is possible and the bus is lower than the data. + * >0 if ordering is possible and the bus is greater than the data. + */ +typedef int (*rte_bus_cmp_t)(const struct rte_bus *bus, const void *data); + +/** + * Bus iterator to find a particular bus. + * + * This function compares each registered bus to find one that matches + * the data passed as parameter. + * + * If the comparison function returns zero this function will stop iterating + * over any more buses. To continue a search the bus of a previous search can + * be passed via the start parameter. + * + * @param start + * Starting point for the iteration. + * + * @param cmp + * Comparison function. + * + * @param data + * Data to pass to comparison function. + * + * @return + * A pointer to a rte_bus structure or NULL in case no bus matches + */ +struct rte_bus *rte_bus_find(const struct rte_bus *start, rte_bus_cmp_t cmp, + const void *data); + +/** + * Find the registered bus for a particular device. + */ +struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev); + +/** + * Find the registered bus for a given name. + */ +struct rte_bus *rte_bus_find_by_name(const char *busname); + + +/** + * Get the common iommu class of devices bound on to buses available in the + * system. RTE_IOVA_DC means that no preference has been expressed. + * + * @return + * enum rte_iova_mode value. + */ +enum rte_iova_mode rte_bus_get_iommu_class(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_BUS_H */ diff --git a/lib/env_dpdk/22.11/rte_bus_pci.h b/lib/env_dpdk/22.11/rte_bus_pci.h new file mode 100644 index 000000000..60e50ca87 --- /dev/null +++ b/lib/env_dpdk/22.11/rte_bus_pci.h @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation. + * Copyright 2013-2014 6WIND S.A. + */ + +#ifndef _RTE_BUS_PCI_H_ +#define _RTE_BUS_PCI_H_ + +/** + * @file + * PCI device & driver interface + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Forward declarations */ +struct rte_pci_device; +struct rte_pci_driver; +struct rte_pci_ioport; + +struct rte_devargs; + +/** + * Map the PCI device resources in user space virtual memory address + * + * Note that driver should not call this function when flag + * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for + * you when it's on. + * + * @param dev + * A pointer to a rte_pci_device structure describing the device + * to use + * + * @return + * 0 on success, negative on error and positive if no driver + * is found for the device. + */ +int rte_pci_map_device(struct rte_pci_device *dev); + +/** + * Unmap this device + * + * @param dev + * A pointer to a rte_pci_device structure describing the device + * to use + */ +void rte_pci_unmap_device(struct rte_pci_device *dev); + +/** + * Dump the content of the PCI bus. + * + * @param f + * A pointer to a file for output + */ +void rte_pci_dump(FILE *f); + +/** + * Find device's extended PCI capability. + * + * @param dev + * A pointer to rte_pci_device structure. + * + * @param cap + * Extended capability to be found, which can be any from + * RTE_PCI_EXT_CAP_ID_*, defined in librte_pci. + * + * @return + * > 0: The offset of the next matching extended capability structure + * within the device's PCI configuration space. + * < 0: An error in PCI config space read. + * = 0: Device does not support it. + */ +__rte_experimental +off_t rte_pci_find_ext_capability(struct rte_pci_device *dev, uint32_t cap); + +/** + * Enables/Disables Bus Master for device's PCI command register. + * + * @param dev + * A pointer to rte_pci_device structure. + * @param enable + * Enable or disable Bus Master. + * + * @return + * 0 on success, -1 on error in PCI config space read/write. + */ +__rte_experimental +int rte_pci_set_bus_master(struct rte_pci_device *dev, bool enable); + +/** + * Read PCI config space. + * + * @param device + * A pointer to a rte_pci_device structure describing the device + * to use + * @param buf + * A data buffer where the bytes should be read into + * @param len + * The length of the data buffer. + * @param offset + * The offset into PCI config space + * @return + * Number of bytes read on success, negative on error. + */ +int rte_pci_read_config(const struct rte_pci_device *device, + void *buf, size_t len, off_t offset); + +/** + * Write PCI config space. + * + * @param device + * A pointer to a rte_pci_device structure describing the device + * to use + * @param buf + * A data buffer containing the bytes should be written + * @param len + * The length of the data buffer. + * @param offset + * The offset into PCI config space + */ +int rte_pci_write_config(const struct rte_pci_device *device, + const void *buf, size_t len, off_t offset); + +/** + * Initialize a rte_pci_ioport object for a pci device io resource. + * + * This object is then used to gain access to those io resources (see below). + * + * @param dev + * A pointer to a rte_pci_device structure describing the device + * to use. + * @param bar + * Index of the io pci resource we want to access. + * @param p + * The rte_pci_ioport object to be initialized. + * @return + * 0 on success, negative on error. + */ +int rte_pci_ioport_map(struct rte_pci_device *dev, int bar, + struct rte_pci_ioport *p); + +/** + * Release any resources used in a rte_pci_ioport object. + * + * @param p + * The rte_pci_ioport object to be uninitialized. + * @return + * 0 on success, negative on error. + */ +int rte_pci_ioport_unmap(struct rte_pci_ioport *p); + +/** + * Read from a io pci resource. + * + * @param p + * The rte_pci_ioport object from which we want to read. + * @param data + * A data buffer where the bytes should be read into + * @param len + * The length of the data buffer. + * @param offset + * The offset into the pci io resource. + */ +void rte_pci_ioport_read(struct rte_pci_ioport *p, + void *data, size_t len, off_t offset); + +/** + * Write to a io pci resource. + * + * @param p + * The rte_pci_ioport object to which we want to write. + * @param data + * A data buffer where the bytes should be read into + * @param len + * The length of the data buffer. + * @param offset + * The offset into the pci io resource. + */ +void rte_pci_ioport_write(struct rte_pci_ioport *p, + const void *data, size_t len, off_t offset); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_BUS_PCI_H_ */ diff --git a/lib/env_dpdk/22.11/rte_dev.h b/lib/env_dpdk/22.11/rte_dev.h new file mode 100644 index 000000000..dc1acc895 --- /dev/null +++ b/lib/env_dpdk/22.11/rte_dev.h @@ -0,0 +1,563 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014 6WIND S.A. + */ + +#ifndef _RTE_DEV_H_ +#define _RTE_DEV_H_ + +/** + * @file + * + * RTE PMD Registration Interface + * + * This file manages the list of device drivers. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + +struct rte_bus; +struct rte_devargs; +struct rte_device; +struct rte_driver; + +/** + * The device event type. + */ +enum rte_dev_event_type { + RTE_DEV_EVENT_ADD, /**< device being added */ + RTE_DEV_EVENT_REMOVE, /**< device being removed */ + RTE_DEV_EVENT_MAX /**< max value of this enum */ +}; + +typedef void (*rte_dev_event_cb_fn)(const char *device_name, + enum rte_dev_event_type event, + void *cb_arg); + +/* Macros to check for invalid function pointers */ +#define RTE_FUNC_PTR_OR_ERR_RET(func, retval) RTE_DEPRECATED(RTE_FUNC_PTR_OR_ERR_RET) \ +do { \ + if ((func) == NULL) \ + return retval; \ +} while (0) + +#define RTE_FUNC_PTR_OR_RET(func) RTE_DEPRECATED(RTE_FUNC_PTR_OR_RET) \ +do { \ + if ((func) == NULL) \ + return; \ +} while (0) + +/** + * Device policies. + */ +enum rte_dev_policy { + RTE_DEV_ALLOWED, + RTE_DEV_BLOCKED, +}; + +/** + * A generic memory resource representation. + */ +struct rte_mem_resource { + uint64_t phys_addr; /**< Physical address, 0 if not resource. */ + uint64_t len; /**< Length of the resource. */ + void *addr; /**< Virtual address, NULL when not mapped. */ +}; + +/** + * Retrieve a driver name. + * + * @param driver + * A pointer to a driver structure. + * @return + * A pointer to the driver name string. + */ +const char * +rte_driver_name(const struct rte_driver *driver); + +/** + * Retrieve a device bus. + * + * @param dev + * A pointer to a device structure. + * @return + * A pointer to this device bus. + */ +const struct rte_bus * +rte_dev_bus(const struct rte_device *dev); + +/** + * Retrieve bus specific information for a device. + * + * @param dev + * A pointer to a device structure. + * @return + * A string describing this device or NULL if none is available. + */ +const char * +rte_dev_bus_info(const struct rte_device *dev); + +/** + * Retrieve a device arguments. + * + * @param dev + * A pointer to a device structure. + * @return + * A pointer to this device devargs. + */ +const struct rte_devargs * +rte_dev_devargs(const struct rte_device *dev); + +/** + * Retrieve a device driver. + * + * @param dev + * A pointer to a device structure. + * @return + * A pointer to this device driver. + */ +const struct rte_driver * +rte_dev_driver(const struct rte_device *dev); + +/** + * Retrieve a device name. + * + * @param dev + * A pointer to a device structure. + * @return + * A pointer to this device name. + */ +const char * +rte_dev_name(const struct rte_device *dev); + +/** + * Retrieve a device numa node. + * + * @param dev + * A pointer to a device structure. + * @return + * A pointer to this device numa node. + */ +int +rte_dev_numa_node(const struct rte_device *dev); + +/* + * Internal identifier length + * Sufficiently large to allow for UUID or PCI address + */ +#define RTE_DEV_NAME_MAX_LEN 64 + +/** + * Query status of a device. + * + * @param dev + * Generic device pointer. + * @return + * (int)true if already probed successfully, 0 otherwise. + */ +int rte_dev_is_probed(const struct rte_device *dev); + +/** + * Hotplug add a given device to a specific bus. + * + * In multi-process, it will request other processes to add the same device. + * A failure, in any process, will rollback the action + * + * @param busname + * The bus name the device is added to. + * @param devname + * The device name. Based on this device name, eal will identify a driver + * capable of handling it and pass it to the driver probing function. + * @param drvargs + * Device arguments to be passed to the driver. + * @return + * 0 on success, negative on error. + */ +int rte_eal_hotplug_add(const char *busname, const char *devname, + const char *drvargs); + +/** + * Add matching devices. + * + * In multi-process, it will request other processes to add the same device. + * A failure, in any process, will rollback the action + * + * @param devargs + * Device arguments including bus, class and driver properties. + * @return + * 0 on success, negative on error. + */ +int rte_dev_probe(const char *devargs); + +/** + * Hotplug remove a given device from a specific bus. + * + * In multi-process, it will request other processes to remove the same device. + * A failure, in any process, will rollback the action + * + * @param busname + * The bus name the device is removed from. + * @param devname + * The device name being removed. + * @return + * 0 on success, negative on error. + */ +int rte_eal_hotplug_remove(const char *busname, const char *devname); + +/** + * Remove one device. + * + * In multi-process, it will request other processes to remove the same device. + * A failure, in any process, will rollback the action + * + * @param dev + * Data structure of the device to remove. + * @return + * 0 on success, negative on error. + */ +int rte_dev_remove(struct rte_device *dev); + +/** + * Device comparison function. + * + * This type of function is used to compare an rte_device with arbitrary + * data. + * + * @param dev + * Device handle. + * + * @param data + * Data to compare against. The type of this parameter is determined by + * the kind of comparison performed by the function. + * + * @return + * 0 if the device matches the data. + * !0 if the device does not match. + * <0 if ordering is possible and the device is lower than the data. + * >0 if ordering is possible and the device is greater than the data. + */ +typedef int (*rte_dev_cmp_t)(const struct rte_device *dev, const void *data); + +#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[] + +#define RTE_PMD_EXPORT_NAME(name, idx) \ +static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \ +__rte_used = RTE_STR(name) + +#define DRV_EXP_TAG(name, tag) __##name##_##tag + +#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \ +static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \ +RTE_STR(table) + +#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \ +static const char DRV_EXP_TAG(name, param_string_export)[] \ +__rte_used = str + +/** + * Advertise the list of kernel modules required to run this driver + * + * This string lists the kernel modules required for the devices + * associated to a PMD. The format of each line of the string is: + * " ". + * + * The possible formats for the device pattern are: + * "*" all devices supported by this driver + * "pci:*" all PCI devices supported by this driver + * "pci:v8086:d*:sv*:sd*" all PCI devices supported by this driver + * whose vendor id is 0x8086. + * + * The format of the kernel modules list is a parenthesized expression + * containing logical-and (&) and logical-or (|). + * + * The device pattern and the kmod expression are separated by a space. + * + * Example: + * - "* igb_uio | uio_pci_generic | vfio" + */ +#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \ +static const char DRV_EXP_TAG(name, kmod_dep_export)[] \ +__rte_used = str + +/** + * Iteration context. + * + * This context carries over the current iteration state. + */ +struct rte_dev_iterator { + const char *dev_str; /**< device string. */ + const char *bus_str; /**< bus-related part of device string. */ + const char *cls_str; /**< class-related part of device string. */ + struct rte_bus *bus; /**< bus handle. */ + struct rte_class *cls; /**< class handle. */ + struct rte_device *device; /**< current position. */ + void *class_device; /**< additional specialized context. */ +}; + +/** + * Device iteration function. + * + * Find the next device matching properties passed in parameters. + * The function takes an additional ``start`` parameter, that is + * used as starting context when relevant. + * + * The function returns the current element in the iteration. + * This return value will potentially be used as a start parameter + * in subsequent calls to the function. + * + * The additional iterator parameter is only there if a specific + * implementation needs additional context. It must not be modified by + * the iteration function itself. + * + * @param start + * Starting iteration context. + * + * @param devstr + * Device description string. + * + * @param it + * Device iterator. + * + * @return + * The address of the current element matching the device description + * string. + */ +typedef void *(*rte_dev_iterate_t)(const void *start, + const char *devstr, + const struct rte_dev_iterator *it); + +/** + * Initializes a device iterator. + * + * This iterator allows accessing a list of devices matching a criteria. + * The device matching is made among all buses and classes currently registered, + * filtered by the device description given as parameter. + * + * This function will not allocate any memory. It is safe to stop the + * iteration at any moment and let the iterator go out of context. + * + * @param it + * Device iterator handle. + * + * @param str + * Device description string. + * + * @return + * 0 on successful initialization. + * <0 on error. + */ +__rte_experimental +int +rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str); + +/** + * Iterates on a device iterator. + * + * Generates a new rte_device handle corresponding to the next element + * in the list described in comprehension by the iterator. + * + * The next object is returned, and the iterator is updated. + * + * @param it + * Device iterator handle. + * + * @return + * An rte_device handle if found. + * NULL if an error occurred (rte_errno is set). + * NULL if no device could be found (rte_errno is not set). + */ +__rte_experimental +struct rte_device * +rte_dev_iterator_next(struct rte_dev_iterator *it); + +#define RTE_DEV_FOREACH(dev, devstr, it) \ + for (rte_dev_iterator_init(it, devstr), \ + dev = rte_dev_iterator_next(it); \ + dev != NULL; \ + dev = rte_dev_iterator_next(it)) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * It registers the callback for the specific device. + * Multiple callbacks can be registered at the same time. + * + * @param device_name + * The device name, that is the param name of the struct rte_device, + * null value means for all devices. + * @param cb_fn + * callback address. + * @param cb_arg + * address of parameter for callback. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_dev_event_callback_register(const char *device_name, + rte_dev_event_cb_fn cb_fn, + void *cb_arg); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * It unregisters the callback according to the specified device. + * + * @param device_name + * The device name, that is the param name of the struct rte_device, + * null value means for all devices and their callbacks. + * @param cb_fn + * callback address. + * @param cb_arg + * address of parameter for callback, (void *)-1 means to remove all + * registered which has the same callback address. + * + * @return + * - On success, return the number of callback entities removed. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_dev_event_callback_unregister(const char *device_name, + rte_dev_event_cb_fn cb_fn, + void *cb_arg); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Executes all the user application registered callbacks for + * the specific device. + * + * @param device_name + * The device name. + * @param event + * the device event type. + */ +__rte_experimental +void +rte_dev_event_callback_process(const char *device_name, + enum rte_dev_event_type event); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Start the device event monitoring. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_dev_event_monitor_start(void); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Stop the device event monitoring. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_dev_event_monitor_stop(void); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Enable hotplug handling for devices. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_dev_hotplug_handle_enable(void); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Disable hotplug handling for devices. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_dev_hotplug_handle_disable(void); + +/** + * Device level DMA map function. + * After a successful call, the memory segment will be mapped to the + * given device. + * + * @note: Memory must be registered in advance using rte_extmem_* APIs. + * + * @param dev + * Device pointer. + * @param addr + * Virtual address to map. + * @param iova + * IOVA address to map. + * @param len + * Length of the memory segment being mapped. + * + * @return + * 0 if mapping was successful. + * Negative value and rte_errno is set otherwise. + */ +__rte_experimental +int +rte_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len); + +/** + * Device level DMA unmap function. + * After a successful call, the memory segment will no longer be + * accessible by the given device. + * + * @note: Memory must be registered in advance using rte_extmem_* APIs. + * + * @param dev + * Device pointer. + * @param addr + * Virtual address to unmap. + * @param iova + * IOVA address to unmap. + * @param len + * Length of the memory segment being mapped. + * + * @return + * 0 if un-mapping was successful. + * Negative value and rte_errno is set otherwise. + */ +__rte_experimental +int +rte_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, + size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_DEV_H_ */ diff --git a/lib/env_dpdk/Makefile b/lib/env_dpdk/Makefile index 4f823996f..1ee792999 100644 --- a/lib/env_dpdk/Makefile +++ b/lib/env_dpdk/Makefile @@ -13,7 +13,7 @@ CFLAGS += $(ENV_CFLAGS) C_SRCS = env.c memory.c pci.c init.c threads.c C_SRCS += pci_ioat.c pci_virtio.c pci_vmd.c pci_idxd.c C_SRCS += pci_event.c sigbus_handler.c pci_dpdk.c -C_SRCS += pci_dpdk_2207.c +C_SRCS += pci_dpdk_2207.c pci_dpdk_2211.c LIBNAME = env_dpdk SPDK_MAP_FILE = $(abspath $(CURDIR)/spdk_env_dpdk.map) diff --git a/lib/env_dpdk/pci_dpdk.c b/lib/env_dpdk/pci_dpdk.c index f298b2639..aafe68953 100644 --- a/lib/env_dpdk/pci_dpdk.c +++ b/lib/env_dpdk/pci_dpdk.c @@ -9,6 +9,7 @@ #include "spdk/log.h" extern struct dpdk_fn_table fn_table_2207; +extern struct dpdk_fn_table fn_table_2211; static struct dpdk_fn_table *g_dpdk_fn_table; @@ -32,14 +33,22 @@ dpdk_pci_init(void) return -EINVAL; } - /* Anything greater than 22.07 is not supported. */ - if (year == 22 && month > 7) { - SPDK_ERRLOG("DPDK version %d.%02d.%d not supported.\n", year, month, minor); - return -EINVAL; + if (year == 22 && month == 11) { + if (minor != 0) { + /* It is possible that LTS minor release changed private ABI, so we + * cannot assume fn_table_2211 works for minor releases. As 22.11 + * minor releases occur, this will need to be updated to either affirm + * no ABI changes for the minor release, or add new header files and + * pci_dpdk_xxx.c implementation for the new minor release. + */ + SPDK_ERRLOG("DPDK LTS version 22.11.%d not supported.\n", minor); + return -EINVAL; + } + g_dpdk_fn_table = &fn_table_2211; + } else { + /* Everything else we use the 22.07 implementation. */ + g_dpdk_fn_table = &fn_table_2207; } - - /* Everything else we use the 22.07 implementation. */ - g_dpdk_fn_table = &fn_table_2207; return 0; } diff --git a/lib/env_dpdk/pci_dpdk_2211.c b/lib/env_dpdk/pci_dpdk_2211.c new file mode 100644 index 000000000..af0ce5255 --- /dev/null +++ b/lib/env_dpdk/pci_dpdk_2211.c @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) Intel Corporation. + * All rights reserved. + */ + +#define ALLOW_INTERNAL_API +#include +#include +#include "pci_dpdk.h" +#include "22.11/bus_pci_driver.h" +#include "22.11/bus_driver.h" +#include "22.11/rte_bus_pci.h" +#include "spdk/assert.h" + +SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver_buf) == 0, "driver_buf must be first"); +SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver) >= sizeof(struct rte_pci_driver), + "driver_buf not big enough"); + +static struct rte_mem_resource * +pci_device_get_mem_resource_2211(struct rte_pci_device *dev, uint32_t bar) +{ + if (bar >= PCI_MAX_RESOURCE) { + assert(false); + return NULL; + } + + return &dev->mem_resource[bar]; +} + +static const char * +pci_device_get_name_2211(struct rte_pci_device *rte_dev) +{ + return rte_dev->name; +} + +static struct rte_devargs * +pci_device_get_devargs_2211(struct rte_pci_device *rte_dev) +{ + return rte_dev->device.devargs; +} + +static struct rte_pci_addr * +pci_device_get_addr_2211(struct rte_pci_device *_dev) +{ + return &_dev->addr; +} + +static struct rte_pci_id * +pci_device_get_id_2211(struct rte_pci_device *_dev) +{ + return &_dev->id; +} + +static int +pci_device_get_numa_node_2211(struct rte_pci_device *_dev) +{ + return _dev->device.numa_node; +} + +static int +pci_device_read_config_2211(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) +{ + int rc; + + rc = rte_pci_read_config(dev, value, len, offset); + + return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; +} + +static int +pci_device_write_config_2211(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) +{ + int rc; + + rc = rte_pci_write_config(dev, value, len, offset); + +#ifdef __FreeBSD__ + /* DPDK returns 0 on success and -1 on failure */ + return rc; +#endif + return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; +} + +/* translate spdk_pci_driver to an rte_pci_driver and register it to dpdk */ +static int +pci_driver_register_2211(struct spdk_pci_driver *driver, + int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device), + int (*remove_fn)(struct rte_pci_device *device)) + +{ + unsigned pci_id_count = 0; + struct rte_pci_id *rte_id_table; + char *rte_name; + size_t rte_name_len; + uint32_t rte_flags; + + assert(driver->id_table); + while (driver->id_table[pci_id_count].vendor_id) { + pci_id_count++; + } + assert(pci_id_count > 0); + + rte_id_table = calloc(pci_id_count + 1, sizeof(*rte_id_table)); + if (!rte_id_table) { + return -ENOMEM; + } + + while (pci_id_count > 0) { + struct rte_pci_id *rte_id = &rte_id_table[pci_id_count - 1]; + const struct spdk_pci_id *spdk_id = &driver->id_table[pci_id_count - 1]; + + rte_id->class_id = spdk_id->class_id; + rte_id->vendor_id = spdk_id->vendor_id; + rte_id->device_id = spdk_id->device_id; + rte_id->subsystem_vendor_id = spdk_id->subvendor_id; + rte_id->subsystem_device_id = spdk_id->subdevice_id; + pci_id_count--; + } + + assert(driver->name); + rte_name_len = strlen(driver->name) + strlen("spdk_") + 1; + rte_name = calloc(rte_name_len, 1); + if (!rte_name) { + free(rte_id_table); + return -ENOMEM; + } + + snprintf(rte_name, rte_name_len, "spdk_%s", driver->name); + driver->driver->driver.name = rte_name; + driver->driver->id_table = rte_id_table; + + rte_flags = 0; + if (driver->drv_flags & SPDK_PCI_DRIVER_NEED_MAPPING) { + rte_flags |= RTE_PCI_DRV_NEED_MAPPING; + } + if (driver->drv_flags & SPDK_PCI_DRIVER_WC_ACTIVATE) { + rte_flags |= RTE_PCI_DRV_WC_ACTIVATE; + } + driver->driver->drv_flags = rte_flags; + + driver->driver->probe = probe_fn; + driver->driver->remove = remove_fn; + + rte_pci_register(driver->driver); + return 0; +} + +static int +pci_device_enable_interrupt_2211(struct rte_pci_device *rte_dev) +{ + return rte_intr_enable(rte_dev->intr_handle); +} + +static int +pci_device_disable_interrupt_2211(struct rte_pci_device *rte_dev) +{ + return rte_intr_disable(rte_dev->intr_handle); +} + +static int +pci_device_get_interrupt_efd_2211(struct rte_pci_device *rte_dev) +{ + return rte_intr_fd_get(rte_dev->intr_handle); +} + +static int +bus_probe_2211(void) +{ + return rte_bus_probe(); +} + +static void +bus_scan_2211(void) +{ + rte_bus_scan(); +} + +static struct rte_devargs * +device_get_devargs_2211(struct rte_device *dev) +{ + return dev->devargs; +} + +static void +device_set_devargs_2211(struct rte_device *dev, struct rte_devargs *devargs) +{ + dev->devargs = devargs; +} + +static const char * +device_get_name_2211(struct rte_device *dev) +{ + return dev->name; +} + +static bool +device_scan_allowed_2211(struct rte_device *dev) +{ + return dev->bus->conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST; +} + +struct dpdk_fn_table fn_table_2211 = { + .pci_device_get_mem_resource = pci_device_get_mem_resource_2211, + .pci_device_get_name = pci_device_get_name_2211, + .pci_device_get_devargs = pci_device_get_devargs_2211, + .pci_device_get_addr = pci_device_get_addr_2211, + .pci_device_get_id = pci_device_get_id_2211, + .pci_device_get_numa_node = pci_device_get_numa_node_2211, + .pci_device_read_config = pci_device_read_config_2211, + .pci_device_write_config = pci_device_write_config_2211, + .pci_driver_register = pci_driver_register_2211, + .pci_device_enable_interrupt = pci_device_enable_interrupt_2211, + .pci_device_disable_interrupt = pci_device_disable_interrupt_2211, + .pci_device_get_interrupt_efd = pci_device_get_interrupt_efd_2211, + .bus_scan = bus_scan_2211, + .bus_probe = bus_probe_2211, + .device_get_devargs = device_get_devargs_2211, + .device_set_devargs = device_set_devargs_2211, + .device_get_name = device_get_name_2211, + .device_scan_allowed = device_scan_allowed_2211, +};