1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2022 Intel Corporation
13 #include <sys/eventfd.h>
16 #include <rte_malloc.h>
17 #include <rte_memzone.h>
18 #include <rte_rawdev_pmd.h>
20 #include "afu_pmd_core.h"
22 static struct rte_afu_uuid afu_pmd_uuid_map[AFU_RAWDEV_MAX_DRVS+1];
23 TAILQ_HEAD(afu_drv_list, afu_rawdev_drv);
24 static struct afu_drv_list afu_pmd_list = TAILQ_HEAD_INITIALIZER(afu_pmd_list);
26 static inline int afu_rawdev_trylock(struct afu_rawdev *dev)
31 return rte_spinlock_trylock(&dev->sd->lock);
34 static inline void afu_rawdev_unlock(struct afu_rawdev *dev)
39 rte_spinlock_unlock(&dev->sd->lock);
42 static int afu_rawdev_configure(const struct rte_rawdev *rawdev,
43 rte_rawdev_obj_t config, size_t config_size)
45 struct afu_rawdev *dev = NULL;
48 IFPGA_RAWDEV_PMD_FUNC_TRACE();
50 dev = afu_rawdev_get_priv(rawdev);
54 if (dev->ops && dev->ops->config)
55 ret = (*dev->ops->config)(dev, config, config_size);
60 static int afu_rawdev_start(struct rte_rawdev *rawdev)
62 struct afu_rawdev *dev = NULL;
65 IFPGA_RAWDEV_PMD_FUNC_TRACE();
67 dev = afu_rawdev_get_priv(rawdev);
71 ret = afu_rawdev_trylock(dev);
73 IFPGA_RAWDEV_PMD_WARN("AFU is busy, please start it later");
77 if (dev->ops && dev->ops->start)
78 ret = (*dev->ops->start)(dev);
80 afu_rawdev_unlock(dev);
85 static void afu_rawdev_stop(struct rte_rawdev *rawdev)
87 struct afu_rawdev *dev = NULL;
90 IFPGA_RAWDEV_PMD_FUNC_TRACE();
92 dev = afu_rawdev_get_priv(rawdev);
96 ret = afu_rawdev_trylock(dev);
98 IFPGA_RAWDEV_PMD_WARN("AFU is busy, please stop it later");
102 if (dev->ops && dev->ops->stop)
103 ret = (*dev->ops->stop)(dev);
105 afu_rawdev_unlock(dev);
108 static int afu_rawdev_close(struct rte_rawdev *rawdev)
110 struct afu_rawdev *dev = NULL;
113 IFPGA_RAWDEV_PMD_FUNC_TRACE();
115 dev = afu_rawdev_get_priv(rawdev);
119 if (dev->ops && dev->ops->close)
120 ret = (*dev->ops->close)(dev);
125 static int afu_rawdev_reset(struct rte_rawdev *rawdev)
127 struct afu_rawdev *dev = NULL;
130 IFPGA_RAWDEV_PMD_FUNC_TRACE();
132 dev = afu_rawdev_get_priv(rawdev);
136 ret = afu_rawdev_trylock(dev);
138 IFPGA_RAWDEV_PMD_WARN("AFU is busy, please reset it later");
142 if (dev->ops && dev->ops->reset)
143 ret = (*dev->ops->reset)(dev);
145 afu_rawdev_unlock(dev);
150 static int afu_rawdev_selftest(uint16_t dev_id)
152 struct afu_rawdev *dev = NULL;
155 IFPGA_RAWDEV_PMD_FUNC_TRACE();
157 if (!rte_rawdev_pmd_is_valid_dev(dev_id))
160 dev = afu_rawdev_get_priv(&rte_rawdevs[dev_id]);
164 ret = afu_rawdev_trylock(dev);
166 IFPGA_RAWDEV_PMD_WARN("AFU is busy, please test it later");
170 if (dev->ops && dev->ops->test)
171 ret = (*dev->ops->test)(dev);
173 afu_rawdev_unlock(dev);
178 static int afu_rawdev_dump(struct rte_rawdev *rawdev, FILE *f)
180 struct afu_rawdev *dev = NULL;
183 IFPGA_RAWDEV_PMD_FUNC_TRACE();
185 dev = afu_rawdev_get_priv(rawdev);
189 if (dev->ops && dev->ops->dump)
190 ret = (*dev->ops->dump)(dev, f);
195 static const struct rte_rawdev_ops afu_rawdev_ops = {
196 .dev_info_get = NULL,
197 .dev_configure = afu_rawdev_configure,
198 .dev_start = afu_rawdev_start,
199 .dev_stop = afu_rawdev_stop,
200 .dev_close = afu_rawdev_close,
201 .dev_reset = afu_rawdev_reset,
203 .queue_def_conf = NULL,
205 .queue_release = NULL,
211 .enqueue_bufs = NULL,
212 .dequeue_bufs = NULL,
214 .dump = afu_rawdev_dump,
217 .xstats_get_names = NULL,
218 .xstats_get_by_name = NULL,
219 .xstats_reset = NULL,
221 .firmware_status_get = NULL,
222 .firmware_version_get = NULL,
223 .firmware_load = NULL,
224 .firmware_unload = NULL,
226 .dev_selftest = afu_rawdev_selftest,
229 static int afu_shared_data_alloc(const char *name,
230 struct afu_shared_data **data, int socket_id)
232 const struct rte_memzone *mz;
233 char mz_name[RTE_MEMZONE_NAMESIZE];
234 struct afu_shared_data *sd = NULL;
240 /* name format is afu_?|??:??.? which is unique */
241 snprintf(mz_name, sizeof(mz_name), "%s", name);
243 mz = rte_memzone_lookup(mz_name);
245 mz = rte_memzone_reserve(mz_name, sizeof(struct afu_shared_data),
251 IFPGA_RAWDEV_PMD_ERR("Allocate memory zone %s failed!",
256 sd = (struct afu_shared_data *)mz->addr;
258 if (init_mz) /* initialize memory zone on the first time */
259 rte_spinlock_init(&sd->lock);
266 static int afu_rawdev_name_get(struct rte_afu_device *afu_dev, char *name,
271 if (!afu_dev || !name || !size)
274 n = snprintf(name, size, "afu_%s", afu_dev->device.name);
275 if (n >= (int)size) {
276 IFPGA_RAWDEV_PMD_ERR("Name of AFU device is too long!");
277 return -ENAMETOOLONG;
283 static struct afu_ops *afu_ops_get(struct rte_afu_uuid *afu_id)
285 struct afu_rawdev_drv *drv = NULL;
290 TAILQ_FOREACH(drv, &afu_pmd_list, next) {
291 if ((drv->uuid.uuid_low == afu_id->uuid_low) &&
292 (drv->uuid.uuid_high == afu_id->uuid_high))
296 return drv ? drv->ops : NULL;
299 static int afu_rawdev_create(struct rte_afu_device *afu_dev, int socket_id)
301 struct rte_rawdev *rawdev = NULL;
302 struct afu_rawdev *dev = NULL;
303 char name[RTE_RAWDEV_NAME_MAX_LEN] = {0};
309 ret = afu_rawdev_name_get(afu_dev, name, sizeof(name));
313 IFPGA_RAWDEV_PMD_INFO("Create raw device %s on NUMA node %d",
316 /* Allocate device structure */
317 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct afu_rawdev),
320 IFPGA_RAWDEV_PMD_ERR("Unable to allocate raw device");
324 rawdev->dev_ops = &afu_rawdev_ops;
325 rawdev->device = &afu_dev->device;
326 rawdev->driver_name = afu_dev->driver->driver.name;
328 dev = afu_rawdev_get_priv(rawdev);
332 dev->rawdev = rawdev;
333 dev->port = afu_dev->id.port;
334 dev->addr = afu_dev->mem_resource[0].addr;
335 dev->ops = afu_ops_get(&afu_dev->id.uuid);
336 if (dev->ops == NULL) {
337 IFPGA_RAWDEV_PMD_ERR("Unsupported AFU device");
341 if (dev->ops->init) {
342 ret = (*dev->ops->init)(dev);
344 IFPGA_RAWDEV_PMD_ERR("Failed to init %s", name);
349 ret = afu_shared_data_alloc(name, &dev->sd, socket_id);
356 rte_rawdev_pmd_release(rawdev);
360 static int afu_rawdev_destroy(struct rte_afu_device *afu_dev)
362 struct rte_rawdev *rawdev = NULL;
363 char name[RTE_RAWDEV_NAME_MAX_LEN] = {0};
369 ret = afu_rawdev_name_get(afu_dev, name, sizeof(name));
373 IFPGA_RAWDEV_PMD_INFO("Destroy raw device %s", name);
375 rawdev = rte_rawdev_pmd_get_named_dev(name);
377 IFPGA_RAWDEV_PMD_ERR("Raw device %s not found", name);
381 /* rte_rawdev_close is called by pmd_release */
382 ret = rte_rawdev_pmd_release(rawdev);
384 IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed");
389 static int afu_rawdev_probe(struct rte_afu_device *afu_dev)
391 IFPGA_RAWDEV_PMD_FUNC_TRACE();
392 return afu_rawdev_create(afu_dev, rte_socket_id());
395 static int afu_rawdev_remove(struct rte_afu_device *afu_dev)
397 IFPGA_RAWDEV_PMD_FUNC_TRACE();
398 return afu_rawdev_destroy(afu_dev);
401 static struct rte_afu_driver afu_pmd = {
402 .id_table = afu_pmd_uuid_map,
403 .probe = afu_rawdev_probe,
404 .remove = afu_rawdev_remove
407 RTE_PMD_REGISTER_AFU(afu_rawdev_driver, afu_pmd);
409 static void update_uuid_map(void)
412 struct rte_afu_uuid *afu_id = afu_pmd_uuid_map;
413 struct afu_rawdev_drv *drv;
415 TAILQ_FOREACH(drv, &afu_pmd_list, next) {
416 if (i++ < AFU_RAWDEV_MAX_DRVS) {
417 afu_id->uuid_low = drv->uuid.uuid_low;
418 afu_id->uuid_high = drv->uuid.uuid_high;
422 if (i <= AFU_RAWDEV_MAX_DRVS) {
423 afu_id->uuid_low = 0;
424 afu_id->uuid_high = 0;
428 void afu_pmd_register(struct afu_rawdev_drv *driver)
430 TAILQ_INSERT_TAIL(&afu_pmd_list, driver, next);
434 void afu_pmd_unregister(struct afu_rawdev_drv *driver)
436 TAILQ_REMOVE(&afu_pmd_list, driver, next);