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