]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/examples/ipsec-secgw/event_helper.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / 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 volatile bool eth_core_running;
15
16 static int
17 eh_get_enabled_cores(struct rte_bitmap *eth_core_mask)
18 {
19 int i, count = 0;
20
21 RTE_LCORE_FOREACH(i) {
22 /* Check if this core is enabled in core mask*/
23 if (rte_bitmap_get(eth_core_mask, i)) {
24 /* Found enabled core */
25 count++;
26 }
27 }
28 return count;
29 }
30
31 static inline unsigned int
32 eh_get_next_eth_core(struct eventmode_conf *em_conf)
33 {
34 static unsigned int prev_core = -1;
35 unsigned int next_core;
36
37 /*
38 * Make sure we have at least one eth core running, else the following
39 * logic would lead to an infinite loop.
40 */
41 if (eh_get_enabled_cores(em_conf->eth_core_mask) == 0) {
42 EH_LOG_ERR("No enabled eth core found");
43 return RTE_MAX_LCORE;
44 }
45
46 /* Only some cores are marked as eth cores, skip others */
47 do {
48 /* Get the next core */
49 next_core = rte_get_next_lcore(prev_core, 0, 1);
50
51 /* Check if we have reached max lcores */
52 if (next_core == RTE_MAX_LCORE)
53 return next_core;
54
55 /* Update prev_core */
56 prev_core = next_core;
57 } while (!(rte_bitmap_get(em_conf->eth_core_mask, next_core)));
58
59 return next_core;
60 }
61
62 static inline unsigned int
63 eh_get_next_active_core(struct eventmode_conf *em_conf, unsigned int prev_core)
64 {
65 unsigned int next_core;
66
67 /* Get next active core skipping cores reserved as eth cores */
68 do {
69 /* Get the next core */
70 next_core = rte_get_next_lcore(prev_core, 0, 0);
71
72 /* Check if we have reached max lcores */
73 if (next_core == RTE_MAX_LCORE)
74 return next_core;
75
76 prev_core = next_core;
77 } while (rte_bitmap_get(em_conf->eth_core_mask, next_core));
78
79 return next_core;
80 }
81
82 static struct eventdev_params *
83 eh_get_eventdev_params(struct eventmode_conf *em_conf, uint8_t eventdev_id)
84 {
85 int i;
86
87 for (i = 0; i < em_conf->nb_eventdev; i++) {
88 if (em_conf->eventdev_config[i].eventdev_id == eventdev_id)
89 break;
90 }
91
92 /* No match */
93 if (i == em_conf->nb_eventdev)
94 return NULL;
95
96 return &(em_conf->eventdev_config[i]);
97 }
98
99 static inline bool
100 eh_dev_has_rx_internal_port(uint8_t eventdev_id)
101 {
102 bool flag = true;
103 int j, ret;
104
105 RTE_ETH_FOREACH_DEV(j) {
106 uint32_t caps = 0;
107
108 ret = rte_event_eth_rx_adapter_caps_get(eventdev_id, j, &caps);
109 if (ret < 0)
110 return false;
111
112 if (!(caps & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT))
113 flag = false;
114 }
115 return flag;
116 }
117
118 static inline bool
119 eh_dev_has_tx_internal_port(uint8_t eventdev_id)
120 {
121 bool flag = true;
122 int j, ret;
123
124 RTE_ETH_FOREACH_DEV(j) {
125 uint32_t caps = 0;
126
127 ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, j, &caps);
128 if (ret < 0)
129 return false;
130
131 if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT))
132 flag = false;
133 }
134 return flag;
135 }
136
137 static inline bool
138 eh_dev_has_burst_mode(uint8_t dev_id)
139 {
140 struct rte_event_dev_info dev_info;
141
142 rte_event_dev_info_get(dev_id, &dev_info);
143 return (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) ?
144 true : false;
145 }
146
147 static int
148 eh_set_default_conf_eventdev(struct eventmode_conf *em_conf)
149 {
150 int lcore_count, nb_eventdev, nb_eth_dev, ret;
151 struct eventdev_params *eventdev_config;
152 struct rte_event_dev_info dev_info;
153
154 /* Get the number of event devices */
155 nb_eventdev = rte_event_dev_count();
156 if (nb_eventdev == 0) {
157 EH_LOG_ERR("No event devices detected");
158 return -EINVAL;
159 }
160
161 if (nb_eventdev != 1) {
162 EH_LOG_ERR("Event mode does not support multiple event devices. "
163 "Please provide only one event device.");
164 return -EINVAL;
165 }
166
167 /* Get the number of eth devs */
168 nb_eth_dev = rte_eth_dev_count_avail();
169 if (nb_eth_dev == 0) {
170 EH_LOG_ERR("No eth devices detected");
171 return -EINVAL;
172 }
173
174 /* Get the number of lcores */
175 lcore_count = rte_lcore_count();
176
177 /* Read event device info */
178 ret = rte_event_dev_info_get(0, &dev_info);
179 if (ret < 0) {
180 EH_LOG_ERR("Failed to read event device info %d", ret);
181 return ret;
182 }
183
184 /* Check if enough ports are available */
185 if (dev_info.max_event_ports < 2) {
186 EH_LOG_ERR("Not enough event ports available");
187 return -EINVAL;
188 }
189
190 /* Get the first event dev conf */
191 eventdev_config = &(em_conf->eventdev_config[0]);
192
193 /* Save number of queues & ports available */
194 eventdev_config->eventdev_id = 0;
195 eventdev_config->nb_eventqueue = dev_info.max_event_queues;
196 eventdev_config->nb_eventport = dev_info.max_event_ports;
197 eventdev_config->ev_queue_mode = RTE_EVENT_QUEUE_CFG_ALL_TYPES;
198
199 /* Check if there are more queues than required */
200 if (eventdev_config->nb_eventqueue > nb_eth_dev + 1) {
201 /* One queue is reserved for Tx */
202 eventdev_config->nb_eventqueue = nb_eth_dev + 1;
203 }
204
205 /* Check if there are more ports than required */
206 if (eventdev_config->nb_eventport > lcore_count) {
207 /* One port per lcore is enough */
208 eventdev_config->nb_eventport = lcore_count;
209 }
210
211 /* Update the number of event devices */
212 em_conf->nb_eventdev++;
213
214 return 0;
215 }
216
217 static void
218 eh_do_capability_check(struct eventmode_conf *em_conf)
219 {
220 struct eventdev_params *eventdev_config;
221 int all_internal_ports = 1;
222 uint32_t eventdev_id;
223 int i;
224
225 for (i = 0; i < em_conf->nb_eventdev; i++) {
226
227 /* Get the event dev conf */
228 eventdev_config = &(em_conf->eventdev_config[i]);
229 eventdev_id = eventdev_config->eventdev_id;
230
231 /* Check if event device has internal port for Rx & Tx */
232 if (eh_dev_has_rx_internal_port(eventdev_id) &&
233 eh_dev_has_tx_internal_port(eventdev_id)) {
234 eventdev_config->all_internal_ports = 1;
235 } else {
236 all_internal_ports = 0;
237 }
238 }
239
240 /*
241 * If Rx & Tx internal ports are supported by all event devices then
242 * eth cores won't be required. Override the eth core mask requested
243 * and decrement number of event queues by one as it won't be needed
244 * for Tx.
245 */
246 if (all_internal_ports) {
247 rte_bitmap_reset(em_conf->eth_core_mask);
248 for (i = 0; i < em_conf->nb_eventdev; i++)
249 em_conf->eventdev_config[i].nb_eventqueue--;
250 }
251 }
252
253 static int
254 eh_set_default_conf_link(struct eventmode_conf *em_conf)
255 {
256 struct eventdev_params *eventdev_config;
257 struct eh_event_link_info *link;
258 unsigned int lcore_id = -1;
259 int i, link_index;
260
261 /*
262 * Create a 1:1 mapping from event ports to cores. If the number
263 * of event ports is lesser than the cores, some cores won't
264 * execute worker. If there are more event ports, then some ports
265 * won't be used.
266 *
267 */
268
269 /*
270 * The event queue-port mapping is done according to the link. Since
271 * we are falling back to the default link config, enabling
272 * "all_ev_queue_to_ev_port" mode flag. This will map all queues
273 * to the port.
274 */
275 em_conf->ext_params.all_ev_queue_to_ev_port = 1;
276
277 /* Get first event dev conf */
278 eventdev_config = &(em_conf->eventdev_config[0]);
279
280 /* Loop through the ports */
281 for (i = 0; i < eventdev_config->nb_eventport; i++) {
282
283 /* Get next active core id */
284 lcore_id = eh_get_next_active_core(em_conf,
285 lcore_id);
286
287 if (lcore_id == RTE_MAX_LCORE) {
288 /* Reached max cores */
289 return 0;
290 }
291
292 /* Save the current combination as one link */
293
294 /* Get the index */
295 link_index = em_conf->nb_link;
296
297 /* Get the corresponding link */
298 link = &(em_conf->link[link_index]);
299
300 /* Save link */
301 link->eventdev_id = eventdev_config->eventdev_id;
302 link->event_port_id = i;
303 link->lcore_id = lcore_id;
304
305 /*
306 * Don't set eventq_id as by default all queues
307 * need to be mapped to the port, which is controlled
308 * by the operating mode.
309 */
310
311 /* Update number of links */
312 em_conf->nb_link++;
313 }
314
315 return 0;
316 }
317
318 static int
319 eh_set_default_conf_rx_adapter(struct eventmode_conf *em_conf)
320 {
321 struct rx_adapter_connection_info *conn;
322 struct eventdev_params *eventdev_config;
323 struct rx_adapter_conf *adapter;
324 bool rx_internal_port = true;
325 bool single_ev_queue = false;
326 int nb_eventqueue;
327 uint32_t caps = 0;
328 int eventdev_id;
329 int nb_eth_dev;
330 int adapter_id;
331 int conn_id;
332 int ret;
333 int i;
334
335 /* Create one adapter with eth queues mapped to event queue(s) */
336
337 if (em_conf->nb_eventdev == 0) {
338 EH_LOG_ERR("No event devs registered");
339 return -EINVAL;
340 }
341
342 /* Get the number of eth devs */
343 nb_eth_dev = rte_eth_dev_count_avail();
344
345 /* Use the first event dev */
346 eventdev_config = &(em_conf->eventdev_config[0]);
347
348 /* Get eventdev ID */
349 eventdev_id = eventdev_config->eventdev_id;
350 adapter_id = 0;
351
352 /* Get adapter conf */
353 adapter = &(em_conf->rx_adapter[adapter_id]);
354
355 /* Set adapter conf */
356 adapter->eventdev_id = eventdev_id;
357 adapter->adapter_id = adapter_id;
358
359 /*
360 * If event device does not have internal ports for passing
361 * packets then reserved one queue for Tx path
362 */
363 nb_eventqueue = eventdev_config->all_internal_ports ?
364 eventdev_config->nb_eventqueue :
365 eventdev_config->nb_eventqueue - 1;
366
367 /*
368 * Map all queues of eth device (port) to an event queue. If there
369 * are more event queues than eth ports then create 1:1 mapping.
370 * Otherwise map all eth ports to a single event queue.
371 */
372 if (nb_eth_dev > nb_eventqueue)
373 single_ev_queue = true;
374
375 for (i = 0; i < nb_eth_dev; i++) {
376
377 /* Use only the ports enabled */
378 if ((em_conf->eth_portmask & (1 << i)) == 0)
379 continue;
380
381 /* Get the connection id */
382 conn_id = adapter->nb_connections;
383
384 /* Get the connection */
385 conn = &(adapter->conn[conn_id]);
386
387 /* Set mapping between eth ports & event queues*/
388 conn->ethdev_id = i;
389 conn->eventq_id = single_ev_queue ? 0 : i;
390
391 /* Add all eth queues eth port to event queue */
392 conn->ethdev_rx_qid = -1;
393
394 /* Get Rx adapter capabilities */
395 ret = rte_event_eth_rx_adapter_caps_get(eventdev_id, i, &caps);
396 if (ret < 0) {
397 EH_LOG_ERR("Failed to get event device %d eth rx adapter"
398 " capabilities for port %d", eventdev_id, i);
399 return ret;
400 }
401 if (!(caps & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT))
402 rx_internal_port = false;
403
404 /* Update no of connections */
405 adapter->nb_connections++;
406
407 }
408
409 if (rx_internal_port) {
410 /* Rx core is not required */
411 adapter->rx_core_id = -1;
412 } else {
413 /* Rx core is required */
414 adapter->rx_core_id = eh_get_next_eth_core(em_conf);
415 }
416
417 /* We have setup one adapter */
418 em_conf->nb_rx_adapter = 1;
419
420 return 0;
421 }
422
423 static int
424 eh_set_default_conf_tx_adapter(struct eventmode_conf *em_conf)
425 {
426 struct tx_adapter_connection_info *conn;
427 struct eventdev_params *eventdev_config;
428 struct tx_adapter_conf *tx_adapter;
429 bool tx_internal_port = true;
430 uint32_t caps = 0;
431 int eventdev_id;
432 int adapter_id;
433 int nb_eth_dev;
434 int conn_id;
435 int ret;
436 int i;
437
438 /*
439 * Create one Tx adapter with all eth queues mapped to event queues
440 * 1:1.
441 */
442
443 if (em_conf->nb_eventdev == 0) {
444 EH_LOG_ERR("No event devs registered");
445 return -EINVAL;
446 }
447
448 /* Get the number of eth devs */
449 nb_eth_dev = rte_eth_dev_count_avail();
450
451 /* Use the first event dev */
452 eventdev_config = &(em_conf->eventdev_config[0]);
453
454 /* Get eventdev ID */
455 eventdev_id = eventdev_config->eventdev_id;
456 adapter_id = 0;
457
458 /* Get adapter conf */
459 tx_adapter = &(em_conf->tx_adapter[adapter_id]);
460
461 /* Set adapter conf */
462 tx_adapter->eventdev_id = eventdev_id;
463 tx_adapter->adapter_id = adapter_id;
464
465 /*
466 * Map all Tx queues of the eth device (port) to the event device.
467 */
468
469 /* Set defaults for connections */
470
471 /*
472 * One eth device (port) is one connection. Map all Tx queues
473 * of the device to the Tx adapter.
474 */
475
476 for (i = 0; i < nb_eth_dev; i++) {
477
478 /* Use only the ports enabled */
479 if ((em_conf->eth_portmask & (1 << i)) == 0)
480 continue;
481
482 /* Get the connection id */
483 conn_id = tx_adapter->nb_connections;
484
485 /* Get the connection */
486 conn = &(tx_adapter->conn[conn_id]);
487
488 /* Add ethdev to connections */
489 conn->ethdev_id = i;
490
491 /* Add all eth tx queues to adapter */
492 conn->ethdev_tx_qid = -1;
493
494 /* Get Tx adapter capabilities */
495 ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, i, &caps);
496 if (ret < 0) {
497 EH_LOG_ERR("Failed to get event device %d eth tx adapter"
498 " capabilities for port %d", eventdev_id, i);
499 return ret;
500 }
501 if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT))
502 tx_internal_port = false;
503
504 /* Update no of connections */
505 tx_adapter->nb_connections++;
506 }
507
508 if (tx_internal_port) {
509 /* Tx core is not required */
510 tx_adapter->tx_core_id = -1;
511 } else {
512 /* Tx core is required */
513 tx_adapter->tx_core_id = eh_get_next_eth_core(em_conf);
514
515 /*
516 * Use one event queue per adapter for submitting packets
517 * for Tx. Reserving the last queue available
518 */
519 /* Queue numbers start at 0 */
520 tx_adapter->tx_ev_queue = eventdev_config->nb_eventqueue - 1;
521 }
522
523 /* We have setup one adapter */
524 em_conf->nb_tx_adapter = 1;
525 return 0;
526 }
527
528 static int
529 eh_validate_conf(struct eventmode_conf *em_conf)
530 {
531 int ret;
532
533 /*
534 * Check if event devs are specified. Else probe the event devices
535 * and initialize the config with all ports & queues available
536 */
537 if (em_conf->nb_eventdev == 0) {
538 ret = eh_set_default_conf_eventdev(em_conf);
539 if (ret != 0)
540 return ret;
541 }
542
543 /* Perform capability check for the selected event devices */
544 eh_do_capability_check(em_conf);
545
546 /*
547 * Check if links are specified. Else generate a default config for
548 * the event ports used.
549 */
550 if (em_conf->nb_link == 0) {
551 ret = eh_set_default_conf_link(em_conf);
552 if (ret != 0)
553 return ret;
554 }
555
556 /*
557 * Check if rx adapters are specified. Else generate a default config
558 * with one rx adapter and all eth queues - event queue mapped.
559 */
560 if (em_conf->nb_rx_adapter == 0) {
561 ret = eh_set_default_conf_rx_adapter(em_conf);
562 if (ret != 0)
563 return ret;
564 }
565
566 /*
567 * Check if tx adapters are specified. Else generate a default config
568 * with one tx adapter.
569 */
570 if (em_conf->nb_tx_adapter == 0) {
571 ret = eh_set_default_conf_tx_adapter(em_conf);
572 if (ret != 0)
573 return ret;
574 }
575
576 return 0;
577 }
578
579 static int
580 eh_initialize_eventdev(struct eventmode_conf *em_conf)
581 {
582 struct rte_event_queue_conf eventq_conf = {0};
583 struct rte_event_dev_info evdev_default_conf;
584 struct rte_event_dev_config eventdev_conf;
585 struct eventdev_params *eventdev_config;
586 int nb_eventdev = em_conf->nb_eventdev;
587 struct eh_event_link_info *link;
588 uint8_t *queue = NULL;
589 uint8_t eventdev_id;
590 int nb_eventqueue;
591 uint8_t i, j;
592 int ret;
593
594 for (i = 0; i < nb_eventdev; i++) {
595
596 /* Get eventdev config */
597 eventdev_config = &(em_conf->eventdev_config[i]);
598
599 /* Get event dev ID */
600 eventdev_id = eventdev_config->eventdev_id;
601
602 /* Get the number of queues */
603 nb_eventqueue = eventdev_config->nb_eventqueue;
604
605 /* Reset the default conf */
606 memset(&evdev_default_conf, 0,
607 sizeof(struct rte_event_dev_info));
608
609 /* Get default conf of eventdev */
610 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf);
611 if (ret < 0) {
612 EH_LOG_ERR(
613 "Error in getting event device info[devID:%d]",
614 eventdev_id);
615 return ret;
616 }
617
618 memset(&eventdev_conf, 0, sizeof(struct rte_event_dev_config));
619 eventdev_conf.nb_events_limit =
620 evdev_default_conf.max_num_events;
621 eventdev_conf.nb_event_queues = nb_eventqueue;
622 eventdev_conf.nb_event_ports =
623 eventdev_config->nb_eventport;
624 eventdev_conf.nb_event_queue_flows =
625 evdev_default_conf.max_event_queue_flows;
626 eventdev_conf.nb_event_port_dequeue_depth =
627 evdev_default_conf.max_event_port_dequeue_depth;
628 eventdev_conf.nb_event_port_enqueue_depth =
629 evdev_default_conf.max_event_port_enqueue_depth;
630
631 /* Configure event device */
632 ret = rte_event_dev_configure(eventdev_id, &eventdev_conf);
633 if (ret < 0) {
634 EH_LOG_ERR("Error in configuring event device");
635 return ret;
636 }
637
638 /* Configure event queues */
639 for (j = 0; j < nb_eventqueue; j++) {
640
641 memset(&eventq_conf, 0,
642 sizeof(struct rte_event_queue_conf));
643
644 /* Per event dev queues can be ATQ or SINGLE LINK */
645 eventq_conf.event_queue_cfg =
646 eventdev_config->ev_queue_mode;
647 /*
648 * All queues need to be set with sched_type as
649 * schedule type for the application stage. One
650 * queue would be reserved for the final eth tx
651 * stage if event device does not have internal
652 * ports. This will be an atomic queue.
653 */
654 if (!eventdev_config->all_internal_ports &&
655 j == nb_eventqueue-1) {
656 eventq_conf.schedule_type =
657 RTE_SCHED_TYPE_ATOMIC;
658 } else {
659 eventq_conf.schedule_type =
660 em_conf->ext_params.sched_type;
661 }
662
663 /* Set max atomic flows to 1024 */
664 eventq_conf.nb_atomic_flows = 1024;
665 eventq_conf.nb_atomic_order_sequences = 1024;
666
667 /* Setup the queue */
668 ret = rte_event_queue_setup(eventdev_id, j,
669 &eventq_conf);
670 if (ret < 0) {
671 EH_LOG_ERR("Failed to setup event queue %d",
672 ret);
673 return ret;
674 }
675 }
676
677 /* Configure event ports */
678 for (j = 0; j < eventdev_config->nb_eventport; j++) {
679 ret = rte_event_port_setup(eventdev_id, j, NULL);
680 if (ret < 0) {
681 EH_LOG_ERR("Failed to setup event port %d",
682 ret);
683 return ret;
684 }
685 }
686 }
687
688 /* Make event queue - event port link */
689 for (j = 0; j < em_conf->nb_link; j++) {
690
691 /* Get link info */
692 link = &(em_conf->link[j]);
693
694 /* Get event dev ID */
695 eventdev_id = link->eventdev_id;
696
697 /*
698 * If "all_ev_queue_to_ev_port" params flag is selected, all
699 * queues need to be mapped to the port.
700 */
701 if (em_conf->ext_params.all_ev_queue_to_ev_port)
702 queue = NULL;
703 else
704 queue = &(link->eventq_id);
705
706 /* Link queue to port */
707 ret = rte_event_port_link(eventdev_id, link->event_port_id,
708 queue, NULL, 1);
709 if (ret < 0) {
710 EH_LOG_ERR("Failed to link event port %d", ret);
711 return ret;
712 }
713 }
714
715 /* Start event devices */
716 for (i = 0; i < nb_eventdev; i++) {
717
718 /* Get eventdev config */
719 eventdev_config = &(em_conf->eventdev_config[i]);
720
721 ret = rte_event_dev_start(eventdev_config->eventdev_id);
722 if (ret < 0) {
723 EH_LOG_ERR("Failed to start event device %d, %d",
724 i, ret);
725 return ret;
726 }
727 }
728 return 0;
729 }
730
731 static int
732 eh_rx_adapter_configure(struct eventmode_conf *em_conf,
733 struct rx_adapter_conf *adapter)
734 {
735 struct rte_event_eth_rx_adapter_queue_conf queue_conf = {0};
736 struct rte_event_dev_info evdev_default_conf = {0};
737 struct rte_event_port_conf port_conf = {0};
738 struct rx_adapter_connection_info *conn;
739 uint8_t eventdev_id;
740 uint32_t service_id;
741 int ret;
742 int j;
743
744 /* Get event dev ID */
745 eventdev_id = adapter->eventdev_id;
746
747 /* Get default configuration of event dev */
748 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf);
749 if (ret < 0) {
750 EH_LOG_ERR("Failed to get event dev info %d", ret);
751 return ret;
752 }
753
754 /* Setup port conf */
755 port_conf.new_event_threshold = 1200;
756 port_conf.dequeue_depth =
757 evdev_default_conf.max_event_port_dequeue_depth;
758 port_conf.enqueue_depth =
759 evdev_default_conf.max_event_port_enqueue_depth;
760
761 /* Create Rx adapter */
762 ret = rte_event_eth_rx_adapter_create(adapter->adapter_id,
763 adapter->eventdev_id, &port_conf);
764 if (ret < 0) {
765 EH_LOG_ERR("Failed to create rx adapter %d", ret);
766 return ret;
767 }
768
769 /* Setup various connections in the adapter */
770 for (j = 0; j < adapter->nb_connections; j++) {
771 /* Get connection */
772 conn = &(adapter->conn[j]);
773
774 /* Setup queue conf */
775 queue_conf.ev.queue_id = conn->eventq_id;
776 queue_conf.ev.sched_type = em_conf->ext_params.sched_type;
777 queue_conf.ev.event_type = RTE_EVENT_TYPE_ETHDEV;
778
779 /* Add queue to the adapter */
780 ret = rte_event_eth_rx_adapter_queue_add(adapter->adapter_id,
781 conn->ethdev_id, conn->ethdev_rx_qid,
782 &queue_conf);
783 if (ret < 0) {
784 EH_LOG_ERR("Failed to add eth queue to rx adapter %d",
785 ret);
786 return ret;
787 }
788 }
789
790 /* Get the service ID used by rx adapter */
791 ret = rte_event_eth_rx_adapter_service_id_get(adapter->adapter_id,
792 &service_id);
793 if (ret != -ESRCH && ret < 0) {
794 EH_LOG_ERR("Failed to get service id used by rx adapter %d",
795 ret);
796 return ret;
797 }
798
799 rte_service_set_runstate_mapped_check(service_id, 0);
800
801 /* Start adapter */
802 ret = rte_event_eth_rx_adapter_start(adapter->adapter_id);
803 if (ret < 0) {
804 EH_LOG_ERR("Failed to start rx adapter %d", ret);
805 return ret;
806 }
807
808 return 0;
809 }
810
811 static int
812 eh_initialize_rx_adapter(struct eventmode_conf *em_conf)
813 {
814 struct rx_adapter_conf *adapter;
815 int i, ret;
816
817 /* Configure rx adapters */
818 for (i = 0; i < em_conf->nb_rx_adapter; i++) {
819 adapter = &(em_conf->rx_adapter[i]);
820 ret = eh_rx_adapter_configure(em_conf, adapter);
821 if (ret < 0) {
822 EH_LOG_ERR("Failed to configure rx adapter %d", ret);
823 return ret;
824 }
825 }
826 return 0;
827 }
828
829 static int32_t
830 eh_start_worker_eth_core(struct eventmode_conf *conf, uint32_t lcore_id)
831 {
832 uint32_t service_id[EVENT_MODE_MAX_ADAPTERS_PER_RX_CORE];
833 struct rx_adapter_conf *rx_adapter;
834 struct tx_adapter_conf *tx_adapter;
835 int service_count = 0;
836 int adapter_id;
837 int32_t ret;
838 int i;
839
840 EH_LOG_INFO("Entering eth_core processing on lcore %u", lcore_id);
841
842 /*
843 * Parse adapter config to check which of all Rx adapters need
844 * to be handled by this core.
845 */
846 for (i = 0; i < conf->nb_rx_adapter; i++) {
847 /* Check if we have exceeded the max allowed */
848 if (service_count > EVENT_MODE_MAX_ADAPTERS_PER_RX_CORE) {
849 EH_LOG_ERR(
850 "Exceeded the max allowed adapters per rx core");
851 break;
852 }
853
854 rx_adapter = &(conf->rx_adapter[i]);
855 if (rx_adapter->rx_core_id != lcore_id)
856 continue;
857
858 /* Adapter is handled by this core */
859 adapter_id = rx_adapter->adapter_id;
860
861 /* Get the service ID for the adapters */
862 ret = rte_event_eth_rx_adapter_service_id_get(adapter_id,
863 &(service_id[service_count]));
864
865 if (ret != -ESRCH && ret < 0) {
866 EH_LOG_ERR(
867 "Failed to get service id used by rx adapter");
868 return ret;
869 }
870
871 /* Update service count */
872 service_count++;
873 }
874
875 /*
876 * Parse adapter config to see which of all Tx adapters need
877 * to be handled by this core.
878 */
879 for (i = 0; i < conf->nb_tx_adapter; i++) {
880 /* Check if we have exceeded the max allowed */
881 if (service_count > EVENT_MODE_MAX_ADAPTERS_PER_TX_CORE) {
882 EH_LOG_ERR(
883 "Exceeded the max allowed adapters per tx core");
884 break;
885 }
886
887 tx_adapter = &conf->tx_adapter[i];
888 if (tx_adapter->tx_core_id != lcore_id)
889 continue;
890
891 /* Adapter is handled by this core */
892 adapter_id = tx_adapter->adapter_id;
893
894 /* Get the service ID for the adapters */
895 ret = rte_event_eth_tx_adapter_service_id_get(adapter_id,
896 &(service_id[service_count]));
897
898 if (ret != -ESRCH && ret < 0) {
899 EH_LOG_ERR(
900 "Failed to get service id used by tx adapter");
901 return ret;
902 }
903
904 /* Update service count */
905 service_count++;
906 }
907
908 eth_core_running = true;
909
910 while (eth_core_running) {
911 for (i = 0; i < service_count; i++) {
912 /* Initiate adapter service */
913 rte_service_run_iter_on_app_lcore(service_id[i], 0);
914 }
915 }
916
917 return 0;
918 }
919
920 static int32_t
921 eh_stop_worker_eth_core(void)
922 {
923 if (eth_core_running) {
924 EH_LOG_INFO("Stopping eth cores");
925 eth_core_running = false;
926 }
927 return 0;
928 }
929
930 static struct eh_app_worker_params *
931 eh_find_worker(uint32_t lcore_id, struct eh_conf *conf,
932 struct eh_app_worker_params *app_wrkrs, uint8_t nb_wrkr_param)
933 {
934 struct eh_app_worker_params curr_conf = { {{0} }, NULL};
935 struct eh_event_link_info *link = NULL;
936 struct eh_app_worker_params *tmp_wrkr;
937 struct eventmode_conf *em_conf;
938 uint8_t eventdev_id;
939 int i;
940
941 /* Get eventmode config */
942 em_conf = conf->mode_params;
943
944 /*
945 * Use event device from the first lcore-event link.
946 *
947 * Assumption: All lcore-event links tied to a core are using the
948 * same event device. In other words, one core would be polling on
949 * queues of a single event device only.
950 */
951
952 /* Get a link for this lcore */
953 for (i = 0; i < em_conf->nb_link; i++) {
954 link = &(em_conf->link[i]);
955 if (link->lcore_id == lcore_id)
956 break;
957 }
958
959 if (link == NULL) {
960 EH_LOG_ERR("No valid link found for lcore %d", lcore_id);
961 return NULL;
962 }
963
964 /* Get event dev ID */
965 eventdev_id = link->eventdev_id;
966
967 /* Populate the curr_conf with the capabilities */
968
969 /* Check for Tx internal port */
970 if (eh_dev_has_tx_internal_port(eventdev_id))
971 curr_conf.cap.tx_internal_port = EH_TX_TYPE_INTERNAL_PORT;
972 else
973 curr_conf.cap.tx_internal_port = EH_TX_TYPE_NO_INTERNAL_PORT;
974
975 /* Check for burst mode */
976 if (eh_dev_has_burst_mode(eventdev_id))
977 curr_conf.cap.burst = EH_RX_TYPE_BURST;
978 else
979 curr_conf.cap.burst = EH_RX_TYPE_NON_BURST;
980
981 curr_conf.cap.ipsec_mode = conf->ipsec_mode;
982
983 /* Parse the passed list and see if we have matching capabilities */
984
985 /* Initialize the pointer used to traverse the list */
986 tmp_wrkr = app_wrkrs;
987
988 for (i = 0; i < nb_wrkr_param; i++, tmp_wrkr++) {
989
990 /* Skip this if capabilities are not matching */
991 if (tmp_wrkr->cap.u64 != curr_conf.cap.u64)
992 continue;
993
994 /* If the checks pass, we have a match */
995 return tmp_wrkr;
996 }
997
998 return NULL;
999 }
1000
1001 static int
1002 eh_verify_match_worker(struct eh_app_worker_params *match_wrkr)
1003 {
1004 /* Verify registered worker */
1005 if (match_wrkr->worker_thread == NULL) {
1006 EH_LOG_ERR("No worker registered");
1007 return 0;
1008 }
1009
1010 /* Success */
1011 return 1;
1012 }
1013
1014 static uint8_t
1015 eh_get_event_lcore_links(uint32_t lcore_id, struct eh_conf *conf,
1016 struct eh_event_link_info **links)
1017 {
1018 struct eh_event_link_info *link_cache;
1019 struct eventmode_conf *em_conf = NULL;
1020 struct eh_event_link_info *link;
1021 uint8_t lcore_nb_link = 0;
1022 size_t single_link_size;
1023 size_t cache_size;
1024 int index = 0;
1025 int i;
1026
1027 if (conf == NULL || links == NULL) {
1028 EH_LOG_ERR("Invalid args");
1029 return -EINVAL;
1030 }
1031
1032 /* Get eventmode conf */
1033 em_conf = conf->mode_params;
1034
1035 if (em_conf == NULL) {
1036 EH_LOG_ERR("Invalid event mode parameters");
1037 return -EINVAL;
1038 }
1039
1040 /* Get the number of links registered */
1041 for (i = 0; i < em_conf->nb_link; i++) {
1042
1043 /* Get link */
1044 link = &(em_conf->link[i]);
1045
1046 /* Check if we have link intended for this lcore */
1047 if (link->lcore_id == lcore_id) {
1048
1049 /* Update the number of links for this core */
1050 lcore_nb_link++;
1051
1052 }
1053 }
1054
1055 /* Compute size of one entry to be copied */
1056 single_link_size = sizeof(struct eh_event_link_info);
1057
1058 /* Compute size of the buffer required */
1059 cache_size = lcore_nb_link * sizeof(struct eh_event_link_info);
1060
1061 /* Compute size of the buffer required */
1062 link_cache = calloc(1, cache_size);
1063
1064 /* Get the number of links registered */
1065 for (i = 0; i < em_conf->nb_link; i++) {
1066
1067 /* Get link */
1068 link = &(em_conf->link[i]);
1069
1070 /* Check if we have link intended for this lcore */
1071 if (link->lcore_id == lcore_id) {
1072
1073 /* Cache the link */
1074 memcpy(&link_cache[index], link, single_link_size);
1075
1076 /* Update index */
1077 index++;
1078 }
1079 }
1080
1081 /* Update the links for application to use the cached links */
1082 *links = link_cache;
1083
1084 /* Return the number of cached links */
1085 return lcore_nb_link;
1086 }
1087
1088 static int
1089 eh_tx_adapter_configure(struct eventmode_conf *em_conf,
1090 struct tx_adapter_conf *adapter)
1091 {
1092 struct rte_event_dev_info evdev_default_conf = {0};
1093 struct rte_event_port_conf port_conf = {0};
1094 struct tx_adapter_connection_info *conn;
1095 struct eventdev_params *eventdev_config;
1096 uint8_t tx_port_id = 0;
1097 uint8_t eventdev_id;
1098 uint32_t service_id;
1099 int ret, j;
1100
1101 /* Get event dev ID */
1102 eventdev_id = adapter->eventdev_id;
1103
1104 /* Get event device conf */
1105 eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id);
1106
1107 /* Create Tx adapter */
1108
1109 /* Get default configuration of event dev */
1110 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf);
1111 if (ret < 0) {
1112 EH_LOG_ERR("Failed to get event dev info %d", ret);
1113 return ret;
1114 }
1115
1116 /* Setup port conf */
1117 port_conf.new_event_threshold =
1118 evdev_default_conf.max_num_events;
1119 port_conf.dequeue_depth =
1120 evdev_default_conf.max_event_port_dequeue_depth;
1121 port_conf.enqueue_depth =
1122 evdev_default_conf.max_event_port_enqueue_depth;
1123
1124 /* Create adapter */
1125 ret = rte_event_eth_tx_adapter_create(adapter->adapter_id,
1126 adapter->eventdev_id, &port_conf);
1127 if (ret < 0) {
1128 EH_LOG_ERR("Failed to create tx adapter %d", ret);
1129 return ret;
1130 }
1131
1132 /* Setup various connections in the adapter */
1133 for (j = 0; j < adapter->nb_connections; j++) {
1134
1135 /* Get connection */
1136 conn = &(adapter->conn[j]);
1137
1138 /* Add queue to the adapter */
1139 ret = rte_event_eth_tx_adapter_queue_add(adapter->adapter_id,
1140 conn->ethdev_id, conn->ethdev_tx_qid);
1141 if (ret < 0) {
1142 EH_LOG_ERR("Failed to add eth queue to tx adapter %d",
1143 ret);
1144 return ret;
1145 }
1146 }
1147
1148 /*
1149 * Check if Tx core is assigned. If Tx core is not assigned then
1150 * the adapter has internal port for submitting Tx packets and
1151 * Tx event queue & port setup is not required
1152 */
1153 if (adapter->tx_core_id == (uint32_t) (-1)) {
1154 /* Internal port is present */
1155 goto skip_tx_queue_port_setup;
1156 }
1157
1158 /* Setup Tx queue & port */
1159
1160 /* Get event port used by the adapter */
1161 ret = rte_event_eth_tx_adapter_event_port_get(
1162 adapter->adapter_id, &tx_port_id);
1163 if (ret) {
1164 EH_LOG_ERR("Failed to get tx adapter port id %d", ret);
1165 return ret;
1166 }
1167
1168 /*
1169 * Tx event queue is reserved for Tx adapter. Unlink this queue
1170 * from all other ports
1171 *
1172 */
1173 for (j = 0; j < eventdev_config->nb_eventport; j++) {
1174 rte_event_port_unlink(eventdev_id, j,
1175 &(adapter->tx_ev_queue), 1);
1176 }
1177
1178 /* Link Tx event queue to Tx port */
1179 ret = rte_event_port_link(eventdev_id, tx_port_id,
1180 &(adapter->tx_ev_queue), NULL, 1);
1181 if (ret != 1) {
1182 EH_LOG_ERR("Failed to link event queue to port");
1183 return ret;
1184 }
1185
1186 /* Get the service ID used by Tx adapter */
1187 ret = rte_event_eth_tx_adapter_service_id_get(adapter->adapter_id,
1188 &service_id);
1189 if (ret != -ESRCH && ret < 0) {
1190 EH_LOG_ERR("Failed to get service id used by tx adapter %d",
1191 ret);
1192 return ret;
1193 }
1194
1195 rte_service_set_runstate_mapped_check(service_id, 0);
1196
1197 skip_tx_queue_port_setup:
1198 /* Start adapter */
1199 ret = rte_event_eth_tx_adapter_start(adapter->adapter_id);
1200 if (ret < 0) {
1201 EH_LOG_ERR("Failed to start tx adapter %d", ret);
1202 return ret;
1203 }
1204
1205 return 0;
1206 }
1207
1208 static int
1209 eh_initialize_tx_adapter(struct eventmode_conf *em_conf)
1210 {
1211 struct tx_adapter_conf *adapter;
1212 int i, ret;
1213
1214 /* Configure Tx adapters */
1215 for (i = 0; i < em_conf->nb_tx_adapter; i++) {
1216 adapter = &(em_conf->tx_adapter[i]);
1217 ret = eh_tx_adapter_configure(em_conf, adapter);
1218 if (ret < 0) {
1219 EH_LOG_ERR("Failed to configure tx adapter %d", ret);
1220 return ret;
1221 }
1222 }
1223 return 0;
1224 }
1225
1226 static void
1227 eh_display_operating_mode(struct eventmode_conf *em_conf)
1228 {
1229 char sched_types[][32] = {
1230 "RTE_SCHED_TYPE_ORDERED",
1231 "RTE_SCHED_TYPE_ATOMIC",
1232 "RTE_SCHED_TYPE_PARALLEL",
1233 };
1234 EH_LOG_INFO("Operating mode:");
1235
1236 EH_LOG_INFO("\tScheduling type: \t%s",
1237 sched_types[em_conf->ext_params.sched_type]);
1238
1239 EH_LOG_INFO("");
1240 }
1241
1242 static void
1243 eh_display_event_dev_conf(struct eventmode_conf *em_conf)
1244 {
1245 char queue_mode[][32] = {
1246 "",
1247 "ATQ (ALL TYPE QUEUE)",
1248 "SINGLE LINK",
1249 };
1250 char print_buf[256] = { 0 };
1251 int i;
1252
1253 EH_LOG_INFO("Event Device Configuration:");
1254
1255 for (i = 0; i < em_conf->nb_eventdev; i++) {
1256 sprintf(print_buf,
1257 "\tDev ID: %-2d \tQueues: %-2d \tPorts: %-2d",
1258 em_conf->eventdev_config[i].eventdev_id,
1259 em_conf->eventdev_config[i].nb_eventqueue,
1260 em_conf->eventdev_config[i].nb_eventport);
1261 sprintf(print_buf + strlen(print_buf),
1262 "\tQueue mode: %s",
1263 queue_mode[em_conf->eventdev_config[i].ev_queue_mode]);
1264 EH_LOG_INFO("%s", print_buf);
1265 }
1266 EH_LOG_INFO("");
1267 }
1268
1269 static void
1270 eh_display_rx_adapter_conf(struct eventmode_conf *em_conf)
1271 {
1272 int nb_rx_adapter = em_conf->nb_rx_adapter;
1273 struct rx_adapter_connection_info *conn;
1274 struct rx_adapter_conf *adapter;
1275 char print_buf[256] = { 0 };
1276 int i, j;
1277
1278 EH_LOG_INFO("Rx adapters configured: %d", nb_rx_adapter);
1279
1280 for (i = 0; i < nb_rx_adapter; i++) {
1281 adapter = &(em_conf->rx_adapter[i]);
1282 sprintf(print_buf,
1283 "\tRx adaper ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
1284 adapter->adapter_id,
1285 adapter->nb_connections,
1286 adapter->eventdev_id);
1287 if (adapter->rx_core_id == (uint32_t)-1)
1288 sprintf(print_buf + strlen(print_buf),
1289 "\tRx core: %-2s", "[INTERNAL PORT]");
1290 else if (adapter->rx_core_id == RTE_MAX_LCORE)
1291 sprintf(print_buf + strlen(print_buf),
1292 "\tRx core: %-2s", "[NONE]");
1293 else
1294 sprintf(print_buf + strlen(print_buf),
1295 "\tRx core: %-2d", adapter->rx_core_id);
1296
1297 EH_LOG_INFO("%s", print_buf);
1298
1299 for (j = 0; j < adapter->nb_connections; j++) {
1300 conn = &(adapter->conn[j]);
1301
1302 sprintf(print_buf,
1303 "\t\tEthdev ID: %-2d", conn->ethdev_id);
1304
1305 if (conn->ethdev_rx_qid == -1)
1306 sprintf(print_buf + strlen(print_buf),
1307 "\tEth rx queue: %-2s", "ALL");
1308 else
1309 sprintf(print_buf + strlen(print_buf),
1310 "\tEth rx queue: %-2d",
1311 conn->ethdev_rx_qid);
1312
1313 sprintf(print_buf + strlen(print_buf),
1314 "\tEvent queue: %-2d", conn->eventq_id);
1315 EH_LOG_INFO("%s", print_buf);
1316 }
1317 }
1318 EH_LOG_INFO("");
1319 }
1320
1321 static void
1322 eh_display_tx_adapter_conf(struct eventmode_conf *em_conf)
1323 {
1324 int nb_tx_adapter = em_conf->nb_tx_adapter;
1325 struct tx_adapter_connection_info *conn;
1326 struct tx_adapter_conf *adapter;
1327 char print_buf[256] = { 0 };
1328 int i, j;
1329
1330 EH_LOG_INFO("Tx adapters configured: %d", nb_tx_adapter);
1331
1332 for (i = 0; i < nb_tx_adapter; i++) {
1333 adapter = &(em_conf->tx_adapter[i]);
1334 sprintf(print_buf,
1335 "\tTx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
1336 adapter->adapter_id,
1337 adapter->nb_connections,
1338 adapter->eventdev_id);
1339 if (adapter->tx_core_id == (uint32_t)-1)
1340 sprintf(print_buf + strlen(print_buf),
1341 "\tTx core: %-2s", "[INTERNAL PORT]");
1342 else if (adapter->tx_core_id == RTE_MAX_LCORE)
1343 sprintf(print_buf + strlen(print_buf),
1344 "\tTx core: %-2s", "[NONE]");
1345 else
1346 sprintf(print_buf + strlen(print_buf),
1347 "\tTx core: %-2d,\tInput event queue: %-2d",
1348 adapter->tx_core_id, adapter->tx_ev_queue);
1349
1350 EH_LOG_INFO("%s", print_buf);
1351
1352 for (j = 0; j < adapter->nb_connections; j++) {
1353 conn = &(adapter->conn[j]);
1354
1355 sprintf(print_buf,
1356 "\t\tEthdev ID: %-2d", conn->ethdev_id);
1357
1358 if (conn->ethdev_tx_qid == -1)
1359 sprintf(print_buf + strlen(print_buf),
1360 "\tEth tx queue: %-2s", "ALL");
1361 else
1362 sprintf(print_buf + strlen(print_buf),
1363 "\tEth tx queue: %-2d",
1364 conn->ethdev_tx_qid);
1365 EH_LOG_INFO("%s", print_buf);
1366 }
1367 }
1368 EH_LOG_INFO("");
1369 }
1370
1371 static void
1372 eh_display_link_conf(struct eventmode_conf *em_conf)
1373 {
1374 struct eh_event_link_info *link;
1375 char print_buf[256] = { 0 };
1376 int i;
1377
1378 EH_LOG_INFO("Links configured: %d", em_conf->nb_link);
1379
1380 for (i = 0; i < em_conf->nb_link; i++) {
1381 link = &(em_conf->link[i]);
1382
1383 sprintf(print_buf,
1384 "\tEvent dev ID: %-2d\tEvent port: %-2d",
1385 link->eventdev_id,
1386 link->event_port_id);
1387
1388 if (em_conf->ext_params.all_ev_queue_to_ev_port)
1389 sprintf(print_buf + strlen(print_buf),
1390 "Event queue: %-2s\t", "ALL");
1391 else
1392 sprintf(print_buf + strlen(print_buf),
1393 "Event queue: %-2d\t", link->eventq_id);
1394
1395 sprintf(print_buf + strlen(print_buf),
1396 "Lcore: %-2d", link->lcore_id);
1397 EH_LOG_INFO("%s", print_buf);
1398 }
1399 EH_LOG_INFO("");
1400 }
1401
1402 struct eh_conf *
1403 eh_conf_init(void)
1404 {
1405 struct eventmode_conf *em_conf = NULL;
1406 struct eh_conf *conf = NULL;
1407 unsigned int eth_core_id;
1408 void *bitmap = NULL;
1409 uint32_t nb_bytes;
1410
1411 /* Allocate memory for config */
1412 conf = calloc(1, sizeof(struct eh_conf));
1413 if (conf == NULL) {
1414 EH_LOG_ERR("Failed to allocate memory for eventmode helper "
1415 "config");
1416 return NULL;
1417 }
1418
1419 /* Set default conf */
1420
1421 /* Packet transfer mode: poll */
1422 conf->mode = EH_PKT_TRANSFER_MODE_POLL;
1423 conf->ipsec_mode = EH_IPSEC_MODE_TYPE_APP;
1424
1425 /* Keep all ethernet ports enabled by default */
1426 conf->eth_portmask = -1;
1427
1428 /* Allocate memory for event mode params */
1429 conf->mode_params = calloc(1, sizeof(struct eventmode_conf));
1430 if (conf->mode_params == NULL) {
1431 EH_LOG_ERR("Failed to allocate memory for event mode params");
1432 goto free_conf;
1433 }
1434
1435 /* Get eventmode conf */
1436 em_conf = conf->mode_params;
1437
1438 /* Allocate and initialize bitmap for eth cores */
1439 nb_bytes = rte_bitmap_get_memory_footprint(RTE_MAX_LCORE);
1440 if (!nb_bytes) {
1441 EH_LOG_ERR("Failed to get bitmap footprint");
1442 goto free_em_conf;
1443 }
1444
1445 bitmap = rte_zmalloc("event-helper-ethcore-bitmap", nb_bytes,
1446 RTE_CACHE_LINE_SIZE);
1447 if (!bitmap) {
1448 EH_LOG_ERR("Failed to allocate memory for eth cores bitmap\n");
1449 goto free_em_conf;
1450 }
1451
1452 em_conf->eth_core_mask = rte_bitmap_init(RTE_MAX_LCORE, bitmap,
1453 nb_bytes);
1454 if (!em_conf->eth_core_mask) {
1455 EH_LOG_ERR("Failed to initialize bitmap");
1456 goto free_bitmap;
1457 }
1458
1459 /* Set schedule type as not set */
1460 em_conf->ext_params.sched_type = SCHED_TYPE_NOT_SET;
1461
1462 /* Set two cores as eth cores for Rx & Tx */
1463
1464 /* Use first core other than master core as Rx core */
1465 eth_core_id = rte_get_next_lcore(0, /* curr core */
1466 1, /* skip master core */
1467 0 /* wrap */);
1468
1469 rte_bitmap_set(em_conf->eth_core_mask, eth_core_id);
1470
1471 /* Use next core as Tx core */
1472 eth_core_id = rte_get_next_lcore(eth_core_id, /* curr core */
1473 1, /* skip master core */
1474 0 /* wrap */);
1475
1476 rte_bitmap_set(em_conf->eth_core_mask, eth_core_id);
1477
1478 return conf;
1479
1480 free_bitmap:
1481 rte_free(bitmap);
1482 free_em_conf:
1483 free(em_conf);
1484 free_conf:
1485 free(conf);
1486 return NULL;
1487 }
1488
1489 void
1490 eh_conf_uninit(struct eh_conf *conf)
1491 {
1492 struct eventmode_conf *em_conf = NULL;
1493
1494 if (!conf || !conf->mode_params)
1495 return;
1496
1497 /* Get eventmode conf */
1498 em_conf = conf->mode_params;
1499
1500 /* Free evenmode configuration memory */
1501 rte_free(em_conf->eth_core_mask);
1502 free(em_conf);
1503 free(conf);
1504 }
1505
1506 void
1507 eh_display_conf(struct eh_conf *conf)
1508 {
1509 struct eventmode_conf *em_conf;
1510
1511 if (conf == NULL) {
1512 EH_LOG_ERR("Invalid event helper configuration");
1513 return;
1514 }
1515
1516 if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
1517 return;
1518
1519 if (conf->mode_params == NULL) {
1520 EH_LOG_ERR("Invalid event mode parameters");
1521 return;
1522 }
1523
1524 /* Get eventmode conf */
1525 em_conf = (struct eventmode_conf *)(conf->mode_params);
1526
1527 /* Display user exposed operating modes */
1528 eh_display_operating_mode(em_conf);
1529
1530 /* Display event device conf */
1531 eh_display_event_dev_conf(em_conf);
1532
1533 /* Display Rx adapter conf */
1534 eh_display_rx_adapter_conf(em_conf);
1535
1536 /* Display Tx adapter conf */
1537 eh_display_tx_adapter_conf(em_conf);
1538
1539 /* Display event-lcore link */
1540 eh_display_link_conf(em_conf);
1541 }
1542
1543 int32_t
1544 eh_devs_init(struct eh_conf *conf)
1545 {
1546 struct eventmode_conf *em_conf;
1547 uint16_t port_id;
1548 int ret;
1549
1550 if (conf == NULL) {
1551 EH_LOG_ERR("Invalid event helper configuration");
1552 return -EINVAL;
1553 }
1554
1555 if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
1556 return 0;
1557
1558 if (conf->mode_params == NULL) {
1559 EH_LOG_ERR("Invalid event mode parameters");
1560 return -EINVAL;
1561 }
1562
1563 /* Get eventmode conf */
1564 em_conf = conf->mode_params;
1565
1566 /* Eventmode conf would need eth portmask */
1567 em_conf->eth_portmask = conf->eth_portmask;
1568
1569 /* Validate the requested config */
1570 ret = eh_validate_conf(em_conf);
1571 if (ret < 0) {
1572 EH_LOG_ERR("Failed to validate the requested config %d", ret);
1573 return ret;
1574 }
1575
1576 /* Display the current configuration */
1577 eh_display_conf(conf);
1578
1579 /* Stop eth devices before setting up adapter */
1580 RTE_ETH_FOREACH_DEV(port_id) {
1581
1582 /* Use only the ports enabled */
1583 if ((conf->eth_portmask & (1 << port_id)) == 0)
1584 continue;
1585
1586 rte_eth_dev_stop(port_id);
1587 }
1588
1589 /* Setup eventdev */
1590 ret = eh_initialize_eventdev(em_conf);
1591 if (ret < 0) {
1592 EH_LOG_ERR("Failed to initialize event dev %d", ret);
1593 return ret;
1594 }
1595
1596 /* Setup Rx adapter */
1597 ret = eh_initialize_rx_adapter(em_conf);
1598 if (ret < 0) {
1599 EH_LOG_ERR("Failed to initialize rx adapter %d", ret);
1600 return ret;
1601 }
1602
1603 /* Setup Tx adapter */
1604 ret = eh_initialize_tx_adapter(em_conf);
1605 if (ret < 0) {
1606 EH_LOG_ERR("Failed to initialize tx adapter %d", ret);
1607 return ret;
1608 }
1609
1610 /* Start eth devices after setting up adapter */
1611 RTE_ETH_FOREACH_DEV(port_id) {
1612
1613 /* Use only the ports enabled */
1614 if ((conf->eth_portmask & (1 << port_id)) == 0)
1615 continue;
1616
1617 ret = rte_eth_dev_start(port_id);
1618 if (ret < 0) {
1619 EH_LOG_ERR("Failed to start eth dev %d, %d",
1620 port_id, ret);
1621 return ret;
1622 }
1623 }
1624
1625 return 0;
1626 }
1627
1628 int32_t
1629 eh_devs_uninit(struct eh_conf *conf)
1630 {
1631 struct eventmode_conf *em_conf;
1632 int ret, i, j;
1633 uint16_t id;
1634
1635 if (conf == NULL) {
1636 EH_LOG_ERR("Invalid event helper configuration");
1637 return -EINVAL;
1638 }
1639
1640 if (conf->mode != EH_PKT_TRANSFER_MODE_EVENT)
1641 return 0;
1642
1643 if (conf->mode_params == NULL) {
1644 EH_LOG_ERR("Invalid event mode parameters");
1645 return -EINVAL;
1646 }
1647
1648 /* Get eventmode conf */
1649 em_conf = conf->mode_params;
1650
1651 /* Stop and release rx adapters */
1652 for (i = 0; i < em_conf->nb_rx_adapter; i++) {
1653
1654 id = em_conf->rx_adapter[i].adapter_id;
1655 ret = rte_event_eth_rx_adapter_stop(id);
1656 if (ret < 0) {
1657 EH_LOG_ERR("Failed to stop rx adapter %d", ret);
1658 return ret;
1659 }
1660
1661 for (j = 0; j < em_conf->rx_adapter[i].nb_connections; j++) {
1662
1663 ret = rte_event_eth_rx_adapter_queue_del(id,
1664 em_conf->rx_adapter[i].conn[j].ethdev_id, -1);
1665 if (ret < 0) {
1666 EH_LOG_ERR(
1667 "Failed to remove rx adapter queues %d",
1668 ret);
1669 return ret;
1670 }
1671 }
1672
1673 ret = rte_event_eth_rx_adapter_free(id);
1674 if (ret < 0) {
1675 EH_LOG_ERR("Failed to free rx adapter %d", ret);
1676 return ret;
1677 }
1678 }
1679
1680 /* Stop and release event devices */
1681 for (i = 0; i < em_conf->nb_eventdev; i++) {
1682
1683 id = em_conf->eventdev_config[i].eventdev_id;
1684 rte_event_dev_stop(id);
1685
1686 ret = rte_event_dev_close(id);
1687 if (ret < 0) {
1688 EH_LOG_ERR("Failed to close event dev %d, %d", id, ret);
1689 return ret;
1690 }
1691 }
1692
1693 /* Stop and release tx adapters */
1694 for (i = 0; i < em_conf->nb_tx_adapter; i++) {
1695
1696 id = em_conf->tx_adapter[i].adapter_id;
1697 ret = rte_event_eth_tx_adapter_stop(id);
1698 if (ret < 0) {
1699 EH_LOG_ERR("Failed to stop tx adapter %d", ret);
1700 return ret;
1701 }
1702
1703 for (j = 0; j < em_conf->tx_adapter[i].nb_connections; j++) {
1704
1705 ret = rte_event_eth_tx_adapter_queue_del(id,
1706 em_conf->tx_adapter[i].conn[j].ethdev_id, -1);
1707 if (ret < 0) {
1708 EH_LOG_ERR(
1709 "Failed to remove tx adapter queues %d",
1710 ret);
1711 return ret;
1712 }
1713 }
1714
1715 ret = rte_event_eth_tx_adapter_free(id);
1716 if (ret < 0) {
1717 EH_LOG_ERR("Failed to free tx adapter %d", ret);
1718 return ret;
1719 }
1720 }
1721
1722 return 0;
1723 }
1724
1725 void
1726 eh_launch_worker(struct eh_conf *conf, struct eh_app_worker_params *app_wrkr,
1727 uint8_t nb_wrkr_param)
1728 {
1729 struct eh_app_worker_params *match_wrkr;
1730 struct eh_event_link_info *links = NULL;
1731 struct eventmode_conf *em_conf;
1732 uint32_t lcore_id;
1733 uint8_t nb_links;
1734
1735 if (conf == NULL) {
1736 EH_LOG_ERR("Invalid event helper configuration");
1737 return;
1738 }
1739
1740 if (conf->mode_params == NULL) {
1741 EH_LOG_ERR("Invalid event mode parameters");
1742 return;
1743 }
1744
1745 /* Get eventmode conf */
1746 em_conf = conf->mode_params;
1747
1748 /* Get core ID */
1749 lcore_id = rte_lcore_id();
1750
1751 /* Check if this is eth core */
1752 if (rte_bitmap_get(em_conf->eth_core_mask, lcore_id)) {
1753 eh_start_worker_eth_core(em_conf, lcore_id);
1754 return;
1755 }
1756
1757 if (app_wrkr == NULL || nb_wrkr_param == 0) {
1758 EH_LOG_ERR("Invalid args");
1759 return;
1760 }
1761
1762 /*
1763 * This is a regular worker thread. The application registers
1764 * multiple workers with various capabilities. Run worker
1765 * based on the selected capabilities of the event
1766 * device configured.
1767 */
1768
1769 /* Get the first matching worker for the event device */
1770 match_wrkr = eh_find_worker(lcore_id, conf, app_wrkr, nb_wrkr_param);
1771 if (match_wrkr == NULL) {
1772 EH_LOG_ERR("Failed to match worker registered for lcore %d",
1773 lcore_id);
1774 goto clean_and_exit;
1775 }
1776
1777 /* Verify sanity of the matched worker */
1778 if (eh_verify_match_worker(match_wrkr) != 1) {
1779 EH_LOG_ERR("Failed to validate the matched worker");
1780 goto clean_and_exit;
1781 }
1782
1783 /* Get worker links */
1784 nb_links = eh_get_event_lcore_links(lcore_id, conf, &links);
1785
1786 /* Launch the worker thread */
1787 match_wrkr->worker_thread(links, nb_links);
1788
1789 /* Free links info memory */
1790 free(links);
1791
1792 clean_and_exit:
1793
1794 /* Flag eth_cores to stop, if started */
1795 eh_stop_worker_eth_core();
1796 }
1797
1798 uint8_t
1799 eh_get_tx_queue(struct eh_conf *conf, uint8_t eventdev_id)
1800 {
1801 struct eventdev_params *eventdev_config;
1802 struct eventmode_conf *em_conf;
1803
1804 if (conf == NULL) {
1805 EH_LOG_ERR("Invalid event helper configuration");
1806 return -EINVAL;
1807 }
1808
1809 if (conf->mode_params == NULL) {
1810 EH_LOG_ERR("Invalid event mode parameters");
1811 return -EINVAL;
1812 }
1813
1814 /* Get eventmode conf */
1815 em_conf = conf->mode_params;
1816
1817 /* Get event device conf */
1818 eventdev_config = eh_get_eventdev_params(em_conf, eventdev_id);
1819
1820 if (eventdev_config == NULL) {
1821 EH_LOG_ERR("Failed to read eventdev config");
1822 return -EINVAL;
1823 }
1824
1825 /*
1826 * The last queue is reserved to be used as atomic queue for the
1827 * last stage (eth packet tx stage)
1828 */
1829 return eventdev_config->nb_eventqueue - 1;
1830 }