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