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 static int 332 mlx5_glue_devx_set_promisc_vport(void *ctx, uint32_t promisc_type, uint8_t f_enable) 333 { 334 #ifdef HAVE_DEVX_SET_PROMISC_SUPPORT 335 int devx_promisc_type = MLX5_DEVX_SET_PROMISC_VPORT_PROMISC_MODE; 336 struct mlx5_context *mlx5_ctx; 337 int err; 338 339 if (!ctx) { 340 errno = EINVAL; 341 return errno; 342 } 343 mlx5_ctx = (struct mlx5_context *)ctx; 344 if (promisc_type == MC_PROMISC) 345 devx_promisc_type = MLX5_DEVX_SET_PROMISC_VPORT_ALL_MULTICAST; 346 err = devx_set_promisc_vport(mlx5_ctx->devx_ctx, devx_promisc_type, f_enable); 347 if (err) { 348 errno = err; 349 return errno; 350 } 351 return 0; 352 #else 353 (void)promisc_type; 354 (void)f_enable; 355 (void)ctx; 356 DRV_LOG(WARNING, "%s: is not supported", __func__); 357 return -ENOTSUP; 358 #endif 359 } 360 361 static int 362 mlx5_glue_devx_get_mtu(void *ctx, uint32_t *mtu) 363 { 364 int err = 0; 365 struct mlx5_context *mlx5_ctx; 366 367 if (!ctx) { 368 errno = EINVAL; 369 return errno; 370 } 371 mlx5_ctx = (struct mlx5_context *)ctx; 372 #ifdef HAVE_DEVX_SET_GET_MTU_SUPPORT 373 err = devx_get_mtu(mlx5_ctx->devx_ctx, mtu); 374 if (err) { 375 errno = err; 376 return errno; 377 } 378 #else 379 *mtu = mlx5_ctx->mlx5_dev.mtu_bytes; 380 #endif 381 382 return err; 383 } 384 385 static int 386 mlx5_glue_devx_set_mtu(void *ctx, uint32_t mtu) 387 { 388 #ifdef HAVE_DEVX_SET_GET_MTU_SUPPORT 389 struct mlx5_context *mlx5_ctx; 390 int err; 391 392 if (!ctx) { 393 errno = EINVAL; 394 return errno; 395 } 396 mlx5_ctx = (struct mlx5_context *)ctx; 397 err = devx_set_mtu(mlx5_ctx->devx_ctx, mtu); 398 if (err) { 399 errno = err; 400 return errno; 401 } 402 return 0; 403 #else 404 (void)mtu; 405 (void)ctx; 406 DRV_LOG(WARNING, "%s: is not supported", __func__); 407 return -ENOTSUP; 408 #endif 409 410 } 411 412 413 414 alignas(RTE_CACHE_LINE_SIZE) 415 const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ 416 .version = MLX5_GLUE_VERSION, 417 .get_device_list = mlx5_glue_devx_get_device_list, 418 .free_device_list = mlx5_glue_devx_free_device_list, 419 .open_device = mlx5_glue_devx_open_device, 420 .close_device = mlx5_glue_devx_close_device, 421 .query_device = mlx5_glue_devx_query_device, 422 .query_hca_iseg = mlx5_glue_devx_query_hca_iseg_mapping, 423 .devx_obj_create = mlx5_glue_devx_obj_create, 424 .devx_obj_destroy = mlx5_glue_devx_obj_destroy, 425 .devx_obj_query = mlx5_glue_devx_obj_query, 426 .devx_obj_modify = mlx5_glue_devx_obj_modify, 427 .devx_general_cmd = mlx5_glue_devx_general_cmd, 428 .devx_umem_reg = mlx5_glue_devx_umem_reg, 429 .devx_umem_dereg = mlx5_glue_devx_umem_dereg, 430 .devx_alloc_uar = mlx5_glue_devx_alloc_uar, 431 .devx_free_uar = mlx5_glue_devx_free_uar, 432 .devx_fs_rule_add = mlx5_glue_devx_fs_rule_add, 433 .devx_fs_rule_del = mlx5_glue_devx_fs_rule_del, 434 .devx_query_eqn = mlx5_glue_devx_query_eqn, 435 .query_rt_values = mlx5_glue_query_rt_values, 436 .devx_init_showdown_event = mlx5_glue_devx_init_showdown_event, 437 .devx_set_promisc_vport = mlx5_glue_devx_set_promisc_vport, 438 .devx_get_mtu = mlx5_glue_devx_get_mtu, 439 .devx_set_mtu = mlx5_glue_devx_set_mtu, 440 }; 441