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"
15 #include "bcmfs_vfio.h"
17 struct bcmfs_device_attr {
18 const char name[BCMFS_MAX_PATH_LEN];
19 const char suffix[BCMFS_DEV_NAME_LEN];
20 const enum bcmfs_device_type type;
21 const uint32_t offset;
22 const uint32_t version;
25 /* BCMFS supported devices */
26 static struct bcmfs_device_attr dev_table[] = {
29 .suffix = "crypto_mbox",
30 .type = BCMFS_SYM_FS4,
32 .version = BCMFS_SYM_FS4_VERSION
37 .type = BCMFS_SYM_FS5,
39 .version = BCMFS_SYM_FS5_VERSION
46 TAILQ_HEAD(fsdev_list, bcmfs_device);
47 static struct fsdev_list fsdev_list = TAILQ_HEAD_INITIALIZER(fsdev_list);
49 static struct bcmfs_device *
50 fsdev_allocate_one_dev(struct rte_vdev_device *vdev,
53 enum bcmfs_device_type dev_type __rte_unused)
55 struct bcmfs_device *fsdev;
57 fsdev = rte_calloc(__func__, 1, sizeof(*fsdev), 0);
61 if (strlen(dirpath) > sizeof(fsdev->dirname)) {
62 BCMFS_LOG(ERR, "dir path name is too long");
66 if (strlen(devname) > sizeof(fsdev->name)) {
67 BCMFS_LOG(ERR, "devname is too long");
71 strcpy(fsdev->dirname, dirpath);
72 strcpy(fsdev->name, devname);
77 if (bcmfs_attach_vfio(fsdev))
80 TAILQ_INSERT_TAIL(&fsdev_list, fsdev, next);
90 static struct bcmfs_device *
91 find_fsdev(struct rte_vdev_device *vdev)
93 struct bcmfs_device *fsdev;
95 TAILQ_FOREACH(fsdev, &fsdev_list, next)
96 if (fsdev->vdev == vdev)
103 fsdev_release(struct bcmfs_device *fsdev)
108 TAILQ_REMOVE(&fsdev_list, fsdev, next);
113 cmprator(const void *a, const void *b)
115 return (*(const unsigned int *)a - *(const unsigned int *)b);
119 fsdev_find_all_devs(const char *path, const char *search,
123 struct dirent *entry;
125 char addr[BCMFS_MAX_NODES][BCMFS_MAX_PATH_LEN];
130 BCMFS_LOG(ERR, "Unable to open directory");
134 while ((entry = readdir(dir)) != NULL) {
135 if (strstr(entry->d_name, search)) {
136 strlcpy(addr[count], entry->d_name,
144 for (i = 0 ; i < count; i++)
145 devs[i] = (uint32_t)strtoul(addr[i], NULL, 16);
146 /* sort the devices based on IO addresses */
147 qsort(devs, count, sizeof(uint32_t), cmprator);
153 fsdev_find_sub_dir(char *path, const char *search, char *output)
156 struct dirent *entry;
160 BCMFS_LOG(ERR, "Unable to open directory");
164 while ((entry = readdir(dir)) != NULL) {
165 if (!strcmp(entry->d_name, search)) {
166 strlcpy(output, entry->d_name, BCMFS_MAX_PATH_LEN);
179 bcmfs_vdev_probe(struct rte_vdev_device *vdev)
181 struct bcmfs_device *fsdev;
182 char top_dirpath[BCMFS_MAX_PATH_LEN];
183 char sub_dirpath[BCMFS_MAX_PATH_LEN];
184 char out_dirpath[BCMFS_MAX_PATH_LEN];
185 char out_dirname[BCMFS_MAX_PATH_LEN];
186 uint32_t fsdev_dev[BCMFS_MAX_NODES];
187 enum bcmfs_device_type dtype;
193 sprintf(top_dirpath, "%s", SYSFS_BCM_PLTFORM_DEVICES);
194 while (strlen(dev_table[i].name)) {
195 found = fsdev_find_sub_dir(top_dirpath,
203 BCMFS_LOG(ERR, "No supported bcmfs dev found");
208 dtype = dev_table[i].type;
210 snprintf(out_dirpath, sizeof(out_dirpath), "%s/%s",
211 top_dirpath, sub_dirpath);
212 count = fsdev_find_all_devs(out_dirpath,
213 dev_table[dev_idx].suffix,
216 BCMFS_LOG(ERR, "No supported bcmfs dev found");
222 /* format the device name present in the patch */
223 snprintf(out_dirname, sizeof(out_dirname), "%x.%s",
224 fsdev_dev[i], dev_table[dev_idx].suffix);
225 fsdev = fsdev_allocate_one_dev(vdev, out_dirpath,
235 BCMFS_LOG(ERR, "All supported devs busy");
243 bcmfs_vdev_remove(struct rte_vdev_device *vdev)
245 struct bcmfs_device *fsdev;
247 fsdev = find_fsdev(vdev);
251 fsdev_release(fsdev);
255 /* Register with vdev */
256 static struct rte_vdev_driver rte_bcmfs_pmd = {
257 .probe = bcmfs_vdev_probe,
258 .remove = bcmfs_vdev_remove
261 RTE_PMD_REGISTER_VDEV(bcmfs_pmd,