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