1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016 RehiveTech. All rights reserved. 3 */ 4 5 #ifndef RTE_VDEV_H 6 #define RTE_VDEV_H 7 8 /** 9 * @file 10 * RTE virtual bus API 11 * 12 */ 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 #include <rte_dev.h> 19 #include <rte_devargs.h> 20 21 struct rte_vdev_device { 22 RTE_TAILQ_ENTRY(rte_vdev_device) next; /**< Next attached vdev */ 23 struct rte_device device; /**< Inherit core device */ 24 }; 25 26 /** 27 * @internal 28 * Helper macro for drivers that need to convert to struct rte_vdev_device. 29 */ 30 #define RTE_DEV_TO_VDEV(ptr) \ 31 container_of(ptr, struct rte_vdev_device, device) 32 33 #define RTE_DEV_TO_VDEV_CONST(ptr) \ 34 container_of(ptr, const struct rte_vdev_device, device) 35 36 #define RTE_ETH_DEV_TO_VDEV(eth_dev) RTE_DEV_TO_VDEV((eth_dev)->device) 37 38 static inline const char * 39 rte_vdev_device_name(const struct rte_vdev_device *dev) 40 { 41 if (dev && dev->device.name) 42 return dev->device.name; 43 return NULL; 44 } 45 46 static inline const char * 47 rte_vdev_device_args(const struct rte_vdev_device *dev) 48 { 49 if (dev && dev->device.devargs) 50 return dev->device.devargs->args; 51 return ""; 52 } 53 54 /** Double linked list of virtual device drivers. */ 55 RTE_TAILQ_HEAD(vdev_driver_list, rte_vdev_driver); 56 57 /** 58 * Probe function called for each virtual device driver once. 59 */ 60 typedef int (rte_vdev_probe_t)(struct rte_vdev_device *dev); 61 62 /** 63 * Remove function called for each virtual device driver once. 64 */ 65 typedef int (rte_vdev_remove_t)(struct rte_vdev_device *dev); 66 67 /** 68 * Driver-specific DMA mapping. After a successful call the device 69 * will be able to read/write from/to this segment. 70 * 71 * @param dev 72 * Pointer to the Virtual device. 73 * @param addr 74 * Starting virtual address of memory to be mapped. 75 * @param iova 76 * Starting IOVA address of memory to be mapped. 77 * @param len 78 * Length of memory segment being mapped. 79 * @return 80 * - 0 On success. 81 * - Negative value and rte_errno is set otherwise. 82 */ 83 typedef int (rte_vdev_dma_map_t)(struct rte_vdev_device *dev, void *addr, 84 uint64_t iova, size_t len); 85 86 /** 87 * Driver-specific DMA un-mapping. After a successful call the device 88 * will not be able to read/write from/to this segment. 89 * 90 * @param dev 91 * Pointer to the Virtual device. 92 * @param addr 93 * Starting virtual address of memory to be unmapped. 94 * @param iova 95 * Starting IOVA address of memory to be unmapped. 96 * @param len 97 * Length of memory segment being unmapped. 98 * @return 99 * - 0 On success. 100 * - Negative value and rte_errno is set otherwise. 101 */ 102 typedef int (rte_vdev_dma_unmap_t)(struct rte_vdev_device *dev, void *addr, 103 uint64_t iova, size_t len); 104 105 /** 106 * A virtual device driver abstraction. 107 */ 108 struct rte_vdev_driver { 109 RTE_TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */ 110 struct rte_driver driver; /**< Inherited general driver. */ 111 rte_vdev_probe_t *probe; /**< Virtual device probe function. */ 112 rte_vdev_remove_t *remove; /**< Virtual device remove function. */ 113 rte_vdev_dma_map_t *dma_map; /**< Virtual device DMA map function. */ 114 rte_vdev_dma_unmap_t *dma_unmap; /**< Virtual device DMA unmap function. */ 115 uint32_t drv_flags; /**< Flags RTE_VDEV_DRV_*. */ 116 }; 117 118 /** Device driver needs IOVA as VA and cannot work with IOVA as PA */ 119 #define RTE_VDEV_DRV_NEED_IOVA_AS_VA 0x0001 120 121 /** 122 * Register a virtual device driver. 123 * 124 * @param driver 125 * A pointer to a rte_vdev_driver structure describing the driver 126 * to be registered. 127 */ 128 void rte_vdev_register(struct rte_vdev_driver *driver); 129 130 /** 131 * Unregister a virtual device driver. 132 * 133 * @param driver 134 * A pointer to a rte_vdev_driver structure describing the driver 135 * to be unregistered. 136 */ 137 void rte_vdev_unregister(struct rte_vdev_driver *driver); 138 139 #define RTE_PMD_REGISTER_VDEV(nm, vdrv)\ 140 static const char *vdrvinit_ ## nm ## _alias;\ 141 RTE_INIT(vdrvinitfn_ ##vdrv)\ 142 {\ 143 (vdrv).driver.name = RTE_STR(nm);\ 144 (vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\ 145 rte_vdev_register(&vdrv);\ 146 } \ 147 RTE_PMD_EXPORT_NAME(nm, __COUNTER__) 148 149 #define RTE_PMD_REGISTER_ALIAS(nm, alias)\ 150 static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias) 151 152 typedef void (*rte_vdev_scan_callback)(void *user_arg); 153 154 /** 155 * Add a callback to be called on vdev scan 156 * before reading the devargs list. 157 * 158 * This function cannot be called in a scan callback 159 * because of deadlock. 160 * 161 * @param callback 162 * The function to be called which can update the devargs list. 163 * @param user_arg 164 * An opaque pointer passed to callback. 165 * @return 166 * 0 on success, negative on error 167 */ 168 int 169 rte_vdev_add_custom_scan(rte_vdev_scan_callback callback, void *user_arg); 170 171 /** 172 * Remove a registered scan callback. 173 * 174 * This function cannot be called in a scan callback 175 * because of deadlock. 176 * 177 * @param callback 178 * The registered function to be removed. 179 * @param user_arg 180 * The associated opaque pointer or (void*)-1 for any. 181 * @return 182 * 0 on success 183 */ 184 int 185 rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg); 186 187 /** 188 * Initialize a driver specified by name. 189 * 190 * @param name 191 * The pointer to a driver name to be initialized. 192 * @param args 193 * The pointer to arguments used by driver initialization. 194 * @return 195 * 0 on success, negative on error 196 */ 197 int rte_vdev_init(const char *name, const char *args); 198 199 /** 200 * Uninitialize a driver specified by name. 201 * 202 * @param name 203 * The pointer to a driver name to be uninitialized. 204 * @return 205 * 0 on success, negative on error 206 */ 207 int rte_vdev_uninit(const char *name); 208 209 #ifdef __cplusplus 210 } 211 #endif 212 213 #endif 214