test/eventdev: add SW xstats tests
[dpdk.git] / test / test / test_eventdev_sw.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <sys/queue.h>
40
41 #include <rte_memory.h>
42 #include <rte_memzone.h>
43 #include <rte_launch.h>
44 #include <rte_eal.h>
45 #include <rte_per_lcore.h>
46 #include <rte_lcore.h>
47 #include <rte_debug.h>
48 #include <rte_ethdev.h>
49 #include <rte_cycles.h>
50
51 #include <rte_eventdev.h>
52 #include "test.h"
53
54 #define MAX_PORTS 16
55 #define MAX_QIDS 16
56 #define NUM_PACKETS (1<<18)
57
58 static int evdev;
59
60 struct test {
61         struct rte_mempool *mbuf_pool;
62         uint8_t port[MAX_PORTS];
63         uint8_t qid[MAX_QIDS];
64         int nb_qids;
65 };
66
67 static struct rte_event release_ev;
68
69 static inline struct rte_mbuf *
70 rte_gen_arp(int portid, struct rte_mempool *mp)
71 {
72         /*
73          * len = 14 + 46
74          * ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 46
75          */
76         static const uint8_t arp_request[] = {
77                 /*0x0000:*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xa8,
78                 0x6b, 0xfd, 0x02, 0x29, 0x08, 0x06, 0x00, 0x01,
79                 /*0x0010:*/ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xec, 0xa8,
80                 0x6b, 0xfd, 0x02, 0x29, 0x0a, 0x00, 0x00, 0x01,
81                 /*0x0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
82                 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83                 /*0x0030:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84                 0x00, 0x00, 0x00, 0x00
85         };
86         struct rte_mbuf *m;
87         int pkt_len = sizeof(arp_request) - 1;
88
89         m = rte_pktmbuf_alloc(mp);
90         if (!m)
91                 return 0;
92
93         memcpy((void *)((uintptr_t)m->buf_addr + m->data_off),
94                 arp_request, pkt_len);
95         rte_pktmbuf_pkt_len(m) = pkt_len;
96         rte_pktmbuf_data_len(m) = pkt_len;
97
98         RTE_SET_USED(portid);
99
100         return m;
101 }
102
103 /* initialization and config */
104 static inline int
105 init(struct test *t, int nb_queues, int nb_ports)
106 {
107         struct rte_event_dev_config config = {
108                         .nb_event_queues = nb_queues,
109                         .nb_event_ports = nb_ports,
110                         .nb_event_queue_flows = 1024,
111                         .nb_events_limit = 4096,
112                         .nb_event_port_dequeue_depth = 128,
113                         .nb_event_port_enqueue_depth = 128,
114         };
115         int ret;
116
117         void *temp = t->mbuf_pool; /* save and restore mbuf pool */
118
119         memset(t, 0, sizeof(*t));
120         t->mbuf_pool = temp;
121
122         ret = rte_event_dev_configure(evdev, &config);
123         if (ret < 0)
124                 printf("%d: Error configuring device\n", __LINE__);
125         return ret;
126 };
127
128 static inline int
129 create_ports(struct test *t, int num_ports)
130 {
131         int i;
132         static const struct rte_event_port_conf conf = {
133                         .new_event_threshold = 1024,
134                         .dequeue_depth = 32,
135                         .enqueue_depth = 64,
136         };
137         if (num_ports > MAX_PORTS)
138                 return -1;
139
140         for (i = 0; i < num_ports; i++) {
141                 if (rte_event_port_setup(evdev, i, &conf) < 0) {
142                         printf("Error setting up port %d\n", i);
143                         return -1;
144                 }
145                 t->port[i] = i;
146         }
147
148         return 0;
149 }
150
151 static inline int
152 create_lb_qids(struct test *t, int num_qids, uint32_t flags)
153 {
154         int i;
155
156         /* Q creation */
157         const struct rte_event_queue_conf conf = {
158                         .event_queue_cfg = flags,
159                         .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
160                         .nb_atomic_flows = 1024,
161                         .nb_atomic_order_sequences = 1024,
162         };
163
164         for (i = t->nb_qids; i < t->nb_qids + num_qids; i++) {
165                 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
166                         printf("%d: error creating qid %d\n", __LINE__, i);
167                         return -1;
168                 }
169                 t->qid[i] = i;
170         }
171         t->nb_qids += num_qids;
172         if (t->nb_qids > MAX_QIDS)
173                 return -1;
174
175         return 0;
176 }
177
178 static inline int
179 create_atomic_qids(struct test *t, int num_qids)
180 {
181         return create_lb_qids(t, num_qids, RTE_EVENT_QUEUE_CFG_ATOMIC_ONLY);
182 }
183
184 static inline int
185 create_ordered_qids(struct test *t, int num_qids)
186 {
187         return create_lb_qids(t, num_qids, RTE_EVENT_QUEUE_CFG_ORDERED_ONLY);
188 }
189
190
191 static inline int
192 create_unordered_qids(struct test *t, int num_qids)
193 {
194         return create_lb_qids(t, num_qids, RTE_EVENT_QUEUE_CFG_PARALLEL_ONLY);
195 }
196
197 static inline int
198 create_directed_qids(struct test *t, int num_qids, const uint8_t ports[])
199 {
200         int i;
201
202         /* Q creation */
203         static const struct rte_event_queue_conf conf = {
204                         .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
205                         .event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK,
206                         .nb_atomic_flows = 1024,
207                         .nb_atomic_order_sequences = 1024,
208         };
209
210         for (i = t->nb_qids; i < t->nb_qids + num_qids; i++) {
211                 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
212                         printf("%d: error creating qid %d\n", __LINE__, i);
213                         return -1;
214                 }
215                 t->qid[i] = i;
216
217                 if (rte_event_port_link(evdev, ports[i - t->nb_qids],
218                                 &t->qid[i], NULL, 1) != 1) {
219                         printf("%d: error creating link for qid %d\n",
220                                         __LINE__, i);
221                         return -1;
222                 }
223         }
224         t->nb_qids += num_qids;
225         if (t->nb_qids > MAX_QIDS)
226                 return -1;
227
228         return 0;
229 }
230
231 /* destruction */
232 static inline int
233 cleanup(struct test *t __rte_unused)
234 {
235         rte_event_dev_stop(evdev);
236         rte_event_dev_close(evdev);
237         return 0;
238 };
239
240 struct test_event_dev_stats {
241         uint64_t rx_pkts;       /**< Total packets received */
242         uint64_t rx_dropped;    /**< Total packets dropped (Eg Invalid QID) */
243         uint64_t tx_pkts;       /**< Total packets transmitted */
244
245         /** Packets received on this port */
246         uint64_t port_rx_pkts[MAX_PORTS];
247         /** Packets dropped on this port */
248         uint64_t port_rx_dropped[MAX_PORTS];
249         /** Packets inflight on this port */
250         uint64_t port_inflight[MAX_PORTS];
251         /** Packets transmitted on this port */
252         uint64_t port_tx_pkts[MAX_PORTS];
253         /** Packets received on this qid */
254         uint64_t qid_rx_pkts[MAX_QIDS];
255         /** Packets dropped on this qid */
256         uint64_t qid_rx_dropped[MAX_QIDS];
257         /** Packets transmitted on this qid */
258         uint64_t qid_tx_pkts[MAX_QIDS];
259 };
260
261 static inline int
262 test_event_dev_stats_get(int dev_id, struct test_event_dev_stats *stats)
263 {
264         static uint32_t i;
265         static uint32_t total_ids[3]; /* rx, tx and drop */
266         static uint32_t port_rx_pkts_ids[MAX_PORTS];
267         static uint32_t port_rx_dropped_ids[MAX_PORTS];
268         static uint32_t port_inflight_ids[MAX_PORTS];
269         static uint32_t port_tx_pkts_ids[MAX_PORTS];
270         static uint32_t qid_rx_pkts_ids[MAX_QIDS];
271         static uint32_t qid_rx_dropped_ids[MAX_QIDS];
272         static uint32_t qid_tx_pkts_ids[MAX_QIDS];
273
274
275         stats->rx_pkts = rte_event_dev_xstats_by_name_get(dev_id,
276                         "dev_rx", &total_ids[0]);
277         stats->rx_dropped = rte_event_dev_xstats_by_name_get(dev_id,
278                         "dev_drop", &total_ids[1]);
279         stats->tx_pkts = rte_event_dev_xstats_by_name_get(dev_id,
280                         "dev_tx", &total_ids[2]);
281         for (i = 0; i < MAX_PORTS; i++) {
282                 char name[32];
283                 snprintf(name, sizeof(name), "port_%u_rx", i);
284                 stats->port_rx_pkts[i] = rte_event_dev_xstats_by_name_get(
285                                 dev_id, name, &port_rx_pkts_ids[i]);
286                 snprintf(name, sizeof(name), "port_%u_drop", i);
287                 stats->port_rx_dropped[i] = rte_event_dev_xstats_by_name_get(
288                                 dev_id, name, &port_rx_dropped_ids[i]);
289                 snprintf(name, sizeof(name), "port_%u_inflight", i);
290                 stats->port_inflight[i] = rte_event_dev_xstats_by_name_get(
291                                 dev_id, name, &port_inflight_ids[i]);
292                 snprintf(name, sizeof(name), "port_%u_tx", i);
293                 stats->port_tx_pkts[i] = rte_event_dev_xstats_by_name_get(
294                                 dev_id, name, &port_tx_pkts_ids[i]);
295         }
296         for (i = 0; i < MAX_QIDS; i++) {
297                 char name[32];
298                 snprintf(name, sizeof(name), "qid_%u_rx", i);
299                 stats->qid_rx_pkts[i] = rte_event_dev_xstats_by_name_get(
300                                 dev_id, name, &qid_rx_pkts_ids[i]);
301                 snprintf(name, sizeof(name), "qid_%u_drop", i);
302                 stats->qid_rx_dropped[i] = rte_event_dev_xstats_by_name_get(
303                                 dev_id, name, &qid_rx_dropped_ids[i]);
304                 snprintf(name, sizeof(name), "qid_%u_tx", i);
305                 stats->qid_tx_pkts[i] = rte_event_dev_xstats_by_name_get(
306                                 dev_id, name, &qid_tx_pkts_ids[i]);
307         }
308
309         return 0;
310 }
311
312 /* run_prio_packet_test
313  * This performs a basic packet priority check on the test instance passed in.
314  * It is factored out of the main priority tests as the same tests must be
315  * performed to ensure prioritization of each type of QID.
316  *
317  * Requirements:
318  *  - An initialized test structure, including mempool
319  *  - t->port[0] is initialized for both Enq / Deq of packets to the QID
320  *  - t->qid[0] is the QID to be tested
321  *  - if LB QID, the CQ must be mapped to the QID.
322  */
323 static int
324 run_prio_packet_test(struct test *t)
325 {
326         int err;
327         const uint32_t MAGIC_SEQN[] = {4711, 1234};
328         const uint32_t PRIORITY[] = {
329                 RTE_EVENT_DEV_PRIORITY_NORMAL,
330                 RTE_EVENT_DEV_PRIORITY_HIGHEST
331         };
332         unsigned int i;
333         for (i = 0; i < RTE_DIM(MAGIC_SEQN); i++) {
334                 /* generate pkt and enqueue */
335                 struct rte_event ev;
336                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
337                 if (!arp) {
338                         printf("%d: gen of pkt failed\n", __LINE__);
339                         return -1;
340                 }
341                 arp->seqn = MAGIC_SEQN[i];
342
343                 ev = (struct rte_event){
344                         .priority = PRIORITY[i],
345                         .op = RTE_EVENT_OP_NEW,
346                         .queue_id = t->qid[0],
347                         .mbuf = arp
348                 };
349                 err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
350                 if (err < 0) {
351                         printf("%d: error failed to enqueue\n", __LINE__);
352                         return -1;
353                 }
354         }
355
356         rte_event_schedule(evdev);
357
358         struct test_event_dev_stats stats;
359         err = test_event_dev_stats_get(evdev, &stats);
360         if (err) {
361                 printf("%d: error failed to get stats\n", __LINE__);
362                 return -1;
363         }
364
365         if (stats.port_rx_pkts[t->port[0]] != 2) {
366                 printf("%d: error stats incorrect for directed port\n",
367                                 __LINE__);
368                 rte_event_dev_dump(evdev, stdout);
369                 return -1;
370         }
371
372         struct rte_event ev, ev2;
373         uint32_t deq_pkts;
374         deq_pkts = rte_event_dequeue_burst(evdev, t->port[0], &ev, 1, 0);
375         if (deq_pkts != 1) {
376                 printf("%d: error failed to deq\n", __LINE__);
377                 rte_event_dev_dump(evdev, stdout);
378                 return -1;
379         }
380         if (ev.mbuf->seqn != MAGIC_SEQN[1]) {
381                 printf("%d: first packet out not highest priority\n",
382                                 __LINE__);
383                 rte_event_dev_dump(evdev, stdout);
384                 return -1;
385         }
386         rte_pktmbuf_free(ev.mbuf);
387
388         deq_pkts = rte_event_dequeue_burst(evdev, t->port[0], &ev2, 1, 0);
389         if (deq_pkts != 1) {
390                 printf("%d: error failed to deq\n", __LINE__);
391                 rte_event_dev_dump(evdev, stdout);
392                 return -1;
393         }
394         if (ev2.mbuf->seqn != MAGIC_SEQN[0]) {
395                 printf("%d: second packet out not lower priority\n",
396                                 __LINE__);
397                 rte_event_dev_dump(evdev, stdout);
398                 return -1;
399         }
400         rte_pktmbuf_free(ev2.mbuf);
401
402         cleanup(t);
403         return 0;
404 }
405
406 static int
407 test_single_directed_packet(struct test *t)
408 {
409         const int rx_enq = 0;
410         const int wrk_enq = 2;
411         int err;
412
413         /* Create instance with 3 directed QIDs going to 3 ports */
414         if (init(t, 3, 3) < 0 ||
415                         create_ports(t, 3) < 0 ||
416                         create_directed_qids(t, 3, t->port) < 0)
417                 return -1;
418
419         if (rte_event_dev_start(evdev) < 0) {
420                 printf("%d: Error with start call\n", __LINE__);
421                 return -1;
422         }
423
424         /************** FORWARD ****************/
425         struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
426         struct rte_event ev = {
427                         .op = RTE_EVENT_OP_NEW,
428                         .queue_id = wrk_enq,
429                         .mbuf = arp,
430         };
431
432         if (!arp) {
433                 printf("%d: gen of pkt failed\n", __LINE__);
434                 return -1;
435         }
436
437         const uint32_t MAGIC_SEQN = 4711;
438         arp->seqn = MAGIC_SEQN;
439
440         /* generate pkt and enqueue */
441         err = rte_event_enqueue_burst(evdev, rx_enq, &ev, 1);
442         if (err < 0) {
443                 printf("%d: error failed to enqueue\n", __LINE__);
444                 return -1;
445         }
446
447         /* Run schedule() as dir packets may need to be re-ordered */
448         rte_event_schedule(evdev);
449
450         struct test_event_dev_stats stats;
451         err = test_event_dev_stats_get(evdev, &stats);
452         if (err) {
453                 printf("%d: error failed to get stats\n", __LINE__);
454                 return -1;
455         }
456
457         if (stats.port_rx_pkts[rx_enq] != 1) {
458                 printf("%d: error stats incorrect for directed port\n",
459                                 __LINE__);
460                 return -1;
461         }
462
463         uint32_t deq_pkts;
464         deq_pkts = rte_event_dequeue_burst(evdev, wrk_enq, &ev, 1, 0);
465         if (deq_pkts != 1) {
466                 printf("%d: error failed to deq\n", __LINE__);
467                 return -1;
468         }
469
470         err = test_event_dev_stats_get(evdev, &stats);
471         if (stats.port_rx_pkts[wrk_enq] != 0 &&
472                         stats.port_rx_pkts[wrk_enq] != 1) {
473                 printf("%d: error directed stats post-dequeue\n", __LINE__);
474                 return -1;
475         }
476
477         if (ev.mbuf->seqn != MAGIC_SEQN) {
478                 printf("%d: error magic sequence number not dequeued\n",
479                                 __LINE__);
480                 return -1;
481         }
482
483         rte_pktmbuf_free(ev.mbuf);
484         cleanup(t);
485         return 0;
486 }
487
488
489 static int
490 test_priority_directed(struct test *t)
491 {
492         if (init(t, 1, 1) < 0 ||
493                         create_ports(t, 1) < 0 ||
494                         create_directed_qids(t, 1, t->port) < 0) {
495                 printf("%d: Error initializing device\n", __LINE__);
496                 return -1;
497         }
498
499         if (rte_event_dev_start(evdev) < 0) {
500                 printf("%d: Error with start call\n", __LINE__);
501                 return -1;
502         }
503
504         return run_prio_packet_test(t);
505 }
506
507 static int
508 test_priority_atomic(struct test *t)
509 {
510         if (init(t, 1, 1) < 0 ||
511                         create_ports(t, 1) < 0 ||
512                         create_atomic_qids(t, 1) < 0) {
513                 printf("%d: Error initializing device\n", __LINE__);
514                 return -1;
515         }
516
517         /* map the QID */
518         if (rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1) != 1) {
519                 printf("%d: error mapping qid to port\n", __LINE__);
520                 return -1;
521         }
522         if (rte_event_dev_start(evdev) < 0) {
523                 printf("%d: Error with start call\n", __LINE__);
524                 return -1;
525         }
526
527         return run_prio_packet_test(t);
528 }
529
530 static int
531 test_priority_ordered(struct test *t)
532 {
533         if (init(t, 1, 1) < 0 ||
534                         create_ports(t, 1) < 0 ||
535                         create_ordered_qids(t, 1) < 0) {
536                 printf("%d: Error initializing device\n", __LINE__);
537                 return -1;
538         }
539
540         /* map the QID */
541         if (rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1) != 1) {
542                 printf("%d: error mapping qid to port\n", __LINE__);
543                 return -1;
544         }
545         if (rte_event_dev_start(evdev) < 0) {
546                 printf("%d: Error with start call\n", __LINE__);
547                 return -1;
548         }
549
550         return run_prio_packet_test(t);
551 }
552
553 static int
554 test_priority_unordered(struct test *t)
555 {
556         if (init(t, 1, 1) < 0 ||
557                         create_ports(t, 1) < 0 ||
558                         create_unordered_qids(t, 1) < 0) {
559                 printf("%d: Error initializing device\n", __LINE__);
560                 return -1;
561         }
562
563         /* map the QID */
564         if (rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1) != 1) {
565                 printf("%d: error mapping qid to port\n", __LINE__);
566                 return -1;
567         }
568         if (rte_event_dev_start(evdev) < 0) {
569                 printf("%d: Error with start call\n", __LINE__);
570                 return -1;
571         }
572
573         return run_prio_packet_test(t);
574 }
575
576 static int
577 burst_packets(struct test *t)
578 {
579         /************** CONFIG ****************/
580         uint32_t i;
581         int err;
582         int ret;
583
584         /* Create instance with 2 ports and 2 queues */
585         if (init(t, 2, 2) < 0 ||
586                         create_ports(t, 2) < 0 ||
587                         create_atomic_qids(t, 2) < 0) {
588                 printf("%d: Error initializing device\n", __LINE__);
589                 return -1;
590         }
591
592         /* CQ mapping to QID */
593         ret = rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1);
594         if (ret != 1) {
595                 printf("%d: error mapping lb qid0\n", __LINE__);
596                 return -1;
597         }
598         ret = rte_event_port_link(evdev, t->port[1], &t->qid[1], NULL, 1);
599         if (ret != 1) {
600                 printf("%d: error mapping lb qid1\n", __LINE__);
601                 return -1;
602         }
603
604         if (rte_event_dev_start(evdev) < 0) {
605                 printf("%d: Error with start call\n", __LINE__);
606                 return -1;
607         }
608
609         /************** FORWARD ****************/
610         const uint32_t rx_port = 0;
611         const uint32_t NUM_PKTS = 2;
612
613         for (i = 0; i < NUM_PKTS; i++) {
614                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
615                 if (!arp) {
616                         printf("%d: error generating pkt\n", __LINE__);
617                         return -1;
618                 }
619
620                 struct rte_event ev = {
621                                 .op = RTE_EVENT_OP_NEW,
622                                 .queue_id = i % 2,
623                                 .flow_id = i % 3,
624                                 .mbuf = arp,
625                 };
626                 /* generate pkt and enqueue */
627                 err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
628                 if (err < 0) {
629                         printf("%d: Failed to enqueue\n", __LINE__);
630                         return -1;
631                 }
632         }
633         rte_event_schedule(evdev);
634
635         /* Check stats for all NUM_PKTS arrived to sched core */
636         struct test_event_dev_stats stats;
637
638         err = test_event_dev_stats_get(evdev, &stats);
639         if (err) {
640                 printf("%d: failed to get stats\n", __LINE__);
641                 return -1;
642         }
643         if (stats.rx_pkts != NUM_PKTS || stats.tx_pkts != NUM_PKTS) {
644                 printf("%d: Sched core didn't receive all %d pkts\n",
645                                 __LINE__, NUM_PKTS);
646                 rte_event_dev_dump(evdev, stdout);
647                 return -1;
648         }
649
650         uint32_t deq_pkts;
651         int p;
652
653         deq_pkts = 0;
654         /******** DEQ QID 1 *******/
655         do {
656                 struct rte_event ev;
657                 p = rte_event_dequeue_burst(evdev, t->port[0], &ev, 1, 0);
658                 deq_pkts += p;
659                 rte_pktmbuf_free(ev.mbuf);
660         } while (p);
661
662         if (deq_pkts != NUM_PKTS/2) {
663                 printf("%d: Half of NUM_PKTS didn't arrive at port 1\n",
664                                 __LINE__);
665                 return -1;
666         }
667
668         /******** DEQ QID 2 *******/
669         deq_pkts = 0;
670         do {
671                 struct rte_event ev;
672                 p = rte_event_dequeue_burst(evdev, t->port[1], &ev, 1, 0);
673                 deq_pkts += p;
674                 rte_pktmbuf_free(ev.mbuf);
675         } while (p);
676         if (deq_pkts != NUM_PKTS/2) {
677                 printf("%d: Half of NUM_PKTS didn't arrive at port 2\n",
678                                 __LINE__);
679                 return -1;
680         }
681
682         cleanup(t);
683         return 0;
684 }
685
686 static int
687 abuse_inflights(struct test *t)
688 {
689         const int rx_enq = 0;
690         const int wrk_enq = 2;
691         int err;
692
693         /* Create instance with 4 ports */
694         if (init(t, 1, 4) < 0 ||
695                         create_ports(t, 4) < 0 ||
696                         create_atomic_qids(t, 1) < 0) {
697                 printf("%d: Error initializing device\n", __LINE__);
698                 return -1;
699         }
700
701         /* CQ mapping to QID */
702         err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
703         if (err != 1) {
704                 printf("%d: error mapping lb qid\n", __LINE__);
705                 cleanup(t);
706                 return -1;
707         }
708
709         if (rte_event_dev_start(evdev) < 0) {
710                 printf("%d: Error with start call\n", __LINE__);
711                 return -1;
712         }
713
714         /* Enqueue op only */
715         err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &release_ev, 1);
716         if (err < 0) {
717                 printf("%d: Failed to enqueue\n", __LINE__);
718                 return -1;
719         }
720
721         /* schedule */
722         rte_event_schedule(evdev);
723
724         struct test_event_dev_stats stats;
725
726         err = test_event_dev_stats_get(evdev, &stats);
727         if (err) {
728                 printf("%d: failed to get stats\n", __LINE__);
729                 return -1;
730         }
731
732         if (stats.rx_pkts != 0 ||
733                         stats.tx_pkts != 0 ||
734                         stats.port_inflight[wrk_enq] != 0) {
735                 printf("%d: Sched core didn't handle pkt as expected\n",
736                                 __LINE__);
737                 return -1;
738         }
739
740         cleanup(t);
741         return 0;
742 }
743
744 static int
745 xstats_tests(struct test *t)
746 {
747         const int wrk_enq = 2;
748         int err;
749
750         /* Create instance with 4 ports */
751         if (init(t, 1, 4) < 0 ||
752                         create_ports(t, 4) < 0 ||
753                         create_atomic_qids(t, 1) < 0) {
754                 printf("%d: Error initializing device\n", __LINE__);
755                 return -1;
756         }
757
758         /* CQ mapping to QID */
759         err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
760         if (err != 1) {
761                 printf("%d: error mapping lb qid\n", __LINE__);
762                 cleanup(t);
763                 return -1;
764         }
765
766         if (rte_event_dev_start(evdev) < 0) {
767                 printf("%d: Error with start call\n", __LINE__);
768                 return -1;
769         }
770
771         const uint32_t XSTATS_MAX = 1024;
772
773         uint32_t i;
774         uint32_t ids[XSTATS_MAX];
775         uint64_t values[XSTATS_MAX];
776         struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
777
778         for (i = 0; i < XSTATS_MAX; i++)
779                 ids[i] = i;
780
781         /* Device names / values */
782         int ret = rte_event_dev_xstats_names_get(evdev,
783                                         RTE_EVENT_DEV_XSTATS_DEVICE,
784                                         0, xstats_names, ids, XSTATS_MAX);
785         if (ret != 6) {
786                 printf("%d: expected 6 stats, got return %d\n", __LINE__, ret);
787                 return -1;
788         }
789         ret = rte_event_dev_xstats_get(evdev,
790                                         RTE_EVENT_DEV_XSTATS_DEVICE,
791                                         0, ids, values, ret);
792         if (ret != 6) {
793                 printf("%d: expected 6 stats, got return %d\n", __LINE__, ret);
794                 return -1;
795         }
796
797         /* Port names / values */
798         ret = rte_event_dev_xstats_names_get(evdev,
799                                         RTE_EVENT_DEV_XSTATS_PORT, 0,
800                                         xstats_names, ids, XSTATS_MAX);
801         if (ret != 21) {
802                 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
803                 return -1;
804         }
805         ret = rte_event_dev_xstats_get(evdev,
806                                         RTE_EVENT_DEV_XSTATS_PORT, 0,
807                                         ids, values, ret);
808         if (ret != 21) {
809                 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
810                 return -1;
811         }
812
813         /* Queue names / values */
814         ret = rte_event_dev_xstats_names_get(evdev,
815                                         RTE_EVENT_DEV_XSTATS_QUEUE,
816                                         0, xstats_names, ids, XSTATS_MAX);
817         if (ret != 13) {
818                 printf("%d: expected 13 stats, got return %d\n", __LINE__, ret);
819                 return -1;
820         }
821
822         /* NEGATIVE TEST: with wrong queue passed, 0 stats should be returned */
823         ret = rte_event_dev_xstats_get(evdev,
824                                         RTE_EVENT_DEV_XSTATS_QUEUE,
825                                         1, ids, values, ret);
826         if (ret != -EINVAL) {
827                 printf("%d: expected 0 stats, got return %d\n", __LINE__, ret);
828                 return -1;
829         }
830
831         ret = rte_event_dev_xstats_get(evdev,
832                                         RTE_EVENT_DEV_XSTATS_QUEUE,
833                                         0, ids, values, ret);
834         if (ret != 13) {
835                 printf("%d: expected 13 stats, got return %d\n", __LINE__, ret);
836                 return -1;
837         }
838
839         /* enqueue packets to check values */
840         for (i = 0; i < 3; i++) {
841                 struct rte_event ev;
842                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
843                 if (!arp) {
844                         printf("%d: gen of pkt failed\n", __LINE__);
845                         return -1;
846                 }
847                 ev.queue_id = t->qid[i];
848                 ev.op = RTE_EVENT_OP_NEW;
849                 ev.mbuf = arp;
850                 ev.flow_id = 7;
851                 arp->seqn = i;
852
853                 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
854                 if (err != 1) {
855                         printf("%d: Failed to enqueue\n", __LINE__);
856                         return -1;
857                 }
858         }
859
860         rte_event_schedule(evdev);
861
862         /* Device names / values */
863         int num_stats = rte_event_dev_xstats_names_get(evdev,
864                                         RTE_EVENT_DEV_XSTATS_DEVICE, 0,
865                                         xstats_names, ids, XSTATS_MAX);
866         if (num_stats < 0)
867                 goto fail;
868         ret = rte_event_dev_xstats_get(evdev,
869                                         RTE_EVENT_DEV_XSTATS_DEVICE,
870                                         0, ids, values, num_stats);
871         static const uint64_t expected[] = {3, 3, 0, 1, 0, 0};
872         for (i = 0; (signed int)i < ret; i++) {
873                 if (expected[i] != values[i]) {
874                         printf(
875                                 "%d Error xstat %d (id %d) %s : %"PRIu64
876                                 ", expect %"PRIu64"\n",
877                                 __LINE__, i, ids[i], xstats_names[i].name,
878                                 values[i], expected[i]);
879                         goto fail;
880                 }
881         }
882
883         ret = rte_event_dev_xstats_reset(evdev, RTE_EVENT_DEV_XSTATS_DEVICE,
884                                         0, NULL, 0);
885
886         /* ensure reset statistics are zero-ed */
887         static const uint64_t expected_zero[] = {0, 0, 0, 0, 0, 0};
888         ret = rte_event_dev_xstats_get(evdev,
889                                         RTE_EVENT_DEV_XSTATS_DEVICE,
890                                         0, ids, values, num_stats);
891         for (i = 0; (signed int)i < ret; i++) {
892                 if (expected_zero[i] != values[i]) {
893                         printf(
894                                 "%d Error, xstat %d (id %d) %s : %"PRIu64
895                                 ", expect %"PRIu64"\n",
896                                 __LINE__, i, ids[i], xstats_names[i].name,
897                                 values[i], expected_zero[i]);
898                         goto fail;
899                 }
900         }
901
902         /* port reset checks */
903         num_stats = rte_event_dev_xstats_names_get(evdev,
904                                         RTE_EVENT_DEV_XSTATS_PORT, 0,
905                                         xstats_names, ids, XSTATS_MAX);
906         if (num_stats < 0)
907                 goto fail;
908         ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_PORT,
909                                         0, ids, values, num_stats);
910
911         static const uint64_t port_expected[] = {
912                 3 /* rx */,
913                 0 /* tx */,
914                 0 /* drop */,
915                 0 /* inflights */,
916                 0 /* avg pkt cycles */,
917                 29 /* credits */,
918                 0 /* rx ring used */,
919                 4096 /* rx ring free */,
920                 0 /* cq ring used */,
921                 32 /* cq ring free */,
922                 0 /* dequeue calls */,
923                 /* 10 dequeue burst buckets */
924                 0, 0, 0, 0, 0,
925                 0, 0, 0, 0, 0,
926         };
927         if (ret != RTE_DIM(port_expected)) {
928                 printf(
929                         "%s %d: wrong number of port stats (%d), expected %zu\n",
930                         __func__, __LINE__, ret, RTE_DIM(port_expected));
931         }
932
933         for (i = 0; (signed int)i < ret; i++) {
934                 if (port_expected[i] != values[i]) {
935                         printf(
936                                 "%s : %d: Error stat %s is %"PRIu64
937                                 ", expected %"PRIu64"\n",
938                                 __func__, __LINE__, xstats_names[i].name,
939                                 values[i], port_expected[i]);
940                         goto fail;
941                 }
942         }
943
944         ret = rte_event_dev_xstats_reset(evdev, RTE_EVENT_DEV_XSTATS_PORT,
945                                         0, NULL, 0);
946
947         /* ensure reset statistics are zero-ed */
948         static const uint64_t port_expected_zero[] = {
949                 0 /* rx */,
950                 0 /* tx */,
951                 0 /* drop */,
952                 0 /* inflights */,
953                 0 /* avg pkt cycles */,
954                 29 /* credits */,
955                 0 /* rx ring used */,
956                 4096 /* rx ring free */,
957                 0 /* cq ring used */,
958                 32 /* cq ring free */,
959                 0 /* dequeue calls */,
960                 /* 10 dequeue burst buckets */
961                 0, 0, 0, 0, 0,
962                 0, 0, 0, 0, 0,
963         };
964         ret = rte_event_dev_xstats_get(evdev,
965                                         RTE_EVENT_DEV_XSTATS_PORT,
966                                         0, ids, values, num_stats);
967         for (i = 0; (signed int)i < ret; i++) {
968                 if (port_expected_zero[i] != values[i]) {
969                         printf(
970                                 "%d, Error, xstat %d (id %d) %s : %"PRIu64
971                                 ", expect %"PRIu64"\n",
972                                 __LINE__, i, ids[i], xstats_names[i].name,
973                                 values[i], port_expected_zero[i]);
974                         goto fail;
975                 }
976         }
977
978         /* QUEUE STATS TESTS */
979         num_stats = rte_event_dev_xstats_names_get(evdev,
980                                                 RTE_EVENT_DEV_XSTATS_QUEUE, 0,
981                                                 xstats_names, ids, XSTATS_MAX);
982         ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE,
983                                         0, ids, values, num_stats);
984         if (ret < 0) {
985                 printf("xstats get returned %d\n", ret);
986                 goto fail;
987         }
988         if ((unsigned int)ret > XSTATS_MAX)
989                 printf("%s %d: more xstats available than space\n",
990                                 __func__, __LINE__);
991
992         static const uint64_t queue_expected[] = {
993                 3 /* rx */,
994                 3 /* tx */,
995                 0 /* drop */,
996                 3 /* inflights */,
997                 512 /* iq size */,
998                 0, 0, 0, 0, /* iq 0, 1, 2, 3 used */
999                 0, 0, 1, 0, /* qid_0_port_X_pinned_flows */
1000         };
1001         for (i = 0; (signed int)i < ret; i++) {
1002                 if (queue_expected[i] != values[i]) {
1003                         printf(
1004                                 "%d, Error, xstat %d (id %d) %s : %"PRIu64
1005                                 ", expect %"PRIu64"\n",
1006                                 __LINE__, i, ids[i], xstats_names[i].name,
1007                                 values[i], queue_expected[i]);
1008                         goto fail;
1009                 }
1010         }
1011
1012         /* Reset the queue stats here */
1013         ret = rte_event_dev_xstats_reset(evdev,
1014                                         RTE_EVENT_DEV_XSTATS_QUEUE, 0,
1015                                         NULL,
1016                                         0);
1017
1018         /* Verify that the resetable stats are reset, and others are not */
1019         static const uint64_t queue_expected_zero[] = {
1020                 0 /* rx */,
1021                 0 /* tx */,
1022                 0 /* drop */,
1023                 3 /* inflight */,
1024                 512 /* iq size */,
1025                 0, 0, 0, 0, /* 4 iq used */
1026                 0, 0, 1, 0, /* qid to port pinned flows */
1027         };
1028
1029         ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE, 0,
1030                                         ids, values, num_stats);
1031         int fails = 0;
1032         for (i = 0; (signed int)i < ret; i++) {
1033                 if (queue_expected_zero[i] != values[i]) {
1034                         printf(
1035                                 "%d, Error, xstat %d (id %d) %s : %"PRIu64
1036                                 ", expect %"PRIu64"\n",
1037                                 __LINE__, i, ids[i], xstats_names[i].name,
1038                                 values[i], queue_expected_zero[i]);
1039                         fails++;
1040                 }
1041         }
1042         if (fails) {
1043                 printf("%d : %d of values were not as expected above\n",
1044                                 __LINE__, fails);
1045                 goto fail;
1046         }
1047
1048         cleanup(t);
1049         return 0;
1050
1051 fail:
1052         rte_event_dev_dump(0, stdout);
1053         cleanup(t);
1054         return -1;
1055 }
1056
1057
1058 static int
1059 xstats_id_abuse_tests(struct test *t)
1060 {
1061         int err;
1062         const uint32_t XSTATS_MAX = 1024;
1063         const uint32_t link_port = 2;
1064
1065         uint32_t ids[XSTATS_MAX];
1066         struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
1067
1068         /* Create instance with 4 ports */
1069         if (init(t, 1, 4) < 0 ||
1070                         create_ports(t, 4) < 0 ||
1071                         create_atomic_qids(t, 1) < 0) {
1072                 printf("%d: Error initializing device\n", __LINE__);
1073                 goto fail;
1074         }
1075
1076         err = rte_event_port_link(evdev, t->port[link_port], NULL, NULL, 0);
1077         if (err != 1) {
1078                 printf("%d: error mapping lb qid\n", __LINE__);
1079                 goto fail;
1080         }
1081
1082         if (rte_event_dev_start(evdev) < 0) {
1083                 printf("%d: Error with start call\n", __LINE__);
1084                 goto fail;
1085         }
1086
1087         /* no test for device, as it ignores the port/q number */
1088         int num_stats = rte_event_dev_xstats_names_get(evdev,
1089                                         RTE_EVENT_DEV_XSTATS_PORT,
1090                                         UINT8_MAX-1, xstats_names, ids,
1091                                         XSTATS_MAX);
1092         if (num_stats != 0) {
1093                 printf("%d: expected %d stats, got return %d\n", __LINE__,
1094                                 0, num_stats);
1095                 goto fail;
1096         }
1097
1098         num_stats = rte_event_dev_xstats_names_get(evdev,
1099                                         RTE_EVENT_DEV_XSTATS_QUEUE,
1100                                         UINT8_MAX-1, xstats_names, ids,
1101                                         XSTATS_MAX);
1102         if (num_stats != 0) {
1103                 printf("%d: expected %d stats, got return %d\n", __LINE__,
1104                                 0, num_stats);
1105                 goto fail;
1106         }
1107
1108         cleanup(t);
1109         return 0;
1110 fail:
1111         cleanup(t);
1112         return -1;
1113 }
1114
1115 static int
1116 port_reconfig_credits(struct test *t)
1117 {
1118         if (init(t, 1, 1) < 0) {
1119                 printf("%d: Error initializing device\n", __LINE__);
1120                 return -1;
1121         }
1122
1123         uint32_t i;
1124         const uint32_t NUM_ITERS = 32;
1125         for (i = 0; i < NUM_ITERS; i++) {
1126                 const struct rte_event_queue_conf conf = {
1127                         .event_queue_cfg = RTE_EVENT_QUEUE_CFG_ATOMIC_ONLY,
1128                         .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1129                         .nb_atomic_flows = 1024,
1130                         .nb_atomic_order_sequences = 1024,
1131                 };
1132                 if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1133                         printf("%d: error creating qid\n", __LINE__);
1134                         return -1;
1135                 }
1136                 t->qid[0] = 0;
1137
1138                 static const struct rte_event_port_conf port_conf = {
1139                                 .new_event_threshold = 128,
1140                                 .dequeue_depth = 32,
1141                                 .enqueue_depth = 64,
1142                 };
1143                 if (rte_event_port_setup(evdev, 0, &port_conf) < 0) {
1144                         printf("%d Error setting up port\n", __LINE__);
1145                         return -1;
1146                 }
1147
1148                 int links = rte_event_port_link(evdev, 0, NULL, NULL, 0);
1149                 if (links != 1) {
1150                         printf("%d: error mapping lb qid\n", __LINE__);
1151                         goto fail;
1152                 }
1153
1154                 if (rte_event_dev_start(evdev) < 0) {
1155                         printf("%d: Error with start call\n", __LINE__);
1156                         goto fail;
1157                 }
1158
1159                 const uint32_t NPKTS = 1;
1160                 uint32_t j;
1161                 for (j = 0; j < NPKTS; j++) {
1162                         struct rte_event ev;
1163                         struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1164                         if (!arp) {
1165                                 printf("%d: gen of pkt failed\n", __LINE__);
1166                                 goto fail;
1167                         }
1168                         ev.queue_id = t->qid[0];
1169                         ev.op = RTE_EVENT_OP_NEW;
1170                         ev.mbuf = arp;
1171                         int err = rte_event_enqueue_burst(evdev, 0, &ev, 1);
1172                         if (err != 1) {
1173                                 printf("%d: Failed to enqueue\n", __LINE__);
1174                                 rte_event_dev_dump(0, stdout);
1175                                 goto fail;
1176                         }
1177                 }
1178
1179                 rte_event_schedule(evdev);
1180
1181                 struct rte_event ev[NPKTS];
1182                 int deq = rte_event_dequeue_burst(evdev, t->port[0], ev,
1183                                                         NPKTS, 0);
1184                 if (deq != 1)
1185                         printf("%d error; no packet dequeued\n", __LINE__);
1186
1187                 /* let cleanup below stop the device on last iter */
1188                 if (i != NUM_ITERS-1)
1189                         rte_event_dev_stop(evdev);
1190         }
1191
1192         cleanup(t);
1193         return 0;
1194 fail:
1195         cleanup(t);
1196         return -1;
1197 }
1198
1199 static int
1200 port_single_lb_reconfig(struct test *t)
1201 {
1202         if (init(t, 2, 2) < 0) {
1203                 printf("%d: Error initializing device\n", __LINE__);
1204                 goto fail;
1205         }
1206
1207         static const struct rte_event_queue_conf conf_lb_atomic = {
1208                 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1209                 .event_queue_cfg = RTE_EVENT_QUEUE_CFG_ATOMIC_ONLY,
1210                 .nb_atomic_flows = 1024,
1211                 .nb_atomic_order_sequences = 1024,
1212         };
1213         if (rte_event_queue_setup(evdev, 0, &conf_lb_atomic) < 0) {
1214                 printf("%d: error creating qid\n", __LINE__);
1215                 goto fail;
1216         }
1217
1218         static const struct rte_event_queue_conf conf_single_link = {
1219                 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1220                 .event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK,
1221                 .nb_atomic_flows = 1024,
1222                 .nb_atomic_order_sequences = 1024,
1223         };
1224         if (rte_event_queue_setup(evdev, 1, &conf_single_link) < 0) {
1225                 printf("%d: error creating qid\n", __LINE__);
1226                 goto fail;
1227         }
1228
1229         struct rte_event_port_conf port_conf = {
1230                 .new_event_threshold = 128,
1231                 .dequeue_depth = 32,
1232                 .enqueue_depth = 64,
1233         };
1234         if (rte_event_port_setup(evdev, 0, &port_conf) < 0) {
1235                 printf("%d Error setting up port\n", __LINE__);
1236                 goto fail;
1237         }
1238         if (rte_event_port_setup(evdev, 1, &port_conf) < 0) {
1239                 printf("%d Error setting up port\n", __LINE__);
1240                 goto fail;
1241         }
1242
1243         /* link port to lb queue */
1244         uint8_t queue_id = 0;
1245         if (rte_event_port_link(evdev, 0, &queue_id, NULL, 1) != 1) {
1246                 printf("%d: error creating link for qid\n", __LINE__);
1247                 goto fail;
1248         }
1249
1250         int ret = rte_event_port_unlink(evdev, 0, &queue_id, 1);
1251         if (ret != 1) {
1252                 printf("%d: Error unlinking lb port\n", __LINE__);
1253                 goto fail;
1254         }
1255
1256         queue_id = 1;
1257         if (rte_event_port_link(evdev, 0, &queue_id, NULL, 1) != 1) {
1258                 printf("%d: error creating link for qid\n", __LINE__);
1259                 goto fail;
1260         }
1261
1262         queue_id = 0;
1263         int err = rte_event_port_link(evdev, 1, &queue_id, NULL, 1);
1264         if (err != 1) {
1265                 printf("%d: error mapping lb qid\n", __LINE__);
1266                 goto fail;
1267         }
1268
1269         if (rte_event_dev_start(evdev) < 0) {
1270                 printf("%d: Error with start call\n", __LINE__);
1271                 goto fail;
1272         }
1273
1274         cleanup(t);
1275         return 0;
1276 fail:
1277         cleanup(t);
1278         return -1;
1279 }
1280
1281 static int
1282 xstats_brute_force(struct test *t)
1283 {
1284         uint32_t i;
1285         const uint32_t XSTATS_MAX = 1024;
1286         uint32_t ids[XSTATS_MAX];
1287         uint64_t values[XSTATS_MAX];
1288         struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
1289
1290
1291         /* Create instance with 4 ports */
1292         if (init(t, 1, 4) < 0 ||
1293                         create_ports(t, 4) < 0 ||
1294                         create_atomic_qids(t, 1) < 0) {
1295                 printf("%d: Error initializing device\n", __LINE__);
1296                 return -1;
1297         }
1298
1299         int err = rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1300         if (err != 1) {
1301                 printf("%d: error mapping lb qid\n", __LINE__);
1302                 goto fail;
1303         }
1304
1305         if (rte_event_dev_start(evdev) < 0) {
1306                 printf("%d: Error with start call\n", __LINE__);
1307                 goto fail;
1308         }
1309
1310         for (i = 0; i < XSTATS_MAX; i++)
1311                 ids[i] = i;
1312
1313         for (i = 0; i < 3; i++) {
1314                 uint32_t mode = RTE_EVENT_DEV_XSTATS_DEVICE + i;
1315                 uint32_t j;
1316                 for (j = 0; j < UINT8_MAX; j++) {
1317                         rte_event_dev_xstats_names_get(evdev, mode,
1318                                 j, xstats_names, ids, XSTATS_MAX);
1319
1320                         rte_event_dev_xstats_get(evdev, mode, j, ids,
1321                                                  values, XSTATS_MAX);
1322                 }
1323         }
1324
1325         cleanup(t);
1326         return 0;
1327 fail:
1328         cleanup(t);
1329         return -1;
1330 }
1331
1332 static int
1333 xstats_id_reset_tests(struct test *t)
1334 {
1335         const int wrk_enq = 2;
1336         int err;
1337
1338         /* Create instance with 4 ports */
1339         if (init(t, 1, 4) < 0 ||
1340                         create_ports(t, 4) < 0 ||
1341                         create_atomic_qids(t, 1) < 0) {
1342                 printf("%d: Error initializing device\n", __LINE__);
1343                 return -1;
1344         }
1345
1346         /* CQ mapping to QID */
1347         err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
1348         if (err != 1) {
1349                 printf("%d: error mapping lb qid\n", __LINE__);
1350                 goto fail;
1351         }
1352
1353         if (rte_event_dev_start(evdev) < 0) {
1354                 printf("%d: Error with start call\n", __LINE__);
1355                 goto fail;
1356         }
1357
1358 #define XSTATS_MAX 1024
1359         int ret;
1360         uint32_t i;
1361         uint32_t ids[XSTATS_MAX];
1362         uint64_t values[XSTATS_MAX];
1363         struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
1364
1365         for (i = 0; i < XSTATS_MAX; i++)
1366                 ids[i] = i;
1367
1368 #define NUM_DEV_STATS 6
1369         /* Device names / values */
1370         int num_stats = rte_event_dev_xstats_names_get(evdev,
1371                                         RTE_EVENT_DEV_XSTATS_DEVICE,
1372                                         0, xstats_names, ids, XSTATS_MAX);
1373         if (num_stats != NUM_DEV_STATS) {
1374                 printf("%d: expected %d stats, got return %d\n", __LINE__,
1375                                 NUM_DEV_STATS, num_stats);
1376                 goto fail;
1377         }
1378         ret = rte_event_dev_xstats_get(evdev,
1379                                         RTE_EVENT_DEV_XSTATS_DEVICE,
1380                                         0, ids, values, num_stats);
1381         if (ret != NUM_DEV_STATS) {
1382                 printf("%d: expected %d stats, got return %d\n", __LINE__,
1383                                 NUM_DEV_STATS, ret);
1384                 goto fail;
1385         }
1386
1387 #define NPKTS 7
1388         for (i = 0; i < NPKTS; i++) {
1389                 struct rte_event ev;
1390                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1391                 if (!arp) {
1392                         printf("%d: gen of pkt failed\n", __LINE__);
1393                         goto fail;
1394                 }
1395                 ev.queue_id = t->qid[i];
1396                 ev.op = RTE_EVENT_OP_NEW;
1397                 ev.mbuf = arp;
1398                 arp->seqn = i;
1399
1400                 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
1401                 if (err != 1) {
1402                         printf("%d: Failed to enqueue\n", __LINE__);
1403                         goto fail;
1404                 }
1405         }
1406
1407         rte_event_schedule(evdev);
1408
1409         static const char * const dev_names[] = {
1410                 "dev_rx", "dev_tx", "dev_drop", "dev_sched_calls",
1411                 "dev_sched_no_iq_enq", "dev_sched_no_cq_enq",
1412         };
1413         uint64_t dev_expected[] = {NPKTS, NPKTS, 0, 1, 0, 0};
1414         for (i = 0; (int)i < ret; i++) {
1415                 unsigned int id;
1416                 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1417                                                                 dev_names[i],
1418                                                                 &id);
1419                 if (id != i) {
1420                         printf("%d: %s id incorrect, expected %d got %d\n",
1421                                         __LINE__, dev_names[i], i, id);
1422                         goto fail;
1423                 }
1424                 if (val != dev_expected[i]) {
1425                         printf("%d: %s value incorrect, expected %"
1426                                 PRIu64" got %d\n", __LINE__, dev_names[i],
1427                                 dev_expected[i], id);
1428                         goto fail;
1429                 }
1430                 /* reset to zero */
1431                 int reset_ret = rte_event_dev_xstats_reset(evdev,
1432                                                 RTE_EVENT_DEV_XSTATS_DEVICE, 0,
1433                                                 &id,
1434                                                 1);
1435                 if (reset_ret) {
1436                         printf("%d: failed to reset successfully\n", __LINE__);
1437                         goto fail;
1438                 }
1439                 dev_expected[i] = 0;
1440                 /* check value again */
1441                 val = rte_event_dev_xstats_by_name_get(evdev, dev_names[i], 0);
1442                 if (val != dev_expected[i]) {
1443                         printf("%d: %s value incorrect, expected %"PRIu64
1444                                 " got %"PRIu64"\n", __LINE__, dev_names[i],
1445                                 dev_expected[i], val);
1446                         goto fail;
1447                 }
1448         };
1449
1450 /* 48 is stat offset from start of the devices whole xstats.
1451  * This WILL break every time we add a statistic to a port
1452  * or the device, but there is no other way to test
1453  */
1454 #define PORT_OFF 48
1455 /* num stats for the tested port. CQ size adds more stats to a port */
1456 #define NUM_PORT_STATS 21
1457 /* the port to test. */
1458 #define PORT 2
1459         num_stats = rte_event_dev_xstats_names_get(evdev,
1460                                         RTE_EVENT_DEV_XSTATS_PORT, PORT,
1461                                         xstats_names, ids, XSTATS_MAX);
1462         if (num_stats != NUM_PORT_STATS) {
1463                 printf("%d: expected %d stats, got return %d\n",
1464                         __LINE__, NUM_PORT_STATS, num_stats);
1465                 goto fail;
1466         }
1467         ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_PORT, PORT,
1468                                         ids, values, num_stats);
1469
1470         if (ret != NUM_PORT_STATS) {
1471                 printf("%d: expected %d stats, got return %d\n",
1472                                 __LINE__, NUM_PORT_STATS, ret);
1473                 goto fail;
1474         }
1475         static const char * const port_names[] = {
1476                 "port_2_rx",
1477                 "port_2_tx",
1478                 "port_2_drop",
1479                 "port_2_inflight",
1480                 "port_2_avg_pkt_cycles",
1481                 "port_2_credits",
1482                 "port_2_rx_ring_used",
1483                 "port_2_rx_ring_free",
1484                 "port_2_cq_ring_used",
1485                 "port_2_cq_ring_free",
1486                 "port_2_dequeue_calls",
1487                 "port_2_dequeues_returning_0",
1488                 "port_2_dequeues_returning_1-4",
1489                 "port_2_dequeues_returning_5-8",
1490                 "port_2_dequeues_returning_9-12",
1491                 "port_2_dequeues_returning_13-16",
1492                 "port_2_dequeues_returning_17-20",
1493                 "port_2_dequeues_returning_21-24",
1494                 "port_2_dequeues_returning_25-28",
1495                 "port_2_dequeues_returning_29-32",
1496                 "port_2_dequeues_returning_33-36",
1497         };
1498         uint64_t port_expected[] = {
1499                 0, /* rx */
1500                 NPKTS, /* tx */
1501                 0, /* drop */
1502                 NPKTS, /* inflight */
1503                 0, /* avg pkt cycles */
1504                 0, /* credits */
1505                 0, /* rx ring used */
1506                 4096, /* rx ring free */
1507                 NPKTS,  /* cq ring used */
1508                 25, /* cq ring free */
1509                 0, /* dequeue zero calls */
1510                 0, 0, 0, 0, 0, /* 10 dequeue buckets */
1511                 0, 0, 0, 0, 0,
1512         };
1513         uint64_t port_expected_zero[] = {
1514                 0, /* rx */
1515                 0, /* tx */
1516                 0, /* drop */
1517                 NPKTS, /* inflight */
1518                 0, /* avg pkt cycles */
1519                 0, /* credits */
1520                 0, /* rx ring used */
1521                 4096, /* rx ring free */
1522                 NPKTS,  /* cq ring used */
1523                 25, /* cq ring free */
1524                 0, /* dequeue zero calls */
1525                 0, 0, 0, 0, 0, /* 10 dequeue buckets */
1526                 0, 0, 0, 0, 0,
1527         };
1528         if (RTE_DIM(port_expected) != NUM_PORT_STATS ||
1529                         RTE_DIM(port_names) != NUM_PORT_STATS) {
1530                 printf("%d: port array of wrong size\n", __LINE__);
1531                 goto fail;
1532         }
1533
1534         int failed = 0;
1535         for (i = 0; (int)i < ret; i++) {
1536                 unsigned int id;
1537                 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1538                                                                 port_names[i],
1539                                                                 &id);
1540                 if (id != i + PORT_OFF) {
1541                         printf("%d: %s id incorrect, expected %d got %d\n",
1542                                         __LINE__, port_names[i], i+PORT_OFF,
1543                                         id);
1544                         failed = 1;
1545                 }
1546                 if (val != port_expected[i]) {
1547                         printf("%d: %s value incorrect, expected %"PRIu64
1548                                 " got %d\n", __LINE__, port_names[i],
1549                                 port_expected[i], id);
1550                         failed = 1;
1551                 }
1552                 /* reset to zero */
1553                 int reset_ret = rte_event_dev_xstats_reset(evdev,
1554                                                 RTE_EVENT_DEV_XSTATS_PORT, PORT,
1555                                                 &id,
1556                                                 1);
1557                 if (reset_ret) {
1558                         printf("%d: failed to reset successfully\n", __LINE__);
1559                         failed = 1;
1560                 }
1561                 /* check value again */
1562                 val = rte_event_dev_xstats_by_name_get(evdev, port_names[i], 0);
1563                 if (val != port_expected_zero[i]) {
1564                         printf("%d: %s value incorrect, expected %"PRIu64
1565                                 " got %"PRIu64"\n", __LINE__, port_names[i],
1566                                 port_expected_zero[i], val);
1567                         failed = 1;
1568                 }
1569         };
1570         if (failed)
1571                 goto fail;
1572
1573 /* num queue stats */
1574 #define NUM_Q_STATS 13
1575 /* queue offset from start of the devices whole xstats.
1576  * This will break every time we add a statistic to a device/port/queue
1577  */
1578 #define QUEUE_OFF 90
1579         const uint32_t queue = 0;
1580         num_stats = rte_event_dev_xstats_names_get(evdev,
1581                                         RTE_EVENT_DEV_XSTATS_QUEUE, queue,
1582                                         xstats_names, ids, XSTATS_MAX);
1583         if (num_stats != NUM_Q_STATS) {
1584                 printf("%d: expected %d stats, got return %d\n",
1585                         __LINE__, NUM_Q_STATS, num_stats);
1586                 goto fail;
1587         }
1588         ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE,
1589                                         queue, ids, values, num_stats);
1590         if (ret != NUM_Q_STATS) {
1591                 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
1592                 goto fail;
1593         }
1594         static const char * const queue_names[] = {
1595                 "qid_0_rx",
1596                 "qid_0_tx",
1597                 "qid_0_drop",
1598                 "qid_0_inflight",
1599                 "qid_0_iq_size",
1600                 "qid_0_iq_0_used",
1601                 "qid_0_iq_1_used",
1602                 "qid_0_iq_2_used",
1603                 "qid_0_iq_3_used",
1604                 "qid_0_port_0_pinned_flows",
1605                 "qid_0_port_1_pinned_flows",
1606                 "qid_0_port_2_pinned_flows",
1607                 "qid_0_port_3_pinned_flows",
1608         };
1609         uint64_t queue_expected[] = {
1610                 7, /* rx */
1611                 7, /* tx */
1612                 0, /* drop */
1613                 7, /* inflight */
1614                 512, /* iq size */
1615                 0, /* iq 0 used */
1616                 0, /* iq 1 used */
1617                 0, /* iq 2 used */
1618                 0, /* iq 3 used */
1619                 0, /* qid 0 port 0 pinned flows */
1620                 0, /* qid 0 port 1 pinned flows */
1621                 1, /* qid 0 port 2 pinned flows */
1622                 0, /* qid 0 port 4 pinned flows */
1623         };
1624         uint64_t queue_expected_zero[] = {
1625                 0, /* rx */
1626                 0, /* tx */
1627                 0, /* drop */
1628                 7, /* inflight */
1629                 512, /* iq size */
1630                 0, /* iq 0 used */
1631                 0, /* iq 1 used */
1632                 0, /* iq 2 used */
1633                 0, /* iq 3 used */
1634                 0, /* qid 0 port 0 pinned flows */
1635                 0, /* qid 0 port 1 pinned flows */
1636                 1, /* qid 0 port 2 pinned flows */
1637                 0, /* qid 0 port 4 pinned flows */
1638         };
1639         if (RTE_DIM(queue_expected) != NUM_Q_STATS ||
1640                         RTE_DIM(queue_names) != NUM_Q_STATS) {
1641                 printf("%d : queue array of wrong size\n", __LINE__);
1642                 goto fail;
1643         }
1644
1645         failed = 0;
1646         for (i = 0; (int)i < ret; i++) {
1647                 unsigned int id;
1648                 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1649                                                                 queue_names[i],
1650                                                                 &id);
1651                 if (id != i + QUEUE_OFF) {
1652                         printf("%d: %s id incorrect, expected %d got %d\n",
1653                                         __LINE__, queue_names[i], i+QUEUE_OFF,
1654                                         id);
1655                         failed = 1;
1656                 }
1657                 if (val != queue_expected[i]) {
1658                         printf("%d: %s value incorrect, expected %"PRIu64
1659                                 " got %d\n", __LINE__, queue_names[i],
1660                                 queue_expected[i], id);
1661                         failed = 1;
1662                 }
1663                 /* reset to zero */
1664                 int reset_ret = rte_event_dev_xstats_reset(evdev,
1665                                                 RTE_EVENT_DEV_XSTATS_QUEUE,
1666                                                 queue, &id, 1);
1667                 if (reset_ret) {
1668                         printf("%d: failed to reset successfully\n", __LINE__);
1669                         failed = 1;
1670                 }
1671                 /* check value again */
1672                 val = rte_event_dev_xstats_by_name_get(evdev, queue_names[i],
1673                                                         0);
1674                 if (val != queue_expected_zero[i]) {
1675                         printf("%d: %s value incorrect, expected %"PRIu64
1676                                 " got %"PRIu64"\n", __LINE__, queue_names[i],
1677                                 queue_expected_zero[i], val);
1678                         failed = 1;
1679                 }
1680         };
1681
1682         if (failed)
1683                 goto fail;
1684
1685         cleanup(t);
1686         return 0;
1687 fail:
1688         cleanup(t);
1689         return -1;
1690 }
1691
1692 static int
1693 ordered_reconfigure(struct test *t)
1694 {
1695         if (init(t, 1, 1) < 0 ||
1696                         create_ports(t, 1) < 0) {
1697                 printf("%d: Error initializing device\n", __LINE__);
1698                 return -1;
1699         }
1700
1701         const struct rte_event_queue_conf conf = {
1702                         .event_queue_cfg = RTE_EVENT_QUEUE_CFG_ORDERED_ONLY,
1703                         .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1704                         .nb_atomic_flows = 1024,
1705                         .nb_atomic_order_sequences = 1024,
1706         };
1707
1708         if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1709                 printf("%d: error creating qid\n", __LINE__);
1710                 goto failed;
1711         }
1712
1713         if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1714                 printf("%d: error creating qid, for 2nd time\n", __LINE__);
1715                 goto failed;
1716         }
1717
1718         rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1719         if (rte_event_dev_start(evdev) < 0) {
1720                 printf("%d: Error with start call\n", __LINE__);
1721                 return -1;
1722         }
1723
1724         cleanup(t);
1725         return 0;
1726 failed:
1727         cleanup(t);
1728         return -1;
1729 }
1730
1731 static int
1732 qid_priorities(struct test *t)
1733 {
1734         /* Test works by having a CQ with enough empty space for all packets,
1735          * and enqueueing 3 packets to 3 QIDs. They must return based on the
1736          * priority of the QID, not the ingress order, to pass the test
1737          */
1738         unsigned int i;
1739         /* Create instance with 1 ports, and 3 qids */
1740         if (init(t, 3, 1) < 0 ||
1741                         create_ports(t, 1) < 0) {
1742                 printf("%d: Error initializing device\n", __LINE__);
1743                 return -1;
1744         }
1745
1746         for (i = 0; i < 3; i++) {
1747                 /* Create QID */
1748                 const struct rte_event_queue_conf conf = {
1749                         .event_queue_cfg = RTE_EVENT_QUEUE_CFG_ATOMIC_ONLY,
1750                         /* increase priority (0 == highest), as we go */
1751                         .priority = RTE_EVENT_DEV_PRIORITY_NORMAL - i,
1752                         .nb_atomic_flows = 1024,
1753                         .nb_atomic_order_sequences = 1024,
1754                 };
1755
1756                 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
1757                         printf("%d: error creating qid %d\n", __LINE__, i);
1758                         return -1;
1759                 }
1760                 t->qid[i] = i;
1761         }
1762         t->nb_qids = i;
1763         /* map all QIDs to port */
1764         rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1765
1766         if (rte_event_dev_start(evdev) < 0) {
1767                 printf("%d: Error with start call\n", __LINE__);
1768                 return -1;
1769         }
1770
1771         /* enqueue 3 packets, setting seqn and QID to check priority */
1772         for (i = 0; i < 3; i++) {
1773                 struct rte_event ev;
1774                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1775                 if (!arp) {
1776                         printf("%d: gen of pkt failed\n", __LINE__);
1777                         return -1;
1778                 }
1779                 ev.queue_id = t->qid[i];
1780                 ev.op = RTE_EVENT_OP_NEW;
1781                 ev.mbuf = arp;
1782                 arp->seqn = i;
1783
1784                 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
1785                 if (err != 1) {
1786                         printf("%d: Failed to enqueue\n", __LINE__);
1787                         return -1;
1788                 }
1789         }
1790
1791         rte_event_schedule(evdev);
1792
1793         /* dequeue packets, verify priority was upheld */
1794         struct rte_event ev[32];
1795         uint32_t deq_pkts =
1796                 rte_event_dequeue_burst(evdev, t->port[0], ev, 32, 0);
1797         if (deq_pkts != 3) {
1798                 printf("%d: failed to deq packets\n", __LINE__);
1799                 rte_event_dev_dump(evdev, stdout);
1800                 return -1;
1801         }
1802         for (i = 0; i < 3; i++) {
1803                 if (ev[i].mbuf->seqn != 2-i) {
1804                         printf(
1805                                 "%d: qid priority test: seqn %d incorrectly prioritized\n",
1806                                         __LINE__, i);
1807                 }
1808         }
1809
1810         cleanup(t);
1811         return 0;
1812 }
1813
1814 static int
1815 load_balancing(struct test *t)
1816 {
1817         const int rx_enq = 0;
1818         int err;
1819         uint32_t i;
1820
1821         if (init(t, 1, 4) < 0 ||
1822                         create_ports(t, 4) < 0 ||
1823                         create_atomic_qids(t, 1) < 0) {
1824                 printf("%d: Error initializing device\n", __LINE__);
1825                 return -1;
1826         }
1827
1828         for (i = 0; i < 3; i++) {
1829                 /* map port 1 - 3 inclusive */
1830                 if (rte_event_port_link(evdev, t->port[i+1], &t->qid[0],
1831                                 NULL, 1) != 1) {
1832                         printf("%d: error mapping qid to port %d\n",
1833                                         __LINE__, i);
1834                         return -1;
1835                 }
1836         }
1837
1838         if (rte_event_dev_start(evdev) < 0) {
1839                 printf("%d: Error with start call\n", __LINE__);
1840                 return -1;
1841         }
1842
1843         /************** FORWARD ****************/
1844         /*
1845          * Create a set of flows that test the load-balancing operation of the
1846          * implementation. Fill CQ 0 and 1 with flows 0 and 1, and test
1847          * with a new flow, which should be sent to the 3rd mapped CQ
1848          */
1849         static uint32_t flows[] = {0, 1, 1, 0, 0, 2, 2, 0, 2};
1850
1851         for (i = 0; i < RTE_DIM(flows); i++) {
1852                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1853                 if (!arp) {
1854                         printf("%d: gen of pkt failed\n", __LINE__);
1855                         return -1;
1856                 }
1857
1858                 struct rte_event ev = {
1859                                 .op = RTE_EVENT_OP_NEW,
1860                                 .queue_id = t->qid[0],
1861                                 .flow_id = flows[i],
1862                                 .mbuf = arp,
1863                 };
1864                 /* generate pkt and enqueue */
1865                 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
1866                 if (err < 0) {
1867                         printf("%d: Failed to enqueue\n", __LINE__);
1868                         return -1;
1869                 }
1870         }
1871
1872         rte_event_schedule(evdev);
1873
1874         struct test_event_dev_stats stats;
1875         err = test_event_dev_stats_get(evdev, &stats);
1876         if (err) {
1877                 printf("%d: failed to get stats\n", __LINE__);
1878                 return -1;
1879         }
1880
1881         if (stats.port_inflight[1] != 4) {
1882                 printf("%d:%s: port 1 inflight not correct\n", __LINE__,
1883                                 __func__);
1884                 return -1;
1885         }
1886         if (stats.port_inflight[2] != 2) {
1887                 printf("%d:%s: port 2 inflight not correct\n", __LINE__,
1888                                 __func__);
1889                 return -1;
1890         }
1891         if (stats.port_inflight[3] != 3) {
1892                 printf("%d:%s: port 3 inflight not correct\n", __LINE__,
1893                                 __func__);
1894                 return -1;
1895         }
1896
1897         cleanup(t);
1898         return 0;
1899 }
1900
1901 static int
1902 load_balancing_history(struct test *t)
1903 {
1904         struct test_event_dev_stats stats = {0};
1905         const int rx_enq = 0;
1906         int err;
1907         uint32_t i;
1908
1909         /* Create instance with 1 atomic QID going to 3 ports + 1 prod port */
1910         if (init(t, 1, 4) < 0 ||
1911                         create_ports(t, 4) < 0 ||
1912                         create_atomic_qids(t, 1) < 0)
1913                 return -1;
1914
1915         /* CQ mapping to QID */
1916         if (rte_event_port_link(evdev, t->port[1], &t->qid[0], NULL, 1) != 1) {
1917                 printf("%d: error mapping port 1 qid\n", __LINE__);
1918                 return -1;
1919         }
1920         if (rte_event_port_link(evdev, t->port[2], &t->qid[0], NULL, 1) != 1) {
1921                 printf("%d: error mapping port 2 qid\n", __LINE__);
1922                 return -1;
1923         }
1924         if (rte_event_port_link(evdev, t->port[3], &t->qid[0], NULL, 1) != 1) {
1925                 printf("%d: error mapping port 3 qid\n", __LINE__);
1926                 return -1;
1927         }
1928         if (rte_event_dev_start(evdev) < 0) {
1929                 printf("%d: Error with start call\n", __LINE__);
1930                 return -1;
1931         }
1932
1933         /*
1934          * Create a set of flows that test the load-balancing operation of the
1935          * implementation. Fill CQ 0, 1 and 2 with flows 0, 1 and 2, drop
1936          * the packet from CQ 0, send in a new set of flows. Ensure that:
1937          *  1. The new flow 3 gets into the empty CQ0
1938          *  2. packets for existing flow gets added into CQ1
1939          *  3. Next flow 0 pkt is now onto CQ2, since CQ0 and CQ1 now contain
1940          *     more outstanding pkts
1941          *
1942          *  This test makes sure that when a flow ends (i.e. all packets
1943          *  have been completed for that flow), that the flow can be moved
1944          *  to a different CQ when new packets come in for that flow.
1945          */
1946         static uint32_t flows1[] = {0, 1, 1, 2};
1947
1948         for (i = 0; i < RTE_DIM(flows1); i++) {
1949                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1950                 struct rte_event ev = {
1951                                 .flow_id = flows1[i],
1952                                 .op = RTE_EVENT_OP_NEW,
1953                                 .queue_id = t->qid[0],
1954                                 .event_type = RTE_EVENT_TYPE_CPU,
1955                                 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1956                                 .mbuf = arp
1957                 };
1958
1959                 if (!arp) {
1960                         printf("%d: gen of pkt failed\n", __LINE__);
1961                         return -1;
1962                 }
1963                 arp->hash.rss = flows1[i];
1964                 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
1965                 if (err < 0) {
1966                         printf("%d: Failed to enqueue\n", __LINE__);
1967                         return -1;
1968                 }
1969         }
1970
1971         /* call the scheduler */
1972         rte_event_schedule(evdev);
1973
1974         /* Dequeue the flow 0 packet from port 1, so that we can then drop */
1975         struct rte_event ev;
1976         if (!rte_event_dequeue_burst(evdev, t->port[1], &ev, 1, 0)) {
1977                 printf("%d: failed to dequeue\n", __LINE__);
1978                 return -1;
1979         }
1980         if (ev.mbuf->hash.rss != flows1[0]) {
1981                 printf("%d: unexpected flow received\n", __LINE__);
1982                 return -1;
1983         }
1984
1985         /* drop the flow 0 packet from port 1 */
1986         rte_event_enqueue_burst(evdev, t->port[1], &release_ev, 1);
1987
1988         /* call the scheduler */
1989         rte_event_schedule(evdev);
1990
1991         /*
1992          * Set up the next set of flows, first a new flow to fill up
1993          * CQ 0, so that the next flow 0 packet should go to CQ2
1994          */
1995         static uint32_t flows2[] = { 3, 3, 3, 1, 1, 0 };
1996
1997         for (i = 0; i < RTE_DIM(flows2); i++) {
1998                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1999                 struct rte_event ev = {
2000                                 .flow_id = flows2[i],
2001                                 .op = RTE_EVENT_OP_NEW,
2002                                 .queue_id = t->qid[0],
2003                                 .event_type = RTE_EVENT_TYPE_CPU,
2004                                 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
2005                                 .mbuf = arp
2006                 };
2007
2008                 if (!arp) {
2009                         printf("%d: gen of pkt failed\n", __LINE__);
2010                         return -1;
2011                 }
2012                 arp->hash.rss = flows2[i];
2013
2014                 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2015                 if (err < 0) {
2016                         printf("%d: Failed to enqueue\n", __LINE__);
2017                         return -1;
2018                 }
2019         }
2020
2021         /* schedule */
2022         rte_event_schedule(evdev);
2023
2024         err = test_event_dev_stats_get(evdev, &stats);
2025         if (err) {
2026                 printf("%d:failed to get stats\n", __LINE__);
2027                 return -1;
2028         }
2029
2030         /*
2031          * Now check the resulting inflights on each port.
2032          */
2033         if (stats.port_inflight[1] != 3) {
2034                 printf("%d:%s: port 1 inflight not correct\n", __LINE__,
2035                                 __func__);
2036                 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2037                                 (unsigned int)stats.port_inflight[1],
2038                                 (unsigned int)stats.port_inflight[2],
2039                                 (unsigned int)stats.port_inflight[3]);
2040                 return -1;
2041         }
2042         if (stats.port_inflight[2] != 4) {
2043                 printf("%d:%s: port 2 inflight not correct\n", __LINE__,
2044                                 __func__);
2045                 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2046                                 (unsigned int)stats.port_inflight[1],
2047                                 (unsigned int)stats.port_inflight[2],
2048                                 (unsigned int)stats.port_inflight[3]);
2049                 return -1;
2050         }
2051         if (stats.port_inflight[3] != 2) {
2052                 printf("%d:%s: port 3 inflight not correct\n", __LINE__,
2053                                 __func__);
2054                 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2055                                 (unsigned int)stats.port_inflight[1],
2056                                 (unsigned int)stats.port_inflight[2],
2057                                 (unsigned int)stats.port_inflight[3]);
2058                 return -1;
2059         }
2060
2061         for (i = 1; i <= 3; i++) {
2062                 struct rte_event ev;
2063                 while (rte_event_dequeue_burst(evdev, i, &ev, 1, 0))
2064                         rte_event_enqueue_burst(evdev, i, &release_ev, 1);
2065         }
2066         rte_event_schedule(evdev);
2067
2068         cleanup(t);
2069         return 0;
2070 }
2071
2072 static int
2073 invalid_qid(struct test *t)
2074 {
2075         struct test_event_dev_stats stats;
2076         const int rx_enq = 0;
2077         int err;
2078         uint32_t i;
2079
2080         if (init(t, 1, 4) < 0 ||
2081                         create_ports(t, 4) < 0 ||
2082                         create_atomic_qids(t, 1) < 0) {
2083                 printf("%d: Error initializing device\n", __LINE__);
2084                 return -1;
2085         }
2086
2087         /* CQ mapping to QID */
2088         for (i = 0; i < 4; i++) {
2089                 err = rte_event_port_link(evdev, t->port[i], &t->qid[0],
2090                                 NULL, 1);
2091                 if (err != 1) {
2092                         printf("%d: error mapping port 1 qid\n", __LINE__);
2093                         return -1;
2094                 }
2095         }
2096
2097         if (rte_event_dev_start(evdev) < 0) {
2098                 printf("%d: Error with start call\n", __LINE__);
2099                 return -1;
2100         }
2101
2102         /*
2103          * Send in a packet with an invalid qid to the scheduler.
2104          * We should see the packed enqueued OK, but the inflights for
2105          * that packet should not be incremented, and the rx_dropped
2106          * should be incremented.
2107          */
2108         static uint32_t flows1[] = {20};
2109
2110         for (i = 0; i < RTE_DIM(flows1); i++) {
2111                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2112                 if (!arp) {
2113                         printf("%d: gen of pkt failed\n", __LINE__);
2114                         return -1;
2115                 }
2116
2117                 struct rte_event ev = {
2118                                 .op = RTE_EVENT_OP_NEW,
2119                                 .queue_id = t->qid[0] + flows1[i],
2120                                 .flow_id = i,
2121                                 .mbuf = arp,
2122                 };
2123                 /* generate pkt and enqueue */
2124                 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2125                 if (err < 0) {
2126                         printf("%d: Failed to enqueue\n", __LINE__);
2127                         return -1;
2128                 }
2129         }
2130
2131         /* call the scheduler */
2132         rte_event_schedule(evdev);
2133
2134         err = test_event_dev_stats_get(evdev, &stats);
2135         if (err) {
2136                 printf("%d: failed to get stats\n", __LINE__);
2137                 return -1;
2138         }
2139
2140         /*
2141          * Now check the resulting inflights on the port, and the rx_dropped.
2142          */
2143         if (stats.port_inflight[0] != 0) {
2144                 printf("%d:%s: port 1 inflight count not correct\n", __LINE__,
2145                                 __func__);
2146                 rte_event_dev_dump(evdev, stdout);
2147                 return -1;
2148         }
2149         if (stats.port_rx_dropped[0] != 1) {
2150                 printf("%d:%s: port 1 drops\n", __LINE__, __func__);
2151                 rte_event_dev_dump(evdev, stdout);
2152                 return -1;
2153         }
2154         /* each packet drop should only be counted in one place - port or dev */
2155         if (stats.rx_dropped != 0) {
2156                 printf("%d:%s: port 1 dropped count not correct\n", __LINE__,
2157                                 __func__);
2158                 rte_event_dev_dump(evdev, stdout);
2159                 return -1;
2160         }
2161
2162         cleanup(t);
2163         return 0;
2164 }
2165
2166 static int
2167 single_packet(struct test *t)
2168 {
2169         const uint32_t MAGIC_SEQN = 7321;
2170         struct rte_event ev;
2171         struct test_event_dev_stats stats;
2172         const int rx_enq = 0;
2173         const int wrk_enq = 2;
2174         int err;
2175
2176         /* Create instance with 4 ports */
2177         if (init(t, 1, 4) < 0 ||
2178                         create_ports(t, 4) < 0 ||
2179                         create_atomic_qids(t, 1) < 0) {
2180                 printf("%d: Error initializing device\n", __LINE__);
2181                 return -1;
2182         }
2183
2184         /* CQ mapping to QID */
2185         err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
2186         if (err != 1) {
2187                 printf("%d: error mapping lb qid\n", __LINE__);
2188                 cleanup(t);
2189                 return -1;
2190         }
2191
2192         if (rte_event_dev_start(evdev) < 0) {
2193                 printf("%d: Error with start call\n", __LINE__);
2194                 return -1;
2195         }
2196
2197         /************** Gen pkt and enqueue ****************/
2198         struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2199         if (!arp) {
2200                 printf("%d: gen of pkt failed\n", __LINE__);
2201                 return -1;
2202         }
2203
2204         ev.op = RTE_EVENT_OP_NEW;
2205         ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
2206         ev.mbuf = arp;
2207         ev.queue_id = 0;
2208         ev.flow_id = 3;
2209         arp->seqn = MAGIC_SEQN;
2210
2211         err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2212         if (err < 0) {
2213                 printf("%d: Failed to enqueue\n", __LINE__);
2214                 return -1;
2215         }
2216
2217         rte_event_schedule(evdev);
2218
2219         err = test_event_dev_stats_get(evdev, &stats);
2220         if (err) {
2221                 printf("%d: failed to get stats\n", __LINE__);
2222                 return -1;
2223         }
2224
2225         if (stats.rx_pkts != 1 ||
2226                         stats.tx_pkts != 1 ||
2227                         stats.port_inflight[wrk_enq] != 1) {
2228                 printf("%d: Sched core didn't handle pkt as expected\n",
2229                                 __LINE__);
2230                 rte_event_dev_dump(evdev, stdout);
2231                 return -1;
2232         }
2233
2234         uint32_t deq_pkts;
2235
2236         deq_pkts = rte_event_dequeue_burst(evdev, t->port[wrk_enq], &ev, 1, 0);
2237         if (deq_pkts < 1) {
2238                 printf("%d: Failed to deq\n", __LINE__);
2239                 return -1;
2240         }
2241
2242         err = test_event_dev_stats_get(evdev, &stats);
2243         if (err) {
2244                 printf("%d: failed to get stats\n", __LINE__);
2245                 return -1;
2246         }
2247
2248         err = test_event_dev_stats_get(evdev, &stats);
2249         if (ev.mbuf->seqn != MAGIC_SEQN) {
2250                 printf("%d: magic sequence number not dequeued\n", __LINE__);
2251                 return -1;
2252         }
2253
2254         rte_pktmbuf_free(ev.mbuf);
2255         err = rte_event_enqueue_burst(evdev, t->port[wrk_enq], &release_ev, 1);
2256         if (err < 0) {
2257                 printf("%d: Failed to enqueue\n", __LINE__);
2258                 return -1;
2259         }
2260         rte_event_schedule(evdev);
2261
2262         err = test_event_dev_stats_get(evdev, &stats);
2263         if (stats.port_inflight[wrk_enq] != 0) {
2264                 printf("%d: port inflight not correct\n", __LINE__);
2265                 return -1;
2266         }
2267
2268         cleanup(t);
2269         return 0;
2270 }
2271
2272 static int
2273 inflight_counts(struct test *t)
2274 {
2275         struct rte_event ev;
2276         struct test_event_dev_stats stats;
2277         const int rx_enq = 0;
2278         const int p1 = 1;
2279         const int p2 = 2;
2280         int err;
2281         int i;
2282
2283         /* Create instance with 4 ports */
2284         if (init(t, 2, 3) < 0 ||
2285                         create_ports(t, 3) < 0 ||
2286                         create_atomic_qids(t, 2) < 0) {
2287                 printf("%d: Error initializing device\n", __LINE__);
2288                 return -1;
2289         }
2290
2291         /* CQ mapping to QID */
2292         err = rte_event_port_link(evdev, t->port[p1], &t->qid[0], NULL, 1);
2293         if (err != 1) {
2294                 printf("%d: error mapping lb qid\n", __LINE__);
2295                 cleanup(t);
2296                 return -1;
2297         }
2298         err = rte_event_port_link(evdev, t->port[p2], &t->qid[1], NULL, 1);
2299         if (err != 1) {
2300                 printf("%d: error mapping lb qid\n", __LINE__);
2301                 cleanup(t);
2302                 return -1;
2303         }
2304
2305         if (rte_event_dev_start(evdev) < 0) {
2306                 printf("%d: Error with start call\n", __LINE__);
2307                 return -1;
2308         }
2309
2310         /************** FORWARD ****************/
2311 #define QID1_NUM 5
2312         for (i = 0; i < QID1_NUM; i++) {
2313                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2314
2315                 if (!arp) {
2316                         printf("%d: gen of pkt failed\n", __LINE__);
2317                         goto err;
2318                 }
2319
2320                 ev.queue_id =  t->qid[0];
2321                 ev.op = RTE_EVENT_OP_NEW;
2322                 ev.mbuf = arp;
2323                 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2324                 if (err != 1) {
2325                         printf("%d: Failed to enqueue\n", __LINE__);
2326                         goto err;
2327                 }
2328         }
2329 #define QID2_NUM 3
2330         for (i = 0; i < QID2_NUM; i++) {
2331                 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2332
2333                 if (!arp) {
2334                         printf("%d: gen of pkt failed\n", __LINE__);
2335                         goto err;
2336                 }
2337                 ev.queue_id =  t->qid[1];
2338                 ev.op = RTE_EVENT_OP_NEW;
2339                 ev.mbuf = arp;
2340                 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2341                 if (err != 1) {
2342                         printf("%d: Failed to enqueue\n", __LINE__);
2343                         goto err;
2344                 }
2345         }
2346
2347         /* schedule */
2348         rte_event_schedule(evdev);
2349
2350         err = test_event_dev_stats_get(evdev, &stats);
2351         if (err) {
2352                 printf("%d: failed to get stats\n", __LINE__);
2353                 goto err;
2354         }
2355
2356         if (stats.rx_pkts != QID1_NUM + QID2_NUM ||
2357                         stats.tx_pkts != QID1_NUM + QID2_NUM) {
2358                 printf("%d: Sched core didn't handle pkt as expected\n",
2359                                 __LINE__);
2360                 goto err;
2361         }
2362
2363         if (stats.port_inflight[p1] != QID1_NUM) {
2364                 printf("%d: %s port 1 inflight not correct\n", __LINE__,
2365                                 __func__);
2366                 goto err;
2367         }
2368         if (stats.port_inflight[p2] != QID2_NUM) {
2369                 printf("%d: %s port 2 inflight not correct\n", __LINE__,
2370                                 __func__);
2371                 goto err;
2372         }
2373
2374         /************** DEQUEUE INFLIGHT COUNT CHECKS  ****************/
2375         /* port 1 */
2376         struct rte_event events[QID1_NUM + QID2_NUM];
2377         uint32_t deq_pkts = rte_event_dequeue_burst(evdev, t->port[p1], events,
2378                         RTE_DIM(events), 0);
2379
2380         if (deq_pkts != QID1_NUM) {
2381                 printf("%d: Port 1: DEQUEUE inflight failed\n", __LINE__);
2382                 goto err;
2383         }
2384         err = test_event_dev_stats_get(evdev, &stats);
2385         if (stats.port_inflight[p1] != QID1_NUM) {
2386                 printf("%d: port 1 inflight decrement after DEQ != 0\n",
2387                                 __LINE__);
2388                 goto err;
2389         }
2390         for (i = 0; i < QID1_NUM; i++) {
2391                 err = rte_event_enqueue_burst(evdev, t->port[p1], &release_ev,
2392                                 1);
2393                 if (err != 1) {
2394                         printf("%d: %s rte enqueue of inf release failed\n",
2395                                 __LINE__, __func__);
2396                         goto err;
2397                 }
2398         }
2399
2400         /*
2401          * As the scheduler core decrements inflights, it needs to run to
2402          * process packets to act on the drop messages
2403          */
2404         rte_event_schedule(evdev);
2405
2406         err = test_event_dev_stats_get(evdev, &stats);
2407         if (stats.port_inflight[p1] != 0) {
2408                 printf("%d: port 1 inflight NON NULL after DROP\n", __LINE__);
2409                 goto err;
2410         }
2411
2412         /* port2 */
2413         deq_pkts = rte_event_dequeue_burst(evdev, t->port[p2], events,
2414                         RTE_DIM(events), 0);
2415         if (deq_pkts != QID2_NUM) {
2416                 printf("%d: Port 2: DEQUEUE inflight failed\n", __LINE__);
2417                 goto err;
2418         }
2419         err = test_event_dev_stats_get(evdev, &stats);
2420         if (stats.port_inflight[p2] != QID2_NUM) {
2421                 printf("%d: port 1 inflight decrement after DEQ != 0\n",
2422                                 __LINE__);
2423                 goto err;
2424         }
2425         for (i = 0; i < QID2_NUM; i++) {
2426                 err = rte_event_enqueue_burst(evdev, t->port[p2], &release_ev,
2427                                 1);
2428                 if (err != 1) {
2429                         printf("%d: %s rte enqueue of inf release failed\n",
2430                                 __LINE__, __func__);
2431                         goto err;
2432                 }
2433         }
2434
2435         /*
2436          * As the scheduler core decrements inflights, it needs to run to
2437          * process packets to act on the drop messages
2438          */
2439         rte_event_schedule(evdev);
2440
2441         err = test_event_dev_stats_get(evdev, &stats);
2442         if (stats.port_inflight[p2] != 0) {
2443                 printf("%d: port 2 inflight NON NULL after DROP\n", __LINE__);
2444                 goto err;
2445         }
2446         cleanup(t);
2447         return 0;
2448
2449 err:
2450         rte_event_dev_dump(evdev, stdout);
2451         cleanup(t);
2452         return -1;
2453 }
2454
2455 static int
2456 parallel_basic(struct test *t, int check_order)
2457 {
2458         const uint8_t rx_port = 0;
2459         const uint8_t w1_port = 1;
2460         const uint8_t w3_port = 3;
2461         const uint8_t tx_port = 4;
2462         int err;
2463         int i;
2464         uint32_t deq_pkts, j;
2465         struct rte_mbuf *mbufs[3];
2466         struct rte_mbuf *mbufs_out[3];
2467         const uint32_t MAGIC_SEQN = 1234;
2468
2469         /* Create instance with 4 ports */
2470         if (init(t, 2, tx_port + 1) < 0 ||
2471                         create_ports(t, tx_port + 1) < 0 ||
2472                         (check_order ?  create_ordered_qids(t, 1) :
2473                                 create_unordered_qids(t, 1)) < 0 ||
2474                         create_directed_qids(t, 1, &tx_port)) {
2475                 printf("%d: Error initializing device\n", __LINE__);
2476                 return -1;
2477         }
2478
2479         /*
2480          * CQ mapping to QID
2481          * We need three ports, all mapped to the same ordered qid0. Then we'll
2482          * take a packet out to each port, re-enqueue in reverse order,
2483          * then make sure the reordering has taken place properly when we
2484          * dequeue from the tx_port.
2485          *
2486          * Simplified test setup diagram:
2487          *
2488          * rx_port        w1_port
2489          *        \     /         \
2490          *         qid0 - w2_port - qid1
2491          *              \         /     \
2492          *                w3_port        tx_port
2493          */
2494         /* CQ mapping to QID for LB ports (directed mapped on create) */
2495         for (i = w1_port; i <= w3_port; i++) {
2496                 err = rte_event_port_link(evdev, t->port[i], &t->qid[0], NULL,
2497                                 1);
2498                 if (err != 1) {
2499                         printf("%d: error mapping lb qid\n", __LINE__);
2500                         cleanup(t);
2501                         return -1;
2502                 }
2503         }
2504
2505         if (rte_event_dev_start(evdev) < 0) {
2506                 printf("%d: Error with start call\n", __LINE__);
2507                 return -1;
2508         }
2509
2510         /* Enqueue 3 packets to the rx port */
2511         for (i = 0; i < 3; i++) {
2512                 struct rte_event ev;
2513                 mbufs[i] = rte_gen_arp(0, t->mbuf_pool);
2514                 if (!mbufs[i]) {
2515                         printf("%d: gen of pkt failed\n", __LINE__);
2516                         return -1;
2517                 }
2518
2519                 ev.queue_id = t->qid[0];
2520                 ev.op = RTE_EVENT_OP_NEW;
2521                 ev.mbuf = mbufs[i];
2522                 mbufs[i]->seqn = MAGIC_SEQN + i;
2523
2524                 /* generate pkt and enqueue */
2525                 err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
2526                 if (err != 1) {
2527                         printf("%d: Failed to enqueue pkt %u, retval = %u\n",
2528                                         __LINE__, i, err);
2529                         return -1;
2530                 }
2531         }
2532
2533         rte_event_schedule(evdev);
2534
2535         /* use extra slot to make logic in loops easier */
2536         struct rte_event deq_ev[w3_port + 1];
2537
2538         /* Dequeue the 3 packets, one from each worker port */
2539         for (i = w1_port; i <= w3_port; i++) {
2540                 deq_pkts = rte_event_dequeue_burst(evdev, t->port[i],
2541                                 &deq_ev[i], 1, 0);
2542                 if (deq_pkts != 1) {
2543                         printf("%d: Failed to deq\n", __LINE__);
2544                         rte_event_dev_dump(evdev, stdout);
2545                         return -1;
2546                 }
2547         }
2548
2549         /* Enqueue each packet in reverse order, flushing after each one */
2550         for (i = w3_port; i >= w1_port; i--) {
2551
2552                 deq_ev[i].op = RTE_EVENT_OP_FORWARD;
2553                 deq_ev[i].queue_id = t->qid[1];
2554                 err = rte_event_enqueue_burst(evdev, t->port[i], &deq_ev[i], 1);
2555                 if (err != 1) {
2556                         printf("%d: Failed to enqueue\n", __LINE__);
2557                         return -1;
2558                 }
2559         }
2560         rte_event_schedule(evdev);
2561
2562         /* dequeue from the tx ports, we should get 3 packets */
2563         deq_pkts = rte_event_dequeue_burst(evdev, t->port[tx_port], deq_ev,
2564                         3, 0);
2565
2566         /* Check to see if we've got all 3 packets */
2567         if (deq_pkts != 3) {
2568                 printf("%d: expected 3 pkts at tx port got %d from port %d\n",
2569                         __LINE__, deq_pkts, tx_port);
2570                 rte_event_dev_dump(evdev, stdout);
2571                 return 1;
2572         }
2573
2574         /* Check to see if the sequence numbers are in expected order */
2575         if (check_order) {
2576                 for (j = 0 ; j < deq_pkts ; j++) {
2577                         if (deq_ev[j].mbuf->seqn != MAGIC_SEQN + j) {
2578                                 printf(
2579                                         "%d: Incorrect sequence number(%d) from port %d\n",
2580                                         __LINE__, mbufs_out[j]->seqn, tx_port);
2581                                 return -1;
2582                         }
2583                 }
2584         }
2585
2586         /* Destroy the instance */
2587         cleanup(t);
2588         return 0;
2589 }
2590
2591 static int
2592 ordered_basic(struct test *t)
2593 {
2594         return parallel_basic(t, 1);
2595 }
2596
2597 static int
2598 unordered_basic(struct test *t)
2599 {
2600         return parallel_basic(t, 0);
2601 }
2602
2603 static struct rte_mempool *eventdev_func_mempool;
2604
2605 static int
2606 test_sw_eventdev(void)
2607 {
2608         struct test *t = malloc(sizeof(struct test));
2609         int ret;
2610
2611         /* manually initialize the op, older gcc's complain on static
2612          * initialization of struct elements that are a bitfield.
2613          */
2614         release_ev.op = RTE_EVENT_OP_RELEASE;
2615
2616         const char *eventdev_name = "event_sw0";
2617         evdev = rte_event_dev_get_dev_id(eventdev_name);
2618         if (evdev < 0) {
2619                 printf("%d: Eventdev %s not found - creating.\n",
2620                                 __LINE__, eventdev_name);
2621                 if (rte_eal_vdev_init(eventdev_name, NULL) < 0) {
2622                         printf("Error creating eventdev\n");
2623                         return -1;
2624                 }
2625                 evdev = rte_event_dev_get_dev_id(eventdev_name);
2626                 if (evdev < 0) {
2627                         printf("Error finding newly created eventdev\n");
2628                         return -1;
2629                 }
2630         }
2631
2632         /* Only create mbuf pool once, reuse for each test run */
2633         if (!eventdev_func_mempool) {
2634                 eventdev_func_mempool = rte_pktmbuf_pool_create(
2635                                 "EVENTDEV_SW_SA_MBUF_POOL",
2636                                 (1<<12), /* 4k buffers */
2637                                 32 /*MBUF_CACHE_SIZE*/,
2638                                 0,
2639                                 512, /* use very small mbufs */
2640                                 rte_socket_id());
2641                 if (!eventdev_func_mempool) {
2642                         printf("ERROR creating mempool\n");
2643                         return -1;
2644                 }
2645         }
2646         t->mbuf_pool = eventdev_func_mempool;
2647
2648         printf("*** Running Single Directed Packet test...\n");
2649         ret = test_single_directed_packet(t);
2650         if (ret != 0) {
2651                 printf("ERROR - Single Directed Packet test FAILED.\n");
2652                 return ret;
2653         }
2654         printf("*** Running Single Load Balanced Packet test...\n");
2655         ret = single_packet(t);
2656         if (ret != 0) {
2657                 printf("ERROR - Single Packet test FAILED.\n");
2658                 return ret;
2659         }
2660         printf("*** Running Unordered Basic test...\n");
2661         ret = unordered_basic(t);
2662         if (ret != 0) {
2663                 printf("ERROR -  Unordered Basic test FAILED.\n");
2664                 return ret;
2665         }
2666         printf("*** Running Ordered Basic test...\n");
2667         ret = ordered_basic(t);
2668         if (ret != 0) {
2669                 printf("ERROR -  Ordered Basic test FAILED.\n");
2670                 return ret;
2671         }
2672         printf("*** Running Burst Packets test...\n");
2673         ret = burst_packets(t);
2674         if (ret != 0) {
2675                 printf("ERROR - Burst Packets test FAILED.\n");
2676                 return ret;
2677         }
2678         printf("*** Running Load Balancing test...\n");
2679         ret = load_balancing(t);
2680         if (ret != 0) {
2681                 printf("ERROR - Load Balancing test FAILED.\n");
2682                 return ret;
2683         }
2684         printf("*** Running Prioritized Directed test...\n");
2685         ret = test_priority_directed(t);
2686         if (ret != 0) {
2687                 printf("ERROR - Prioritized Directed test FAILED.\n");
2688                 return ret;
2689         }
2690         printf("*** Running Prioritized Atomic test...\n");
2691         ret = test_priority_atomic(t);
2692         if (ret != 0) {
2693                 printf("ERROR - Prioritized Atomic test FAILED.\n");
2694                 return ret;
2695         }
2696
2697         printf("*** Running Prioritized Ordered test...\n");
2698         ret = test_priority_ordered(t);
2699         if (ret != 0) {
2700                 printf("ERROR - Prioritized Ordered test FAILED.\n");
2701                 return ret;
2702         }
2703         printf("*** Running Prioritized Unordered test...\n");
2704         ret = test_priority_unordered(t);
2705         if (ret != 0) {
2706                 printf("ERROR - Prioritized Unordered test FAILED.\n");
2707                 return ret;
2708         }
2709         printf("*** Running Invalid QID test...\n");
2710         ret = invalid_qid(t);
2711         if (ret != 0) {
2712                 printf("ERROR - Invalid QID test FAILED.\n");
2713                 return ret;
2714         }
2715         printf("*** Running Load Balancing History test...\n");
2716         ret = load_balancing_history(t);
2717         if (ret != 0) {
2718                 printf("ERROR - Load Balancing History test FAILED.\n");
2719                 return ret;
2720         }
2721         printf("*** Running Inflight Count test...\n");
2722         ret = inflight_counts(t);
2723         if (ret != 0) {
2724                 printf("ERROR - Inflight Count test FAILED.\n");
2725                 return ret;
2726         }
2727         printf("*** Running Abuse Inflights test...\n");
2728         ret = abuse_inflights(t);
2729         if (ret != 0) {
2730                 printf("ERROR - Abuse Inflights test FAILED.\n");
2731                 return ret;
2732         }
2733         printf("*** Running XStats test...\n");
2734         ret = xstats_tests(t);
2735         if (ret != 0) {
2736                 printf("ERROR - XStats test FAILED.\n");
2737                 return ret;
2738         }
2739         printf("*** Running XStats ID Reset test...\n");
2740         ret = xstats_id_reset_tests(t);
2741         if (ret != 0) {
2742                 printf("ERROR - XStats ID Reset test FAILED.\n");
2743                 return ret;
2744         }
2745         printf("*** Running XStats Brute Force test...\n");
2746         ret = xstats_brute_force(t);
2747         if (ret != 0) {
2748                 printf("ERROR - XStats Brute Force test FAILED.\n");
2749                 return ret;
2750         }
2751         printf("*** Running XStats ID Abuse test...\n");
2752         ret = xstats_id_abuse_tests(t);
2753         if (ret != 0) {
2754                 printf("ERROR - XStats ID Abuse test FAILED.\n");
2755                 return ret;
2756         }
2757         printf("*** Running QID Priority test...\n");
2758         ret = qid_priorities(t);
2759         if (ret != 0) {
2760                 printf("ERROR - QID Priority test FAILED.\n");
2761                 return ret;
2762         }
2763         printf("*** Running Ordered Reconfigure test...\n");
2764         ret = ordered_reconfigure(t);
2765         if (ret != 0) {
2766                 printf("ERROR - Ordered Reconfigure test FAILED.\n");
2767                 return ret;
2768         }
2769         printf("*** Running Port LB Single Reconfig test...\n");
2770         ret = port_single_lb_reconfig(t);
2771         if (ret != 0) {
2772                 printf("ERROR - Port LB Single Reconfig test FAILED.\n");
2773                 return ret;
2774         }
2775         printf("*** Running Port Reconfig Credits test...\n");
2776         ret = port_reconfig_credits(t);
2777         if (ret != 0) {
2778                 printf("ERROR - Port Reconfig Credits Reset test FAILED.\n");
2779                 return ret;
2780         }
2781         /*
2782          * Free test instance, leaving mempool initialized, and a pointer to it
2783          * in static eventdev_func_mempool, as it is re-used on re-runs
2784          */
2785         free(t);
2786
2787         return 0;
2788 }
2789
2790 REGISTER_TEST_COMMAND(eventdev_sw_autotest, test_sw_eventdev);