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