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