xref: /dpdk/app/test-pmd/testpmd.c (revision d6af1a13d7a14d062d11b37f6e31caa0f3823fe0)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <time.h>
40 #include <fcntl.h>
41 #include <sys/types.h>
42 #include <errno.h>
43 
44 #include <sys/queue.h>
45 #include <sys/stat.h>
46 
47 #include <stdint.h>
48 #include <unistd.h>
49 #include <inttypes.h>
50 
51 #include <rte_common.h>
52 #include <rte_errno.h>
53 #include <rte_byteorder.h>
54 #include <rte_log.h>
55 #include <rte_debug.h>
56 #include <rte_cycles.h>
57 #include <rte_memory.h>
58 #include <rte_memcpy.h>
59 #include <rte_memzone.h>
60 #include <rte_launch.h>
61 #include <rte_eal.h>
62 #include <rte_alarm.h>
63 #include <rte_per_lcore.h>
64 #include <rte_lcore.h>
65 #include <rte_atomic.h>
66 #include <rte_branch_prediction.h>
67 #include <rte_mempool.h>
68 #include <rte_malloc.h>
69 #include <rte_mbuf.h>
70 #include <rte_interrupts.h>
71 #include <rte_pci.h>
72 #include <rte_ether.h>
73 #include <rte_ethdev.h>
74 #include <rte_dev.h>
75 #include <rte_string_fns.h>
76 #ifdef RTE_LIBRTE_IXGBE_PMD
77 #include <rte_pmd_ixgbe.h>
78 #endif
79 #ifdef RTE_LIBRTE_PMD_XENVIRT
80 #include <rte_eth_xenvirt.h>
81 #endif
82 #ifdef RTE_LIBRTE_PDUMP
83 #include <rte_pdump.h>
84 #endif
85 #include <rte_flow.h>
86 #include <rte_metrics.h>
87 #ifdef RTE_LIBRTE_BITRATE
88 #include <rte_bitrate.h>
89 #endif
90 #ifdef RTE_LIBRTE_LATENCY_STATS
91 #include <rte_latencystats.h>
92 #endif
93 
94 #include "testpmd.h"
95 
96 uint16_t verbose_level = 0; /**< Silent by default. */
97 
98 /* use master core for command line ? */
99 uint8_t interactive = 0;
100 uint8_t auto_start = 0;
101 char cmdline_filename[PATH_MAX] = {0};
102 
103 /*
104  * NUMA support configuration.
105  * When set, the NUMA support attempts to dispatch the allocation of the
106  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
107  * probed ports among the CPU sockets 0 and 1.
108  * Otherwise, all memory is allocated from CPU socket 0.
109  */
110 uint8_t numa_support = 1; /**< numa enabled by default */
111 
112 /*
113  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
114  * not configured.
115  */
116 uint8_t socket_num = UMA_NO_CONFIG;
117 
118 /*
119  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
120  */
121 uint8_t mp_anon = 0;
122 
123 /*
124  * Record the Ethernet address of peer target ports to which packets are
125  * forwarded.
126  * Must be instantiated with the ethernet addresses of peer traffic generator
127  * ports.
128  */
129 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
130 portid_t nb_peer_eth_addrs = 0;
131 
132 /*
133  * Probed Target Environment.
134  */
135 struct rte_port *ports;	       /**< For all probed ethernet ports. */
136 portid_t nb_ports;             /**< Number of probed ethernet ports. */
137 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
138 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
139 
140 /*
141  * Test Forwarding Configuration.
142  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
143  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
144  */
145 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
146 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
147 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
148 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
149 
150 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
151 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
152 
153 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
154 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
155 
156 /*
157  * Forwarding engines.
158  */
159 struct fwd_engine * fwd_engines[] = {
160 	&io_fwd_engine,
161 	&mac_fwd_engine,
162 	&mac_swap_engine,
163 	&flow_gen_engine,
164 	&rx_only_engine,
165 	&tx_only_engine,
166 	&csum_fwd_engine,
167 	&icmp_echo_engine,
168 #ifdef RTE_LIBRTE_IEEE1588
169 	&ieee1588_fwd_engine,
170 #endif
171 	NULL,
172 };
173 
174 struct fwd_config cur_fwd_config;
175 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
176 uint32_t retry_enabled;
177 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
178 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
179 
180 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
181 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
182                                       * specified on command-line. */
183 
184 /*
185  * Configuration of packet segments used by the "txonly" processing engine.
186  */
187 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
188 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
189 	TXONLY_DEF_PACKET_LEN,
190 };
191 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
192 
193 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
194 /**< Split policy for packets to TX. */
195 
196 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
197 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
198 
199 /* current configuration is in DCB or not,0 means it is not in DCB mode */
200 uint8_t dcb_config = 0;
201 
202 /* Whether the dcb is in testing status */
203 uint8_t dcb_test = 0;
204 
205 /*
206  * Configurable number of RX/TX queues.
207  */
208 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
209 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
210 
211 /*
212  * Configurable number of RX/TX ring descriptors.
213  */
214 #define RTE_TEST_RX_DESC_DEFAULT 128
215 #define RTE_TEST_TX_DESC_DEFAULT 512
216 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
217 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
218 
219 #define RTE_PMD_PARAM_UNSET -1
220 /*
221  * Configurable values of RX and TX ring threshold registers.
222  */
223 
224 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
225 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
226 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
227 
228 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
229 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
230 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
231 
232 /*
233  * Configurable value of RX free threshold.
234  */
235 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
236 
237 /*
238  * Configurable value of RX drop enable.
239  */
240 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
241 
242 /*
243  * Configurable value of TX free threshold.
244  */
245 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
246 
247 /*
248  * Configurable value of TX RS bit threshold.
249  */
250 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
251 
252 /*
253  * Configurable value of TX queue flags.
254  */
255 int32_t txq_flags = RTE_PMD_PARAM_UNSET;
256 
257 /*
258  * Receive Side Scaling (RSS) configuration.
259  */
260 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
261 
262 /*
263  * Port topology configuration
264  */
265 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
266 
267 /*
268  * Avoids to flush all the RX streams before starts forwarding.
269  */
270 uint8_t no_flush_rx = 0; /* flush by default */
271 
272 /*
273  * Avoids to check link status when starting/stopping a port.
274  */
275 uint8_t no_link_check = 0; /* check by default */
276 
277 /*
278  * Enable link status change notification
279  */
280 uint8_t lsc_interrupt = 1; /* enabled by default */
281 
282 /*
283  * Enable device removal notification.
284  */
285 uint8_t rmv_interrupt = 1; /* enabled by default */
286 
287 /*
288  * Display or mask ether events
289  * Default to all events except VF_MBOX
290  */
291 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
292 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
293 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
294 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
295 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
296 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
297 
298 /*
299  * NIC bypass mode configuration options.
300  */
301 
302 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
303 /* The NIC bypass watchdog timeout. */
304 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
305 #endif
306 
307 
308 #ifdef RTE_LIBRTE_LATENCY_STATS
309 
310 /*
311  * Set when latency stats is enabled in the commandline
312  */
313 uint8_t latencystats_enabled;
314 
315 /*
316  * Lcore ID to serive latency statistics.
317  */
318 lcoreid_t latencystats_lcore_id = -1;
319 
320 #endif
321 
322 /*
323  * Ethernet device configuration.
324  */
325 struct rte_eth_rxmode rx_mode = {
326 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
327 	.split_hdr_size = 0,
328 	.header_split   = 0, /**< Header Split disabled. */
329 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
330 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
331 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
332 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
333 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
334 	.hw_strip_crc   = 1, /**< CRC stripping by hardware enabled. */
335 };
336 
337 struct rte_fdir_conf fdir_conf = {
338 	.mode = RTE_FDIR_MODE_NONE,
339 	.pballoc = RTE_FDIR_PBALLOC_64K,
340 	.status = RTE_FDIR_REPORT_STATUS,
341 	.mask = {
342 		.vlan_tci_mask = 0x0,
343 		.ipv4_mask     = {
344 			.src_ip = 0xFFFFFFFF,
345 			.dst_ip = 0xFFFFFFFF,
346 		},
347 		.ipv6_mask     = {
348 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
349 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
350 		},
351 		.src_port_mask = 0xFFFF,
352 		.dst_port_mask = 0xFFFF,
353 		.mac_addr_byte_mask = 0xFF,
354 		.tunnel_type_mask = 1,
355 		.tunnel_id_mask = 0xFFFFFFFF,
356 	},
357 	.drop_queue = 127,
358 };
359 
360 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
361 
362 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
363 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
364 
365 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
366 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
367 
368 uint16_t nb_tx_queue_stats_mappings = 0;
369 uint16_t nb_rx_queue_stats_mappings = 0;
370 
371 unsigned int num_sockets = 0;
372 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
373 
374 #ifdef RTE_LIBRTE_BITRATE
375 /* Bitrate statistics */
376 struct rte_stats_bitrates *bitrate_data;
377 lcoreid_t bitrate_lcore_id;
378 uint8_t bitrate_enabled;
379 #endif
380 
381 /* Forward function declarations */
382 static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
383 static void check_all_ports_link_status(uint32_t port_mask);
384 static int eth_event_callback(uint8_t port_id,
385 			      enum rte_eth_event_type type,
386 			      void *param, void *ret_param);
387 
388 /*
389  * Check if all the ports are started.
390  * If yes, return positive value. If not, return zero.
391  */
392 static int all_ports_started(void);
393 
394 /*
395  * Helper function to check if socket is already discovered.
396  * If yes, return positive value. If not, return zero.
397  */
398 int
399 new_socket_id(unsigned int socket_id)
400 {
401 	unsigned int i;
402 
403 	for (i = 0; i < num_sockets; i++) {
404 		if (socket_ids[i] == socket_id)
405 			return 0;
406 	}
407 	return 1;
408 }
409 
410 /*
411  * Setup default configuration.
412  */
413 static void
414 set_default_fwd_lcores_config(void)
415 {
416 	unsigned int i;
417 	unsigned int nb_lc;
418 	unsigned int sock_num;
419 
420 	nb_lc = 0;
421 	for (i = 0; i < RTE_MAX_LCORE; i++) {
422 		sock_num = rte_lcore_to_socket_id(i);
423 		if (new_socket_id(sock_num)) {
424 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
425 				rte_exit(EXIT_FAILURE,
426 					 "Total sockets greater than %u\n",
427 					 RTE_MAX_NUMA_NODES);
428 			}
429 			socket_ids[num_sockets++] = sock_num;
430 		}
431 		if (!rte_lcore_is_enabled(i))
432 			continue;
433 		if (i == rte_get_master_lcore())
434 			continue;
435 		fwd_lcores_cpuids[nb_lc++] = i;
436 	}
437 	nb_lcores = (lcoreid_t) nb_lc;
438 	nb_cfg_lcores = nb_lcores;
439 	nb_fwd_lcores = 1;
440 }
441 
442 static void
443 set_def_peer_eth_addrs(void)
444 {
445 	portid_t i;
446 
447 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
448 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
449 		peer_eth_addrs[i].addr_bytes[5] = i;
450 	}
451 }
452 
453 static void
454 set_default_fwd_ports_config(void)
455 {
456 	portid_t pt_id;
457 
458 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
459 		fwd_ports_ids[pt_id] = pt_id;
460 
461 	nb_cfg_ports = nb_ports;
462 	nb_fwd_ports = nb_ports;
463 }
464 
465 void
466 set_def_fwd_config(void)
467 {
468 	set_default_fwd_lcores_config();
469 	set_def_peer_eth_addrs();
470 	set_default_fwd_ports_config();
471 }
472 
473 /*
474  * Configuration initialisation done once at init time.
475  */
476 static void
477 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
478 		 unsigned int socket_id)
479 {
480 	char pool_name[RTE_MEMPOOL_NAMESIZE];
481 	struct rte_mempool *rte_mp = NULL;
482 	uint32_t mb_size;
483 
484 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
485 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
486 
487 	RTE_LOG(INFO, USER1,
488 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
489 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
490 
491 #ifdef RTE_LIBRTE_PMD_XENVIRT
492 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
493 		(unsigned) mb_mempool_cache,
494 		sizeof(struct rte_pktmbuf_pool_private),
495 		rte_pktmbuf_pool_init, NULL,
496 		rte_pktmbuf_init, NULL,
497 		socket_id, 0);
498 #endif
499 
500 	/* if the former XEN allocation failed fall back to normal allocation */
501 	if (rte_mp == NULL) {
502 		if (mp_anon != 0) {
503 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
504 				mb_size, (unsigned) mb_mempool_cache,
505 				sizeof(struct rte_pktmbuf_pool_private),
506 				socket_id, 0);
507 			if (rte_mp == NULL)
508 				goto err;
509 
510 			if (rte_mempool_populate_anon(rte_mp) == 0) {
511 				rte_mempool_free(rte_mp);
512 				rte_mp = NULL;
513 				goto err;
514 			}
515 			rte_pktmbuf_pool_init(rte_mp, NULL);
516 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
517 		} else {
518 			/* wrapper to rte_mempool_create() */
519 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
520 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
521 		}
522 	}
523 
524 err:
525 	if (rte_mp == NULL) {
526 		rte_exit(EXIT_FAILURE,
527 			"Creation of mbuf pool for socket %u failed: %s\n",
528 			socket_id, rte_strerror(rte_errno));
529 	} else if (verbose_level > 0) {
530 		rte_mempool_dump(stdout, rte_mp);
531 	}
532 }
533 
534 /*
535  * Check given socket id is valid or not with NUMA mode,
536  * if valid, return 0, else return -1
537  */
538 static int
539 check_socket_id(const unsigned int socket_id)
540 {
541 	static int warning_once = 0;
542 
543 	if (new_socket_id(socket_id)) {
544 		if (!warning_once && numa_support)
545 			printf("Warning: NUMA should be configured manually by"
546 			       " using --port-numa-config and"
547 			       " --ring-numa-config parameters along with"
548 			       " --numa.\n");
549 		warning_once = 1;
550 		return -1;
551 	}
552 	return 0;
553 }
554 
555 static void
556 init_config(void)
557 {
558 	portid_t pid;
559 	struct rte_port *port;
560 	struct rte_mempool *mbp;
561 	unsigned int nb_mbuf_per_pool;
562 	lcoreid_t  lc_id;
563 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
564 
565 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
566 
567 	if (numa_support) {
568 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
569 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
570 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
571 	}
572 
573 	/* Configuration of logical cores. */
574 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
575 				sizeof(struct fwd_lcore *) * nb_lcores,
576 				RTE_CACHE_LINE_SIZE);
577 	if (fwd_lcores == NULL) {
578 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
579 							"failed\n", nb_lcores);
580 	}
581 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
582 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
583 					       sizeof(struct fwd_lcore),
584 					       RTE_CACHE_LINE_SIZE);
585 		if (fwd_lcores[lc_id] == NULL) {
586 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
587 								"failed\n");
588 		}
589 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
590 	}
591 
592 	RTE_ETH_FOREACH_DEV(pid) {
593 		port = &ports[pid];
594 		rte_eth_dev_info_get(pid, &port->dev_info);
595 
596 		if (numa_support) {
597 			if (port_numa[pid] != NUMA_NO_CONFIG)
598 				port_per_socket[port_numa[pid]]++;
599 			else {
600 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
601 
602 				/* if socket_id is invalid, set to 0 */
603 				if (check_socket_id(socket_id) < 0)
604 					socket_id = 0;
605 				port_per_socket[socket_id]++;
606 			}
607 		}
608 
609 		/* set flag to initialize port/queue */
610 		port->need_reconfig = 1;
611 		port->need_reconfig_queues = 1;
612 	}
613 
614 	/*
615 	 * Create pools of mbuf.
616 	 * If NUMA support is disabled, create a single pool of mbuf in
617 	 * socket 0 memory by default.
618 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
619 	 *
620 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
621 	 * nb_txd can be configured at run time.
622 	 */
623 	if (param_total_num_mbufs)
624 		nb_mbuf_per_pool = param_total_num_mbufs;
625 	else {
626 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
627 			(nb_lcores * mb_mempool_cache) +
628 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
629 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
630 	}
631 
632 	if (numa_support) {
633 		uint8_t i;
634 
635 		for (i = 0; i < num_sockets; i++)
636 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
637 					 socket_ids[i]);
638 	} else {
639 		if (socket_num == UMA_NO_CONFIG)
640 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
641 		else
642 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
643 						 socket_num);
644 	}
645 
646 	init_port_config();
647 
648 	/*
649 	 * Records which Mbuf pool to use by each logical core, if needed.
650 	 */
651 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
652 		mbp = mbuf_pool_find(
653 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
654 
655 		if (mbp == NULL)
656 			mbp = mbuf_pool_find(0);
657 		fwd_lcores[lc_id]->mbp = mbp;
658 	}
659 
660 	/* Configuration of packet forwarding streams. */
661 	if (init_fwd_streams() < 0)
662 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
663 
664 	fwd_config_setup();
665 }
666 
667 
668 void
669 reconfig(portid_t new_port_id, unsigned socket_id)
670 {
671 	struct rte_port *port;
672 
673 	/* Reconfiguration of Ethernet ports. */
674 	port = &ports[new_port_id];
675 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
676 
677 	/* set flag to initialize port/queue */
678 	port->need_reconfig = 1;
679 	port->need_reconfig_queues = 1;
680 	port->socket_id = socket_id;
681 
682 	init_port_config();
683 }
684 
685 
686 int
687 init_fwd_streams(void)
688 {
689 	portid_t pid;
690 	struct rte_port *port;
691 	streamid_t sm_id, nb_fwd_streams_new;
692 	queueid_t q;
693 
694 	/* set socket id according to numa or not */
695 	RTE_ETH_FOREACH_DEV(pid) {
696 		port = &ports[pid];
697 		if (nb_rxq > port->dev_info.max_rx_queues) {
698 			printf("Fail: nb_rxq(%d) is greater than "
699 				"max_rx_queues(%d)\n", nb_rxq,
700 				port->dev_info.max_rx_queues);
701 			return -1;
702 		}
703 		if (nb_txq > port->dev_info.max_tx_queues) {
704 			printf("Fail: nb_txq(%d) is greater than "
705 				"max_tx_queues(%d)\n", nb_txq,
706 				port->dev_info.max_tx_queues);
707 			return -1;
708 		}
709 		if (numa_support) {
710 			if (port_numa[pid] != NUMA_NO_CONFIG)
711 				port->socket_id = port_numa[pid];
712 			else {
713 				port->socket_id = rte_eth_dev_socket_id(pid);
714 
715 				/* if socket_id is invalid, set to 0 */
716 				if (check_socket_id(port->socket_id) < 0)
717 					port->socket_id = 0;
718 			}
719 		}
720 		else {
721 			if (socket_num == UMA_NO_CONFIG)
722 				port->socket_id = 0;
723 			else
724 				port->socket_id = socket_num;
725 		}
726 	}
727 
728 	q = RTE_MAX(nb_rxq, nb_txq);
729 	if (q == 0) {
730 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
731 		return -1;
732 	}
733 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
734 	if (nb_fwd_streams_new == nb_fwd_streams)
735 		return 0;
736 	/* clear the old */
737 	if (fwd_streams != NULL) {
738 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
739 			if (fwd_streams[sm_id] == NULL)
740 				continue;
741 			rte_free(fwd_streams[sm_id]);
742 			fwd_streams[sm_id] = NULL;
743 		}
744 		rte_free(fwd_streams);
745 		fwd_streams = NULL;
746 	}
747 
748 	/* init new */
749 	nb_fwd_streams = nb_fwd_streams_new;
750 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
751 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
752 	if (fwd_streams == NULL)
753 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
754 						"failed\n", nb_fwd_streams);
755 
756 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
757 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
758 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
759 		if (fwd_streams[sm_id] == NULL)
760 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
761 								" failed\n");
762 	}
763 
764 	return 0;
765 }
766 
767 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
768 static void
769 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
770 {
771 	unsigned int total_burst;
772 	unsigned int nb_burst;
773 	unsigned int burst_stats[3];
774 	uint16_t pktnb_stats[3];
775 	uint16_t nb_pkt;
776 	int burst_percent[3];
777 
778 	/*
779 	 * First compute the total number of packet bursts and the
780 	 * two highest numbers of bursts of the same number of packets.
781 	 */
782 	total_burst = 0;
783 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
784 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
785 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
786 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
787 		if (nb_burst == 0)
788 			continue;
789 		total_burst += nb_burst;
790 		if (nb_burst > burst_stats[0]) {
791 			burst_stats[1] = burst_stats[0];
792 			pktnb_stats[1] = pktnb_stats[0];
793 			burst_stats[0] = nb_burst;
794 			pktnb_stats[0] = nb_pkt;
795 		}
796 	}
797 	if (total_burst == 0)
798 		return;
799 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
800 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
801 	       burst_percent[0], (int) pktnb_stats[0]);
802 	if (burst_stats[0] == total_burst) {
803 		printf("]\n");
804 		return;
805 	}
806 	if (burst_stats[0] + burst_stats[1] == total_burst) {
807 		printf(" + %d%% of %d pkts]\n",
808 		       100 - burst_percent[0], pktnb_stats[1]);
809 		return;
810 	}
811 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
812 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
813 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
814 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
815 		return;
816 	}
817 	printf(" + %d%% of %d pkts + %d%% of others]\n",
818 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
819 }
820 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
821 
822 static void
823 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
824 {
825 	struct rte_port *port;
826 	uint8_t i;
827 
828 	static const char *fwd_stats_border = "----------------------";
829 
830 	port = &ports[port_id];
831 	printf("\n  %s Forward statistics for port %-2d %s\n",
832 	       fwd_stats_border, port_id, fwd_stats_border);
833 
834 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
835 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
836 		       "%-"PRIu64"\n",
837 		       stats->ipackets, stats->imissed,
838 		       (uint64_t) (stats->ipackets + stats->imissed));
839 
840 		if (cur_fwd_eng == &csum_fwd_engine)
841 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
842 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
843 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
844 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
845 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
846 		}
847 
848 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
849 		       "%-"PRIu64"\n",
850 		       stats->opackets, port->tx_dropped,
851 		       (uint64_t) (stats->opackets + port->tx_dropped));
852 	}
853 	else {
854 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
855 		       "%14"PRIu64"\n",
856 		       stats->ipackets, stats->imissed,
857 		       (uint64_t) (stats->ipackets + stats->imissed));
858 
859 		if (cur_fwd_eng == &csum_fwd_engine)
860 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
861 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
862 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
863 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
864 			printf("  RX-nombufs:             %14"PRIu64"\n",
865 			       stats->rx_nombuf);
866 		}
867 
868 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
869 		       "%14"PRIu64"\n",
870 		       stats->opackets, port->tx_dropped,
871 		       (uint64_t) (stats->opackets + port->tx_dropped));
872 	}
873 
874 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
875 	if (port->rx_stream)
876 		pkt_burst_stats_display("RX",
877 			&port->rx_stream->rx_burst_stats);
878 	if (port->tx_stream)
879 		pkt_burst_stats_display("TX",
880 			&port->tx_stream->tx_burst_stats);
881 #endif
882 
883 	if (port->rx_queue_stats_mapping_enabled) {
884 		printf("\n");
885 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
886 			printf("  Stats reg %2d RX-packets:%14"PRIu64
887 			       "     RX-errors:%14"PRIu64
888 			       "    RX-bytes:%14"PRIu64"\n",
889 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
890 		}
891 		printf("\n");
892 	}
893 	if (port->tx_queue_stats_mapping_enabled) {
894 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
895 			printf("  Stats reg %2d TX-packets:%14"PRIu64
896 			       "                                 TX-bytes:%14"PRIu64"\n",
897 			       i, stats->q_opackets[i], stats->q_obytes[i]);
898 		}
899 	}
900 
901 	printf("  %s--------------------------------%s\n",
902 	       fwd_stats_border, fwd_stats_border);
903 }
904 
905 static void
906 fwd_stream_stats_display(streamid_t stream_id)
907 {
908 	struct fwd_stream *fs;
909 	static const char *fwd_top_stats_border = "-------";
910 
911 	fs = fwd_streams[stream_id];
912 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
913 	    (fs->fwd_dropped == 0))
914 		return;
915 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
916 	       "TX Port=%2d/Queue=%2d %s\n",
917 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
918 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
919 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
920 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
921 
922 	/* if checksum mode */
923 	if (cur_fwd_eng == &csum_fwd_engine) {
924 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
925 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
926 	}
927 
928 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
929 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
930 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
931 #endif
932 }
933 
934 static void
935 flush_fwd_rx_queues(void)
936 {
937 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
938 	portid_t  rxp;
939 	portid_t port_id;
940 	queueid_t rxq;
941 	uint16_t  nb_rx;
942 	uint16_t  i;
943 	uint8_t   j;
944 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
945 	uint64_t timer_period;
946 
947 	/* convert to number of cycles */
948 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
949 
950 	for (j = 0; j < 2; j++) {
951 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
952 			for (rxq = 0; rxq < nb_rxq; rxq++) {
953 				port_id = fwd_ports_ids[rxp];
954 				/**
955 				* testpmd can stuck in the below do while loop
956 				* if rte_eth_rx_burst() always returns nonzero
957 				* packets. So timer is added to exit this loop
958 				* after 1sec timer expiry.
959 				*/
960 				prev_tsc = rte_rdtsc();
961 				do {
962 					nb_rx = rte_eth_rx_burst(port_id, rxq,
963 						pkts_burst, MAX_PKT_BURST);
964 					for (i = 0; i < nb_rx; i++)
965 						rte_pktmbuf_free(pkts_burst[i]);
966 
967 					cur_tsc = rte_rdtsc();
968 					diff_tsc = cur_tsc - prev_tsc;
969 					timer_tsc += diff_tsc;
970 				} while ((nb_rx > 0) &&
971 					(timer_tsc < timer_period));
972 				timer_tsc = 0;
973 			}
974 		}
975 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
976 	}
977 }
978 
979 static void
980 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
981 {
982 	struct fwd_stream **fsm;
983 	streamid_t nb_fs;
984 	streamid_t sm_id;
985 #ifdef RTE_LIBRTE_BITRATE
986 	uint64_t tics_per_1sec;
987 	uint64_t tics_datum;
988 	uint64_t tics_current;
989 	uint8_t idx_port, cnt_ports;
990 
991 	cnt_ports = rte_eth_dev_count();
992 	tics_datum = rte_rdtsc();
993 	tics_per_1sec = rte_get_timer_hz();
994 #endif
995 	fsm = &fwd_streams[fc->stream_idx];
996 	nb_fs = fc->stream_nb;
997 	do {
998 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
999 			(*pkt_fwd)(fsm[sm_id]);
1000 #ifdef RTE_LIBRTE_BITRATE
1001 		if (bitrate_enabled != 0 &&
1002 				bitrate_lcore_id == rte_lcore_id()) {
1003 			tics_current = rte_rdtsc();
1004 			if (tics_current - tics_datum >= tics_per_1sec) {
1005 				/* Periodic bitrate calculation */
1006 				for (idx_port = 0;
1007 						idx_port < cnt_ports;
1008 						idx_port++)
1009 					rte_stats_bitrate_calc(bitrate_data,
1010 						idx_port);
1011 				tics_datum = tics_current;
1012 			}
1013 		}
1014 #endif
1015 #ifdef RTE_LIBRTE_LATENCY_STATS
1016 		if (latencystats_enabled != 0 &&
1017 				latencystats_lcore_id == rte_lcore_id())
1018 			rte_latencystats_update();
1019 #endif
1020 
1021 	} while (! fc->stopped);
1022 }
1023 
1024 static int
1025 start_pkt_forward_on_core(void *fwd_arg)
1026 {
1027 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1028 			     cur_fwd_config.fwd_eng->packet_fwd);
1029 	return 0;
1030 }
1031 
1032 /*
1033  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1034  * Used to start communication flows in network loopback test configurations.
1035  */
1036 static int
1037 run_one_txonly_burst_on_core(void *fwd_arg)
1038 {
1039 	struct fwd_lcore *fwd_lc;
1040 	struct fwd_lcore tmp_lcore;
1041 
1042 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1043 	tmp_lcore = *fwd_lc;
1044 	tmp_lcore.stopped = 1;
1045 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1046 	return 0;
1047 }
1048 
1049 /*
1050  * Launch packet forwarding:
1051  *     - Setup per-port forwarding context.
1052  *     - launch logical cores with their forwarding configuration.
1053  */
1054 static void
1055 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1056 {
1057 	port_fwd_begin_t port_fwd_begin;
1058 	unsigned int i;
1059 	unsigned int lc_id;
1060 	int diag;
1061 
1062 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1063 	if (port_fwd_begin != NULL) {
1064 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1065 			(*port_fwd_begin)(fwd_ports_ids[i]);
1066 	}
1067 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1068 		lc_id = fwd_lcores_cpuids[i];
1069 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1070 			fwd_lcores[i]->stopped = 0;
1071 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1072 						     fwd_lcores[i], lc_id);
1073 			if (diag != 0)
1074 				printf("launch lcore %u failed - diag=%d\n",
1075 				       lc_id, diag);
1076 		}
1077 	}
1078 }
1079 
1080 /*
1081  * Launch packet forwarding configuration.
1082  */
1083 void
1084 start_packet_forwarding(int with_tx_first)
1085 {
1086 	port_fwd_begin_t port_fwd_begin;
1087 	port_fwd_end_t  port_fwd_end;
1088 	struct rte_port *port;
1089 	unsigned int i;
1090 	portid_t   pt_id;
1091 	streamid_t sm_id;
1092 
1093 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1094 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1095 
1096 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1097 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1098 
1099 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1100 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1101 		(!nb_rxq || !nb_txq))
1102 		rte_exit(EXIT_FAILURE,
1103 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
1104 			cur_fwd_eng->fwd_mode_name);
1105 
1106 	if (all_ports_started() == 0) {
1107 		printf("Not all ports were started\n");
1108 		return;
1109 	}
1110 	if (test_done == 0) {
1111 		printf("Packet forwarding already started\n");
1112 		return;
1113 	}
1114 
1115 	if (init_fwd_streams() < 0) {
1116 		printf("Fail from init_fwd_streams()\n");
1117 		return;
1118 	}
1119 
1120 	if(dcb_test) {
1121 		for (i = 0; i < nb_fwd_ports; i++) {
1122 			pt_id = fwd_ports_ids[i];
1123 			port = &ports[pt_id];
1124 			if (!port->dcb_flag) {
1125 				printf("In DCB mode, all forwarding ports must "
1126                                        "be configured in this mode.\n");
1127 				return;
1128 			}
1129 		}
1130 		if (nb_fwd_lcores == 1) {
1131 			printf("In DCB mode,the nb forwarding cores "
1132                                "should be larger than 1.\n");
1133 			return;
1134 		}
1135 	}
1136 	test_done = 0;
1137 
1138 	if(!no_flush_rx)
1139 		flush_fwd_rx_queues();
1140 
1141 	fwd_config_setup();
1142 	pkt_fwd_config_display(&cur_fwd_config);
1143 	rxtx_config_display();
1144 
1145 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1146 		pt_id = fwd_ports_ids[i];
1147 		port = &ports[pt_id];
1148 		rte_eth_stats_get(pt_id, &port->stats);
1149 		port->tx_dropped = 0;
1150 
1151 		map_port_queue_stats_mapping_registers(pt_id, port);
1152 	}
1153 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1154 		fwd_streams[sm_id]->rx_packets = 0;
1155 		fwd_streams[sm_id]->tx_packets = 0;
1156 		fwd_streams[sm_id]->fwd_dropped = 0;
1157 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1158 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1159 
1160 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1161 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1162 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1163 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1164 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1165 #endif
1166 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1167 		fwd_streams[sm_id]->core_cycles = 0;
1168 #endif
1169 	}
1170 	if (with_tx_first) {
1171 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1172 		if (port_fwd_begin != NULL) {
1173 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1174 				(*port_fwd_begin)(fwd_ports_ids[i]);
1175 		}
1176 		while (with_tx_first--) {
1177 			launch_packet_forwarding(
1178 					run_one_txonly_burst_on_core);
1179 			rte_eal_mp_wait_lcore();
1180 		}
1181 		port_fwd_end = tx_only_engine.port_fwd_end;
1182 		if (port_fwd_end != NULL) {
1183 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1184 				(*port_fwd_end)(fwd_ports_ids[i]);
1185 		}
1186 	}
1187 	launch_packet_forwarding(start_pkt_forward_on_core);
1188 }
1189 
1190 void
1191 stop_packet_forwarding(void)
1192 {
1193 	struct rte_eth_stats stats;
1194 	struct rte_port *port;
1195 	port_fwd_end_t  port_fwd_end;
1196 	int i;
1197 	portid_t   pt_id;
1198 	streamid_t sm_id;
1199 	lcoreid_t  lc_id;
1200 	uint64_t total_recv;
1201 	uint64_t total_xmit;
1202 	uint64_t total_rx_dropped;
1203 	uint64_t total_tx_dropped;
1204 	uint64_t total_rx_nombuf;
1205 	uint64_t tx_dropped;
1206 	uint64_t rx_bad_ip_csum;
1207 	uint64_t rx_bad_l4_csum;
1208 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1209 	uint64_t fwd_cycles;
1210 #endif
1211 	static const char *acc_stats_border = "+++++++++++++++";
1212 
1213 	if (test_done) {
1214 		printf("Packet forwarding not started\n");
1215 		return;
1216 	}
1217 	printf("Telling cores to stop...");
1218 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1219 		fwd_lcores[lc_id]->stopped = 1;
1220 	printf("\nWaiting for lcores to finish...\n");
1221 	rte_eal_mp_wait_lcore();
1222 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1223 	if (port_fwd_end != NULL) {
1224 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1225 			pt_id = fwd_ports_ids[i];
1226 			(*port_fwd_end)(pt_id);
1227 		}
1228 	}
1229 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1230 	fwd_cycles = 0;
1231 #endif
1232 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1233 		if (cur_fwd_config.nb_fwd_streams >
1234 		    cur_fwd_config.nb_fwd_ports) {
1235 			fwd_stream_stats_display(sm_id);
1236 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1237 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1238 		} else {
1239 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1240 				fwd_streams[sm_id];
1241 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1242 				fwd_streams[sm_id];
1243 		}
1244 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1245 		tx_dropped = (uint64_t) (tx_dropped +
1246 					 fwd_streams[sm_id]->fwd_dropped);
1247 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1248 
1249 		rx_bad_ip_csum =
1250 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1251 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1252 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1253 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1254 							rx_bad_ip_csum;
1255 
1256 		rx_bad_l4_csum =
1257 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1258 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1259 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1260 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1261 							rx_bad_l4_csum;
1262 
1263 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1264 		fwd_cycles = (uint64_t) (fwd_cycles +
1265 					 fwd_streams[sm_id]->core_cycles);
1266 #endif
1267 	}
1268 	total_recv = 0;
1269 	total_xmit = 0;
1270 	total_rx_dropped = 0;
1271 	total_tx_dropped = 0;
1272 	total_rx_nombuf  = 0;
1273 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1274 		pt_id = fwd_ports_ids[i];
1275 
1276 		port = &ports[pt_id];
1277 		rte_eth_stats_get(pt_id, &stats);
1278 		stats.ipackets -= port->stats.ipackets;
1279 		port->stats.ipackets = 0;
1280 		stats.opackets -= port->stats.opackets;
1281 		port->stats.opackets = 0;
1282 		stats.ibytes   -= port->stats.ibytes;
1283 		port->stats.ibytes = 0;
1284 		stats.obytes   -= port->stats.obytes;
1285 		port->stats.obytes = 0;
1286 		stats.imissed  -= port->stats.imissed;
1287 		port->stats.imissed = 0;
1288 		stats.oerrors  -= port->stats.oerrors;
1289 		port->stats.oerrors = 0;
1290 		stats.rx_nombuf -= port->stats.rx_nombuf;
1291 		port->stats.rx_nombuf = 0;
1292 
1293 		total_recv += stats.ipackets;
1294 		total_xmit += stats.opackets;
1295 		total_rx_dropped += stats.imissed;
1296 		total_tx_dropped += port->tx_dropped;
1297 		total_rx_nombuf  += stats.rx_nombuf;
1298 
1299 		fwd_port_stats_display(pt_id, &stats);
1300 	}
1301 	printf("\n  %s Accumulated forward statistics for all ports"
1302 	       "%s\n",
1303 	       acc_stats_border, acc_stats_border);
1304 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1305 	       "%-"PRIu64"\n"
1306 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1307 	       "%-"PRIu64"\n",
1308 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1309 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1310 	if (total_rx_nombuf > 0)
1311 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1312 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1313 	       "%s\n",
1314 	       acc_stats_border, acc_stats_border);
1315 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1316 	if (total_recv > 0)
1317 		printf("\n  CPU cycles/packet=%u (total cycles="
1318 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1319 		       (unsigned int)(fwd_cycles / total_recv),
1320 		       fwd_cycles, total_recv);
1321 #endif
1322 	printf("\nDone.\n");
1323 	test_done = 1;
1324 }
1325 
1326 void
1327 dev_set_link_up(portid_t pid)
1328 {
1329 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1330 		printf("\nSet link up fail.\n");
1331 }
1332 
1333 void
1334 dev_set_link_down(portid_t pid)
1335 {
1336 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1337 		printf("\nSet link down fail.\n");
1338 }
1339 
1340 static int
1341 all_ports_started(void)
1342 {
1343 	portid_t pi;
1344 	struct rte_port *port;
1345 
1346 	RTE_ETH_FOREACH_DEV(pi) {
1347 		port = &ports[pi];
1348 		/* Check if there is a port which is not started */
1349 		if ((port->port_status != RTE_PORT_STARTED) &&
1350 			(port->slave_flag == 0))
1351 			return 0;
1352 	}
1353 
1354 	/* No port is not started */
1355 	return 1;
1356 }
1357 
1358 int
1359 all_ports_stopped(void)
1360 {
1361 	portid_t pi;
1362 	struct rte_port *port;
1363 
1364 	RTE_ETH_FOREACH_DEV(pi) {
1365 		port = &ports[pi];
1366 		if ((port->port_status != RTE_PORT_STOPPED) &&
1367 			(port->slave_flag == 0))
1368 			return 0;
1369 	}
1370 
1371 	return 1;
1372 }
1373 
1374 int
1375 port_is_started(portid_t port_id)
1376 {
1377 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1378 		return 0;
1379 
1380 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1381 		return 0;
1382 
1383 	return 1;
1384 }
1385 
1386 static int
1387 port_is_closed(portid_t port_id)
1388 {
1389 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1390 		return 0;
1391 
1392 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1393 		return 0;
1394 
1395 	return 1;
1396 }
1397 
1398 int
1399 start_port(portid_t pid)
1400 {
1401 	int diag, need_check_link_status = -1;
1402 	portid_t pi;
1403 	queueid_t qi;
1404 	struct rte_port *port;
1405 	struct ether_addr mac_addr;
1406 	enum rte_eth_event_type event_type;
1407 
1408 	if (port_id_is_invalid(pid, ENABLED_WARN))
1409 		return 0;
1410 
1411 	if(dcb_config)
1412 		dcb_test = 1;
1413 	RTE_ETH_FOREACH_DEV(pi) {
1414 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1415 			continue;
1416 
1417 		need_check_link_status = 0;
1418 		port = &ports[pi];
1419 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1420 						 RTE_PORT_HANDLING) == 0) {
1421 			printf("Port %d is now not stopped\n", pi);
1422 			continue;
1423 		}
1424 
1425 		if (port->need_reconfig > 0) {
1426 			port->need_reconfig = 0;
1427 
1428 			printf("Configuring Port %d (socket %u)\n", pi,
1429 					port->socket_id);
1430 			/* configure port */
1431 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1432 						&(port->dev_conf));
1433 			if (diag != 0) {
1434 				if (rte_atomic16_cmpset(&(port->port_status),
1435 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1436 					printf("Port %d can not be set back "
1437 							"to stopped\n", pi);
1438 				printf("Fail to configure port %d\n", pi);
1439 				/* try to reconfigure port next time */
1440 				port->need_reconfig = 1;
1441 				return -1;
1442 			}
1443 		}
1444 		if (port->need_reconfig_queues > 0) {
1445 			port->need_reconfig_queues = 0;
1446 			/* setup tx queues */
1447 			for (qi = 0; qi < nb_txq; qi++) {
1448 				if ((numa_support) &&
1449 					(txring_numa[pi] != NUMA_NO_CONFIG))
1450 					diag = rte_eth_tx_queue_setup(pi, qi,
1451 						nb_txd,txring_numa[pi],
1452 						&(port->tx_conf));
1453 				else
1454 					diag = rte_eth_tx_queue_setup(pi, qi,
1455 						nb_txd,port->socket_id,
1456 						&(port->tx_conf));
1457 
1458 				if (diag == 0)
1459 					continue;
1460 
1461 				/* Fail to setup tx queue, return */
1462 				if (rte_atomic16_cmpset(&(port->port_status),
1463 							RTE_PORT_HANDLING,
1464 							RTE_PORT_STOPPED) == 0)
1465 					printf("Port %d can not be set back "
1466 							"to stopped\n", pi);
1467 				printf("Fail to configure port %d tx queues\n", pi);
1468 				/* try to reconfigure queues next time */
1469 				port->need_reconfig_queues = 1;
1470 				return -1;
1471 			}
1472 			/* setup rx queues */
1473 			for (qi = 0; qi < nb_rxq; qi++) {
1474 				if ((numa_support) &&
1475 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1476 					struct rte_mempool * mp =
1477 						mbuf_pool_find(rxring_numa[pi]);
1478 					if (mp == NULL) {
1479 						printf("Failed to setup RX queue:"
1480 							"No mempool allocation"
1481 							" on the socket %d\n",
1482 							rxring_numa[pi]);
1483 						return -1;
1484 					}
1485 
1486 					diag = rte_eth_rx_queue_setup(pi, qi,
1487 					     nb_rxd,rxring_numa[pi],
1488 					     &(port->rx_conf),mp);
1489 				} else {
1490 					struct rte_mempool *mp =
1491 						mbuf_pool_find(port->socket_id);
1492 					if (mp == NULL) {
1493 						printf("Failed to setup RX queue:"
1494 							"No mempool allocation"
1495 							" on the socket %d\n",
1496 							port->socket_id);
1497 						return -1;
1498 					}
1499 					diag = rte_eth_rx_queue_setup(pi, qi,
1500 					     nb_rxd,port->socket_id,
1501 					     &(port->rx_conf), mp);
1502 				}
1503 				if (diag == 0)
1504 					continue;
1505 
1506 				/* Fail to setup rx queue, return */
1507 				if (rte_atomic16_cmpset(&(port->port_status),
1508 							RTE_PORT_HANDLING,
1509 							RTE_PORT_STOPPED) == 0)
1510 					printf("Port %d can not be set back "
1511 							"to stopped\n", pi);
1512 				printf("Fail to configure port %d rx queues\n", pi);
1513 				/* try to reconfigure queues next time */
1514 				port->need_reconfig_queues = 1;
1515 				return -1;
1516 			}
1517 		}
1518 
1519 		for (event_type = RTE_ETH_EVENT_UNKNOWN;
1520 		     event_type < RTE_ETH_EVENT_MAX;
1521 		     event_type++) {
1522 			diag = rte_eth_dev_callback_register(pi,
1523 							event_type,
1524 							eth_event_callback,
1525 							NULL);
1526 			if (diag) {
1527 				printf("Failed to setup even callback for event %d\n",
1528 					event_type);
1529 				return -1;
1530 			}
1531 		}
1532 
1533 		/* start port */
1534 		if (rte_eth_dev_start(pi) < 0) {
1535 			printf("Fail to start port %d\n", pi);
1536 
1537 			/* Fail to setup rx queue, return */
1538 			if (rte_atomic16_cmpset(&(port->port_status),
1539 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1540 				printf("Port %d can not be set back to "
1541 							"stopped\n", pi);
1542 			continue;
1543 		}
1544 
1545 		if (rte_atomic16_cmpset(&(port->port_status),
1546 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1547 			printf("Port %d can not be set into started\n", pi);
1548 
1549 		rte_eth_macaddr_get(pi, &mac_addr);
1550 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1551 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1552 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1553 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1554 
1555 		/* at least one port started, need checking link status */
1556 		need_check_link_status = 1;
1557 	}
1558 
1559 	if (need_check_link_status == 1 && !no_link_check)
1560 		check_all_ports_link_status(RTE_PORT_ALL);
1561 	else if (need_check_link_status == 0)
1562 		printf("Please stop the ports first\n");
1563 
1564 	printf("Done\n");
1565 	return 0;
1566 }
1567 
1568 void
1569 stop_port(portid_t pid)
1570 {
1571 	portid_t pi;
1572 	struct rte_port *port;
1573 	int need_check_link_status = 0;
1574 
1575 	if (dcb_test) {
1576 		dcb_test = 0;
1577 		dcb_config = 0;
1578 	}
1579 
1580 	if (port_id_is_invalid(pid, ENABLED_WARN))
1581 		return;
1582 
1583 	printf("Stopping ports...\n");
1584 
1585 	RTE_ETH_FOREACH_DEV(pi) {
1586 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1587 			continue;
1588 
1589 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1590 			printf("Please remove port %d from forwarding configuration.\n", pi);
1591 			continue;
1592 		}
1593 
1594 		if (port_is_bonding_slave(pi)) {
1595 			printf("Please remove port %d from bonded device.\n", pi);
1596 			continue;
1597 		}
1598 
1599 		port = &ports[pi];
1600 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1601 						RTE_PORT_HANDLING) == 0)
1602 			continue;
1603 
1604 		rte_eth_dev_stop(pi);
1605 
1606 		if (rte_atomic16_cmpset(&(port->port_status),
1607 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1608 			printf("Port %d can not be set into stopped\n", pi);
1609 		need_check_link_status = 1;
1610 	}
1611 	if (need_check_link_status && !no_link_check)
1612 		check_all_ports_link_status(RTE_PORT_ALL);
1613 
1614 	printf("Done\n");
1615 }
1616 
1617 void
1618 close_port(portid_t pid)
1619 {
1620 	portid_t pi;
1621 	struct rte_port *port;
1622 
1623 	if (port_id_is_invalid(pid, ENABLED_WARN))
1624 		return;
1625 
1626 	printf("Closing ports...\n");
1627 
1628 	RTE_ETH_FOREACH_DEV(pi) {
1629 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1630 			continue;
1631 
1632 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1633 			printf("Please remove port %d from forwarding configuration.\n", pi);
1634 			continue;
1635 		}
1636 
1637 		if (port_is_bonding_slave(pi)) {
1638 			printf("Please remove port %d from bonded device.\n", pi);
1639 			continue;
1640 		}
1641 
1642 		port = &ports[pi];
1643 		if (rte_atomic16_cmpset(&(port->port_status),
1644 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1645 			printf("Port %d is already closed\n", pi);
1646 			continue;
1647 		}
1648 
1649 		if (rte_atomic16_cmpset(&(port->port_status),
1650 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1651 			printf("Port %d is now not stopped\n", pi);
1652 			continue;
1653 		}
1654 
1655 		if (port->flow_list)
1656 			port_flow_flush(pi);
1657 		rte_eth_dev_close(pi);
1658 
1659 		if (rte_atomic16_cmpset(&(port->port_status),
1660 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1661 			printf("Port %d cannot be set to closed\n", pi);
1662 	}
1663 
1664 	printf("Done\n");
1665 }
1666 
1667 void
1668 attach_port(char *identifier)
1669 {
1670 	portid_t pi = 0;
1671 	unsigned int socket_id;
1672 
1673 	printf("Attaching a new port...\n");
1674 
1675 	if (identifier == NULL) {
1676 		printf("Invalid parameters are specified\n");
1677 		return;
1678 	}
1679 
1680 	if (rte_eth_dev_attach(identifier, &pi))
1681 		return;
1682 
1683 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1684 	/* if socket_id is invalid, set to 0 */
1685 	if (check_socket_id(socket_id) < 0)
1686 		socket_id = 0;
1687 	reconfig(pi, socket_id);
1688 	rte_eth_promiscuous_enable(pi);
1689 
1690 	nb_ports = rte_eth_dev_count();
1691 
1692 	ports[pi].port_status = RTE_PORT_STOPPED;
1693 
1694 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1695 	printf("Done\n");
1696 }
1697 
1698 void
1699 detach_port(uint8_t port_id)
1700 {
1701 	char name[RTE_ETH_NAME_MAX_LEN];
1702 
1703 	printf("Detaching a port...\n");
1704 
1705 	if (!port_is_closed(port_id)) {
1706 		printf("Please close port first\n");
1707 		return;
1708 	}
1709 
1710 	if (ports[port_id].flow_list)
1711 		port_flow_flush(port_id);
1712 
1713 	if (rte_eth_dev_detach(port_id, name))
1714 		return;
1715 
1716 	nb_ports = rte_eth_dev_count();
1717 
1718 	printf("Port '%s' is detached. Now total ports is %d\n",
1719 			name, nb_ports);
1720 	printf("Done\n");
1721 	return;
1722 }
1723 
1724 void
1725 pmd_test_exit(void)
1726 {
1727 	portid_t pt_id;
1728 
1729 	if (test_done == 0)
1730 		stop_packet_forwarding();
1731 
1732 	if (ports != NULL) {
1733 		no_link_check = 1;
1734 		RTE_ETH_FOREACH_DEV(pt_id) {
1735 			printf("\nShutting down port %d...\n", pt_id);
1736 			fflush(stdout);
1737 			stop_port(pt_id);
1738 			close_port(pt_id);
1739 		}
1740 	}
1741 	printf("\nBye...\n");
1742 }
1743 
1744 typedef void (*cmd_func_t)(void);
1745 struct pmd_test_command {
1746 	const char *cmd_name;
1747 	cmd_func_t cmd_func;
1748 };
1749 
1750 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1751 
1752 /* Check the link status of all ports in up to 9s, and print them finally */
1753 static void
1754 check_all_ports_link_status(uint32_t port_mask)
1755 {
1756 #define CHECK_INTERVAL 100 /* 100ms */
1757 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1758 	uint8_t portid, count, all_ports_up, print_flag = 0;
1759 	struct rte_eth_link link;
1760 
1761 	printf("Checking link statuses...\n");
1762 	fflush(stdout);
1763 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1764 		all_ports_up = 1;
1765 		RTE_ETH_FOREACH_DEV(portid) {
1766 			if ((port_mask & (1 << portid)) == 0)
1767 				continue;
1768 			memset(&link, 0, sizeof(link));
1769 			rte_eth_link_get_nowait(portid, &link);
1770 			/* print link status if flag set */
1771 			if (print_flag == 1) {
1772 				if (link.link_status)
1773 					printf("Port %d Link Up - speed %u "
1774 						"Mbps - %s\n", (uint8_t)portid,
1775 						(unsigned)link.link_speed,
1776 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1777 					("full-duplex") : ("half-duplex\n"));
1778 				else
1779 					printf("Port %d Link Down\n",
1780 						(uint8_t)portid);
1781 				continue;
1782 			}
1783 			/* clear all_ports_up flag if any link down */
1784 			if (link.link_status == ETH_LINK_DOWN) {
1785 				all_ports_up = 0;
1786 				break;
1787 			}
1788 		}
1789 		/* after finally printing all link status, get out */
1790 		if (print_flag == 1)
1791 			break;
1792 
1793 		if (all_ports_up == 0) {
1794 			fflush(stdout);
1795 			rte_delay_ms(CHECK_INTERVAL);
1796 		}
1797 
1798 		/* set the print_flag if all ports up or timeout */
1799 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1800 			print_flag = 1;
1801 		}
1802 
1803 		if (lsc_interrupt)
1804 			break;
1805 	}
1806 }
1807 
1808 static void
1809 rmv_event_callback(void *arg)
1810 {
1811 	struct rte_eth_dev *dev;
1812 	struct rte_devargs *da;
1813 	char name[32] = "";
1814 	uint8_t port_id = (intptr_t)arg;
1815 
1816 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
1817 	dev = &rte_eth_devices[port_id];
1818 	da = dev->device->devargs;
1819 
1820 	stop_port(port_id);
1821 	close_port(port_id);
1822 	if (da->type == RTE_DEVTYPE_VIRTUAL)
1823 		snprintf(name, sizeof(name), "%s", da->virt.drv_name);
1824 	else if (da->type == RTE_DEVTYPE_WHITELISTED_PCI)
1825 		rte_pci_device_name(&da->pci.addr, name, sizeof(name));
1826 	printf("removing device %s\n", name);
1827 	rte_eal_dev_detach(name);
1828 	dev->state = RTE_ETH_DEV_UNUSED;
1829 }
1830 
1831 /* This function is used by the interrupt thread */
1832 static int
1833 eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param,
1834 		  void *ret_param)
1835 {
1836 	static const char * const event_desc[] = {
1837 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
1838 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
1839 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
1840 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
1841 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
1842 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
1843 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
1844 		[RTE_ETH_EVENT_MAX] = NULL,
1845 	};
1846 
1847 	RTE_SET_USED(param);
1848 	RTE_SET_USED(ret_param);
1849 
1850 	if (type >= RTE_ETH_EVENT_MAX) {
1851 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
1852 			port_id, __func__, type);
1853 		fflush(stderr);
1854 	} else if (event_print_mask & (UINT32_C(1) << type)) {
1855 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
1856 			event_desc[type]);
1857 		fflush(stdout);
1858 	}
1859 
1860 	switch (type) {
1861 	case RTE_ETH_EVENT_INTR_RMV:
1862 		if (rte_eal_alarm_set(100000,
1863 				rmv_event_callback, (void *)(intptr_t)port_id))
1864 			fprintf(stderr, "Could not set up deferred device removal\n");
1865 		break;
1866 	default:
1867 		break;
1868 	}
1869 	return 0;
1870 }
1871 
1872 static int
1873 set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1874 {
1875 	uint16_t i;
1876 	int diag;
1877 	uint8_t mapping_found = 0;
1878 
1879 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1880 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1881 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1882 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1883 					tx_queue_stats_mappings[i].queue_id,
1884 					tx_queue_stats_mappings[i].stats_counter_id);
1885 			if (diag != 0)
1886 				return diag;
1887 			mapping_found = 1;
1888 		}
1889 	}
1890 	if (mapping_found)
1891 		port->tx_queue_stats_mapping_enabled = 1;
1892 	return 0;
1893 }
1894 
1895 static int
1896 set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1897 {
1898 	uint16_t i;
1899 	int diag;
1900 	uint8_t mapping_found = 0;
1901 
1902 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1903 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1904 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1905 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1906 					rx_queue_stats_mappings[i].queue_id,
1907 					rx_queue_stats_mappings[i].stats_counter_id);
1908 			if (diag != 0)
1909 				return diag;
1910 			mapping_found = 1;
1911 		}
1912 	}
1913 	if (mapping_found)
1914 		port->rx_queue_stats_mapping_enabled = 1;
1915 	return 0;
1916 }
1917 
1918 static void
1919 map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1920 {
1921 	int diag = 0;
1922 
1923 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1924 	if (diag != 0) {
1925 		if (diag == -ENOTSUP) {
1926 			port->tx_queue_stats_mapping_enabled = 0;
1927 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1928 		}
1929 		else
1930 			rte_exit(EXIT_FAILURE,
1931 					"set_tx_queue_stats_mapping_registers "
1932 					"failed for port id=%d diag=%d\n",
1933 					pi, diag);
1934 	}
1935 
1936 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1937 	if (diag != 0) {
1938 		if (diag == -ENOTSUP) {
1939 			port->rx_queue_stats_mapping_enabled = 0;
1940 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1941 		}
1942 		else
1943 			rte_exit(EXIT_FAILURE,
1944 					"set_rx_queue_stats_mapping_registers "
1945 					"failed for port id=%d diag=%d\n",
1946 					pi, diag);
1947 	}
1948 }
1949 
1950 static void
1951 rxtx_port_config(struct rte_port *port)
1952 {
1953 	port->rx_conf = port->dev_info.default_rxconf;
1954 	port->tx_conf = port->dev_info.default_txconf;
1955 
1956 	/* Check if any RX/TX parameters have been passed */
1957 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1958 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1959 
1960 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1961 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1962 
1963 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1964 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1965 
1966 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1967 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1968 
1969 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1970 		port->rx_conf.rx_drop_en = rx_drop_en;
1971 
1972 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1973 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1974 
1975 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1976 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1977 
1978 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1979 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1980 
1981 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1982 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1983 
1984 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1985 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1986 
1987 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1988 		port->tx_conf.txq_flags = txq_flags;
1989 }
1990 
1991 void
1992 init_port_config(void)
1993 {
1994 	portid_t pid;
1995 	struct rte_port *port;
1996 
1997 	RTE_ETH_FOREACH_DEV(pid) {
1998 		port = &ports[pid];
1999 		port->dev_conf.rxmode = rx_mode;
2000 		port->dev_conf.fdir_conf = fdir_conf;
2001 		if (nb_rxq > 1) {
2002 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2003 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2004 		} else {
2005 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2006 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2007 		}
2008 
2009 		if (port->dcb_flag == 0) {
2010 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2011 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2012 			else
2013 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2014 		}
2015 
2016 		rxtx_port_config(port);
2017 
2018 		rte_eth_macaddr_get(pid, &port->eth_addr);
2019 
2020 		map_port_queue_stats_mapping_registers(pid, port);
2021 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2022 		rte_pmd_ixgbe_bypass_init(pid);
2023 #endif
2024 
2025 		if (lsc_interrupt &&
2026 		    (rte_eth_devices[pid].data->dev_flags &
2027 		     RTE_ETH_DEV_INTR_LSC))
2028 			port->dev_conf.intr_conf.lsc = 1;
2029 		if (rmv_interrupt &&
2030 		    (rte_eth_devices[pid].data->dev_flags &
2031 		     RTE_ETH_DEV_INTR_RMV))
2032 			port->dev_conf.intr_conf.rmv = 1;
2033 	}
2034 }
2035 
2036 void set_port_slave_flag(portid_t slave_pid)
2037 {
2038 	struct rte_port *port;
2039 
2040 	port = &ports[slave_pid];
2041 	port->slave_flag = 1;
2042 }
2043 
2044 void clear_port_slave_flag(portid_t slave_pid)
2045 {
2046 	struct rte_port *port;
2047 
2048 	port = &ports[slave_pid];
2049 	port->slave_flag = 0;
2050 }
2051 
2052 uint8_t port_is_bonding_slave(portid_t slave_pid)
2053 {
2054 	struct rte_port *port;
2055 
2056 	port = &ports[slave_pid];
2057 	return port->slave_flag;
2058 }
2059 
2060 const uint16_t vlan_tags[] = {
2061 		0,  1,  2,  3,  4,  5,  6,  7,
2062 		8,  9, 10, 11,  12, 13, 14, 15,
2063 		16, 17, 18, 19, 20, 21, 22, 23,
2064 		24, 25, 26, 27, 28, 29, 30, 31
2065 };
2066 
2067 static  int
2068 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
2069 		 enum dcb_mode_enable dcb_mode,
2070 		 enum rte_eth_nb_tcs num_tcs,
2071 		 uint8_t pfc_en)
2072 {
2073 	uint8_t i;
2074 
2075 	/*
2076 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2077 	 * given above, and the number of traffic classes available for use.
2078 	 */
2079 	if (dcb_mode == DCB_VT_ENABLED) {
2080 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2081 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
2082 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2083 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2084 
2085 		/* VMDQ+DCB RX and TX configurations */
2086 		vmdq_rx_conf->enable_default_pool = 0;
2087 		vmdq_rx_conf->default_pool = 0;
2088 		vmdq_rx_conf->nb_queue_pools =
2089 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2090 		vmdq_tx_conf->nb_queue_pools =
2091 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2092 
2093 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2094 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2095 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2096 			vmdq_rx_conf->pool_map[i].pools =
2097 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2098 		}
2099 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2100 			vmdq_rx_conf->dcb_tc[i] = i;
2101 			vmdq_tx_conf->dcb_tc[i] = i;
2102 		}
2103 
2104 		/* set DCB mode of RX and TX of multiple queues */
2105 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2106 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2107 	} else {
2108 		struct rte_eth_dcb_rx_conf *rx_conf =
2109 				&eth_conf->rx_adv_conf.dcb_rx_conf;
2110 		struct rte_eth_dcb_tx_conf *tx_conf =
2111 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2112 
2113 		rx_conf->nb_tcs = num_tcs;
2114 		tx_conf->nb_tcs = num_tcs;
2115 
2116 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2117 			rx_conf->dcb_tc[i] = i % num_tcs;
2118 			tx_conf->dcb_tc[i] = i % num_tcs;
2119 		}
2120 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2121 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
2122 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2123 	}
2124 
2125 	if (pfc_en)
2126 		eth_conf->dcb_capability_en =
2127 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2128 	else
2129 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2130 
2131 	return 0;
2132 }
2133 
2134 int
2135 init_port_dcb_config(portid_t pid,
2136 		     enum dcb_mode_enable dcb_mode,
2137 		     enum rte_eth_nb_tcs num_tcs,
2138 		     uint8_t pfc_en)
2139 {
2140 	struct rte_eth_conf port_conf;
2141 	struct rte_port *rte_port;
2142 	int retval;
2143 	uint16_t i;
2144 
2145 	rte_port = &ports[pid];
2146 
2147 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2148 	/* Enter DCB configuration status */
2149 	dcb_config = 1;
2150 
2151 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
2152 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2153 	if (retval < 0)
2154 		return retval;
2155 	port_conf.rxmode.hw_vlan_filter = 1;
2156 
2157 	/**
2158 	 * Write the configuration into the device.
2159 	 * Set the numbers of RX & TX queues to 0, so
2160 	 * the RX & TX queues will not be setup.
2161 	 */
2162 	(void)rte_eth_dev_configure(pid, 0, 0, &port_conf);
2163 
2164 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
2165 
2166 	/* If dev_info.vmdq_pool_base is greater than 0,
2167 	 * the queue id of vmdq pools is started after pf queues.
2168 	 */
2169 	if (dcb_mode == DCB_VT_ENABLED &&
2170 	    rte_port->dev_info.vmdq_pool_base > 0) {
2171 		printf("VMDQ_DCB multi-queue mode is nonsensical"
2172 			" for port %d.", pid);
2173 		return -1;
2174 	}
2175 
2176 	/* Assume the ports in testpmd have the same dcb capability
2177 	 * and has the same number of rxq and txq in dcb mode
2178 	 */
2179 	if (dcb_mode == DCB_VT_ENABLED) {
2180 		if (rte_port->dev_info.max_vfs > 0) {
2181 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2182 			nb_txq = rte_port->dev_info.nb_tx_queues;
2183 		} else {
2184 			nb_rxq = rte_port->dev_info.max_rx_queues;
2185 			nb_txq = rte_port->dev_info.max_tx_queues;
2186 		}
2187 	} else {
2188 		/*if vt is disabled, use all pf queues */
2189 		if (rte_port->dev_info.vmdq_pool_base == 0) {
2190 			nb_rxq = rte_port->dev_info.max_rx_queues;
2191 			nb_txq = rte_port->dev_info.max_tx_queues;
2192 		} else {
2193 			nb_rxq = (queueid_t)num_tcs;
2194 			nb_txq = (queueid_t)num_tcs;
2195 
2196 		}
2197 	}
2198 	rx_free_thresh = 64;
2199 
2200 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2201 
2202 	rxtx_port_config(rte_port);
2203 	/* VLAN filter */
2204 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
2205 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2206 		rx_vft_set(pid, vlan_tags[i], 1);
2207 
2208 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2209 	map_port_queue_stats_mapping_registers(pid, rte_port);
2210 
2211 	rte_port->dcb_flag = 1;
2212 
2213 	return 0;
2214 }
2215 
2216 static void
2217 init_port(void)
2218 {
2219 	/* Configuration of Ethernet ports. */
2220 	ports = rte_zmalloc("testpmd: ports",
2221 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2222 			    RTE_CACHE_LINE_SIZE);
2223 	if (ports == NULL) {
2224 		rte_exit(EXIT_FAILURE,
2225 				"rte_zmalloc(%d struct rte_port) failed\n",
2226 				RTE_MAX_ETHPORTS);
2227 	}
2228 }
2229 
2230 static void
2231 force_quit(void)
2232 {
2233 	pmd_test_exit();
2234 	prompt_exit();
2235 }
2236 
2237 static void
2238 signal_handler(int signum)
2239 {
2240 	if (signum == SIGINT || signum == SIGTERM) {
2241 		printf("\nSignal %d received, preparing to exit...\n",
2242 				signum);
2243 #ifdef RTE_LIBRTE_PDUMP
2244 		/* uninitialize packet capture framework */
2245 		rte_pdump_uninit();
2246 #endif
2247 #ifdef RTE_LIBRTE_LATENCY_STATS
2248 		rte_latencystats_uninit();
2249 #endif
2250 		force_quit();
2251 		/* exit with the expected status */
2252 		signal(signum, SIG_DFL);
2253 		kill(getpid(), signum);
2254 	}
2255 }
2256 
2257 int
2258 main(int argc, char** argv)
2259 {
2260 	int  diag;
2261 	uint8_t port_id;
2262 
2263 	signal(SIGINT, signal_handler);
2264 	signal(SIGTERM, signal_handler);
2265 
2266 	diag = rte_eal_init(argc, argv);
2267 	if (diag < 0)
2268 		rte_panic("Cannot init EAL\n");
2269 
2270 #ifdef RTE_LIBRTE_PDUMP
2271 	/* initialize packet capture framework */
2272 	rte_pdump_init(NULL);
2273 #endif
2274 
2275 	nb_ports = (portid_t) rte_eth_dev_count();
2276 	if (nb_ports == 0)
2277 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2278 
2279 	/* allocate port structures, and init them */
2280 	init_port();
2281 
2282 	set_def_fwd_config();
2283 	if (nb_lcores == 0)
2284 		rte_panic("Empty set of forwarding logical cores - check the "
2285 			  "core mask supplied in the command parameters\n");
2286 
2287 	/* Bitrate/latency stats disabled by default */
2288 #ifdef RTE_LIBRTE_BITRATE
2289 	bitrate_enabled = 0;
2290 #endif
2291 #ifdef RTE_LIBRTE_LATENCY_STATS
2292 	latencystats_enabled = 0;
2293 #endif
2294 
2295 	argc -= diag;
2296 	argv += diag;
2297 	if (argc > 1)
2298 		launch_args_parse(argc, argv);
2299 
2300 	if (!nb_rxq && !nb_txq)
2301 		printf("Warning: Either rx or tx queues should be non-zero\n");
2302 
2303 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2304 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2305 		       "but nb_txq=%d will prevent to fully test it.\n",
2306 		       nb_rxq, nb_txq);
2307 
2308 	init_config();
2309 	if (start_port(RTE_PORT_ALL) != 0)
2310 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2311 
2312 	/* set all ports to promiscuous mode by default */
2313 	RTE_ETH_FOREACH_DEV(port_id)
2314 		rte_eth_promiscuous_enable(port_id);
2315 
2316 	/* Init metrics library */
2317 	rte_metrics_init(rte_socket_id());
2318 
2319 #ifdef RTE_LIBRTE_LATENCY_STATS
2320 	if (latencystats_enabled != 0) {
2321 		int ret = rte_latencystats_init(1, NULL);
2322 		if (ret)
2323 			printf("Warning: latencystats init()"
2324 				" returned error %d\n",	ret);
2325 		printf("Latencystats running on lcore %d\n",
2326 			latencystats_lcore_id);
2327 	}
2328 #endif
2329 
2330 	/* Setup bitrate stats */
2331 #ifdef RTE_LIBRTE_BITRATE
2332 	if (bitrate_enabled != 0) {
2333 		bitrate_data = rte_stats_bitrate_create();
2334 		if (bitrate_data == NULL)
2335 			rte_exit(EXIT_FAILURE,
2336 				"Could not allocate bitrate data.\n");
2337 		rte_stats_bitrate_reg(bitrate_data);
2338 	}
2339 #endif
2340 
2341 #ifdef RTE_LIBRTE_CMDLINE
2342 	if (strlen(cmdline_filename) != 0)
2343 		cmdline_read_from_file(cmdline_filename);
2344 
2345 	if (interactive == 1) {
2346 		if (auto_start) {
2347 			printf("Start automatic packet forwarding\n");
2348 			start_packet_forwarding(0);
2349 		}
2350 		prompt();
2351 		pmd_test_exit();
2352 	} else
2353 #endif
2354 	{
2355 		char c;
2356 		int rc;
2357 
2358 		printf("No commandline core given, start packet forwarding\n");
2359 		start_packet_forwarding(0);
2360 		printf("Press enter to exit\n");
2361 		rc = read(0, &c, 1);
2362 		pmd_test_exit();
2363 		if (rc < 0)
2364 			return 1;
2365 	}
2366 
2367 	return 0;
2368 }
2369