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