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