dpdk/drivers/common/mlx5/linux/mlx5_common_auxiliary.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright 2020 Mellanox Technologies Ltd
   3 */
   4
   5#include <stdlib.h>
   6#include <dirent.h>
   7#include <libgen.h>
   8
   9#include <rte_malloc.h>
  10#include <rte_errno.h>
  11#include <rte_bus_auxiliary.h>
  12#include <rte_common.h>
  13#include "eal_filesystem.h"
  14
  15#include "mlx5_common_utils.h"
  16#include "mlx5_common_private.h"
  17
  18#define AUXILIARY_SYSFS_PATH "/sys/bus/auxiliary/devices"
  19#define MLX5_AUXILIARY_PREFIX "mlx5_core.sf."
  20
  21int
  22mlx5_auxiliary_get_child_name(const char *dev, const char *node,
  23                              char *child, size_t size)
  24{
  25        DIR *dir;
  26        struct dirent *dent;
  27        MKSTR(path, "%s/%s%s", AUXILIARY_SYSFS_PATH, dev, node);
  28
  29        dir = opendir(path);
  30        if (dir == NULL) {
  31                rte_errno = errno;
  32                return -rte_errno;
  33        }
  34        /* Get the first file name. */
  35        while ((dent = readdir(dir)) != NULL) {
  36                if (dent->d_name[0] != '.')
  37                        break;
  38        }
  39        closedir(dir);
  40        if (dent == NULL) {
  41                rte_errno = ENOENT;
  42                return -rte_errno;
  43        }
  44        if (rte_strscpy(child, dent->d_name, size) < 0)
  45                return -rte_errno;
  46        return 0;
  47}
  48
  49static int
  50mlx5_auxiliary_get_pci_path(const struct rte_auxiliary_device *dev,
  51                            char *sysfs_pci, size_t size)
  52{
  53        char sysfs_real[PATH_MAX] = { 0 };
  54        MKSTR(sysfs_aux, "%s/%s", AUXILIARY_SYSFS_PATH, dev->name);
  55        char *dir;
  56
  57        if (realpath(sysfs_aux, sysfs_real) == NULL) {
  58                rte_errno = errno;
  59                return -rte_errno;
  60        }
  61        dir = dirname(sysfs_real);
  62        if (dir == NULL) {
  63                rte_errno = errno;
  64                return -rte_errno;
  65        }
  66        if (rte_strscpy(sysfs_pci, dir, size) < 0)
  67                return -rte_errno;
  68        return 0;
  69}
  70
  71int
  72mlx5_auxiliary_get_pci_str(const struct rte_auxiliary_device *dev,
  73                           char *addr, size_t size)
  74{
  75        char sysfs_pci[PATH_MAX];
  76        char *base;
  77
  78        if (mlx5_auxiliary_get_pci_path(dev, sysfs_pci, sizeof(sysfs_pci)) != 0)
  79                return -ENODEV;
  80        base = basename(sysfs_pci);
  81        if (base == NULL)
  82                return -errno;
  83        if (rte_strscpy(addr, base, size) < 0)
  84                return -rte_errno;
  85        return 0;
  86}
  87
  88static int
  89mlx5_auxiliary_get_numa(const struct rte_auxiliary_device *dev)
  90{
  91        unsigned long numa;
  92        char numa_path[PATH_MAX];
  93
  94        if (mlx5_auxiliary_get_pci_path(dev, numa_path, sizeof(numa_path)) != 0)
  95                return SOCKET_ID_ANY;
  96        if (strcat(numa_path, "/numa_node") == NULL) {
  97                rte_errno = ENAMETOOLONG;
  98                return SOCKET_ID_ANY;
  99        }
 100        if (eal_parse_sysfs_value(numa_path, &numa) != 0) {
 101                rte_errno = EINVAL;
 102                return SOCKET_ID_ANY;
 103        }
 104        return (int)numa;
 105}
 106
 107struct ibv_device *
 108mlx5_get_aux_ibv_device(const struct rte_auxiliary_device *dev)
 109{
 110        int n;
 111        char ib_name[64] = { 0 };
 112        struct ibv_device **ibv_list = mlx5_glue->get_device_list(&n);
 113        struct ibv_device *ibv_match = NULL;
 114
 115        if (!ibv_list) {
 116                rte_errno = ENOSYS;
 117                return NULL;
 118        }
 119        if (mlx5_auxiliary_get_child_name(dev->name, "/infiniband",
 120                                          ib_name, sizeof(ib_name)) != 0)
 121                goto out;
 122        while (n-- > 0) {
 123                if (strcmp(ibv_list[n]->name, ib_name) != 0)
 124                        continue;
 125                ibv_match = ibv_list[n];
 126                break;
 127        }
 128        if (ibv_match == NULL)
 129                rte_errno = ENOENT;
 130out:
 131        mlx5_glue->free_device_list(ibv_list);
 132        return ibv_match;
 133}
 134
 135static bool
 136mlx5_common_auxiliary_match(const char *name)
 137{
 138        return strncmp(name, MLX5_AUXILIARY_PREFIX,
 139                       strlen(MLX5_AUXILIARY_PREFIX)) == 0;
 140}
 141
 142static int
 143mlx5_common_auxiliary_probe(struct rte_auxiliary_driver *drv __rte_unused,
 144                            struct rte_auxiliary_device *dev)
 145{
 146        dev->device.numa_node = mlx5_auxiliary_get_numa(dev);
 147        return mlx5_common_dev_probe(&dev->device);
 148}
 149
 150static int
 151mlx5_common_auxiliary_remove(struct rte_auxiliary_device *auxiliary_dev)
 152{
 153        return mlx5_common_dev_remove(&auxiliary_dev->device);
 154}
 155
 156static int
 157mlx5_common_auxiliary_dma_map(struct rte_auxiliary_device *auxiliary_dev,
 158                              void *addr, uint64_t iova, size_t len)
 159{
 160        return mlx5_common_dev_dma_map(&auxiliary_dev->device, addr, iova, len);
 161}
 162
 163static int
 164mlx5_common_auxiliary_dma_unmap(struct rte_auxiliary_device *auxiliary_dev,
 165                                void *addr, uint64_t iova, size_t len)
 166{
 167        return mlx5_common_dev_dma_unmap(&auxiliary_dev->device, addr, iova,
 168                                         len);
 169}
 170
 171static struct rte_auxiliary_driver mlx5_auxiliary_driver = {
 172        .driver = {
 173                   .name = MLX5_AUXILIARY_DRIVER_NAME,
 174        },
 175        .match = mlx5_common_auxiliary_match,
 176        .probe = mlx5_common_auxiliary_probe,
 177        .remove = mlx5_common_auxiliary_remove,
 178        .dma_map = mlx5_common_auxiliary_dma_map,
 179        .dma_unmap = mlx5_common_auxiliary_dma_unmap,
 180};
 181
 182void mlx5_common_auxiliary_init(void)
 183{
 184        if (mlx5_auxiliary_driver.bus == NULL)
 185                rte_auxiliary_register(&mlx5_auxiliary_driver);
 186}
 187
 188RTE_FINI(mlx5_common_auxiliary_driver_finish)
 189{
 190        if (mlx5_auxiliary_driver.bus != NULL)
 191                rte_auxiliary_unregister(&mlx5_auxiliary_driver);
 192}
 193