3896cf093227e571f011668274be1c501f455b5e
[dpdk.git] / drivers / common / mlx5 / windows / mlx5_glue.c
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_utils.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 alignas(RTE_CACHE_LINE_SIZE)
287 const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){
288         .version = MLX5_GLUE_VERSION,
289         .get_device_list = mlx5_glue_devx_get_device_list,
290         .free_device_list = mlx5_glue_devx_free_device_list,
291         .open_device = mlx5_glue_devx_open_device,
292         .close_device = mlx5_glue_devx_close_device,
293         .query_device = mlx5_glue_devx_query_device,
294         .query_hca_iseg = mlx5_glue_devx_query_hca_iseg_mapping,
295         .devx_obj_create = mlx5_glue_devx_obj_create,
296         .devx_obj_destroy = mlx5_glue_devx_obj_destroy,
297         .devx_obj_query = mlx5_glue_devx_obj_query,
298         .devx_obj_modify = mlx5_glue_devx_obj_modify,
299         .devx_general_cmd = mlx5_glue_devx_general_cmd,
300         .devx_umem_reg = mlx5_glue_devx_umem_reg,
301         .devx_umem_dereg = mlx5_glue_devx_umem_dereg,
302         .devx_alloc_uar = mlx5_glue_devx_alloc_uar,
303         .devx_free_uar = mlx5_glue_devx_free_uar,
304         .devx_fs_rule_add = mlx5_glue_devx_fs_rule_add,
305         .devx_fs_rule_del = mlx5_glue_devx_fs_rule_del,
306         .devx_query_eqn = mlx5_glue_devx_query_eqn,
307 };