1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include <rte_config.h> 7 #include <rte_version.h> 8 #include "pci_dpdk.h" 9 #include <rte_bus_pci.h> 10 #include "spdk/assert.h" 11 12 SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver_buf) == 0, "driver_buf must be first"); 13 SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver) >= sizeof(struct rte_pci_driver), 14 "driver_buf not big enough"); 15 16 uint64_t 17 dpdk_pci_device_vtophys(struct rte_pci_device *dev, uint64_t vaddr) 18 { 19 struct rte_mem_resource *res; 20 uint64_t paddr; 21 unsigned r; 22 23 for (r = 0; r < PCI_MAX_RESOURCE; r++) { 24 res = &dev->mem_resource[r]; 25 if (res->phys_addr && vaddr >= (uint64_t)res->addr && 26 vaddr < (uint64_t)res->addr + res->len) { 27 paddr = res->phys_addr + (vaddr - (uint64_t)res->addr); 28 return paddr; 29 } 30 } 31 32 return SPDK_VTOPHYS_ERROR; 33 } 34 35 const char * 36 dpdk_pci_device_get_name(struct rte_pci_device *rte_dev) 37 { 38 return rte_dev->name; 39 } 40 41 struct rte_devargs * 42 dpdk_pci_device_get_devargs(struct rte_pci_device *rte_dev) 43 { 44 return rte_dev->device.devargs; 45 } 46 47 void 48 dpdk_pci_device_copy_identifiers(struct rte_pci_device *_dev, struct spdk_pci_device *dev) 49 { 50 dev->addr.domain = _dev->addr.domain; 51 dev->addr.bus = _dev->addr.bus; 52 dev->addr.dev = _dev->addr.devid; 53 dev->addr.func = _dev->addr.function; 54 dev->id.class_id = _dev->id.class_id; 55 dev->id.vendor_id = _dev->id.vendor_id; 56 dev->id.device_id = _dev->id.device_id; 57 dev->id.subvendor_id = _dev->id.subsystem_vendor_id; 58 dev->id.subdevice_id = _dev->id.subsystem_device_id; 59 dev->socket_id = _dev->device.numa_node; 60 } 61 62 int 63 dpdk_pci_device_map_bar(struct rte_pci_device *dev, uint32_t bar, 64 void **mapped_addr, uint64_t *phys_addr, uint64_t *size) 65 { 66 *mapped_addr = dev->mem_resource[bar].addr; 67 *phys_addr = (uint64_t)dev->mem_resource[bar].phys_addr; 68 *size = (uint64_t)dev->mem_resource[bar].len; 69 70 return 0; 71 } 72 73 int 74 dpdk_pci_device_read_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) 75 { 76 int rc; 77 78 rc = rte_pci_read_config(dev, value, len, offset); 79 80 return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; 81 } 82 83 int 84 dpdk_pci_device_write_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) 85 { 86 int rc; 87 88 rc = rte_pci_write_config(dev, value, len, offset); 89 90 #ifdef __FreeBSD__ 91 /* DPDK returns 0 on success and -1 on failure */ 92 return rc; 93 #endif 94 return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; 95 } 96 97 /* translate spdk_pci_driver to an rte_pci_driver and register it to dpdk */ 98 int 99 dpdk_pci_driver_register(struct spdk_pci_driver *driver, 100 int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device), 101 int (*remove_fn)(struct rte_pci_device *device)) 102 103 { 104 unsigned pci_id_count = 0; 105 struct rte_pci_id *rte_id_table; 106 char *rte_name; 107 size_t rte_name_len; 108 uint32_t rte_flags; 109 110 assert(driver->id_table); 111 while (driver->id_table[pci_id_count].vendor_id) { 112 pci_id_count++; 113 } 114 assert(pci_id_count > 0); 115 116 rte_id_table = calloc(pci_id_count + 1, sizeof(*rte_id_table)); 117 if (!rte_id_table) { 118 return -ENOMEM; 119 } 120 121 while (pci_id_count > 0) { 122 struct rte_pci_id *rte_id = &rte_id_table[pci_id_count - 1]; 123 const struct spdk_pci_id *spdk_id = &driver->id_table[pci_id_count - 1]; 124 125 rte_id->class_id = spdk_id->class_id; 126 rte_id->vendor_id = spdk_id->vendor_id; 127 rte_id->device_id = spdk_id->device_id; 128 rte_id->subsystem_vendor_id = spdk_id->subvendor_id; 129 rte_id->subsystem_device_id = spdk_id->subdevice_id; 130 pci_id_count--; 131 } 132 133 assert(driver->name); 134 rte_name_len = strlen(driver->name) + strlen("spdk_") + 1; 135 rte_name = calloc(rte_name_len, 1); 136 if (!rte_name) { 137 free(rte_id_table); 138 return -ENOMEM; 139 } 140 141 snprintf(rte_name, rte_name_len, "spdk_%s", driver->name); 142 driver->driver->driver.name = rte_name; 143 driver->driver->id_table = rte_id_table; 144 145 rte_flags = 0; 146 if (driver->drv_flags & SPDK_PCI_DRIVER_NEED_MAPPING) { 147 rte_flags |= RTE_PCI_DRV_NEED_MAPPING; 148 } 149 if (driver->drv_flags & SPDK_PCI_DRIVER_WC_ACTIVATE) { 150 rte_flags |= RTE_PCI_DRV_WC_ACTIVATE; 151 } 152 driver->driver->drv_flags = rte_flags; 153 154 driver->driver->probe = probe_fn; 155 driver->driver->remove = remove_fn; 156 157 rte_pci_register(driver->driver); 158 return 0; 159 } 160 161 int 162 dpdk_pci_device_enable_interrupt(struct rte_pci_device *rte_dev) 163 { 164 #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) 165 return rte_intr_enable(&rte_dev->intr_handle); 166 #else 167 return rte_intr_enable(rte_dev->intr_handle); 168 #endif 169 } 170 171 int 172 dpdk_pci_device_disable_interrupt(struct rte_pci_device *rte_dev) 173 { 174 #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) 175 return rte_intr_disable(&rte_dev->intr_handle); 176 #else 177 return rte_intr_disable(rte_dev->intr_handle); 178 #endif 179 } 180 181 int 182 dpdk_pci_device_get_interrupt_efd(struct rte_pci_device *rte_dev) 183 { 184 #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) 185 return rte_dev->intr_handle.fd; 186 #else 187 return rte_intr_fd_get(rte_dev->intr_handle); 188 #endif 189 } 190 191 int 192 dpdk_bus_probe(void) 193 { 194 return rte_bus_probe(); 195 } 196 197 void 198 dpdk_bus_scan(void) 199 { 200 rte_bus_scan(); 201 } 202 203 struct rte_devargs * 204 dpdk_device_get_devargs(struct rte_device *dev) 205 { 206 return dev->devargs; 207 } 208 209 void 210 dpdk_device_set_devargs(struct rte_device *dev, struct rte_devargs *devargs) 211 { 212 dev->devargs = devargs; 213 } 214 215 const char * 216 dpdk_device_get_name(struct rte_device *dev) 217 { 218 return dev->name; 219 } 220 221 bool 222 dpdk_device_scan_allowed(struct rte_device *dev) 223 { 224 return dev->bus->conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST; 225 } 226