17525ebd8STal Shnaiderman /* SPDX-License-Identifier: BSD-3-Clause 27525ebd8STal Shnaiderman * Copyright 2020 Mellanox Technologies, Ltd 37525ebd8STal Shnaiderman */ 47525ebd8STal Shnaiderman 57525ebd8STal Shnaiderman #include <errno.h> 67525ebd8STal Shnaiderman #include <stdalign.h> 77525ebd8STal Shnaiderman #include <stddef.h> 87525ebd8STal Shnaiderman #include <stdint.h> 97525ebd8STal Shnaiderman #include <stdlib.h> 107525ebd8STal Shnaiderman #include <unistd.h> 117525ebd8STal Shnaiderman 127525ebd8STal Shnaiderman #include <rte_malloc.h> 137525ebd8STal Shnaiderman 147525ebd8STal Shnaiderman #include "mlx5_glue.h" 15*25245d5dSShiri Kuzin #include "../mlx5_common_log.h" 167525ebd8STal Shnaiderman #include "mlx5_win_ext.h" 177525ebd8STal Shnaiderman 187525ebd8STal Shnaiderman /* 197525ebd8STal Shnaiderman * The returned value of this API is an array of pointers to mlx5 207525ebd8STal Shnaiderman * devices under Windows. The interesting parameters of a device: 217525ebd8STal Shnaiderman * Device PCI parameters: domain, bus, device id, function. 227525ebd8STal Shnaiderman * Device name. 237525ebd8STal Shnaiderman */ 247525ebd8STal Shnaiderman static void * 257525ebd8STal Shnaiderman mlx5_glue_devx_get_device_list(int *num_devices) 267525ebd8STal Shnaiderman { 277525ebd8STal Shnaiderman struct devx_device_bdf *devx_bdf_devs = NULL; 287525ebd8STal Shnaiderman size_t n_devx_devx = 0; 297525ebd8STal Shnaiderman int32_t ret = devx_get_device_list(&n_devx_devx, &devx_bdf_devs); 307525ebd8STal Shnaiderman 317525ebd8STal Shnaiderman if (ret) { 327525ebd8STal Shnaiderman errno = ret; 337525ebd8STal Shnaiderman *num_devices = 0; 347525ebd8STal Shnaiderman return NULL; 357525ebd8STal Shnaiderman } 367525ebd8STal Shnaiderman *num_devices = (int)n_devx_devx; 377525ebd8STal Shnaiderman return devx_bdf_devs; 387525ebd8STal Shnaiderman } 397525ebd8STal Shnaiderman 407525ebd8STal Shnaiderman static void 417525ebd8STal Shnaiderman mlx5_glue_devx_free_device_list(void *list) 427525ebd8STal Shnaiderman { 437525ebd8STal Shnaiderman if (!list) { 447525ebd8STal Shnaiderman errno = EINVAL; 457525ebd8STal Shnaiderman return; 467525ebd8STal Shnaiderman } 477525ebd8STal Shnaiderman devx_free_device_list(list); 487525ebd8STal Shnaiderman } 497525ebd8STal Shnaiderman 507525ebd8STal Shnaiderman static int 517525ebd8STal Shnaiderman mlx5_glue_devx_close_device(void *ctx) 527525ebd8STal Shnaiderman { 537525ebd8STal Shnaiderman mlx5_context_st *mlx5_ctx; 547525ebd8STal Shnaiderman int rc; 557525ebd8STal Shnaiderman 567525ebd8STal Shnaiderman if (!ctx) 577525ebd8STal Shnaiderman return -EINVAL; 587525ebd8STal Shnaiderman mlx5_ctx = (mlx5_context_st *)ctx; 597525ebd8STal Shnaiderman rc = devx_close_device(mlx5_ctx->devx_ctx); 607525ebd8STal Shnaiderman free(mlx5_ctx); 617525ebd8STal Shnaiderman return rc; 627525ebd8STal Shnaiderman } 637525ebd8STal Shnaiderman 647525ebd8STal Shnaiderman static void * 657525ebd8STal Shnaiderman mlx5_glue_devx_open_device(void *device) 667525ebd8STal Shnaiderman { 677525ebd8STal Shnaiderman struct mlx5_context *mlx5_ctx; 687525ebd8STal Shnaiderman 697525ebd8STal Shnaiderman if (!device) { 707525ebd8STal Shnaiderman errno = EINVAL; 717525ebd8STal Shnaiderman return NULL; 727525ebd8STal Shnaiderman } 737525ebd8STal Shnaiderman mlx5_ctx = malloc((sizeof(struct mlx5_context))); 747525ebd8STal Shnaiderman if (!mlx5_ctx) { 757525ebd8STal Shnaiderman errno = ENOMEM; 767525ebd8STal Shnaiderman return NULL; 777525ebd8STal Shnaiderman } 787525ebd8STal Shnaiderman memset(mlx5_ctx, 0, sizeof(*mlx5_ctx)); 797525ebd8STal Shnaiderman mlx5_ctx->devx_ctx = devx_open_device(device); 807525ebd8STal Shnaiderman if (DEVX_IS_ERR(mlx5_ctx->devx_ctx)) { 817525ebd8STal Shnaiderman errno = -DEVX_PTR_ERR(mlx5_ctx->devx_ctx); 827525ebd8STal Shnaiderman free(mlx5_ctx); 837525ebd8STal Shnaiderman return NULL; 847525ebd8STal Shnaiderman } 857525ebd8STal Shnaiderman return mlx5_ctx; 867525ebd8STal Shnaiderman } 877525ebd8STal Shnaiderman 887525ebd8STal Shnaiderman static int 897525ebd8STal Shnaiderman mlx5_glue_devx_query_device(void *device_bdf, void *dev_inf) 907525ebd8STal Shnaiderman { 917525ebd8STal Shnaiderman struct devx_device_bdf *dev_bdf; 927525ebd8STal Shnaiderman struct devx_device *mlx5_dev; 937525ebd8STal Shnaiderman 947525ebd8STal Shnaiderman if (!device_bdf) 957525ebd8STal Shnaiderman return -EINVAL; 967525ebd8STal Shnaiderman dev_bdf = (struct devx_device_bdf *)device_bdf; 977525ebd8STal Shnaiderman mlx5_dev = (struct devx_device *)dev_inf; 987525ebd8STal Shnaiderman int err = devx_query_device(dev_bdf, mlx5_dev); 997525ebd8STal Shnaiderman if (err) 1007525ebd8STal Shnaiderman return -E_FAIL; 1017525ebd8STal Shnaiderman return 0; 1027525ebd8STal Shnaiderman } 1037525ebd8STal Shnaiderman 1047525ebd8STal Shnaiderman static void * 1057525ebd8STal Shnaiderman mlx5_glue_devx_query_hca_iseg_mapping(void *ctx, uint32_t *cb_iseg) 1067525ebd8STal Shnaiderman { 1077525ebd8STal Shnaiderman struct mlx5_context *mlx5_ctx; 1087525ebd8STal Shnaiderman void *pv_iseg; 1097525ebd8STal Shnaiderman int err; 1107525ebd8STal Shnaiderman 1117525ebd8STal Shnaiderman if (!ctx) { 1127525ebd8STal Shnaiderman errno = EINVAL; 1137525ebd8STal Shnaiderman return NULL; 1147525ebd8STal Shnaiderman } 1157525ebd8STal Shnaiderman mlx5_ctx = (struct mlx5_context *)ctx; 1167525ebd8STal Shnaiderman err = devx_query_hca_iseg_mapping(mlx5_ctx->devx_ctx, 1177525ebd8STal Shnaiderman cb_iseg, &pv_iseg); 1187525ebd8STal Shnaiderman if (err) { 1197525ebd8STal Shnaiderman errno = err; 1207525ebd8STal Shnaiderman return NULL; 1217525ebd8STal Shnaiderman } 1227525ebd8STal Shnaiderman return pv_iseg; 1237525ebd8STal Shnaiderman } 1247525ebd8STal Shnaiderman 1257525ebd8STal Shnaiderman static void * 1267525ebd8STal Shnaiderman mlx5_glue_devx_obj_create(void *ctx, 1277525ebd8STal Shnaiderman void *in, size_t inlen, 1287525ebd8STal Shnaiderman void *out, size_t outlen) 1297525ebd8STal Shnaiderman { 1307525ebd8STal Shnaiderman mlx5_devx_obj_st *devx_obj; 1317525ebd8STal Shnaiderman 1327525ebd8STal Shnaiderman if (!ctx) { 1337525ebd8STal Shnaiderman errno = EINVAL; 1347525ebd8STal Shnaiderman return NULL; 1357525ebd8STal Shnaiderman } 1367525ebd8STal Shnaiderman devx_obj = malloc((sizeof(*devx_obj))); 1377525ebd8STal Shnaiderman if (!devx_obj) { 1387525ebd8STal Shnaiderman errno = ENOMEM; 1397525ebd8STal Shnaiderman return NULL; 1407525ebd8STal Shnaiderman } 1417525ebd8STal Shnaiderman memset(devx_obj, 0, sizeof(*devx_obj)); 1427525ebd8STal Shnaiderman devx_obj->devx_ctx = GET_DEVX_CTX(ctx); 1437525ebd8STal Shnaiderman devx_obj->obj = devx_obj_create(devx_obj->devx_ctx, 1447525ebd8STal Shnaiderman in, inlen, out, outlen); 1457525ebd8STal Shnaiderman if (DEVX_IS_ERR(devx_obj->obj)) { 1467525ebd8STal Shnaiderman errno = -DEVX_PTR_ERR(devx_obj->obj); 1477525ebd8STal Shnaiderman free(devx_obj); 1487525ebd8STal Shnaiderman return NULL; 1497525ebd8STal Shnaiderman } 1507525ebd8STal Shnaiderman return devx_obj; 1517525ebd8STal Shnaiderman } 1527525ebd8STal Shnaiderman 1537525ebd8STal Shnaiderman static int 1547525ebd8STal Shnaiderman mlx5_glue_devx_obj_destroy(void *obj) 1557525ebd8STal Shnaiderman { 1567525ebd8STal Shnaiderman mlx5_devx_obj_st *devx_obj; 1577525ebd8STal Shnaiderman 1587525ebd8STal Shnaiderman if (!obj) 1597525ebd8STal Shnaiderman return -EINVAL; 1607525ebd8STal Shnaiderman devx_obj = obj; 1617525ebd8STal Shnaiderman int rc = devx_obj_destroy(devx_obj->obj); 1627525ebd8STal Shnaiderman free(devx_obj); 1637525ebd8STal Shnaiderman return rc; 1647525ebd8STal Shnaiderman } 1657525ebd8STal Shnaiderman 1667525ebd8STal Shnaiderman static int 1677525ebd8STal Shnaiderman mlx5_glue_devx_general_cmd(void *ctx, 1687525ebd8STal Shnaiderman void *in, size_t inlen, 1697525ebd8STal Shnaiderman void *out, size_t outlen) 1707525ebd8STal Shnaiderman { 1717525ebd8STal Shnaiderman if (!ctx) 1727525ebd8STal Shnaiderman return -EINVAL; 1737525ebd8STal Shnaiderman return devx_cmd(GET_DEVX_CTX(ctx), in, inlen, out, outlen); 1747525ebd8STal Shnaiderman } 1757525ebd8STal Shnaiderman 1767525ebd8STal Shnaiderman static int 1777525ebd8STal Shnaiderman mlx5_glue_devx_obj_query(void *obj, 1787525ebd8STal Shnaiderman void *in, size_t inlen, 1797525ebd8STal Shnaiderman void *out, size_t outlen) 1807525ebd8STal Shnaiderman { 1817525ebd8STal Shnaiderman return devx_cmd(GET_OBJ_CTX(obj), in, inlen, out, outlen); 1827525ebd8STal Shnaiderman } 1837525ebd8STal Shnaiderman 1847525ebd8STal Shnaiderman static int 1857525ebd8STal Shnaiderman mlx5_glue_devx_obj_modify(void *obj, 1867525ebd8STal Shnaiderman void *in, size_t inlen, 1877525ebd8STal Shnaiderman void *out, size_t outlen) 1887525ebd8STal Shnaiderman { 1897525ebd8STal Shnaiderman return devx_cmd(GET_OBJ_CTX(obj), in, inlen, out, outlen); 1907525ebd8STal Shnaiderman } 1917525ebd8STal Shnaiderman 1927525ebd8STal Shnaiderman static int 1937525ebd8STal Shnaiderman mlx5_glue_devx_umem_dereg(void *pumem) 1947525ebd8STal Shnaiderman { 1957525ebd8STal Shnaiderman struct devx_obj_handle *umem; 1967525ebd8STal Shnaiderman 1977525ebd8STal Shnaiderman if (!pumem) 1987525ebd8STal Shnaiderman return -EINVAL; 1997525ebd8STal Shnaiderman umem = pumem; 2007525ebd8STal Shnaiderman return devx_umem_unreg(umem); 2017525ebd8STal Shnaiderman } 2027525ebd8STal Shnaiderman 2037525ebd8STal Shnaiderman static void * 2047525ebd8STal Shnaiderman mlx5_glue_devx_umem_reg(void *ctx, void *addr, size_t size, 2057525ebd8STal Shnaiderman uint32_t access, uint32_t *id) 2067525ebd8STal Shnaiderman { 2077525ebd8STal Shnaiderman struct devx_obj_handle *umem_hdl; 2087525ebd8STal Shnaiderman int w_access = DEVX_UMEM_ACCESS_READ; 2097525ebd8STal Shnaiderman 2107525ebd8STal Shnaiderman if (!ctx) { 2117525ebd8STal Shnaiderman errno = EINVAL; 2127525ebd8STal Shnaiderman return NULL; 2137525ebd8STal Shnaiderman } 2147525ebd8STal Shnaiderman if (access) 2157525ebd8STal Shnaiderman w_access |= DEVX_UMEM_ACCESS_WRITE; 2167525ebd8STal Shnaiderman 2177525ebd8STal Shnaiderman umem_hdl = devx_umem_reg(GET_DEVX_CTX(ctx), addr, 2187525ebd8STal Shnaiderman size, w_access, id); 2197525ebd8STal Shnaiderman if (DEVX_IS_ERR(umem_hdl)) { 2207525ebd8STal Shnaiderman errno = -DEVX_PTR_ERR(umem_hdl); 2217525ebd8STal Shnaiderman return NULL; 2227525ebd8STal Shnaiderman } 2237525ebd8STal Shnaiderman return umem_hdl; 2247525ebd8STal Shnaiderman } 2257525ebd8STal Shnaiderman 2267525ebd8STal Shnaiderman static void * 2277525ebd8STal Shnaiderman mlx5_glue_devx_alloc_uar(void *ctx, 2287525ebd8STal Shnaiderman uint32_t flags) 2297525ebd8STal Shnaiderman { 2307525ebd8STal Shnaiderman devx_uar_handle *uar; 2317525ebd8STal Shnaiderman 2327525ebd8STal Shnaiderman if (!ctx) { 2337525ebd8STal Shnaiderman errno = EINVAL; 2347525ebd8STal Shnaiderman return NULL; 2357525ebd8STal Shnaiderman } 2367525ebd8STal Shnaiderman uar = devx_alloc_uar(GET_DEVX_CTX(ctx), flags); 2377525ebd8STal Shnaiderman if (DEVX_IS_ERR(uar)) { 2387525ebd8STal Shnaiderman errno = -DEVX_PTR_ERR(uar); 2397525ebd8STal Shnaiderman return NULL; 2407525ebd8STal Shnaiderman } 2417525ebd8STal Shnaiderman return uar; 2427525ebd8STal Shnaiderman } 2437525ebd8STal Shnaiderman 2447525ebd8STal Shnaiderman static int 2457525ebd8STal Shnaiderman mlx5_glue_devx_query_eqn(void *ctx, 2467525ebd8STal Shnaiderman uint32_t cpus, uint32_t *eqn) 2477525ebd8STal Shnaiderman { 2487525ebd8STal Shnaiderman if (!ctx) 2497525ebd8STal Shnaiderman return -EINVAL; 2507525ebd8STal Shnaiderman return devx_query_eqn(GET_DEVX_CTX(ctx), cpus, eqn); 2517525ebd8STal Shnaiderman } 2527525ebd8STal Shnaiderman 2537525ebd8STal Shnaiderman static void 2547525ebd8STal Shnaiderman mlx5_glue_devx_free_uar(void *uar) 2557525ebd8STal Shnaiderman { 2567525ebd8STal Shnaiderman devx_free_uar((devx_uar_handle *)uar); 2577525ebd8STal Shnaiderman } 2587525ebd8STal Shnaiderman 259e961c8e3STal Shnaiderman static_assert(MLX5_ST_SZ_BYTES(fte_match_param) == 0x200, 260e961c8e3STal Shnaiderman "PRM size of fte_match_param is broken! cannot compile Windows!"); 261e961c8e3STal Shnaiderman 2627525ebd8STal Shnaiderman static void* 2637525ebd8STal Shnaiderman mlx5_glue_devx_fs_rule_add(void *ctx, void *in, uint32_t inlen) 2647525ebd8STal Shnaiderman 2657525ebd8STal Shnaiderman { 2667525ebd8STal Shnaiderman struct devx_obj_handle *rule_hdl = NULL; 2677525ebd8STal Shnaiderman 2687525ebd8STal Shnaiderman if (!ctx) { 2697525ebd8STal Shnaiderman errno = EINVAL; 2707525ebd8STal Shnaiderman return NULL; 2717525ebd8STal Shnaiderman } 2727525ebd8STal Shnaiderman rule_hdl = devx_fs_rule_add(GET_DEVX_CTX(ctx), in, inlen); 2737525ebd8STal Shnaiderman if (DEVX_IS_ERR(rule_hdl)) { 2747525ebd8STal Shnaiderman errno = -DEVX_PTR_ERR(rule_hdl); 2757525ebd8STal Shnaiderman return NULL; 2767525ebd8STal Shnaiderman } 2777525ebd8STal Shnaiderman return rule_hdl; 2787525ebd8STal Shnaiderman } 2797525ebd8STal Shnaiderman 2807525ebd8STal Shnaiderman static int 2817525ebd8STal Shnaiderman mlx5_glue_devx_fs_rule_del(void *flow) 2827525ebd8STal Shnaiderman { 2837525ebd8STal Shnaiderman return devx_fs_rule_del(flow); 2847525ebd8STal Shnaiderman } 2857525ebd8STal Shnaiderman 28699d7c45cSTal Shnaiderman static int 28799d7c45cSTal Shnaiderman mlx5_glue_query_rt_values(void *ctx, void *devx_clock) 28899d7c45cSTal Shnaiderman { 28999d7c45cSTal Shnaiderman struct mlx5_context *mlx5_ctx; 29099d7c45cSTal Shnaiderman struct mlx5_devx_clock *clock; 29199d7c45cSTal Shnaiderman int err; 29299d7c45cSTal Shnaiderman 29399d7c45cSTal Shnaiderman if (!ctx) { 29499d7c45cSTal Shnaiderman errno = EINVAL; 29599d7c45cSTal Shnaiderman return errno; 29699d7c45cSTal Shnaiderman } 29799d7c45cSTal Shnaiderman mlx5_ctx = (struct mlx5_context *)ctx; 29899d7c45cSTal Shnaiderman clock = (struct mlx5_devx_clock *)devx_clock; 29999d7c45cSTal Shnaiderman err = devx_hca_clock_query( 30099d7c45cSTal Shnaiderman mlx5_ctx->devx_ctx, 30199d7c45cSTal Shnaiderman &clock->p_iseg_internal_timer, 30299d7c45cSTal Shnaiderman &clock->clock_frequency_hz, 30399d7c45cSTal Shnaiderman &clock->is_stable_clock_frequency); 30499d7c45cSTal Shnaiderman if (err) { 30599d7c45cSTal Shnaiderman errno = err; 30699d7c45cSTal Shnaiderman return errno; 30799d7c45cSTal Shnaiderman } 30899d7c45cSTal Shnaiderman return 0; 30999d7c45cSTal Shnaiderman } 31099d7c45cSTal Shnaiderman 311165e5d07STal Shnaiderman static int 312165e5d07STal Shnaiderman mlx5_glue_devx_init_showdown_event(void *ctx) 313165e5d07STal Shnaiderman { 314165e5d07STal Shnaiderman struct mlx5_context *mlx5_ctx; 315165e5d07STal Shnaiderman int err; 316165e5d07STal Shnaiderman 317165e5d07STal Shnaiderman if (!ctx) { 318165e5d07STal Shnaiderman errno = EINVAL; 319165e5d07STal Shnaiderman return errno; 320165e5d07STal Shnaiderman } 321165e5d07STal Shnaiderman mlx5_ctx = (struct mlx5_context *)ctx; 322165e5d07STal Shnaiderman err = devx_query_shutdown_event(mlx5_ctx->devx_ctx, 323165e5d07STal Shnaiderman &mlx5_ctx->shutdown_event_obj); 324165e5d07STal Shnaiderman if (err) { 325165e5d07STal Shnaiderman errno = err; 326165e5d07STal Shnaiderman return errno; 327165e5d07STal Shnaiderman } 328165e5d07STal Shnaiderman return 0; 329165e5d07STal Shnaiderman } 330165e5d07STal Shnaiderman 3317525ebd8STal Shnaiderman alignas(RTE_CACHE_LINE_SIZE) 3327525ebd8STal Shnaiderman const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ 3337525ebd8STal Shnaiderman .version = MLX5_GLUE_VERSION, 3347525ebd8STal Shnaiderman .get_device_list = mlx5_glue_devx_get_device_list, 3357525ebd8STal Shnaiderman .free_device_list = mlx5_glue_devx_free_device_list, 3367525ebd8STal Shnaiderman .open_device = mlx5_glue_devx_open_device, 3377525ebd8STal Shnaiderman .close_device = mlx5_glue_devx_close_device, 3387525ebd8STal Shnaiderman .query_device = mlx5_glue_devx_query_device, 3397525ebd8STal Shnaiderman .query_hca_iseg = mlx5_glue_devx_query_hca_iseg_mapping, 3407525ebd8STal Shnaiderman .devx_obj_create = mlx5_glue_devx_obj_create, 3417525ebd8STal Shnaiderman .devx_obj_destroy = mlx5_glue_devx_obj_destroy, 3427525ebd8STal Shnaiderman .devx_obj_query = mlx5_glue_devx_obj_query, 3437525ebd8STal Shnaiderman .devx_obj_modify = mlx5_glue_devx_obj_modify, 3447525ebd8STal Shnaiderman .devx_general_cmd = mlx5_glue_devx_general_cmd, 3457525ebd8STal Shnaiderman .devx_umem_reg = mlx5_glue_devx_umem_reg, 3467525ebd8STal Shnaiderman .devx_umem_dereg = mlx5_glue_devx_umem_dereg, 3477525ebd8STal Shnaiderman .devx_alloc_uar = mlx5_glue_devx_alloc_uar, 3487525ebd8STal Shnaiderman .devx_free_uar = mlx5_glue_devx_free_uar, 3497525ebd8STal Shnaiderman .devx_fs_rule_add = mlx5_glue_devx_fs_rule_add, 3507525ebd8STal Shnaiderman .devx_fs_rule_del = mlx5_glue_devx_fs_rule_del, 3517525ebd8STal Shnaiderman .devx_query_eqn = mlx5_glue_devx_query_eqn, 35299d7c45cSTal Shnaiderman .query_rt_values = mlx5_glue_query_rt_values, 353165e5d07STal Shnaiderman .devx_init_showdown_event = mlx5_glue_devx_init_showdown_event, 3547525ebd8STal Shnaiderman }; 355