1
2
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
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