examples/ipsec-secgw: add event config display
[dpdk.git] / examples / ipsec-secgw / event_helper.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2020 Marvell International Ltd.
3  */
4 #include <rte_bitmap.h>
5 #include <rte_ethdev.h>
6 #include <rte_eventdev.h>
7 #include <rte_event_eth_rx_adapter.h>
8 #include <rte_event_eth_tx_adapter.h>
9 #include <rte_malloc.h>
10 #include <stdbool.h>
11
12 #include "event_helper.h"
13
14 static int
15 eh_get_enabled_cores(struct rte_bitmap *eth_core_mask)
16 {
17         int i, count = 0;
18
19         RTE_LCORE_FOREACH(i) {
20                 /* Check if this core is enabled in core mask*/
21                 if (rte_bitmap_get(eth_core_mask, i)) {
22                         /* Found enabled core */
23                         count++;
24                 }
25         }
26         return count;
27 }
28
29 static inline unsigned int
30 eh_get_next_eth_core(struct eventmode_conf *em_conf)
31 {
32         static unsigned int prev_core = -1;
33         unsigned int next_core;
34
35         /*
36          * Make sure we have at least one eth core running, else the following
37          * logic would lead to an infinite loop.
38          */
39         if (eh_get_enabled_cores(em_conf->eth_core_mask) == 0) {
40                 EH_LOG_ERR("No enabled eth core found");
41                 return RTE_MAX_LCORE;
42         }
43
44         /* Only some cores are marked as eth cores, skip others */
45         do {
46                 /* Get the next core */
47                 next_core = rte_get_next_lcore(prev_core, 0, 1);
48
49                 /* Check if we have reached max lcores */
50                 if (next_core == RTE_MAX_LCORE)
51                         return next_core;
52
53                 /* Update prev_core */
54                 prev_core = next_core;
55         } while (!(rte_bitmap_get(em_conf->eth_core_mask, next_core)));
56
57         return next_core;
58 }
59
60 static inline unsigned int
61 eh_get_next_active_core(struct eventmode_conf *em_conf, unsigned int prev_core)
62 {
63         unsigned int next_core;
64
65         /* Get next active core skipping cores reserved as eth cores */
66         do {
67                 /* Get the next core */
68                 next_core = rte_get_next_lcore(prev_core, 0, 0);
69
70                 /* Check if we have reached max lcores */
71                 if (next_core == RTE_MAX_LCORE)
72                         return next_core;
73
74                 prev_core = next_core;
75         } while (rte_bitmap_get(em_conf->eth_core_mask, next_core));
76
77         return next_core;
78 }
79
80 static struct eventdev_params *
81 eh_get_eventdev_params(struct eventmode_conf *em_conf, uint8_t eventdev_id)
82 {
83         int i;
84
85         for (i = 0; i < em_conf->nb_eventdev; i++) {
86                 if (em_conf->eventdev_config[i].eventdev_id == eventdev_id)
87                         break;
88         }
89
90         /* No match */
91         if (i == em_conf->nb_eventdev)
92                 return NULL;
93
94         return &(em_conf->eventdev_config[i]);
95 }
96 static int
97 eh_set_default_conf_eventdev(struct eventmode_conf *em_conf)
98 {
99         int lcore_count, nb_eventdev, nb_eth_dev, ret;
100         struct eventdev_params *eventdev_config;
101         struct rte_event_dev_info dev_info;
102
103         /* Get the number of event devices */
104         nb_eventdev = rte_event_dev_count();
105         if (nb_eventdev == 0) {
106                 EH_LOG_ERR("No event devices detected");
107                 return -EINVAL;
108         }
109
110         if (nb_eventdev != 1) {
111                 EH_LOG_ERR("Event mode does not support multiple event devices. "
112                            "Please provide only one event device.");
113                 return -EINVAL;
114         }
115
116         /* Get the number of eth devs */
117         nb_eth_dev = rte_eth_dev_count_avail();
118         if (nb_eth_dev == 0) {
119                 EH_LOG_ERR("No eth devices detected");
120                 return -EINVAL;
121         }
122
123         /* Get the number of lcores */
124         lcore_count = rte_lcore_count();
125
126         /* Read event device info */
127         ret = rte_event_dev_info_get(0, &dev_info);
128         if (ret < 0) {
129                 EH_LOG_ERR("Failed to read event device info %d", ret);
130                 return ret;
131         }
132
133         /* Check if enough ports are available */
134         if (dev_info.max_event_ports < 2) {
135                 EH_LOG_ERR("Not enough event ports available");
136                 return -EINVAL;
137         }
138
139         /* Get the first event dev conf */
140         eventdev_config = &(em_conf->eventdev_config[0]);
141
142         /* Save number of queues & ports available */
143         eventdev_config->eventdev_id = 0;
144         eventdev_config->nb_eventqueue = dev_info.max_event_queues;
145         eventdev_config->nb_eventport = dev_info.max_event_ports;
146         eventdev_config->ev_queue_mode = RTE_EVENT_QUEUE_CFG_ALL_TYPES;
147
148         /* Check if there are more queues than required */
149         if (eventdev_config->nb_eventqueue > nb_eth_dev + 1) {
150                 /* One queue is reserved for Tx */
151                 eventdev_config->nb_eventqueue = nb_eth_dev + 1;
152         }
153
154         /* Check if there are more ports than required */
155         if (eventdev_config->nb_eventport > lcore_count) {
156                 /* One port per lcore is enough */
157                 eventdev_config->nb_eventport = lcore_count;
158         }
159
160         /* Update the number of event devices */
161         em_conf->nb_eventdev++;
162
163         return 0;
164 }
165
166 static int
167 eh_set_default_conf_link(struct eventmode_conf *em_conf)
168 {
169         struct eventdev_params *eventdev_config;
170         struct eh_event_link_info *link;
171         unsigned int lcore_id = -1;
172         int i, link_index;
173
174         /*
175          * Create a 1:1 mapping from event ports to cores. If the number
176          * of event ports is lesser than the cores, some cores won't
177          * execute worker. If there are more event ports, then some ports
178          * won't be used.
179          *
180          */
181
182         /*
183          * The event queue-port mapping is done according to the link. Since
184          * we are falling back to the default link config, enabling
185          * "all_ev_queue_to_ev_port" mode flag. This will map all queues
186          * to the port.
187          */
188         em_conf->ext_params.all_ev_queue_to_ev_port = 1;
189
190         /* Get first event dev conf */
191         eventdev_config = &(em_conf->eventdev_config[0]);
192
193         /* Loop through the ports */
194         for (i = 0; i < eventdev_config->nb_eventport; i++) {
195
196                 /* Get next active core id */
197                 lcore_id = eh_get_next_active_core(em_conf,
198                                 lcore_id);
199
200                 if (lcore_id == RTE_MAX_LCORE) {
201                         /* Reached max cores */
202                         return 0;
203                 }
204
205                 /* Save the current combination as one link */
206
207                 /* Get the index */
208                 link_index = em_conf->nb_link;
209
210                 /* Get the corresponding link */
211                 link = &(em_conf->link[link_index]);
212
213                 /* Save link */
214                 link->eventdev_id = eventdev_config->eventdev_id;
215                 link->event_port_id = i;
216                 link->lcore_id = lcore_id;
217
218                 /*
219                  * Don't set eventq_id as by default all queues
220                  * need to be mapped to the port, which is controlled
221                  * by the operating mode.
222                  */
223
224                 /* Update number of links */
225                 em_conf->nb_link++;
226         }
227
228         return 0;
229 }
230
231 static int
232 eh_set_default_conf_rx_adapter(struct eventmode_conf *em_conf)
233 {
234         struct rx_adapter_connection_info *conn;
235         struct eventdev_params *eventdev_config;
236         struct rx_adapter_conf *adapter;
237         bool single_ev_queue = false;
238         int eventdev_id;
239         int nb_eth_dev;
240         int adapter_id;
241         int conn_id;
242         int i;
243
244         /* Create one adapter with eth queues mapped to event queue(s) */
245
246         if (em_conf->nb_eventdev == 0) {
247                 EH_LOG_ERR("No event devs registered");
248                 return -EINVAL;
249         }
250
251         /* Get the number of eth devs */
252         nb_eth_dev = rte_eth_dev_count_avail();
253
254         /* Use the first event dev */
255         eventdev_config = &(em_conf->eventdev_config[0]);
256
257         /* Get eventdev ID */
258         eventdev_id = eventdev_config->eventdev_id;
259         adapter_id = 0;
260
261         /* Get adapter conf */
262         adapter = &(em_conf->rx_adapter[adapter_id]);
263
264         /* Set adapter conf */
265         adapter->eventdev_id = eventdev_id;
266         adapter->adapter_id = adapter_id;
267         adapter->rx_core_id = eh_get_next_eth_core(em_conf);
268
269         /*
270          * Map all queues of eth device (port) to an event queue. If there
271          * are more event queues than eth ports then create 1:1 mapping.
272          * Otherwise map all eth ports to a single event queue.
273          */
274         if (nb_eth_dev > eventdev_config->nb_eventqueue)
275                 single_ev_queue = true;
276
277         for (i = 0; i < nb_eth_dev; i++) {
278
279                 /* Use only the ports enabled */
280                 if ((em_conf->eth_portmask & (1 << i)) == 0)
281                         continue;
282
283                 /* Get the connection id */
284                 conn_id = adapter->nb_connections;
285
286                 /* Get the connection */
287                 conn = &(adapter->conn[conn_id]);
288
289                 /* Set mapping between eth ports & event queues*/
290                 conn->ethdev_id = i;
291                 conn->eventq_id = single_ev_queue ? 0 : i;
292
293                 /* Add all eth queues eth port to event queue */
294                 conn->ethdev_rx_qid = -1;
295
296                 /* Update no of connections */
297                 adapter->nb_connections++;
298
299         }
300
301         /* We have setup one adapter */
302         em_conf->nb_rx_adapter = 1;
303
304         return 0;
305 }
306
307 static int
308 eh_set_default_conf_tx_adapter(struct eventmode_conf *em_conf)
309 {
310         struct tx_adapter_connection_info *conn;
311         struct eventdev_params *eventdev_config;
312         struct tx_adapter_conf *tx_adapter;
313         int eventdev_id;
314         int adapter_id;
315         int nb_eth_dev;
316         int conn_id;
317         int i;
318
319         /*
320          * Create one Tx adapter with all eth queues mapped to event queues
321          * 1:1.
322          */
323
324         if (em_conf->nb_eventdev == 0) {
325                 EH_LOG_ERR("No event devs registered");
326                 return -EINVAL;
327         }
328
329         /* Get the number of eth devs */
330         nb_eth_dev = rte_eth_dev_count_avail();
331
332         /* Use the first event dev */
333         eventdev_config = &(em_conf->eventdev_config[0]);
334
335         /* Get eventdev ID */
336         eventdev_id = eventdev_config->eventdev_id;
337         adapter_id = 0;
338
339         /* Get adapter conf */
340         tx_adapter = &(em_conf->tx_adapter[adapter_id]);
341
342         /* Set adapter conf */
343         tx_adapter->eventdev_id = eventdev_id;
344         tx_adapter->adapter_id = adapter_id;
345
346         /* TODO: Tx core is required only when internal port is not present */
347         tx_adapter->tx_core_id = eh_get_next_eth_core(em_conf);
348
349         /*
350          * Application uses one event queue per adapter for submitting
351          * packets for Tx. Reserve the last queue available and decrement
352          * the total available event queues for this
353          */
354
355         /* Queue numbers start at 0 */
356         tx_adapter->tx_ev_queue = eventdev_config->nb_eventqueue - 1;
357
358         /*
359          * Map all Tx queues of the eth device (port) to the event device.
360          */
361
362         /* Set defaults for connections */
363
364         /*
365          * One eth device (port) is one connection. Map all Tx queues
366          * of the device to the Tx adapter.
367          */
368
369         for (i = 0; i < nb_eth_dev; i++) {
370
371                 /* Use only the ports enabled */
372                 if ((em_conf->eth_portmask & (1 << i)) == 0)
373                         continue;
374
375                 /* Get the connection id */
376                 conn_id = tx_adapter->nb_connections;
377
378                 /* Get the connection */
379                 conn = &(tx_adapter->conn[conn_id]);
380
381                 /* Add ethdev to connections */
382                 conn->ethdev_id = i;
383
384                 /* Add all eth tx queues to adapter */
385                 conn->ethdev_tx_qid = -1;
386
387                 /* Update no of connections */
388                 tx_adapter->nb_connections++;
389         }
390
391         /* We have setup one adapter */
392         em_conf->nb_tx_adapter = 1;
393         return 0;
394 }
395
396 static int
397 eh_validate_conf(struct eventmode_conf *em_conf)
398 {
399         int ret;
400
401         /*
402          * Check if event devs are specified. Else probe the event devices
403          * and initialize the config with all ports & queues available
404          */
405         if (em_conf->nb_eventdev == 0) {
406                 ret = eh_set_default_conf_eventdev(em_conf);
407                 if (ret != 0)
408                         return ret;
409         }
410
411         /*
412          * Check if links are specified. Else generate a default config for
413          * the event ports used.
414          */
415         if (em_conf->nb_link == 0) {
416                 ret = eh_set_default_conf_link(em_conf);
417                 if (ret != 0)
418                         return ret;
419         }
420
421         /*
422          * Check if rx adapters are specified. Else generate a default config
423          * with one rx adapter and all eth queues - event queue mapped.
424          */
425         if (em_conf->nb_rx_adapter == 0) {
426                 ret = eh_set_default_conf_rx_adapter(em_conf);
427                 if (ret != 0)
428                         return ret;
429         }
430
431         /*
432          * Check if tx adapters are specified. Else generate a default config
433          * with one tx adapter.
434          */
435         if (em_conf->nb_tx_adapter == 0) {
436                 ret = eh_set_default_conf_tx_adapter(em_conf);
437                 if (ret != 0)
438                         return ret;
439         }
440
441         return 0;
442 }
443
444 static int
445 eh_initialize_eventdev(struct eventmode_conf *em_conf)
446 {
447         struct rte_event_queue_conf eventq_conf = {0};
448         struct rte_event_dev_info evdev_default_conf;
449         struct rte_event_dev_config eventdev_conf;
450         struct eventdev_params *eventdev_config;
451         int nb_eventdev = em_conf->nb_eventdev;
452         struct eh_event_link_info *link;
453         uint8_t *queue = NULL;
454         uint8_t eventdev_id;
455         int nb_eventqueue;
456         uint8_t i, j;
457         int ret;
458
459         for (i = 0; i < nb_eventdev; i++) {
460
461                 /* Get eventdev config */
462                 eventdev_config = &(em_conf->eventdev_config[i]);
463
464                 /* Get event dev ID */
465                 eventdev_id = eventdev_config->eventdev_id;
466
467                 /* Get the number of queues */
468                 nb_eventqueue = eventdev_config->nb_eventqueue;
469
470                 /* Reset the default conf */
471                 memset(&evdev_default_conf, 0,
472                         sizeof(struct rte_event_dev_info));
473
474                 /* Get default conf of eventdev */
475                 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf);
476                 if (ret < 0) {
477                         EH_LOG_ERR(
478                                 "Error in getting event device info[devID:%d]",
479                                 eventdev_id);
480                         return ret;
481                 }
482
483                 memset(&eventdev_conf, 0, sizeof(struct rte_event_dev_config));
484                 eventdev_conf.nb_events_limit =
485                                 evdev_default_conf.max_num_events;
486                 eventdev_conf.nb_event_queues = nb_eventqueue;
487                 eventdev_conf.nb_event_ports =
488                                 eventdev_config->nb_eventport;
489                 eventdev_conf.nb_event_queue_flows =
490                                 evdev_default_conf.max_event_queue_flows;
491                 eventdev_conf.nb_event_port_dequeue_depth =
492                                 evdev_default_conf.max_event_port_dequeue_depth;
493                 eventdev_conf.nb_event_port_enqueue_depth =
494                                 evdev_default_conf.max_event_port_enqueue_depth;
495
496                 /* Configure event device */
497                 ret = rte_event_dev_configure(eventdev_id, &eventdev_conf);
498                 if (ret < 0) {
499                         EH_LOG_ERR("Error in configuring event device");
500                         return ret;
501                 }
502
503                 /* Configure event queues */
504                 for (j = 0; j < nb_eventqueue; j++) {
505
506                         memset(&eventq_conf, 0,
507                                         sizeof(struct rte_event_queue_conf));
508
509                         /* Per event dev queues can be ATQ or SINGLE LINK */
510                         eventq_conf.event_queue_cfg =
511                                         eventdev_config->ev_queue_mode;
512                         /*
513                          * All queues need to be set with sched_type as
514                          * schedule type for the application stage. One queue
515                          * would be reserved for the final eth tx stage. This
516                          * will be an atomic queue.
517                          */
518                         if (j == nb_eventqueue-1) {
519                                 eventq_conf.schedule_type =
520                                         RTE_SCHED_TYPE_ATOMIC;
521                         } else {
522                                 eventq_conf.schedule_type =
523                                         em_conf->ext_params.sched_type;
524                         }
525
526                         /* Set max atomic flows to 1024 */
527                         eventq_conf.nb_atomic_flows = 1024;
528                         eventq_conf.nb_atomic_order_sequences = 1024;
529
530                         /* Setup the queue */
531                         ret = rte_event_queue_setup(eventdev_id, j,
532                                         &eventq_conf);
533                         if (ret < 0) {
534                                 EH_LOG_ERR("Failed to setup event queue %d",
535                                            ret);
536                                 return ret;
537                         }
538                 }
539
540                 /* Configure event ports */
541                 for (j = 0; j <  eventdev_config->nb_eventport; j++) {
542                         ret = rte_event_port_setup(eventdev_id, j, NULL);
543                         if (ret < 0) {
544                                 EH_LOG_ERR("Failed to setup event port %d",
545                                            ret);
546                                 return ret;
547                         }
548                 }
549         }
550
551         /* Make event queue - event port link */
552         for (j = 0; j <  em_conf->nb_link; j++) {
553
554                 /* Get link info */
555                 link = &(em_conf->link[j]);
556
557                 /* Get event dev ID */
558                 eventdev_id = link->eventdev_id;
559
560                 /*
561                  * If "all_ev_queue_to_ev_port" params flag is selected, all
562                  * queues need to be mapped to the port.
563                  */
564                 if (em_conf->ext_params.all_ev_queue_to_ev_port)
565                         queue = NULL;
566                 else
567                         queue = &(link->eventq_id);
568
569                 /* Link queue to port */
570                 ret = rte_event_port_link(eventdev_id, link->event_port_id,
571                                 queue, NULL, 1);
572                 if (ret < 0) {
573                         EH_LOG_ERR("Failed to link event port %d", ret);
574                         return ret;
575                 }
576         }
577
578         /* Start event devices */
579         for (i = 0; i < nb_eventdev; i++) {
580
581                 /* Get eventdev config */
582                 eventdev_config = &(em_conf->eventdev_config[i]);
583
584                 ret = rte_event_dev_start(eventdev_config->eventdev_id);
585                 if (ret < 0) {
586                         EH_LOG_ERR("Failed to start event device %d, %d",
587                                    i, ret);
588                         return ret;
589                 }
590         }
591         return 0;
592 }
593
594 static int
595 eh_rx_adapter_configure(struct eventmode_conf *em_conf,
596                 struct rx_adapter_conf *adapter)
597 {
598         struct rte_event_eth_rx_adapter_queue_conf queue_conf = {0};
599         struct rte_event_dev_info evdev_default_conf = {0};
600         struct rte_event_port_conf port_conf = {0};
601         struct rx_adapter_connection_info *conn;
602         uint8_t eventdev_id;
603         uint32_t service_id;
604         int ret;
605         int j;
606
607         /* Get event dev ID */
608         eventdev_id = adapter->eventdev_id;
609
610         /* Get default configuration of event dev */
611         ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf);
612         if (ret < 0) {
613                 EH_LOG_ERR("Failed to get event dev info %d", ret);
614                 return ret;
615         }
616
617         /* Setup port conf */
618         port_conf.new_event_threshold = 1200;
619         port_conf.dequeue_depth =
620                         evdev_default_conf.max_event_port_dequeue_depth;
621         port_conf.enqueue_depth =
622                         evdev_default_conf.max_event_port_enqueue_depth;
623
624         /* Create Rx adapter */
625         ret = rte_event_eth_rx_adapter_create(adapter->adapter_id,
626                         adapter->eventdev_id, &port_conf);
627         if (ret < 0) {
628                 EH_LOG_ERR("Failed to create rx adapter %d", ret);
629                 return ret;
630         }
631
632         /* Setup various connections in the adapter */
633         for (j = 0; j < adapter->nb_connections; j++) {
634                 /* Get connection */
635                 conn = &(adapter->conn[j]);
636
637                 /* Setup queue conf */
638                 queue_conf.ev.queue_id = conn->eventq_id;
639                 queue_conf.ev.sched_type = em_conf->ext_params.sched_type;
640                 queue_conf.ev.event_type = RTE_EVENT_TYPE_ETHDEV;
641
642                 /* Add queue to the adapter */
643                 ret = rte_event_eth_rx_adapter_queue_add(adapter->adapter_id,
644                                 conn->ethdev_id, conn->ethdev_rx_qid,
645                                 &queue_conf);
646                 if (ret < 0) {
647                         EH_LOG_ERR("Failed to add eth queue to rx adapter %d",
648                                    ret);
649                         return ret;
650                 }
651         }
652
653         /* Get the service ID used by rx adapter */
654         ret = rte_event_eth_rx_adapter_service_id_get(adapter->adapter_id,
655                                                       &service_id);
656         if (ret != -ESRCH && ret < 0) {
657                 EH_LOG_ERR("Failed to get service id used by rx adapter %d",
658                            ret);
659                 return ret;
660         }
661
662         rte_service_set_runstate_mapped_check(service_id, 0);
663
664         /* Start adapter */
665         ret = rte_event_eth_rx_adapter_start(adapter->adapter_id);
666         if (ret < 0) {
667                 EH_LOG_ERR("Failed to start rx adapter %d", ret);
668                 return ret;
669         }
670
671         return 0;
672 }
673
674 static int
675 eh_initialize_rx_adapter(struct eventmode_conf *em_conf)
676 {
677         struct rx_adapter_conf *adapter;
678         int i, ret;
679
680         /* Configure rx adapters */
681         for (i = 0; i < em_conf->nb_rx_adapter; i++) {
682                 adapter = &(em_conf->rx_adapter[i]);
683                 ret = eh_rx_adapter_configure(em_conf, adapter);
684                 if (ret < 0) {
685                         EH_LOG_ERR("Failed to configure rx adapter %d", ret);
686                         return ret;
687                 }
688         }
689         return 0;
690 }
691
692 static int
693 eh_tx_adapter_configure(struct eventmode_conf *em_conf,
694                 struct tx_adapter_conf *adapter)
695 {
696         struct rte_event_dev_info evdev_default_conf = {0};
697         struct rte_event_port_conf port_conf = {0};
698         struct tx_adapter_connection_info *conn;
699         struct eventdev_params *eventdev_config;
700         uint8_t tx_port_id = 0;
701         uint8_t eventdev_id;
702         uint32_t service_id;
703         int ret, j;
704
705         /* Get event dev ID */
706         eventdev_id = adapter->eventdev_id;
707
708         /* Get event device conf */
709         eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id);
710
711         /* Create Tx adapter */
712
713         /* Get default configuration of event dev */
714         ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf);
715         if (ret < 0) {
716                 EH_LOG_ERR("Failed to get event dev info %d", ret);
717                 return ret;
718         }
719
720         /* Setup port conf */
721         port_conf.new_event_threshold =
722                         evdev_default_conf.max_num_events;
723         port_conf.dequeue_depth =
724                         evdev_default_conf.max_event_port_dequeue_depth;
725         port_conf.enqueue_depth =
726                         evdev_default_conf.max_event_port_enqueue_depth;
727
728         /* Create adapter */
729         ret = rte_event_eth_tx_adapter_create(adapter->adapter_id,
730                         adapter->eventdev_id, &port_conf);
731         if (ret < 0) {
732                 EH_LOG_ERR("Failed to create tx adapter %d", ret);
733                 return ret;
734         }
735
736         /* Setup various connections in the adapter */
737         for (j = 0; j < adapter->nb_connections; j++) {
738
739                 /* Get connection */
740                 conn = &(adapter->conn[j]);
741
742                 /* Add queue to the adapter */
743                 ret = rte_event_eth_tx_adapter_queue_add(adapter->adapter_id,
744                                 conn->ethdev_id, conn->ethdev_tx_qid);
745                 if (ret < 0) {
746                         EH_LOG_ERR("Failed to add eth queue to tx adapter %d",
747                                    ret);
748                         return ret;
749                 }
750         }
751
752         /* Setup Tx queue & port */
753
754         /* Get event port used by the adapter */
755         ret = rte_event_eth_tx_adapter_event_port_get(
756                         adapter->adapter_id, &tx_port_id);
757         if (ret) {
758                 EH_LOG_ERR("Failed to get tx adapter port id %d", ret);
759                 return ret;
760         }
761
762         /*
763          * Tx event queue is reserved for Tx adapter. Unlink this queue
764          * from all other ports
765          *
766          */
767         for (j = 0; j < eventdev_config->nb_eventport; j++) {
768                 rte_event_port_unlink(eventdev_id, j,
769                                       &(adapter->tx_ev_queue), 1);
770         }
771
772         /* Link Tx event queue to Tx port */
773         ret = rte_event_port_link(eventdev_id, tx_port_id,
774                         &(adapter->tx_ev_queue), NULL, 1);
775         if (ret != 1) {
776                 EH_LOG_ERR("Failed to link event queue to port");
777                 return ret;
778         }
779
780         /* Get the service ID used by Tx adapter */
781         ret = rte_event_eth_tx_adapter_service_id_get(adapter->adapter_id,
782                                                       &service_id);
783         if (ret != -ESRCH && ret < 0) {
784                 EH_LOG_ERR("Failed to get service id used by tx adapter %d",
785                            ret);
786                 return ret;
787         }
788
789         rte_service_set_runstate_mapped_check(service_id, 0);
790
791         /* Start adapter */
792         ret = rte_event_eth_tx_adapter_start(adapter->adapter_id);
793         if (ret < 0) {
794                 EH_LOG_ERR("Failed to start tx adapter %d", ret);
795                 return ret;
796         }
797
798         return 0;
799 }
800
801 static int
802 eh_initialize_tx_adapter(struct eventmode_conf *em_conf)
803 {
804         struct tx_adapter_conf *adapter;
805         int i, ret;
806
807         /* Configure Tx adapters */
808         for (i = 0; i < em_conf->nb_tx_adapter; i++) {
809                 adapter = &(em_conf->tx_adapter[i]);
810                 ret = eh_tx_adapter_configure(em_conf, adapter);
811                 if (ret < 0) {
812                         EH_LOG_ERR("Failed to configure tx adapter %d", ret);
813                         return ret;
814                 }
815         }
816         return 0;
817 }
818
819 static void
820 eh_display_operating_mode(struct eventmode_conf *em_conf)
821 {
822         char sched_types[][32] = {
823                 "RTE_SCHED_TYPE_ORDERED",
824                 "RTE_SCHED_TYPE_ATOMIC",
825                 "RTE_SCHED_TYPE_PARALLEL",
826         };
827         EH_LOG_INFO("Operating mode:");
828
829         EH_LOG_INFO("\tScheduling type: \t%s",
830                 sched_types[em_conf->ext_params.sched_type]);
831
832         EH_LOG_INFO("");
833 }
834
835 static void
836 eh_display_event_dev_conf(struct eventmode_conf *em_conf)
837 {
838         char queue_mode[][32] = {
839                 "",
840                 "ATQ (ALL TYPE QUEUE)",
841                 "SINGLE LINK",
842         };
843         char print_buf[256] = { 0 };
844         int i;
845
846         EH_LOG_INFO("Event Device Configuration:");
847
848         for (i = 0; i < em_conf->nb_eventdev; i++) {
849                 sprintf(print_buf,
850                         "\tDev ID: %-2d \tQueues: %-2d \tPorts: %-2d",
851                         em_conf->eventdev_config[i].eventdev_id,
852                         em_conf->eventdev_config[i].nb_eventqueue,
853                         em_conf->eventdev_config[i].nb_eventport);
854                 sprintf(print_buf + strlen(print_buf),
855                         "\tQueue mode: %s",
856                         queue_mode[em_conf->eventdev_config[i].ev_queue_mode]);
857                 EH_LOG_INFO("%s", print_buf);
858         }
859         EH_LOG_INFO("");
860 }
861
862 static void
863 eh_display_rx_adapter_conf(struct eventmode_conf *em_conf)
864 {
865         int nb_rx_adapter = em_conf->nb_rx_adapter;
866         struct rx_adapter_connection_info *conn;
867         struct rx_adapter_conf *adapter;
868         char print_buf[256] = { 0 };
869         int i, j;
870
871         EH_LOG_INFO("Rx adapters configured: %d", nb_rx_adapter);
872
873         for (i = 0; i < nb_rx_adapter; i++) {
874                 adapter = &(em_conf->rx_adapter[i]);
875                 EH_LOG_INFO(
876                         "\tRx adaper ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d"
877                         "\tRx core: %-2d",
878                         adapter->adapter_id,
879                         adapter->nb_connections,
880                         adapter->eventdev_id,
881                         adapter->rx_core_id);
882
883                 for (j = 0; j < adapter->nb_connections; j++) {
884                         conn = &(adapter->conn[j]);
885
886                         sprintf(print_buf,
887                                 "\t\tEthdev ID: %-2d", conn->ethdev_id);
888
889                         if (conn->ethdev_rx_qid == -1)
890                                 sprintf(print_buf + strlen(print_buf),
891                                         "\tEth rx queue: %-2s", "ALL");
892                         else
893                                 sprintf(print_buf + strlen(print_buf),
894                                         "\tEth rx queue: %-2d",
895                                         conn->ethdev_rx_qid);
896
897                         sprintf(print_buf + strlen(print_buf),
898                                 "\tEvent queue: %-2d", conn->eventq_id);
899                         EH_LOG_INFO("%s", print_buf);
900                 }
901         }
902         EH_LOG_INFO("");
903 }
904
905 static void
906 eh_display_tx_adapter_conf(struct eventmode_conf *em_conf)
907 {
908         int nb_tx_adapter = em_conf->nb_tx_adapter;
909         struct tx_adapter_connection_info *conn;
910         struct tx_adapter_conf *adapter;
911         char print_buf[256] = { 0 };
912         int i, j;
913
914         EH_LOG_INFO("Tx adapters configured: %d", nb_tx_adapter);
915
916         for (i = 0; i < nb_tx_adapter; i++) {
917                 adapter = &(em_conf->tx_adapter[i]);
918                 sprintf(print_buf,
919                         "\tTx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
920                         adapter->adapter_id,
921                         adapter->nb_connections,
922                         adapter->eventdev_id);
923                 if (adapter->tx_core_id == (uint32_t)-1)
924                         sprintf(print_buf + strlen(print_buf),
925                                 "\tTx core: %-2s", "[INTERNAL PORT]");
926                 else if (adapter->tx_core_id == RTE_MAX_LCORE)
927                         sprintf(print_buf + strlen(print_buf),
928                                 "\tTx core: %-2s", "[NONE]");
929                 else
930                         sprintf(print_buf + strlen(print_buf),
931                                 "\tTx core: %-2d,\tInput event queue: %-2d",
932                                 adapter->tx_core_id, adapter->tx_ev_queue);
933
934                 EH_LOG_INFO("%s", print_buf);
935
936                 for (j = 0; j < adapter->nb_connections; j++) {
937                         conn = &(adapter->conn[j]);
938
939                         sprintf(print_buf,
940                                 "\t\tEthdev ID: %-2d", conn->ethdev_id);
941
942                         if (conn->ethdev_tx_qid == -1)
943                                 sprintf(print_buf + strlen(print_buf),
944                                         "\tEth tx queue: %-2s", "ALL");
945                         else
946                                 sprintf(print_buf + strlen(print_buf),
947                                         "\tEth tx queue: %-2d",
948                                         conn->ethdev_tx_qid);
949                         EH_LOG_INFO("%s", print_buf);
950                 }
951         }
952         EH_LOG_INFO("");
953 }
954
955 static void
956 eh_display_link_conf(struct eventmode_conf *em_conf)
957 {
958         struct eh_event_link_info *link;
959         char print_buf[256] = { 0 };
960         int i;
961
962         EH_LOG_INFO("Links configured: %d", em_conf->nb_link);
963
964         for (i = 0; i < em_conf->nb_link; i++) {
965                 link = &(em_conf->link[i]);
966
967                 sprintf(print_buf,
968                         "\tEvent dev ID: %-2d\tEvent port: %-2d",
969                         link->eventdev_id,
970                         link->event_port_id);
971
972                 if (em_conf->ext_params.all_ev_queue_to_ev_port)
973                         sprintf(print_buf + strlen(print_buf),
974                                 "Event queue: %-2s\t", "ALL");
975                 else
976                         sprintf(print_buf + strlen(print_buf),
977                                 "Event queue: %-2d\t", link->eventq_id);
978
979                 sprintf(print_buf + strlen(print_buf),
980                         "Lcore: %-2d", link->lcore_id);
981                 EH_LOG_INFO("%s", print_buf);
982         }
983         EH_LOG_INFO("");
984 }
985
986 void
987 eh_display_conf(struct eh_conf *conf)
988 {
989         struct eventmode_conf *em_conf;
990
991         if (conf == NULL) {
992                 EH_LOG_ERR("Invalid event helper configuration");
993                 return;
994         }
995
996         if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
997                 return;
998
999         if (conf->mode_params == NULL) {
1000                 EH_LOG_ERR("Invalid event mode parameters");
1001                 return;
1002         }
1003
1004         /* Get eventmode conf */
1005         em_conf = (struct eventmode_conf *)(conf->mode_params);
1006
1007         /* Display user exposed operating modes */
1008         eh_display_operating_mode(em_conf);
1009
1010         /* Display event device conf */
1011         eh_display_event_dev_conf(em_conf);
1012
1013         /* Display Rx adapter conf */
1014         eh_display_rx_adapter_conf(em_conf);
1015
1016         /* Display Tx adapter conf */
1017         eh_display_tx_adapter_conf(em_conf);
1018
1019         /* Display event-lcore link */
1020         eh_display_link_conf(em_conf);
1021 }
1022
1023 int32_t
1024 eh_devs_init(struct eh_conf *conf)
1025 {
1026         struct eventmode_conf *em_conf;
1027         uint16_t port_id;
1028         int ret;
1029
1030         if (conf == NULL) {
1031                 EH_LOG_ERR("Invalid event helper configuration");
1032                 return -EINVAL;
1033         }
1034
1035         if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
1036                 return 0;
1037
1038         if (conf->mode_params == NULL) {
1039                 EH_LOG_ERR("Invalid event mode parameters");
1040                 return -EINVAL;
1041         }
1042
1043         /* Get eventmode conf */
1044         em_conf = conf->mode_params;
1045
1046         /* Eventmode conf would need eth portmask */
1047         em_conf->eth_portmask = conf->eth_portmask;
1048
1049         /* Validate the requested config */
1050         ret = eh_validate_conf(em_conf);
1051         if (ret < 0) {
1052                 EH_LOG_ERR("Failed to validate the requested config %d", ret);
1053                 return ret;
1054         }
1055
1056         /* Display the current configuration */
1057         eh_display_conf(conf);
1058
1059         /* Stop eth devices before setting up adapter */
1060         RTE_ETH_FOREACH_DEV(port_id) {
1061
1062                 /* Use only the ports enabled */
1063                 if ((conf->eth_portmask & (1 << port_id)) == 0)
1064                         continue;
1065
1066                 rte_eth_dev_stop(port_id);
1067         }
1068
1069         /* Setup eventdev */
1070         ret = eh_initialize_eventdev(em_conf);
1071         if (ret < 0) {
1072                 EH_LOG_ERR("Failed to initialize event dev %d", ret);
1073                 return ret;
1074         }
1075
1076         /* Setup Rx adapter */
1077         ret = eh_initialize_rx_adapter(em_conf);
1078         if (ret < 0) {
1079                 EH_LOG_ERR("Failed to initialize rx adapter %d", ret);
1080                 return ret;
1081         }
1082
1083         /* Setup Tx adapter */
1084         ret = eh_initialize_tx_adapter(em_conf);
1085         if (ret < 0) {
1086                 EH_LOG_ERR("Failed to initialize tx adapter %d", ret);
1087                 return ret;
1088         }
1089
1090         /* Start eth devices after setting up adapter */
1091         RTE_ETH_FOREACH_DEV(port_id) {
1092
1093                 /* Use only the ports enabled */
1094                 if ((conf->eth_portmask & (1 << port_id)) == 0)
1095                         continue;
1096
1097                 ret = rte_eth_dev_start(port_id);
1098                 if (ret < 0) {
1099                         EH_LOG_ERR("Failed to start eth dev %d, %d",
1100                                    port_id, ret);
1101                         return ret;
1102                 }
1103         }
1104
1105         return 0;
1106 }
1107
1108 int32_t
1109 eh_devs_uninit(struct eh_conf *conf)
1110 {
1111         struct eventmode_conf *em_conf;
1112         int ret, i, j;
1113         uint16_t id;
1114
1115         if (conf == NULL) {
1116                 EH_LOG_ERR("Invalid event helper configuration");
1117                 return -EINVAL;
1118         }
1119
1120         if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
1121                 return 0;
1122
1123         if (conf->mode_params == NULL) {
1124                 EH_LOG_ERR("Invalid event mode parameters");
1125                 return -EINVAL;
1126         }
1127
1128         /* Get eventmode conf */
1129         em_conf = conf->mode_params;
1130
1131         /* Stop and release rx adapters */
1132         for (i = 0; i < em_conf->nb_rx_adapter; i++) {
1133
1134                 id = em_conf->rx_adapter[i].adapter_id;
1135                 ret = rte_event_eth_rx_adapter_stop(id);
1136                 if (ret < 0) {
1137                         EH_LOG_ERR("Failed to stop rx adapter %d", ret);
1138                         return ret;
1139                 }
1140
1141                 for (j = 0; j < em_conf->rx_adapter[i].nb_connections; j++) {
1142
1143                         ret = rte_event_eth_rx_adapter_queue_del(id,
1144                                 em_conf->rx_adapter[i].conn[j].ethdev_id, -1);
1145                         if (ret < 0) {
1146                                 EH_LOG_ERR(
1147                                        "Failed to remove rx adapter queues %d",
1148                                        ret);
1149                                 return ret;
1150                         }
1151                 }
1152
1153                 ret = rte_event_eth_rx_adapter_free(id);
1154                 if (ret < 0) {
1155                         EH_LOG_ERR("Failed to free rx adapter %d", ret);
1156                         return ret;
1157                 }
1158         }
1159
1160         /* Stop and release event devices */
1161         for (i = 0; i < em_conf->nb_eventdev; i++) {
1162
1163                 id = em_conf->eventdev_config[i].eventdev_id;
1164                 rte_event_dev_stop(id);
1165
1166                 ret = rte_event_dev_close(id);
1167                 if (ret < 0) {
1168                         EH_LOG_ERR("Failed to close event dev %d, %d", id, ret);
1169                         return ret;
1170                 }
1171         }
1172
1173         /* Stop and release tx adapters */
1174         for (i = 0; i < em_conf->nb_tx_adapter; i++) {
1175
1176                 id = em_conf->tx_adapter[i].adapter_id;
1177                 ret = rte_event_eth_tx_adapter_stop(id);
1178                 if (ret < 0) {
1179                         EH_LOG_ERR("Failed to stop tx adapter %d", ret);
1180                         return ret;
1181                 }
1182
1183                 for (j = 0; j < em_conf->tx_adapter[i].nb_connections; j++) {
1184
1185                         ret = rte_event_eth_tx_adapter_queue_del(id,
1186                                 em_conf->tx_adapter[i].conn[j].ethdev_id, -1);
1187                         if (ret < 0) {
1188                                 EH_LOG_ERR(
1189                                         "Failed to remove tx adapter queues %d",
1190                                         ret);
1191                                 return ret;
1192                         }
1193                 }
1194
1195                 ret = rte_event_eth_tx_adapter_free(id);
1196                 if (ret < 0) {
1197                         EH_LOG_ERR("Failed to free tx adapter %d", ret);
1198                         return ret;
1199                 }
1200         }
1201
1202         return 0;
1203 }
1204
1205 uint8_t
1206 eh_get_tx_queue(struct eh_conf *conf, uint8_t eventdev_id)
1207 {
1208         struct eventdev_params *eventdev_config;
1209         struct eventmode_conf *em_conf;
1210
1211         if (conf == NULL) {
1212                 EH_LOG_ERR("Invalid event helper configuration");
1213                 return -EINVAL;
1214         }
1215
1216         if (conf->mode_params == NULL) {
1217                 EH_LOG_ERR("Invalid event mode parameters");
1218                 return -EINVAL;
1219         }
1220
1221         /* Get eventmode conf */
1222         em_conf = conf->mode_params;
1223
1224         /* Get event device conf */
1225         eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id);
1226
1227         if (eventdev_config == NULL) {
1228                 EH_LOG_ERR("Failed to read eventdev config");
1229                 return -EINVAL;
1230         }
1231
1232         /*
1233          * The last queue is reserved to be used as atomic queue for the
1234          * last stage (eth packet tx stage)
1235          */
1236         return eventdev_config->nb_eventqueue - 1;
1237 }