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