xref: /dpdk/app/test-pmd/testpmd.c (revision 4aa0d0121a3a1c542dce35194b8704bb2358c06b)
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  * Update the forward ports list.
1223  */
1224 void
1225 update_fwd_ports(portid_t new_pid)
1226 {
1227 	unsigned int i;
1228 	unsigned int new_nb_fwd_ports = 0;
1229 	int move = 0;
1230 
1231 	for (i = 0; i < nb_fwd_ports; ++i) {
1232 		if (port_id_is_invalid(fwd_ports_ids[i], DISABLED_WARN))
1233 			move = 1;
1234 		else if (move)
1235 			fwd_ports_ids[new_nb_fwd_ports++] = fwd_ports_ids[i];
1236 		else
1237 			new_nb_fwd_ports++;
1238 	}
1239 	if (new_pid < RTE_MAX_ETHPORTS)
1240 		fwd_ports_ids[new_nb_fwd_ports++] = new_pid;
1241 
1242 	nb_fwd_ports = new_nb_fwd_ports;
1243 	nb_cfg_ports = new_nb_fwd_ports;
1244 }
1245 
1246 /*
1247  * Launch packet forwarding configuration.
1248  */
1249 void
1250 start_packet_forwarding(int with_tx_first)
1251 {
1252 	port_fwd_begin_t port_fwd_begin;
1253 	port_fwd_end_t  port_fwd_end;
1254 	struct rte_port *port;
1255 	unsigned int i;
1256 	portid_t   pt_id;
1257 	streamid_t sm_id;
1258 
1259 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1260 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1261 
1262 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1263 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1264 
1265 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1266 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1267 		(!nb_rxq || !nb_txq))
1268 		rte_exit(EXIT_FAILURE,
1269 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
1270 			cur_fwd_eng->fwd_mode_name);
1271 
1272 	if (all_ports_started() == 0) {
1273 		printf("Not all ports were started\n");
1274 		return;
1275 	}
1276 	if (test_done == 0) {
1277 		printf("Packet forwarding already started\n");
1278 		return;
1279 	}
1280 
1281 
1282 	if(dcb_test) {
1283 		for (i = 0; i < nb_fwd_ports; i++) {
1284 			pt_id = fwd_ports_ids[i];
1285 			port = &ports[pt_id];
1286 			if (!port->dcb_flag) {
1287 				printf("In DCB mode, all forwarding ports must "
1288                                        "be configured in this mode.\n");
1289 				return;
1290 			}
1291 		}
1292 		if (nb_fwd_lcores == 1) {
1293 			printf("In DCB mode,the nb forwarding cores "
1294                                "should be larger than 1.\n");
1295 			return;
1296 		}
1297 	}
1298 	test_done = 0;
1299 
1300 	fwd_config_setup();
1301 
1302 	if(!no_flush_rx)
1303 		flush_fwd_rx_queues();
1304 
1305 	pkt_fwd_config_display(&cur_fwd_config);
1306 	rxtx_config_display();
1307 
1308 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1309 		pt_id = fwd_ports_ids[i];
1310 		port = &ports[pt_id];
1311 		rte_eth_stats_get(pt_id, &port->stats);
1312 		port->tx_dropped = 0;
1313 
1314 		map_port_queue_stats_mapping_registers(pt_id, port);
1315 	}
1316 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1317 		fwd_streams[sm_id]->rx_packets = 0;
1318 		fwd_streams[sm_id]->tx_packets = 0;
1319 		fwd_streams[sm_id]->fwd_dropped = 0;
1320 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1321 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1322 
1323 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1324 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1325 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1326 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1327 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1328 #endif
1329 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1330 		fwd_streams[sm_id]->core_cycles = 0;
1331 #endif
1332 	}
1333 	if (with_tx_first) {
1334 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1335 		if (port_fwd_begin != NULL) {
1336 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1337 				(*port_fwd_begin)(fwd_ports_ids[i]);
1338 		}
1339 		while (with_tx_first--) {
1340 			launch_packet_forwarding(
1341 					run_one_txonly_burst_on_core);
1342 			rte_eal_mp_wait_lcore();
1343 		}
1344 		port_fwd_end = tx_only_engine.port_fwd_end;
1345 		if (port_fwd_end != NULL) {
1346 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1347 				(*port_fwd_end)(fwd_ports_ids[i]);
1348 		}
1349 	}
1350 	launch_packet_forwarding(start_pkt_forward_on_core);
1351 }
1352 
1353 void
1354 stop_packet_forwarding(void)
1355 {
1356 	struct rte_eth_stats stats;
1357 	struct rte_port *port;
1358 	port_fwd_end_t  port_fwd_end;
1359 	int i;
1360 	portid_t   pt_id;
1361 	streamid_t sm_id;
1362 	lcoreid_t  lc_id;
1363 	uint64_t total_recv;
1364 	uint64_t total_xmit;
1365 	uint64_t total_rx_dropped;
1366 	uint64_t total_tx_dropped;
1367 	uint64_t total_rx_nombuf;
1368 	uint64_t tx_dropped;
1369 	uint64_t rx_bad_ip_csum;
1370 	uint64_t rx_bad_l4_csum;
1371 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1372 	uint64_t fwd_cycles;
1373 #endif
1374 
1375 	static const char *acc_stats_border = "+++++++++++++++";
1376 
1377 	if (test_done) {
1378 		printf("Packet forwarding not started\n");
1379 		return;
1380 	}
1381 	printf("Telling cores to stop...");
1382 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1383 		fwd_lcores[lc_id]->stopped = 1;
1384 	printf("\nWaiting for lcores to finish...\n");
1385 	rte_eal_mp_wait_lcore();
1386 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1387 	if (port_fwd_end != NULL) {
1388 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1389 			pt_id = fwd_ports_ids[i];
1390 			(*port_fwd_end)(pt_id);
1391 		}
1392 	}
1393 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1394 	fwd_cycles = 0;
1395 #endif
1396 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1397 		if (cur_fwd_config.nb_fwd_streams >
1398 		    cur_fwd_config.nb_fwd_ports) {
1399 			fwd_stream_stats_display(sm_id);
1400 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1401 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1402 		} else {
1403 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1404 				fwd_streams[sm_id];
1405 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1406 				fwd_streams[sm_id];
1407 		}
1408 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1409 		tx_dropped = (uint64_t) (tx_dropped +
1410 					 fwd_streams[sm_id]->fwd_dropped);
1411 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1412 
1413 		rx_bad_ip_csum =
1414 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1415 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1416 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1417 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1418 							rx_bad_ip_csum;
1419 
1420 		rx_bad_l4_csum =
1421 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1422 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1423 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1424 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1425 							rx_bad_l4_csum;
1426 
1427 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1428 		fwd_cycles = (uint64_t) (fwd_cycles +
1429 					 fwd_streams[sm_id]->core_cycles);
1430 #endif
1431 	}
1432 	total_recv = 0;
1433 	total_xmit = 0;
1434 	total_rx_dropped = 0;
1435 	total_tx_dropped = 0;
1436 	total_rx_nombuf  = 0;
1437 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1438 		pt_id = fwd_ports_ids[i];
1439 
1440 		port = &ports[pt_id];
1441 		rte_eth_stats_get(pt_id, &stats);
1442 		stats.ipackets -= port->stats.ipackets;
1443 		port->stats.ipackets = 0;
1444 		stats.opackets -= port->stats.opackets;
1445 		port->stats.opackets = 0;
1446 		stats.ibytes   -= port->stats.ibytes;
1447 		port->stats.ibytes = 0;
1448 		stats.obytes   -= port->stats.obytes;
1449 		port->stats.obytes = 0;
1450 		stats.imissed  -= port->stats.imissed;
1451 		port->stats.imissed = 0;
1452 		stats.oerrors  -= port->stats.oerrors;
1453 		port->stats.oerrors = 0;
1454 		stats.rx_nombuf -= port->stats.rx_nombuf;
1455 		port->stats.rx_nombuf = 0;
1456 
1457 		total_recv += stats.ipackets;
1458 		total_xmit += stats.opackets;
1459 		total_rx_dropped += stats.imissed;
1460 		total_tx_dropped += port->tx_dropped;
1461 		total_rx_nombuf  += stats.rx_nombuf;
1462 
1463 		fwd_port_stats_display(pt_id, &stats);
1464 	}
1465 
1466 	printf("\n  %s Accumulated forward statistics for all ports"
1467 	       "%s\n",
1468 	       acc_stats_border, acc_stats_border);
1469 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1470 	       "%-"PRIu64"\n"
1471 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1472 	       "%-"PRIu64"\n",
1473 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1474 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1475 	if (total_rx_nombuf > 0)
1476 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1477 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1478 	       "%s\n",
1479 	       acc_stats_border, acc_stats_border);
1480 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1481 	if (total_recv > 0)
1482 		printf("\n  CPU cycles/packet=%u (total cycles="
1483 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1484 		       (unsigned int)(fwd_cycles / total_recv),
1485 		       fwd_cycles, total_recv);
1486 #endif
1487 	printf("\nDone.\n");
1488 	test_done = 1;
1489 }
1490 
1491 void
1492 dev_set_link_up(portid_t pid)
1493 {
1494 	if (rte_eth_dev_set_link_up(pid) < 0)
1495 		printf("\nSet link up fail.\n");
1496 }
1497 
1498 void
1499 dev_set_link_down(portid_t pid)
1500 {
1501 	if (rte_eth_dev_set_link_down(pid) < 0)
1502 		printf("\nSet link down fail.\n");
1503 }
1504 
1505 static int
1506 all_ports_started(void)
1507 {
1508 	portid_t pi;
1509 	struct rte_port *port;
1510 
1511 	RTE_ETH_FOREACH_DEV(pi) {
1512 		port = &ports[pi];
1513 		/* Check if there is a port which is not started */
1514 		if ((port->port_status != RTE_PORT_STARTED) &&
1515 			(port->slave_flag == 0))
1516 			return 0;
1517 	}
1518 
1519 	/* No port is not started */
1520 	return 1;
1521 }
1522 
1523 int
1524 port_is_stopped(portid_t port_id)
1525 {
1526 	struct rte_port *port = &ports[port_id];
1527 
1528 	if ((port->port_status != RTE_PORT_STOPPED) &&
1529 	    (port->slave_flag == 0))
1530 		return 0;
1531 	return 1;
1532 }
1533 
1534 int
1535 all_ports_stopped(void)
1536 {
1537 	portid_t pi;
1538 
1539 	RTE_ETH_FOREACH_DEV(pi) {
1540 		if (!port_is_stopped(pi))
1541 			return 0;
1542 	}
1543 
1544 	return 1;
1545 }
1546 
1547 int
1548 port_is_started(portid_t port_id)
1549 {
1550 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1551 		return 0;
1552 
1553 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1554 		return 0;
1555 
1556 	return 1;
1557 }
1558 
1559 static int
1560 port_is_closed(portid_t port_id)
1561 {
1562 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1563 		return 0;
1564 
1565 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1566 		return 0;
1567 
1568 	return 1;
1569 }
1570 
1571 int
1572 start_port(portid_t pid)
1573 {
1574 	int diag, need_check_link_status = -1;
1575 	portid_t pi;
1576 	queueid_t qi;
1577 	struct rte_port *port;
1578 	struct ether_addr mac_addr;
1579 	enum rte_eth_event_type event_type;
1580 
1581 	if (port_id_is_invalid(pid, ENABLED_WARN))
1582 		return 0;
1583 
1584 	if(dcb_config)
1585 		dcb_test = 1;
1586 	RTE_ETH_FOREACH_DEV(pi) {
1587 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1588 			continue;
1589 
1590 		need_check_link_status = 0;
1591 		port = &ports[pi];
1592 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1593 						 RTE_PORT_HANDLING) == 0) {
1594 			printf("Port %d is now not stopped\n", pi);
1595 			continue;
1596 		}
1597 
1598 		if (port->need_reconfig > 0) {
1599 			port->need_reconfig = 0;
1600 
1601 			if (flow_isolate_all) {
1602 				int ret = port_flow_isolate(pi, 1);
1603 				if (ret) {
1604 					printf("Failed to apply isolated"
1605 					       " mode on port %d\n", pi);
1606 					return -1;
1607 				}
1608 			}
1609 
1610 			printf("Configuring Port %d (socket %u)\n", pi,
1611 					port->socket_id);
1612 			/* configure port */
1613 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1614 						&(port->dev_conf));
1615 			if (diag != 0) {
1616 				if (rte_atomic16_cmpset(&(port->port_status),
1617 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1618 					printf("Port %d can not be set back "
1619 							"to stopped\n", pi);
1620 				printf("Fail to configure port %d\n", pi);
1621 				/* try to reconfigure port next time */
1622 				port->need_reconfig = 1;
1623 				return -1;
1624 			}
1625 		}
1626 		if (port->need_reconfig_queues > 0) {
1627 			port->need_reconfig_queues = 0;
1628 			/* setup tx queues */
1629 			for (qi = 0; qi < nb_txq; qi++) {
1630 				port->tx_conf[qi].txq_flags =
1631 					ETH_TXQ_FLAGS_IGNORE;
1632 				/* Apply Tx offloads configuration */
1633 				port->tx_conf[qi].offloads =
1634 					port->dev_conf.txmode.offloads;
1635 				if ((numa_support) &&
1636 					(txring_numa[pi] != NUMA_NO_CONFIG))
1637 					diag = rte_eth_tx_queue_setup(pi, qi,
1638 						port->nb_tx_desc[qi],
1639 						txring_numa[pi],
1640 						&(port->tx_conf[qi]));
1641 				else
1642 					diag = rte_eth_tx_queue_setup(pi, qi,
1643 						port->nb_tx_desc[qi],
1644 						port->socket_id,
1645 						&(port->tx_conf[qi]));
1646 
1647 				if (diag == 0)
1648 					continue;
1649 
1650 				/* Fail to setup tx 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 tx queues\n",
1657 				       pi);
1658 				/* try to reconfigure queues next time */
1659 				port->need_reconfig_queues = 1;
1660 				return -1;
1661 			}
1662 			for (qi = 0; qi < nb_rxq; qi++) {
1663 				/* Apply Rx offloads configuration */
1664 				port->rx_conf[qi].offloads =
1665 					port->dev_conf.rxmode.offloads;
1666 				/* setup rx queues */
1667 				if ((numa_support) &&
1668 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1669 					struct rte_mempool * mp =
1670 						mbuf_pool_find(rxring_numa[pi]);
1671 					if (mp == NULL) {
1672 						printf("Failed to setup RX queue:"
1673 							"No mempool allocation"
1674 							" on the socket %d\n",
1675 							rxring_numa[pi]);
1676 						return -1;
1677 					}
1678 
1679 					diag = rte_eth_rx_queue_setup(pi, qi,
1680 					     port->nb_rx_desc[pi],
1681 					     rxring_numa[pi],
1682 					     &(port->rx_conf[qi]),
1683 					     mp);
1684 				} else {
1685 					struct rte_mempool *mp =
1686 						mbuf_pool_find(port->socket_id);
1687 					if (mp == NULL) {
1688 						printf("Failed to setup RX queue:"
1689 							"No mempool allocation"
1690 							" on the socket %d\n",
1691 							port->socket_id);
1692 						return -1;
1693 					}
1694 					diag = rte_eth_rx_queue_setup(pi, qi,
1695 					     port->nb_rx_desc[pi],
1696 					     port->socket_id,
1697 					     &(port->rx_conf[qi]),
1698 					     mp);
1699 				}
1700 				if (diag == 0)
1701 					continue;
1702 
1703 				/* Fail to setup rx queue, return */
1704 				if (rte_atomic16_cmpset(&(port->port_status),
1705 							RTE_PORT_HANDLING,
1706 							RTE_PORT_STOPPED) == 0)
1707 					printf("Port %d can not be set back "
1708 							"to stopped\n", pi);
1709 				printf("Fail to configure port %d rx queues\n",
1710 				       pi);
1711 				/* try to reconfigure queues next time */
1712 				port->need_reconfig_queues = 1;
1713 				return -1;
1714 			}
1715 		}
1716 
1717 		/* start port */
1718 		if (rte_eth_dev_start(pi) < 0) {
1719 			printf("Fail to start port %d\n", pi);
1720 
1721 			/* Fail to setup rx queue, return */
1722 			if (rte_atomic16_cmpset(&(port->port_status),
1723 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1724 				printf("Port %d can not be set back to "
1725 							"stopped\n", pi);
1726 			continue;
1727 		}
1728 
1729 		if (rte_atomic16_cmpset(&(port->port_status),
1730 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1731 			printf("Port %d can not be set into started\n", pi);
1732 
1733 		rte_eth_macaddr_get(pi, &mac_addr);
1734 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1735 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1736 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1737 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1738 
1739 		/* at least one port started, need checking link status */
1740 		need_check_link_status = 1;
1741 	}
1742 
1743 	for (event_type = RTE_ETH_EVENT_UNKNOWN;
1744 	     event_type < RTE_ETH_EVENT_MAX;
1745 	     event_type++) {
1746 		diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
1747 						event_type,
1748 						eth_event_callback,
1749 						NULL);
1750 		if (diag) {
1751 			printf("Failed to setup even callback for event %d\n",
1752 				event_type);
1753 			return -1;
1754 		}
1755 	}
1756 
1757 	if (need_check_link_status == 1 && !no_link_check)
1758 		check_all_ports_link_status(RTE_PORT_ALL);
1759 	else if (need_check_link_status == 0)
1760 		printf("Please stop the ports first\n");
1761 
1762 	printf("Done\n");
1763 	return 0;
1764 }
1765 
1766 void
1767 stop_port(portid_t pid)
1768 {
1769 	portid_t pi;
1770 	struct rte_port *port;
1771 	int need_check_link_status = 0;
1772 
1773 	if (dcb_test) {
1774 		dcb_test = 0;
1775 		dcb_config = 0;
1776 	}
1777 
1778 	if (port_id_is_invalid(pid, ENABLED_WARN))
1779 		return;
1780 
1781 	printf("Stopping ports...\n");
1782 
1783 	RTE_ETH_FOREACH_DEV(pi) {
1784 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1785 			continue;
1786 
1787 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1788 			printf("Please remove port %d from forwarding configuration.\n", pi);
1789 			continue;
1790 		}
1791 
1792 		if (port_is_bonding_slave(pi)) {
1793 			printf("Please remove port %d from bonded device.\n", pi);
1794 			continue;
1795 		}
1796 
1797 		port = &ports[pi];
1798 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1799 						RTE_PORT_HANDLING) == 0)
1800 			continue;
1801 
1802 		rte_eth_dev_stop(pi);
1803 
1804 		if (rte_atomic16_cmpset(&(port->port_status),
1805 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1806 			printf("Port %d can not be set into stopped\n", pi);
1807 		need_check_link_status = 1;
1808 	}
1809 	if (need_check_link_status && !no_link_check)
1810 		check_all_ports_link_status(RTE_PORT_ALL);
1811 
1812 	printf("Done\n");
1813 }
1814 
1815 void
1816 close_port(portid_t pid)
1817 {
1818 	portid_t pi;
1819 	struct rte_port *port;
1820 
1821 	if (port_id_is_invalid(pid, ENABLED_WARN))
1822 		return;
1823 
1824 	printf("Closing ports...\n");
1825 
1826 	RTE_ETH_FOREACH_DEV(pi) {
1827 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1828 			continue;
1829 
1830 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1831 			printf("Please remove port %d from forwarding configuration.\n", pi);
1832 			continue;
1833 		}
1834 
1835 		if (port_is_bonding_slave(pi)) {
1836 			printf("Please remove port %d from bonded device.\n", pi);
1837 			continue;
1838 		}
1839 
1840 		port = &ports[pi];
1841 		if (rte_atomic16_cmpset(&(port->port_status),
1842 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1843 			printf("Port %d is already closed\n", pi);
1844 			continue;
1845 		}
1846 
1847 		if (rte_atomic16_cmpset(&(port->port_status),
1848 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1849 			printf("Port %d is now not stopped\n", pi);
1850 			continue;
1851 		}
1852 
1853 		if (port->flow_list)
1854 			port_flow_flush(pi);
1855 		rte_eth_dev_close(pi);
1856 
1857 		if (rte_atomic16_cmpset(&(port->port_status),
1858 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1859 			printf("Port %d cannot be set to closed\n", pi);
1860 	}
1861 
1862 	printf("Done\n");
1863 }
1864 
1865 void
1866 reset_port(portid_t pid)
1867 {
1868 	int diag;
1869 	portid_t pi;
1870 	struct rte_port *port;
1871 
1872 	if (port_id_is_invalid(pid, ENABLED_WARN))
1873 		return;
1874 
1875 	printf("Resetting ports...\n");
1876 
1877 	RTE_ETH_FOREACH_DEV(pi) {
1878 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1879 			continue;
1880 
1881 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1882 			printf("Please remove port %d from forwarding "
1883 			       "configuration.\n", pi);
1884 			continue;
1885 		}
1886 
1887 		if (port_is_bonding_slave(pi)) {
1888 			printf("Please remove port %d from bonded device.\n",
1889 			       pi);
1890 			continue;
1891 		}
1892 
1893 		diag = rte_eth_dev_reset(pi);
1894 		if (diag == 0) {
1895 			port = &ports[pi];
1896 			port->need_reconfig = 1;
1897 			port->need_reconfig_queues = 1;
1898 		} else {
1899 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
1900 		}
1901 	}
1902 
1903 	printf("Done\n");
1904 }
1905 
1906 static int
1907 eth_dev_event_callback_register(void)
1908 {
1909 	int ret;
1910 
1911 	/* register the device event callback */
1912 	ret = rte_dev_event_callback_register(NULL,
1913 		eth_dev_event_callback, NULL);
1914 	if (ret) {
1915 		printf("Failed to register device event callback\n");
1916 		return -1;
1917 	}
1918 
1919 	return 0;
1920 }
1921 
1922 
1923 static int
1924 eth_dev_event_callback_unregister(void)
1925 {
1926 	int ret;
1927 
1928 	/* unregister the device event callback */
1929 	ret = rte_dev_event_callback_unregister(NULL,
1930 		eth_dev_event_callback, NULL);
1931 	if (ret < 0) {
1932 		printf("Failed to unregister device event callback\n");
1933 		return -1;
1934 	}
1935 
1936 	return 0;
1937 }
1938 
1939 void
1940 attach_port(char *identifier)
1941 {
1942 	portid_t pi = 0;
1943 	unsigned int socket_id;
1944 
1945 	printf("Attaching a new port...\n");
1946 
1947 	if (identifier == NULL) {
1948 		printf("Invalid parameters are specified\n");
1949 		return;
1950 	}
1951 
1952 	if (rte_eth_dev_attach(identifier, &pi))
1953 		return;
1954 
1955 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1956 	/* if socket_id is invalid, set to 0 */
1957 	if (check_socket_id(socket_id) < 0)
1958 		socket_id = 0;
1959 	reconfig(pi, socket_id);
1960 	rte_eth_promiscuous_enable(pi);
1961 
1962 	nb_ports = rte_eth_dev_count_avail();
1963 
1964 	ports[pi].port_status = RTE_PORT_STOPPED;
1965 
1966 	update_fwd_ports(pi);
1967 
1968 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1969 	printf("Done\n");
1970 }
1971 
1972 void
1973 detach_port(portid_t port_id)
1974 {
1975 	char name[RTE_ETH_NAME_MAX_LEN];
1976 
1977 	printf("Detaching a port...\n");
1978 
1979 	if (!port_is_closed(port_id)) {
1980 		printf("Please close port first\n");
1981 		return;
1982 	}
1983 
1984 	if (ports[port_id].flow_list)
1985 		port_flow_flush(port_id);
1986 
1987 	if (rte_eth_dev_detach(port_id, name)) {
1988 		TESTPMD_LOG(ERR, "Failed to detach port %u\n", port_id);
1989 		return;
1990 	}
1991 
1992 	nb_ports = rte_eth_dev_count_avail();
1993 
1994 	update_fwd_ports(RTE_MAX_ETHPORTS);
1995 
1996 	printf("Port %u is detached. Now total ports is %d\n",
1997 			port_id, nb_ports);
1998 	printf("Done\n");
1999 	return;
2000 }
2001 
2002 void
2003 pmd_test_exit(void)
2004 {
2005 	portid_t pt_id;
2006 	int ret;
2007 
2008 	if (test_done == 0)
2009 		stop_packet_forwarding();
2010 
2011 	if (ports != NULL) {
2012 		no_link_check = 1;
2013 		RTE_ETH_FOREACH_DEV(pt_id) {
2014 			printf("\nShutting down port %d...\n", pt_id);
2015 			fflush(stdout);
2016 			stop_port(pt_id);
2017 			close_port(pt_id);
2018 		}
2019 	}
2020 
2021 	if (hot_plug) {
2022 		ret = rte_dev_event_monitor_stop();
2023 		if (ret)
2024 			RTE_LOG(ERR, EAL,
2025 				"fail to stop device event monitor.");
2026 
2027 		ret = eth_dev_event_callback_unregister();
2028 		if (ret)
2029 			RTE_LOG(ERR, EAL,
2030 				"fail to unregister all event callbacks.");
2031 	}
2032 
2033 	printf("\nBye...\n");
2034 }
2035 
2036 typedef void (*cmd_func_t)(void);
2037 struct pmd_test_command {
2038 	const char *cmd_name;
2039 	cmd_func_t cmd_func;
2040 };
2041 
2042 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
2043 
2044 /* Check the link status of all ports in up to 9s, and print them finally */
2045 static void
2046 check_all_ports_link_status(uint32_t port_mask)
2047 {
2048 #define CHECK_INTERVAL 100 /* 100ms */
2049 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
2050 	portid_t portid;
2051 	uint8_t count, all_ports_up, print_flag = 0;
2052 	struct rte_eth_link link;
2053 
2054 	printf("Checking link statuses...\n");
2055 	fflush(stdout);
2056 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
2057 		all_ports_up = 1;
2058 		RTE_ETH_FOREACH_DEV(portid) {
2059 			if ((port_mask & (1 << portid)) == 0)
2060 				continue;
2061 			memset(&link, 0, sizeof(link));
2062 			rte_eth_link_get_nowait(portid, &link);
2063 			/* print link status if flag set */
2064 			if (print_flag == 1) {
2065 				if (link.link_status)
2066 					printf(
2067 					"Port%d Link Up. speed %u Mbps- %s\n",
2068 					portid, link.link_speed,
2069 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
2070 					("full-duplex") : ("half-duplex\n"));
2071 				else
2072 					printf("Port %d Link Down\n", portid);
2073 				continue;
2074 			}
2075 			/* clear all_ports_up flag if any link down */
2076 			if (link.link_status == ETH_LINK_DOWN) {
2077 				all_ports_up = 0;
2078 				break;
2079 			}
2080 		}
2081 		/* after finally printing all link status, get out */
2082 		if (print_flag == 1)
2083 			break;
2084 
2085 		if (all_ports_up == 0) {
2086 			fflush(stdout);
2087 			rte_delay_ms(CHECK_INTERVAL);
2088 		}
2089 
2090 		/* set the print_flag if all ports up or timeout */
2091 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
2092 			print_flag = 1;
2093 		}
2094 
2095 		if (lsc_interrupt)
2096 			break;
2097 	}
2098 }
2099 
2100 static void
2101 rmv_event_callback(void *arg)
2102 {
2103 	int need_to_start = 0;
2104 	int org_no_link_check = no_link_check;
2105 	portid_t port_id = (intptr_t)arg;
2106 
2107 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
2108 
2109 	if (!test_done && port_is_forwarding(port_id)) {
2110 		need_to_start = 1;
2111 		stop_packet_forwarding();
2112 	}
2113 	no_link_check = 1;
2114 	stop_port(port_id);
2115 	no_link_check = org_no_link_check;
2116 	close_port(port_id);
2117 	detach_port(port_id);
2118 	if (need_to_start)
2119 		start_packet_forwarding(0);
2120 }
2121 
2122 /* This function is used by the interrupt thread */
2123 static int
2124 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
2125 		  void *ret_param)
2126 {
2127 	static const char * const event_desc[] = {
2128 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
2129 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
2130 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
2131 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
2132 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
2133 		[RTE_ETH_EVENT_IPSEC] = "IPsec",
2134 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
2135 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
2136 		[RTE_ETH_EVENT_NEW] = "device probed",
2137 		[RTE_ETH_EVENT_DESTROY] = "device released",
2138 		[RTE_ETH_EVENT_MAX] = NULL,
2139 	};
2140 
2141 	RTE_SET_USED(param);
2142 	RTE_SET_USED(ret_param);
2143 
2144 	if (type >= RTE_ETH_EVENT_MAX) {
2145 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
2146 			port_id, __func__, type);
2147 		fflush(stderr);
2148 	} else if (event_print_mask & (UINT32_C(1) << type)) {
2149 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
2150 			event_desc[type]);
2151 		fflush(stdout);
2152 	}
2153 
2154 	if (port_id_is_invalid(port_id, DISABLED_WARN))
2155 		return 0;
2156 
2157 	switch (type) {
2158 	case RTE_ETH_EVENT_INTR_RMV:
2159 		if (rte_eal_alarm_set(100000,
2160 				rmv_event_callback, (void *)(intptr_t)port_id))
2161 			fprintf(stderr, "Could not set up deferred device removal\n");
2162 		break;
2163 	default:
2164 		break;
2165 	}
2166 	return 0;
2167 }
2168 
2169 /* This function is used by the interrupt thread */
2170 static void
2171 eth_dev_event_callback(char *device_name, enum rte_dev_event_type type,
2172 			     __rte_unused void *arg)
2173 {
2174 	if (type >= RTE_DEV_EVENT_MAX) {
2175 		fprintf(stderr, "%s called upon invalid event %d\n",
2176 			__func__, type);
2177 		fflush(stderr);
2178 	}
2179 
2180 	switch (type) {
2181 	case RTE_DEV_EVENT_REMOVE:
2182 		RTE_LOG(ERR, EAL, "The device: %s has been removed!\n",
2183 			device_name);
2184 		/* TODO: After finish failure handle, begin to stop
2185 		 * packet forward, stop port, close port, detach port.
2186 		 */
2187 		break;
2188 	case RTE_DEV_EVENT_ADD:
2189 		RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
2190 			device_name);
2191 		/* TODO: After finish kernel driver binding,
2192 		 * begin to attach port.
2193 		 */
2194 		break;
2195 	default:
2196 		break;
2197 	}
2198 }
2199 
2200 static int
2201 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2202 {
2203 	uint16_t i;
2204 	int diag;
2205 	uint8_t mapping_found = 0;
2206 
2207 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
2208 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
2209 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
2210 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
2211 					tx_queue_stats_mappings[i].queue_id,
2212 					tx_queue_stats_mappings[i].stats_counter_id);
2213 			if (diag != 0)
2214 				return diag;
2215 			mapping_found = 1;
2216 		}
2217 	}
2218 	if (mapping_found)
2219 		port->tx_queue_stats_mapping_enabled = 1;
2220 	return 0;
2221 }
2222 
2223 static int
2224 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2225 {
2226 	uint16_t i;
2227 	int diag;
2228 	uint8_t mapping_found = 0;
2229 
2230 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
2231 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
2232 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
2233 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
2234 					rx_queue_stats_mappings[i].queue_id,
2235 					rx_queue_stats_mappings[i].stats_counter_id);
2236 			if (diag != 0)
2237 				return diag;
2238 			mapping_found = 1;
2239 		}
2240 	}
2241 	if (mapping_found)
2242 		port->rx_queue_stats_mapping_enabled = 1;
2243 	return 0;
2244 }
2245 
2246 static void
2247 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2248 {
2249 	int diag = 0;
2250 
2251 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2252 	if (diag != 0) {
2253 		if (diag == -ENOTSUP) {
2254 			port->tx_queue_stats_mapping_enabled = 0;
2255 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2256 		}
2257 		else
2258 			rte_exit(EXIT_FAILURE,
2259 					"set_tx_queue_stats_mapping_registers "
2260 					"failed for port id=%d diag=%d\n",
2261 					pi, diag);
2262 	}
2263 
2264 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2265 	if (diag != 0) {
2266 		if (diag == -ENOTSUP) {
2267 			port->rx_queue_stats_mapping_enabled = 0;
2268 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2269 		}
2270 		else
2271 			rte_exit(EXIT_FAILURE,
2272 					"set_rx_queue_stats_mapping_registers "
2273 					"failed for port id=%d diag=%d\n",
2274 					pi, diag);
2275 	}
2276 }
2277 
2278 static void
2279 rxtx_port_config(struct rte_port *port)
2280 {
2281 	uint16_t qid;
2282 
2283 	for (qid = 0; qid < nb_rxq; qid++) {
2284 		port->rx_conf[qid] = port->dev_info.default_rxconf;
2285 
2286 		/* Check if any Rx parameters have been passed */
2287 		if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2288 			port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
2289 
2290 		if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2291 			port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
2292 
2293 		if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2294 			port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
2295 
2296 		if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2297 			port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
2298 
2299 		if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2300 			port->rx_conf[qid].rx_drop_en = rx_drop_en;
2301 
2302 		port->nb_rx_desc[qid] = nb_rxd;
2303 	}
2304 
2305 	for (qid = 0; qid < nb_txq; qid++) {
2306 		port->tx_conf[qid] = port->dev_info.default_txconf;
2307 
2308 		/* Check if any Tx parameters have been passed */
2309 		if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2310 			port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
2311 
2312 		if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2313 			port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
2314 
2315 		if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2316 			port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
2317 
2318 		if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2319 			port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
2320 
2321 		if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2322 			port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
2323 
2324 		port->nb_tx_desc[qid] = nb_txd;
2325 	}
2326 }
2327 
2328 void
2329 init_port_config(void)
2330 {
2331 	portid_t pid;
2332 	struct rte_port *port;
2333 	struct rte_eth_dev_info dev_info;
2334 
2335 	RTE_ETH_FOREACH_DEV(pid) {
2336 		port = &ports[pid];
2337 		port->dev_conf.fdir_conf = fdir_conf;
2338 		if (nb_rxq > 1) {
2339 			rte_eth_dev_info_get(pid, &dev_info);
2340 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2341 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
2342 				rss_hf & dev_info.flow_type_rss_offloads;
2343 		} else {
2344 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2345 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2346 		}
2347 
2348 		if (port->dcb_flag == 0) {
2349 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2350 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2351 			else
2352 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2353 		}
2354 
2355 		rxtx_port_config(port);
2356 
2357 		rte_eth_macaddr_get(pid, &port->eth_addr);
2358 
2359 		map_port_queue_stats_mapping_registers(pid, port);
2360 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2361 		rte_pmd_ixgbe_bypass_init(pid);
2362 #endif
2363 
2364 		if (lsc_interrupt &&
2365 		    (rte_eth_devices[pid].data->dev_flags &
2366 		     RTE_ETH_DEV_INTR_LSC))
2367 			port->dev_conf.intr_conf.lsc = 1;
2368 		if (rmv_interrupt &&
2369 		    (rte_eth_devices[pid].data->dev_flags &
2370 		     RTE_ETH_DEV_INTR_RMV))
2371 			port->dev_conf.intr_conf.rmv = 1;
2372 
2373 #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
2374 		/* Detect softnic port */
2375 		if (!strcmp(port->dev_info.driver_name, "net_softnic")) {
2376 			port->softnic_enable = 1;
2377 			memset(&port->softport, 0, sizeof(struct softnic_port));
2378 
2379 			if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm"))
2380 				port->softport.tm_flag = 1;
2381 		}
2382 #endif
2383 	}
2384 }
2385 
2386 void set_port_slave_flag(portid_t slave_pid)
2387 {
2388 	struct rte_port *port;
2389 
2390 	port = &ports[slave_pid];
2391 	port->slave_flag = 1;
2392 }
2393 
2394 void clear_port_slave_flag(portid_t slave_pid)
2395 {
2396 	struct rte_port *port;
2397 
2398 	port = &ports[slave_pid];
2399 	port->slave_flag = 0;
2400 }
2401 
2402 uint8_t port_is_bonding_slave(portid_t slave_pid)
2403 {
2404 	struct rte_port *port;
2405 
2406 	port = &ports[slave_pid];
2407 	if ((rte_eth_devices[slave_pid].data->dev_flags &
2408 	    RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
2409 		return 1;
2410 	return 0;
2411 }
2412 
2413 const uint16_t vlan_tags[] = {
2414 		0,  1,  2,  3,  4,  5,  6,  7,
2415 		8,  9, 10, 11,  12, 13, 14, 15,
2416 		16, 17, 18, 19, 20, 21, 22, 23,
2417 		24, 25, 26, 27, 28, 29, 30, 31
2418 };
2419 
2420 static  int
2421 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
2422 		 enum dcb_mode_enable dcb_mode,
2423 		 enum rte_eth_nb_tcs num_tcs,
2424 		 uint8_t pfc_en)
2425 {
2426 	uint8_t i;
2427 
2428 	/*
2429 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2430 	 * given above, and the number of traffic classes available for use.
2431 	 */
2432 	if (dcb_mode == DCB_VT_ENABLED) {
2433 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2434 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
2435 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2436 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2437 
2438 		/* VMDQ+DCB RX and TX configurations */
2439 		vmdq_rx_conf->enable_default_pool = 0;
2440 		vmdq_rx_conf->default_pool = 0;
2441 		vmdq_rx_conf->nb_queue_pools =
2442 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2443 		vmdq_tx_conf->nb_queue_pools =
2444 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2445 
2446 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2447 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2448 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2449 			vmdq_rx_conf->pool_map[i].pools =
2450 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2451 		}
2452 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2453 			vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2454 			vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2455 		}
2456 
2457 		/* set DCB mode of RX and TX of multiple queues */
2458 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2459 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2460 	} else {
2461 		struct rte_eth_dcb_rx_conf *rx_conf =
2462 				&eth_conf->rx_adv_conf.dcb_rx_conf;
2463 		struct rte_eth_dcb_tx_conf *tx_conf =
2464 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2465 
2466 		rx_conf->nb_tcs = num_tcs;
2467 		tx_conf->nb_tcs = num_tcs;
2468 
2469 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2470 			rx_conf->dcb_tc[i] = i % num_tcs;
2471 			tx_conf->dcb_tc[i] = i % num_tcs;
2472 		}
2473 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2474 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
2475 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2476 	}
2477 
2478 	if (pfc_en)
2479 		eth_conf->dcb_capability_en =
2480 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2481 	else
2482 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2483 
2484 	return 0;
2485 }
2486 
2487 int
2488 init_port_dcb_config(portid_t pid,
2489 		     enum dcb_mode_enable dcb_mode,
2490 		     enum rte_eth_nb_tcs num_tcs,
2491 		     uint8_t pfc_en)
2492 {
2493 	struct rte_eth_conf port_conf;
2494 	struct rte_port *rte_port;
2495 	int retval;
2496 	uint16_t i;
2497 
2498 	rte_port = &ports[pid];
2499 
2500 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2501 	/* Enter DCB configuration status */
2502 	dcb_config = 1;
2503 
2504 	port_conf.rxmode = rte_port->dev_conf.rxmode;
2505 	port_conf.txmode = rte_port->dev_conf.txmode;
2506 
2507 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
2508 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2509 	if (retval < 0)
2510 		return retval;
2511 	port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2512 
2513 	/**
2514 	 * Write the configuration into the device.
2515 	 * Set the numbers of RX & TX queues to 0, so
2516 	 * the RX & TX queues will not be setup.
2517 	 */
2518 	rte_eth_dev_configure(pid, 0, 0, &port_conf);
2519 
2520 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
2521 
2522 	/* If dev_info.vmdq_pool_base is greater than 0,
2523 	 * the queue id of vmdq pools is started after pf queues.
2524 	 */
2525 	if (dcb_mode == DCB_VT_ENABLED &&
2526 	    rte_port->dev_info.vmdq_pool_base > 0) {
2527 		printf("VMDQ_DCB multi-queue mode is nonsensical"
2528 			" for port %d.", pid);
2529 		return -1;
2530 	}
2531 
2532 	/* Assume the ports in testpmd have the same dcb capability
2533 	 * and has the same number of rxq and txq in dcb mode
2534 	 */
2535 	if (dcb_mode == DCB_VT_ENABLED) {
2536 		if (rte_port->dev_info.max_vfs > 0) {
2537 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2538 			nb_txq = rte_port->dev_info.nb_tx_queues;
2539 		} else {
2540 			nb_rxq = rte_port->dev_info.max_rx_queues;
2541 			nb_txq = rte_port->dev_info.max_tx_queues;
2542 		}
2543 	} else {
2544 		/*if vt is disabled, use all pf queues */
2545 		if (rte_port->dev_info.vmdq_pool_base == 0) {
2546 			nb_rxq = rte_port->dev_info.max_rx_queues;
2547 			nb_txq = rte_port->dev_info.max_tx_queues;
2548 		} else {
2549 			nb_rxq = (queueid_t)num_tcs;
2550 			nb_txq = (queueid_t)num_tcs;
2551 
2552 		}
2553 	}
2554 	rx_free_thresh = 64;
2555 
2556 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2557 
2558 	rxtx_port_config(rte_port);
2559 	/* VLAN filter */
2560 	rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2561 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2562 		rx_vft_set(pid, vlan_tags[i], 1);
2563 
2564 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2565 	map_port_queue_stats_mapping_registers(pid, rte_port);
2566 
2567 	rte_port->dcb_flag = 1;
2568 
2569 	return 0;
2570 }
2571 
2572 static void
2573 init_port(void)
2574 {
2575 	/* Configuration of Ethernet ports. */
2576 	ports = rte_zmalloc("testpmd: ports",
2577 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2578 			    RTE_CACHE_LINE_SIZE);
2579 	if (ports == NULL) {
2580 		rte_exit(EXIT_FAILURE,
2581 				"rte_zmalloc(%d struct rte_port) failed\n",
2582 				RTE_MAX_ETHPORTS);
2583 	}
2584 }
2585 
2586 static void
2587 force_quit(void)
2588 {
2589 	pmd_test_exit();
2590 	prompt_exit();
2591 }
2592 
2593 static void
2594 print_stats(void)
2595 {
2596 	uint8_t i;
2597 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2598 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2599 
2600 	/* Clear screen and move to top left */
2601 	printf("%s%s", clr, top_left);
2602 
2603 	printf("\nPort statistics ====================================");
2604 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2605 		nic_stats_display(fwd_ports_ids[i]);
2606 }
2607 
2608 static void
2609 signal_handler(int signum)
2610 {
2611 	if (signum == SIGINT || signum == SIGTERM) {
2612 		printf("\nSignal %d received, preparing to exit...\n",
2613 				signum);
2614 #ifdef RTE_LIBRTE_PDUMP
2615 		/* uninitialize packet capture framework */
2616 		rte_pdump_uninit();
2617 #endif
2618 #ifdef RTE_LIBRTE_LATENCY_STATS
2619 		rte_latencystats_uninit();
2620 #endif
2621 		force_quit();
2622 		/* Set flag to indicate the force termination. */
2623 		f_quit = 1;
2624 		/* exit with the expected status */
2625 		signal(signum, SIG_DFL);
2626 		kill(getpid(), signum);
2627 	}
2628 }
2629 
2630 int
2631 main(int argc, char** argv)
2632 {
2633 	int diag;
2634 	portid_t port_id;
2635 	int ret;
2636 
2637 	signal(SIGINT, signal_handler);
2638 	signal(SIGTERM, signal_handler);
2639 
2640 	diag = rte_eal_init(argc, argv);
2641 	if (diag < 0)
2642 		rte_panic("Cannot init EAL\n");
2643 
2644 	testpmd_logtype = rte_log_register("testpmd");
2645 	if (testpmd_logtype < 0)
2646 		rte_panic("Cannot register log type");
2647 	rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
2648 
2649 #ifdef RTE_LIBRTE_PDUMP
2650 	/* initialize packet capture framework */
2651 	rte_pdump_init(NULL);
2652 #endif
2653 
2654 	nb_ports = (portid_t) rte_eth_dev_count_avail();
2655 	if (nb_ports == 0)
2656 		TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
2657 
2658 	/* allocate port structures, and init them */
2659 	init_port();
2660 
2661 	set_def_fwd_config();
2662 	if (nb_lcores == 0)
2663 		rte_panic("Empty set of forwarding logical cores - check the "
2664 			  "core mask supplied in the command parameters\n");
2665 
2666 	/* Bitrate/latency stats disabled by default */
2667 #ifdef RTE_LIBRTE_BITRATE
2668 	bitrate_enabled = 0;
2669 #endif
2670 #ifdef RTE_LIBRTE_LATENCY_STATS
2671 	latencystats_enabled = 0;
2672 #endif
2673 
2674 	/* on FreeBSD, mlockall() is disabled by default */
2675 #ifdef RTE_EXEC_ENV_BSDAPP
2676 	do_mlockall = 0;
2677 #else
2678 	do_mlockall = 1;
2679 #endif
2680 
2681 	argc -= diag;
2682 	argv += diag;
2683 	if (argc > 1)
2684 		launch_args_parse(argc, argv);
2685 
2686 	if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
2687 		TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
2688 			strerror(errno));
2689 	}
2690 
2691 	if (tx_first && interactive)
2692 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
2693 				"interactive mode.\n");
2694 
2695 	if (tx_first && lsc_interrupt) {
2696 		printf("Warning: lsc_interrupt needs to be off when "
2697 				" using tx_first. Disabling.\n");
2698 		lsc_interrupt = 0;
2699 	}
2700 
2701 	if (!nb_rxq && !nb_txq)
2702 		printf("Warning: Either rx or tx queues should be non-zero\n");
2703 
2704 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2705 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2706 		       "but nb_txq=%d will prevent to fully test it.\n",
2707 		       nb_rxq, nb_txq);
2708 
2709 	init_config();
2710 
2711 	if (hot_plug) {
2712 		/* enable hot plug monitoring */
2713 		ret = rte_dev_event_monitor_start();
2714 		if (ret) {
2715 			rte_errno = EINVAL;
2716 			return -1;
2717 		}
2718 		eth_dev_event_callback_register();
2719 
2720 	}
2721 
2722 	if (start_port(RTE_PORT_ALL) != 0)
2723 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2724 
2725 	/* set all ports to promiscuous mode by default */
2726 	RTE_ETH_FOREACH_DEV(port_id)
2727 		rte_eth_promiscuous_enable(port_id);
2728 
2729 	/* Init metrics library */
2730 	rte_metrics_init(rte_socket_id());
2731 
2732 #ifdef RTE_LIBRTE_LATENCY_STATS
2733 	if (latencystats_enabled != 0) {
2734 		int ret = rte_latencystats_init(1, NULL);
2735 		if (ret)
2736 			printf("Warning: latencystats init()"
2737 				" returned error %d\n",	ret);
2738 		printf("Latencystats running on lcore %d\n",
2739 			latencystats_lcore_id);
2740 	}
2741 #endif
2742 
2743 	/* Setup bitrate stats */
2744 #ifdef RTE_LIBRTE_BITRATE
2745 	if (bitrate_enabled != 0) {
2746 		bitrate_data = rte_stats_bitrate_create();
2747 		if (bitrate_data == NULL)
2748 			rte_exit(EXIT_FAILURE,
2749 				"Could not allocate bitrate data.\n");
2750 		rte_stats_bitrate_reg(bitrate_data);
2751 	}
2752 #endif
2753 
2754 #ifdef RTE_LIBRTE_CMDLINE
2755 	if (strlen(cmdline_filename) != 0)
2756 		cmdline_read_from_file(cmdline_filename);
2757 
2758 	if (interactive == 1) {
2759 		if (auto_start) {
2760 			printf("Start automatic packet forwarding\n");
2761 			start_packet_forwarding(0);
2762 		}
2763 		prompt();
2764 		pmd_test_exit();
2765 	} else
2766 #endif
2767 	{
2768 		char c;
2769 		int rc;
2770 
2771 		f_quit = 0;
2772 
2773 		printf("No commandline core given, start packet forwarding\n");
2774 		start_packet_forwarding(tx_first);
2775 		if (stats_period != 0) {
2776 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2777 			uint64_t timer_period;
2778 
2779 			/* Convert to number of cycles */
2780 			timer_period = stats_period * rte_get_timer_hz();
2781 
2782 			while (f_quit == 0) {
2783 				cur_time = rte_get_timer_cycles();
2784 				diff_time += cur_time - prev_time;
2785 
2786 				if (diff_time >= timer_period) {
2787 					print_stats();
2788 					/* Reset the timer */
2789 					diff_time = 0;
2790 				}
2791 				/* Sleep to avoid unnecessary checks */
2792 				prev_time = cur_time;
2793 				sleep(1);
2794 			}
2795 		}
2796 
2797 		printf("Press enter to exit\n");
2798 		rc = read(0, &c, 1);
2799 		pmd_test_exit();
2800 		if (rc < 0)
2801 			return 1;
2802 	}
2803 
2804 	return 0;
2805 }
2806