xref: /dpdk/app/test-pmd/testpmd.c (revision 3e0ceb9f17fff027fc6c8f18de35e11719ffa61e)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <time.h>
40 #include <fcntl.h>
41 #include <sys/mman.h>
42 #include <sys/types.h>
43 #include <errno.h>
44 
45 #include <sys/queue.h>
46 #include <sys/stat.h>
47 
48 #include <stdint.h>
49 #include <unistd.h>
50 #include <inttypes.h>
51 
52 #include <rte_common.h>
53 #include <rte_errno.h>
54 #include <rte_byteorder.h>
55 #include <rte_log.h>
56 #include <rte_debug.h>
57 #include <rte_cycles.h>
58 #include <rte_memory.h>
59 #include <rte_memcpy.h>
60 #include <rte_launch.h>
61 #include <rte_eal.h>
62 #include <rte_alarm.h>
63 #include <rte_per_lcore.h>
64 #include <rte_lcore.h>
65 #include <rte_atomic.h>
66 #include <rte_branch_prediction.h>
67 #include <rte_mempool.h>
68 #include <rte_malloc.h>
69 #include <rte_mbuf.h>
70 #include <rte_interrupts.h>
71 #include <rte_pci.h>
72 #include <rte_ether.h>
73 #include <rte_ethdev.h>
74 #include <rte_dev.h>
75 #include <rte_string_fns.h>
76 #ifdef RTE_LIBRTE_IXGBE_PMD
77 #include <rte_pmd_ixgbe.h>
78 #endif
79 #ifdef RTE_LIBRTE_PDUMP
80 #include <rte_pdump.h>
81 #endif
82 #include <rte_flow.h>
83 #include <rte_metrics.h>
84 #ifdef RTE_LIBRTE_BITRATE
85 #include <rte_bitrate.h>
86 #endif
87 #ifdef RTE_LIBRTE_LATENCY_STATS
88 #include <rte_latencystats.h>
89 #endif
90 
91 #include "testpmd.h"
92 
93 uint16_t verbose_level = 0; /**< Silent by default. */
94 
95 /* use master core for command line ? */
96 uint8_t interactive = 0;
97 uint8_t auto_start = 0;
98 uint8_t tx_first;
99 char cmdline_filename[PATH_MAX] = {0};
100 
101 /*
102  * NUMA support configuration.
103  * When set, the NUMA support attempts to dispatch the allocation of the
104  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
105  * probed ports among the CPU sockets 0 and 1.
106  * Otherwise, all memory is allocated from CPU socket 0.
107  */
108 uint8_t numa_support = 1; /**< numa enabled by default */
109 
110 /*
111  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
112  * not configured.
113  */
114 uint8_t socket_num = UMA_NO_CONFIG;
115 
116 /*
117  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
118  */
119 uint8_t mp_anon = 0;
120 
121 /*
122  * Record the Ethernet address of peer target ports to which packets are
123  * forwarded.
124  * Must be instantiated with the ethernet addresses of peer traffic generator
125  * ports.
126  */
127 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
128 portid_t nb_peer_eth_addrs = 0;
129 
130 /*
131  * Probed Target Environment.
132  */
133 struct rte_port *ports;	       /**< For all probed ethernet ports. */
134 portid_t nb_ports;             /**< Number of probed ethernet ports. */
135 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
136 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
137 
138 /*
139  * Test Forwarding Configuration.
140  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
141  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
142  */
143 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
144 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
145 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
146 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
147 
148 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
149 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
150 
151 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
152 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
153 
154 /*
155  * Forwarding engines.
156  */
157 struct fwd_engine * fwd_engines[] = {
158 	&io_fwd_engine,
159 	&mac_fwd_engine,
160 	&mac_swap_engine,
161 	&flow_gen_engine,
162 	&rx_only_engine,
163 	&tx_only_engine,
164 	&csum_fwd_engine,
165 	&icmp_echo_engine,
166 #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
167 	&softnic_tm_engine,
168 	&softnic_tm_bypass_engine,
169 #endif
170 #ifdef RTE_LIBRTE_IEEE1588
171 	&ieee1588_fwd_engine,
172 #endif
173 	NULL,
174 };
175 
176 struct fwd_config cur_fwd_config;
177 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
178 uint32_t retry_enabled;
179 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
180 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
181 
182 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
183 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
184                                       * specified on command-line. */
185 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
186 
187 /*
188  * In container, it cannot terminate the process which running with 'stats-period'
189  * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
190  */
191 uint8_t f_quit;
192 
193 /*
194  * Configuration of packet segments used by the "txonly" processing engine.
195  */
196 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
197 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
198 	TXONLY_DEF_PACKET_LEN,
199 };
200 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
201 
202 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
203 /**< Split policy for packets to TX. */
204 
205 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
206 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
207 
208 /* current configuration is in DCB or not,0 means it is not in DCB mode */
209 uint8_t dcb_config = 0;
210 
211 /* Whether the dcb is in testing status */
212 uint8_t dcb_test = 0;
213 
214 /*
215  * Configurable number of RX/TX queues.
216  */
217 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
218 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
219 
220 /*
221  * Configurable number of RX/TX ring descriptors.
222  */
223 #define RTE_TEST_RX_DESC_DEFAULT 128
224 #define RTE_TEST_TX_DESC_DEFAULT 512
225 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
226 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
227 
228 #define RTE_PMD_PARAM_UNSET -1
229 /*
230  * Configurable values of RX and TX ring threshold registers.
231  */
232 
233 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
234 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
235 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
236 
237 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
238 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
239 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
240 
241 /*
242  * Configurable value of RX free threshold.
243  */
244 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
245 
246 /*
247  * Configurable value of RX drop enable.
248  */
249 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
250 
251 /*
252  * Configurable value of TX free threshold.
253  */
254 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
255 
256 /*
257  * Configurable value of TX RS bit threshold.
258  */
259 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
260 
261 /*
262  * Configurable value of TX queue flags.
263  */
264 int32_t txq_flags = RTE_PMD_PARAM_UNSET;
265 
266 /*
267  * Receive Side Scaling (RSS) configuration.
268  */
269 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
270 
271 /*
272  * Port topology configuration
273  */
274 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
275 
276 /*
277  * Avoids to flush all the RX streams before starts forwarding.
278  */
279 uint8_t no_flush_rx = 0; /* flush by default */
280 
281 /*
282  * Flow API isolated mode.
283  */
284 uint8_t flow_isolate_all;
285 
286 /*
287  * Avoids to check link status when starting/stopping a port.
288  */
289 uint8_t no_link_check = 0; /* check by default */
290 
291 /*
292  * Enable link status change notification
293  */
294 uint8_t lsc_interrupt = 1; /* enabled by default */
295 
296 /*
297  * Enable device removal notification.
298  */
299 uint8_t rmv_interrupt = 1; /* enabled by default */
300 
301 /*
302  * Display or mask ether events
303  * Default to all events except VF_MBOX
304  */
305 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
306 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
307 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
308 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
309 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
310 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
311 
312 /*
313  * NIC bypass mode configuration options.
314  */
315 
316 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
317 /* The NIC bypass watchdog timeout. */
318 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
319 #endif
320 
321 
322 #ifdef RTE_LIBRTE_LATENCY_STATS
323 
324 /*
325  * Set when latency stats is enabled in the commandline
326  */
327 uint8_t latencystats_enabled;
328 
329 /*
330  * Lcore ID to serive latency statistics.
331  */
332 lcoreid_t latencystats_lcore_id = -1;
333 
334 #endif
335 
336 /*
337  * Ethernet device configuration.
338  */
339 struct rte_eth_rxmode rx_mode = {
340 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
341 	.split_hdr_size = 0,
342 	.header_split   = 0, /**< Header Split disabled. */
343 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
344 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
345 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
346 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
347 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
348 	.hw_strip_crc   = 1, /**< CRC stripping by hardware enabled. */
349 	.hw_timestamp   = 0, /**< HW timestamp enabled. */
350 };
351 
352 struct rte_fdir_conf fdir_conf = {
353 	.mode = RTE_FDIR_MODE_NONE,
354 	.pballoc = RTE_FDIR_PBALLOC_64K,
355 	.status = RTE_FDIR_REPORT_STATUS,
356 	.mask = {
357 		.vlan_tci_mask = 0x0,
358 		.ipv4_mask     = {
359 			.src_ip = 0xFFFFFFFF,
360 			.dst_ip = 0xFFFFFFFF,
361 		},
362 		.ipv6_mask     = {
363 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
364 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
365 		},
366 		.src_port_mask = 0xFFFF,
367 		.dst_port_mask = 0xFFFF,
368 		.mac_addr_byte_mask = 0xFF,
369 		.tunnel_type_mask = 1,
370 		.tunnel_id_mask = 0xFFFFFFFF,
371 	},
372 	.drop_queue = 127,
373 };
374 
375 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
376 
377 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
378 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
379 
380 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
381 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
382 
383 uint16_t nb_tx_queue_stats_mappings = 0;
384 uint16_t nb_rx_queue_stats_mappings = 0;
385 
386 /*
387  * Display zero values by default for xstats
388  */
389 uint8_t xstats_hide_zero;
390 
391 unsigned int num_sockets = 0;
392 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
393 
394 #ifdef RTE_LIBRTE_BITRATE
395 /* Bitrate statistics */
396 struct rte_stats_bitrates *bitrate_data;
397 lcoreid_t bitrate_lcore_id;
398 uint8_t bitrate_enabled;
399 #endif
400 
401 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
402 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
403 
404 /* Forward function declarations */
405 static void map_port_queue_stats_mapping_registers(portid_t pi,
406 						   struct rte_port *port);
407 static void check_all_ports_link_status(uint32_t port_mask);
408 static int eth_event_callback(portid_t port_id,
409 			      enum rte_eth_event_type type,
410 			      void *param, void *ret_param);
411 
412 /*
413  * Check if all the ports are started.
414  * If yes, return positive value. If not, return zero.
415  */
416 static int all_ports_started(void);
417 
418 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
419 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
420 
421 /*
422  * Helper function to check if socket is already discovered.
423  * If yes, return positive value. If not, return zero.
424  */
425 int
426 new_socket_id(unsigned int socket_id)
427 {
428 	unsigned int i;
429 
430 	for (i = 0; i < num_sockets; i++) {
431 		if (socket_ids[i] == socket_id)
432 			return 0;
433 	}
434 	return 1;
435 }
436 
437 /*
438  * Setup default configuration.
439  */
440 static void
441 set_default_fwd_lcores_config(void)
442 {
443 	unsigned int i;
444 	unsigned int nb_lc;
445 	unsigned int sock_num;
446 
447 	nb_lc = 0;
448 	for (i = 0; i < RTE_MAX_LCORE; i++) {
449 		sock_num = rte_lcore_to_socket_id(i);
450 		if (new_socket_id(sock_num)) {
451 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
452 				rte_exit(EXIT_FAILURE,
453 					 "Total sockets greater than %u\n",
454 					 RTE_MAX_NUMA_NODES);
455 			}
456 			socket_ids[num_sockets++] = sock_num;
457 		}
458 		if (!rte_lcore_is_enabled(i))
459 			continue;
460 		if (i == rte_get_master_lcore())
461 			continue;
462 		fwd_lcores_cpuids[nb_lc++] = i;
463 	}
464 	nb_lcores = (lcoreid_t) nb_lc;
465 	nb_cfg_lcores = nb_lcores;
466 	nb_fwd_lcores = 1;
467 }
468 
469 static void
470 set_def_peer_eth_addrs(void)
471 {
472 	portid_t i;
473 
474 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
475 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
476 		peer_eth_addrs[i].addr_bytes[5] = i;
477 	}
478 }
479 
480 static void
481 set_default_fwd_ports_config(void)
482 {
483 	portid_t pt_id;
484 	int i = 0;
485 
486 	RTE_ETH_FOREACH_DEV(pt_id)
487 		fwd_ports_ids[i++] = pt_id;
488 
489 	nb_cfg_ports = nb_ports;
490 	nb_fwd_ports = nb_ports;
491 }
492 
493 void
494 set_def_fwd_config(void)
495 {
496 	set_default_fwd_lcores_config();
497 	set_def_peer_eth_addrs();
498 	set_default_fwd_ports_config();
499 }
500 
501 /*
502  * Configuration initialisation done once at init time.
503  */
504 static void
505 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
506 		 unsigned int socket_id)
507 {
508 	char pool_name[RTE_MEMPOOL_NAMESIZE];
509 	struct rte_mempool *rte_mp = NULL;
510 	uint32_t mb_size;
511 
512 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
513 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
514 
515 	RTE_LOG(INFO, USER1,
516 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
517 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
518 
519 	if (mp_anon != 0) {
520 		rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
521 			mb_size, (unsigned) mb_mempool_cache,
522 			sizeof(struct rte_pktmbuf_pool_private),
523 			socket_id, 0);
524 		if (rte_mp == NULL)
525 			goto err;
526 
527 		if (rte_mempool_populate_anon(rte_mp) == 0) {
528 			rte_mempool_free(rte_mp);
529 			rte_mp = NULL;
530 			goto err;
531 		}
532 		rte_pktmbuf_pool_init(rte_mp, NULL);
533 		rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
534 	} else {
535 		/* wrapper to rte_mempool_create() */
536 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
537 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
538 	}
539 
540 err:
541 	if (rte_mp == NULL) {
542 		rte_exit(EXIT_FAILURE,
543 			"Creation of mbuf pool for socket %u failed: %s\n",
544 			socket_id, rte_strerror(rte_errno));
545 	} else if (verbose_level > 0) {
546 		rte_mempool_dump(stdout, rte_mp);
547 	}
548 }
549 
550 /*
551  * Check given socket id is valid or not with NUMA mode,
552  * if valid, return 0, else return -1
553  */
554 static int
555 check_socket_id(const unsigned int socket_id)
556 {
557 	static int warning_once = 0;
558 
559 	if (new_socket_id(socket_id)) {
560 		if (!warning_once && numa_support)
561 			printf("Warning: NUMA should be configured manually by"
562 			       " using --port-numa-config and"
563 			       " --ring-numa-config parameters along with"
564 			       " --numa.\n");
565 		warning_once = 1;
566 		return -1;
567 	}
568 	return 0;
569 }
570 
571 static void
572 init_config(void)
573 {
574 	portid_t pid;
575 	struct rte_port *port;
576 	struct rte_mempool *mbp;
577 	unsigned int nb_mbuf_per_pool;
578 	lcoreid_t  lc_id;
579 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
580 	struct rte_gro_param gro_param;
581 	uint32_t gso_types;
582 
583 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
584 
585 	if (numa_support) {
586 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
587 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
588 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
589 	}
590 
591 	/* Configuration of logical cores. */
592 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
593 				sizeof(struct fwd_lcore *) * nb_lcores,
594 				RTE_CACHE_LINE_SIZE);
595 	if (fwd_lcores == NULL) {
596 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
597 							"failed\n", nb_lcores);
598 	}
599 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
600 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
601 					       sizeof(struct fwd_lcore),
602 					       RTE_CACHE_LINE_SIZE);
603 		if (fwd_lcores[lc_id] == NULL) {
604 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
605 								"failed\n");
606 		}
607 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
608 	}
609 
610 	RTE_ETH_FOREACH_DEV(pid) {
611 		port = &ports[pid];
612 		rte_eth_dev_info_get(pid, &port->dev_info);
613 
614 		if (numa_support) {
615 			if (port_numa[pid] != NUMA_NO_CONFIG)
616 				port_per_socket[port_numa[pid]]++;
617 			else {
618 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
619 
620 				/* if socket_id is invalid, set to 0 */
621 				if (check_socket_id(socket_id) < 0)
622 					socket_id = 0;
623 				port_per_socket[socket_id]++;
624 			}
625 		}
626 
627 		/* set flag to initialize port/queue */
628 		port->need_reconfig = 1;
629 		port->need_reconfig_queues = 1;
630 	}
631 
632 	/*
633 	 * Create pools of mbuf.
634 	 * If NUMA support is disabled, create a single pool of mbuf in
635 	 * socket 0 memory by default.
636 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
637 	 *
638 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
639 	 * nb_txd can be configured at run time.
640 	 */
641 	if (param_total_num_mbufs)
642 		nb_mbuf_per_pool = param_total_num_mbufs;
643 	else {
644 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
645 			(nb_lcores * mb_mempool_cache) +
646 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
647 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
648 	}
649 
650 	if (numa_support) {
651 		uint8_t i;
652 
653 		for (i = 0; i < num_sockets; i++)
654 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
655 					 socket_ids[i]);
656 	} else {
657 		if (socket_num == UMA_NO_CONFIG)
658 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
659 		else
660 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
661 						 socket_num);
662 	}
663 
664 	init_port_config();
665 
666 	gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
667 		DEV_TX_OFFLOAD_GRE_TNL_TSO;
668 	/*
669 	 * Records which Mbuf pool to use by each logical core, if needed.
670 	 */
671 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
672 		mbp = mbuf_pool_find(
673 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
674 
675 		if (mbp == NULL)
676 			mbp = mbuf_pool_find(0);
677 		fwd_lcores[lc_id]->mbp = mbp;
678 		/* initialize GSO context */
679 		fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
680 		fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
681 		fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
682 		fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
683 			ETHER_CRC_LEN;
684 		fwd_lcores[lc_id]->gso_ctx.flag = 0;
685 	}
686 
687 	/* Configuration of packet forwarding streams. */
688 	if (init_fwd_streams() < 0)
689 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
690 
691 	fwd_config_setup();
692 
693 	/* create a gro context for each lcore */
694 	gro_param.gro_types = RTE_GRO_TCP_IPV4;
695 	gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
696 	gro_param.max_item_per_flow = MAX_PKT_BURST;
697 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
698 		gro_param.socket_id = rte_lcore_to_socket_id(
699 				fwd_lcores_cpuids[lc_id]);
700 		fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
701 		if (fwd_lcores[lc_id]->gro_ctx == NULL) {
702 			rte_exit(EXIT_FAILURE,
703 					"rte_gro_ctx_create() failed\n");
704 		}
705 	}
706 }
707 
708 
709 void
710 reconfig(portid_t new_port_id, unsigned socket_id)
711 {
712 	struct rte_port *port;
713 
714 	/* Reconfiguration of Ethernet ports. */
715 	port = &ports[new_port_id];
716 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
717 
718 	/* set flag to initialize port/queue */
719 	port->need_reconfig = 1;
720 	port->need_reconfig_queues = 1;
721 	port->socket_id = socket_id;
722 
723 	init_port_config();
724 }
725 
726 
727 int
728 init_fwd_streams(void)
729 {
730 	portid_t pid;
731 	struct rte_port *port;
732 	streamid_t sm_id, nb_fwd_streams_new;
733 	queueid_t q;
734 
735 	/* set socket id according to numa or not */
736 	RTE_ETH_FOREACH_DEV(pid) {
737 		port = &ports[pid];
738 		if (nb_rxq > port->dev_info.max_rx_queues) {
739 			printf("Fail: nb_rxq(%d) is greater than "
740 				"max_rx_queues(%d)\n", nb_rxq,
741 				port->dev_info.max_rx_queues);
742 			return -1;
743 		}
744 		if (nb_txq > port->dev_info.max_tx_queues) {
745 			printf("Fail: nb_txq(%d) is greater than "
746 				"max_tx_queues(%d)\n", nb_txq,
747 				port->dev_info.max_tx_queues);
748 			return -1;
749 		}
750 		if (numa_support) {
751 			if (port_numa[pid] != NUMA_NO_CONFIG)
752 				port->socket_id = port_numa[pid];
753 			else {
754 				port->socket_id = rte_eth_dev_socket_id(pid);
755 
756 				/* if socket_id is invalid, set to 0 */
757 				if (check_socket_id(port->socket_id) < 0)
758 					port->socket_id = 0;
759 			}
760 		}
761 		else {
762 			if (socket_num == UMA_NO_CONFIG)
763 				port->socket_id = 0;
764 			else
765 				port->socket_id = socket_num;
766 		}
767 	}
768 
769 	q = RTE_MAX(nb_rxq, nb_txq);
770 	if (q == 0) {
771 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
772 		return -1;
773 	}
774 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
775 	if (nb_fwd_streams_new == nb_fwd_streams)
776 		return 0;
777 	/* clear the old */
778 	if (fwd_streams != NULL) {
779 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
780 			if (fwd_streams[sm_id] == NULL)
781 				continue;
782 			rte_free(fwd_streams[sm_id]);
783 			fwd_streams[sm_id] = NULL;
784 		}
785 		rte_free(fwd_streams);
786 		fwd_streams = NULL;
787 	}
788 
789 	/* init new */
790 	nb_fwd_streams = nb_fwd_streams_new;
791 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
792 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
793 	if (fwd_streams == NULL)
794 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
795 						"failed\n", nb_fwd_streams);
796 
797 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
798 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
799 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
800 		if (fwd_streams[sm_id] == NULL)
801 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
802 								" failed\n");
803 	}
804 
805 	return 0;
806 }
807 
808 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
809 static void
810 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
811 {
812 	unsigned int total_burst;
813 	unsigned int nb_burst;
814 	unsigned int burst_stats[3];
815 	uint16_t pktnb_stats[3];
816 	uint16_t nb_pkt;
817 	int burst_percent[3];
818 
819 	/*
820 	 * First compute the total number of packet bursts and the
821 	 * two highest numbers of bursts of the same number of packets.
822 	 */
823 	total_burst = 0;
824 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
825 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
826 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
827 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
828 		if (nb_burst == 0)
829 			continue;
830 		total_burst += nb_burst;
831 		if (nb_burst > burst_stats[0]) {
832 			burst_stats[1] = burst_stats[0];
833 			pktnb_stats[1] = pktnb_stats[0];
834 			burst_stats[0] = nb_burst;
835 			pktnb_stats[0] = nb_pkt;
836 		}
837 	}
838 	if (total_burst == 0)
839 		return;
840 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
841 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
842 	       burst_percent[0], (int) pktnb_stats[0]);
843 	if (burst_stats[0] == total_burst) {
844 		printf("]\n");
845 		return;
846 	}
847 	if (burst_stats[0] + burst_stats[1] == total_burst) {
848 		printf(" + %d%% of %d pkts]\n",
849 		       100 - burst_percent[0], pktnb_stats[1]);
850 		return;
851 	}
852 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
853 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
854 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
855 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
856 		return;
857 	}
858 	printf(" + %d%% of %d pkts + %d%% of others]\n",
859 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
860 }
861 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
862 
863 static void
864 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
865 {
866 	struct rte_port *port;
867 	uint8_t i;
868 
869 	static const char *fwd_stats_border = "----------------------";
870 
871 	port = &ports[port_id];
872 	printf("\n  %s Forward statistics for port %-2d %s\n",
873 	       fwd_stats_border, port_id, fwd_stats_border);
874 
875 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
876 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
877 		       "%-"PRIu64"\n",
878 		       stats->ipackets, stats->imissed,
879 		       (uint64_t) (stats->ipackets + stats->imissed));
880 
881 		if (cur_fwd_eng == &csum_fwd_engine)
882 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
883 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
884 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
885 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
886 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
887 		}
888 
889 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
890 		       "%-"PRIu64"\n",
891 		       stats->opackets, port->tx_dropped,
892 		       (uint64_t) (stats->opackets + port->tx_dropped));
893 	}
894 	else {
895 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
896 		       "%14"PRIu64"\n",
897 		       stats->ipackets, stats->imissed,
898 		       (uint64_t) (stats->ipackets + stats->imissed));
899 
900 		if (cur_fwd_eng == &csum_fwd_engine)
901 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
902 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
903 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
904 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
905 			printf("  RX-nombufs:             %14"PRIu64"\n",
906 			       stats->rx_nombuf);
907 		}
908 
909 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
910 		       "%14"PRIu64"\n",
911 		       stats->opackets, port->tx_dropped,
912 		       (uint64_t) (stats->opackets + port->tx_dropped));
913 	}
914 
915 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
916 	if (port->rx_stream)
917 		pkt_burst_stats_display("RX",
918 			&port->rx_stream->rx_burst_stats);
919 	if (port->tx_stream)
920 		pkt_burst_stats_display("TX",
921 			&port->tx_stream->tx_burst_stats);
922 #endif
923 
924 	if (port->rx_queue_stats_mapping_enabled) {
925 		printf("\n");
926 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
927 			printf("  Stats reg %2d RX-packets:%14"PRIu64
928 			       "     RX-errors:%14"PRIu64
929 			       "    RX-bytes:%14"PRIu64"\n",
930 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
931 		}
932 		printf("\n");
933 	}
934 	if (port->tx_queue_stats_mapping_enabled) {
935 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
936 			printf("  Stats reg %2d TX-packets:%14"PRIu64
937 			       "                                 TX-bytes:%14"PRIu64"\n",
938 			       i, stats->q_opackets[i], stats->q_obytes[i]);
939 		}
940 	}
941 
942 	printf("  %s--------------------------------%s\n",
943 	       fwd_stats_border, fwd_stats_border);
944 }
945 
946 static void
947 fwd_stream_stats_display(streamid_t stream_id)
948 {
949 	struct fwd_stream *fs;
950 	static const char *fwd_top_stats_border = "-------";
951 
952 	fs = fwd_streams[stream_id];
953 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
954 	    (fs->fwd_dropped == 0))
955 		return;
956 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
957 	       "TX Port=%2d/Queue=%2d %s\n",
958 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
959 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
960 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
961 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
962 
963 	/* if checksum mode */
964 	if (cur_fwd_eng == &csum_fwd_engine) {
965 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
966 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
967 	}
968 
969 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
970 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
971 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
972 #endif
973 }
974 
975 static void
976 flush_fwd_rx_queues(void)
977 {
978 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
979 	portid_t  rxp;
980 	portid_t port_id;
981 	queueid_t rxq;
982 	uint16_t  nb_rx;
983 	uint16_t  i;
984 	uint8_t   j;
985 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
986 	uint64_t timer_period;
987 
988 	/* convert to number of cycles */
989 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
990 
991 	for (j = 0; j < 2; j++) {
992 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
993 			for (rxq = 0; rxq < nb_rxq; rxq++) {
994 				port_id = fwd_ports_ids[rxp];
995 				/**
996 				* testpmd can stuck in the below do while loop
997 				* if rte_eth_rx_burst() always returns nonzero
998 				* packets. So timer is added to exit this loop
999 				* after 1sec timer expiry.
1000 				*/
1001 				prev_tsc = rte_rdtsc();
1002 				do {
1003 					nb_rx = rte_eth_rx_burst(port_id, rxq,
1004 						pkts_burst, MAX_PKT_BURST);
1005 					for (i = 0; i < nb_rx; i++)
1006 						rte_pktmbuf_free(pkts_burst[i]);
1007 
1008 					cur_tsc = rte_rdtsc();
1009 					diff_tsc = cur_tsc - prev_tsc;
1010 					timer_tsc += diff_tsc;
1011 				} while ((nb_rx > 0) &&
1012 					(timer_tsc < timer_period));
1013 				timer_tsc = 0;
1014 			}
1015 		}
1016 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1017 	}
1018 }
1019 
1020 static void
1021 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1022 {
1023 	struct fwd_stream **fsm;
1024 	streamid_t nb_fs;
1025 	streamid_t sm_id;
1026 #ifdef RTE_LIBRTE_BITRATE
1027 	uint64_t tics_per_1sec;
1028 	uint64_t tics_datum;
1029 	uint64_t tics_current;
1030 	uint8_t idx_port, cnt_ports;
1031 
1032 	cnt_ports = rte_eth_dev_count();
1033 	tics_datum = rte_rdtsc();
1034 	tics_per_1sec = rte_get_timer_hz();
1035 #endif
1036 	fsm = &fwd_streams[fc->stream_idx];
1037 	nb_fs = fc->stream_nb;
1038 	do {
1039 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1040 			(*pkt_fwd)(fsm[sm_id]);
1041 #ifdef RTE_LIBRTE_BITRATE
1042 		if (bitrate_enabled != 0 &&
1043 				bitrate_lcore_id == rte_lcore_id()) {
1044 			tics_current = rte_rdtsc();
1045 			if (tics_current - tics_datum >= tics_per_1sec) {
1046 				/* Periodic bitrate calculation */
1047 				for (idx_port = 0;
1048 						idx_port < cnt_ports;
1049 						idx_port++)
1050 					rte_stats_bitrate_calc(bitrate_data,
1051 						idx_port);
1052 				tics_datum = tics_current;
1053 			}
1054 		}
1055 #endif
1056 #ifdef RTE_LIBRTE_LATENCY_STATS
1057 		if (latencystats_enabled != 0 &&
1058 				latencystats_lcore_id == rte_lcore_id())
1059 			rte_latencystats_update();
1060 #endif
1061 
1062 	} while (! fc->stopped);
1063 }
1064 
1065 static int
1066 start_pkt_forward_on_core(void *fwd_arg)
1067 {
1068 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1069 			     cur_fwd_config.fwd_eng->packet_fwd);
1070 	return 0;
1071 }
1072 
1073 /*
1074  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1075  * Used to start communication flows in network loopback test configurations.
1076  */
1077 static int
1078 run_one_txonly_burst_on_core(void *fwd_arg)
1079 {
1080 	struct fwd_lcore *fwd_lc;
1081 	struct fwd_lcore tmp_lcore;
1082 
1083 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1084 	tmp_lcore = *fwd_lc;
1085 	tmp_lcore.stopped = 1;
1086 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1087 	return 0;
1088 }
1089 
1090 /*
1091  * Launch packet forwarding:
1092  *     - Setup per-port forwarding context.
1093  *     - launch logical cores with their forwarding configuration.
1094  */
1095 static void
1096 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1097 {
1098 	port_fwd_begin_t port_fwd_begin;
1099 	unsigned int i;
1100 	unsigned int lc_id;
1101 	int diag;
1102 
1103 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1104 	if (port_fwd_begin != NULL) {
1105 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1106 			(*port_fwd_begin)(fwd_ports_ids[i]);
1107 	}
1108 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1109 		lc_id = fwd_lcores_cpuids[i];
1110 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1111 			fwd_lcores[i]->stopped = 0;
1112 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1113 						     fwd_lcores[i], lc_id);
1114 			if (diag != 0)
1115 				printf("launch lcore %u failed - diag=%d\n",
1116 				       lc_id, diag);
1117 		}
1118 	}
1119 }
1120 
1121 /*
1122  * Launch packet forwarding configuration.
1123  */
1124 void
1125 start_packet_forwarding(int with_tx_first)
1126 {
1127 	port_fwd_begin_t port_fwd_begin;
1128 	port_fwd_end_t  port_fwd_end;
1129 	struct rte_port *port;
1130 	unsigned int i;
1131 	portid_t   pt_id;
1132 	streamid_t sm_id;
1133 
1134 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1135 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1136 
1137 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1138 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1139 
1140 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1141 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1142 		(!nb_rxq || !nb_txq))
1143 		rte_exit(EXIT_FAILURE,
1144 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
1145 			cur_fwd_eng->fwd_mode_name);
1146 
1147 	if (all_ports_started() == 0) {
1148 		printf("Not all ports were started\n");
1149 		return;
1150 	}
1151 	if (test_done == 0) {
1152 		printf("Packet forwarding already started\n");
1153 		return;
1154 	}
1155 
1156 	if (init_fwd_streams() < 0) {
1157 		printf("Fail from init_fwd_streams()\n");
1158 		return;
1159 	}
1160 
1161 	if(dcb_test) {
1162 		for (i = 0; i < nb_fwd_ports; i++) {
1163 			pt_id = fwd_ports_ids[i];
1164 			port = &ports[pt_id];
1165 			if (!port->dcb_flag) {
1166 				printf("In DCB mode, all forwarding ports must "
1167                                        "be configured in this mode.\n");
1168 				return;
1169 			}
1170 		}
1171 		if (nb_fwd_lcores == 1) {
1172 			printf("In DCB mode,the nb forwarding cores "
1173                                "should be larger than 1.\n");
1174 			return;
1175 		}
1176 	}
1177 	test_done = 0;
1178 
1179 	if(!no_flush_rx)
1180 		flush_fwd_rx_queues();
1181 
1182 	fwd_config_setup();
1183 	pkt_fwd_config_display(&cur_fwd_config);
1184 	rxtx_config_display();
1185 
1186 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1187 		pt_id = fwd_ports_ids[i];
1188 		port = &ports[pt_id];
1189 		rte_eth_stats_get(pt_id, &port->stats);
1190 		port->tx_dropped = 0;
1191 
1192 		map_port_queue_stats_mapping_registers(pt_id, port);
1193 	}
1194 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1195 		fwd_streams[sm_id]->rx_packets = 0;
1196 		fwd_streams[sm_id]->tx_packets = 0;
1197 		fwd_streams[sm_id]->fwd_dropped = 0;
1198 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1199 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1200 
1201 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1202 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1203 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1204 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1205 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1206 #endif
1207 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1208 		fwd_streams[sm_id]->core_cycles = 0;
1209 #endif
1210 	}
1211 	if (with_tx_first) {
1212 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1213 		if (port_fwd_begin != NULL) {
1214 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1215 				(*port_fwd_begin)(fwd_ports_ids[i]);
1216 		}
1217 		while (with_tx_first--) {
1218 			launch_packet_forwarding(
1219 					run_one_txonly_burst_on_core);
1220 			rte_eal_mp_wait_lcore();
1221 		}
1222 		port_fwd_end = tx_only_engine.port_fwd_end;
1223 		if (port_fwd_end != NULL) {
1224 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1225 				(*port_fwd_end)(fwd_ports_ids[i]);
1226 		}
1227 	}
1228 	launch_packet_forwarding(start_pkt_forward_on_core);
1229 }
1230 
1231 void
1232 stop_packet_forwarding(void)
1233 {
1234 	struct rte_eth_stats stats;
1235 	struct rte_port *port;
1236 	port_fwd_end_t  port_fwd_end;
1237 	int i;
1238 	portid_t   pt_id;
1239 	streamid_t sm_id;
1240 	lcoreid_t  lc_id;
1241 	uint64_t total_recv;
1242 	uint64_t total_xmit;
1243 	uint64_t total_rx_dropped;
1244 	uint64_t total_tx_dropped;
1245 	uint64_t total_rx_nombuf;
1246 	uint64_t tx_dropped;
1247 	uint64_t rx_bad_ip_csum;
1248 	uint64_t rx_bad_l4_csum;
1249 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1250 	uint64_t fwd_cycles;
1251 #endif
1252 
1253 	static const char *acc_stats_border = "+++++++++++++++";
1254 
1255 	if (test_done) {
1256 		printf("Packet forwarding not started\n");
1257 		return;
1258 	}
1259 	printf("Telling cores to stop...");
1260 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1261 		fwd_lcores[lc_id]->stopped = 1;
1262 	printf("\nWaiting for lcores to finish...\n");
1263 	rte_eal_mp_wait_lcore();
1264 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1265 	if (port_fwd_end != NULL) {
1266 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1267 			pt_id = fwd_ports_ids[i];
1268 			(*port_fwd_end)(pt_id);
1269 		}
1270 	}
1271 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1272 	fwd_cycles = 0;
1273 #endif
1274 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1275 		if (cur_fwd_config.nb_fwd_streams >
1276 		    cur_fwd_config.nb_fwd_ports) {
1277 			fwd_stream_stats_display(sm_id);
1278 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1279 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1280 		} else {
1281 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1282 				fwd_streams[sm_id];
1283 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1284 				fwd_streams[sm_id];
1285 		}
1286 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1287 		tx_dropped = (uint64_t) (tx_dropped +
1288 					 fwd_streams[sm_id]->fwd_dropped);
1289 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1290 
1291 		rx_bad_ip_csum =
1292 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1293 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1294 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1295 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1296 							rx_bad_ip_csum;
1297 
1298 		rx_bad_l4_csum =
1299 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1300 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1301 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1302 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1303 							rx_bad_l4_csum;
1304 
1305 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1306 		fwd_cycles = (uint64_t) (fwd_cycles +
1307 					 fwd_streams[sm_id]->core_cycles);
1308 #endif
1309 	}
1310 	total_recv = 0;
1311 	total_xmit = 0;
1312 	total_rx_dropped = 0;
1313 	total_tx_dropped = 0;
1314 	total_rx_nombuf  = 0;
1315 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1316 		pt_id = fwd_ports_ids[i];
1317 
1318 		port = &ports[pt_id];
1319 		rte_eth_stats_get(pt_id, &stats);
1320 		stats.ipackets -= port->stats.ipackets;
1321 		port->stats.ipackets = 0;
1322 		stats.opackets -= port->stats.opackets;
1323 		port->stats.opackets = 0;
1324 		stats.ibytes   -= port->stats.ibytes;
1325 		port->stats.ibytes = 0;
1326 		stats.obytes   -= port->stats.obytes;
1327 		port->stats.obytes = 0;
1328 		stats.imissed  -= port->stats.imissed;
1329 		port->stats.imissed = 0;
1330 		stats.oerrors  -= port->stats.oerrors;
1331 		port->stats.oerrors = 0;
1332 		stats.rx_nombuf -= port->stats.rx_nombuf;
1333 		port->stats.rx_nombuf = 0;
1334 
1335 		total_recv += stats.ipackets;
1336 		total_xmit += stats.opackets;
1337 		total_rx_dropped += stats.imissed;
1338 		total_tx_dropped += port->tx_dropped;
1339 		total_rx_nombuf  += stats.rx_nombuf;
1340 
1341 		fwd_port_stats_display(pt_id, &stats);
1342 	}
1343 
1344 	printf("\n  %s Accumulated forward statistics for all ports"
1345 	       "%s\n",
1346 	       acc_stats_border, acc_stats_border);
1347 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1348 	       "%-"PRIu64"\n"
1349 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1350 	       "%-"PRIu64"\n",
1351 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1352 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1353 	if (total_rx_nombuf > 0)
1354 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1355 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1356 	       "%s\n",
1357 	       acc_stats_border, acc_stats_border);
1358 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1359 	if (total_recv > 0)
1360 		printf("\n  CPU cycles/packet=%u (total cycles="
1361 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1362 		       (unsigned int)(fwd_cycles / total_recv),
1363 		       fwd_cycles, total_recv);
1364 #endif
1365 	printf("\nDone.\n");
1366 	test_done = 1;
1367 }
1368 
1369 void
1370 dev_set_link_up(portid_t pid)
1371 {
1372 	if (rte_eth_dev_set_link_up(pid) < 0)
1373 		printf("\nSet link up fail.\n");
1374 }
1375 
1376 void
1377 dev_set_link_down(portid_t pid)
1378 {
1379 	if (rte_eth_dev_set_link_down(pid) < 0)
1380 		printf("\nSet link down fail.\n");
1381 }
1382 
1383 static int
1384 all_ports_started(void)
1385 {
1386 	portid_t pi;
1387 	struct rte_port *port;
1388 
1389 	RTE_ETH_FOREACH_DEV(pi) {
1390 		port = &ports[pi];
1391 		/* Check if there is a port which is not started */
1392 		if ((port->port_status != RTE_PORT_STARTED) &&
1393 			(port->slave_flag == 0))
1394 			return 0;
1395 	}
1396 
1397 	/* No port is not started */
1398 	return 1;
1399 }
1400 
1401 int
1402 all_ports_stopped(void)
1403 {
1404 	portid_t pi;
1405 	struct rte_port *port;
1406 
1407 	RTE_ETH_FOREACH_DEV(pi) {
1408 		port = &ports[pi];
1409 		if ((port->port_status != RTE_PORT_STOPPED) &&
1410 			(port->slave_flag == 0))
1411 			return 0;
1412 	}
1413 
1414 	return 1;
1415 }
1416 
1417 int
1418 port_is_started(portid_t port_id)
1419 {
1420 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1421 		return 0;
1422 
1423 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1424 		return 0;
1425 
1426 	return 1;
1427 }
1428 
1429 static int
1430 port_is_closed(portid_t port_id)
1431 {
1432 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1433 		return 0;
1434 
1435 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1436 		return 0;
1437 
1438 	return 1;
1439 }
1440 
1441 int
1442 start_port(portid_t pid)
1443 {
1444 	int diag, need_check_link_status = -1;
1445 	portid_t pi;
1446 	queueid_t qi;
1447 	struct rte_port *port;
1448 	struct ether_addr mac_addr;
1449 	enum rte_eth_event_type event_type;
1450 
1451 	if (port_id_is_invalid(pid, ENABLED_WARN))
1452 		return 0;
1453 
1454 	if(dcb_config)
1455 		dcb_test = 1;
1456 	RTE_ETH_FOREACH_DEV(pi) {
1457 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1458 			continue;
1459 
1460 		need_check_link_status = 0;
1461 		port = &ports[pi];
1462 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1463 						 RTE_PORT_HANDLING) == 0) {
1464 			printf("Port %d is now not stopped\n", pi);
1465 			continue;
1466 		}
1467 
1468 		if (port->need_reconfig > 0) {
1469 			port->need_reconfig = 0;
1470 
1471 			if (flow_isolate_all) {
1472 				int ret = port_flow_isolate(pi, 1);
1473 				if (ret) {
1474 					printf("Failed to apply isolated"
1475 					       " mode on port %d\n", pi);
1476 					return -1;
1477 				}
1478 			}
1479 
1480 			printf("Configuring Port %d (socket %u)\n", pi,
1481 					port->socket_id);
1482 			/* configure port */
1483 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1484 						&(port->dev_conf));
1485 			if (diag != 0) {
1486 				if (rte_atomic16_cmpset(&(port->port_status),
1487 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1488 					printf("Port %d can not be set back "
1489 							"to stopped\n", pi);
1490 				printf("Fail to configure port %d\n", pi);
1491 				/* try to reconfigure port next time */
1492 				port->need_reconfig = 1;
1493 				return -1;
1494 			}
1495 		}
1496 		if (port->need_reconfig_queues > 0) {
1497 			port->need_reconfig_queues = 0;
1498 			/* setup tx queues */
1499 			for (qi = 0; qi < nb_txq; qi++) {
1500 				if ((numa_support) &&
1501 					(txring_numa[pi] != NUMA_NO_CONFIG))
1502 					diag = rte_eth_tx_queue_setup(pi, qi,
1503 						nb_txd,txring_numa[pi],
1504 						&(port->tx_conf));
1505 				else
1506 					diag = rte_eth_tx_queue_setup(pi, qi,
1507 						nb_txd,port->socket_id,
1508 						&(port->tx_conf));
1509 
1510 				if (diag == 0)
1511 					continue;
1512 
1513 				/* Fail to setup tx queue, return */
1514 				if (rte_atomic16_cmpset(&(port->port_status),
1515 							RTE_PORT_HANDLING,
1516 							RTE_PORT_STOPPED) == 0)
1517 					printf("Port %d can not be set back "
1518 							"to stopped\n", pi);
1519 				printf("Fail to configure port %d tx queues\n", pi);
1520 				/* try to reconfigure queues next time */
1521 				port->need_reconfig_queues = 1;
1522 				return -1;
1523 			}
1524 			/* setup rx queues */
1525 			for (qi = 0; qi < nb_rxq; qi++) {
1526 				if ((numa_support) &&
1527 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1528 					struct rte_mempool * mp =
1529 						mbuf_pool_find(rxring_numa[pi]);
1530 					if (mp == NULL) {
1531 						printf("Failed to setup RX queue:"
1532 							"No mempool allocation"
1533 							" on the socket %d\n",
1534 							rxring_numa[pi]);
1535 						return -1;
1536 					}
1537 
1538 					diag = rte_eth_rx_queue_setup(pi, qi,
1539 					     nb_rxd,rxring_numa[pi],
1540 					     &(port->rx_conf),mp);
1541 				} else {
1542 					struct rte_mempool *mp =
1543 						mbuf_pool_find(port->socket_id);
1544 					if (mp == NULL) {
1545 						printf("Failed to setup RX queue:"
1546 							"No mempool allocation"
1547 							" on the socket %d\n",
1548 							port->socket_id);
1549 						return -1;
1550 					}
1551 					diag = rte_eth_rx_queue_setup(pi, qi,
1552 					     nb_rxd,port->socket_id,
1553 					     &(port->rx_conf), mp);
1554 				}
1555 				if (diag == 0)
1556 					continue;
1557 
1558 				/* Fail to setup rx queue, return */
1559 				if (rte_atomic16_cmpset(&(port->port_status),
1560 							RTE_PORT_HANDLING,
1561 							RTE_PORT_STOPPED) == 0)
1562 					printf("Port %d can not be set back "
1563 							"to stopped\n", pi);
1564 				printf("Fail to configure port %d rx queues\n", pi);
1565 				/* try to reconfigure queues next time */
1566 				port->need_reconfig_queues = 1;
1567 				return -1;
1568 			}
1569 		}
1570 
1571 		for (event_type = RTE_ETH_EVENT_UNKNOWN;
1572 		     event_type < RTE_ETH_EVENT_MAX;
1573 		     event_type++) {
1574 			diag = rte_eth_dev_callback_register(pi,
1575 							event_type,
1576 							eth_event_callback,
1577 							NULL);
1578 			if (diag) {
1579 				printf("Failed to setup even callback for event %d\n",
1580 					event_type);
1581 				return -1;
1582 			}
1583 		}
1584 
1585 		/* start port */
1586 		if (rte_eth_dev_start(pi) < 0) {
1587 			printf("Fail to start port %d\n", pi);
1588 
1589 			/* Fail to setup rx queue, return */
1590 			if (rte_atomic16_cmpset(&(port->port_status),
1591 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1592 				printf("Port %d can not be set back to "
1593 							"stopped\n", pi);
1594 			continue;
1595 		}
1596 
1597 		if (rte_atomic16_cmpset(&(port->port_status),
1598 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1599 			printf("Port %d can not be set into started\n", pi);
1600 
1601 		rte_eth_macaddr_get(pi, &mac_addr);
1602 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1603 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1604 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1605 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1606 
1607 		/* at least one port started, need checking link status */
1608 		need_check_link_status = 1;
1609 	}
1610 
1611 	if (need_check_link_status == 1 && !no_link_check)
1612 		check_all_ports_link_status(RTE_PORT_ALL);
1613 	else if (need_check_link_status == 0)
1614 		printf("Please stop the ports first\n");
1615 
1616 	printf("Done\n");
1617 	return 0;
1618 }
1619 
1620 void
1621 stop_port(portid_t pid)
1622 {
1623 	portid_t pi;
1624 	struct rte_port *port;
1625 	int need_check_link_status = 0;
1626 
1627 	if (dcb_test) {
1628 		dcb_test = 0;
1629 		dcb_config = 0;
1630 	}
1631 
1632 	if (port_id_is_invalid(pid, ENABLED_WARN))
1633 		return;
1634 
1635 	printf("Stopping ports...\n");
1636 
1637 	RTE_ETH_FOREACH_DEV(pi) {
1638 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1639 			continue;
1640 
1641 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1642 			printf("Please remove port %d from forwarding configuration.\n", pi);
1643 			continue;
1644 		}
1645 
1646 		if (port_is_bonding_slave(pi)) {
1647 			printf("Please remove port %d from bonded device.\n", pi);
1648 			continue;
1649 		}
1650 
1651 		port = &ports[pi];
1652 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1653 						RTE_PORT_HANDLING) == 0)
1654 			continue;
1655 
1656 		rte_eth_dev_stop(pi);
1657 
1658 		if (rte_atomic16_cmpset(&(port->port_status),
1659 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1660 			printf("Port %d can not be set into stopped\n", pi);
1661 		need_check_link_status = 1;
1662 	}
1663 	if (need_check_link_status && !no_link_check)
1664 		check_all_ports_link_status(RTE_PORT_ALL);
1665 
1666 	printf("Done\n");
1667 }
1668 
1669 void
1670 close_port(portid_t pid)
1671 {
1672 	portid_t pi;
1673 	struct rte_port *port;
1674 
1675 	if (port_id_is_invalid(pid, ENABLED_WARN))
1676 		return;
1677 
1678 	printf("Closing ports...\n");
1679 
1680 	RTE_ETH_FOREACH_DEV(pi) {
1681 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1682 			continue;
1683 
1684 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1685 			printf("Please remove port %d from forwarding configuration.\n", pi);
1686 			continue;
1687 		}
1688 
1689 		if (port_is_bonding_slave(pi)) {
1690 			printf("Please remove port %d from bonded device.\n", pi);
1691 			continue;
1692 		}
1693 
1694 		port = &ports[pi];
1695 		if (rte_atomic16_cmpset(&(port->port_status),
1696 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1697 			printf("Port %d is already closed\n", pi);
1698 			continue;
1699 		}
1700 
1701 		if (rte_atomic16_cmpset(&(port->port_status),
1702 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1703 			printf("Port %d is now not stopped\n", pi);
1704 			continue;
1705 		}
1706 
1707 		if (port->flow_list)
1708 			port_flow_flush(pi);
1709 		rte_eth_dev_close(pi);
1710 
1711 		if (rte_atomic16_cmpset(&(port->port_status),
1712 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1713 			printf("Port %d cannot be set to closed\n", pi);
1714 	}
1715 
1716 	printf("Done\n");
1717 }
1718 
1719 void
1720 reset_port(portid_t pid)
1721 {
1722 	int diag;
1723 	portid_t pi;
1724 	struct rte_port *port;
1725 
1726 	if (port_id_is_invalid(pid, ENABLED_WARN))
1727 		return;
1728 
1729 	printf("Resetting ports...\n");
1730 
1731 	RTE_ETH_FOREACH_DEV(pi) {
1732 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1733 			continue;
1734 
1735 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1736 			printf("Please remove port %d from forwarding "
1737 			       "configuration.\n", pi);
1738 			continue;
1739 		}
1740 
1741 		if (port_is_bonding_slave(pi)) {
1742 			printf("Please remove port %d from bonded device.\n",
1743 			       pi);
1744 			continue;
1745 		}
1746 
1747 		diag = rte_eth_dev_reset(pi);
1748 		if (diag == 0) {
1749 			port = &ports[pi];
1750 			port->need_reconfig = 1;
1751 			port->need_reconfig_queues = 1;
1752 		} else {
1753 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
1754 		}
1755 	}
1756 
1757 	printf("Done\n");
1758 }
1759 
1760 void
1761 attach_port(char *identifier)
1762 {
1763 	portid_t pi = 0;
1764 	unsigned int socket_id;
1765 
1766 	printf("Attaching a new port...\n");
1767 
1768 	if (identifier == NULL) {
1769 		printf("Invalid parameters are specified\n");
1770 		return;
1771 	}
1772 
1773 	if (rte_eth_dev_attach(identifier, &pi))
1774 		return;
1775 
1776 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1777 	/* if socket_id is invalid, set to 0 */
1778 	if (check_socket_id(socket_id) < 0)
1779 		socket_id = 0;
1780 	reconfig(pi, socket_id);
1781 	rte_eth_promiscuous_enable(pi);
1782 
1783 	nb_ports = rte_eth_dev_count();
1784 
1785 	ports[pi].port_status = RTE_PORT_STOPPED;
1786 
1787 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1788 	printf("Done\n");
1789 }
1790 
1791 void
1792 detach_port(portid_t port_id)
1793 {
1794 	char name[RTE_ETH_NAME_MAX_LEN];
1795 
1796 	printf("Detaching a port...\n");
1797 
1798 	if (!port_is_closed(port_id)) {
1799 		printf("Please close port first\n");
1800 		return;
1801 	}
1802 
1803 	if (ports[port_id].flow_list)
1804 		port_flow_flush(port_id);
1805 
1806 	if (rte_eth_dev_detach(port_id, name)) {
1807 		RTE_LOG(ERR, USER1, "Failed to detach port '%s'\n", name);
1808 		return;
1809 	}
1810 
1811 	nb_ports = rte_eth_dev_count();
1812 
1813 	printf("Port '%s' is detached. Now total ports is %d\n",
1814 			name, nb_ports);
1815 	printf("Done\n");
1816 	return;
1817 }
1818 
1819 void
1820 pmd_test_exit(void)
1821 {
1822 	portid_t pt_id;
1823 
1824 	if (test_done == 0)
1825 		stop_packet_forwarding();
1826 
1827 	if (ports != NULL) {
1828 		no_link_check = 1;
1829 		RTE_ETH_FOREACH_DEV(pt_id) {
1830 			printf("\nShutting down port %d...\n", pt_id);
1831 			fflush(stdout);
1832 			stop_port(pt_id);
1833 			close_port(pt_id);
1834 		}
1835 	}
1836 	printf("\nBye...\n");
1837 }
1838 
1839 typedef void (*cmd_func_t)(void);
1840 struct pmd_test_command {
1841 	const char *cmd_name;
1842 	cmd_func_t cmd_func;
1843 };
1844 
1845 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1846 
1847 /* Check the link status of all ports in up to 9s, and print them finally */
1848 static void
1849 check_all_ports_link_status(uint32_t port_mask)
1850 {
1851 #define CHECK_INTERVAL 100 /* 100ms */
1852 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1853 	portid_t portid;
1854 	uint8_t count, all_ports_up, print_flag = 0;
1855 	struct rte_eth_link link;
1856 
1857 	printf("Checking link statuses...\n");
1858 	fflush(stdout);
1859 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1860 		all_ports_up = 1;
1861 		RTE_ETH_FOREACH_DEV(portid) {
1862 			if ((port_mask & (1 << portid)) == 0)
1863 				continue;
1864 			memset(&link, 0, sizeof(link));
1865 			rte_eth_link_get_nowait(portid, &link);
1866 			/* print link status if flag set */
1867 			if (print_flag == 1) {
1868 				if (link.link_status)
1869 					printf(
1870 					"Port%d Link Up. speed %u Mbps- %s\n",
1871 					portid, link.link_speed,
1872 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1873 					("full-duplex") : ("half-duplex\n"));
1874 				else
1875 					printf("Port %d Link Down\n", portid);
1876 				continue;
1877 			}
1878 			/* clear all_ports_up flag if any link down */
1879 			if (link.link_status == ETH_LINK_DOWN) {
1880 				all_ports_up = 0;
1881 				break;
1882 			}
1883 		}
1884 		/* after finally printing all link status, get out */
1885 		if (print_flag == 1)
1886 			break;
1887 
1888 		if (all_ports_up == 0) {
1889 			fflush(stdout);
1890 			rte_delay_ms(CHECK_INTERVAL);
1891 		}
1892 
1893 		/* set the print_flag if all ports up or timeout */
1894 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1895 			print_flag = 1;
1896 		}
1897 
1898 		if (lsc_interrupt)
1899 			break;
1900 	}
1901 }
1902 
1903 static void
1904 rmv_event_callback(void *arg)
1905 {
1906 	struct rte_eth_dev *dev;
1907 	portid_t port_id = (intptr_t)arg;
1908 
1909 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
1910 	dev = &rte_eth_devices[port_id];
1911 
1912 	stop_port(port_id);
1913 	close_port(port_id);
1914 	printf("removing device %s\n", dev->device->name);
1915 	if (rte_eal_dev_detach(dev->device))
1916 		RTE_LOG(ERR, USER1, "Failed to detach device %s\n",
1917 			dev->device->name);
1918 }
1919 
1920 /* This function is used by the interrupt thread */
1921 static int
1922 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
1923 		  void *ret_param)
1924 {
1925 	static const char * const event_desc[] = {
1926 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
1927 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
1928 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
1929 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
1930 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
1931 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
1932 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
1933 		[RTE_ETH_EVENT_MAX] = NULL,
1934 	};
1935 
1936 	RTE_SET_USED(param);
1937 	RTE_SET_USED(ret_param);
1938 
1939 	if (type >= RTE_ETH_EVENT_MAX) {
1940 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
1941 			port_id, __func__, type);
1942 		fflush(stderr);
1943 	} else if (event_print_mask & (UINT32_C(1) << type)) {
1944 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
1945 			event_desc[type]);
1946 		fflush(stdout);
1947 	}
1948 
1949 	switch (type) {
1950 	case RTE_ETH_EVENT_INTR_RMV:
1951 		if (rte_eal_alarm_set(100000,
1952 				rmv_event_callback, (void *)(intptr_t)port_id))
1953 			fprintf(stderr, "Could not set up deferred device removal\n");
1954 		break;
1955 	default:
1956 		break;
1957 	}
1958 	return 0;
1959 }
1960 
1961 static int
1962 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
1963 {
1964 	uint16_t i;
1965 	int diag;
1966 	uint8_t mapping_found = 0;
1967 
1968 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1969 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1970 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1971 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1972 					tx_queue_stats_mappings[i].queue_id,
1973 					tx_queue_stats_mappings[i].stats_counter_id);
1974 			if (diag != 0)
1975 				return diag;
1976 			mapping_found = 1;
1977 		}
1978 	}
1979 	if (mapping_found)
1980 		port->tx_queue_stats_mapping_enabled = 1;
1981 	return 0;
1982 }
1983 
1984 static int
1985 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
1986 {
1987 	uint16_t i;
1988 	int diag;
1989 	uint8_t mapping_found = 0;
1990 
1991 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1992 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1993 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1994 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1995 					rx_queue_stats_mappings[i].queue_id,
1996 					rx_queue_stats_mappings[i].stats_counter_id);
1997 			if (diag != 0)
1998 				return diag;
1999 			mapping_found = 1;
2000 		}
2001 	}
2002 	if (mapping_found)
2003 		port->rx_queue_stats_mapping_enabled = 1;
2004 	return 0;
2005 }
2006 
2007 static void
2008 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2009 {
2010 	int diag = 0;
2011 
2012 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2013 	if (diag != 0) {
2014 		if (diag == -ENOTSUP) {
2015 			port->tx_queue_stats_mapping_enabled = 0;
2016 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2017 		}
2018 		else
2019 			rte_exit(EXIT_FAILURE,
2020 					"set_tx_queue_stats_mapping_registers "
2021 					"failed for port id=%d diag=%d\n",
2022 					pi, diag);
2023 	}
2024 
2025 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2026 	if (diag != 0) {
2027 		if (diag == -ENOTSUP) {
2028 			port->rx_queue_stats_mapping_enabled = 0;
2029 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2030 		}
2031 		else
2032 			rte_exit(EXIT_FAILURE,
2033 					"set_rx_queue_stats_mapping_registers "
2034 					"failed for port id=%d diag=%d\n",
2035 					pi, diag);
2036 	}
2037 }
2038 
2039 static void
2040 rxtx_port_config(struct rte_port *port)
2041 {
2042 	port->rx_conf = port->dev_info.default_rxconf;
2043 	port->tx_conf = port->dev_info.default_txconf;
2044 
2045 	/* Check if any RX/TX parameters have been passed */
2046 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2047 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
2048 
2049 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2050 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
2051 
2052 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2053 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
2054 
2055 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2056 		port->rx_conf.rx_free_thresh = rx_free_thresh;
2057 
2058 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2059 		port->rx_conf.rx_drop_en = rx_drop_en;
2060 
2061 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2062 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
2063 
2064 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2065 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
2066 
2067 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2068 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
2069 
2070 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2071 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
2072 
2073 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2074 		port->tx_conf.tx_free_thresh = tx_free_thresh;
2075 
2076 	if (txq_flags != RTE_PMD_PARAM_UNSET)
2077 		port->tx_conf.txq_flags = txq_flags;
2078 }
2079 
2080 void
2081 init_port_config(void)
2082 {
2083 	portid_t pid;
2084 	struct rte_port *port;
2085 
2086 	RTE_ETH_FOREACH_DEV(pid) {
2087 		port = &ports[pid];
2088 		port->dev_conf.rxmode = rx_mode;
2089 		port->dev_conf.fdir_conf = fdir_conf;
2090 		if (nb_rxq > 1) {
2091 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2092 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2093 		} else {
2094 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2095 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2096 		}
2097 
2098 		if (port->dcb_flag == 0) {
2099 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2100 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2101 			else
2102 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2103 		}
2104 
2105 		rxtx_port_config(port);
2106 
2107 		rte_eth_macaddr_get(pid, &port->eth_addr);
2108 
2109 		map_port_queue_stats_mapping_registers(pid, port);
2110 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2111 		rte_pmd_ixgbe_bypass_init(pid);
2112 #endif
2113 
2114 		if (lsc_interrupt &&
2115 		    (rte_eth_devices[pid].data->dev_flags &
2116 		     RTE_ETH_DEV_INTR_LSC))
2117 			port->dev_conf.intr_conf.lsc = 1;
2118 		if (rmv_interrupt &&
2119 		    (rte_eth_devices[pid].data->dev_flags &
2120 		     RTE_ETH_DEV_INTR_RMV))
2121 			port->dev_conf.intr_conf.rmv = 1;
2122 
2123 #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
2124 		/* Detect softnic port */
2125 		if (!strcmp(port->dev_info.driver_name, "net_softnic")) {
2126 			port->softnic_enable = 1;
2127 			memset(&port->softport, 0, sizeof(struct softnic_port));
2128 
2129 			if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm"))
2130 				port->softport.tm_flag = 1;
2131 		}
2132 #endif
2133 	}
2134 }
2135 
2136 void set_port_slave_flag(portid_t slave_pid)
2137 {
2138 	struct rte_port *port;
2139 
2140 	port = &ports[slave_pid];
2141 	port->slave_flag = 1;
2142 }
2143 
2144 void clear_port_slave_flag(portid_t slave_pid)
2145 {
2146 	struct rte_port *port;
2147 
2148 	port = &ports[slave_pid];
2149 	port->slave_flag = 0;
2150 }
2151 
2152 uint8_t port_is_bonding_slave(portid_t slave_pid)
2153 {
2154 	struct rte_port *port;
2155 
2156 	port = &ports[slave_pid];
2157 	return port->slave_flag;
2158 }
2159 
2160 const uint16_t vlan_tags[] = {
2161 		0,  1,  2,  3,  4,  5,  6,  7,
2162 		8,  9, 10, 11,  12, 13, 14, 15,
2163 		16, 17, 18, 19, 20, 21, 22, 23,
2164 		24, 25, 26, 27, 28, 29, 30, 31
2165 };
2166 
2167 static  int
2168 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
2169 		 enum dcb_mode_enable dcb_mode,
2170 		 enum rte_eth_nb_tcs num_tcs,
2171 		 uint8_t pfc_en)
2172 {
2173 	uint8_t i;
2174 
2175 	/*
2176 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2177 	 * given above, and the number of traffic classes available for use.
2178 	 */
2179 	if (dcb_mode == DCB_VT_ENABLED) {
2180 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2181 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
2182 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2183 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2184 
2185 		/* VMDQ+DCB RX and TX configurations */
2186 		vmdq_rx_conf->enable_default_pool = 0;
2187 		vmdq_rx_conf->default_pool = 0;
2188 		vmdq_rx_conf->nb_queue_pools =
2189 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2190 		vmdq_tx_conf->nb_queue_pools =
2191 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2192 
2193 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2194 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2195 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2196 			vmdq_rx_conf->pool_map[i].pools =
2197 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2198 		}
2199 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2200 			vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2201 			vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2202 		}
2203 
2204 		/* set DCB mode of RX and TX of multiple queues */
2205 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2206 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2207 	} else {
2208 		struct rte_eth_dcb_rx_conf *rx_conf =
2209 				&eth_conf->rx_adv_conf.dcb_rx_conf;
2210 		struct rte_eth_dcb_tx_conf *tx_conf =
2211 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2212 
2213 		rx_conf->nb_tcs = num_tcs;
2214 		tx_conf->nb_tcs = num_tcs;
2215 
2216 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2217 			rx_conf->dcb_tc[i] = i % num_tcs;
2218 			tx_conf->dcb_tc[i] = i % num_tcs;
2219 		}
2220 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2221 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
2222 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2223 	}
2224 
2225 	if (pfc_en)
2226 		eth_conf->dcb_capability_en =
2227 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2228 	else
2229 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2230 
2231 	return 0;
2232 }
2233 
2234 int
2235 init_port_dcb_config(portid_t pid,
2236 		     enum dcb_mode_enable dcb_mode,
2237 		     enum rte_eth_nb_tcs num_tcs,
2238 		     uint8_t pfc_en)
2239 {
2240 	struct rte_eth_conf port_conf;
2241 	struct rte_port *rte_port;
2242 	int retval;
2243 	uint16_t i;
2244 
2245 	rte_port = &ports[pid];
2246 
2247 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2248 	/* Enter DCB configuration status */
2249 	dcb_config = 1;
2250 
2251 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
2252 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2253 	if (retval < 0)
2254 		return retval;
2255 	port_conf.rxmode.hw_vlan_filter = 1;
2256 
2257 	/**
2258 	 * Write the configuration into the device.
2259 	 * Set the numbers of RX & TX queues to 0, so
2260 	 * the RX & TX queues will not be setup.
2261 	 */
2262 	rte_eth_dev_configure(pid, 0, 0, &port_conf);
2263 
2264 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
2265 
2266 	/* If dev_info.vmdq_pool_base is greater than 0,
2267 	 * the queue id of vmdq pools is started after pf queues.
2268 	 */
2269 	if (dcb_mode == DCB_VT_ENABLED &&
2270 	    rte_port->dev_info.vmdq_pool_base > 0) {
2271 		printf("VMDQ_DCB multi-queue mode is nonsensical"
2272 			" for port %d.", pid);
2273 		return -1;
2274 	}
2275 
2276 	/* Assume the ports in testpmd have the same dcb capability
2277 	 * and has the same number of rxq and txq in dcb mode
2278 	 */
2279 	if (dcb_mode == DCB_VT_ENABLED) {
2280 		if (rte_port->dev_info.max_vfs > 0) {
2281 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2282 			nb_txq = rte_port->dev_info.nb_tx_queues;
2283 		} else {
2284 			nb_rxq = rte_port->dev_info.max_rx_queues;
2285 			nb_txq = rte_port->dev_info.max_tx_queues;
2286 		}
2287 	} else {
2288 		/*if vt is disabled, use all pf queues */
2289 		if (rte_port->dev_info.vmdq_pool_base == 0) {
2290 			nb_rxq = rte_port->dev_info.max_rx_queues;
2291 			nb_txq = rte_port->dev_info.max_tx_queues;
2292 		} else {
2293 			nb_rxq = (queueid_t)num_tcs;
2294 			nb_txq = (queueid_t)num_tcs;
2295 
2296 		}
2297 	}
2298 	rx_free_thresh = 64;
2299 
2300 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2301 
2302 	rxtx_port_config(rte_port);
2303 	/* VLAN filter */
2304 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
2305 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2306 		rx_vft_set(pid, vlan_tags[i], 1);
2307 
2308 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2309 	map_port_queue_stats_mapping_registers(pid, rte_port);
2310 
2311 	rte_port->dcb_flag = 1;
2312 
2313 	return 0;
2314 }
2315 
2316 static void
2317 init_port(void)
2318 {
2319 	/* Configuration of Ethernet ports. */
2320 	ports = rte_zmalloc("testpmd: ports",
2321 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2322 			    RTE_CACHE_LINE_SIZE);
2323 	if (ports == NULL) {
2324 		rte_exit(EXIT_FAILURE,
2325 				"rte_zmalloc(%d struct rte_port) failed\n",
2326 				RTE_MAX_ETHPORTS);
2327 	}
2328 }
2329 
2330 static void
2331 force_quit(void)
2332 {
2333 	pmd_test_exit();
2334 	prompt_exit();
2335 }
2336 
2337 static void
2338 print_stats(void)
2339 {
2340 	uint8_t i;
2341 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2342 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2343 
2344 	/* Clear screen and move to top left */
2345 	printf("%s%s", clr, top_left);
2346 
2347 	printf("\nPort statistics ====================================");
2348 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2349 		nic_stats_display(fwd_ports_ids[i]);
2350 }
2351 
2352 static void
2353 signal_handler(int signum)
2354 {
2355 	if (signum == SIGINT || signum == SIGTERM) {
2356 		printf("\nSignal %d received, preparing to exit...\n",
2357 				signum);
2358 #ifdef RTE_LIBRTE_PDUMP
2359 		/* uninitialize packet capture framework */
2360 		rte_pdump_uninit();
2361 #endif
2362 #ifdef RTE_LIBRTE_LATENCY_STATS
2363 		rte_latencystats_uninit();
2364 #endif
2365 		force_quit();
2366 		/* Set flag to indicate the force termination. */
2367 		f_quit = 1;
2368 		/* exit with the expected status */
2369 		signal(signum, SIG_DFL);
2370 		kill(getpid(), signum);
2371 	}
2372 }
2373 
2374 int
2375 main(int argc, char** argv)
2376 {
2377 	int  diag;
2378 	portid_t port_id;
2379 
2380 	signal(SIGINT, signal_handler);
2381 	signal(SIGTERM, signal_handler);
2382 
2383 	diag = rte_eal_init(argc, argv);
2384 	if (diag < 0)
2385 		rte_panic("Cannot init EAL\n");
2386 
2387 	if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
2388 		RTE_LOG(NOTICE, USER1, "mlockall() failed with error \"%s\"\n",
2389 			strerror(errno));
2390 	}
2391 
2392 #ifdef RTE_LIBRTE_PDUMP
2393 	/* initialize packet capture framework */
2394 	rte_pdump_init(NULL);
2395 #endif
2396 
2397 	nb_ports = (portid_t) rte_eth_dev_count();
2398 	if (nb_ports == 0)
2399 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2400 
2401 	/* allocate port structures, and init them */
2402 	init_port();
2403 
2404 	set_def_fwd_config();
2405 	if (nb_lcores == 0)
2406 		rte_panic("Empty set of forwarding logical cores - check the "
2407 			  "core mask supplied in the command parameters\n");
2408 
2409 	/* Bitrate/latency stats disabled by default */
2410 #ifdef RTE_LIBRTE_BITRATE
2411 	bitrate_enabled = 0;
2412 #endif
2413 #ifdef RTE_LIBRTE_LATENCY_STATS
2414 	latencystats_enabled = 0;
2415 #endif
2416 
2417 	argc -= diag;
2418 	argv += diag;
2419 	if (argc > 1)
2420 		launch_args_parse(argc, argv);
2421 
2422 	if (tx_first && interactive)
2423 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
2424 				"interactive mode.\n");
2425 
2426 	if (tx_first && lsc_interrupt) {
2427 		printf("Warning: lsc_interrupt needs to be off when "
2428 				" using tx_first. Disabling.\n");
2429 		lsc_interrupt = 0;
2430 	}
2431 
2432 	if (!nb_rxq && !nb_txq)
2433 		printf("Warning: Either rx or tx queues should be non-zero\n");
2434 
2435 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2436 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2437 		       "but nb_txq=%d will prevent to fully test it.\n",
2438 		       nb_rxq, nb_txq);
2439 
2440 	init_config();
2441 	if (start_port(RTE_PORT_ALL) != 0)
2442 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2443 
2444 	/* set all ports to promiscuous mode by default */
2445 	RTE_ETH_FOREACH_DEV(port_id)
2446 		rte_eth_promiscuous_enable(port_id);
2447 
2448 	/* Init metrics library */
2449 	rte_metrics_init(rte_socket_id());
2450 
2451 #ifdef RTE_LIBRTE_LATENCY_STATS
2452 	if (latencystats_enabled != 0) {
2453 		int ret = rte_latencystats_init(1, NULL);
2454 		if (ret)
2455 			printf("Warning: latencystats init()"
2456 				" returned error %d\n",	ret);
2457 		printf("Latencystats running on lcore %d\n",
2458 			latencystats_lcore_id);
2459 	}
2460 #endif
2461 
2462 	/* Setup bitrate stats */
2463 #ifdef RTE_LIBRTE_BITRATE
2464 	if (bitrate_enabled != 0) {
2465 		bitrate_data = rte_stats_bitrate_create();
2466 		if (bitrate_data == NULL)
2467 			rte_exit(EXIT_FAILURE,
2468 				"Could not allocate bitrate data.\n");
2469 		rte_stats_bitrate_reg(bitrate_data);
2470 	}
2471 #endif
2472 
2473 #ifdef RTE_LIBRTE_CMDLINE
2474 	if (strlen(cmdline_filename) != 0)
2475 		cmdline_read_from_file(cmdline_filename);
2476 
2477 	if (interactive == 1) {
2478 		if (auto_start) {
2479 			printf("Start automatic packet forwarding\n");
2480 			start_packet_forwarding(0);
2481 		}
2482 		prompt();
2483 		pmd_test_exit();
2484 	} else
2485 #endif
2486 	{
2487 		char c;
2488 		int rc;
2489 
2490 		f_quit = 0;
2491 
2492 		printf("No commandline core given, start packet forwarding\n");
2493 		start_packet_forwarding(tx_first);
2494 		if (stats_period != 0) {
2495 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2496 			uint64_t timer_period;
2497 
2498 			/* Convert to number of cycles */
2499 			timer_period = stats_period * rte_get_timer_hz();
2500 
2501 			while (f_quit == 0) {
2502 				cur_time = rte_get_timer_cycles();
2503 				diff_time += cur_time - prev_time;
2504 
2505 				if (diff_time >= timer_period) {
2506 					print_stats();
2507 					/* Reset the timer */
2508 					diff_time = 0;
2509 				}
2510 				/* Sleep to avoid unnecessary checks */
2511 				prev_time = cur_time;
2512 				sleep(1);
2513 			}
2514 		}
2515 
2516 		printf("Press enter to exit\n");
2517 		rc = read(0, &c, 1);
2518 		pmd_test_exit();
2519 		if (rc < 0)
2520 			return 1;
2521 	}
2522 
2523 	return 0;
2524 }
2525