xref: /dpdk/app/test-pmd/testpmd.c (revision 0e545d3047fe930d7792e159dc92df97c2fdfb1c)
1af75078fSIntel /*-
2af75078fSIntel  *   BSD LICENSE
3af75078fSIntel  *
45a8fb55cSReshma Pattan  *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5af75078fSIntel  *   All rights reserved.
6af75078fSIntel  *
7af75078fSIntel  *   Redistribution and use in source and binary forms, with or without
8af75078fSIntel  *   modification, are permitted provided that the following conditions
9af75078fSIntel  *   are met:
10af75078fSIntel  *
11af75078fSIntel  *     * Redistributions of source code must retain the above copyright
12af75078fSIntel  *       notice, this list of conditions and the following disclaimer.
13af75078fSIntel  *     * Redistributions in binary form must reproduce the above copyright
14af75078fSIntel  *       notice, this list of conditions and the following disclaimer in
15af75078fSIntel  *       the documentation and/or other materials provided with the
16af75078fSIntel  *       distribution.
17af75078fSIntel  *     * Neither the name of Intel Corporation nor the names of its
18af75078fSIntel  *       contributors may be used to endorse or promote products derived
19af75078fSIntel  *       from this software without specific prior written permission.
20af75078fSIntel  *
21af75078fSIntel  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22af75078fSIntel  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23af75078fSIntel  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24af75078fSIntel  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25af75078fSIntel  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26af75078fSIntel  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27af75078fSIntel  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28af75078fSIntel  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29af75078fSIntel  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30af75078fSIntel  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31af75078fSIntel  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32af75078fSIntel  */
33af75078fSIntel 
34af75078fSIntel #include <stdarg.h>
35af75078fSIntel #include <stdio.h>
36af75078fSIntel #include <stdlib.h>
37af75078fSIntel #include <signal.h>
38af75078fSIntel #include <string.h>
39af75078fSIntel #include <time.h>
40af75078fSIntel #include <fcntl.h>
41af75078fSIntel #include <sys/types.h>
42af75078fSIntel #include <errno.h>
43af75078fSIntel 
44af75078fSIntel #include <sys/queue.h>
45af75078fSIntel #include <sys/stat.h>
46af75078fSIntel 
47af75078fSIntel #include <stdint.h>
48af75078fSIntel #include <unistd.h>
49af75078fSIntel #include <inttypes.h>
50af75078fSIntel 
51af75078fSIntel #include <rte_common.h>
52d1eb542eSOlivier Matz #include <rte_errno.h>
53af75078fSIntel #include <rte_byteorder.h>
54af75078fSIntel #include <rte_log.h>
55af75078fSIntel #include <rte_debug.h>
56af75078fSIntel #include <rte_cycles.h>
57af75078fSIntel #include <rte_memory.h>
58af75078fSIntel #include <rte_memcpy.h>
59af75078fSIntel #include <rte_memzone.h>
60af75078fSIntel #include <rte_launch.h>
61af75078fSIntel #include <rte_eal.h>
62af75078fSIntel #include <rte_per_lcore.h>
63af75078fSIntel #include <rte_lcore.h>
64af75078fSIntel #include <rte_atomic.h>
65af75078fSIntel #include <rte_branch_prediction.h>
66af75078fSIntel #include <rte_ring.h>
67af75078fSIntel #include <rte_mempool.h>
68af75078fSIntel #include <rte_malloc.h>
69af75078fSIntel #include <rte_mbuf.h>
70af75078fSIntel #include <rte_interrupts.h>
71af75078fSIntel #include <rte_pci.h>
72af75078fSIntel #include <rte_ether.h>
73af75078fSIntel #include <rte_ethdev.h>
74edab33b1STetsuya Mukawa #include <rte_dev.h>
75af75078fSIntel #include <rte_string_fns.h>
76148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
77148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
78148f963fSBruce Richardson #endif
79af75078fSIntel 
80af75078fSIntel #include "testpmd.h"
81af75078fSIntel 
82af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
83af75078fSIntel 
84af75078fSIntel /* use master core for command line ? */
85af75078fSIntel uint8_t interactive = 0;
86ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
87af75078fSIntel 
88af75078fSIntel /*
89af75078fSIntel  * NUMA support configuration.
90af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
91af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
92af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
93af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
94af75078fSIntel  */
95af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */
96af75078fSIntel 
97af75078fSIntel /*
98b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
99b6ea6408SIntel  * not configured.
100b6ea6408SIntel  */
101b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
102b6ea6408SIntel 
103b6ea6408SIntel /*
104148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
105148f963fSBruce Richardson  */
106148f963fSBruce Richardson uint8_t mp_anon = 0;
107148f963fSBruce Richardson 
108148f963fSBruce Richardson /*
109af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
110af75078fSIntel  * forwarded.
111af75078fSIntel  * Must be instanciated with the ethernet addresses of peer traffic generator
112af75078fSIntel  * ports.
113af75078fSIntel  */
114af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
115af75078fSIntel portid_t nb_peer_eth_addrs = 0;
116af75078fSIntel 
117af75078fSIntel /*
118af75078fSIntel  * Probed Target Environment.
119af75078fSIntel  */
120af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
121af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
122af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
123af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
124af75078fSIntel 
125af75078fSIntel /*
126af75078fSIntel  * Test Forwarding Configuration.
127af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
128af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
129af75078fSIntel  */
130af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
131af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
132af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
133af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
134af75078fSIntel 
135af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
136af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
137af75078fSIntel 
138af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
139af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
140af75078fSIntel 
141af75078fSIntel /*
142af75078fSIntel  * Forwarding engines.
143af75078fSIntel  */
144af75078fSIntel struct fwd_engine * fwd_engines[] = {
145af75078fSIntel 	&io_fwd_engine,
146af75078fSIntel 	&mac_fwd_engine,
14757e85242SBruce Richardson 	&mac_retry_fwd_engine,
148d47388f1SCyril Chemparathy 	&mac_swap_engine,
149e9e23a61SCyril Chemparathy 	&flow_gen_engine,
150af75078fSIntel 	&rx_only_engine,
151af75078fSIntel 	&tx_only_engine,
152af75078fSIntel 	&csum_fwd_engine,
153168dfa61SIvan Boule 	&icmp_echo_engine,
154af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
155af75078fSIntel 	&ieee1588_fwd_engine,
156af75078fSIntel #endif
157af75078fSIntel 	NULL,
158af75078fSIntel };
159af75078fSIntel 
160af75078fSIntel struct fwd_config cur_fwd_config;
161af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
162af75078fSIntel 
163af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
164c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
165c8798818SIntel                                       * specified on command-line. */
166af75078fSIntel 
167af75078fSIntel /*
168af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
169af75078fSIntel  */
170af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
171af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
172af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
173af75078fSIntel };
174af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
175af75078fSIntel 
17679bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
17779bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
17879bec05bSKonstantin Ananyev 
179af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
180e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
181af75078fSIntel 
182900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
183900550deSIntel uint8_t dcb_config = 0;
184900550deSIntel 
185900550deSIntel /* Whether the dcb is in testing status */
186900550deSIntel uint8_t dcb_test = 0;
187900550deSIntel 
188af75078fSIntel /*
189af75078fSIntel  * Configurable number of RX/TX queues.
190af75078fSIntel  */
191af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
192af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
193af75078fSIntel 
194af75078fSIntel /*
195af75078fSIntel  * Configurable number of RX/TX ring descriptors.
196af75078fSIntel  */
197af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
198af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
199af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
200af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
201af75078fSIntel 
202f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
203af75078fSIntel /*
204af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
205af75078fSIntel  */
206af75078fSIntel 
207f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
208f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
209f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
210af75078fSIntel 
211f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
212f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
213f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
214af75078fSIntel 
215af75078fSIntel /*
216af75078fSIntel  * Configurable value of RX free threshold.
217af75078fSIntel  */
218f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
219af75078fSIntel 
220af75078fSIntel /*
221ce8d5614SIntel  * Configurable value of RX drop enable.
222ce8d5614SIntel  */
223f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
224ce8d5614SIntel 
225ce8d5614SIntel /*
226af75078fSIntel  * Configurable value of TX free threshold.
227af75078fSIntel  */
228f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
229af75078fSIntel 
230af75078fSIntel /*
231af75078fSIntel  * Configurable value of TX RS bit threshold.
232af75078fSIntel  */
233f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
234af75078fSIntel 
235af75078fSIntel /*
236ce8d5614SIntel  * Configurable value of TX queue flags.
237ce8d5614SIntel  */
238f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
239ce8d5614SIntel 
240ce8d5614SIntel /*
241af75078fSIntel  * Receive Side Scaling (RSS) configuration.
242af75078fSIntel  */
2438a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
244af75078fSIntel 
245af75078fSIntel /*
246af75078fSIntel  * Port topology configuration
247af75078fSIntel  */
248af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
249af75078fSIntel 
2507741e4cfSIntel /*
2517741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2527741e4cfSIntel  */
2537741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2547741e4cfSIntel 
255af75078fSIntel /*
256bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
257bc202406SDavid Marchand  */
258bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
259bc202406SDavid Marchand 
260bc202406SDavid Marchand /*
2617b7e5ba7SIntel  * NIC bypass mode configuration options.
2627b7e5ba7SIntel  */
2637b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
2647b7e5ba7SIntel 
2657b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
2667b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
2677b7e5ba7SIntel 
2687b7e5ba7SIntel #endif
2697b7e5ba7SIntel 
2707b7e5ba7SIntel /*
271af75078fSIntel  * Ethernet device configuration.
272af75078fSIntel  */
273af75078fSIntel struct rte_eth_rxmode rx_mode = {
274af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
275af75078fSIntel 	.split_hdr_size = 0,
276af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
277af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
278af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
279a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
280a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
281af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
282af75078fSIntel 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
283af75078fSIntel };
284af75078fSIntel 
285af75078fSIntel struct rte_fdir_conf fdir_conf = {
286af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
287af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
288af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
289d9d5e6f2SJingjing Wu 	.mask = {
290d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
291d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
292d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
293d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
294d9d5e6f2SJingjing Wu 		},
295d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
296d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
297d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
298d9d5e6f2SJingjing Wu 		},
299d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
300d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
30147b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
30247b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
30347b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
304d9d5e6f2SJingjing Wu 	},
305af75078fSIntel 	.drop_queue = 127,
306af75078fSIntel };
307af75078fSIntel 
3082950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
309af75078fSIntel 
310ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
311ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
312ed30d9b6SIntel 
313ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
314ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
315ed30d9b6SIntel 
316ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
317ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
318ed30d9b6SIntel 
3197acf894dSStephen Hurd unsigned max_socket = 0;
3207acf894dSStephen Hurd 
321ed30d9b6SIntel /* Forward function declarations */
322ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
323edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
324ce8d5614SIntel 
325ce8d5614SIntel /*
326ce8d5614SIntel  * Check if all the ports are started.
327ce8d5614SIntel  * If yes, return positive value. If not, return zero.
328ce8d5614SIntel  */
329ce8d5614SIntel static int all_ports_started(void);
330ed30d9b6SIntel 
331af75078fSIntel /*
332edab33b1STetsuya Mukawa  * Find next enabled port
333edab33b1STetsuya Mukawa  */
334edab33b1STetsuya Mukawa portid_t
335edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
336edab33b1STetsuya Mukawa {
337edab33b1STetsuya Mukawa 	if (ports == NULL)
338edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
339edab33b1STetsuya Mukawa 
34012a8e30fSJulien Cretin 	while ((p < size) && (ports[p].enabled == 0))
341edab33b1STetsuya Mukawa 		p++;
342edab33b1STetsuya Mukawa 	return p;
343edab33b1STetsuya Mukawa }
344edab33b1STetsuya Mukawa 
345edab33b1STetsuya Mukawa /*
346af75078fSIntel  * Setup default configuration.
347af75078fSIntel  */
348af75078fSIntel static void
349af75078fSIntel set_default_fwd_lcores_config(void)
350af75078fSIntel {
351af75078fSIntel 	unsigned int i;
352af75078fSIntel 	unsigned int nb_lc;
3537acf894dSStephen Hurd 	unsigned int sock_num;
354af75078fSIntel 
355af75078fSIntel 	nb_lc = 0;
356af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
3577acf894dSStephen Hurd 		sock_num = rte_lcore_to_socket_id(i) + 1;
3587acf894dSStephen Hurd 		if (sock_num > max_socket) {
3597acf894dSStephen Hurd 			if (sock_num > RTE_MAX_NUMA_NODES)
3607acf894dSStephen Hurd 				rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
3617acf894dSStephen Hurd 			max_socket = sock_num;
3627acf894dSStephen Hurd 		}
363f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
364f54fe5eeSStephen Hurd 			continue;
365f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
366f54fe5eeSStephen Hurd 			continue;
367f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
368af75078fSIntel 	}
369af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
370af75078fSIntel 	nb_cfg_lcores = nb_lcores;
371af75078fSIntel 	nb_fwd_lcores = 1;
372af75078fSIntel }
373af75078fSIntel 
374af75078fSIntel static void
375af75078fSIntel set_def_peer_eth_addrs(void)
376af75078fSIntel {
377af75078fSIntel 	portid_t i;
378af75078fSIntel 
379af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
380af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
381af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
382af75078fSIntel 	}
383af75078fSIntel }
384af75078fSIntel 
385af75078fSIntel static void
386af75078fSIntel set_default_fwd_ports_config(void)
387af75078fSIntel {
388af75078fSIntel 	portid_t pt_id;
389af75078fSIntel 
390af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
391af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
392af75078fSIntel 
393af75078fSIntel 	nb_cfg_ports = nb_ports;
394af75078fSIntel 	nb_fwd_ports = nb_ports;
395af75078fSIntel }
396af75078fSIntel 
397af75078fSIntel void
398af75078fSIntel set_def_fwd_config(void)
399af75078fSIntel {
400af75078fSIntel 	set_default_fwd_lcores_config();
401af75078fSIntel 	set_def_peer_eth_addrs();
402af75078fSIntel 	set_default_fwd_ports_config();
403af75078fSIntel }
404af75078fSIntel 
405af75078fSIntel /*
406af75078fSIntel  * Configuration initialisation done once at init time.
407af75078fSIntel  */
408af75078fSIntel static void
409af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
410af75078fSIntel 		 unsigned int socket_id)
411af75078fSIntel {
412af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
413bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
414af75078fSIntel 	uint32_t mb_size;
415af75078fSIntel 
416dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
417af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
418148f963fSBruce Richardson 
419d1eb542eSOlivier Matz 	RTE_LOG(INFO, USER1,
420d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
421d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
422d1eb542eSOlivier Matz 
423148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
424148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
425af75078fSIntel 		(unsigned) mb_mempool_cache,
426af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
427dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
428dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
429af75078fSIntel 		socket_id, 0);
430bece7b6cSChristian Ehrhardt #endif
431148f963fSBruce Richardson 
432bece7b6cSChristian Ehrhardt 	/* if the former XEN allocation failed fall back to normal allocation */
433bece7b6cSChristian Ehrhardt 	if (rte_mp == NULL) {
434b19a0c75SOlivier Matz 		if (mp_anon != 0) {
435b19a0c75SOlivier Matz 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
436bece7b6cSChristian Ehrhardt 				mb_size, (unsigned) mb_mempool_cache,
437148f963fSBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private),
438148f963fSBruce Richardson 				socket_id, 0);
439b19a0c75SOlivier Matz 
440b19a0c75SOlivier Matz 			if (rte_mempool_populate_anon(rte_mp) == 0) {
441b19a0c75SOlivier Matz 				rte_mempool_free(rte_mp);
442b19a0c75SOlivier Matz 				rte_mp = NULL;
443b19a0c75SOlivier Matz 			}
444b19a0c75SOlivier Matz 			rte_pktmbuf_pool_init(rte_mp, NULL);
445b19a0c75SOlivier Matz 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
446b19a0c75SOlivier Matz 		} else {
447ea0c20eaSOlivier Matz 			/* wrapper to rte_mempool_create() */
448ea0c20eaSOlivier Matz 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
449ea0c20eaSOlivier Matz 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
450bece7b6cSChristian Ehrhardt 		}
451b19a0c75SOlivier Matz 	}
452148f963fSBruce Richardson 
453af75078fSIntel 	if (rte_mp == NULL) {
454d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
455d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
456d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
457148f963fSBruce Richardson 	} else if (verbose_level > 0) {
458591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
459af75078fSIntel 	}
460af75078fSIntel }
461af75078fSIntel 
46220a0286fSLiu Xiaofeng /*
46320a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
46420a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
46520a0286fSLiu Xiaofeng  */
46620a0286fSLiu Xiaofeng static int
46720a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
46820a0286fSLiu Xiaofeng {
46920a0286fSLiu Xiaofeng 	static int warning_once = 0;
47020a0286fSLiu Xiaofeng 
4717acf894dSStephen Hurd 	if (socket_id >= max_socket) {
47220a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
47320a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
47420a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
47520a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
47620a0286fSLiu Xiaofeng 			       " --numa.\n");
47720a0286fSLiu Xiaofeng 		warning_once = 1;
47820a0286fSLiu Xiaofeng 		return -1;
47920a0286fSLiu Xiaofeng 	}
48020a0286fSLiu Xiaofeng 	return 0;
48120a0286fSLiu Xiaofeng }
48220a0286fSLiu Xiaofeng 
483af75078fSIntel static void
484af75078fSIntel init_config(void)
485af75078fSIntel {
486ce8d5614SIntel 	portid_t pid;
487af75078fSIntel 	struct rte_port *port;
488af75078fSIntel 	struct rte_mempool *mbp;
489af75078fSIntel 	unsigned int nb_mbuf_per_pool;
490af75078fSIntel 	lcoreid_t  lc_id;
4917acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
492af75078fSIntel 
4937acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
494af75078fSIntel 	/* Configuration of logical cores. */
495af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
496af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
497fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
498af75078fSIntel 	if (fwd_lcores == NULL) {
499ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
500ce8d5614SIntel 							"failed\n", nb_lcores);
501af75078fSIntel 	}
502af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
503af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
504af75078fSIntel 					       sizeof(struct fwd_lcore),
505fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
506af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
507ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
508ce8d5614SIntel 								"failed\n");
509af75078fSIntel 		}
510af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
511af75078fSIntel 	}
512af75078fSIntel 
513af75078fSIntel 	/*
514af75078fSIntel 	 * Create pools of mbuf.
515af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
516b6ea6408SIntel 	 * socket 0 memory by default.
517af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
518c8798818SIntel 	 *
519c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
520c8798818SIntel 	 * nb_txd can be configured at run time.
521af75078fSIntel 	 */
522c8798818SIntel 	if (param_total_num_mbufs)
523c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
524c8798818SIntel 	else {
525c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
526c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
527b6ea6408SIntel 
528b6ea6408SIntel 		if (!numa_support)
529edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
530edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
531c8798818SIntel 	}
532af75078fSIntel 
533b6ea6408SIntel 	if (!numa_support) {
534b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
535b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
536b6ea6408SIntel 		else
537b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
538b6ea6408SIntel 						 socket_num);
539b6ea6408SIntel 	}
540af75078fSIntel 
541edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
542ce8d5614SIntel 		port = &ports[pid];
543ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
544ce8d5614SIntel 
545b6ea6408SIntel 		if (numa_support) {
546b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
547b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
548b6ea6408SIntel 			else {
549b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
55020a0286fSLiu Xiaofeng 
55120a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
55220a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
55320a0286fSLiu Xiaofeng 					socket_id = 0;
554b6ea6408SIntel 				port_per_socket[socket_id]++;
555b6ea6408SIntel 			}
556b6ea6408SIntel 		}
557b6ea6408SIntel 
558ce8d5614SIntel 		/* set flag to initialize port/queue */
559ce8d5614SIntel 		port->need_reconfig = 1;
560ce8d5614SIntel 		port->need_reconfig_queues = 1;
561ce8d5614SIntel 	}
562ce8d5614SIntel 
563b6ea6408SIntel 	if (numa_support) {
564b6ea6408SIntel 		uint8_t i;
565b6ea6408SIntel 		unsigned int nb_mbuf;
566ce8d5614SIntel 
567b6ea6408SIntel 		if (param_total_num_mbufs)
568b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
569b6ea6408SIntel 
5707acf894dSStephen Hurd 		for (i = 0; i < max_socket; i++) {
571edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
572b6ea6408SIntel 			if (nb_mbuf)
573b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
574b6ea6408SIntel 						nb_mbuf,i);
575b6ea6408SIntel 		}
576b6ea6408SIntel 	}
577b6ea6408SIntel 	init_port_config();
5785886ae07SAdrien Mazarguil 
5795886ae07SAdrien Mazarguil 	/*
5805886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
5815886ae07SAdrien Mazarguil 	 */
5825886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
5838fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
5848fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
5858fd8bebcSAdrien Mazarguil 
5865886ae07SAdrien Mazarguil 		if (mbp == NULL)
5875886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
5885886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
5895886ae07SAdrien Mazarguil 	}
5905886ae07SAdrien Mazarguil 
591ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
592ce8d5614SIntel 	if (init_fwd_streams() < 0)
593ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
594ce8d5614SIntel }
595ce8d5614SIntel 
5962950a769SDeclan Doherty 
5972950a769SDeclan Doherty void
598a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
5992950a769SDeclan Doherty {
6002950a769SDeclan Doherty 	struct rte_port *port;
6012950a769SDeclan Doherty 
6022950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6032950a769SDeclan Doherty 	port = &ports[new_port_id];
6042950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6052950a769SDeclan Doherty 
6062950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6072950a769SDeclan Doherty 	port->need_reconfig = 1;
6082950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
609a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6102950a769SDeclan Doherty 
6112950a769SDeclan Doherty 	init_port_config();
6122950a769SDeclan Doherty }
6132950a769SDeclan Doherty 
6142950a769SDeclan Doherty 
615ce8d5614SIntel int
616ce8d5614SIntel init_fwd_streams(void)
617ce8d5614SIntel {
618ce8d5614SIntel 	portid_t pid;
619ce8d5614SIntel 	struct rte_port *port;
620ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
6215a8fb55cSReshma Pattan 	queueid_t q;
622ce8d5614SIntel 
623ce8d5614SIntel 	/* set socket id according to numa or not */
624edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
625ce8d5614SIntel 		port = &ports[pid];
626ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
627ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
628ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
629ce8d5614SIntel 				port->dev_info.max_rx_queues);
630ce8d5614SIntel 			return -1;
631ce8d5614SIntel 		}
632ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
633ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
634ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
635ce8d5614SIntel 				port->dev_info.max_tx_queues);
636ce8d5614SIntel 			return -1;
637ce8d5614SIntel 		}
63820a0286fSLiu Xiaofeng 		if (numa_support) {
63920a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
64020a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
64120a0286fSLiu Xiaofeng 			else {
642b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
64320a0286fSLiu Xiaofeng 
64420a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
64520a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
64620a0286fSLiu Xiaofeng 					port->socket_id = 0;
64720a0286fSLiu Xiaofeng 			}
64820a0286fSLiu Xiaofeng 		}
649b6ea6408SIntel 		else {
650b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
651af75078fSIntel 				port->socket_id = 0;
652b6ea6408SIntel 			else
653b6ea6408SIntel 				port->socket_id = socket_num;
654b6ea6408SIntel 		}
655af75078fSIntel 	}
656af75078fSIntel 
6575a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
6585a8fb55cSReshma Pattan 	if (q == 0) {
6595a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
6605a8fb55cSReshma Pattan 		return -1;
6615a8fb55cSReshma Pattan 	}
6625a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
663ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
664ce8d5614SIntel 		return 0;
665ce8d5614SIntel 	/* clear the old */
666ce8d5614SIntel 	if (fwd_streams != NULL) {
667ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
668ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
669ce8d5614SIntel 				continue;
670ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
671ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
672af75078fSIntel 		}
673ce8d5614SIntel 		rte_free(fwd_streams);
674ce8d5614SIntel 		fwd_streams = NULL;
675ce8d5614SIntel 	}
676ce8d5614SIntel 
677ce8d5614SIntel 	/* init new */
678ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
679ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
680fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
681ce8d5614SIntel 	if (fwd_streams == NULL)
682ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
683ce8d5614SIntel 						"failed\n", nb_fwd_streams);
684ce8d5614SIntel 
685af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
686af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
687fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
688ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
689ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
690ce8d5614SIntel 								" failed\n");
691af75078fSIntel 	}
692ce8d5614SIntel 
693ce8d5614SIntel 	return 0;
694af75078fSIntel }
695af75078fSIntel 
696af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
697af75078fSIntel static void
698af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
699af75078fSIntel {
700af75078fSIntel 	unsigned int total_burst;
701af75078fSIntel 	unsigned int nb_burst;
702af75078fSIntel 	unsigned int burst_stats[3];
703af75078fSIntel 	uint16_t pktnb_stats[3];
704af75078fSIntel 	uint16_t nb_pkt;
705af75078fSIntel 	int burst_percent[3];
706af75078fSIntel 
707af75078fSIntel 	/*
708af75078fSIntel 	 * First compute the total number of packet bursts and the
709af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
710af75078fSIntel 	 */
711af75078fSIntel 	total_burst = 0;
712af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
713af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
714af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
715af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
716af75078fSIntel 		if (nb_burst == 0)
717af75078fSIntel 			continue;
718af75078fSIntel 		total_burst += nb_burst;
719af75078fSIntel 		if (nb_burst > burst_stats[0]) {
720af75078fSIntel 			burst_stats[1] = burst_stats[0];
721af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
722af75078fSIntel 			burst_stats[0] = nb_burst;
723af75078fSIntel 			pktnb_stats[0] = nb_pkt;
724af75078fSIntel 		}
725af75078fSIntel 	}
726af75078fSIntel 	if (total_burst == 0)
727af75078fSIntel 		return;
728af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
729af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
730af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
731af75078fSIntel 	if (burst_stats[0] == total_burst) {
732af75078fSIntel 		printf("]\n");
733af75078fSIntel 		return;
734af75078fSIntel 	}
735af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
736af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
737af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
738af75078fSIntel 		return;
739af75078fSIntel 	}
740af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
741af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
742af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
743af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
744af75078fSIntel 		return;
745af75078fSIntel 	}
746af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
747af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
748af75078fSIntel }
749af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
750af75078fSIntel 
751af75078fSIntel static void
752af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
753af75078fSIntel {
754af75078fSIntel 	struct rte_port *port;
755013af9b6SIntel 	uint8_t i;
756af75078fSIntel 
757af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
758af75078fSIntel 
759af75078fSIntel 	port = &ports[port_id];
760af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
761af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
762013af9b6SIntel 
763013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
764af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
765af75078fSIntel 		       "%-"PRIu64"\n",
76670bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
76770bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
768af75078fSIntel 
769af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
770af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
771af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
77286057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
773f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
77470bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
77570bdb186SIvan Boule 		}
776af75078fSIntel 
777af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
778af75078fSIntel 		       "%-"PRIu64"\n",
779af75078fSIntel 		       stats->opackets, port->tx_dropped,
780af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
781013af9b6SIntel 	}
782013af9b6SIntel 	else {
783013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
784013af9b6SIntel 		       "%14"PRIu64"\n",
78570bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
78670bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
787013af9b6SIntel 
788013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
789013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
790013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
79186057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
792f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
79370bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
79470bdb186SIvan Boule 			       stats->rx_nombuf);
79570bdb186SIvan Boule 		}
796013af9b6SIntel 
797013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
798013af9b6SIntel 		       "%14"PRIu64"\n",
799013af9b6SIntel 		       stats->opackets, port->tx_dropped,
800013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
801013af9b6SIntel 	}
802e659b6b4SIvan Boule 
803af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
804af75078fSIntel 	if (port->rx_stream)
805013af9b6SIntel 		pkt_burst_stats_display("RX",
806013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
807af75078fSIntel 	if (port->tx_stream)
808013af9b6SIntel 		pkt_burst_stats_display("TX",
809013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
810af75078fSIntel #endif
811af75078fSIntel 
812013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
813013af9b6SIntel 		printf("\n");
814013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
815013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
816013af9b6SIntel 			       "     RX-errors:%14"PRIu64
817013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
818013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
819013af9b6SIntel 		}
820013af9b6SIntel 		printf("\n");
821013af9b6SIntel 	}
822013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
823013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
824013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
825013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
826013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
827013af9b6SIntel 		}
828013af9b6SIntel 	}
829013af9b6SIntel 
830af75078fSIntel 	printf("  %s--------------------------------%s\n",
831af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
832af75078fSIntel }
833af75078fSIntel 
834af75078fSIntel static void
835af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
836af75078fSIntel {
837af75078fSIntel 	struct fwd_stream *fs;
838af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
839af75078fSIntel 
840af75078fSIntel 	fs = fwd_streams[stream_id];
841af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
842af75078fSIntel 	    (fs->fwd_dropped == 0))
843af75078fSIntel 		return;
844af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
845af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
846af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
847af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
848af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
849af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
850af75078fSIntel 
851af75078fSIntel 	/* if checksum mode */
852af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
853013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
854013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
855af75078fSIntel 	}
856af75078fSIntel 
857af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
858af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
859af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
860af75078fSIntel #endif
861af75078fSIntel }
862af75078fSIntel 
863af75078fSIntel static void
8647741e4cfSIntel flush_fwd_rx_queues(void)
865af75078fSIntel {
866af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
867af75078fSIntel 	portid_t  rxp;
8687741e4cfSIntel 	portid_t port_id;
869af75078fSIntel 	queueid_t rxq;
870af75078fSIntel 	uint16_t  nb_rx;
871af75078fSIntel 	uint16_t  i;
872af75078fSIntel 	uint8_t   j;
873af75078fSIntel 
874af75078fSIntel 	for (j = 0; j < 2; j++) {
8757741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
876af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
8777741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
878af75078fSIntel 				do {
8797741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
880013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
881af75078fSIntel 					for (i = 0; i < nb_rx; i++)
882af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
883af75078fSIntel 				} while (nb_rx > 0);
884af75078fSIntel 			}
885af75078fSIntel 		}
886af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
887af75078fSIntel 	}
888af75078fSIntel }
889af75078fSIntel 
890af75078fSIntel static void
891af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
892af75078fSIntel {
893af75078fSIntel 	struct fwd_stream **fsm;
894af75078fSIntel 	streamid_t nb_fs;
895af75078fSIntel 	streamid_t sm_id;
896af75078fSIntel 
897af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
898af75078fSIntel 	nb_fs = fc->stream_nb;
899af75078fSIntel 	do {
900af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
901af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
902af75078fSIntel 	} while (! fc->stopped);
903af75078fSIntel }
904af75078fSIntel 
905af75078fSIntel static int
906af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
907af75078fSIntel {
908af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
909af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
910af75078fSIntel 	return 0;
911af75078fSIntel }
912af75078fSIntel 
913af75078fSIntel /*
914af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
915af75078fSIntel  * Used to start communication flows in network loopback test configurations.
916af75078fSIntel  */
917af75078fSIntel static int
918af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
919af75078fSIntel {
920af75078fSIntel 	struct fwd_lcore *fwd_lc;
921af75078fSIntel 	struct fwd_lcore tmp_lcore;
922af75078fSIntel 
923af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
924af75078fSIntel 	tmp_lcore = *fwd_lc;
925af75078fSIntel 	tmp_lcore.stopped = 1;
926af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
927af75078fSIntel 	return 0;
928af75078fSIntel }
929af75078fSIntel 
930af75078fSIntel /*
931af75078fSIntel  * Launch packet forwarding:
932af75078fSIntel  *     - Setup per-port forwarding context.
933af75078fSIntel  *     - launch logical cores with their forwarding configuration.
934af75078fSIntel  */
935af75078fSIntel static void
936af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
937af75078fSIntel {
938af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
939af75078fSIntel 	unsigned int i;
940af75078fSIntel 	unsigned int lc_id;
941af75078fSIntel 	int diag;
942af75078fSIntel 
943af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
944af75078fSIntel 	if (port_fwd_begin != NULL) {
945af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
946af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
947af75078fSIntel 	}
948af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
949af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
950af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
951af75078fSIntel 			fwd_lcores[i]->stopped = 0;
952af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
953af75078fSIntel 						     fwd_lcores[i], lc_id);
954af75078fSIntel 			if (diag != 0)
955af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
956af75078fSIntel 				       lc_id, diag);
957af75078fSIntel 		}
958af75078fSIntel 	}
959af75078fSIntel }
960af75078fSIntel 
961af75078fSIntel /*
962af75078fSIntel  * Launch packet forwarding configuration.
963af75078fSIntel  */
964af75078fSIntel void
965af75078fSIntel start_packet_forwarding(int with_tx_first)
966af75078fSIntel {
967af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
968af75078fSIntel 	port_fwd_end_t  port_fwd_end;
969af75078fSIntel 	struct rte_port *port;
970af75078fSIntel 	unsigned int i;
971af75078fSIntel 	portid_t   pt_id;
972af75078fSIntel 	streamid_t sm_id;
973af75078fSIntel 
9745a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
9755a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
9765a8fb55cSReshma Pattan 
9775a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
9785a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
9795a8fb55cSReshma Pattan 
9805a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
9815a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
9825a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
9835a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
9845a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
9855a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
9865a8fb55cSReshma Pattan 
987ce8d5614SIntel 	if (all_ports_started() == 0) {
988ce8d5614SIntel 		printf("Not all ports were started\n");
989ce8d5614SIntel 		return;
990ce8d5614SIntel 	}
991af75078fSIntel 	if (test_done == 0) {
992af75078fSIntel 		printf("Packet forwarding already started\n");
993af75078fSIntel 		return;
994af75078fSIntel 	}
9957741e4cfSIntel 	if(dcb_test) {
9967741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
9977741e4cfSIntel 			pt_id = fwd_ports_ids[i];
9987741e4cfSIntel 			port = &ports[pt_id];
9997741e4cfSIntel 			if (!port->dcb_flag) {
10007741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
10017741e4cfSIntel                                        "be configured in this mode.\n");
1002013af9b6SIntel 				return;
1003013af9b6SIntel 			}
10047741e4cfSIntel 		}
10057741e4cfSIntel 		if (nb_fwd_lcores == 1) {
10067741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
10077741e4cfSIntel                                "should be larger than 1.\n");
10087741e4cfSIntel 			return;
10097741e4cfSIntel 		}
10107741e4cfSIntel 	}
1011af75078fSIntel 	test_done = 0;
10127741e4cfSIntel 
10137741e4cfSIntel 	if(!no_flush_rx)
10147741e4cfSIntel 		flush_fwd_rx_queues();
10157741e4cfSIntel 
1016af75078fSIntel 	fwd_config_setup();
1017af75078fSIntel 	rxtx_config_display();
1018af75078fSIntel 
1019af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1020af75078fSIntel 		pt_id = fwd_ports_ids[i];
1021af75078fSIntel 		port = &ports[pt_id];
1022af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1023af75078fSIntel 		port->tx_dropped = 0;
1024013af9b6SIntel 
1025013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1026af75078fSIntel 	}
1027af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1028af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1029af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1030af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1031af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1032af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1033af75078fSIntel 
1034af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1035af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1036af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1037af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1038af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1039af75078fSIntel #endif
1040af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1041af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1042af75078fSIntel #endif
1043af75078fSIntel 	}
1044af75078fSIntel 	if (with_tx_first) {
1045af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1046af75078fSIntel 		if (port_fwd_begin != NULL) {
1047af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1048af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1049af75078fSIntel 		}
1050af75078fSIntel 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1051af75078fSIntel 		rte_eal_mp_wait_lcore();
1052af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1053af75078fSIntel 		if (port_fwd_end != NULL) {
1054af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1055af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1056af75078fSIntel 		}
1057af75078fSIntel 	}
1058af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1059af75078fSIntel }
1060af75078fSIntel 
1061af75078fSIntel void
1062af75078fSIntel stop_packet_forwarding(void)
1063af75078fSIntel {
1064af75078fSIntel 	struct rte_eth_stats stats;
1065af75078fSIntel 	struct rte_port *port;
1066af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1067af75078fSIntel 	int i;
1068af75078fSIntel 	portid_t   pt_id;
1069af75078fSIntel 	streamid_t sm_id;
1070af75078fSIntel 	lcoreid_t  lc_id;
1071af75078fSIntel 	uint64_t total_recv;
1072af75078fSIntel 	uint64_t total_xmit;
1073af75078fSIntel 	uint64_t total_rx_dropped;
1074af75078fSIntel 	uint64_t total_tx_dropped;
1075af75078fSIntel 	uint64_t total_rx_nombuf;
1076af75078fSIntel 	uint64_t tx_dropped;
1077af75078fSIntel 	uint64_t rx_bad_ip_csum;
1078af75078fSIntel 	uint64_t rx_bad_l4_csum;
1079af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1080af75078fSIntel 	uint64_t fwd_cycles;
1081af75078fSIntel #endif
1082af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1083af75078fSIntel 
1084ce8d5614SIntel 	if (all_ports_started() == 0) {
1085ce8d5614SIntel 		printf("Not all ports were started\n");
1086ce8d5614SIntel 		return;
1087ce8d5614SIntel 	}
1088af75078fSIntel 	if (test_done) {
1089af75078fSIntel 		printf("Packet forwarding not started\n");
1090af75078fSIntel 		return;
1091af75078fSIntel 	}
1092af75078fSIntel 	printf("Telling cores to stop...");
1093af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1094af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1095af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1096af75078fSIntel 	rte_eal_mp_wait_lcore();
1097af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1098af75078fSIntel 	if (port_fwd_end != NULL) {
1099af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1100af75078fSIntel 			pt_id = fwd_ports_ids[i];
1101af75078fSIntel 			(*port_fwd_end)(pt_id);
1102af75078fSIntel 		}
1103af75078fSIntel 	}
1104af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1105af75078fSIntel 	fwd_cycles = 0;
1106af75078fSIntel #endif
1107af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1108af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1109af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1110af75078fSIntel 			fwd_stream_stats_display(sm_id);
1111af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1112af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1113af75078fSIntel 		} else {
1114af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1115af75078fSIntel 				fwd_streams[sm_id];
1116af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1117af75078fSIntel 				fwd_streams[sm_id];
1118af75078fSIntel 		}
1119af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1120af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1121af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1122af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1123af75078fSIntel 
1124013af9b6SIntel 		rx_bad_ip_csum =
1125013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1126af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1127af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1128013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1129013af9b6SIntel 							rx_bad_ip_csum;
1130af75078fSIntel 
1131013af9b6SIntel 		rx_bad_l4_csum =
1132013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1133af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1134af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1135013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1136013af9b6SIntel 							rx_bad_l4_csum;
1137af75078fSIntel 
1138af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1139af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1140af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1141af75078fSIntel #endif
1142af75078fSIntel 	}
1143af75078fSIntel 	total_recv = 0;
1144af75078fSIntel 	total_xmit = 0;
1145af75078fSIntel 	total_rx_dropped = 0;
1146af75078fSIntel 	total_tx_dropped = 0;
1147af75078fSIntel 	total_rx_nombuf  = 0;
11487741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1149af75078fSIntel 		pt_id = fwd_ports_ids[i];
1150af75078fSIntel 
1151af75078fSIntel 		port = &ports[pt_id];
1152af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1153af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1154af75078fSIntel 		port->stats.ipackets = 0;
1155af75078fSIntel 		stats.opackets -= port->stats.opackets;
1156af75078fSIntel 		port->stats.opackets = 0;
1157af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1158af75078fSIntel 		port->stats.ibytes = 0;
1159af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1160af75078fSIntel 		port->stats.obytes = 0;
116170bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
116270bdb186SIvan Boule 		port->stats.imissed = 0;
1163af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1164af75078fSIntel 		port->stats.oerrors = 0;
1165af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1166af75078fSIntel 		port->stats.rx_nombuf = 0;
1167af75078fSIntel 
1168af75078fSIntel 		total_recv += stats.ipackets;
1169af75078fSIntel 		total_xmit += stats.opackets;
117070bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1171af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1172af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1173af75078fSIntel 
1174af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1175af75078fSIntel 	}
1176af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1177af75078fSIntel 	       "%s\n",
1178af75078fSIntel 	       acc_stats_border, acc_stats_border);
1179af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1180af75078fSIntel 	       "%-"PRIu64"\n"
1181af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1182af75078fSIntel 	       "%-"PRIu64"\n",
1183af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1184af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1185af75078fSIntel 	if (total_rx_nombuf > 0)
1186af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1187af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1188af75078fSIntel 	       "%s\n",
1189af75078fSIntel 	       acc_stats_border, acc_stats_border);
1190af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1191af75078fSIntel 	if (total_recv > 0)
1192af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1193af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1194af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1195af75078fSIntel 		       fwd_cycles, total_recv);
1196af75078fSIntel #endif
1197af75078fSIntel 	printf("\nDone.\n");
1198af75078fSIntel 	test_done = 1;
1199af75078fSIntel }
1200af75078fSIntel 
1201cfae07fdSOuyang Changchun void
1202cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1203cfae07fdSOuyang Changchun {
1204cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1205cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1206cfae07fdSOuyang Changchun }
1207cfae07fdSOuyang Changchun 
1208cfae07fdSOuyang Changchun void
1209cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1210cfae07fdSOuyang Changchun {
1211cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1212cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1213cfae07fdSOuyang Changchun }
1214cfae07fdSOuyang Changchun 
1215ce8d5614SIntel static int
1216ce8d5614SIntel all_ports_started(void)
1217ce8d5614SIntel {
1218ce8d5614SIntel 	portid_t pi;
1219ce8d5614SIntel 	struct rte_port *port;
1220ce8d5614SIntel 
1221edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1222ce8d5614SIntel 		port = &ports[pi];
1223ce8d5614SIntel 		/* Check if there is a port which is not started */
122441b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
122541b05095SBernard Iremonger 			(port->slave_flag == 0))
1226ce8d5614SIntel 			return 0;
1227ce8d5614SIntel 	}
1228ce8d5614SIntel 
1229ce8d5614SIntel 	/* No port is not started */
1230ce8d5614SIntel 	return 1;
1231ce8d5614SIntel }
1232ce8d5614SIntel 
1233148f963fSBruce Richardson int
1234edab33b1STetsuya Mukawa all_ports_stopped(void)
1235edab33b1STetsuya Mukawa {
1236edab33b1STetsuya Mukawa 	portid_t pi;
1237edab33b1STetsuya Mukawa 	struct rte_port *port;
1238edab33b1STetsuya Mukawa 
1239edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1240edab33b1STetsuya Mukawa 		port = &ports[pi];
124141b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
124241b05095SBernard Iremonger 			(port->slave_flag == 0))
1243edab33b1STetsuya Mukawa 			return 0;
1244edab33b1STetsuya Mukawa 	}
1245edab33b1STetsuya Mukawa 
1246edab33b1STetsuya Mukawa 	return 1;
1247edab33b1STetsuya Mukawa }
1248edab33b1STetsuya Mukawa 
1249edab33b1STetsuya Mukawa int
1250edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1251edab33b1STetsuya Mukawa {
1252edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1253edab33b1STetsuya Mukawa 		return 0;
1254edab33b1STetsuya Mukawa 
1255edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1256edab33b1STetsuya Mukawa 		return 0;
1257edab33b1STetsuya Mukawa 
1258edab33b1STetsuya Mukawa 	return 1;
1259edab33b1STetsuya Mukawa }
1260edab33b1STetsuya Mukawa 
1261edab33b1STetsuya Mukawa static int
1262edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1263edab33b1STetsuya Mukawa {
1264edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1265edab33b1STetsuya Mukawa 		return 0;
1266edab33b1STetsuya Mukawa 
1267edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1268edab33b1STetsuya Mukawa 		return 0;
1269edab33b1STetsuya Mukawa 
1270edab33b1STetsuya Mukawa 	return 1;
1271edab33b1STetsuya Mukawa }
1272edab33b1STetsuya Mukawa 
1273edab33b1STetsuya Mukawa int
1274ce8d5614SIntel start_port(portid_t pid)
1275ce8d5614SIntel {
127692d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1277ce8d5614SIntel 	portid_t pi;
1278ce8d5614SIntel 	queueid_t qi;
1279ce8d5614SIntel 	struct rte_port *port;
12802950a769SDeclan Doherty 	struct ether_addr mac_addr;
1281ce8d5614SIntel 
12824468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
12834468635fSMichael Qiu 		return 0;
12844468635fSMichael Qiu 
1285ce8d5614SIntel 	if (init_fwd_streams() < 0) {
1286ce8d5614SIntel 		printf("Fail from init_fwd_streams()\n");
1287148f963fSBruce Richardson 		return -1;
1288ce8d5614SIntel 	}
1289ce8d5614SIntel 
1290ce8d5614SIntel 	if(dcb_config)
1291ce8d5614SIntel 		dcb_test = 1;
1292edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1293edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1294ce8d5614SIntel 			continue;
1295ce8d5614SIntel 
129692d2703eSMichael Qiu 		need_check_link_status = 0;
1297ce8d5614SIntel 		port = &ports[pi];
1298ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1299ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1300ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1301ce8d5614SIntel 			continue;
1302ce8d5614SIntel 		}
1303ce8d5614SIntel 
1304ce8d5614SIntel 		if (port->need_reconfig > 0) {
1305ce8d5614SIntel 			port->need_reconfig = 0;
1306ce8d5614SIntel 
13075706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
130820a0286fSLiu Xiaofeng 					port->socket_id);
1309ce8d5614SIntel 			/* configure port */
1310ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1311ce8d5614SIntel 						&(port->dev_conf));
1312ce8d5614SIntel 			if (diag != 0) {
1313ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1314ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1315ce8d5614SIntel 					printf("Port %d can not be set back "
1316ce8d5614SIntel 							"to stopped\n", pi);
1317ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1318ce8d5614SIntel 				/* try to reconfigure port next time */
1319ce8d5614SIntel 				port->need_reconfig = 1;
1320148f963fSBruce Richardson 				return -1;
1321ce8d5614SIntel 			}
1322ce8d5614SIntel 		}
1323ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1324ce8d5614SIntel 			port->need_reconfig_queues = 0;
1325ce8d5614SIntel 			/* setup tx queues */
1326ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1327b6ea6408SIntel 				if ((numa_support) &&
1328b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1329b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1330b6ea6408SIntel 						nb_txd,txring_numa[pi],
1331b6ea6408SIntel 						&(port->tx_conf));
1332b6ea6408SIntel 				else
1333b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1334b6ea6408SIntel 						nb_txd,port->socket_id,
1335b6ea6408SIntel 						&(port->tx_conf));
1336b6ea6408SIntel 
1337ce8d5614SIntel 				if (diag == 0)
1338ce8d5614SIntel 					continue;
1339ce8d5614SIntel 
1340ce8d5614SIntel 				/* Fail to setup tx queue, return */
1341ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1342ce8d5614SIntel 							RTE_PORT_HANDLING,
1343ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1344ce8d5614SIntel 					printf("Port %d can not be set back "
1345ce8d5614SIntel 							"to stopped\n", pi);
1346ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1347ce8d5614SIntel 				/* try to reconfigure queues next time */
1348ce8d5614SIntel 				port->need_reconfig_queues = 1;
1349148f963fSBruce Richardson 				return -1;
1350ce8d5614SIntel 			}
1351ce8d5614SIntel 			/* setup rx queues */
1352ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1353b6ea6408SIntel 				if ((numa_support) &&
1354b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1355b6ea6408SIntel 					struct rte_mempool * mp =
1356b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1357b6ea6408SIntel 					if (mp == NULL) {
1358b6ea6408SIntel 						printf("Failed to setup RX queue:"
1359b6ea6408SIntel 							"No mempool allocation"
1360b6ea6408SIntel 							"on the socket %d\n",
1361b6ea6408SIntel 							rxring_numa[pi]);
1362148f963fSBruce Richardson 						return -1;
1363b6ea6408SIntel 					}
1364b6ea6408SIntel 
1365b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1366b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1367b6ea6408SIntel 					     &(port->rx_conf),mp);
1368b6ea6408SIntel 				}
1369b6ea6408SIntel 				else
1370b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1371b6ea6408SIntel 					     nb_rxd,port->socket_id,
1372b6ea6408SIntel 					     &(port->rx_conf),
1373ce8d5614SIntel 				             mbuf_pool_find(port->socket_id));
1374b6ea6408SIntel 
1375ce8d5614SIntel 				if (diag == 0)
1376ce8d5614SIntel 					continue;
1377ce8d5614SIntel 
1378b6ea6408SIntel 
1379ce8d5614SIntel 				/* Fail to setup rx queue, return */
1380ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1381ce8d5614SIntel 							RTE_PORT_HANDLING,
1382ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1383ce8d5614SIntel 					printf("Port %d can not be set back "
1384ce8d5614SIntel 							"to stopped\n", pi);
1385ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1386ce8d5614SIntel 				/* try to reconfigure queues next time */
1387ce8d5614SIntel 				port->need_reconfig_queues = 1;
1388148f963fSBruce Richardson 				return -1;
1389ce8d5614SIntel 			}
1390ce8d5614SIntel 		}
1391ce8d5614SIntel 		/* start port */
1392ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1393ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1394ce8d5614SIntel 
1395ce8d5614SIntel 			/* Fail to setup rx queue, return */
1396ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1397ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1398ce8d5614SIntel 				printf("Port %d can not be set back to "
1399ce8d5614SIntel 							"stopped\n", pi);
1400ce8d5614SIntel 			continue;
1401ce8d5614SIntel 		}
1402ce8d5614SIntel 
1403ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1404ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1405ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1406ce8d5614SIntel 
14072950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1408d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
14092950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
14102950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
14112950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1412d8c89163SZijie Pan 
1413ce8d5614SIntel 		/* at least one port started, need checking link status */
1414ce8d5614SIntel 		need_check_link_status = 1;
1415ce8d5614SIntel 	}
1416ce8d5614SIntel 
141792d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1418edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
141992d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1420ce8d5614SIntel 		printf("Please stop the ports first\n");
1421ce8d5614SIntel 
1422ce8d5614SIntel 	printf("Done\n");
1423148f963fSBruce Richardson 	return 0;
1424ce8d5614SIntel }
1425ce8d5614SIntel 
1426ce8d5614SIntel void
1427ce8d5614SIntel stop_port(portid_t pid)
1428ce8d5614SIntel {
1429ce8d5614SIntel 	portid_t pi;
1430ce8d5614SIntel 	struct rte_port *port;
1431ce8d5614SIntel 	int need_check_link_status = 0;
1432ce8d5614SIntel 
1433ce8d5614SIntel 	if (dcb_test) {
1434ce8d5614SIntel 		dcb_test = 0;
1435ce8d5614SIntel 		dcb_config = 0;
1436ce8d5614SIntel 	}
14374468635fSMichael Qiu 
14384468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14394468635fSMichael Qiu 		return;
14404468635fSMichael Qiu 
1441ce8d5614SIntel 	printf("Stopping ports...\n");
1442ce8d5614SIntel 
1443edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14444468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1445ce8d5614SIntel 			continue;
1446ce8d5614SIntel 
1447a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1448a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1449a8ef3e3aSBernard Iremonger 			continue;
1450a8ef3e3aSBernard Iremonger 		}
1451a8ef3e3aSBernard Iremonger 
1452*0e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
1453*0e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
1454*0e545d30SBernard Iremonger 			continue;
1455*0e545d30SBernard Iremonger 		}
1456*0e545d30SBernard Iremonger 
1457ce8d5614SIntel 		port = &ports[pi];
1458ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1459ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1460ce8d5614SIntel 			continue;
1461ce8d5614SIntel 
1462ce8d5614SIntel 		rte_eth_dev_stop(pi);
1463ce8d5614SIntel 
1464ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1465ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1466ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1467ce8d5614SIntel 		need_check_link_status = 1;
1468ce8d5614SIntel 	}
1469bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1470edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1471ce8d5614SIntel 
1472ce8d5614SIntel 	printf("Done\n");
1473ce8d5614SIntel }
1474ce8d5614SIntel 
1475ce8d5614SIntel void
1476ce8d5614SIntel close_port(portid_t pid)
1477ce8d5614SIntel {
1478ce8d5614SIntel 	portid_t pi;
1479ce8d5614SIntel 	struct rte_port *port;
1480ce8d5614SIntel 
14814468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14824468635fSMichael Qiu 		return;
14834468635fSMichael Qiu 
1484ce8d5614SIntel 	printf("Closing ports...\n");
1485ce8d5614SIntel 
1486edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14874468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1488ce8d5614SIntel 			continue;
1489ce8d5614SIntel 
1490a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1491a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1492a8ef3e3aSBernard Iremonger 			continue;
1493a8ef3e3aSBernard Iremonger 		}
1494a8ef3e3aSBernard Iremonger 
1495*0e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
1496*0e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
1497*0e545d30SBernard Iremonger 			continue;
1498*0e545d30SBernard Iremonger 		}
1499*0e545d30SBernard Iremonger 
1500ce8d5614SIntel 		port = &ports[pi];
1501ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1502d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1503d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1504d4e8ad64SMichael Qiu 			continue;
1505d4e8ad64SMichael Qiu 		}
1506d4e8ad64SMichael Qiu 
1507d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1508ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1509ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1510ce8d5614SIntel 			continue;
1511ce8d5614SIntel 		}
1512ce8d5614SIntel 
1513ce8d5614SIntel 		rte_eth_dev_close(pi);
1514ce8d5614SIntel 
1515ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1516ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1517b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1518ce8d5614SIntel 	}
1519ce8d5614SIntel 
1520ce8d5614SIntel 	printf("Done\n");
1521ce8d5614SIntel }
1522ce8d5614SIntel 
1523edab33b1STetsuya Mukawa void
1524edab33b1STetsuya Mukawa attach_port(char *identifier)
1525ce8d5614SIntel {
1526ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1527ce8d5614SIntel 
1528edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1529edab33b1STetsuya Mukawa 
1530edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1531edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1532edab33b1STetsuya Mukawa 		return;
1533ce8d5614SIntel 	}
1534ce8d5614SIntel 
1535edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1536edab33b1STetsuya Mukawa 		return;
1537edab33b1STetsuya Mukawa 
1538edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1539edab33b1STetsuya Mukawa 	reconfig(pi, rte_eth_dev_socket_id(pi));
1540edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1541edab33b1STetsuya Mukawa 
1542edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1543edab33b1STetsuya Mukawa 
1544edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1545edab33b1STetsuya Mukawa 
1546edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1547edab33b1STetsuya Mukawa 	printf("Done\n");
1548edab33b1STetsuya Mukawa }
1549edab33b1STetsuya Mukawa 
1550edab33b1STetsuya Mukawa void
1551edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
15525f4ec54fSChen Jing D(Mark) {
1553edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
15545f4ec54fSChen Jing D(Mark) 
1555edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
15565f4ec54fSChen Jing D(Mark) 
1557edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1558edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1559edab33b1STetsuya Mukawa 		return;
1560edab33b1STetsuya Mukawa 	}
1561edab33b1STetsuya Mukawa 
1562edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1563edab33b1STetsuya Mukawa 		return;
1564edab33b1STetsuya Mukawa 
1565edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1566edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1567edab33b1STetsuya Mukawa 
1568edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1569edab33b1STetsuya Mukawa 			name, nb_ports);
1570edab33b1STetsuya Mukawa 	printf("Done\n");
1571edab33b1STetsuya Mukawa 	return;
15725f4ec54fSChen Jing D(Mark) }
15735f4ec54fSChen Jing D(Mark) 
1574af75078fSIntel void
1575af75078fSIntel pmd_test_exit(void)
1576af75078fSIntel {
1577af75078fSIntel 	portid_t pt_id;
1578af75078fSIntel 
15798210ec25SPablo de Lara 	if (test_done == 0)
15808210ec25SPablo de Lara 		stop_packet_forwarding();
15818210ec25SPablo de Lara 
1582d3a274ceSZhihong Wang 	if (ports != NULL) {
1583d3a274ceSZhihong Wang 		no_link_check = 1;
1584edab33b1STetsuya Mukawa 		FOREACH_PORT(pt_id, ports) {
1585d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1586af75078fSIntel 			fflush(stdout);
1587d3a274ceSZhihong Wang 			stop_port(pt_id);
1588d3a274ceSZhihong Wang 			close_port(pt_id);
1589af75078fSIntel 		}
1590d3a274ceSZhihong Wang 	}
1591d3a274ceSZhihong Wang 	printf("\nBye...\n");
1592af75078fSIntel }
1593af75078fSIntel 
1594af75078fSIntel typedef void (*cmd_func_t)(void);
1595af75078fSIntel struct pmd_test_command {
1596af75078fSIntel 	const char *cmd_name;
1597af75078fSIntel 	cmd_func_t cmd_func;
1598af75078fSIntel };
1599af75078fSIntel 
1600af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1601af75078fSIntel 
1602ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1603af75078fSIntel static void
1604edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1605af75078fSIntel {
1606ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1607ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1608ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1609ce8d5614SIntel 	struct rte_eth_link link;
1610ce8d5614SIntel 
1611ce8d5614SIntel 	printf("Checking link statuses...\n");
1612ce8d5614SIntel 	fflush(stdout);
1613ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1614ce8d5614SIntel 		all_ports_up = 1;
1615edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1616ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1617ce8d5614SIntel 				continue;
1618ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1619ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1620ce8d5614SIntel 			/* print link status if flag set */
1621ce8d5614SIntel 			if (print_flag == 1) {
1622ce8d5614SIntel 				if (link.link_status)
1623ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1624ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1625ce8d5614SIntel 						(unsigned)link.link_speed,
1626ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1627ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1628ce8d5614SIntel 				else
1629ce8d5614SIntel 					printf("Port %d Link Down\n",
1630ce8d5614SIntel 						(uint8_t)portid);
1631ce8d5614SIntel 				continue;
1632ce8d5614SIntel 			}
1633ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
163409419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1635ce8d5614SIntel 				all_ports_up = 0;
1636ce8d5614SIntel 				break;
1637ce8d5614SIntel 			}
1638ce8d5614SIntel 		}
1639ce8d5614SIntel 		/* after finally printing all link status, get out */
1640ce8d5614SIntel 		if (print_flag == 1)
1641ce8d5614SIntel 			break;
1642ce8d5614SIntel 
1643ce8d5614SIntel 		if (all_ports_up == 0) {
1644ce8d5614SIntel 			fflush(stdout);
1645ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1646ce8d5614SIntel 		}
1647ce8d5614SIntel 
1648ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1649ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1650ce8d5614SIntel 			print_flag = 1;
1651ce8d5614SIntel 		}
1652ce8d5614SIntel 	}
1653af75078fSIntel }
1654af75078fSIntel 
1655013af9b6SIntel static int
1656013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1657af75078fSIntel {
1658013af9b6SIntel 	uint16_t i;
1659af75078fSIntel 	int diag;
1660013af9b6SIntel 	uint8_t mapping_found = 0;
1661af75078fSIntel 
1662013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1663013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1664013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1665013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1666013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1667013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1668013af9b6SIntel 			if (diag != 0)
1669013af9b6SIntel 				return diag;
1670013af9b6SIntel 			mapping_found = 1;
1671af75078fSIntel 		}
1672013af9b6SIntel 	}
1673013af9b6SIntel 	if (mapping_found)
1674013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1675013af9b6SIntel 	return 0;
1676013af9b6SIntel }
1677013af9b6SIntel 
1678013af9b6SIntel static int
1679013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1680013af9b6SIntel {
1681013af9b6SIntel 	uint16_t i;
1682013af9b6SIntel 	int diag;
1683013af9b6SIntel 	uint8_t mapping_found = 0;
1684013af9b6SIntel 
1685013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1686013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1687013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1688013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1689013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1690013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1691013af9b6SIntel 			if (diag != 0)
1692013af9b6SIntel 				return diag;
1693013af9b6SIntel 			mapping_found = 1;
1694013af9b6SIntel 		}
1695013af9b6SIntel 	}
1696013af9b6SIntel 	if (mapping_found)
1697013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1698013af9b6SIntel 	return 0;
1699013af9b6SIntel }
1700013af9b6SIntel 
1701013af9b6SIntel static void
1702013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1703013af9b6SIntel {
1704013af9b6SIntel 	int diag = 0;
1705013af9b6SIntel 
1706013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1707af75078fSIntel 	if (diag != 0) {
1708013af9b6SIntel 		if (diag == -ENOTSUP) {
1709013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1710013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1711013af9b6SIntel 		}
1712013af9b6SIntel 		else
1713013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1714013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1715013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1716af75078fSIntel 					pi, diag);
1717af75078fSIntel 	}
1718013af9b6SIntel 
1719013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1720af75078fSIntel 	if (diag != 0) {
1721013af9b6SIntel 		if (diag == -ENOTSUP) {
1722013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1723013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1724013af9b6SIntel 		}
1725013af9b6SIntel 		else
1726013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1727013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1728013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1729af75078fSIntel 					pi, diag);
1730af75078fSIntel 	}
1731af75078fSIntel }
1732af75078fSIntel 
1733f2c5125aSPablo de Lara static void
1734f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1735f2c5125aSPablo de Lara {
1736f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1737f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1738f2c5125aSPablo de Lara 
1739f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1740f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1741f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1742f2c5125aSPablo de Lara 
1743f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1744f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1745f2c5125aSPablo de Lara 
1746f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1747f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1748f2c5125aSPablo de Lara 
1749f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1750f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1751f2c5125aSPablo de Lara 
1752f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1753f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1754f2c5125aSPablo de Lara 
1755f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1756f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1757f2c5125aSPablo de Lara 
1758f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1759f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1760f2c5125aSPablo de Lara 
1761f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1762f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1763f2c5125aSPablo de Lara 
1764f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1765f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1766f2c5125aSPablo de Lara 
1767f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1768f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1769f2c5125aSPablo de Lara 
1770f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1771f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1772f2c5125aSPablo de Lara }
1773f2c5125aSPablo de Lara 
1774013af9b6SIntel void
1775013af9b6SIntel init_port_config(void)
1776013af9b6SIntel {
1777013af9b6SIntel 	portid_t pid;
1778013af9b6SIntel 	struct rte_port *port;
1779013af9b6SIntel 
1780edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1781013af9b6SIntel 		port = &ports[pid];
1782013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1783013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
17843ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1785013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1786013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1787af75078fSIntel 		} else {
1788013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1789013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1790af75078fSIntel 		}
17913ce690d3SBruce Richardson 
17923ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
17933ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
17943ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
17953ce690d3SBruce Richardson 			else
17963ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
17973ce690d3SBruce Richardson 		}
17983ce690d3SBruce Richardson 
1799a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1800a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1801a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1802a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1803a30979f6SOuyang Changchun 			else
1804a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1805a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1806a30979f6SOuyang Changchun 
1807a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1808a30979f6SOuyang Changchun 		}
1809a30979f6SOuyang Changchun 
1810f2c5125aSPablo de Lara 		rxtx_port_config(port);
1811013af9b6SIntel 
1812013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1813013af9b6SIntel 
1814013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18157b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18167b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18177b7e5ba7SIntel #endif
1818013af9b6SIntel 	}
1819013af9b6SIntel }
1820013af9b6SIntel 
182141b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
182241b05095SBernard Iremonger {
182341b05095SBernard Iremonger 	struct rte_port *port;
182441b05095SBernard Iremonger 
182541b05095SBernard Iremonger 	port = &ports[slave_pid];
182641b05095SBernard Iremonger 	port->slave_flag = 1;
182741b05095SBernard Iremonger }
182841b05095SBernard Iremonger 
182941b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
183041b05095SBernard Iremonger {
183141b05095SBernard Iremonger 	struct rte_port *port;
183241b05095SBernard Iremonger 
183341b05095SBernard Iremonger 	port = &ports[slave_pid];
183441b05095SBernard Iremonger 	port->slave_flag = 0;
183541b05095SBernard Iremonger }
183641b05095SBernard Iremonger 
1837*0e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
1838*0e545d30SBernard Iremonger {
1839*0e545d30SBernard Iremonger 	struct rte_port *port;
1840*0e545d30SBernard Iremonger 
1841*0e545d30SBernard Iremonger 	port = &ports[slave_pid];
1842*0e545d30SBernard Iremonger 	return port->slave_flag;
1843*0e545d30SBernard Iremonger }
1844*0e545d30SBernard Iremonger 
1845013af9b6SIntel const uint16_t vlan_tags[] = {
1846013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1847013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1848013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1849013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1850013af9b6SIntel };
1851013af9b6SIntel 
1852013af9b6SIntel static  int
18531a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
18541a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
18551a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
18561a572499SJingjing Wu 		 uint8_t pfc_en)
1857013af9b6SIntel {
1858013af9b6SIntel 	uint8_t i;
1859af75078fSIntel 
1860af75078fSIntel 	/*
1861013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1862013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
1863af75078fSIntel 	 */
18641a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
18651a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
18661a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
18671a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
18681a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
1869013af9b6SIntel 
1870013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
18711a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
18721a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
18731a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
18741a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
18751a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
18761a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1877013af9b6SIntel 
18781a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
18791a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
18801a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
18811a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
18821a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
1883af75078fSIntel 		}
1884013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
18851a572499SJingjing Wu 			vmdq_rx_conf->dcb_tc[i] = i;
18861a572499SJingjing Wu 			vmdq_tx_conf->dcb_tc[i] = i;
1887013af9b6SIntel 		}
1888013af9b6SIntel 
1889013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
189032e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
189132e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
18921a572499SJingjing Wu 	} else {
18931a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
18941a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
18951a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
18961a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
1897013af9b6SIntel 
18981a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
18991a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
19001a572499SJingjing Wu 
19011a572499SJingjing Wu 		for (i = 0; i < num_tcs; i++) {
19021a572499SJingjing Wu 			rx_conf->dcb_tc[i] = i;
19031a572499SJingjing Wu 			tx_conf->dcb_tc[i] = i;
1904013af9b6SIntel 		}
19051a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
19061a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
190732e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
19081a572499SJingjing Wu 	}
19091a572499SJingjing Wu 
19101a572499SJingjing Wu 	if (pfc_en)
19111a572499SJingjing Wu 		eth_conf->dcb_capability_en =
19121a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
1913013af9b6SIntel 	else
1914013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1915013af9b6SIntel 
1916013af9b6SIntel 	return 0;
1917013af9b6SIntel }
1918013af9b6SIntel 
1919013af9b6SIntel int
19201a572499SJingjing Wu init_port_dcb_config(portid_t pid,
19211a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
19221a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
19231a572499SJingjing Wu 		     uint8_t pfc_en)
1924013af9b6SIntel {
1925013af9b6SIntel 	struct rte_eth_conf port_conf;
19261a572499SJingjing Wu 	struct rte_eth_dev_info dev_info;
1927013af9b6SIntel 	struct rte_port *rte_port;
1928013af9b6SIntel 	int retval;
1929013af9b6SIntel 	uint16_t i;
1930013af9b6SIntel 
19311a572499SJingjing Wu 	rte_eth_dev_info_get(pid, &dev_info);
19321a572499SJingjing Wu 
19331a572499SJingjing Wu 	/* If dev_info.vmdq_pool_base is greater than 0,
19341a572499SJingjing Wu 	 * the queue id of vmdq pools is started after pf queues.
19351a572499SJingjing Wu 	 */
19361a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED && dev_info.vmdq_pool_base > 0) {
19371a572499SJingjing Wu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
19381a572499SJingjing Wu 			" for port %d.", pid);
19391a572499SJingjing Wu 		return -1;
19401a572499SJingjing Wu 	}
19411a572499SJingjing Wu 
19421a572499SJingjing Wu 	/* Assume the ports in testpmd have the same dcb capability
19431a572499SJingjing Wu 	 * and has the same number of rxq and txq in dcb mode
19441a572499SJingjing Wu 	 */
19451a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
19461a572499SJingjing Wu 		nb_rxq = dev_info.max_rx_queues;
19471a572499SJingjing Wu 		nb_txq = dev_info.max_tx_queues;
19481a572499SJingjing Wu 	} else {
19491a572499SJingjing Wu 		/*if vt is disabled, use all pf queues */
19501a572499SJingjing Wu 		if (dev_info.vmdq_pool_base == 0) {
19511a572499SJingjing Wu 			nb_rxq = dev_info.max_rx_queues;
19521a572499SJingjing Wu 			nb_txq = dev_info.max_tx_queues;
19531a572499SJingjing Wu 		} else {
19541a572499SJingjing Wu 			nb_rxq = (queueid_t)num_tcs;
19551a572499SJingjing Wu 			nb_txq = (queueid_t)num_tcs;
19561a572499SJingjing Wu 
19571a572499SJingjing Wu 		}
19581a572499SJingjing Wu 	}
1959013af9b6SIntel 	rx_free_thresh = 64;
1960013af9b6SIntel 
1961013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
1962013af9b6SIntel 	/* Enter DCB configuration status */
1963013af9b6SIntel 	dcb_config = 1;
1964013af9b6SIntel 
1965013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
19661a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
1967013af9b6SIntel 	if (retval < 0)
1968013af9b6SIntel 		return retval;
1969013af9b6SIntel 
1970013af9b6SIntel 	rte_port = &ports[pid];
1971013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
1972013af9b6SIntel 
1973f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
1974013af9b6SIntel 	/* VLAN filter */
1975013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
19761a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
1977013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1978013af9b6SIntel 
1979013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1980013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1981013af9b6SIntel 
19827741e4cfSIntel 	rte_port->dcb_flag = 1;
19837741e4cfSIntel 
1984013af9b6SIntel 	return 0;
1985af75078fSIntel }
1986af75078fSIntel 
1987ffc468ffSTetsuya Mukawa static void
1988ffc468ffSTetsuya Mukawa init_port(void)
1989ffc468ffSTetsuya Mukawa {
1990ffc468ffSTetsuya Mukawa 	portid_t pid;
1991ffc468ffSTetsuya Mukawa 
1992ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
1993ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
1994ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
1995ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
1996ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
1997ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
1998ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
1999ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2000ffc468ffSTetsuya Mukawa 	}
2001ffc468ffSTetsuya Mukawa 
2002ffc468ffSTetsuya Mukawa 	/* enabled allocated ports */
2003ffc468ffSTetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
2004ffc468ffSTetsuya Mukawa 		ports[pid].enabled = 1;
2005ffc468ffSTetsuya Mukawa }
2006ffc468ffSTetsuya Mukawa 
2007d3a274ceSZhihong Wang static void
2008d3a274ceSZhihong Wang force_quit(void)
2009d3a274ceSZhihong Wang {
2010d3a274ceSZhihong Wang 	pmd_test_exit();
2011d3a274ceSZhihong Wang 	prompt_exit();
2012d3a274ceSZhihong Wang }
2013d3a274ceSZhihong Wang 
2014d3a274ceSZhihong Wang static void
2015d3a274ceSZhihong Wang signal_handler(int signum)
2016d3a274ceSZhihong Wang {
2017d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2018d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2019d3a274ceSZhihong Wang 				signum);
2020d3a274ceSZhihong Wang 		force_quit();
2021d3a274ceSZhihong Wang 		/* exit with the expected status */
2022d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2023d3a274ceSZhihong Wang 		kill(getpid(), signum);
2024d3a274ceSZhihong Wang 	}
2025d3a274ceSZhihong Wang }
2026d3a274ceSZhihong Wang 
2027af75078fSIntel int
2028af75078fSIntel main(int argc, char** argv)
2029af75078fSIntel {
2030af75078fSIntel 	int  diag;
2031013af9b6SIntel 	uint8_t port_id;
2032af75078fSIntel 
2033d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2034d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2035d3a274ceSZhihong Wang 
2036af75078fSIntel 	diag = rte_eal_init(argc, argv);
2037af75078fSIntel 	if (diag < 0)
2038af75078fSIntel 		rte_panic("Cannot init EAL\n");
2039af75078fSIntel 
2040af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2041af75078fSIntel 	if (nb_ports == 0)
2042edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2043af75078fSIntel 
2044ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2045ffc468ffSTetsuya Mukawa 	init_port();
2046ffc468ffSTetsuya Mukawa 
2047af75078fSIntel 	set_def_fwd_config();
2048af75078fSIntel 	if (nb_lcores == 0)
2049af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2050af75078fSIntel 			  "core mask supplied in the command parameters\n");
2051af75078fSIntel 
2052af75078fSIntel 	argc -= diag;
2053af75078fSIntel 	argv += diag;
2054af75078fSIntel 	if (argc > 1)
2055af75078fSIntel 		launch_args_parse(argc, argv);
2056af75078fSIntel 
20575a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
20585a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
20595a8fb55cSReshma Pattan 
20605a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2061af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2062af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2063af75078fSIntel 		       nb_rxq, nb_txq);
2064af75078fSIntel 
2065af75078fSIntel 	init_config();
2066148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2067148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2068af75078fSIntel 
2069ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
2070edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
2071ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2072af75078fSIntel 
20730d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2074ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2075ca7feb22SCyril Chemparathy 		if (auto_start) {
2076ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2077ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2078ca7feb22SCyril Chemparathy 		}
2079af75078fSIntel 		prompt();
2080ca7feb22SCyril Chemparathy 	} else
20810d56cb81SThomas Monjalon #endif
20820d56cb81SThomas Monjalon 	{
2083af75078fSIntel 		char c;
2084af75078fSIntel 		int rc;
2085af75078fSIntel 
2086af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2087af75078fSIntel 		start_packet_forwarding(0);
2088af75078fSIntel 		printf("Press enter to exit\n");
2089af75078fSIntel 		rc = read(0, &c, 1);
2090d3a274ceSZhihong Wang 		pmd_test_exit();
2091af75078fSIntel 		if (rc < 0)
2092af75078fSIntel 			return 1;
2093af75078fSIntel 	}
2094af75078fSIntel 
2095af75078fSIntel 	return 0;
2096af75078fSIntel }
2097