+static_always_inline vnet_crypto_async_frame_t *
+cryptodev_frame_dequeue (vlib_main_t *vm, u32 *nb_elts_processed,
+ u32 *enqueue_thread_idx)
+{
+ cryptodev_main_t *cmt = &cryptodev_main;
+ vnet_crypto_main_t *cm = &crypto_main;
+ cryptodev_engine_thread_t *cet = cmt->per_thread_data + vm->thread_index;
+
+ cryptodev_async_frame_sw_ring *ring = &cet->frame_ring;
+ cryptodev_async_ring_elt *ring_elt = &ring->frames[ring->tail];
+ vnet_crypto_async_frame_t *ret_frame = 0;
+ u8 dequeue_more = 1;
+
+ while (cet->inflight > 0 && dequeue_more)
+ {
+ dequeue_more = cryptodev_frame_dequeue_internal (vm, nb_elts_processed,
+ enqueue_thread_idx);
+ }
+
+ if (PREDICT_TRUE (ring->frames[ring->enq].f != 0))
+ cryptodev_enqueue_frame (vm, &ring->frames[ring->enq]);
+
+ if (PREDICT_TRUE (ring_elt->f != 0))
+ {
+ if ((ring_elt->f->state == VNET_CRYPTO_FRAME_STATE_SUCCESS ||
+ ring_elt->f->state == VNET_CRYPTO_FRAME_STATE_ELT_ERROR) &&
+ ring_elt->enqueued == ring_elt->dequeued)
+ {
+ vlib_node_set_interrupt_pending (
+ vlib_get_main_by_index (vm->thread_index), cm->crypto_node_index);
+ ret_frame = ring_elt->f;
+ memset (ring_elt, 0, sizeof (*ring_elt));
+ ring->tail += 1;
+ ring->tail &= (VNET_CRYPTO_FRAME_POOL_SIZE - 1);
+ cet->frames_on_ring--;
+ cet->deqeued_not_returned--;
+ return ret_frame;
+ }
+ }
+
+ return ret_frame;
+}