1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Broadcom.
10 #include <rte_malloc.h>
11 #include <rte_string_fns.h>
13 #include "bcmfs_device.h"
14 #include "bcmfs_logs.h"
16 #include "bcmfs_vfio.h"
18 struct bcmfs_device_attr {
19 const char name[BCMFS_MAX_PATH_LEN];
20 const char suffix[BCMFS_DEV_NAME_LEN];
21 const enum bcmfs_device_type type;
22 const uint32_t offset;
23 const uint32_t version;
26 /* BCMFS supported devices */
27 static struct bcmfs_device_attr dev_table[] = {
30 .suffix = "crypto_mbox",
31 .type = BCMFS_SYM_FS4,
33 .version = BCMFS_SYM_FS4_VERSION
38 .type = BCMFS_SYM_FS5,
40 .version = BCMFS_SYM_FS5_VERSION
47 TAILQ_HEAD(fsdev_list, bcmfs_device);
48 static struct fsdev_list fsdev_list = TAILQ_HEAD_INITIALIZER(fsdev_list);
50 static struct bcmfs_device *
51 fsdev_allocate_one_dev(struct rte_vdev_device *vdev,
54 enum bcmfs_device_type dev_type __rte_unused)
56 struct bcmfs_device *fsdev;
58 fsdev = rte_calloc(__func__, 1, sizeof(*fsdev), 0);
62 if (strlen(dirpath) > sizeof(fsdev->dirname)) {
63 BCMFS_LOG(ERR, "dir path name is too long");
67 if (strlen(devname) > sizeof(fsdev->name)) {
68 BCMFS_LOG(ERR, "devname is too long");
72 strcpy(fsdev->dirname, dirpath);
73 strcpy(fsdev->name, devname);
78 if (bcmfs_attach_vfio(fsdev))
81 /* Maximum number of QPs supported */
82 fsdev->max_hw_qps = fsdev->mmap_size / BCMFS_HW_QUEUE_IO_ADDR_LEN;
84 TAILQ_INSERT_TAIL(&fsdev_list, fsdev, next);
94 static struct bcmfs_device *
95 find_fsdev(struct rte_vdev_device *vdev)
97 struct bcmfs_device *fsdev;
99 TAILQ_FOREACH(fsdev, &fsdev_list, next)
100 if (fsdev->vdev == vdev)
107 fsdev_release(struct bcmfs_device *fsdev)
112 TAILQ_REMOVE(&fsdev_list, fsdev, next);
117 cmprator(const void *a, const void *b)
119 return (*(const unsigned int *)a - *(const unsigned int *)b);
123 fsdev_find_all_devs(const char *path, const char *search,
127 struct dirent *entry;
129 char addr[BCMFS_MAX_NODES][BCMFS_MAX_PATH_LEN];
134 BCMFS_LOG(ERR, "Unable to open directory");
138 while ((entry = readdir(dir)) != NULL) {
139 if (strstr(entry->d_name, search)) {
140 strlcpy(addr[count], entry->d_name,
148 for (i = 0 ; i < count; i++)
149 devs[i] = (uint32_t)strtoul(addr[i], NULL, 16);
150 /* sort the devices based on IO addresses */
151 qsort(devs, count, sizeof(uint32_t), cmprator);
157 fsdev_find_sub_dir(char *path, const char *search, char *output)
160 struct dirent *entry;
164 BCMFS_LOG(ERR, "Unable to open directory");
168 while ((entry = readdir(dir)) != NULL) {
169 if (!strcmp(entry->d_name, search)) {
170 strlcpy(output, entry->d_name, BCMFS_MAX_PATH_LEN);
183 bcmfs_vdev_probe(struct rte_vdev_device *vdev)
185 struct bcmfs_device *fsdev;
186 char top_dirpath[BCMFS_MAX_PATH_LEN];
187 char sub_dirpath[BCMFS_MAX_PATH_LEN];
188 char out_dirpath[BCMFS_MAX_PATH_LEN];
189 char out_dirname[BCMFS_MAX_PATH_LEN];
190 uint32_t fsdev_dev[BCMFS_MAX_NODES];
191 enum bcmfs_device_type dtype;
197 sprintf(top_dirpath, "%s", SYSFS_BCM_PLTFORM_DEVICES);
198 while (strlen(dev_table[i].name)) {
199 found = fsdev_find_sub_dir(top_dirpath,
207 BCMFS_LOG(ERR, "No supported bcmfs dev found");
212 dtype = dev_table[i].type;
214 snprintf(out_dirpath, sizeof(out_dirpath), "%s/%s",
215 top_dirpath, sub_dirpath);
216 count = fsdev_find_all_devs(out_dirpath,
217 dev_table[dev_idx].suffix,
220 BCMFS_LOG(ERR, "No supported bcmfs dev found");
226 /* format the device name present in the patch */
227 snprintf(out_dirname, sizeof(out_dirname), "%x.%s",
228 fsdev_dev[i], dev_table[dev_idx].suffix);
229 fsdev = fsdev_allocate_one_dev(vdev, out_dirpath,
239 BCMFS_LOG(ERR, "All supported devs busy");
247 bcmfs_vdev_remove(struct rte_vdev_device *vdev)
249 struct bcmfs_device *fsdev;
251 fsdev = find_fsdev(vdev);
255 fsdev_release(fsdev);
259 /* Register with vdev */
260 static struct rte_vdev_driver rte_bcmfs_pmd = {
261 .probe = bcmfs_vdev_probe,
262 .remove = bcmfs_vdev_remove
265 RTE_PMD_REGISTER_VDEV(bcmfs_pmd,