<commit_before>/* SPDX-License-Identifier: BSD-3-Clause
 *
 *   Copyright 2017 NXP
 *
 */

#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/epoll.h>

#include <rte_atomic.h>
#include <rte_byteorder.h>
#include <rte_common.h>
#include <rte_debug.h>
#include <rte_dev.h>
#include <rte_eal.h>
#include <rte_fslmc.h>
#include <rte_lcore.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memcpy.h>
#include <rte_memory.h>
#include <rte_pci.h>
#include <rte_bus_vdev.h>
#include <rte_ethdev_driver.h>
#include <rte_event_eth_rx_adapter.h>

#include <fslmc_vfio.h>
#include <dpaa2_hw_pvt.h>
#include <dpaa2_hw_mempool.h>
#include <dpaa2_hw_dpio.h>
#include <dpaa2_ethdev.h>
#include "dpaa2_eventdev.h"
#include "dpaa2_eventdev_logs.h"
#include <portal/dpaa2_hw_pvt.h>
#include <mc/fsl_dpci.h>

/* Clarifications
 * Evendev = SoC Instance
 * Eventport = DPIO Instance
 * Eventqueue = DPCON Instance
 * 1 Eventdev can have N Eventqueue
 * Soft Event Flow is DPCI Instance
 */

/* Dynamic logging identified for mempool */
int dpaa2_logtype_event;

static uint16_t
dpaa2_eventdev_enqueue_burst(void *port, const struct rte_event ev[],
			     uint16_t nb_events)
{
	struct rte_eventdev *ev_dev =
			((struct dpaa2_io_portal_t *)port)->eventdev;
	struct dpaa2_eventdev *priv = ev_dev->data->dev_private;
	uint32_t queue_id = ev[0].queue_id;
	struct evq_info_t *evq_info = &priv->evq_info[queue_id];
	uint32_t fqid;
	struct qbman_swp *swp;
	struct qbman_fd fd_arr[MAX_TX_RING_SLOTS];
	uint32_t loop, frames_to_send;
	struct qbman_eq_desc eqdesc[MAX_TX_RING_SLOTS];
	uint16_t num_tx = 0;
	int ret;

	RTE_SET_USED(port);

	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
		ret = dpaa2_affine_qbman_swp();
		if (ret) {
			DPAA2_EVENTDEV_ERR("Failure in affining portal");
			return 0;
		}
	}

	swp = DPAA2_PER_LCORE_PORTAL;

	while (nb_events) {
		frames_to_send = (nb_events >> 3) ?
			MAX_TX_RING_SLOTS : nb_events;

		for (loop = 0; loop < frames_to_send; loop++) {
			const struct rte_event *event = &ev[num_tx + loop];

			if (event->sched_type != RTE_SCHED_TYPE_ATOMIC)
				fqid = evq_info->dpci->rx_queue[
					DPAA2_EVENT_DPCI_PARALLEL_QUEUE].fqid;
			else
				fqid = evq_info->dpci->rx_queue[
					DPAA2_EVENT_DPCI_ATOMIC_QUEUE].fqid;

			/* Prepare enqueue descriptor */
			qbman_eq_desc_clear(&eqdesc[loop]);
			qbman_eq_desc_set_fq(&eqdesc[loop], fqid);
			qbman_eq_desc_set_no_orp(&eqdesc[loop], 0);
			qbman_eq_desc_set_response(&eqdesc[loop], 0, 0);

			if (event->mbuf->seqn) {
				uint8_t dqrr_index = event->mbuf->seqn - 1;

				qbman_eq_desc_set_dca(&eqdesc[loop], 1,
						      dqrr_index, 0);
				DPAA2_PER_LCORE_DQRR_SIZE--;
				DPAA2_PER_LCORE_DQRR_HELD &=
					~(1 << dqrr_index);
			}

			memset(&fd_arr[loop], 0, sizeof(struct qbman_fd));

			/*
			 * todo - need to align with hw context data
			 * to avoid copy
			 */
			struct rte_event *ev_temp = rte_malloc(NULL,
				sizeof(struct rte_event), 0);

			if (!ev_temp) {
				if (!loop)
					return num_tx;
				frames_to_send = loop;
				DPAA2_EVENTDEV_ERR(
					"Unable to allocate event object");
				goto send_partial;
			}
			rte_memcpy(ev_temp, event, sizeof(struct rte_event));
			DPAA2_SET_FD_ADDR((&fd_arr[loop]), (size_t)ev_temp);
			DPAA2_SET_FD_LEN((&fd_arr[loop]),
					 sizeof(struct rte_event));
		}
send_partial:
		loop = 0;
		while (loop < frames_to_send) {
			loop += qbman_swp_enqueue_multiple_desc(swp,
					&eqdesc[loop], &fd_arr[loop],
					frames_to_send - loop);
		}
		num_tx += frames_to_send;
		nb_events -= frames_to_send;
	}

	return num_tx;
}

