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