xref: /f-stack/dpdk/lib/librte_bbdev/rte_bbdev.c (revision 2d9fd380)
1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2017 Intel Corporation
3d30ea906Sjfb8856606  */
4d30ea906Sjfb8856606 
5d30ea906Sjfb8856606 #include <stdint.h>
6d30ea906Sjfb8856606 #include <string.h>
7d30ea906Sjfb8856606 #include <stdbool.h>
8d30ea906Sjfb8856606 
9d30ea906Sjfb8856606 #include <rte_compat.h>
10d30ea906Sjfb8856606 #include <rte_common.h>
11d30ea906Sjfb8856606 #include <rte_errno.h>
12d30ea906Sjfb8856606 #include <rte_log.h>
13d30ea906Sjfb8856606 #include <rte_debug.h>
14d30ea906Sjfb8856606 #include <rte_eal.h>
15d30ea906Sjfb8856606 #include <rte_malloc.h>
16d30ea906Sjfb8856606 #include <rte_mempool.h>
17d30ea906Sjfb8856606 #include <rte_memzone.h>
18d30ea906Sjfb8856606 #include <rte_lcore.h>
19d30ea906Sjfb8856606 #include <rte_dev.h>
20d30ea906Sjfb8856606 #include <rte_spinlock.h>
21d30ea906Sjfb8856606 #include <rte_tailq.h>
22d30ea906Sjfb8856606 #include <rte_interrupts.h>
23d30ea906Sjfb8856606 
24d30ea906Sjfb8856606 #include "rte_bbdev_op.h"
25d30ea906Sjfb8856606 #include "rte_bbdev.h"
26d30ea906Sjfb8856606 #include "rte_bbdev_pmd.h"
27d30ea906Sjfb8856606 
28d30ea906Sjfb8856606 #define DEV_NAME "BBDEV"
29d30ea906Sjfb8856606 
30d30ea906Sjfb8856606 
31d30ea906Sjfb8856606 /* BBDev library logging ID */
32*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(bbdev_logtype, lib.bbdev, NOTICE);
33d30ea906Sjfb8856606 
34d30ea906Sjfb8856606 /* Helper macro for logging */
35d30ea906Sjfb8856606 #define rte_bbdev_log(level, fmt, ...) \
36d30ea906Sjfb8856606 	rte_log(RTE_LOG_ ## level, bbdev_logtype, fmt "\n", ##__VA_ARGS__)
37d30ea906Sjfb8856606 
38d30ea906Sjfb8856606 #define rte_bbdev_log_debug(fmt, ...) \
39d30ea906Sjfb8856606 	rte_bbdev_log(DEBUG, RTE_STR(__LINE__) ":%s() " fmt, __func__, \
40d30ea906Sjfb8856606 		##__VA_ARGS__)
41d30ea906Sjfb8856606 
42d30ea906Sjfb8856606 /* Helper macro to check dev_id is valid */
43d30ea906Sjfb8856606 #define VALID_DEV_OR_RET_ERR(dev, dev_id) do { \
44d30ea906Sjfb8856606 	if (dev == NULL) { \
45d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "device %u is invalid", dev_id); \
46d30ea906Sjfb8856606 		return -ENODEV; \
47d30ea906Sjfb8856606 	} \
48d30ea906Sjfb8856606 } while (0)
49d30ea906Sjfb8856606 
50d30ea906Sjfb8856606 /* Helper macro to check dev_ops is valid */
51d30ea906Sjfb8856606 #define VALID_DEV_OPS_OR_RET_ERR(dev, dev_id) do { \
52d30ea906Sjfb8856606 	if (dev->dev_ops == NULL) { \
53d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL dev_ops structure in device %u", \
54d30ea906Sjfb8856606 				dev_id); \
55d30ea906Sjfb8856606 		return -ENODEV; \
56d30ea906Sjfb8856606 	} \
57d30ea906Sjfb8856606 } while (0)
58d30ea906Sjfb8856606 
59d30ea906Sjfb8856606 /* Helper macro to check that driver implements required function pointer */
60d30ea906Sjfb8856606 #define VALID_FUNC_OR_RET_ERR(func, dev_id) do { \
61d30ea906Sjfb8856606 	if (func == NULL) { \
62d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "device %u does not support %s", \
63d30ea906Sjfb8856606 				dev_id, #func); \
64d30ea906Sjfb8856606 		return -ENOTSUP; \
65d30ea906Sjfb8856606 	} \
66d30ea906Sjfb8856606 } while (0)
67d30ea906Sjfb8856606 
68d30ea906Sjfb8856606 /* Helper macro to check that queue is valid */
69d30ea906Sjfb8856606 #define VALID_QUEUE_OR_RET_ERR(queue_id, dev) do { \
70d30ea906Sjfb8856606 	if (queue_id >= dev->data->num_queues) { \
71d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Invalid queue_id %u for device %u", \
72d30ea906Sjfb8856606 				queue_id, dev->data->dev_id); \
73d30ea906Sjfb8856606 		return -ERANGE; \
74d30ea906Sjfb8856606 	} \
75d30ea906Sjfb8856606 } while (0)
76d30ea906Sjfb8856606 
77d30ea906Sjfb8856606 /* List of callback functions registered by an application */
78d30ea906Sjfb8856606 struct rte_bbdev_callback {
79d30ea906Sjfb8856606 	TAILQ_ENTRY(rte_bbdev_callback) next;  /* Callbacks list */
80d30ea906Sjfb8856606 	rte_bbdev_cb_fn cb_fn;  /* Callback address */
81d30ea906Sjfb8856606 	void *cb_arg;  /* Parameter for callback */
82d30ea906Sjfb8856606 	void *ret_param;  /* Return parameter */
83d30ea906Sjfb8856606 	enum rte_bbdev_event_type event; /* Interrupt event type */
84d30ea906Sjfb8856606 	uint32_t active; /* Callback is executing */
85d30ea906Sjfb8856606 };
86d30ea906Sjfb8856606 
87d30ea906Sjfb8856606 /* spinlock for bbdev device callbacks */
88d30ea906Sjfb8856606 static rte_spinlock_t rte_bbdev_cb_lock = RTE_SPINLOCK_INITIALIZER;
89d30ea906Sjfb8856606 
90d30ea906Sjfb8856606 /*
91d30ea906Sjfb8856606  * Global array of all devices. This is not static because it's used by the
92d30ea906Sjfb8856606  * inline enqueue and dequeue functions
93d30ea906Sjfb8856606  */
94d30ea906Sjfb8856606 struct rte_bbdev rte_bbdev_devices[RTE_BBDEV_MAX_DEVS];
95d30ea906Sjfb8856606 
96d30ea906Sjfb8856606 /* Global array with rte_bbdev_data structures */
97d30ea906Sjfb8856606 static struct rte_bbdev_data *rte_bbdev_data;
98d30ea906Sjfb8856606 
99d30ea906Sjfb8856606 /* Memzone name for global bbdev data pool */
100d30ea906Sjfb8856606 static const char *MZ_RTE_BBDEV_DATA = "rte_bbdev_data";
101d30ea906Sjfb8856606 
102d30ea906Sjfb8856606 /* Number of currently valid devices */
103d30ea906Sjfb8856606 static uint16_t num_devs;
104d30ea906Sjfb8856606 
105d30ea906Sjfb8856606 /* Return pointer to device structure, with validity check */
106d30ea906Sjfb8856606 static struct rte_bbdev *
get_dev(uint16_t dev_id)107d30ea906Sjfb8856606 get_dev(uint16_t dev_id)
108d30ea906Sjfb8856606 {
109d30ea906Sjfb8856606 	if (rte_bbdev_is_valid(dev_id))
110d30ea906Sjfb8856606 		return &rte_bbdev_devices[dev_id];
111d30ea906Sjfb8856606 	return NULL;
112d30ea906Sjfb8856606 }
113d30ea906Sjfb8856606 
114d30ea906Sjfb8856606 /* Allocate global data array */
115d30ea906Sjfb8856606 static int
rte_bbdev_data_alloc(void)116d30ea906Sjfb8856606 rte_bbdev_data_alloc(void)
117d30ea906Sjfb8856606 {
118d30ea906Sjfb8856606 	const unsigned int flags = 0;
119d30ea906Sjfb8856606 	const struct rte_memzone *mz;
120d30ea906Sjfb8856606 
121d30ea906Sjfb8856606 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
122d30ea906Sjfb8856606 		mz = rte_memzone_reserve(MZ_RTE_BBDEV_DATA,
123d30ea906Sjfb8856606 				RTE_BBDEV_MAX_DEVS * sizeof(*rte_bbdev_data),
124d30ea906Sjfb8856606 				rte_socket_id(), flags);
125d30ea906Sjfb8856606 	} else
126d30ea906Sjfb8856606 		mz = rte_memzone_lookup(MZ_RTE_BBDEV_DATA);
127d30ea906Sjfb8856606 	if (mz == NULL) {
128d30ea906Sjfb8856606 		rte_bbdev_log(CRIT,
129d30ea906Sjfb8856606 				"Cannot allocate memzone for bbdev port data");
130d30ea906Sjfb8856606 		return -ENOMEM;
131d30ea906Sjfb8856606 	}
132d30ea906Sjfb8856606 
133d30ea906Sjfb8856606 	rte_bbdev_data = mz->addr;
134d30ea906Sjfb8856606 	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
135d30ea906Sjfb8856606 		memset(rte_bbdev_data, 0,
136d30ea906Sjfb8856606 				RTE_BBDEV_MAX_DEVS * sizeof(*rte_bbdev_data));
137d30ea906Sjfb8856606 	return 0;
138d30ea906Sjfb8856606 }
139d30ea906Sjfb8856606 
140d30ea906Sjfb8856606 /*
141d30ea906Sjfb8856606  * Find data alocated for the device or if not found return first unused bbdev
142d30ea906Sjfb8856606  * data. If all structures are in use and none is used by the device return
143d30ea906Sjfb8856606  * NULL.
144d30ea906Sjfb8856606  */
145d30ea906Sjfb8856606 static struct rte_bbdev_data *
find_bbdev_data(const char * name)146d30ea906Sjfb8856606 find_bbdev_data(const char *name)
147d30ea906Sjfb8856606 {
148d30ea906Sjfb8856606 	uint16_t data_id;
149d30ea906Sjfb8856606 
150d30ea906Sjfb8856606 	for (data_id = 0; data_id < RTE_BBDEV_MAX_DEVS; ++data_id) {
151d30ea906Sjfb8856606 		if (strlen(rte_bbdev_data[data_id].name) == 0) {
152d30ea906Sjfb8856606 			memset(&rte_bbdev_data[data_id], 0,
153d30ea906Sjfb8856606 					sizeof(struct rte_bbdev_data));
154d30ea906Sjfb8856606 			return &rte_bbdev_data[data_id];
155d30ea906Sjfb8856606 		} else if (strncmp(rte_bbdev_data[data_id].name, name,
156d30ea906Sjfb8856606 				RTE_BBDEV_NAME_MAX_LEN) == 0)
157d30ea906Sjfb8856606 			return &rte_bbdev_data[data_id];
158d30ea906Sjfb8856606 	}
159d30ea906Sjfb8856606 
160d30ea906Sjfb8856606 	return NULL;
161d30ea906Sjfb8856606 }
162d30ea906Sjfb8856606 
163d30ea906Sjfb8856606 /* Find lowest device id with no attached device */
164d30ea906Sjfb8856606 static uint16_t
find_free_dev_id(void)165d30ea906Sjfb8856606 find_free_dev_id(void)
166d30ea906Sjfb8856606 {
167d30ea906Sjfb8856606 	uint16_t i;
168d30ea906Sjfb8856606 	for (i = 0; i < RTE_BBDEV_MAX_DEVS; i++) {
169d30ea906Sjfb8856606 		if (rte_bbdev_devices[i].state == RTE_BBDEV_UNUSED)
170d30ea906Sjfb8856606 			return i;
171d30ea906Sjfb8856606 	}
172d30ea906Sjfb8856606 	return RTE_BBDEV_MAX_DEVS;
173d30ea906Sjfb8856606 }
174d30ea906Sjfb8856606 
1754418919fSjohnjiang struct rte_bbdev *
rte_bbdev_allocate(const char * name)176d30ea906Sjfb8856606 rte_bbdev_allocate(const char *name)
177d30ea906Sjfb8856606 {
178d30ea906Sjfb8856606 	int ret;
179d30ea906Sjfb8856606 	struct rte_bbdev *bbdev;
180d30ea906Sjfb8856606 	uint16_t dev_id;
181d30ea906Sjfb8856606 
182d30ea906Sjfb8856606 	if (name == NULL) {
183d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Invalid null device name");
184d30ea906Sjfb8856606 		return NULL;
185d30ea906Sjfb8856606 	}
186d30ea906Sjfb8856606 
187d30ea906Sjfb8856606 	if (rte_bbdev_get_named_dev(name) != NULL) {
188d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Device \"%s\" is already allocated", name);
189d30ea906Sjfb8856606 		return NULL;
190d30ea906Sjfb8856606 	}
191d30ea906Sjfb8856606 
192d30ea906Sjfb8856606 	dev_id = find_free_dev_id();
193d30ea906Sjfb8856606 	if (dev_id == RTE_BBDEV_MAX_DEVS) {
194d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Reached maximum number of devices");
195d30ea906Sjfb8856606 		return NULL;
196d30ea906Sjfb8856606 	}
197d30ea906Sjfb8856606 
198d30ea906Sjfb8856606 	bbdev = &rte_bbdev_devices[dev_id];
199d30ea906Sjfb8856606 
200d30ea906Sjfb8856606 	if (rte_bbdev_data == NULL) {
201d30ea906Sjfb8856606 		ret = rte_bbdev_data_alloc();
202d30ea906Sjfb8856606 		if (ret != 0)
203d30ea906Sjfb8856606 			return NULL;
204d30ea906Sjfb8856606 	}
205d30ea906Sjfb8856606 
206d30ea906Sjfb8856606 	bbdev->data = find_bbdev_data(name);
207d30ea906Sjfb8856606 	if (bbdev->data == NULL) {
208d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
209d30ea906Sjfb8856606 				"Max BBDevs already allocated in multi-process environment!");
210d30ea906Sjfb8856606 		return NULL;
211d30ea906Sjfb8856606 	}
212d30ea906Sjfb8856606 
213*2d9fd380Sjfb8856606 	__atomic_add_fetch(&bbdev->data->process_cnt, 1, __ATOMIC_RELAXED);
214d30ea906Sjfb8856606 	bbdev->data->dev_id = dev_id;
215d30ea906Sjfb8856606 	bbdev->state = RTE_BBDEV_INITIALIZED;
216d30ea906Sjfb8856606 
217d30ea906Sjfb8856606 	ret = snprintf(bbdev->data->name, RTE_BBDEV_NAME_MAX_LEN, "%s", name);
218d30ea906Sjfb8856606 	if ((ret < 0) || (ret >= RTE_BBDEV_NAME_MAX_LEN)) {
219d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Copying device name \"%s\" failed", name);
220d30ea906Sjfb8856606 		return NULL;
221d30ea906Sjfb8856606 	}
222d30ea906Sjfb8856606 
223d30ea906Sjfb8856606 	/* init user callbacks */
224d30ea906Sjfb8856606 	TAILQ_INIT(&(bbdev->list_cbs));
225d30ea906Sjfb8856606 
226d30ea906Sjfb8856606 	num_devs++;
227d30ea906Sjfb8856606 
228d30ea906Sjfb8856606 	rte_bbdev_log_debug("Initialised device %s (id = %u). Num devices = %u",
229d30ea906Sjfb8856606 			name, dev_id, num_devs);
230d30ea906Sjfb8856606 
231d30ea906Sjfb8856606 	return bbdev;
232d30ea906Sjfb8856606 }
233d30ea906Sjfb8856606 
2344418919fSjohnjiang int
rte_bbdev_release(struct rte_bbdev * bbdev)235d30ea906Sjfb8856606 rte_bbdev_release(struct rte_bbdev *bbdev)
236d30ea906Sjfb8856606 {
237d30ea906Sjfb8856606 	uint16_t dev_id;
238d30ea906Sjfb8856606 	struct rte_bbdev_callback *cb, *next;
239d30ea906Sjfb8856606 
240d30ea906Sjfb8856606 	if (bbdev == NULL) {
241d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL bbdev");
242d30ea906Sjfb8856606 		return -ENODEV;
243d30ea906Sjfb8856606 	}
244d30ea906Sjfb8856606 	dev_id = bbdev->data->dev_id;
245d30ea906Sjfb8856606 
246d30ea906Sjfb8856606 	/* free all callbacks from the device's list */
247d30ea906Sjfb8856606 	for (cb = TAILQ_FIRST(&bbdev->list_cbs); cb != NULL; cb = next) {
248d30ea906Sjfb8856606 
249d30ea906Sjfb8856606 		next = TAILQ_NEXT(cb, next);
250d30ea906Sjfb8856606 		TAILQ_REMOVE(&(bbdev->list_cbs), cb, next);
251d30ea906Sjfb8856606 		rte_free(cb);
252d30ea906Sjfb8856606 	}
253d30ea906Sjfb8856606 
254d30ea906Sjfb8856606 	/* clear shared BBDev Data if no process is using the device anymore */
255*2d9fd380Sjfb8856606 	if (__atomic_sub_fetch(&bbdev->data->process_cnt, 1,
256*2d9fd380Sjfb8856606 			      __ATOMIC_RELAXED) == 0)
257d30ea906Sjfb8856606 		memset(bbdev->data, 0, sizeof(*bbdev->data));
258d30ea906Sjfb8856606 
259d30ea906Sjfb8856606 	memset(bbdev, 0, sizeof(*bbdev));
260d30ea906Sjfb8856606 	num_devs--;
261d30ea906Sjfb8856606 	bbdev->state = RTE_BBDEV_UNUSED;
262d30ea906Sjfb8856606 
263d30ea906Sjfb8856606 	rte_bbdev_log_debug(
264d30ea906Sjfb8856606 			"Un-initialised device id = %u. Num devices = %u",
265d30ea906Sjfb8856606 			dev_id, num_devs);
266d30ea906Sjfb8856606 	return 0;
267d30ea906Sjfb8856606 }
268d30ea906Sjfb8856606 
2694418919fSjohnjiang struct rte_bbdev *
rte_bbdev_get_named_dev(const char * name)270d30ea906Sjfb8856606 rte_bbdev_get_named_dev(const char *name)
271d30ea906Sjfb8856606 {
272d30ea906Sjfb8856606 	unsigned int i;
273d30ea906Sjfb8856606 
274d30ea906Sjfb8856606 	if (name == NULL) {
275d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL driver name");
276d30ea906Sjfb8856606 		return NULL;
277d30ea906Sjfb8856606 	}
278d30ea906Sjfb8856606 
279d30ea906Sjfb8856606 	for (i = 0; i < RTE_BBDEV_MAX_DEVS; i++) {
280d30ea906Sjfb8856606 		struct rte_bbdev *dev = get_dev(i);
281d30ea906Sjfb8856606 		if (dev && (strncmp(dev->data->name,
282d30ea906Sjfb8856606 				name, RTE_BBDEV_NAME_MAX_LEN) == 0))
283d30ea906Sjfb8856606 			return dev;
284d30ea906Sjfb8856606 	}
285d30ea906Sjfb8856606 
286d30ea906Sjfb8856606 	return NULL;
287d30ea906Sjfb8856606 }
288d30ea906Sjfb8856606 
2894418919fSjohnjiang uint16_t
rte_bbdev_count(void)290d30ea906Sjfb8856606 rte_bbdev_count(void)
291d30ea906Sjfb8856606 {
292d30ea906Sjfb8856606 	return num_devs;
293d30ea906Sjfb8856606 }
294d30ea906Sjfb8856606 
2954418919fSjohnjiang bool
rte_bbdev_is_valid(uint16_t dev_id)296d30ea906Sjfb8856606 rte_bbdev_is_valid(uint16_t dev_id)
297d30ea906Sjfb8856606 {
298d30ea906Sjfb8856606 	if ((dev_id < RTE_BBDEV_MAX_DEVS) &&
299d30ea906Sjfb8856606 		rte_bbdev_devices[dev_id].state == RTE_BBDEV_INITIALIZED)
300d30ea906Sjfb8856606 		return true;
301d30ea906Sjfb8856606 	return false;
302d30ea906Sjfb8856606 }
303d30ea906Sjfb8856606 
3044418919fSjohnjiang uint16_t
rte_bbdev_find_next(uint16_t dev_id)305d30ea906Sjfb8856606 rte_bbdev_find_next(uint16_t dev_id)
306d30ea906Sjfb8856606 {
307d30ea906Sjfb8856606 	dev_id++;
308d30ea906Sjfb8856606 	for (; dev_id < RTE_BBDEV_MAX_DEVS; dev_id++)
309d30ea906Sjfb8856606 		if (rte_bbdev_is_valid(dev_id))
310d30ea906Sjfb8856606 			break;
311d30ea906Sjfb8856606 	return dev_id;
312d30ea906Sjfb8856606 }
313d30ea906Sjfb8856606 
3144418919fSjohnjiang int
rte_bbdev_setup_queues(uint16_t dev_id,uint16_t num_queues,int socket_id)315d30ea906Sjfb8856606 rte_bbdev_setup_queues(uint16_t dev_id, uint16_t num_queues, int socket_id)
316d30ea906Sjfb8856606 {
317d30ea906Sjfb8856606 	unsigned int i;
318d30ea906Sjfb8856606 	int ret;
319d30ea906Sjfb8856606 	struct rte_bbdev_driver_info dev_info;
320d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
321d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
322d30ea906Sjfb8856606 
323d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
324d30ea906Sjfb8856606 
325d30ea906Sjfb8856606 	if (dev->data->started) {
326d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
327d30ea906Sjfb8856606 				"Device %u cannot be configured when started",
328d30ea906Sjfb8856606 				dev_id);
329d30ea906Sjfb8856606 		return -EBUSY;
330d30ea906Sjfb8856606 	}
331d30ea906Sjfb8856606 
332d30ea906Sjfb8856606 	/* Get device driver information to get max number of queues */
333d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);
334d30ea906Sjfb8856606 	memset(&dev_info, 0, sizeof(dev_info));
335d30ea906Sjfb8856606 	dev->dev_ops->info_get(dev, &dev_info);
336d30ea906Sjfb8856606 
337d30ea906Sjfb8856606 	if ((num_queues == 0) || (num_queues > dev_info.max_num_queues)) {
338d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
339d30ea906Sjfb8856606 				"Device %u supports 0 < N <= %u queues, not %u",
340d30ea906Sjfb8856606 				dev_id, dev_info.max_num_queues, num_queues);
341d30ea906Sjfb8856606 		return -EINVAL;
342d30ea906Sjfb8856606 	}
343d30ea906Sjfb8856606 
344d30ea906Sjfb8856606 	/* If re-configuration, get driver to free existing internal memory */
345d30ea906Sjfb8856606 	if (dev->data->queues != NULL) {
346d30ea906Sjfb8856606 		VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_release, dev_id);
347d30ea906Sjfb8856606 		for (i = 0; i < dev->data->num_queues; i++) {
348d30ea906Sjfb8856606 			int ret = dev->dev_ops->queue_release(dev, i);
349d30ea906Sjfb8856606 			if (ret < 0) {
350d30ea906Sjfb8856606 				rte_bbdev_log(ERR,
351d30ea906Sjfb8856606 						"Device %u queue %u release failed",
352d30ea906Sjfb8856606 						dev_id, i);
353d30ea906Sjfb8856606 				return ret;
354d30ea906Sjfb8856606 			}
355d30ea906Sjfb8856606 		}
356d30ea906Sjfb8856606 		/* Call optional device close */
357d30ea906Sjfb8856606 		if (dev->dev_ops->close) {
358d30ea906Sjfb8856606 			ret = dev->dev_ops->close(dev);
359d30ea906Sjfb8856606 			if (ret < 0) {
360d30ea906Sjfb8856606 				rte_bbdev_log(ERR,
361d30ea906Sjfb8856606 						"Device %u couldn't be closed",
362d30ea906Sjfb8856606 						dev_id);
363d30ea906Sjfb8856606 				return ret;
364d30ea906Sjfb8856606 			}
365d30ea906Sjfb8856606 		}
366d30ea906Sjfb8856606 		rte_free(dev->data->queues);
367d30ea906Sjfb8856606 	}
368d30ea906Sjfb8856606 
369d30ea906Sjfb8856606 	/* Allocate queue pointers */
370d30ea906Sjfb8856606 	dev->data->queues = rte_calloc_socket(DEV_NAME, num_queues,
371d30ea906Sjfb8856606 			sizeof(dev->data->queues[0]), RTE_CACHE_LINE_SIZE,
372d30ea906Sjfb8856606 				dev->data->socket_id);
373d30ea906Sjfb8856606 	if (dev->data->queues == NULL) {
374d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
375d30ea906Sjfb8856606 				"calloc of %u queues for device %u on socket %i failed",
376d30ea906Sjfb8856606 				num_queues, dev_id, dev->data->socket_id);
377d30ea906Sjfb8856606 		return -ENOMEM;
378d30ea906Sjfb8856606 	}
379d30ea906Sjfb8856606 
380d30ea906Sjfb8856606 	dev->data->num_queues = num_queues;
381d30ea906Sjfb8856606 
382d30ea906Sjfb8856606 	/* Call optional device configuration */
383d30ea906Sjfb8856606 	if (dev->dev_ops->setup_queues) {
384d30ea906Sjfb8856606 		ret = dev->dev_ops->setup_queues(dev, num_queues, socket_id);
385d30ea906Sjfb8856606 		if (ret < 0) {
386d30ea906Sjfb8856606 			rte_bbdev_log(ERR,
387d30ea906Sjfb8856606 					"Device %u memory configuration failed",
388d30ea906Sjfb8856606 					dev_id);
389d30ea906Sjfb8856606 			goto error;
390d30ea906Sjfb8856606 		}
391d30ea906Sjfb8856606 	}
392d30ea906Sjfb8856606 
393d30ea906Sjfb8856606 	rte_bbdev_log_debug("Device %u set up with %u queues", dev_id,
394d30ea906Sjfb8856606 			num_queues);
395d30ea906Sjfb8856606 	return 0;
396d30ea906Sjfb8856606 
397d30ea906Sjfb8856606 error:
398d30ea906Sjfb8856606 	dev->data->num_queues = 0;
399d30ea906Sjfb8856606 	rte_free(dev->data->queues);
400d30ea906Sjfb8856606 	dev->data->queues = NULL;
401d30ea906Sjfb8856606 	return ret;
402d30ea906Sjfb8856606 }
403d30ea906Sjfb8856606 
4044418919fSjohnjiang int
rte_bbdev_intr_enable(uint16_t dev_id)405d30ea906Sjfb8856606 rte_bbdev_intr_enable(uint16_t dev_id)
406d30ea906Sjfb8856606 {
407d30ea906Sjfb8856606 	int ret;
408d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
409d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
410d30ea906Sjfb8856606 
411d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
412d30ea906Sjfb8856606 
413d30ea906Sjfb8856606 	if (dev->data->started) {
414d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
415d30ea906Sjfb8856606 				"Device %u cannot be configured when started",
416d30ea906Sjfb8856606 				dev_id);
417d30ea906Sjfb8856606 		return -EBUSY;
418d30ea906Sjfb8856606 	}
419d30ea906Sjfb8856606 
420d30ea906Sjfb8856606 	if (dev->dev_ops->intr_enable) {
421d30ea906Sjfb8856606 		ret = dev->dev_ops->intr_enable(dev);
422d30ea906Sjfb8856606 		if (ret < 0) {
423d30ea906Sjfb8856606 			rte_bbdev_log(ERR,
424d30ea906Sjfb8856606 					"Device %u interrupts configuration failed",
425d30ea906Sjfb8856606 					dev_id);
426d30ea906Sjfb8856606 			return ret;
427d30ea906Sjfb8856606 		}
428d30ea906Sjfb8856606 		rte_bbdev_log_debug("Enabled interrupts for dev %u", dev_id);
429d30ea906Sjfb8856606 		return 0;
430d30ea906Sjfb8856606 	}
431d30ea906Sjfb8856606 
432d30ea906Sjfb8856606 	rte_bbdev_log(ERR, "Device %u doesn't support interrupts", dev_id);
433d30ea906Sjfb8856606 	return -ENOTSUP;
434d30ea906Sjfb8856606 }
435d30ea906Sjfb8856606 
4364418919fSjohnjiang int
rte_bbdev_queue_configure(uint16_t dev_id,uint16_t queue_id,const struct rte_bbdev_queue_conf * conf)437d30ea906Sjfb8856606 rte_bbdev_queue_configure(uint16_t dev_id, uint16_t queue_id,
438d30ea906Sjfb8856606 		const struct rte_bbdev_queue_conf *conf)
439d30ea906Sjfb8856606 {
440d30ea906Sjfb8856606 	int ret = 0;
441d30ea906Sjfb8856606 	struct rte_bbdev_driver_info dev_info;
442d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
443d30ea906Sjfb8856606 	const struct rte_bbdev_op_cap *p;
444d30ea906Sjfb8856606 	struct rte_bbdev_queue_conf *stored_conf;
445d30ea906Sjfb8856606 	const char *op_type_str;
446d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
447d30ea906Sjfb8856606 
448d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
449d30ea906Sjfb8856606 
450d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
451d30ea906Sjfb8856606 
452d30ea906Sjfb8856606 	if (dev->data->queues[queue_id].started || dev->data->started) {
453d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
454d30ea906Sjfb8856606 				"Queue %u of device %u cannot be configured when started",
455d30ea906Sjfb8856606 				queue_id, dev_id);
456d30ea906Sjfb8856606 		return -EBUSY;
457d30ea906Sjfb8856606 	}
458d30ea906Sjfb8856606 
459d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_release, dev_id);
460d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_setup, dev_id);
461d30ea906Sjfb8856606 
462d30ea906Sjfb8856606 	/* Get device driver information to verify config is valid */
463d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);
464d30ea906Sjfb8856606 	memset(&dev_info, 0, sizeof(dev_info));
465d30ea906Sjfb8856606 	dev->dev_ops->info_get(dev, &dev_info);
466d30ea906Sjfb8856606 
467d30ea906Sjfb8856606 	/* Check configuration is valid */
468d30ea906Sjfb8856606 	if (conf != NULL) {
469d30ea906Sjfb8856606 		if ((conf->op_type == RTE_BBDEV_OP_NONE) &&
470d30ea906Sjfb8856606 				(dev_info.capabilities[0].type ==
471d30ea906Sjfb8856606 				RTE_BBDEV_OP_NONE)) {
472d30ea906Sjfb8856606 			ret = 1;
473d30ea906Sjfb8856606 		} else {
474d30ea906Sjfb8856606 			for (p = dev_info.capabilities;
475d30ea906Sjfb8856606 					p->type != RTE_BBDEV_OP_NONE; p++) {
476d30ea906Sjfb8856606 				if (conf->op_type == p->type) {
477d30ea906Sjfb8856606 					ret = 1;
478d30ea906Sjfb8856606 					break;
479d30ea906Sjfb8856606 				}
480d30ea906Sjfb8856606 			}
481d30ea906Sjfb8856606 		}
482d30ea906Sjfb8856606 		if (ret == 0) {
483d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Invalid operation type");
484d30ea906Sjfb8856606 			return -EINVAL;
485d30ea906Sjfb8856606 		}
486d30ea906Sjfb8856606 		if (conf->queue_size > dev_info.queue_size_lim) {
487d30ea906Sjfb8856606 			rte_bbdev_log(ERR,
488d30ea906Sjfb8856606 					"Size (%u) of queue %u of device %u must be: <= %u",
489d30ea906Sjfb8856606 					conf->queue_size, queue_id, dev_id,
490d30ea906Sjfb8856606 					dev_info.queue_size_lim);
491d30ea906Sjfb8856606 			return -EINVAL;
492d30ea906Sjfb8856606 		}
493d30ea906Sjfb8856606 		if (!rte_is_power_of_2(conf->queue_size)) {
494d30ea906Sjfb8856606 			rte_bbdev_log(ERR,
495d30ea906Sjfb8856606 					"Size (%u) of queue %u of device %u must be a power of 2",
496d30ea906Sjfb8856606 					conf->queue_size, queue_id, dev_id);
497d30ea906Sjfb8856606 			return -EINVAL;
498d30ea906Sjfb8856606 		}
499d30ea906Sjfb8856606 		if (conf->op_type == RTE_BBDEV_OP_TURBO_DEC &&
500d30ea906Sjfb8856606 			conf->priority > dev_info.max_ul_queue_priority) {
501d30ea906Sjfb8856606 			rte_bbdev_log(ERR,
5024418919fSjohnjiang 					"Priority (%u) of queue %u of bbdev %u must be <= %u",
503d30ea906Sjfb8856606 					conf->priority, queue_id, dev_id,
504d30ea906Sjfb8856606 					dev_info.max_ul_queue_priority);
505d30ea906Sjfb8856606 			return -EINVAL;
506d30ea906Sjfb8856606 		}
507d30ea906Sjfb8856606 		if (conf->op_type == RTE_BBDEV_OP_TURBO_ENC &&
508d30ea906Sjfb8856606 			conf->priority > dev_info.max_dl_queue_priority) {
509d30ea906Sjfb8856606 			rte_bbdev_log(ERR,
5104418919fSjohnjiang 					"Priority (%u) of queue %u of bbdev %u must be <= %u",
511d30ea906Sjfb8856606 					conf->priority, queue_id, dev_id,
512d30ea906Sjfb8856606 					dev_info.max_dl_queue_priority);
513d30ea906Sjfb8856606 			return -EINVAL;
514d30ea906Sjfb8856606 		}
515d30ea906Sjfb8856606 	}
516d30ea906Sjfb8856606 
517d30ea906Sjfb8856606 	/* Release existing queue (in case of queue reconfiguration) */
518d30ea906Sjfb8856606 	if (dev->data->queues[queue_id].queue_private != NULL) {
519d30ea906Sjfb8856606 		ret = dev->dev_ops->queue_release(dev, queue_id);
520d30ea906Sjfb8856606 		if (ret < 0) {
521d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u queue %u release failed",
522d30ea906Sjfb8856606 					dev_id, queue_id);
523d30ea906Sjfb8856606 			return ret;
524d30ea906Sjfb8856606 		}
525d30ea906Sjfb8856606 	}
526d30ea906Sjfb8856606 
527d30ea906Sjfb8856606 	/* Get driver to setup the queue */
528d30ea906Sjfb8856606 	ret = dev->dev_ops->queue_setup(dev, queue_id, (conf != NULL) ?
529d30ea906Sjfb8856606 			conf : &dev_info.default_queue_conf);
530d30ea906Sjfb8856606 	if (ret < 0) {
531d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
532d30ea906Sjfb8856606 				"Device %u queue %u setup failed", dev_id,
533d30ea906Sjfb8856606 				queue_id);
534d30ea906Sjfb8856606 		return ret;
535d30ea906Sjfb8856606 	}
536d30ea906Sjfb8856606 
537d30ea906Sjfb8856606 	/* Store configuration */
538d30ea906Sjfb8856606 	stored_conf = &dev->data->queues[queue_id].conf;
539d30ea906Sjfb8856606 	memcpy(stored_conf,
540d30ea906Sjfb8856606 			(conf != NULL) ? conf : &dev_info.default_queue_conf,
541d30ea906Sjfb8856606 			sizeof(*stored_conf));
542d30ea906Sjfb8856606 
543d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(stored_conf->op_type);
544d30ea906Sjfb8856606 	if (op_type_str == NULL)
545d30ea906Sjfb8856606 		return -EINVAL;
546d30ea906Sjfb8856606 
547d30ea906Sjfb8856606 	rte_bbdev_log_debug("Configured dev%uq%u (size=%u, type=%s, prio=%u)",
548d30ea906Sjfb8856606 			dev_id, queue_id, stored_conf->queue_size, op_type_str,
549d30ea906Sjfb8856606 			stored_conf->priority);
550d30ea906Sjfb8856606 
551d30ea906Sjfb8856606 	return 0;
552d30ea906Sjfb8856606 }
553d30ea906Sjfb8856606 
5544418919fSjohnjiang int
rte_bbdev_start(uint16_t dev_id)555d30ea906Sjfb8856606 rte_bbdev_start(uint16_t dev_id)
556d30ea906Sjfb8856606 {
557d30ea906Sjfb8856606 	int i;
558d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
559d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
560d30ea906Sjfb8856606 
561d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
562d30ea906Sjfb8856606 
563d30ea906Sjfb8856606 	if (dev->data->started) {
564d30ea906Sjfb8856606 		rte_bbdev_log_debug("Device %u is already started", dev_id);
565d30ea906Sjfb8856606 		return 0;
566d30ea906Sjfb8856606 	}
567d30ea906Sjfb8856606 
568d30ea906Sjfb8856606 	if (dev->dev_ops->start) {
569d30ea906Sjfb8856606 		int ret = dev->dev_ops->start(dev);
570d30ea906Sjfb8856606 		if (ret < 0) {
571d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u start failed", dev_id);
572d30ea906Sjfb8856606 			return ret;
573d30ea906Sjfb8856606 		}
574d30ea906Sjfb8856606 	}
575d30ea906Sjfb8856606 
576d30ea906Sjfb8856606 	/* Store new state */
577d30ea906Sjfb8856606 	for (i = 0; i < dev->data->num_queues; i++)
578d30ea906Sjfb8856606 		if (!dev->data->queues[i].conf.deferred_start)
579d30ea906Sjfb8856606 			dev->data->queues[i].started = true;
580d30ea906Sjfb8856606 	dev->data->started = true;
581d30ea906Sjfb8856606 
582d30ea906Sjfb8856606 	rte_bbdev_log_debug("Started device %u", dev_id);
583d30ea906Sjfb8856606 	return 0;
584d30ea906Sjfb8856606 }
585d30ea906Sjfb8856606 
5864418919fSjohnjiang int
rte_bbdev_stop(uint16_t dev_id)587d30ea906Sjfb8856606 rte_bbdev_stop(uint16_t dev_id)
588d30ea906Sjfb8856606 {
589d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
590d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
591d30ea906Sjfb8856606 
592d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
593d30ea906Sjfb8856606 
594d30ea906Sjfb8856606 	if (!dev->data->started) {
595d30ea906Sjfb8856606 		rte_bbdev_log_debug("Device %u is already stopped", dev_id);
596d30ea906Sjfb8856606 		return 0;
597d30ea906Sjfb8856606 	}
598d30ea906Sjfb8856606 
599d30ea906Sjfb8856606 	if (dev->dev_ops->stop)
600d30ea906Sjfb8856606 		dev->dev_ops->stop(dev);
601d30ea906Sjfb8856606 	dev->data->started = false;
602d30ea906Sjfb8856606 
603d30ea906Sjfb8856606 	rte_bbdev_log_debug("Stopped device %u", dev_id);
604d30ea906Sjfb8856606 	return 0;
605d30ea906Sjfb8856606 }
606d30ea906Sjfb8856606 
6074418919fSjohnjiang int
rte_bbdev_close(uint16_t dev_id)608d30ea906Sjfb8856606 rte_bbdev_close(uint16_t dev_id)
609d30ea906Sjfb8856606 {
610d30ea906Sjfb8856606 	int ret;
611d30ea906Sjfb8856606 	uint16_t i;
612d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
613d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
614d30ea906Sjfb8856606 
615d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
616d30ea906Sjfb8856606 
617d30ea906Sjfb8856606 	if (dev->data->started) {
618d30ea906Sjfb8856606 		ret = rte_bbdev_stop(dev_id);
619d30ea906Sjfb8856606 		if (ret < 0) {
620d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u stop failed", dev_id);
621d30ea906Sjfb8856606 			return ret;
622d30ea906Sjfb8856606 		}
623d30ea906Sjfb8856606 	}
624d30ea906Sjfb8856606 
625d30ea906Sjfb8856606 	/* Free memory used by queues */
626d30ea906Sjfb8856606 	for (i = 0; i < dev->data->num_queues; i++) {
627d30ea906Sjfb8856606 		ret = dev->dev_ops->queue_release(dev, i);
628d30ea906Sjfb8856606 		if (ret < 0) {
629d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u queue %u release failed",
630d30ea906Sjfb8856606 					dev_id, i);
631d30ea906Sjfb8856606 			return ret;
632d30ea906Sjfb8856606 		}
633d30ea906Sjfb8856606 	}
634d30ea906Sjfb8856606 	rte_free(dev->data->queues);
635d30ea906Sjfb8856606 
636d30ea906Sjfb8856606 	if (dev->dev_ops->close) {
637d30ea906Sjfb8856606 		ret = dev->dev_ops->close(dev);
638d30ea906Sjfb8856606 		if (ret < 0) {
639d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u close failed", dev_id);
640d30ea906Sjfb8856606 			return ret;
641d30ea906Sjfb8856606 		}
642d30ea906Sjfb8856606 	}
643d30ea906Sjfb8856606 
644d30ea906Sjfb8856606 	/* Clear configuration */
645d30ea906Sjfb8856606 	dev->data->queues = NULL;
646d30ea906Sjfb8856606 	dev->data->num_queues = 0;
647d30ea906Sjfb8856606 
648d30ea906Sjfb8856606 	rte_bbdev_log_debug("Closed device %u", dev_id);
649d30ea906Sjfb8856606 	return 0;
650d30ea906Sjfb8856606 }
651d30ea906Sjfb8856606 
6524418919fSjohnjiang int
rte_bbdev_queue_start(uint16_t dev_id,uint16_t queue_id)653d30ea906Sjfb8856606 rte_bbdev_queue_start(uint16_t dev_id, uint16_t queue_id)
654d30ea906Sjfb8856606 {
655d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
656d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
657d30ea906Sjfb8856606 
658d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
659d30ea906Sjfb8856606 
660d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
661d30ea906Sjfb8856606 
662d30ea906Sjfb8856606 	if (dev->data->queues[queue_id].started) {
663d30ea906Sjfb8856606 		rte_bbdev_log_debug("Queue %u of device %u already started",
664d30ea906Sjfb8856606 				queue_id, dev_id);
665d30ea906Sjfb8856606 		return 0;
666d30ea906Sjfb8856606 	}
667d30ea906Sjfb8856606 
668d30ea906Sjfb8856606 	if (dev->dev_ops->queue_start) {
669d30ea906Sjfb8856606 		int ret = dev->dev_ops->queue_start(dev, queue_id);
670d30ea906Sjfb8856606 		if (ret < 0) {
671d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u queue %u start failed",
672d30ea906Sjfb8856606 					dev_id, queue_id);
673d30ea906Sjfb8856606 			return ret;
674d30ea906Sjfb8856606 		}
675d30ea906Sjfb8856606 	}
676d30ea906Sjfb8856606 	dev->data->queues[queue_id].started = true;
677d30ea906Sjfb8856606 
678d30ea906Sjfb8856606 	rte_bbdev_log_debug("Started queue %u of device %u", queue_id, dev_id);
679d30ea906Sjfb8856606 	return 0;
680d30ea906Sjfb8856606 }
681d30ea906Sjfb8856606 
6824418919fSjohnjiang int
rte_bbdev_queue_stop(uint16_t dev_id,uint16_t queue_id)683d30ea906Sjfb8856606 rte_bbdev_queue_stop(uint16_t dev_id, uint16_t queue_id)
684d30ea906Sjfb8856606 {
685d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
686d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
687d30ea906Sjfb8856606 
688d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
689d30ea906Sjfb8856606 
690d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
691d30ea906Sjfb8856606 
692d30ea906Sjfb8856606 	if (!dev->data->queues[queue_id].started) {
693d30ea906Sjfb8856606 		rte_bbdev_log_debug("Queue %u of device %u already stopped",
694d30ea906Sjfb8856606 				queue_id, dev_id);
695d30ea906Sjfb8856606 		return 0;
696d30ea906Sjfb8856606 	}
697d30ea906Sjfb8856606 
698d30ea906Sjfb8856606 	if (dev->dev_ops->queue_stop) {
699d30ea906Sjfb8856606 		int ret = dev->dev_ops->queue_stop(dev, queue_id);
700d30ea906Sjfb8856606 		if (ret < 0) {
701d30ea906Sjfb8856606 			rte_bbdev_log(ERR, "Device %u queue %u stop failed",
702d30ea906Sjfb8856606 					dev_id, queue_id);
703d30ea906Sjfb8856606 			return ret;
704d30ea906Sjfb8856606 		}
705d30ea906Sjfb8856606 	}
706d30ea906Sjfb8856606 	dev->data->queues[queue_id].started = false;
707d30ea906Sjfb8856606 
708d30ea906Sjfb8856606 	rte_bbdev_log_debug("Stopped queue %u of device %u", queue_id, dev_id);
709d30ea906Sjfb8856606 	return 0;
710d30ea906Sjfb8856606 }
711d30ea906Sjfb8856606 
712d30ea906Sjfb8856606 /* Get device statistics */
713d30ea906Sjfb8856606 static void
get_stats_from_queues(struct rte_bbdev * dev,struct rte_bbdev_stats * stats)714d30ea906Sjfb8856606 get_stats_from_queues(struct rte_bbdev *dev, struct rte_bbdev_stats *stats)
715d30ea906Sjfb8856606 {
716d30ea906Sjfb8856606 	unsigned int q_id;
717d30ea906Sjfb8856606 	for (q_id = 0; q_id < dev->data->num_queues; q_id++) {
718d30ea906Sjfb8856606 		struct rte_bbdev_stats *q_stats =
719d30ea906Sjfb8856606 				&dev->data->queues[q_id].queue_stats;
720d30ea906Sjfb8856606 
721d30ea906Sjfb8856606 		stats->enqueued_count += q_stats->enqueued_count;
722d30ea906Sjfb8856606 		stats->dequeued_count += q_stats->dequeued_count;
723d30ea906Sjfb8856606 		stats->enqueue_err_count += q_stats->enqueue_err_count;
724d30ea906Sjfb8856606 		stats->dequeue_err_count += q_stats->dequeue_err_count;
725d30ea906Sjfb8856606 	}
726d30ea906Sjfb8856606 	rte_bbdev_log_debug("Got stats on %u", dev->data->dev_id);
727d30ea906Sjfb8856606 }
728d30ea906Sjfb8856606 
729d30ea906Sjfb8856606 static void
reset_stats_in_queues(struct rte_bbdev * dev)730d30ea906Sjfb8856606 reset_stats_in_queues(struct rte_bbdev *dev)
731d30ea906Sjfb8856606 {
732d30ea906Sjfb8856606 	unsigned int q_id;
733d30ea906Sjfb8856606 	for (q_id = 0; q_id < dev->data->num_queues; q_id++) {
734d30ea906Sjfb8856606 		struct rte_bbdev_stats *q_stats =
735d30ea906Sjfb8856606 				&dev->data->queues[q_id].queue_stats;
736d30ea906Sjfb8856606 
737d30ea906Sjfb8856606 		memset(q_stats, 0, sizeof(*q_stats));
738d30ea906Sjfb8856606 	}
739d30ea906Sjfb8856606 	rte_bbdev_log_debug("Reset stats on %u", dev->data->dev_id);
740d30ea906Sjfb8856606 }
741d30ea906Sjfb8856606 
7424418919fSjohnjiang int
rte_bbdev_stats_get(uint16_t dev_id,struct rte_bbdev_stats * stats)743d30ea906Sjfb8856606 rte_bbdev_stats_get(uint16_t dev_id, struct rte_bbdev_stats *stats)
744d30ea906Sjfb8856606 {
745d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
746d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
747d30ea906Sjfb8856606 
748d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
749d30ea906Sjfb8856606 
750d30ea906Sjfb8856606 	if (stats == NULL) {
751d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL stats structure");
752d30ea906Sjfb8856606 		return -EINVAL;
753d30ea906Sjfb8856606 	}
754d30ea906Sjfb8856606 
755d30ea906Sjfb8856606 	memset(stats, 0, sizeof(*stats));
756d30ea906Sjfb8856606 	if (dev->dev_ops->stats_get != NULL)
757d30ea906Sjfb8856606 		dev->dev_ops->stats_get(dev, stats);
758d30ea906Sjfb8856606 	else
759d30ea906Sjfb8856606 		get_stats_from_queues(dev, stats);
760d30ea906Sjfb8856606 
761d30ea906Sjfb8856606 	rte_bbdev_log_debug("Retrieved stats of device %u", dev_id);
762d30ea906Sjfb8856606 	return 0;
763d30ea906Sjfb8856606 }
764d30ea906Sjfb8856606 
7654418919fSjohnjiang int
rte_bbdev_stats_reset(uint16_t dev_id)766d30ea906Sjfb8856606 rte_bbdev_stats_reset(uint16_t dev_id)
767d30ea906Sjfb8856606 {
768d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
769d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
770d30ea906Sjfb8856606 
771d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
772d30ea906Sjfb8856606 
773d30ea906Sjfb8856606 	if (dev->dev_ops->stats_reset != NULL)
774d30ea906Sjfb8856606 		dev->dev_ops->stats_reset(dev);
775d30ea906Sjfb8856606 	else
776d30ea906Sjfb8856606 		reset_stats_in_queues(dev);
777d30ea906Sjfb8856606 
778d30ea906Sjfb8856606 	rte_bbdev_log_debug("Reset stats of device %u", dev_id);
779d30ea906Sjfb8856606 	return 0;
780d30ea906Sjfb8856606 }
781d30ea906Sjfb8856606 
7824418919fSjohnjiang int
rte_bbdev_info_get(uint16_t dev_id,struct rte_bbdev_info * dev_info)783d30ea906Sjfb8856606 rte_bbdev_info_get(uint16_t dev_id, struct rte_bbdev_info *dev_info)
784d30ea906Sjfb8856606 {
785d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
786d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
787d30ea906Sjfb8856606 
788d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->info_get, dev_id);
789d30ea906Sjfb8856606 
790d30ea906Sjfb8856606 	if (dev_info == NULL) {
791d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL dev info structure");
792d30ea906Sjfb8856606 		return -EINVAL;
793d30ea906Sjfb8856606 	}
794d30ea906Sjfb8856606 
795d30ea906Sjfb8856606 	/* Copy data maintained by device interface layer */
796d30ea906Sjfb8856606 	memset(dev_info, 0, sizeof(*dev_info));
797d30ea906Sjfb8856606 	dev_info->dev_name = dev->data->name;
798d30ea906Sjfb8856606 	dev_info->num_queues = dev->data->num_queues;
7994418919fSjohnjiang 	dev_info->device = dev->device;
800d30ea906Sjfb8856606 	dev_info->socket_id = dev->data->socket_id;
801d30ea906Sjfb8856606 	dev_info->started = dev->data->started;
802d30ea906Sjfb8856606 
803d30ea906Sjfb8856606 	/* Copy data maintained by device driver layer */
804d30ea906Sjfb8856606 	dev->dev_ops->info_get(dev, &dev_info->drv);
805d30ea906Sjfb8856606 
806d30ea906Sjfb8856606 	rte_bbdev_log_debug("Retrieved info of device %u", dev_id);
807d30ea906Sjfb8856606 	return 0;
808d30ea906Sjfb8856606 }
809d30ea906Sjfb8856606 
8104418919fSjohnjiang int
rte_bbdev_queue_info_get(uint16_t dev_id,uint16_t queue_id,struct rte_bbdev_queue_info * queue_info)811d30ea906Sjfb8856606 rte_bbdev_queue_info_get(uint16_t dev_id, uint16_t queue_id,
812d30ea906Sjfb8856606 		struct rte_bbdev_queue_info *queue_info)
813d30ea906Sjfb8856606 {
814d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
815d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
816d30ea906Sjfb8856606 
817d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
818d30ea906Sjfb8856606 
819d30ea906Sjfb8856606 	if (queue_info == NULL) {
820d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL queue info structure");
821d30ea906Sjfb8856606 		return -EINVAL;
822d30ea906Sjfb8856606 	}
823d30ea906Sjfb8856606 
824d30ea906Sjfb8856606 	/* Copy data to output */
825d30ea906Sjfb8856606 	memset(queue_info, 0, sizeof(*queue_info));
826d30ea906Sjfb8856606 	queue_info->conf = dev->data->queues[queue_id].conf;
827d30ea906Sjfb8856606 	queue_info->started = dev->data->queues[queue_id].started;
828d30ea906Sjfb8856606 
829d30ea906Sjfb8856606 	rte_bbdev_log_debug("Retrieved info of queue %u of device %u",
830d30ea906Sjfb8856606 			queue_id, dev_id);
831d30ea906Sjfb8856606 	return 0;
832d30ea906Sjfb8856606 }
833d30ea906Sjfb8856606 
834d30ea906Sjfb8856606 /* Calculate size needed to store bbdev_op, depending on type */
835d30ea906Sjfb8856606 static unsigned int
get_bbdev_op_size(enum rte_bbdev_op_type type)836d30ea906Sjfb8856606 get_bbdev_op_size(enum rte_bbdev_op_type type)
837d30ea906Sjfb8856606 {
838d30ea906Sjfb8856606 	unsigned int result = 0;
839d30ea906Sjfb8856606 	switch (type) {
840d30ea906Sjfb8856606 	case RTE_BBDEV_OP_NONE:
841d30ea906Sjfb8856606 		result = RTE_MAX(sizeof(struct rte_bbdev_dec_op),
842d30ea906Sjfb8856606 				sizeof(struct rte_bbdev_enc_op));
843d30ea906Sjfb8856606 		break;
844d30ea906Sjfb8856606 	case RTE_BBDEV_OP_TURBO_DEC:
845d30ea906Sjfb8856606 		result = sizeof(struct rte_bbdev_dec_op);
846d30ea906Sjfb8856606 		break;
847d30ea906Sjfb8856606 	case RTE_BBDEV_OP_TURBO_ENC:
848d30ea906Sjfb8856606 		result = sizeof(struct rte_bbdev_enc_op);
849d30ea906Sjfb8856606 		break;
8504418919fSjohnjiang 	case RTE_BBDEV_OP_LDPC_DEC:
8514418919fSjohnjiang 		result = sizeof(struct rte_bbdev_dec_op);
8524418919fSjohnjiang 		break;
8534418919fSjohnjiang 	case RTE_BBDEV_OP_LDPC_ENC:
8544418919fSjohnjiang 		result = sizeof(struct rte_bbdev_enc_op);
8554418919fSjohnjiang 		break;
856d30ea906Sjfb8856606 	default:
857d30ea906Sjfb8856606 		break;
858d30ea906Sjfb8856606 	}
859d30ea906Sjfb8856606 
860d30ea906Sjfb8856606 	return result;
861d30ea906Sjfb8856606 }
862d30ea906Sjfb8856606 
863d30ea906Sjfb8856606 /* Initialise a bbdev_op structure */
864d30ea906Sjfb8856606 static void
bbdev_op_init(struct rte_mempool * mempool,void * arg,void * element,__rte_unused unsigned int n)865d30ea906Sjfb8856606 bbdev_op_init(struct rte_mempool *mempool, void *arg, void *element,
866d30ea906Sjfb8856606 		__rte_unused unsigned int n)
867d30ea906Sjfb8856606 {
868d30ea906Sjfb8856606 	enum rte_bbdev_op_type type = *(enum rte_bbdev_op_type *)arg;
869d30ea906Sjfb8856606 
8704418919fSjohnjiang 	if (type == RTE_BBDEV_OP_TURBO_DEC || type == RTE_BBDEV_OP_LDPC_DEC) {
871d30ea906Sjfb8856606 		struct rte_bbdev_dec_op *op = element;
872d30ea906Sjfb8856606 		memset(op, 0, mempool->elt_size);
873d30ea906Sjfb8856606 		op->mempool = mempool;
8744418919fSjohnjiang 	} else if (type == RTE_BBDEV_OP_TURBO_ENC ||
8754418919fSjohnjiang 			type == RTE_BBDEV_OP_LDPC_ENC) {
876d30ea906Sjfb8856606 		struct rte_bbdev_enc_op *op = element;
877d30ea906Sjfb8856606 		memset(op, 0, mempool->elt_size);
878d30ea906Sjfb8856606 		op->mempool = mempool;
879d30ea906Sjfb8856606 	}
880d30ea906Sjfb8856606 }
881d30ea906Sjfb8856606 
8824418919fSjohnjiang 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)883d30ea906Sjfb8856606 rte_bbdev_op_pool_create(const char *name, enum rte_bbdev_op_type type,
884d30ea906Sjfb8856606 		unsigned int num_elements, unsigned int cache_size,
885d30ea906Sjfb8856606 		int socket_id)
886d30ea906Sjfb8856606 {
887d30ea906Sjfb8856606 	struct rte_bbdev_op_pool_private *priv;
888d30ea906Sjfb8856606 	struct rte_mempool *mp;
889d30ea906Sjfb8856606 	const char *op_type_str;
890d30ea906Sjfb8856606 
891d30ea906Sjfb8856606 	if (name == NULL) {
892d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL name for op pool");
893d30ea906Sjfb8856606 		return NULL;
894d30ea906Sjfb8856606 	}
895d30ea906Sjfb8856606 
896d30ea906Sjfb8856606 	if (type >= RTE_BBDEV_OP_TYPE_COUNT) {
897d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
898d30ea906Sjfb8856606 				"Invalid op type (%u), should be less than %u",
899d30ea906Sjfb8856606 				type, RTE_BBDEV_OP_TYPE_COUNT);
900d30ea906Sjfb8856606 		return NULL;
901d30ea906Sjfb8856606 	}
902d30ea906Sjfb8856606 
903d30ea906Sjfb8856606 	mp = rte_mempool_create(name, num_elements, get_bbdev_op_size(type),
904d30ea906Sjfb8856606 			cache_size, sizeof(struct rte_bbdev_op_pool_private),
905d30ea906Sjfb8856606 			NULL, NULL, bbdev_op_init, &type, socket_id, 0);
906d30ea906Sjfb8856606 	if (mp == NULL) {
907d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
908d30ea906Sjfb8856606 				"Failed to create op pool %s (num ops=%u, op size=%u) with error: %s",
909d30ea906Sjfb8856606 				name, num_elements, get_bbdev_op_size(type),
910d30ea906Sjfb8856606 				rte_strerror(rte_errno));
911d30ea906Sjfb8856606 		return NULL;
912d30ea906Sjfb8856606 	}
913d30ea906Sjfb8856606 
914d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(type);
915d30ea906Sjfb8856606 	if (op_type_str == NULL)
916d30ea906Sjfb8856606 		return NULL;
917d30ea906Sjfb8856606 
918d30ea906Sjfb8856606 	rte_bbdev_log_debug(
919d30ea906Sjfb8856606 			"Op pool %s created for %u ops (type=%s, cache=%u, socket=%u, size=%u)",
920d30ea906Sjfb8856606 			name, num_elements, op_type_str, cache_size, socket_id,
921d30ea906Sjfb8856606 			get_bbdev_op_size(type));
922d30ea906Sjfb8856606 
923d30ea906Sjfb8856606 	priv = (struct rte_bbdev_op_pool_private *)rte_mempool_get_priv(mp);
924d30ea906Sjfb8856606 	priv->type = type;
925d30ea906Sjfb8856606 
926d30ea906Sjfb8856606 	return mp;
927d30ea906Sjfb8856606 }
928d30ea906Sjfb8856606 
9294418919fSjohnjiang int
rte_bbdev_callback_register(uint16_t dev_id,enum rte_bbdev_event_type event,rte_bbdev_cb_fn cb_fn,void * cb_arg)930d30ea906Sjfb8856606 rte_bbdev_callback_register(uint16_t dev_id, enum rte_bbdev_event_type event,
931d30ea906Sjfb8856606 		rte_bbdev_cb_fn cb_fn, void *cb_arg)
932d30ea906Sjfb8856606 {
933d30ea906Sjfb8856606 	struct rte_bbdev_callback *user_cb;
934d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
935d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
936d30ea906Sjfb8856606 
937d30ea906Sjfb8856606 	if (event >= RTE_BBDEV_EVENT_MAX) {
938d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
939d30ea906Sjfb8856606 				"Invalid event type (%u), should be less than %u",
940d30ea906Sjfb8856606 				event, RTE_BBDEV_EVENT_MAX);
941d30ea906Sjfb8856606 		return -EINVAL;
942d30ea906Sjfb8856606 	}
943d30ea906Sjfb8856606 
944d30ea906Sjfb8856606 	if (cb_fn == NULL) {
945d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL callback function");
946d30ea906Sjfb8856606 		return -EINVAL;
947d30ea906Sjfb8856606 	}
948d30ea906Sjfb8856606 
949d30ea906Sjfb8856606 	rte_spinlock_lock(&rte_bbdev_cb_lock);
950d30ea906Sjfb8856606 
951d30ea906Sjfb8856606 	TAILQ_FOREACH(user_cb, &(dev->list_cbs), next) {
952d30ea906Sjfb8856606 		if (user_cb->cb_fn == cb_fn &&
953d30ea906Sjfb8856606 				user_cb->cb_arg == cb_arg &&
954d30ea906Sjfb8856606 				user_cb->event == event)
955d30ea906Sjfb8856606 			break;
956d30ea906Sjfb8856606 	}
957d30ea906Sjfb8856606 
958d30ea906Sjfb8856606 	/* create a new callback. */
959d30ea906Sjfb8856606 	if (user_cb == NULL) {
960d30ea906Sjfb8856606 		user_cb = rte_zmalloc("INTR_USER_CALLBACK",
961d30ea906Sjfb8856606 				sizeof(struct rte_bbdev_callback), 0);
962d30ea906Sjfb8856606 		if (user_cb != NULL) {
963d30ea906Sjfb8856606 			user_cb->cb_fn = cb_fn;
964d30ea906Sjfb8856606 			user_cb->cb_arg = cb_arg;
965d30ea906Sjfb8856606 			user_cb->event = event;
966d30ea906Sjfb8856606 			TAILQ_INSERT_TAIL(&(dev->list_cbs), user_cb, next);
967d30ea906Sjfb8856606 		}
968d30ea906Sjfb8856606 	}
969d30ea906Sjfb8856606 
970d30ea906Sjfb8856606 	rte_spinlock_unlock(&rte_bbdev_cb_lock);
971d30ea906Sjfb8856606 	return (user_cb == NULL) ? -ENOMEM : 0;
972d30ea906Sjfb8856606 }
973d30ea906Sjfb8856606 
9744418919fSjohnjiang int
rte_bbdev_callback_unregister(uint16_t dev_id,enum rte_bbdev_event_type event,rte_bbdev_cb_fn cb_fn,void * cb_arg)975d30ea906Sjfb8856606 rte_bbdev_callback_unregister(uint16_t dev_id, enum rte_bbdev_event_type event,
976d30ea906Sjfb8856606 		rte_bbdev_cb_fn cb_fn, void *cb_arg)
977d30ea906Sjfb8856606 {
978d30ea906Sjfb8856606 	int ret = 0;
979d30ea906Sjfb8856606 	struct rte_bbdev_callback *cb, *next;
980d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
981d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
982d30ea906Sjfb8856606 
983d30ea906Sjfb8856606 	if (event >= RTE_BBDEV_EVENT_MAX) {
984d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
985d30ea906Sjfb8856606 				"Invalid event type (%u), should be less than %u",
986d30ea906Sjfb8856606 				event, RTE_BBDEV_EVENT_MAX);
987d30ea906Sjfb8856606 		return -EINVAL;
988d30ea906Sjfb8856606 	}
989d30ea906Sjfb8856606 
990d30ea906Sjfb8856606 	if (cb_fn == NULL) {
991d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
992d30ea906Sjfb8856606 				"NULL callback function cannot be unregistered");
993d30ea906Sjfb8856606 		return -EINVAL;
994d30ea906Sjfb8856606 	}
995d30ea906Sjfb8856606 
996d30ea906Sjfb8856606 	dev = &rte_bbdev_devices[dev_id];
997d30ea906Sjfb8856606 	rte_spinlock_lock(&rte_bbdev_cb_lock);
998d30ea906Sjfb8856606 
999d30ea906Sjfb8856606 	for (cb = TAILQ_FIRST(&dev->list_cbs); cb != NULL; cb = next) {
1000d30ea906Sjfb8856606 
1001d30ea906Sjfb8856606 		next = TAILQ_NEXT(cb, next);
1002d30ea906Sjfb8856606 
1003d30ea906Sjfb8856606 		if (cb->cb_fn != cb_fn || cb->event != event ||
1004d30ea906Sjfb8856606 				(cb_arg != (void *)-1 && cb->cb_arg != cb_arg))
1005d30ea906Sjfb8856606 			continue;
1006d30ea906Sjfb8856606 
1007d30ea906Sjfb8856606 		/* If this callback is not executing right now, remove it. */
1008d30ea906Sjfb8856606 		if (cb->active == 0) {
1009d30ea906Sjfb8856606 			TAILQ_REMOVE(&(dev->list_cbs), cb, next);
1010d30ea906Sjfb8856606 			rte_free(cb);
1011d30ea906Sjfb8856606 		} else
1012d30ea906Sjfb8856606 			ret = -EAGAIN;
1013d30ea906Sjfb8856606 	}
1014d30ea906Sjfb8856606 
1015d30ea906Sjfb8856606 	rte_spinlock_unlock(&rte_bbdev_cb_lock);
1016d30ea906Sjfb8856606 	return ret;
1017d30ea906Sjfb8856606 }
1018d30ea906Sjfb8856606 
10194418919fSjohnjiang void
rte_bbdev_pmd_callback_process(struct rte_bbdev * dev,enum rte_bbdev_event_type event,void * ret_param)1020d30ea906Sjfb8856606 rte_bbdev_pmd_callback_process(struct rte_bbdev *dev,
1021d30ea906Sjfb8856606 	enum rte_bbdev_event_type event, void *ret_param)
1022d30ea906Sjfb8856606 {
1023d30ea906Sjfb8856606 	struct rte_bbdev_callback *cb_lst;
1024d30ea906Sjfb8856606 	struct rte_bbdev_callback dev_cb;
1025d30ea906Sjfb8856606 
1026d30ea906Sjfb8856606 	if (dev == NULL) {
1027d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL device");
1028d30ea906Sjfb8856606 		return;
1029d30ea906Sjfb8856606 	}
1030d30ea906Sjfb8856606 
1031d30ea906Sjfb8856606 	if (dev->data == NULL) {
1032d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "NULL data structure");
1033d30ea906Sjfb8856606 		return;
1034d30ea906Sjfb8856606 	}
1035d30ea906Sjfb8856606 
1036d30ea906Sjfb8856606 	if (event >= RTE_BBDEV_EVENT_MAX) {
1037d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
1038d30ea906Sjfb8856606 				"Invalid event type (%u), should be less than %u",
1039d30ea906Sjfb8856606 				event, RTE_BBDEV_EVENT_MAX);
1040d30ea906Sjfb8856606 		return;
1041d30ea906Sjfb8856606 	}
1042d30ea906Sjfb8856606 
1043d30ea906Sjfb8856606 	rte_spinlock_lock(&rte_bbdev_cb_lock);
1044d30ea906Sjfb8856606 	TAILQ_FOREACH(cb_lst, &(dev->list_cbs), next) {
1045d30ea906Sjfb8856606 		if (cb_lst->cb_fn == NULL || cb_lst->event != event)
1046d30ea906Sjfb8856606 			continue;
1047d30ea906Sjfb8856606 		dev_cb = *cb_lst;
1048d30ea906Sjfb8856606 		cb_lst->active = 1;
1049d30ea906Sjfb8856606 		if (ret_param != NULL)
1050d30ea906Sjfb8856606 			dev_cb.ret_param = ret_param;
1051d30ea906Sjfb8856606 
1052d30ea906Sjfb8856606 		rte_spinlock_unlock(&rte_bbdev_cb_lock);
1053d30ea906Sjfb8856606 		dev_cb.cb_fn(dev->data->dev_id, dev_cb.event,
1054d30ea906Sjfb8856606 				dev_cb.cb_arg, dev_cb.ret_param);
1055d30ea906Sjfb8856606 		rte_spinlock_lock(&rte_bbdev_cb_lock);
1056d30ea906Sjfb8856606 		cb_lst->active = 0;
1057d30ea906Sjfb8856606 	}
1058d30ea906Sjfb8856606 	rte_spinlock_unlock(&rte_bbdev_cb_lock);
1059d30ea906Sjfb8856606 }
1060d30ea906Sjfb8856606 
10614418919fSjohnjiang int
rte_bbdev_queue_intr_enable(uint16_t dev_id,uint16_t queue_id)1062d30ea906Sjfb8856606 rte_bbdev_queue_intr_enable(uint16_t dev_id, uint16_t queue_id)
1063d30ea906Sjfb8856606 {
1064d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
1065d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
1066d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
1067d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
1068d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_intr_enable, dev_id);
1069d30ea906Sjfb8856606 	return dev->dev_ops->queue_intr_enable(dev, queue_id);
1070d30ea906Sjfb8856606 }
1071d30ea906Sjfb8856606 
10724418919fSjohnjiang int
rte_bbdev_queue_intr_disable(uint16_t dev_id,uint16_t queue_id)1073d30ea906Sjfb8856606 rte_bbdev_queue_intr_disable(uint16_t dev_id, uint16_t queue_id)
1074d30ea906Sjfb8856606 {
1075d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
1076d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
1077d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
1078d30ea906Sjfb8856606 	VALID_DEV_OPS_OR_RET_ERR(dev, dev_id);
1079d30ea906Sjfb8856606 	VALID_FUNC_OR_RET_ERR(dev->dev_ops->queue_intr_disable, dev_id);
1080d30ea906Sjfb8856606 	return dev->dev_ops->queue_intr_disable(dev, queue_id);
1081d30ea906Sjfb8856606 }
1082d30ea906Sjfb8856606 
10834418919fSjohnjiang int
rte_bbdev_queue_intr_ctl(uint16_t dev_id,uint16_t queue_id,int epfd,int op,void * data)1084d30ea906Sjfb8856606 rte_bbdev_queue_intr_ctl(uint16_t dev_id, uint16_t queue_id, int epfd, int op,
1085d30ea906Sjfb8856606 		void *data)
1086d30ea906Sjfb8856606 {
1087d30ea906Sjfb8856606 	uint32_t vec;
1088d30ea906Sjfb8856606 	struct rte_bbdev *dev = get_dev(dev_id);
1089d30ea906Sjfb8856606 	struct rte_intr_handle *intr_handle;
1090d30ea906Sjfb8856606 	int ret;
1091d30ea906Sjfb8856606 
1092d30ea906Sjfb8856606 	VALID_DEV_OR_RET_ERR(dev, dev_id);
1093d30ea906Sjfb8856606 	VALID_QUEUE_OR_RET_ERR(queue_id, dev);
1094d30ea906Sjfb8856606 
1095d30ea906Sjfb8856606 	intr_handle = dev->intr_handle;
1096d30ea906Sjfb8856606 	if (!intr_handle || !intr_handle->intr_vec) {
1097d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Device %u intr handle unset\n", dev_id);
1098d30ea906Sjfb8856606 		return -ENOTSUP;
1099d30ea906Sjfb8856606 	}
1100d30ea906Sjfb8856606 
1101d30ea906Sjfb8856606 	if (queue_id >= RTE_MAX_RXTX_INTR_VEC_ID) {
1102d30ea906Sjfb8856606 		rte_bbdev_log(ERR, "Device %u queue_id %u is too big\n",
1103d30ea906Sjfb8856606 				dev_id, queue_id);
1104d30ea906Sjfb8856606 		return -ENOTSUP;
1105d30ea906Sjfb8856606 	}
1106d30ea906Sjfb8856606 
1107d30ea906Sjfb8856606 	vec = intr_handle->intr_vec[queue_id];
1108d30ea906Sjfb8856606 	ret = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
1109d30ea906Sjfb8856606 	if (ret && (ret != -EEXIST)) {
1110d30ea906Sjfb8856606 		rte_bbdev_log(ERR,
1111d30ea906Sjfb8856606 				"dev %u q %u int ctl error op %d epfd %d vec %u\n",
1112d30ea906Sjfb8856606 				dev_id, queue_id, op, epfd, vec);
1113d30ea906Sjfb8856606 		return ret;
1114d30ea906Sjfb8856606 	}
1115d30ea906Sjfb8856606 
1116d30ea906Sjfb8856606 	return 0;
1117d30ea906Sjfb8856606 }
1118d30ea906Sjfb8856606 
1119d30ea906Sjfb8856606 
11204418919fSjohnjiang const char *
rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type)1121d30ea906Sjfb8856606 rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type)
1122d30ea906Sjfb8856606 {
1123d30ea906Sjfb8856606 	static const char * const op_types[] = {
1124d30ea906Sjfb8856606 		"RTE_BBDEV_OP_NONE",
1125d30ea906Sjfb8856606 		"RTE_BBDEV_OP_TURBO_DEC",
1126d30ea906Sjfb8856606 		"RTE_BBDEV_OP_TURBO_ENC",
11274418919fSjohnjiang 		"RTE_BBDEV_OP_LDPC_DEC",
11284418919fSjohnjiang 		"RTE_BBDEV_OP_LDPC_ENC",
1129d30ea906Sjfb8856606 	};
1130d30ea906Sjfb8856606 
1131d30ea906Sjfb8856606 	if (op_type < RTE_BBDEV_OP_TYPE_COUNT)
1132d30ea906Sjfb8856606 		return op_types[op_type];
1133d30ea906Sjfb8856606 
1134d30ea906Sjfb8856606 	rte_bbdev_log(ERR, "Invalid operation type");
1135d30ea906Sjfb8856606 	return NULL;
1136d30ea906Sjfb8856606 }
1137