xref: /dpdk/drivers/bus/pci/private.h (revision 849f773b7645216954022a47e466043a23125af9)
1fd4ab1feSOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause
2fd4ab1feSOlivier Matz  * Copyright(c) 2017 6WIND S.A.
3c752998bSGaetan Rivet  */
4c752998bSGaetan Rivet 
5c752998bSGaetan Rivet #ifndef _PCI_PRIVATE_H_
6c752998bSGaetan Rivet #define _PCI_PRIVATE_H_
7c752998bSGaetan Rivet 
8c752998bSGaetan Rivet #include <stdbool.h>
9c752998bSGaetan Rivet #include <stdio.h>
1045d62067SDmitry Kozlyuk 
11a04322f6SDavid Marchand #include <bus_driver.h>
121f37cb2bSDavid Marchand #include <bus_pci_driver.h>
13*849f773bSDavid Marchand #include <rte_log.h>
1445d62067SDmitry Kozlyuk #include <rte_os_shim.h>
1545d62067SDmitry Kozlyuk #include <rte_pci.h>
16c752998bSGaetan Rivet 
17*849f773bSDavid Marchand extern int pci_bus_logtype;
18*849f773bSDavid Marchand #define RTE_LOGTYPE_PCI_BUS pci_bus_logtype
19*849f773bSDavid Marchand #define PCI_LOG(level, ...) \
20*849f773bSDavid Marchand 	RTE_LOG_LINE(level, PCI_BUS, "" __VA_ARGS__)
21*849f773bSDavid Marchand 
224b741542SChenbo Xia #define RTE_MAX_PCI_REGIONS    9
234b741542SChenbo Xia 
2487a02023SChenbo Xia /*
2587a02023SChenbo Xia  * Convert struct rte_pci_device to struct rte_pci_device_internal
2687a02023SChenbo Xia  */
2787a02023SChenbo Xia #define RTE_PCI_DEVICE_INTERNAL(ptr) \
2887a02023SChenbo Xia 	container_of(ptr, struct rte_pci_device_internal, device)
2987a02023SChenbo Xia #define RTE_PCI_DEVICE_INTERNAL_CONST(ptr) \
3087a02023SChenbo Xia 	container_of(ptr, const struct rte_pci_device_internal, device)
3187a02023SChenbo Xia 
321f37cb2bSDavid Marchand /**
331f37cb2bSDavid Marchand  * Structure describing the PCI bus
341f37cb2bSDavid Marchand  */
351f37cb2bSDavid Marchand struct rte_pci_bus {
361f37cb2bSDavid Marchand 	struct rte_bus bus;               /**< Inherit the generic class */
371f37cb2bSDavid Marchand 	RTE_TAILQ_HEAD(, rte_pci_device) device_list; /**< List of PCI devices */
381f37cb2bSDavid Marchand 	RTE_TAILQ_HEAD(, rte_pci_driver) driver_list; /**< List of PCI drivers */
391f37cb2bSDavid Marchand };
401f37cb2bSDavid Marchand 
4146521ca2SGaetan Rivet extern struct rte_pci_bus rte_pci_bus;
4246521ca2SGaetan Rivet 
431f37cb2bSDavid Marchand /* PCI Bus iterators */
441f37cb2bSDavid Marchand #define FOREACH_DEVICE_ON_PCIBUS(p)	\
451f37cb2bSDavid Marchand 	RTE_TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
461f37cb2bSDavid Marchand 
471f37cb2bSDavid Marchand #define FOREACH_DRIVER_ON_PCIBUS(p)	\
481f37cb2bSDavid Marchand 	RTE_TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
491f37cb2bSDavid Marchand 
50c752998bSGaetan Rivet struct rte_pci_driver;
51c752998bSGaetan Rivet struct rte_pci_device;
52c752998bSGaetan Rivet 
534b741542SChenbo Xia struct rte_pci_region {
544b741542SChenbo Xia 	uint64_t size;
554b741542SChenbo Xia 	uint64_t offset;
564b741542SChenbo Xia };
574b741542SChenbo Xia 
5887a02023SChenbo Xia struct rte_pci_device_internal {
5987a02023SChenbo Xia 	struct rte_pci_device device;
604b741542SChenbo Xia 	/* PCI regions provided by e.g. VFIO. */
614b741542SChenbo Xia 	struct rte_pci_region region[RTE_MAX_PCI_REGIONS];
6287a02023SChenbo Xia };
6387a02023SChenbo Xia 
64c752998bSGaetan Rivet /**
65c752998bSGaetan Rivet  * Scan the content of the PCI bus, and the devices in the devices
66c752998bSGaetan Rivet  * list
67c752998bSGaetan Rivet  *
68c752998bSGaetan Rivet  * @return
69c752998bSGaetan Rivet  *  0 on success, negative on error
70c752998bSGaetan Rivet  */
71c752998bSGaetan Rivet int rte_pci_scan(void);
72c752998bSGaetan Rivet 
73c752998bSGaetan Rivet /**
748f4de2dbSDavid Marchand  * Set common internal information for a PCI device.
75c752998bSGaetan Rivet  */
76c752998bSGaetan Rivet void
778f4de2dbSDavid Marchand pci_common_set(struct rte_pci_device *dev);
788f4de2dbSDavid Marchand 
798f4de2dbSDavid Marchand /**
808f4de2dbSDavid Marchand  * Free a PCI device.
818f4de2dbSDavid Marchand  */
828f4de2dbSDavid Marchand void
8387a02023SChenbo Xia pci_free(struct rte_pci_device_internal *pdev);
84c752998bSGaetan Rivet 
85c752998bSGaetan Rivet /**
86463a5245SSunil Kumar Kori  * Validate whether a device with given PCI address should be ignored or not.
87463a5245SSunil Kumar Kori  *
88463a5245SSunil Kumar Kori  * @param pci_addr
89463a5245SSunil Kumar Kori  *	PCI address of device to be validated
90463a5245SSunil Kumar Kori  * @return
91463a5245SSunil Kumar Kori  *	true: if device is to be ignored,
92463a5245SSunil Kumar Kori  *	false: if device is to be scanned,
93463a5245SSunil Kumar Kori  */
94463a5245SSunil Kumar Kori bool rte_pci_ignore_device(const struct rte_pci_addr *pci_addr);
95463a5245SSunil Kumar Kori 
96463a5245SSunil Kumar Kori /**
97c752998bSGaetan Rivet  * Add a PCI device to the PCI Bus (append to PCI Device list). This function
98c752998bSGaetan Rivet  * also updates the bus references of the PCI Device (and the generic device
99c752998bSGaetan Rivet  * object embedded within.
100c752998bSGaetan Rivet  *
101c752998bSGaetan Rivet  * @param pci_dev
102c752998bSGaetan Rivet  *	PCI device to add
103c752998bSGaetan Rivet  * @return void
104c752998bSGaetan Rivet  */
105c752998bSGaetan Rivet void rte_pci_add_device(struct rte_pci_device *pci_dev);
106c752998bSGaetan Rivet 
107c752998bSGaetan Rivet /**
108c752998bSGaetan Rivet  * Insert a PCI device in the PCI Bus at a particular location in the device
109c752998bSGaetan Rivet  * list. It also updates the PCI Bus reference of the new devices to be
110c752998bSGaetan Rivet  * inserted.
111c752998bSGaetan Rivet  *
112c752998bSGaetan Rivet  * @param exist_pci_dev
113c752998bSGaetan Rivet  *	Existing PCI device in PCI Bus
114c752998bSGaetan Rivet  * @param new_pci_dev
115c752998bSGaetan Rivet  *	PCI device to be added before exist_pci_dev
116c752998bSGaetan Rivet  * @return void
117c752998bSGaetan Rivet  */
118c752998bSGaetan Rivet void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
119c752998bSGaetan Rivet 		struct rte_pci_device *new_pci_dev);
120c752998bSGaetan Rivet 
121c752998bSGaetan Rivet /**
122e1ece609SDavid Marchand  * A structure describing a PCI mapping.
123e1ece609SDavid Marchand  */
124e1ece609SDavid Marchand struct pci_map {
125e1ece609SDavid Marchand 	void *addr;
126e1ece609SDavid Marchand 	char *path;
127e1ece609SDavid Marchand 	uint64_t offset;
128e1ece609SDavid Marchand 	uint64_t size;
129e1ece609SDavid Marchand 	uint64_t phaddr;
130f60abf97SMiao Li 	uint32_t nr_areas;
131f60abf97SMiao Li 	struct vfio_region_sparse_mmap_area *areas;
132e1ece609SDavid Marchand };
133e1ece609SDavid Marchand 
134e1ece609SDavid Marchand struct pci_msix_table {
135e1ece609SDavid Marchand 	int bar_index;
136e1ece609SDavid Marchand 	uint32_t offset;
137e1ece609SDavid Marchand 	uint32_t size;
138e1ece609SDavid Marchand };
139e1ece609SDavid Marchand 
140e1ece609SDavid Marchand /**
141e1ece609SDavid Marchand  * A structure describing a mapped PCI resource.
142e1ece609SDavid Marchand  * For multi-process we need to reproduce all PCI mappings in secondary
143e1ece609SDavid Marchand  * processes, so save them in a tailq.
144e1ece609SDavid Marchand  */
145e1ece609SDavid Marchand struct mapped_pci_resource {
146e1ece609SDavid Marchand 	TAILQ_ENTRY(mapped_pci_resource) next;
147e1ece609SDavid Marchand 
148e1ece609SDavid Marchand 	struct rte_pci_addr pci_addr;
149e1ece609SDavid Marchand 	char path[PATH_MAX];
150e1ece609SDavid Marchand 	int nb_maps;
151e1ece609SDavid Marchand 	struct pci_map maps[PCI_MAX_RESOURCE];
152e1ece609SDavid Marchand 	struct pci_msix_table msix_table;
153e1ece609SDavid Marchand };
154e1ece609SDavid Marchand 
155e1ece609SDavid Marchand /** mapped pci device list */
156e1ece609SDavid Marchand TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
157e1ece609SDavid Marchand 
158e1ece609SDavid Marchand /**
159e1ece609SDavid Marchand  * Map a particular resource from a file.
160e1ece609SDavid Marchand  *
161e1ece609SDavid Marchand  * @param requested_addr
162e1ece609SDavid Marchand  *      The starting address for the new mapping range.
163e1ece609SDavid Marchand  * @param fd
164e1ece609SDavid Marchand  *      The file descriptor.
165e1ece609SDavid Marchand  * @param offset
166e1ece609SDavid Marchand  *      The offset for the mapping range.
167e1ece609SDavid Marchand  * @param size
168e1ece609SDavid Marchand  *      The size for the mapping range.
169e1ece609SDavid Marchand  * @param additional_flags
170e1ece609SDavid Marchand  *      The additional rte_mem_map() flags for the mapping range.
171e1ece609SDavid Marchand  * @return
172e1ece609SDavid Marchand  *   - On success, the function returns a pointer to the mapped area.
173e200535cSDavid Marchand  *   - On error, NULL is returned.
174e1ece609SDavid Marchand  */
175e1ece609SDavid Marchand void *pci_map_resource(void *requested_addr, int fd, off_t offset,
176e1ece609SDavid Marchand 		size_t size, int additional_flags);
177e1ece609SDavid Marchand 
178e1ece609SDavid Marchand /**
179e1ece609SDavid Marchand  * Unmap a particular resource.
180e1ece609SDavid Marchand  *
181e1ece609SDavid Marchand  * @param requested_addr
182e1ece609SDavid Marchand  *      The address for the unmapping range.
183e1ece609SDavid Marchand  * @param size
184e1ece609SDavid Marchand  *      The size for the unmapping range.
185e1ece609SDavid Marchand  */
186e1ece609SDavid Marchand void pci_unmap_resource(void *requested_addr, size_t size);
187e1ece609SDavid Marchand 
188e1ece609SDavid Marchand /**
189c752998bSGaetan Rivet  * Map the PCI resource of a PCI device in virtual memory
190c752998bSGaetan Rivet  *
191c752998bSGaetan Rivet  * This function is private to EAL.
192c752998bSGaetan Rivet  *
193c752998bSGaetan Rivet  * @return
194c752998bSGaetan Rivet  *   0 on success, negative on error
195c752998bSGaetan Rivet  */
196c752998bSGaetan Rivet int pci_uio_map_resource(struct rte_pci_device *dev);
197c752998bSGaetan Rivet 
198c752998bSGaetan Rivet /**
199c752998bSGaetan Rivet  * Unmap the PCI resource of a PCI device
200c752998bSGaetan Rivet  *
201c752998bSGaetan Rivet  * This function is private to EAL.
202c752998bSGaetan Rivet  */
203c752998bSGaetan Rivet void pci_uio_unmap_resource(struct rte_pci_device *dev);
204c752998bSGaetan Rivet 
205c752998bSGaetan Rivet /**
206c752998bSGaetan Rivet  * Allocate uio resource for PCI device
207c752998bSGaetan Rivet  *
208c752998bSGaetan Rivet  * This function is private to EAL.
209c752998bSGaetan Rivet  *
210c752998bSGaetan Rivet  * @param dev
211c752998bSGaetan Rivet  *   PCI device to allocate uio resource
212c752998bSGaetan Rivet  * @param uio_res
213c752998bSGaetan Rivet  *   Pointer to uio resource.
214c752998bSGaetan Rivet  *   If the function returns 0, the pointer will be filled.
215c752998bSGaetan Rivet  * @return
216c752998bSGaetan Rivet  *   0 on success, negative on error
217c752998bSGaetan Rivet  */
218c752998bSGaetan Rivet int pci_uio_alloc_resource(struct rte_pci_device *dev,
219c752998bSGaetan Rivet 		struct mapped_pci_resource **uio_res);
220c752998bSGaetan Rivet 
221c752998bSGaetan Rivet /**
222c752998bSGaetan Rivet  * Free uio resource for PCI device
223c752998bSGaetan Rivet  *
224c752998bSGaetan Rivet  * This function is private to EAL.
225c752998bSGaetan Rivet  *
226c752998bSGaetan Rivet  * @param dev
227c752998bSGaetan Rivet  *   PCI device to free uio resource
228c752998bSGaetan Rivet  * @param uio_res
229c752998bSGaetan Rivet  *   Pointer to uio resource.
230c752998bSGaetan Rivet  */
231c752998bSGaetan Rivet void pci_uio_free_resource(struct rte_pci_device *dev,
232c752998bSGaetan Rivet 		struct mapped_pci_resource *uio_res);
233c752998bSGaetan Rivet 
234c752998bSGaetan Rivet /**
235b01dc3daSJeff Guo  * Remap the PCI resource of a PCI device in anonymous virtual memory.
236b01dc3daSJeff Guo  *
237b01dc3daSJeff Guo  * @param dev
238b01dc3daSJeff Guo  *   Point to the struct rte pci device.
239b01dc3daSJeff Guo  * @return
240b01dc3daSJeff Guo  *   - On success, zero.
241b01dc3daSJeff Guo  *   - On failure, a negative value.
242b01dc3daSJeff Guo  */
243b01dc3daSJeff Guo int
244b01dc3daSJeff Guo pci_uio_remap_resource(struct rte_pci_device *dev);
245b01dc3daSJeff Guo 
246b01dc3daSJeff Guo /**
247c752998bSGaetan Rivet  * Map device memory to uio resource
248c752998bSGaetan Rivet  *
249c752998bSGaetan Rivet  * This function is private to EAL.
250c752998bSGaetan Rivet  *
251c752998bSGaetan Rivet  * @param dev
252c752998bSGaetan Rivet  *   PCI device that has memory information.
253c752998bSGaetan Rivet  * @param res_idx
254c752998bSGaetan Rivet  *   Memory resource index of the PCI device.
255c752998bSGaetan Rivet  * @param uio_res
256c752998bSGaetan Rivet  *  uio resource that will keep mapping information.
257c752998bSGaetan Rivet  * @param map_idx
258c752998bSGaetan Rivet  *   Mapping information index of the uio resource.
259c752998bSGaetan Rivet  * @return
260c752998bSGaetan Rivet  *   0 on success, negative on error
261c752998bSGaetan Rivet  */
262c752998bSGaetan Rivet int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
263c752998bSGaetan Rivet 		struct mapped_pci_resource *uio_res, int map_idx);
264c752998bSGaetan Rivet 
265c752998bSGaetan Rivet /*
266c752998bSGaetan Rivet  * Match the PCI Driver and Device using the ID Table
267c752998bSGaetan Rivet  *
268c752998bSGaetan Rivet  * @param pci_drv
269c752998bSGaetan Rivet  *      PCI driver from which ID table would be extracted
270c752998bSGaetan Rivet  * @param pci_dev
271c752998bSGaetan Rivet  *      PCI device to match against the driver
272c752998bSGaetan Rivet  * @return
273c752998bSGaetan Rivet  *      1 for successful match
274c752998bSGaetan Rivet  *      0 for unsuccessful match
275c752998bSGaetan Rivet  */
276c752998bSGaetan Rivet int
277c752998bSGaetan Rivet rte_pci_match(const struct rte_pci_driver *pci_drv,
278c752998bSGaetan Rivet 	      const struct rte_pci_device *pci_dev);
279c752998bSGaetan Rivet 
280c752998bSGaetan Rivet /**
28166d3724bSDavid Marchand  * OS specific callbacks for rte_pci_get_iommu_class
282703458e1SBen Walker  *
283703458e1SBen Walker  */
28466d3724bSDavid Marchand bool
28566d3724bSDavid Marchand pci_device_iommu_support_va(const struct rte_pci_device *dev);
28666d3724bSDavid Marchand 
287703458e1SBen Walker enum rte_iova_mode
288703458e1SBen Walker pci_device_iova_mode(const struct rte_pci_driver *pci_drv,
289703458e1SBen Walker 		     const struct rte_pci_device *pci_dev);
290703458e1SBen Walker 
291703458e1SBen Walker /**
292c752998bSGaetan Rivet  * Get iommu class of PCI devices on the bus.
293c752998bSGaetan Rivet  * And return their preferred iova mapping mode.
294c752998bSGaetan Rivet  *
295c752998bSGaetan Rivet  * @return
296c752998bSGaetan Rivet  *   - enum rte_iova_mode.
297c752998bSGaetan Rivet  */
298c752998bSGaetan Rivet enum rte_iova_mode
299c752998bSGaetan Rivet rte_pci_get_iommu_class(void);
300c752998bSGaetan Rivet 
30146521ca2SGaetan Rivet /*
30246521ca2SGaetan Rivet  * Iterate over internal devices,
30346521ca2SGaetan Rivet  * matching any device against the provided
30446521ca2SGaetan Rivet  * string.
30546521ca2SGaetan Rivet  *
30646521ca2SGaetan Rivet  * @param start
30746521ca2SGaetan Rivet  *   Iteration starting point.
30846521ca2SGaetan Rivet  *
30946521ca2SGaetan Rivet  * @param str
31046521ca2SGaetan Rivet  *   Device string to match against.
31146521ca2SGaetan Rivet  *
31246521ca2SGaetan Rivet  * @param it
31346521ca2SGaetan Rivet  *   (unused) iterator structure.
31446521ca2SGaetan Rivet  *
31546521ca2SGaetan Rivet  * @return
31646521ca2SGaetan Rivet  *   A pointer to the next matching device if any.
31746521ca2SGaetan Rivet  *   NULL otherwise.
31846521ca2SGaetan Rivet  */
31946521ca2SGaetan Rivet void *
32046521ca2SGaetan Rivet rte_pci_dev_iterate(const void *start,
32146521ca2SGaetan Rivet 		    const char *str,
32246521ca2SGaetan Rivet 		    const struct rte_dev_iterator *it);
32346521ca2SGaetan Rivet 
324d2a66ad7SXueming Li /*
325d2a66ad7SXueming Li  * Parse device arguments and update name.
326d2a66ad7SXueming Li  *
327d2a66ad7SXueming Li  * @param da
328d2a66ad7SXueming Li  *   device arguments to parse.
329d2a66ad7SXueming Li  *
330d2a66ad7SXueming Li  * @return
331d2a66ad7SXueming Li  *   0 on success.
332d2a66ad7SXueming Li  *   -EINVAL: kvargs string is invalid and cannot be parsed.
333d2a66ad7SXueming Li  *   -ENODEV: no key matching a device ID is found in the kv list.
334d2a66ad7SXueming Li  */
335d2a66ad7SXueming Li int
336d2a66ad7SXueming Li rte_pci_devargs_parse(struct rte_devargs *da);
337d2a66ad7SXueming Li 
338c752998bSGaetan Rivet #endif /* _PCI_PRIVATE_H_ */
339