xref: /spdk/lib/env_dpdk/pci_dpdk.c (revision e0d7428b482257aa6999b8b4cc44159dcc292df9)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 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 "spdk/log.h"
10 
11 extern struct dpdk_fn_table fn_table_2207;
12 extern struct dpdk_fn_table fn_table_2211;
13 
14 static struct dpdk_fn_table *g_dpdk_fn_table;
15 
16 int
17 dpdk_pci_init(void)
18 {
19 	uint32_t year;
20 	uint32_t month;
21 	uint32_t minor;
22 	char release[32] = {0}; /* Max size of DPDK version string */
23 	int count;
24 
25 	count = sscanf(rte_version(), "DPDK %u.%u.%u%s", &year, &month, &minor, release);
26 	if (count != 3 && count != 4) {
27 		SPDK_ERRLOG("Unrecognized DPDK version format '%s'\n", rte_version());
28 		return -EINVAL;
29 	}
30 
31 	/* Add support for DPDK main branch, should be updated after each new release.
32 	 * Only DPDK in development has additional suffix past minor version.
33 	 */
34 	if (strlen(release) != 0) {
35 		if (year == 24 && month == 11 && minor == 0) {
36 			g_dpdk_fn_table = &fn_table_2211;
37 			SPDK_NOTICELOG("In-development %s is used. There is no support for it in SPDK. "
38 				       "Enabled only for validation.\n", rte_version());
39 			return 0;
40 		}
41 	}
42 
43 	/* Anything 25.x or higher is not supported. */
44 	if (year >= 25) {
45 		SPDK_ERRLOG("DPDK version %d.%02d.%d not supported.\n", year, month, minor);
46 		return -EINVAL;
47 	}
48 
49 	if (year == 22 && month == 11) {
50 		if (minor > 4) {
51 			/* It is possible that LTS minor release changed private ABI, so we
52 			 * cannot assume fn_table_2211 works for minor releases.  As 22.11
53 			 * minor releases occur, this will need to be updated to either affirm
54 			 * no ABI changes for the minor release, or add new header files and
55 			 * pci_dpdk_xxx.c implementation for the new minor release.
56 			 */
57 			SPDK_ERRLOG("DPDK LTS version 22.11.%d not supported.\n", minor);
58 			return -EINVAL;
59 		}
60 		g_dpdk_fn_table = &fn_table_2211;
61 	} else if (year == 23) {
62 		/* Only 23.11.0, 23.07.0 and 23.03.0 are supported. */
63 		if ((month != 11 || minor != 0) &&
64 		    (month != 7 || minor != 0) &&
65 		    (month != 3 || minor != 0)) {
66 			SPDK_ERRLOG("DPDK version 23.%02d.%d is not supported.\n", month, minor);
67 			return -EINVAL;
68 		}
69 		/* There were no changes between 22.11 and 23.11, so use the 22.11 implementation. */
70 		g_dpdk_fn_table = &fn_table_2211;
71 	} else if (year == 24) {
72 		/* Only 24.03.0 and 24.07.0 are supported. */
73 		if ((month != 7 || minor != 0) &&
74 		    (month != 3 || minor != 0)) {
75 			SPDK_ERRLOG("DPDK version 24.%02d.%d is not supported.\n", month, minor);
76 			return -EINVAL;
77 		}
78 		/* There were no changes between 22.11 and 24.*, so use the 22.11 implementation. */
79 		g_dpdk_fn_table = &fn_table_2211;
80 	} else if (year < 21 || (year == 21 && month < 11)) {
81 		SPDK_ERRLOG("DPDK version %02d.%02d.%d is not supported.\n", year, month, minor);
82 		return -EINVAL;
83 	} else {
84 		/* Everything else we use the 22.07 implementation. */
85 		g_dpdk_fn_table = &fn_table_2207;
86 	}
87 	return 0;
88 }
89 
90 struct rte_mem_resource *
91 dpdk_pci_device_get_mem_resource(struct rte_pci_device *dev, uint32_t bar)
92 {
93 	return g_dpdk_fn_table->pci_device_get_mem_resource(dev, bar);
94 }
95 
96 const char *
97 dpdk_pci_device_get_name(struct rte_pci_device *rte_dev)
98 {
99 	return g_dpdk_fn_table->pci_device_get_name(rte_dev);
100 }
101 
102 struct rte_devargs *
103 dpdk_pci_device_get_devargs(struct rte_pci_device *rte_dev)
104 {
105 	return g_dpdk_fn_table->pci_device_get_devargs(rte_dev);
106 }
107 
108 struct rte_pci_addr *
109 dpdk_pci_device_get_addr(struct rte_pci_device *rte_dev)
110 {
111 	return g_dpdk_fn_table->pci_device_get_addr(rte_dev);
112 }
113 
114 struct rte_pci_id *
115 dpdk_pci_device_get_id(struct rte_pci_device *rte_dev)
116 {
117 	return g_dpdk_fn_table->pci_device_get_id(rte_dev);
118 }
119 
120 int
121 dpdk_pci_device_get_numa_node(struct rte_pci_device *_dev)
122 {
123 	return g_dpdk_fn_table->pci_device_get_numa_node(_dev);
124 }
125 
126 int
127 dpdk_pci_device_read_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset)
128 {
129 	return g_dpdk_fn_table->pci_device_read_config(dev, value, len, offset);
130 }
131 
132 int
133 dpdk_pci_device_write_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset)
134 {
135 	return g_dpdk_fn_table->pci_device_write_config(dev, value, len, offset);
136 }
137 
138 int
139 dpdk_pci_driver_register(struct spdk_pci_driver *driver,
140 			 int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device),
141 			 int (*remove_fn)(struct rte_pci_device *device))
142 
143 {
144 	return g_dpdk_fn_table->pci_driver_register(driver, probe_fn, remove_fn);
145 }
146 
147 int
148 dpdk_pci_device_enable_interrupt(struct rte_pci_device *rte_dev)
149 {
150 	return g_dpdk_fn_table->pci_device_enable_interrupt(rte_dev);
151 }
152 
153 int
154 dpdk_pci_device_disable_interrupt(struct rte_pci_device *rte_dev)
155 {
156 	return g_dpdk_fn_table->pci_device_disable_interrupt(rte_dev);
157 }
158 
159 int
160 dpdk_pci_device_get_interrupt_efd(struct rte_pci_device *rte_dev)
161 {
162 	return g_dpdk_fn_table->pci_device_get_interrupt_efd(rte_dev);
163 }
164 
165 int
166 dpdk_pci_device_create_interrupt_efds(struct rte_pci_device *rte_dev, uint32_t count)
167 {
168 	return g_dpdk_fn_table->pci_device_create_interrupt_efds(rte_dev, count);
169 }
170 
171 void
172 dpdk_pci_device_delete_interrupt_efds(struct rte_pci_device *rte_dev)
173 {
174 	g_dpdk_fn_table->pci_device_delete_interrupt_efds(rte_dev);
175 }
176 
177 int
178 dpdk_pci_device_get_interrupt_efd_by_index(struct rte_pci_device *rte_dev, uint32_t index)
179 {
180 	return g_dpdk_fn_table->pci_device_get_interrupt_efd_by_index(rte_dev, index);
181 }
182 
183 int
184 dpdk_pci_device_interrupt_cap_multi(struct rte_pci_device *rte_dev)
185 {
186 	return g_dpdk_fn_table->pci_device_interrupt_cap_multi(rte_dev);
187 }
188 
189 int
190 dpdk_bus_probe(void)
191 {
192 	return g_dpdk_fn_table->bus_probe();
193 }
194 
195 void
196 dpdk_bus_scan(void)
197 {
198 	g_dpdk_fn_table->bus_scan();
199 }
200 
201 struct rte_devargs *
202 dpdk_device_get_devargs(struct rte_device *dev)
203 {
204 	return g_dpdk_fn_table->device_get_devargs(dev);
205 }
206 
207 void
208 dpdk_device_set_devargs(struct rte_device *dev, struct rte_devargs *devargs)
209 {
210 	g_dpdk_fn_table->device_set_devargs(dev, devargs);
211 }
212 
213 const char *
214 dpdk_device_get_name(struct rte_device *dev)
215 {
216 	return g_dpdk_fn_table->device_get_name(dev);
217 }
218 
219 bool
220 dpdk_device_scan_allowed(struct rte_device *dev)
221 {
222 	return g_dpdk_fn_table->device_scan_allowed(dev);
223 }
224