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