static uint16_t
dpaa2_eventdev_enqueue(void *port, const struct rte_event *ev)
{
	return dpaa2_eventdev_enqueue_burst(port, ev, 1);
}

static void dpaa2_eventdev_dequeue_wait(uint64_t timeout_ticks)
{
	struct epoll_event epoll_ev;
	int ret, i = 0;

	qbman_swp_interrupt_clear_status(DPAA2_PER_LCORE_PORTAL,
					 QBMAN_SWP_INTERRUPT_DQRI);

RETRY:
	ret = epoll_wait(DPAA2_PER_LCORE_DPIO->epoll_fd,
			 &epoll_ev, 1, timeout_ticks);
	if (ret < 1) {
		/* sometimes due to some spurious interrupts epoll_wait fails
		 * with errno EINTR. so here we are retrying epoll_wait in such
		 * case to avoid the problem.
		 */
		if (errno == EINTR) {
			DPAA2_EVENTDEV_DEBUG("epoll_wait fails");
			if (i++ > 10)
				DPAA2_EVENTDEV_DEBUG("Dequeue burst Failed");
		goto RETRY;
		}
	}
}

static void dpaa2_eventdev_process_parallel(struct qbman_swp *swp,
					    const struct qbman_fd *fd,
					    const struct qbman_result *dq,
					    struct dpaa2_queue *rxq,
					    struct rte_event *ev)
{
	struct rte_event *ev_temp =
		(struct rte_event *)(size_t)DPAA2_GET_FD_ADDR(fd);
<commit_msg>event/dpaa2: remove check on epoll return<commit_after>/* SPDX-License-Identifier: BSD-3-Clause
 *
 *   Copyright 2017 NXP
 *
 */

#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/epoll.h>

#include <rte_atomic.h>
#include <rte_byteorder.h>
#include <rte_common.h>
#include <rte_debug.h>
#include <rte_dev.h>
#include <rte_eal.h>
#include <rte_fslmc.h>
#include <rte_lcore.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memcpy.h>
#include <rte_memory.h>
#include <rte_pci.h>
#include <rte_bus_vdev.h>
#include <rte_ethdev_driver.h>
#include <rte_event_eth_rx_adapter.h>

#include <fslmc_vfio.h>
#include <dpaa2_hw_pvt.h>
#include <dpaa2_hw_mempool.h>
#include <dpaa2_hw_dpio.h>
#include <dpaa2_ethdev.h>
#include "dpaa2_eventdev.h"
#include "dpaa2_eventdev_logs.h"
#include <portal/dpaa2_hw_pvt.h>
#include <mc/fsl_dpci.h>

/* Clarifications
 * Evendev = SoC Instance
 * Eventport = DPIO Instance
 * Eventqueue = DPCON Instance
 * 1 Eventdev can have N Eventqueue
 * Soft Event Flow is DPCI Instance
 */

/* Dynamic logging identified for mempool */
int dpaa2_logtype_event;

static uint16_t
dpaa2_eventdev_enqueue_burst(void *port, const struct rte_event ev[],
			     uint16_t nb_events)
{
	struct rte_eventdev *ev_dev =
			((struct dpaa2_io_portal_t *)port)->eventdev;
	struct dpaa2_eventdev *priv = ev_dev->data->dev_private;
	uint32_t queue_id = ev[0].queue_id;
	struct evq_info_t *evq_info = &priv->evq_info[queue_id];
	uint32_t fqid;
	struct qbman_swp *swp;
	struct qbman_fd fd_arr[MAX_TX_RING_SLOTS];
	uint32_t loop, frames_to_send;
	struct qbman_eq_desc eqdesc[MAX_TX_RING_SLOTS];
	uint16_t num_tx = 0;
	int ret;

	RTE_SET_USED(port);

	if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
		ret = dpaa2_affine_qbman_swp();
		if (ret) {
			DPAA2_EVENTDEV_ERR("Failure in affining portal");
			return 0;
		}
	}

