1777b72a9SXueming Li /* SPDX-License-Identifier: BSD-3-Clause 2777b72a9SXueming Li * Copyright 2020 Mellanox Technologies Ltd 3777b72a9SXueming Li */ 4777b72a9SXueming Li 5777b72a9SXueming Li #include <stdlib.h> 6777b72a9SXueming Li #include <dirent.h> 7777b72a9SXueming Li #include <libgen.h> 8777b72a9SXueming Li 9777b72a9SXueming Li #include <rte_malloc.h> 10777b72a9SXueming Li #include <rte_errno.h> 11777b72a9SXueming Li #include <rte_bus_auxiliary.h> 12777b72a9SXueming Li #include <rte_common.h> 13777b72a9SXueming Li #include "eal_filesystem.h" 14777b72a9SXueming Li 15777b72a9SXueming Li #include "mlx5_common_utils.h" 16777b72a9SXueming Li #include "mlx5_common_private.h" 17777b72a9SXueming Li 18777b72a9SXueming Li #define AUXILIARY_SYSFS_PATH "/sys/bus/auxiliary/devices" 19777b72a9SXueming Li #define MLX5_AUXILIARY_PREFIX "mlx5_core.sf." 20777b72a9SXueming Li 21777b72a9SXueming Li int 22777b72a9SXueming Li mlx5_auxiliary_get_child_name(const char *dev, const char *node, 23777b72a9SXueming Li char *child, size_t size) 24777b72a9SXueming Li { 25777b72a9SXueming Li DIR *dir; 26777b72a9SXueming Li struct dirent *dent; 27777b72a9SXueming Li MKSTR(path, "%s/%s%s", AUXILIARY_SYSFS_PATH, dev, node); 28777b72a9SXueming Li 29777b72a9SXueming Li dir = opendir(path); 30777b72a9SXueming Li if (dir == NULL) { 31777b72a9SXueming Li rte_errno = errno; 32777b72a9SXueming Li return -rte_errno; 33777b72a9SXueming Li } 34777b72a9SXueming Li /* Get the first file name. */ 35777b72a9SXueming Li while ((dent = readdir(dir)) != NULL) { 36777b72a9SXueming Li if (dent->d_name[0] != '.') 37777b72a9SXueming Li break; 38777b72a9SXueming Li } 39777b72a9SXueming Li closedir(dir); 40777b72a9SXueming Li if (dent == NULL) { 41777b72a9SXueming Li rte_errno = ENOENT; 42777b72a9SXueming Li return -rte_errno; 43777b72a9SXueming Li } 44777b72a9SXueming Li if (rte_strscpy(child, dent->d_name, size) < 0) 45777b72a9SXueming Li return -rte_errno; 46777b72a9SXueming Li return 0; 47777b72a9SXueming Li } 48777b72a9SXueming Li 49777b72a9SXueming Li static int 50777b72a9SXueming Li mlx5_auxiliary_get_pci_path(const struct rte_auxiliary_device *dev, 51777b72a9SXueming Li char *sysfs_pci, size_t size) 52777b72a9SXueming Li { 53777b72a9SXueming Li char sysfs_real[PATH_MAX] = { 0 }; 54777b72a9SXueming Li MKSTR(sysfs_aux, "%s/%s", AUXILIARY_SYSFS_PATH, dev->name); 55777b72a9SXueming Li char *dir; 56777b72a9SXueming Li 57777b72a9SXueming Li if (realpath(sysfs_aux, sysfs_real) == NULL) { 58777b72a9SXueming Li rte_errno = errno; 59777b72a9SXueming Li return -rte_errno; 60777b72a9SXueming Li } 61777b72a9SXueming Li dir = dirname(sysfs_real); 62777b72a9SXueming Li if (dir == NULL) { 63777b72a9SXueming Li rte_errno = errno; 64777b72a9SXueming Li return -rte_errno; 65777b72a9SXueming Li } 66777b72a9SXueming Li if (rte_strscpy(sysfs_pci, dir, size) < 0) 67777b72a9SXueming Li return -rte_errno; 68777b72a9SXueming Li return 0; 69777b72a9SXueming Li } 70777b72a9SXueming Li 71*4d567938SThomas Monjalon int 72*4d567938SThomas Monjalon mlx5_auxiliary_get_pci_str(const struct rte_auxiliary_device *dev, 73*4d567938SThomas Monjalon char *addr, size_t size) 74*4d567938SThomas Monjalon { 75*4d567938SThomas Monjalon char sysfs_pci[PATH_MAX]; 76*4d567938SThomas Monjalon char *base; 77*4d567938SThomas Monjalon 78*4d567938SThomas Monjalon if (mlx5_auxiliary_get_pci_path(dev, sysfs_pci, sizeof(sysfs_pci)) != 0) 79*4d567938SThomas Monjalon return -ENODEV; 80*4d567938SThomas Monjalon base = basename(sysfs_pci); 81*4d567938SThomas Monjalon if (base == NULL) 82*4d567938SThomas Monjalon return -errno; 83*4d567938SThomas Monjalon if (rte_strscpy(addr, base, size) < 0) 84*4d567938SThomas Monjalon return -rte_errno; 85*4d567938SThomas Monjalon return 0; 86*4d567938SThomas Monjalon } 87*4d567938SThomas Monjalon 88777b72a9SXueming Li static int 89777b72a9SXueming Li mlx5_auxiliary_get_numa(const struct rte_auxiliary_device *dev) 90777b72a9SXueming Li { 91777b72a9SXueming Li unsigned long numa; 92777b72a9SXueming Li char numa_path[PATH_MAX]; 93777b72a9SXueming Li 94777b72a9SXueming Li if (mlx5_auxiliary_get_pci_path(dev, numa_path, sizeof(numa_path)) != 0) 95777b72a9SXueming Li return SOCKET_ID_ANY; 96777b72a9SXueming Li if (strcat(numa_path, "/numa_node") == NULL) { 97777b72a9SXueming Li rte_errno = ENAMETOOLONG; 98777b72a9SXueming Li return SOCKET_ID_ANY; 99777b72a9SXueming Li } 100777b72a9SXueming Li if (eal_parse_sysfs_value(numa_path, &numa) != 0) { 101777b72a9SXueming Li rte_errno = EINVAL; 102777b72a9SXueming Li return SOCKET_ID_ANY; 103777b72a9SXueming Li } 104777b72a9SXueming Li return (int)numa; 105777b72a9SXueming Li } 106777b72a9SXueming Li 107777b72a9SXueming Li struct ibv_device * 108777b72a9SXueming Li mlx5_get_aux_ibv_device(const struct rte_auxiliary_device *dev) 109777b72a9SXueming Li { 110777b72a9SXueming Li int n; 111777b72a9SXueming Li char ib_name[64] = { 0 }; 112777b72a9SXueming Li struct ibv_device **ibv_list = mlx5_glue->get_device_list(&n); 113777b72a9SXueming Li struct ibv_device *ibv_match = NULL; 114777b72a9SXueming Li 115777b72a9SXueming Li if (!ibv_list) { 116777b72a9SXueming Li rte_errno = ENOSYS; 117777b72a9SXueming Li return NULL; 118777b72a9SXueming Li } 119777b72a9SXueming Li if (mlx5_auxiliary_get_child_name(dev->name, "/infiniband", 120777b72a9SXueming Li ib_name, sizeof(ib_name)) != 0) 121777b72a9SXueming Li goto out; 122777b72a9SXueming Li while (n-- > 0) { 123777b72a9SXueming Li if (strcmp(ibv_list[n]->name, ib_name) != 0) 124777b72a9SXueming Li continue; 125777b72a9SXueming Li ibv_match = ibv_list[n]; 126777b72a9SXueming Li break; 127777b72a9SXueming Li } 128777b72a9SXueming Li if (ibv_match == NULL) 129777b72a9SXueming Li rte_errno = ENOENT; 130777b72a9SXueming Li out: 131777b72a9SXueming Li mlx5_glue->free_device_list(ibv_list); 132777b72a9SXueming Li return ibv_match; 133777b72a9SXueming Li } 134777b72a9SXueming Li 135777b72a9SXueming Li static bool 136777b72a9SXueming Li mlx5_common_auxiliary_match(const char *name) 137777b72a9SXueming Li { 138777b72a9SXueming Li return strncmp(name, MLX5_AUXILIARY_PREFIX, 139777b72a9SXueming Li strlen(MLX5_AUXILIARY_PREFIX)) == 0; 140777b72a9SXueming Li } 141777b72a9SXueming Li 142777b72a9SXueming Li static int 143777b72a9SXueming Li mlx5_common_auxiliary_probe(struct rte_auxiliary_driver *drv __rte_unused, 144777b72a9SXueming Li struct rte_auxiliary_device *dev) 145777b72a9SXueming Li { 146777b72a9SXueming Li dev->device.numa_node = mlx5_auxiliary_get_numa(dev); 147777b72a9SXueming Li return mlx5_common_dev_probe(&dev->device); 148777b72a9SXueming Li } 149777b72a9SXueming Li 150777b72a9SXueming Li static int 151777b72a9SXueming Li mlx5_common_auxiliary_remove(struct rte_auxiliary_device *auxiliary_dev) 152777b72a9SXueming Li { 153777b72a9SXueming Li return mlx5_common_dev_remove(&auxiliary_dev->device); 154777b72a9SXueming Li } 155777b72a9SXueming Li 156777b72a9SXueming Li static int 157777b72a9SXueming Li mlx5_common_auxiliary_dma_map(struct rte_auxiliary_device *auxiliary_dev, 158777b72a9SXueming Li void *addr, uint64_t iova, size_t len) 159777b72a9SXueming Li { 160777b72a9SXueming Li return mlx5_common_dev_dma_map(&auxiliary_dev->device, addr, iova, len); 161777b72a9SXueming Li } 162777b72a9SXueming Li 163777b72a9SXueming Li static int 164777b72a9SXueming Li mlx5_common_auxiliary_dma_unmap(struct rte_auxiliary_device *auxiliary_dev, 165777b72a9SXueming Li void *addr, uint64_t iova, size_t len) 166777b72a9SXueming Li { 167777b72a9SXueming Li return mlx5_common_dev_dma_unmap(&auxiliary_dev->device, addr, iova, 168777b72a9SXueming Li len); 169777b72a9SXueming Li } 170777b72a9SXueming Li 171777b72a9SXueming Li static struct rte_auxiliary_driver mlx5_auxiliary_driver = { 172777b72a9SXueming Li .driver = { 173777b72a9SXueming Li .name = MLX5_AUXILIARY_DRIVER_NAME, 174777b72a9SXueming Li }, 175777b72a9SXueming Li .match = mlx5_common_auxiliary_match, 176777b72a9SXueming Li .probe = mlx5_common_auxiliary_probe, 177777b72a9SXueming Li .remove = mlx5_common_auxiliary_remove, 178777b72a9SXueming Li .dma_map = mlx5_common_auxiliary_dma_map, 179777b72a9SXueming Li .dma_unmap = mlx5_common_auxiliary_dma_unmap, 180777b72a9SXueming Li }; 181777b72a9SXueming Li 182777b72a9SXueming Li void mlx5_common_auxiliary_init(void) 183777b72a9SXueming Li { 184777b72a9SXueming Li if (mlx5_auxiliary_driver.bus == NULL) 185777b72a9SXueming Li rte_auxiliary_register(&mlx5_auxiliary_driver); 186777b72a9SXueming Li } 187777b72a9SXueming Li 188777b72a9SXueming Li RTE_FINI(mlx5_common_auxiliary_driver_finish) 189777b72a9SXueming Li { 190777b72a9SXueming Li if (mlx5_auxiliary_driver.bus != NULL) 191777b72a9SXueming Li rte_auxiliary_unregister(&mlx5_auxiliary_driver); 192777b72a9SXueming Li } 193