xref: /dpdk/drivers/event/opdl/opdl_evdev_init.c (revision 4851ef2b40bc31accfffc3bb476930a73f50afac)
1e07a3ed7SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2e07a3ed7SBruce Richardson  * Copyright(c) 2017 Intel Corporation
33c7f3dcfSLiang Ma  */
43c7f3dcfSLiang Ma 
53c7f3dcfSLiang Ma #include <inttypes.h>
63c7f3dcfSLiang Ma #include <string.h>
73c7f3dcfSLiang Ma 
8*4851ef2bSDavid Marchand #include <bus_vdev_driver.h>
93c7f3dcfSLiang Ma #include <rte_errno.h>
103c7f3dcfSLiang Ma #include <rte_cycles.h>
113c7f3dcfSLiang Ma #include <rte_memzone.h>
123c7f3dcfSLiang Ma 
133c7f3dcfSLiang Ma #include "opdl_evdev.h"
143c7f3dcfSLiang Ma #include "opdl_ring.h"
153c7f3dcfSLiang Ma #include "opdl_log.h"
163c7f3dcfSLiang Ma 
173c7f3dcfSLiang Ma 
183c7f3dcfSLiang Ma static __rte_always_inline uint32_t
enqueue_check(struct opdl_port * p,const struct rte_event ev[],uint16_t num,uint16_t num_events)193c7f3dcfSLiang Ma enqueue_check(struct opdl_port *p,
203c7f3dcfSLiang Ma 		const struct rte_event ev[],
213c7f3dcfSLiang Ma 		uint16_t num,
223c7f3dcfSLiang Ma 		uint16_t num_events)
233c7f3dcfSLiang Ma {
243c7f3dcfSLiang Ma 	uint16_t i;
253c7f3dcfSLiang Ma 
263c7f3dcfSLiang Ma 	if (p->opdl->do_validation) {
273c7f3dcfSLiang Ma 
283c7f3dcfSLiang Ma 		for (i = 0; i < num; i++) {
293c7f3dcfSLiang Ma 			if (ev[i].queue_id != p->next_external_qid) {
303c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
313c7f3dcfSLiang Ma 					     "ERROR - port:[%u] - event wants"
323c7f3dcfSLiang Ma 					     " to enq to q_id[%u],"
333c7f3dcfSLiang Ma 					     " but should be [%u]",
343c7f3dcfSLiang Ma 					     opdl_pmd_dev_id(p->opdl),
353c7f3dcfSLiang Ma 					     p->id,
363c7f3dcfSLiang Ma 					     ev[i].queue_id,
373c7f3dcfSLiang Ma 					     p->next_external_qid);
38db8bdaecSDilshod Urazov 				rte_errno = EINVAL;
393c7f3dcfSLiang Ma 				return 0;
403c7f3dcfSLiang Ma 			}
413c7f3dcfSLiang Ma 		}
423c7f3dcfSLiang Ma 
433c7f3dcfSLiang Ma 		/* Stats */
443c7f3dcfSLiang Ma 		if (p->p_type == OPDL_PURE_RX_PORT ||
453c7f3dcfSLiang Ma 				p->p_type == OPDL_ASYNC_PORT) {
463c7f3dcfSLiang Ma 			/* Stats */
473c7f3dcfSLiang Ma 			if (num_events) {
483c7f3dcfSLiang Ma 				p->port_stat[claim_pkts_requested] += num;
493c7f3dcfSLiang Ma 				p->port_stat[claim_pkts_granted] += num_events;
503c7f3dcfSLiang Ma 				p->port_stat[claim_non_empty]++;
513c7f3dcfSLiang Ma 				p->start_cycles = rte_rdtsc();
523c7f3dcfSLiang Ma 			} else {
533c7f3dcfSLiang Ma 				p->port_stat[claim_empty]++;
543c7f3dcfSLiang Ma 				p->start_cycles = 0;
553c7f3dcfSLiang Ma 			}
563c7f3dcfSLiang Ma 		} else {
573c7f3dcfSLiang Ma 			if (p->start_cycles) {
583c7f3dcfSLiang Ma 				uint64_t end_cycles = rte_rdtsc();
593c7f3dcfSLiang Ma 				p->port_stat[total_cycles] +=
603c7f3dcfSLiang Ma 					end_cycles - p->start_cycles;
613c7f3dcfSLiang Ma 			}
623c7f3dcfSLiang Ma 		}
633c7f3dcfSLiang Ma 	} else {
643c7f3dcfSLiang Ma 		if (num > 0 &&
653c7f3dcfSLiang Ma 				ev[0].queue_id != p->next_external_qid) {
66db8bdaecSDilshod Urazov 			rte_errno = EINVAL;
673c7f3dcfSLiang Ma 			return 0;
683c7f3dcfSLiang Ma 		}
693c7f3dcfSLiang Ma 	}
703c7f3dcfSLiang Ma 
713c7f3dcfSLiang Ma 	return num;
723c7f3dcfSLiang Ma }
733c7f3dcfSLiang Ma 
743c7f3dcfSLiang Ma static __rte_always_inline void
update_on_dequeue(struct opdl_port * p,struct rte_event ev[],uint16_t num,uint16_t num_events)753c7f3dcfSLiang Ma update_on_dequeue(struct opdl_port *p,
763c7f3dcfSLiang Ma 		struct rte_event ev[],
773c7f3dcfSLiang Ma 		uint16_t num,
783c7f3dcfSLiang Ma 		uint16_t num_events)
793c7f3dcfSLiang Ma {
803c7f3dcfSLiang Ma 	if (p->opdl->do_validation) {
813c7f3dcfSLiang Ma 		int16_t i;
823c7f3dcfSLiang Ma 		for (i = 0; i < num; i++)
833c7f3dcfSLiang Ma 			ev[i].queue_id =
843c7f3dcfSLiang Ma 				p->opdl->queue[p->queue_id].external_qid;
853c7f3dcfSLiang Ma 
863c7f3dcfSLiang Ma 		/* Stats */
873c7f3dcfSLiang Ma 		if (num_events) {
883c7f3dcfSLiang Ma 			p->port_stat[claim_pkts_requested] += num;
893c7f3dcfSLiang Ma 			p->port_stat[claim_pkts_granted] += num_events;
903c7f3dcfSLiang Ma 			p->port_stat[claim_non_empty]++;
913c7f3dcfSLiang Ma 			p->start_cycles = rte_rdtsc();
923c7f3dcfSLiang Ma 		} else {
933c7f3dcfSLiang Ma 			p->port_stat[claim_empty]++;
943c7f3dcfSLiang Ma 			p->start_cycles = 0;
953c7f3dcfSLiang Ma 		}
963c7f3dcfSLiang Ma 	} else {
973c7f3dcfSLiang Ma 		if (num > 0)
983c7f3dcfSLiang Ma 			ev[0].queue_id =
993c7f3dcfSLiang Ma 				p->opdl->queue[p->queue_id].external_qid;
1003c7f3dcfSLiang Ma 	}
1013c7f3dcfSLiang Ma }
1023c7f3dcfSLiang Ma 
1033c7f3dcfSLiang Ma 
1043c7f3dcfSLiang Ma /*
1053c7f3dcfSLiang Ma  * Error RX enqueue:
1063c7f3dcfSLiang Ma  *
1073c7f3dcfSLiang Ma  *
1083c7f3dcfSLiang Ma  */
1093c7f3dcfSLiang Ma 
1103c7f3dcfSLiang Ma static uint16_t
opdl_rx_error_enqueue(struct opdl_port * p,const struct rte_event ev[],uint16_t num)1113c7f3dcfSLiang Ma opdl_rx_error_enqueue(struct opdl_port *p,
1123c7f3dcfSLiang Ma 		const struct rte_event ev[],
1133c7f3dcfSLiang Ma 		uint16_t num)
1143c7f3dcfSLiang Ma {
1153c7f3dcfSLiang Ma 	RTE_SET_USED(p);
1163c7f3dcfSLiang Ma 	RTE_SET_USED(ev);
1173c7f3dcfSLiang Ma 	RTE_SET_USED(num);
1183c7f3dcfSLiang Ma 
119db8bdaecSDilshod Urazov 	rte_errno = ENOSPC;
1203c7f3dcfSLiang Ma 
1213c7f3dcfSLiang Ma 	return 0;
1223c7f3dcfSLiang Ma }
1233c7f3dcfSLiang Ma 
1243c7f3dcfSLiang Ma /*
1253c7f3dcfSLiang Ma  * RX enqueue:
1263c7f3dcfSLiang Ma  *
1273c7f3dcfSLiang Ma  * This function handles enqueue for a single input stage_inst with
1283c7f3dcfSLiang Ma  *	threadsafe disabled or enabled. eg 1 thread using a stage_inst or
1293c7f3dcfSLiang Ma  *	multiple threads sharing a stage_inst
1303c7f3dcfSLiang Ma  */
1313c7f3dcfSLiang Ma 
1323c7f3dcfSLiang Ma static uint16_t
opdl_rx_enqueue(struct opdl_port * p,const struct rte_event ev[],uint16_t num)1333c7f3dcfSLiang Ma opdl_rx_enqueue(struct opdl_port *p,
1343c7f3dcfSLiang Ma 		const struct rte_event ev[],
1353c7f3dcfSLiang Ma 		uint16_t num)
1363c7f3dcfSLiang Ma {
1373c7f3dcfSLiang Ma 	uint16_t enqueued = 0;
1383c7f3dcfSLiang Ma 
1393c7f3dcfSLiang Ma 	enqueued = opdl_ring_input(opdl_stage_get_opdl_ring(p->enq_stage_inst),
1403c7f3dcfSLiang Ma 				   ev,
1413c7f3dcfSLiang Ma 				   num,
1423c7f3dcfSLiang Ma 				   false);
1433c7f3dcfSLiang Ma 	if (!enqueue_check(p, ev, num, enqueued))
1443c7f3dcfSLiang Ma 		return 0;
1453c7f3dcfSLiang Ma 
1463c7f3dcfSLiang Ma 
1473c7f3dcfSLiang Ma 	if (enqueued < num)
148db8bdaecSDilshod Urazov 		rte_errno = ENOSPC;
1493c7f3dcfSLiang Ma 
1503c7f3dcfSLiang Ma 	return enqueued;
1513c7f3dcfSLiang Ma }
1523c7f3dcfSLiang Ma 
1533c7f3dcfSLiang Ma /*
1543c7f3dcfSLiang Ma  * Error TX handler
1553c7f3dcfSLiang Ma  *
1563c7f3dcfSLiang Ma  */
1573c7f3dcfSLiang Ma 
1583c7f3dcfSLiang Ma static uint16_t
opdl_tx_error_dequeue(struct opdl_port * p,struct rte_event ev[],uint16_t num)1593c7f3dcfSLiang Ma opdl_tx_error_dequeue(struct opdl_port *p,
1603c7f3dcfSLiang Ma 		struct rte_event ev[],
1613c7f3dcfSLiang Ma 		uint16_t num)
1623c7f3dcfSLiang Ma {
1633c7f3dcfSLiang Ma 	RTE_SET_USED(p);
1643c7f3dcfSLiang Ma 	RTE_SET_USED(ev);
1653c7f3dcfSLiang Ma 	RTE_SET_USED(num);
1663c7f3dcfSLiang Ma 
167db8bdaecSDilshod Urazov 	rte_errno = ENOSPC;
1683c7f3dcfSLiang Ma 
1693c7f3dcfSLiang Ma 	return 0;
1703c7f3dcfSLiang Ma }
1713c7f3dcfSLiang Ma 
1723c7f3dcfSLiang Ma /*
1733c7f3dcfSLiang Ma  * TX single threaded claim
1743c7f3dcfSLiang Ma  *
1753c7f3dcfSLiang Ma  * This function handles dequeue for a single worker stage_inst with
1763c7f3dcfSLiang Ma  *	threadsafe disabled. eg 1 thread using an stage_inst
1773c7f3dcfSLiang Ma  */
1783c7f3dcfSLiang Ma 
1793c7f3dcfSLiang Ma static uint16_t
opdl_tx_dequeue_single_thread(struct opdl_port * p,struct rte_event ev[],uint16_t num)1803c7f3dcfSLiang Ma opdl_tx_dequeue_single_thread(struct opdl_port *p,
1813c7f3dcfSLiang Ma 			struct rte_event ev[],
1823c7f3dcfSLiang Ma 			uint16_t num)
1833c7f3dcfSLiang Ma {
1843c7f3dcfSLiang Ma 	uint16_t returned;
1853c7f3dcfSLiang Ma 
1863c7f3dcfSLiang Ma 	struct opdl_ring  *ring;
1873c7f3dcfSLiang Ma 
1883c7f3dcfSLiang Ma 	ring = opdl_stage_get_opdl_ring(p->deq_stage_inst);
1893c7f3dcfSLiang Ma 
1903c7f3dcfSLiang Ma 	returned = opdl_ring_copy_to_burst(ring,
1913c7f3dcfSLiang Ma 					   p->deq_stage_inst,
1923c7f3dcfSLiang Ma 					   ev,
1933c7f3dcfSLiang Ma 					   num,
1943c7f3dcfSLiang Ma 					   false);
1953c7f3dcfSLiang Ma 
1963c7f3dcfSLiang Ma 	update_on_dequeue(p, ev, num, returned);
1973c7f3dcfSLiang Ma 
1983c7f3dcfSLiang Ma 	return returned;
1993c7f3dcfSLiang Ma }
2003c7f3dcfSLiang Ma 
2013c7f3dcfSLiang Ma /*
2023c7f3dcfSLiang Ma  * TX multi threaded claim
2033c7f3dcfSLiang Ma  *
2043c7f3dcfSLiang Ma  * This function handles dequeue for multiple worker stage_inst with
2053c7f3dcfSLiang Ma  *	threadsafe disabled. eg multiple stage_inst each with its own instance
2063c7f3dcfSLiang Ma  */
2073c7f3dcfSLiang Ma 
2083c7f3dcfSLiang Ma static uint16_t
opdl_tx_dequeue_multi_inst(struct opdl_port * p,struct rte_event ev[],uint16_t num)2093c7f3dcfSLiang Ma opdl_tx_dequeue_multi_inst(struct opdl_port *p,
2103c7f3dcfSLiang Ma 			struct rte_event ev[],
2113c7f3dcfSLiang Ma 			uint16_t num)
2123c7f3dcfSLiang Ma {
2133c7f3dcfSLiang Ma 	uint32_t num_events = 0;
2143c7f3dcfSLiang Ma 
2153c7f3dcfSLiang Ma 	num_events = opdl_stage_claim(p->deq_stage_inst,
2163c7f3dcfSLiang Ma 				    (void *)ev,
2173c7f3dcfSLiang Ma 				    num,
2183c7f3dcfSLiang Ma 				    NULL,
2193c7f3dcfSLiang Ma 				    false,
2203c7f3dcfSLiang Ma 				    false);
2213c7f3dcfSLiang Ma 
2223c7f3dcfSLiang Ma 	update_on_dequeue(p, ev, num, num_events);
2233c7f3dcfSLiang Ma 
2243c7f3dcfSLiang Ma 	return opdl_stage_disclaim(p->deq_stage_inst, num_events, false);
2253c7f3dcfSLiang Ma }
2263c7f3dcfSLiang Ma 
2273c7f3dcfSLiang Ma 
2283c7f3dcfSLiang Ma /*
2293c7f3dcfSLiang Ma  * Worker thread claim
2303c7f3dcfSLiang Ma  *
2313c7f3dcfSLiang Ma  */
2323c7f3dcfSLiang Ma 
2333c7f3dcfSLiang Ma static uint16_t
opdl_claim(struct opdl_port * p,struct rte_event ev[],uint16_t num)2343c7f3dcfSLiang Ma opdl_claim(struct opdl_port *p, struct rte_event ev[], uint16_t num)
2353c7f3dcfSLiang Ma {
2363c7f3dcfSLiang Ma 	uint32_t num_events = 0;
2373c7f3dcfSLiang Ma 
2383c7f3dcfSLiang Ma 	if (unlikely(num > MAX_OPDL_CONS_Q_DEPTH)) {
2393c7f3dcfSLiang Ma 		PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
2403c7f3dcfSLiang Ma 			     "Attempt to dequeue num of events larger than port (%d) max",
2413c7f3dcfSLiang Ma 			     opdl_pmd_dev_id(p->opdl),
2423c7f3dcfSLiang Ma 			     p->id);
243db8bdaecSDilshod Urazov 		rte_errno = EINVAL;
2443c7f3dcfSLiang Ma 		return 0;
2453c7f3dcfSLiang Ma 	}
2463c7f3dcfSLiang Ma 
2473c7f3dcfSLiang Ma 
2483c7f3dcfSLiang Ma 	num_events = opdl_stage_claim(p->deq_stage_inst,
2493c7f3dcfSLiang Ma 			(void *)ev,
2503c7f3dcfSLiang Ma 			num,
2513c7f3dcfSLiang Ma 			NULL,
2523c7f3dcfSLiang Ma 			false,
2533c7f3dcfSLiang Ma 			p->atomic_claim);
2543c7f3dcfSLiang Ma 
2553c7f3dcfSLiang Ma 
2563c7f3dcfSLiang Ma 	update_on_dequeue(p, ev, num, num_events);
2573c7f3dcfSLiang Ma 
2583c7f3dcfSLiang Ma 	return num_events;
2593c7f3dcfSLiang Ma }
2603c7f3dcfSLiang Ma 
2613c7f3dcfSLiang Ma /*
2623c7f3dcfSLiang Ma  * Worker thread disclaim
2633c7f3dcfSLiang Ma  */
2643c7f3dcfSLiang Ma 
2653c7f3dcfSLiang Ma static uint16_t
opdl_disclaim(struct opdl_port * p,const struct rte_event ev[],uint16_t num)2663c7f3dcfSLiang Ma opdl_disclaim(struct opdl_port *p, const struct rte_event ev[], uint16_t num)
2673c7f3dcfSLiang Ma {
2683c7f3dcfSLiang Ma 	uint16_t enqueued = 0;
2693c7f3dcfSLiang Ma 
2703c7f3dcfSLiang Ma 	uint32_t i = 0;
2713c7f3dcfSLiang Ma 
2723c7f3dcfSLiang Ma 	for (i = 0; i < num; i++)
2733c7f3dcfSLiang Ma 		opdl_ring_cas_slot(p->enq_stage_inst, &ev[i],
2743c7f3dcfSLiang Ma 				i, p->atomic_claim);
2753c7f3dcfSLiang Ma 
2763c7f3dcfSLiang Ma 	enqueued = opdl_stage_disclaim(p->enq_stage_inst,
2773c7f3dcfSLiang Ma 				       num,
2783c7f3dcfSLiang Ma 				       false);
2793c7f3dcfSLiang Ma 
2803c7f3dcfSLiang Ma 	return enqueue_check(p, ev, num, enqueued);
2813c7f3dcfSLiang Ma }
2823c7f3dcfSLiang Ma 
2833c7f3dcfSLiang Ma static __rte_always_inline struct opdl_stage *
stage_for_port(struct opdl_queue * q,unsigned int i)2843c7f3dcfSLiang Ma stage_for_port(struct opdl_queue *q, unsigned int i)
2853c7f3dcfSLiang Ma {
2863c7f3dcfSLiang Ma 	if (q->q_pos == OPDL_Q_POS_START || q->q_pos == OPDL_Q_POS_MIDDLE)
2873c7f3dcfSLiang Ma 		return q->ports[i]->enq_stage_inst;
2883c7f3dcfSLiang Ma 	else
2893c7f3dcfSLiang Ma 		return q->ports[i]->deq_stage_inst;
2903c7f3dcfSLiang Ma }
2913c7f3dcfSLiang Ma 
opdl_add_deps(struct opdl_evdev * device,int q_id,int deps_q_id)2923c7f3dcfSLiang Ma static int opdl_add_deps(struct opdl_evdev *device,
2933c7f3dcfSLiang Ma 			 int q_id,
2943c7f3dcfSLiang Ma 			 int deps_q_id)
2953c7f3dcfSLiang Ma {
2963c7f3dcfSLiang Ma 	unsigned int i, j;
2973c7f3dcfSLiang Ma 	int status;
2983c7f3dcfSLiang Ma 	struct opdl_ring  *ring;
2993c7f3dcfSLiang Ma 	struct opdl_queue *queue = &device->queue[q_id];
3003c7f3dcfSLiang Ma 	struct opdl_queue *queue_deps = &device->queue[deps_q_id];
3013c7f3dcfSLiang Ma 	struct opdl_stage *dep_stages[OPDL_PORTS_MAX];
3023c7f3dcfSLiang Ma 
3033c7f3dcfSLiang Ma 	/* sanity check that all stages are for same opdl ring */
3043c7f3dcfSLiang Ma 	for (i = 0; i < queue->nb_ports; i++) {
3053c7f3dcfSLiang Ma 		struct opdl_ring *r =
3063c7f3dcfSLiang Ma 			opdl_stage_get_opdl_ring(stage_for_port(queue, i));
3073c7f3dcfSLiang Ma 		for (j = 0; j < queue_deps->nb_ports; j++) {
3083c7f3dcfSLiang Ma 			struct opdl_ring *rj =
3093c7f3dcfSLiang Ma 				opdl_stage_get_opdl_ring(
3103c7f3dcfSLiang Ma 						stage_for_port(queue_deps, j));
3113c7f3dcfSLiang Ma 			if (r != rj) {
3123c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
3133c7f3dcfSLiang Ma 					     "Stages and dependents"
3143c7f3dcfSLiang Ma 					     " are not for same opdl ring",
3153c7f3dcfSLiang Ma 					     opdl_pmd_dev_id(device));
316be455196SHarry van Haaren 				uint32_t k;
317be455196SHarry van Haaren 				for (k = 0; k < device->nb_opdls; k++) {
3183c7f3dcfSLiang Ma 					opdl_ring_dump(device->opdl[k],
3193c7f3dcfSLiang Ma 							stdout);
3203c7f3dcfSLiang Ma 				}
3213c7f3dcfSLiang Ma 				return -EINVAL;
3223c7f3dcfSLiang Ma 			}
3233c7f3dcfSLiang Ma 		}
3243c7f3dcfSLiang Ma 	}
3253c7f3dcfSLiang Ma 
3263c7f3dcfSLiang Ma 	/* Gather all stages instance in deps */
3273c7f3dcfSLiang Ma 	for (i = 0; i < queue_deps->nb_ports; i++)
3283c7f3dcfSLiang Ma 		dep_stages[i] = stage_for_port(queue_deps, i);
3293c7f3dcfSLiang Ma 
3303c7f3dcfSLiang Ma 
3313c7f3dcfSLiang Ma 	/* Add all deps for each port->stage_inst in this queue */
3323c7f3dcfSLiang Ma 	for (i = 0; i < queue->nb_ports; i++) {
3333c7f3dcfSLiang Ma 
3343c7f3dcfSLiang Ma 		ring = opdl_stage_get_opdl_ring(stage_for_port(queue, i));
3353c7f3dcfSLiang Ma 
3363c7f3dcfSLiang Ma 		status = opdl_stage_deps_add(ring,
3373c7f3dcfSLiang Ma 				stage_for_port(queue, i),
3383c7f3dcfSLiang Ma 				queue->ports[i]->num_instance,
3393c7f3dcfSLiang Ma 				queue->ports[i]->instance_id,
3403c7f3dcfSLiang Ma 				dep_stages,
3413c7f3dcfSLiang Ma 				queue_deps->nb_ports);
3423c7f3dcfSLiang Ma 		if (status < 0)
3433c7f3dcfSLiang Ma 			return -EINVAL;
3443c7f3dcfSLiang Ma 	}
3453c7f3dcfSLiang Ma 
3463c7f3dcfSLiang Ma 	return 0;
3473c7f3dcfSLiang Ma }
3483c7f3dcfSLiang Ma 
3493c7f3dcfSLiang Ma int
opdl_add_event_handlers(struct rte_eventdev * dev)3503c7f3dcfSLiang Ma opdl_add_event_handlers(struct rte_eventdev *dev)
3513c7f3dcfSLiang Ma {
3523c7f3dcfSLiang Ma 	int err = 0;
3533c7f3dcfSLiang Ma 
3543c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
3553c7f3dcfSLiang Ma 	unsigned int i;
3563c7f3dcfSLiang Ma 
3573c7f3dcfSLiang Ma 	for (i = 0; i < device->max_port_nb; i++) {
3583c7f3dcfSLiang Ma 
3593c7f3dcfSLiang Ma 		struct opdl_port *port = &device->ports[i];
3603c7f3dcfSLiang Ma 
3613c7f3dcfSLiang Ma 		if (port->configured) {
3623c7f3dcfSLiang Ma 			if (port->p_type == OPDL_PURE_RX_PORT) {
3633c7f3dcfSLiang Ma 				port->enq = opdl_rx_enqueue;
3643c7f3dcfSLiang Ma 				port->deq = opdl_tx_error_dequeue;
3653c7f3dcfSLiang Ma 
3663c7f3dcfSLiang Ma 			} else if (port->p_type == OPDL_PURE_TX_PORT) {
3673c7f3dcfSLiang Ma 
3683c7f3dcfSLiang Ma 				port->enq = opdl_rx_error_enqueue;
3693c7f3dcfSLiang Ma 
3703c7f3dcfSLiang Ma 				if (port->num_instance == 1)
3713c7f3dcfSLiang Ma 					port->deq =
3723c7f3dcfSLiang Ma 						opdl_tx_dequeue_single_thread;
3733c7f3dcfSLiang Ma 				else
3743c7f3dcfSLiang Ma 					port->deq = opdl_tx_dequeue_multi_inst;
3753c7f3dcfSLiang Ma 
3763c7f3dcfSLiang Ma 			} else if (port->p_type == OPDL_REGULAR_PORT) {
3773c7f3dcfSLiang Ma 
3783c7f3dcfSLiang Ma 				port->enq = opdl_disclaim;
3793c7f3dcfSLiang Ma 				port->deq = opdl_claim;
3803c7f3dcfSLiang Ma 
3813c7f3dcfSLiang Ma 			} else if (port->p_type == OPDL_ASYNC_PORT) {
3823c7f3dcfSLiang Ma 
3833c7f3dcfSLiang Ma 				port->enq = opdl_rx_enqueue;
3843c7f3dcfSLiang Ma 
3853c7f3dcfSLiang Ma 				/* Always single instance */
3863c7f3dcfSLiang Ma 				port->deq = opdl_tx_dequeue_single_thread;
3873c7f3dcfSLiang Ma 			} else {
3883c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
3893c7f3dcfSLiang Ma 					     "port:[%u] has invalid port type - ",
3903c7f3dcfSLiang Ma 					     opdl_pmd_dev_id(port->opdl),
3913c7f3dcfSLiang Ma 					     port->id);
3923c7f3dcfSLiang Ma 				err = -EINVAL;
3933c7f3dcfSLiang Ma 				break;
3943c7f3dcfSLiang Ma 			}
3953c7f3dcfSLiang Ma 			port->initialized = 1;
3963c7f3dcfSLiang Ma 		}
3973c7f3dcfSLiang Ma 	}
3983c7f3dcfSLiang Ma 
3993c7f3dcfSLiang Ma 	if (!err)
4003c7f3dcfSLiang Ma 		fprintf(stdout, "Success - enqueue/dequeue handler(s) added\n");
4013c7f3dcfSLiang Ma 	return err;
4023c7f3dcfSLiang Ma }
4033c7f3dcfSLiang Ma 
4043c7f3dcfSLiang Ma int
build_all_dependencies(struct rte_eventdev * dev)4053c7f3dcfSLiang Ma build_all_dependencies(struct rte_eventdev *dev)
4063c7f3dcfSLiang Ma {
4073c7f3dcfSLiang Ma 
4083c7f3dcfSLiang Ma 	int err = 0;
4093c7f3dcfSLiang Ma 	unsigned int i;
4103c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
4113c7f3dcfSLiang Ma 
4123c7f3dcfSLiang Ma 	uint8_t start_qid = 0;
4133c7f3dcfSLiang Ma 
4143c7f3dcfSLiang Ma 	for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
4153c7f3dcfSLiang Ma 		struct opdl_queue *queue = &device->queue[i];
4163c7f3dcfSLiang Ma 		if (!queue->initialized)
4173c7f3dcfSLiang Ma 			break;
4183c7f3dcfSLiang Ma 
4193c7f3dcfSLiang Ma 		if (queue->q_pos == OPDL_Q_POS_START) {
4203c7f3dcfSLiang Ma 			start_qid = i;
4213c7f3dcfSLiang Ma 			continue;
4223c7f3dcfSLiang Ma 		}
4233c7f3dcfSLiang Ma 
4243c7f3dcfSLiang Ma 		if (queue->q_pos == OPDL_Q_POS_MIDDLE) {
4253c7f3dcfSLiang Ma 			err = opdl_add_deps(device, i, i-1);
4263c7f3dcfSLiang Ma 			if (err < 0) {
4273c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
4283c7f3dcfSLiang Ma 					     "dependency addition for queue:[%u] - FAILED",
4293c7f3dcfSLiang Ma 					     dev->data->dev_id,
4303c7f3dcfSLiang Ma 					     queue->external_qid);
4313c7f3dcfSLiang Ma 				break;
4323c7f3dcfSLiang Ma 			}
4333c7f3dcfSLiang Ma 		}
4343c7f3dcfSLiang Ma 
4353c7f3dcfSLiang Ma 		if (queue->q_pos == OPDL_Q_POS_END) {
4363c7f3dcfSLiang Ma 			/* Add this dependency */
4373c7f3dcfSLiang Ma 			err = opdl_add_deps(device, i, i-1);
4383c7f3dcfSLiang Ma 			if (err < 0) {
4393c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
4403c7f3dcfSLiang Ma 					     "dependency addition for queue:[%u] - FAILED",
4413c7f3dcfSLiang Ma 					     dev->data->dev_id,
4423c7f3dcfSLiang Ma 					     queue->external_qid);
4433c7f3dcfSLiang Ma 				break;
4443c7f3dcfSLiang Ma 			}
4453c7f3dcfSLiang Ma 			/* Add dependency for rx on tx */
4463c7f3dcfSLiang Ma 			err = opdl_add_deps(device, start_qid, i);
4473c7f3dcfSLiang Ma 			if (err < 0) {
4483c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
4493c7f3dcfSLiang Ma 					     "dependency addition for queue:[%u] - FAILED",
4503c7f3dcfSLiang Ma 					     dev->data->dev_id,
4513c7f3dcfSLiang Ma 					     queue->external_qid);
4523c7f3dcfSLiang Ma 				break;
4533c7f3dcfSLiang Ma 			}
4543c7f3dcfSLiang Ma 		}
4553c7f3dcfSLiang Ma 	}
4563c7f3dcfSLiang Ma 
4573c7f3dcfSLiang Ma 	if (!err)
4583c7f3dcfSLiang Ma 		fprintf(stdout, "Success - dependencies built\n");
4593c7f3dcfSLiang Ma 
4603c7f3dcfSLiang Ma 	return err;
4613c7f3dcfSLiang Ma }
4623c7f3dcfSLiang Ma int
check_queues_linked(struct rte_eventdev * dev)4633c7f3dcfSLiang Ma check_queues_linked(struct rte_eventdev *dev)
4643c7f3dcfSLiang Ma {
4653c7f3dcfSLiang Ma 
4663c7f3dcfSLiang Ma 	int err = 0;
4673c7f3dcfSLiang Ma 	unsigned int i;
4683c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
4693c7f3dcfSLiang Ma 	uint32_t nb_iq = 0;
4703c7f3dcfSLiang Ma 
4713c7f3dcfSLiang Ma 	for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
4723c7f3dcfSLiang Ma 		struct opdl_queue *queue = &device->queue[i];
4733c7f3dcfSLiang Ma 
4743c7f3dcfSLiang Ma 		if (!queue->initialized)
4753c7f3dcfSLiang Ma 			break;
4763c7f3dcfSLiang Ma 
4773c7f3dcfSLiang Ma 		if (queue->external_qid == OPDL_INVALID_QID)
4783c7f3dcfSLiang Ma 			nb_iq++;
4793c7f3dcfSLiang Ma 
4803c7f3dcfSLiang Ma 		if (queue->nb_ports == 0) {
4813c7f3dcfSLiang Ma 			PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
4823c7f3dcfSLiang Ma 				     "queue:[%u] has no associated ports",
4833c7f3dcfSLiang Ma 				     dev->data->dev_id,
4843c7f3dcfSLiang Ma 				     i);
4853c7f3dcfSLiang Ma 			err = -EINVAL;
4863c7f3dcfSLiang Ma 			break;
4873c7f3dcfSLiang Ma 		}
4883c7f3dcfSLiang Ma 	}
4893c7f3dcfSLiang Ma 	if (!err) {
4903c7f3dcfSLiang Ma 		if ((i - nb_iq) != device->max_queue_nb) {
4913c7f3dcfSLiang Ma 			PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
4923c7f3dcfSLiang Ma 				     "%u queues counted but should be %u",
4933c7f3dcfSLiang Ma 				     dev->data->dev_id,
4943c7f3dcfSLiang Ma 				     i - nb_iq,
4953c7f3dcfSLiang Ma 				     device->max_queue_nb);
4963c7f3dcfSLiang Ma 			err = -1;
4973c7f3dcfSLiang Ma 		}
4983c7f3dcfSLiang Ma 
4993c7f3dcfSLiang Ma 	}
5003c7f3dcfSLiang Ma 	return err;
5013c7f3dcfSLiang Ma }
5023c7f3dcfSLiang Ma 
5033c7f3dcfSLiang Ma void
destroy_queues_and_rings(struct rte_eventdev * dev)5043c7f3dcfSLiang Ma destroy_queues_and_rings(struct rte_eventdev *dev)
5053c7f3dcfSLiang Ma {
5063c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
507be455196SHarry van Haaren 	uint32_t i;
5083c7f3dcfSLiang Ma 
509be455196SHarry van Haaren 	for (i = 0; i < device->nb_opdls; i++) {
5103c7f3dcfSLiang Ma 		if (device->opdl[i])
5113c7f3dcfSLiang Ma 			opdl_ring_free(device->opdl[i]);
5123c7f3dcfSLiang Ma 	}
5133c7f3dcfSLiang Ma 
5143c7f3dcfSLiang Ma 	memset(&device->queue,
5153c7f3dcfSLiang Ma 			0,
5163c7f3dcfSLiang Ma 			sizeof(struct opdl_queue)
5173c7f3dcfSLiang Ma 			* RTE_EVENT_MAX_QUEUES_PER_DEV);
5183c7f3dcfSLiang Ma }
5193c7f3dcfSLiang Ma 
5203c7f3dcfSLiang Ma #define OPDL_ID(d)(d->nb_opdls - 1)
5213c7f3dcfSLiang Ma 
5223c7f3dcfSLiang Ma static __rte_always_inline void
initialise_queue(struct opdl_evdev * device,enum queue_pos pos,int32_t i)5233c7f3dcfSLiang Ma initialise_queue(struct opdl_evdev *device,
5243c7f3dcfSLiang Ma 		enum queue_pos pos,
5253c7f3dcfSLiang Ma 		int32_t i)
5263c7f3dcfSLiang Ma {
5273c7f3dcfSLiang Ma 	struct opdl_queue *queue = &device->queue[device->nb_queues];
5283c7f3dcfSLiang Ma 
5293c7f3dcfSLiang Ma 	if (i == -1) {
5303c7f3dcfSLiang Ma 		queue->q_type = OPDL_Q_TYPE_ORDERED;
5313c7f3dcfSLiang Ma 		queue->external_qid = OPDL_INVALID_QID;
5323c7f3dcfSLiang Ma 	} else {
5333c7f3dcfSLiang Ma 		queue->q_type = device->q_md[i].type;
5343c7f3dcfSLiang Ma 		queue->external_qid = device->q_md[i].ext_id;
5353c7f3dcfSLiang Ma 		/* Add ex->in for queues setup */
5363c7f3dcfSLiang Ma 		device->q_map_ex_to_in[queue->external_qid] = device->nb_queues;
5373c7f3dcfSLiang Ma 	}
5383c7f3dcfSLiang Ma 	queue->opdl_id = OPDL_ID(device);
5393c7f3dcfSLiang Ma 	queue->q_pos = pos;
5403c7f3dcfSLiang Ma 	queue->nb_ports = 0;
5413c7f3dcfSLiang Ma 	queue->configured = 1;
5423c7f3dcfSLiang Ma 
5433c7f3dcfSLiang Ma 	device->nb_queues++;
5443c7f3dcfSLiang Ma }
5453c7f3dcfSLiang Ma 
5463c7f3dcfSLiang Ma 
5473c7f3dcfSLiang Ma static __rte_always_inline int
create_opdl(struct opdl_evdev * device)5483c7f3dcfSLiang Ma create_opdl(struct opdl_evdev *device)
5493c7f3dcfSLiang Ma {
5503c7f3dcfSLiang Ma 	int err = 0;
5513c7f3dcfSLiang Ma 
5523c7f3dcfSLiang Ma 	char name[RTE_MEMZONE_NAMESIZE];
5533c7f3dcfSLiang Ma 
5543c7f3dcfSLiang Ma 	snprintf(name, RTE_MEMZONE_NAMESIZE,
5553c7f3dcfSLiang Ma 			"%s_%u", device->service_name, device->nb_opdls);
5563c7f3dcfSLiang Ma 
5573c7f3dcfSLiang Ma 	device->opdl[device->nb_opdls] =
5583c7f3dcfSLiang Ma 		opdl_ring_create(name,
5593c7f3dcfSLiang Ma 				device->nb_events_limit,
5603c7f3dcfSLiang Ma 				sizeof(struct rte_event),
5613c7f3dcfSLiang Ma 				device->max_port_nb * 2,
5623c7f3dcfSLiang Ma 				device->socket);
5633c7f3dcfSLiang Ma 
5643c7f3dcfSLiang Ma 	if (!device->opdl[device->nb_opdls]) {
5653c7f3dcfSLiang Ma 		PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
5663c7f3dcfSLiang Ma 			     "opdl ring %u creation - FAILED",
5673c7f3dcfSLiang Ma 			     opdl_pmd_dev_id(device),
5683c7f3dcfSLiang Ma 			     device->nb_opdls);
5693c7f3dcfSLiang Ma 		err = -EINVAL;
5703c7f3dcfSLiang Ma 	} else {
5713c7f3dcfSLiang Ma 		device->nb_opdls++;
5723c7f3dcfSLiang Ma 	}
5733c7f3dcfSLiang Ma 	return err;
5743c7f3dcfSLiang Ma }
5753c7f3dcfSLiang Ma 
5763c7f3dcfSLiang Ma static __rte_always_inline int
create_link_opdl(struct opdl_evdev * device,uint32_t index)5773c7f3dcfSLiang Ma create_link_opdl(struct opdl_evdev *device, uint32_t index)
5783c7f3dcfSLiang Ma {
5793c7f3dcfSLiang Ma 
5803c7f3dcfSLiang Ma 	int err = 0;
5813c7f3dcfSLiang Ma 
5823c7f3dcfSLiang Ma 	if (device->q_md[index + 1].type !=
5833c7f3dcfSLiang Ma 			OPDL_Q_TYPE_SINGLE_LINK) {
5843c7f3dcfSLiang Ma 
5853c7f3dcfSLiang Ma 		/* async queue with regular
5863c7f3dcfSLiang Ma 		 * queue following it
5873c7f3dcfSLiang Ma 		 */
5883c7f3dcfSLiang Ma 
5893c7f3dcfSLiang Ma 		/* create a new opdl ring */
5903c7f3dcfSLiang Ma 		err = create_opdl(device);
5913c7f3dcfSLiang Ma 		if (!err) {
5923c7f3dcfSLiang Ma 			/* create an initial
5933c7f3dcfSLiang Ma 			 * dummy queue for new opdl
5943c7f3dcfSLiang Ma 			 */
5953c7f3dcfSLiang Ma 			initialise_queue(device,
5963c7f3dcfSLiang Ma 					OPDL_Q_POS_START,
5973c7f3dcfSLiang Ma 					-1);
5983c7f3dcfSLiang Ma 		} else {
5993c7f3dcfSLiang Ma 			err = -EINVAL;
6003c7f3dcfSLiang Ma 		}
6013c7f3dcfSLiang Ma 	} else {
6023c7f3dcfSLiang Ma 		PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
6033c7f3dcfSLiang Ma 			     "queue %u, two consecutive"
6043c7f3dcfSLiang Ma 			     " SINGLE_LINK queues, not allowed",
6053c7f3dcfSLiang Ma 			     opdl_pmd_dev_id(device),
6063c7f3dcfSLiang Ma 			     index);
6073c7f3dcfSLiang Ma 		err = -EINVAL;
6083c7f3dcfSLiang Ma 	}
6093c7f3dcfSLiang Ma 
6103c7f3dcfSLiang Ma 	return err;
6113c7f3dcfSLiang Ma }
6123c7f3dcfSLiang Ma 
6133c7f3dcfSLiang Ma int
create_queues_and_rings(struct rte_eventdev * dev)6143c7f3dcfSLiang Ma create_queues_and_rings(struct rte_eventdev *dev)
6153c7f3dcfSLiang Ma {
6163c7f3dcfSLiang Ma 	int err = 0;
6173c7f3dcfSLiang Ma 
6183c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
6193c7f3dcfSLiang Ma 
6203c7f3dcfSLiang Ma 	device->nb_queues = 0;
6213c7f3dcfSLiang Ma 
6223c7f3dcfSLiang Ma 	if (device->nb_ports != device->max_port_nb) {
6233c7f3dcfSLiang Ma 		PMD_DRV_LOG(ERR, "Number ports setup:%u NOT EQUAL to max port"
6243c7f3dcfSLiang Ma 				" number:%u for this device",
6253c7f3dcfSLiang Ma 				device->nb_ports,
6263c7f3dcfSLiang Ma 				device->max_port_nb);
6273c7f3dcfSLiang Ma 		err = -1;
6283c7f3dcfSLiang Ma 	}
6293c7f3dcfSLiang Ma 
6303c7f3dcfSLiang Ma 	if (!err) {
6313c7f3dcfSLiang Ma 		/* We will have at least one opdl so create it now */
6323c7f3dcfSLiang Ma 		err = create_opdl(device);
6333c7f3dcfSLiang Ma 	}
6343c7f3dcfSLiang Ma 
6353c7f3dcfSLiang Ma 	if (!err) {
6363c7f3dcfSLiang Ma 
6373c7f3dcfSLiang Ma 		/* Create 1st "dummy" queue */
6383c7f3dcfSLiang Ma 		initialise_queue(device,
6393c7f3dcfSLiang Ma 				 OPDL_Q_POS_START,
6403c7f3dcfSLiang Ma 				 -1);
6413c7f3dcfSLiang Ma 
642be455196SHarry van Haaren 		uint32_t i;
643be455196SHarry van Haaren 		for (i = 0; i < device->nb_q_md; i++) {
6443c7f3dcfSLiang Ma 
6453c7f3dcfSLiang Ma 			/* Check */
6463c7f3dcfSLiang Ma 			if (!device->q_md[i].setup) {
6473c7f3dcfSLiang Ma 
6483c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
6493c7f3dcfSLiang Ma 					     "queue meta data slot %u"
6503c7f3dcfSLiang Ma 					     " not setup - FAILING",
6513c7f3dcfSLiang Ma 					     dev->data->dev_id,
6523c7f3dcfSLiang Ma 					     i);
6533c7f3dcfSLiang Ma 				err = -EINVAL;
6543c7f3dcfSLiang Ma 				break;
6553c7f3dcfSLiang Ma 			} else if (device->q_md[i].type !=
6563c7f3dcfSLiang Ma 					OPDL_Q_TYPE_SINGLE_LINK) {
6573c7f3dcfSLiang Ma 
6583c7f3dcfSLiang Ma 				if (!device->q_md[i + 1].setup) {
6593c7f3dcfSLiang Ma 					/* Create a simple ORDERED/ATOMIC
6603c7f3dcfSLiang Ma 					 * queue at the end
6613c7f3dcfSLiang Ma 					 */
6623c7f3dcfSLiang Ma 					initialise_queue(device,
6633c7f3dcfSLiang Ma 							OPDL_Q_POS_END,
6643c7f3dcfSLiang Ma 							i);
6653c7f3dcfSLiang Ma 
6663c7f3dcfSLiang Ma 				} else {
6673c7f3dcfSLiang Ma 					/* Create a simple ORDERED/ATOMIC
6683c7f3dcfSLiang Ma 					 * queue in the middle
6693c7f3dcfSLiang Ma 					 */
6703c7f3dcfSLiang Ma 					initialise_queue(device,
6713c7f3dcfSLiang Ma 							OPDL_Q_POS_MIDDLE,
6723c7f3dcfSLiang Ma 							i);
6733c7f3dcfSLiang Ma 				}
6743c7f3dcfSLiang Ma 			} else if (device->q_md[i].type ==
6753c7f3dcfSLiang Ma 					OPDL_Q_TYPE_SINGLE_LINK) {
6763c7f3dcfSLiang Ma 
6773c7f3dcfSLiang Ma 				/* create last queue for this opdl */
6783c7f3dcfSLiang Ma 				initialise_queue(device,
6793c7f3dcfSLiang Ma 						OPDL_Q_POS_END,
6803c7f3dcfSLiang Ma 						i);
6813c7f3dcfSLiang Ma 
6823c7f3dcfSLiang Ma 				err = create_link_opdl(device, i);
6833c7f3dcfSLiang Ma 
6843c7f3dcfSLiang Ma 				if (err)
6853c7f3dcfSLiang Ma 					break;
6863c7f3dcfSLiang Ma 
6873c7f3dcfSLiang Ma 
6883c7f3dcfSLiang Ma 			}
6893c7f3dcfSLiang Ma 		}
6903c7f3dcfSLiang Ma 	}
6913c7f3dcfSLiang Ma 	if (err)
6923c7f3dcfSLiang Ma 		destroy_queues_and_rings(dev);
6933c7f3dcfSLiang Ma 
6943c7f3dcfSLiang Ma 	return err;
6953c7f3dcfSLiang Ma }
6963c7f3dcfSLiang Ma 
6973c7f3dcfSLiang Ma 
6983c7f3dcfSLiang Ma int
initialise_all_other_ports(struct rte_eventdev * dev)6993c7f3dcfSLiang Ma initialise_all_other_ports(struct rte_eventdev *dev)
7003c7f3dcfSLiang Ma {
7013c7f3dcfSLiang Ma 	int err = 0;
7023c7f3dcfSLiang Ma 	struct opdl_stage *stage_inst = NULL;
7033c7f3dcfSLiang Ma 
7043c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
7053c7f3dcfSLiang Ma 
706be455196SHarry van Haaren 	uint32_t i;
707be455196SHarry van Haaren 	for (i = 0; i < device->nb_ports; i++) {
7083c7f3dcfSLiang Ma 		struct opdl_port *port = &device->ports[i];
7093c7f3dcfSLiang Ma 		struct opdl_queue *queue = &device->queue[port->queue_id];
7103c7f3dcfSLiang Ma 
7113c7f3dcfSLiang Ma 		if (port->queue_id == 0) {
7123c7f3dcfSLiang Ma 			continue;
7133c7f3dcfSLiang Ma 		} else if (queue->q_type != OPDL_Q_TYPE_SINGLE_LINK) {
7143c7f3dcfSLiang Ma 
7153c7f3dcfSLiang Ma 			if (queue->q_pos == OPDL_Q_POS_MIDDLE) {
7163c7f3dcfSLiang Ma 
7173c7f3dcfSLiang Ma 				/* Regular port with claim/disclaim */
7183c7f3dcfSLiang Ma 				stage_inst = opdl_stage_add(
7193c7f3dcfSLiang Ma 					device->opdl[queue->opdl_id],
7203c7f3dcfSLiang Ma 						false,
7213c7f3dcfSLiang Ma 						false);
7223c7f3dcfSLiang Ma 				port->deq_stage_inst = stage_inst;
7233c7f3dcfSLiang Ma 				port->enq_stage_inst = stage_inst;
7243c7f3dcfSLiang Ma 
7253c7f3dcfSLiang Ma 				if (queue->q_type == OPDL_Q_TYPE_ATOMIC)
7263c7f3dcfSLiang Ma 					port->atomic_claim = true;
7273c7f3dcfSLiang Ma 				else
7283c7f3dcfSLiang Ma 					port->atomic_claim = false;
7293c7f3dcfSLiang Ma 
7303c7f3dcfSLiang Ma 				port->p_type =  OPDL_REGULAR_PORT;
7313c7f3dcfSLiang Ma 
7323c7f3dcfSLiang Ma 				/* Add the port to the queue array of ports */
7333c7f3dcfSLiang Ma 				queue->ports[queue->nb_ports] = port;
7343c7f3dcfSLiang Ma 				port->instance_id = queue->nb_ports;
7353c7f3dcfSLiang Ma 				queue->nb_ports++;
736b770f952SLiang Ma 				opdl_stage_set_queue_id(stage_inst,
737b770f952SLiang Ma 						port->queue_id);
738b770f952SLiang Ma 
7393c7f3dcfSLiang Ma 			} else if (queue->q_pos == OPDL_Q_POS_END) {
7403c7f3dcfSLiang Ma 
7413c7f3dcfSLiang Ma 				/* tx port  */
7423c7f3dcfSLiang Ma 				stage_inst = opdl_stage_add(
7433c7f3dcfSLiang Ma 					device->opdl[queue->opdl_id],
7443c7f3dcfSLiang Ma 						false,
7453c7f3dcfSLiang Ma 						false);
7463c7f3dcfSLiang Ma 				port->deq_stage_inst = stage_inst;
7473c7f3dcfSLiang Ma 				port->enq_stage_inst = NULL;
7483c7f3dcfSLiang Ma 				port->p_type = OPDL_PURE_TX_PORT;
7493c7f3dcfSLiang Ma 
7503c7f3dcfSLiang Ma 				/* Add the port to the queue array of ports */
7513c7f3dcfSLiang Ma 				queue->ports[queue->nb_ports] = port;
7523c7f3dcfSLiang Ma 				port->instance_id = queue->nb_ports;
7533c7f3dcfSLiang Ma 				queue->nb_ports++;
7543c7f3dcfSLiang Ma 			} else {
7553c7f3dcfSLiang Ma 
7563c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
7573c7f3dcfSLiang Ma 					     "port %u:, linked incorrectly"
7583c7f3dcfSLiang Ma 					     " to a q_pos START/INVALID %u",
7593c7f3dcfSLiang Ma 					     opdl_pmd_dev_id(port->opdl),
7603c7f3dcfSLiang Ma 					     port->id,
7613c7f3dcfSLiang Ma 					     queue->q_pos);
7623c7f3dcfSLiang Ma 				err = -EINVAL;
7633c7f3dcfSLiang Ma 				break;
7643c7f3dcfSLiang Ma 			}
7653c7f3dcfSLiang Ma 
7663c7f3dcfSLiang Ma 		} else if (queue->q_type == OPDL_Q_TYPE_SINGLE_LINK) {
7673c7f3dcfSLiang Ma 
7683c7f3dcfSLiang Ma 			port->p_type = OPDL_ASYNC_PORT;
7693c7f3dcfSLiang Ma 
7703c7f3dcfSLiang Ma 			/* -- tx -- */
7713c7f3dcfSLiang Ma 			stage_inst = opdl_stage_add(
7723c7f3dcfSLiang Ma 				device->opdl[queue->opdl_id],
7733c7f3dcfSLiang Ma 					false,
7743c7f3dcfSLiang Ma 					false); /* First stage */
7753c7f3dcfSLiang Ma 			port->deq_stage_inst = stage_inst;
7763c7f3dcfSLiang Ma 
7773c7f3dcfSLiang Ma 			/* Add the port to the queue array of ports */
7783c7f3dcfSLiang Ma 			queue->ports[queue->nb_ports] = port;
7793c7f3dcfSLiang Ma 			port->instance_id = queue->nb_ports;
7803c7f3dcfSLiang Ma 			queue->nb_ports++;
7813c7f3dcfSLiang Ma 
7823c7f3dcfSLiang Ma 			if (queue->nb_ports > 1) {
7833c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
7843c7f3dcfSLiang Ma 					     "queue %u:, setup as SINGLE_LINK"
7853c7f3dcfSLiang Ma 					     " but has more than one port linked",
7863c7f3dcfSLiang Ma 					     opdl_pmd_dev_id(port->opdl),
7873c7f3dcfSLiang Ma 					     queue->external_qid);
7883c7f3dcfSLiang Ma 				err = -EINVAL;
7893c7f3dcfSLiang Ma 				break;
7903c7f3dcfSLiang Ma 			}
7913c7f3dcfSLiang Ma 
7923c7f3dcfSLiang Ma 			/* -- single instance rx for next opdl -- */
7933c7f3dcfSLiang Ma 			uint8_t next_qid =
7943c7f3dcfSLiang Ma 				device->q_map_ex_to_in[queue->external_qid] + 1;
7953c7f3dcfSLiang Ma 			if (next_qid < RTE_EVENT_MAX_QUEUES_PER_DEV &&
7963c7f3dcfSLiang Ma 					device->queue[next_qid].configured) {
7973c7f3dcfSLiang Ma 
7983c7f3dcfSLiang Ma 				/* Remap the queue */
7993c7f3dcfSLiang Ma 				queue = &device->queue[next_qid];
8003c7f3dcfSLiang Ma 
8013c7f3dcfSLiang Ma 				stage_inst = opdl_stage_add(
8023c7f3dcfSLiang Ma 					device->opdl[queue->opdl_id],
8033c7f3dcfSLiang Ma 						false,
8043c7f3dcfSLiang Ma 						true);
8053c7f3dcfSLiang Ma 				port->enq_stage_inst = stage_inst;
8063c7f3dcfSLiang Ma 
8073c7f3dcfSLiang Ma 				/* Add the port to the queue array of ports */
8083c7f3dcfSLiang Ma 				queue->ports[queue->nb_ports] = port;
8093c7f3dcfSLiang Ma 				port->instance_id = queue->nb_ports;
8103c7f3dcfSLiang Ma 				queue->nb_ports++;
8113c7f3dcfSLiang Ma 				if (queue->nb_ports > 1) {
8123c7f3dcfSLiang Ma 					PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
8133c7f3dcfSLiang Ma 						"dummy queue %u: for "
8143c7f3dcfSLiang Ma 						"port %u, "
8153c7f3dcfSLiang Ma 						"SINGLE_LINK but has more "
8163c7f3dcfSLiang Ma 						"than one port linked",
8173c7f3dcfSLiang Ma 						opdl_pmd_dev_id(port->opdl),
8183c7f3dcfSLiang Ma 						next_qid,
8193c7f3dcfSLiang Ma 						port->id);
8203c7f3dcfSLiang Ma 					err = -EINVAL;
8213c7f3dcfSLiang Ma 					break;
8223c7f3dcfSLiang Ma 				}
8233c7f3dcfSLiang Ma 				/* Set this queue to initialized as it is never
8243c7f3dcfSLiang Ma 				 * referenced by any ports
8253c7f3dcfSLiang Ma 				 */
8263c7f3dcfSLiang Ma 				queue->initialized = 1;
8273c7f3dcfSLiang Ma 			}
8283c7f3dcfSLiang Ma 		}
8293c7f3dcfSLiang Ma 	}
8303c7f3dcfSLiang Ma 
8313c7f3dcfSLiang Ma 	/* Now that all ports are initialised we need to
8323c7f3dcfSLiang Ma 	 * setup the last bit of stage md
8333c7f3dcfSLiang Ma 	 */
8343c7f3dcfSLiang Ma 	if (!err) {
835be455196SHarry van Haaren 		for (i = 0; i < device->nb_ports; i++) {
8363c7f3dcfSLiang Ma 			struct opdl_port *port = &device->ports[i];
8373c7f3dcfSLiang Ma 			struct opdl_queue *queue =
8383c7f3dcfSLiang Ma 				&device->queue[port->queue_id];
8393c7f3dcfSLiang Ma 
8403c7f3dcfSLiang Ma 			if (port->configured &&
8413c7f3dcfSLiang Ma 					(port->queue_id != OPDL_INVALID_QID)) {
8423c7f3dcfSLiang Ma 				if (queue->nb_ports == 0) {
8433c7f3dcfSLiang Ma 					PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
8443c7f3dcfSLiang Ma 						"queue:[%u] has no ports"
8453c7f3dcfSLiang Ma 						" linked to it",
8463c7f3dcfSLiang Ma 						opdl_pmd_dev_id(port->opdl),
8473c7f3dcfSLiang Ma 						port->id);
8483c7f3dcfSLiang Ma 					err = -EINVAL;
8493c7f3dcfSLiang Ma 					break;
8503c7f3dcfSLiang Ma 				}
8513c7f3dcfSLiang Ma 
8523c7f3dcfSLiang Ma 				port->num_instance = queue->nb_ports;
8533c7f3dcfSLiang Ma 				port->initialized = 1;
8543c7f3dcfSLiang Ma 				queue->initialized = 1;
8553c7f3dcfSLiang Ma 			} else {
8563c7f3dcfSLiang Ma 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
8573c7f3dcfSLiang Ma 					     "Port:[%u] not configured  invalid"
8583c7f3dcfSLiang Ma 					     " queue configuration",
8593c7f3dcfSLiang Ma 					     opdl_pmd_dev_id(port->opdl),
8603c7f3dcfSLiang Ma 					     port->id);
8613c7f3dcfSLiang Ma 				err = -EINVAL;
8623c7f3dcfSLiang Ma 				break;
8633c7f3dcfSLiang Ma 			}
8643c7f3dcfSLiang Ma 		}
8653c7f3dcfSLiang Ma 	}
8663c7f3dcfSLiang Ma 	return err;
8673c7f3dcfSLiang Ma }
8683c7f3dcfSLiang Ma 
8693c7f3dcfSLiang Ma int
initialise_queue_zero_ports(struct rte_eventdev * dev)8703c7f3dcfSLiang Ma initialise_queue_zero_ports(struct rte_eventdev *dev)
8713c7f3dcfSLiang Ma {
8723c7f3dcfSLiang Ma 	int err = 0;
8733c7f3dcfSLiang Ma 	uint8_t mt_rx = 0;
8743c7f3dcfSLiang Ma 	struct opdl_stage *stage_inst = NULL;
8753c7f3dcfSLiang Ma 	struct opdl_queue *queue = NULL;
8763c7f3dcfSLiang Ma 
8773c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
8783c7f3dcfSLiang Ma 
8793c7f3dcfSLiang Ma 	/* Assign queue zero and figure out how many Q0 ports we have */
880be455196SHarry van Haaren 	uint32_t i;
881be455196SHarry van Haaren 	for (i = 0; i < device->nb_ports; i++) {
8823c7f3dcfSLiang Ma 		struct opdl_port *port = &device->ports[i];
8833c7f3dcfSLiang Ma 		if (port->queue_id == OPDL_INVALID_QID) {
8843c7f3dcfSLiang Ma 			port->queue_id = 0;
8853c7f3dcfSLiang Ma 			port->external_qid = OPDL_INVALID_QID;
8863c7f3dcfSLiang Ma 			port->p_type = OPDL_PURE_RX_PORT;
8873c7f3dcfSLiang Ma 			mt_rx++;
8883c7f3dcfSLiang Ma 		}
8893c7f3dcfSLiang Ma 	}
8903c7f3dcfSLiang Ma 
8913c7f3dcfSLiang Ma 	/* Create the stage */
8923c7f3dcfSLiang Ma 	stage_inst = opdl_stage_add(device->opdl[0],
8933c7f3dcfSLiang Ma 			(mt_rx > 1 ? true : false),
8943c7f3dcfSLiang Ma 			true);
8953c7f3dcfSLiang Ma 	if (stage_inst) {
8963c7f3dcfSLiang Ma 
8973c7f3dcfSLiang Ma 		/* Assign the new created input stage to all relevant ports */
898be455196SHarry van Haaren 		for (i = 0; i < device->nb_ports; i++) {
8993c7f3dcfSLiang Ma 			struct opdl_port *port = &device->ports[i];
9003c7f3dcfSLiang Ma 			if (port->queue_id == 0) {
9013c7f3dcfSLiang Ma 				queue = &device->queue[port->queue_id];
9023c7f3dcfSLiang Ma 				port->enq_stage_inst = stage_inst;
9033c7f3dcfSLiang Ma 				port->deq_stage_inst = NULL;
9043c7f3dcfSLiang Ma 				port->configured = 1;
9053c7f3dcfSLiang Ma 				port->initialized = 1;
9063c7f3dcfSLiang Ma 
9073c7f3dcfSLiang Ma 				queue->ports[queue->nb_ports] = port;
9083c7f3dcfSLiang Ma 				port->instance_id = queue->nb_ports;
9093c7f3dcfSLiang Ma 				queue->nb_ports++;
9103c7f3dcfSLiang Ma 			}
9113c7f3dcfSLiang Ma 		}
9123c7f3dcfSLiang Ma 	} else {
9133c7f3dcfSLiang Ma 		err = -1;
9143c7f3dcfSLiang Ma 	}
9153c7f3dcfSLiang Ma 	return err;
9163c7f3dcfSLiang Ma }
9173c7f3dcfSLiang Ma 
9183c7f3dcfSLiang Ma int
assign_internal_queue_ids(struct rte_eventdev * dev)9193c7f3dcfSLiang Ma assign_internal_queue_ids(struct rte_eventdev *dev)
9203c7f3dcfSLiang Ma {
9213c7f3dcfSLiang Ma 	int err = 0;
9223c7f3dcfSLiang Ma 	struct opdl_evdev *device = opdl_pmd_priv(dev);
923be455196SHarry van Haaren 	uint32_t i;
9243c7f3dcfSLiang Ma 
925be455196SHarry van Haaren 	for (i = 0; i < device->nb_ports; i++) {
9263c7f3dcfSLiang Ma 		struct opdl_port *port = &device->ports[i];
9273c7f3dcfSLiang Ma 		if (port->external_qid != OPDL_INVALID_QID) {
9283c7f3dcfSLiang Ma 			port->queue_id =
9293c7f3dcfSLiang Ma 				device->q_map_ex_to_in[port->external_qid];
9303c7f3dcfSLiang Ma 
9313c7f3dcfSLiang Ma 			/* Now do the external_qid of the next queue */
9323c7f3dcfSLiang Ma 			struct opdl_queue *queue =
9333c7f3dcfSLiang Ma 				&device->queue[port->queue_id];
9343c7f3dcfSLiang Ma 			if (queue->q_pos == OPDL_Q_POS_END)
9353c7f3dcfSLiang Ma 				port->next_external_qid =
9363c7f3dcfSLiang Ma 				device->queue[port->queue_id + 2].external_qid;
9373c7f3dcfSLiang Ma 			else
9383c7f3dcfSLiang Ma 				port->next_external_qid =
9393c7f3dcfSLiang Ma 				device->queue[port->queue_id + 1].external_qid;
9403c7f3dcfSLiang Ma 		}
9413c7f3dcfSLiang Ma 	}
9423c7f3dcfSLiang Ma 	return err;
9433c7f3dcfSLiang Ma }
944