1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <stdint.h> 8 #include <inttypes.h> 9 #include <sys/types.h> 10 #include <string.h> 11 #include <sys/queue.h> 12 #include <stdarg.h> 13 #include <errno.h> 14 #include <getopt.h> 15 16 #include <rte_common.h> 17 #include <rte_byteorder.h> 18 #include <rte_log.h> 19 #include <rte_memory.h> 20 #include <rte_memcpy.h> 21 #include <rte_eal.h> 22 #include <rte_per_lcore.h> 23 #include <rte_launch.h> 24 #include <rte_cycles.h> 25 #include <rte_prefetch.h> 26 #include <rte_lcore.h> 27 #include <rte_branch_prediction.h> 28 #include <rte_interrupts.h> 29 #include <rte_pci.h> 30 #include <rte_random.h> 31 #include <rte_debug.h> 32 #include <rte_ether.h> 33 #include <rte_ethdev.h> 34 #include <rte_ring.h> 35 #include <rte_mempool.h> 36 #include <rte_mbuf.h> 37 #include <rte_string_fns.h> 38 #include <rte_ip.h> 39 #include <rte_tcp.h> 40 #include <rte_lpm.h> 41 #include <rte_lpm6.h> 42 43 #include "main.h" 44 45 struct app_params app = { 46 /* Ports*/ 47 .n_ports = APP_MAX_PORTS, 48 .port_rx_ring_size = 128, 49 .port_tx_ring_size = 512, 50 51 /* Rings */ 52 .ring_rx_size = 128, 53 .ring_tx_size = 128, 54 55 /* Buffer pool */ 56 .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM, 57 .pool_size = 32 * 1024, 58 .pool_cache_size = 256, 59 60 /* Burst sizes */ 61 .burst_size_rx_read = 64, 62 .burst_size_rx_write = 64, 63 .burst_size_worker_read = 64, 64 .burst_size_worker_write = 64, 65 .burst_size_tx_read = 64, 66 .burst_size_tx_write = 64, 67 }; 68 69 static struct rte_eth_conf port_conf = { 70 .rxmode = { 71 .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM, 72 }, 73 .rx_adv_conf = { 74 .rss_conf = { 75 .rss_key = NULL, 76 .rss_hf = RTE_ETH_RSS_IP, 77 }, 78 }, 79 .txmode = { 80 .mq_mode = RTE_ETH_MQ_TX_NONE, 81 }, 82 }; 83 84 static struct rte_eth_rxconf rx_conf = { 85 .rx_thresh = { 86 .pthresh = 8, 87 .hthresh = 8, 88 .wthresh = 4, 89 }, 90 .rx_free_thresh = 64, 91 .rx_drop_en = 0, 92 }; 93 94 static struct rte_eth_txconf tx_conf = { 95 .tx_thresh = { 96 .pthresh = 36, 97 .hthresh = 0, 98 .wthresh = 0, 99 }, 100 .tx_free_thresh = 0, 101 .tx_rs_thresh = 0, 102 }; 103 104 static void 105 app_init_mbuf_pools(void) 106 { 107 /* Init the buffer pool */ 108 RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n"); 109 app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size, 110 app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id()); 111 if (app.pool == NULL) 112 rte_panic("Cannot create mbuf pool\n"); 113 } 114 115 static void 116 app_init_rings(void) 117 { 118 uint32_t i; 119 120 for (i = 0; i < app.n_ports; i++) { 121 char name[32]; 122 123 snprintf(name, sizeof(name), "app_ring_rx_%u", i); 124 125 app.rings_rx[i] = rte_ring_create( 126 name, 127 app.ring_rx_size, 128 rte_socket_id(), 129 RING_F_SP_ENQ | RING_F_SC_DEQ); 130 131 if (app.rings_rx[i] == NULL) 132 rte_panic("Cannot create RX ring %u\n", i); 133 } 134 135 for (i = 0; i < app.n_ports; i++) { 136 char name[32]; 137 138 snprintf(name, sizeof(name), "app_ring_tx_%u", i); 139 140 app.rings_tx[i] = rte_ring_create( 141 name, 142 app.ring_tx_size, 143 rte_socket_id(), 144 RING_F_SP_ENQ | RING_F_SC_DEQ); 145 146 if (app.rings_tx[i] == NULL) 147 rte_panic("Cannot create TX ring %u\n", i); 148 } 149 150 } 151 152 static void 153 app_ports_check_link(void) 154 { 155 uint32_t all_ports_up, i; 156 char link_status_text[RTE_ETH_LINK_MAX_STR_LEN]; 157 all_ports_up = 1; 158 159 for (i = 0; i < app.n_ports; i++) { 160 struct rte_eth_link link; 161 uint16_t port; 162 int ret; 163 164 port = app.ports[i]; 165 memset(&link, 0, sizeof(link)); 166 ret = rte_eth_link_get_nowait(port, &link); 167 if (ret < 0) { 168 RTE_LOG(INFO, USER1, 169 "Failed to get port %u link status: %s\n", 170 port, rte_strerror(-ret)); 171 all_ports_up = 0; 172 continue; 173 } 174 rte_eth_link_to_str(link_status_text, sizeof(link_status_text), 175 &link); 176 RTE_LOG(INFO, USER1, "Port %u %s\n", 177 port, 178 link_status_text); 179 if (link.link_status == RTE_ETH_LINK_DOWN) 180 all_ports_up = 0; 181 } 182 183 if (all_ports_up == 0) 184 rte_panic("Some NIC ports are DOWN\n"); 185 } 186 187 static void 188 app_init_ports(void) 189 { 190 uint32_t i; 191 struct rte_eth_dev_info dev_info; 192 193 /* Init NIC ports, then start the ports */ 194 for (i = 0; i < app.n_ports; i++) { 195 uint16_t port; 196 int ret; 197 struct rte_eth_conf local_port_conf = port_conf; 198 199 port = app.ports[i]; 200 RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port); 201 202 ret = rte_eth_dev_info_get(port, &dev_info); 203 if (ret != 0) 204 rte_panic("Error during getting device (port %u) info: %s\n", 205 port, rte_strerror(-ret)); 206 207 /* Init port */ 208 local_port_conf.rx_adv_conf.rss_conf.rss_hf &= 209 dev_info.flow_type_rss_offloads; 210 if (local_port_conf.rx_adv_conf.rss_conf.rss_hf != 211 port_conf.rx_adv_conf.rss_conf.rss_hf) { 212 printf("Warning:" 213 "Port %u modified RSS hash function based on hardware support," 214 "requested:%#"PRIx64" configured:%#"PRIx64"\n", 215 port, 216 port_conf.rx_adv_conf.rss_conf.rss_hf, 217 local_port_conf.rx_adv_conf.rss_conf.rss_hf); 218 } 219 220 ret = rte_eth_dev_configure( 221 port, 222 1, 223 1, 224 &local_port_conf); 225 if (ret < 0) 226 rte_panic("Cannot init NIC port %u (%d)\n", port, ret); 227 228 ret = rte_eth_promiscuous_enable(port); 229 if (ret != 0) 230 rte_panic("Cannot enable promiscuous mode for port %u: %s\n", 231 port, rte_strerror(-ret)); 232 233 /* Init RX queues */ 234 ret = rte_eth_rx_queue_setup( 235 port, 236 0, 237 app.port_rx_ring_size, 238 rte_eth_dev_socket_id(port), 239 &rx_conf, 240 app.pool); 241 if (ret < 0) 242 rte_panic("Cannot init RX for port %u (%d)\n", 243 (uint32_t) port, ret); 244 245 /* Init TX queues */ 246 ret = rte_eth_tx_queue_setup( 247 port, 248 0, 249 app.port_tx_ring_size, 250 rte_eth_dev_socket_id(port), 251 &tx_conf); 252 if (ret < 0) 253 rte_panic("Cannot init TX for port %u (%d)\n", 254 (uint32_t) port, ret); 255 256 /* Start port */ 257 ret = rte_eth_dev_start(port); 258 if (ret < 0) 259 rte_panic("Cannot start port %u (%d)\n", port, ret); 260 } 261 262 app_ports_check_link(); 263 } 264 265 void 266 app_init(void) 267 { 268 app_init_mbuf_pools(); 269 app_init_rings(); 270 app_init_ports(); 271 272 RTE_LOG(INFO, USER1, "Initialization completed\n"); 273 } 274