xref: /dpdk/drivers/common/mlx5/windows/mlx5_glue.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  */
4 
5 #include <errno.h>
6 #include <stdalign.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 
12 #include <rte_malloc.h>
13 
14 #include "mlx5_glue.h"
15 #include "../mlx5_common_log.h"
16 #include "mlx5_win_ext.h"
17 
18 /*
19  * The returned value of this API is an array of pointers to mlx5
20  * devices under Windows. The interesting parameters of a device:
21  * Device PCI parameters: domain, bus, device id, function.
22  * Device name.
23  */
24 static void *
25 mlx5_glue_devx_get_device_list(int *num_devices)
26 {
27 	struct devx_device_bdf *devx_bdf_devs = NULL;
28 	size_t n_devx_devx = 0;
29 	int32_t ret = devx_get_device_list(&n_devx_devx, &devx_bdf_devs);
30 
31 	if (ret) {
32 		errno = ret;
33 		*num_devices = 0;
34 		return NULL;
35 	}
36 	*num_devices = (int)n_devx_devx;
37 	return devx_bdf_devs;
38 }
39 
40 static void
41 mlx5_glue_devx_free_device_list(void *list)
42 {
43 	if (!list) {
44 		errno = EINVAL;
45 		return;
46 	}
47 	devx_free_device_list(list);
48 }
49 
50 static int
51 mlx5_glue_devx_close_device(void *ctx)
52 {
53 	mlx5_context_st *mlx5_ctx;
54 	int rc;
55 
56 	if (!ctx)
57 		return -EINVAL;
58 	mlx5_ctx = (mlx5_context_st *)ctx;
59 	rc = devx_close_device(mlx5_ctx->devx_ctx);
60 	free(mlx5_ctx);
61 	return rc;
62 }
63 
64 static void *
65 mlx5_glue_devx_open_device(void *device)
66 {
67 	struct mlx5_context *mlx5_ctx;
68 
69 	if (!device) {
70 		errno = EINVAL;
71 		return NULL;
72 	}
73 	mlx5_ctx = malloc((sizeof(struct mlx5_context)));
74 	if (!mlx5_ctx) {
75 		errno = ENOMEM;
76 		return NULL;
77 	}
78 	memset(mlx5_ctx, 0, sizeof(*mlx5_ctx));
79 	mlx5_ctx->devx_ctx = devx_open_device(device);
80 	if (DEVX_IS_ERR(mlx5_ctx->devx_ctx)) {
81 		errno = -DEVX_PTR_ERR(mlx5_ctx->devx_ctx);
82 		free(mlx5_ctx);
83 		return NULL;
84 	}
85 	return mlx5_ctx;
86 }
87 
88 static int
89 mlx5_glue_devx_query_device(void *device_bdf, void *dev_inf)
90 {
91 	struct devx_device_bdf *dev_bdf;
92 	struct devx_device *mlx5_dev;
93 
94 	if (!device_bdf)
95 		return -EINVAL;
96 	dev_bdf = (struct devx_device_bdf *)device_bdf;
97 	mlx5_dev = (struct devx_device *)dev_inf;
98 	int err = devx_query_device(dev_bdf, mlx5_dev);
99 	if (err)
100 		return -E_FAIL;
101 	return 0;
102 }
103 
104 static void *
105 mlx5_glue_devx_query_hca_iseg_mapping(void *ctx, uint32_t *cb_iseg)
106 {
107 	struct mlx5_context *mlx5_ctx;
108 	void *pv_iseg;
109 	int err;
110 
111 	if (!ctx) {
112 		errno = EINVAL;
113 		return NULL;
114 	}
115 	mlx5_ctx = (struct mlx5_context *)ctx;
116 	err = devx_query_hca_iseg_mapping(mlx5_ctx->devx_ctx,
117 						cb_iseg, &pv_iseg);
118 	if (err) {
119 		errno = err;
120 		return NULL;
121 	}
122 	return pv_iseg;
123 }
124 
125 static void *
126 mlx5_glue_devx_obj_create(void *ctx,
127 			      void *in, size_t inlen,
128 			      void *out, size_t outlen)
129 {
130 	mlx5_devx_obj_st *devx_obj;
131 
132 	if (!ctx) {
133 		errno = EINVAL;
134 		return NULL;
135 	}
136 	devx_obj = malloc((sizeof(*devx_obj)));
137 	if (!devx_obj) {
138 		errno = ENOMEM;
139 		return NULL;
140 	}
141 	memset(devx_obj, 0, sizeof(*devx_obj));
142 	devx_obj->devx_ctx = GET_DEVX_CTX(ctx);
143 	devx_obj->obj = devx_obj_create(devx_obj->devx_ctx,
144 					in, inlen, out, outlen);
145 	if (DEVX_IS_ERR(devx_obj->obj)) {
146 		errno = -DEVX_PTR_ERR(devx_obj->obj);
147 		free(devx_obj);
148 		return NULL;
149 	}
150 	return devx_obj;
151 }
152 
153 static int
154 mlx5_glue_devx_obj_destroy(void *obj)
155 {
156 	mlx5_devx_obj_st *devx_obj;
157 
158 	if (!obj)
159 		return -EINVAL;
160 	devx_obj = obj;
161 	int rc = devx_obj_destroy(devx_obj->obj);
162 	free(devx_obj);
163 	return rc;
164 }
165 
166 static int
167 mlx5_glue_devx_general_cmd(void *ctx,
168 			   void *in, size_t inlen,
169 			   void *out, size_t outlen)
170 {
171 	if (!ctx)
172 		return -EINVAL;
173 	return devx_cmd(GET_DEVX_CTX(ctx), in, inlen, out, outlen);
174 }
175 
176 static int
177 mlx5_glue_devx_obj_query(void *obj,
178 			    void *in, size_t inlen,
179 			    void *out, size_t outlen)
180 {
181 	return devx_cmd(GET_OBJ_CTX(obj), in, inlen, out, outlen);
182 }
183 
184 static int
185 mlx5_glue_devx_obj_modify(void *obj,
186 			    void *in, size_t inlen,
187 			    void *out, size_t outlen)
188 {
189 	return devx_cmd(GET_OBJ_CTX(obj), in, inlen, out, outlen);
190 }
191 
192 static int
193 mlx5_glue_devx_umem_dereg(void *pumem)
194 {
195 	struct devx_obj_handle *umem;
196 
197 	if (!pumem)
198 		return -EINVAL;
199 	umem = pumem;
200 	return devx_umem_unreg(umem);
201 }
202 
203 static void *
204 mlx5_glue_devx_umem_reg(void *ctx, void *addr, size_t size,
205 				  uint32_t access, uint32_t *id)
206 {
207 	struct devx_obj_handle *umem_hdl;
208 	int w_access = DEVX_UMEM_ACCESS_READ;
209 
210 	if (!ctx) {
211 		errno = EINVAL;
212 		return NULL;
213 	}
214 	if (access)
215 		w_access |= DEVX_UMEM_ACCESS_WRITE;
216 
217 	umem_hdl = devx_umem_reg(GET_DEVX_CTX(ctx), addr,
218 					size, w_access, id);
219 	if (DEVX_IS_ERR(umem_hdl)) {
220 		errno = -DEVX_PTR_ERR(umem_hdl);
221 		return NULL;
222 	}
223 	return umem_hdl;
224 }
225 
226 static void *
227 mlx5_glue_devx_alloc_uar(void *ctx,
228 		uint32_t flags)
229 {
230 	devx_uar_handle *uar;
231 
232 	if (!ctx) {
233 		errno = EINVAL;
234 		return NULL;
235 	}
236 	uar = devx_alloc_uar(GET_DEVX_CTX(ctx), flags);
237 	if (DEVX_IS_ERR(uar)) {
238 		errno = -DEVX_PTR_ERR(uar);
239 		return NULL;
240 	}
241 	return uar;
242 }
243 
244 static int
245 mlx5_glue_devx_query_eqn(void *ctx,
246 		uint32_t cpus, uint32_t *eqn)
247 {
248 	if (!ctx)
249 		return -EINVAL;
250 	return devx_query_eqn(GET_DEVX_CTX(ctx), cpus, eqn);
251 }
252 
253 static void
254 mlx5_glue_devx_free_uar(void *uar)
255 {
256 	devx_free_uar((devx_uar_handle *)uar);
257 }
258 
259 static_assert(MLX5_ST_SZ_BYTES(fte_match_param) == 0x200,
260 	"PRM size of fte_match_param is broken! cannot compile Windows!");
261 
262 static void*
263 mlx5_glue_devx_fs_rule_add(void *ctx, void *in, uint32_t inlen)
264 
265 {
266 	struct devx_obj_handle *rule_hdl = NULL;
267 
268 	if (!ctx) {
269 		errno = EINVAL;
270 		return NULL;
271 	}
272 	rule_hdl = devx_fs_rule_add(GET_DEVX_CTX(ctx), in, inlen);
273 	if (DEVX_IS_ERR(rule_hdl)) {
274 		errno = -DEVX_PTR_ERR(rule_hdl);
275 		return NULL;
276 	}
277 	return rule_hdl;
278 }
279 
280 static int
281 mlx5_glue_devx_fs_rule_del(void *flow)
282 {
283 	return devx_fs_rule_del(flow);
284 }
285 
286 static int
287 mlx5_glue_query_rt_values(void *ctx, void *devx_clock)
288 {
289 	struct mlx5_context *mlx5_ctx;
290 	struct mlx5_devx_clock *clock;
291 	int err;
292 
293 	if (!ctx) {
294 		errno = EINVAL;
295 		return errno;
296 	}
297 	mlx5_ctx = (struct mlx5_context *)ctx;
298 	clock = (struct mlx5_devx_clock *)devx_clock;
299 	err = devx_hca_clock_query(
300 			mlx5_ctx->devx_ctx,
301 			&clock->p_iseg_internal_timer,
302 			&clock->clock_frequency_hz,
303 			&clock->is_stable_clock_frequency);
304 	if (err) {
305 		errno = err;
306 		return errno;
307 	}
308 	return 0;
309 }
310 
311 static int
312 mlx5_glue_devx_init_showdown_event(void *ctx)
313 {
314 	struct mlx5_context *mlx5_ctx;
315 	int err;
316 
317 	if (!ctx) {
318 		errno = EINVAL;
319 		return errno;
320 	}
321 	mlx5_ctx = (struct mlx5_context *)ctx;
322 	err = devx_query_shutdown_event(mlx5_ctx->devx_ctx,
323 			&mlx5_ctx->shutdown_event_obj);
324 	if (err) {
325 		errno = err;
326 		return errno;
327 	}
328 	return 0;
329 }
330 
331 alignas(RTE_CACHE_LINE_SIZE)
332 const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){
333 	.version = MLX5_GLUE_VERSION,
334 	.get_device_list = mlx5_glue_devx_get_device_list,
335 	.free_device_list = mlx5_glue_devx_free_device_list,
336 	.open_device = mlx5_glue_devx_open_device,
337 	.close_device = mlx5_glue_devx_close_device,
338 	.query_device = mlx5_glue_devx_query_device,
339 	.query_hca_iseg = mlx5_glue_devx_query_hca_iseg_mapping,
340 	.devx_obj_create = mlx5_glue_devx_obj_create,
341 	.devx_obj_destroy = mlx5_glue_devx_obj_destroy,
342 	.devx_obj_query = mlx5_glue_devx_obj_query,
343 	.devx_obj_modify = mlx5_glue_devx_obj_modify,
344 	.devx_general_cmd = mlx5_glue_devx_general_cmd,
345 	.devx_umem_reg = mlx5_glue_devx_umem_reg,
346 	.devx_umem_dereg = mlx5_glue_devx_umem_dereg,
347 	.devx_alloc_uar = mlx5_glue_devx_alloc_uar,
348 	.devx_free_uar = mlx5_glue_devx_free_uar,
349 	.devx_fs_rule_add = mlx5_glue_devx_fs_rule_add,
350 	.devx_fs_rule_del = mlx5_glue_devx_fs_rule_del,
351 	.devx_query_eqn = mlx5_glue_devx_query_eqn,
352 	.query_rt_values = mlx5_glue_query_rt_values,
353 	.devx_init_showdown_event = mlx5_glue_devx_init_showdown_event,
354 };
355