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