xref: /dpdk/app/test-pmd/testpmd.c (revision f8e5baa2662d2cc89af25e8b077e4a6ae073754a)
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_malloc_heap.h>
31 #include <rte_memory.h>
32 #include <rte_memcpy.h>
33 #include <rte_launch.h>
34 #include <rte_eal.h>
35 #include <rte_alarm.h>
36 #include <rte_per_lcore.h>
37 #include <rte_lcore.h>
38 #include <rte_atomic.h>
39 #include <rte_branch_prediction.h>
40 #include <rte_mempool.h>
41 #include <rte_malloc.h>
42 #include <rte_mbuf.h>
43 #include <rte_mbuf_pool_ops.h>
44 #include <rte_interrupts.h>
45 #include <rte_pci.h>
46 #include <rte_ether.h>
47 #include <rte_ethdev.h>
48 #include <rte_dev.h>
49 #include <rte_string_fns.h>
50 #ifdef RTE_LIBRTE_IXGBE_PMD
51 #include <rte_pmd_ixgbe.h>
52 #endif
53 #ifdef RTE_LIBRTE_PDUMP
54 #include <rte_pdump.h>
55 #endif
56 #include <rte_flow.h>
57 #include <rte_metrics.h>
58 #ifdef RTE_LIBRTE_BITRATE
59 #include <rte_bitrate.h>
60 #endif
61 #ifdef RTE_LIBRTE_LATENCY_STATS
62 #include <rte_latencystats.h>
63 #endif
64 
65 #include "testpmd.h"
66 
67 #ifndef MAP_HUGETLB
68 /* FreeBSD may not have MAP_HUGETLB (in fact, it probably doesn't) */
69 #define HUGE_FLAG (0x40000)
70 #else
71 #define HUGE_FLAG MAP_HUGETLB
72 #endif
73 
74 #ifndef MAP_HUGE_SHIFT
75 /* older kernels (or FreeBSD) will not have this define */
76 #define HUGE_SHIFT (26)
77 #else
78 #define HUGE_SHIFT MAP_HUGE_SHIFT
79 #endif
80 
81 #define EXTMEM_HEAP_NAME "extmem"
82 
83 uint16_t verbose_level = 0; /**< Silent by default. */
84 int testpmd_logtype; /**< Log type for testpmd logs */
85 
86 /* use master core for command line ? */
87 uint8_t interactive = 0;
88 uint8_t auto_start = 0;
89 uint8_t tx_first;
90 char cmdline_filename[PATH_MAX] = {0};
91 
92 /*
93  * NUMA support configuration.
94  * When set, the NUMA support attempts to dispatch the allocation of the
95  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
96  * probed ports among the CPU sockets 0 and 1.
97  * Otherwise, all memory is allocated from CPU socket 0.
98  */
99 uint8_t numa_support = 1; /**< numa enabled by default */
100 
101 /*
102  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
103  * not configured.
104  */
105 uint8_t socket_num = UMA_NO_CONFIG;
106 
107 /*
108  * Select mempool allocation type:
109  * - native: use regular DPDK memory
110  * - anon: use regular DPDK memory to create mempool, but populate using
111  *         anonymous memory (may not be IOVA-contiguous)
112  * - xmem: use externally allocated hugepage memory
113  */
114 uint8_t mp_alloc_type = MP_ALLOC_NATIVE;
115 
116 /*
117  * Store specified sockets on which memory pool to be used by ports
118  * is allocated.
119  */
120 uint8_t port_numa[RTE_MAX_ETHPORTS];
121 
122 /*
123  * Store specified sockets on which RX ring to be used by ports
124  * is allocated.
125  */
126 uint8_t rxring_numa[RTE_MAX_ETHPORTS];
127 
128 /*
129  * Store specified sockets on which TX ring to be used by ports
130  * is allocated.
131  */
132 uint8_t txring_numa[RTE_MAX_ETHPORTS];
133 
134 /*
135  * Record the Ethernet address of peer target ports to which packets are
136  * forwarded.
137  * Must be instantiated with the ethernet addresses of peer traffic generator
138  * ports.
139  */
140 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
141 portid_t nb_peer_eth_addrs = 0;
142 
143 /*
144  * Probed Target Environment.
145  */
146 struct rte_port *ports;	       /**< For all probed ethernet ports. */
147 portid_t nb_ports;             /**< Number of probed ethernet ports. */
148 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
149 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
150 
151 portid_t ports_ids[RTE_MAX_ETHPORTS]; /**< Store all port ids. */
152 
153 /*
154  * Test Forwarding Configuration.
155  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
156  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
157  */
158 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
159 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
160 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
161 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
162 
163 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
164 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
165 
166 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
167 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
168 
169 /*
170  * Forwarding engines.
171  */
172 struct fwd_engine * fwd_engines[] = {
173 	&io_fwd_engine,
174 	&mac_fwd_engine,
175 	&mac_swap_engine,
176 	&flow_gen_engine,
177 	&rx_only_engine,
178 	&tx_only_engine,
179 	&csum_fwd_engine,
180 	&icmp_echo_engine,
181 	&noisy_vnf_engine,
182 #if defined RTE_LIBRTE_PMD_SOFTNIC
183 	&softnic_fwd_engine,
184 #endif
185 #ifdef RTE_LIBRTE_IEEE1588
186 	&ieee1588_fwd_engine,
187 #endif
188 	NULL,
189 };
190 
191 struct fwd_config cur_fwd_config;
192 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
193 uint32_t retry_enabled;
194 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
195 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
196 
197 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
198 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
199                                       * specified on command-line. */
200 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
201 
202 /*
203  * In container, it cannot terminate the process which running with 'stats-period'
204  * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
205  */
206 uint8_t f_quit;
207 
208 /*
209  * Configuration of packet segments used by the "txonly" processing engine.
210  */
211 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
212 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
213 	TXONLY_DEF_PACKET_LEN,
214 };
215 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
216 
217 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
218 /**< Split policy for packets to TX. */
219 
220 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
221 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
222 
223 /* current configuration is in DCB or not,0 means it is not in DCB mode */
224 uint8_t dcb_config = 0;
225 
226 /* Whether the dcb is in testing status */
227 uint8_t dcb_test = 0;
228 
229 /*
230  * Configurable number of RX/TX queues.
231  */
232 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
233 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
234 
235 /*
236  * Configurable number of RX/TX ring descriptors.
237  * Defaults are supplied by drivers via ethdev.
238  */
239 #define RTE_TEST_RX_DESC_DEFAULT 0
240 #define RTE_TEST_TX_DESC_DEFAULT 0
241 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
242 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
243 
244 #define RTE_PMD_PARAM_UNSET -1
245 /*
246  * Configurable values of RX and TX ring threshold registers.
247  */
248 
249 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
250 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
251 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
252 
253 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
254 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
255 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
256 
257 /*
258  * Configurable value of RX free threshold.
259  */
260 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
261 
262 /*
263  * Configurable value of RX drop enable.
264  */
265 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
266 
267 /*
268  * Configurable value of TX free threshold.
269  */
270 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
271 
272 /*
273  * Configurable value of TX RS bit threshold.
274  */
275 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
276 
277 /*
278  * Configurable value of buffered packets before sending.
279  */
280 uint16_t noisy_tx_sw_bufsz;
281 
282 /*
283  * Configurable value of packet buffer timeout.
284  */
285 uint16_t noisy_tx_sw_buf_flush_time;
286 
287 /*
288  * Configurable value for size of VNF internal memory area
289  * used for simulating noisy neighbour behaviour
290  */
291 uint64_t noisy_lkup_mem_sz;
292 
293 /*
294  * Configurable value of number of random writes done in
295  * VNF simulation memory area.
296  */
297 uint64_t noisy_lkup_num_writes;
298 
299 /*
300  * Configurable value of number of random reads done in
301  * VNF simulation memory area.
302  */
303 uint64_t noisy_lkup_num_reads;
304 
305 /*
306  * Configurable value of number of random reads/writes done in
307  * VNF simulation memory area.
308  */
309 uint64_t noisy_lkup_num_reads_writes;
310 
311 /*
312  * Receive Side Scaling (RSS) configuration.
313  */
314 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
315 
316 /*
317  * Port topology configuration
318  */
319 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
320 
321 /*
322  * Avoids to flush all the RX streams before starts forwarding.
323  */
324 uint8_t no_flush_rx = 0; /* flush by default */
325 
326 /*
327  * Flow API isolated mode.
328  */
329 uint8_t flow_isolate_all;
330 
331 /*
332  * Avoids to check link status when starting/stopping a port.
333  */
334 uint8_t no_link_check = 0; /* check by default */
335 
336 /*
337  * Enable link status change notification
338  */
339 uint8_t lsc_interrupt = 1; /* enabled by default */
340 
341 /*
342  * Enable device removal notification.
343  */
344 uint8_t rmv_interrupt = 1; /* enabled by default */
345 
346 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
347 
348 /*
349  * Display or mask ether events
350  * Default to all events except VF_MBOX
351  */
352 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
353 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
354 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
355 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
356 			    (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) |
357 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
358 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
359 /*
360  * Decide if all memory are locked for performance.
361  */
362 int do_mlockall = 0;
363 
364 /*
365  * NIC bypass mode configuration options.
366  */
367 
368 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
369 /* The NIC bypass watchdog timeout. */
370 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
371 #endif
372 
373 
374 #ifdef RTE_LIBRTE_LATENCY_STATS
375 
376 /*
377  * Set when latency stats is enabled in the commandline
378  */
379 uint8_t latencystats_enabled;
380 
381 /*
382  * Lcore ID to serive latency statistics.
383  */
384 lcoreid_t latencystats_lcore_id = -1;
385 
386 #endif
387 
388 /*
389  * Ethernet device configuration.
390  */
391 struct rte_eth_rxmode rx_mode = {
392 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
393 };
394 
395 struct rte_eth_txmode tx_mode = {
396 	.offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
397 };
398 
399 struct rte_fdir_conf fdir_conf = {
400 	.mode = RTE_FDIR_MODE_NONE,
401 	.pballoc = RTE_FDIR_PBALLOC_64K,
402 	.status = RTE_FDIR_REPORT_STATUS,
403 	.mask = {
404 		.vlan_tci_mask = 0xFFEF,
405 		.ipv4_mask     = {
406 			.src_ip = 0xFFFFFFFF,
407 			.dst_ip = 0xFFFFFFFF,
408 		},
409 		.ipv6_mask     = {
410 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
411 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
412 		},
413 		.src_port_mask = 0xFFFF,
414 		.dst_port_mask = 0xFFFF,
415 		.mac_addr_byte_mask = 0xFF,
416 		.tunnel_type_mask = 1,
417 		.tunnel_id_mask = 0xFFFFFFFF,
418 	},
419 	.drop_queue = 127,
420 };
421 
422 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
423 
424 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
425 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
426 
427 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
428 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
429 
430 uint16_t nb_tx_queue_stats_mappings = 0;
431 uint16_t nb_rx_queue_stats_mappings = 0;
432 
433 /*
434  * Display zero values by default for xstats
435  */
436 uint8_t xstats_hide_zero;
437 
438 unsigned int num_sockets = 0;
439 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
440 
441 #ifdef RTE_LIBRTE_BITRATE
442 /* Bitrate statistics */
443 struct rte_stats_bitrates *bitrate_data;
444 lcoreid_t bitrate_lcore_id;
445 uint8_t bitrate_enabled;
446 #endif
447 
448 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
449 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
450 
451 struct vxlan_encap_conf vxlan_encap_conf = {
452 	.select_ipv4 = 1,
453 	.select_vlan = 0,
454 	.vni = "\x00\x00\x00",
455 	.udp_src = 0,
456 	.udp_dst = RTE_BE16(4789),
457 	.ipv4_src = IPv4(127, 0, 0, 1),
458 	.ipv4_dst = IPv4(255, 255, 255, 255),
459 	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
460 		"\x00\x00\x00\x00\x00\x00\x00\x01",
461 	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
462 		"\x00\x00\x00\x00\x00\x00\x11\x11",
463 	.vlan_tci = 0,
464 	.eth_src = "\x00\x00\x00\x00\x00\x00",
465 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
466 };
467 
468 struct nvgre_encap_conf nvgre_encap_conf = {
469 	.select_ipv4 = 1,
470 	.select_vlan = 0,
471 	.tni = "\x00\x00\x00",
472 	.ipv4_src = IPv4(127, 0, 0, 1),
473 	.ipv4_dst = IPv4(255, 255, 255, 255),
474 	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
475 		"\x00\x00\x00\x00\x00\x00\x00\x01",
476 	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
477 		"\x00\x00\x00\x00\x00\x00\x11\x11",
478 	.vlan_tci = 0,
479 	.eth_src = "\x00\x00\x00\x00\x00\x00",
480 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
481 };
482 
483 /* Forward function declarations */
484 static void setup_attached_port(portid_t pi);
485 static void map_port_queue_stats_mapping_registers(portid_t pi,
486 						   struct rte_port *port);
487 static void check_all_ports_link_status(uint32_t port_mask);
488 static int eth_event_callback(portid_t port_id,
489 			      enum rte_eth_event_type type,
490 			      void *param, void *ret_param);
491 static void eth_dev_event_callback(const char *device_name,
492 				enum rte_dev_event_type type,
493 				void *param);
494 
495 /*
496  * Check if all the ports are started.
497  * If yes, return positive value. If not, return zero.
498  */
499 static int all_ports_started(void);
500 
501 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
502 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
503 
504 /*
505  * Helper function to check if socket is already discovered.
506  * If yes, return positive value. If not, return zero.
507  */
508 int
509 new_socket_id(unsigned int socket_id)
510 {
511 	unsigned int i;
512 
513 	for (i = 0; i < num_sockets; i++) {
514 		if (socket_ids[i] == socket_id)
515 			return 0;
516 	}
517 	return 1;
518 }
519 
520 /*
521  * Setup default configuration.
522  */
523 static void
524 set_default_fwd_lcores_config(void)
525 {
526 	unsigned int i;
527 	unsigned int nb_lc;
528 	unsigned int sock_num;
529 
530 	nb_lc = 0;
531 	for (i = 0; i < RTE_MAX_LCORE; i++) {
532 		if (!rte_lcore_is_enabled(i))
533 			continue;
534 		sock_num = rte_lcore_to_socket_id(i);
535 		if (new_socket_id(sock_num)) {
536 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
537 				rte_exit(EXIT_FAILURE,
538 					 "Total sockets greater than %u\n",
539 					 RTE_MAX_NUMA_NODES);
540 			}
541 			socket_ids[num_sockets++] = sock_num;
542 		}
543 		if (i == rte_get_master_lcore())
544 			continue;
545 		fwd_lcores_cpuids[nb_lc++] = i;
546 	}
547 	nb_lcores = (lcoreid_t) nb_lc;
548 	nb_cfg_lcores = nb_lcores;
549 	nb_fwd_lcores = 1;
550 }
551 
552 static void
553 set_def_peer_eth_addrs(void)
554 {
555 	portid_t i;
556 
557 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
558 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
559 		peer_eth_addrs[i].addr_bytes[5] = i;
560 	}
561 }
562 
563 static void
564 set_default_fwd_ports_config(void)
565 {
566 	portid_t pt_id;
567 	int i = 0;
568 
569 	RTE_ETH_FOREACH_DEV(pt_id) {
570 		fwd_ports_ids[i++] = pt_id;
571 
572 		/* Update sockets info according to the attached device */
573 		int socket_id = rte_eth_dev_socket_id(pt_id);
574 		if (socket_id >= 0 && new_socket_id(socket_id)) {
575 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
576 				rte_exit(EXIT_FAILURE,
577 					 "Total sockets greater than %u\n",
578 					 RTE_MAX_NUMA_NODES);
579 			}
580 			socket_ids[num_sockets++] = socket_id;
581 		}
582 	}
583 
584 	nb_cfg_ports = nb_ports;
585 	nb_fwd_ports = nb_ports;
586 }
587 
588 void
589 set_def_fwd_config(void)
590 {
591 	set_default_fwd_lcores_config();
592 	set_def_peer_eth_addrs();
593 	set_default_fwd_ports_config();
594 }
595 
596 /* extremely pessimistic estimation of memory required to create a mempool */
597 static int
598 calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out)
599 {
600 	unsigned int n_pages, mbuf_per_pg, leftover;
601 	uint64_t total_mem, mbuf_mem, obj_sz;
602 
603 	/* there is no good way to predict how much space the mempool will
604 	 * occupy because it will allocate chunks on the fly, and some of those
605 	 * will come from default DPDK memory while some will come from our
606 	 * external memory, so just assume 128MB will be enough for everyone.
607 	 */
608 	uint64_t hdr_mem = 128 << 20;
609 
610 	/* account for possible non-contiguousness */
611 	obj_sz = rte_mempool_calc_obj_size(mbuf_sz, 0, NULL);
612 	if (obj_sz > pgsz) {
613 		TESTPMD_LOG(ERR, "Object size is bigger than page size\n");
614 		return -1;
615 	}
616 
617 	mbuf_per_pg = pgsz / obj_sz;
618 	leftover = (nb_mbufs % mbuf_per_pg) > 0;
619 	n_pages = (nb_mbufs / mbuf_per_pg) + leftover;
620 
621 	mbuf_mem = n_pages * pgsz;
622 
623 	total_mem = RTE_ALIGN(hdr_mem + mbuf_mem, pgsz);
624 
625 	if (total_mem > SIZE_MAX) {
626 		TESTPMD_LOG(ERR, "Memory size too big\n");
627 		return -1;
628 	}
629 	*out = (size_t)total_mem;
630 
631 	return 0;
632 }
633 
634 static inline uint32_t
635 bsf64(uint64_t v)
636 {
637 	return (uint32_t)__builtin_ctzll(v);
638 }
639 
640 static inline uint32_t
641 log2_u64(uint64_t v)
642 {
643 	if (v == 0)
644 		return 0;
645 	v = rte_align64pow2(v);
646 	return bsf64(v);
647 }
648 
649 static int
650 pagesz_flags(uint64_t page_sz)
651 {
652 	/* as per mmap() manpage, all page sizes are log2 of page size
653 	 * shifted by MAP_HUGE_SHIFT
654 	 */
655 	int log2 = log2_u64(page_sz);
656 
657 	return (log2 << HUGE_SHIFT);
658 }
659 
660 static void *
661 alloc_mem(size_t memsz, size_t pgsz, bool huge)
662 {
663 	void *addr;
664 	int flags;
665 
666 	/* allocate anonymous hugepages */
667 	flags = MAP_ANONYMOUS | MAP_PRIVATE;
668 	if (huge)
669 		flags |= HUGE_FLAG | pagesz_flags(pgsz);
670 
671 	addr = mmap(NULL, memsz, PROT_READ | PROT_WRITE, flags, -1, 0);
672 	if (addr == MAP_FAILED)
673 		return NULL;
674 
675 	return addr;
676 }
677 
678 struct extmem_param {
679 	void *addr;
680 	size_t len;
681 	size_t pgsz;
682 	rte_iova_t *iova_table;
683 	unsigned int iova_table_len;
684 };
685 
686 static int
687 create_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, struct extmem_param *param,
688 		bool huge)
689 {
690 	uint64_t pgsizes[] = {RTE_PGSIZE_2M, RTE_PGSIZE_1G, /* x86_64, ARM */
691 			RTE_PGSIZE_16M, RTE_PGSIZE_16G};    /* POWER */
692 	unsigned int cur_page, n_pages, pgsz_idx;
693 	size_t mem_sz, cur_pgsz;
694 	rte_iova_t *iovas = NULL;
695 	void *addr;
696 	int ret;
697 
698 	for (pgsz_idx = 0; pgsz_idx < RTE_DIM(pgsizes); pgsz_idx++) {
699 		/* skip anything that is too big */
700 		if (pgsizes[pgsz_idx] > SIZE_MAX)
701 			continue;
702 
703 		cur_pgsz = pgsizes[pgsz_idx];
704 
705 		/* if we were told not to allocate hugepages, override */
706 		if (!huge)
707 			cur_pgsz = sysconf(_SC_PAGESIZE);
708 
709 		ret = calc_mem_size(nb_mbufs, mbuf_sz, cur_pgsz, &mem_sz);
710 		if (ret < 0) {
711 			TESTPMD_LOG(ERR, "Cannot calculate memory size\n");
712 			return -1;
713 		}
714 
715 		/* allocate our memory */
716 		addr = alloc_mem(mem_sz, cur_pgsz, huge);
717 
718 		/* if we couldn't allocate memory with a specified page size,
719 		 * that doesn't mean we can't do it with other page sizes, so
720 		 * try another one.
721 		 */
722 		if (addr == NULL)
723 			continue;
724 
725 		/* store IOVA addresses for every page in this memory area */
726 		n_pages = mem_sz / cur_pgsz;
727 
728 		iovas = malloc(sizeof(*iovas) * n_pages);
729 
730 		if (iovas == NULL) {
731 			TESTPMD_LOG(ERR, "Cannot allocate memory for iova addresses\n");
732 			goto fail;
733 		}
734 		/* lock memory if it's not huge pages */
735 		if (!huge)
736 			mlock(addr, mem_sz);
737 
738 		/* populate IOVA addresses */
739 		for (cur_page = 0; cur_page < n_pages; cur_page++) {
740 			rte_iova_t iova;
741 			size_t offset;
742 			void *cur;
743 
744 			offset = cur_pgsz * cur_page;
745 			cur = RTE_PTR_ADD(addr, offset);
746 
747 			/* touch the page before getting its IOVA */
748 			*(volatile char *)cur = 0;
749 
750 			iova = rte_mem_virt2iova(cur);
751 
752 			iovas[cur_page] = iova;
753 		}
754 
755 		break;
756 	}
757 	/* if we couldn't allocate anything */
758 	if (iovas == NULL)
759 		return -1;
760 
761 	param->addr = addr;
762 	param->len = mem_sz;
763 	param->pgsz = cur_pgsz;
764 	param->iova_table = iovas;
765 	param->iova_table_len = n_pages;
766 
767 	return 0;
768 fail:
769 	if (iovas)
770 		free(iovas);
771 	if (addr)
772 		munmap(addr, mem_sz);
773 
774 	return -1;
775 }
776 
777 static int
778 setup_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, bool huge)
779 {
780 	struct extmem_param param;
781 	int socket_id, ret;
782 
783 	memset(&param, 0, sizeof(param));
784 
785 	/* check if our heap exists */
786 	socket_id = rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
787 	if (socket_id < 0) {
788 		/* create our heap */
789 		ret = rte_malloc_heap_create(EXTMEM_HEAP_NAME);
790 		if (ret < 0) {
791 			TESTPMD_LOG(ERR, "Cannot create heap\n");
792 			return -1;
793 		}
794 	}
795 
796 	ret = create_extmem(nb_mbufs, mbuf_sz, &param, huge);
797 	if (ret < 0) {
798 		TESTPMD_LOG(ERR, "Cannot create memory area\n");
799 		return -1;
800 	}
801 
802 	/* we now have a valid memory area, so add it to heap */
803 	ret = rte_malloc_heap_memory_add(EXTMEM_HEAP_NAME,
804 			param.addr, param.len, param.iova_table,
805 			param.iova_table_len, param.pgsz);
806 
807 	/* when using VFIO, memory is automatically mapped for DMA by EAL */
808 
809 	/* not needed any more */
810 	free(param.iova_table);
811 
812 	if (ret < 0) {
813 		TESTPMD_LOG(ERR, "Cannot add memory to heap\n");
814 		munmap(param.addr, param.len);
815 		return -1;
816 	}
817 
818 	/* success */
819 
820 	TESTPMD_LOG(DEBUG, "Allocated %zuMB of external memory\n",
821 			param.len >> 20);
822 
823 	return 0;
824 }
825 
826 /*
827  * Configuration initialisation done once at init time.
828  */
829 static void
830 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
831 		 unsigned int socket_id)
832 {
833 	char pool_name[RTE_MEMPOOL_NAMESIZE];
834 	struct rte_mempool *rte_mp = NULL;
835 	uint32_t mb_size;
836 
837 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
838 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
839 
840 	TESTPMD_LOG(INFO,
841 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
842 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
843 
844 	switch (mp_alloc_type) {
845 	case MP_ALLOC_NATIVE:
846 		{
847 			/* wrapper to rte_mempool_create() */
848 			TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
849 					rte_mbuf_best_mempool_ops());
850 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
851 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
852 			break;
853 		}
854 	case MP_ALLOC_ANON:
855 		{
856 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
857 				mb_size, (unsigned int) mb_mempool_cache,
858 				sizeof(struct rte_pktmbuf_pool_private),
859 				socket_id, 0);
860 			if (rte_mp == NULL)
861 				goto err;
862 
863 			if (rte_mempool_populate_anon(rte_mp) == 0) {
864 				rte_mempool_free(rte_mp);
865 				rte_mp = NULL;
866 				goto err;
867 			}
868 			rte_pktmbuf_pool_init(rte_mp, NULL);
869 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
870 			break;
871 		}
872 	case MP_ALLOC_XMEM:
873 	case MP_ALLOC_XMEM_HUGE:
874 		{
875 			int heap_socket;
876 			bool huge = mp_alloc_type == MP_ALLOC_XMEM_HUGE;
877 
878 			if (setup_extmem(nb_mbuf, mbuf_seg_size, huge) < 0)
879 				rte_exit(EXIT_FAILURE, "Could not create external memory\n");
880 
881 			heap_socket =
882 				rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
883 			if (heap_socket < 0)
884 				rte_exit(EXIT_FAILURE, "Could not get external memory socket ID\n");
885 
886 			TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
887 					rte_mbuf_best_mempool_ops());
888 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
889 					mb_mempool_cache, 0, mbuf_seg_size,
890 					heap_socket);
891 			break;
892 		}
893 	default:
894 		{
895 			rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n");
896 		}
897 	}
898 
899 err:
900 	if (rte_mp == NULL) {
901 		rte_exit(EXIT_FAILURE,
902 			"Creation of mbuf pool for socket %u failed: %s\n",
903 			socket_id, rte_strerror(rte_errno));
904 	} else if (verbose_level > 0) {
905 		rte_mempool_dump(stdout, rte_mp);
906 	}
907 }
908 
909 /*
910  * Check given socket id is valid or not with NUMA mode,
911  * if valid, return 0, else return -1
912  */
913 static int
914 check_socket_id(const unsigned int socket_id)
915 {
916 	static int warning_once = 0;
917 
918 	if (new_socket_id(socket_id)) {
919 		if (!warning_once && numa_support)
920 			printf("Warning: NUMA should be configured manually by"
921 			       " using --port-numa-config and"
922 			       " --ring-numa-config parameters along with"
923 			       " --numa.\n");
924 		warning_once = 1;
925 		return -1;
926 	}
927 	return 0;
928 }
929 
930 /*
931  * Get the allowed maximum number of RX queues.
932  * *pid return the port id which has minimal value of
933  * max_rx_queues in all ports.
934  */
935 queueid_t
936 get_allowed_max_nb_rxq(portid_t *pid)
937 {
938 	queueid_t allowed_max_rxq = MAX_QUEUE_ID;
939 	portid_t pi;
940 	struct rte_eth_dev_info dev_info;
941 
942 	RTE_ETH_FOREACH_DEV(pi) {
943 		rte_eth_dev_info_get(pi, &dev_info);
944 		if (dev_info.max_rx_queues < allowed_max_rxq) {
945 			allowed_max_rxq = dev_info.max_rx_queues;
946 			*pid = pi;
947 		}
948 	}
949 	return allowed_max_rxq;
950 }
951 
952 /*
953  * Check input rxq is valid or not.
954  * If input rxq is not greater than any of maximum number
955  * of RX queues of all ports, it is valid.
956  * if valid, return 0, else return -1
957  */
958 int
959 check_nb_rxq(queueid_t rxq)
960 {
961 	queueid_t allowed_max_rxq;
962 	portid_t pid = 0;
963 
964 	allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
965 	if (rxq > allowed_max_rxq) {
966 		printf("Fail: input rxq (%u) can't be greater "
967 		       "than max_rx_queues (%u) of port %u\n",
968 		       rxq,
969 		       allowed_max_rxq,
970 		       pid);
971 		return -1;
972 	}
973 	return 0;
974 }
975 
976 /*
977  * Get the allowed maximum number of TX queues.
978  * *pid return the port id which has minimal value of
979  * max_tx_queues in all ports.
980  */
981 queueid_t
982 get_allowed_max_nb_txq(portid_t *pid)
983 {
984 	queueid_t allowed_max_txq = MAX_QUEUE_ID;
985 	portid_t pi;
986 	struct rte_eth_dev_info dev_info;
987 
988 	RTE_ETH_FOREACH_DEV(pi) {
989 		rte_eth_dev_info_get(pi, &dev_info);
990 		if (dev_info.max_tx_queues < allowed_max_txq) {
991 			allowed_max_txq = dev_info.max_tx_queues;
992 			*pid = pi;
993 		}
994 	}
995 	return allowed_max_txq;
996 }
997 
998 /*
999  * Check input txq is valid or not.
1000  * If input txq is not greater than any of maximum number
1001  * of TX queues of all ports, it is valid.
1002  * if valid, return 0, else return -1
1003  */
1004 int
1005 check_nb_txq(queueid_t txq)
1006 {
1007 	queueid_t allowed_max_txq;
1008 	portid_t pid = 0;
1009 
1010 	allowed_max_txq = get_allowed_max_nb_txq(&pid);
1011 	if (txq > allowed_max_txq) {
1012 		printf("Fail: input txq (%u) can't be greater "
1013 		       "than max_tx_queues (%u) of port %u\n",
1014 		       txq,
1015 		       allowed_max_txq,
1016 		       pid);
1017 		return -1;
1018 	}
1019 	return 0;
1020 }
1021 
1022 static void
1023 init_config(void)
1024 {
1025 	portid_t pid;
1026 	struct rte_port *port;
1027 	struct rte_mempool *mbp;
1028 	unsigned int nb_mbuf_per_pool;
1029 	lcoreid_t  lc_id;
1030 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
1031 	struct rte_gro_param gro_param;
1032 	uint32_t gso_types;
1033 	int k;
1034 
1035 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
1036 
1037 	/* Configuration of logical cores. */
1038 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
1039 				sizeof(struct fwd_lcore *) * nb_lcores,
1040 				RTE_CACHE_LINE_SIZE);
1041 	if (fwd_lcores == NULL) {
1042 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
1043 							"failed\n", nb_lcores);
1044 	}
1045 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1046 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
1047 					       sizeof(struct fwd_lcore),
1048 					       RTE_CACHE_LINE_SIZE);
1049 		if (fwd_lcores[lc_id] == NULL) {
1050 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
1051 								"failed\n");
1052 		}
1053 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
1054 	}
1055 
1056 	RTE_ETH_FOREACH_DEV(pid) {
1057 		port = &ports[pid];
1058 		/* Apply default TxRx configuration for all ports */
1059 		port->dev_conf.txmode = tx_mode;
1060 		port->dev_conf.rxmode = rx_mode;
1061 		rte_eth_dev_info_get(pid, &port->dev_info);
1062 
1063 		if (!(port->dev_info.tx_offload_capa &
1064 		      DEV_TX_OFFLOAD_MBUF_FAST_FREE))
1065 			port->dev_conf.txmode.offloads &=
1066 				~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
1067 		if (!(port->dev_info.tx_offload_capa &
1068 			DEV_TX_OFFLOAD_MATCH_METADATA))
1069 			port->dev_conf.txmode.offloads &=
1070 				~DEV_TX_OFFLOAD_MATCH_METADATA;
1071 		if (numa_support) {
1072 			if (port_numa[pid] != NUMA_NO_CONFIG)
1073 				port_per_socket[port_numa[pid]]++;
1074 			else {
1075 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
1076 
1077 				/*
1078 				 * if socket_id is invalid,
1079 				 * set to the first available socket.
1080 				 */
1081 				if (check_socket_id(socket_id) < 0)
1082 					socket_id = socket_ids[0];
1083 				port_per_socket[socket_id]++;
1084 			}
1085 		}
1086 
1087 		/* Apply Rx offloads configuration */
1088 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
1089 			port->rx_conf[k].offloads =
1090 				port->dev_conf.rxmode.offloads;
1091 		/* Apply Tx offloads configuration */
1092 		for (k = 0; k < port->dev_info.max_tx_queues; k++)
1093 			port->tx_conf[k].offloads =
1094 				port->dev_conf.txmode.offloads;
1095 
1096 		/* set flag to initialize port/queue */
1097 		port->need_reconfig = 1;
1098 		port->need_reconfig_queues = 1;
1099 		port->tx_metadata = 0;
1100 	}
1101 
1102 	/*
1103 	 * Create pools of mbuf.
1104 	 * If NUMA support is disabled, create a single pool of mbuf in
1105 	 * socket 0 memory by default.
1106 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
1107 	 *
1108 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
1109 	 * nb_txd can be configured at run time.
1110 	 */
1111 	if (param_total_num_mbufs)
1112 		nb_mbuf_per_pool = param_total_num_mbufs;
1113 	else {
1114 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
1115 			(nb_lcores * mb_mempool_cache) +
1116 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
1117 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
1118 	}
1119 
1120 	if (numa_support) {
1121 		uint8_t i;
1122 
1123 		for (i = 0; i < num_sockets; i++)
1124 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
1125 					 socket_ids[i]);
1126 	} else {
1127 		if (socket_num == UMA_NO_CONFIG)
1128 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
1129 		else
1130 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
1131 						 socket_num);
1132 	}
1133 
1134 	init_port_config();
1135 
1136 	gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
1137 		DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO;
1138 	/*
1139 	 * Records which Mbuf pool to use by each logical core, if needed.
1140 	 */
1141 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1142 		mbp = mbuf_pool_find(
1143 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
1144 
1145 		if (mbp == NULL)
1146 			mbp = mbuf_pool_find(0);
1147 		fwd_lcores[lc_id]->mbp = mbp;
1148 		/* initialize GSO context */
1149 		fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
1150 		fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
1151 		fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
1152 		fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
1153 			ETHER_CRC_LEN;
1154 		fwd_lcores[lc_id]->gso_ctx.flag = 0;
1155 	}
1156 
1157 	/* Configuration of packet forwarding streams. */
1158 	if (init_fwd_streams() < 0)
1159 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
1160 
1161 	fwd_config_setup();
1162 
1163 	/* create a gro context for each lcore */
1164 	gro_param.gro_types = RTE_GRO_TCP_IPV4;
1165 	gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
1166 	gro_param.max_item_per_flow = MAX_PKT_BURST;
1167 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1168 		gro_param.socket_id = rte_lcore_to_socket_id(
1169 				fwd_lcores_cpuids[lc_id]);
1170 		fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
1171 		if (fwd_lcores[lc_id]->gro_ctx == NULL) {
1172 			rte_exit(EXIT_FAILURE,
1173 					"rte_gro_ctx_create() failed\n");
1174 		}
1175 	}
1176 
1177 #if defined RTE_LIBRTE_PMD_SOFTNIC
1178 	if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) {
1179 		RTE_ETH_FOREACH_DEV(pid) {
1180 			port = &ports[pid];
1181 			const char *driver = port->dev_info.driver_name;
1182 
1183 			if (strcmp(driver, "net_softnic") == 0)
1184 				port->softport.fwd_lcore_arg = fwd_lcores;
1185 		}
1186 	}
1187 #endif
1188 
1189 }
1190 
1191 
1192 void
1193 reconfig(portid_t new_port_id, unsigned socket_id)
1194 {
1195 	struct rte_port *port;
1196 
1197 	/* Reconfiguration of Ethernet ports. */
1198 	port = &ports[new_port_id];
1199 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
1200 
1201 	/* set flag to initialize port/queue */
1202 	port->need_reconfig = 1;
1203 	port->need_reconfig_queues = 1;
1204 	port->socket_id = socket_id;
1205 
1206 	init_port_config();
1207 }
1208 
1209 
1210 int
1211 init_fwd_streams(void)
1212 {
1213 	portid_t pid;
1214 	struct rte_port *port;
1215 	streamid_t sm_id, nb_fwd_streams_new;
1216 	queueid_t q;
1217 
1218 	/* set socket id according to numa or not */
1219 	RTE_ETH_FOREACH_DEV(pid) {
1220 		port = &ports[pid];
1221 		if (nb_rxq > port->dev_info.max_rx_queues) {
1222 			printf("Fail: nb_rxq(%d) is greater than "
1223 				"max_rx_queues(%d)\n", nb_rxq,
1224 				port->dev_info.max_rx_queues);
1225 			return -1;
1226 		}
1227 		if (nb_txq > port->dev_info.max_tx_queues) {
1228 			printf("Fail: nb_txq(%d) is greater than "
1229 				"max_tx_queues(%d)\n", nb_txq,
1230 				port->dev_info.max_tx_queues);
1231 			return -1;
1232 		}
1233 		if (numa_support) {
1234 			if (port_numa[pid] != NUMA_NO_CONFIG)
1235 				port->socket_id = port_numa[pid];
1236 			else {
1237 				port->socket_id = rte_eth_dev_socket_id(pid);
1238 
1239 				/*
1240 				 * if socket_id is invalid,
1241 				 * set to the first available socket.
1242 				 */
1243 				if (check_socket_id(port->socket_id) < 0)
1244 					port->socket_id = socket_ids[0];
1245 			}
1246 		}
1247 		else {
1248 			if (socket_num == UMA_NO_CONFIG)
1249 				port->socket_id = 0;
1250 			else
1251 				port->socket_id = socket_num;
1252 		}
1253 	}
1254 
1255 	q = RTE_MAX(nb_rxq, nb_txq);
1256 	if (q == 0) {
1257 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
1258 		return -1;
1259 	}
1260 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
1261 	if (nb_fwd_streams_new == nb_fwd_streams)
1262 		return 0;
1263 	/* clear the old */
1264 	if (fwd_streams != NULL) {
1265 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1266 			if (fwd_streams[sm_id] == NULL)
1267 				continue;
1268 			rte_free(fwd_streams[sm_id]);
1269 			fwd_streams[sm_id] = NULL;
1270 		}
1271 		rte_free(fwd_streams);
1272 		fwd_streams = NULL;
1273 	}
1274 
1275 	/* init new */
1276 	nb_fwd_streams = nb_fwd_streams_new;
1277 	if (nb_fwd_streams) {
1278 		fwd_streams = rte_zmalloc("testpmd: fwd_streams",
1279 			sizeof(struct fwd_stream *) * nb_fwd_streams,
1280 			RTE_CACHE_LINE_SIZE);
1281 		if (fwd_streams == NULL)
1282 			rte_exit(EXIT_FAILURE, "rte_zmalloc(%d"
1283 				 " (struct fwd_stream *)) failed\n",
1284 				 nb_fwd_streams);
1285 
1286 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1287 			fwd_streams[sm_id] = rte_zmalloc("testpmd:"
1288 				" struct fwd_stream", sizeof(struct fwd_stream),
1289 				RTE_CACHE_LINE_SIZE);
1290 			if (fwd_streams[sm_id] == NULL)
1291 				rte_exit(EXIT_FAILURE, "rte_zmalloc"
1292 					 "(struct fwd_stream) failed\n");
1293 		}
1294 	}
1295 
1296 	return 0;
1297 }
1298 
1299 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1300 static void
1301 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
1302 {
1303 	unsigned int total_burst;
1304 	unsigned int nb_burst;
1305 	unsigned int burst_stats[3];
1306 	uint16_t pktnb_stats[3];
1307 	uint16_t nb_pkt;
1308 	int burst_percent[3];
1309 
1310 	/*
1311 	 * First compute the total number of packet bursts and the
1312 	 * two highest numbers of bursts of the same number of packets.
1313 	 */
1314 	total_burst = 0;
1315 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
1316 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
1317 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
1318 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
1319 		if (nb_burst == 0)
1320 			continue;
1321 		total_burst += nb_burst;
1322 		if (nb_burst > burst_stats[0]) {
1323 			burst_stats[1] = burst_stats[0];
1324 			pktnb_stats[1] = pktnb_stats[0];
1325 			burst_stats[0] = nb_burst;
1326 			pktnb_stats[0] = nb_pkt;
1327 		} else if (nb_burst > burst_stats[1]) {
1328 			burst_stats[1] = nb_burst;
1329 			pktnb_stats[1] = nb_pkt;
1330 		}
1331 	}
1332 	if (total_burst == 0)
1333 		return;
1334 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
1335 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
1336 	       burst_percent[0], (int) pktnb_stats[0]);
1337 	if (burst_stats[0] == total_burst) {
1338 		printf("]\n");
1339 		return;
1340 	}
1341 	if (burst_stats[0] + burst_stats[1] == total_burst) {
1342 		printf(" + %d%% of %d pkts]\n",
1343 		       100 - burst_percent[0], pktnb_stats[1]);
1344 		return;
1345 	}
1346 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
1347 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
1348 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
1349 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
1350 		return;
1351 	}
1352 	printf(" + %d%% of %d pkts + %d%% of others]\n",
1353 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
1354 }
1355 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
1356 
1357 static void
1358 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
1359 {
1360 	struct rte_port *port;
1361 	uint8_t i;
1362 
1363 	static const char *fwd_stats_border = "----------------------";
1364 
1365 	port = &ports[port_id];
1366 	printf("\n  %s Forward statistics for port %-2d %s\n",
1367 	       fwd_stats_border, port_id, fwd_stats_border);
1368 
1369 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
1370 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1371 		       "%-"PRIu64"\n",
1372 		       stats->ipackets, stats->imissed,
1373 		       (uint64_t) (stats->ipackets + stats->imissed));
1374 
1375 		if (cur_fwd_eng == &csum_fwd_engine)
1376 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64"Bad-outer-l4csum: %-14"PRIu64"\n",
1377 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum,
1378 			       port->rx_bad_outer_l4_csum);
1379 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
1380 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
1381 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
1382 		}
1383 
1384 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1385 		       "%-"PRIu64"\n",
1386 		       stats->opackets, port->tx_dropped,
1387 		       (uint64_t) (stats->opackets + port->tx_dropped));
1388 	}
1389 	else {
1390 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
1391 		       "%14"PRIu64"\n",
1392 		       stats->ipackets, stats->imissed,
1393 		       (uint64_t) (stats->ipackets + stats->imissed));
1394 
1395 		if (cur_fwd_eng == &csum_fwd_engine)
1396 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"    Bad-outer-l4csum: %-14"PRIu64"\n",
1397 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum,
1398 			       port->rx_bad_outer_l4_csum);
1399 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
1400 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
1401 			printf("  RX-nombufs:             %14"PRIu64"\n",
1402 			       stats->rx_nombuf);
1403 		}
1404 
1405 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
1406 		       "%14"PRIu64"\n",
1407 		       stats->opackets, port->tx_dropped,
1408 		       (uint64_t) (stats->opackets + port->tx_dropped));
1409 	}
1410 
1411 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1412 	if (port->rx_stream)
1413 		pkt_burst_stats_display("RX",
1414 			&port->rx_stream->rx_burst_stats);
1415 	if (port->tx_stream)
1416 		pkt_burst_stats_display("TX",
1417 			&port->tx_stream->tx_burst_stats);
1418 #endif
1419 
1420 	if (port->rx_queue_stats_mapping_enabled) {
1421 		printf("\n");
1422 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1423 			printf("  Stats reg %2d RX-packets:%14"PRIu64
1424 			       "     RX-errors:%14"PRIu64
1425 			       "    RX-bytes:%14"PRIu64"\n",
1426 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
1427 		}
1428 		printf("\n");
1429 	}
1430 	if (port->tx_queue_stats_mapping_enabled) {
1431 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1432 			printf("  Stats reg %2d TX-packets:%14"PRIu64
1433 			       "                                 TX-bytes:%14"PRIu64"\n",
1434 			       i, stats->q_opackets[i], stats->q_obytes[i]);
1435 		}
1436 	}
1437 
1438 	printf("  %s--------------------------------%s\n",
1439 	       fwd_stats_border, fwd_stats_border);
1440 }
1441 
1442 static void
1443 fwd_stream_stats_display(streamid_t stream_id)
1444 {
1445 	struct fwd_stream *fs;
1446 	static const char *fwd_top_stats_border = "-------";
1447 
1448 	fs = fwd_streams[stream_id];
1449 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1450 	    (fs->fwd_dropped == 0))
1451 		return;
1452 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1453 	       "TX Port=%2d/Queue=%2d %s\n",
1454 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1455 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1456 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
1457 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1458 
1459 	/* if checksum mode */
1460 	if (cur_fwd_eng == &csum_fwd_engine) {
1461 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
1462 			"%-14u Rx- bad outer L4 checksum: %-14u\n",
1463 			fs->rx_bad_ip_csum, fs->rx_bad_l4_csum,
1464 			fs->rx_bad_outer_l4_csum);
1465 	}
1466 
1467 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1468 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1469 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1470 #endif
1471 }
1472 
1473 static void
1474 flush_fwd_rx_queues(void)
1475 {
1476 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1477 	portid_t  rxp;
1478 	portid_t port_id;
1479 	queueid_t rxq;
1480 	uint16_t  nb_rx;
1481 	uint16_t  i;
1482 	uint8_t   j;
1483 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1484 	uint64_t timer_period;
1485 
1486 	/* convert to number of cycles */
1487 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
1488 
1489 	for (j = 0; j < 2; j++) {
1490 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
1491 			for (rxq = 0; rxq < nb_rxq; rxq++) {
1492 				port_id = fwd_ports_ids[rxp];
1493 				/**
1494 				* testpmd can stuck in the below do while loop
1495 				* if rte_eth_rx_burst() always returns nonzero
1496 				* packets. So timer is added to exit this loop
1497 				* after 1sec timer expiry.
1498 				*/
1499 				prev_tsc = rte_rdtsc();
1500 				do {
1501 					nb_rx = rte_eth_rx_burst(port_id, rxq,
1502 						pkts_burst, MAX_PKT_BURST);
1503 					for (i = 0; i < nb_rx; i++)
1504 						rte_pktmbuf_free(pkts_burst[i]);
1505 
1506 					cur_tsc = rte_rdtsc();
1507 					diff_tsc = cur_tsc - prev_tsc;
1508 					timer_tsc += diff_tsc;
1509 				} while ((nb_rx > 0) &&
1510 					(timer_tsc < timer_period));
1511 				timer_tsc = 0;
1512 			}
1513 		}
1514 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1515 	}
1516 }
1517 
1518 static void
1519 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1520 {
1521 	struct fwd_stream **fsm;
1522 	streamid_t nb_fs;
1523 	streamid_t sm_id;
1524 #ifdef RTE_LIBRTE_BITRATE
1525 	uint64_t tics_per_1sec;
1526 	uint64_t tics_datum;
1527 	uint64_t tics_current;
1528 	uint16_t i, cnt_ports;
1529 
1530 	cnt_ports = nb_ports;
1531 	tics_datum = rte_rdtsc();
1532 	tics_per_1sec = rte_get_timer_hz();
1533 #endif
1534 	fsm = &fwd_streams[fc->stream_idx];
1535 	nb_fs = fc->stream_nb;
1536 	do {
1537 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1538 			(*pkt_fwd)(fsm[sm_id]);
1539 #ifdef RTE_LIBRTE_BITRATE
1540 		if (bitrate_enabled != 0 &&
1541 				bitrate_lcore_id == rte_lcore_id()) {
1542 			tics_current = rte_rdtsc();
1543 			if (tics_current - tics_datum >= tics_per_1sec) {
1544 				/* Periodic bitrate calculation */
1545 				for (i = 0; i < cnt_ports; i++)
1546 					rte_stats_bitrate_calc(bitrate_data,
1547 						ports_ids[i]);
1548 				tics_datum = tics_current;
1549 			}
1550 		}
1551 #endif
1552 #ifdef RTE_LIBRTE_LATENCY_STATS
1553 		if (latencystats_enabled != 0 &&
1554 				latencystats_lcore_id == rte_lcore_id())
1555 			rte_latencystats_update();
1556 #endif
1557 
1558 	} while (! fc->stopped);
1559 }
1560 
1561 static int
1562 start_pkt_forward_on_core(void *fwd_arg)
1563 {
1564 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1565 			     cur_fwd_config.fwd_eng->packet_fwd);
1566 	return 0;
1567 }
1568 
1569 /*
1570  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1571  * Used to start communication flows in network loopback test configurations.
1572  */
1573 static int
1574 run_one_txonly_burst_on_core(void *fwd_arg)
1575 {
1576 	struct fwd_lcore *fwd_lc;
1577 	struct fwd_lcore tmp_lcore;
1578 
1579 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1580 	tmp_lcore = *fwd_lc;
1581 	tmp_lcore.stopped = 1;
1582 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1583 	return 0;
1584 }
1585 
1586 /*
1587  * Launch packet forwarding:
1588  *     - Setup per-port forwarding context.
1589  *     - launch logical cores with their forwarding configuration.
1590  */
1591 static void
1592 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1593 {
1594 	port_fwd_begin_t port_fwd_begin;
1595 	unsigned int i;
1596 	unsigned int lc_id;
1597 	int diag;
1598 
1599 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1600 	if (port_fwd_begin != NULL) {
1601 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1602 			(*port_fwd_begin)(fwd_ports_ids[i]);
1603 	}
1604 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1605 		lc_id = fwd_lcores_cpuids[i];
1606 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1607 			fwd_lcores[i]->stopped = 0;
1608 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1609 						     fwd_lcores[i], lc_id);
1610 			if (diag != 0)
1611 				printf("launch lcore %u failed - diag=%d\n",
1612 				       lc_id, diag);
1613 		}
1614 	}
1615 }
1616 
1617 /*
1618  * Update the forward ports list.
1619  */
1620 void
1621 update_fwd_ports(portid_t new_pid)
1622 {
1623 	unsigned int i;
1624 	unsigned int new_nb_fwd_ports = 0;
1625 	int move = 0;
1626 
1627 	for (i = 0; i < nb_fwd_ports; ++i) {
1628 		if (port_id_is_invalid(fwd_ports_ids[i], DISABLED_WARN))
1629 			move = 1;
1630 		else if (move)
1631 			fwd_ports_ids[new_nb_fwd_ports++] = fwd_ports_ids[i];
1632 		else
1633 			new_nb_fwd_ports++;
1634 	}
1635 	if (new_pid < RTE_MAX_ETHPORTS)
1636 		fwd_ports_ids[new_nb_fwd_ports++] = new_pid;
1637 
1638 	nb_fwd_ports = new_nb_fwd_ports;
1639 	nb_cfg_ports = new_nb_fwd_ports;
1640 }
1641 
1642 /*
1643  * Launch packet forwarding configuration.
1644  */
1645 void
1646 start_packet_forwarding(int with_tx_first)
1647 {
1648 	port_fwd_begin_t port_fwd_begin;
1649 	port_fwd_end_t  port_fwd_end;
1650 	struct rte_port *port;
1651 	unsigned int i;
1652 	portid_t   pt_id;
1653 	streamid_t sm_id;
1654 
1655 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1656 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1657 
1658 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1659 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1660 
1661 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1662 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1663 		(!nb_rxq || !nb_txq))
1664 		rte_exit(EXIT_FAILURE,
1665 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
1666 			cur_fwd_eng->fwd_mode_name);
1667 
1668 	if (all_ports_started() == 0) {
1669 		printf("Not all ports were started\n");
1670 		return;
1671 	}
1672 	if (test_done == 0) {
1673 		printf("Packet forwarding already started\n");
1674 		return;
1675 	}
1676 
1677 
1678 	if(dcb_test) {
1679 		for (i = 0; i < nb_fwd_ports; i++) {
1680 			pt_id = fwd_ports_ids[i];
1681 			port = &ports[pt_id];
1682 			if (!port->dcb_flag) {
1683 				printf("In DCB mode, all forwarding ports must "
1684                                        "be configured in this mode.\n");
1685 				return;
1686 			}
1687 		}
1688 		if (nb_fwd_lcores == 1) {
1689 			printf("In DCB mode,the nb forwarding cores "
1690                                "should be larger than 1.\n");
1691 			return;
1692 		}
1693 	}
1694 	test_done = 0;
1695 
1696 	fwd_config_setup();
1697 
1698 	if(!no_flush_rx)
1699 		flush_fwd_rx_queues();
1700 
1701 	pkt_fwd_config_display(&cur_fwd_config);
1702 	rxtx_config_display();
1703 
1704 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1705 		pt_id = fwd_ports_ids[i];
1706 		port = &ports[pt_id];
1707 		rte_eth_stats_get(pt_id, &port->stats);
1708 		port->tx_dropped = 0;
1709 
1710 		map_port_queue_stats_mapping_registers(pt_id, port);
1711 	}
1712 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1713 		fwd_streams[sm_id]->rx_packets = 0;
1714 		fwd_streams[sm_id]->tx_packets = 0;
1715 		fwd_streams[sm_id]->fwd_dropped = 0;
1716 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1717 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1718 		fwd_streams[sm_id]->rx_bad_outer_l4_csum = 0;
1719 
1720 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1721 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1722 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1723 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1724 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1725 #endif
1726 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1727 		fwd_streams[sm_id]->core_cycles = 0;
1728 #endif
1729 	}
1730 	if (with_tx_first) {
1731 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1732 		if (port_fwd_begin != NULL) {
1733 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1734 				(*port_fwd_begin)(fwd_ports_ids[i]);
1735 		}
1736 		while (with_tx_first--) {
1737 			launch_packet_forwarding(
1738 					run_one_txonly_burst_on_core);
1739 			rte_eal_mp_wait_lcore();
1740 		}
1741 		port_fwd_end = tx_only_engine.port_fwd_end;
1742 		if (port_fwd_end != NULL) {
1743 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1744 				(*port_fwd_end)(fwd_ports_ids[i]);
1745 		}
1746 	}
1747 	launch_packet_forwarding(start_pkt_forward_on_core);
1748 }
1749 
1750 void
1751 stop_packet_forwarding(void)
1752 {
1753 	struct rte_eth_stats stats;
1754 	struct rte_port *port;
1755 	port_fwd_end_t  port_fwd_end;
1756 	int i;
1757 	portid_t   pt_id;
1758 	streamid_t sm_id;
1759 	lcoreid_t  lc_id;
1760 	uint64_t total_recv;
1761 	uint64_t total_xmit;
1762 	uint64_t total_rx_dropped;
1763 	uint64_t total_tx_dropped;
1764 	uint64_t total_rx_nombuf;
1765 	uint64_t tx_dropped;
1766 	uint64_t rx_bad_ip_csum;
1767 	uint64_t rx_bad_l4_csum;
1768 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1769 	uint64_t fwd_cycles;
1770 #endif
1771 
1772 	static const char *acc_stats_border = "+++++++++++++++";
1773 
1774 	if (test_done) {
1775 		printf("Packet forwarding not started\n");
1776 		return;
1777 	}
1778 	printf("Telling cores to stop...");
1779 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1780 		fwd_lcores[lc_id]->stopped = 1;
1781 	printf("\nWaiting for lcores to finish...\n");
1782 	rte_eal_mp_wait_lcore();
1783 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1784 	if (port_fwd_end != NULL) {
1785 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1786 			pt_id = fwd_ports_ids[i];
1787 			(*port_fwd_end)(pt_id);
1788 		}
1789 	}
1790 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1791 	fwd_cycles = 0;
1792 #endif
1793 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1794 		if (cur_fwd_config.nb_fwd_streams >
1795 		    cur_fwd_config.nb_fwd_ports) {
1796 			fwd_stream_stats_display(sm_id);
1797 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1798 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1799 		} else {
1800 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1801 				fwd_streams[sm_id];
1802 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1803 				fwd_streams[sm_id];
1804 		}
1805 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1806 		tx_dropped = (uint64_t) (tx_dropped +
1807 					 fwd_streams[sm_id]->fwd_dropped);
1808 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1809 
1810 		rx_bad_ip_csum =
1811 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1812 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1813 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1814 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1815 							rx_bad_ip_csum;
1816 
1817 		rx_bad_l4_csum =
1818 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1819 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1820 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1821 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1822 							rx_bad_l4_csum;
1823 
1824 		ports[fwd_streams[sm_id]->rx_port].rx_bad_outer_l4_csum +=
1825 				fwd_streams[sm_id]->rx_bad_outer_l4_csum;
1826 
1827 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1828 		fwd_cycles = (uint64_t) (fwd_cycles +
1829 					 fwd_streams[sm_id]->core_cycles);
1830 #endif
1831 	}
1832 	total_recv = 0;
1833 	total_xmit = 0;
1834 	total_rx_dropped = 0;
1835 	total_tx_dropped = 0;
1836 	total_rx_nombuf  = 0;
1837 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1838 		pt_id = fwd_ports_ids[i];
1839 
1840 		port = &ports[pt_id];
1841 		rte_eth_stats_get(pt_id, &stats);
1842 		stats.ipackets -= port->stats.ipackets;
1843 		port->stats.ipackets = 0;
1844 		stats.opackets -= port->stats.opackets;
1845 		port->stats.opackets = 0;
1846 		stats.ibytes   -= port->stats.ibytes;
1847 		port->stats.ibytes = 0;
1848 		stats.obytes   -= port->stats.obytes;
1849 		port->stats.obytes = 0;
1850 		stats.imissed  -= port->stats.imissed;
1851 		port->stats.imissed = 0;
1852 		stats.oerrors  -= port->stats.oerrors;
1853 		port->stats.oerrors = 0;
1854 		stats.rx_nombuf -= port->stats.rx_nombuf;
1855 		port->stats.rx_nombuf = 0;
1856 
1857 		total_recv += stats.ipackets;
1858 		total_xmit += stats.opackets;
1859 		total_rx_dropped += stats.imissed;
1860 		total_tx_dropped += port->tx_dropped;
1861 		total_rx_nombuf  += stats.rx_nombuf;
1862 
1863 		fwd_port_stats_display(pt_id, &stats);
1864 	}
1865 
1866 	printf("\n  %s Accumulated forward statistics for all ports"
1867 	       "%s\n",
1868 	       acc_stats_border, acc_stats_border);
1869 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1870 	       "%-"PRIu64"\n"
1871 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1872 	       "%-"PRIu64"\n",
1873 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1874 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1875 	if (total_rx_nombuf > 0)
1876 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1877 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1878 	       "%s\n",
1879 	       acc_stats_border, acc_stats_border);
1880 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1881 	if (total_recv > 0)
1882 		printf("\n  CPU cycles/packet=%u (total cycles="
1883 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1884 		       (unsigned int)(fwd_cycles / total_recv),
1885 		       fwd_cycles, total_recv);
1886 #endif
1887 	printf("\nDone.\n");
1888 	test_done = 1;
1889 }
1890 
1891 void
1892 dev_set_link_up(portid_t pid)
1893 {
1894 	if (rte_eth_dev_set_link_up(pid) < 0)
1895 		printf("\nSet link up fail.\n");
1896 }
1897 
1898 void
1899 dev_set_link_down(portid_t pid)
1900 {
1901 	if (rte_eth_dev_set_link_down(pid) < 0)
1902 		printf("\nSet link down fail.\n");
1903 }
1904 
1905 static int
1906 all_ports_started(void)
1907 {
1908 	portid_t pi;
1909 	struct rte_port *port;
1910 
1911 	RTE_ETH_FOREACH_DEV(pi) {
1912 		port = &ports[pi];
1913 		/* Check if there is a port which is not started */
1914 		if ((port->port_status != RTE_PORT_STARTED) &&
1915 			(port->slave_flag == 0))
1916 			return 0;
1917 	}
1918 
1919 	/* No port is not started */
1920 	return 1;
1921 }
1922 
1923 int
1924 port_is_stopped(portid_t port_id)
1925 {
1926 	struct rte_port *port = &ports[port_id];
1927 
1928 	if ((port->port_status != RTE_PORT_STOPPED) &&
1929 	    (port->slave_flag == 0))
1930 		return 0;
1931 	return 1;
1932 }
1933 
1934 int
1935 all_ports_stopped(void)
1936 {
1937 	portid_t pi;
1938 
1939 	RTE_ETH_FOREACH_DEV(pi) {
1940 		if (!port_is_stopped(pi))
1941 			return 0;
1942 	}
1943 
1944 	return 1;
1945 }
1946 
1947 int
1948 port_is_started(portid_t port_id)
1949 {
1950 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1951 		return 0;
1952 
1953 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1954 		return 0;
1955 
1956 	return 1;
1957 }
1958 
1959 int
1960 start_port(portid_t pid)
1961 {
1962 	int diag, need_check_link_status = -1;
1963 	portid_t pi;
1964 	queueid_t qi;
1965 	struct rte_port *port;
1966 	struct ether_addr mac_addr;
1967 	enum rte_eth_event_type event_type;
1968 
1969 	if (port_id_is_invalid(pid, ENABLED_WARN))
1970 		return 0;
1971 
1972 	if(dcb_config)
1973 		dcb_test = 1;
1974 	RTE_ETH_FOREACH_DEV(pi) {
1975 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1976 			continue;
1977 
1978 		need_check_link_status = 0;
1979 		port = &ports[pi];
1980 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1981 						 RTE_PORT_HANDLING) == 0) {
1982 			printf("Port %d is now not stopped\n", pi);
1983 			continue;
1984 		}
1985 
1986 		if (port->need_reconfig > 0) {
1987 			port->need_reconfig = 0;
1988 
1989 			if (flow_isolate_all) {
1990 				int ret = port_flow_isolate(pi, 1);
1991 				if (ret) {
1992 					printf("Failed to apply isolated"
1993 					       " mode on port %d\n", pi);
1994 					return -1;
1995 				}
1996 			}
1997 			configure_rxtx_dump_callbacks(0);
1998 			printf("Configuring Port %d (socket %u)\n", pi,
1999 					port->socket_id);
2000 			/* configure port */
2001 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
2002 						&(port->dev_conf));
2003 			if (diag != 0) {
2004 				if (rte_atomic16_cmpset(&(port->port_status),
2005 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2006 					printf("Port %d can not be set back "
2007 							"to stopped\n", pi);
2008 				printf("Fail to configure port %d\n", pi);
2009 				/* try to reconfigure port next time */
2010 				port->need_reconfig = 1;
2011 				return -1;
2012 			}
2013 		}
2014 		if (port->need_reconfig_queues > 0) {
2015 			port->need_reconfig_queues = 0;
2016 			/* setup tx queues */
2017 			for (qi = 0; qi < nb_txq; qi++) {
2018 				if ((numa_support) &&
2019 					(txring_numa[pi] != NUMA_NO_CONFIG))
2020 					diag = rte_eth_tx_queue_setup(pi, qi,
2021 						port->nb_tx_desc[qi],
2022 						txring_numa[pi],
2023 						&(port->tx_conf[qi]));
2024 				else
2025 					diag = rte_eth_tx_queue_setup(pi, qi,
2026 						port->nb_tx_desc[qi],
2027 						port->socket_id,
2028 						&(port->tx_conf[qi]));
2029 
2030 				if (diag == 0)
2031 					continue;
2032 
2033 				/* Fail to setup tx queue, return */
2034 				if (rte_atomic16_cmpset(&(port->port_status),
2035 							RTE_PORT_HANDLING,
2036 							RTE_PORT_STOPPED) == 0)
2037 					printf("Port %d can not be set back "
2038 							"to stopped\n", pi);
2039 				printf("Fail to configure port %d tx queues\n",
2040 				       pi);
2041 				/* try to reconfigure queues next time */
2042 				port->need_reconfig_queues = 1;
2043 				return -1;
2044 			}
2045 			for (qi = 0; qi < nb_rxq; qi++) {
2046 				/* setup rx queues */
2047 				if ((numa_support) &&
2048 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
2049 					struct rte_mempool * mp =
2050 						mbuf_pool_find(rxring_numa[pi]);
2051 					if (mp == NULL) {
2052 						printf("Failed to setup RX queue:"
2053 							"No mempool allocation"
2054 							" on the socket %d\n",
2055 							rxring_numa[pi]);
2056 						return -1;
2057 					}
2058 
2059 					diag = rte_eth_rx_queue_setup(pi, qi,
2060 					     port->nb_rx_desc[qi],
2061 					     rxring_numa[pi],
2062 					     &(port->rx_conf[qi]),
2063 					     mp);
2064 				} else {
2065 					struct rte_mempool *mp =
2066 						mbuf_pool_find(port->socket_id);
2067 					if (mp == NULL) {
2068 						printf("Failed to setup RX queue:"
2069 							"No mempool allocation"
2070 							" on the socket %d\n",
2071 							port->socket_id);
2072 						return -1;
2073 					}
2074 					diag = rte_eth_rx_queue_setup(pi, qi,
2075 					     port->nb_rx_desc[qi],
2076 					     port->socket_id,
2077 					     &(port->rx_conf[qi]),
2078 					     mp);
2079 				}
2080 				if (diag == 0)
2081 					continue;
2082 
2083 				/* Fail to setup rx queue, return */
2084 				if (rte_atomic16_cmpset(&(port->port_status),
2085 							RTE_PORT_HANDLING,
2086 							RTE_PORT_STOPPED) == 0)
2087 					printf("Port %d can not be set back "
2088 							"to stopped\n", pi);
2089 				printf("Fail to configure port %d rx queues\n",
2090 				       pi);
2091 				/* try to reconfigure queues next time */
2092 				port->need_reconfig_queues = 1;
2093 				return -1;
2094 			}
2095 		}
2096 		configure_rxtx_dump_callbacks(verbose_level);
2097 		/* start port */
2098 		if (rte_eth_dev_start(pi) < 0) {
2099 			printf("Fail to start port %d\n", pi);
2100 
2101 			/* Fail to setup rx queue, return */
2102 			if (rte_atomic16_cmpset(&(port->port_status),
2103 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2104 				printf("Port %d can not be set back to "
2105 							"stopped\n", pi);
2106 			continue;
2107 		}
2108 
2109 		if (rte_atomic16_cmpset(&(port->port_status),
2110 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
2111 			printf("Port %d can not be set into started\n", pi);
2112 
2113 		rte_eth_macaddr_get(pi, &mac_addr);
2114 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
2115 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
2116 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
2117 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
2118 
2119 		/* at least one port started, need checking link status */
2120 		need_check_link_status = 1;
2121 	}
2122 
2123 	for (event_type = RTE_ETH_EVENT_UNKNOWN;
2124 	     event_type < RTE_ETH_EVENT_MAX;
2125 	     event_type++) {
2126 		diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
2127 						event_type,
2128 						eth_event_callback,
2129 						NULL);
2130 		if (diag) {
2131 			printf("Failed to setup even callback for event %d\n",
2132 				event_type);
2133 			return -1;
2134 		}
2135 	}
2136 
2137 	if (need_check_link_status == 1 && !no_link_check)
2138 		check_all_ports_link_status(RTE_PORT_ALL);
2139 	else if (need_check_link_status == 0)
2140 		printf("Please stop the ports first\n");
2141 
2142 	printf("Done\n");
2143 	return 0;
2144 }
2145 
2146 void
2147 stop_port(portid_t pid)
2148 {
2149 	portid_t pi;
2150 	struct rte_port *port;
2151 	int need_check_link_status = 0;
2152 
2153 	if (dcb_test) {
2154 		dcb_test = 0;
2155 		dcb_config = 0;
2156 	}
2157 
2158 	if (port_id_is_invalid(pid, ENABLED_WARN))
2159 		return;
2160 
2161 	printf("Stopping ports...\n");
2162 
2163 	RTE_ETH_FOREACH_DEV(pi) {
2164 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2165 			continue;
2166 
2167 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
2168 			printf("Please remove port %d from forwarding configuration.\n", pi);
2169 			continue;
2170 		}
2171 
2172 		if (port_is_bonding_slave(pi)) {
2173 			printf("Please remove port %d from bonded device.\n", pi);
2174 			continue;
2175 		}
2176 
2177 		port = &ports[pi];
2178 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
2179 						RTE_PORT_HANDLING) == 0)
2180 			continue;
2181 
2182 		rte_eth_dev_stop(pi);
2183 
2184 		if (rte_atomic16_cmpset(&(port->port_status),
2185 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2186 			printf("Port %d can not be set into stopped\n", pi);
2187 		need_check_link_status = 1;
2188 	}
2189 	if (need_check_link_status && !no_link_check)
2190 		check_all_ports_link_status(RTE_PORT_ALL);
2191 
2192 	printf("Done\n");
2193 }
2194 
2195 static void
2196 remove_unused_fwd_ports(void)
2197 {
2198 	int i;
2199 	int last_port_idx = nb_ports - 1;
2200 
2201 	for (i = 0; i <= last_port_idx; i++) { /* iterate in ports_ids */
2202 		if (rte_eth_devices[ports_ids[i]].state != RTE_ETH_DEV_UNUSED)
2203 			continue;
2204 		/* skip unused ports at the end */
2205 		while (i <= last_port_idx &&
2206 				rte_eth_devices[ports_ids[last_port_idx]].state
2207 				== RTE_ETH_DEV_UNUSED)
2208 			last_port_idx--;
2209 		if (last_port_idx < i)
2210 			break;
2211 		/* overwrite unused port with last valid port */
2212 		ports_ids[i] = ports_ids[last_port_idx];
2213 		/* decrease ports count */
2214 		last_port_idx--;
2215 	}
2216 	nb_ports = rte_eth_dev_count_avail();
2217 	update_fwd_ports(RTE_MAX_ETHPORTS);
2218 }
2219 
2220 void
2221 close_port(portid_t pid)
2222 {
2223 	portid_t pi;
2224 	struct rte_port *port;
2225 
2226 	if (port_id_is_invalid(pid, ENABLED_WARN))
2227 		return;
2228 
2229 	printf("Closing ports...\n");
2230 
2231 	RTE_ETH_FOREACH_DEV(pi) {
2232 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2233 			continue;
2234 
2235 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
2236 			printf("Please remove port %d from forwarding configuration.\n", pi);
2237 			continue;
2238 		}
2239 
2240 		if (port_is_bonding_slave(pi)) {
2241 			printf("Please remove port %d from bonded device.\n", pi);
2242 			continue;
2243 		}
2244 
2245 		port = &ports[pi];
2246 		if (rte_atomic16_cmpset(&(port->port_status),
2247 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
2248 			printf("Port %d is already closed\n", pi);
2249 			continue;
2250 		}
2251 
2252 		if (rte_atomic16_cmpset(&(port->port_status),
2253 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
2254 			printf("Port %d is now not stopped\n", pi);
2255 			continue;
2256 		}
2257 
2258 		if (port->flow_list)
2259 			port_flow_flush(pi);
2260 		rte_eth_dev_close(pi);
2261 
2262 		remove_unused_fwd_ports();
2263 
2264 		if (rte_atomic16_cmpset(&(port->port_status),
2265 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
2266 			printf("Port %d cannot be set to closed\n", pi);
2267 	}
2268 
2269 	printf("Done\n");
2270 }
2271 
2272 void
2273 reset_port(portid_t pid)
2274 {
2275 	int diag;
2276 	portid_t pi;
2277 	struct rte_port *port;
2278 
2279 	if (port_id_is_invalid(pid, ENABLED_WARN))
2280 		return;
2281 
2282 	printf("Resetting ports...\n");
2283 
2284 	RTE_ETH_FOREACH_DEV(pi) {
2285 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2286 			continue;
2287 
2288 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
2289 			printf("Please remove port %d from forwarding "
2290 			       "configuration.\n", pi);
2291 			continue;
2292 		}
2293 
2294 		if (port_is_bonding_slave(pi)) {
2295 			printf("Please remove port %d from bonded device.\n",
2296 			       pi);
2297 			continue;
2298 		}
2299 
2300 		diag = rte_eth_dev_reset(pi);
2301 		if (diag == 0) {
2302 			port = &ports[pi];
2303 			port->need_reconfig = 1;
2304 			port->need_reconfig_queues = 1;
2305 		} else {
2306 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
2307 		}
2308 	}
2309 
2310 	printf("Done\n");
2311 }
2312 
2313 void
2314 attach_port(char *identifier)
2315 {
2316 	portid_t pi = 0;
2317 	struct rte_dev_iterator iterator;
2318 
2319 	printf("Attaching a new port...\n");
2320 
2321 	if (identifier == NULL) {
2322 		printf("Invalid parameters are specified\n");
2323 		return;
2324 	}
2325 
2326 	if (rte_dev_probe(identifier) != 0) {
2327 		TESTPMD_LOG(ERR, "Failed to attach port %s\n", identifier);
2328 		return;
2329 	}
2330 
2331 	RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator)
2332 		setup_attached_port(pi);
2333 }
2334 
2335 static void
2336 setup_attached_port(portid_t pi)
2337 {
2338 	unsigned int socket_id;
2339 
2340 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
2341 	/* if socket_id is invalid, set to the first available socket. */
2342 	if (check_socket_id(socket_id) < 0)
2343 		socket_id = socket_ids[0];
2344 	reconfig(pi, socket_id);
2345 	rte_eth_promiscuous_enable(pi);
2346 
2347 	ports_ids[nb_ports] = pi;
2348 	nb_ports = rte_eth_dev_count_avail();
2349 
2350 	ports[pi].port_status = RTE_PORT_STOPPED;
2351 
2352 	update_fwd_ports(pi);
2353 
2354 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2355 	printf("Done\n");
2356 }
2357 
2358 void
2359 detach_port_device(portid_t port_id)
2360 {
2361 	struct rte_device *dev;
2362 	portid_t sibling;
2363 
2364 	printf("Removing a device...\n");
2365 
2366 	dev = rte_eth_devices[port_id].device;
2367 	if (dev == NULL) {
2368 		printf("Device already removed\n");
2369 		return;
2370 	}
2371 
2372 	if (ports[port_id].port_status != RTE_PORT_CLOSED) {
2373 		if (ports[port_id].port_status != RTE_PORT_STOPPED) {
2374 			printf("Port not stopped\n");
2375 			return;
2376 		}
2377 		printf("Port was not closed\n");
2378 		if (ports[port_id].flow_list)
2379 			port_flow_flush(port_id);
2380 	}
2381 
2382 	if (rte_dev_remove(dev) != 0) {
2383 		TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name);
2384 		return;
2385 	}
2386 
2387 	for (sibling = 0; sibling < RTE_MAX_ETHPORTS; sibling++) {
2388 		if (rte_eth_devices[sibling].device != dev)
2389 			continue;
2390 		/* reset mapping between old ports and removed device */
2391 		rte_eth_devices[sibling].device = NULL;
2392 		if (ports[sibling].port_status != RTE_PORT_CLOSED) {
2393 			/* sibling ports are forced to be closed */
2394 			ports[sibling].port_status = RTE_PORT_CLOSED;
2395 			printf("Port %u is closed\n", sibling);
2396 		}
2397 	}
2398 
2399 	remove_unused_fwd_ports();
2400 
2401 	printf("Device of port %u is detached\n", port_id);
2402 	printf("Now total ports is %d\n", nb_ports);
2403 	printf("Done\n");
2404 	return;
2405 }
2406 
2407 void
2408 pmd_test_exit(void)
2409 {
2410 	struct rte_device *device;
2411 	portid_t pt_id;
2412 	int ret;
2413 
2414 	if (test_done == 0)
2415 		stop_packet_forwarding();
2416 
2417 	if (ports != NULL) {
2418 		no_link_check = 1;
2419 		RTE_ETH_FOREACH_DEV(pt_id) {
2420 			printf("\nShutting down port %d...\n", pt_id);
2421 			fflush(stdout);
2422 			stop_port(pt_id);
2423 			close_port(pt_id);
2424 
2425 			/*
2426 			 * This is a workaround to fix a virtio-user issue that
2427 			 * requires to call clean-up routine to remove existing
2428 			 * socket.
2429 			 * This workaround valid only for testpmd, needs a fix
2430 			 * valid for all applications.
2431 			 * TODO: Implement proper resource cleanup
2432 			 */
2433 			device = rte_eth_devices[pt_id].device;
2434 			if (device && !strcmp(device->driver->name, "net_virtio_user"))
2435 				detach_port_device(pt_id);
2436 		}
2437 	}
2438 
2439 	if (hot_plug) {
2440 		ret = rte_dev_event_monitor_stop();
2441 		if (ret) {
2442 			RTE_LOG(ERR, EAL,
2443 				"fail to stop device event monitor.");
2444 			return;
2445 		}
2446 
2447 		ret = rte_dev_event_callback_unregister(NULL,
2448 			eth_dev_event_callback, NULL);
2449 		if (ret < 0) {
2450 			RTE_LOG(ERR, EAL,
2451 				"fail to unregister device event callback.\n");
2452 			return;
2453 		}
2454 
2455 		ret = rte_dev_hotplug_handle_disable();
2456 		if (ret) {
2457 			RTE_LOG(ERR, EAL,
2458 				"fail to disable hotplug handling.\n");
2459 			return;
2460 		}
2461 	}
2462 
2463 	printf("\nBye...\n");
2464 }
2465 
2466 typedef void (*cmd_func_t)(void);
2467 struct pmd_test_command {
2468 	const char *cmd_name;
2469 	cmd_func_t cmd_func;
2470 };
2471 
2472 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
2473 
2474 /* Check the link status of all ports in up to 9s, and print them finally */
2475 static void
2476 check_all_ports_link_status(uint32_t port_mask)
2477 {
2478 #define CHECK_INTERVAL 100 /* 100ms */
2479 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
2480 	portid_t portid;
2481 	uint8_t count, all_ports_up, print_flag = 0;
2482 	struct rte_eth_link link;
2483 
2484 	printf("Checking link statuses...\n");
2485 	fflush(stdout);
2486 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
2487 		all_ports_up = 1;
2488 		RTE_ETH_FOREACH_DEV(portid) {
2489 			if ((port_mask & (1 << portid)) == 0)
2490 				continue;
2491 			memset(&link, 0, sizeof(link));
2492 			rte_eth_link_get_nowait(portid, &link);
2493 			/* print link status if flag set */
2494 			if (print_flag == 1) {
2495 				if (link.link_status)
2496 					printf(
2497 					"Port%d Link Up. speed %u Mbps- %s\n",
2498 					portid, link.link_speed,
2499 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
2500 					("full-duplex") : ("half-duplex\n"));
2501 				else
2502 					printf("Port %d Link Down\n", portid);
2503 				continue;
2504 			}
2505 			/* clear all_ports_up flag if any link down */
2506 			if (link.link_status == ETH_LINK_DOWN) {
2507 				all_ports_up = 0;
2508 				break;
2509 			}
2510 		}
2511 		/* after finally printing all link status, get out */
2512 		if (print_flag == 1)
2513 			break;
2514 
2515 		if (all_ports_up == 0) {
2516 			fflush(stdout);
2517 			rte_delay_ms(CHECK_INTERVAL);
2518 		}
2519 
2520 		/* set the print_flag if all ports up or timeout */
2521 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
2522 			print_flag = 1;
2523 		}
2524 
2525 		if (lsc_interrupt)
2526 			break;
2527 	}
2528 }
2529 
2530 static void
2531 rmv_event_callback(void *arg)
2532 {
2533 	int need_to_start = 0;
2534 	int org_no_link_check = no_link_check;
2535 	portid_t port_id = (intptr_t)arg;
2536 
2537 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
2538 
2539 	if (!test_done && port_is_forwarding(port_id)) {
2540 		need_to_start = 1;
2541 		stop_packet_forwarding();
2542 	}
2543 	no_link_check = 1;
2544 	stop_port(port_id);
2545 	no_link_check = org_no_link_check;
2546 	close_port(port_id);
2547 	detach_port_device(port_id);
2548 	if (need_to_start)
2549 		start_packet_forwarding(0);
2550 }
2551 
2552 /* This function is used by the interrupt thread */
2553 static int
2554 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
2555 		  void *ret_param)
2556 {
2557 	static const char * const event_desc[] = {
2558 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
2559 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
2560 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
2561 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
2562 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
2563 		[RTE_ETH_EVENT_IPSEC] = "IPsec",
2564 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
2565 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
2566 		[RTE_ETH_EVENT_NEW] = "device probed",
2567 		[RTE_ETH_EVENT_DESTROY] = "device released",
2568 		[RTE_ETH_EVENT_MAX] = NULL,
2569 	};
2570 
2571 	RTE_SET_USED(param);
2572 	RTE_SET_USED(ret_param);
2573 
2574 	if (type >= RTE_ETH_EVENT_MAX) {
2575 		fprintf(stderr, "\nPort %" PRIu16 ": %s called upon invalid event %d\n",
2576 			port_id, __func__, type);
2577 		fflush(stderr);
2578 	} else if (event_print_mask & (UINT32_C(1) << type)) {
2579 		printf("\nPort %" PRIu16 ": %s event\n", port_id,
2580 			event_desc[type]);
2581 		fflush(stdout);
2582 	}
2583 
2584 	if (port_id_is_invalid(port_id, DISABLED_WARN))
2585 		return 0;
2586 
2587 	switch (type) {
2588 	case RTE_ETH_EVENT_INTR_RMV:
2589 		if (rte_eal_alarm_set(100000,
2590 				rmv_event_callback, (void *)(intptr_t)port_id))
2591 			fprintf(stderr, "Could not set up deferred device removal\n");
2592 		break;
2593 	default:
2594 		break;
2595 	}
2596 	return 0;
2597 }
2598 
2599 /* This function is used by the interrupt thread */
2600 static void
2601 eth_dev_event_callback(const char *device_name, enum rte_dev_event_type type,
2602 			     __rte_unused void *arg)
2603 {
2604 	uint16_t port_id;
2605 	int ret;
2606 
2607 	if (type >= RTE_DEV_EVENT_MAX) {
2608 		fprintf(stderr, "%s called upon invalid event %d\n",
2609 			__func__, type);
2610 		fflush(stderr);
2611 	}
2612 
2613 	switch (type) {
2614 	case RTE_DEV_EVENT_REMOVE:
2615 		RTE_LOG(ERR, EAL, "The device: %s has been removed!\n",
2616 			device_name);
2617 		ret = rte_eth_dev_get_port_by_name(device_name, &port_id);
2618 		if (ret) {
2619 			RTE_LOG(ERR, EAL, "can not get port by device %s!\n",
2620 				device_name);
2621 			return;
2622 		}
2623 		rmv_event_callback((void *)(intptr_t)port_id);
2624 		break;
2625 	case RTE_DEV_EVENT_ADD:
2626 		RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
2627 			device_name);
2628 		/* TODO: After finish kernel driver binding,
2629 		 * begin to attach port.
2630 		 */
2631 		break;
2632 	default:
2633 		break;
2634 	}
2635 }
2636 
2637 static int
2638 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2639 {
2640 	uint16_t i;
2641 	int diag;
2642 	uint8_t mapping_found = 0;
2643 
2644 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
2645 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
2646 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
2647 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
2648 					tx_queue_stats_mappings[i].queue_id,
2649 					tx_queue_stats_mappings[i].stats_counter_id);
2650 			if (diag != 0)
2651 				return diag;
2652 			mapping_found = 1;
2653 		}
2654 	}
2655 	if (mapping_found)
2656 		port->tx_queue_stats_mapping_enabled = 1;
2657 	return 0;
2658 }
2659 
2660 static int
2661 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2662 {
2663 	uint16_t i;
2664 	int diag;
2665 	uint8_t mapping_found = 0;
2666 
2667 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
2668 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
2669 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
2670 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
2671 					rx_queue_stats_mappings[i].queue_id,
2672 					rx_queue_stats_mappings[i].stats_counter_id);
2673 			if (diag != 0)
2674 				return diag;
2675 			mapping_found = 1;
2676 		}
2677 	}
2678 	if (mapping_found)
2679 		port->rx_queue_stats_mapping_enabled = 1;
2680 	return 0;
2681 }
2682 
2683 static void
2684 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2685 {
2686 	int diag = 0;
2687 
2688 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2689 	if (diag != 0) {
2690 		if (diag == -ENOTSUP) {
2691 			port->tx_queue_stats_mapping_enabled = 0;
2692 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2693 		}
2694 		else
2695 			rte_exit(EXIT_FAILURE,
2696 					"set_tx_queue_stats_mapping_registers "
2697 					"failed for port id=%d diag=%d\n",
2698 					pi, diag);
2699 	}
2700 
2701 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2702 	if (diag != 0) {
2703 		if (diag == -ENOTSUP) {
2704 			port->rx_queue_stats_mapping_enabled = 0;
2705 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2706 		}
2707 		else
2708 			rte_exit(EXIT_FAILURE,
2709 					"set_rx_queue_stats_mapping_registers "
2710 					"failed for port id=%d diag=%d\n",
2711 					pi, diag);
2712 	}
2713 }
2714 
2715 static void
2716 rxtx_port_config(struct rte_port *port)
2717 {
2718 	uint16_t qid;
2719 
2720 	for (qid = 0; qid < nb_rxq; qid++) {
2721 		port->rx_conf[qid] = port->dev_info.default_rxconf;
2722 
2723 		/* Check if any Rx parameters have been passed */
2724 		if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2725 			port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
2726 
2727 		if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2728 			port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
2729 
2730 		if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2731 			port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
2732 
2733 		if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2734 			port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
2735 
2736 		if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2737 			port->rx_conf[qid].rx_drop_en = rx_drop_en;
2738 
2739 		port->nb_rx_desc[qid] = nb_rxd;
2740 	}
2741 
2742 	for (qid = 0; qid < nb_txq; qid++) {
2743 		port->tx_conf[qid] = port->dev_info.default_txconf;
2744 
2745 		/* Check if any Tx parameters have been passed */
2746 		if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2747 			port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
2748 
2749 		if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2750 			port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
2751 
2752 		if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2753 			port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
2754 
2755 		if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2756 			port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
2757 
2758 		if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2759 			port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
2760 
2761 		port->nb_tx_desc[qid] = nb_txd;
2762 	}
2763 }
2764 
2765 void
2766 init_port_config(void)
2767 {
2768 	portid_t pid;
2769 	struct rte_port *port;
2770 
2771 	RTE_ETH_FOREACH_DEV(pid) {
2772 		port = &ports[pid];
2773 		port->dev_conf.fdir_conf = fdir_conf;
2774 		rte_eth_dev_info_get(pid, &port->dev_info);
2775 		if (nb_rxq > 1) {
2776 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2777 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
2778 				rss_hf & port->dev_info.flow_type_rss_offloads;
2779 		} else {
2780 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2781 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2782 		}
2783 
2784 		if (port->dcb_flag == 0) {
2785 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2786 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2787 			else
2788 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2789 		}
2790 
2791 		rxtx_port_config(port);
2792 
2793 		rte_eth_macaddr_get(pid, &port->eth_addr);
2794 
2795 		map_port_queue_stats_mapping_registers(pid, port);
2796 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2797 		rte_pmd_ixgbe_bypass_init(pid);
2798 #endif
2799 
2800 		if (lsc_interrupt &&
2801 		    (rte_eth_devices[pid].data->dev_flags &
2802 		     RTE_ETH_DEV_INTR_LSC))
2803 			port->dev_conf.intr_conf.lsc = 1;
2804 		if (rmv_interrupt &&
2805 		    (rte_eth_devices[pid].data->dev_flags &
2806 		     RTE_ETH_DEV_INTR_RMV))
2807 			port->dev_conf.intr_conf.rmv = 1;
2808 	}
2809 }
2810 
2811 void set_port_slave_flag(portid_t slave_pid)
2812 {
2813 	struct rte_port *port;
2814 
2815 	port = &ports[slave_pid];
2816 	port->slave_flag = 1;
2817 }
2818 
2819 void clear_port_slave_flag(portid_t slave_pid)
2820 {
2821 	struct rte_port *port;
2822 
2823 	port = &ports[slave_pid];
2824 	port->slave_flag = 0;
2825 }
2826 
2827 uint8_t port_is_bonding_slave(portid_t slave_pid)
2828 {
2829 	struct rte_port *port;
2830 
2831 	port = &ports[slave_pid];
2832 	if ((rte_eth_devices[slave_pid].data->dev_flags &
2833 	    RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
2834 		return 1;
2835 	return 0;
2836 }
2837 
2838 const uint16_t vlan_tags[] = {
2839 		0,  1,  2,  3,  4,  5,  6,  7,
2840 		8,  9, 10, 11,  12, 13, 14, 15,
2841 		16, 17, 18, 19, 20, 21, 22, 23,
2842 		24, 25, 26, 27, 28, 29, 30, 31
2843 };
2844 
2845 static  int
2846 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
2847 		 enum dcb_mode_enable dcb_mode,
2848 		 enum rte_eth_nb_tcs num_tcs,
2849 		 uint8_t pfc_en)
2850 {
2851 	uint8_t i;
2852 	int32_t rc;
2853 	struct rte_eth_rss_conf rss_conf;
2854 
2855 	/*
2856 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2857 	 * given above, and the number of traffic classes available for use.
2858 	 */
2859 	if (dcb_mode == DCB_VT_ENABLED) {
2860 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2861 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
2862 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2863 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2864 
2865 		/* VMDQ+DCB RX and TX configurations */
2866 		vmdq_rx_conf->enable_default_pool = 0;
2867 		vmdq_rx_conf->default_pool = 0;
2868 		vmdq_rx_conf->nb_queue_pools =
2869 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2870 		vmdq_tx_conf->nb_queue_pools =
2871 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2872 
2873 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2874 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2875 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2876 			vmdq_rx_conf->pool_map[i].pools =
2877 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2878 		}
2879 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2880 			vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2881 			vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2882 		}
2883 
2884 		/* set DCB mode of RX and TX of multiple queues */
2885 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2886 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2887 	} else {
2888 		struct rte_eth_dcb_rx_conf *rx_conf =
2889 				&eth_conf->rx_adv_conf.dcb_rx_conf;
2890 		struct rte_eth_dcb_tx_conf *tx_conf =
2891 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2892 
2893 		rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
2894 		if (rc != 0)
2895 			return rc;
2896 
2897 		rx_conf->nb_tcs = num_tcs;
2898 		tx_conf->nb_tcs = num_tcs;
2899 
2900 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2901 			rx_conf->dcb_tc[i] = i % num_tcs;
2902 			tx_conf->dcb_tc[i] = i % num_tcs;
2903 		}
2904 
2905 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2906 		eth_conf->rx_adv_conf.rss_conf = rss_conf;
2907 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2908 	}
2909 
2910 	if (pfc_en)
2911 		eth_conf->dcb_capability_en =
2912 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2913 	else
2914 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2915 
2916 	return 0;
2917 }
2918 
2919 int
2920 init_port_dcb_config(portid_t pid,
2921 		     enum dcb_mode_enable dcb_mode,
2922 		     enum rte_eth_nb_tcs num_tcs,
2923 		     uint8_t pfc_en)
2924 {
2925 	struct rte_eth_conf port_conf;
2926 	struct rte_port *rte_port;
2927 	int retval;
2928 	uint16_t i;
2929 
2930 	rte_port = &ports[pid];
2931 
2932 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2933 	/* Enter DCB configuration status */
2934 	dcb_config = 1;
2935 
2936 	port_conf.rxmode = rte_port->dev_conf.rxmode;
2937 	port_conf.txmode = rte_port->dev_conf.txmode;
2938 
2939 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
2940 	retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
2941 	if (retval < 0)
2942 		return retval;
2943 	port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2944 
2945 	/* re-configure the device . */
2946 	rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
2947 
2948 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
2949 
2950 	/* If dev_info.vmdq_pool_base is greater than 0,
2951 	 * the queue id of vmdq pools is started after pf queues.
2952 	 */
2953 	if (dcb_mode == DCB_VT_ENABLED &&
2954 	    rte_port->dev_info.vmdq_pool_base > 0) {
2955 		printf("VMDQ_DCB multi-queue mode is nonsensical"
2956 			" for port %d.", pid);
2957 		return -1;
2958 	}
2959 
2960 	/* Assume the ports in testpmd have the same dcb capability
2961 	 * and has the same number of rxq and txq in dcb mode
2962 	 */
2963 	if (dcb_mode == DCB_VT_ENABLED) {
2964 		if (rte_port->dev_info.max_vfs > 0) {
2965 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2966 			nb_txq = rte_port->dev_info.nb_tx_queues;
2967 		} else {
2968 			nb_rxq = rte_port->dev_info.max_rx_queues;
2969 			nb_txq = rte_port->dev_info.max_tx_queues;
2970 		}
2971 	} else {
2972 		/*if vt is disabled, use all pf queues */
2973 		if (rte_port->dev_info.vmdq_pool_base == 0) {
2974 			nb_rxq = rte_port->dev_info.max_rx_queues;
2975 			nb_txq = rte_port->dev_info.max_tx_queues;
2976 		} else {
2977 			nb_rxq = (queueid_t)num_tcs;
2978 			nb_txq = (queueid_t)num_tcs;
2979 
2980 		}
2981 	}
2982 	rx_free_thresh = 64;
2983 
2984 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2985 
2986 	rxtx_port_config(rte_port);
2987 	/* VLAN filter */
2988 	rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2989 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2990 		rx_vft_set(pid, vlan_tags[i], 1);
2991 
2992 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2993 	map_port_queue_stats_mapping_registers(pid, rte_port);
2994 
2995 	rte_port->dcb_flag = 1;
2996 
2997 	return 0;
2998 }
2999 
3000 static void
3001 init_port(void)
3002 {
3003 	/* Configuration of Ethernet ports. */
3004 	ports = rte_zmalloc("testpmd: ports",
3005 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
3006 			    RTE_CACHE_LINE_SIZE);
3007 	if (ports == NULL) {
3008 		rte_exit(EXIT_FAILURE,
3009 				"rte_zmalloc(%d struct rte_port) failed\n",
3010 				RTE_MAX_ETHPORTS);
3011 	}
3012 
3013 	/* Initialize ports NUMA structures */
3014 	memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3015 	memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3016 	memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3017 }
3018 
3019 static void
3020 force_quit(void)
3021 {
3022 	pmd_test_exit();
3023 	prompt_exit();
3024 }
3025 
3026 static void
3027 print_stats(void)
3028 {
3029 	uint8_t i;
3030 	const char clr[] = { 27, '[', '2', 'J', '\0' };
3031 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
3032 
3033 	/* Clear screen and move to top left */
3034 	printf("%s%s", clr, top_left);
3035 
3036 	printf("\nPort statistics ====================================");
3037 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
3038 		nic_stats_display(fwd_ports_ids[i]);
3039 }
3040 
3041 static void
3042 signal_handler(int signum)
3043 {
3044 	if (signum == SIGINT || signum == SIGTERM) {
3045 		printf("\nSignal %d received, preparing to exit...\n",
3046 				signum);
3047 #ifdef RTE_LIBRTE_PDUMP
3048 		/* uninitialize packet capture framework */
3049 		rte_pdump_uninit();
3050 #endif
3051 #ifdef RTE_LIBRTE_LATENCY_STATS
3052 		rte_latencystats_uninit();
3053 #endif
3054 		force_quit();
3055 		/* Set flag to indicate the force termination. */
3056 		f_quit = 1;
3057 		/* exit with the expected status */
3058 		signal(signum, SIG_DFL);
3059 		kill(getpid(), signum);
3060 	}
3061 }
3062 
3063 int
3064 main(int argc, char** argv)
3065 {
3066 	int diag;
3067 	portid_t port_id;
3068 	uint16_t count;
3069 	int ret;
3070 
3071 	signal(SIGINT, signal_handler);
3072 	signal(SIGTERM, signal_handler);
3073 
3074 	diag = rte_eal_init(argc, argv);
3075 	if (diag < 0)
3076 		rte_panic("Cannot init EAL\n");
3077 
3078 	testpmd_logtype = rte_log_register("testpmd");
3079 	if (testpmd_logtype < 0)
3080 		rte_panic("Cannot register log type");
3081 	rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
3082 
3083 #ifdef RTE_LIBRTE_PDUMP
3084 	/* initialize packet capture framework */
3085 	rte_pdump_init(NULL);
3086 #endif
3087 
3088 	count = 0;
3089 	RTE_ETH_FOREACH_DEV(port_id) {
3090 		ports_ids[count] = port_id;
3091 		count++;
3092 	}
3093 	nb_ports = (portid_t) count;
3094 	if (nb_ports == 0)
3095 		TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
3096 
3097 	/* allocate port structures, and init them */
3098 	init_port();
3099 
3100 	set_def_fwd_config();
3101 	if (nb_lcores == 0)
3102 		rte_panic("Empty set of forwarding logical cores - check the "
3103 			  "core mask supplied in the command parameters\n");
3104 
3105 	/* Bitrate/latency stats disabled by default */
3106 #ifdef RTE_LIBRTE_BITRATE
3107 	bitrate_enabled = 0;
3108 #endif
3109 #ifdef RTE_LIBRTE_LATENCY_STATS
3110 	latencystats_enabled = 0;
3111 #endif
3112 
3113 	/* on FreeBSD, mlockall() is disabled by default */
3114 #ifdef RTE_EXEC_ENV_BSDAPP
3115 	do_mlockall = 0;
3116 #else
3117 	do_mlockall = 1;
3118 #endif
3119 
3120 	argc -= diag;
3121 	argv += diag;
3122 	if (argc > 1)
3123 		launch_args_parse(argc, argv);
3124 
3125 	if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
3126 		TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
3127 			strerror(errno));
3128 	}
3129 
3130 	if (tx_first && interactive)
3131 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
3132 				"interactive mode.\n");
3133 
3134 	if (tx_first && lsc_interrupt) {
3135 		printf("Warning: lsc_interrupt needs to be off when "
3136 				" using tx_first. Disabling.\n");
3137 		lsc_interrupt = 0;
3138 	}
3139 
3140 	if (!nb_rxq && !nb_txq)
3141 		printf("Warning: Either rx or tx queues should be non-zero\n");
3142 
3143 	if (nb_rxq > 1 && nb_rxq > nb_txq)
3144 		printf("Warning: nb_rxq=%d enables RSS configuration, "
3145 		       "but nb_txq=%d will prevent to fully test it.\n",
3146 		       nb_rxq, nb_txq);
3147 
3148 	init_config();
3149 
3150 	if (hot_plug) {
3151 		ret = rte_dev_hotplug_handle_enable();
3152 		if (ret) {
3153 			RTE_LOG(ERR, EAL,
3154 				"fail to enable hotplug handling.");
3155 			return -1;
3156 		}
3157 
3158 		ret = rte_dev_event_monitor_start();
3159 		if (ret) {
3160 			RTE_LOG(ERR, EAL,
3161 				"fail to start device event monitoring.");
3162 			return -1;
3163 		}
3164 
3165 		ret = rte_dev_event_callback_register(NULL,
3166 			eth_dev_event_callback, NULL);
3167 		if (ret) {
3168 			RTE_LOG(ERR, EAL,
3169 				"fail  to register device event callback\n");
3170 			return -1;
3171 		}
3172 	}
3173 
3174 	if (start_port(RTE_PORT_ALL) != 0)
3175 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
3176 
3177 	/* set all ports to promiscuous mode by default */
3178 	RTE_ETH_FOREACH_DEV(port_id)
3179 		rte_eth_promiscuous_enable(port_id);
3180 
3181 	/* Init metrics library */
3182 	rte_metrics_init(rte_socket_id());
3183 
3184 #ifdef RTE_LIBRTE_LATENCY_STATS
3185 	if (latencystats_enabled != 0) {
3186 		int ret = rte_latencystats_init(1, NULL);
3187 		if (ret)
3188 			printf("Warning: latencystats init()"
3189 				" returned error %d\n",	ret);
3190 		printf("Latencystats running on lcore %d\n",
3191 			latencystats_lcore_id);
3192 	}
3193 #endif
3194 
3195 	/* Setup bitrate stats */
3196 #ifdef RTE_LIBRTE_BITRATE
3197 	if (bitrate_enabled != 0) {
3198 		bitrate_data = rte_stats_bitrate_create();
3199 		if (bitrate_data == NULL)
3200 			rte_exit(EXIT_FAILURE,
3201 				"Could not allocate bitrate data.\n");
3202 		rte_stats_bitrate_reg(bitrate_data);
3203 	}
3204 #endif
3205 
3206 #ifdef RTE_LIBRTE_CMDLINE
3207 	if (strlen(cmdline_filename) != 0)
3208 		cmdline_read_from_file(cmdline_filename);
3209 
3210 	if (interactive == 1) {
3211 		if (auto_start) {
3212 			printf("Start automatic packet forwarding\n");
3213 			start_packet_forwarding(0);
3214 		}
3215 		prompt();
3216 		pmd_test_exit();
3217 	} else
3218 #endif
3219 	{
3220 		char c;
3221 		int rc;
3222 
3223 		f_quit = 0;
3224 
3225 		printf("No commandline core given, start packet forwarding\n");
3226 		start_packet_forwarding(tx_first);
3227 		if (stats_period != 0) {
3228 			uint64_t prev_time = 0, cur_time, diff_time = 0;
3229 			uint64_t timer_period;
3230 
3231 			/* Convert to number of cycles */
3232 			timer_period = stats_period * rte_get_timer_hz();
3233 
3234 			while (f_quit == 0) {
3235 				cur_time = rte_get_timer_cycles();
3236 				diff_time += cur_time - prev_time;
3237 
3238 				if (diff_time >= timer_period) {
3239 					print_stats();
3240 					/* Reset the timer */
3241 					diff_time = 0;
3242 				}
3243 				/* Sleep to avoid unnecessary checks */
3244 				prev_time = cur_time;
3245 				sleep(1);
3246 			}
3247 		}
3248 
3249 		printf("Press enter to exit\n");
3250 		rc = read(0, &c, 1);
3251 		pmd_test_exit();
3252 		if (rc < 0)
3253 			return 1;
3254 	}
3255 
3256 	return 0;
3257 }
3258