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