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