xref: /dpdk/drivers/common/mlx5/linux/mlx5_common_auxiliary.c (revision b3f89090d667a3ab29e8327242dbc0c12d8b7262)
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>
11*b3f89090SDavid Marchand #include <bus_auxiliary_driver.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
mlx5_auxiliary_get_child_name(const char * dev,const char * node,char * child,size_t size)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
mlx5_auxiliary_get_pci_path(const struct rte_auxiliary_device * dev,char * sysfs_pci,size_t size)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 
714d567938SThomas Monjalon int
mlx5_auxiliary_get_pci_str(const struct rte_auxiliary_device * dev,char * addr,size_t size)724d567938SThomas Monjalon mlx5_auxiliary_get_pci_str(const struct rte_auxiliary_device *dev,
734d567938SThomas Monjalon 			   char *addr, size_t size)
744d567938SThomas Monjalon {
754d567938SThomas Monjalon 	char sysfs_pci[PATH_MAX];
764d567938SThomas Monjalon 	char *base;
774d567938SThomas Monjalon 
784d567938SThomas Monjalon 	if (mlx5_auxiliary_get_pci_path(dev, sysfs_pci, sizeof(sysfs_pci)) != 0)
794d567938SThomas Monjalon 		return -ENODEV;
804d567938SThomas Monjalon 	base = basename(sysfs_pci);
814d567938SThomas Monjalon 	if (base == NULL)
824d567938SThomas Monjalon 		return -errno;
834d567938SThomas Monjalon 	if (rte_strscpy(addr, base, size) < 0)
844d567938SThomas Monjalon 		return -rte_errno;
854d567938SThomas Monjalon 	return 0;
864d567938SThomas Monjalon }
874d567938SThomas Monjalon 
88777b72a9SXueming Li static int
mlx5_auxiliary_get_numa(const struct rte_auxiliary_device * dev)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 *
mlx5_get_aux_ibv_device(const struct rte_auxiliary_device * dev)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
mlx5_common_auxiliary_match(const char * name)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
mlx5_common_auxiliary_probe(struct rte_auxiliary_driver * drv __rte_unused,struct rte_auxiliary_device * dev)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
mlx5_common_auxiliary_remove(struct rte_auxiliary_device * auxiliary_dev)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
mlx5_common_auxiliary_dma_map(struct rte_auxiliary_device * auxiliary_dev,void * addr,uint64_t iova,size_t len)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
mlx5_common_auxiliary_dma_unmap(struct rte_auxiliary_device * auxiliary_dev,void * addr,uint64_t iova,size_t len)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 
182709b9a47SDavid Marchand static bool mlx5_common_auxiliary_initialized;
183709b9a47SDavid Marchand 
mlx5_common_auxiliary_init(void)184777b72a9SXueming Li void mlx5_common_auxiliary_init(void)
185777b72a9SXueming Li {
186709b9a47SDavid Marchand 	if (!mlx5_common_auxiliary_initialized) {
187777b72a9SXueming Li 		rte_auxiliary_register(&mlx5_auxiliary_driver);
188709b9a47SDavid Marchand 		mlx5_common_auxiliary_initialized = true;
189709b9a47SDavid Marchand 	}
190777b72a9SXueming Li }
191777b72a9SXueming Li 
RTE_FINI(mlx5_common_auxiliary_driver_finish)192777b72a9SXueming Li RTE_FINI(mlx5_common_auxiliary_driver_finish)
193777b72a9SXueming Li {
194709b9a47SDavid Marchand 	if (mlx5_common_auxiliary_initialized) {
195777b72a9SXueming Li 		rte_auxiliary_unregister(&mlx5_auxiliary_driver);
196709b9a47SDavid Marchand 		mlx5_common_auxiliary_initialized = false;
197709b9a47SDavid Marchand 	}
198777b72a9SXueming Li }
199