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