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