+static int
+dpaa_event_dequeue_timeout_ticks_intr(struct rte_eventdev *dev, uint64_t ns,
+ uint64_t *timeout_ticks)
+{
+ RTE_SET_USED(dev);
+
+ *timeout_ticks = ns/1000;
+ return 0;
+}
+
+static void
+dpaa_eventq_portal_add(u16 ch_id)
+{
+ uint32_t sdqcr;
+
+ sdqcr = QM_SDQCR_CHANNELS_POOL_CONV(ch_id);
+ qman_static_dequeue_add(sdqcr, NULL);
+}
+
+static uint16_t
+dpaa_event_enqueue_burst(void *port, const struct rte_event ev[],
+ uint16_t nb_events)
+{
+ uint16_t i;
+ struct rte_mbuf *mbuf;
+
+ RTE_SET_USED(port);
+ /*Release all the contexts saved previously*/
+ for (i = 0; i < nb_events; i++) {
+ switch (ev[i].op) {
+ case RTE_EVENT_OP_RELEASE:
+ qman_dca_index(ev[i].impl_opaque, 0);
+ mbuf = DPAA_PER_LCORE_DQRR_MBUF(i);
+ *dpaa_seqn(mbuf) = DPAA_INVALID_MBUF_SEQN;
+ DPAA_PER_LCORE_DQRR_HELD &= ~(1 << i);
+ DPAA_PER_LCORE_DQRR_SIZE--;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return nb_events;
+}
+
+static uint16_t
+dpaa_event_enqueue(void *port, const struct rte_event *ev)
+{
+ return dpaa_event_enqueue_burst(port, ev, 1);
+}
+
+static void drain_4_bytes(int fd, fd_set *fdset)
+{
+ if (FD_ISSET(fd, fdset)) {
+ /* drain 4 bytes */
+ uint32_t junk;
+ ssize_t sjunk = read(qman_thread_fd(), &junk, sizeof(junk));
+ if (sjunk != sizeof(junk))
+ DPAA_EVENTDEV_ERR("UIO irq read error");
+ }
+}
+
+static inline int
+dpaa_event_dequeue_wait(uint64_t timeout_ticks)
+{
+ int fd_qman, nfds;
+ int ret;
+ fd_set readset;
+
+ /* Go into (and back out of) IRQ mode for each select,
+ * it simplifies exit-path considerations and other
+ * potential nastiness.
+ */
+ struct timeval tv = {
+ .tv_sec = timeout_ticks / 1000000,
+ .tv_usec = timeout_ticks % 1000000
+ };
+
+ fd_qman = qman_thread_fd();
+ nfds = fd_qman + 1;
+ FD_ZERO(&readset);
+ FD_SET(fd_qman, &readset);
+
+ qman_irqsource_add(QM_PIRQ_DQRI);
+
+ ret = select(nfds, &readset, NULL, NULL, &tv);
+ if (ret < 0)
+ return ret;
+ /* Calling irqsource_remove() prior to thread_irq()
+ * means thread_irq() will not process whatever caused
+ * the interrupts, however it does ensure that, once
+ * thread_irq() re-enables interrupts, they won't fire
+ * again immediately.
+ */
+ qman_irqsource_remove(~0);
+ drain_4_bytes(fd_qman, &readset);
+ qman_thread_irq();
+
+ return ret;
+}
+
+static uint16_t
+dpaa_event_dequeue_burst(void *port, struct rte_event ev[],
+ uint16_t nb_events, uint64_t timeout_ticks)
+{
+ int ret;
+ u16 ch_id;
+ void *buffers[8];
+ u32 num_frames, i;
+ uint64_t cur_ticks = 0, wait_time_ticks = 0;
+ struct dpaa_port *portal = (struct dpaa_port *)port;
+ struct rte_mbuf *mbuf;
+
+ if (unlikely(!DPAA_PER_LCORE_PORTAL)) {
+ /* Affine current thread context to a qman portal */
+ ret = rte_dpaa_portal_init((void *)0);
+ if (ret) {
+ DPAA_EVENTDEV_ERR("Unable to initialize portal");
+ return ret;
+ }
+ }
+
+ if (unlikely(!portal->is_port_linked)) {
+ /*
+ * Affine event queue for current thread context
+ * to a qman portal.
+ */
+ for (i = 0; i < portal->num_linked_evq; i++) {
+ ch_id = portal->evq_info[i].ch_id;
+ dpaa_eventq_portal_add(ch_id);
+ }
+ portal->is_port_linked = true;
+ }
+
+ /* Check if there are atomic contexts to be released */
+ i = 0;
+ while (DPAA_PER_LCORE_DQRR_SIZE) {
+ if (DPAA_PER_LCORE_DQRR_HELD & (1 << i)) {
+ qman_dca_index(i, 0);
+ mbuf = DPAA_PER_LCORE_DQRR_MBUF(i);
+ *dpaa_seqn(mbuf) = DPAA_INVALID_MBUF_SEQN;
+ DPAA_PER_LCORE_DQRR_HELD &= ~(1 << i);
+ DPAA_PER_LCORE_DQRR_SIZE--;
+ }
+ i++;
+ }
+ DPAA_PER_LCORE_DQRR_HELD = 0;
+
+ if (timeout_ticks)
+ wait_time_ticks = timeout_ticks;
+ else
+ wait_time_ticks = portal->timeout_us;
+
+ wait_time_ticks += rte_get_timer_cycles();
+ do {
+ /* Lets dequeue the frames */
+ num_frames = qman_portal_dequeue(ev, nb_events, buffers);
+ if (num_frames)
+ break;
+ cur_ticks = rte_get_timer_cycles();
+ } while (cur_ticks < wait_time_ticks);
+
+ return num_frames;
+}
+
+static uint16_t
+dpaa_event_dequeue(void *port, struct rte_event *ev, uint64_t timeout_ticks)
+{
+ return dpaa_event_dequeue_burst(port, ev, 1, timeout_ticks);
+}
+
+static uint16_t
+dpaa_event_dequeue_burst_intr(void *port, struct rte_event ev[],
+ uint16_t nb_events, uint64_t timeout_ticks)
+{
+ int ret;
+ u16 ch_id;
+ void *buffers[8];
+ u32 num_frames, i, irq = 0;
+ uint64_t cur_ticks = 0, wait_time_ticks = 0;
+ struct dpaa_port *portal = (struct dpaa_port *)port;
+ struct rte_mbuf *mbuf;
+
+ if (unlikely(!DPAA_PER_LCORE_PORTAL)) {
+ /* Affine current thread context to a qman portal */
+ ret = rte_dpaa_portal_init((void *)0);
+ if (ret) {
+ DPAA_EVENTDEV_ERR("Unable to initialize portal");
+ return ret;
+ }
+ }
+
+ if (unlikely(!portal->is_port_linked)) {
+ /*
+ * Affine event queue for current thread context
+ * to a qman portal.
+ */
+ for (i = 0; i < portal->num_linked_evq; i++) {
+ ch_id = portal->evq_info[i].ch_id;
+ dpaa_eventq_portal_add(ch_id);
+ }
+ portal->is_port_linked = true;
+ }
+
+ /* Check if there are atomic contexts to be released */
+ i = 0;
+ while (DPAA_PER_LCORE_DQRR_SIZE) {
+ if (DPAA_PER_LCORE_DQRR_HELD & (1 << i)) {
+ qman_dca_index(i, 0);
+ mbuf = DPAA_PER_LCORE_DQRR_MBUF(i);
+ *dpaa_seqn(mbuf) = DPAA_INVALID_MBUF_SEQN;
+ DPAA_PER_LCORE_DQRR_HELD &= ~(1 << i);
+ DPAA_PER_LCORE_DQRR_SIZE--;
+ }
+ i++;
+ }
+ DPAA_PER_LCORE_DQRR_HELD = 0;
+
+ if (timeout_ticks)
+ wait_time_ticks = timeout_ticks;
+ else
+ wait_time_ticks = portal->timeout_us;
+
+ do {
+ /* Lets dequeue the frames */
+ num_frames = qman_portal_dequeue(ev, nb_events, buffers);
+ if (irq)
+ irq = 0;
+ if (num_frames)
+ break;
+ if (wait_time_ticks) { /* wait for time */
+ if (dpaa_event_dequeue_wait(wait_time_ticks) > 0) {
+ irq = 1;
+ continue;
+ }
+ break; /* no event after waiting */
+ }
+ cur_ticks = rte_get_timer_cycles();
+ } while (cur_ticks < wait_time_ticks);
+
+ return num_frames;
+}
+
+static uint16_t
+dpaa_event_dequeue_intr(void *port,
+ struct rte_event *ev,
+ uint64_t timeout_ticks)
+{
+ return dpaa_event_dequeue_burst_intr(port, ev, 1, timeout_ticks);
+}
+