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