xref: /dpdk/drivers/event/opdl/opdl_test.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <errno.h>
9 #include <unistd.h>
10 #include <sys/queue.h>
11 
12 #include <rte_memory.h>
13 #include <rte_memzone.h>
14 #include <rte_launch.h>
15 #include <rte_eal.h>
16 #include <rte_per_lcore.h>
17 #include <rte_lcore.h>
18 #include <rte_debug.h>
19 #include <rte_ethdev.h>
20 #include <rte_cycles.h>
21 #include <rte_eventdev.h>
22 #include <rte_bus_vdev.h>
23 #include <rte_pause.h>
24 
25 #include "opdl_evdev.h"
26 #include "opdl_log.h"
27 
28 
29 #define MAX_PORTS 16
30 #define MAX_QIDS 16
31 #define NUM_PACKETS (1<<18)
32 #define NUM_EVENTS 256
33 #define BURST_SIZE 32
34 
35 
36 
37 static int evdev;
38 
39 struct test {
40 	struct rte_mempool *mbuf_pool;
41 	uint8_t port[MAX_PORTS];
42 	uint8_t qid[MAX_QIDS];
43 	int nb_qids;
44 };
45 
46 static struct rte_mempool *eventdev_func_mempool;
47 
48 static __rte_always_inline struct rte_mbuf *
49 rte_gen_arp(int portid, struct rte_mempool *mp)
50 {
51 	/*
52 	 * len = 14 + 46
53 	 * ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 46
54 	 */
55 	static const uint8_t arp_request[] = {
56 		/*0x0000:*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xa8,
57 		0x6b, 0xfd, 0x02, 0x29, 0x08, 0x06, 0x00, 0x01,
58 		/*0x0010:*/ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xec, 0xa8,
59 		0x6b, 0xfd, 0x02, 0x29, 0x0a, 0x00, 0x00, 0x01,
60 		/*0x0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
61 		0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 		/*0x0030:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 		0x00, 0x00, 0x00, 0x00
64 	};
65 	struct rte_mbuf *m;
66 	int pkt_len = sizeof(arp_request) - 1;
67 
68 	m = rte_pktmbuf_alloc(mp);
69 	if (!m)
70 		return 0;
71 
72 	memcpy((void *)((uintptr_t)m->buf_addr + m->data_off),
73 		arp_request, pkt_len);
74 	rte_pktmbuf_pkt_len(m) = pkt_len;
75 	rte_pktmbuf_data_len(m) = pkt_len;
76 
77 	RTE_SET_USED(portid);
78 
79 	return m;
80 }
81 
82 /* initialization and config */
83 static __rte_always_inline int
84 init(struct test *t, int nb_queues, int nb_ports)
85 {
86 	struct rte_event_dev_config config = {
87 			.nb_event_queues = nb_queues,
88 			.nb_event_ports = nb_ports,
89 			.nb_event_queue_flows = 1024,
90 			.nb_events_limit = 4096,
91 			.nb_event_port_dequeue_depth = 128,
92 			.nb_event_port_enqueue_depth = 128,
93 	};
94 	int ret;
95 
96 	void *temp = t->mbuf_pool; /* save and restore mbuf pool */
97 
98 	memset(t, 0, sizeof(*t));
99 	t->mbuf_pool = temp;
100 
101 	ret = rte_event_dev_configure(evdev, &config);
102 	if (ret < 0)
103 		PMD_DRV_LOG(ERR, "%d: Error configuring device\n", __LINE__);
104 	return ret;
105 };
106 
107 static __rte_always_inline int
108 create_ports(struct test *t, int num_ports)
109 {
110 	int i;
111 	static const struct rte_event_port_conf conf = {
112 			.new_event_threshold = 1024,
113 			.dequeue_depth = 32,
114 			.enqueue_depth = 32,
115 	};
116 	if (num_ports > MAX_PORTS)
117 		return -1;
118 
119 	for (i = 0; i < num_ports; i++) {
120 		if (rte_event_port_setup(evdev, i, &conf) < 0) {
121 			PMD_DRV_LOG(ERR, "Error setting up port %d\n", i);
122 			return -1;
123 		}
124 		t->port[i] = i;
125 	}
126 
127 	return 0;
128 };
129 
130 static __rte_always_inline int
131 create_queues_type(struct test *t, int num_qids, enum queue_type flags)
132 {
133 	int i;
134 	uint8_t type;
135 
136 	switch (flags) {
137 	case OPDL_Q_TYPE_ORDERED:
138 		type = RTE_SCHED_TYPE_ORDERED;
139 		break;
140 	case OPDL_Q_TYPE_ATOMIC:
141 		type = RTE_SCHED_TYPE_ATOMIC;
142 		break;
143 	default:
144 		type = 0;
145 	}
146 
147 	/* Q creation */
148 	const struct rte_event_queue_conf conf = {
149 		.event_queue_cfg =
150 		(flags == OPDL_Q_TYPE_SINGLE_LINK ?
151 		 RTE_EVENT_QUEUE_CFG_SINGLE_LINK : 0),
152 		.schedule_type = type,
153 		.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
154 		.nb_atomic_flows = 1024,
155 		.nb_atomic_order_sequences = 1024,
156 	};
157 
158 	for (i = t->nb_qids ; i < t->nb_qids + num_qids; i++) {
159 		if (rte_event_queue_setup(evdev, i, &conf) < 0) {
160 			PMD_DRV_LOG(ERR, "%d: error creating qid %d\n ",
161 					__LINE__, i);
162 			return -1;
163 		}
164 		t->qid[i] = i;
165 	}
166 
167 	t->nb_qids += num_qids;
168 
169 	if (t->nb_qids > MAX_QIDS)
170 		return -1;
171 
172 	return 0;
173 }
174 
175 
176 /* destruction */
177 static __rte_always_inline int
178 cleanup(struct test *t __rte_unused)
179 {
180 	rte_event_dev_stop(evdev);
181 	rte_event_dev_close(evdev);
182 	PMD_DRV_LOG(ERR, "clean up for test done\n");
183 	return 0;
184 };
185 
186 static int
187 ordered_basic(struct test *t)
188 {
189 	const uint8_t rx_port = 0;
190 	const uint8_t w1_port = 1;
191 	const uint8_t w3_port = 3;
192 	const uint8_t tx_port = 4;
193 	int err;
194 	uint32_t i;
195 	uint32_t deq_pkts;
196 	struct rte_mbuf *mbufs[3];
197 
198 	const uint32_t MAGIC_SEQN = 1234;
199 
200 	/* Create instance with 5 ports */
201 	if (init(t, 2, tx_port+1) < 0 ||
202 	    create_ports(t, tx_port+1) < 0 ||
203 	    create_queues_type(t, 2, OPDL_Q_TYPE_ORDERED)) {
204 		PMD_DRV_LOG(ERR, "%d: Error initializing device\n", __LINE__);
205 		return -1;
206 	}
207 
208 	/*
209 	 * CQ mapping to QID
210 	 * We need three ports, all mapped to the same ordered qid0. Then we'll
211 	 * take a packet out to each port, re-enqueue in reverse order,
212 	 * then make sure the reordering has taken place properly when we
213 	 * dequeue from the tx_port.
214 	 *
215 	 * Simplified test setup diagram:
216 	 *
217 	 * rx_port        w1_port
218 	 *        \     /         \
219 	 *         qid0 - w2_port - qid1
220 	 *              \         /     \
221 	 *                w3_port        tx_port
222 	 */
223 	/* CQ mapping to QID for LB ports (directed mapped on create) */
224 	for (i = w1_port; i <= w3_port; i++) {
225 		err = rte_event_port_link(evdev, t->port[i], &t->qid[0], NULL,
226 				1);
227 		if (err != 1) {
228 			PMD_DRV_LOG(ERR, "%d: error mapping lb qid\n",
229 					__LINE__);
230 			cleanup(t);
231 			return -1;
232 		}
233 	}
234 
235 	err = rte_event_port_link(evdev, t->port[tx_port], &t->qid[1], NULL,
236 			1);
237 	if (err != 1) {
238 		PMD_DRV_LOG(ERR, "%d: error mapping TX  qid\n", __LINE__);
239 		cleanup(t);
240 		return -1;
241 	}
242 
243 	if (rte_event_dev_start(evdev) < 0) {
244 		PMD_DRV_LOG(ERR, "%d: Error with start call\n", __LINE__);
245 		return -1;
246 	}
247 	/* Enqueue 3 packets to the rx port */
248 	for (i = 0; i < 3; i++) {
249 		struct rte_event ev;
250 		mbufs[i] = rte_gen_arp(0, t->mbuf_pool);
251 		if (!mbufs[i]) {
252 			PMD_DRV_LOG(ERR, "%d: gen of pkt failed\n", __LINE__);
253 			return -1;
254 		}
255 
256 		ev.queue_id = t->qid[0];
257 		ev.op = RTE_EVENT_OP_NEW;
258 		ev.mbuf = mbufs[i];
259 		*rte_event_pmd_selftest_seqn(mbufs[i]) = MAGIC_SEQN + i;
260 
261 		/* generate pkt and enqueue */
262 		err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
263 		if (err != 1) {
264 			PMD_DRV_LOG(ERR, "%d: Failed to enqueue pkt %u, retval = %u\n",
265 					__LINE__, i, err);
266 			return -1;
267 		}
268 	}
269 
270 	/* use extra slot to make logic in loops easier */
271 	struct rte_event deq_ev[w3_port + 1];
272 
273 	uint32_t  seq  = 0;
274 
275 	/* Dequeue the 3 packets, one from each worker port */
276 	for (i = w1_port; i <= w3_port; i++) {
277 		deq_pkts = rte_event_dequeue_burst(evdev, t->port[i],
278 				&deq_ev[i], 1, 0);
279 		if (deq_pkts != 1) {
280 			PMD_DRV_LOG(ERR, "%d: Failed to deq\n", __LINE__);
281 			rte_event_dev_dump(evdev, stdout);
282 			return -1;
283 		}
284 		seq = *rte_event_pmd_selftest_seqn(deq_ev[i].mbuf)  - MAGIC_SEQN;
285 
286 		if (seq != (i-1)) {
287 			PMD_DRV_LOG(ERR, " seq test failed ! eq is %d , "
288 					"port number is %u\n", seq, i);
289 			return -1;
290 		}
291 	}
292 
293 	/* Enqueue each packet in reverse order, flushing after each one */
294 	for (i = w3_port; i >= w1_port; i--) {
295 
296 		deq_ev[i].op = RTE_EVENT_OP_FORWARD;
297 		deq_ev[i].queue_id = t->qid[1];
298 		err = rte_event_enqueue_burst(evdev, t->port[i], &deq_ev[i], 1);
299 		if (err != 1) {
300 			PMD_DRV_LOG(ERR, "%d: Failed to enqueue\n", __LINE__);
301 			return -1;
302 		}
303 	}
304 
305 	/* dequeue from the tx ports, we should get 3 packets */
306 	deq_pkts = rte_event_dequeue_burst(evdev, t->port[tx_port], deq_ev,
307 			3, 0);
308 
309 	/* Check to see if we've got all 3 packets */
310 	if (deq_pkts != 3) {
311 		PMD_DRV_LOG(ERR, "%d: expected 3 pkts at tx port got %d from port %d\n",
312 			__LINE__, deq_pkts, tx_port);
313 		rte_event_dev_dump(evdev, stdout);
314 		return 1;
315 	}
316 
317 	/* Destroy the instance */
318 	cleanup(t);
319 
320 	return 0;
321 }
322 
323 
324 static int
325 atomic_basic(struct test *t)
326 {
327 	const uint8_t rx_port = 0;
328 	const uint8_t w1_port = 1;
329 	const uint8_t w3_port = 3;
330 	const uint8_t tx_port = 4;
331 	int err;
332 	int i;
333 	uint32_t deq_pkts;
334 	struct rte_mbuf *mbufs[3];
335 	const uint32_t MAGIC_SEQN = 1234;
336 
337 	/* Create instance with 5 ports */
338 	if (init(t, 2, tx_port+1) < 0 ||
339 	    create_ports(t, tx_port+1) < 0 ||
340 	    create_queues_type(t, 2, OPDL_Q_TYPE_ATOMIC)) {
341 		PMD_DRV_LOG(ERR, "%d: Error initializing device\n", __LINE__);
342 		return -1;
343 	}
344 
345 
346 	/*
347 	 * CQ mapping to QID
348 	 * We need three ports, all mapped to the same ordered qid0. Then we'll
349 	 * take a packet out to each port, re-enqueue in reverse order,
350 	 * then make sure the reordering has taken place properly when we
351 	 * dequeue from the tx_port.
352 	 *
353 	 * Simplified test setup diagram:
354 	 *
355 	 * rx_port        w1_port
356 	 *        \     /         \
357 	 *         qid0 - w2_port - qid1
358 	 *              \         /     \
359 	 *                w3_port        tx_port
360 	 */
361 	/* CQ mapping to QID for Atomic  ports (directed mapped on create) */
362 	for (i = w1_port; i <= w3_port; i++) {
363 		err = rte_event_port_link(evdev, t->port[i], &t->qid[0], NULL,
364 				1);
365 		if (err != 1) {
366 			PMD_DRV_LOG(ERR, "%d: error mapping lb qid\n",
367 					__LINE__);
368 			cleanup(t);
369 			return -1;
370 		}
371 	}
372 
373 	err = rte_event_port_link(evdev, t->port[tx_port], &t->qid[1], NULL,
374 			1);
375 	if (err != 1) {
376 		PMD_DRV_LOG(ERR, "%d: error mapping TX  qid\n", __LINE__);
377 		cleanup(t);
378 		return -1;
379 	}
380 
381 	if (rte_event_dev_start(evdev) < 0) {
382 		PMD_DRV_LOG(ERR, "%d: Error with start call\n", __LINE__);
383 		return -1;
384 	}
385 
386 	/* Enqueue 3 packets to the rx port */
387 	for (i = 0; i < 3; i++) {
388 		struct rte_event ev;
389 		mbufs[i] = rte_gen_arp(0, t->mbuf_pool);
390 		if (!mbufs[i]) {
391 			PMD_DRV_LOG(ERR, "%d: gen of pkt failed\n", __LINE__);
392 			return -1;
393 		}
394 
395 		ev.queue_id = t->qid[0];
396 		ev.op = RTE_EVENT_OP_NEW;
397 		ev.flow_id = 1;
398 		ev.mbuf = mbufs[i];
399 		*rte_event_pmd_selftest_seqn(mbufs[i]) = MAGIC_SEQN + i;
400 
401 		/* generate pkt and enqueue */
402 		err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
403 		if (err != 1) {
404 			PMD_DRV_LOG(ERR, "%d: Failed to enqueue pkt %u, retval = %u\n",
405 					__LINE__, i, err);
406 			return -1;
407 		}
408 	}
409 
410 	/* use extra slot to make logic in loops easier */
411 	struct rte_event deq_ev[w3_port + 1];
412 
413 	/* Dequeue the 3 packets, one from each worker port */
414 	for (i = w1_port; i <= w3_port; i++) {
415 
416 		deq_pkts = rte_event_dequeue_burst(evdev, t->port[i],
417 				deq_ev, 3, 0);
418 
419 		if (t->port[i] != 2) {
420 			if (deq_pkts != 0) {
421 				PMD_DRV_LOG(ERR, "%d: deq none zero !\n",
422 						__LINE__);
423 				rte_event_dev_dump(evdev, stdout);
424 				return -1;
425 			}
426 		} else {
427 
428 			if (deq_pkts != 3) {
429 				PMD_DRV_LOG(ERR, "%d: deq not eqal to 3 %u !\n",
430 						__LINE__, deq_pkts);
431 				rte_event_dev_dump(evdev, stdout);
432 				return -1;
433 			}
434 
435 			int j;
436 			for (j = 0; j < 3; j++) {
437 				deq_ev[j].op = RTE_EVENT_OP_FORWARD;
438 				deq_ev[j].queue_id = t->qid[1];
439 			}
440 
441 			err = rte_event_enqueue_burst(evdev, t->port[i],
442 					deq_ev, 3);
443 
444 			if (err != 3) {
445 				PMD_DRV_LOG(ERR, "port %d: Failed to enqueue pkt %u, "
446 						"retval = %u\n",
447 						t->port[i], 3, err);
448 				return -1;
449 			}
450 
451 		}
452 
453 	}
454 
455 
456 	/* dequeue from the tx ports, we should get 3 packets */
457 	deq_pkts = rte_event_dequeue_burst(evdev, t->port[tx_port], deq_ev,
458 			3, 0);
459 
460 	/* Check to see if we've got all 3 packets */
461 	if (deq_pkts != 3) {
462 		PMD_DRV_LOG(ERR, "%d: expected 3 pkts at tx port got %d from port %d\n",
463 			__LINE__, deq_pkts, tx_port);
464 		rte_event_dev_dump(evdev, stdout);
465 		return 1;
466 	}
467 
468 	cleanup(t);
469 
470 	return 0;
471 }
472 static __rte_always_inline int
473 check_qid_stats(uint32_t id[], int index)
474 {
475 
476 	if (index == 0) {
477 		if (id[0] != 3 || id[1] != 3
478 				|| id[2] != 3)
479 			return -1;
480 	} else if (index == 1) {
481 		if (id[0] != 5 || id[1] != 5
482 				|| id[2] != 2)
483 			return -1;
484 	} else if (index == 2) {
485 		if (id[0] != 3 || id[1] != 1
486 				|| id[2] != 1)
487 			return -1;
488 	}
489 
490 	return 0;
491 }
492 
493 
494 static int
495 check_statistics(void)
496 {
497 	int num_ports = 3; /* Hard-coded for this app */
498 	int i;
499 
500 	for (i = 0; i < num_ports; i++) {
501 		int num_stats, num_stats_returned;
502 
503 		num_stats = rte_event_dev_xstats_names_get(0,
504 				RTE_EVENT_DEV_XSTATS_PORT,
505 				i,
506 				NULL,
507 				NULL,
508 				0);
509 		if (num_stats > 0) {
510 
511 			uint32_t id[num_stats];
512 			struct rte_event_dev_xstats_name names[num_stats];
513 			uint64_t values[num_stats];
514 
515 			num_stats_returned = rte_event_dev_xstats_names_get(0,
516 					RTE_EVENT_DEV_XSTATS_PORT,
517 					i,
518 					names,
519 					id,
520 					num_stats);
521 
522 			if (num_stats == num_stats_returned) {
523 				num_stats_returned = rte_event_dev_xstats_get(0,
524 						RTE_EVENT_DEV_XSTATS_PORT,
525 						i,
526 						id,
527 						values,
528 						num_stats);
529 
530 				if (num_stats == num_stats_returned) {
531 					int err;
532 
533 					err = check_qid_stats(id, i);
534 
535 					if (err)
536 						return err;
537 
538 				} else {
539 					return -1;
540 				}
541 			} else {
542 				return -1;
543 			}
544 		} else {
545 			return -1;
546 		}
547 	}
548 	return 0;
549 }
550 
551 #define OLD_NUM_PACKETS 3
552 #define NEW_NUM_PACKETS 2
553 static int
554 single_link_w_stats(struct test *t)
555 {
556 	const uint8_t rx_port = 0;
557 	const uint8_t w1_port = 1;
558 	const uint8_t tx_port = 2;
559 	int err;
560 	int i;
561 	uint32_t deq_pkts;
562 	struct rte_mbuf *mbufs[3];
563 	RTE_SET_USED(mbufs);
564 
565 	/* Create instance with 3 ports */
566 	if (init(t, 2, tx_port + 1) < 0 ||
567 	    create_ports(t, 3) < 0 || /* 0,1,2 */
568 	    create_queues_type(t, 1, OPDL_Q_TYPE_SINGLE_LINK) < 0 ||
569 	    create_queues_type(t, 1, OPDL_Q_TYPE_ORDERED) < 0) {
570 		PMD_DRV_LOG(ERR, "%d: Error initializing device\n", __LINE__);
571 		return -1;
572 	}
573 
574 
575 	/*
576 	 *
577 	 * Simplified test setup diagram:
578 	 *
579 	 * rx_port(0)
580 	 *           \
581 	 *            qid0 - w1_port(1) - qid1
582 	 *                                    \
583 	 *                                     tx_port(2)
584 	 */
585 
586 	err = rte_event_port_link(evdev, t->port[1], &t->qid[0], NULL,
587 				  1);
588 	if (err != 1) {
589 		PMD_DRV_LOG(ERR, "%d: error linking port:[%u] to queue:[%u]\n",
590 		       __LINE__,
591 		       t->port[1],
592 		       t->qid[0]);
593 		cleanup(t);
594 		return -1;
595 	}
596 
597 	err = rte_event_port_link(evdev, t->port[2], &t->qid[1], NULL,
598 				  1);
599 	if (err != 1) {
600 		PMD_DRV_LOG(ERR, "%d: error linking port:[%u] to queue:[%u]\n",
601 		       __LINE__,
602 		       t->port[2],
603 		       t->qid[1]);
604 		cleanup(t);
605 		return -1;
606 	}
607 
608 	if (rte_event_dev_start(evdev) != 0) {
609 		PMD_DRV_LOG(ERR, "%d: failed to start device\n", __LINE__);
610 		cleanup(t);
611 		return -1;
612 	}
613 
614 	/*
615 	 * Enqueue 3 packets to the rx port
616 	 */
617 	for (i = 0; i < 3; i++) {
618 		struct rte_event ev;
619 		mbufs[i] = rte_gen_arp(0, t->mbuf_pool);
620 		if (!mbufs[i]) {
621 			PMD_DRV_LOG(ERR, "%d: gen of pkt failed\n", __LINE__);
622 			return -1;
623 		}
624 
625 		ev.queue_id = t->qid[0];
626 		ev.op = RTE_EVENT_OP_NEW;
627 		ev.mbuf = mbufs[i];
628 		*rte_event_pmd_selftest_seqn(mbufs[i]) = 1234 + i;
629 
630 		/* generate pkt and enqueue */
631 		err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
632 		if (err != 1) {
633 			PMD_DRV_LOG(ERR, "%d: Failed to enqueue pkt %u, retval = %u\n",
634 			       __LINE__,
635 			       t->port[rx_port],
636 			       err);
637 			return -1;
638 		}
639 	}
640 
641 	/* Dequeue the 3 packets, from SINGLE_LINK worker port */
642 	struct rte_event deq_ev[3];
643 
644 	deq_pkts = rte_event_dequeue_burst(evdev,
645 					   t->port[w1_port],
646 					   deq_ev, 3, 0);
647 
648 	if (deq_pkts != 3) {
649 		PMD_DRV_LOG(ERR, "%d: deq not 3 !\n", __LINE__);
650 		cleanup(t);
651 		return -1;
652 	}
653 
654 	/* Just enqueue 2 onto new ring */
655 	for (i = 0; i < NEW_NUM_PACKETS; i++)
656 		deq_ev[i].queue_id = t->qid[1];
657 
658 	deq_pkts = rte_event_enqueue_burst(evdev,
659 					   t->port[w1_port],
660 					   deq_ev,
661 					   NEW_NUM_PACKETS);
662 
663 	if (deq_pkts != 2) {
664 		PMD_DRV_LOG(ERR, "%d: enq not 2 but %u!\n", __LINE__, deq_pkts);
665 		cleanup(t);
666 		return -1;
667 	}
668 
669 	/* dequeue from the tx ports, we should get 2 packets */
670 	deq_pkts = rte_event_dequeue_burst(evdev,
671 					   t->port[tx_port],
672 					   deq_ev,
673 					   3,
674 					   0);
675 
676 	/* Check to see if we've got all 2 packets */
677 	if (deq_pkts != 2) {
678 		PMD_DRV_LOG(ERR, "%d: expected 2 pkts at tx port got %d from port %d\n",
679 			__LINE__, deq_pkts, tx_port);
680 		cleanup(t);
681 		return -1;
682 	}
683 
684 	if (!check_statistics()) {
685 		PMD_DRV_LOG(ERR, "xstats check failed");
686 		cleanup(t);
687 		return -1;
688 	}
689 
690 	cleanup(t);
691 
692 	return 0;
693 }
694 
695 static int
696 single_link(struct test *t)
697 {
698 	const uint8_t tx_port = 2;
699 	int err;
700 	struct rte_mbuf *mbufs[3];
701 	RTE_SET_USED(mbufs);
702 
703 	/* Create instance with 5 ports */
704 	if (init(t, 2, tx_port+1) < 0 ||
705 	    create_ports(t, 3) < 0 || /* 0,1,2 */
706 	    create_queues_type(t, 1, OPDL_Q_TYPE_SINGLE_LINK) < 0 ||
707 	    create_queues_type(t, 1, OPDL_Q_TYPE_ORDERED) < 0) {
708 		PMD_DRV_LOG(ERR, "%d: Error initializing device\n", __LINE__);
709 		return -1;
710 	}
711 
712 
713 	/*
714 	 *
715 	 * Simplified test setup diagram:
716 	 *
717 	 * rx_port(0)
718 	 *           \
719 	 *            qid0 - w1_port(1) - qid1
720 	 *                                    \
721 	 *                                     tx_port(2)
722 	 */
723 
724 	err = rte_event_port_link(evdev, t->port[1], &t->qid[0], NULL,
725 				  1);
726 	if (err != 1) {
727 		PMD_DRV_LOG(ERR, "%d: error mapping lb qid\n", __LINE__);
728 		cleanup(t);
729 		return -1;
730 	}
731 
732 	err = rte_event_port_link(evdev, t->port[2], &t->qid[0], NULL,
733 				  1);
734 	if (err != 1) {
735 		PMD_DRV_LOG(ERR, "%d: error mapping lb qid\n", __LINE__);
736 		cleanup(t);
737 		return -1;
738 	}
739 
740 	if (rte_event_dev_start(evdev) == 0) {
741 		PMD_DRV_LOG(ERR, "%d: start DIDN'T FAIL with more than 1 "
742 				"SINGLE_LINK PORT\n", __LINE__);
743 		cleanup(t);
744 		return -1;
745 	}
746 
747 	cleanup(t);
748 
749 	return 0;
750 }
751 
752 
753 static __rte_always_inline void
754 populate_event_burst(struct rte_event ev[],
755 		     uint8_t qid,
756 		     uint16_t num_events)
757 {
758 	uint16_t i;
759 	for (i = 0; i < num_events; i++) {
760 		ev[i].flow_id = 1;
761 		ev[i].op = RTE_EVENT_OP_NEW;
762 		ev[i].sched_type = RTE_SCHED_TYPE_ORDERED;
763 		ev[i].queue_id = qid;
764 		ev[i].event_type = RTE_EVENT_TYPE_ETHDEV;
765 		ev[i].sub_event_type = 0;
766 		ev[i].priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
767 		ev[i].mbuf = (struct rte_mbuf *)0xdead0000;
768 	}
769 }
770 
771 #define NUM_QUEUES 3
772 #define BATCH_SIZE 32
773 
774 static int
775 qid_basic(struct test *t)
776 {
777 	int err = 0;
778 
779 	uint8_t q_id = 0;
780 	uint8_t p_id = 0;
781 
782 	uint32_t num_events;
783 	uint32_t i;
784 
785 	struct rte_event ev[BATCH_SIZE];
786 
787 	/* Create instance with 4 ports */
788 	if (init(t, NUM_QUEUES, NUM_QUEUES+1) < 0 ||
789 	    create_ports(t, NUM_QUEUES+1) < 0 ||
790 	    create_queues_type(t, NUM_QUEUES, OPDL_Q_TYPE_ORDERED)) {
791 		PMD_DRV_LOG(ERR, "%d: Error initializing device\n", __LINE__);
792 		return -1;
793 	}
794 
795 	for (i = 0; i < NUM_QUEUES; i++) {
796 		int nb_linked;
797 		q_id = i;
798 
799 		nb_linked = rte_event_port_link(evdev,
800 				i+1, /* port = q_id + 1*/
801 				&q_id,
802 				NULL,
803 				1);
804 
805 		if (nb_linked != 1) {
806 
807 			PMD_DRV_LOG(ERR, "%s:%d: error mapping port:%u to queue:%u\n",
808 					__FILE__,
809 					__LINE__,
810 					i + 1,
811 					q_id);
812 
813 			err = -1;
814 			break;
815 		}
816 
817 	}
818 
819 
820 	/* Try and link to the same port again */
821 	if (!err) {
822 		uint8_t t_qid = 0;
823 		if (rte_event_port_link(evdev,
824 					1,
825 					&t_qid,
826 					NULL,
827 					1) > 0) {
828 			PMD_DRV_LOG(ERR, "%s:%d: Second call to port link on same port DID NOT fail\n",
829 					__FILE__,
830 					__LINE__);
831 			err = -1;
832 		}
833 
834 		uint32_t test_num_events;
835 
836 		if (!err) {
837 			test_num_events = rte_event_dequeue_burst(evdev,
838 					p_id,
839 					ev,
840 					BATCH_SIZE,
841 					0);
842 			if (test_num_events != 0) {
843 				PMD_DRV_LOG(ERR, "%s:%d: Error dequeuing 0 packets from port %u on stopped device\n",
844 						__FILE__,
845 						__LINE__,
846 						p_id);
847 				err = -1;
848 			}
849 		}
850 
851 		if (!err) {
852 			test_num_events = rte_event_enqueue_burst(evdev,
853 					p_id,
854 					ev,
855 					BATCH_SIZE);
856 			if (test_num_events != 0) {
857 				PMD_DRV_LOG(ERR, "%s:%d: Error enqueuing 0 packets to port %u on stopped device\n",
858 						__FILE__,
859 						__LINE__,
860 						p_id);
861 				err = -1;
862 			}
863 		}
864 	}
865 
866 
867 	/* Start the devicea */
868 	if (!err) {
869 		if (rte_event_dev_start(evdev) < 0) {
870 			PMD_DRV_LOG(ERR, "%s:%d: Error with start call\n",
871 					__FILE__,
872 					__LINE__);
873 			err = -1;
874 		}
875 	}
876 
877 
878 	/* Check we can't do any more links now that device is started.*/
879 	if (!err) {
880 		uint8_t t_qid = 0;
881 		if (rte_event_port_link(evdev,
882 					1,
883 					&t_qid,
884 					NULL,
885 					1) > 0) {
886 			PMD_DRV_LOG(ERR, "%s:%d: Call to port link on started device DID NOT fail\n",
887 					__FILE__,
888 					__LINE__);
889 			err = -1;
890 		}
891 	}
892 
893 	if (!err) {
894 
895 		q_id = 0;
896 
897 		populate_event_burst(ev,
898 				q_id,
899 				BATCH_SIZE);
900 
901 		num_events = rte_event_enqueue_burst(evdev,
902 				p_id,
903 				ev,
904 				BATCH_SIZE);
905 		if (num_events != BATCH_SIZE) {
906 			PMD_DRV_LOG(ERR, "%s:%d: Error enqueuing rx packets\n",
907 					__FILE__,
908 					__LINE__);
909 			err = -1;
910 		}
911 	}
912 
913 	if (!err) {
914 		while (++p_id < NUM_QUEUES) {
915 
916 			num_events = rte_event_dequeue_burst(evdev,
917 					p_id,
918 					ev,
919 					BATCH_SIZE,
920 					0);
921 
922 			if (num_events != BATCH_SIZE) {
923 				PMD_DRV_LOG(ERR, "%s:%d: Error dequeuing packets from port %u\n",
924 						__FILE__,
925 						__LINE__,
926 						p_id);
927 				err = -1;
928 				break;
929 			}
930 
931 			if (ev[0].queue_id != q_id) {
932 				PMD_DRV_LOG(ERR, "%s:%d: Error event portid[%u] q_id:[%u] does not match expected:[%u]\n",
933 						__FILE__,
934 						__LINE__,
935 						p_id,
936 						ev[0].queue_id,
937 						q_id);
938 				err = -1;
939 				break;
940 			}
941 
942 			populate_event_burst(ev,
943 					++q_id,
944 					BATCH_SIZE);
945 
946 			num_events = rte_event_enqueue_burst(evdev,
947 					p_id,
948 					ev,
949 					BATCH_SIZE);
950 			if (num_events != BATCH_SIZE) {
951 				PMD_DRV_LOG(ERR, "%s:%d: Error enqueuing packets from port:%u to queue:%u\n",
952 						__FILE__,
953 						__LINE__,
954 						p_id,
955 						q_id);
956 				err = -1;
957 				break;
958 			}
959 		}
960 	}
961 
962 	if (!err) {
963 		num_events = rte_event_dequeue_burst(evdev,
964 				p_id,
965 				ev,
966 				BATCH_SIZE,
967 				0);
968 		if (num_events != BATCH_SIZE) {
969 			PMD_DRV_LOG(ERR, "%s:%d: Error dequeuing packets from tx port %u\n",
970 					__FILE__,
971 					__LINE__,
972 					p_id);
973 			err = -1;
974 		}
975 	}
976 
977 	cleanup(t);
978 
979 	return err;
980 }
981 
982 
983 
984 int
985 opdl_selftest(void)
986 {
987 	struct test *t = malloc(sizeof(struct test));
988 	int ret;
989 
990 	const char *eventdev_name = "event_opdl0";
991 
992 	evdev = rte_event_dev_get_dev_id(eventdev_name);
993 
994 	if (evdev < 0) {
995 		PMD_DRV_LOG(ERR, "%d: Eventdev %s not found - creating.\n",
996 				__LINE__, eventdev_name);
997 		/* turn on stats by default */
998 		if (rte_vdev_init(eventdev_name, "do_validation=1") < 0) {
999 			PMD_DRV_LOG(ERR, "Error creating eventdev\n");
1000 			free(t);
1001 			return -1;
1002 		}
1003 		evdev = rte_event_dev_get_dev_id(eventdev_name);
1004 		if (evdev < 0) {
1005 			PMD_DRV_LOG(ERR, "Error finding newly created eventdev\n");
1006 			free(t);
1007 			return -1;
1008 		}
1009 	}
1010 
1011 	/* Only create mbuf pool once, reuse for each test run */
1012 	if (!eventdev_func_mempool) {
1013 		eventdev_func_mempool = rte_pktmbuf_pool_create(
1014 				"EVENTDEV_SW_SA_MBUF_POOL",
1015 				(1<<12), /* 4k buffers */
1016 				32 /*MBUF_CACHE_SIZE*/,
1017 				0,
1018 				512, /* use very small mbufs */
1019 				rte_socket_id());
1020 		if (!eventdev_func_mempool) {
1021 			PMD_DRV_LOG(ERR, "ERROR creating mempool\n");
1022 			free(t);
1023 			return -1;
1024 		}
1025 	}
1026 	t->mbuf_pool = eventdev_func_mempool;
1027 
1028 	PMD_DRV_LOG(ERR, "*** Running Ordered Basic test...\n");
1029 	ret = ordered_basic(t);
1030 
1031 	PMD_DRV_LOG(ERR, "*** Running Atomic Basic test...\n");
1032 	ret = atomic_basic(t);
1033 
1034 
1035 	PMD_DRV_LOG(ERR, "*** Running QID  Basic test...\n");
1036 	ret = qid_basic(t);
1037 
1038 	PMD_DRV_LOG(ERR, "*** Running SINGLE LINK failure test...\n");
1039 	ret = single_link(t);
1040 
1041 	PMD_DRV_LOG(ERR, "*** Running SINGLE LINK w stats test...\n");
1042 	ret = single_link_w_stats(t);
1043 
1044 	/*
1045 	 * Free test instance, free  mempool
1046 	 */
1047 	rte_mempool_free(t->mbuf_pool);
1048 	free(t);
1049 
1050 	if (ret != 0)
1051 		return ret;
1052 	return 0;
1053 
1054 }
1055