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