1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 NXP 3 */ 4 5 #ifndef _RTE_BUS_H_ 6 #define _RTE_BUS_H_ 7 8 /** 9 * @file 10 * 11 * DPDK device bus interface 12 * 13 * This file exposes API and interfaces for bus abstraction 14 * over the devices and drivers in EAL. 15 */ 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <stdio.h> 22 23 #include <rte_log.h> 24 #include "rte_dev.h" 25 26 /** Double linked list of buses */ 27 RTE_TAILQ_HEAD(rte_bus_list, rte_bus); 28 29 30 /** 31 * IOVA mapping mode. 32 * 33 * IOVA mapping mode is iommu programming mode of a device. 34 * That device (for example: IOMMU backed DMA device) based 35 * on rte_iova_mode will generate physical or virtual address. 36 * 37 */ 38 enum rte_iova_mode { 39 RTE_IOVA_DC = 0, /* Don't care mode */ 40 RTE_IOVA_PA = (1 << 0), /* DMA using physical address */ 41 RTE_IOVA_VA = (1 << 1) /* DMA using virtual address */ 42 }; 43 44 /** 45 * Bus specific scan for devices attached on the bus. 46 * For each bus object, the scan would be responsible for finding devices and 47 * adding them to its private device list. 48 * 49 * A bus should mandatorily implement this method. 50 * 51 * @return 52 * 0 for successful scan 53 * <0 for unsuccessful scan with error value 54 */ 55 typedef int (*rte_bus_scan_t)(void); 56 57 /** 58 * Implementation specific probe function which is responsible for linking 59 * devices on that bus with applicable drivers. 60 * 61 * This is called while iterating over each registered bus. 62 * 63 * @return 64 * 0 for successful probe 65 * !0 for any error while probing 66 */ 67 typedef int (*rte_bus_probe_t)(void); 68 69 /** 70 * Device iterator to find a device on a bus. 71 * 72 * This function returns an rte_device if one of those held by the bus 73 * matches the data passed as parameter. 74 * 75 * If the comparison function returns zero this function should stop iterating 76 * over any more devices. To continue a search the device of a previous search 77 * can be passed via the start parameter. 78 * 79 * @param cmp 80 * Comparison function. 81 * 82 * @param data 83 * Data to compare each device against. 84 * 85 * @param start 86 * starting point for the iteration 87 * 88 * @return 89 * The first device matching the data, NULL if none exists. 90 */ 91 typedef struct rte_device * 92 (*rte_bus_find_device_t)(const struct rte_device *start, rte_dev_cmp_t cmp, 93 const void *data); 94 95 /** 96 * Implementation specific probe function which is responsible for linking 97 * devices on that bus with applicable drivers. 98 * 99 * @param dev 100 * Device pointer that was returned by a previous call to find_device. 101 * 102 * @return 103 * 0 on success. 104 * !0 on error. 105 */ 106 typedef int (*rte_bus_plug_t)(struct rte_device *dev); 107 108 /** 109 * Implementation specific remove function which is responsible for unlinking 110 * devices on that bus from assigned driver. 111 * 112 * @param dev 113 * Device pointer that was returned by a previous call to find_device. 114 * 115 * @return 116 * 0 on success. 117 * !0 on error. 118 */ 119 typedef int (*rte_bus_unplug_t)(struct rte_device *dev); 120 121 /** 122 * Bus specific parsing function. 123 * Validates the syntax used in the textual representation of a device, 124 * If the syntax is valid and ``addr`` is not NULL, writes the bus-specific 125 * device representation to ``addr``. 126 * 127 * @param[in] name 128 * device textual description 129 * 130 * @param[out] addr 131 * device information location address, into which parsed info 132 * should be written. If NULL, nothing should be written, which 133 * is not an error. 134 * 135 * @return 136 * 0 if parsing was successful. 137 * !0 for any error. 138 */ 139 typedef int (*rte_bus_parse_t)(const char *name, void *addr); 140 141 /** 142 * Parse bus part of the device arguments. 143 * 144 * The field name of the struct rte_devargs will be set. 145 * 146 * @param da 147 * Pointer to the devargs to parse. 148 * 149 * @return 150 * 0 on successful parsing, otherwise rte_errno is set. 151 * -EINVAL: on parsing error. 152 * -ENODEV: if no key matching a device argument is specified. 153 * -E2BIG: device name is too long. 154 */ 155 typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da); 156 157 /** 158 * Device level DMA map function. 159 * After a successful call, the memory segment will be mapped to the 160 * given device. 161 * 162 * @param dev 163 * Device pointer. 164 * @param addr 165 * Virtual address to map. 166 * @param iova 167 * IOVA address to map. 168 * @param len 169 * Length of the memory segment being mapped. 170 * 171 * @return 172 * 0 if mapping was successful. 173 * Negative value and rte_errno is set otherwise. 174 */ 175 typedef int (*rte_dev_dma_map_t)(struct rte_device *dev, void *addr, 176 uint64_t iova, size_t len); 177 178 /** 179 * Device level DMA unmap function. 180 * After a successful call, the memory segment will no longer be 181 * accessible by the given device. 182 * 183 * @param dev 184 * Device pointer. 185 * @param addr 186 * Virtual address to unmap. 187 * @param iova 188 * IOVA address to unmap. 189 * @param len 190 * Length of the memory segment being mapped. 191 * 192 * @return 193 * 0 if un-mapping was successful. 194 * Negative value and rte_errno is set otherwise. 195 */ 196 typedef int (*rte_dev_dma_unmap_t)(struct rte_device *dev, void *addr, 197 uint64_t iova, size_t len); 198 199 /** 200 * Implement a specific hot-unplug handler, which is responsible for 201 * handle the failure when device be hot-unplugged. When the event of 202 * hot-unplug be detected, it could call this function to handle 203 * the hot-unplug failure and avoid app crash. 204 * @param dev 205 * Pointer of the device structure. 206 * 207 * @return 208 * 0 on success. 209 * !0 on error. 210 */ 211 typedef int (*rte_bus_hot_unplug_handler_t)(struct rte_device *dev); 212 213 /** 214 * Implement a specific sigbus handler, which is responsible for handling 215 * the sigbus error which is either original memory error, or specific memory 216 * error that caused of device be hot-unplugged. When sigbus error be captured, 217 * it could call this function to handle sigbus error. 218 * @param failure_addr 219 * Pointer of the fault address of the sigbus error. 220 * 221 * @return 222 * 0 for success handle the sigbus for hot-unplug. 223 * 1 for not process it, because it is a generic sigbus error. 224 * -1 for failed to handle the sigbus for hot-unplug. 225 */ 226 typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr); 227 228 /** 229 * Bus scan policies 230 */ 231 enum rte_bus_scan_mode { 232 RTE_BUS_SCAN_UNDEFINED, 233 RTE_BUS_SCAN_ALLOWLIST, 234 RTE_BUS_SCAN_BLOCKLIST, 235 }; 236 237 /** 238 * A structure used to configure bus operations. 239 */ 240 struct rte_bus_conf { 241 enum rte_bus_scan_mode scan_mode; /**< Scan policy. */ 242 }; 243 244 245 /** 246 * Get common iommu class of the all the devices on the bus. The bus may 247 * check that those devices are attached to iommu driver. 248 * If no devices are attached to the bus. The bus may return with don't care 249 * (_DC) value. 250 * Otherwise, The bus will return appropriate _pa or _va iova mode. 251 * 252 * @return 253 * enum rte_iova_mode value. 254 */ 255 typedef enum rte_iova_mode (*rte_bus_get_iommu_class_t)(void); 256 257 258 /** 259 * A structure describing a generic bus. 260 */ 261 struct rte_bus { 262 RTE_TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */ 263 const char *name; /**< Name of the bus */ 264 rte_bus_scan_t scan; /**< Scan for devices attached to bus */ 265 rte_bus_probe_t probe; /**< Probe devices on bus */ 266 rte_bus_find_device_t find_device; /**< Find a device on the bus */ 267 rte_bus_plug_t plug; /**< Probe single device for drivers */ 268 rte_bus_unplug_t unplug; /**< Remove single device from driver */ 269 rte_bus_parse_t parse; /**< Parse a device name */ 270 rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */ 271 rte_dev_dma_map_t dma_map; /**< DMA map for device in the bus */ 272 rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */ 273 struct rte_bus_conf conf; /**< Bus configuration */ 274 rte_bus_get_iommu_class_t get_iommu_class; /**< Get iommu class */ 275 rte_dev_iterate_t dev_iterate; /**< Device iterator. */ 276 rte_bus_hot_unplug_handler_t hot_unplug_handler; 277 /**< handle hot-unplug failure on the bus */ 278 rte_bus_sigbus_handler_t sigbus_handler; 279 /**< handle sigbus error on the bus */ 280 281 }; 282 283 /** 284 * Register a Bus handler. 285 * 286 * @param bus 287 * A pointer to a rte_bus structure describing the bus 288 * to be registered. 289 */ 290 void rte_bus_register(struct rte_bus *bus); 291 292 /** 293 * Unregister a Bus handler. 294 * 295 * @param bus 296 * A pointer to a rte_bus structure describing the bus 297 * to be unregistered. 298 */ 299 void rte_bus_unregister(struct rte_bus *bus); 300 301 /** 302 * Scan all the buses. 303 * 304 * @return 305 * 0 in case of success in scanning all buses 306 * !0 in case of failure to scan 307 */ 308 int rte_bus_scan(void); 309 310 /** 311 * For each device on the buses, perform a driver 'match' and call the 312 * driver-specific probe for device initialization. 313 * 314 * @return 315 * 0 for successful match/probe 316 * !0 otherwise 317 */ 318 int rte_bus_probe(void); 319 320 /** 321 * Dump information of all the buses registered with EAL. 322 * 323 * @param f 324 * A valid and open output stream handle 325 */ 326 void rte_bus_dump(FILE *f); 327 328 /** 329 * Bus comparison function. 330 * 331 * @param bus 332 * Bus under test. 333 * 334 * @param data 335 * Data to compare against. 336 * 337 * @return 338 * 0 if the bus matches the data. 339 * !0 if the bus does not match. 340 * <0 if ordering is possible and the bus is lower than the data. 341 * >0 if ordering is possible and the bus is greater than the data. 342 */ 343 typedef int (*rte_bus_cmp_t)(const struct rte_bus *bus, const void *data); 344 345 /** 346 * Bus iterator to find a particular bus. 347 * 348 * This function compares each registered bus to find one that matches 349 * the data passed as parameter. 350 * 351 * If the comparison function returns zero this function will stop iterating 352 * over any more buses. To continue a search the bus of a previous search can 353 * be passed via the start parameter. 354 * 355 * @param start 356 * Starting point for the iteration. 357 * 358 * @param cmp 359 * Comparison function. 360 * 361 * @param data 362 * Data to pass to comparison function. 363 * 364 * @return 365 * A pointer to a rte_bus structure or NULL in case no bus matches 366 */ 367 struct rte_bus *rte_bus_find(const struct rte_bus *start, rte_bus_cmp_t cmp, 368 const void *data); 369 370 /** 371 * Find the registered bus for a particular device. 372 */ 373 struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev); 374 375 /** 376 * Find the registered bus for a given name. 377 */ 378 struct rte_bus *rte_bus_find_by_name(const char *busname); 379 380 381 /** 382 * Get the common iommu class of devices bound on to buses available in the 383 * system. RTE_IOVA_DC means that no preference has been expressed. 384 * 385 * @return 386 * enum rte_iova_mode value. 387 */ 388 enum rte_iova_mode rte_bus_get_iommu_class(void); 389 390 /** 391 * Helper for Bus registration. 392 * The constructor has higher priority than PMD constructors. 393 */ 394 #define RTE_REGISTER_BUS(nm, bus) \ 395 RTE_INIT_PRIO(businitfn_ ##nm, BUS) \ 396 {\ 397 (bus).name = RTE_STR(nm);\ 398 rte_bus_register(&bus); \ 399 } 400 401 #ifdef __cplusplus 402 } 403 #endif 404 405 #endif /* _RTE_BUS_H */ 406