xref: /f-stack/dpdk/app/test-pmd/testpmd.c (revision 2bfe3f2e)
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 /*
572  * Get the allowed maximum number of RX queues.
573  * *pid return the port id which has minimal value of
574  * max_rx_queues in all ports.
575  */
576 queueid_t
577 get_allowed_max_nb_rxq(portid_t *pid)
578 {
579 	queueid_t allowed_max_rxq = MAX_QUEUE_ID;
580 	portid_t pi;
581 	struct rte_eth_dev_info dev_info;
582 
583 	RTE_ETH_FOREACH_DEV(pi) {
584 		rte_eth_dev_info_get(pi, &dev_info);
585 		if (dev_info.max_rx_queues < allowed_max_rxq) {
586 			allowed_max_rxq = dev_info.max_rx_queues;
587 			*pid = pi;
588 		}
589 	}
590 	return allowed_max_rxq;
591 }
592 
593 /*
594  * Check input rxq is valid or not.
595  * If input rxq is not greater than any of maximum number
596  * of RX queues of all ports, it is valid.
597  * if valid, return 0, else return -1
598  */
599 int
600 check_nb_rxq(queueid_t rxq)
601 {
602 	queueid_t allowed_max_rxq;
603 	portid_t pid = 0;
604 
605 	allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
606 	if (rxq > allowed_max_rxq) {
607 		printf("Fail: input rxq (%u) can't be greater "
608 		       "than max_rx_queues (%u) of port %u\n",
609 		       rxq,
610 		       allowed_max_rxq,
611 		       pid);
612 		return -1;
613 	}
614 	return 0;
615 }
616 
617 /*
618  * Get the allowed maximum number of TX queues.
619  * *pid return the port id which has minimal value of
620  * max_tx_queues in all ports.
621  */
622 queueid_t
623 get_allowed_max_nb_txq(portid_t *pid)
624 {
625 	queueid_t allowed_max_txq = MAX_QUEUE_ID;
626 	portid_t pi;
627 	struct rte_eth_dev_info dev_info;
628 
629 	RTE_ETH_FOREACH_DEV(pi) {
630 		rte_eth_dev_info_get(pi, &dev_info);
631 		if (dev_info.max_tx_queues < allowed_max_txq) {
632 			allowed_max_txq = dev_info.max_tx_queues;
633 			*pid = pi;
634 		}
635 	}
636 	return allowed_max_txq;
637 }
638 
639 /*
640  * Check input txq is valid or not.
641  * If input txq is not greater than any of maximum number
642  * of TX queues of all ports, it is valid.
643  * if valid, return 0, else return -1
644  */
645 int
646 check_nb_txq(queueid_t txq)
647 {
648 	queueid_t allowed_max_txq;
649 	portid_t pid = 0;
650 
651 	allowed_max_txq = get_allowed_max_nb_txq(&pid);
652 	if (txq > allowed_max_txq) {
653 		printf("Fail: input txq (%u) can't be greater "
654 		       "than max_tx_queues (%u) of port %u\n",
655 		       txq,
656 		       allowed_max_txq,
657 		       pid);
658 		return -1;
659 	}
660 	return 0;
661 }
662 
663 static void
664 init_config(void)
665 {
666 	portid_t pid;
667 	struct rte_port *port;
668 	struct rte_mempool *mbp;
669 	unsigned int nb_mbuf_per_pool;
670 	lcoreid_t  lc_id;
671 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
672 	struct rte_gro_param gro_param;
673 	uint32_t gso_types;
674 
675 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
676 
677 	if (numa_support) {
678 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
679 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
680 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
681 	}
682 
683 	/* Configuration of logical cores. */
684 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
685 				sizeof(struct fwd_lcore *) * nb_lcores,
686 				RTE_CACHE_LINE_SIZE);
687 	if (fwd_lcores == NULL) {
688 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
689 							"failed\n", nb_lcores);
690 	}
691 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
692 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
693 					       sizeof(struct fwd_lcore),
694 					       RTE_CACHE_LINE_SIZE);
695 		if (fwd_lcores[lc_id] == NULL) {
696 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
697 								"failed\n");
698 		}
699 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
700 	}
701 
702 	RTE_ETH_FOREACH_DEV(pid) {
703 		port = &ports[pid];
704 		rte_eth_dev_info_get(pid, &port->dev_info);
705 
706 		if (numa_support) {
707 			if (port_numa[pid] != NUMA_NO_CONFIG)
708 				port_per_socket[port_numa[pid]]++;
709 			else {
710 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
711 
712 				/* if socket_id is invalid, set to 0 */
713 				if (check_socket_id(socket_id) < 0)
714 					socket_id = 0;
715 				port_per_socket[socket_id]++;
716 			}
717 		}
718 
719 		/* set flag to initialize port/queue */
720 		port->need_reconfig = 1;
721 		port->need_reconfig_queues = 1;
722 	}
723 
724 	/*
725 	 * Create pools of mbuf.
726 	 * If NUMA support is disabled, create a single pool of mbuf in
727 	 * socket 0 memory by default.
728 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
729 	 *
730 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
731 	 * nb_txd can be configured at run time.
732 	 */
733 	if (param_total_num_mbufs)
734 		nb_mbuf_per_pool = param_total_num_mbufs;
735 	else {
736 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
737 			(nb_lcores * mb_mempool_cache) +
738 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
739 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
740 	}
741 
742 	if (numa_support) {
743 		uint8_t i;
744 
745 		for (i = 0; i < num_sockets; i++)
746 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
747 					 socket_ids[i]);
748 	} else {
749 		if (socket_num == UMA_NO_CONFIG)
750 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
751 		else
752 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
753 						 socket_num);
754 	}
755 
756 	init_port_config();
757 
758 	gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
759 		DEV_TX_OFFLOAD_GRE_TNL_TSO;
760 	/*
761 	 * Records which Mbuf pool to use by each logical core, if needed.
762 	 */
763 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
764 		mbp = mbuf_pool_find(
765 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
766 
767 		if (mbp == NULL)
768 			mbp = mbuf_pool_find(0);
769 		fwd_lcores[lc_id]->mbp = mbp;
770 		/* initialize GSO context */
771 		fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
772 		fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
773 		fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
774 		fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
775 			ETHER_CRC_LEN;
776 		fwd_lcores[lc_id]->gso_ctx.flag = 0;
777 	}
778 
779 	/* Configuration of packet forwarding streams. */
780 	if (init_fwd_streams() < 0)
781 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
782 
783 	fwd_config_setup();
784 
785 	/* create a gro context for each lcore */
786 	gro_param.gro_types = RTE_GRO_TCP_IPV4;
787 	gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
788 	gro_param.max_item_per_flow = MAX_PKT_BURST;
789 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
790 		gro_param.socket_id = rte_lcore_to_socket_id(
791 				fwd_lcores_cpuids[lc_id]);
792 		fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
793 		if (fwd_lcores[lc_id]->gro_ctx == NULL) {
794 			rte_exit(EXIT_FAILURE,
795 					"rte_gro_ctx_create() failed\n");
796 		}
797 	}
798 }
799 
800 
801 void
802 reconfig(portid_t new_port_id, unsigned socket_id)
803 {
804 	struct rte_port *port;
805 
806 	/* Reconfiguration of Ethernet ports. */
807 	port = &ports[new_port_id];
808 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
809 
810 	/* set flag to initialize port/queue */
811 	port->need_reconfig = 1;
812 	port->need_reconfig_queues = 1;
813 	port->socket_id = socket_id;
814 
815 	init_port_config();
816 }
817 
818 
819 int
820 init_fwd_streams(void)
821 {
822 	portid_t pid;
823 	struct rte_port *port;
824 	streamid_t sm_id, nb_fwd_streams_new;
825 	queueid_t q;
826 
827 	/* set socket id according to numa or not */
828 	RTE_ETH_FOREACH_DEV(pid) {
829 		port = &ports[pid];
830 		if (nb_rxq > port->dev_info.max_rx_queues) {
831 			printf("Fail: nb_rxq(%d) is greater than "
832 				"max_rx_queues(%d)\n", nb_rxq,
833 				port->dev_info.max_rx_queues);
834 			return -1;
835 		}
836 		if (nb_txq > port->dev_info.max_tx_queues) {
837 			printf("Fail: nb_txq(%d) is greater than "
838 				"max_tx_queues(%d)\n", nb_txq,
839 				port->dev_info.max_tx_queues);
840 			return -1;
841 		}
842 		if (numa_support) {
843 			if (port_numa[pid] != NUMA_NO_CONFIG)
844 				port->socket_id = port_numa[pid];
845 			else {
846 				port->socket_id = rte_eth_dev_socket_id(pid);
847 
848 				/* if socket_id is invalid, set to 0 */
849 				if (check_socket_id(port->socket_id) < 0)
850 					port->socket_id = 0;
851 			}
852 		}
853 		else {
854 			if (socket_num == UMA_NO_CONFIG)
855 				port->socket_id = 0;
856 			else
857 				port->socket_id = socket_num;
858 		}
859 	}
860 
861 	q = RTE_MAX(nb_rxq, nb_txq);
862 	if (q == 0) {
863 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
864 		return -1;
865 	}
866 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
867 	if (nb_fwd_streams_new == nb_fwd_streams)
868 		return 0;
869 	/* clear the old */
870 	if (fwd_streams != NULL) {
871 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
872 			if (fwd_streams[sm_id] == NULL)
873 				continue;
874 			rte_free(fwd_streams[sm_id]);
875 			fwd_streams[sm_id] = NULL;
876 		}
877 		rte_free(fwd_streams);
878 		fwd_streams = NULL;
879 	}
880 
881 	/* init new */
882 	nb_fwd_streams = nb_fwd_streams_new;
883 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
884 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
885 	if (fwd_streams == NULL)
886 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
887 						"failed\n", nb_fwd_streams);
888 
889 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
890 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
891 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
892 		if (fwd_streams[sm_id] == NULL)
893 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
894 								" failed\n");
895 	}
896 
897 	return 0;
898 }
899 
900 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
901 static void
902 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
903 {
904 	unsigned int total_burst;
905 	unsigned int nb_burst;
906 	unsigned int burst_stats[3];
907 	uint16_t pktnb_stats[3];
908 	uint16_t nb_pkt;
909 	int burst_percent[3];
910 
911 	/*
912 	 * First compute the total number of packet bursts and the
913 	 * two highest numbers of bursts of the same number of packets.
914 	 */
915 	total_burst = 0;
916 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
917 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
918 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
919 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
920 		if (nb_burst == 0)
921 			continue;
922 		total_burst += nb_burst;
923 		if (nb_burst > burst_stats[0]) {
924 			burst_stats[1] = burst_stats[0];
925 			pktnb_stats[1] = pktnb_stats[0];
926 			burst_stats[0] = nb_burst;
927 			pktnb_stats[0] = nb_pkt;
928 		}
929 	}
930 	if (total_burst == 0)
931 		return;
932 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
933 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
934 	       burst_percent[0], (int) pktnb_stats[0]);
935 	if (burst_stats[0] == total_burst) {
936 		printf("]\n");
937 		return;
938 	}
939 	if (burst_stats[0] + burst_stats[1] == total_burst) {
940 		printf(" + %d%% of %d pkts]\n",
941 		       100 - burst_percent[0], pktnb_stats[1]);
942 		return;
943 	}
944 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
945 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
946 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
947 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
948 		return;
949 	}
950 	printf(" + %d%% of %d pkts + %d%% of others]\n",
951 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
952 }
953 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
954 
955 static void
956 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
957 {
958 	struct rte_port *port;
959 	uint8_t i;
960 
961 	static const char *fwd_stats_border = "----------------------";
962 
963 	port = &ports[port_id];
964 	printf("\n  %s Forward statistics for port %-2d %s\n",
965 	       fwd_stats_border, port_id, fwd_stats_border);
966 
967 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
968 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
969 		       "%-"PRIu64"\n",
970 		       stats->ipackets, stats->imissed,
971 		       (uint64_t) (stats->ipackets + stats->imissed));
972 
973 		if (cur_fwd_eng == &csum_fwd_engine)
974 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
975 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
976 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
977 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
978 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
979 		}
980 
981 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
982 		       "%-"PRIu64"\n",
983 		       stats->opackets, port->tx_dropped,
984 		       (uint64_t) (stats->opackets + port->tx_dropped));
985 	}
986 	else {
987 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
988 		       "%14"PRIu64"\n",
989 		       stats->ipackets, stats->imissed,
990 		       (uint64_t) (stats->ipackets + stats->imissed));
991 
992 		if (cur_fwd_eng == &csum_fwd_engine)
993 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
994 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
995 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
996 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
997 			printf("  RX-nombufs:             %14"PRIu64"\n",
998 			       stats->rx_nombuf);
999 		}
1000 
1001 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
1002 		       "%14"PRIu64"\n",
1003 		       stats->opackets, port->tx_dropped,
1004 		       (uint64_t) (stats->opackets + port->tx_dropped));
1005 	}
1006 
1007 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1008 	if (port->rx_stream)
1009 		pkt_burst_stats_display("RX",
1010 			&port->rx_stream->rx_burst_stats);
1011 	if (port->tx_stream)
1012 		pkt_burst_stats_display("TX",
1013 			&port->tx_stream->tx_burst_stats);
1014 #endif
1015 
1016 	if (port->rx_queue_stats_mapping_enabled) {
1017 		printf("\n");
1018 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1019 			printf("  Stats reg %2d RX-packets:%14"PRIu64
1020 			       "     RX-errors:%14"PRIu64
1021 			       "    RX-bytes:%14"PRIu64"\n",
1022 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
1023 		}
1024 		printf("\n");
1025 	}
1026 	if (port->tx_queue_stats_mapping_enabled) {
1027 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1028 			printf("  Stats reg %2d TX-packets:%14"PRIu64
1029 			       "                                 TX-bytes:%14"PRIu64"\n",
1030 			       i, stats->q_opackets[i], stats->q_obytes[i]);
1031 		}
1032 	}
1033 
1034 	printf("  %s--------------------------------%s\n",
1035 	       fwd_stats_border, fwd_stats_border);
1036 }
1037 
1038 static void
1039 fwd_stream_stats_display(streamid_t stream_id)
1040 {
1041 	struct fwd_stream *fs;
1042 	static const char *fwd_top_stats_border = "-------";
1043 
1044 	fs = fwd_streams[stream_id];
1045 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1046 	    (fs->fwd_dropped == 0))
1047 		return;
1048 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1049 	       "TX Port=%2d/Queue=%2d %s\n",
1050 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1051 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1052 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
1053 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1054 
1055 	/* if checksum mode */
1056 	if (cur_fwd_eng == &csum_fwd_engine) {
1057 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
1058 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
1059 	}
1060 
1061 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1062 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1063 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1064 #endif
1065 }
1066 
1067 static void
1068 flush_fwd_rx_queues(void)
1069 {
1070 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1071 	portid_t  rxp;
1072 	portid_t port_id;
1073 	queueid_t rxq;
1074 	uint16_t  nb_rx;
1075 	uint16_t  i;
1076 	uint8_t   j;
1077 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1078 	uint64_t timer_period;
1079 
1080 	/* convert to number of cycles */
1081 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
1082 
1083 	for (j = 0; j < 2; j++) {
1084 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
1085 			for (rxq = 0; rxq < nb_rxq; rxq++) {
1086 				port_id = fwd_ports_ids[rxp];
1087 				/**
1088 				* testpmd can stuck in the below do while loop
1089 				* if rte_eth_rx_burst() always returns nonzero
1090 				* packets. So timer is added to exit this loop
1091 				* after 1sec timer expiry.
1092 				*/
1093 				prev_tsc = rte_rdtsc();
1094 				do {
1095 					nb_rx = rte_eth_rx_burst(port_id, rxq,
1096 						pkts_burst, MAX_PKT_BURST);
1097 					for (i = 0; i < nb_rx; i++)
1098 						rte_pktmbuf_free(pkts_burst[i]);
1099 
1100 					cur_tsc = rte_rdtsc();
1101 					diff_tsc = cur_tsc - prev_tsc;
1102 					timer_tsc += diff_tsc;
1103 				} while ((nb_rx > 0) &&
1104 					(timer_tsc < timer_period));
1105 				timer_tsc = 0;
1106 			}
1107 		}
1108 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1109 	}
1110 }
1111 
1112 static void
1113 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1114 {
1115 	struct fwd_stream **fsm;
1116 	streamid_t nb_fs;
1117 	streamid_t sm_id;
1118 #ifdef RTE_LIBRTE_BITRATE
1119 	uint64_t tics_per_1sec;
1120 	uint64_t tics_datum;
1121 	uint64_t tics_current;
1122 	uint8_t idx_port, cnt_ports;
1123 
1124 	cnt_ports = rte_eth_dev_count();
1125 	tics_datum = rte_rdtsc();
1126 	tics_per_1sec = rte_get_timer_hz();
1127 #endif
1128 	fsm = &fwd_streams[fc->stream_idx];
1129 	nb_fs = fc->stream_nb;
1130 	do {
1131 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1132 			(*pkt_fwd)(fsm[sm_id]);
1133 #ifdef RTE_LIBRTE_BITRATE
1134 		if (bitrate_enabled != 0 &&
1135 				bitrate_lcore_id == rte_lcore_id()) {
1136 			tics_current = rte_rdtsc();
1137 			if (tics_current - tics_datum >= tics_per_1sec) {
1138 				/* Periodic bitrate calculation */
1139 				for (idx_port = 0;
1140 						idx_port < cnt_ports;
1141 						idx_port++)
1142 					rte_stats_bitrate_calc(bitrate_data,
1143 						idx_port);
1144 				tics_datum = tics_current;
1145 			}
1146 		}
1147 #endif
1148 #ifdef RTE_LIBRTE_LATENCY_STATS
1149 		if (latencystats_enabled != 0 &&
1150 				latencystats_lcore_id == rte_lcore_id())
1151 			rte_latencystats_update();
1152 #endif
1153 
1154 	} while (! fc->stopped);
1155 }
1156 
1157 static int
1158 start_pkt_forward_on_core(void *fwd_arg)
1159 {
1160 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1161 			     cur_fwd_config.fwd_eng->packet_fwd);
1162 	return 0;
1163 }
1164 
1165 /*
1166  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1167  * Used to start communication flows in network loopback test configurations.
1168  */
1169 static int
1170 run_one_txonly_burst_on_core(void *fwd_arg)
1171 {
1172 	struct fwd_lcore *fwd_lc;
1173 	struct fwd_lcore tmp_lcore;
1174 
1175 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1176 	tmp_lcore = *fwd_lc;
1177 	tmp_lcore.stopped = 1;
1178 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1179 	return 0;
1180 }
1181 
1182 /*
1183  * Launch packet forwarding:
1184  *     - Setup per-port forwarding context.
1185  *     - launch logical cores with their forwarding configuration.
1186  */
1187 static void
1188 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1189 {
1190 	port_fwd_begin_t port_fwd_begin;
1191 	unsigned int i;
1192 	unsigned int lc_id;
1193 	int diag;
1194 
1195 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1196 	if (port_fwd_begin != NULL) {
1197 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1198 			(*port_fwd_begin)(fwd_ports_ids[i]);
1199 	}
1200 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1201 		lc_id = fwd_lcores_cpuids[i];
1202 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1203 			fwd_lcores[i]->stopped = 0;
1204 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1205 						     fwd_lcores[i], lc_id);
1206 			if (diag != 0)
1207 				printf("launch lcore %u failed - diag=%d\n",
1208 				       lc_id, diag);
1209 		}
1210 	}
1211 }
1212 
1213 /*
1214  * Launch packet forwarding configuration.
1215  */
1216 void
1217 start_packet_forwarding(int with_tx_first)
1218 {
1219 	port_fwd_begin_t port_fwd_begin;
1220 	port_fwd_end_t  port_fwd_end;
1221 	struct rte_port *port;
1222 	unsigned int i;
1223 	portid_t   pt_id;
1224 	streamid_t sm_id;
1225 
1226 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1227 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1228 
1229 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1230 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1231 
1232 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1233 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1234 		(!nb_rxq || !nb_txq))
1235 		rte_exit(EXIT_FAILURE,
1236 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
1237 			cur_fwd_eng->fwd_mode_name);
1238 
1239 	if (all_ports_started() == 0) {
1240 		printf("Not all ports were started\n");
1241 		return;
1242 	}
1243 	if (test_done == 0) {
1244 		printf("Packet forwarding already started\n");
1245 		return;
1246 	}
1247 
1248 	if (init_fwd_streams() < 0) {
1249 		printf("Fail from init_fwd_streams()\n");
1250 		return;
1251 	}
1252 
1253 	if(dcb_test) {
1254 		for (i = 0; i < nb_fwd_ports; i++) {
1255 			pt_id = fwd_ports_ids[i];
1256 			port = &ports[pt_id];
1257 			if (!port->dcb_flag) {
1258 				printf("In DCB mode, all forwarding ports must "
1259                                        "be configured in this mode.\n");
1260 				return;
1261 			}
1262 		}
1263 		if (nb_fwd_lcores == 1) {
1264 			printf("In DCB mode,the nb forwarding cores "
1265                                "should be larger than 1.\n");
1266 			return;
1267 		}
1268 	}
1269 	test_done = 0;
1270 
1271 	if(!no_flush_rx)
1272 		flush_fwd_rx_queues();
1273 
1274 	fwd_config_setup();
1275 	pkt_fwd_config_display(&cur_fwd_config);
1276 	rxtx_config_display();
1277 
1278 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1279 		pt_id = fwd_ports_ids[i];
1280 		port = &ports[pt_id];
1281 		rte_eth_stats_get(pt_id, &port->stats);
1282 		port->tx_dropped = 0;
1283 
1284 		map_port_queue_stats_mapping_registers(pt_id, port);
1285 	}
1286 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1287 		fwd_streams[sm_id]->rx_packets = 0;
1288 		fwd_streams[sm_id]->tx_packets = 0;
1289 		fwd_streams[sm_id]->fwd_dropped = 0;
1290 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1291 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1292 
1293 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1294 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1295 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1296 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1297 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1298 #endif
1299 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1300 		fwd_streams[sm_id]->core_cycles = 0;
1301 #endif
1302 	}
1303 	if (with_tx_first) {
1304 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1305 		if (port_fwd_begin != NULL) {
1306 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1307 				(*port_fwd_begin)(fwd_ports_ids[i]);
1308 		}
1309 		while (with_tx_first--) {
1310 			launch_packet_forwarding(
1311 					run_one_txonly_burst_on_core);
1312 			rte_eal_mp_wait_lcore();
1313 		}
1314 		port_fwd_end = tx_only_engine.port_fwd_end;
1315 		if (port_fwd_end != NULL) {
1316 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1317 				(*port_fwd_end)(fwd_ports_ids[i]);
1318 		}
1319 	}
1320 	launch_packet_forwarding(start_pkt_forward_on_core);
1321 }
1322 
1323 void
1324 stop_packet_forwarding(void)
1325 {
1326 	struct rte_eth_stats stats;
1327 	struct rte_port *port;
1328 	port_fwd_end_t  port_fwd_end;
1329 	int i;
1330 	portid_t   pt_id;
1331 	streamid_t sm_id;
1332 	lcoreid_t  lc_id;
1333 	uint64_t total_recv;
1334 	uint64_t total_xmit;
1335 	uint64_t total_rx_dropped;
1336 	uint64_t total_tx_dropped;
1337 	uint64_t total_rx_nombuf;
1338 	uint64_t tx_dropped;
1339 	uint64_t rx_bad_ip_csum;
1340 	uint64_t rx_bad_l4_csum;
1341 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1342 	uint64_t fwd_cycles;
1343 #endif
1344 
1345 	static const char *acc_stats_border = "+++++++++++++++";
1346 
1347 	if (test_done) {
1348 		printf("Packet forwarding not started\n");
1349 		return;
1350 	}
1351 	printf("Telling cores to stop...");
1352 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1353 		fwd_lcores[lc_id]->stopped = 1;
1354 	printf("\nWaiting for lcores to finish...\n");
1355 	rte_eal_mp_wait_lcore();
1356 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1357 	if (port_fwd_end != NULL) {
1358 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1359 			pt_id = fwd_ports_ids[i];
1360 			(*port_fwd_end)(pt_id);
1361 		}
1362 	}
1363 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1364 	fwd_cycles = 0;
1365 #endif
1366 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1367 		if (cur_fwd_config.nb_fwd_streams >
1368 		    cur_fwd_config.nb_fwd_ports) {
1369 			fwd_stream_stats_display(sm_id);
1370 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1371 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1372 		} else {
1373 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1374 				fwd_streams[sm_id];
1375 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1376 				fwd_streams[sm_id];
1377 		}
1378 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1379 		tx_dropped = (uint64_t) (tx_dropped +
1380 					 fwd_streams[sm_id]->fwd_dropped);
1381 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1382 
1383 		rx_bad_ip_csum =
1384 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1385 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1386 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1387 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1388 							rx_bad_ip_csum;
1389 
1390 		rx_bad_l4_csum =
1391 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1392 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1393 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1394 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1395 							rx_bad_l4_csum;
1396 
1397 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1398 		fwd_cycles = (uint64_t) (fwd_cycles +
1399 					 fwd_streams[sm_id]->core_cycles);
1400 #endif
1401 	}
1402 	total_recv = 0;
1403 	total_xmit = 0;
1404 	total_rx_dropped = 0;
1405 	total_tx_dropped = 0;
1406 	total_rx_nombuf  = 0;
1407 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1408 		pt_id = fwd_ports_ids[i];
1409 
1410 		port = &ports[pt_id];
1411 		rte_eth_stats_get(pt_id, &stats);
1412 		stats.ipackets -= port->stats.ipackets;
1413 		port->stats.ipackets = 0;
1414 		stats.opackets -= port->stats.opackets;
1415 		port->stats.opackets = 0;
1416 		stats.ibytes   -= port->stats.ibytes;
1417 		port->stats.ibytes = 0;
1418 		stats.obytes   -= port->stats.obytes;
1419 		port->stats.obytes = 0;
1420 		stats.imissed  -= port->stats.imissed;
1421 		port->stats.imissed = 0;
1422 		stats.oerrors  -= port->stats.oerrors;
1423 		port->stats.oerrors = 0;
1424 		stats.rx_nombuf -= port->stats.rx_nombuf;
1425 		port->stats.rx_nombuf = 0;
1426 
1427 		total_recv += stats.ipackets;
1428 		total_xmit += stats.opackets;
1429 		total_rx_dropped += stats.imissed;
1430 		total_tx_dropped += port->tx_dropped;
1431 		total_rx_nombuf  += stats.rx_nombuf;
1432 
1433 		fwd_port_stats_display(pt_id, &stats);
1434 	}
1435 
1436 	printf("\n  %s Accumulated forward statistics for all ports"
1437 	       "%s\n",
1438 	       acc_stats_border, acc_stats_border);
1439 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1440 	       "%-"PRIu64"\n"
1441 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1442 	       "%-"PRIu64"\n",
1443 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1444 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1445 	if (total_rx_nombuf > 0)
1446 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1447 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1448 	       "%s\n",
1449 	       acc_stats_border, acc_stats_border);
1450 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1451 	if (total_recv > 0)
1452 		printf("\n  CPU cycles/packet=%u (total cycles="
1453 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1454 		       (unsigned int)(fwd_cycles / total_recv),
1455 		       fwd_cycles, total_recv);
1456 #endif
1457 	printf("\nDone.\n");
1458 	test_done = 1;
1459 }
1460 
1461 void
1462 dev_set_link_up(portid_t pid)
1463 {
1464 	if (rte_eth_dev_set_link_up(pid) < 0)
1465 		printf("\nSet link up fail.\n");
1466 }
1467 
1468 void
1469 dev_set_link_down(portid_t pid)
1470 {
1471 	if (rte_eth_dev_set_link_down(pid) < 0)
1472 		printf("\nSet link down fail.\n");
1473 }
1474 
1475 static int
1476 all_ports_started(void)
1477 {
1478 	portid_t pi;
1479 	struct rte_port *port;
1480 
1481 	RTE_ETH_FOREACH_DEV(pi) {
1482 		port = &ports[pi];
1483 		/* Check if there is a port which is not started */
1484 		if ((port->port_status != RTE_PORT_STARTED) &&
1485 			(port->slave_flag == 0))
1486 			return 0;
1487 	}
1488 
1489 	/* No port is not started */
1490 	return 1;
1491 }
1492 
1493 int
1494 all_ports_stopped(void)
1495 {
1496 	portid_t pi;
1497 	struct rte_port *port;
1498 
1499 	RTE_ETH_FOREACH_DEV(pi) {
1500 		port = &ports[pi];
1501 		if ((port->port_status != RTE_PORT_STOPPED) &&
1502 			(port->slave_flag == 0))
1503 			return 0;
1504 	}
1505 
1506 	return 1;
1507 }
1508 
1509 int
1510 port_is_started(portid_t port_id)
1511 {
1512 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1513 		return 0;
1514 
1515 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1516 		return 0;
1517 
1518 	return 1;
1519 }
1520 
1521 static int
1522 port_is_closed(portid_t port_id)
1523 {
1524 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1525 		return 0;
1526 
1527 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1528 		return 0;
1529 
1530 	return 1;
1531 }
1532 
1533 int
1534 start_port(portid_t pid)
1535 {
1536 	int diag, need_check_link_status = -1;
1537 	portid_t pi;
1538 	queueid_t qi;
1539 	struct rte_port *port;
1540 	struct ether_addr mac_addr;
1541 	enum rte_eth_event_type event_type;
1542 
1543 	if (port_id_is_invalid(pid, ENABLED_WARN))
1544 		return 0;
1545 
1546 	if(dcb_config)
1547 		dcb_test = 1;
1548 	RTE_ETH_FOREACH_DEV(pi) {
1549 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1550 			continue;
1551 
1552 		need_check_link_status = 0;
1553 		port = &ports[pi];
1554 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1555 						 RTE_PORT_HANDLING) == 0) {
1556 			printf("Port %d is now not stopped\n", pi);
1557 			continue;
1558 		}
1559 
1560 		if (port->need_reconfig > 0) {
1561 			port->need_reconfig = 0;
1562 
1563 			if (flow_isolate_all) {
1564 				int ret = port_flow_isolate(pi, 1);
1565 				if (ret) {
1566 					printf("Failed to apply isolated"
1567 					       " mode on port %d\n", pi);
1568 					return -1;
1569 				}
1570 			}
1571 
1572 			printf("Configuring Port %d (socket %u)\n", pi,
1573 					port->socket_id);
1574 			/* configure port */
1575 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1576 						&(port->dev_conf));
1577 			if (diag != 0) {
1578 				if (rte_atomic16_cmpset(&(port->port_status),
1579 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1580 					printf("Port %d can not be set back "
1581 							"to stopped\n", pi);
1582 				printf("Fail to configure port %d\n", pi);
1583 				/* try to reconfigure port next time */
1584 				port->need_reconfig = 1;
1585 				return -1;
1586 			}
1587 		}
1588 		if (port->need_reconfig_queues > 0) {
1589 			port->need_reconfig_queues = 0;
1590 			/* setup tx queues */
1591 			for (qi = 0; qi < nb_txq; qi++) {
1592 				if ((numa_support) &&
1593 					(txring_numa[pi] != NUMA_NO_CONFIG))
1594 					diag = rte_eth_tx_queue_setup(pi, qi,
1595 						nb_txd,txring_numa[pi],
1596 						&(port->tx_conf));
1597 				else
1598 					diag = rte_eth_tx_queue_setup(pi, qi,
1599 						nb_txd,port->socket_id,
1600 						&(port->tx_conf));
1601 
1602 				if (diag == 0)
1603 					continue;
1604 
1605 				/* Fail to setup tx queue, return */
1606 				if (rte_atomic16_cmpset(&(port->port_status),
1607 							RTE_PORT_HANDLING,
1608 							RTE_PORT_STOPPED) == 0)
1609 					printf("Port %d can not be set back "
1610 							"to stopped\n", pi);
1611 				printf("Fail to configure port %d tx queues\n", pi);
1612 				/* try to reconfigure queues next time */
1613 				port->need_reconfig_queues = 1;
1614 				return -1;
1615 			}
1616 			/* setup rx queues */
1617 			for (qi = 0; qi < nb_rxq; qi++) {
1618 				if ((numa_support) &&
1619 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1620 					struct rte_mempool * mp =
1621 						mbuf_pool_find(rxring_numa[pi]);
1622 					if (mp == NULL) {
1623 						printf("Failed to setup RX queue:"
1624 							"No mempool allocation"
1625 							" on the socket %d\n",
1626 							rxring_numa[pi]);
1627 						return -1;
1628 					}
1629 
1630 					diag = rte_eth_rx_queue_setup(pi, qi,
1631 					     nb_rxd,rxring_numa[pi],
1632 					     &(port->rx_conf),mp);
1633 				} else {
1634 					struct rte_mempool *mp =
1635 						mbuf_pool_find(port->socket_id);
1636 					if (mp == NULL) {
1637 						printf("Failed to setup RX queue:"
1638 							"No mempool allocation"
1639 							" on the socket %d\n",
1640 							port->socket_id);
1641 						return -1;
1642 					}
1643 					diag = rte_eth_rx_queue_setup(pi, qi,
1644 					     nb_rxd,port->socket_id,
1645 					     &(port->rx_conf), mp);
1646 				}
1647 				if (diag == 0)
1648 					continue;
1649 
1650 				/* Fail to setup rx queue, return */
1651 				if (rte_atomic16_cmpset(&(port->port_status),
1652 							RTE_PORT_HANDLING,
1653 							RTE_PORT_STOPPED) == 0)
1654 					printf("Port %d can not be set back "
1655 							"to stopped\n", pi);
1656 				printf("Fail to configure port %d rx queues\n", pi);
1657 				/* try to reconfigure queues next time */
1658 				port->need_reconfig_queues = 1;
1659 				return -1;
1660 			}
1661 		}
1662 
1663 		for (event_type = RTE_ETH_EVENT_UNKNOWN;
1664 		     event_type < RTE_ETH_EVENT_MAX;
1665 		     event_type++) {
1666 			diag = rte_eth_dev_callback_register(pi,
1667 							event_type,
1668 							eth_event_callback,
1669 							NULL);
1670 			if (diag) {
1671 				printf("Failed to setup even callback for event %d\n",
1672 					event_type);
1673 				return -1;
1674 			}
1675 		}
1676 
1677 		/* start port */
1678 		if (rte_eth_dev_start(pi) < 0) {
1679 			printf("Fail to start port %d\n", pi);
1680 
1681 			/* Fail to setup rx queue, return */
1682 			if (rte_atomic16_cmpset(&(port->port_status),
1683 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1684 				printf("Port %d can not be set back to "
1685 							"stopped\n", pi);
1686 			continue;
1687 		}
1688 
1689 		if (rte_atomic16_cmpset(&(port->port_status),
1690 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1691 			printf("Port %d can not be set into started\n", pi);
1692 
1693 		rte_eth_macaddr_get(pi, &mac_addr);
1694 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1695 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1696 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1697 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1698 
1699 		/* at least one port started, need checking link status */
1700 		need_check_link_status = 1;
1701 	}
1702 
1703 	if (need_check_link_status == 1 && !no_link_check)
1704 		check_all_ports_link_status(RTE_PORT_ALL);
1705 	else if (need_check_link_status == 0)
1706 		printf("Please stop the ports first\n");
1707 
1708 	printf("Done\n");
1709 	return 0;
1710 }
1711 
1712 void
1713 stop_port(portid_t pid)
1714 {
1715 	portid_t pi;
1716 	struct rte_port *port;
1717 	int need_check_link_status = 0;
1718 
1719 	if (dcb_test) {
1720 		dcb_test = 0;
1721 		dcb_config = 0;
1722 	}
1723 
1724 	if (port_id_is_invalid(pid, ENABLED_WARN))
1725 		return;
1726 
1727 	printf("Stopping ports...\n");
1728 
1729 	RTE_ETH_FOREACH_DEV(pi) {
1730 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1731 			continue;
1732 
1733 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1734 			printf("Please remove port %d from forwarding configuration.\n", pi);
1735 			continue;
1736 		}
1737 
1738 		if (port_is_bonding_slave(pi)) {
1739 			printf("Please remove port %d from bonded device.\n", pi);
1740 			continue;
1741 		}
1742 
1743 		port = &ports[pi];
1744 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1745 						RTE_PORT_HANDLING) == 0)
1746 			continue;
1747 
1748 		rte_eth_dev_stop(pi);
1749 
1750 		if (rte_atomic16_cmpset(&(port->port_status),
1751 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1752 			printf("Port %d can not be set into stopped\n", pi);
1753 		need_check_link_status = 1;
1754 	}
1755 	if (need_check_link_status && !no_link_check)
1756 		check_all_ports_link_status(RTE_PORT_ALL);
1757 
1758 	printf("Done\n");
1759 }
1760 
1761 void
1762 close_port(portid_t pid)
1763 {
1764 	portid_t pi;
1765 	struct rte_port *port;
1766 
1767 	if (port_id_is_invalid(pid, ENABLED_WARN))
1768 		return;
1769 
1770 	printf("Closing ports...\n");
1771 
1772 	RTE_ETH_FOREACH_DEV(pi) {
1773 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1774 			continue;
1775 
1776 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1777 			printf("Please remove port %d from forwarding configuration.\n", pi);
1778 			continue;
1779 		}
1780 
1781 		if (port_is_bonding_slave(pi)) {
1782 			printf("Please remove port %d from bonded device.\n", pi);
1783 			continue;
1784 		}
1785 
1786 		port = &ports[pi];
1787 		if (rte_atomic16_cmpset(&(port->port_status),
1788 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1789 			printf("Port %d is already closed\n", pi);
1790 			continue;
1791 		}
1792 
1793 		if (rte_atomic16_cmpset(&(port->port_status),
1794 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1795 			printf("Port %d is now not stopped\n", pi);
1796 			continue;
1797 		}
1798 
1799 		if (port->flow_list)
1800 			port_flow_flush(pi);
1801 		rte_eth_dev_close(pi);
1802 
1803 		if (rte_atomic16_cmpset(&(port->port_status),
1804 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1805 			printf("Port %d cannot be set to closed\n", pi);
1806 	}
1807 
1808 	printf("Done\n");
1809 }
1810 
1811 void
1812 reset_port(portid_t pid)
1813 {
1814 	int diag;
1815 	portid_t pi;
1816 	struct rte_port *port;
1817 
1818 	if (port_id_is_invalid(pid, ENABLED_WARN))
1819 		return;
1820 
1821 	printf("Resetting ports...\n");
1822 
1823 	RTE_ETH_FOREACH_DEV(pi) {
1824 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1825 			continue;
1826 
1827 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1828 			printf("Please remove port %d from forwarding "
1829 			       "configuration.\n", pi);
1830 			continue;
1831 		}
1832 
1833 		if (port_is_bonding_slave(pi)) {
1834 			printf("Please remove port %d from bonded device.\n",
1835 			       pi);
1836 			continue;
1837 		}
1838 
1839 		diag = rte_eth_dev_reset(pi);
1840 		if (diag == 0) {
1841 			port = &ports[pi];
1842 			port->need_reconfig = 1;
1843 			port->need_reconfig_queues = 1;
1844 		} else {
1845 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
1846 		}
1847 	}
1848 
1849 	printf("Done\n");
1850 }
1851 
1852 void
1853 attach_port(char *identifier)
1854 {
1855 	portid_t pi = 0;
1856 	unsigned int socket_id;
1857 
1858 	printf("Attaching a new port...\n");
1859 
1860 	if (identifier == NULL) {
1861 		printf("Invalid parameters are specified\n");
1862 		return;
1863 	}
1864 
1865 	if (rte_eth_dev_attach(identifier, &pi))
1866 		return;
1867 
1868 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1869 	/* if socket_id is invalid, set to 0 */
1870 	if (check_socket_id(socket_id) < 0)
1871 		socket_id = 0;
1872 	reconfig(pi, socket_id);
1873 	rte_eth_promiscuous_enable(pi);
1874 
1875 	nb_ports = rte_eth_dev_count();
1876 
1877 	ports[pi].port_status = RTE_PORT_STOPPED;
1878 
1879 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1880 	printf("Done\n");
1881 }
1882 
1883 void
1884 detach_port(portid_t port_id)
1885 {
1886 	char name[RTE_ETH_NAME_MAX_LEN];
1887 
1888 	printf("Detaching a port...\n");
1889 
1890 	if (!port_is_closed(port_id)) {
1891 		printf("Please close port first\n");
1892 		return;
1893 	}
1894 
1895 	if (ports[port_id].flow_list)
1896 		port_flow_flush(port_id);
1897 
1898 	if (rte_eth_dev_detach(port_id, name)) {
1899 		RTE_LOG(ERR, USER1, "Failed to detach port '%s'\n", name);
1900 		return;
1901 	}
1902 
1903 	nb_ports = rte_eth_dev_count();
1904 
1905 	printf("Port '%s' is detached. Now total ports is %d\n",
1906 			name, nb_ports);
1907 	printf("Done\n");
1908 	return;
1909 }
1910 
1911 void
1912 pmd_test_exit(void)
1913 {
1914 	portid_t pt_id;
1915 
1916 	if (test_done == 0)
1917 		stop_packet_forwarding();
1918 
1919 	if (ports != NULL) {
1920 		no_link_check = 1;
1921 		RTE_ETH_FOREACH_DEV(pt_id) {
1922 			printf("\nShutting down port %d...\n", pt_id);
1923 			fflush(stdout);
1924 			stop_port(pt_id);
1925 			close_port(pt_id);
1926 		}
1927 	}
1928 	printf("\nBye...\n");
1929 }
1930 
1931 typedef void (*cmd_func_t)(void);
1932 struct pmd_test_command {
1933 	const char *cmd_name;
1934 	cmd_func_t cmd_func;
1935 };
1936 
1937 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1938 
1939 /* Check the link status of all ports in up to 9s, and print them finally */
1940 static void
1941 check_all_ports_link_status(uint32_t port_mask)
1942 {
1943 #define CHECK_INTERVAL 100 /* 100ms */
1944 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1945 	portid_t portid;
1946 	uint8_t count, all_ports_up, print_flag = 0;
1947 	struct rte_eth_link link;
1948 
1949 	printf("Checking link statuses...\n");
1950 	fflush(stdout);
1951 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1952 		all_ports_up = 1;
1953 		RTE_ETH_FOREACH_DEV(portid) {
1954 			if ((port_mask & (1 << portid)) == 0)
1955 				continue;
1956 			memset(&link, 0, sizeof(link));
1957 			rte_eth_link_get_nowait(portid, &link);
1958 			/* print link status if flag set */
1959 			if (print_flag == 1) {
1960 				if (link.link_status)
1961 					printf(
1962 					"Port%d Link Up. speed %u Mbps- %s\n",
1963 					portid, link.link_speed,
1964 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1965 					("full-duplex") : ("half-duplex\n"));
1966 				else
1967 					printf("Port %d Link Down\n", portid);
1968 				continue;
1969 			}
1970 			/* clear all_ports_up flag if any link down */
1971 			if (link.link_status == ETH_LINK_DOWN) {
1972 				all_ports_up = 0;
1973 				break;
1974 			}
1975 		}
1976 		/* after finally printing all link status, get out */
1977 		if (print_flag == 1)
1978 			break;
1979 
1980 		if (all_ports_up == 0) {
1981 			fflush(stdout);
1982 			rte_delay_ms(CHECK_INTERVAL);
1983 		}
1984 
1985 		/* set the print_flag if all ports up or timeout */
1986 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1987 			print_flag = 1;
1988 		}
1989 
1990 		if (lsc_interrupt)
1991 			break;
1992 	}
1993 }
1994 
1995 static void
1996 rmv_event_callback(void *arg)
1997 {
1998 	struct rte_eth_dev *dev;
1999 	portid_t port_id = (intptr_t)arg;
2000 
2001 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
2002 	dev = &rte_eth_devices[port_id];
2003 
2004 	stop_port(port_id);
2005 	close_port(port_id);
2006 	printf("removing device %s\n", dev->device->name);
2007 	if (rte_eal_dev_detach(dev->device))
2008 		RTE_LOG(ERR, USER1, "Failed to detach device %s\n",
2009 			dev->device->name);
2010 }
2011 
2012 /* This function is used by the interrupt thread */
2013 static int
2014 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
2015 		  void *ret_param)
2016 {
2017 	static const char * const event_desc[] = {
2018 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
2019 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
2020 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
2021 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
2022 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
2023 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
2024 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
2025 		[RTE_ETH_EVENT_MAX] = NULL,
2026 	};
2027 
2028 	RTE_SET_USED(param);
2029 	RTE_SET_USED(ret_param);
2030 
2031 	if (type >= RTE_ETH_EVENT_MAX) {
2032 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
2033 			port_id, __func__, type);
2034 		fflush(stderr);
2035 	} else if (event_print_mask & (UINT32_C(1) << type)) {
2036 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
2037 			event_desc[type]);
2038 		fflush(stdout);
2039 	}
2040 
2041 	switch (type) {
2042 	case RTE_ETH_EVENT_INTR_RMV:
2043 		if (rte_eal_alarm_set(100000,
2044 				rmv_event_callback, (void *)(intptr_t)port_id))
2045 			fprintf(stderr, "Could not set up deferred device removal\n");
2046 		break;
2047 	default:
2048 		break;
2049 	}
2050 	return 0;
2051 }
2052 
2053 static int
2054 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2055 {
2056 	uint16_t i;
2057 	int diag;
2058 	uint8_t mapping_found = 0;
2059 
2060 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
2061 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
2062 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
2063 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
2064 					tx_queue_stats_mappings[i].queue_id,
2065 					tx_queue_stats_mappings[i].stats_counter_id);
2066 			if (diag != 0)
2067 				return diag;
2068 			mapping_found = 1;
2069 		}
2070 	}
2071 	if (mapping_found)
2072 		port->tx_queue_stats_mapping_enabled = 1;
2073 	return 0;
2074 }
2075 
2076 static int
2077 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2078 {
2079 	uint16_t i;
2080 	int diag;
2081 	uint8_t mapping_found = 0;
2082 
2083 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
2084 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
2085 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
2086 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
2087 					rx_queue_stats_mappings[i].queue_id,
2088 					rx_queue_stats_mappings[i].stats_counter_id);
2089 			if (diag != 0)
2090 				return diag;
2091 			mapping_found = 1;
2092 		}
2093 	}
2094 	if (mapping_found)
2095 		port->rx_queue_stats_mapping_enabled = 1;
2096 	return 0;
2097 }
2098 
2099 static void
2100 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2101 {
2102 	int diag = 0;
2103 
2104 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2105 	if (diag != 0) {
2106 		if (diag == -ENOTSUP) {
2107 			port->tx_queue_stats_mapping_enabled = 0;
2108 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2109 		}
2110 		else
2111 			rte_exit(EXIT_FAILURE,
2112 					"set_tx_queue_stats_mapping_registers "
2113 					"failed for port id=%d diag=%d\n",
2114 					pi, diag);
2115 	}
2116 
2117 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2118 	if (diag != 0) {
2119 		if (diag == -ENOTSUP) {
2120 			port->rx_queue_stats_mapping_enabled = 0;
2121 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2122 		}
2123 		else
2124 			rte_exit(EXIT_FAILURE,
2125 					"set_rx_queue_stats_mapping_registers "
2126 					"failed for port id=%d diag=%d\n",
2127 					pi, diag);
2128 	}
2129 }
2130 
2131 static void
2132 rxtx_port_config(struct rte_port *port)
2133 {
2134 	port->rx_conf = port->dev_info.default_rxconf;
2135 	port->tx_conf = port->dev_info.default_txconf;
2136 
2137 	/* Check if any RX/TX parameters have been passed */
2138 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2139 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
2140 
2141 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2142 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
2143 
2144 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2145 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
2146 
2147 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2148 		port->rx_conf.rx_free_thresh = rx_free_thresh;
2149 
2150 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2151 		port->rx_conf.rx_drop_en = rx_drop_en;
2152 
2153 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2154 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
2155 
2156 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2157 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
2158 
2159 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2160 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
2161 
2162 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2163 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
2164 
2165 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2166 		port->tx_conf.tx_free_thresh = tx_free_thresh;
2167 
2168 	if (txq_flags != RTE_PMD_PARAM_UNSET)
2169 		port->tx_conf.txq_flags = txq_flags;
2170 }
2171 
2172 void
2173 init_port_config(void)
2174 {
2175 	portid_t pid;
2176 	struct rte_port *port;
2177 
2178 	RTE_ETH_FOREACH_DEV(pid) {
2179 		port = &ports[pid];
2180 		port->dev_conf.rxmode = rx_mode;
2181 		port->dev_conf.fdir_conf = fdir_conf;
2182 		if (nb_rxq > 1) {
2183 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2184 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2185 		} else {
2186 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2187 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2188 		}
2189 
2190 		if (port->dcb_flag == 0) {
2191 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2192 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2193 			else
2194 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2195 		}
2196 
2197 		rxtx_port_config(port);
2198 
2199 		rte_eth_macaddr_get(pid, &port->eth_addr);
2200 
2201 		map_port_queue_stats_mapping_registers(pid, port);
2202 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2203 		rte_pmd_ixgbe_bypass_init(pid);
2204 #endif
2205 
2206 		if (lsc_interrupt &&
2207 		    (rte_eth_devices[pid].data->dev_flags &
2208 		     RTE_ETH_DEV_INTR_LSC))
2209 			port->dev_conf.intr_conf.lsc = 1;
2210 		if (rmv_interrupt &&
2211 		    (rte_eth_devices[pid].data->dev_flags &
2212 		     RTE_ETH_DEV_INTR_RMV))
2213 			port->dev_conf.intr_conf.rmv = 1;
2214 
2215 #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
2216 		/* Detect softnic port */
2217 		if (!strcmp(port->dev_info.driver_name, "net_softnic")) {
2218 			port->softnic_enable = 1;
2219 			memset(&port->softport, 0, sizeof(struct softnic_port));
2220 
2221 			if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm"))
2222 				port->softport.tm_flag = 1;
2223 		}
2224 #endif
2225 	}
2226 }
2227 
2228 void set_port_slave_flag(portid_t slave_pid)
2229 {
2230 	struct rte_port *port;
2231 
2232 	port = &ports[slave_pid];
2233 	port->slave_flag = 1;
2234 }
2235 
2236 void clear_port_slave_flag(portid_t slave_pid)
2237 {
2238 	struct rte_port *port;
2239 
2240 	port = &ports[slave_pid];
2241 	port->slave_flag = 0;
2242 }
2243 
2244 uint8_t port_is_bonding_slave(portid_t slave_pid)
2245 {
2246 	struct rte_port *port;
2247 
2248 	port = &ports[slave_pid];
2249 	return port->slave_flag;
2250 }
2251 
2252 const uint16_t vlan_tags[] = {
2253 		0,  1,  2,  3,  4,  5,  6,  7,
2254 		8,  9, 10, 11,  12, 13, 14, 15,
2255 		16, 17, 18, 19, 20, 21, 22, 23,
2256 		24, 25, 26, 27, 28, 29, 30, 31
2257 };
2258 
2259 static  int
2260 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
2261 		 enum dcb_mode_enable dcb_mode,
2262 		 enum rte_eth_nb_tcs num_tcs,
2263 		 uint8_t pfc_en)
2264 {
2265 	uint8_t i;
2266 
2267 	/*
2268 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2269 	 * given above, and the number of traffic classes available for use.
2270 	 */
2271 	if (dcb_mode == DCB_VT_ENABLED) {
2272 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2273 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
2274 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2275 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2276 
2277 		/* VMDQ+DCB RX and TX configurations */
2278 		vmdq_rx_conf->enable_default_pool = 0;
2279 		vmdq_rx_conf->default_pool = 0;
2280 		vmdq_rx_conf->nb_queue_pools =
2281 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2282 		vmdq_tx_conf->nb_queue_pools =
2283 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2284 
2285 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2286 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2287 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2288 			vmdq_rx_conf->pool_map[i].pools =
2289 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2290 		}
2291 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2292 			vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2293 			vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2294 		}
2295 
2296 		/* set DCB mode of RX and TX of multiple queues */
2297 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2298 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2299 	} else {
2300 		struct rte_eth_dcb_rx_conf *rx_conf =
2301 				&eth_conf->rx_adv_conf.dcb_rx_conf;
2302 		struct rte_eth_dcb_tx_conf *tx_conf =
2303 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2304 
2305 		rx_conf->nb_tcs = num_tcs;
2306 		tx_conf->nb_tcs = num_tcs;
2307 
2308 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2309 			rx_conf->dcb_tc[i] = i % num_tcs;
2310 			tx_conf->dcb_tc[i] = i % num_tcs;
2311 		}
2312 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2313 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
2314 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2315 	}
2316 
2317 	if (pfc_en)
2318 		eth_conf->dcb_capability_en =
2319 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2320 	else
2321 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2322 
2323 	return 0;
2324 }
2325 
2326 int
2327 init_port_dcb_config(portid_t pid,
2328 		     enum dcb_mode_enable dcb_mode,
2329 		     enum rte_eth_nb_tcs num_tcs,
2330 		     uint8_t pfc_en)
2331 {
2332 	struct rte_eth_conf port_conf;
2333 	struct rte_port *rte_port;
2334 	int retval;
2335 	uint16_t i;
2336 
2337 	rte_port = &ports[pid];
2338 
2339 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2340 	/* Enter DCB configuration status */
2341 	dcb_config = 1;
2342 
2343 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
2344 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2345 	if (retval < 0)
2346 		return retval;
2347 	port_conf.rxmode.hw_vlan_filter = 1;
2348 
2349 	/**
2350 	 * Write the configuration into the device.
2351 	 * Set the numbers of RX & TX queues to 0, so
2352 	 * the RX & TX queues will not be setup.
2353 	 */
2354 	rte_eth_dev_configure(pid, 0, 0, &port_conf);
2355 
2356 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
2357 
2358 	/* If dev_info.vmdq_pool_base is greater than 0,
2359 	 * the queue id of vmdq pools is started after pf queues.
2360 	 */
2361 	if (dcb_mode == DCB_VT_ENABLED &&
2362 	    rte_port->dev_info.vmdq_pool_base > 0) {
2363 		printf("VMDQ_DCB multi-queue mode is nonsensical"
2364 			" for port %d.", pid);
2365 		return -1;
2366 	}
2367 
2368 	/* Assume the ports in testpmd have the same dcb capability
2369 	 * and has the same number of rxq and txq in dcb mode
2370 	 */
2371 	if (dcb_mode == DCB_VT_ENABLED) {
2372 		if (rte_port->dev_info.max_vfs > 0) {
2373 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2374 			nb_txq = rte_port->dev_info.nb_tx_queues;
2375 		} else {
2376 			nb_rxq = rte_port->dev_info.max_rx_queues;
2377 			nb_txq = rte_port->dev_info.max_tx_queues;
2378 		}
2379 	} else {
2380 		/*if vt is disabled, use all pf queues */
2381 		if (rte_port->dev_info.vmdq_pool_base == 0) {
2382 			nb_rxq = rte_port->dev_info.max_rx_queues;
2383 			nb_txq = rte_port->dev_info.max_tx_queues;
2384 		} else {
2385 			nb_rxq = (queueid_t)num_tcs;
2386 			nb_txq = (queueid_t)num_tcs;
2387 
2388 		}
2389 	}
2390 	rx_free_thresh = 64;
2391 
2392 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2393 
2394 	rxtx_port_config(rte_port);
2395 	/* VLAN filter */
2396 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
2397 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2398 		rx_vft_set(pid, vlan_tags[i], 1);
2399 
2400 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2401 	map_port_queue_stats_mapping_registers(pid, rte_port);
2402 
2403 	rte_port->dcb_flag = 1;
2404 
2405 	return 0;
2406 }
2407 
2408 static void
2409 init_port(void)
2410 {
2411 	/* Configuration of Ethernet ports. */
2412 	ports = rte_zmalloc("testpmd: ports",
2413 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2414 			    RTE_CACHE_LINE_SIZE);
2415 	if (ports == NULL) {
2416 		rte_exit(EXIT_FAILURE,
2417 				"rte_zmalloc(%d struct rte_port) failed\n",
2418 				RTE_MAX_ETHPORTS);
2419 	}
2420 }
2421 
2422 static void
2423 force_quit(void)
2424 {
2425 	pmd_test_exit();
2426 	prompt_exit();
2427 }
2428 
2429 static void
2430 print_stats(void)
2431 {
2432 	uint8_t i;
2433 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2434 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2435 
2436 	/* Clear screen and move to top left */
2437 	printf("%s%s", clr, top_left);
2438 
2439 	printf("\nPort statistics ====================================");
2440 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2441 		nic_stats_display(fwd_ports_ids[i]);
2442 }
2443 
2444 static void
2445 signal_handler(int signum)
2446 {
2447 	if (signum == SIGINT || signum == SIGTERM) {
2448 		printf("\nSignal %d received, preparing to exit...\n",
2449 				signum);
2450 #ifdef RTE_LIBRTE_PDUMP
2451 		/* uninitialize packet capture framework */
2452 		rte_pdump_uninit();
2453 #endif
2454 #ifdef RTE_LIBRTE_LATENCY_STATS
2455 		rte_latencystats_uninit();
2456 #endif
2457 		force_quit();
2458 		/* Set flag to indicate the force termination. */
2459 		f_quit = 1;
2460 		/* exit with the expected status */
2461 		signal(signum, SIG_DFL);
2462 		kill(getpid(), signum);
2463 	}
2464 }
2465 
2466 int
2467 main(int argc, char** argv)
2468 {
2469 	int  diag;
2470 	portid_t port_id;
2471 
2472 	signal(SIGINT, signal_handler);
2473 	signal(SIGTERM, signal_handler);
2474 
2475 	diag = rte_eal_init(argc, argv);
2476 	if (diag < 0)
2477 		rte_panic("Cannot init EAL\n");
2478 
2479 	if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
2480 		RTE_LOG(NOTICE, USER1, "mlockall() failed with error \"%s\"\n",
2481 			strerror(errno));
2482 	}
2483 
2484 #ifdef RTE_LIBRTE_PDUMP
2485 	/* initialize packet capture framework */
2486 	rte_pdump_init(NULL);
2487 #endif
2488 
2489 	nb_ports = (portid_t) rte_eth_dev_count();
2490 	if (nb_ports == 0)
2491 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2492 
2493 	/* allocate port structures, and init them */
2494 	init_port();
2495 
2496 	set_def_fwd_config();
2497 	if (nb_lcores == 0)
2498 		rte_panic("Empty set of forwarding logical cores - check the "
2499 			  "core mask supplied in the command parameters\n");
2500 
2501 	/* Bitrate/latency stats disabled by default */
2502 #ifdef RTE_LIBRTE_BITRATE
2503 	bitrate_enabled = 0;
2504 #endif
2505 #ifdef RTE_LIBRTE_LATENCY_STATS
2506 	latencystats_enabled = 0;
2507 #endif
2508 
2509 	argc -= diag;
2510 	argv += diag;
2511 	if (argc > 1)
2512 		launch_args_parse(argc, argv);
2513 
2514 	if (tx_first && interactive)
2515 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
2516 				"interactive mode.\n");
2517 
2518 	if (tx_first && lsc_interrupt) {
2519 		printf("Warning: lsc_interrupt needs to be off when "
2520 				" using tx_first. Disabling.\n");
2521 		lsc_interrupt = 0;
2522 	}
2523 
2524 	if (!nb_rxq && !nb_txq)
2525 		printf("Warning: Either rx or tx queues should be non-zero\n");
2526 
2527 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2528 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2529 		       "but nb_txq=%d will prevent to fully test it.\n",
2530 		       nb_rxq, nb_txq);
2531 
2532 	init_config();
2533 	if (start_port(RTE_PORT_ALL) != 0)
2534 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2535 
2536 	/* set all ports to promiscuous mode by default */
2537 	RTE_ETH_FOREACH_DEV(port_id)
2538 		rte_eth_promiscuous_enable(port_id);
2539 
2540 	/* Init metrics library */
2541 	rte_metrics_init(rte_socket_id());
2542 
2543 #ifdef RTE_LIBRTE_LATENCY_STATS
2544 	if (latencystats_enabled != 0) {
2545 		int ret = rte_latencystats_init(1, NULL);
2546 		if (ret)
2547 			printf("Warning: latencystats init()"
2548 				" returned error %d\n",	ret);
2549 		printf("Latencystats running on lcore %d\n",
2550 			latencystats_lcore_id);
2551 	}
2552 #endif
2553 
2554 	/* Setup bitrate stats */
2555 #ifdef RTE_LIBRTE_BITRATE
2556 	if (bitrate_enabled != 0) {
2557 		bitrate_data = rte_stats_bitrate_create();
2558 		if (bitrate_data == NULL)
2559 			rte_exit(EXIT_FAILURE,
2560 				"Could not allocate bitrate data.\n");
2561 		rte_stats_bitrate_reg(bitrate_data);
2562 	}
2563 #endif
2564 
2565 #ifdef RTE_LIBRTE_CMDLINE
2566 	if (strlen(cmdline_filename) != 0)
2567 		cmdline_read_from_file(cmdline_filename);
2568 
2569 	if (interactive == 1) {
2570 		if (auto_start) {
2571 			printf("Start automatic packet forwarding\n");
2572 			start_packet_forwarding(0);
2573 		}
2574 		prompt();
2575 		pmd_test_exit();
2576 	} else
2577 #endif
2578 	{
2579 		char c;
2580 		int rc;
2581 
2582 		f_quit = 0;
2583 
2584 		printf("No commandline core given, start packet forwarding\n");
2585 		start_packet_forwarding(tx_first);
2586 		if (stats_period != 0) {
2587 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2588 			uint64_t timer_period;
2589 
2590 			/* Convert to number of cycles */
2591 			timer_period = stats_period * rte_get_timer_hz();
2592 
2593 			while (f_quit == 0) {
2594 				cur_time = rte_get_timer_cycles();
2595 				diff_time += cur_time - prev_time;
2596 
2597 				if (diff_time >= timer_period) {
2598 					print_stats();
2599 					/* Reset the timer */
2600 					diff_time = 0;
2601 				}
2602 				/* Sleep to avoid unnecessary checks */
2603 				prev_time = cur_time;
2604 				sleep(1);
2605 			}
2606 		}
2607 
2608 		printf("Press enter to exit\n");
2609 		rc = read(0, &c, 1);
2610 		pmd_test_exit();
2611 		if (rc < 0)
2612 			return 1;
2613 	}
2614 
2615 	return 0;
2616 }
2617