xref: /dpdk/app/test-pmd/testpmd.c (revision e76d7a768ce085c140e41f338f45d50118964ae3)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 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_byteorder.h>
53 #include <rte_log.h>
54 #include <rte_debug.h>
55 #include <rte_cycles.h>
56 #include <rte_memory.h>
57 #include <rte_memcpy.h>
58 #include <rte_memzone.h>
59 #include <rte_launch.h>
60 #include <rte_eal.h>
61 #include <rte_per_lcore.h>
62 #include <rte_lcore.h>
63 #include <rte_atomic.h>
64 #include <rte_branch_prediction.h>
65 #include <rte_ring.h>
66 #include <rte_mempool.h>
67 #include <rte_malloc.h>
68 #include <rte_mbuf.h>
69 #include <rte_interrupts.h>
70 #include <rte_pci.h>
71 #include <rte_ether.h>
72 #include <rte_ethdev.h>
73 #include <rte_dev.h>
74 #include <rte_string_fns.h>
75 #ifdef RTE_LIBRTE_PMD_XENVIRT
76 #include <rte_eth_xenvirt.h>
77 #endif
78 
79 #include "testpmd.h"
80 #include "mempool_osdep.h"
81 
82 uint16_t verbose_level = 0; /**< Silent by default. */
83 
84 /* use master core for command line ? */
85 uint8_t interactive = 0;
86 uint8_t auto_start = 0;
87 
88 /*
89  * NUMA support configuration.
90  * When set, the NUMA support attempts to dispatch the allocation of the
91  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
92  * probed ports among the CPU sockets 0 and 1.
93  * Otherwise, all memory is allocated from CPU socket 0.
94  */
95 uint8_t numa_support = 0; /**< No numa support by default */
96 
97 /*
98  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
99  * not configured.
100  */
101 uint8_t socket_num = UMA_NO_CONFIG;
102 
103 /*
104  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
105  */
106 uint8_t mp_anon = 0;
107 
108 /*
109  * Record the Ethernet address of peer target ports to which packets are
110  * forwarded.
111  * Must be instanciated with the ethernet addresses of peer traffic generator
112  * ports.
113  */
114 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
115 portid_t nb_peer_eth_addrs = 0;
116 
117 /*
118  * Probed Target Environment.
119  */
120 struct rte_port *ports;	       /**< For all probed ethernet ports. */
121 portid_t nb_ports;             /**< Number of probed ethernet ports. */
122 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
123 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
124 
125 /*
126  * Test Forwarding Configuration.
127  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
128  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
129  */
130 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
131 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
132 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
133 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
134 
135 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
136 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
137 
138 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
139 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
140 
141 /*
142  * Forwarding engines.
143  */
144 struct fwd_engine * fwd_engines[] = {
145 	&io_fwd_engine,
146 	&mac_fwd_engine,
147 	&mac_retry_fwd_engine,
148 	&mac_swap_engine,
149 	&flow_gen_engine,
150 	&rx_only_engine,
151 	&tx_only_engine,
152 	&csum_fwd_engine,
153 	&icmp_echo_engine,
154 #ifdef RTE_LIBRTE_IEEE1588
155 	&ieee1588_fwd_engine,
156 #endif
157 	NULL,
158 };
159 
160 struct fwd_config cur_fwd_config;
161 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
162 
163 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
164 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
165                                       * specified on command-line. */
166 
167 /*
168  * Configuration of packet segments used by the "txonly" processing engine.
169  */
170 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
171 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
172 	TXONLY_DEF_PACKET_LEN,
173 };
174 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
175 
176 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
177 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
178 
179 /* current configuration is in DCB or not,0 means it is not in DCB mode */
180 uint8_t dcb_config = 0;
181 
182 /* Whether the dcb is in testing status */
183 uint8_t dcb_test = 0;
184 
185 /* DCB on and VT on mapping is default */
186 enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
187 
188 /*
189  * Configurable number of RX/TX queues.
190  */
191 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
192 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
193 
194 /*
195  * Configurable number of RX/TX ring descriptors.
196  */
197 #define RTE_TEST_RX_DESC_DEFAULT 128
198 #define RTE_TEST_TX_DESC_DEFAULT 512
199 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
200 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
201 
202 #define RTE_PMD_PARAM_UNSET -1
203 /*
204  * Configurable values of RX and TX ring threshold registers.
205  */
206 
207 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
208 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
209 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
210 
211 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
212 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
213 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
214 
215 /*
216  * Configurable value of RX free threshold.
217  */
218 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
219 
220 /*
221  * Configurable value of RX drop enable.
222  */
223 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
224 
225 /*
226  * Configurable value of TX free threshold.
227  */
228 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
229 
230 /*
231  * Configurable value of TX RS bit threshold.
232  */
233 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
234 
235 /*
236  * Configurable value of TX queue flags.
237  */
238 int32_t txq_flags = RTE_PMD_PARAM_UNSET;
239 
240 /*
241  * Receive Side Scaling (RSS) configuration.
242  */
243 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
244 
245 /*
246  * Port topology configuration
247  */
248 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
249 
250 /*
251  * Avoids to flush all the RX streams before starts forwarding.
252  */
253 uint8_t no_flush_rx = 0; /* flush by default */
254 
255 /*
256  * Avoids to check link status when starting/stopping a port.
257  */
258 uint8_t no_link_check = 0; /* check by default */
259 
260 /*
261  * NIC bypass mode configuration options.
262  */
263 #ifdef RTE_NIC_BYPASS
264 
265 /* The NIC bypass watchdog timeout. */
266 uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
267 
268 #endif
269 
270 /*
271  * Ethernet device configuration.
272  */
273 struct rte_eth_rxmode rx_mode = {
274 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
275 	.split_hdr_size = 0,
276 	.header_split   = 0, /**< Header Split disabled. */
277 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
278 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
279 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
280 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
281 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
282 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
283 };
284 
285 struct rte_fdir_conf fdir_conf = {
286 	.mode = RTE_FDIR_MODE_NONE,
287 	.pballoc = RTE_FDIR_PBALLOC_64K,
288 	.status = RTE_FDIR_REPORT_STATUS,
289 	.mask = {
290 		.vlan_tci_mask = 0x0,
291 		.ipv4_mask     = {
292 			.src_ip = 0xFFFFFFFF,
293 			.dst_ip = 0xFFFFFFFF,
294 		},
295 		.ipv6_mask     = {
296 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
297 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
298 		},
299 		.src_port_mask = 0xFFFF,
300 		.dst_port_mask = 0xFFFF,
301 	},
302 	.drop_queue = 127,
303 };
304 
305 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
306 
307 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
308 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
309 
310 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
311 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
312 
313 uint16_t nb_tx_queue_stats_mappings = 0;
314 uint16_t nb_rx_queue_stats_mappings = 0;
315 
316 unsigned max_socket = 0;
317 
318 /* Forward function declarations */
319 static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
320 static void check_all_ports_link_status(uint32_t port_mask);
321 
322 /*
323  * Check if all the ports are started.
324  * If yes, return positive value. If not, return zero.
325  */
326 static int all_ports_started(void);
327 
328 /*
329  * Find next enabled port
330  */
331 portid_t
332 find_next_port(portid_t p, struct rte_port *ports, int size)
333 {
334 	if (ports == NULL)
335 		rte_exit(-EINVAL, "failed to find a next port id\n");
336 
337 	while ((p < size) && (ports[p].enabled == 0))
338 		p++;
339 	return p;
340 }
341 
342 /*
343  * Setup default configuration.
344  */
345 static void
346 set_default_fwd_lcores_config(void)
347 {
348 	unsigned int i;
349 	unsigned int nb_lc;
350 	unsigned int sock_num;
351 
352 	nb_lc = 0;
353 	for (i = 0; i < RTE_MAX_LCORE; i++) {
354 		if (! rte_lcore_is_enabled(i))
355 			continue;
356 		if (i == rte_get_master_lcore())
357 			continue;
358 		fwd_lcores_cpuids[nb_lc++] = i;
359 		sock_num = rte_lcore_to_socket_id(i) + 1;
360 		if (sock_num > max_socket) {
361 			if (sock_num > RTE_MAX_NUMA_NODES)
362 				rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
363 			max_socket = sock_num;
364 		}
365 	}
366 	nb_lcores = (lcoreid_t) nb_lc;
367 	nb_cfg_lcores = nb_lcores;
368 	nb_fwd_lcores = 1;
369 }
370 
371 static void
372 set_def_peer_eth_addrs(void)
373 {
374 	portid_t i;
375 
376 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
377 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
378 		peer_eth_addrs[i].addr_bytes[5] = i;
379 	}
380 }
381 
382 static void
383 set_default_fwd_ports_config(void)
384 {
385 	portid_t pt_id;
386 
387 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
388 		fwd_ports_ids[pt_id] = pt_id;
389 
390 	nb_cfg_ports = nb_ports;
391 	nb_fwd_ports = nb_ports;
392 }
393 
394 void
395 set_def_fwd_config(void)
396 {
397 	set_default_fwd_lcores_config();
398 	set_def_peer_eth_addrs();
399 	set_default_fwd_ports_config();
400 }
401 
402 /*
403  * Configuration initialisation done once at init time.
404  */
405 static void
406 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
407 		 unsigned int socket_id)
408 {
409 	char pool_name[RTE_MEMPOOL_NAMESIZE];
410 	struct rte_mempool *rte_mp;
411 	uint32_t mb_size;
412 
413 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
414 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
415 
416 #ifdef RTE_LIBRTE_PMD_XENVIRT
417 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
418 		(unsigned) mb_mempool_cache,
419 		sizeof(struct rte_pktmbuf_pool_private),
420 		rte_pktmbuf_pool_init, NULL,
421 		rte_pktmbuf_init, NULL,
422 		socket_id, 0);
423 
424 
425 
426 #else
427 	if (mp_anon != 0)
428 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
429 				    (unsigned) mb_mempool_cache,
430 				    sizeof(struct rte_pktmbuf_pool_private),
431 				    rte_pktmbuf_pool_init, NULL,
432 				    rte_pktmbuf_init, NULL,
433 				    socket_id, 0);
434 	else
435 		/* wrapper to rte_mempool_create() */
436 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
437 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
438 
439 #endif
440 
441 	if (rte_mp == NULL) {
442 		rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
443 						"failed\n", socket_id);
444 	} else if (verbose_level > 0) {
445 		rte_mempool_dump(stdout, rte_mp);
446 	}
447 }
448 
449 /*
450  * Check given socket id is valid or not with NUMA mode,
451  * if valid, return 0, else return -1
452  */
453 static int
454 check_socket_id(const unsigned int socket_id)
455 {
456 	static int warning_once = 0;
457 
458 	if (socket_id >= max_socket) {
459 		if (!warning_once && numa_support)
460 			printf("Warning: NUMA should be configured manually by"
461 			       " using --port-numa-config and"
462 			       " --ring-numa-config parameters along with"
463 			       " --numa.\n");
464 		warning_once = 1;
465 		return -1;
466 	}
467 	return 0;
468 }
469 
470 static void
471 init_config(void)
472 {
473 	portid_t pid;
474 	struct rte_port *port;
475 	struct rte_mempool *mbp;
476 	unsigned int nb_mbuf_per_pool;
477 	lcoreid_t  lc_id;
478 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
479 
480 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
481 	/* Configuration of logical cores. */
482 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
483 				sizeof(struct fwd_lcore *) * nb_lcores,
484 				RTE_CACHE_LINE_SIZE);
485 	if (fwd_lcores == NULL) {
486 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
487 							"failed\n", nb_lcores);
488 	}
489 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
490 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
491 					       sizeof(struct fwd_lcore),
492 					       RTE_CACHE_LINE_SIZE);
493 		if (fwd_lcores[lc_id] == NULL) {
494 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
495 								"failed\n");
496 		}
497 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
498 	}
499 
500 	/*
501 	 * Create pools of mbuf.
502 	 * If NUMA support is disabled, create a single pool of mbuf in
503 	 * socket 0 memory by default.
504 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
505 	 *
506 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
507 	 * nb_txd can be configured at run time.
508 	 */
509 	if (param_total_num_mbufs)
510 		nb_mbuf_per_pool = param_total_num_mbufs;
511 	else {
512 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
513 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
514 
515 		if (!numa_support)
516 			nb_mbuf_per_pool =
517 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
518 	}
519 
520 	if (!numa_support) {
521 		if (socket_num == UMA_NO_CONFIG)
522 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
523 		else
524 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
525 						 socket_num);
526 	}
527 
528 	FOREACH_PORT(pid, ports) {
529 		port = &ports[pid];
530 		rte_eth_dev_info_get(pid, &port->dev_info);
531 
532 		if (numa_support) {
533 			if (port_numa[pid] != NUMA_NO_CONFIG)
534 				port_per_socket[port_numa[pid]]++;
535 			else {
536 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
537 
538 				/* if socket_id is invalid, set to 0 */
539 				if (check_socket_id(socket_id) < 0)
540 					socket_id = 0;
541 				port_per_socket[socket_id]++;
542 			}
543 		}
544 
545 		/* set flag to initialize port/queue */
546 		port->need_reconfig = 1;
547 		port->need_reconfig_queues = 1;
548 	}
549 
550 	if (numa_support) {
551 		uint8_t i;
552 		unsigned int nb_mbuf;
553 
554 		if (param_total_num_mbufs)
555 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
556 
557 		for (i = 0; i < max_socket; i++) {
558 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
559 			if (nb_mbuf)
560 				mbuf_pool_create(mbuf_data_size,
561 						nb_mbuf,i);
562 		}
563 	}
564 	init_port_config();
565 
566 	/*
567 	 * Records which Mbuf pool to use by each logical core, if needed.
568 	 */
569 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
570 		mbp = mbuf_pool_find(
571 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
572 
573 		if (mbp == NULL)
574 			mbp = mbuf_pool_find(0);
575 		fwd_lcores[lc_id]->mbp = mbp;
576 	}
577 
578 	/* Configuration of packet forwarding streams. */
579 	if (init_fwd_streams() < 0)
580 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
581 }
582 
583 
584 void
585 reconfig(portid_t new_port_id, unsigned socket_id)
586 {
587 	struct rte_port *port;
588 
589 	/* Reconfiguration of Ethernet ports. */
590 	port = &ports[new_port_id];
591 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
592 
593 	/* set flag to initialize port/queue */
594 	port->need_reconfig = 1;
595 	port->need_reconfig_queues = 1;
596 	port->socket_id = socket_id;
597 
598 	init_port_config();
599 }
600 
601 
602 int
603 init_fwd_streams(void)
604 {
605 	portid_t pid;
606 	struct rte_port *port;
607 	streamid_t sm_id, nb_fwd_streams_new;
608 
609 	/* set socket id according to numa or not */
610 	FOREACH_PORT(pid, ports) {
611 		port = &ports[pid];
612 		if (nb_rxq > port->dev_info.max_rx_queues) {
613 			printf("Fail: nb_rxq(%d) is greater than "
614 				"max_rx_queues(%d)\n", nb_rxq,
615 				port->dev_info.max_rx_queues);
616 			return -1;
617 		}
618 		if (nb_txq > port->dev_info.max_tx_queues) {
619 			printf("Fail: nb_txq(%d) is greater than "
620 				"max_tx_queues(%d)\n", nb_txq,
621 				port->dev_info.max_tx_queues);
622 			return -1;
623 		}
624 		if (numa_support) {
625 			if (port_numa[pid] != NUMA_NO_CONFIG)
626 				port->socket_id = port_numa[pid];
627 			else {
628 				port->socket_id = rte_eth_dev_socket_id(pid);
629 
630 				/* if socket_id is invalid, set to 0 */
631 				if (check_socket_id(port->socket_id) < 0)
632 					port->socket_id = 0;
633 			}
634 		}
635 		else {
636 			if (socket_num == UMA_NO_CONFIG)
637 				port->socket_id = 0;
638 			else
639 				port->socket_id = socket_num;
640 		}
641 	}
642 
643 	nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
644 	if (nb_fwd_streams_new == nb_fwd_streams)
645 		return 0;
646 	/* clear the old */
647 	if (fwd_streams != NULL) {
648 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
649 			if (fwd_streams[sm_id] == NULL)
650 				continue;
651 			rte_free(fwd_streams[sm_id]);
652 			fwd_streams[sm_id] = NULL;
653 		}
654 		rte_free(fwd_streams);
655 		fwd_streams = NULL;
656 	}
657 
658 	/* init new */
659 	nb_fwd_streams = nb_fwd_streams_new;
660 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
661 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
662 	if (fwd_streams == NULL)
663 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
664 						"failed\n", nb_fwd_streams);
665 
666 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
667 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
668 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
669 		if (fwd_streams[sm_id] == NULL)
670 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
671 								" failed\n");
672 	}
673 
674 	return 0;
675 }
676 
677 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
678 static void
679 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
680 {
681 	unsigned int total_burst;
682 	unsigned int nb_burst;
683 	unsigned int burst_stats[3];
684 	uint16_t pktnb_stats[3];
685 	uint16_t nb_pkt;
686 	int burst_percent[3];
687 
688 	/*
689 	 * First compute the total number of packet bursts and the
690 	 * two highest numbers of bursts of the same number of packets.
691 	 */
692 	total_burst = 0;
693 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
694 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
695 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
696 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
697 		if (nb_burst == 0)
698 			continue;
699 		total_burst += nb_burst;
700 		if (nb_burst > burst_stats[0]) {
701 			burst_stats[1] = burst_stats[0];
702 			pktnb_stats[1] = pktnb_stats[0];
703 			burst_stats[0] = nb_burst;
704 			pktnb_stats[0] = nb_pkt;
705 		}
706 	}
707 	if (total_burst == 0)
708 		return;
709 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
710 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
711 	       burst_percent[0], (int) pktnb_stats[0]);
712 	if (burst_stats[0] == total_burst) {
713 		printf("]\n");
714 		return;
715 	}
716 	if (burst_stats[0] + burst_stats[1] == total_burst) {
717 		printf(" + %d%% of %d pkts]\n",
718 		       100 - burst_percent[0], pktnb_stats[1]);
719 		return;
720 	}
721 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
722 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
723 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
724 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
725 		return;
726 	}
727 	printf(" + %d%% of %d pkts + %d%% of others]\n",
728 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
729 }
730 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
731 
732 static void
733 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
734 {
735 	struct rte_port *port;
736 	uint8_t i;
737 
738 	static const char *fwd_stats_border = "----------------------";
739 
740 	port = &ports[port_id];
741 	printf("\n  %s Forward statistics for port %-2d %s\n",
742 	       fwd_stats_border, port_id, fwd_stats_border);
743 
744 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
745 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
746 		       "%-"PRIu64"\n",
747 		       stats->ipackets, stats->imissed,
748 		       (uint64_t) (stats->ipackets + stats->imissed));
749 
750 		if (cur_fwd_eng == &csum_fwd_engine)
751 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
752 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
753 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
754 			printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
755 			       "RX-error: %-"PRIu64"\n",
756 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
757 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
758 		}
759 
760 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
761 		       "%-"PRIu64"\n",
762 		       stats->opackets, port->tx_dropped,
763 		       (uint64_t) (stats->opackets + port->tx_dropped));
764 	}
765 	else {
766 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
767 		       "%14"PRIu64"\n",
768 		       stats->ipackets, stats->imissed,
769 		       (uint64_t) (stats->ipackets + stats->imissed));
770 
771 		if (cur_fwd_eng == &csum_fwd_engine)
772 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
773 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
774 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
775 			printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
776 			       "    RX-error:%"PRIu64"\n",
777 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
778 			printf("  RX-nombufs:             %14"PRIu64"\n",
779 			       stats->rx_nombuf);
780 		}
781 
782 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
783 		       "%14"PRIu64"\n",
784 		       stats->opackets, port->tx_dropped,
785 		       (uint64_t) (stats->opackets + port->tx_dropped));
786 	}
787 
788 	/* Display statistics of XON/XOFF pause frames, if any. */
789 	if ((stats->tx_pause_xon  | stats->rx_pause_xon |
790 	     stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
791 		printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
792 		       stats->rx_pause_xoff, stats->rx_pause_xon);
793 		printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
794 		       stats->tx_pause_xoff, stats->tx_pause_xon);
795 	}
796 
797 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
798 	if (port->rx_stream)
799 		pkt_burst_stats_display("RX",
800 			&port->rx_stream->rx_burst_stats);
801 	if (port->tx_stream)
802 		pkt_burst_stats_display("TX",
803 			&port->tx_stream->tx_burst_stats);
804 #endif
805 	/* stats fdir */
806 	if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
807 		printf("  Fdirmiss:%14"PRIu64"	  Fdirmatch:%14"PRIu64"\n",
808 		       stats->fdirmiss,
809 		       stats->fdirmatch);
810 
811 	if (port->rx_queue_stats_mapping_enabled) {
812 		printf("\n");
813 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
814 			printf("  Stats reg %2d RX-packets:%14"PRIu64
815 			       "     RX-errors:%14"PRIu64
816 			       "    RX-bytes:%14"PRIu64"\n",
817 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
818 		}
819 		printf("\n");
820 	}
821 	if (port->tx_queue_stats_mapping_enabled) {
822 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
823 			printf("  Stats reg %2d TX-packets:%14"PRIu64
824 			       "                                 TX-bytes:%14"PRIu64"\n",
825 			       i, stats->q_opackets[i], stats->q_obytes[i]);
826 		}
827 	}
828 
829 	printf("  %s--------------------------------%s\n",
830 	       fwd_stats_border, fwd_stats_border);
831 }
832 
833 static void
834 fwd_stream_stats_display(streamid_t stream_id)
835 {
836 	struct fwd_stream *fs;
837 	static const char *fwd_top_stats_border = "-------";
838 
839 	fs = fwd_streams[stream_id];
840 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
841 	    (fs->fwd_dropped == 0))
842 		return;
843 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
844 	       "TX Port=%2d/Queue=%2d %s\n",
845 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
846 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
847 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
848 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
849 
850 	/* if checksum mode */
851 	if (cur_fwd_eng == &csum_fwd_engine) {
852 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
853 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
854 	}
855 
856 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
857 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
858 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
859 #endif
860 }
861 
862 static void
863 flush_fwd_rx_queues(void)
864 {
865 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
866 	portid_t  rxp;
867 	portid_t port_id;
868 	queueid_t rxq;
869 	uint16_t  nb_rx;
870 	uint16_t  i;
871 	uint8_t   j;
872 
873 	for (j = 0; j < 2; j++) {
874 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
875 			for (rxq = 0; rxq < nb_rxq; rxq++) {
876 				port_id = fwd_ports_ids[rxp];
877 				do {
878 					nb_rx = rte_eth_rx_burst(port_id, rxq,
879 						pkts_burst, MAX_PKT_BURST);
880 					for (i = 0; i < nb_rx; i++)
881 						rte_pktmbuf_free(pkts_burst[i]);
882 				} while (nb_rx > 0);
883 			}
884 		}
885 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
886 	}
887 }
888 
889 static void
890 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
891 {
892 	struct fwd_stream **fsm;
893 	streamid_t nb_fs;
894 	streamid_t sm_id;
895 
896 	fsm = &fwd_streams[fc->stream_idx];
897 	nb_fs = fc->stream_nb;
898 	do {
899 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
900 			(*pkt_fwd)(fsm[sm_id]);
901 	} while (! fc->stopped);
902 }
903 
904 static int
905 start_pkt_forward_on_core(void *fwd_arg)
906 {
907 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
908 			     cur_fwd_config.fwd_eng->packet_fwd);
909 	return 0;
910 }
911 
912 /*
913  * Run the TXONLY packet forwarding engine to send a single burst of packets.
914  * Used to start communication flows in network loopback test configurations.
915  */
916 static int
917 run_one_txonly_burst_on_core(void *fwd_arg)
918 {
919 	struct fwd_lcore *fwd_lc;
920 	struct fwd_lcore tmp_lcore;
921 
922 	fwd_lc = (struct fwd_lcore *) fwd_arg;
923 	tmp_lcore = *fwd_lc;
924 	tmp_lcore.stopped = 1;
925 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
926 	return 0;
927 }
928 
929 /*
930  * Launch packet forwarding:
931  *     - Setup per-port forwarding context.
932  *     - launch logical cores with their forwarding configuration.
933  */
934 static void
935 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
936 {
937 	port_fwd_begin_t port_fwd_begin;
938 	unsigned int i;
939 	unsigned int lc_id;
940 	int diag;
941 
942 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
943 	if (port_fwd_begin != NULL) {
944 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
945 			(*port_fwd_begin)(fwd_ports_ids[i]);
946 	}
947 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
948 		lc_id = fwd_lcores_cpuids[i];
949 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
950 			fwd_lcores[i]->stopped = 0;
951 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
952 						     fwd_lcores[i], lc_id);
953 			if (diag != 0)
954 				printf("launch lcore %u failed - diag=%d\n",
955 				       lc_id, diag);
956 		}
957 	}
958 }
959 
960 /*
961  * Launch packet forwarding configuration.
962  */
963 void
964 start_packet_forwarding(int with_tx_first)
965 {
966 	port_fwd_begin_t port_fwd_begin;
967 	port_fwd_end_t  port_fwd_end;
968 	struct rte_port *port;
969 	unsigned int i;
970 	portid_t   pt_id;
971 	streamid_t sm_id;
972 
973 	if (all_ports_started() == 0) {
974 		printf("Not all ports were started\n");
975 		return;
976 	}
977 	if (test_done == 0) {
978 		printf("Packet forwarding already started\n");
979 		return;
980 	}
981 	if(dcb_test) {
982 		for (i = 0; i < nb_fwd_ports; i++) {
983 			pt_id = fwd_ports_ids[i];
984 			port = &ports[pt_id];
985 			if (!port->dcb_flag) {
986 				printf("In DCB mode, all forwarding ports must "
987                                        "be configured in this mode.\n");
988 				return;
989 			}
990 		}
991 		if (nb_fwd_lcores == 1) {
992 			printf("In DCB mode,the nb forwarding cores "
993                                "should be larger than 1.\n");
994 			return;
995 		}
996 	}
997 	test_done = 0;
998 
999 	if(!no_flush_rx)
1000 		flush_fwd_rx_queues();
1001 
1002 	fwd_config_setup();
1003 	rxtx_config_display();
1004 
1005 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1006 		pt_id = fwd_ports_ids[i];
1007 		port = &ports[pt_id];
1008 		rte_eth_stats_get(pt_id, &port->stats);
1009 		port->tx_dropped = 0;
1010 
1011 		map_port_queue_stats_mapping_registers(pt_id, port);
1012 	}
1013 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1014 		fwd_streams[sm_id]->rx_packets = 0;
1015 		fwd_streams[sm_id]->tx_packets = 0;
1016 		fwd_streams[sm_id]->fwd_dropped = 0;
1017 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1018 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1019 
1020 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1021 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1022 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1023 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1024 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1025 #endif
1026 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1027 		fwd_streams[sm_id]->core_cycles = 0;
1028 #endif
1029 	}
1030 	if (with_tx_first) {
1031 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1032 		if (port_fwd_begin != NULL) {
1033 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1034 				(*port_fwd_begin)(fwd_ports_ids[i]);
1035 		}
1036 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1037 		rte_eal_mp_wait_lcore();
1038 		port_fwd_end = tx_only_engine.port_fwd_end;
1039 		if (port_fwd_end != NULL) {
1040 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1041 				(*port_fwd_end)(fwd_ports_ids[i]);
1042 		}
1043 	}
1044 	launch_packet_forwarding(start_pkt_forward_on_core);
1045 }
1046 
1047 void
1048 stop_packet_forwarding(void)
1049 {
1050 	struct rte_eth_stats stats;
1051 	struct rte_port *port;
1052 	port_fwd_end_t  port_fwd_end;
1053 	int i;
1054 	portid_t   pt_id;
1055 	streamid_t sm_id;
1056 	lcoreid_t  lc_id;
1057 	uint64_t total_recv;
1058 	uint64_t total_xmit;
1059 	uint64_t total_rx_dropped;
1060 	uint64_t total_tx_dropped;
1061 	uint64_t total_rx_nombuf;
1062 	uint64_t tx_dropped;
1063 	uint64_t rx_bad_ip_csum;
1064 	uint64_t rx_bad_l4_csum;
1065 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1066 	uint64_t fwd_cycles;
1067 #endif
1068 	static const char *acc_stats_border = "+++++++++++++++";
1069 
1070 	if (all_ports_started() == 0) {
1071 		printf("Not all ports were started\n");
1072 		return;
1073 	}
1074 	if (test_done) {
1075 		printf("Packet forwarding not started\n");
1076 		return;
1077 	}
1078 	printf("Telling cores to stop...");
1079 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1080 		fwd_lcores[lc_id]->stopped = 1;
1081 	printf("\nWaiting for lcores to finish...\n");
1082 	rte_eal_mp_wait_lcore();
1083 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1084 	if (port_fwd_end != NULL) {
1085 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1086 			pt_id = fwd_ports_ids[i];
1087 			(*port_fwd_end)(pt_id);
1088 		}
1089 	}
1090 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1091 	fwd_cycles = 0;
1092 #endif
1093 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1094 		if (cur_fwd_config.nb_fwd_streams >
1095 		    cur_fwd_config.nb_fwd_ports) {
1096 			fwd_stream_stats_display(sm_id);
1097 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1098 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1099 		} else {
1100 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1101 				fwd_streams[sm_id];
1102 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1103 				fwd_streams[sm_id];
1104 		}
1105 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1106 		tx_dropped = (uint64_t) (tx_dropped +
1107 					 fwd_streams[sm_id]->fwd_dropped);
1108 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1109 
1110 		rx_bad_ip_csum =
1111 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1112 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1113 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1114 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1115 							rx_bad_ip_csum;
1116 
1117 		rx_bad_l4_csum =
1118 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1119 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1120 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1121 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1122 							rx_bad_l4_csum;
1123 
1124 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1125 		fwd_cycles = (uint64_t) (fwd_cycles +
1126 					 fwd_streams[sm_id]->core_cycles);
1127 #endif
1128 	}
1129 	total_recv = 0;
1130 	total_xmit = 0;
1131 	total_rx_dropped = 0;
1132 	total_tx_dropped = 0;
1133 	total_rx_nombuf  = 0;
1134 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1135 		pt_id = fwd_ports_ids[i];
1136 
1137 		port = &ports[pt_id];
1138 		rte_eth_stats_get(pt_id, &stats);
1139 		stats.ipackets -= port->stats.ipackets;
1140 		port->stats.ipackets = 0;
1141 		stats.opackets -= port->stats.opackets;
1142 		port->stats.opackets = 0;
1143 		stats.ibytes   -= port->stats.ibytes;
1144 		port->stats.ibytes = 0;
1145 		stats.obytes   -= port->stats.obytes;
1146 		port->stats.obytes = 0;
1147 		stats.imissed  -= port->stats.imissed;
1148 		port->stats.imissed = 0;
1149 		stats.oerrors  -= port->stats.oerrors;
1150 		port->stats.oerrors = 0;
1151 		stats.rx_nombuf -= port->stats.rx_nombuf;
1152 		port->stats.rx_nombuf = 0;
1153 		stats.fdirmatch -= port->stats.fdirmatch;
1154 		port->stats.rx_nombuf = 0;
1155 		stats.fdirmiss -= port->stats.fdirmiss;
1156 		port->stats.rx_nombuf = 0;
1157 
1158 		total_recv += stats.ipackets;
1159 		total_xmit += stats.opackets;
1160 		total_rx_dropped += stats.imissed;
1161 		total_tx_dropped += port->tx_dropped;
1162 		total_rx_nombuf  += stats.rx_nombuf;
1163 
1164 		fwd_port_stats_display(pt_id, &stats);
1165 	}
1166 	printf("\n  %s Accumulated forward statistics for all ports"
1167 	       "%s\n",
1168 	       acc_stats_border, acc_stats_border);
1169 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1170 	       "%-"PRIu64"\n"
1171 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1172 	       "%-"PRIu64"\n",
1173 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1174 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1175 	if (total_rx_nombuf > 0)
1176 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1177 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1178 	       "%s\n",
1179 	       acc_stats_border, acc_stats_border);
1180 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1181 	if (total_recv > 0)
1182 		printf("\n  CPU cycles/packet=%u (total cycles="
1183 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1184 		       (unsigned int)(fwd_cycles / total_recv),
1185 		       fwd_cycles, total_recv);
1186 #endif
1187 	printf("\nDone.\n");
1188 	test_done = 1;
1189 }
1190 
1191 void
1192 dev_set_link_up(portid_t pid)
1193 {
1194 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1195 		printf("\nSet link up fail.\n");
1196 }
1197 
1198 void
1199 dev_set_link_down(portid_t pid)
1200 {
1201 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1202 		printf("\nSet link down fail.\n");
1203 }
1204 
1205 static int
1206 all_ports_started(void)
1207 {
1208 	portid_t pi;
1209 	struct rte_port *port;
1210 
1211 	FOREACH_PORT(pi, ports) {
1212 		port = &ports[pi];
1213 		/* Check if there is a port which is not started */
1214 		if ((port->port_status != RTE_PORT_STARTED) &&
1215 			(port->slave_flag == 0))
1216 			return 0;
1217 	}
1218 
1219 	/* No port is not started */
1220 	return 1;
1221 }
1222 
1223 int
1224 all_ports_stopped(void)
1225 {
1226 	portid_t pi;
1227 	struct rte_port *port;
1228 
1229 	FOREACH_PORT(pi, ports) {
1230 		port = &ports[pi];
1231 		if ((port->port_status != RTE_PORT_STOPPED) &&
1232 			(port->slave_flag == 0))
1233 			return 0;
1234 	}
1235 
1236 	return 1;
1237 }
1238 
1239 int
1240 port_is_started(portid_t port_id)
1241 {
1242 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1243 		return 0;
1244 
1245 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1246 		return 0;
1247 
1248 	return 1;
1249 }
1250 
1251 static int
1252 port_is_closed(portid_t port_id)
1253 {
1254 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1255 		return 0;
1256 
1257 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1258 		return 0;
1259 
1260 	return 1;
1261 }
1262 
1263 int
1264 start_port(portid_t pid)
1265 {
1266 	int diag, need_check_link_status = -1;
1267 	portid_t pi;
1268 	queueid_t qi;
1269 	struct rte_port *port;
1270 	struct ether_addr mac_addr;
1271 
1272 	if (test_done == 0) {
1273 		printf("Please stop forwarding first\n");
1274 		return -1;
1275 	}
1276 
1277 	if (port_id_is_invalid(pid, ENABLED_WARN))
1278 		return 0;
1279 
1280 	if (init_fwd_streams() < 0) {
1281 		printf("Fail from init_fwd_streams()\n");
1282 		return -1;
1283 	}
1284 
1285 	if(dcb_config)
1286 		dcb_test = 1;
1287 	FOREACH_PORT(pi, ports) {
1288 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1289 			continue;
1290 
1291 		need_check_link_status = 0;
1292 		port = &ports[pi];
1293 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1294 						 RTE_PORT_HANDLING) == 0) {
1295 			printf("Port %d is now not stopped\n", pi);
1296 			continue;
1297 		}
1298 
1299 		if (port->need_reconfig > 0) {
1300 			port->need_reconfig = 0;
1301 
1302 			printf("Configuring Port %d (socket %u)\n", pi,
1303 					port->socket_id);
1304 			/* configure port */
1305 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1306 						&(port->dev_conf));
1307 			if (diag != 0) {
1308 				if (rte_atomic16_cmpset(&(port->port_status),
1309 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1310 					printf("Port %d can not be set back "
1311 							"to stopped\n", pi);
1312 				printf("Fail to configure port %d\n", pi);
1313 				/* try to reconfigure port next time */
1314 				port->need_reconfig = 1;
1315 				return -1;
1316 			}
1317 		}
1318 		if (port->need_reconfig_queues > 0) {
1319 			port->need_reconfig_queues = 0;
1320 			/* setup tx queues */
1321 			for (qi = 0; qi < nb_txq; qi++) {
1322 				if ((numa_support) &&
1323 					(txring_numa[pi] != NUMA_NO_CONFIG))
1324 					diag = rte_eth_tx_queue_setup(pi, qi,
1325 						nb_txd,txring_numa[pi],
1326 						&(port->tx_conf));
1327 				else
1328 					diag = rte_eth_tx_queue_setup(pi, qi,
1329 						nb_txd,port->socket_id,
1330 						&(port->tx_conf));
1331 
1332 				if (diag == 0)
1333 					continue;
1334 
1335 				/* Fail to setup tx queue, return */
1336 				if (rte_atomic16_cmpset(&(port->port_status),
1337 							RTE_PORT_HANDLING,
1338 							RTE_PORT_STOPPED) == 0)
1339 					printf("Port %d can not be set back "
1340 							"to stopped\n", pi);
1341 				printf("Fail to configure port %d tx queues\n", pi);
1342 				/* try to reconfigure queues next time */
1343 				port->need_reconfig_queues = 1;
1344 				return -1;
1345 			}
1346 			/* setup rx queues */
1347 			for (qi = 0; qi < nb_rxq; qi++) {
1348 				if ((numa_support) &&
1349 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1350 					struct rte_mempool * mp =
1351 						mbuf_pool_find(rxring_numa[pi]);
1352 					if (mp == NULL) {
1353 						printf("Failed to setup RX queue:"
1354 							"No mempool allocation"
1355 							"on the socket %d\n",
1356 							rxring_numa[pi]);
1357 						return -1;
1358 					}
1359 
1360 					diag = rte_eth_rx_queue_setup(pi, qi,
1361 					     nb_rxd,rxring_numa[pi],
1362 					     &(port->rx_conf),mp);
1363 				}
1364 				else
1365 					diag = rte_eth_rx_queue_setup(pi, qi,
1366 					     nb_rxd,port->socket_id,
1367 					     &(port->rx_conf),
1368 				             mbuf_pool_find(port->socket_id));
1369 
1370 				if (diag == 0)
1371 					continue;
1372 
1373 
1374 				/* Fail to setup rx queue, return */
1375 				if (rte_atomic16_cmpset(&(port->port_status),
1376 							RTE_PORT_HANDLING,
1377 							RTE_PORT_STOPPED) == 0)
1378 					printf("Port %d can not be set back "
1379 							"to stopped\n", pi);
1380 				printf("Fail to configure port %d rx queues\n", pi);
1381 				/* try to reconfigure queues next time */
1382 				port->need_reconfig_queues = 1;
1383 				return -1;
1384 			}
1385 		}
1386 		/* start port */
1387 		if (rte_eth_dev_start(pi) < 0) {
1388 			printf("Fail to start port %d\n", pi);
1389 
1390 			/* Fail to setup rx queue, return */
1391 			if (rte_atomic16_cmpset(&(port->port_status),
1392 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1393 				printf("Port %d can not be set back to "
1394 							"stopped\n", pi);
1395 			continue;
1396 		}
1397 
1398 		if (rte_atomic16_cmpset(&(port->port_status),
1399 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1400 			printf("Port %d can not be set into started\n", pi);
1401 
1402 		rte_eth_macaddr_get(pi, &mac_addr);
1403 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1404 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1405 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1406 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1407 
1408 		/* at least one port started, need checking link status */
1409 		need_check_link_status = 1;
1410 	}
1411 
1412 	if (need_check_link_status == 1 && !no_link_check)
1413 		check_all_ports_link_status(RTE_PORT_ALL);
1414 	else if (need_check_link_status == 0)
1415 		printf("Please stop the ports first\n");
1416 
1417 	printf("Done\n");
1418 	return 0;
1419 }
1420 
1421 void
1422 stop_port(portid_t pid)
1423 {
1424 	portid_t pi;
1425 	struct rte_port *port;
1426 	int need_check_link_status = 0;
1427 
1428 	if (test_done == 0) {
1429 		printf("Please stop forwarding first\n");
1430 		return;
1431 	}
1432 	if (dcb_test) {
1433 		dcb_test = 0;
1434 		dcb_config = 0;
1435 	}
1436 
1437 	if (port_id_is_invalid(pid, ENABLED_WARN))
1438 		return;
1439 
1440 	printf("Stopping ports...\n");
1441 
1442 	FOREACH_PORT(pi, ports) {
1443 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1444 			continue;
1445 
1446 		port = &ports[pi];
1447 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1448 						RTE_PORT_HANDLING) == 0)
1449 			continue;
1450 
1451 		rte_eth_dev_stop(pi);
1452 
1453 		if (rte_atomic16_cmpset(&(port->port_status),
1454 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1455 			printf("Port %d can not be set into stopped\n", pi);
1456 		need_check_link_status = 1;
1457 	}
1458 	if (need_check_link_status && !no_link_check)
1459 		check_all_ports_link_status(RTE_PORT_ALL);
1460 
1461 	printf("Done\n");
1462 }
1463 
1464 void
1465 close_port(portid_t pid)
1466 {
1467 	portid_t pi;
1468 	struct rte_port *port;
1469 
1470 	if (test_done == 0) {
1471 		printf("Please stop forwarding first\n");
1472 		return;
1473 	}
1474 
1475 	if (port_id_is_invalid(pid, ENABLED_WARN))
1476 		return;
1477 
1478 	printf("Closing ports...\n");
1479 
1480 	FOREACH_PORT(pi, ports) {
1481 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1482 			continue;
1483 
1484 		port = &ports[pi];
1485 		if (rte_atomic16_cmpset(&(port->port_status),
1486 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1487 			printf("Port %d is already closed\n", pi);
1488 			continue;
1489 		}
1490 
1491 		if (rte_atomic16_cmpset(&(port->port_status),
1492 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1493 			printf("Port %d is now not stopped\n", pi);
1494 			continue;
1495 		}
1496 
1497 		rte_eth_dev_close(pi);
1498 
1499 		if (rte_atomic16_cmpset(&(port->port_status),
1500 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1501 			printf("Port %d can not be set into stopped\n", pi);
1502 	}
1503 
1504 	printf("Done\n");
1505 }
1506 
1507 void
1508 attach_port(char *identifier)
1509 {
1510 	portid_t i, j, pi = 0;
1511 
1512 	printf("Attaching a new port...\n");
1513 
1514 	if (identifier == NULL) {
1515 		printf("Invalid parameters are specified\n");
1516 		return;
1517 	}
1518 
1519 	if (test_done == 0) {
1520 		printf("Please stop forwarding first\n");
1521 		return;
1522 	}
1523 
1524 	if (rte_eth_dev_attach(identifier, &pi))
1525 		return;
1526 
1527 	ports[pi].enabled = 1;
1528 	reconfig(pi, rte_eth_dev_socket_id(pi));
1529 	rte_eth_promiscuous_enable(pi);
1530 
1531 	nb_ports = rte_eth_dev_count();
1532 
1533 	/* set_default_fwd_ports_config(); */
1534 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1535 	i = 0;
1536 	FOREACH_PORT(j, ports) {
1537 		fwd_ports_ids[i] = j;
1538 		i++;
1539 	}
1540 	nb_cfg_ports = nb_ports;
1541 	nb_fwd_ports++;
1542 
1543 	ports[pi].port_status = RTE_PORT_STOPPED;
1544 
1545 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1546 	printf("Done\n");
1547 }
1548 
1549 void
1550 detach_port(uint8_t port_id)
1551 {
1552 	portid_t i, pi = 0;
1553 	char name[RTE_ETH_NAME_MAX_LEN];
1554 
1555 	printf("Detaching a port...\n");
1556 
1557 	if (!port_is_closed(port_id)) {
1558 		printf("Please close port first\n");
1559 		return;
1560 	}
1561 
1562 	if (rte_eth_dev_detach(port_id, name))
1563 		return;
1564 
1565 	ports[port_id].enabled = 0;
1566 	nb_ports = rte_eth_dev_count();
1567 
1568 	/* set_default_fwd_ports_config(); */
1569 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1570 	i = 0;
1571 	FOREACH_PORT(pi, ports) {
1572 		fwd_ports_ids[i] = pi;
1573 		i++;
1574 	}
1575 	nb_cfg_ports = nb_ports;
1576 	nb_fwd_ports--;
1577 
1578 	printf("Port '%s' is detached. Now total ports is %d\n",
1579 			name, nb_ports);
1580 	printf("Done\n");
1581 	return;
1582 }
1583 
1584 void
1585 pmd_test_exit(void)
1586 {
1587 	portid_t pt_id;
1588 
1589 	if (test_done == 0)
1590 		stop_packet_forwarding();
1591 
1592 	FOREACH_PORT(pt_id, ports) {
1593 		printf("Stopping port %d...", pt_id);
1594 		fflush(stdout);
1595 		rte_eth_dev_close(pt_id);
1596 		printf("done\n");
1597 	}
1598 	printf("bye...\n");
1599 }
1600 
1601 typedef void (*cmd_func_t)(void);
1602 struct pmd_test_command {
1603 	const char *cmd_name;
1604 	cmd_func_t cmd_func;
1605 };
1606 
1607 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1608 
1609 /* Check the link status of all ports in up to 9s, and print them finally */
1610 static void
1611 check_all_ports_link_status(uint32_t port_mask)
1612 {
1613 #define CHECK_INTERVAL 100 /* 100ms */
1614 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1615 	uint8_t portid, count, all_ports_up, print_flag = 0;
1616 	struct rte_eth_link link;
1617 
1618 	printf("Checking link statuses...\n");
1619 	fflush(stdout);
1620 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1621 		all_ports_up = 1;
1622 		FOREACH_PORT(portid, ports) {
1623 			if ((port_mask & (1 << portid)) == 0)
1624 				continue;
1625 			memset(&link, 0, sizeof(link));
1626 			rte_eth_link_get_nowait(portid, &link);
1627 			/* print link status if flag set */
1628 			if (print_flag == 1) {
1629 				if (link.link_status)
1630 					printf("Port %d Link Up - speed %u "
1631 						"Mbps - %s\n", (uint8_t)portid,
1632 						(unsigned)link.link_speed,
1633 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1634 					("full-duplex") : ("half-duplex\n"));
1635 				else
1636 					printf("Port %d Link Down\n",
1637 						(uint8_t)portid);
1638 				continue;
1639 			}
1640 			/* clear all_ports_up flag if any link down */
1641 			if (link.link_status == 0) {
1642 				all_ports_up = 0;
1643 				break;
1644 			}
1645 		}
1646 		/* after finally printing all link status, get out */
1647 		if (print_flag == 1)
1648 			break;
1649 
1650 		if (all_ports_up == 0) {
1651 			fflush(stdout);
1652 			rte_delay_ms(CHECK_INTERVAL);
1653 		}
1654 
1655 		/* set the print_flag if all ports up or timeout */
1656 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1657 			print_flag = 1;
1658 		}
1659 	}
1660 }
1661 
1662 static int
1663 set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1664 {
1665 	uint16_t i;
1666 	int diag;
1667 	uint8_t mapping_found = 0;
1668 
1669 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1670 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1671 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1672 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1673 					tx_queue_stats_mappings[i].queue_id,
1674 					tx_queue_stats_mappings[i].stats_counter_id);
1675 			if (diag != 0)
1676 				return diag;
1677 			mapping_found = 1;
1678 		}
1679 	}
1680 	if (mapping_found)
1681 		port->tx_queue_stats_mapping_enabled = 1;
1682 	return 0;
1683 }
1684 
1685 static int
1686 set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1687 {
1688 	uint16_t i;
1689 	int diag;
1690 	uint8_t mapping_found = 0;
1691 
1692 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1693 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1694 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1695 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1696 					rx_queue_stats_mappings[i].queue_id,
1697 					rx_queue_stats_mappings[i].stats_counter_id);
1698 			if (diag != 0)
1699 				return diag;
1700 			mapping_found = 1;
1701 		}
1702 	}
1703 	if (mapping_found)
1704 		port->rx_queue_stats_mapping_enabled = 1;
1705 	return 0;
1706 }
1707 
1708 static void
1709 map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1710 {
1711 	int diag = 0;
1712 
1713 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1714 	if (diag != 0) {
1715 		if (diag == -ENOTSUP) {
1716 			port->tx_queue_stats_mapping_enabled = 0;
1717 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1718 		}
1719 		else
1720 			rte_exit(EXIT_FAILURE,
1721 					"set_tx_queue_stats_mapping_registers "
1722 					"failed for port id=%d diag=%d\n",
1723 					pi, diag);
1724 	}
1725 
1726 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1727 	if (diag != 0) {
1728 		if (diag == -ENOTSUP) {
1729 			port->rx_queue_stats_mapping_enabled = 0;
1730 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1731 		}
1732 		else
1733 			rte_exit(EXIT_FAILURE,
1734 					"set_rx_queue_stats_mapping_registers "
1735 					"failed for port id=%d diag=%d\n",
1736 					pi, diag);
1737 	}
1738 }
1739 
1740 static void
1741 rxtx_port_config(struct rte_port *port)
1742 {
1743 	port->rx_conf = port->dev_info.default_rxconf;
1744 	port->tx_conf = port->dev_info.default_txconf;
1745 
1746 	/* Check if any RX/TX parameters have been passed */
1747 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1748 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1749 
1750 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1751 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1752 
1753 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1754 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1755 
1756 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1757 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1758 
1759 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1760 		port->rx_conf.rx_drop_en = rx_drop_en;
1761 
1762 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1763 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1764 
1765 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1766 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1767 
1768 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1769 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1770 
1771 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1772 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1773 
1774 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1775 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1776 
1777 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1778 		port->tx_conf.txq_flags = txq_flags;
1779 }
1780 
1781 void
1782 init_port_config(void)
1783 {
1784 	portid_t pid;
1785 	struct rte_port *port;
1786 
1787 	FOREACH_PORT(pid, ports) {
1788 		port = &ports[pid];
1789 		port->dev_conf.rxmode = rx_mode;
1790 		port->dev_conf.fdir_conf = fdir_conf;
1791 		if (nb_rxq > 1) {
1792 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1793 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1794 		} else {
1795 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1796 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1797 		}
1798 
1799 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
1800 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1801 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
1802 			else
1803 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
1804 		}
1805 
1806 		if (port->dev_info.max_vfs != 0) {
1807 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1808 				port->dev_conf.rxmode.mq_mode =
1809 					ETH_MQ_RX_VMDQ_RSS;
1810 			else
1811 				port->dev_conf.rxmode.mq_mode =
1812 					ETH_MQ_RX_NONE;
1813 
1814 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1815 		}
1816 
1817 		rxtx_port_config(port);
1818 
1819 		rte_eth_macaddr_get(pid, &port->eth_addr);
1820 
1821 		map_port_queue_stats_mapping_registers(pid, port);
1822 #ifdef RTE_NIC_BYPASS
1823 		rte_eth_dev_bypass_init(pid);
1824 #endif
1825 	}
1826 }
1827 
1828 void set_port_slave_flag(portid_t slave_pid)
1829 {
1830 	struct rte_port *port;
1831 
1832 	port = &ports[slave_pid];
1833 	port->slave_flag = 1;
1834 }
1835 
1836 void clear_port_slave_flag(portid_t slave_pid)
1837 {
1838 	struct rte_port *port;
1839 
1840 	port = &ports[slave_pid];
1841 	port->slave_flag = 0;
1842 }
1843 
1844 const uint16_t vlan_tags[] = {
1845 		0,  1,  2,  3,  4,  5,  6,  7,
1846 		8,  9, 10, 11,  12, 13, 14, 15,
1847 		16, 17, 18, 19, 20, 21, 22, 23,
1848 		24, 25, 26, 27, 28, 29, 30, 31
1849 };
1850 
1851 static  int
1852 get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1853 {
1854         uint8_t i;
1855 
1856 	/*
1857 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1858 	 * given above, and the number of traffic classes available for use.
1859 	 */
1860 	if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1861 		struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1862 		struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1863 
1864 		/* VMDQ+DCB RX and TX configrations */
1865 		vmdq_rx_conf.enable_default_pool = 0;
1866 		vmdq_rx_conf.default_pool = 0;
1867 		vmdq_rx_conf.nb_queue_pools =
1868 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1869 		vmdq_tx_conf.nb_queue_pools =
1870 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1871 
1872 		vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1873 		for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1874 			vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1875 			vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1876 		}
1877 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1878 			vmdq_rx_conf.dcb_queue[i] = i;
1879 			vmdq_tx_conf.dcb_queue[i] = i;
1880 		}
1881 
1882 		/*set DCB mode of RX and TX of multiple queues*/
1883 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
1884 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1885 		if (dcb_conf->pfc_en)
1886 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1887 		else
1888 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1889 
1890 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1891                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1892 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1893                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1894 	}
1895 	else {
1896 		struct rte_eth_dcb_rx_conf rx_conf;
1897 		struct rte_eth_dcb_tx_conf tx_conf;
1898 
1899 		/* queue mapping configuration of DCB RX and TX */
1900 		if (dcb_conf->num_tcs == ETH_4_TCS)
1901 			dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1902 		else
1903 			dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1904 
1905 		rx_conf.nb_tcs = dcb_conf->num_tcs;
1906 		tx_conf.nb_tcs = dcb_conf->num_tcs;
1907 
1908 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1909 			rx_conf.dcb_queue[i] = i;
1910 			tx_conf.dcb_queue[i] = i;
1911 		}
1912 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
1913 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1914 		if (dcb_conf->pfc_en)
1915 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1916 		else
1917 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1918 
1919 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1920                                 sizeof(struct rte_eth_dcb_rx_conf)));
1921 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1922                                 sizeof(struct rte_eth_dcb_tx_conf)));
1923 	}
1924 
1925 	return 0;
1926 }
1927 
1928 int
1929 init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1930 {
1931 	struct rte_eth_conf port_conf;
1932 	struct rte_port *rte_port;
1933 	int retval;
1934 	uint16_t nb_vlan;
1935 	uint16_t i;
1936 
1937 	/* rxq and txq configuration in dcb mode */
1938 	nb_rxq = 128;
1939 	nb_txq = 128;
1940 	rx_free_thresh = 64;
1941 
1942 	memset(&port_conf,0,sizeof(struct rte_eth_conf));
1943 	/* Enter DCB configuration status */
1944 	dcb_config = 1;
1945 
1946 	nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1947 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
1948 	retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1949 	if (retval < 0)
1950 		return retval;
1951 
1952 	rte_port = &ports[pid];
1953 	memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1954 
1955 	rxtx_port_config(rte_port);
1956 	/* VLAN filter */
1957 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1958 	for (i = 0; i < nb_vlan; i++){
1959 		rx_vft_set(pid, vlan_tags[i], 1);
1960 	}
1961 
1962 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1963 	map_port_queue_stats_mapping_registers(pid, rte_port);
1964 
1965 	rte_port->dcb_flag = 1;
1966 
1967 	return 0;
1968 }
1969 
1970 static void
1971 init_port(void)
1972 {
1973 	portid_t pid;
1974 
1975 	/* Configuration of Ethernet ports. */
1976 	ports = rte_zmalloc("testpmd: ports",
1977 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
1978 			    RTE_CACHE_LINE_SIZE);
1979 	if (ports == NULL) {
1980 		rte_exit(EXIT_FAILURE,
1981 				"rte_zmalloc(%d struct rte_port) failed\n",
1982 				RTE_MAX_ETHPORTS);
1983 	}
1984 
1985 	/* enabled allocated ports */
1986 	for (pid = 0; pid < nb_ports; pid++)
1987 		ports[pid].enabled = 1;
1988 }
1989 
1990 int
1991 main(int argc, char** argv)
1992 {
1993 	int  diag;
1994 	uint8_t port_id;
1995 
1996 	diag = rte_eal_init(argc, argv);
1997 	if (diag < 0)
1998 		rte_panic("Cannot init EAL\n");
1999 
2000 	nb_ports = (portid_t) rte_eth_dev_count();
2001 	if (nb_ports == 0)
2002 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2003 
2004 	/* allocate port structures, and init them */
2005 	init_port();
2006 
2007 	set_def_fwd_config();
2008 	if (nb_lcores == 0)
2009 		rte_panic("Empty set of forwarding logical cores - check the "
2010 			  "core mask supplied in the command parameters\n");
2011 
2012 	argc -= diag;
2013 	argv += diag;
2014 	if (argc > 1)
2015 		launch_args_parse(argc, argv);
2016 
2017 	if (nb_rxq > nb_txq)
2018 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2019 		       "but nb_txq=%d will prevent to fully test it.\n",
2020 		       nb_rxq, nb_txq);
2021 
2022 	init_config();
2023 	if (start_port(RTE_PORT_ALL) != 0)
2024 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2025 
2026 	/* set all ports to promiscuous mode by default */
2027 	FOREACH_PORT(port_id, ports)
2028 		rte_eth_promiscuous_enable(port_id);
2029 
2030 #ifdef RTE_LIBRTE_CMDLINE
2031 	if (interactive == 1) {
2032 		if (auto_start) {
2033 			printf("Start automatic packet forwarding\n");
2034 			start_packet_forwarding(0);
2035 		}
2036 		prompt();
2037 	} else
2038 #endif
2039 	{
2040 		char c;
2041 		int rc;
2042 
2043 		printf("No commandline core given, start packet forwarding\n");
2044 		start_packet_forwarding(0);
2045 		printf("Press enter to exit\n");
2046 		rc = read(0, &c, 1);
2047 		if (rc < 0)
2048 			return 1;
2049 	}
2050 
2051 	return 0;
2052 }
2053