xref: /spdk/lib/env_dpdk/pci_dpdk.c (revision dfc989439662457d39bac524be72e8ea1c20e817)
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