xref: /dpdk/app/test-pmd/testpmd.c (revision dcd962fc6b4e6012bd22710bc94ac244b3aaf7d7)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2017 Intel Corporation
3  */
4 
5 #include <stdarg.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <string.h>
10 #include <time.h>
11 #include <fcntl.h>
12 #include <sys/mman.h>
13 #include <sys/types.h>
14 #include <errno.h>
15 #include <stdbool.h>
16 
17 #include <sys/queue.h>
18 #include <sys/stat.h>
19 
20 #include <stdint.h>
21 #include <unistd.h>
22 #include <inttypes.h>
23 
24 #include <rte_common.h>
25 #include <rte_errno.h>
26 #include <rte_byteorder.h>
27 #include <rte_log.h>
28 #include <rte_debug.h>
29 #include <rte_cycles.h>
30 #include <rte_memory.h>
31 #include <rte_memcpy.h>
32 #include <rte_launch.h>
33 #include <rte_eal.h>
34 #include <rte_alarm.h>
35 #include <rte_per_lcore.h>
36 #include <rte_lcore.h>
37 #include <rte_atomic.h>
38 #include <rte_branch_prediction.h>
39 #include <rte_mempool.h>
40 #include <rte_malloc.h>
41 #include <rte_mbuf.h>
42 #include <rte_mbuf_pool_ops.h>
43 #include <rte_interrupts.h>
44 #include <rte_pci.h>
45 #include <rte_ether.h>
46 #include <rte_ethdev.h>
47 #include <rte_dev.h>
48 #include <rte_string_fns.h>
49 #ifdef RTE_LIBRTE_IXGBE_PMD
50 #include <rte_pmd_ixgbe.h>
51 #endif
52 #ifdef RTE_LIBRTE_PDUMP
53 #include <rte_pdump.h>
54 #endif
55 #include <rte_flow.h>
56 #include <rte_metrics.h>
57 #ifdef RTE_LIBRTE_BITRATE
58 #include <rte_bitrate.h>
59 #endif
60 #ifdef RTE_LIBRTE_LATENCY_STATS
61 #include <rte_latencystats.h>
62 #endif
63 
64 #include "testpmd.h"
65 
66 uint16_t verbose_level = 0; /**< Silent by default. */
67 int testpmd_logtype; /**< Log type for testpmd logs */
68 
69 /* use master core for command line ? */
70 uint8_t interactive = 0;
71 uint8_t auto_start = 0;
72 uint8_t tx_first;
73 char cmdline_filename[PATH_MAX] = {0};
74 
75 /*
76  * NUMA support configuration.
77  * When set, the NUMA support attempts to dispatch the allocation of the
78  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
79  * probed ports among the CPU sockets 0 and 1.
80  * Otherwise, all memory is allocated from CPU socket 0.
81  */
82 uint8_t numa_support = 1; /**< numa enabled by default */
83 
84 /*
85  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
86  * not configured.
87  */
88 uint8_t socket_num = UMA_NO_CONFIG;
89 
90 /*
91  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
92  */
93 uint8_t mp_anon = 0;
94 
95 /*
96  * Store specified sockets on which memory pool to be used by ports
97  * is allocated.
98  */
99 uint8_t port_numa[RTE_MAX_ETHPORTS];
100 
101 /*
102  * Store specified sockets on which RX ring to be used by ports
103  * is allocated.
104  */
105 uint8_t rxring_numa[RTE_MAX_ETHPORTS];
106 
107 /*
108  * Store specified sockets on which TX ring to be used by ports
109  * is allocated.
110  */
111 uint8_t txring_numa[RTE_MAX_ETHPORTS];
112 
113 /*
114  * Record the Ethernet address of peer target ports to which packets are
115  * forwarded.
116  * Must be instantiated with the ethernet addresses of peer traffic generator
117  * ports.
118  */
119 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
120 portid_t nb_peer_eth_addrs = 0;
121 
122 /*
123  * Probed Target Environment.
124  */
125 struct rte_port *ports;	       /**< For all probed ethernet ports. */
126 portid_t nb_ports;             /**< Number of probed ethernet ports. */
127 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
128 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
129 
130 /*
131  * Test Forwarding Configuration.
132  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
133  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
134  */
135 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
136 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
137 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
138 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
139 
140 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
141 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
142 
143 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
144 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
145 
146 /*
147  * Forwarding engines.
148  */
149 struct fwd_engine * fwd_engines[] = {
150 	&io_fwd_engine,
151 	&mac_fwd_engine,
152 	&mac_swap_engine,
153 	&flow_gen_engine,
154 	&rx_only_engine,
155 	&tx_only_engine,
156 	&csum_fwd_engine,
157 	&icmp_echo_engine,
158 #if defined RTE_LIBRTE_PMD_SOFTNIC
159 	&softnic_fwd_engine,
160 #endif
161 #ifdef RTE_LIBRTE_IEEE1588
162 	&ieee1588_fwd_engine,
163 #endif
164 	NULL,
165 };
166 
167 struct fwd_config cur_fwd_config;
168 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
169 uint32_t retry_enabled;
170 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
171 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
172 
173 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
174 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
175                                       * specified on command-line. */
176 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
177 
178 /*
179  * In container, it cannot terminate the process which running with 'stats-period'
180  * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
181  */
182 uint8_t f_quit;
183 
184 /*
185  * Configuration of packet segments used by the "txonly" processing engine.
186  */
187 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
188 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
189 	TXONLY_DEF_PACKET_LEN,
190 };
191 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
192 
193 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
194 /**< Split policy for packets to TX. */
195 
196 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
197 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
198 
199 /* current configuration is in DCB or not,0 means it is not in DCB mode */
200 uint8_t dcb_config = 0;
201 
202 /* Whether the dcb is in testing status */
203 uint8_t dcb_test = 0;
204 
205 /*
206  * Configurable number of RX/TX queues.
207  */
208 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
209 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
210 
211 /*
212  * Configurable number of RX/TX ring descriptors.
213  * Defaults are supplied by drivers via ethdev.
214  */
215 #define RTE_TEST_RX_DESC_DEFAULT 0
216 #define RTE_TEST_TX_DESC_DEFAULT 0
217 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
218 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
219 
220 #define RTE_PMD_PARAM_UNSET -1
221 /*
222  * Configurable values of RX and TX ring threshold registers.
223  */
224 
225 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
226 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
227 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
228 
229 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
230 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
231 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
232 
233 /*
234  * Configurable value of RX free threshold.
235  */
236 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
237 
238 /*
239  * Configurable value of RX drop enable.
240  */
241 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
242 
243 /*
244  * Configurable value of TX free threshold.
245  */
246 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
247 
248 /*
249  * Configurable value of TX RS bit threshold.
250  */
251 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
252 
253 /*
254  * Receive Side Scaling (RSS) configuration.
255  */
256 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
257 
258 /*
259  * Port topology configuration
260  */
261 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
262 
263 /*
264  * Avoids to flush all the RX streams before starts forwarding.
265  */
266 uint8_t no_flush_rx = 0; /* flush by default */
267 
268 /*
269  * Flow API isolated mode.
270  */
271 uint8_t flow_isolate_all;
272 
273 /*
274  * Avoids to check link status when starting/stopping a port.
275  */
276 uint8_t no_link_check = 0; /* check by default */
277 
278 /*
279  * Enable link status change notification
280  */
281 uint8_t lsc_interrupt = 1; /* enabled by default */
282 
283 /*
284  * Enable device removal notification.
285  */
286 uint8_t rmv_interrupt = 1; /* enabled by default */
287 
288 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
289 
290 /*
291  * Display or mask ether events
292  * Default to all events except VF_MBOX
293  */
294 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
295 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
296 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
297 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
298 			    (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) |
299 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
300 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
301 /*
302  * Decide if all memory are locked for performance.
303  */
304 int do_mlockall = 0;
305 
306 /*
307  * NIC bypass mode configuration options.
308  */
309 
310 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
311 /* The NIC bypass watchdog timeout. */
312 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
313 #endif
314 
315 
316 #ifdef RTE_LIBRTE_LATENCY_STATS
317 
318 /*
319  * Set when latency stats is enabled in the commandline
320  */
321 uint8_t latencystats_enabled;
322 
323 /*
324  * Lcore ID to serive latency statistics.
325  */
326 lcoreid_t latencystats_lcore_id = -1;
327 
328 #endif
329 
330 /*
331  * Ethernet device configuration.
332  */
333 struct rte_eth_rxmode rx_mode = {
334 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
335 	.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
336 };
337 
338 struct rte_eth_txmode tx_mode = {
339 	.offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
340 };
341 
342 struct rte_fdir_conf fdir_conf = {
343 	.mode = RTE_FDIR_MODE_NONE,
344 	.pballoc = RTE_FDIR_PBALLOC_64K,
345 	.status = RTE_FDIR_REPORT_STATUS,
346 	.mask = {
347 		.vlan_tci_mask = 0xFFEF,
348 		.ipv4_mask     = {
349 			.src_ip = 0xFFFFFFFF,
350 			.dst_ip = 0xFFFFFFFF,
351 		},
352 		.ipv6_mask     = {
353 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
354 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
355 		},
356 		.src_port_mask = 0xFFFF,
357 		.dst_port_mask = 0xFFFF,
358 		.mac_addr_byte_mask = 0xFF,
359 		.tunnel_type_mask = 1,
360 		.tunnel_id_mask = 0xFFFFFFFF,
361 	},
362 	.drop_queue = 127,
363 };
364 
365 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
366 
367 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
368 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
369 
370 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
371 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
372 
373 uint16_t nb_tx_queue_stats_mappings = 0;
374 uint16_t nb_rx_queue_stats_mappings = 0;
375 
376 /*
377  * Display zero values by default for xstats
378  */
379 uint8_t xstats_hide_zero;
380 
381 unsigned int num_sockets = 0;
382 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
383 
384 #ifdef RTE_LIBRTE_BITRATE
385 /* Bitrate statistics */
386 struct rte_stats_bitrates *bitrate_data;
387 lcoreid_t bitrate_lcore_id;
388 uint8_t bitrate_enabled;
389 #endif
390 
391 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
392 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
393 
394 struct vxlan_encap_conf vxlan_encap_conf = {
395 	.select_ipv4 = 1,
396 	.select_vlan = 0,
397 	.vni = "\x00\x00\x00",
398 	.udp_src = 0,
399 	.udp_dst = RTE_BE16(4789),
400 	.ipv4_src = IPv4(127, 0, 0, 1),
401 	.ipv4_dst = IPv4(255, 255, 255, 255),
402 	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
403 		"\x00\x00\x00\x00\x00\x00\x00\x01",
404 	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
405 		"\x00\x00\x00\x00\x00\x00\x11\x11",
406 	.vlan_tci = 0,
407 	.eth_src = "\x00\x00\x00\x00\x00\x00",
408 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
409 };
410 
411 struct nvgre_encap_conf nvgre_encap_conf = {
412 	.select_ipv4 = 1,
413 	.select_vlan = 0,
414 	.tni = "\x00\x00\x00",
415 	.ipv4_src = IPv4(127, 0, 0, 1),
416 	.ipv4_dst = IPv4(255, 255, 255, 255),
417 	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
418 		"\x00\x00\x00\x00\x00\x00\x00\x01",
419 	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
420 		"\x00\x00\x00\x00\x00\x00\x11\x11",
421 	.vlan_tci = 0,
422 	.eth_src = "\x00\x00\x00\x00\x00\x00",
423 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
424 };
425 
426 /* Forward function declarations */
427 static void map_port_queue_stats_mapping_registers(portid_t pi,
428 						   struct rte_port *port);
429 static void check_all_ports_link_status(uint32_t port_mask);
430 static int eth_event_callback(portid_t port_id,
431 			      enum rte_eth_event_type type,
432 			      void *param, void *ret_param);
433 static void eth_dev_event_callback(char *device_name,
434 				enum rte_dev_event_type type,
435 				void *param);
436 static int eth_dev_event_callback_register(void);
437 static int eth_dev_event_callback_unregister(void);
438 
439 
440 /*
441  * Check if all the ports are started.
442  * If yes, return positive value. If not, return zero.
443  */
444 static int all_ports_started(void);
445 
446 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
447 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
448 
449 /*
450  * Helper function to check if socket is already discovered.
451  * If yes, return positive value. If not, return zero.
452  */
453 int
454 new_socket_id(unsigned int socket_id)
455 {
456 	unsigned int i;
457 
458 	for (i = 0; i < num_sockets; i++) {
459 		if (socket_ids[i] == socket_id)
460 			return 0;
461 	}
462 	return 1;
463 }
464 
465 /*
466  * Setup default configuration.
467  */
468 static void
469 set_default_fwd_lcores_config(void)
470 {
471 	unsigned int i;
472 	unsigned int nb_lc;
473 	unsigned int sock_num;
474 
475 	nb_lc = 0;
476 	for (i = 0; i < RTE_MAX_LCORE; i++) {
477 		sock_num = rte_lcore_to_socket_id(i);
478 		if (new_socket_id(sock_num)) {
479 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
480 				rte_exit(EXIT_FAILURE,
481 					 "Total sockets greater than %u\n",
482 					 RTE_MAX_NUMA_NODES);
483 			}
484 			socket_ids[num_sockets++] = sock_num;
485 		}
486 		if (!rte_lcore_is_enabled(i))
487 			continue;
488 		if (i == rte_get_master_lcore())
489 			continue;
490 		fwd_lcores_cpuids[nb_lc++] = i;
491 	}
492 	nb_lcores = (lcoreid_t) nb_lc;
493 	nb_cfg_lcores = nb_lcores;
494 	nb_fwd_lcores = 1;
495 }
496 
497 static void
498 set_def_peer_eth_addrs(void)
499 {
500 	portid_t i;
501 
502 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
503 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
504 		peer_eth_addrs[i].addr_bytes[5] = i;
505 	}
506 }
507 
508 static void
509 set_default_fwd_ports_config(void)
510 {
511 	portid_t pt_id;
512 	int i = 0;
513 
514 	RTE_ETH_FOREACH_DEV(pt_id)
515 		fwd_ports_ids[i++] = pt_id;
516 
517 	nb_cfg_ports = nb_ports;
518 	nb_fwd_ports = nb_ports;
519 }
520 
521 void
522 set_def_fwd_config(void)
523 {
524 	set_default_fwd_lcores_config();
525 	set_def_peer_eth_addrs();
526 	set_default_fwd_ports_config();
527 }
528 
529 /*
530  * Configuration initialisation done once at init time.
531  */
532 static void
533 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
534 		 unsigned int socket_id)
535 {
536 	char pool_name[RTE_MEMPOOL_NAMESIZE];
537 	struct rte_mempool *rte_mp = NULL;
538 	uint32_t mb_size;
539 
540 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
541 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
542 
543 	TESTPMD_LOG(INFO,
544 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
545 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
546 
547 	if (mp_anon != 0) {
548 		rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
549 			mb_size, (unsigned) mb_mempool_cache,
550 			sizeof(struct rte_pktmbuf_pool_private),
551 			socket_id, 0);
552 		if (rte_mp == NULL)
553 			goto err;
554 
555 		if (rte_mempool_populate_anon(rte_mp) == 0) {
556 			rte_mempool_free(rte_mp);
557 			rte_mp = NULL;
558 			goto err;
559 		}
560 		rte_pktmbuf_pool_init(rte_mp, NULL);
561 		rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
562 	} else {
563 		/* wrapper to rte_mempool_create() */
564 		TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
565 				rte_mbuf_best_mempool_ops());
566 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
567 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
568 	}
569 
570 err:
571 	if (rte_mp == NULL) {
572 		rte_exit(EXIT_FAILURE,
573 			"Creation of mbuf pool for socket %u failed: %s\n",
574 			socket_id, rte_strerror(rte_errno));
575 	} else if (verbose_level > 0) {
576 		rte_mempool_dump(stdout, rte_mp);
577 	}
578 }
579 
580 /*
581  * Check given socket id is valid or not with NUMA mode,
582  * if valid, return 0, else return -1
583  */
584 static int
585 check_socket_id(const unsigned int socket_id)
586 {
587 	static int warning_once = 0;
588 
589 	if (new_socket_id(socket_id)) {
590 		if (!warning_once && numa_support)
591 			printf("Warning: NUMA should be configured manually by"
592 			       " using --port-numa-config and"
593 			       " --ring-numa-config parameters along with"
594 			       " --numa.\n");
595 		warning_once = 1;
596 		return -1;
597 	}
598 	return 0;
599 }
600 
601 /*
602  * Get the allowed maximum number of RX queues.
603  * *pid return the port id which has minimal value of
604  * max_rx_queues in all ports.
605  */
606 queueid_t
607 get_allowed_max_nb_rxq(portid_t *pid)
608 {
609 	queueid_t allowed_max_rxq = MAX_QUEUE_ID;
610 	portid_t pi;
611 	struct rte_eth_dev_info dev_info;
612 
613 	RTE_ETH_FOREACH_DEV(pi) {
614 		rte_eth_dev_info_get(pi, &dev_info);
615 		if (dev_info.max_rx_queues < allowed_max_rxq) {
616 			allowed_max_rxq = dev_info.max_rx_queues;
617 			*pid = pi;
618 		}
619 	}
620 	return allowed_max_rxq;
621 }
622 
623 /*
624  * Check input rxq is valid or not.
625  * If input rxq is not greater than any of maximum number
626  * of RX queues of all ports, it is valid.
627  * if valid, return 0, else return -1
628  */
629 int
630 check_nb_rxq(queueid_t rxq)
631 {
632 	queueid_t allowed_max_rxq;
633 	portid_t pid = 0;
634 
635 	allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
636 	if (rxq > allowed_max_rxq) {
637 		printf("Fail: input rxq (%u) can't be greater "
638 		       "than max_rx_queues (%u) of port %u\n",
639 		       rxq,
640 		       allowed_max_rxq,
641 		       pid);
642 		return -1;
643 	}
644 	return 0;
645 }
646 
647 /*
648  * Get the allowed maximum number of TX queues.
649  * *pid return the port id which has minimal value of
650  * max_tx_queues in all ports.
651  */
652 queueid_t
653 get_allowed_max_nb_txq(portid_t *pid)
654 {
655 	queueid_t allowed_max_txq = MAX_QUEUE_ID;
656 	portid_t pi;
657 	struct rte_eth_dev_info dev_info;
658 
659 	RTE_ETH_FOREACH_DEV(pi) {
660 		rte_eth_dev_info_get(pi, &dev_info);
661 		if (dev_info.max_tx_queues < allowed_max_txq) {
662 			allowed_max_txq = dev_info.max_tx_queues;
663 			*pid = pi;
664 		}
665 	}
666 	return allowed_max_txq;
667 }
668 
669 /*
670  * Check input txq is valid or not.
671  * If input txq is not greater than any of maximum number
672  * of TX queues of all ports, it is valid.
673  * if valid, return 0, else return -1
674  */
675 int
676 check_nb_txq(queueid_t txq)
677 {
678 	queueid_t allowed_max_txq;
679 	portid_t pid = 0;
680 
681 	allowed_max_txq = get_allowed_max_nb_txq(&pid);
682 	if (txq > allowed_max_txq) {
683 		printf("Fail: input txq (%u) can't be greater "
684 		       "than max_tx_queues (%u) of port %u\n",
685 		       txq,
686 		       allowed_max_txq,
687 		       pid);
688 		return -1;
689 	}
690 	return 0;
691 }
692 
693 static void
694 init_config(void)
695 {
696 	portid_t pid;
697 	struct rte_port *port;
698 	struct rte_mempool *mbp;
699 	unsigned int nb_mbuf_per_pool;
700 	lcoreid_t  lc_id;
701 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
702 	struct rte_gro_param gro_param;
703 	uint32_t gso_types;
704 	int k;
705 
706 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
707 
708 	if (numa_support) {
709 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
710 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
711 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
712 	}
713 
714 	/* Configuration of logical cores. */
715 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
716 				sizeof(struct fwd_lcore *) * nb_lcores,
717 				RTE_CACHE_LINE_SIZE);
718 	if (fwd_lcores == NULL) {
719 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
720 							"failed\n", nb_lcores);
721 	}
722 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
723 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
724 					       sizeof(struct fwd_lcore),
725 					       RTE_CACHE_LINE_SIZE);
726 		if (fwd_lcores[lc_id] == NULL) {
727 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
728 								"failed\n");
729 		}
730 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
731 	}
732 
733 	RTE_ETH_FOREACH_DEV(pid) {
734 		port = &ports[pid];
735 		/* Apply default TxRx configuration for all ports */
736 		port->dev_conf.txmode = tx_mode;
737 		port->dev_conf.rxmode = rx_mode;
738 		rte_eth_dev_info_get(pid, &port->dev_info);
739 
740 		if (!(port->dev_info.rx_offload_capa &
741 					DEV_RX_OFFLOAD_CRC_STRIP))
742 			port->dev_conf.rxmode.offloads &=
743 				~DEV_RX_OFFLOAD_CRC_STRIP;
744 		if (!(port->dev_info.tx_offload_capa &
745 		      DEV_TX_OFFLOAD_MBUF_FAST_FREE))
746 			port->dev_conf.txmode.offloads &=
747 				~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
748 		if (numa_support) {
749 			if (port_numa[pid] != NUMA_NO_CONFIG)
750 				port_per_socket[port_numa[pid]]++;
751 			else {
752 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
753 
754 				/* if socket_id is invalid, set to 0 */
755 				if (check_socket_id(socket_id) < 0)
756 					socket_id = 0;
757 				port_per_socket[socket_id]++;
758 			}
759 		}
760 
761 		/* Apply Rx offloads configuration */
762 		for (k = 0; k < port->dev_info.max_rx_queues; k++)
763 			port->rx_conf[k].offloads =
764 				port->dev_conf.rxmode.offloads;
765 		/* Apply Tx offloads configuration */
766 		for (k = 0; k < port->dev_info.max_tx_queues; k++)
767 			port->tx_conf[k].offloads =
768 				port->dev_conf.txmode.offloads;
769 
770 		/* set flag to initialize port/queue */
771 		port->need_reconfig = 1;
772 		port->need_reconfig_queues = 1;
773 	}
774 
775 	/*
776 	 * Create pools of mbuf.
777 	 * If NUMA support is disabled, create a single pool of mbuf in
778 	 * socket 0 memory by default.
779 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
780 	 *
781 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
782 	 * nb_txd can be configured at run time.
783 	 */
784 	if (param_total_num_mbufs)
785 		nb_mbuf_per_pool = param_total_num_mbufs;
786 	else {
787 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
788 			(nb_lcores * mb_mempool_cache) +
789 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
790 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
791 	}
792 
793 	if (numa_support) {
794 		uint8_t i;
795 
796 		for (i = 0; i < num_sockets; i++)
797 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
798 					 socket_ids[i]);
799 	} else {
800 		if (socket_num == UMA_NO_CONFIG)
801 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
802 		else
803 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
804 						 socket_num);
805 	}
806 
807 	init_port_config();
808 
809 	gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
810 		DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO;
811 	/*
812 	 * Records which Mbuf pool to use by each logical core, if needed.
813 	 */
814 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
815 		mbp = mbuf_pool_find(
816 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
817 
818 		if (mbp == NULL)
819 			mbp = mbuf_pool_find(0);
820 		fwd_lcores[lc_id]->mbp = mbp;
821 		/* initialize GSO context */
822 		fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
823 		fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
824 		fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
825 		fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
826 			ETHER_CRC_LEN;
827 		fwd_lcores[lc_id]->gso_ctx.flag = 0;
828 	}
829 
830 	/* Configuration of packet forwarding streams. */
831 	if (init_fwd_streams() < 0)
832 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
833 
834 	fwd_config_setup();
835 
836 	/* create a gro context for each lcore */
837 	gro_param.gro_types = RTE_GRO_TCP_IPV4;
838 	gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
839 	gro_param.max_item_per_flow = MAX_PKT_BURST;
840 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
841 		gro_param.socket_id = rte_lcore_to_socket_id(
842 				fwd_lcores_cpuids[lc_id]);
843 		fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
844 		if (fwd_lcores[lc_id]->gro_ctx == NULL) {
845 			rte_exit(EXIT_FAILURE,
846 					"rte_gro_ctx_create() failed\n");
847 		}
848 	}
849 
850 #if defined RTE_LIBRTE_PMD_SOFTNIC
851 	if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) {
852 		RTE_ETH_FOREACH_DEV(pid) {
853 			port = &ports[pid];
854 			const char *driver = port->dev_info.driver_name;
855 
856 			if (strcmp(driver, "net_softnic") == 0)
857 				port->softport.fwd_lcore_arg = fwd_lcores;
858 		}
859 	}
860 #endif
861 
862 }
863 
864 
865 void
866 reconfig(portid_t new_port_id, unsigned socket_id)
867 {
868 	struct rte_port *port;
869 
870 	/* Reconfiguration of Ethernet ports. */
871 	port = &ports[new_port_id];
872 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
873 
874 	/* set flag to initialize port/queue */
875 	port->need_reconfig = 1;
876 	port->need_reconfig_queues = 1;
877 	port->socket_id = socket_id;
878 
879 	init_port_config();
880 }
881 
882 
883 int
884 init_fwd_streams(void)
885 {
886 	portid_t pid;
887 	struct rte_port *port;
888 	streamid_t sm_id, nb_fwd_streams_new;
889 	queueid_t q;
890 
891 	/* set socket id according to numa or not */
892 	RTE_ETH_FOREACH_DEV(pid) {
893 		port = &ports[pid];
894 		if (nb_rxq > port->dev_info.max_rx_queues) {
895 			printf("Fail: nb_rxq(%d) is greater than "
896 				"max_rx_queues(%d)\n", nb_rxq,
897 				port->dev_info.max_rx_queues);
898 			return -1;
899 		}
900 		if (nb_txq > port->dev_info.max_tx_queues) {
901 			printf("Fail: nb_txq(%d) is greater than "
902 				"max_tx_queues(%d)\n", nb_txq,
903 				port->dev_info.max_tx_queues);
904 			return -1;
905 		}
906 		if (numa_support) {
907 			if (port_numa[pid] != NUMA_NO_CONFIG)
908 				port->socket_id = port_numa[pid];
909 			else {
910 				port->socket_id = rte_eth_dev_socket_id(pid);
911 
912 				/* if socket_id is invalid, set to 0 */
913 				if (check_socket_id(port->socket_id) < 0)
914 					port->socket_id = 0;
915 			}
916 		}
917 		else {
918 			if (socket_num == UMA_NO_CONFIG)
919 				port->socket_id = 0;
920 			else
921 				port->socket_id = socket_num;
922 		}
923 	}
924 
925 	q = RTE_MAX(nb_rxq, nb_txq);
926 	if (q == 0) {
927 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
928 		return -1;
929 	}
930 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
931 	if (nb_fwd_streams_new == nb_fwd_streams)
932 		return 0;
933 	/* clear the old */
934 	if (fwd_streams != NULL) {
935 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
936 			if (fwd_streams[sm_id] == NULL)
937 				continue;
938 			rte_free(fwd_streams[sm_id]);
939 			fwd_streams[sm_id] = NULL;
940 		}
941 		rte_free(fwd_streams);
942 		fwd_streams = NULL;
943 	}
944 
945 	/* init new */
946 	nb_fwd_streams = nb_fwd_streams_new;
947 	if (nb_fwd_streams) {
948 		fwd_streams = rte_zmalloc("testpmd: fwd_streams",
949 			sizeof(struct fwd_stream *) * nb_fwd_streams,
950 			RTE_CACHE_LINE_SIZE);
951 		if (fwd_streams == NULL)
952 			rte_exit(EXIT_FAILURE, "rte_zmalloc(%d"
953 				 " (struct fwd_stream *)) failed\n",
954 				 nb_fwd_streams);
955 
956 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
957 			fwd_streams[sm_id] = rte_zmalloc("testpmd:"
958 				" struct fwd_stream", sizeof(struct fwd_stream),
959 				RTE_CACHE_LINE_SIZE);
960 			if (fwd_streams[sm_id] == NULL)
961 				rte_exit(EXIT_FAILURE, "rte_zmalloc"
962 					 "(struct fwd_stream) failed\n");
963 		}
964 	}
965 
966 	return 0;
967 }
968 
969 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
970 static void
971 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
972 {
973 	unsigned int total_burst;
974 	unsigned int nb_burst;
975 	unsigned int burst_stats[3];
976 	uint16_t pktnb_stats[3];
977 	uint16_t nb_pkt;
978 	int burst_percent[3];
979 
980 	/*
981 	 * First compute the total number of packet bursts and the
982 	 * two highest numbers of bursts of the same number of packets.
983 	 */
984 	total_burst = 0;
985 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
986 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
987 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
988 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
989 		if (nb_burst == 0)
990 			continue;
991 		total_burst += nb_burst;
992 		if (nb_burst > burst_stats[0]) {
993 			burst_stats[1] = burst_stats[0];
994 			pktnb_stats[1] = pktnb_stats[0];
995 			burst_stats[0] = nb_burst;
996 			pktnb_stats[0] = nb_pkt;
997 		} else if (nb_burst > burst_stats[1]) {
998 			burst_stats[1] = nb_burst;
999 			pktnb_stats[1] = nb_pkt;
1000 		}
1001 	}
1002 	if (total_burst == 0)
1003 		return;
1004 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
1005 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
1006 	       burst_percent[0], (int) pktnb_stats[0]);
1007 	if (burst_stats[0] == total_burst) {
1008 		printf("]\n");
1009 		return;
1010 	}
1011 	if (burst_stats[0] + burst_stats[1] == total_burst) {
1012 		printf(" + %d%% of %d pkts]\n",
1013 		       100 - burst_percent[0], pktnb_stats[1]);
1014 		return;
1015 	}
1016 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
1017 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
1018 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
1019 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
1020 		return;
1021 	}
1022 	printf(" + %d%% of %d pkts + %d%% of others]\n",
1023 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
1024 }
1025 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
1026 
1027 static void
1028 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
1029 {
1030 	struct rte_port *port;
1031 	uint8_t i;
1032 
1033 	static const char *fwd_stats_border = "----------------------";
1034 
1035 	port = &ports[port_id];
1036 	printf("\n  %s Forward statistics for port %-2d %s\n",
1037 	       fwd_stats_border, port_id, fwd_stats_border);
1038 
1039 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
1040 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1041 		       "%-"PRIu64"\n",
1042 		       stats->ipackets, stats->imissed,
1043 		       (uint64_t) (stats->ipackets + stats->imissed));
1044 
1045 		if (cur_fwd_eng == &csum_fwd_engine)
1046 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
1047 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
1048 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
1049 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
1050 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
1051 		}
1052 
1053 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1054 		       "%-"PRIu64"\n",
1055 		       stats->opackets, port->tx_dropped,
1056 		       (uint64_t) (stats->opackets + port->tx_dropped));
1057 	}
1058 	else {
1059 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
1060 		       "%14"PRIu64"\n",
1061 		       stats->ipackets, stats->imissed,
1062 		       (uint64_t) (stats->ipackets + stats->imissed));
1063 
1064 		if (cur_fwd_eng == &csum_fwd_engine)
1065 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
1066 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
1067 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
1068 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
1069 			printf("  RX-nombufs:             %14"PRIu64"\n",
1070 			       stats->rx_nombuf);
1071 		}
1072 
1073 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
1074 		       "%14"PRIu64"\n",
1075 		       stats->opackets, port->tx_dropped,
1076 		       (uint64_t) (stats->opackets + port->tx_dropped));
1077 	}
1078 
1079 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1080 	if (port->rx_stream)
1081 		pkt_burst_stats_display("RX",
1082 			&port->rx_stream->rx_burst_stats);
1083 	if (port->tx_stream)
1084 		pkt_burst_stats_display("TX",
1085 			&port->tx_stream->tx_burst_stats);
1086 #endif
1087 
1088 	if (port->rx_queue_stats_mapping_enabled) {
1089 		printf("\n");
1090 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1091 			printf("  Stats reg %2d RX-packets:%14"PRIu64
1092 			       "     RX-errors:%14"PRIu64
1093 			       "    RX-bytes:%14"PRIu64"\n",
1094 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
1095 		}
1096 		printf("\n");
1097 	}
1098 	if (port->tx_queue_stats_mapping_enabled) {
1099 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1100 			printf("  Stats reg %2d TX-packets:%14"PRIu64
1101 			       "                                 TX-bytes:%14"PRIu64"\n",
1102 			       i, stats->q_opackets[i], stats->q_obytes[i]);
1103 		}
1104 	}
1105 
1106 	printf("  %s--------------------------------%s\n",
1107 	       fwd_stats_border, fwd_stats_border);
1108 }
1109 
1110 static void
1111 fwd_stream_stats_display(streamid_t stream_id)
1112 {
1113 	struct fwd_stream *fs;
1114 	static const char *fwd_top_stats_border = "-------";
1115 
1116 	fs = fwd_streams[stream_id];
1117 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1118 	    (fs->fwd_dropped == 0))
1119 		return;
1120 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1121 	       "TX Port=%2d/Queue=%2d %s\n",
1122 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1123 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1124 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
1125 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1126 
1127 	/* if checksum mode */
1128 	if (cur_fwd_eng == &csum_fwd_engine) {
1129 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
1130 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
1131 	}
1132 
1133 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1134 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1135 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1136 #endif
1137 }
1138 
1139 static void
1140 flush_fwd_rx_queues(void)
1141 {
1142 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1143 	portid_t  rxp;
1144 	portid_t port_id;
1145 	queueid_t rxq;
1146 	uint16_t  nb_rx;
1147 	uint16_t  i;
1148 	uint8_t   j;
1149 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1150 	uint64_t timer_period;
1151 
1152 	/* convert to number of cycles */
1153 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
1154 
1155 	for (j = 0; j < 2; j++) {
1156 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
1157 			for (rxq = 0; rxq < nb_rxq; rxq++) {
1158 				port_id = fwd_ports_ids[rxp];
1159 				/**
1160 				* testpmd can stuck in the below do while loop
1161 				* if rte_eth_rx_burst() always returns nonzero
1162 				* packets. So timer is added to exit this loop
1163 				* after 1sec timer expiry.
1164 				*/
1165 				prev_tsc = rte_rdtsc();
1166 				do {
1167 					nb_rx = rte_eth_rx_burst(port_id, rxq,
1168 						pkts_burst, MAX_PKT_BURST);
1169 					for (i = 0; i < nb_rx; i++)
1170 						rte_pktmbuf_free(pkts_burst[i]);
1171 
1172 					cur_tsc = rte_rdtsc();
1173 					diff_tsc = cur_tsc - prev_tsc;
1174 					timer_tsc += diff_tsc;
1175 				} while ((nb_rx > 0) &&
1176 					(timer_tsc < timer_period));
1177 				timer_tsc = 0;
1178 			}
1179 		}
1180 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1181 	}
1182 }
1183 
1184 static void
1185 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1186 {
1187 	struct fwd_stream **fsm;
1188 	streamid_t nb_fs;
1189 	streamid_t sm_id;
1190 #ifdef RTE_LIBRTE_BITRATE
1191 	uint64_t tics_per_1sec;
1192 	uint64_t tics_datum;
1193 	uint64_t tics_current;
1194 	uint16_t idx_port;
1195 
1196 	tics_datum = rte_rdtsc();
1197 	tics_per_1sec = rte_get_timer_hz();
1198 #endif
1199 	fsm = &fwd_streams[fc->stream_idx];
1200 	nb_fs = fc->stream_nb;
1201 	do {
1202 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1203 			(*pkt_fwd)(fsm[sm_id]);
1204 #ifdef RTE_LIBRTE_BITRATE
1205 		if (bitrate_enabled != 0 &&
1206 				bitrate_lcore_id == rte_lcore_id()) {
1207 			tics_current = rte_rdtsc();
1208 			if (tics_current - tics_datum >= tics_per_1sec) {
1209 				/* Periodic bitrate calculation */
1210 				RTE_ETH_FOREACH_DEV(idx_port)
1211 					rte_stats_bitrate_calc(bitrate_data,
1212 						idx_port);
1213 				tics_datum = tics_current;
1214 			}
1215 		}
1216 #endif
1217 #ifdef RTE_LIBRTE_LATENCY_STATS
1218 		if (latencystats_enabled != 0 &&
1219 				latencystats_lcore_id == rte_lcore_id())
1220 			rte_latencystats_update();
1221 #endif
1222 
1223 	} while (! fc->stopped);
1224 }
1225 
1226 static int
1227 start_pkt_forward_on_core(void *fwd_arg)
1228 {
1229 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1230 			     cur_fwd_config.fwd_eng->packet_fwd);
1231 	return 0;
1232 }
1233 
1234 /*
1235  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1236  * Used to start communication flows in network loopback test configurations.
1237  */
1238 static int
1239 run_one_txonly_burst_on_core(void *fwd_arg)
1240 {
1241 	struct fwd_lcore *fwd_lc;
1242 	struct fwd_lcore tmp_lcore;
1243 
1244 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1245 	tmp_lcore = *fwd_lc;
1246 	tmp_lcore.stopped = 1;
1247 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1248 	return 0;
1249 }
1250 
1251 /*
1252  * Launch packet forwarding:
1253  *     - Setup per-port forwarding context.
1254  *     - launch logical cores with their forwarding configuration.
1255  */
1256 static void
1257 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1258 {
1259 	port_fwd_begin_t port_fwd_begin;
1260 	unsigned int i;
1261 	unsigned int lc_id;
1262 	int diag;
1263 
1264 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1265 	if (port_fwd_begin != NULL) {
1266 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1267 			(*port_fwd_begin)(fwd_ports_ids[i]);
1268 	}
1269 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1270 		lc_id = fwd_lcores_cpuids[i];
1271 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1272 			fwd_lcores[i]->stopped = 0;
1273 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1274 						     fwd_lcores[i], lc_id);
1275 			if (diag != 0)
1276 				printf("launch lcore %u failed - diag=%d\n",
1277 				       lc_id, diag);
1278 		}
1279 	}
1280 }
1281 
1282 /*
1283  * Update the forward ports list.
1284  */
1285 void
1286 update_fwd_ports(portid_t new_pid)
1287 {
1288 	unsigned int i;
1289 	unsigned int new_nb_fwd_ports = 0;
1290 	int move = 0;
1291 
1292 	for (i = 0; i < nb_fwd_ports; ++i) {
1293 		if (port_id_is_invalid(fwd_ports_ids[i], DISABLED_WARN))
1294 			move = 1;
1295 		else if (move)
1296 			fwd_ports_ids[new_nb_fwd_ports++] = fwd_ports_ids[i];
1297 		else
1298 			new_nb_fwd_ports++;
1299 	}
1300 	if (new_pid < RTE_MAX_ETHPORTS)
1301 		fwd_ports_ids[new_nb_fwd_ports++] = new_pid;
1302 
1303 	nb_fwd_ports = new_nb_fwd_ports;
1304 	nb_cfg_ports = new_nb_fwd_ports;
1305 }
1306 
1307 /*
1308  * Launch packet forwarding configuration.
1309  */
1310 void
1311 start_packet_forwarding(int with_tx_first)
1312 {
1313 	port_fwd_begin_t port_fwd_begin;
1314 	port_fwd_end_t  port_fwd_end;
1315 	struct rte_port *port;
1316 	unsigned int i;
1317 	portid_t   pt_id;
1318 	streamid_t sm_id;
1319 
1320 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1321 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1322 
1323 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1324 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1325 
1326 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1327 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1328 		(!nb_rxq || !nb_txq))
1329 		rte_exit(EXIT_FAILURE,
1330 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
1331 			cur_fwd_eng->fwd_mode_name);
1332 
1333 	if (all_ports_started() == 0) {
1334 		printf("Not all ports were started\n");
1335 		return;
1336 	}
1337 	if (test_done == 0) {
1338 		printf("Packet forwarding already started\n");
1339 		return;
1340 	}
1341 
1342 
1343 	if(dcb_test) {
1344 		for (i = 0; i < nb_fwd_ports; i++) {
1345 			pt_id = fwd_ports_ids[i];
1346 			port = &ports[pt_id];
1347 			if (!port->dcb_flag) {
1348 				printf("In DCB mode, all forwarding ports must "
1349                                        "be configured in this mode.\n");
1350 				return;
1351 			}
1352 		}
1353 		if (nb_fwd_lcores == 1) {
1354 			printf("In DCB mode,the nb forwarding cores "
1355                                "should be larger than 1.\n");
1356 			return;
1357 		}
1358 	}
1359 	test_done = 0;
1360 
1361 	fwd_config_setup();
1362 
1363 	if(!no_flush_rx)
1364 		flush_fwd_rx_queues();
1365 
1366 	pkt_fwd_config_display(&cur_fwd_config);
1367 	rxtx_config_display();
1368 
1369 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1370 		pt_id = fwd_ports_ids[i];
1371 		port = &ports[pt_id];
1372 		rte_eth_stats_get(pt_id, &port->stats);
1373 		port->tx_dropped = 0;
1374 
1375 		map_port_queue_stats_mapping_registers(pt_id, port);
1376 	}
1377 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1378 		fwd_streams[sm_id]->rx_packets = 0;
1379 		fwd_streams[sm_id]->tx_packets = 0;
1380 		fwd_streams[sm_id]->fwd_dropped = 0;
1381 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1382 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1383 
1384 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1385 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1386 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1387 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1388 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1389 #endif
1390 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1391 		fwd_streams[sm_id]->core_cycles = 0;
1392 #endif
1393 	}
1394 	if (with_tx_first) {
1395 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1396 		if (port_fwd_begin != NULL) {
1397 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1398 				(*port_fwd_begin)(fwd_ports_ids[i]);
1399 		}
1400 		while (with_tx_first--) {
1401 			launch_packet_forwarding(
1402 					run_one_txonly_burst_on_core);
1403 			rte_eal_mp_wait_lcore();
1404 		}
1405 		port_fwd_end = tx_only_engine.port_fwd_end;
1406 		if (port_fwd_end != NULL) {
1407 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1408 				(*port_fwd_end)(fwd_ports_ids[i]);
1409 		}
1410 	}
1411 	launch_packet_forwarding(start_pkt_forward_on_core);
1412 }
1413 
1414 void
1415 stop_packet_forwarding(void)
1416 {
1417 	struct rte_eth_stats stats;
1418 	struct rte_port *port;
1419 	port_fwd_end_t  port_fwd_end;
1420 	int i;
1421 	portid_t   pt_id;
1422 	streamid_t sm_id;
1423 	lcoreid_t  lc_id;
1424 	uint64_t total_recv;
1425 	uint64_t total_xmit;
1426 	uint64_t total_rx_dropped;
1427 	uint64_t total_tx_dropped;
1428 	uint64_t total_rx_nombuf;
1429 	uint64_t tx_dropped;
1430 	uint64_t rx_bad_ip_csum;
1431 	uint64_t rx_bad_l4_csum;
1432 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1433 	uint64_t fwd_cycles;
1434 #endif
1435 
1436 	static const char *acc_stats_border = "+++++++++++++++";
1437 
1438 	if (test_done) {
1439 		printf("Packet forwarding not started\n");
1440 		return;
1441 	}
1442 	printf("Telling cores to stop...");
1443 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1444 		fwd_lcores[lc_id]->stopped = 1;
1445 	printf("\nWaiting for lcores to finish...\n");
1446 	rte_eal_mp_wait_lcore();
1447 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1448 	if (port_fwd_end != NULL) {
1449 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1450 			pt_id = fwd_ports_ids[i];
1451 			(*port_fwd_end)(pt_id);
1452 		}
1453 	}
1454 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1455 	fwd_cycles = 0;
1456 #endif
1457 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1458 		if (cur_fwd_config.nb_fwd_streams >
1459 		    cur_fwd_config.nb_fwd_ports) {
1460 			fwd_stream_stats_display(sm_id);
1461 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1462 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1463 		} else {
1464 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1465 				fwd_streams[sm_id];
1466 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1467 				fwd_streams[sm_id];
1468 		}
1469 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1470 		tx_dropped = (uint64_t) (tx_dropped +
1471 					 fwd_streams[sm_id]->fwd_dropped);
1472 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1473 
1474 		rx_bad_ip_csum =
1475 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1476 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1477 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1478 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1479 							rx_bad_ip_csum;
1480 
1481 		rx_bad_l4_csum =
1482 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1483 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1484 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1485 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1486 							rx_bad_l4_csum;
1487 
1488 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1489 		fwd_cycles = (uint64_t) (fwd_cycles +
1490 					 fwd_streams[sm_id]->core_cycles);
1491 #endif
1492 	}
1493 	total_recv = 0;
1494 	total_xmit = 0;
1495 	total_rx_dropped = 0;
1496 	total_tx_dropped = 0;
1497 	total_rx_nombuf  = 0;
1498 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1499 		pt_id = fwd_ports_ids[i];
1500 
1501 		port = &ports[pt_id];
1502 		rte_eth_stats_get(pt_id, &stats);
1503 		stats.ipackets -= port->stats.ipackets;
1504 		port->stats.ipackets = 0;
1505 		stats.opackets -= port->stats.opackets;
1506 		port->stats.opackets = 0;
1507 		stats.ibytes   -= port->stats.ibytes;
1508 		port->stats.ibytes = 0;
1509 		stats.obytes   -= port->stats.obytes;
1510 		port->stats.obytes = 0;
1511 		stats.imissed  -= port->stats.imissed;
1512 		port->stats.imissed = 0;
1513 		stats.oerrors  -= port->stats.oerrors;
1514 		port->stats.oerrors = 0;
1515 		stats.rx_nombuf -= port->stats.rx_nombuf;
1516 		port->stats.rx_nombuf = 0;
1517 
1518 		total_recv += stats.ipackets;
1519 		total_xmit += stats.opackets;
1520 		total_rx_dropped += stats.imissed;
1521 		total_tx_dropped += port->tx_dropped;
1522 		total_rx_nombuf  += stats.rx_nombuf;
1523 
1524 		fwd_port_stats_display(pt_id, &stats);
1525 	}
1526 
1527 	printf("\n  %s Accumulated forward statistics for all ports"
1528 	       "%s\n",
1529 	       acc_stats_border, acc_stats_border);
1530 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1531 	       "%-"PRIu64"\n"
1532 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1533 	       "%-"PRIu64"\n",
1534 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1535 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1536 	if (total_rx_nombuf > 0)
1537 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1538 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1539 	       "%s\n",
1540 	       acc_stats_border, acc_stats_border);
1541 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1542 	if (total_recv > 0)
1543 		printf("\n  CPU cycles/packet=%u (total cycles="
1544 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1545 		       (unsigned int)(fwd_cycles / total_recv),
1546 		       fwd_cycles, total_recv);
1547 #endif
1548 	printf("\nDone.\n");
1549 	test_done = 1;
1550 }
1551 
1552 void
1553 dev_set_link_up(portid_t pid)
1554 {
1555 	if (rte_eth_dev_set_link_up(pid) < 0)
1556 		printf("\nSet link up fail.\n");
1557 }
1558 
1559 void
1560 dev_set_link_down(portid_t pid)
1561 {
1562 	if (rte_eth_dev_set_link_down(pid) < 0)
1563 		printf("\nSet link down fail.\n");
1564 }
1565 
1566 static int
1567 all_ports_started(void)
1568 {
1569 	portid_t pi;
1570 	struct rte_port *port;
1571 
1572 	RTE_ETH_FOREACH_DEV(pi) {
1573 		port = &ports[pi];
1574 		/* Check if there is a port which is not started */
1575 		if ((port->port_status != RTE_PORT_STARTED) &&
1576 			(port->slave_flag == 0))
1577 			return 0;
1578 	}
1579 
1580 	/* No port is not started */
1581 	return 1;
1582 }
1583 
1584 int
1585 port_is_stopped(portid_t port_id)
1586 {
1587 	struct rte_port *port = &ports[port_id];
1588 
1589 	if ((port->port_status != RTE_PORT_STOPPED) &&
1590 	    (port->slave_flag == 0))
1591 		return 0;
1592 	return 1;
1593 }
1594 
1595 int
1596 all_ports_stopped(void)
1597 {
1598 	portid_t pi;
1599 
1600 	RTE_ETH_FOREACH_DEV(pi) {
1601 		if (!port_is_stopped(pi))
1602 			return 0;
1603 	}
1604 
1605 	return 1;
1606 }
1607 
1608 int
1609 port_is_started(portid_t port_id)
1610 {
1611 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1612 		return 0;
1613 
1614 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1615 		return 0;
1616 
1617 	return 1;
1618 }
1619 
1620 static int
1621 port_is_closed(portid_t port_id)
1622 {
1623 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1624 		return 0;
1625 
1626 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1627 		return 0;
1628 
1629 	return 1;
1630 }
1631 
1632 int
1633 start_port(portid_t pid)
1634 {
1635 	int diag, need_check_link_status = -1;
1636 	portid_t pi;
1637 	queueid_t qi;
1638 	struct rte_port *port;
1639 	struct ether_addr mac_addr;
1640 	enum rte_eth_event_type event_type;
1641 
1642 	if (port_id_is_invalid(pid, ENABLED_WARN))
1643 		return 0;
1644 
1645 	if(dcb_config)
1646 		dcb_test = 1;
1647 	RTE_ETH_FOREACH_DEV(pi) {
1648 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1649 			continue;
1650 
1651 		need_check_link_status = 0;
1652 		port = &ports[pi];
1653 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1654 						 RTE_PORT_HANDLING) == 0) {
1655 			printf("Port %d is now not stopped\n", pi);
1656 			continue;
1657 		}
1658 
1659 		if (port->need_reconfig > 0) {
1660 			port->need_reconfig = 0;
1661 
1662 			if (flow_isolate_all) {
1663 				int ret = port_flow_isolate(pi, 1);
1664 				if (ret) {
1665 					printf("Failed to apply isolated"
1666 					       " mode on port %d\n", pi);
1667 					return -1;
1668 				}
1669 			}
1670 
1671 			printf("Configuring Port %d (socket %u)\n", pi,
1672 					port->socket_id);
1673 			/* configure port */
1674 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1675 						&(port->dev_conf));
1676 			if (diag != 0) {
1677 				if (rte_atomic16_cmpset(&(port->port_status),
1678 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1679 					printf("Port %d can not be set back "
1680 							"to stopped\n", pi);
1681 				printf("Fail to configure port %d\n", pi);
1682 				/* try to reconfigure port next time */
1683 				port->need_reconfig = 1;
1684 				return -1;
1685 			}
1686 		}
1687 		if (port->need_reconfig_queues > 0) {
1688 			port->need_reconfig_queues = 0;
1689 			/* setup tx queues */
1690 			for (qi = 0; qi < nb_txq; qi++) {
1691 				if ((numa_support) &&
1692 					(txring_numa[pi] != NUMA_NO_CONFIG))
1693 					diag = rte_eth_tx_queue_setup(pi, qi,
1694 						port->nb_tx_desc[qi],
1695 						txring_numa[pi],
1696 						&(port->tx_conf[qi]));
1697 				else
1698 					diag = rte_eth_tx_queue_setup(pi, qi,
1699 						port->nb_tx_desc[qi],
1700 						port->socket_id,
1701 						&(port->tx_conf[qi]));
1702 
1703 				if (diag == 0)
1704 					continue;
1705 
1706 				/* Fail to setup tx queue, return */
1707 				if (rte_atomic16_cmpset(&(port->port_status),
1708 							RTE_PORT_HANDLING,
1709 							RTE_PORT_STOPPED) == 0)
1710 					printf("Port %d can not be set back "
1711 							"to stopped\n", pi);
1712 				printf("Fail to configure port %d tx queues\n",
1713 				       pi);
1714 				/* try to reconfigure queues next time */
1715 				port->need_reconfig_queues = 1;
1716 				return -1;
1717 			}
1718 			for (qi = 0; qi < nb_rxq; qi++) {
1719 				/* setup rx queues */
1720 				if ((numa_support) &&
1721 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1722 					struct rte_mempool * mp =
1723 						mbuf_pool_find(rxring_numa[pi]);
1724 					if (mp == NULL) {
1725 						printf("Failed to setup RX queue:"
1726 							"No mempool allocation"
1727 							" on the socket %d\n",
1728 							rxring_numa[pi]);
1729 						return -1;
1730 					}
1731 
1732 					diag = rte_eth_rx_queue_setup(pi, qi,
1733 					     port->nb_rx_desc[qi],
1734 					     rxring_numa[pi],
1735 					     &(port->rx_conf[qi]),
1736 					     mp);
1737 				} else {
1738 					struct rte_mempool *mp =
1739 						mbuf_pool_find(port->socket_id);
1740 					if (mp == NULL) {
1741 						printf("Failed to setup RX queue:"
1742 							"No mempool allocation"
1743 							" on the socket %d\n",
1744 							port->socket_id);
1745 						return -1;
1746 					}
1747 					diag = rte_eth_rx_queue_setup(pi, qi,
1748 					     port->nb_rx_desc[qi],
1749 					     port->socket_id,
1750 					     &(port->rx_conf[qi]),
1751 					     mp);
1752 				}
1753 				if (diag == 0)
1754 					continue;
1755 
1756 				/* Fail to setup rx queue, return */
1757 				if (rte_atomic16_cmpset(&(port->port_status),
1758 							RTE_PORT_HANDLING,
1759 							RTE_PORT_STOPPED) == 0)
1760 					printf("Port %d can not be set back "
1761 							"to stopped\n", pi);
1762 				printf("Fail to configure port %d rx queues\n",
1763 				       pi);
1764 				/* try to reconfigure queues next time */
1765 				port->need_reconfig_queues = 1;
1766 				return -1;
1767 			}
1768 		}
1769 
1770 		/* start port */
1771 		if (rte_eth_dev_start(pi) < 0) {
1772 			printf("Fail to start port %d\n", pi);
1773 
1774 			/* Fail to setup rx queue, return */
1775 			if (rte_atomic16_cmpset(&(port->port_status),
1776 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1777 				printf("Port %d can not be set back to "
1778 							"stopped\n", pi);
1779 			continue;
1780 		}
1781 
1782 		if (rte_atomic16_cmpset(&(port->port_status),
1783 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1784 			printf("Port %d can not be set into started\n", pi);
1785 
1786 		rte_eth_macaddr_get(pi, &mac_addr);
1787 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1788 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1789 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1790 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1791 
1792 		/* at least one port started, need checking link status */
1793 		need_check_link_status = 1;
1794 	}
1795 
1796 	for (event_type = RTE_ETH_EVENT_UNKNOWN;
1797 	     event_type < RTE_ETH_EVENT_MAX;
1798 	     event_type++) {
1799 		diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
1800 						event_type,
1801 						eth_event_callback,
1802 						NULL);
1803 		if (diag) {
1804 			printf("Failed to setup even callback for event %d\n",
1805 				event_type);
1806 			return -1;
1807 		}
1808 	}
1809 
1810 	if (need_check_link_status == 1 && !no_link_check)
1811 		check_all_ports_link_status(RTE_PORT_ALL);
1812 	else if (need_check_link_status == 0)
1813 		printf("Please stop the ports first\n");
1814 
1815 	printf("Done\n");
1816 	return 0;
1817 }
1818 
1819 void
1820 stop_port(portid_t pid)
1821 {
1822 	portid_t pi;
1823 	struct rte_port *port;
1824 	int need_check_link_status = 0;
1825 
1826 	if (dcb_test) {
1827 		dcb_test = 0;
1828 		dcb_config = 0;
1829 	}
1830 
1831 	if (port_id_is_invalid(pid, ENABLED_WARN))
1832 		return;
1833 
1834 	printf("Stopping ports...\n");
1835 
1836 	RTE_ETH_FOREACH_DEV(pi) {
1837 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1838 			continue;
1839 
1840 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1841 			printf("Please remove port %d from forwarding configuration.\n", pi);
1842 			continue;
1843 		}
1844 
1845 		if (port_is_bonding_slave(pi)) {
1846 			printf("Please remove port %d from bonded device.\n", pi);
1847 			continue;
1848 		}
1849 
1850 		port = &ports[pi];
1851 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1852 						RTE_PORT_HANDLING) == 0)
1853 			continue;
1854 
1855 		rte_eth_dev_stop(pi);
1856 
1857 		if (rte_atomic16_cmpset(&(port->port_status),
1858 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1859 			printf("Port %d can not be set into stopped\n", pi);
1860 		need_check_link_status = 1;
1861 	}
1862 	if (need_check_link_status && !no_link_check)
1863 		check_all_ports_link_status(RTE_PORT_ALL);
1864 
1865 	printf("Done\n");
1866 }
1867 
1868 void
1869 close_port(portid_t pid)
1870 {
1871 	portid_t pi;
1872 	struct rte_port *port;
1873 
1874 	if (port_id_is_invalid(pid, ENABLED_WARN))
1875 		return;
1876 
1877 	printf("Closing ports...\n");
1878 
1879 	RTE_ETH_FOREACH_DEV(pi) {
1880 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1881 			continue;
1882 
1883 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1884 			printf("Please remove port %d from forwarding configuration.\n", pi);
1885 			continue;
1886 		}
1887 
1888 		if (port_is_bonding_slave(pi)) {
1889 			printf("Please remove port %d from bonded device.\n", pi);
1890 			continue;
1891 		}
1892 
1893 		port = &ports[pi];
1894 		if (rte_atomic16_cmpset(&(port->port_status),
1895 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1896 			printf("Port %d is already closed\n", pi);
1897 			continue;
1898 		}
1899 
1900 		if (rte_atomic16_cmpset(&(port->port_status),
1901 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1902 			printf("Port %d is now not stopped\n", pi);
1903 			continue;
1904 		}
1905 
1906 		if (port->flow_list)
1907 			port_flow_flush(pi);
1908 		rte_eth_dev_close(pi);
1909 
1910 		if (rte_atomic16_cmpset(&(port->port_status),
1911 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1912 			printf("Port %d cannot be set to closed\n", pi);
1913 	}
1914 
1915 	printf("Done\n");
1916 }
1917 
1918 void
1919 reset_port(portid_t pid)
1920 {
1921 	int diag;
1922 	portid_t pi;
1923 	struct rte_port *port;
1924 
1925 	if (port_id_is_invalid(pid, ENABLED_WARN))
1926 		return;
1927 
1928 	printf("Resetting ports...\n");
1929 
1930 	RTE_ETH_FOREACH_DEV(pi) {
1931 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1932 			continue;
1933 
1934 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1935 			printf("Please remove port %d from forwarding "
1936 			       "configuration.\n", pi);
1937 			continue;
1938 		}
1939 
1940 		if (port_is_bonding_slave(pi)) {
1941 			printf("Please remove port %d from bonded device.\n",
1942 			       pi);
1943 			continue;
1944 		}
1945 
1946 		diag = rte_eth_dev_reset(pi);
1947 		if (diag == 0) {
1948 			port = &ports[pi];
1949 			port->need_reconfig = 1;
1950 			port->need_reconfig_queues = 1;
1951 		} else {
1952 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
1953 		}
1954 	}
1955 
1956 	printf("Done\n");
1957 }
1958 
1959 static int
1960 eth_dev_event_callback_register(void)
1961 {
1962 	int ret;
1963 
1964 	/* register the device event callback */
1965 	ret = rte_dev_event_callback_register(NULL,
1966 		eth_dev_event_callback, NULL);
1967 	if (ret) {
1968 		printf("Failed to register device event callback\n");
1969 		return -1;
1970 	}
1971 
1972 	return 0;
1973 }
1974 
1975 
1976 static int
1977 eth_dev_event_callback_unregister(void)
1978 {
1979 	int ret;
1980 
1981 	/* unregister the device event callback */
1982 	ret = rte_dev_event_callback_unregister(NULL,
1983 		eth_dev_event_callback, NULL);
1984 	if (ret < 0) {
1985 		printf("Failed to unregister device event callback\n");
1986 		return -1;
1987 	}
1988 
1989 	return 0;
1990 }
1991 
1992 void
1993 attach_port(char *identifier)
1994 {
1995 	portid_t pi = 0;
1996 	unsigned int socket_id;
1997 
1998 	printf("Attaching a new port...\n");
1999 
2000 	if (identifier == NULL) {
2001 		printf("Invalid parameters are specified\n");
2002 		return;
2003 	}
2004 
2005 	if (rte_eth_dev_attach(identifier, &pi))
2006 		return;
2007 
2008 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
2009 	/* if socket_id is invalid, set to 0 */
2010 	if (check_socket_id(socket_id) < 0)
2011 		socket_id = 0;
2012 	reconfig(pi, socket_id);
2013 	rte_eth_promiscuous_enable(pi);
2014 
2015 	nb_ports = rte_eth_dev_count_avail();
2016 
2017 	ports[pi].port_status = RTE_PORT_STOPPED;
2018 
2019 	update_fwd_ports(pi);
2020 
2021 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2022 	printf("Done\n");
2023 }
2024 
2025 void
2026 detach_port(portid_t port_id)
2027 {
2028 	char name[RTE_ETH_NAME_MAX_LEN];
2029 
2030 	printf("Detaching a port...\n");
2031 
2032 	if (!port_is_closed(port_id)) {
2033 		printf("Please close port first\n");
2034 		return;
2035 	}
2036 
2037 	if (ports[port_id].flow_list)
2038 		port_flow_flush(port_id);
2039 
2040 	if (rte_eth_dev_detach(port_id, name)) {
2041 		TESTPMD_LOG(ERR, "Failed to detach port %u\n", port_id);
2042 		return;
2043 	}
2044 
2045 	nb_ports = rte_eth_dev_count_avail();
2046 
2047 	update_fwd_ports(RTE_MAX_ETHPORTS);
2048 
2049 	printf("Port %u is detached. Now total ports is %d\n",
2050 			port_id, nb_ports);
2051 	printf("Done\n");
2052 	return;
2053 }
2054 
2055 void
2056 pmd_test_exit(void)
2057 {
2058 	struct rte_device *device;
2059 	portid_t pt_id;
2060 	int ret;
2061 
2062 	if (test_done == 0)
2063 		stop_packet_forwarding();
2064 
2065 	if (ports != NULL) {
2066 		no_link_check = 1;
2067 		RTE_ETH_FOREACH_DEV(pt_id) {
2068 			printf("\nShutting down port %d...\n", pt_id);
2069 			fflush(stdout);
2070 			stop_port(pt_id);
2071 			close_port(pt_id);
2072 
2073 			/*
2074 			 * This is a workaround to fix a virtio-user issue that
2075 			 * requires to call clean-up routine to remove existing
2076 			 * socket.
2077 			 * This workaround valid only for testpmd, needs a fix
2078 			 * valid for all applications.
2079 			 * TODO: Implement proper resource cleanup
2080 			 */
2081 			device = rte_eth_devices[pt_id].device;
2082 			if (device && !strcmp(device->driver->name, "net_virtio_user"))
2083 				detach_port(pt_id);
2084 		}
2085 	}
2086 
2087 	if (hot_plug) {
2088 		ret = rte_dev_event_monitor_stop();
2089 		if (ret)
2090 			RTE_LOG(ERR, EAL,
2091 				"fail to stop device event monitor.");
2092 
2093 		ret = eth_dev_event_callback_unregister();
2094 		if (ret)
2095 			RTE_LOG(ERR, EAL,
2096 				"fail to unregister all event callbacks.");
2097 	}
2098 
2099 	printf("\nBye...\n");
2100 }
2101 
2102 typedef void (*cmd_func_t)(void);
2103 struct pmd_test_command {
2104 	const char *cmd_name;
2105 	cmd_func_t cmd_func;
2106 };
2107 
2108 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
2109 
2110 /* Check the link status of all ports in up to 9s, and print them finally */
2111 static void
2112 check_all_ports_link_status(uint32_t port_mask)
2113 {
2114 #define CHECK_INTERVAL 100 /* 100ms */
2115 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
2116 	portid_t portid;
2117 	uint8_t count, all_ports_up, print_flag = 0;
2118 	struct rte_eth_link link;
2119 
2120 	printf("Checking link statuses...\n");
2121 	fflush(stdout);
2122 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
2123 		all_ports_up = 1;
2124 		RTE_ETH_FOREACH_DEV(portid) {
2125 			if ((port_mask & (1 << portid)) == 0)
2126 				continue;
2127 			memset(&link, 0, sizeof(link));
2128 			rte_eth_link_get_nowait(portid, &link);
2129 			/* print link status if flag set */
2130 			if (print_flag == 1) {
2131 				if (link.link_status)
2132 					printf(
2133 					"Port%d Link Up. speed %u Mbps- %s\n",
2134 					portid, link.link_speed,
2135 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
2136 					("full-duplex") : ("half-duplex\n"));
2137 				else
2138 					printf("Port %d Link Down\n", portid);
2139 				continue;
2140 			}
2141 			/* clear all_ports_up flag if any link down */
2142 			if (link.link_status == ETH_LINK_DOWN) {
2143 				all_ports_up = 0;
2144 				break;
2145 			}
2146 		}
2147 		/* after finally printing all link status, get out */
2148 		if (print_flag == 1)
2149 			break;
2150 
2151 		if (all_ports_up == 0) {
2152 			fflush(stdout);
2153 			rte_delay_ms(CHECK_INTERVAL);
2154 		}
2155 
2156 		/* set the print_flag if all ports up or timeout */
2157 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
2158 			print_flag = 1;
2159 		}
2160 
2161 		if (lsc_interrupt)
2162 			break;
2163 	}
2164 }
2165 
2166 static void
2167 rmv_event_callback(void *arg)
2168 {
2169 	int need_to_start = 0;
2170 	int org_no_link_check = no_link_check;
2171 	portid_t port_id = (intptr_t)arg;
2172 
2173 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
2174 
2175 	if (!test_done && port_is_forwarding(port_id)) {
2176 		need_to_start = 1;
2177 		stop_packet_forwarding();
2178 	}
2179 	no_link_check = 1;
2180 	stop_port(port_id);
2181 	no_link_check = org_no_link_check;
2182 	close_port(port_id);
2183 	detach_port(port_id);
2184 	if (need_to_start)
2185 		start_packet_forwarding(0);
2186 }
2187 
2188 /* This function is used by the interrupt thread */
2189 static int
2190 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
2191 		  void *ret_param)
2192 {
2193 	static const char * const event_desc[] = {
2194 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
2195 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
2196 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
2197 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
2198 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
2199 		[RTE_ETH_EVENT_IPSEC] = "IPsec",
2200 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
2201 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
2202 		[RTE_ETH_EVENT_NEW] = "device probed",
2203 		[RTE_ETH_EVENT_DESTROY] = "device released",
2204 		[RTE_ETH_EVENT_MAX] = NULL,
2205 	};
2206 
2207 	RTE_SET_USED(param);
2208 	RTE_SET_USED(ret_param);
2209 
2210 	if (type >= RTE_ETH_EVENT_MAX) {
2211 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
2212 			port_id, __func__, type);
2213 		fflush(stderr);
2214 	} else if (event_print_mask & (UINT32_C(1) << type)) {
2215 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
2216 			event_desc[type]);
2217 		fflush(stdout);
2218 	}
2219 
2220 	if (port_id_is_invalid(port_id, DISABLED_WARN))
2221 		return 0;
2222 
2223 	switch (type) {
2224 	case RTE_ETH_EVENT_INTR_RMV:
2225 		if (rte_eal_alarm_set(100000,
2226 				rmv_event_callback, (void *)(intptr_t)port_id))
2227 			fprintf(stderr, "Could not set up deferred device removal\n");
2228 		break;
2229 	default:
2230 		break;
2231 	}
2232 	return 0;
2233 }
2234 
2235 /* This function is used by the interrupt thread */
2236 static void
2237 eth_dev_event_callback(char *device_name, enum rte_dev_event_type type,
2238 			     __rte_unused void *arg)
2239 {
2240 	if (type >= RTE_DEV_EVENT_MAX) {
2241 		fprintf(stderr, "%s called upon invalid event %d\n",
2242 			__func__, type);
2243 		fflush(stderr);
2244 	}
2245 
2246 	switch (type) {
2247 	case RTE_DEV_EVENT_REMOVE:
2248 		RTE_LOG(ERR, EAL, "The device: %s has been removed!\n",
2249 			device_name);
2250 		/* TODO: After finish failure handle, begin to stop
2251 		 * packet forward, stop port, close port, detach port.
2252 		 */
2253 		break;
2254 	case RTE_DEV_EVENT_ADD:
2255 		RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
2256 			device_name);
2257 		/* TODO: After finish kernel driver binding,
2258 		 * begin to attach port.
2259 		 */
2260 		break;
2261 	default:
2262 		break;
2263 	}
2264 }
2265 
2266 static int
2267 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2268 {
2269 	uint16_t i;
2270 	int diag;
2271 	uint8_t mapping_found = 0;
2272 
2273 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
2274 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
2275 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
2276 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
2277 					tx_queue_stats_mappings[i].queue_id,
2278 					tx_queue_stats_mappings[i].stats_counter_id);
2279 			if (diag != 0)
2280 				return diag;
2281 			mapping_found = 1;
2282 		}
2283 	}
2284 	if (mapping_found)
2285 		port->tx_queue_stats_mapping_enabled = 1;
2286 	return 0;
2287 }
2288 
2289 static int
2290 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2291 {
2292 	uint16_t i;
2293 	int diag;
2294 	uint8_t mapping_found = 0;
2295 
2296 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
2297 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
2298 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
2299 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
2300 					rx_queue_stats_mappings[i].queue_id,
2301 					rx_queue_stats_mappings[i].stats_counter_id);
2302 			if (diag != 0)
2303 				return diag;
2304 			mapping_found = 1;
2305 		}
2306 	}
2307 	if (mapping_found)
2308 		port->rx_queue_stats_mapping_enabled = 1;
2309 	return 0;
2310 }
2311 
2312 static void
2313 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2314 {
2315 	int diag = 0;
2316 
2317 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2318 	if (diag != 0) {
2319 		if (diag == -ENOTSUP) {
2320 			port->tx_queue_stats_mapping_enabled = 0;
2321 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2322 		}
2323 		else
2324 			rte_exit(EXIT_FAILURE,
2325 					"set_tx_queue_stats_mapping_registers "
2326 					"failed for port id=%d diag=%d\n",
2327 					pi, diag);
2328 	}
2329 
2330 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2331 	if (diag != 0) {
2332 		if (diag == -ENOTSUP) {
2333 			port->rx_queue_stats_mapping_enabled = 0;
2334 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2335 		}
2336 		else
2337 			rte_exit(EXIT_FAILURE,
2338 					"set_rx_queue_stats_mapping_registers "
2339 					"failed for port id=%d diag=%d\n",
2340 					pi, diag);
2341 	}
2342 }
2343 
2344 static void
2345 rxtx_port_config(struct rte_port *port)
2346 {
2347 	uint16_t qid;
2348 
2349 	for (qid = 0; qid < nb_rxq; qid++) {
2350 		port->rx_conf[qid] = port->dev_info.default_rxconf;
2351 
2352 		/* Check if any Rx parameters have been passed */
2353 		if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2354 			port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
2355 
2356 		if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2357 			port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
2358 
2359 		if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2360 			port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
2361 
2362 		if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2363 			port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
2364 
2365 		if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2366 			port->rx_conf[qid].rx_drop_en = rx_drop_en;
2367 
2368 		port->nb_rx_desc[qid] = nb_rxd;
2369 	}
2370 
2371 	for (qid = 0; qid < nb_txq; qid++) {
2372 		port->tx_conf[qid] = port->dev_info.default_txconf;
2373 
2374 		/* Check if any Tx parameters have been passed */
2375 		if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2376 			port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
2377 
2378 		if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2379 			port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
2380 
2381 		if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2382 			port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
2383 
2384 		if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2385 			port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
2386 
2387 		if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2388 			port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
2389 
2390 		port->nb_tx_desc[qid] = nb_txd;
2391 	}
2392 }
2393 
2394 void
2395 init_port_config(void)
2396 {
2397 	portid_t pid;
2398 	struct rte_port *port;
2399 
2400 	RTE_ETH_FOREACH_DEV(pid) {
2401 		port = &ports[pid];
2402 		port->dev_conf.fdir_conf = fdir_conf;
2403 		rte_eth_dev_info_get(pid, &port->dev_info);
2404 		if (nb_rxq > 1) {
2405 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2406 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
2407 				rss_hf & port->dev_info.flow_type_rss_offloads;
2408 		} else {
2409 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2410 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2411 		}
2412 
2413 		if (port->dcb_flag == 0) {
2414 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2415 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2416 			else
2417 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2418 		}
2419 
2420 		rxtx_port_config(port);
2421 
2422 		rte_eth_macaddr_get(pid, &port->eth_addr);
2423 
2424 		map_port_queue_stats_mapping_registers(pid, port);
2425 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2426 		rte_pmd_ixgbe_bypass_init(pid);
2427 #endif
2428 
2429 		if (lsc_interrupt &&
2430 		    (rte_eth_devices[pid].data->dev_flags &
2431 		     RTE_ETH_DEV_INTR_LSC))
2432 			port->dev_conf.intr_conf.lsc = 1;
2433 		if (rmv_interrupt &&
2434 		    (rte_eth_devices[pid].data->dev_flags &
2435 		     RTE_ETH_DEV_INTR_RMV))
2436 			port->dev_conf.intr_conf.rmv = 1;
2437 	}
2438 }
2439 
2440 void set_port_slave_flag(portid_t slave_pid)
2441 {
2442 	struct rte_port *port;
2443 
2444 	port = &ports[slave_pid];
2445 	port->slave_flag = 1;
2446 }
2447 
2448 void clear_port_slave_flag(portid_t slave_pid)
2449 {
2450 	struct rte_port *port;
2451 
2452 	port = &ports[slave_pid];
2453 	port->slave_flag = 0;
2454 }
2455 
2456 uint8_t port_is_bonding_slave(portid_t slave_pid)
2457 {
2458 	struct rte_port *port;
2459 
2460 	port = &ports[slave_pid];
2461 	if ((rte_eth_devices[slave_pid].data->dev_flags &
2462 	    RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
2463 		return 1;
2464 	return 0;
2465 }
2466 
2467 const uint16_t vlan_tags[] = {
2468 		0,  1,  2,  3,  4,  5,  6,  7,
2469 		8,  9, 10, 11,  12, 13, 14, 15,
2470 		16, 17, 18, 19, 20, 21, 22, 23,
2471 		24, 25, 26, 27, 28, 29, 30, 31
2472 };
2473 
2474 static  int
2475 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
2476 		 enum dcb_mode_enable dcb_mode,
2477 		 enum rte_eth_nb_tcs num_tcs,
2478 		 uint8_t pfc_en)
2479 {
2480 	uint8_t i;
2481 
2482 	/*
2483 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2484 	 * given above, and the number of traffic classes available for use.
2485 	 */
2486 	if (dcb_mode == DCB_VT_ENABLED) {
2487 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2488 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
2489 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2490 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2491 
2492 		/* VMDQ+DCB RX and TX configurations */
2493 		vmdq_rx_conf->enable_default_pool = 0;
2494 		vmdq_rx_conf->default_pool = 0;
2495 		vmdq_rx_conf->nb_queue_pools =
2496 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2497 		vmdq_tx_conf->nb_queue_pools =
2498 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2499 
2500 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2501 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2502 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2503 			vmdq_rx_conf->pool_map[i].pools =
2504 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2505 		}
2506 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2507 			vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2508 			vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2509 		}
2510 
2511 		/* set DCB mode of RX and TX of multiple queues */
2512 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2513 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2514 	} else {
2515 		struct rte_eth_dcb_rx_conf *rx_conf =
2516 				&eth_conf->rx_adv_conf.dcb_rx_conf;
2517 		struct rte_eth_dcb_tx_conf *tx_conf =
2518 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2519 
2520 		rx_conf->nb_tcs = num_tcs;
2521 		tx_conf->nb_tcs = num_tcs;
2522 
2523 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2524 			rx_conf->dcb_tc[i] = i % num_tcs;
2525 			tx_conf->dcb_tc[i] = i % num_tcs;
2526 		}
2527 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2528 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
2529 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2530 	}
2531 
2532 	if (pfc_en)
2533 		eth_conf->dcb_capability_en =
2534 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2535 	else
2536 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2537 
2538 	return 0;
2539 }
2540 
2541 int
2542 init_port_dcb_config(portid_t pid,
2543 		     enum dcb_mode_enable dcb_mode,
2544 		     enum rte_eth_nb_tcs num_tcs,
2545 		     uint8_t pfc_en)
2546 {
2547 	struct rte_eth_conf port_conf;
2548 	struct rte_port *rte_port;
2549 	int retval;
2550 	uint16_t i;
2551 
2552 	rte_port = &ports[pid];
2553 
2554 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2555 	/* Enter DCB configuration status */
2556 	dcb_config = 1;
2557 
2558 	port_conf.rxmode = rte_port->dev_conf.rxmode;
2559 	port_conf.txmode = rte_port->dev_conf.txmode;
2560 
2561 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
2562 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2563 	if (retval < 0)
2564 		return retval;
2565 	port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2566 
2567 	/* re-configure the device . */
2568 	rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
2569 
2570 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
2571 
2572 	/* If dev_info.vmdq_pool_base is greater than 0,
2573 	 * the queue id of vmdq pools is started after pf queues.
2574 	 */
2575 	if (dcb_mode == DCB_VT_ENABLED &&
2576 	    rte_port->dev_info.vmdq_pool_base > 0) {
2577 		printf("VMDQ_DCB multi-queue mode is nonsensical"
2578 			" for port %d.", pid);
2579 		return -1;
2580 	}
2581 
2582 	/* Assume the ports in testpmd have the same dcb capability
2583 	 * and has the same number of rxq and txq in dcb mode
2584 	 */
2585 	if (dcb_mode == DCB_VT_ENABLED) {
2586 		if (rte_port->dev_info.max_vfs > 0) {
2587 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2588 			nb_txq = rte_port->dev_info.nb_tx_queues;
2589 		} else {
2590 			nb_rxq = rte_port->dev_info.max_rx_queues;
2591 			nb_txq = rte_port->dev_info.max_tx_queues;
2592 		}
2593 	} else {
2594 		/*if vt is disabled, use all pf queues */
2595 		if (rte_port->dev_info.vmdq_pool_base == 0) {
2596 			nb_rxq = rte_port->dev_info.max_rx_queues;
2597 			nb_txq = rte_port->dev_info.max_tx_queues;
2598 		} else {
2599 			nb_rxq = (queueid_t)num_tcs;
2600 			nb_txq = (queueid_t)num_tcs;
2601 
2602 		}
2603 	}
2604 	rx_free_thresh = 64;
2605 
2606 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2607 
2608 	rxtx_port_config(rte_port);
2609 	/* VLAN filter */
2610 	rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2611 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2612 		rx_vft_set(pid, vlan_tags[i], 1);
2613 
2614 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2615 	map_port_queue_stats_mapping_registers(pid, rte_port);
2616 
2617 	rte_port->dcb_flag = 1;
2618 
2619 	return 0;
2620 }
2621 
2622 static void
2623 init_port(void)
2624 {
2625 	/* Configuration of Ethernet ports. */
2626 	ports = rte_zmalloc("testpmd: ports",
2627 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2628 			    RTE_CACHE_LINE_SIZE);
2629 	if (ports == NULL) {
2630 		rte_exit(EXIT_FAILURE,
2631 				"rte_zmalloc(%d struct rte_port) failed\n",
2632 				RTE_MAX_ETHPORTS);
2633 	}
2634 }
2635 
2636 static void
2637 force_quit(void)
2638 {
2639 	pmd_test_exit();
2640 	prompt_exit();
2641 }
2642 
2643 static void
2644 print_stats(void)
2645 {
2646 	uint8_t i;
2647 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2648 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2649 
2650 	/* Clear screen and move to top left */
2651 	printf("%s%s", clr, top_left);
2652 
2653 	printf("\nPort statistics ====================================");
2654 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2655 		nic_stats_display(fwd_ports_ids[i]);
2656 }
2657 
2658 static void
2659 signal_handler(int signum)
2660 {
2661 	if (signum == SIGINT || signum == SIGTERM) {
2662 		printf("\nSignal %d received, preparing to exit...\n",
2663 				signum);
2664 #ifdef RTE_LIBRTE_PDUMP
2665 		/* uninitialize packet capture framework */
2666 		rte_pdump_uninit();
2667 #endif
2668 #ifdef RTE_LIBRTE_LATENCY_STATS
2669 		rte_latencystats_uninit();
2670 #endif
2671 		force_quit();
2672 		/* Set flag to indicate the force termination. */
2673 		f_quit = 1;
2674 		/* exit with the expected status */
2675 		signal(signum, SIG_DFL);
2676 		kill(getpid(), signum);
2677 	}
2678 }
2679 
2680 int
2681 main(int argc, char** argv)
2682 {
2683 	int diag;
2684 	portid_t port_id;
2685 	int ret;
2686 
2687 	signal(SIGINT, signal_handler);
2688 	signal(SIGTERM, signal_handler);
2689 
2690 	diag = rte_eal_init(argc, argv);
2691 	if (diag < 0)
2692 		rte_panic("Cannot init EAL\n");
2693 
2694 	testpmd_logtype = rte_log_register("testpmd");
2695 	if (testpmd_logtype < 0)
2696 		rte_panic("Cannot register log type");
2697 	rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
2698 
2699 #ifdef RTE_LIBRTE_PDUMP
2700 	/* initialize packet capture framework */
2701 	rte_pdump_init(NULL);
2702 #endif
2703 
2704 	nb_ports = (portid_t) rte_eth_dev_count_avail();
2705 	if (nb_ports == 0)
2706 		TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
2707 
2708 	/* allocate port structures, and init them */
2709 	init_port();
2710 
2711 	set_def_fwd_config();
2712 	if (nb_lcores == 0)
2713 		rte_panic("Empty set of forwarding logical cores - check the "
2714 			  "core mask supplied in the command parameters\n");
2715 
2716 	/* Bitrate/latency stats disabled by default */
2717 #ifdef RTE_LIBRTE_BITRATE
2718 	bitrate_enabled = 0;
2719 #endif
2720 #ifdef RTE_LIBRTE_LATENCY_STATS
2721 	latencystats_enabled = 0;
2722 #endif
2723 
2724 	/* on FreeBSD, mlockall() is disabled by default */
2725 #ifdef RTE_EXEC_ENV_BSDAPP
2726 	do_mlockall = 0;
2727 #else
2728 	do_mlockall = 1;
2729 #endif
2730 
2731 	argc -= diag;
2732 	argv += diag;
2733 	if (argc > 1)
2734 		launch_args_parse(argc, argv);
2735 
2736 	if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
2737 		TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
2738 			strerror(errno));
2739 	}
2740 
2741 	if (tx_first && interactive)
2742 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
2743 				"interactive mode.\n");
2744 
2745 	if (tx_first && lsc_interrupt) {
2746 		printf("Warning: lsc_interrupt needs to be off when "
2747 				" using tx_first. Disabling.\n");
2748 		lsc_interrupt = 0;
2749 	}
2750 
2751 	if (!nb_rxq && !nb_txq)
2752 		printf("Warning: Either rx or tx queues should be non-zero\n");
2753 
2754 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2755 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2756 		       "but nb_txq=%d will prevent to fully test it.\n",
2757 		       nb_rxq, nb_txq);
2758 
2759 	init_config();
2760 
2761 	if (hot_plug) {
2762 		/* enable hot plug monitoring */
2763 		ret = rte_dev_event_monitor_start();
2764 		if (ret) {
2765 			rte_errno = EINVAL;
2766 			return -1;
2767 		}
2768 		eth_dev_event_callback_register();
2769 
2770 	}
2771 
2772 	if (start_port(RTE_PORT_ALL) != 0)
2773 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2774 
2775 	/* set all ports to promiscuous mode by default */
2776 	RTE_ETH_FOREACH_DEV(port_id)
2777 		rte_eth_promiscuous_enable(port_id);
2778 
2779 	/* Init metrics library */
2780 	rte_metrics_init(rte_socket_id());
2781 
2782 #ifdef RTE_LIBRTE_LATENCY_STATS
2783 	if (latencystats_enabled != 0) {
2784 		int ret = rte_latencystats_init(1, NULL);
2785 		if (ret)
2786 			printf("Warning: latencystats init()"
2787 				" returned error %d\n",	ret);
2788 		printf("Latencystats running on lcore %d\n",
2789 			latencystats_lcore_id);
2790 	}
2791 #endif
2792 
2793 	/* Setup bitrate stats */
2794 #ifdef RTE_LIBRTE_BITRATE
2795 	if (bitrate_enabled != 0) {
2796 		bitrate_data = rte_stats_bitrate_create();
2797 		if (bitrate_data == NULL)
2798 			rte_exit(EXIT_FAILURE,
2799 				"Could not allocate bitrate data.\n");
2800 		rte_stats_bitrate_reg(bitrate_data);
2801 	}
2802 #endif
2803 
2804 #ifdef RTE_LIBRTE_CMDLINE
2805 	if (strlen(cmdline_filename) != 0)
2806 		cmdline_read_from_file(cmdline_filename);
2807 
2808 	if (interactive == 1) {
2809 		if (auto_start) {
2810 			printf("Start automatic packet forwarding\n");
2811 			start_packet_forwarding(0);
2812 		}
2813 		prompt();
2814 		pmd_test_exit();
2815 	} else
2816 #endif
2817 	{
2818 		char c;
2819 		int rc;
2820 
2821 		f_quit = 0;
2822 
2823 		printf("No commandline core given, start packet forwarding\n");
2824 		start_packet_forwarding(tx_first);
2825 		if (stats_period != 0) {
2826 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2827 			uint64_t timer_period;
2828 
2829 			/* Convert to number of cycles */
2830 			timer_period = stats_period * rte_get_timer_hz();
2831 
2832 			while (f_quit == 0) {
2833 				cur_time = rte_get_timer_cycles();
2834 				diff_time += cur_time - prev_time;
2835 
2836 				if (diff_time >= timer_period) {
2837 					print_stats();
2838 					/* Reset the timer */
2839 					diff_time = 0;
2840 				}
2841 				/* Sleep to avoid unnecessary checks */
2842 				prev_time = cur_time;
2843 				sleep(1);
2844 			}
2845 		}
2846 
2847 		printf("Press enter to exit\n");
2848 		rc = read(0, &c, 1);
2849 		pmd_test_exit();
2850 		if (rc < 0)
2851 			return 1;
2852 	}
2853 
2854 	return 0;
2855 }
2856