1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020 Mellanox Technologies, Ltd
3 */
4
5 #ifndef RTE_PMD_MLX5_COMMON_OS_H_
6 #define RTE_PMD_MLX5_COMMON_OS_H_
7
8 #include <stdio.h>
9 #include <malloc.h>
10
11 #include <rte_pci.h>
12 #include <rte_bus_pci.h>
13 #include <rte_debug.h>
14 #include <rte_atomic.h>
15 #include <rte_log.h>
16 #include <rte_kvargs.h>
17 #include <rte_devargs.h>
18
19 #include "mlx5_autoconf.h"
20 #include "mlx5_glue.h"
21 #include "mlx5_malloc.h"
22
23 /**
24 * Get device name. Given an ibv_device pointer - return a
25 * pointer to the corresponding device name.
26 *
27 * @param[in] dev
28 * Pointer to ibv device.
29 *
30 * @return
31 * Pointer to device name if dev is valid, NULL otherwise.
32 */
33 static inline const char *
mlx5_os_get_dev_device_name(void * dev)34 mlx5_os_get_dev_device_name(void *dev)
35 {
36 if (!dev)
37 return NULL;
38 return ((struct ibv_device *)dev)->name;
39 }
40
41 /**
42 * Get ibv device name. Given an ibv_context pointer - return a
43 * pointer to the corresponding device name.
44 *
45 * @param[in] ctx
46 * Pointer to ibv context.
47 *
48 * @return
49 * Pointer to device name if ctx is valid, NULL otherwise.
50 */
51 static inline const char *
mlx5_os_get_ctx_device_name(void * ctx)52 mlx5_os_get_ctx_device_name(void *ctx)
53 {
54 if (!ctx)
55 return NULL;
56 return ((struct ibv_context *)ctx)->device->name;
57 }
58
59 /**
60 * Get ibv device path name. Given an ibv_context pointer - return a
61 * pointer to the corresponding device path name.
62 *
63 * @param[in] ctx
64 * Pointer to ibv context.
65 *
66 * @return
67 * Pointer to device path name if ctx is valid, NULL otherwise.
68 */
69
70 static inline const char *
mlx5_os_get_ctx_device_path(void * ctx)71 mlx5_os_get_ctx_device_path(void *ctx)
72 {
73 if (!ctx)
74 return NULL;
75
76 return ((struct ibv_context *)ctx)->device->ibdev_path;
77 }
78
79 /**
80 * Get umem id. Given a pointer to umem object of type
81 * 'struct mlx5dv_devx_umem *' - return its id.
82 *
83 * @param[in] umem
84 * Pointer to umem object.
85 *
86 * @return
87 * The umem id if umem is valid, 0 otherwise.
88 */
89 static inline uint32_t
mlx5_os_get_umem_id(void * umem)90 mlx5_os_get_umem_id(void *umem)
91 {
92 if (!umem)
93 return 0;
94 return ((struct mlx5dv_devx_umem *)umem)->umem_id;
95 }
96
97 /**
98 * Get fd. Given a pointer to DevX channel object of type
99 * 'struct mlx5dv_devx_event_channel*' - return its fd.
100 *
101 * @param[in] channel
102 * Pointer to channel object.
103 *
104 * @return
105 * The fd if channel is valid, 0 otherwise.
106 */
107 static inline int
mlx5_os_get_devx_channel_fd(void * channel)108 mlx5_os_get_devx_channel_fd(void *channel)
109 {
110 if (!channel)
111 return 0;
112 return ((struct mlx5dv_devx_event_channel *)channel)->fd;
113 }
114
115 /**
116 * Get mmap offset. Given a pointer to an DevX UAR object of type
117 * 'struct mlx5dv_devx_uar *' - return its mmap offset.
118 *
119 * @param[in] uar
120 * Pointer to UAR object.
121 *
122 * @return
123 * The mmap offset if uar is valid, 0 otherwise.
124 */
125 static inline off_t
mlx5_os_get_devx_uar_mmap_offset(void * uar)126 mlx5_os_get_devx_uar_mmap_offset(void *uar)
127 {
128 #ifdef HAVE_MLX5DV_DEVX_UAR_OFFSET
129 if (!uar)
130 return 0;
131 return ((struct mlx5dv_devx_uar *)uar)->mmap_off;
132 #else
133 RTE_SET_USED(uar);
134 return 0;
135 #endif
136 }
137
138 /**
139 * Get base addr pointer. Given a pointer to an UAR object of type
140 * 'struct mlx5dv_devx_uar *' - return its base address.
141 *
142 * @param[in] uar
143 * Pointer to an UAR object.
144 *
145 * @return
146 * The base address if UAR is valid, 0 otherwise.
147 */
148 static inline void *
mlx5_os_get_devx_uar_base_addr(void * uar)149 mlx5_os_get_devx_uar_base_addr(void *uar)
150 {
151 #ifdef HAVE_MLX5DV_DEVX_UAR_OFFSET
152 if (!uar)
153 return NULL;
154 return ((struct mlx5dv_devx_uar *)uar)->base_addr;
155 #else
156 RTE_SET_USED(uar);
157 return NULL;
158 #endif
159 }
160
161 /**
162 * Get reg addr pointer. Given a pointer to an UAR object of type
163 * 'struct mlx5dv_devx_uar *' - return its reg address.
164 *
165 * @param[in] uar
166 * Pointer to an UAR object.
167 *
168 * @return
169 * The reg address if UAR is valid, 0 otherwise.
170 */
171 static inline void *
mlx5_os_get_devx_uar_reg_addr(void * uar)172 mlx5_os_get_devx_uar_reg_addr(void *uar)
173 {
174 #ifdef HAVE_MLX5DV_DEVX_UAR_OFFSET
175 if (!uar)
176 return NULL;
177 return ((struct mlx5dv_devx_uar *)uar)->reg_addr;
178 #else
179 RTE_SET_USED(uar);
180 return NULL;
181 #endif
182 }
183
184 /**
185 * Get page id. Given a pointer to an UAR object of type
186 * 'struct mlx5dv_devx_uar *' - return its page id.
187 *
188 * @param[in] uar
189 * Pointer to an UAR object.
190 *
191 * @return
192 * The page id if UAR is valid, 0 otherwise.
193 */
194 static inline uint32_t
mlx5_os_get_devx_uar_page_id(void * uar)195 mlx5_os_get_devx_uar_page_id(void *uar)
196 {
197 #ifdef HAVE_MLX5DV_DEVX_UAR_OFFSET
198 if (!uar)
199 return 0;
200 return ((struct mlx5dv_devx_uar *)uar)->page_id;
201 #else
202 RTE_SET_USED(uar);
203 return 0;
204 #endif
205 }
206
207 __rte_internal
208 static inline void *
mlx5_os_umem_reg(void * ctx,void * addr,size_t size,uint32_t access)209 mlx5_os_umem_reg(void *ctx, void *addr, size_t size, uint32_t access)
210 {
211 return mlx5_glue->devx_umem_reg(ctx, addr, size, access);
212 }
213
214 __rte_internal
215 static inline int
mlx5_os_umem_dereg(void * pumem)216 mlx5_os_umem_dereg(void *pumem)
217 {
218 return mlx5_glue->devx_umem_dereg(pumem);
219 }
220
221 static inline void *
mlx5_os_devx_create_event_channel(void * ctx,int flags)222 mlx5_os_devx_create_event_channel(void *ctx, int flags)
223 {
224 return mlx5_glue->devx_create_event_channel(ctx, flags);
225 }
226
227 static inline void
mlx5_os_devx_destroy_event_channel(void * eventc)228 mlx5_os_devx_destroy_event_channel(void *eventc)
229 {
230 mlx5_glue->devx_destroy_event_channel(eventc);
231 }
232
233 static inline int
mlx5_os_devx_subscribe_devx_event(void * eventc,void * obj,uint16_t events_sz,uint16_t events_num[],uint64_t cookie)234 mlx5_os_devx_subscribe_devx_event(void *eventc,
235 void *obj,
236 uint16_t events_sz, uint16_t events_num[],
237 uint64_t cookie)
238 {
239 return mlx5_glue->devx_subscribe_devx_event(eventc, obj, events_sz,
240 events_num, cookie);
241 }
242
243 /**
244 * Memory allocation optionally with alignment.
245 *
246 * @param[in] align
247 * Alignment size (may be zero)
248 * @param[in] size
249 * Size in bytes to allocate
250 *
251 * @return
252 * Valid pointer to allocated memory, NULL in case of failure
253 */
254 static inline void *
mlx5_os_malloc(size_t align,size_t size)255 mlx5_os_malloc(size_t align, size_t size)
256 {
257 void *buf;
258
259 if (posix_memalign(&buf, align, size))
260 return NULL;
261 return buf;
262 }
263
264 /**
265 * This API de-allocates a memory that originally could have been
266 * allocated aligned or non-aligned. In Linux it is a wrapper
267 * around free().
268 *
269 * @param[in] addr
270 * Pointer to address to free
271 *
272 */
273 static inline void
mlx5_os_free(void * addr)274 mlx5_os_free(void *addr)
275 {
276 free(addr);
277 }
278
279 void
280 mlx5_set_context_attr(struct rte_device *dev, struct ibv_context *ctx);
281
282 /**
283 * This is used to query system_image_guid as describing in PRM.
284 *
285 * @param dev[in]
286 * Pointer to a device instance as PCIe id.
287 * @param guid[out]
288 * Pointer to the buffer to hold device guid.
289 * Guid is uint64_t and corresponding to 17 bytes string.
290 * @param len[in]
291 * Guid buffer length, 17 bytes at least.
292 *
293 * @return
294 * -1 if internal failure.
295 * 0 if OFED doesn't support.
296 * >0 if success.
297 */
298 __rte_internal
299 int
300 mlx5_get_device_guid(const struct rte_pci_addr *dev, uint8_t *guid, size_t len);
301
302 #endif /* RTE_PMD_MLX5_COMMON_OS_H_ */
303