199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2017 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson
599a2dd95SBruce Richardson #include <stdint.h>
699a2dd95SBruce Richardson #include <string.h>
799a2dd95SBruce Richardson #include <stdbool.h>
899a2dd95SBruce Richardson
999a2dd95SBruce Richardson #include <rte_common.h>
1099a2dd95SBruce Richardson #include <rte_errno.h>
1199a2dd95SBruce Richardson #include <rte_log.h>
1299a2dd95SBruce Richardson #include <rte_eal.h>
1399a2dd95SBruce Richardson #include <rte_malloc.h>
1499a2dd95SBruce Richardson #include <rte_mempool.h>
1599a2dd95SBruce Richardson #include <rte_memzone.h>
1699a2dd95SBruce Richardson #include <rte_lcore.h>
1799a2dd95SBruce Richardson #include <rte_spinlock.h>
1899a2dd95SBruce Richardson #include <rte_interrupts.h>
1999a2dd95SBruce Richardson
2099a2dd95SBruce Richardson #include "rte_bbdev_op.h"
2199a2dd95SBruce Richardson #include "rte_bbdev.h"
2299a2dd95SBruce Richardson #include "rte_bbdev_pmd.h"
2399a2dd95SBruce Richardson
2499a2dd95SBruce Richardson #define DEV_NAME "BBDEV"
2599a2dd95SBruce Richardson
2699a2dd95SBruce Richardson
2799a2dd95SBruce Richardson /* BBDev library logging ID */
28eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(bbdev_logtype, NOTICE);
2999a2dd95SBruce Richardson
3099a2dd95SBruce Richardson /* Helper macro for logging */
3199a2dd95SBruce Richardson #define rte_bbdev_log(level, fmt, ...) \
3299a2dd95SBruce Richardson rte_log(RTE_LOG_ ## level, bbdev_logtype, fmt "\n", ##__VA_ARGS__)
3399a2dd95SBruce Richardson
3499a2dd95SBruce Richardson #define rte_bbdev_log_debug(fmt, ...) \
3599a2dd95SBruce Richardson rte_bbdev_log(DEBUG, RTE_STR(__LINE__) ":%s() " fmt, __func__, \
3699a2dd95SBruce Richardson ##__VA_ARGS__)
3799a2dd95SBruce Richardson
3899a2dd95SBruce Richardson /* Helper macro to check dev_id is valid */
3999a2dd95SBruce Richardson #define VALID_DEV_OR_RET_ERR(dev, dev_id) do { \
4099a2dd95SBruce Richardson if (dev == NULL) { \
4199a2dd95SBruce Richardson rte_bbdev_log(ERR, "device %u is invalid", dev_id); \
4299a2dd95SBruce Richardson return -ENODEV; \
4399a2dd95SBruce Richardson } \
4499a2dd95SBruce Richardson } while (0)
4599a2dd95SBruce Richardson
4699a2dd95SBruce Richardson /* Helper macro to check dev_ops is valid */
4799a2dd95SBruce Richardson #define VALID_DEV_OPS_OR_RET_ERR(dev, dev_id) do { \
4899a2dd95SBruce Richardson if (dev->dev_ops == NULL) { \
4999a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL dev_ops structure in device %u", \
5099a2dd95SBruce Richardson dev_id); \
5199a2dd95SBruce Richardson return -ENODEV; \
5299a2dd95SBruce Richardson } \
5399a2dd95SBruce Richardson } while (0)
5499a2dd95SBruce Richardson
5599a2dd95SBruce Richardson /* Helper macro to check that driver implements required function pointer */
5699a2dd95SBruce Richardson #define VALID_FUNC_OR_RET_ERR(func, dev_id) do { \
5799a2dd95SBruce Richardson if (func == NULL) { \
5899a2dd95SBruce Richardson rte_bbdev_log(ERR, "device %u does not support %s", \
5999a2dd95SBruce Richardson dev_id, #func); \
6099a2dd95SBruce Richardson return -ENOTSUP; \
6199a2dd95SBruce Richardson } \
6299a2dd95SBruce Richardson } while (0)
6399a2dd95SBruce Richardson
6499a2dd95SBruce Richardson /* Helper macro to check that queue is valid */
6599a2dd95SBruce Richardson #define VALID_QUEUE_OR_RET_ERR(queue_id, dev) do { \
6699a2dd95SBruce Richardson if (queue_id >= dev->data->num_queues) { \
6799a2dd95SBruce Richardson rte_bbdev_log(ERR, "Invalid queue_id %u for device %u", \
6899a2dd95SBruce Richardson queue_id, dev->data->dev_id); \
6999a2dd95SBruce Richardson return -ERANGE; \
7099a2dd95SBruce Richardson } \
7199a2dd95SBruce Richardson } while (0)
7299a2dd95SBruce Richardson
7399a2dd95SBruce Richardson /* List of callback functions registered by an application */
7499a2dd95SBruce Richardson struct rte_bbdev_callback {
7599a2dd95SBruce Richardson TAILQ_ENTRY(rte_bbdev_callback) next; /* Callbacks list */
7699a2dd95SBruce Richardson rte_bbdev_cb_fn cb_fn; /* Callback address */
7799a2dd95SBruce Richardson void *cb_arg; /* Parameter for callback */
7899a2dd95SBruce Richardson void *ret_param; /* Return parameter */
7999a2dd95SBruce Richardson enum rte_bbdev_event_type event; /* Interrupt event type */
8099a2dd95SBruce Richardson uint32_t active; /* Callback is executing */
8199a2dd95SBruce Richardson };
8299a2dd95SBruce Richardson
8399a2dd95SBruce Richardson /* spinlock for bbdev device callbacks */
8499a2dd95SBruce Richardson static rte_spinlock_t rte_bbdev_cb_lock = RTE_SPINLOCK_INITIALIZER;
8599a2dd95SBruce Richardson
8699a2dd95SBruce Richardson /*
8799a2dd95SBruce Richardson * Global array of all devices. This is not static because it's used by the
8899a2dd95SBruce Richardson * inline enqueue and dequeue functions
8999a2dd95SBruce Richardson */
9099a2dd95SBruce Richardson struct rte_bbdev rte_bbdev_devices[RTE_BBDEV_MAX_DEVS];
9199a2dd95SBruce Richardson
9299a2dd95SBruce Richardson /* Global array with rte_bbdev_data structures */
9399a2dd95SBruce Richardson static struct rte_bbdev_data *rte_bbdev_data;
9499a2dd95SBruce Richardson
9599a2dd95SBruce Richardson /* Memzone name for global bbdev data pool */
9699a2dd95SBruce Richardson static const char *MZ_RTE_BBDEV_DATA = "rte_bbdev_data";
9799a2dd95SBruce Richardson
9899a2dd95SBruce Richardson /* Number of currently valid devices */
9999a2dd95SBruce Richardson static uint16_t num_devs;
10099a2dd95SBruce Richardson
10199a2dd95SBruce Richardson /* Return pointer to device structure, with validity check */
10299a2dd95SBruce Richardson static struct rte_bbdev *
get_dev(uint16_t dev_id)10399a2dd95SBruce Richardson get_dev(uint16_t dev_id)
10499a2dd95SBruce Richardson {
10599a2dd95SBruce Richardson if (rte_bbdev_is_valid(dev_id))
10699a2dd95SBruce Richardson return &rte_bbdev_devices[dev_id];
10799a2dd95SBruce Richardson return NULL;
10899a2dd95SBruce Richardson }
10999a2dd95SBruce Richardson
11099a2dd95SBruce Richardson /* Allocate global data array */
11199a2dd95SBruce Richardson static int
rte_bbdev_data_alloc(void)11299a2dd95SBruce Richardson rte_bbdev_data_alloc(void)
11399a2dd95SBruce Richardson {
11499a2dd95SBruce Richardson const unsigned int flags = 0;
11599a2dd95SBruce Richardson const struct rte_memzone *mz;
11699a2dd95SBruce Richardson
11799a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
11899a2dd95SBruce Richardson mz = rte_memzone_reserve(MZ_RTE_BBDEV_DATA,
11999a2dd95SBruce Richardson RTE_BBDEV_MAX_DEVS * sizeof(*rte_bbdev_data),
12099a2dd95SBruce Richardson rte_socket_id(), flags);
12199a2dd95SBruce Richardson } else
12299a2dd95SBruce Richardson mz = rte_memzone_lookup(MZ_RTE_BBDEV_DATA);
12399a2dd95SBruce Richardson if (mz == NULL) {
12499a2dd95SBruce Richardson rte_bbdev_log(CRIT,
12599a2dd95SBruce Richardson "Cannot allocate memzone for bbdev port data");
12699a2dd95SBruce Richardson return -ENOMEM;
12799a2dd95SBruce Richardson }
12899a2dd95SBruce Richardson
12999a2dd95SBruce Richardson rte_bbdev_data = mz->addr;
13099a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY)
13199a2dd95SBruce Richardson memset(rte_bbdev_data, 0,
13299a2dd95SBruce Richardson RTE_BBDEV_MAX_DEVS * sizeof(*rte_bbdev_data));
13399a2dd95SBruce Richardson return 0;
13499a2dd95SBruce Richardson }
13599a2dd95SBruce Richardson
13699a2dd95SBruce Richardson /*
137*4a6672c2SStephen Hemminger * Find data allocated for the device or if not found return first unused bbdev
13899a2dd95SBruce Richardson * data. If all structures are in use and none is used by the device return
13999a2dd95SBruce Richardson * NULL.
14099a2dd95SBruce Richardson */
14199a2dd95SBruce Richardson static struct rte_bbdev_data *
find_bbdev_data(const char * name)14299a2dd95SBruce Richardson find_bbdev_data(const char *name)
14399a2dd95SBruce Richardson {
14499a2dd95SBruce Richardson uint16_t data_id;
14599a2dd95SBruce Richardson
14699a2dd95SBruce Richardson for (data_id = 0; data_id < RTE_BBDEV_MAX_DEVS; ++data_id) {
14799a2dd95SBruce Richardson if (strlen(rte_bbdev_data[data_id].name) == 0) {
14899a2dd95SBruce Richardson memset(&rte_bbdev_data[data_id], 0,
14999a2dd95SBruce Richardson sizeof(struct rte_bbdev_data));
15099a2dd95SBruce Richardson return &rte_bbdev_data[data_id];
15199a2dd95SBruce Richardson } else if (strncmp(rte_bbdev_data[data_id].name, name,
15299a2dd95SBruce Richardson RTE_BBDEV_NAME_MAX_LEN) == 0)
15399a2dd95SBruce Richardson return &rte_bbdev_data[data_id];
15499a2dd95SBruce Richardson }
15599a2dd95SBruce Richardson
15699a2dd95SBruce Richardson return NULL;
15799a2dd95SBruce Richardson }
15899a2dd95SBruce Richardson
15999a2dd95SBruce Richardson /* Find lowest device id with no attached device */
16099a2dd95SBruce Richardson static uint16_t
find_free_dev_id(void)16199a2dd95SBruce Richardson find_free_dev_id(void)
16299a2dd95SBruce Richardson {
16399a2dd95SBruce Richardson uint16_t i;
16499a2dd95SBruce Richardson for (i = 0; i < RTE_BBDEV_MAX_DEVS; i++) {
16599a2dd95SBruce Richardson if (rte_bbdev_devices[i].state == RTE_BBDEV_UNUSED)
16699a2dd95SBruce Richardson return i;
16799a2dd95SBruce Richardson }
16899a2dd95SBruce Richardson return RTE_BBDEV_MAX_DEVS;
16999a2dd95SBruce Richardson }
17099a2dd95SBruce Richardson
17199a2dd95SBruce Richardson struct rte_bbdev *
rte_bbdev_allocate(const char * name)17299a2dd95SBruce Richardson rte_bbdev_allocate(const char *name)
17399a2dd95SBruce Richardson {
17499a2dd95SBruce Richardson int ret;
17599a2dd95SBruce Richardson struct rte_bbdev *bbdev;
17699a2dd95SBruce Richardson uint16_t dev_id;
17799a2dd95SBruce Richardson
17899a2dd95SBruce Richardson if (name == NULL) {
17999a2dd95SBruce Richardson rte_bbdev_log(ERR, "Invalid null device name");
18099a2dd95SBruce Richardson return NULL;
18199a2dd95SBruce Richardson }
18299a2dd95SBruce Richardson
18399a2dd95SBruce Richardson if (rte_bbdev_get_named_dev(name) != NULL) {
18499a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device \"%s\" is already allocated", name);
18599a2dd95SBruce Richardson return NULL;
18699a2dd95SBruce Richardson }
18799a2dd95SBruce Richardson
18899a2dd95SBruce Richardson dev_id = find_free_dev_id();
18999a2dd95SBruce Richardson if (dev_id == RTE_BBDEV_MAX_DEVS) {
19099a2dd95SBruce Richardson rte_bbdev_log(ERR, "Reached maximum number of devices");
19199a2dd95SBruce Richardson return NULL;
19299a2dd95SBruce Richardson }
19399a2dd95SBruce Richardson
19499a2dd95SBruce Richardson bbdev = &rte_bbdev_devices[dev_id];
19599a2dd95SBruce Richardson
19699a2dd95SBruce Richardson if (rte_bbdev_data == NULL) {
19799a2dd95SBruce Richardson ret = rte_bbdev_data_alloc();
19899a2dd95SBruce Richardson if (ret != 0)
19999a2dd95SBruce Richardson return NULL;
20099a2dd95SBruce Richardson }
20199a2dd95SBruce Richardson
20299a2dd95SBruce Richardson bbdev->data = find_bbdev_data(name);
20399a2dd95SBruce Richardson if (bbdev->data == NULL) {
20499a2dd95SBruce Richardson rte_bbdev_log(ERR,
20599a2dd95SBruce Richardson "Max BBDevs already allocated in multi-process environment!");
20699a2dd95SBruce Richardson return NULL;
20799a2dd95SBruce Richardson }
20899a2dd95SBruce Richardson
20999a2dd95SBruce Richardson __atomic_add_fetch(&bbdev->data->process_cnt, 1, __ATOMIC_RELAXED);
21099a2dd95SBruce Richardson bbdev->data->dev_id = dev_id;
21199a2dd95SBruce Richardson bbdev->state = RTE_BBDEV_INITIALIZED;
21299a2dd95SBruce Richardson
21399a2dd95SBruce Richardson ret = snprintf(bbdev->data->name, RTE_BBDEV_NAME_MAX_LEN, "%s", name);
21499a2dd95SBruce Richardson if ((ret < 0) || (ret >= RTE_BBDEV_NAME_MAX_LEN)) {
21599a2dd95SBruce Richardson rte_bbdev_log(ERR, "Copying device name \"%s\" failed", name);
21699a2dd95SBruce Richardson return NULL;
21799a2dd95SBruce Richardson }
21899a2dd95SBruce Richardson
21999a2dd95SBruce Richardson /* init user callbacks */
22099a2dd95SBruce Richardson TAILQ_INIT(&(bbdev->list_cbs));
22199a2dd95SBruce Richardson
22299a2dd95SBruce Richardson num_devs++;
22399a2dd95SBruce Richardson
22499a2dd95SBruce Richardson rte_bbdev_log_debug("Initialised device %s (id = %u). Num devices = %u",
22599a2dd95SBruce Richardson name, dev_id, num_devs);
22699a2dd95SBruce Richardson
22799a2dd95SBruce Richardson return bbdev;
22899a2dd95SBruce Richardson }
22999a2dd95SBruce Richardson
23099a2dd95SBruce Richardson int
rte_bbdev_release(struct rte_bbdev * bbdev)23199a2dd95SBruce Richardson rte_bbdev_release(struct rte_bbdev *bbdev)
23299a2dd95SBruce Richardson {
23399a2dd95SBruce Richardson uint16_t dev_id;
23499a2dd95SBruce Richardson struct rte_bbdev_callback *cb, *next;
23599a2dd95SBruce Richardson
23699a2dd95SBruce Richardson if (bbdev == NULL) {
23799a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL bbdev");
23899a2dd95SBruce Richardson return -ENODEV;
23999a2dd95SBruce Richardson }
24099a2dd95SBruce Richardson dev_id = bbdev->data->dev_id;
24199a2dd95SBruce Richardson
24299a2dd95SBruce Richardson /* free all callbacks from the device's list */
24399a2dd95SBruce Richardson for (cb = TAILQ_FIRST(&bbdev->list_cbs); cb != NULL; cb = next) {
24499a2dd95SBruce Richardson
24599a2dd95SBruce Richardson next = TAILQ_NEXT(cb, next);
24699a2dd95SBruce Richardson TAILQ_REMOVE(&(bbdev->list_cbs), cb, next);
24799a2dd95SBruce Richardson rte_free(cb);
24899a2dd95SBruce Richardson }
24999a2dd95SBruce Richardson
25099a2dd95SBruce Richardson /* clear shared BBDev Data if no process is using the device anymore */
25199a2dd95SBruce Richardson if (__atomic_sub_fetch(&bbdev->data->process_cnt, 1,
25299a2dd95SBruce Richardson __ATOMIC_RELAXED) == 0)
25399a2dd95SBruce Richardson memset(bbdev->data, 0, sizeof(*bbdev->data));
25499a2dd95SBruce Richardson
25599a2dd95SBruce Richardson memset(bbdev, 0, sizeof(*bbdev));
25699a2dd95SBruce Richardson num_devs--;
25799a2dd95SBruce Richardson bbdev->state = RTE_BBDEV_UNUSED;
25899a2dd95SBruce Richardson
25999a2dd95SBruce Richardson rte_bbdev_log_debug(
26099a2dd95SBruce Richardson "Un-initialised device id = %u. Num devices = %u",
26199a2dd95SBruce Richardson dev_id, num_devs);
26299a2dd95SBruce Richardson return 0;
26399a2dd95SBruce Richardson }
26499a2dd95SBruce Richardson
26599a2dd95SBruce Richardson struct rte_bbdev *
rte_bbdev_get_named_dev(const char * name)26699a2dd95SBruce Richardson rte_bbdev_get_named_dev(const char *name)
26799a2dd95SBruce Richardson {
26899a2dd95SBruce Richardson unsigned int i;
26999a2dd95SBruce Richardson
27099a2dd95SBruce Richardson if (name == NULL) {
27199a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL driver name");
27299a2dd95SBruce Richardson return NULL;
27399a2dd95SBruce Richardson }
27499a2dd95SBruce Richardson
27599a2dd95SBruce Richardson for (i = 0; i < RTE_BBDEV_MAX_DEVS; i++) {
27699a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(i);
27799a2dd95SBruce Richardson if (dev && (strncmp(dev->data->name,
27899a2dd95SBruce Richardson name, RTE_BBDEV_NAME_MAX_LEN) == 0))
27999a2dd95SBruce Richardson return dev;
28099a2dd95SBruce Richardson }
28199a2dd95SBruce Richardson
28299a2dd95SBruce Richardson return NULL;
28399a2dd95SBruce Richardson }
28499a2dd95SBruce Richardson
28599a2dd95SBruce Richardson uint16_t
rte_bbdev_count(void)28699a2dd95SBruce Richardson rte_bbdev_count(void)
28799a2dd95SBruce Richardson {
28899a2dd95SBruce Richardson return num_devs;
28999a2dd95SBruce Richardson }
29099a2dd95SBruce Richardson
29199a2dd95SBruce Richardson bool
rte_bbdev_is_valid(uint16_t dev_id)29299a2dd95SBruce Richardson rte_bbdev_is_valid(uint16_t dev_id)
29399a2dd95SBruce Richardson {
29499a2dd95SBruce Richardson if ((dev_id < RTE_BBDEV_MAX_DEVS) &&
29599a2dd95SBruce Richardson rte_bbdev_devices[dev_id].state == RTE_BBDEV_INITIALIZED)
29699a2dd95SBruce Richardson return true;
29799a2dd95SBruce Richardson return false;
29899a2dd95SBruce Richardson }
29999a2dd95SBruce Richardson
30099a2dd95SBruce Richardson uint16_t
rte_bbdev_find_next(uint16_t dev_id)30199a2dd95SBruce Richardson rte_bbdev_find_next(uint16_t dev_id)
30299a2dd95SBruce Richardson {
30399a2dd95SBruce Richardson dev_id++;
30499a2dd95SBruce Richardson for (; dev_id < RTE_BBDEV_MAX_DEVS; dev_id++)
30599a2dd95SBruce Richardson if (rte_bbdev_is_valid(dev_id))
30699a2dd95SBruce Richardson break;
30799a2dd95SBruce Richardson return dev_id;
30899a2dd95SBruce Richardson }
30999a2dd95SBruce Richardson
31099a2dd95SBruce Richardson int
rte_bbdev_setup_queues(uint16_t dev_id,uint16_t num_queues,int socket_id)31199a2dd95SBruce Richardson rte_bbdev_setup_queues(uint16_t dev_id, uint16_t num_queues, int socket_id)
31299a2dd95SBruce Richardson {
31399a2dd95SBruce Richardson unsigned int i;
31499a2dd95SBruce Richardson int ret;
31599a2dd95SBruce Richardson struct rte_bbdev_driver_info dev_info;
31699a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
31799a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
31899a2dd95SBruce Richardson
31999a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
32099a2dd95SBruce Richardson
32199a2dd95SBruce Richardson if (dev->data->started) {
32299a2dd95SBruce Richardson rte_bbdev_log(ERR,
32399a2dd95SBruce Richardson "Device %u cannot be configured when started",
32499a2dd95SBruce Richardson dev_id);
32599a2dd95SBruce Richardson return -EBUSY;
32699a2dd95SBruce Richardson }
32799a2dd95SBruce Richardson
32899a2dd95SBruce Richardson /* Get device driver information to get max number of queues */
32999a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);
33099a2dd95SBruce Richardson memset(&dev_info, 0, sizeof(dev_info));
33199a2dd95SBruce Richardson dev->dev_ops->info_get(dev, &dev_info);
33299a2dd95SBruce Richardson
33399a2dd95SBruce Richardson if ((num_queues == 0) || (num_queues > dev_info.max_num_queues)) {
33499a2dd95SBruce Richardson rte_bbdev_log(ERR,
33599a2dd95SBruce Richardson "Device %u supports 0 < N <= %u queues, not %u",
33699a2dd95SBruce Richardson dev_id, dev_info.max_num_queues, num_queues);
33799a2dd95SBruce Richardson return -EINVAL;
33899a2dd95SBruce Richardson }
33999a2dd95SBruce Richardson
34099a2dd95SBruce Richardson /* If re-configuration, get driver to free existing internal memory */
34199a2dd95SBruce Richardson if (dev->data->queues != NULL) {
34299a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_release, dev_id);
34399a2dd95SBruce Richardson for (i = 0; i < dev->data->num_queues; i++) {
34499a2dd95SBruce Richardson int ret = dev->dev_ops->queue_release(dev, i);
34599a2dd95SBruce Richardson if (ret < 0) {
34699a2dd95SBruce Richardson rte_bbdev_log(ERR,
34799a2dd95SBruce Richardson "Device %u queue %u release failed",
34899a2dd95SBruce Richardson dev_id, i);
34999a2dd95SBruce Richardson return ret;
35099a2dd95SBruce Richardson }
35199a2dd95SBruce Richardson }
35299a2dd95SBruce Richardson /* Call optional device close */
35399a2dd95SBruce Richardson if (dev->dev_ops->close) {
35499a2dd95SBruce Richardson ret = dev->dev_ops->close(dev);
35599a2dd95SBruce Richardson if (ret < 0) {
35699a2dd95SBruce Richardson rte_bbdev_log(ERR,
35799a2dd95SBruce Richardson "Device %u couldn't be closed",
35899a2dd95SBruce Richardson dev_id);
35999a2dd95SBruce Richardson return ret;
36099a2dd95SBruce Richardson }
36199a2dd95SBruce Richardson }
36299a2dd95SBruce Richardson rte_free(dev->data->queues);
36399a2dd95SBruce Richardson }
36499a2dd95SBruce Richardson
36599a2dd95SBruce Richardson /* Allocate queue pointers */
36699a2dd95SBruce Richardson dev->data->queues = rte_calloc_socket(DEV_NAME, num_queues,
36799a2dd95SBruce Richardson sizeof(dev->data->queues[0]), RTE_CACHE_LINE_SIZE,
36899a2dd95SBruce Richardson dev->data->socket_id);
36999a2dd95SBruce Richardson if (dev->data->queues == NULL) {
37099a2dd95SBruce Richardson rte_bbdev_log(ERR,
37199a2dd95SBruce Richardson "calloc of %u queues for device %u on socket %i failed",
37299a2dd95SBruce Richardson num_queues, dev_id, dev->data->socket_id);
37399a2dd95SBruce Richardson return -ENOMEM;
37499a2dd95SBruce Richardson }
37599a2dd95SBruce Richardson
37699a2dd95SBruce Richardson dev->data->num_queues = num_queues;
37799a2dd95SBruce Richardson
37899a2dd95SBruce Richardson /* Call optional device configuration */
37999a2dd95SBruce Richardson if (dev->dev_ops->setup_queues) {
38099a2dd95SBruce Richardson ret = dev->dev_ops->setup_queues(dev, num_queues, socket_id);
38199a2dd95SBruce Richardson if (ret < 0) {
38299a2dd95SBruce Richardson rte_bbdev_log(ERR,
38399a2dd95SBruce Richardson "Device %u memory configuration failed",
38499a2dd95SBruce Richardson dev_id);
38599a2dd95SBruce Richardson goto error;
38699a2dd95SBruce Richardson }
38799a2dd95SBruce Richardson }
38899a2dd95SBruce Richardson
38999a2dd95SBruce Richardson rte_bbdev_log_debug("Device %u set up with %u queues", dev_id,
39099a2dd95SBruce Richardson num_queues);
39199a2dd95SBruce Richardson return 0;
39299a2dd95SBruce Richardson
39399a2dd95SBruce Richardson error:
39499a2dd95SBruce Richardson dev->data->num_queues = 0;
39599a2dd95SBruce Richardson rte_free(dev->data->queues);
39699a2dd95SBruce Richardson dev->data->queues = NULL;
39799a2dd95SBruce Richardson return ret;
39899a2dd95SBruce Richardson }
39999a2dd95SBruce Richardson
40099a2dd95SBruce Richardson int
rte_bbdev_intr_enable(uint16_t dev_id)40199a2dd95SBruce Richardson rte_bbdev_intr_enable(uint16_t dev_id)
40299a2dd95SBruce Richardson {
40399a2dd95SBruce Richardson int ret;
40499a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
40599a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
40699a2dd95SBruce Richardson
40799a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
40899a2dd95SBruce Richardson
40999a2dd95SBruce Richardson if (dev->data->started) {
41099a2dd95SBruce Richardson rte_bbdev_log(ERR,
41199a2dd95SBruce Richardson "Device %u cannot be configured when started",
41299a2dd95SBruce Richardson dev_id);
41399a2dd95SBruce Richardson return -EBUSY;
41499a2dd95SBruce Richardson }
41599a2dd95SBruce Richardson
41699a2dd95SBruce Richardson if (dev->dev_ops->intr_enable) {
41799a2dd95SBruce Richardson ret = dev->dev_ops->intr_enable(dev);
41899a2dd95SBruce Richardson if (ret < 0) {
41999a2dd95SBruce Richardson rte_bbdev_log(ERR,
42099a2dd95SBruce Richardson "Device %u interrupts configuration failed",
42199a2dd95SBruce Richardson dev_id);
42299a2dd95SBruce Richardson return ret;
42399a2dd95SBruce Richardson }
42499a2dd95SBruce Richardson rte_bbdev_log_debug("Enabled interrupts for dev %u", dev_id);
42599a2dd95SBruce Richardson return 0;
42699a2dd95SBruce Richardson }
42799a2dd95SBruce Richardson
42899a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u doesn't support interrupts", dev_id);
42999a2dd95SBruce Richardson return -ENOTSUP;
43099a2dd95SBruce Richardson }
43199a2dd95SBruce Richardson
43299a2dd95SBruce Richardson int
rte_bbdev_queue_configure(uint16_t dev_id,uint16_t queue_id,const struct rte_bbdev_queue_conf * conf)43399a2dd95SBruce Richardson rte_bbdev_queue_configure(uint16_t dev_id, uint16_t queue_id,
43499a2dd95SBruce Richardson const struct rte_bbdev_queue_conf *conf)
43599a2dd95SBruce Richardson {
43699a2dd95SBruce Richardson int ret = 0;
43799a2dd95SBruce Richardson struct rte_bbdev_driver_info dev_info;
43899a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
43999a2dd95SBruce Richardson const struct rte_bbdev_op_cap *p;
44099a2dd95SBruce Richardson struct rte_bbdev_queue_conf *stored_conf;
44199a2dd95SBruce Richardson const char *op_type_str;
44299a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
44399a2dd95SBruce Richardson
44499a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
44599a2dd95SBruce Richardson
44699a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
44799a2dd95SBruce Richardson
44899a2dd95SBruce Richardson if (dev->data->queues[queue_id].started || dev->data->started) {
44999a2dd95SBruce Richardson rte_bbdev_log(ERR,
45099a2dd95SBruce Richardson "Queue %u of device %u cannot be configured when started",
45199a2dd95SBruce Richardson queue_id, dev_id);
45299a2dd95SBruce Richardson return -EBUSY;
45399a2dd95SBruce Richardson }
45499a2dd95SBruce Richardson
45599a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_release, dev_id);
45699a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_setup, dev_id);
45799a2dd95SBruce Richardson
45899a2dd95SBruce Richardson /* Get device driver information to verify config is valid */
45999a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);
46099a2dd95SBruce Richardson memset(&dev_info, 0, sizeof(dev_info));
46199a2dd95SBruce Richardson dev->dev_ops->info_get(dev, &dev_info);
46299a2dd95SBruce Richardson
46399a2dd95SBruce Richardson /* Check configuration is valid */
46499a2dd95SBruce Richardson if (conf != NULL) {
46599a2dd95SBruce Richardson if ((conf->op_type == RTE_BBDEV_OP_NONE) &&
46699a2dd95SBruce Richardson (dev_info.capabilities[0].type ==
46799a2dd95SBruce Richardson RTE_BBDEV_OP_NONE)) {
46899a2dd95SBruce Richardson ret = 1;
46999a2dd95SBruce Richardson } else {
47099a2dd95SBruce Richardson for (p = dev_info.capabilities;
47199a2dd95SBruce Richardson p->type != RTE_BBDEV_OP_NONE; p++) {
47299a2dd95SBruce Richardson if (conf->op_type == p->type) {
47399a2dd95SBruce Richardson ret = 1;
47499a2dd95SBruce Richardson break;
47599a2dd95SBruce Richardson }
47699a2dd95SBruce Richardson }
47799a2dd95SBruce Richardson }
47899a2dd95SBruce Richardson if (ret == 0) {
47999a2dd95SBruce Richardson rte_bbdev_log(ERR, "Invalid operation type");
48099a2dd95SBruce Richardson return -EINVAL;
48199a2dd95SBruce Richardson }
48299a2dd95SBruce Richardson if (conf->queue_size > dev_info.queue_size_lim) {
48399a2dd95SBruce Richardson rte_bbdev_log(ERR,
48499a2dd95SBruce Richardson "Size (%u) of queue %u of device %u must be: <= %u",
48599a2dd95SBruce Richardson conf->queue_size, queue_id, dev_id,
48699a2dd95SBruce Richardson dev_info.queue_size_lim);
48799a2dd95SBruce Richardson return -EINVAL;
48899a2dd95SBruce Richardson }
48999a2dd95SBruce Richardson if (!rte_is_power_of_2(conf->queue_size)) {
49099a2dd95SBruce Richardson rte_bbdev_log(ERR,
49199a2dd95SBruce Richardson "Size (%u) of queue %u of device %u must be a power of 2",
49299a2dd95SBruce Richardson conf->queue_size, queue_id, dev_id);
49399a2dd95SBruce Richardson return -EINVAL;
49499a2dd95SBruce Richardson }
49599a2dd95SBruce Richardson if (conf->op_type == RTE_BBDEV_OP_TURBO_DEC &&
49699a2dd95SBruce Richardson conf->priority > dev_info.max_ul_queue_priority) {
49799a2dd95SBruce Richardson rte_bbdev_log(ERR,
49899a2dd95SBruce Richardson "Priority (%u) of queue %u of bbdev %u must be <= %u",
49999a2dd95SBruce Richardson conf->priority, queue_id, dev_id,
50099a2dd95SBruce Richardson dev_info.max_ul_queue_priority);
50199a2dd95SBruce Richardson return -EINVAL;
50299a2dd95SBruce Richardson }
50399a2dd95SBruce Richardson if (conf->op_type == RTE_BBDEV_OP_TURBO_ENC &&
50499a2dd95SBruce Richardson conf->priority > dev_info.max_dl_queue_priority) {
50599a2dd95SBruce Richardson rte_bbdev_log(ERR,
50699a2dd95SBruce Richardson "Priority (%u) of queue %u of bbdev %u must be <= %u",
50799a2dd95SBruce Richardson conf->priority, queue_id, dev_id,
50899a2dd95SBruce Richardson dev_info.max_dl_queue_priority);
50999a2dd95SBruce Richardson return -EINVAL;
51099a2dd95SBruce Richardson }
51199a2dd95SBruce Richardson }
51299a2dd95SBruce Richardson
51399a2dd95SBruce Richardson /* Release existing queue (in case of queue reconfiguration) */
51499a2dd95SBruce Richardson if (dev->data->queues[queue_id].queue_private != NULL) {
51599a2dd95SBruce Richardson ret = dev->dev_ops->queue_release(dev, queue_id);
51699a2dd95SBruce Richardson if (ret < 0) {
51799a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u queue %u release failed",
51899a2dd95SBruce Richardson dev_id, queue_id);
51999a2dd95SBruce Richardson return ret;
52099a2dd95SBruce Richardson }
52199a2dd95SBruce Richardson }
52299a2dd95SBruce Richardson
52399a2dd95SBruce Richardson /* Get driver to setup the queue */
52499a2dd95SBruce Richardson ret = dev->dev_ops->queue_setup(dev, queue_id, (conf != NULL) ?
52599a2dd95SBruce Richardson conf : &dev_info.default_queue_conf);
52699a2dd95SBruce Richardson if (ret < 0) {
5275f13f4c0SNicolas Chautru /* This may happen when trying different priority levels */
5285f13f4c0SNicolas Chautru rte_bbdev_log(INFO,
5295f13f4c0SNicolas Chautru "Device %u queue %u setup failed",
5305f13f4c0SNicolas Chautru dev_id, queue_id);
53199a2dd95SBruce Richardson return ret;
53299a2dd95SBruce Richardson }
53399a2dd95SBruce Richardson
53499a2dd95SBruce Richardson /* Store configuration */
53599a2dd95SBruce Richardson stored_conf = &dev->data->queues[queue_id].conf;
53699a2dd95SBruce Richardson memcpy(stored_conf,
53799a2dd95SBruce Richardson (conf != NULL) ? conf : &dev_info.default_queue_conf,
53899a2dd95SBruce Richardson sizeof(*stored_conf));
53999a2dd95SBruce Richardson
54099a2dd95SBruce Richardson op_type_str = rte_bbdev_op_type_str(stored_conf->op_type);
54199a2dd95SBruce Richardson if (op_type_str == NULL)
54299a2dd95SBruce Richardson return -EINVAL;
54399a2dd95SBruce Richardson
54499a2dd95SBruce Richardson rte_bbdev_log_debug("Configured dev%uq%u (size=%u, type=%s, prio=%u)",
54599a2dd95SBruce Richardson dev_id, queue_id, stored_conf->queue_size, op_type_str,
54699a2dd95SBruce Richardson stored_conf->priority);
54799a2dd95SBruce Richardson
54899a2dd95SBruce Richardson return 0;
54999a2dd95SBruce Richardson }
55099a2dd95SBruce Richardson
55199a2dd95SBruce Richardson int
rte_bbdev_start(uint16_t dev_id)55299a2dd95SBruce Richardson rte_bbdev_start(uint16_t dev_id)
55399a2dd95SBruce Richardson {
55499a2dd95SBruce Richardson int i;
55599a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
55699a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
55799a2dd95SBruce Richardson
55899a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
55999a2dd95SBruce Richardson
56099a2dd95SBruce Richardson if (dev->data->started) {
56199a2dd95SBruce Richardson rte_bbdev_log_debug("Device %u is already started", dev_id);
56299a2dd95SBruce Richardson return 0;
56399a2dd95SBruce Richardson }
56499a2dd95SBruce Richardson
56599a2dd95SBruce Richardson if (dev->dev_ops->start) {
56699a2dd95SBruce Richardson int ret = dev->dev_ops->start(dev);
56799a2dd95SBruce Richardson if (ret < 0) {
56899a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u start failed", dev_id);
56999a2dd95SBruce Richardson return ret;
57099a2dd95SBruce Richardson }
57199a2dd95SBruce Richardson }
57299a2dd95SBruce Richardson
57399a2dd95SBruce Richardson /* Store new state */
57499a2dd95SBruce Richardson for (i = 0; i < dev->data->num_queues; i++)
57599a2dd95SBruce Richardson if (!dev->data->queues[i].conf.deferred_start)
57699a2dd95SBruce Richardson dev->data->queues[i].started = true;
57799a2dd95SBruce Richardson dev->data->started = true;
57899a2dd95SBruce Richardson
57999a2dd95SBruce Richardson rte_bbdev_log_debug("Started device %u", dev_id);
58099a2dd95SBruce Richardson return 0;
58199a2dd95SBruce Richardson }
58299a2dd95SBruce Richardson
58399a2dd95SBruce Richardson int
rte_bbdev_stop(uint16_t dev_id)58499a2dd95SBruce Richardson rte_bbdev_stop(uint16_t dev_id)
58599a2dd95SBruce Richardson {
58699a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
58799a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
58899a2dd95SBruce Richardson
58999a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
59099a2dd95SBruce Richardson
59199a2dd95SBruce Richardson if (!dev->data->started) {
59299a2dd95SBruce Richardson rte_bbdev_log_debug("Device %u is already stopped", dev_id);
59399a2dd95SBruce Richardson return 0;
59499a2dd95SBruce Richardson }
59599a2dd95SBruce Richardson
59699a2dd95SBruce Richardson if (dev->dev_ops->stop)
59799a2dd95SBruce Richardson dev->dev_ops->stop(dev);
59899a2dd95SBruce Richardson dev->data->started = false;
59999a2dd95SBruce Richardson
60099a2dd95SBruce Richardson rte_bbdev_log_debug("Stopped device %u", dev_id);
60199a2dd95SBruce Richardson return 0;
60299a2dd95SBruce Richardson }
60399a2dd95SBruce Richardson
60499a2dd95SBruce Richardson int
rte_bbdev_close(uint16_t dev_id)60599a2dd95SBruce Richardson rte_bbdev_close(uint16_t dev_id)
60699a2dd95SBruce Richardson {
60799a2dd95SBruce Richardson int ret;
60899a2dd95SBruce Richardson uint16_t i;
60999a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
61099a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
61199a2dd95SBruce Richardson
61299a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
61399a2dd95SBruce Richardson
61499a2dd95SBruce Richardson if (dev->data->started) {
61599a2dd95SBruce Richardson ret = rte_bbdev_stop(dev_id);
61699a2dd95SBruce Richardson if (ret < 0) {
61799a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u stop failed", dev_id);
61899a2dd95SBruce Richardson return ret;
61999a2dd95SBruce Richardson }
62099a2dd95SBruce Richardson }
62199a2dd95SBruce Richardson
62299a2dd95SBruce Richardson /* Free memory used by queues */
62399a2dd95SBruce Richardson for (i = 0; i < dev->data->num_queues; i++) {
62499a2dd95SBruce Richardson ret = dev->dev_ops->queue_release(dev, i);
62599a2dd95SBruce Richardson if (ret < 0) {
62699a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u queue %u release failed",
62799a2dd95SBruce Richardson dev_id, i);
62899a2dd95SBruce Richardson return ret;
62999a2dd95SBruce Richardson }
63099a2dd95SBruce Richardson }
63199a2dd95SBruce Richardson rte_free(dev->data->queues);
63299a2dd95SBruce Richardson
63399a2dd95SBruce Richardson if (dev->dev_ops->close) {
63499a2dd95SBruce Richardson ret = dev->dev_ops->close(dev);
63599a2dd95SBruce Richardson if (ret < 0) {
63699a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u close failed", dev_id);
63799a2dd95SBruce Richardson return ret;
63899a2dd95SBruce Richardson }
63999a2dd95SBruce Richardson }
64099a2dd95SBruce Richardson
64199a2dd95SBruce Richardson /* Clear configuration */
64299a2dd95SBruce Richardson dev->data->queues = NULL;
64399a2dd95SBruce Richardson dev->data->num_queues = 0;
64499a2dd95SBruce Richardson
64599a2dd95SBruce Richardson rte_bbdev_log_debug("Closed device %u", dev_id);
64699a2dd95SBruce Richardson return 0;
64799a2dd95SBruce Richardson }
64899a2dd95SBruce Richardson
64999a2dd95SBruce Richardson int
rte_bbdev_queue_start(uint16_t dev_id,uint16_t queue_id)65099a2dd95SBruce Richardson rte_bbdev_queue_start(uint16_t dev_id, uint16_t queue_id)
65199a2dd95SBruce Richardson {
65299a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
65399a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
65499a2dd95SBruce Richardson
65599a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
65699a2dd95SBruce Richardson
65799a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
65899a2dd95SBruce Richardson
65999a2dd95SBruce Richardson if (dev->data->queues[queue_id].started) {
66099a2dd95SBruce Richardson rte_bbdev_log_debug("Queue %u of device %u already started",
66199a2dd95SBruce Richardson queue_id, dev_id);
66299a2dd95SBruce Richardson return 0;
66399a2dd95SBruce Richardson }
66499a2dd95SBruce Richardson
66599a2dd95SBruce Richardson if (dev->dev_ops->queue_start) {
66699a2dd95SBruce Richardson int ret = dev->dev_ops->queue_start(dev, queue_id);
66799a2dd95SBruce Richardson if (ret < 0) {
66899a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u queue %u start failed",
66999a2dd95SBruce Richardson dev_id, queue_id);
67099a2dd95SBruce Richardson return ret;
67199a2dd95SBruce Richardson }
67299a2dd95SBruce Richardson }
67399a2dd95SBruce Richardson dev->data->queues[queue_id].started = true;
67499a2dd95SBruce Richardson
67599a2dd95SBruce Richardson rte_bbdev_log_debug("Started queue %u of device %u", queue_id, dev_id);
67699a2dd95SBruce Richardson return 0;
67799a2dd95SBruce Richardson }
67899a2dd95SBruce Richardson
67999a2dd95SBruce Richardson int
rte_bbdev_queue_stop(uint16_t dev_id,uint16_t queue_id)68099a2dd95SBruce Richardson rte_bbdev_queue_stop(uint16_t dev_id, uint16_t queue_id)
68199a2dd95SBruce Richardson {
68299a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
68399a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
68499a2dd95SBruce Richardson
68599a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
68699a2dd95SBruce Richardson
68799a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
68899a2dd95SBruce Richardson
68999a2dd95SBruce Richardson if (!dev->data->queues[queue_id].started) {
69099a2dd95SBruce Richardson rte_bbdev_log_debug("Queue %u of device %u already stopped",
69199a2dd95SBruce Richardson queue_id, dev_id);
69299a2dd95SBruce Richardson return 0;
69399a2dd95SBruce Richardson }
69499a2dd95SBruce Richardson
69599a2dd95SBruce Richardson if (dev->dev_ops->queue_stop) {
69699a2dd95SBruce Richardson int ret = dev->dev_ops->queue_stop(dev, queue_id);
69799a2dd95SBruce Richardson if (ret < 0) {
69899a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u queue %u stop failed",
69999a2dd95SBruce Richardson dev_id, queue_id);
70099a2dd95SBruce Richardson return ret;
70199a2dd95SBruce Richardson }
70299a2dd95SBruce Richardson }
70399a2dd95SBruce Richardson dev->data->queues[queue_id].started = false;
70499a2dd95SBruce Richardson
70599a2dd95SBruce Richardson rte_bbdev_log_debug("Stopped queue %u of device %u", queue_id, dev_id);
70699a2dd95SBruce Richardson return 0;
70799a2dd95SBruce Richardson }
70899a2dd95SBruce Richardson
70999a2dd95SBruce Richardson /* Get device statistics */
71099a2dd95SBruce Richardson static void
get_stats_from_queues(struct rte_bbdev * dev,struct rte_bbdev_stats * stats)71199a2dd95SBruce Richardson get_stats_from_queues(struct rte_bbdev *dev, struct rte_bbdev_stats *stats)
71299a2dd95SBruce Richardson {
71399a2dd95SBruce Richardson unsigned int q_id;
71499a2dd95SBruce Richardson for (q_id = 0; q_id < dev->data->num_queues; q_id++) {
71599a2dd95SBruce Richardson struct rte_bbdev_stats *q_stats =
71699a2dd95SBruce Richardson &dev->data->queues[q_id].queue_stats;
71799a2dd95SBruce Richardson
71899a2dd95SBruce Richardson stats->enqueued_count += q_stats->enqueued_count;
71999a2dd95SBruce Richardson stats->dequeued_count += q_stats->dequeued_count;
72099a2dd95SBruce Richardson stats->enqueue_err_count += q_stats->enqueue_err_count;
72199a2dd95SBruce Richardson stats->dequeue_err_count += q_stats->dequeue_err_count;
72299a2dd95SBruce Richardson }
72399a2dd95SBruce Richardson rte_bbdev_log_debug("Got stats on %u", dev->data->dev_id);
72499a2dd95SBruce Richardson }
72599a2dd95SBruce Richardson
72699a2dd95SBruce Richardson static void
reset_stats_in_queues(struct rte_bbdev * dev)72799a2dd95SBruce Richardson reset_stats_in_queues(struct rte_bbdev *dev)
72899a2dd95SBruce Richardson {
72999a2dd95SBruce Richardson unsigned int q_id;
73099a2dd95SBruce Richardson for (q_id = 0; q_id < dev->data->num_queues; q_id++) {
73199a2dd95SBruce Richardson struct rte_bbdev_stats *q_stats =
73299a2dd95SBruce Richardson &dev->data->queues[q_id].queue_stats;
73399a2dd95SBruce Richardson
73499a2dd95SBruce Richardson memset(q_stats, 0, sizeof(*q_stats));
73599a2dd95SBruce Richardson }
73699a2dd95SBruce Richardson rte_bbdev_log_debug("Reset stats on %u", dev->data->dev_id);
73799a2dd95SBruce Richardson }
73899a2dd95SBruce Richardson
73999a2dd95SBruce Richardson int
rte_bbdev_stats_get(uint16_t dev_id,struct rte_bbdev_stats * stats)74099a2dd95SBruce Richardson rte_bbdev_stats_get(uint16_t dev_id, struct rte_bbdev_stats *stats)
74199a2dd95SBruce Richardson {
74299a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
74399a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
74499a2dd95SBruce Richardson
74599a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
74699a2dd95SBruce Richardson
74799a2dd95SBruce Richardson if (stats == NULL) {
74899a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL stats structure");
74999a2dd95SBruce Richardson return -EINVAL;
75099a2dd95SBruce Richardson }
75199a2dd95SBruce Richardson
75299a2dd95SBruce Richardson memset(stats, 0, sizeof(*stats));
75399a2dd95SBruce Richardson if (dev->dev_ops->stats_get != NULL)
75499a2dd95SBruce Richardson dev->dev_ops->stats_get(dev, stats);
75599a2dd95SBruce Richardson else
75699a2dd95SBruce Richardson get_stats_from_queues(dev, stats);
75799a2dd95SBruce Richardson
75899a2dd95SBruce Richardson rte_bbdev_log_debug("Retrieved stats of device %u", dev_id);
75999a2dd95SBruce Richardson return 0;
76099a2dd95SBruce Richardson }
76199a2dd95SBruce Richardson
76299a2dd95SBruce Richardson int
rte_bbdev_stats_reset(uint16_t dev_id)76399a2dd95SBruce Richardson rte_bbdev_stats_reset(uint16_t dev_id)
76499a2dd95SBruce Richardson {
76599a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
76699a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
76799a2dd95SBruce Richardson
76899a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
76999a2dd95SBruce Richardson
77099a2dd95SBruce Richardson if (dev->dev_ops->stats_reset != NULL)
77199a2dd95SBruce Richardson dev->dev_ops->stats_reset(dev);
77299a2dd95SBruce Richardson else
77399a2dd95SBruce Richardson reset_stats_in_queues(dev);
77499a2dd95SBruce Richardson
77599a2dd95SBruce Richardson rte_bbdev_log_debug("Reset stats of device %u", dev_id);
77699a2dd95SBruce Richardson return 0;
77799a2dd95SBruce Richardson }
77899a2dd95SBruce Richardson
77999a2dd95SBruce Richardson int
rte_bbdev_info_get(uint16_t dev_id,struct rte_bbdev_info * dev_info)78099a2dd95SBruce Richardson rte_bbdev_info_get(uint16_t dev_id, struct rte_bbdev_info *dev_info)
78199a2dd95SBruce Richardson {
78299a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
78399a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
78499a2dd95SBruce Richardson
78599a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);
78699a2dd95SBruce Richardson
78799a2dd95SBruce Richardson if (dev_info == NULL) {
78899a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL dev info structure");
78999a2dd95SBruce Richardson return -EINVAL;
79099a2dd95SBruce Richardson }
79199a2dd95SBruce Richardson
79299a2dd95SBruce Richardson /* Copy data maintained by device interface layer */
79399a2dd95SBruce Richardson memset(dev_info, 0, sizeof(*dev_info));
79499a2dd95SBruce Richardson dev_info->dev_name = dev->data->name;
79599a2dd95SBruce Richardson dev_info->num_queues = dev->data->num_queues;
79699a2dd95SBruce Richardson dev_info->device = dev->device;
79799a2dd95SBruce Richardson dev_info->socket_id = dev->data->socket_id;
79899a2dd95SBruce Richardson dev_info->started = dev->data->started;
79999a2dd95SBruce Richardson
80099a2dd95SBruce Richardson /* Copy data maintained by device driver layer */
80199a2dd95SBruce Richardson dev->dev_ops->info_get(dev, &dev_info->drv);
80299a2dd95SBruce Richardson
80399a2dd95SBruce Richardson rte_bbdev_log_debug("Retrieved info of device %u", dev_id);
80499a2dd95SBruce Richardson return 0;
80599a2dd95SBruce Richardson }
80699a2dd95SBruce Richardson
80799a2dd95SBruce Richardson int
rte_bbdev_queue_info_get(uint16_t dev_id,uint16_t queue_id,struct rte_bbdev_queue_info * queue_info)80899a2dd95SBruce Richardson rte_bbdev_queue_info_get(uint16_t dev_id, uint16_t queue_id,
80999a2dd95SBruce Richardson struct rte_bbdev_queue_info *queue_info)
81099a2dd95SBruce Richardson {
81199a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
81299a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
81399a2dd95SBruce Richardson
81499a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
81599a2dd95SBruce Richardson
81699a2dd95SBruce Richardson if (queue_info == NULL) {
81799a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL queue info structure");
81899a2dd95SBruce Richardson return -EINVAL;
81999a2dd95SBruce Richardson }
82099a2dd95SBruce Richardson
82199a2dd95SBruce Richardson /* Copy data to output */
82299a2dd95SBruce Richardson memset(queue_info, 0, sizeof(*queue_info));
82399a2dd95SBruce Richardson queue_info->conf = dev->data->queues[queue_id].conf;
82499a2dd95SBruce Richardson queue_info->started = dev->data->queues[queue_id].started;
82599a2dd95SBruce Richardson
82699a2dd95SBruce Richardson rte_bbdev_log_debug("Retrieved info of queue %u of device %u",
82799a2dd95SBruce Richardson queue_id, dev_id);
82899a2dd95SBruce Richardson return 0;
82999a2dd95SBruce Richardson }
83099a2dd95SBruce Richardson
83199a2dd95SBruce Richardson /* Calculate size needed to store bbdev_op, depending on type */
83299a2dd95SBruce Richardson static unsigned int
get_bbdev_op_size(enum rte_bbdev_op_type type)83399a2dd95SBruce Richardson get_bbdev_op_size(enum rte_bbdev_op_type type)
83499a2dd95SBruce Richardson {
83599a2dd95SBruce Richardson unsigned int result = 0;
83699a2dd95SBruce Richardson switch (type) {
83799a2dd95SBruce Richardson case RTE_BBDEV_OP_NONE:
83899a2dd95SBruce Richardson result = RTE_MAX(sizeof(struct rte_bbdev_dec_op),
83999a2dd95SBruce Richardson sizeof(struct rte_bbdev_enc_op));
84099a2dd95SBruce Richardson break;
84199a2dd95SBruce Richardson case RTE_BBDEV_OP_TURBO_DEC:
84299a2dd95SBruce Richardson result = sizeof(struct rte_bbdev_dec_op);
84399a2dd95SBruce Richardson break;
84499a2dd95SBruce Richardson case RTE_BBDEV_OP_TURBO_ENC:
84599a2dd95SBruce Richardson result = sizeof(struct rte_bbdev_enc_op);
84699a2dd95SBruce Richardson break;
84799a2dd95SBruce Richardson case RTE_BBDEV_OP_LDPC_DEC:
84899a2dd95SBruce Richardson result = sizeof(struct rte_bbdev_dec_op);
84999a2dd95SBruce Richardson break;
85099a2dd95SBruce Richardson case RTE_BBDEV_OP_LDPC_ENC:
85199a2dd95SBruce Richardson result = sizeof(struct rte_bbdev_enc_op);
85299a2dd95SBruce Richardson break;
85399a2dd95SBruce Richardson default:
85499a2dd95SBruce Richardson break;
85599a2dd95SBruce Richardson }
85699a2dd95SBruce Richardson
85799a2dd95SBruce Richardson return result;
85899a2dd95SBruce Richardson }
85999a2dd95SBruce Richardson
86099a2dd95SBruce Richardson /* Initialise a bbdev_op structure */
86199a2dd95SBruce Richardson static void
bbdev_op_init(struct rte_mempool * mempool,void * arg,void * element,__rte_unused unsigned int n)86299a2dd95SBruce Richardson bbdev_op_init(struct rte_mempool *mempool, void *arg, void *element,
86399a2dd95SBruce Richardson __rte_unused unsigned int n)
86499a2dd95SBruce Richardson {
86599a2dd95SBruce Richardson enum rte_bbdev_op_type type = *(enum rte_bbdev_op_type *)arg;
86699a2dd95SBruce Richardson
86799a2dd95SBruce Richardson if (type == RTE_BBDEV_OP_TURBO_DEC || type == RTE_BBDEV_OP_LDPC_DEC) {
86899a2dd95SBruce Richardson struct rte_bbdev_dec_op *op = element;
86999a2dd95SBruce Richardson memset(op, 0, mempool->elt_size);
87099a2dd95SBruce Richardson op->mempool = mempool;
87199a2dd95SBruce Richardson } else if (type == RTE_BBDEV_OP_TURBO_ENC ||
87299a2dd95SBruce Richardson type == RTE_BBDEV_OP_LDPC_ENC) {
87399a2dd95SBruce Richardson struct rte_bbdev_enc_op *op = element;
87499a2dd95SBruce Richardson memset(op, 0, mempool->elt_size);
87599a2dd95SBruce Richardson op->mempool = mempool;
87699a2dd95SBruce Richardson }
87799a2dd95SBruce Richardson }
87899a2dd95SBruce Richardson
87999a2dd95SBruce Richardson struct rte_mempool *
rte_bbdev_op_pool_create(const char * name,enum rte_bbdev_op_type type,unsigned int num_elements,unsigned int cache_size,int socket_id)88099a2dd95SBruce Richardson rte_bbdev_op_pool_create(const char *name, enum rte_bbdev_op_type type,
88199a2dd95SBruce Richardson unsigned int num_elements, unsigned int cache_size,
88299a2dd95SBruce Richardson int socket_id)
88399a2dd95SBruce Richardson {
88499a2dd95SBruce Richardson struct rte_bbdev_op_pool_private *priv;
88599a2dd95SBruce Richardson struct rte_mempool *mp;
88699a2dd95SBruce Richardson const char *op_type_str;
88799a2dd95SBruce Richardson
88899a2dd95SBruce Richardson if (name == NULL) {
88999a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL name for op pool");
89099a2dd95SBruce Richardson return NULL;
89199a2dd95SBruce Richardson }
89299a2dd95SBruce Richardson
89399a2dd95SBruce Richardson if (type >= RTE_BBDEV_OP_TYPE_COUNT) {
89499a2dd95SBruce Richardson rte_bbdev_log(ERR,
89599a2dd95SBruce Richardson "Invalid op type (%u), should be less than %u",
89699a2dd95SBruce Richardson type, RTE_BBDEV_OP_TYPE_COUNT);
89799a2dd95SBruce Richardson return NULL;
89899a2dd95SBruce Richardson }
89999a2dd95SBruce Richardson
90099a2dd95SBruce Richardson mp = rte_mempool_create(name, num_elements, get_bbdev_op_size(type),
90199a2dd95SBruce Richardson cache_size, sizeof(struct rte_bbdev_op_pool_private),
90299a2dd95SBruce Richardson NULL, NULL, bbdev_op_init, &type, socket_id, 0);
90399a2dd95SBruce Richardson if (mp == NULL) {
90499a2dd95SBruce Richardson rte_bbdev_log(ERR,
90599a2dd95SBruce Richardson "Failed to create op pool %s (num ops=%u, op size=%u) with error: %s",
90699a2dd95SBruce Richardson name, num_elements, get_bbdev_op_size(type),
90799a2dd95SBruce Richardson rte_strerror(rte_errno));
90899a2dd95SBruce Richardson return NULL;
90999a2dd95SBruce Richardson }
91099a2dd95SBruce Richardson
91199a2dd95SBruce Richardson op_type_str = rte_bbdev_op_type_str(type);
91299a2dd95SBruce Richardson if (op_type_str == NULL)
91399a2dd95SBruce Richardson return NULL;
91499a2dd95SBruce Richardson
91599a2dd95SBruce Richardson rte_bbdev_log_debug(
91699a2dd95SBruce Richardson "Op pool %s created for %u ops (type=%s, cache=%u, socket=%u, size=%u)",
91799a2dd95SBruce Richardson name, num_elements, op_type_str, cache_size, socket_id,
91899a2dd95SBruce Richardson get_bbdev_op_size(type));
91999a2dd95SBruce Richardson
92099a2dd95SBruce Richardson priv = (struct rte_bbdev_op_pool_private *)rte_mempool_get_priv(mp);
92199a2dd95SBruce Richardson priv->type = type;
92299a2dd95SBruce Richardson
92399a2dd95SBruce Richardson return mp;
92499a2dd95SBruce Richardson }
92599a2dd95SBruce Richardson
92699a2dd95SBruce Richardson int
rte_bbdev_callback_register(uint16_t dev_id,enum rte_bbdev_event_type event,rte_bbdev_cb_fn cb_fn,void * cb_arg)92799a2dd95SBruce Richardson rte_bbdev_callback_register(uint16_t dev_id, enum rte_bbdev_event_type event,
92899a2dd95SBruce Richardson rte_bbdev_cb_fn cb_fn, void *cb_arg)
92999a2dd95SBruce Richardson {
93099a2dd95SBruce Richardson struct rte_bbdev_callback *user_cb;
93199a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
93299a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
93399a2dd95SBruce Richardson
93499a2dd95SBruce Richardson if (event >= RTE_BBDEV_EVENT_MAX) {
93599a2dd95SBruce Richardson rte_bbdev_log(ERR,
93699a2dd95SBruce Richardson "Invalid event type (%u), should be less than %u",
93799a2dd95SBruce Richardson event, RTE_BBDEV_EVENT_MAX);
93899a2dd95SBruce Richardson return -EINVAL;
93999a2dd95SBruce Richardson }
94099a2dd95SBruce Richardson
94199a2dd95SBruce Richardson if (cb_fn == NULL) {
94299a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL callback function");
94399a2dd95SBruce Richardson return -EINVAL;
94499a2dd95SBruce Richardson }
94599a2dd95SBruce Richardson
94699a2dd95SBruce Richardson rte_spinlock_lock(&rte_bbdev_cb_lock);
94799a2dd95SBruce Richardson
94899a2dd95SBruce Richardson TAILQ_FOREACH(user_cb, &(dev->list_cbs), next) {
94999a2dd95SBruce Richardson if (user_cb->cb_fn == cb_fn &&
95099a2dd95SBruce Richardson user_cb->cb_arg == cb_arg &&
95199a2dd95SBruce Richardson user_cb->event == event)
95299a2dd95SBruce Richardson break;
95399a2dd95SBruce Richardson }
95499a2dd95SBruce Richardson
95599a2dd95SBruce Richardson /* create a new callback. */
95699a2dd95SBruce Richardson if (user_cb == NULL) {
95799a2dd95SBruce Richardson user_cb = rte_zmalloc("INTR_USER_CALLBACK",
95899a2dd95SBruce Richardson sizeof(struct rte_bbdev_callback), 0);
95999a2dd95SBruce Richardson if (user_cb != NULL) {
96099a2dd95SBruce Richardson user_cb->cb_fn = cb_fn;
96199a2dd95SBruce Richardson user_cb->cb_arg = cb_arg;
96299a2dd95SBruce Richardson user_cb->event = event;
96399a2dd95SBruce Richardson TAILQ_INSERT_TAIL(&(dev->list_cbs), user_cb, next);
96499a2dd95SBruce Richardson }
96599a2dd95SBruce Richardson }
96699a2dd95SBruce Richardson
96799a2dd95SBruce Richardson rte_spinlock_unlock(&rte_bbdev_cb_lock);
96899a2dd95SBruce Richardson return (user_cb == NULL) ? -ENOMEM : 0;
96999a2dd95SBruce Richardson }
97099a2dd95SBruce Richardson
97199a2dd95SBruce Richardson int
rte_bbdev_callback_unregister(uint16_t dev_id,enum rte_bbdev_event_type event,rte_bbdev_cb_fn cb_fn,void * cb_arg)97299a2dd95SBruce Richardson rte_bbdev_callback_unregister(uint16_t dev_id, enum rte_bbdev_event_type event,
97399a2dd95SBruce Richardson rte_bbdev_cb_fn cb_fn, void *cb_arg)
97499a2dd95SBruce Richardson {
97599a2dd95SBruce Richardson int ret = 0;
97699a2dd95SBruce Richardson struct rte_bbdev_callback *cb, *next;
97799a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
97899a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
97999a2dd95SBruce Richardson
98099a2dd95SBruce Richardson if (event >= RTE_BBDEV_EVENT_MAX) {
98199a2dd95SBruce Richardson rte_bbdev_log(ERR,
98299a2dd95SBruce Richardson "Invalid event type (%u), should be less than %u",
98399a2dd95SBruce Richardson event, RTE_BBDEV_EVENT_MAX);
98499a2dd95SBruce Richardson return -EINVAL;
98599a2dd95SBruce Richardson }
98699a2dd95SBruce Richardson
98799a2dd95SBruce Richardson if (cb_fn == NULL) {
98899a2dd95SBruce Richardson rte_bbdev_log(ERR,
98999a2dd95SBruce Richardson "NULL callback function cannot be unregistered");
99099a2dd95SBruce Richardson return -EINVAL;
99199a2dd95SBruce Richardson }
99299a2dd95SBruce Richardson
99399a2dd95SBruce Richardson dev = &rte_bbdev_devices[dev_id];
99499a2dd95SBruce Richardson rte_spinlock_lock(&rte_bbdev_cb_lock);
99599a2dd95SBruce Richardson
99699a2dd95SBruce Richardson for (cb = TAILQ_FIRST(&dev->list_cbs); cb != NULL; cb = next) {
99799a2dd95SBruce Richardson
99899a2dd95SBruce Richardson next = TAILQ_NEXT(cb, next);
99999a2dd95SBruce Richardson
100099a2dd95SBruce Richardson if (cb->cb_fn != cb_fn || cb->event != event ||
100199a2dd95SBruce Richardson (cb_arg != (void *)-1 && cb->cb_arg != cb_arg))
100299a2dd95SBruce Richardson continue;
100399a2dd95SBruce Richardson
100499a2dd95SBruce Richardson /* If this callback is not executing right now, remove it. */
100599a2dd95SBruce Richardson if (cb->active == 0) {
100699a2dd95SBruce Richardson TAILQ_REMOVE(&(dev->list_cbs), cb, next);
100799a2dd95SBruce Richardson rte_free(cb);
100899a2dd95SBruce Richardson } else
100999a2dd95SBruce Richardson ret = -EAGAIN;
101099a2dd95SBruce Richardson }
101199a2dd95SBruce Richardson
101299a2dd95SBruce Richardson rte_spinlock_unlock(&rte_bbdev_cb_lock);
101399a2dd95SBruce Richardson return ret;
101499a2dd95SBruce Richardson }
101599a2dd95SBruce Richardson
101699a2dd95SBruce Richardson void
rte_bbdev_pmd_callback_process(struct rte_bbdev * dev,enum rte_bbdev_event_type event,void * ret_param)101799a2dd95SBruce Richardson rte_bbdev_pmd_callback_process(struct rte_bbdev *dev,
101899a2dd95SBruce Richardson enum rte_bbdev_event_type event, void *ret_param)
101999a2dd95SBruce Richardson {
102099a2dd95SBruce Richardson struct rte_bbdev_callback *cb_lst;
102199a2dd95SBruce Richardson struct rte_bbdev_callback dev_cb;
102299a2dd95SBruce Richardson
102399a2dd95SBruce Richardson if (dev == NULL) {
102499a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL device");
102599a2dd95SBruce Richardson return;
102699a2dd95SBruce Richardson }
102799a2dd95SBruce Richardson
102899a2dd95SBruce Richardson if (dev->data == NULL) {
102999a2dd95SBruce Richardson rte_bbdev_log(ERR, "NULL data structure");
103099a2dd95SBruce Richardson return;
103199a2dd95SBruce Richardson }
103299a2dd95SBruce Richardson
103399a2dd95SBruce Richardson if (event >= RTE_BBDEV_EVENT_MAX) {
103499a2dd95SBruce Richardson rte_bbdev_log(ERR,
103599a2dd95SBruce Richardson "Invalid event type (%u), should be less than %u",
103699a2dd95SBruce Richardson event, RTE_BBDEV_EVENT_MAX);
103799a2dd95SBruce Richardson return;
103899a2dd95SBruce Richardson }
103999a2dd95SBruce Richardson
104099a2dd95SBruce Richardson rte_spinlock_lock(&rte_bbdev_cb_lock);
104199a2dd95SBruce Richardson TAILQ_FOREACH(cb_lst, &(dev->list_cbs), next) {
104299a2dd95SBruce Richardson if (cb_lst->cb_fn == NULL || cb_lst->event != event)
104399a2dd95SBruce Richardson continue;
104499a2dd95SBruce Richardson dev_cb = *cb_lst;
104599a2dd95SBruce Richardson cb_lst->active = 1;
104699a2dd95SBruce Richardson if (ret_param != NULL)
104799a2dd95SBruce Richardson dev_cb.ret_param = ret_param;
104899a2dd95SBruce Richardson
104999a2dd95SBruce Richardson rte_spinlock_unlock(&rte_bbdev_cb_lock);
105099a2dd95SBruce Richardson dev_cb.cb_fn(dev->data->dev_id, dev_cb.event,
105199a2dd95SBruce Richardson dev_cb.cb_arg, dev_cb.ret_param);
105299a2dd95SBruce Richardson rte_spinlock_lock(&rte_bbdev_cb_lock);
105399a2dd95SBruce Richardson cb_lst->active = 0;
105499a2dd95SBruce Richardson }
105599a2dd95SBruce Richardson rte_spinlock_unlock(&rte_bbdev_cb_lock);
105699a2dd95SBruce Richardson }
105799a2dd95SBruce Richardson
105899a2dd95SBruce Richardson int
rte_bbdev_queue_intr_enable(uint16_t dev_id,uint16_t queue_id)105999a2dd95SBruce Richardson rte_bbdev_queue_intr_enable(uint16_t dev_id, uint16_t queue_id)
106099a2dd95SBruce Richardson {
106199a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
106299a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
106399a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
106499a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
106599a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_intr_enable, dev_id);
106699a2dd95SBruce Richardson return dev->dev_ops->queue_intr_enable(dev, queue_id);
106799a2dd95SBruce Richardson }
106899a2dd95SBruce Richardson
106999a2dd95SBruce Richardson int
rte_bbdev_queue_intr_disable(uint16_t dev_id,uint16_t queue_id)107099a2dd95SBruce Richardson rte_bbdev_queue_intr_disable(uint16_t dev_id, uint16_t queue_id)
107199a2dd95SBruce Richardson {
107299a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
107399a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
107499a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
107599a2dd95SBruce Richardson VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
107699a2dd95SBruce Richardson VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_intr_disable, dev_id);
107799a2dd95SBruce Richardson return dev->dev_ops->queue_intr_disable(dev, queue_id);
107899a2dd95SBruce Richardson }
107999a2dd95SBruce Richardson
108099a2dd95SBruce Richardson int
rte_bbdev_queue_intr_ctl(uint16_t dev_id,uint16_t queue_id,int epfd,int op,void * data)108199a2dd95SBruce Richardson rte_bbdev_queue_intr_ctl(uint16_t dev_id, uint16_t queue_id, int epfd, int op,
108299a2dd95SBruce Richardson void *data)
108399a2dd95SBruce Richardson {
108499a2dd95SBruce Richardson uint32_t vec;
108599a2dd95SBruce Richardson struct rte_bbdev *dev = get_dev(dev_id);
108699a2dd95SBruce Richardson struct rte_intr_handle *intr_handle;
108799a2dd95SBruce Richardson int ret;
108899a2dd95SBruce Richardson
108999a2dd95SBruce Richardson VALID_DEV_OR_RET_ERR(dev, dev_id);
109099a2dd95SBruce Richardson VALID_QUEUE_OR_RET_ERR(queue_id, dev);
109199a2dd95SBruce Richardson
109299a2dd95SBruce Richardson intr_handle = dev->intr_handle;
1093c2bd9367SHarman Kalra if (intr_handle == NULL) {
109499a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u intr handle unset\n", dev_id);
109599a2dd95SBruce Richardson return -ENOTSUP;
109699a2dd95SBruce Richardson }
109799a2dd95SBruce Richardson
109899a2dd95SBruce Richardson if (queue_id >= RTE_MAX_RXTX_INTR_VEC_ID) {
109999a2dd95SBruce Richardson rte_bbdev_log(ERR, "Device %u queue_id %u is too big\n",
110099a2dd95SBruce Richardson dev_id, queue_id);
110199a2dd95SBruce Richardson return -ENOTSUP;
110299a2dd95SBruce Richardson }
110399a2dd95SBruce Richardson
1104c2bd9367SHarman Kalra vec = rte_intr_vec_list_index_get(intr_handle, queue_id);
110599a2dd95SBruce Richardson ret = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
110699a2dd95SBruce Richardson if (ret && (ret != -EEXIST)) {
110799a2dd95SBruce Richardson rte_bbdev_log(ERR,
110899a2dd95SBruce Richardson "dev %u q %u int ctl error op %d epfd %d vec %u\n",
110999a2dd95SBruce Richardson dev_id, queue_id, op, epfd, vec);
111099a2dd95SBruce Richardson return ret;
111199a2dd95SBruce Richardson }
111299a2dd95SBruce Richardson
111399a2dd95SBruce Richardson return 0;
111499a2dd95SBruce Richardson }
111599a2dd95SBruce Richardson
111699a2dd95SBruce Richardson
111799a2dd95SBruce Richardson const char *
rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type)111899a2dd95SBruce Richardson rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type)
111999a2dd95SBruce Richardson {
112099a2dd95SBruce Richardson static const char * const op_types[] = {
112199a2dd95SBruce Richardson "RTE_BBDEV_OP_NONE",
112299a2dd95SBruce Richardson "RTE_BBDEV_OP_TURBO_DEC",
112399a2dd95SBruce Richardson "RTE_BBDEV_OP_TURBO_ENC",
112499a2dd95SBruce Richardson "RTE_BBDEV_OP_LDPC_DEC",
112599a2dd95SBruce Richardson "RTE_BBDEV_OP_LDPC_ENC",
112699a2dd95SBruce Richardson };
112799a2dd95SBruce Richardson
112899a2dd95SBruce Richardson if (op_type < RTE_BBDEV_OP_TYPE_COUNT)
112999a2dd95SBruce Richardson return op_types[op_type];
113099a2dd95SBruce Richardson
113199a2dd95SBruce Richardson rte_bbdev_log(ERR, "Invalid operation type");
113299a2dd95SBruce Richardson return NULL;
113399a2dd95SBruce Richardson }
1134