	swp = DPAA2_PER_LCORE_PORTAL;

	while (nb_events) {
		frames_to_send = (nb_events >> 3) ?
			MAX_TX_RING_SLOTS : nb_events;

		for (loop = 0; loop < frames_to_send; loop++) {
			const struct rte_event *event = &ev[num_tx + loop];

			if (event->sched_type != RTE_SCHED_TYPE_ATOMIC)
				fqid = evq_info->dpci->rx_queue[
					DPAA2_EVENT_DPCI_PARALLEL_QUEUE].fqid;
			else
				fqid = evq_info->dpci->rx_queue[
					DPAA2_EVENT_DPCI_ATOMIC_QUEUE].fqid;

			/* Prepare enqueue descriptor */
			qbman_eq_desc_clear(&eqdesc[loop]);
			qbman_eq_desc_set_fq(&eqdesc[loop], fqid);
			qbman_eq_desc_set_no_orp(&eqdesc[loop], 0);
			qbman_eq_desc_set_response(&eqdesc[loop], 0, 0);

			if (event->mbuf->seqn) {
				uint8_t dqrr_index = event->mbuf->seqn - 1;

				qbman_eq_desc_set_dca(&eqdesc[loop], 1,
						      dqrr_index, 0);
				DPAA2_PER_LCORE_DQRR_SIZE--;
				DPAA2_PER_LCORE_DQRR_HELD &=
					~(1 << dqrr_index);
			}

			memset(&fd_arr[loop], 0, sizeof(struct qbman_fd));

			/*
			 * todo - need to align with hw context data
			 * to avoid copy
			 */
			struct rte_event *ev_temp = rte_malloc(NULL,
				sizeof(struct rte_event), 0);

			if (!ev_temp) {
				if (!loop)
					return num_tx;
				frames_to_send = loop;
				DPAA2_EVENTDEV_ERR(
					"Unable to allocate event object");
				goto send_partial;
			}
			rte_memcpy(ev_temp, event, sizeof(struct rte_event));
			DPAA2_SET_FD_ADDR((&fd_arr[loop]), (size_t)ev_temp);
			DPAA2_SET_FD_LEN((&fd_arr[loop]),
					 sizeof(struct rte_event));
		}
send_partial:
		loop = 0;
		while (loop < frames_to_send) {
			loop += qbman_swp_enqueue_multiple_desc(swp,
					&eqdesc[loop], &fd_arr[loop],
					frames_to_send - loop);
		}
		num_tx += frames_to_send;
		nb_events -= frames_to_send;
	}

	return num_tx;
}

static uint16_t
dpaa2_eventdev_enqueue(void *port, const struct rte_event *ev)
{
	return dpaa2_eventdev_enqueue_burst(port, ev, 1);
}

static void dpaa2_eventdev_dequeue_wait(uint64_t timeout_ticks)
{
	struct epoll_event epoll_ev;

	qbman_swp_interrupt_clear_status(DPAA2_PER_LCORE_PORTAL,
					 QBMAN_SWP_INTERRUPT_DQRI);

	epoll_wait(DPAA2_PER_LCORE_DPIO->epoll_fd,
			 &epoll_ev, 1, timeout_ticks);
}

static void dpaa2_eventdev_process_parallel(struct qbman_swp *swp,
					    const struct qbman_fd *fd,
					    const struct qbman_result *dq,
					    struct dpaa2_queue *rxq,
					    struct rte_event *ev)
{
	struct rte_event *ev_temp =
		(struct rte_event *)(size_t)DPAA2_GET_FD_ADDR(fd);

{'fraction_non_alphanumeric': 0.11852996358017878, 'fraction_numerical': 0.016223374903432293, 'mean_word_length': 4.387633769322235, 'pattern_counts': {'":': 0, '<': 72, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '507233', 'n_tokens_mistral': 4361, 'n_tokens_neox': 3899, 'n_words': 709}