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