1474572d2SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2474572d2SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
3474572d2SBruce Richardson */
4474572d2SBruce Richardson
5474572d2SBruce Richardson #include <stdio.h>
6474572d2SBruce Richardson #include <stdlib.h>
7474572d2SBruce Richardson #include <stdint.h>
8474572d2SBruce Richardson #include <inttypes.h>
9474572d2SBruce Richardson #include <sys/types.h>
10474572d2SBruce Richardson #include <string.h>
11474572d2SBruce Richardson #include <sys/queue.h>
12474572d2SBruce Richardson #include <stdarg.h>
13474572d2SBruce Richardson #include <errno.h>
14474572d2SBruce Richardson #include <getopt.h>
15474572d2SBruce Richardson
16474572d2SBruce Richardson #include <rte_common.h>
17474572d2SBruce Richardson #include <rte_byteorder.h>
18474572d2SBruce Richardson #include <rte_log.h>
19474572d2SBruce Richardson #include <rte_memory.h>
20474572d2SBruce Richardson #include <rte_memcpy.h>
21474572d2SBruce Richardson #include <rte_eal.h>
22474572d2SBruce Richardson #include <rte_per_lcore.h>
23474572d2SBruce Richardson #include <rte_launch.h>
24474572d2SBruce Richardson #include <rte_cycles.h>
25474572d2SBruce Richardson #include <rte_prefetch.h>
26474572d2SBruce Richardson #include <rte_lcore.h>
27474572d2SBruce Richardson #include <rte_branch_prediction.h>
28474572d2SBruce Richardson #include <rte_interrupts.h>
29474572d2SBruce Richardson #include <rte_pci.h>
30474572d2SBruce Richardson #include <rte_random.h>
31474572d2SBruce Richardson #include <rte_debug.h>
32474572d2SBruce Richardson #include <rte_ether.h>
33474572d2SBruce Richardson #include <rte_ethdev.h>
34474572d2SBruce Richardson #include <rte_ring.h>
35474572d2SBruce Richardson #include <rte_mempool.h>
36474572d2SBruce Richardson #include <rte_mbuf.h>
37474572d2SBruce Richardson #include <rte_string_fns.h>
38474572d2SBruce Richardson #include <rte_ip.h>
39474572d2SBruce Richardson #include <rte_tcp.h>
40474572d2SBruce Richardson #include <rte_lpm.h>
41474572d2SBruce Richardson #include <rte_lpm6.h>
42474572d2SBruce Richardson
43474572d2SBruce Richardson #include "main.h"
44474572d2SBruce Richardson
45474572d2SBruce Richardson struct app_params app = {
46474572d2SBruce Richardson /* Ports*/
47474572d2SBruce Richardson .n_ports = APP_MAX_PORTS,
48474572d2SBruce Richardson .port_rx_ring_size = 128,
49474572d2SBruce Richardson .port_tx_ring_size = 512,
50474572d2SBruce Richardson
51474572d2SBruce Richardson /* Rings */
52474572d2SBruce Richardson .ring_rx_size = 128,
53474572d2SBruce Richardson .ring_tx_size = 128,
54474572d2SBruce Richardson
55474572d2SBruce Richardson /* Buffer pool */
56474572d2SBruce Richardson .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
57474572d2SBruce Richardson .pool_size = 32 * 1024,
58474572d2SBruce Richardson .pool_cache_size = 256,
59474572d2SBruce Richardson
60474572d2SBruce Richardson /* Burst sizes */
61474572d2SBruce Richardson .burst_size_rx_read = 64,
62474572d2SBruce Richardson .burst_size_rx_write = 64,
63474572d2SBruce Richardson .burst_size_worker_read = 64,
64474572d2SBruce Richardson .burst_size_worker_write = 64,
65474572d2SBruce Richardson .burst_size_tx_read = 64,
66474572d2SBruce Richardson .burst_size_tx_write = 64,
67474572d2SBruce Richardson };
68474572d2SBruce Richardson
69474572d2SBruce Richardson static struct rte_eth_conf port_conf = {
70474572d2SBruce Richardson .rxmode = {
71295968d1SFerruh Yigit .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM,
72474572d2SBruce Richardson },
73474572d2SBruce Richardson .rx_adv_conf = {
74474572d2SBruce Richardson .rss_conf = {
75474572d2SBruce Richardson .rss_key = NULL,
76295968d1SFerruh Yigit .rss_hf = RTE_ETH_RSS_IP,
77474572d2SBruce Richardson },
78474572d2SBruce Richardson },
79474572d2SBruce Richardson .txmode = {
80295968d1SFerruh Yigit .mq_mode = RTE_ETH_MQ_TX_NONE,
81474572d2SBruce Richardson },
82474572d2SBruce Richardson };
83474572d2SBruce Richardson
84474572d2SBruce Richardson static struct rte_eth_rxconf rx_conf = {
85474572d2SBruce Richardson .rx_thresh = {
86474572d2SBruce Richardson .pthresh = 8,
87474572d2SBruce Richardson .hthresh = 8,
88474572d2SBruce Richardson .wthresh = 4,
89474572d2SBruce Richardson },
90474572d2SBruce Richardson .rx_free_thresh = 64,
91474572d2SBruce Richardson .rx_drop_en = 0,
92474572d2SBruce Richardson };
93474572d2SBruce Richardson
94474572d2SBruce Richardson static struct rte_eth_txconf tx_conf = {
95474572d2SBruce Richardson .tx_thresh = {
96474572d2SBruce Richardson .pthresh = 36,
97474572d2SBruce Richardson .hthresh = 0,
98474572d2SBruce Richardson .wthresh = 0,
99474572d2SBruce Richardson },
100474572d2SBruce Richardson .tx_free_thresh = 0,
101474572d2SBruce Richardson .tx_rs_thresh = 0,
102474572d2SBruce Richardson };
103474572d2SBruce Richardson
104474572d2SBruce Richardson static void
app_init_mbuf_pools(void)105474572d2SBruce Richardson app_init_mbuf_pools(void)
106474572d2SBruce Richardson {
107474572d2SBruce Richardson /* Init the buffer pool */
108474572d2SBruce Richardson RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
109474572d2SBruce Richardson app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
110474572d2SBruce Richardson app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
111474572d2SBruce Richardson if (app.pool == NULL)
112474572d2SBruce Richardson rte_panic("Cannot create mbuf pool\n");
113474572d2SBruce Richardson }
114474572d2SBruce Richardson
115474572d2SBruce Richardson static void
app_init_rings(void)116474572d2SBruce Richardson app_init_rings(void)
117474572d2SBruce Richardson {
118474572d2SBruce Richardson uint32_t i;
119474572d2SBruce Richardson
120474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
121474572d2SBruce Richardson char name[32];
122474572d2SBruce Richardson
123474572d2SBruce Richardson snprintf(name, sizeof(name), "app_ring_rx_%u", i);
124474572d2SBruce Richardson
125474572d2SBruce Richardson app.rings_rx[i] = rte_ring_create(
126474572d2SBruce Richardson name,
127474572d2SBruce Richardson app.ring_rx_size,
128474572d2SBruce Richardson rte_socket_id(),
129474572d2SBruce Richardson RING_F_SP_ENQ | RING_F_SC_DEQ);
130474572d2SBruce Richardson
131474572d2SBruce Richardson if (app.rings_rx[i] == NULL)
132474572d2SBruce Richardson rte_panic("Cannot create RX ring %u\n", i);
133474572d2SBruce Richardson }
134474572d2SBruce Richardson
135474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
136474572d2SBruce Richardson char name[32];
137474572d2SBruce Richardson
138474572d2SBruce Richardson snprintf(name, sizeof(name), "app_ring_tx_%u", i);
139474572d2SBruce Richardson
140474572d2SBruce Richardson app.rings_tx[i] = rte_ring_create(
141474572d2SBruce Richardson name,
142474572d2SBruce Richardson app.ring_tx_size,
143474572d2SBruce Richardson rte_socket_id(),
144474572d2SBruce Richardson RING_F_SP_ENQ | RING_F_SC_DEQ);
145474572d2SBruce Richardson
146474572d2SBruce Richardson if (app.rings_tx[i] == NULL)
147474572d2SBruce Richardson rte_panic("Cannot create TX ring %u\n", i);
148474572d2SBruce Richardson }
149474572d2SBruce Richardson
150474572d2SBruce Richardson }
151474572d2SBruce Richardson
152474572d2SBruce Richardson static void
app_ports_check_link(void)153474572d2SBruce Richardson app_ports_check_link(void)
154474572d2SBruce Richardson {
155474572d2SBruce Richardson uint32_t all_ports_up, i;
156ba5509a6SIvan Dyukov char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
157474572d2SBruce Richardson all_ports_up = 1;
158474572d2SBruce Richardson
159474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
160474572d2SBruce Richardson struct rte_eth_link link;
161474572d2SBruce Richardson uint16_t port;
1622dc3131fSAndrew Rybchenko int ret;
163474572d2SBruce Richardson
164474572d2SBruce Richardson port = app.ports[i];
165474572d2SBruce Richardson memset(&link, 0, sizeof(link));
1662dc3131fSAndrew Rybchenko ret = rte_eth_link_get_nowait(port, &link);
1672dc3131fSAndrew Rybchenko if (ret < 0) {
1682dc3131fSAndrew Rybchenko RTE_LOG(INFO, USER1,
1692dc3131fSAndrew Rybchenko "Failed to get port %u link status: %s\n",
1702dc3131fSAndrew Rybchenko port, rte_strerror(-ret));
1712dc3131fSAndrew Rybchenko all_ports_up = 0;
1722dc3131fSAndrew Rybchenko continue;
1732dc3131fSAndrew Rybchenko }
174ba5509a6SIvan Dyukov rte_eth_link_to_str(link_status_text, sizeof(link_status_text),
175ba5509a6SIvan Dyukov &link);
176ba5509a6SIvan Dyukov RTE_LOG(INFO, USER1, "Port %u %s\n",
177474572d2SBruce Richardson port,
178ba5509a6SIvan Dyukov link_status_text);
179295968d1SFerruh Yigit if (link.link_status == RTE_ETH_LINK_DOWN)
180474572d2SBruce Richardson all_ports_up = 0;
181474572d2SBruce Richardson }
182474572d2SBruce Richardson
183474572d2SBruce Richardson if (all_ports_up == 0)
184474572d2SBruce Richardson rte_panic("Some NIC ports are DOWN\n");
185474572d2SBruce Richardson }
186474572d2SBruce Richardson
187474572d2SBruce Richardson static void
app_init_ports(void)188474572d2SBruce Richardson app_init_ports(void)
189474572d2SBruce Richardson {
190474572d2SBruce Richardson uint32_t i;
191*66419bf2SFeifei Wang struct rte_eth_dev_info dev_info;
192474572d2SBruce Richardson
193474572d2SBruce Richardson /* Init NIC ports, then start the ports */
194474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
195474572d2SBruce Richardson uint16_t port;
196474572d2SBruce Richardson int ret;
197*66419bf2SFeifei Wang struct rte_eth_conf local_port_conf = port_conf;
198474572d2SBruce Richardson
199474572d2SBruce Richardson port = app.ports[i];
200474572d2SBruce Richardson RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port);
201474572d2SBruce Richardson
202*66419bf2SFeifei Wang ret = rte_eth_dev_info_get(port, &dev_info);
203*66419bf2SFeifei Wang if (ret != 0)
204*66419bf2SFeifei Wang rte_panic("Error during getting device (port %u) info: %s\n",
205*66419bf2SFeifei Wang port, rte_strerror(-ret));
206*66419bf2SFeifei Wang
207474572d2SBruce Richardson /* Init port */
208*66419bf2SFeifei Wang local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
209*66419bf2SFeifei Wang dev_info.flow_type_rss_offloads;
210*66419bf2SFeifei Wang if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
211*66419bf2SFeifei Wang port_conf.rx_adv_conf.rss_conf.rss_hf) {
212*66419bf2SFeifei Wang printf("Warning:"
213*66419bf2SFeifei Wang "Port %u modified RSS hash function based on hardware support,"
214*66419bf2SFeifei Wang "requested:%#"PRIx64" configured:%#"PRIx64"\n",
215*66419bf2SFeifei Wang port,
216*66419bf2SFeifei Wang port_conf.rx_adv_conf.rss_conf.rss_hf,
217*66419bf2SFeifei Wang local_port_conf.rx_adv_conf.rss_conf.rss_hf);
218*66419bf2SFeifei Wang }
219*66419bf2SFeifei Wang
220474572d2SBruce Richardson ret = rte_eth_dev_configure(
221474572d2SBruce Richardson port,
222474572d2SBruce Richardson 1,
223474572d2SBruce Richardson 1,
224*66419bf2SFeifei Wang &local_port_conf);
225474572d2SBruce Richardson if (ret < 0)
226474572d2SBruce Richardson rte_panic("Cannot init NIC port %u (%d)\n", port, ret);
227474572d2SBruce Richardson
22870e51a0eSIvan Ilchenko ret = rte_eth_promiscuous_enable(port);
22970e51a0eSIvan Ilchenko if (ret != 0)
23070e51a0eSIvan Ilchenko rte_panic("Cannot enable promiscuous mode for port %u: %s\n",
23170e51a0eSIvan Ilchenko port, rte_strerror(-ret));
232474572d2SBruce Richardson
233474572d2SBruce Richardson /* Init RX queues */
234474572d2SBruce Richardson ret = rte_eth_rx_queue_setup(
235474572d2SBruce Richardson port,
236474572d2SBruce Richardson 0,
237474572d2SBruce Richardson app.port_rx_ring_size,
238474572d2SBruce Richardson rte_eth_dev_socket_id(port),
239474572d2SBruce Richardson &rx_conf,
240474572d2SBruce Richardson app.pool);
241474572d2SBruce Richardson if (ret < 0)
242474572d2SBruce Richardson rte_panic("Cannot init RX for port %u (%d)\n",
243474572d2SBruce Richardson (uint32_t) port, ret);
244474572d2SBruce Richardson
245474572d2SBruce Richardson /* Init TX queues */
246474572d2SBruce Richardson ret = rte_eth_tx_queue_setup(
247474572d2SBruce Richardson port,
248474572d2SBruce Richardson 0,
249474572d2SBruce Richardson app.port_tx_ring_size,
250474572d2SBruce Richardson rte_eth_dev_socket_id(port),
251474572d2SBruce Richardson &tx_conf);
252474572d2SBruce Richardson if (ret < 0)
253474572d2SBruce Richardson rte_panic("Cannot init TX for port %u (%d)\n",
254474572d2SBruce Richardson (uint32_t) port, ret);
255474572d2SBruce Richardson
256474572d2SBruce Richardson /* Start port */
257474572d2SBruce Richardson ret = rte_eth_dev_start(port);
258474572d2SBruce Richardson if (ret < 0)
259474572d2SBruce Richardson rte_panic("Cannot start port %u (%d)\n", port, ret);
260474572d2SBruce Richardson }
261474572d2SBruce Richardson
262474572d2SBruce Richardson app_ports_check_link();
263474572d2SBruce Richardson }
264474572d2SBruce Richardson
265474572d2SBruce Richardson void
app_init(void)266474572d2SBruce Richardson app_init(void)
267474572d2SBruce Richardson {
268474572d2SBruce Richardson app_init_mbuf_pools();
269474572d2SBruce Richardson app_init_rings();
270474572d2SBruce Richardson app_init_ports();
271474572d2SBruce Richardson
272474572d2SBruce Richardson RTE_LOG(INFO, USER1, "Initialization completed\n");
273474572d2SBruce Richardson }
274