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