1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606  * Copyright(c) 2017 Intel Corporation
3*d30ea906Sjfb8856606  */
4*d30ea906Sjfb8856606 
5*d30ea906Sjfb8856606 #include <inttypes.h>
6*d30ea906Sjfb8856606 #include <string.h>
7*d30ea906Sjfb8856606 
8*d30ea906Sjfb8856606 #include <rte_bus_vdev.h>
9*d30ea906Sjfb8856606 #include <rte_errno.h>
10*d30ea906Sjfb8856606 #include <rte_cycles.h>
11*d30ea906Sjfb8856606 #include <rte_memzone.h>
12*d30ea906Sjfb8856606 
13*d30ea906Sjfb8856606 #include "opdl_evdev.h"
14*d30ea906Sjfb8856606 #include "opdl_ring.h"
15*d30ea906Sjfb8856606 #include "opdl_log.h"
16*d30ea906Sjfb8856606 
17*d30ea906Sjfb8856606 
18*d30ea906Sjfb8856606 static __rte_always_inline uint32_t
19*d30ea906Sjfb8856606 enqueue_check(struct opdl_port *p,
20*d30ea906Sjfb8856606 		const struct rte_event ev[],
21*d30ea906Sjfb8856606 		uint16_t num,
22*d30ea906Sjfb8856606 		uint16_t num_events)
23*d30ea906Sjfb8856606 {
24*d30ea906Sjfb8856606 	uint16_t i;
25*d30ea906Sjfb8856606 
26*d30ea906Sjfb8856606 	if (p->opdl->do_validation) {
27*d30ea906Sjfb8856606 
28*d30ea906Sjfb8856606 		for (i = 0; i < num; i++) {
29*d30ea906Sjfb8856606 			if (ev[i].queue_id != p->next_external_qid) {
30*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
31*d30ea906Sjfb8856606 					     "ERROR - port:[%u] - event wants"
32*d30ea906Sjfb8856606 					     " to enq to q_id[%u],"
33*d30ea906Sjfb8856606 					     " but should be [%u]",
34*d30ea906Sjfb8856606 					     opdl_pmd_dev_id(p->opdl),
35*d30ea906Sjfb8856606 					     p->id,
36*d30ea906Sjfb8856606 					     ev[i].queue_id,
37*d30ea906Sjfb8856606 					     p->next_external_qid);
38*d30ea906Sjfb8856606 				rte_errno = -EINVAL;
39*d30ea906Sjfb8856606 				return 0;
40*d30ea906Sjfb8856606 			}
41*d30ea906Sjfb8856606 		}
42*d30ea906Sjfb8856606 
43*d30ea906Sjfb8856606 		/* Stats */
44*d30ea906Sjfb8856606 		if (p->p_type == OPDL_PURE_RX_PORT ||
45*d30ea906Sjfb8856606 				p->p_type == OPDL_ASYNC_PORT) {
46*d30ea906Sjfb8856606 			/* Stats */
47*d30ea906Sjfb8856606 			if (num_events) {
48*d30ea906Sjfb8856606 				p->port_stat[claim_pkts_requested] += num;
49*d30ea906Sjfb8856606 				p->port_stat[claim_pkts_granted] += num_events;
50*d30ea906Sjfb8856606 				p->port_stat[claim_non_empty]++;
51*d30ea906Sjfb8856606 				p->start_cycles = rte_rdtsc();
52*d30ea906Sjfb8856606 			} else {
53*d30ea906Sjfb8856606 				p->port_stat[claim_empty]++;
54*d30ea906Sjfb8856606 				p->start_cycles = 0;
55*d30ea906Sjfb8856606 			}
56*d30ea906Sjfb8856606 		} else {
57*d30ea906Sjfb8856606 			if (p->start_cycles) {
58*d30ea906Sjfb8856606 				uint64_t end_cycles = rte_rdtsc();
59*d30ea906Sjfb8856606 				p->port_stat[total_cycles] +=
60*d30ea906Sjfb8856606 					end_cycles - p->start_cycles;
61*d30ea906Sjfb8856606 			}
62*d30ea906Sjfb8856606 		}
63*d30ea906Sjfb8856606 	} else {
64*d30ea906Sjfb8856606 		if (num > 0 &&
65*d30ea906Sjfb8856606 				ev[0].queue_id != p->next_external_qid) {
66*d30ea906Sjfb8856606 			rte_errno = -EINVAL;
67*d30ea906Sjfb8856606 			return 0;
68*d30ea906Sjfb8856606 		}
69*d30ea906Sjfb8856606 	}
70*d30ea906Sjfb8856606 
71*d30ea906Sjfb8856606 	return num;
72*d30ea906Sjfb8856606 }
73*d30ea906Sjfb8856606 
74*d30ea906Sjfb8856606 static __rte_always_inline void
75*d30ea906Sjfb8856606 update_on_dequeue(struct opdl_port *p,
76*d30ea906Sjfb8856606 		struct rte_event ev[],
77*d30ea906Sjfb8856606 		uint16_t num,
78*d30ea906Sjfb8856606 		uint16_t num_events)
79*d30ea906Sjfb8856606 {
80*d30ea906Sjfb8856606 	if (p->opdl->do_validation) {
81*d30ea906Sjfb8856606 		int16_t i;
82*d30ea906Sjfb8856606 		for (i = 0; i < num; i++)
83*d30ea906Sjfb8856606 			ev[i].queue_id =
84*d30ea906Sjfb8856606 				p->opdl->queue[p->queue_id].external_qid;
85*d30ea906Sjfb8856606 
86*d30ea906Sjfb8856606 		/* Stats */
87*d30ea906Sjfb8856606 		if (num_events) {
88*d30ea906Sjfb8856606 			p->port_stat[claim_pkts_requested] += num;
89*d30ea906Sjfb8856606 			p->port_stat[claim_pkts_granted] += num_events;
90*d30ea906Sjfb8856606 			p->port_stat[claim_non_empty]++;
91*d30ea906Sjfb8856606 			p->start_cycles = rte_rdtsc();
92*d30ea906Sjfb8856606 		} else {
93*d30ea906Sjfb8856606 			p->port_stat[claim_empty]++;
94*d30ea906Sjfb8856606 			p->start_cycles = 0;
95*d30ea906Sjfb8856606 		}
96*d30ea906Sjfb8856606 	} else {
97*d30ea906Sjfb8856606 		if (num > 0)
98*d30ea906Sjfb8856606 			ev[0].queue_id =
99*d30ea906Sjfb8856606 				p->opdl->queue[p->queue_id].external_qid;
100*d30ea906Sjfb8856606 	}
101*d30ea906Sjfb8856606 }
102*d30ea906Sjfb8856606 
103*d30ea906Sjfb8856606 
104*d30ea906Sjfb8856606 /*
105*d30ea906Sjfb8856606  * Error RX enqueue:
106*d30ea906Sjfb8856606  *
107*d30ea906Sjfb8856606  *
108*d30ea906Sjfb8856606  */
109*d30ea906Sjfb8856606 
110*d30ea906Sjfb8856606 static uint16_t
111*d30ea906Sjfb8856606 opdl_rx_error_enqueue(struct opdl_port *p,
112*d30ea906Sjfb8856606 		const struct rte_event ev[],
113*d30ea906Sjfb8856606 		uint16_t num)
114*d30ea906Sjfb8856606 {
115*d30ea906Sjfb8856606 	RTE_SET_USED(p);
116*d30ea906Sjfb8856606 	RTE_SET_USED(ev);
117*d30ea906Sjfb8856606 	RTE_SET_USED(num);
118*d30ea906Sjfb8856606 
119*d30ea906Sjfb8856606 	rte_errno = -ENOSPC;
120*d30ea906Sjfb8856606 
121*d30ea906Sjfb8856606 	return 0;
122*d30ea906Sjfb8856606 }
123*d30ea906Sjfb8856606 
124*d30ea906Sjfb8856606 /*
125*d30ea906Sjfb8856606  * RX enqueue:
126*d30ea906Sjfb8856606  *
127*d30ea906Sjfb8856606  * This function handles enqueue for a single input stage_inst with
128*d30ea906Sjfb8856606  *	threadsafe disabled or enabled. eg 1 thread using a stage_inst or
129*d30ea906Sjfb8856606  *	multiple threads sharing a stage_inst
130*d30ea906Sjfb8856606  */
131*d30ea906Sjfb8856606 
132*d30ea906Sjfb8856606 static uint16_t
133*d30ea906Sjfb8856606 opdl_rx_enqueue(struct opdl_port *p,
134*d30ea906Sjfb8856606 		const struct rte_event ev[],
135*d30ea906Sjfb8856606 		uint16_t num)
136*d30ea906Sjfb8856606 {
137*d30ea906Sjfb8856606 	uint16_t enqueued = 0;
138*d30ea906Sjfb8856606 
139*d30ea906Sjfb8856606 	enqueued = opdl_ring_input(opdl_stage_get_opdl_ring(p->enq_stage_inst),
140*d30ea906Sjfb8856606 				   ev,
141*d30ea906Sjfb8856606 				   num,
142*d30ea906Sjfb8856606 				   false);
143*d30ea906Sjfb8856606 	if (!enqueue_check(p, ev, num, enqueued))
144*d30ea906Sjfb8856606 		return 0;
145*d30ea906Sjfb8856606 
146*d30ea906Sjfb8856606 
147*d30ea906Sjfb8856606 	if (enqueued < num)
148*d30ea906Sjfb8856606 		rte_errno = -ENOSPC;
149*d30ea906Sjfb8856606 
150*d30ea906Sjfb8856606 	return enqueued;
151*d30ea906Sjfb8856606 }
152*d30ea906Sjfb8856606 
153*d30ea906Sjfb8856606 /*
154*d30ea906Sjfb8856606  * Error TX handler
155*d30ea906Sjfb8856606  *
156*d30ea906Sjfb8856606  */
157*d30ea906Sjfb8856606 
158*d30ea906Sjfb8856606 static uint16_t
159*d30ea906Sjfb8856606 opdl_tx_error_dequeue(struct opdl_port *p,
160*d30ea906Sjfb8856606 		struct rte_event ev[],
161*d30ea906Sjfb8856606 		uint16_t num)
162*d30ea906Sjfb8856606 {
163*d30ea906Sjfb8856606 	RTE_SET_USED(p);
164*d30ea906Sjfb8856606 	RTE_SET_USED(ev);
165*d30ea906Sjfb8856606 	RTE_SET_USED(num);
166*d30ea906Sjfb8856606 
167*d30ea906Sjfb8856606 	rte_errno = -ENOSPC;
168*d30ea906Sjfb8856606 
169*d30ea906Sjfb8856606 	return 0;
170*d30ea906Sjfb8856606 }
171*d30ea906Sjfb8856606 
172*d30ea906Sjfb8856606 /*
173*d30ea906Sjfb8856606  * TX single threaded claim
174*d30ea906Sjfb8856606  *
175*d30ea906Sjfb8856606  * This function handles dequeue for a single worker stage_inst with
176*d30ea906Sjfb8856606  *	threadsafe disabled. eg 1 thread using an stage_inst
177*d30ea906Sjfb8856606  */
178*d30ea906Sjfb8856606 
179*d30ea906Sjfb8856606 static uint16_t
180*d30ea906Sjfb8856606 opdl_tx_dequeue_single_thread(struct opdl_port *p,
181*d30ea906Sjfb8856606 			struct rte_event ev[],
182*d30ea906Sjfb8856606 			uint16_t num)
183*d30ea906Sjfb8856606 {
184*d30ea906Sjfb8856606 	uint16_t returned;
185*d30ea906Sjfb8856606 
186*d30ea906Sjfb8856606 	struct opdl_ring  *ring;
187*d30ea906Sjfb8856606 
188*d30ea906Sjfb8856606 	ring = opdl_stage_get_opdl_ring(p->deq_stage_inst);
189*d30ea906Sjfb8856606 
190*d30ea906Sjfb8856606 	returned = opdl_ring_copy_to_burst(ring,
191*d30ea906Sjfb8856606 					   p->deq_stage_inst,
192*d30ea906Sjfb8856606 					   ev,
193*d30ea906Sjfb8856606 					   num,
194*d30ea906Sjfb8856606 					   false);
195*d30ea906Sjfb8856606 
196*d30ea906Sjfb8856606 	update_on_dequeue(p, ev, num, returned);
197*d30ea906Sjfb8856606 
198*d30ea906Sjfb8856606 	return returned;
199*d30ea906Sjfb8856606 }
200*d30ea906Sjfb8856606 
201*d30ea906Sjfb8856606 /*
202*d30ea906Sjfb8856606  * TX multi threaded claim
203*d30ea906Sjfb8856606  *
204*d30ea906Sjfb8856606  * This function handles dequeue for multiple worker stage_inst with
205*d30ea906Sjfb8856606  *	threadsafe disabled. eg multiple stage_inst each with its own instance
206*d30ea906Sjfb8856606  */
207*d30ea906Sjfb8856606 
208*d30ea906Sjfb8856606 static uint16_t
209*d30ea906Sjfb8856606 opdl_tx_dequeue_multi_inst(struct opdl_port *p,
210*d30ea906Sjfb8856606 			struct rte_event ev[],
211*d30ea906Sjfb8856606 			uint16_t num)
212*d30ea906Sjfb8856606 {
213*d30ea906Sjfb8856606 	uint32_t num_events = 0;
214*d30ea906Sjfb8856606 
215*d30ea906Sjfb8856606 	num_events = opdl_stage_claim(p->deq_stage_inst,
216*d30ea906Sjfb8856606 				    (void *)ev,
217*d30ea906Sjfb8856606 				    num,
218*d30ea906Sjfb8856606 				    NULL,
219*d30ea906Sjfb8856606 				    false,
220*d30ea906Sjfb8856606 				    false);
221*d30ea906Sjfb8856606 
222*d30ea906Sjfb8856606 	update_on_dequeue(p, ev, num, num_events);
223*d30ea906Sjfb8856606 
224*d30ea906Sjfb8856606 	return opdl_stage_disclaim(p->deq_stage_inst, num_events, false);
225*d30ea906Sjfb8856606 }
226*d30ea906Sjfb8856606 
227*d30ea906Sjfb8856606 
228*d30ea906Sjfb8856606 /*
229*d30ea906Sjfb8856606  * Worker thread claim
230*d30ea906Sjfb8856606  *
231*d30ea906Sjfb8856606  */
232*d30ea906Sjfb8856606 
233*d30ea906Sjfb8856606 static uint16_t
234*d30ea906Sjfb8856606 opdl_claim(struct opdl_port *p, struct rte_event ev[], uint16_t num)
235*d30ea906Sjfb8856606 {
236*d30ea906Sjfb8856606 	uint32_t num_events = 0;
237*d30ea906Sjfb8856606 
238*d30ea906Sjfb8856606 	if (unlikely(num > MAX_OPDL_CONS_Q_DEPTH)) {
239*d30ea906Sjfb8856606 		PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
240*d30ea906Sjfb8856606 			     "Attempt to dequeue num of events larger than port (%d) max",
241*d30ea906Sjfb8856606 			     opdl_pmd_dev_id(p->opdl),
242*d30ea906Sjfb8856606 			     p->id);
243*d30ea906Sjfb8856606 		rte_errno = -EINVAL;
244*d30ea906Sjfb8856606 		return 0;
245*d30ea906Sjfb8856606 	}
246*d30ea906Sjfb8856606 
247*d30ea906Sjfb8856606 
248*d30ea906Sjfb8856606 	num_events = opdl_stage_claim(p->deq_stage_inst,
249*d30ea906Sjfb8856606 			(void *)ev,
250*d30ea906Sjfb8856606 			num,
251*d30ea906Sjfb8856606 			NULL,
252*d30ea906Sjfb8856606 			false,
253*d30ea906Sjfb8856606 			p->atomic_claim);
254*d30ea906Sjfb8856606 
255*d30ea906Sjfb8856606 
256*d30ea906Sjfb8856606 	update_on_dequeue(p, ev, num, num_events);
257*d30ea906Sjfb8856606 
258*d30ea906Sjfb8856606 	return num_events;
259*d30ea906Sjfb8856606 }
260*d30ea906Sjfb8856606 
261*d30ea906Sjfb8856606 /*
262*d30ea906Sjfb8856606  * Worker thread disclaim
263*d30ea906Sjfb8856606  */
264*d30ea906Sjfb8856606 
265*d30ea906Sjfb8856606 static uint16_t
266*d30ea906Sjfb8856606 opdl_disclaim(struct opdl_port *p, const struct rte_event ev[], uint16_t num)
267*d30ea906Sjfb8856606 {
268*d30ea906Sjfb8856606 	uint16_t enqueued = 0;
269*d30ea906Sjfb8856606 
270*d30ea906Sjfb8856606 	uint32_t i = 0;
271*d30ea906Sjfb8856606 
272*d30ea906Sjfb8856606 	for (i = 0; i < num; i++)
273*d30ea906Sjfb8856606 		opdl_ring_cas_slot(p->enq_stage_inst, &ev[i],
274*d30ea906Sjfb8856606 				i, p->atomic_claim);
275*d30ea906Sjfb8856606 
276*d30ea906Sjfb8856606 	enqueued = opdl_stage_disclaim(p->enq_stage_inst,
277*d30ea906Sjfb8856606 				       num,
278*d30ea906Sjfb8856606 				       false);
279*d30ea906Sjfb8856606 
280*d30ea906Sjfb8856606 	return enqueue_check(p, ev, num, enqueued);
281*d30ea906Sjfb8856606 }
282*d30ea906Sjfb8856606 
283*d30ea906Sjfb8856606 static __rte_always_inline struct opdl_stage *
284*d30ea906Sjfb8856606 stage_for_port(struct opdl_queue *q, unsigned int i)
285*d30ea906Sjfb8856606 {
286*d30ea906Sjfb8856606 	if (q->q_pos == OPDL_Q_POS_START || q->q_pos == OPDL_Q_POS_MIDDLE)
287*d30ea906Sjfb8856606 		return q->ports[i]->enq_stage_inst;
288*d30ea906Sjfb8856606 	else
289*d30ea906Sjfb8856606 		return q->ports[i]->deq_stage_inst;
290*d30ea906Sjfb8856606 }
291*d30ea906Sjfb8856606 
292*d30ea906Sjfb8856606 static int opdl_add_deps(struct opdl_evdev *device,
293*d30ea906Sjfb8856606 			 int q_id,
294*d30ea906Sjfb8856606 			 int deps_q_id)
295*d30ea906Sjfb8856606 {
296*d30ea906Sjfb8856606 	unsigned int i, j;
297*d30ea906Sjfb8856606 	int status;
298*d30ea906Sjfb8856606 	struct opdl_ring  *ring;
299*d30ea906Sjfb8856606 	struct opdl_queue *queue = &device->queue[q_id];
300*d30ea906Sjfb8856606 	struct opdl_queue *queue_deps = &device->queue[deps_q_id];
301*d30ea906Sjfb8856606 	struct opdl_stage *dep_stages[OPDL_PORTS_MAX];
302*d30ea906Sjfb8856606 
303*d30ea906Sjfb8856606 	/* sanity check that all stages are for same opdl ring */
304*d30ea906Sjfb8856606 	for (i = 0; i < queue->nb_ports; i++) {
305*d30ea906Sjfb8856606 		struct opdl_ring *r =
306*d30ea906Sjfb8856606 			opdl_stage_get_opdl_ring(stage_for_port(queue, i));
307*d30ea906Sjfb8856606 		for (j = 0; j < queue_deps->nb_ports; j++) {
308*d30ea906Sjfb8856606 			struct opdl_ring *rj =
309*d30ea906Sjfb8856606 				opdl_stage_get_opdl_ring(
310*d30ea906Sjfb8856606 						stage_for_port(queue_deps, j));
311*d30ea906Sjfb8856606 			if (r != rj) {
312*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
313*d30ea906Sjfb8856606 					     "Stages and dependents"
314*d30ea906Sjfb8856606 					     " are not for same opdl ring",
315*d30ea906Sjfb8856606 					     opdl_pmd_dev_id(device));
316*d30ea906Sjfb8856606 				uint32_t k;
317*d30ea906Sjfb8856606 				for (k = 0; k < device->nb_opdls; k++) {
318*d30ea906Sjfb8856606 					opdl_ring_dump(device->opdl[k],
319*d30ea906Sjfb8856606 							stdout);
320*d30ea906Sjfb8856606 				}
321*d30ea906Sjfb8856606 				return -EINVAL;
322*d30ea906Sjfb8856606 			}
323*d30ea906Sjfb8856606 		}
324*d30ea906Sjfb8856606 	}
325*d30ea906Sjfb8856606 
326*d30ea906Sjfb8856606 	/* Gather all stages instance in deps */
327*d30ea906Sjfb8856606 	for (i = 0; i < queue_deps->nb_ports; i++)
328*d30ea906Sjfb8856606 		dep_stages[i] = stage_for_port(queue_deps, i);
329*d30ea906Sjfb8856606 
330*d30ea906Sjfb8856606 
331*d30ea906Sjfb8856606 	/* Add all deps for each port->stage_inst in this queue */
332*d30ea906Sjfb8856606 	for (i = 0; i < queue->nb_ports; i++) {
333*d30ea906Sjfb8856606 
334*d30ea906Sjfb8856606 		ring = opdl_stage_get_opdl_ring(stage_for_port(queue, i));
335*d30ea906Sjfb8856606 
336*d30ea906Sjfb8856606 		status = opdl_stage_deps_add(ring,
337*d30ea906Sjfb8856606 				stage_for_port(queue, i),
338*d30ea906Sjfb8856606 				queue->ports[i]->num_instance,
339*d30ea906Sjfb8856606 				queue->ports[i]->instance_id,
340*d30ea906Sjfb8856606 				dep_stages,
341*d30ea906Sjfb8856606 				queue_deps->nb_ports);
342*d30ea906Sjfb8856606 		if (status < 0)
343*d30ea906Sjfb8856606 			return -EINVAL;
344*d30ea906Sjfb8856606 	}
345*d30ea906Sjfb8856606 
346*d30ea906Sjfb8856606 	return 0;
347*d30ea906Sjfb8856606 }
348*d30ea906Sjfb8856606 
349*d30ea906Sjfb8856606 int
350*d30ea906Sjfb8856606 opdl_add_event_handlers(struct rte_eventdev *dev)
351*d30ea906Sjfb8856606 {
352*d30ea906Sjfb8856606 	int err = 0;
353*d30ea906Sjfb8856606 
354*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
355*d30ea906Sjfb8856606 	unsigned int i;
356*d30ea906Sjfb8856606 
357*d30ea906Sjfb8856606 	for (i = 0; i < device->max_port_nb; i++) {
358*d30ea906Sjfb8856606 
359*d30ea906Sjfb8856606 		struct opdl_port *port = &device->ports[i];
360*d30ea906Sjfb8856606 
361*d30ea906Sjfb8856606 		if (port->configured) {
362*d30ea906Sjfb8856606 			if (port->p_type == OPDL_PURE_RX_PORT) {
363*d30ea906Sjfb8856606 				port->enq = opdl_rx_enqueue;
364*d30ea906Sjfb8856606 				port->deq = opdl_tx_error_dequeue;
365*d30ea906Sjfb8856606 
366*d30ea906Sjfb8856606 			} else if (port->p_type == OPDL_PURE_TX_PORT) {
367*d30ea906Sjfb8856606 
368*d30ea906Sjfb8856606 				port->enq = opdl_rx_error_enqueue;
369*d30ea906Sjfb8856606 
370*d30ea906Sjfb8856606 				if (port->num_instance == 1)
371*d30ea906Sjfb8856606 					port->deq =
372*d30ea906Sjfb8856606 						opdl_tx_dequeue_single_thread;
373*d30ea906Sjfb8856606 				else
374*d30ea906Sjfb8856606 					port->deq = opdl_tx_dequeue_multi_inst;
375*d30ea906Sjfb8856606 
376*d30ea906Sjfb8856606 			} else if (port->p_type == OPDL_REGULAR_PORT) {
377*d30ea906Sjfb8856606 
378*d30ea906Sjfb8856606 				port->enq = opdl_disclaim;
379*d30ea906Sjfb8856606 				port->deq = opdl_claim;
380*d30ea906Sjfb8856606 
381*d30ea906Sjfb8856606 			} else if (port->p_type == OPDL_ASYNC_PORT) {
382*d30ea906Sjfb8856606 
383*d30ea906Sjfb8856606 				port->enq = opdl_rx_enqueue;
384*d30ea906Sjfb8856606 
385*d30ea906Sjfb8856606 				/* Always single instance */
386*d30ea906Sjfb8856606 				port->deq = opdl_tx_dequeue_single_thread;
387*d30ea906Sjfb8856606 			} else {
388*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
389*d30ea906Sjfb8856606 					     "port:[%u] has invalid port type - ",
390*d30ea906Sjfb8856606 					     opdl_pmd_dev_id(port->opdl),
391*d30ea906Sjfb8856606 					     port->id);
392*d30ea906Sjfb8856606 				err = -EINVAL;
393*d30ea906Sjfb8856606 				break;
394*d30ea906Sjfb8856606 			}
395*d30ea906Sjfb8856606 			port->initialized = 1;
396*d30ea906Sjfb8856606 		}
397*d30ea906Sjfb8856606 	}
398*d30ea906Sjfb8856606 
399*d30ea906Sjfb8856606 	if (!err)
400*d30ea906Sjfb8856606 		fprintf(stdout, "Success - enqueue/dequeue handler(s) added\n");
401*d30ea906Sjfb8856606 	return err;
402*d30ea906Sjfb8856606 }
403*d30ea906Sjfb8856606 
404*d30ea906Sjfb8856606 int
405*d30ea906Sjfb8856606 build_all_dependencies(struct rte_eventdev *dev)
406*d30ea906Sjfb8856606 {
407*d30ea906Sjfb8856606 
408*d30ea906Sjfb8856606 	int err = 0;
409*d30ea906Sjfb8856606 	unsigned int i;
410*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
411*d30ea906Sjfb8856606 
412*d30ea906Sjfb8856606 	uint8_t start_qid = 0;
413*d30ea906Sjfb8856606 
414*d30ea906Sjfb8856606 	for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
415*d30ea906Sjfb8856606 		struct opdl_queue *queue = &device->queue[i];
416*d30ea906Sjfb8856606 		if (!queue->initialized)
417*d30ea906Sjfb8856606 			break;
418*d30ea906Sjfb8856606 
419*d30ea906Sjfb8856606 		if (queue->q_pos == OPDL_Q_POS_START) {
420*d30ea906Sjfb8856606 			start_qid = i;
421*d30ea906Sjfb8856606 			continue;
422*d30ea906Sjfb8856606 		}
423*d30ea906Sjfb8856606 
424*d30ea906Sjfb8856606 		if (queue->q_pos == OPDL_Q_POS_MIDDLE) {
425*d30ea906Sjfb8856606 			err = opdl_add_deps(device, i, i-1);
426*d30ea906Sjfb8856606 			if (err < 0) {
427*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
428*d30ea906Sjfb8856606 					     "dependency addition for queue:[%u] - FAILED",
429*d30ea906Sjfb8856606 					     dev->data->dev_id,
430*d30ea906Sjfb8856606 					     queue->external_qid);
431*d30ea906Sjfb8856606 				break;
432*d30ea906Sjfb8856606 			}
433*d30ea906Sjfb8856606 		}
434*d30ea906Sjfb8856606 
435*d30ea906Sjfb8856606 		if (queue->q_pos == OPDL_Q_POS_END) {
436*d30ea906Sjfb8856606 			/* Add this dependency */
437*d30ea906Sjfb8856606 			err = opdl_add_deps(device, i, i-1);
438*d30ea906Sjfb8856606 			if (err < 0) {
439*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
440*d30ea906Sjfb8856606 					     "dependency addition for queue:[%u] - FAILED",
441*d30ea906Sjfb8856606 					     dev->data->dev_id,
442*d30ea906Sjfb8856606 					     queue->external_qid);
443*d30ea906Sjfb8856606 				break;
444*d30ea906Sjfb8856606 			}
445*d30ea906Sjfb8856606 			/* Add dependency for rx on tx */
446*d30ea906Sjfb8856606 			err = opdl_add_deps(device, start_qid, i);
447*d30ea906Sjfb8856606 			if (err < 0) {
448*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
449*d30ea906Sjfb8856606 					     "dependency addition for queue:[%u] - FAILED",
450*d30ea906Sjfb8856606 					     dev->data->dev_id,
451*d30ea906Sjfb8856606 					     queue->external_qid);
452*d30ea906Sjfb8856606 				break;
453*d30ea906Sjfb8856606 			}
454*d30ea906Sjfb8856606 		}
455*d30ea906Sjfb8856606 	}
456*d30ea906Sjfb8856606 
457*d30ea906Sjfb8856606 	if (!err)
458*d30ea906Sjfb8856606 		fprintf(stdout, "Success - dependencies built\n");
459*d30ea906Sjfb8856606 
460*d30ea906Sjfb8856606 	return err;
461*d30ea906Sjfb8856606 }
462*d30ea906Sjfb8856606 int
463*d30ea906Sjfb8856606 check_queues_linked(struct rte_eventdev *dev)
464*d30ea906Sjfb8856606 {
465*d30ea906Sjfb8856606 
466*d30ea906Sjfb8856606 	int err = 0;
467*d30ea906Sjfb8856606 	unsigned int i;
468*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
469*d30ea906Sjfb8856606 	uint32_t nb_iq = 0;
470*d30ea906Sjfb8856606 
471*d30ea906Sjfb8856606 	for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
472*d30ea906Sjfb8856606 		struct opdl_queue *queue = &device->queue[i];
473*d30ea906Sjfb8856606 
474*d30ea906Sjfb8856606 		if (!queue->initialized)
475*d30ea906Sjfb8856606 			break;
476*d30ea906Sjfb8856606 
477*d30ea906Sjfb8856606 		if (queue->external_qid == OPDL_INVALID_QID)
478*d30ea906Sjfb8856606 			nb_iq++;
479*d30ea906Sjfb8856606 
480*d30ea906Sjfb8856606 		if (queue->nb_ports == 0) {
481*d30ea906Sjfb8856606 			PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
482*d30ea906Sjfb8856606 				     "queue:[%u] has no associated ports",
483*d30ea906Sjfb8856606 				     dev->data->dev_id,
484*d30ea906Sjfb8856606 				     i);
485*d30ea906Sjfb8856606 			err = -EINVAL;
486*d30ea906Sjfb8856606 			break;
487*d30ea906Sjfb8856606 		}
488*d30ea906Sjfb8856606 	}
489*d30ea906Sjfb8856606 	if (!err) {
490*d30ea906Sjfb8856606 		if ((i - nb_iq) != device->max_queue_nb) {
491*d30ea906Sjfb8856606 			PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
492*d30ea906Sjfb8856606 				     "%u queues counted but should be %u",
493*d30ea906Sjfb8856606 				     dev->data->dev_id,
494*d30ea906Sjfb8856606 				     i - nb_iq,
495*d30ea906Sjfb8856606 				     device->max_queue_nb);
496*d30ea906Sjfb8856606 			err = -1;
497*d30ea906Sjfb8856606 		}
498*d30ea906Sjfb8856606 
499*d30ea906Sjfb8856606 	}
500*d30ea906Sjfb8856606 	return err;
501*d30ea906Sjfb8856606 }
502*d30ea906Sjfb8856606 
503*d30ea906Sjfb8856606 void
504*d30ea906Sjfb8856606 destroy_queues_and_rings(struct rte_eventdev *dev)
505*d30ea906Sjfb8856606 {
506*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
507*d30ea906Sjfb8856606 	uint32_t i;
508*d30ea906Sjfb8856606 
509*d30ea906Sjfb8856606 	for (i = 0; i < device->nb_opdls; i++) {
510*d30ea906Sjfb8856606 		if (device->opdl[i])
511*d30ea906Sjfb8856606 			opdl_ring_free(device->opdl[i]);
512*d30ea906Sjfb8856606 	}
513*d30ea906Sjfb8856606 
514*d30ea906Sjfb8856606 	memset(&device->queue,
515*d30ea906Sjfb8856606 			0,
516*d30ea906Sjfb8856606 			sizeof(struct opdl_queue)
517*d30ea906Sjfb8856606 			* RTE_EVENT_MAX_QUEUES_PER_DEV);
518*d30ea906Sjfb8856606 }
519*d30ea906Sjfb8856606 
520*d30ea906Sjfb8856606 #define OPDL_ID(d)(d->nb_opdls - 1)
521*d30ea906Sjfb8856606 
522*d30ea906Sjfb8856606 static __rte_always_inline void
523*d30ea906Sjfb8856606 initialise_queue(struct opdl_evdev *device,
524*d30ea906Sjfb8856606 		enum queue_pos pos,
525*d30ea906Sjfb8856606 		int32_t i)
526*d30ea906Sjfb8856606 {
527*d30ea906Sjfb8856606 	struct opdl_queue *queue = &device->queue[device->nb_queues];
528*d30ea906Sjfb8856606 
529*d30ea906Sjfb8856606 	if (i == -1) {
530*d30ea906Sjfb8856606 		queue->q_type = OPDL_Q_TYPE_ORDERED;
531*d30ea906Sjfb8856606 		queue->external_qid = OPDL_INVALID_QID;
532*d30ea906Sjfb8856606 	} else {
533*d30ea906Sjfb8856606 		queue->q_type = device->q_md[i].type;
534*d30ea906Sjfb8856606 		queue->external_qid = device->q_md[i].ext_id;
535*d30ea906Sjfb8856606 		/* Add ex->in for queues setup */
536*d30ea906Sjfb8856606 		device->q_map_ex_to_in[queue->external_qid] = device->nb_queues;
537*d30ea906Sjfb8856606 	}
538*d30ea906Sjfb8856606 	queue->opdl_id = OPDL_ID(device);
539*d30ea906Sjfb8856606 	queue->q_pos = pos;
540*d30ea906Sjfb8856606 	queue->nb_ports = 0;
541*d30ea906Sjfb8856606 	queue->configured = 1;
542*d30ea906Sjfb8856606 
543*d30ea906Sjfb8856606 	device->nb_queues++;
544*d30ea906Sjfb8856606 }
545*d30ea906Sjfb8856606 
546*d30ea906Sjfb8856606 
547*d30ea906Sjfb8856606 static __rte_always_inline int
548*d30ea906Sjfb8856606 create_opdl(struct opdl_evdev *device)
549*d30ea906Sjfb8856606 {
550*d30ea906Sjfb8856606 	int err = 0;
551*d30ea906Sjfb8856606 
552*d30ea906Sjfb8856606 	char name[RTE_MEMZONE_NAMESIZE];
553*d30ea906Sjfb8856606 
554*d30ea906Sjfb8856606 	snprintf(name, RTE_MEMZONE_NAMESIZE,
555*d30ea906Sjfb8856606 			"%s_%u", device->service_name, device->nb_opdls);
556*d30ea906Sjfb8856606 
557*d30ea906Sjfb8856606 	device->opdl[device->nb_opdls] =
558*d30ea906Sjfb8856606 		opdl_ring_create(name,
559*d30ea906Sjfb8856606 				device->nb_events_limit,
560*d30ea906Sjfb8856606 				sizeof(struct rte_event),
561*d30ea906Sjfb8856606 				device->max_port_nb * 2,
562*d30ea906Sjfb8856606 				device->socket);
563*d30ea906Sjfb8856606 
564*d30ea906Sjfb8856606 	if (!device->opdl[device->nb_opdls]) {
565*d30ea906Sjfb8856606 		PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
566*d30ea906Sjfb8856606 			     "opdl ring %u creation - FAILED",
567*d30ea906Sjfb8856606 			     opdl_pmd_dev_id(device),
568*d30ea906Sjfb8856606 			     device->nb_opdls);
569*d30ea906Sjfb8856606 		err = -EINVAL;
570*d30ea906Sjfb8856606 	} else {
571*d30ea906Sjfb8856606 		device->nb_opdls++;
572*d30ea906Sjfb8856606 	}
573*d30ea906Sjfb8856606 	return err;
574*d30ea906Sjfb8856606 }
575*d30ea906Sjfb8856606 
576*d30ea906Sjfb8856606 static __rte_always_inline int
577*d30ea906Sjfb8856606 create_link_opdl(struct opdl_evdev *device, uint32_t index)
578*d30ea906Sjfb8856606 {
579*d30ea906Sjfb8856606 
580*d30ea906Sjfb8856606 	int err = 0;
581*d30ea906Sjfb8856606 
582*d30ea906Sjfb8856606 	if (device->q_md[index + 1].type !=
583*d30ea906Sjfb8856606 			OPDL_Q_TYPE_SINGLE_LINK) {
584*d30ea906Sjfb8856606 
585*d30ea906Sjfb8856606 		/* async queue with regular
586*d30ea906Sjfb8856606 		 * queue following it
587*d30ea906Sjfb8856606 		 */
588*d30ea906Sjfb8856606 
589*d30ea906Sjfb8856606 		/* create a new opdl ring */
590*d30ea906Sjfb8856606 		err = create_opdl(device);
591*d30ea906Sjfb8856606 		if (!err) {
592*d30ea906Sjfb8856606 			/* create an initial
593*d30ea906Sjfb8856606 			 * dummy queue for new opdl
594*d30ea906Sjfb8856606 			 */
595*d30ea906Sjfb8856606 			initialise_queue(device,
596*d30ea906Sjfb8856606 					OPDL_Q_POS_START,
597*d30ea906Sjfb8856606 					-1);
598*d30ea906Sjfb8856606 		} else {
599*d30ea906Sjfb8856606 			err = -EINVAL;
600*d30ea906Sjfb8856606 		}
601*d30ea906Sjfb8856606 	} else {
602*d30ea906Sjfb8856606 		PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
603*d30ea906Sjfb8856606 			     "queue %u, two consecutive"
604*d30ea906Sjfb8856606 			     " SINGLE_LINK queues, not allowed",
605*d30ea906Sjfb8856606 			     opdl_pmd_dev_id(device),
606*d30ea906Sjfb8856606 			     index);
607*d30ea906Sjfb8856606 		err = -EINVAL;
608*d30ea906Sjfb8856606 	}
609*d30ea906Sjfb8856606 
610*d30ea906Sjfb8856606 	return err;
611*d30ea906Sjfb8856606 }
612*d30ea906Sjfb8856606 
613*d30ea906Sjfb8856606 int
614*d30ea906Sjfb8856606 create_queues_and_rings(struct rte_eventdev *dev)
615*d30ea906Sjfb8856606 {
616*d30ea906Sjfb8856606 	int err = 0;
617*d30ea906Sjfb8856606 
618*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
619*d30ea906Sjfb8856606 
620*d30ea906Sjfb8856606 	device->nb_queues = 0;
621*d30ea906Sjfb8856606 
622*d30ea906Sjfb8856606 	if (device->nb_ports != device->max_port_nb) {
623*d30ea906Sjfb8856606 		PMD_DRV_LOG(ERR, "Number ports setup:%u NOT EQUAL to max port"
624*d30ea906Sjfb8856606 				" number:%u for this device",
625*d30ea906Sjfb8856606 				device->nb_ports,
626*d30ea906Sjfb8856606 				device->max_port_nb);
627*d30ea906Sjfb8856606 		err = -1;
628*d30ea906Sjfb8856606 	}
629*d30ea906Sjfb8856606 
630*d30ea906Sjfb8856606 	if (!err) {
631*d30ea906Sjfb8856606 		/* We will have at least one opdl so create it now */
632*d30ea906Sjfb8856606 		err = create_opdl(device);
633*d30ea906Sjfb8856606 	}
634*d30ea906Sjfb8856606 
635*d30ea906Sjfb8856606 	if (!err) {
636*d30ea906Sjfb8856606 
637*d30ea906Sjfb8856606 		/* Create 1st "dummy" queue */
638*d30ea906Sjfb8856606 		initialise_queue(device,
639*d30ea906Sjfb8856606 				 OPDL_Q_POS_START,
640*d30ea906Sjfb8856606 				 -1);
641*d30ea906Sjfb8856606 
642*d30ea906Sjfb8856606 		uint32_t i;
643*d30ea906Sjfb8856606 		for (i = 0; i < device->nb_q_md; i++) {
644*d30ea906Sjfb8856606 
645*d30ea906Sjfb8856606 			/* Check */
646*d30ea906Sjfb8856606 			if (!device->q_md[i].setup) {
647*d30ea906Sjfb8856606 
648*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
649*d30ea906Sjfb8856606 					     "queue meta data slot %u"
650*d30ea906Sjfb8856606 					     " not setup - FAILING",
651*d30ea906Sjfb8856606 					     dev->data->dev_id,
652*d30ea906Sjfb8856606 					     i);
653*d30ea906Sjfb8856606 				err = -EINVAL;
654*d30ea906Sjfb8856606 				break;
655*d30ea906Sjfb8856606 			} else if (device->q_md[i].type !=
656*d30ea906Sjfb8856606 					OPDL_Q_TYPE_SINGLE_LINK) {
657*d30ea906Sjfb8856606 
658*d30ea906Sjfb8856606 				if (!device->q_md[i + 1].setup) {
659*d30ea906Sjfb8856606 					/* Create a simple ORDERED/ATOMIC
660*d30ea906Sjfb8856606 					 * queue at the end
661*d30ea906Sjfb8856606 					 */
662*d30ea906Sjfb8856606 					initialise_queue(device,
663*d30ea906Sjfb8856606 							OPDL_Q_POS_END,
664*d30ea906Sjfb8856606 							i);
665*d30ea906Sjfb8856606 
666*d30ea906Sjfb8856606 				} else {
667*d30ea906Sjfb8856606 					/* Create a simple ORDERED/ATOMIC
668*d30ea906Sjfb8856606 					 * queue in the middle
669*d30ea906Sjfb8856606 					 */
670*d30ea906Sjfb8856606 					initialise_queue(device,
671*d30ea906Sjfb8856606 							OPDL_Q_POS_MIDDLE,
672*d30ea906Sjfb8856606 							i);
673*d30ea906Sjfb8856606 				}
674*d30ea906Sjfb8856606 			} else if (device->q_md[i].type ==
675*d30ea906Sjfb8856606 					OPDL_Q_TYPE_SINGLE_LINK) {
676*d30ea906Sjfb8856606 
677*d30ea906Sjfb8856606 				/* create last queue for this opdl */
678*d30ea906Sjfb8856606 				initialise_queue(device,
679*d30ea906Sjfb8856606 						OPDL_Q_POS_END,
680*d30ea906Sjfb8856606 						i);
681*d30ea906Sjfb8856606 
682*d30ea906Sjfb8856606 				err = create_link_opdl(device, i);
683*d30ea906Sjfb8856606 
684*d30ea906Sjfb8856606 				if (err)
685*d30ea906Sjfb8856606 					break;
686*d30ea906Sjfb8856606 
687*d30ea906Sjfb8856606 
688*d30ea906Sjfb8856606 			}
689*d30ea906Sjfb8856606 		}
690*d30ea906Sjfb8856606 	}
691*d30ea906Sjfb8856606 	if (err)
692*d30ea906Sjfb8856606 		destroy_queues_and_rings(dev);
693*d30ea906Sjfb8856606 
694*d30ea906Sjfb8856606 	return err;
695*d30ea906Sjfb8856606 }
696*d30ea906Sjfb8856606 
697*d30ea906Sjfb8856606 
698*d30ea906Sjfb8856606 int
699*d30ea906Sjfb8856606 initialise_all_other_ports(struct rte_eventdev *dev)
700*d30ea906Sjfb8856606 {
701*d30ea906Sjfb8856606 	int err = 0;
702*d30ea906Sjfb8856606 	struct opdl_stage *stage_inst = NULL;
703*d30ea906Sjfb8856606 
704*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
705*d30ea906Sjfb8856606 
706*d30ea906Sjfb8856606 	uint32_t i;
707*d30ea906Sjfb8856606 	for (i = 0; i < device->nb_ports; i++) {
708*d30ea906Sjfb8856606 		struct opdl_port *port = &device->ports[i];
709*d30ea906Sjfb8856606 		struct opdl_queue *queue = &device->queue[port->queue_id];
710*d30ea906Sjfb8856606 
711*d30ea906Sjfb8856606 		if (port->queue_id == 0) {
712*d30ea906Sjfb8856606 			continue;
713*d30ea906Sjfb8856606 		} else if (queue->q_type != OPDL_Q_TYPE_SINGLE_LINK) {
714*d30ea906Sjfb8856606 
715*d30ea906Sjfb8856606 			if (queue->q_pos == OPDL_Q_POS_MIDDLE) {
716*d30ea906Sjfb8856606 
717*d30ea906Sjfb8856606 				/* Regular port with claim/disclaim */
718*d30ea906Sjfb8856606 				stage_inst = opdl_stage_add(
719*d30ea906Sjfb8856606 					device->opdl[queue->opdl_id],
720*d30ea906Sjfb8856606 						false,
721*d30ea906Sjfb8856606 						false);
722*d30ea906Sjfb8856606 				port->deq_stage_inst = stage_inst;
723*d30ea906Sjfb8856606 				port->enq_stage_inst = stage_inst;
724*d30ea906Sjfb8856606 
725*d30ea906Sjfb8856606 				if (queue->q_type == OPDL_Q_TYPE_ATOMIC)
726*d30ea906Sjfb8856606 					port->atomic_claim = true;
727*d30ea906Sjfb8856606 				else
728*d30ea906Sjfb8856606 					port->atomic_claim = false;
729*d30ea906Sjfb8856606 
730*d30ea906Sjfb8856606 				port->p_type =  OPDL_REGULAR_PORT;
731*d30ea906Sjfb8856606 
732*d30ea906Sjfb8856606 				/* Add the port to the queue array of ports */
733*d30ea906Sjfb8856606 				queue->ports[queue->nb_ports] = port;
734*d30ea906Sjfb8856606 				port->instance_id = queue->nb_ports;
735*d30ea906Sjfb8856606 				queue->nb_ports++;
736*d30ea906Sjfb8856606 				opdl_stage_set_queue_id(stage_inst,
737*d30ea906Sjfb8856606 						port->queue_id);
738*d30ea906Sjfb8856606 
739*d30ea906Sjfb8856606 			} else if (queue->q_pos == OPDL_Q_POS_END) {
740*d30ea906Sjfb8856606 
741*d30ea906Sjfb8856606 				/* tx port  */
742*d30ea906Sjfb8856606 				stage_inst = opdl_stage_add(
743*d30ea906Sjfb8856606 					device->opdl[queue->opdl_id],
744*d30ea906Sjfb8856606 						false,
745*d30ea906Sjfb8856606 						false);
746*d30ea906Sjfb8856606 				port->deq_stage_inst = stage_inst;
747*d30ea906Sjfb8856606 				port->enq_stage_inst = NULL;
748*d30ea906Sjfb8856606 				port->p_type = OPDL_PURE_TX_PORT;
749*d30ea906Sjfb8856606 
750*d30ea906Sjfb8856606 				/* Add the port to the queue array of ports */
751*d30ea906Sjfb8856606 				queue->ports[queue->nb_ports] = port;
752*d30ea906Sjfb8856606 				port->instance_id = queue->nb_ports;
753*d30ea906Sjfb8856606 				queue->nb_ports++;
754*d30ea906Sjfb8856606 			} else {
755*d30ea906Sjfb8856606 
756*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
757*d30ea906Sjfb8856606 					     "port %u:, linked incorrectly"
758*d30ea906Sjfb8856606 					     " to a q_pos START/INVALID %u",
759*d30ea906Sjfb8856606 					     opdl_pmd_dev_id(port->opdl),
760*d30ea906Sjfb8856606 					     port->id,
761*d30ea906Sjfb8856606 					     queue->q_pos);
762*d30ea906Sjfb8856606 				err = -EINVAL;
763*d30ea906Sjfb8856606 				break;
764*d30ea906Sjfb8856606 			}
765*d30ea906Sjfb8856606 
766*d30ea906Sjfb8856606 		} else if (queue->q_type == OPDL_Q_TYPE_SINGLE_LINK) {
767*d30ea906Sjfb8856606 
768*d30ea906Sjfb8856606 			port->p_type = OPDL_ASYNC_PORT;
769*d30ea906Sjfb8856606 
770*d30ea906Sjfb8856606 			/* -- tx -- */
771*d30ea906Sjfb8856606 			stage_inst = opdl_stage_add(
772*d30ea906Sjfb8856606 				device->opdl[queue->opdl_id],
773*d30ea906Sjfb8856606 					false,
774*d30ea906Sjfb8856606 					false); /* First stage */
775*d30ea906Sjfb8856606 			port->deq_stage_inst = stage_inst;
776*d30ea906Sjfb8856606 
777*d30ea906Sjfb8856606 			/* Add the port to the queue array of ports */
778*d30ea906Sjfb8856606 			queue->ports[queue->nb_ports] = port;
779*d30ea906Sjfb8856606 			port->instance_id = queue->nb_ports;
780*d30ea906Sjfb8856606 			queue->nb_ports++;
781*d30ea906Sjfb8856606 
782*d30ea906Sjfb8856606 			if (queue->nb_ports > 1) {
783*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
784*d30ea906Sjfb8856606 					     "queue %u:, setup as SINGLE_LINK"
785*d30ea906Sjfb8856606 					     " but has more than one port linked",
786*d30ea906Sjfb8856606 					     opdl_pmd_dev_id(port->opdl),
787*d30ea906Sjfb8856606 					     queue->external_qid);
788*d30ea906Sjfb8856606 				err = -EINVAL;
789*d30ea906Sjfb8856606 				break;
790*d30ea906Sjfb8856606 			}
791*d30ea906Sjfb8856606 
792*d30ea906Sjfb8856606 			/* -- single instance rx for next opdl -- */
793*d30ea906Sjfb8856606 			uint8_t next_qid =
794*d30ea906Sjfb8856606 				device->q_map_ex_to_in[queue->external_qid] + 1;
795*d30ea906Sjfb8856606 			if (next_qid < RTE_EVENT_MAX_QUEUES_PER_DEV &&
796*d30ea906Sjfb8856606 					device->queue[next_qid].configured) {
797*d30ea906Sjfb8856606 
798*d30ea906Sjfb8856606 				/* Remap the queue */
799*d30ea906Sjfb8856606 				queue = &device->queue[next_qid];
800*d30ea906Sjfb8856606 
801*d30ea906Sjfb8856606 				stage_inst = opdl_stage_add(
802*d30ea906Sjfb8856606 					device->opdl[queue->opdl_id],
803*d30ea906Sjfb8856606 						false,
804*d30ea906Sjfb8856606 						true);
805*d30ea906Sjfb8856606 				port->enq_stage_inst = stage_inst;
806*d30ea906Sjfb8856606 
807*d30ea906Sjfb8856606 				/* Add the port to the queue array of ports */
808*d30ea906Sjfb8856606 				queue->ports[queue->nb_ports] = port;
809*d30ea906Sjfb8856606 				port->instance_id = queue->nb_ports;
810*d30ea906Sjfb8856606 				queue->nb_ports++;
811*d30ea906Sjfb8856606 				if (queue->nb_ports > 1) {
812*d30ea906Sjfb8856606 					PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
813*d30ea906Sjfb8856606 						"dummy queue %u: for "
814*d30ea906Sjfb8856606 						"port %u, "
815*d30ea906Sjfb8856606 						"SINGLE_LINK but has more "
816*d30ea906Sjfb8856606 						"than one port linked",
817*d30ea906Sjfb8856606 						opdl_pmd_dev_id(port->opdl),
818*d30ea906Sjfb8856606 						next_qid,
819*d30ea906Sjfb8856606 						port->id);
820*d30ea906Sjfb8856606 					err = -EINVAL;
821*d30ea906Sjfb8856606 					break;
822*d30ea906Sjfb8856606 				}
823*d30ea906Sjfb8856606 				/* Set this queue to initialized as it is never
824*d30ea906Sjfb8856606 				 * referenced by any ports
825*d30ea906Sjfb8856606 				 */
826*d30ea906Sjfb8856606 				queue->initialized = 1;
827*d30ea906Sjfb8856606 			}
828*d30ea906Sjfb8856606 		}
829*d30ea906Sjfb8856606 	}
830*d30ea906Sjfb8856606 
831*d30ea906Sjfb8856606 	/* Now that all ports are initialised we need to
832*d30ea906Sjfb8856606 	 * setup the last bit of stage md
833*d30ea906Sjfb8856606 	 */
834*d30ea906Sjfb8856606 	if (!err) {
835*d30ea906Sjfb8856606 		for (i = 0; i < device->nb_ports; i++) {
836*d30ea906Sjfb8856606 			struct opdl_port *port = &device->ports[i];
837*d30ea906Sjfb8856606 			struct opdl_queue *queue =
838*d30ea906Sjfb8856606 				&device->queue[port->queue_id];
839*d30ea906Sjfb8856606 
840*d30ea906Sjfb8856606 			if (port->configured &&
841*d30ea906Sjfb8856606 					(port->queue_id != OPDL_INVALID_QID)) {
842*d30ea906Sjfb8856606 				if (queue->nb_ports == 0) {
843*d30ea906Sjfb8856606 					PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
844*d30ea906Sjfb8856606 						"queue:[%u] has no ports"
845*d30ea906Sjfb8856606 						" linked to it",
846*d30ea906Sjfb8856606 						opdl_pmd_dev_id(port->opdl),
847*d30ea906Sjfb8856606 						port->id);
848*d30ea906Sjfb8856606 					err = -EINVAL;
849*d30ea906Sjfb8856606 					break;
850*d30ea906Sjfb8856606 				}
851*d30ea906Sjfb8856606 
852*d30ea906Sjfb8856606 				port->num_instance = queue->nb_ports;
853*d30ea906Sjfb8856606 				port->initialized = 1;
854*d30ea906Sjfb8856606 				queue->initialized = 1;
855*d30ea906Sjfb8856606 			} else {
856*d30ea906Sjfb8856606 				PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
857*d30ea906Sjfb8856606 					     "Port:[%u] not configured  invalid"
858*d30ea906Sjfb8856606 					     " queue configuration",
859*d30ea906Sjfb8856606 					     opdl_pmd_dev_id(port->opdl),
860*d30ea906Sjfb8856606 					     port->id);
861*d30ea906Sjfb8856606 				err = -EINVAL;
862*d30ea906Sjfb8856606 				break;
863*d30ea906Sjfb8856606 			}
864*d30ea906Sjfb8856606 		}
865*d30ea906Sjfb8856606 	}
866*d30ea906Sjfb8856606 	return err;
867*d30ea906Sjfb8856606 }
868*d30ea906Sjfb8856606 
869*d30ea906Sjfb8856606 int
870*d30ea906Sjfb8856606 initialise_queue_zero_ports(struct rte_eventdev *dev)
871*d30ea906Sjfb8856606 {
872*d30ea906Sjfb8856606 	int err = 0;
873*d30ea906Sjfb8856606 	uint8_t mt_rx = 0;
874*d30ea906Sjfb8856606 	struct opdl_stage *stage_inst = NULL;
875*d30ea906Sjfb8856606 	struct opdl_queue *queue = NULL;
876*d30ea906Sjfb8856606 
877*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
878*d30ea906Sjfb8856606 
879*d30ea906Sjfb8856606 	/* Assign queue zero and figure out how many Q0 ports we have */
880*d30ea906Sjfb8856606 	uint32_t i;
881*d30ea906Sjfb8856606 	for (i = 0; i < device->nb_ports; i++) {
882*d30ea906Sjfb8856606 		struct opdl_port *port = &device->ports[i];
883*d30ea906Sjfb8856606 		if (port->queue_id == OPDL_INVALID_QID) {
884*d30ea906Sjfb8856606 			port->queue_id = 0;
885*d30ea906Sjfb8856606 			port->external_qid = OPDL_INVALID_QID;
886*d30ea906Sjfb8856606 			port->p_type = OPDL_PURE_RX_PORT;
887*d30ea906Sjfb8856606 			mt_rx++;
888*d30ea906Sjfb8856606 		}
889*d30ea906Sjfb8856606 	}
890*d30ea906Sjfb8856606 
891*d30ea906Sjfb8856606 	/* Create the stage */
892*d30ea906Sjfb8856606 	stage_inst = opdl_stage_add(device->opdl[0],
893*d30ea906Sjfb8856606 			(mt_rx > 1 ? true : false),
894*d30ea906Sjfb8856606 			true);
895*d30ea906Sjfb8856606 	if (stage_inst) {
896*d30ea906Sjfb8856606 
897*d30ea906Sjfb8856606 		/* Assign the new created input stage to all relevant ports */
898*d30ea906Sjfb8856606 		for (i = 0; i < device->nb_ports; i++) {
899*d30ea906Sjfb8856606 			struct opdl_port *port = &device->ports[i];
900*d30ea906Sjfb8856606 			if (port->queue_id == 0) {
901*d30ea906Sjfb8856606 				queue = &device->queue[port->queue_id];
902*d30ea906Sjfb8856606 				port->enq_stage_inst = stage_inst;
903*d30ea906Sjfb8856606 				port->deq_stage_inst = NULL;
904*d30ea906Sjfb8856606 				port->configured = 1;
905*d30ea906Sjfb8856606 				port->initialized = 1;
906*d30ea906Sjfb8856606 
907*d30ea906Sjfb8856606 				queue->ports[queue->nb_ports] = port;
908*d30ea906Sjfb8856606 				port->instance_id = queue->nb_ports;
909*d30ea906Sjfb8856606 				queue->nb_ports++;
910*d30ea906Sjfb8856606 			}
911*d30ea906Sjfb8856606 		}
912*d30ea906Sjfb8856606 	} else {
913*d30ea906Sjfb8856606 		err = -1;
914*d30ea906Sjfb8856606 	}
915*d30ea906Sjfb8856606 	return err;
916*d30ea906Sjfb8856606 }
917*d30ea906Sjfb8856606 
918*d30ea906Sjfb8856606 int
919*d30ea906Sjfb8856606 assign_internal_queue_ids(struct rte_eventdev *dev)
920*d30ea906Sjfb8856606 {
921*d30ea906Sjfb8856606 	int err = 0;
922*d30ea906Sjfb8856606 	struct opdl_evdev *device = opdl_pmd_priv(dev);
923*d30ea906Sjfb8856606 	uint32_t i;
924*d30ea906Sjfb8856606 
925*d30ea906Sjfb8856606 	for (i = 0; i < device->nb_ports; i++) {
926*d30ea906Sjfb8856606 		struct opdl_port *port = &device->ports[i];
927*d30ea906Sjfb8856606 		if (port->external_qid != OPDL_INVALID_QID) {
928*d30ea906Sjfb8856606 			port->queue_id =
929*d30ea906Sjfb8856606 				device->q_map_ex_to_in[port->external_qid];
930*d30ea906Sjfb8856606 
931*d30ea906Sjfb8856606 			/* Now do the external_qid of the next queue */
932*d30ea906Sjfb8856606 			struct opdl_queue *queue =
933*d30ea906Sjfb8856606 				&device->queue[port->queue_id];
934*d30ea906Sjfb8856606 			if (queue->q_pos == OPDL_Q_POS_END)
935*d30ea906Sjfb8856606 				port->next_external_qid =
936*d30ea906Sjfb8856606 				device->queue[port->queue_id + 2].external_qid;
937*d30ea906Sjfb8856606 			else
938*d30ea906Sjfb8856606 				port->next_external_qid =
939*d30ea906Sjfb8856606 				device->queue[port->queue_id + 1].external_qid;
940*d30ea906Sjfb8856606 		}
941*d30ea906Sjfb8856606 	}
942*d30ea906Sjfb8856606 	return err;
943*d30ea906Sjfb8856606 }
944