xref: /dpdk/drivers/bus/pci/bus_pci_driver.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
11f37cb2bSDavid Marchand /* SPDX-License-Identifier: BSD-3-Clause
21f37cb2bSDavid Marchand  * Copyright(c) 2010-2015 Intel Corporation.
31f37cb2bSDavid Marchand  * Copyright 2013-2014 6WIND S.A.
41f37cb2bSDavid Marchand  */
51f37cb2bSDavid Marchand 
61f37cb2bSDavid Marchand #ifndef BUS_PCI_DRIVER_H
71f37cb2bSDavid Marchand #define BUS_PCI_DRIVER_H
81f37cb2bSDavid Marchand 
91f37cb2bSDavid Marchand #include <rte_bus_pci.h>
101acb7f54SDavid Marchand #include <dev_driver.h>
111f37cb2bSDavid Marchand #include <rte_compat.h>
121f37cb2bSDavid Marchand 
13*719834a6SMattias Rönnblom #ifdef __cplusplus
14*719834a6SMattias Rönnblom extern "C" {
15*719834a6SMattias Rönnblom #endif
16*719834a6SMattias Rönnblom 
171f37cb2bSDavid Marchand /** Pathname of PCI devices directory. */
181f37cb2bSDavid Marchand __rte_internal
191f37cb2bSDavid Marchand const char *rte_pci_get_sysfs_path(void);
201f37cb2bSDavid Marchand 
211f37cb2bSDavid Marchand enum rte_pci_kernel_driver {
221f37cb2bSDavid Marchand 	RTE_PCI_KDRV_UNKNOWN = 0,  /* may be misc UIO or bifurcated driver */
231f37cb2bSDavid Marchand 	RTE_PCI_KDRV_IGB_UIO,      /* igb_uio for Linux */
241f37cb2bSDavid Marchand 	RTE_PCI_KDRV_VFIO,         /* VFIO for Linux */
251f37cb2bSDavid Marchand 	RTE_PCI_KDRV_UIO_GENERIC,  /* uio_pci_generic for Linux */
261f37cb2bSDavid Marchand 	RTE_PCI_KDRV_NIC_UIO,      /* nic_uio for FreeBSD */
271f37cb2bSDavid Marchand 	RTE_PCI_KDRV_NONE,         /* no attached driver */
281f37cb2bSDavid Marchand 	RTE_PCI_KDRV_NET_UIO,      /* NetUIO for Windows */
291f37cb2bSDavid Marchand };
301f37cb2bSDavid Marchand 
311f37cb2bSDavid Marchand /**
321f37cb2bSDavid Marchand  * A structure describing a PCI device.
331f37cb2bSDavid Marchand  */
341f37cb2bSDavid Marchand struct rte_pci_device {
351f37cb2bSDavid Marchand 	RTE_TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
361f37cb2bSDavid Marchand 	struct rte_device device;           /**< Inherit core device */
371f37cb2bSDavid Marchand 	struct rte_pci_addr addr;           /**< PCI location. */
381f37cb2bSDavid Marchand 	struct rte_pci_id id;               /**< PCI ID. */
391f37cb2bSDavid Marchand 	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
401f37cb2bSDavid Marchand 					    /**< PCI Memory Resource */
411f37cb2bSDavid Marchand 	struct rte_intr_handle *intr_handle; /**< Interrupt handle */
421f37cb2bSDavid Marchand 	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
431f37cb2bSDavid Marchand 	uint16_t max_vfs;                   /**< sriov enable if not zero */
441f37cb2bSDavid Marchand 	enum rte_pci_kernel_driver kdrv;    /**< Kernel driver passthrough */
451f37cb2bSDavid Marchand 	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
468f4de2dbSDavid Marchand 	char *bus_info;                     /**< PCI bus specific info */
471f37cb2bSDavid Marchand 	struct rte_intr_handle *vfio_req_intr_handle;
481f37cb2bSDavid Marchand 				/**< Handler of VFIO request interrupt */
491f37cb2bSDavid Marchand };
501f37cb2bSDavid Marchand 
511f37cb2bSDavid Marchand /**
521f37cb2bSDavid Marchand  * @internal
531f37cb2bSDavid Marchand  * Helper macro for drivers that need to convert to struct rte_pci_device.
541f37cb2bSDavid Marchand  */
551f37cb2bSDavid Marchand #define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
561f37cb2bSDavid Marchand 
571f37cb2bSDavid Marchand #define RTE_DEV_TO_PCI_CONST(ptr) \
581f37cb2bSDavid Marchand 	container_of(ptr, const struct rte_pci_device, device)
591f37cb2bSDavid Marchand 
601f37cb2bSDavid Marchand #define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
611f37cb2bSDavid Marchand 
621f37cb2bSDavid Marchand #ifdef __cplusplus
631f37cb2bSDavid Marchand /** C++ macro used to help building up tables of device IDs */
641f37cb2bSDavid Marchand #define RTE_PCI_DEVICE(vend, dev) \
651f37cb2bSDavid Marchand 	RTE_CLASS_ANY_ID,         \
661f37cb2bSDavid Marchand 	(vend),                   \
671f37cb2bSDavid Marchand 	(dev),                    \
681f37cb2bSDavid Marchand 	RTE_PCI_ANY_ID,           \
691f37cb2bSDavid Marchand 	RTE_PCI_ANY_ID
701f37cb2bSDavid Marchand #else
711f37cb2bSDavid Marchand /** Macro used to help building up tables of device IDs */
721f37cb2bSDavid Marchand #define RTE_PCI_DEVICE(vend, dev)          \
731f37cb2bSDavid Marchand 	.class_id = RTE_CLASS_ANY_ID,      \
741f37cb2bSDavid Marchand 	.vendor_id = (vend),               \
751f37cb2bSDavid Marchand 	.device_id = (dev),                \
761f37cb2bSDavid Marchand 	.subsystem_vendor_id = RTE_PCI_ANY_ID, \
771f37cb2bSDavid Marchand 	.subsystem_device_id = RTE_PCI_ANY_ID
781f37cb2bSDavid Marchand #endif
791f37cb2bSDavid Marchand 
801f37cb2bSDavid Marchand /**
811f37cb2bSDavid Marchand  * Initialisation function for the driver called during PCI probing.
821f37cb2bSDavid Marchand  */
831f37cb2bSDavid Marchand typedef int (rte_pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
841f37cb2bSDavid Marchand 
851f37cb2bSDavid Marchand /**
861f37cb2bSDavid Marchand  * Uninitialisation function for the driver called during hotplugging.
871f37cb2bSDavid Marchand  */
881f37cb2bSDavid Marchand typedef int (rte_pci_remove_t)(struct rte_pci_device *);
891f37cb2bSDavid Marchand 
901f37cb2bSDavid Marchand /**
911f37cb2bSDavid Marchand  * Driver-specific DMA mapping. After a successful call the device
921f37cb2bSDavid Marchand  * will be able to read/write from/to this segment.
931f37cb2bSDavid Marchand  *
941f37cb2bSDavid Marchand  * @param dev
951f37cb2bSDavid Marchand  *   Pointer to the PCI device.
961f37cb2bSDavid Marchand  * @param addr
971f37cb2bSDavid Marchand  *   Starting virtual address of memory to be mapped.
981f37cb2bSDavid Marchand  * @param iova
991f37cb2bSDavid Marchand  *   Starting IOVA address of memory to be mapped.
1001f37cb2bSDavid Marchand  * @param len
1011f37cb2bSDavid Marchand  *   Length of memory segment being mapped.
1021f37cb2bSDavid Marchand  * @return
1031f37cb2bSDavid Marchand  *   - 0 On success.
1041f37cb2bSDavid Marchand  *   - Negative value and rte_errno is set otherwise.
1051f37cb2bSDavid Marchand  */
1061f37cb2bSDavid Marchand typedef int (pci_dma_map_t)(struct rte_pci_device *dev, void *addr,
1071f37cb2bSDavid Marchand 			    uint64_t iova, size_t len);
1081f37cb2bSDavid Marchand 
1091f37cb2bSDavid Marchand /**
1101f37cb2bSDavid Marchand  * Driver-specific DMA un-mapping. After a successful call the device
1111f37cb2bSDavid Marchand  * will not be able to read/write from/to this segment.
1121f37cb2bSDavid Marchand  *
1131f37cb2bSDavid Marchand  * @param dev
1141f37cb2bSDavid Marchand  *   Pointer to the PCI device.
1151f37cb2bSDavid Marchand  * @param addr
1161f37cb2bSDavid Marchand  *   Starting virtual address of memory to be unmapped.
1171f37cb2bSDavid Marchand  * @param iova
1181f37cb2bSDavid Marchand  *   Starting IOVA address of memory to be unmapped.
1191f37cb2bSDavid Marchand  * @param len
1201f37cb2bSDavid Marchand  *   Length of memory segment being unmapped.
1211f37cb2bSDavid Marchand  * @return
1221f37cb2bSDavid Marchand  *   - 0 On success.
1231f37cb2bSDavid Marchand  *   - Negative value and rte_errno is set otherwise.
1241f37cb2bSDavid Marchand  */
1251f37cb2bSDavid Marchand typedef int (pci_dma_unmap_t)(struct rte_pci_device *dev, void *addr,
1261f37cb2bSDavid Marchand 			      uint64_t iova, size_t len);
1271f37cb2bSDavid Marchand 
1281f37cb2bSDavid Marchand /**
1291f37cb2bSDavid Marchand  * A structure describing a PCI driver.
1301f37cb2bSDavid Marchand  */
1311f37cb2bSDavid Marchand struct rte_pci_driver {
1321f37cb2bSDavid Marchand 	RTE_TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
1331f37cb2bSDavid Marchand 	struct rte_driver driver;          /**< Inherit core driver. */
1341f37cb2bSDavid Marchand 	rte_pci_probe_t *probe;            /**< Device probe function. */
1351f37cb2bSDavid Marchand 	rte_pci_remove_t *remove;          /**< Device remove function. */
1361f37cb2bSDavid Marchand 	pci_dma_map_t *dma_map;		   /**< device dma map function. */
1371f37cb2bSDavid Marchand 	pci_dma_unmap_t *dma_unmap;	   /**< device dma unmap function. */
1381f37cb2bSDavid Marchand 	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
1391f37cb2bSDavid Marchand 	uint32_t drv_flags;                /**< Flags RTE_PCI_DRV_*. */
1401f37cb2bSDavid Marchand };
1411f37cb2bSDavid Marchand 
1421f37cb2bSDavid Marchand /** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
1431f37cb2bSDavid Marchand #define RTE_PCI_DRV_NEED_MAPPING 0x0001
1441f37cb2bSDavid Marchand /** Device needs PCI BAR mapping with enabled write combining (wc) */
1451f37cb2bSDavid Marchand #define RTE_PCI_DRV_WC_ACTIVATE 0x0002
1461f37cb2bSDavid Marchand /** Device already probed can be probed again to check for new ports. */
1471f37cb2bSDavid Marchand #define RTE_PCI_DRV_PROBE_AGAIN 0x0004
1481f37cb2bSDavid Marchand /** Device driver supports link state interrupt */
1491f37cb2bSDavid Marchand #define RTE_PCI_DRV_INTR_LSC	0x0008
1501f37cb2bSDavid Marchand /** Device driver supports device removal interrupt */
1511f37cb2bSDavid Marchand #define RTE_PCI_DRV_INTR_RMV 0x0010
1521f37cb2bSDavid Marchand /** Device driver needs to keep mapped resources if unsupported dev detected */
1531f37cb2bSDavid Marchand #define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
1541f37cb2bSDavid Marchand /** Device driver needs IOVA as VA and cannot work with IOVA as PA */
1551f37cb2bSDavid Marchand #define RTE_PCI_DRV_NEED_IOVA_AS_VA 0x0040
1561f37cb2bSDavid Marchand 
1571f37cb2bSDavid Marchand /**
1581f37cb2bSDavid Marchand  * Register a PCI driver.
1591f37cb2bSDavid Marchand  *
1601f37cb2bSDavid Marchand  * @param driver
1611f37cb2bSDavid Marchand  *   A pointer to a rte_pci_driver structure describing the driver
1621f37cb2bSDavid Marchand  *   to be registered.
1631f37cb2bSDavid Marchand  */
1641f37cb2bSDavid Marchand __rte_internal
1651f37cb2bSDavid Marchand void rte_pci_register(struct rte_pci_driver *driver);
1661f37cb2bSDavid Marchand 
1671f37cb2bSDavid Marchand /** Helper for PCI device registration from driver (eth, crypto) instance */
1681f37cb2bSDavid Marchand #define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
1691f37cb2bSDavid Marchand RTE_INIT(pciinitfn_ ##nm) \
1701f37cb2bSDavid Marchand {\
1711f37cb2bSDavid Marchand 	(pci_drv).driver.name = RTE_STR(nm);\
1721f37cb2bSDavid Marchand 	rte_pci_register(&pci_drv); \
1731f37cb2bSDavid Marchand } \
1741f37cb2bSDavid Marchand RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
1751f37cb2bSDavid Marchand 
1761f37cb2bSDavid Marchand /**
1771f37cb2bSDavid Marchand  * Unregister a PCI driver.
1781f37cb2bSDavid Marchand  *
1791f37cb2bSDavid Marchand  * @param driver
1801f37cb2bSDavid Marchand  *   A pointer to a rte_pci_driver structure describing the driver
1811f37cb2bSDavid Marchand  *   to be unregistered.
1821f37cb2bSDavid Marchand  */
1831f37cb2bSDavid Marchand __rte_internal
1841f37cb2bSDavid Marchand void rte_pci_unregister(struct rte_pci_driver *driver);
1851f37cb2bSDavid Marchand 
1861f37cb2bSDavid Marchand /*
1871f37cb2bSDavid Marchand  * A structure used to access io resources for a pci device.
1881f37cb2bSDavid Marchand  * rte_pci_ioport is arch, os, driver specific, and should not be used outside
1891f37cb2bSDavid Marchand  * of pci ioport api.
1901f37cb2bSDavid Marchand  */
1911f37cb2bSDavid Marchand struct rte_pci_ioport {
1921f37cb2bSDavid Marchand 	struct rte_pci_device *dev;
1931f37cb2bSDavid Marchand 	uint64_t base;
1941f37cb2bSDavid Marchand 	uint64_t len; /* only filled for memory mapped ports */
1951f37cb2bSDavid Marchand };
1961f37cb2bSDavid Marchand 
1971f37cb2bSDavid Marchand #ifdef __cplusplus
1981f37cb2bSDavid Marchand }
1991f37cb2bSDavid Marchand #endif
2001f37cb2bSDavid Marchand 
2011f37cb2bSDavid Marchand #endif /* BUS_PCI_DRIVER_H */
202