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