1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
9 #include <rte_string_fns.h>
10 #include <rte_compat.h>
11 #include <rte_common.h>
12 #include <rte_errno.h>
14 #include <rte_debug.h>
16 #include <rte_malloc.h>
17 #include <rte_mempool.h>
18 #include <rte_memzone.h>
19 #include <rte_lcore.h>
21 #include <rte_spinlock.h>
22 #include <rte_tailq.h>
23 #include <rte_interrupts.h>
25 #include "rte_bbdev_op.h"
26 #include "rte_bbdev.h"
27 #include "rte_bbdev_pmd.h"
29 #define DEV_NAME "BBDEV"
32 /* BBDev library logging ID */
33 static int bbdev_logtype
;
35 /* Helper macro for logging */
36 #define rte_bbdev_log(level, fmt, ...) \
37 rte_log(RTE_LOG_ ## level, bbdev_logtype, fmt "\n", ##__VA_ARGS__)
39 #define rte_bbdev_log_debug(fmt, ...) \
40 rte_bbdev_log(DEBUG, RTE_STR(__LINE__) ":%s() " fmt, __func__, \
43 /* Helper macro to check dev_id is valid */
44 #define VALID_DEV_OR_RET_ERR(dev, dev_id) do { \
46 rte_bbdev_log(ERR, "device %u is invalid", dev_id); \
51 /* Helper macro to check dev_ops is valid */
52 #define VALID_DEV_OPS_OR_RET_ERR(dev, dev_id) do { \
53 if (dev->dev_ops == NULL) { \
54 rte_bbdev_log(ERR, "NULL dev_ops structure in device %u", \
60 /* Helper macro to check that driver implements required function pointer */
61 #define VALID_FUNC_OR_RET_ERR(func, dev_id) do { \
63 rte_bbdev_log(ERR, "device %u does not support %s", \
69 /* Helper macro to check that queue is valid */
70 #define VALID_QUEUE_OR_RET_ERR(queue_id, dev) do { \
71 if (queue_id >= dev->data->num_queues) { \
72 rte_bbdev_log(ERR, "Invalid queue_id %u for device %u", \
73 queue_id, dev->data->dev_id); \
78 /* List of callback functions registered by an application */
79 struct rte_bbdev_callback
{
80 TAILQ_ENTRY(rte_bbdev_callback
) next
; /* Callbacks list */
81 rte_bbdev_cb_fn cb_fn
; /* Callback address */
82 void *cb_arg
; /* Parameter for callback */
83 void *ret_param
; /* Return parameter */
84 enum rte_bbdev_event_type event
; /* Interrupt event type */
85 uint32_t active
; /* Callback is executing */
88 /* spinlock for bbdev device callbacks */
89 static rte_spinlock_t rte_bbdev_cb_lock
= RTE_SPINLOCK_INITIALIZER
;
92 * Global array of all devices. This is not static because it's used by the
93 * inline enqueue and dequeue functions
95 struct rte_bbdev rte_bbdev_devices
[RTE_BBDEV_MAX_DEVS
];
97 /* Global array with rte_bbdev_data structures */
98 static struct rte_bbdev_data
*rte_bbdev_data
;
100 /* Memzone name for global bbdev data pool */
101 static const char *MZ_RTE_BBDEV_DATA
= "rte_bbdev_data";
103 /* Number of currently valid devices */
104 static uint16_t num_devs
;
106 /* Return pointer to device structure, with validity check */
107 static struct rte_bbdev
*
108 get_dev(uint16_t dev_id
)
110 if (rte_bbdev_is_valid(dev_id
))
111 return &rte_bbdev_devices
[dev_id
];
115 /* Allocate global data array */
117 rte_bbdev_data_alloc(void)
119 const unsigned int flags
= 0;
120 const struct rte_memzone
*mz
;
122 if (rte_eal_process_type() == RTE_PROC_PRIMARY
) {
123 mz
= rte_memzone_reserve(MZ_RTE_BBDEV_DATA
,
124 RTE_BBDEV_MAX_DEVS
* sizeof(*rte_bbdev_data
),
125 rte_socket_id(), flags
);
127 mz
= rte_memzone_lookup(MZ_RTE_BBDEV_DATA
);
130 "Cannot allocate memzone for bbdev port data");
134 rte_bbdev_data
= mz
->addr
;
135 if (rte_eal_process_type() == RTE_PROC_PRIMARY
)
136 memset(rte_bbdev_data
, 0,
137 RTE_BBDEV_MAX_DEVS
* sizeof(*rte_bbdev_data
));
142 * Find data alocated for the device or if not found return first unused bbdev
143 * data. If all structures are in use and none is used by the device return
146 static struct rte_bbdev_data
*
147 find_bbdev_data(const char *name
)
151 for (data_id
= 0; data_id
< RTE_BBDEV_MAX_DEVS
; ++data_id
) {
152 if (strlen(rte_bbdev_data
[data_id
].name
) == 0) {
153 memset(&rte_bbdev_data
[data_id
], 0,
154 sizeof(struct rte_bbdev_data
));
155 return &rte_bbdev_data
[data_id
];
156 } else if (strncmp(rte_bbdev_data
[data_id
].name
, name
,
157 RTE_BBDEV_NAME_MAX_LEN
) == 0)
158 return &rte_bbdev_data
[data_id
];
164 /* Find lowest device id with no attached device */
166 find_free_dev_id(void)
169 for (i
= 0; i
< RTE_BBDEV_MAX_DEVS
; i
++) {
170 if (rte_bbdev_devices
[i
].state
== RTE_BBDEV_UNUSED
)
173 return RTE_BBDEV_MAX_DEVS
;
176 struct rte_bbdev
* __rte_experimental
177 rte_bbdev_allocate(const char *name
)
180 struct rte_bbdev
*bbdev
;
184 rte_bbdev_log(ERR
, "Invalid null device name");
188 if (rte_bbdev_get_named_dev(name
) != NULL
) {
189 rte_bbdev_log(ERR
, "Device \"%s\" is already allocated", name
);
193 dev_id
= find_free_dev_id();
194 if (dev_id
== RTE_BBDEV_MAX_DEVS
) {
195 rte_bbdev_log(ERR
, "Reached maximum number of devices");
199 bbdev
= &rte_bbdev_devices
[dev_id
];
201 if (rte_bbdev_data
== NULL
) {
202 ret
= rte_bbdev_data_alloc();
207 bbdev
->data
= find_bbdev_data(name
);
208 if (bbdev
->data
== NULL
) {
210 "Max BBDevs already allocated in multi-process environment!");
214 rte_atomic16_inc(&bbdev
->data
->process_cnt
);
215 bbdev
->data
->dev_id
= dev_id
;
216 bbdev
->state
= RTE_BBDEV_INITIALIZED
;
218 ret
= strlcpy(bbdev
->data
->name
, name
, RTE_BBDEV_NAME_MAX_LEN
);
219 if ((ret
< 0) || (ret
>= RTE_BBDEV_NAME_MAX_LEN
)) {
220 rte_bbdev_log(ERR
, "Copying device name \"%s\" failed", name
);
224 /* init user callbacks */
225 TAILQ_INIT(&(bbdev
->list_cbs
));
229 rte_bbdev_log_debug("Initialised device %s (id = %u). Num devices = %u",
230 name
, dev_id
, num_devs
);
235 int __rte_experimental
236 rte_bbdev_release(struct rte_bbdev
*bbdev
)
239 struct rte_bbdev_callback
*cb
, *next
;
242 rte_bbdev_log(ERR
, "NULL bbdev");
245 dev_id
= bbdev
->data
->dev_id
;
247 /* free all callbacks from the device's list */
248 for (cb
= TAILQ_FIRST(&bbdev
->list_cbs
); cb
!= NULL
; cb
= next
) {
250 next
= TAILQ_NEXT(cb
, next
);
251 TAILQ_REMOVE(&(bbdev
->list_cbs
), cb
, next
);
255 /* clear shared BBDev Data if no process is using the device anymore */
256 if (rte_atomic16_dec_and_test(&bbdev
->data
->process_cnt
))
257 memset(bbdev
->data
, 0, sizeof(*bbdev
->data
));
259 memset(bbdev
, 0, sizeof(*bbdev
));
261 bbdev
->state
= RTE_BBDEV_UNUSED
;
264 "Un-initialised device id = %u. Num devices = %u",
269 struct rte_bbdev
* __rte_experimental
270 rte_bbdev_get_named_dev(const char *name
)
275 rte_bbdev_log(ERR
, "NULL driver name");
279 for (i
= 0; i
< RTE_BBDEV_MAX_DEVS
; i
++) {
280 struct rte_bbdev
*dev
= get_dev(i
);
281 if (dev
&& (strncmp(dev
->data
->name
,
282 name
, RTE_BBDEV_NAME_MAX_LEN
) == 0))
289 uint16_t __rte_experimental
290 rte_bbdev_count(void)
295 bool __rte_experimental
296 rte_bbdev_is_valid(uint16_t dev_id
)
298 if ((dev_id
< RTE_BBDEV_MAX_DEVS
) &&
299 rte_bbdev_devices
[dev_id
].state
== RTE_BBDEV_INITIALIZED
)
304 uint16_t __rte_experimental
305 rte_bbdev_find_next(uint16_t dev_id
)
308 for (; dev_id
< RTE_BBDEV_MAX_DEVS
; dev_id
++)
309 if (rte_bbdev_is_valid(dev_id
))
314 int __rte_experimental
315 rte_bbdev_setup_queues(uint16_t dev_id
, uint16_t num_queues
, int socket_id
)
319 struct rte_bbdev_driver_info dev_info
;
320 struct rte_bbdev
*dev
= get_dev(dev_id
);
321 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
323 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
325 if (dev
->data
->started
) {
327 "Device %u cannot be configured when started",
332 /* Get device driver information to get max number of queues */
333 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->info_get
, dev_id
);
334 memset(&dev_info
, 0, sizeof(dev_info
));
335 dev
->dev_ops
->info_get(dev
, &dev_info
);
337 if ((num_queues
== 0) || (num_queues
> dev_info
.max_num_queues
)) {
339 "Device %u supports 0 < N <= %u queues, not %u",
340 dev_id
, dev_info
.max_num_queues
, num_queues
);
344 /* If re-configuration, get driver to free existing internal memory */
345 if (dev
->data
->queues
!= NULL
) {
346 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->queue_release
, dev_id
);
347 for (i
= 0; i
< dev
->data
->num_queues
; i
++) {
348 int ret
= dev
->dev_ops
->queue_release(dev
, i
);
351 "Device %u queue %u release failed",
356 /* Call optional device close */
357 if (dev
->dev_ops
->close
) {
358 ret
= dev
->dev_ops
->close(dev
);
361 "Device %u couldn't be closed",
366 rte_free(dev
->data
->queues
);
369 /* Allocate queue pointers */
370 dev
->data
->queues
= rte_calloc_socket(DEV_NAME
, num_queues
,
371 sizeof(dev
->data
->queues
[0]), RTE_CACHE_LINE_SIZE
,
372 dev
->data
->socket_id
);
373 if (dev
->data
->queues
== NULL
) {
375 "calloc of %u queues for device %u on socket %i failed",
376 num_queues
, dev_id
, dev
->data
->socket_id
);
380 dev
->data
->num_queues
= num_queues
;
382 /* Call optional device configuration */
383 if (dev
->dev_ops
->setup_queues
) {
384 ret
= dev
->dev_ops
->setup_queues(dev
, num_queues
, socket_id
);
387 "Device %u memory configuration failed",
393 rte_bbdev_log_debug("Device %u set up with %u queues", dev_id
,
398 dev
->data
->num_queues
= 0;
399 rte_free(dev
->data
->queues
);
400 dev
->data
->queues
= NULL
;
404 int __rte_experimental
405 rte_bbdev_intr_enable(uint16_t dev_id
)
408 struct rte_bbdev
*dev
= get_dev(dev_id
);
409 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
411 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
413 if (dev
->data
->started
) {
415 "Device %u cannot be configured when started",
420 if (dev
->dev_ops
->intr_enable
) {
421 ret
= dev
->dev_ops
->intr_enable(dev
);
424 "Device %u interrupts configuration failed",
428 rte_bbdev_log_debug("Enabled interrupts for dev %u", dev_id
);
432 rte_bbdev_log(ERR
, "Device %u doesn't support interrupts", dev_id
);
436 int __rte_experimental
437 rte_bbdev_queue_configure(uint16_t dev_id
, uint16_t queue_id
,
438 const struct rte_bbdev_queue_conf
*conf
)
441 struct rte_bbdev_driver_info dev_info
;
442 struct rte_bbdev
*dev
= get_dev(dev_id
);
443 const struct rte_bbdev_op_cap
*p
;
444 struct rte_bbdev_queue_conf
*stored_conf
;
445 const char *op_type_str
;
446 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
448 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
450 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
452 if (dev
->data
->queues
[queue_id
].started
|| dev
->data
->started
) {
454 "Queue %u of device %u cannot be configured when started",
459 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->queue_release
, dev_id
);
460 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->queue_setup
, dev_id
);
462 /* Get device driver information to verify config is valid */
463 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->info_get
, dev_id
);
464 memset(&dev_info
, 0, sizeof(dev_info
));
465 dev
->dev_ops
->info_get(dev
, &dev_info
);
467 /* Check configuration is valid */
469 if ((conf
->op_type
== RTE_BBDEV_OP_NONE
) &&
470 (dev_info
.capabilities
[0].type
==
471 RTE_BBDEV_OP_NONE
)) {
474 for (p
= dev_info
.capabilities
;
475 p
->type
!= RTE_BBDEV_OP_NONE
; p
++) {
476 if (conf
->op_type
== p
->type
) {
483 rte_bbdev_log(ERR
, "Invalid operation type");
486 if (conf
->queue_size
> dev_info
.queue_size_lim
) {
488 "Size (%u) of queue %u of device %u must be: <= %u",
489 conf
->queue_size
, queue_id
, dev_id
,
490 dev_info
.queue_size_lim
);
493 if (!rte_is_power_of_2(conf
->queue_size
)) {
495 "Size (%u) of queue %u of device %u must be a power of 2",
496 conf
->queue_size
, queue_id
, dev_id
);
499 if (conf
->op_type
== RTE_BBDEV_OP_TURBO_DEC
&&
500 conf
->priority
> dev_info
.max_ul_queue_priority
) {
502 "Priority (%u) of queue %u of bdev %u must be <= %u",
503 conf
->priority
, queue_id
, dev_id
,
504 dev_info
.max_ul_queue_priority
);
507 if (conf
->op_type
== RTE_BBDEV_OP_TURBO_ENC
&&
508 conf
->priority
> dev_info
.max_dl_queue_priority
) {
510 "Priority (%u) of queue %u of bdev %u must be <= %u",
511 conf
->priority
, queue_id
, dev_id
,
512 dev_info
.max_dl_queue_priority
);
517 /* Release existing queue (in case of queue reconfiguration) */
518 if (dev
->data
->queues
[queue_id
].queue_private
!= NULL
) {
519 ret
= dev
->dev_ops
->queue_release(dev
, queue_id
);
521 rte_bbdev_log(ERR
, "Device %u queue %u release failed",
527 /* Get driver to setup the queue */
528 ret
= dev
->dev_ops
->queue_setup(dev
, queue_id
, (conf
!= NULL
) ?
529 conf
: &dev_info
.default_queue_conf
);
532 "Device %u queue %u setup failed", dev_id
,
537 /* Store configuration */
538 stored_conf
= &dev
->data
->queues
[queue_id
].conf
;
540 (conf
!= NULL
) ? conf
: &dev_info
.default_queue_conf
,
541 sizeof(*stored_conf
));
543 op_type_str
= rte_bbdev_op_type_str(stored_conf
->op_type
);
544 if (op_type_str
== NULL
)
547 rte_bbdev_log_debug("Configured dev%uq%u (size=%u, type=%s, prio=%u)",
548 dev_id
, queue_id
, stored_conf
->queue_size
, op_type_str
,
549 stored_conf
->priority
);
554 int __rte_experimental
555 rte_bbdev_start(uint16_t dev_id
)
558 struct rte_bbdev
*dev
= get_dev(dev_id
);
559 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
561 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
563 if (dev
->data
->started
) {
564 rte_bbdev_log_debug("Device %u is already started", dev_id
);
568 if (dev
->dev_ops
->start
) {
569 int ret
= dev
->dev_ops
->start(dev
);
571 rte_bbdev_log(ERR
, "Device %u start failed", dev_id
);
576 /* Store new state */
577 for (i
= 0; i
< dev
->data
->num_queues
; i
++)
578 if (!dev
->data
->queues
[i
].conf
.deferred_start
)
579 dev
->data
->queues
[i
].started
= true;
580 dev
->data
->started
= true;
582 rte_bbdev_log_debug("Started device %u", dev_id
);
586 int __rte_experimental
587 rte_bbdev_stop(uint16_t dev_id
)
589 struct rte_bbdev
*dev
= get_dev(dev_id
);
590 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
592 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
594 if (!dev
->data
->started
) {
595 rte_bbdev_log_debug("Device %u is already stopped", dev_id
);
599 if (dev
->dev_ops
->stop
)
600 dev
->dev_ops
->stop(dev
);
601 dev
->data
->started
= false;
603 rte_bbdev_log_debug("Stopped device %u", dev_id
);
607 int __rte_experimental
608 rte_bbdev_close(uint16_t dev_id
)
612 struct rte_bbdev
*dev
= get_dev(dev_id
);
613 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
615 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
617 if (dev
->data
->started
) {
618 ret
= rte_bbdev_stop(dev_id
);
620 rte_bbdev_log(ERR
, "Device %u stop failed", dev_id
);
625 /* Free memory used by queues */
626 for (i
= 0; i
< dev
->data
->num_queues
; i
++) {
627 ret
= dev
->dev_ops
->queue_release(dev
, i
);
629 rte_bbdev_log(ERR
, "Device %u queue %u release failed",
634 rte_free(dev
->data
->queues
);
636 if (dev
->dev_ops
->close
) {
637 ret
= dev
->dev_ops
->close(dev
);
639 rte_bbdev_log(ERR
, "Device %u close failed", dev_id
);
644 /* Clear configuration */
645 dev
->data
->queues
= NULL
;
646 dev
->data
->num_queues
= 0;
648 rte_bbdev_log_debug("Closed device %u", dev_id
);
652 int __rte_experimental
653 rte_bbdev_queue_start(uint16_t dev_id
, uint16_t queue_id
)
655 struct rte_bbdev
*dev
= get_dev(dev_id
);
656 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
658 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
660 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
662 if (dev
->data
->queues
[queue_id
].started
) {
663 rte_bbdev_log_debug("Queue %u of device %u already started",
668 if (dev
->dev_ops
->queue_start
) {
669 int ret
= dev
->dev_ops
->queue_start(dev
, queue_id
);
671 rte_bbdev_log(ERR
, "Device %u queue %u start failed",
676 dev
->data
->queues
[queue_id
].started
= true;
678 rte_bbdev_log_debug("Started queue %u of device %u", queue_id
, dev_id
);
682 int __rte_experimental
683 rte_bbdev_queue_stop(uint16_t dev_id
, uint16_t queue_id
)
685 struct rte_bbdev
*dev
= get_dev(dev_id
);
686 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
688 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
690 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
692 if (!dev
->data
->queues
[queue_id
].started
) {
693 rte_bbdev_log_debug("Queue %u of device %u already stopped",
698 if (dev
->dev_ops
->queue_stop
) {
699 int ret
= dev
->dev_ops
->queue_stop(dev
, queue_id
);
701 rte_bbdev_log(ERR
, "Device %u queue %u stop failed",
706 dev
->data
->queues
[queue_id
].started
= false;
708 rte_bbdev_log_debug("Stopped queue %u of device %u", queue_id
, dev_id
);
712 /* Get device statistics */
714 get_stats_from_queues(struct rte_bbdev
*dev
, struct rte_bbdev_stats
*stats
)
717 for (q_id
= 0; q_id
< dev
->data
->num_queues
; q_id
++) {
718 struct rte_bbdev_stats
*q_stats
=
719 &dev
->data
->queues
[q_id
].queue_stats
;
721 stats
->enqueued_count
+= q_stats
->enqueued_count
;
722 stats
->dequeued_count
+= q_stats
->dequeued_count
;
723 stats
->enqueue_err_count
+= q_stats
->enqueue_err_count
;
724 stats
->dequeue_err_count
+= q_stats
->dequeue_err_count
;
726 rte_bbdev_log_debug("Got stats on %u", dev
->data
->dev_id
);
730 reset_stats_in_queues(struct rte_bbdev
*dev
)
733 for (q_id
= 0; q_id
< dev
->data
->num_queues
; q_id
++) {
734 struct rte_bbdev_stats
*q_stats
=
735 &dev
->data
->queues
[q_id
].queue_stats
;
737 memset(q_stats
, 0, sizeof(*q_stats
));
739 rte_bbdev_log_debug("Reset stats on %u", dev
->data
->dev_id
);
742 int __rte_experimental
743 rte_bbdev_stats_get(uint16_t dev_id
, struct rte_bbdev_stats
*stats
)
745 struct rte_bbdev
*dev
= get_dev(dev_id
);
746 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
748 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
751 rte_bbdev_log(ERR
, "NULL stats structure");
755 memset(stats
, 0, sizeof(*stats
));
756 if (dev
->dev_ops
->stats_get
!= NULL
)
757 dev
->dev_ops
->stats_get(dev
, stats
);
759 get_stats_from_queues(dev
, stats
);
761 rte_bbdev_log_debug("Retrieved stats of device %u", dev_id
);
765 int __rte_experimental
766 rte_bbdev_stats_reset(uint16_t dev_id
)
768 struct rte_bbdev
*dev
= get_dev(dev_id
);
769 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
771 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
773 if (dev
->dev_ops
->stats_reset
!= NULL
)
774 dev
->dev_ops
->stats_reset(dev
);
776 reset_stats_in_queues(dev
);
778 rte_bbdev_log_debug("Reset stats of device %u", dev_id
);
782 int __rte_experimental
783 rte_bbdev_info_get(uint16_t dev_id
, struct rte_bbdev_info
*dev_info
)
785 struct rte_bbdev
*dev
= get_dev(dev_id
);
786 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
788 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->info_get
, dev_id
);
790 if (dev_info
== NULL
) {
791 rte_bbdev_log(ERR
, "NULL dev info structure");
795 /* Copy data maintained by device interface layer */
796 memset(dev_info
, 0, sizeof(*dev_info
));
797 dev_info
->dev_name
= dev
->data
->name
;
798 dev_info
->num_queues
= dev
->data
->num_queues
;
799 dev_info
->bus
= rte_bus_find_by_device(dev
->device
);
800 dev_info
->socket_id
= dev
->data
->socket_id
;
801 dev_info
->started
= dev
->data
->started
;
803 /* Copy data maintained by device driver layer */
804 dev
->dev_ops
->info_get(dev
, &dev_info
->drv
);
806 rte_bbdev_log_debug("Retrieved info of device %u", dev_id
);
810 int __rte_experimental
811 rte_bbdev_queue_info_get(uint16_t dev_id
, uint16_t queue_id
,
812 struct rte_bbdev_queue_info
*queue_info
)
814 struct rte_bbdev
*dev
= get_dev(dev_id
);
815 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
817 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
819 if (queue_info
== NULL
) {
820 rte_bbdev_log(ERR
, "NULL queue info structure");
824 /* Copy data to output */
825 memset(queue_info
, 0, sizeof(*queue_info
));
826 queue_info
->conf
= dev
->data
->queues
[queue_id
].conf
;
827 queue_info
->started
= dev
->data
->queues
[queue_id
].started
;
829 rte_bbdev_log_debug("Retrieved info of queue %u of device %u",
834 /* Calculate size needed to store bbdev_op, depending on type */
836 get_bbdev_op_size(enum rte_bbdev_op_type type
)
838 unsigned int result
= 0;
840 case RTE_BBDEV_OP_NONE
:
841 result
= RTE_MAX(sizeof(struct rte_bbdev_dec_op
),
842 sizeof(struct rte_bbdev_enc_op
));
844 case RTE_BBDEV_OP_TURBO_DEC
:
845 result
= sizeof(struct rte_bbdev_dec_op
);
847 case RTE_BBDEV_OP_TURBO_ENC
:
848 result
= sizeof(struct rte_bbdev_enc_op
);
857 /* Initialise a bbdev_op structure */
859 bbdev_op_init(struct rte_mempool
*mempool
, void *arg
, void *element
,
860 __rte_unused
unsigned int n
)
862 enum rte_bbdev_op_type type
= *(enum rte_bbdev_op_type
*)arg
;
864 if (type
== RTE_BBDEV_OP_TURBO_DEC
) {
865 struct rte_bbdev_dec_op
*op
= element
;
866 memset(op
, 0, mempool
->elt_size
);
867 op
->mempool
= mempool
;
868 } else if (type
== RTE_BBDEV_OP_TURBO_ENC
) {
869 struct rte_bbdev_enc_op
*op
= element
;
870 memset(op
, 0, mempool
->elt_size
);
871 op
->mempool
= mempool
;
875 struct rte_mempool
* __rte_experimental
876 rte_bbdev_op_pool_create(const char *name
, enum rte_bbdev_op_type type
,
877 unsigned int num_elements
, unsigned int cache_size
,
880 struct rte_bbdev_op_pool_private
*priv
;
881 struct rte_mempool
*mp
;
882 const char *op_type_str
;
885 rte_bbdev_log(ERR
, "NULL name for op pool");
889 if (type
>= RTE_BBDEV_OP_TYPE_COUNT
) {
891 "Invalid op type (%u), should be less than %u",
892 type
, RTE_BBDEV_OP_TYPE_COUNT
);
896 mp
= rte_mempool_create(name
, num_elements
, get_bbdev_op_size(type
),
897 cache_size
, sizeof(struct rte_bbdev_op_pool_private
),
898 NULL
, NULL
, bbdev_op_init
, &type
, socket_id
, 0);
901 "Failed to create op pool %s (num ops=%u, op size=%u) with error: %s",
902 name
, num_elements
, get_bbdev_op_size(type
),
903 rte_strerror(rte_errno
));
907 op_type_str
= rte_bbdev_op_type_str(type
);
908 if (op_type_str
== NULL
)
912 "Op pool %s created for %u ops (type=%s, cache=%u, socket=%u, size=%u)",
913 name
, num_elements
, op_type_str
, cache_size
, socket_id
,
914 get_bbdev_op_size(type
));
916 priv
= (struct rte_bbdev_op_pool_private
*)rte_mempool_get_priv(mp
);
922 int __rte_experimental
923 rte_bbdev_callback_register(uint16_t dev_id
, enum rte_bbdev_event_type event
,
924 rte_bbdev_cb_fn cb_fn
, void *cb_arg
)
926 struct rte_bbdev_callback
*user_cb
;
927 struct rte_bbdev
*dev
= get_dev(dev_id
);
928 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
930 if (event
>= RTE_BBDEV_EVENT_MAX
) {
932 "Invalid event type (%u), should be less than %u",
933 event
, RTE_BBDEV_EVENT_MAX
);
938 rte_bbdev_log(ERR
, "NULL callback function");
942 rte_spinlock_lock(&rte_bbdev_cb_lock
);
944 TAILQ_FOREACH(user_cb
, &(dev
->list_cbs
), next
) {
945 if (user_cb
->cb_fn
== cb_fn
&&
946 user_cb
->cb_arg
== cb_arg
&&
947 user_cb
->event
== event
)
951 /* create a new callback. */
952 if (user_cb
== NULL
) {
953 user_cb
= rte_zmalloc("INTR_USER_CALLBACK",
954 sizeof(struct rte_bbdev_callback
), 0);
955 if (user_cb
!= NULL
) {
956 user_cb
->cb_fn
= cb_fn
;
957 user_cb
->cb_arg
= cb_arg
;
958 user_cb
->event
= event
;
959 TAILQ_INSERT_TAIL(&(dev
->list_cbs
), user_cb
, next
);
963 rte_spinlock_unlock(&rte_bbdev_cb_lock
);
964 return (user_cb
== NULL
) ? -ENOMEM
: 0;
967 int __rte_experimental
968 rte_bbdev_callback_unregister(uint16_t dev_id
, enum rte_bbdev_event_type event
,
969 rte_bbdev_cb_fn cb_fn
, void *cb_arg
)
972 struct rte_bbdev_callback
*cb
, *next
;
973 struct rte_bbdev
*dev
= get_dev(dev_id
);
974 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
976 if (event
>= RTE_BBDEV_EVENT_MAX
) {
978 "Invalid event type (%u), should be less than %u",
979 event
, RTE_BBDEV_EVENT_MAX
);
985 "NULL callback function cannot be unregistered");
989 dev
= &rte_bbdev_devices
[dev_id
];
990 rte_spinlock_lock(&rte_bbdev_cb_lock
);
992 for (cb
= TAILQ_FIRST(&dev
->list_cbs
); cb
!= NULL
; cb
= next
) {
994 next
= TAILQ_NEXT(cb
, next
);
996 if (cb
->cb_fn
!= cb_fn
|| cb
->event
!= event
||
997 (cb_arg
!= (void *)-1 && cb
->cb_arg
!= cb_arg
))
1000 /* If this callback is not executing right now, remove it. */
1001 if (cb
->active
== 0) {
1002 TAILQ_REMOVE(&(dev
->list_cbs
), cb
, next
);
1008 rte_spinlock_unlock(&rte_bbdev_cb_lock
);
1012 void __rte_experimental
1013 rte_bbdev_pmd_callback_process(struct rte_bbdev
*dev
,
1014 enum rte_bbdev_event_type event
, void *ret_param
)
1016 struct rte_bbdev_callback
*cb_lst
;
1017 struct rte_bbdev_callback dev_cb
;
1020 rte_bbdev_log(ERR
, "NULL device");
1024 if (dev
->data
== NULL
) {
1025 rte_bbdev_log(ERR
, "NULL data structure");
1029 if (event
>= RTE_BBDEV_EVENT_MAX
) {
1031 "Invalid event type (%u), should be less than %u",
1032 event
, RTE_BBDEV_EVENT_MAX
);
1036 rte_spinlock_lock(&rte_bbdev_cb_lock
);
1037 TAILQ_FOREACH(cb_lst
, &(dev
->list_cbs
), next
) {
1038 if (cb_lst
->cb_fn
== NULL
|| cb_lst
->event
!= event
)
1042 if (ret_param
!= NULL
)
1043 dev_cb
.ret_param
= ret_param
;
1045 rte_spinlock_unlock(&rte_bbdev_cb_lock
);
1046 dev_cb
.cb_fn(dev
->data
->dev_id
, dev_cb
.event
,
1047 dev_cb
.cb_arg
, dev_cb
.ret_param
);
1048 rte_spinlock_lock(&rte_bbdev_cb_lock
);
1051 rte_spinlock_unlock(&rte_bbdev_cb_lock
);
1054 int __rte_experimental
1055 rte_bbdev_queue_intr_enable(uint16_t dev_id
, uint16_t queue_id
)
1057 struct rte_bbdev
*dev
= get_dev(dev_id
);
1058 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
1059 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
1060 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
1061 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->queue_intr_enable
, dev_id
);
1062 return dev
->dev_ops
->queue_intr_enable(dev
, queue_id
);
1065 int __rte_experimental
1066 rte_bbdev_queue_intr_disable(uint16_t dev_id
, uint16_t queue_id
)
1068 struct rte_bbdev
*dev
= get_dev(dev_id
);
1069 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
1070 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
1071 VALID_DEV_OPS_OR_RET_ERR(dev
, dev_id
);
1072 VALID_FUNC_OR_RET_ERR(dev
->dev_ops
->queue_intr_disable
, dev_id
);
1073 return dev
->dev_ops
->queue_intr_disable(dev
, queue_id
);
1076 int __rte_experimental
1077 rte_bbdev_queue_intr_ctl(uint16_t dev_id
, uint16_t queue_id
, int epfd
, int op
,
1081 struct rte_bbdev
*dev
= get_dev(dev_id
);
1082 struct rte_intr_handle
*intr_handle
;
1085 VALID_DEV_OR_RET_ERR(dev
, dev_id
);
1086 VALID_QUEUE_OR_RET_ERR(queue_id
, dev
);
1088 intr_handle
= dev
->intr_handle
;
1089 if (!intr_handle
|| !intr_handle
->intr_vec
) {
1090 rte_bbdev_log(ERR
, "Device %u intr handle unset\n", dev_id
);
1094 if (queue_id
>= RTE_MAX_RXTX_INTR_VEC_ID
) {
1095 rte_bbdev_log(ERR
, "Device %u queue_id %u is too big\n",
1100 vec
= intr_handle
->intr_vec
[queue_id
];
1101 ret
= rte_intr_rx_ctl(intr_handle
, epfd
, op
, vec
, data
);
1102 if (ret
&& (ret
!= -EEXIST
)) {
1104 "dev %u q %u int ctl error op %d epfd %d vec %u\n",
1105 dev_id
, queue_id
, op
, epfd
, vec
);
1113 const char * __rte_experimental
1114 rte_bbdev_op_type_str(enum rte_bbdev_op_type op_type
)
1116 static const char * const op_types
[] = {
1117 "RTE_BBDEV_OP_NONE",
1118 "RTE_BBDEV_OP_TURBO_DEC",
1119 "RTE_BBDEV_OP_TURBO_ENC",
1122 if (op_type
< RTE_BBDEV_OP_TYPE_COUNT
)
1123 return op_types
[op_type
];
1125 rte_bbdev_log(ERR
, "Invalid operation type");
1129 RTE_INIT(rte_bbdev_init_log
)
1131 bbdev_logtype
= rte_log_register("lib.bbdev");
1132 if (bbdev_logtype
>= 0)
1133 rte_log_set_level(bbdev_logtype
, RTE_LOG_NOTICE
);