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