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