1*2c7debd9SRakesh Kudurumalla /* SPDX-License-Identifier: BSD-3-Clause
2*2c7debd9SRakesh Kudurumalla * Copyright(c) 2023 Marvell.
3*2c7debd9SRakesh Kudurumalla */
4*2c7debd9SRakesh Kudurumalla
5*2c7debd9SRakesh Kudurumalla #include <errno.h>
6*2c7debd9SRakesh Kudurumalla #include <stdbool.h>
7*2c7debd9SRakesh Kudurumalla #include <stdint.h>
8*2c7debd9SRakesh Kudurumalla #include <stdio.h>
9*2c7debd9SRakesh Kudurumalla #include <stdlib.h>
10*2c7debd9SRakesh Kudurumalla #include <string.h>
11*2c7debd9SRakesh Kudurumalla
12*2c7debd9SRakesh Kudurumalla #include <rte_common.h>
13*2c7debd9SRakesh Kudurumalla #include <rte_ethdev.h>
14*2c7debd9SRakesh Kudurumalla #include <rte_graph.h>
15*2c7debd9SRakesh Kudurumalla #include <rte_graph_worker.h>
16*2c7debd9SRakesh Kudurumalla #include <rte_lcore.h>
17*2c7debd9SRakesh Kudurumalla #include <rte_node_eth_api.h>
18*2c7debd9SRakesh Kudurumalla
19*2c7debd9SRakesh Kudurumalla #include "module_api.h"
20*2c7debd9SRakesh Kudurumalla
21*2c7debd9SRakesh Kudurumalla static int
l2fwd_pattern_configure(void)22*2c7debd9SRakesh Kudurumalla l2fwd_pattern_configure(void)
23*2c7debd9SRakesh Kudurumalla {
24*2c7debd9SRakesh Kudurumalla struct rte_graph_param graph_conf;
25*2c7debd9SRakesh Kudurumalla const char **node_patterns;
26*2c7debd9SRakesh Kudurumalla uint64_t pcap_pkts_count;
27*2c7debd9SRakesh Kudurumalla struct lcore_conf *qconf;
28*2c7debd9SRakesh Kudurumalla uint16_t nb_patterns;
29*2c7debd9SRakesh Kudurumalla uint8_t pcap_ena;
30*2c7debd9SRakesh Kudurumalla char *pcap_file;
31*2c7debd9SRakesh Kudurumalla int lcore_id;
32*2c7debd9SRakesh Kudurumalla
33*2c7debd9SRakesh Kudurumalla nb_patterns = 0;
34*2c7debd9SRakesh Kudurumalla node_patterns = malloc((ETHDEV_RX_QUEUE_PER_LCORE_MAX + nb_patterns) *
35*2c7debd9SRakesh Kudurumalla sizeof(*node_patterns));
36*2c7debd9SRakesh Kudurumalla if (!node_patterns)
37*2c7debd9SRakesh Kudurumalla return -ENOMEM;
38*2c7debd9SRakesh Kudurumalla
39*2c7debd9SRakesh Kudurumalla memset(&graph_conf, 0, sizeof(graph_conf));
40*2c7debd9SRakesh Kudurumalla graph_conf.node_patterns = node_patterns;
41*2c7debd9SRakesh Kudurumalla
42*2c7debd9SRakesh Kudurumalla /* Pcap config */
43*2c7debd9SRakesh Kudurumalla graph_pcap_config_get(&pcap_ena, &pcap_pkts_count, &pcap_file);
44*2c7debd9SRakesh Kudurumalla graph_conf.pcap_enable = pcap_ena;
45*2c7debd9SRakesh Kudurumalla graph_conf.num_pkt_to_capture = pcap_pkts_count;
46*2c7debd9SRakesh Kudurumalla graph_conf.pcap_filename = strdup(pcap_file);
47*2c7debd9SRakesh Kudurumalla
48*2c7debd9SRakesh Kudurumalla for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
49*2c7debd9SRakesh Kudurumalla rte_graph_t graph_id;
50*2c7debd9SRakesh Kudurumalla rte_edge_t i;
51*2c7debd9SRakesh Kudurumalla
52*2c7debd9SRakesh Kudurumalla if (rte_lcore_is_enabled(lcore_id) == 0)
53*2c7debd9SRakesh Kudurumalla continue;
54*2c7debd9SRakesh Kudurumalla
55*2c7debd9SRakesh Kudurumalla qconf = &lcore_conf[lcore_id];
56*2c7debd9SRakesh Kudurumalla
57*2c7debd9SRakesh Kudurumalla /* Skip graph creation if no source exists */
58*2c7debd9SRakesh Kudurumalla if (!qconf->n_rx_queue)
59*2c7debd9SRakesh Kudurumalla continue;
60*2c7debd9SRakesh Kudurumalla
61*2c7debd9SRakesh Kudurumalla /* Add rx node patterns of this lcore */
62*2c7debd9SRakesh Kudurumalla for (i = 0; i < qconf->n_rx_queue; i++) {
63*2c7debd9SRakesh Kudurumalla graph_conf.node_patterns[nb_patterns + i] =
64*2c7debd9SRakesh Kudurumalla qconf->rx_queue_list[i].node_name;
65*2c7debd9SRakesh Kudurumalla }
66*2c7debd9SRakesh Kudurumalla
67*2c7debd9SRakesh Kudurumalla graph_conf.nb_node_patterns = nb_patterns + i;
68*2c7debd9SRakesh Kudurumalla graph_conf.socket_id = rte_lcore_to_socket_id(lcore_id);
69*2c7debd9SRakesh Kudurumalla
70*2c7debd9SRakesh Kudurumalla snprintf(qconf->name, sizeof(qconf->name), "worker_%u",
71*2c7debd9SRakesh Kudurumalla lcore_id);
72*2c7debd9SRakesh Kudurumalla
73*2c7debd9SRakesh Kudurumalla graph_id = rte_graph_create(qconf->name, &graph_conf);
74*2c7debd9SRakesh Kudurumalla if (graph_id == RTE_GRAPH_ID_INVALID)
75*2c7debd9SRakesh Kudurumalla rte_exit(EXIT_FAILURE,
76*2c7debd9SRakesh Kudurumalla "rte_graph_create(): graph_id invalid"
77*2c7debd9SRakesh Kudurumalla " for lcore %u\n", lcore_id);
78*2c7debd9SRakesh Kudurumalla
79*2c7debd9SRakesh Kudurumalla qconf->graph_id = graph_id;
80*2c7debd9SRakesh Kudurumalla qconf->graph = rte_graph_lookup(qconf->name);
81*2c7debd9SRakesh Kudurumalla /* >8 End of graph initialization. */
82*2c7debd9SRakesh Kudurumalla if (!qconf->graph)
83*2c7debd9SRakesh Kudurumalla rte_exit(EXIT_FAILURE,
84*2c7debd9SRakesh Kudurumalla "rte_graph_lookup(): graph %s not found\n",
85*2c7debd9SRakesh Kudurumalla qconf->name);
86*2c7debd9SRakesh Kudurumalla }
87*2c7debd9SRakesh Kudurumalla
88*2c7debd9SRakesh Kudurumalla /* Launch per-lcore init on every worker lcore */
89*2c7debd9SRakesh Kudurumalla rte_eal_mp_remote_launch(graph_walk_start, NULL, SKIP_MAIN);
90*2c7debd9SRakesh Kudurumalla
91*2c7debd9SRakesh Kudurumalla /* Accumulate and print stats on main until exit */
92*2c7debd9SRakesh Kudurumalla if (rte_graph_has_stats_feature() && app_graph_stats_enabled())
93*2c7debd9SRakesh Kudurumalla graph_stats_print();
94*2c7debd9SRakesh Kudurumalla
95*2c7debd9SRakesh Kudurumalla return 0;
96*2c7debd9SRakesh Kudurumalla }
97*2c7debd9SRakesh Kudurumalla
98*2c7debd9SRakesh Kudurumalla static int
ethdev_rx_to_tx_node_link(uint32_t lcore_id)99*2c7debd9SRakesh Kudurumalla ethdev_rx_to_tx_node_link(uint32_t lcore_id)
100*2c7debd9SRakesh Kudurumalla {
101*2c7debd9SRakesh Kudurumalla char name[RTE_NODE_NAMESIZE];
102*2c7debd9SRakesh Kudurumalla const char *next_node = name;
103*2c7debd9SRakesh Kudurumalla struct lcore_conf *qconf;
104*2c7debd9SRakesh Kudurumalla uint16_t queue, port_id;
105*2c7debd9SRakesh Kudurumalla rte_node_t rx_id;
106*2c7debd9SRakesh Kudurumalla int16_t txport;
107*2c7debd9SRakesh Kudurumalla int rc = 0;
108*2c7debd9SRakesh Kudurumalla
109*2c7debd9SRakesh Kudurumalla qconf = &lcore_conf[lcore_id];
110*2c7debd9SRakesh Kudurumalla
111*2c7debd9SRakesh Kudurumalla for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
112*2c7debd9SRakesh Kudurumalla port_id = qconf->rx_queue_list[queue].port_id;
113*2c7debd9SRakesh Kudurumalla txport = ethdev_txport_by_rxport_get(port_id);
114*2c7debd9SRakesh Kudurumalla if (txport >= 0) {
115*2c7debd9SRakesh Kudurumalla rx_id = rte_node_from_name(qconf->rx_queue_list[queue].node_name);
116*2c7debd9SRakesh Kudurumalla snprintf(name, sizeof(name), "ethdev_tx-%u", txport);
117*2c7debd9SRakesh Kudurumalla rte_node_edge_update(rx_id, RTE_EDGE_ID_INVALID, &next_node, 1);
118*2c7debd9SRakesh Kudurumalla rc = rte_node_ethdev_rx_next_update(rx_id, name);
119*2c7debd9SRakesh Kudurumalla if (rc)
120*2c7debd9SRakesh Kudurumalla goto exit;
121*2c7debd9SRakesh Kudurumalla } else {
122*2c7debd9SRakesh Kudurumalla rc = -EINVAL;
123*2c7debd9SRakesh Kudurumalla goto exit;
124*2c7debd9SRakesh Kudurumalla }
125*2c7debd9SRakesh Kudurumalla }
126*2c7debd9SRakesh Kudurumalla exit:
127*2c7debd9SRakesh Kudurumalla return rc;
128*2c7debd9SRakesh Kudurumalla }
129*2c7debd9SRakesh Kudurumalla
130*2c7debd9SRakesh Kudurumalla
131*2c7debd9SRakesh Kudurumalla int
usecase_l2fwd_configure(struct rte_node_ethdev_config * conf,uint16_t nb_confs,uint16_t nb_graphs)132*2c7debd9SRakesh Kudurumalla usecase_l2fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs)
133*2c7debd9SRakesh Kudurumalla {
134*2c7debd9SRakesh Kudurumalla uint32_t lcore_id;
135*2c7debd9SRakesh Kudurumalla int rc;
136*2c7debd9SRakesh Kudurumalla
137*2c7debd9SRakesh Kudurumalla rc = rte_node_eth_config(conf, nb_confs, nb_graphs);
138*2c7debd9SRakesh Kudurumalla if (rc)
139*2c7debd9SRakesh Kudurumalla rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc);
140*2c7debd9SRakesh Kudurumalla
141*2c7debd9SRakesh Kudurumalla for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
142*2c7debd9SRakesh Kudurumalla rc = ethdev_rx_to_tx_node_link(lcore_id);
143*2c7debd9SRakesh Kudurumalla if (rc)
144*2c7debd9SRakesh Kudurumalla rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc);
145*2c7debd9SRakesh Kudurumalla }
146*2c7debd9SRakesh Kudurumalla
147*2c7debd9SRakesh Kudurumalla rc = l2fwd_pattern_configure();
148*2c7debd9SRakesh Kudurumalla if (rc)
149*2c7debd9SRakesh Kudurumalla rte_exit(EXIT_FAILURE, "l2fwd_pattern_failure: err=%d\n", rc);
150*2c7debd9SRakesh Kudurumalla
151*2c7debd9SRakesh Kudurumalla return rc;
152*2c7debd9SRakesh Kudurumalla }
153