xref: /dpdk/app/test-pmd/testpmd.c (revision 12a8e30fd73dbb6c238a585c995eca5e2c58e24f)
1af75078fSIntel /*-
2af75078fSIntel  *   BSD LICENSE
3af75078fSIntel  *
4e9d48c00SBruce Richardson  *   Copyright(c) 2010-2014 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>
52af75078fSIntel #include <rte_byteorder.h>
53af75078fSIntel #include <rte_log.h>
54af75078fSIntel #include <rte_debug.h>
55af75078fSIntel #include <rte_cycles.h>
56af75078fSIntel #include <rte_memory.h>
57af75078fSIntel #include <rte_memcpy.h>
58af75078fSIntel #include <rte_memzone.h>
59af75078fSIntel #include <rte_launch.h>
60af75078fSIntel #include <rte_eal.h>
61af75078fSIntel #include <rte_per_lcore.h>
62af75078fSIntel #include <rte_lcore.h>
63af75078fSIntel #include <rte_atomic.h>
64af75078fSIntel #include <rte_branch_prediction.h>
65af75078fSIntel #include <rte_ring.h>
66af75078fSIntel #include <rte_mempool.h>
67af75078fSIntel #include <rte_malloc.h>
68af75078fSIntel #include <rte_mbuf.h>
69af75078fSIntel #include <rte_interrupts.h>
70af75078fSIntel #include <rte_pci.h>
71af75078fSIntel #include <rte_ether.h>
72af75078fSIntel #include <rte_ethdev.h>
73edab33b1STetsuya Mukawa #include <rte_dev.h>
74af75078fSIntel #include <rte_string_fns.h>
75148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
76148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
77148f963fSBruce Richardson #endif
78af75078fSIntel 
79af75078fSIntel #include "testpmd.h"
80148f963fSBruce Richardson #include "mempool_osdep.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 
176af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
177e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
178af75078fSIntel 
179900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
180900550deSIntel uint8_t dcb_config = 0;
181900550deSIntel 
182900550deSIntel /* Whether the dcb is in testing status */
183900550deSIntel uint8_t dcb_test = 0;
184900550deSIntel 
185900550deSIntel /* DCB on and VT on mapping is default */
186900550deSIntel enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
187af75078fSIntel 
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,
301d9d5e6f2SJingjing Wu 	},
302af75078fSIntel 	.drop_queue = 127,
303af75078fSIntel };
304af75078fSIntel 
3052950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
306af75078fSIntel 
307ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
308ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
309ed30d9b6SIntel 
310ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
311ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
312ed30d9b6SIntel 
313ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
314ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
315ed30d9b6SIntel 
316ed30d9b6SIntel /* Forward function declarations */
317ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
318edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
319ce8d5614SIntel 
320ce8d5614SIntel /*
321ce8d5614SIntel  * Check if all the ports are started.
322ce8d5614SIntel  * If yes, return positive value. If not, return zero.
323ce8d5614SIntel  */
324ce8d5614SIntel static int all_ports_started(void);
325ed30d9b6SIntel 
326af75078fSIntel /*
327edab33b1STetsuya Mukawa  * Find next enabled port
328edab33b1STetsuya Mukawa  */
329edab33b1STetsuya Mukawa portid_t
330edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
331edab33b1STetsuya Mukawa {
332edab33b1STetsuya Mukawa 	if (ports == NULL)
333edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
334edab33b1STetsuya Mukawa 
335*12a8e30fSJulien Cretin 	while ((p < size) && (ports[p].enabled == 0))
336edab33b1STetsuya Mukawa 		p++;
337edab33b1STetsuya Mukawa 	return p;
338edab33b1STetsuya Mukawa }
339edab33b1STetsuya Mukawa 
340edab33b1STetsuya Mukawa /*
341af75078fSIntel  * Setup default configuration.
342af75078fSIntel  */
343af75078fSIntel static void
344af75078fSIntel set_default_fwd_lcores_config(void)
345af75078fSIntel {
346af75078fSIntel 	unsigned int i;
347af75078fSIntel 	unsigned int nb_lc;
348af75078fSIntel 
349af75078fSIntel 	nb_lc = 0;
350af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
351af75078fSIntel 		if (! rte_lcore_is_enabled(i))
352af75078fSIntel 			continue;
353af75078fSIntel 		if (i == rte_get_master_lcore())
354af75078fSIntel 			continue;
355af75078fSIntel 		fwd_lcores_cpuids[nb_lc++] = i;
356af75078fSIntel 	}
357af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
358af75078fSIntel 	nb_cfg_lcores = nb_lcores;
359af75078fSIntel 	nb_fwd_lcores = 1;
360af75078fSIntel }
361af75078fSIntel 
362af75078fSIntel static void
363af75078fSIntel set_def_peer_eth_addrs(void)
364af75078fSIntel {
365af75078fSIntel 	portid_t i;
366af75078fSIntel 
367af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
368af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
369af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
370af75078fSIntel 	}
371af75078fSIntel }
372af75078fSIntel 
373af75078fSIntel static void
374af75078fSIntel set_default_fwd_ports_config(void)
375af75078fSIntel {
376af75078fSIntel 	portid_t pt_id;
377af75078fSIntel 
378af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
379af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
380af75078fSIntel 
381af75078fSIntel 	nb_cfg_ports = nb_ports;
382af75078fSIntel 	nb_fwd_ports = nb_ports;
383af75078fSIntel }
384af75078fSIntel 
385af75078fSIntel void
386af75078fSIntel set_def_fwd_config(void)
387af75078fSIntel {
388af75078fSIntel 	set_default_fwd_lcores_config();
389af75078fSIntel 	set_def_peer_eth_addrs();
390af75078fSIntel 	set_default_fwd_ports_config();
391af75078fSIntel }
392af75078fSIntel 
393af75078fSIntel /*
394af75078fSIntel  * Configuration initialisation done once at init time.
395af75078fSIntel  */
396af75078fSIntel struct mbuf_ctor_arg {
397af75078fSIntel 	uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
398af75078fSIntel 	uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
399af75078fSIntel };
400af75078fSIntel 
401af75078fSIntel struct mbuf_pool_ctor_arg {
402af75078fSIntel 	uint16_t seg_buf_size; /**< size of data segment in mbuf. */
403af75078fSIntel };
404af75078fSIntel 
405af75078fSIntel static void
406af75078fSIntel testpmd_mbuf_ctor(struct rte_mempool *mp,
407af75078fSIntel 		  void *opaque_arg,
408af75078fSIntel 		  void *raw_mbuf,
409af75078fSIntel 		  __attribute__((unused)) unsigned i)
410af75078fSIntel {
411af75078fSIntel 	struct mbuf_ctor_arg *mb_ctor_arg;
412af75078fSIntel 	struct rte_mbuf    *mb;
413af75078fSIntel 
414af75078fSIntel 	mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
415af75078fSIntel 	mb = (struct rte_mbuf *) raw_mbuf;
416af75078fSIntel 
417af75078fSIntel 	mb->pool         = mp;
418af75078fSIntel 	mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
419af75078fSIntel 	mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
420af75078fSIntel 			mb_ctor_arg->seg_buf_offset);
421af75078fSIntel 	mb->buf_len      = mb_ctor_arg->seg_buf_size;
422af75078fSIntel 	mb->ol_flags     = 0;
42308b563ffSOlivier Matz 	mb->data_off     = RTE_PKTMBUF_HEADROOM;
424ea672a8bSOlivier Matz 	mb->nb_segs      = 1;
4254199fdeaSOlivier Matz 	mb->tx_offload   = 0;
4267869536fSBruce Richardson 	mb->vlan_tci     = 0;
427ea672a8bSOlivier Matz 	mb->hash.rss     = 0;
428af75078fSIntel }
429af75078fSIntel 
430af75078fSIntel static void
431af75078fSIntel testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
432af75078fSIntel 		       void *opaque_arg)
433af75078fSIntel {
434af75078fSIntel 	struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
435af75078fSIntel 	struct rte_pktmbuf_pool_private *mbp_priv;
436af75078fSIntel 
437af75078fSIntel 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
438af75078fSIntel 		printf("%s(%s) private_data_size %d < %d\n",
439af75078fSIntel 		       __func__, mp->name, (int) mp->private_data_size,
440af75078fSIntel 		       (int) sizeof(struct rte_pktmbuf_pool_private));
441af75078fSIntel 		return;
442af75078fSIntel 	}
443af75078fSIntel 	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
444148f963fSBruce Richardson 	mbp_priv = rte_mempool_get_priv(mp);
445af75078fSIntel 	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
446af75078fSIntel }
447af75078fSIntel 
448af75078fSIntel static void
449af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
450af75078fSIntel 		 unsigned int socket_id)
451af75078fSIntel {
452af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
453af75078fSIntel 	struct rte_mempool *rte_mp;
454af75078fSIntel 	struct mbuf_pool_ctor_arg mbp_ctor_arg;
455af75078fSIntel 	struct mbuf_ctor_arg mb_ctor_arg;
456af75078fSIntel 	uint32_t mb_size;
457af75078fSIntel 
458af75078fSIntel 	mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
459af75078fSIntel 						mbuf_seg_size);
460af75078fSIntel 	mb_ctor_arg.seg_buf_offset =
461fdf20fa7SSergio Gonzalez Monroy 		(uint16_t) RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
462af75078fSIntel 	mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
463af75078fSIntel 	mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
464af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
465148f963fSBruce Richardson 
466148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
467148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
468af75078fSIntel                                    (unsigned) mb_mempool_cache,
469af75078fSIntel                                    sizeof(struct rte_pktmbuf_pool_private),
470af75078fSIntel                                    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
471af75078fSIntel                                    testpmd_mbuf_ctor, &mb_ctor_arg,
472af75078fSIntel                                    socket_id, 0);
473148f963fSBruce Richardson 
474148f963fSBruce Richardson 
475148f963fSBruce Richardson 
476148f963fSBruce Richardson #else
477148f963fSBruce Richardson 	if (mp_anon != 0)
478148f963fSBruce Richardson 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
479148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
480148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
481148f963fSBruce Richardson 				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
482148f963fSBruce Richardson 				    testpmd_mbuf_ctor, &mb_ctor_arg,
483148f963fSBruce Richardson 				    socket_id, 0);
484148f963fSBruce Richardson 	else
485148f963fSBruce Richardson 		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
486148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
487148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
488148f963fSBruce Richardson 				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
489148f963fSBruce Richardson 				    testpmd_mbuf_ctor, &mb_ctor_arg,
490148f963fSBruce Richardson 				    socket_id, 0);
491148f963fSBruce Richardson 
492148f963fSBruce Richardson #endif
493148f963fSBruce Richardson 
494af75078fSIntel 	if (rte_mp == NULL) {
495ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
496ce8d5614SIntel 						"failed\n", socket_id);
497148f963fSBruce Richardson 	} else if (verbose_level > 0) {
498591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
499af75078fSIntel 	}
500af75078fSIntel }
501af75078fSIntel 
50220a0286fSLiu Xiaofeng /*
50320a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
50420a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
50520a0286fSLiu Xiaofeng  */
50620a0286fSLiu Xiaofeng static int
50720a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
50820a0286fSLiu Xiaofeng {
50920a0286fSLiu Xiaofeng 	static int warning_once = 0;
51020a0286fSLiu Xiaofeng 
51120a0286fSLiu Xiaofeng 	if (socket_id >= MAX_SOCKET) {
51220a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
51320a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
51420a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
51520a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
51620a0286fSLiu Xiaofeng 			       " --numa.\n");
51720a0286fSLiu Xiaofeng 		warning_once = 1;
51820a0286fSLiu Xiaofeng 		return -1;
51920a0286fSLiu Xiaofeng 	}
52020a0286fSLiu Xiaofeng 	return 0;
52120a0286fSLiu Xiaofeng }
52220a0286fSLiu Xiaofeng 
523af75078fSIntel static void
524af75078fSIntel init_config(void)
525af75078fSIntel {
526ce8d5614SIntel 	portid_t pid;
527af75078fSIntel 	struct rte_port *port;
528af75078fSIntel 	struct rte_mempool *mbp;
529af75078fSIntel 	unsigned int nb_mbuf_per_pool;
530af75078fSIntel 	lcoreid_t  lc_id;
531b6ea6408SIntel 	uint8_t port_per_socket[MAX_SOCKET];
532af75078fSIntel 
533b6ea6408SIntel 	memset(port_per_socket,0,MAX_SOCKET);
534af75078fSIntel 	/* Configuration of logical cores. */
535af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
536af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
537fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
538af75078fSIntel 	if (fwd_lcores == NULL) {
539ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
540ce8d5614SIntel 							"failed\n", nb_lcores);
541af75078fSIntel 	}
542af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
543af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
544af75078fSIntel 					       sizeof(struct fwd_lcore),
545fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
546af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
547ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
548ce8d5614SIntel 								"failed\n");
549af75078fSIntel 		}
550af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
551af75078fSIntel 	}
552af75078fSIntel 
553af75078fSIntel 	/*
554af75078fSIntel 	 * Create pools of mbuf.
555af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
556b6ea6408SIntel 	 * socket 0 memory by default.
557af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
558c8798818SIntel 	 *
559c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
560c8798818SIntel 	 * nb_txd can be configured at run time.
561af75078fSIntel 	 */
562c8798818SIntel 	if (param_total_num_mbufs)
563c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
564c8798818SIntel 	else {
565c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
566c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
567b6ea6408SIntel 
568b6ea6408SIntel 		if (!numa_support)
569edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
570edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
571c8798818SIntel 	}
572af75078fSIntel 
573b6ea6408SIntel 	if (!numa_support) {
574b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
575b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
576b6ea6408SIntel 		else
577b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
578b6ea6408SIntel 						 socket_num);
579b6ea6408SIntel 	}
580af75078fSIntel 
581edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
582ce8d5614SIntel 		port = &ports[pid];
583ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
584ce8d5614SIntel 
585b6ea6408SIntel 		if (numa_support) {
586b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
587b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
588b6ea6408SIntel 			else {
589b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
59020a0286fSLiu Xiaofeng 
59120a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
59220a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
59320a0286fSLiu Xiaofeng 					socket_id = 0;
594b6ea6408SIntel 				port_per_socket[socket_id]++;
595b6ea6408SIntel 			}
596b6ea6408SIntel 		}
597b6ea6408SIntel 
598ce8d5614SIntel 		/* set flag to initialize port/queue */
599ce8d5614SIntel 		port->need_reconfig = 1;
600ce8d5614SIntel 		port->need_reconfig_queues = 1;
601ce8d5614SIntel 	}
602ce8d5614SIntel 
603b6ea6408SIntel 	if (numa_support) {
604b6ea6408SIntel 		uint8_t i;
605b6ea6408SIntel 		unsigned int nb_mbuf;
606ce8d5614SIntel 
607b6ea6408SIntel 		if (param_total_num_mbufs)
608b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
609b6ea6408SIntel 
610b6ea6408SIntel 		for (i = 0; i < MAX_SOCKET; i++) {
611edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
612b6ea6408SIntel 			if (nb_mbuf)
613b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
614b6ea6408SIntel 						nb_mbuf,i);
615b6ea6408SIntel 		}
616b6ea6408SIntel 	}
617b6ea6408SIntel 	init_port_config();
6185886ae07SAdrien Mazarguil 
6195886ae07SAdrien Mazarguil 	/*
6205886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6215886ae07SAdrien Mazarguil 	 */
6225886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6238fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
6248fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
6258fd8bebcSAdrien Mazarguil 
6265886ae07SAdrien Mazarguil 		if (mbp == NULL)
6275886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6285886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
6295886ae07SAdrien Mazarguil 	}
6305886ae07SAdrien Mazarguil 
631ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
632ce8d5614SIntel 	if (init_fwd_streams() < 0)
633ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
634ce8d5614SIntel }
635ce8d5614SIntel 
6362950a769SDeclan Doherty 
6372950a769SDeclan Doherty void
638a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6392950a769SDeclan Doherty {
6402950a769SDeclan Doherty 	struct rte_port *port;
6412950a769SDeclan Doherty 
6422950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6432950a769SDeclan Doherty 	port = &ports[new_port_id];
6442950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6452950a769SDeclan Doherty 
6462950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6472950a769SDeclan Doherty 	port->need_reconfig = 1;
6482950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
649a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6502950a769SDeclan Doherty 
6512950a769SDeclan Doherty 	init_port_config();
6522950a769SDeclan Doherty }
6532950a769SDeclan Doherty 
6542950a769SDeclan Doherty 
655ce8d5614SIntel int
656ce8d5614SIntel init_fwd_streams(void)
657ce8d5614SIntel {
658ce8d5614SIntel 	portid_t pid;
659ce8d5614SIntel 	struct rte_port *port;
660ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
661ce8d5614SIntel 
662ce8d5614SIntel 	/* set socket id according to numa or not */
663edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
664ce8d5614SIntel 		port = &ports[pid];
665ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
666ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
667ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
668ce8d5614SIntel 				port->dev_info.max_rx_queues);
669ce8d5614SIntel 			return -1;
670ce8d5614SIntel 		}
671ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
672ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
673ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
674ce8d5614SIntel 				port->dev_info.max_tx_queues);
675ce8d5614SIntel 			return -1;
676ce8d5614SIntel 		}
67720a0286fSLiu Xiaofeng 		if (numa_support) {
67820a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
67920a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
68020a0286fSLiu Xiaofeng 			else {
681b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
68220a0286fSLiu Xiaofeng 
68320a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
68420a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
68520a0286fSLiu Xiaofeng 					port->socket_id = 0;
68620a0286fSLiu Xiaofeng 			}
68720a0286fSLiu Xiaofeng 		}
688b6ea6408SIntel 		else {
689b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
690af75078fSIntel 				port->socket_id = 0;
691b6ea6408SIntel 			else
692b6ea6408SIntel 				port->socket_id = socket_num;
693b6ea6408SIntel 		}
694af75078fSIntel 	}
695af75078fSIntel 
696ce8d5614SIntel 	nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
697ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
698ce8d5614SIntel 		return 0;
699ce8d5614SIntel 	/* clear the old */
700ce8d5614SIntel 	if (fwd_streams != NULL) {
701ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
702ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
703ce8d5614SIntel 				continue;
704ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
705ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
706af75078fSIntel 		}
707ce8d5614SIntel 		rte_free(fwd_streams);
708ce8d5614SIntel 		fwd_streams = NULL;
709ce8d5614SIntel 	}
710ce8d5614SIntel 
711ce8d5614SIntel 	/* init new */
712ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
713ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
714fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
715ce8d5614SIntel 	if (fwd_streams == NULL)
716ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
717ce8d5614SIntel 						"failed\n", nb_fwd_streams);
718ce8d5614SIntel 
719af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
720af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
721fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
722ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
723ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
724ce8d5614SIntel 								" failed\n");
725af75078fSIntel 	}
726ce8d5614SIntel 
727ce8d5614SIntel 	return 0;
728af75078fSIntel }
729af75078fSIntel 
730af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
731af75078fSIntel static void
732af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
733af75078fSIntel {
734af75078fSIntel 	unsigned int total_burst;
735af75078fSIntel 	unsigned int nb_burst;
736af75078fSIntel 	unsigned int burst_stats[3];
737af75078fSIntel 	uint16_t pktnb_stats[3];
738af75078fSIntel 	uint16_t nb_pkt;
739af75078fSIntel 	int burst_percent[3];
740af75078fSIntel 
741af75078fSIntel 	/*
742af75078fSIntel 	 * First compute the total number of packet bursts and the
743af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
744af75078fSIntel 	 */
745af75078fSIntel 	total_burst = 0;
746af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
747af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
748af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
749af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
750af75078fSIntel 		if (nb_burst == 0)
751af75078fSIntel 			continue;
752af75078fSIntel 		total_burst += nb_burst;
753af75078fSIntel 		if (nb_burst > burst_stats[0]) {
754af75078fSIntel 			burst_stats[1] = burst_stats[0];
755af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
756af75078fSIntel 			burst_stats[0] = nb_burst;
757af75078fSIntel 			pktnb_stats[0] = nb_pkt;
758af75078fSIntel 		}
759af75078fSIntel 	}
760af75078fSIntel 	if (total_burst == 0)
761af75078fSIntel 		return;
762af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
763af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
764af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
765af75078fSIntel 	if (burst_stats[0] == total_burst) {
766af75078fSIntel 		printf("]\n");
767af75078fSIntel 		return;
768af75078fSIntel 	}
769af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
770af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
771af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
772af75078fSIntel 		return;
773af75078fSIntel 	}
774af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
775af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
776af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
777af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
778af75078fSIntel 		return;
779af75078fSIntel 	}
780af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
781af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
782af75078fSIntel }
783af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
784af75078fSIntel 
785af75078fSIntel static void
786af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
787af75078fSIntel {
788af75078fSIntel 	struct rte_port *port;
789013af9b6SIntel 	uint8_t i;
790af75078fSIntel 
791af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
792af75078fSIntel 
793af75078fSIntel 	port = &ports[port_id];
794af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
795af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
796013af9b6SIntel 
797013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
798af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
799af75078fSIntel 		       "%-"PRIu64"\n",
80070bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
80170bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
802af75078fSIntel 
803af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
804af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
805af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
80670bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
80770bdb186SIvan Boule 			printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
80870bdb186SIvan Boule 			       "RX-error: %-"PRIu64"\n",
80970bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
81070bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
81170bdb186SIvan Boule 		}
812af75078fSIntel 
813af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
814af75078fSIntel 		       "%-"PRIu64"\n",
815af75078fSIntel 		       stats->opackets, port->tx_dropped,
816af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
817013af9b6SIntel 	}
818013af9b6SIntel 	else {
819013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
820013af9b6SIntel 		       "%14"PRIu64"\n",
82170bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
82270bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
823013af9b6SIntel 
824013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
825013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
826013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
82770bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
82870bdb186SIvan Boule 			printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
82970bdb186SIvan Boule 			       "    RX-error:%"PRIu64"\n",
83070bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
83170bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
83270bdb186SIvan Boule 			       stats->rx_nombuf);
83370bdb186SIvan Boule 		}
834013af9b6SIntel 
835013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
836013af9b6SIntel 		       "%14"PRIu64"\n",
837013af9b6SIntel 		       stats->opackets, port->tx_dropped,
838013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
839013af9b6SIntel 	}
840e659b6b4SIvan Boule 
841e659b6b4SIvan Boule 	/* Display statistics of XON/XOFF pause frames, if any. */
842e659b6b4SIvan Boule 	if ((stats->tx_pause_xon  | stats->rx_pause_xon |
843e659b6b4SIvan Boule 	     stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
844e659b6b4SIvan Boule 		printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
845e659b6b4SIvan Boule 		       stats->rx_pause_xoff, stats->rx_pause_xon);
846e659b6b4SIvan Boule 		printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
847e659b6b4SIvan Boule 		       stats->tx_pause_xoff, stats->tx_pause_xon);
848e659b6b4SIvan Boule 	}
849e659b6b4SIvan Boule 
850af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
851af75078fSIntel 	if (port->rx_stream)
852013af9b6SIntel 		pkt_burst_stats_display("RX",
853013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
854af75078fSIntel 	if (port->tx_stream)
855013af9b6SIntel 		pkt_burst_stats_display("TX",
856013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
857af75078fSIntel #endif
858af75078fSIntel 	/* stats fdir */
859af75078fSIntel 	if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
860013af9b6SIntel 		printf("  Fdirmiss:%14"PRIu64"	  Fdirmatch:%14"PRIu64"\n",
861af75078fSIntel 		       stats->fdirmiss,
862af75078fSIntel 		       stats->fdirmatch);
863af75078fSIntel 
864013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
865013af9b6SIntel 		printf("\n");
866013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
867013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
868013af9b6SIntel 			       "     RX-errors:%14"PRIu64
869013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
870013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
871013af9b6SIntel 		}
872013af9b6SIntel 		printf("\n");
873013af9b6SIntel 	}
874013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
875013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
876013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
877013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
878013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
879013af9b6SIntel 		}
880013af9b6SIntel 	}
881013af9b6SIntel 
882af75078fSIntel 	printf("  %s--------------------------------%s\n",
883af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
884af75078fSIntel }
885af75078fSIntel 
886af75078fSIntel static void
887af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
888af75078fSIntel {
889af75078fSIntel 	struct fwd_stream *fs;
890af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
891af75078fSIntel 
892af75078fSIntel 	fs = fwd_streams[stream_id];
893af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
894af75078fSIntel 	    (fs->fwd_dropped == 0))
895af75078fSIntel 		return;
896af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
897af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
898af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
899af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
900af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
901af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
902af75078fSIntel 
903af75078fSIntel 	/* if checksum mode */
904af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
905013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
906013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
907af75078fSIntel 	}
908af75078fSIntel 
909af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
910af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
911af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
912af75078fSIntel #endif
913af75078fSIntel }
914af75078fSIntel 
915af75078fSIntel static void
9167741e4cfSIntel flush_fwd_rx_queues(void)
917af75078fSIntel {
918af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
919af75078fSIntel 	portid_t  rxp;
9207741e4cfSIntel 	portid_t port_id;
921af75078fSIntel 	queueid_t rxq;
922af75078fSIntel 	uint16_t  nb_rx;
923af75078fSIntel 	uint16_t  i;
924af75078fSIntel 	uint8_t   j;
925af75078fSIntel 
926af75078fSIntel 	for (j = 0; j < 2; j++) {
9277741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
928af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
9297741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
930af75078fSIntel 				do {
9317741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
932013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
933af75078fSIntel 					for (i = 0; i < nb_rx; i++)
934af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
935af75078fSIntel 				} while (nb_rx > 0);
936af75078fSIntel 			}
937af75078fSIntel 		}
938af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
939af75078fSIntel 	}
940af75078fSIntel }
941af75078fSIntel 
942af75078fSIntel static void
943af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
944af75078fSIntel {
945af75078fSIntel 	struct fwd_stream **fsm;
946af75078fSIntel 	streamid_t nb_fs;
947af75078fSIntel 	streamid_t sm_id;
948af75078fSIntel 
949af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
950af75078fSIntel 	nb_fs = fc->stream_nb;
951af75078fSIntel 	do {
952af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
953af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
954af75078fSIntel 	} while (! fc->stopped);
955af75078fSIntel }
956af75078fSIntel 
957af75078fSIntel static int
958af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
959af75078fSIntel {
960af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
961af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
962af75078fSIntel 	return 0;
963af75078fSIntel }
964af75078fSIntel 
965af75078fSIntel /*
966af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
967af75078fSIntel  * Used to start communication flows in network loopback test configurations.
968af75078fSIntel  */
969af75078fSIntel static int
970af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
971af75078fSIntel {
972af75078fSIntel 	struct fwd_lcore *fwd_lc;
973af75078fSIntel 	struct fwd_lcore tmp_lcore;
974af75078fSIntel 
975af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
976af75078fSIntel 	tmp_lcore = *fwd_lc;
977af75078fSIntel 	tmp_lcore.stopped = 1;
978af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
979af75078fSIntel 	return 0;
980af75078fSIntel }
981af75078fSIntel 
982af75078fSIntel /*
983af75078fSIntel  * Launch packet forwarding:
984af75078fSIntel  *     - Setup per-port forwarding context.
985af75078fSIntel  *     - launch logical cores with their forwarding configuration.
986af75078fSIntel  */
987af75078fSIntel static void
988af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
989af75078fSIntel {
990af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
991af75078fSIntel 	unsigned int i;
992af75078fSIntel 	unsigned int lc_id;
993af75078fSIntel 	int diag;
994af75078fSIntel 
995af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
996af75078fSIntel 	if (port_fwd_begin != NULL) {
997af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
998af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
999af75078fSIntel 	}
1000af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1001af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
1002af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1003af75078fSIntel 			fwd_lcores[i]->stopped = 0;
1004af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1005af75078fSIntel 						     fwd_lcores[i], lc_id);
1006af75078fSIntel 			if (diag != 0)
1007af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
1008af75078fSIntel 				       lc_id, diag);
1009af75078fSIntel 		}
1010af75078fSIntel 	}
1011af75078fSIntel }
1012af75078fSIntel 
1013af75078fSIntel /*
1014af75078fSIntel  * Launch packet forwarding configuration.
1015af75078fSIntel  */
1016af75078fSIntel void
1017af75078fSIntel start_packet_forwarding(int with_tx_first)
1018af75078fSIntel {
1019af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1020af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1021af75078fSIntel 	struct rte_port *port;
1022af75078fSIntel 	unsigned int i;
1023af75078fSIntel 	portid_t   pt_id;
1024af75078fSIntel 	streamid_t sm_id;
1025af75078fSIntel 
1026ce8d5614SIntel 	if (all_ports_started() == 0) {
1027ce8d5614SIntel 		printf("Not all ports were started\n");
1028ce8d5614SIntel 		return;
1029ce8d5614SIntel 	}
1030af75078fSIntel 	if (test_done == 0) {
1031af75078fSIntel 		printf("Packet forwarding already started\n");
1032af75078fSIntel 		return;
1033af75078fSIntel 	}
10347741e4cfSIntel 	if(dcb_test) {
10357741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
10367741e4cfSIntel 			pt_id = fwd_ports_ids[i];
10377741e4cfSIntel 			port = &ports[pt_id];
10387741e4cfSIntel 			if (!port->dcb_flag) {
10397741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
10407741e4cfSIntel                                        "be configured in this mode.\n");
1041013af9b6SIntel 				return;
1042013af9b6SIntel 			}
10437741e4cfSIntel 		}
10447741e4cfSIntel 		if (nb_fwd_lcores == 1) {
10457741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
10467741e4cfSIntel                                "should be larger than 1.\n");
10477741e4cfSIntel 			return;
10487741e4cfSIntel 		}
10497741e4cfSIntel 	}
1050af75078fSIntel 	test_done = 0;
10517741e4cfSIntel 
10527741e4cfSIntel 	if(!no_flush_rx)
10537741e4cfSIntel 		flush_fwd_rx_queues();
10547741e4cfSIntel 
1055af75078fSIntel 	fwd_config_setup();
1056af75078fSIntel 	rxtx_config_display();
1057af75078fSIntel 
1058af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1059af75078fSIntel 		pt_id = fwd_ports_ids[i];
1060af75078fSIntel 		port = &ports[pt_id];
1061af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1062af75078fSIntel 		port->tx_dropped = 0;
1063013af9b6SIntel 
1064013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1065af75078fSIntel 	}
1066af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1067af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1068af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1069af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1070af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1071af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1072af75078fSIntel 
1073af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1074af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1075af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1076af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1077af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1078af75078fSIntel #endif
1079af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1080af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1081af75078fSIntel #endif
1082af75078fSIntel 	}
1083af75078fSIntel 	if (with_tx_first) {
1084af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1085af75078fSIntel 		if (port_fwd_begin != NULL) {
1086af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1087af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1088af75078fSIntel 		}
1089af75078fSIntel 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1090af75078fSIntel 		rte_eal_mp_wait_lcore();
1091af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1092af75078fSIntel 		if (port_fwd_end != NULL) {
1093af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1094af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1095af75078fSIntel 		}
1096af75078fSIntel 	}
1097af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1098af75078fSIntel }
1099af75078fSIntel 
1100af75078fSIntel void
1101af75078fSIntel stop_packet_forwarding(void)
1102af75078fSIntel {
1103af75078fSIntel 	struct rte_eth_stats stats;
1104af75078fSIntel 	struct rte_port *port;
1105af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1106af75078fSIntel 	int i;
1107af75078fSIntel 	portid_t   pt_id;
1108af75078fSIntel 	streamid_t sm_id;
1109af75078fSIntel 	lcoreid_t  lc_id;
1110af75078fSIntel 	uint64_t total_recv;
1111af75078fSIntel 	uint64_t total_xmit;
1112af75078fSIntel 	uint64_t total_rx_dropped;
1113af75078fSIntel 	uint64_t total_tx_dropped;
1114af75078fSIntel 	uint64_t total_rx_nombuf;
1115af75078fSIntel 	uint64_t tx_dropped;
1116af75078fSIntel 	uint64_t rx_bad_ip_csum;
1117af75078fSIntel 	uint64_t rx_bad_l4_csum;
1118af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1119af75078fSIntel 	uint64_t fwd_cycles;
1120af75078fSIntel #endif
1121af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1122af75078fSIntel 
1123ce8d5614SIntel 	if (all_ports_started() == 0) {
1124ce8d5614SIntel 		printf("Not all ports were started\n");
1125ce8d5614SIntel 		return;
1126ce8d5614SIntel 	}
1127af75078fSIntel 	if (test_done) {
1128af75078fSIntel 		printf("Packet forwarding not started\n");
1129af75078fSIntel 		return;
1130af75078fSIntel 	}
1131af75078fSIntel 	printf("Telling cores to stop...");
1132af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1133af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1134af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1135af75078fSIntel 	rte_eal_mp_wait_lcore();
1136af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1137af75078fSIntel 	if (port_fwd_end != NULL) {
1138af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1139af75078fSIntel 			pt_id = fwd_ports_ids[i];
1140af75078fSIntel 			(*port_fwd_end)(pt_id);
1141af75078fSIntel 		}
1142af75078fSIntel 	}
1143af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1144af75078fSIntel 	fwd_cycles = 0;
1145af75078fSIntel #endif
1146af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1147af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1148af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1149af75078fSIntel 			fwd_stream_stats_display(sm_id);
1150af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1151af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1152af75078fSIntel 		} else {
1153af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1154af75078fSIntel 				fwd_streams[sm_id];
1155af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1156af75078fSIntel 				fwd_streams[sm_id];
1157af75078fSIntel 		}
1158af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1159af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1160af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1161af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1162af75078fSIntel 
1163013af9b6SIntel 		rx_bad_ip_csum =
1164013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1165af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1166af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1167013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1168013af9b6SIntel 							rx_bad_ip_csum;
1169af75078fSIntel 
1170013af9b6SIntel 		rx_bad_l4_csum =
1171013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1172af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1173af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1174013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1175013af9b6SIntel 							rx_bad_l4_csum;
1176af75078fSIntel 
1177af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1178af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1179af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1180af75078fSIntel #endif
1181af75078fSIntel 	}
1182af75078fSIntel 	total_recv = 0;
1183af75078fSIntel 	total_xmit = 0;
1184af75078fSIntel 	total_rx_dropped = 0;
1185af75078fSIntel 	total_tx_dropped = 0;
1186af75078fSIntel 	total_rx_nombuf  = 0;
11877741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1188af75078fSIntel 		pt_id = fwd_ports_ids[i];
1189af75078fSIntel 
1190af75078fSIntel 		port = &ports[pt_id];
1191af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1192af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1193af75078fSIntel 		port->stats.ipackets = 0;
1194af75078fSIntel 		stats.opackets -= port->stats.opackets;
1195af75078fSIntel 		port->stats.opackets = 0;
1196af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1197af75078fSIntel 		port->stats.ibytes = 0;
1198af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1199af75078fSIntel 		port->stats.obytes = 0;
120070bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
120170bdb186SIvan Boule 		port->stats.imissed = 0;
1202af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1203af75078fSIntel 		port->stats.oerrors = 0;
1204af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1205af75078fSIntel 		port->stats.rx_nombuf = 0;
1206af75078fSIntel 		stats.fdirmatch -= port->stats.fdirmatch;
1207af75078fSIntel 		port->stats.rx_nombuf = 0;
1208af75078fSIntel 		stats.fdirmiss -= port->stats.fdirmiss;
1209af75078fSIntel 		port->stats.rx_nombuf = 0;
1210af75078fSIntel 
1211af75078fSIntel 		total_recv += stats.ipackets;
1212af75078fSIntel 		total_xmit += stats.opackets;
121370bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1214af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1215af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1216af75078fSIntel 
1217af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1218af75078fSIntel 	}
1219af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1220af75078fSIntel 	       "%s\n",
1221af75078fSIntel 	       acc_stats_border, acc_stats_border);
1222af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1223af75078fSIntel 	       "%-"PRIu64"\n"
1224af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1225af75078fSIntel 	       "%-"PRIu64"\n",
1226af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1227af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1228af75078fSIntel 	if (total_rx_nombuf > 0)
1229af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1230af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1231af75078fSIntel 	       "%s\n",
1232af75078fSIntel 	       acc_stats_border, acc_stats_border);
1233af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1234af75078fSIntel 	if (total_recv > 0)
1235af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1236af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1237af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1238af75078fSIntel 		       fwd_cycles, total_recv);
1239af75078fSIntel #endif
1240af75078fSIntel 	printf("\nDone.\n");
1241af75078fSIntel 	test_done = 1;
1242af75078fSIntel }
1243af75078fSIntel 
1244cfae07fdSOuyang Changchun void
1245cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1246cfae07fdSOuyang Changchun {
1247cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1248cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1249cfae07fdSOuyang Changchun }
1250cfae07fdSOuyang Changchun 
1251cfae07fdSOuyang Changchun void
1252cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1253cfae07fdSOuyang Changchun {
1254cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1255cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1256cfae07fdSOuyang Changchun }
1257cfae07fdSOuyang Changchun 
1258ce8d5614SIntel static int
1259ce8d5614SIntel all_ports_started(void)
1260ce8d5614SIntel {
1261ce8d5614SIntel 	portid_t pi;
1262ce8d5614SIntel 	struct rte_port *port;
1263ce8d5614SIntel 
1264edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1265ce8d5614SIntel 		port = &ports[pi];
1266ce8d5614SIntel 		/* Check if there is a port which is not started */
1267ce8d5614SIntel 		if (port->port_status != RTE_PORT_STARTED)
1268ce8d5614SIntel 			return 0;
1269ce8d5614SIntel 	}
1270ce8d5614SIntel 
1271ce8d5614SIntel 	/* No port is not started */
1272ce8d5614SIntel 	return 1;
1273ce8d5614SIntel }
1274ce8d5614SIntel 
1275148f963fSBruce Richardson int
1276edab33b1STetsuya Mukawa all_ports_stopped(void)
1277edab33b1STetsuya Mukawa {
1278edab33b1STetsuya Mukawa 	portid_t pi;
1279edab33b1STetsuya Mukawa 	struct rte_port *port;
1280edab33b1STetsuya Mukawa 
1281edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1282edab33b1STetsuya Mukawa 		port = &ports[pi];
1283edab33b1STetsuya Mukawa 		if (port->port_status != RTE_PORT_STOPPED)
1284edab33b1STetsuya Mukawa 			return 0;
1285edab33b1STetsuya Mukawa 	}
1286edab33b1STetsuya Mukawa 
1287edab33b1STetsuya Mukawa 	return 1;
1288edab33b1STetsuya Mukawa }
1289edab33b1STetsuya Mukawa 
1290edab33b1STetsuya Mukawa int
1291edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1292edab33b1STetsuya Mukawa {
1293edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1294edab33b1STetsuya Mukawa 		return 0;
1295edab33b1STetsuya Mukawa 
1296edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1297edab33b1STetsuya Mukawa 		return 0;
1298edab33b1STetsuya Mukawa 
1299edab33b1STetsuya Mukawa 	return 1;
1300edab33b1STetsuya Mukawa }
1301edab33b1STetsuya Mukawa 
1302edab33b1STetsuya Mukawa static int
1303edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1304edab33b1STetsuya Mukawa {
1305edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1306edab33b1STetsuya Mukawa 		return 0;
1307edab33b1STetsuya Mukawa 
1308edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1309edab33b1STetsuya Mukawa 		return 0;
1310edab33b1STetsuya Mukawa 
1311edab33b1STetsuya Mukawa 	return 1;
1312edab33b1STetsuya Mukawa }
1313edab33b1STetsuya Mukawa 
1314edab33b1STetsuya Mukawa int
1315ce8d5614SIntel start_port(portid_t pid)
1316ce8d5614SIntel {
131792d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1318ce8d5614SIntel 	portid_t pi;
1319ce8d5614SIntel 	queueid_t qi;
1320ce8d5614SIntel 	struct rte_port *port;
13212950a769SDeclan Doherty 	struct ether_addr mac_addr;
1322ce8d5614SIntel 
1323ce8d5614SIntel 	if (test_done == 0) {
1324ce8d5614SIntel 		printf("Please stop forwarding first\n");
1325148f963fSBruce Richardson 		return -1;
1326ce8d5614SIntel 	}
1327ce8d5614SIntel 
13284468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
13294468635fSMichael Qiu 		return 0;
13304468635fSMichael Qiu 
1331ce8d5614SIntel 	if (init_fwd_streams() < 0) {
1332ce8d5614SIntel 		printf("Fail from init_fwd_streams()\n");
1333148f963fSBruce Richardson 		return -1;
1334ce8d5614SIntel 	}
1335ce8d5614SIntel 
1336ce8d5614SIntel 	if(dcb_config)
1337ce8d5614SIntel 		dcb_test = 1;
1338edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1339edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1340ce8d5614SIntel 			continue;
1341ce8d5614SIntel 
134292d2703eSMichael Qiu 		need_check_link_status = 0;
1343ce8d5614SIntel 		port = &ports[pi];
1344ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1345ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1346ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1347ce8d5614SIntel 			continue;
1348ce8d5614SIntel 		}
1349ce8d5614SIntel 
1350ce8d5614SIntel 		if (port->need_reconfig > 0) {
1351ce8d5614SIntel 			port->need_reconfig = 0;
1352ce8d5614SIntel 
13535706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
135420a0286fSLiu Xiaofeng 					port->socket_id);
1355ce8d5614SIntel 			/* configure port */
1356ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1357ce8d5614SIntel 						&(port->dev_conf));
1358ce8d5614SIntel 			if (diag != 0) {
1359ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1360ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1361ce8d5614SIntel 					printf("Port %d can not be set back "
1362ce8d5614SIntel 							"to stopped\n", pi);
1363ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1364ce8d5614SIntel 				/* try to reconfigure port next time */
1365ce8d5614SIntel 				port->need_reconfig = 1;
1366148f963fSBruce Richardson 				return -1;
1367ce8d5614SIntel 			}
1368ce8d5614SIntel 		}
1369ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1370ce8d5614SIntel 			port->need_reconfig_queues = 0;
1371ce8d5614SIntel 			/* setup tx queues */
1372ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1373b6ea6408SIntel 				if ((numa_support) &&
1374b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1375b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1376b6ea6408SIntel 						nb_txd,txring_numa[pi],
1377b6ea6408SIntel 						&(port->tx_conf));
1378b6ea6408SIntel 				else
1379b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1380b6ea6408SIntel 						nb_txd,port->socket_id,
1381b6ea6408SIntel 						&(port->tx_conf));
1382b6ea6408SIntel 
1383ce8d5614SIntel 				if (diag == 0)
1384ce8d5614SIntel 					continue;
1385ce8d5614SIntel 
1386ce8d5614SIntel 				/* Fail to setup tx queue, return */
1387ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1388ce8d5614SIntel 							RTE_PORT_HANDLING,
1389ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1390ce8d5614SIntel 					printf("Port %d can not be set back "
1391ce8d5614SIntel 							"to stopped\n", pi);
1392ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1393ce8d5614SIntel 				/* try to reconfigure queues next time */
1394ce8d5614SIntel 				port->need_reconfig_queues = 1;
1395148f963fSBruce Richardson 				return -1;
1396ce8d5614SIntel 			}
1397ce8d5614SIntel 			/* setup rx queues */
1398ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1399b6ea6408SIntel 				if ((numa_support) &&
1400b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1401b6ea6408SIntel 					struct rte_mempool * mp =
1402b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1403b6ea6408SIntel 					if (mp == NULL) {
1404b6ea6408SIntel 						printf("Failed to setup RX queue:"
1405b6ea6408SIntel 							"No mempool allocation"
1406b6ea6408SIntel 							"on the socket %d\n",
1407b6ea6408SIntel 							rxring_numa[pi]);
1408148f963fSBruce Richardson 						return -1;
1409b6ea6408SIntel 					}
1410b6ea6408SIntel 
1411b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1412b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1413b6ea6408SIntel 					     &(port->rx_conf),mp);
1414b6ea6408SIntel 				}
1415b6ea6408SIntel 				else
1416b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1417b6ea6408SIntel 					     nb_rxd,port->socket_id,
1418b6ea6408SIntel 					     &(port->rx_conf),
1419ce8d5614SIntel 				             mbuf_pool_find(port->socket_id));
1420b6ea6408SIntel 
1421ce8d5614SIntel 				if (diag == 0)
1422ce8d5614SIntel 					continue;
1423ce8d5614SIntel 
1424b6ea6408SIntel 
1425ce8d5614SIntel 				/* Fail to setup rx queue, return */
1426ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1427ce8d5614SIntel 							RTE_PORT_HANDLING,
1428ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1429ce8d5614SIntel 					printf("Port %d can not be set back "
1430ce8d5614SIntel 							"to stopped\n", pi);
1431ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1432ce8d5614SIntel 				/* try to reconfigure queues next time */
1433ce8d5614SIntel 				port->need_reconfig_queues = 1;
1434148f963fSBruce Richardson 				return -1;
1435ce8d5614SIntel 			}
1436ce8d5614SIntel 		}
1437ce8d5614SIntel 		/* start port */
1438ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1439ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1440ce8d5614SIntel 
1441ce8d5614SIntel 			/* Fail to setup rx queue, return */
1442ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1443ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1444ce8d5614SIntel 				printf("Port %d can not be set back to "
1445ce8d5614SIntel 							"stopped\n", pi);
1446ce8d5614SIntel 			continue;
1447ce8d5614SIntel 		}
1448ce8d5614SIntel 
1449ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1450ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1451ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1452ce8d5614SIntel 
14532950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1454d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
14552950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
14562950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
14572950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1458d8c89163SZijie Pan 
1459ce8d5614SIntel 		/* at least one port started, need checking link status */
1460ce8d5614SIntel 		need_check_link_status = 1;
1461ce8d5614SIntel 	}
1462ce8d5614SIntel 
146392d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1464edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
146592d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1466ce8d5614SIntel 		printf("Please stop the ports first\n");
1467ce8d5614SIntel 
1468ce8d5614SIntel 	printf("Done\n");
1469148f963fSBruce Richardson 	return 0;
1470ce8d5614SIntel }
1471ce8d5614SIntel 
1472ce8d5614SIntel void
1473ce8d5614SIntel stop_port(portid_t pid)
1474ce8d5614SIntel {
1475ce8d5614SIntel 	portid_t pi;
1476ce8d5614SIntel 	struct rte_port *port;
1477ce8d5614SIntel 	int need_check_link_status = 0;
1478ce8d5614SIntel 
1479ce8d5614SIntel 	if (test_done == 0) {
1480ce8d5614SIntel 		printf("Please stop forwarding first\n");
1481ce8d5614SIntel 		return;
1482ce8d5614SIntel 	}
1483ce8d5614SIntel 	if (dcb_test) {
1484ce8d5614SIntel 		dcb_test = 0;
1485ce8d5614SIntel 		dcb_config = 0;
1486ce8d5614SIntel 	}
14874468635fSMichael Qiu 
14884468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14894468635fSMichael Qiu 		return;
14904468635fSMichael Qiu 
1491ce8d5614SIntel 	printf("Stopping ports...\n");
1492ce8d5614SIntel 
1493edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14944468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1495ce8d5614SIntel 			continue;
1496ce8d5614SIntel 
1497ce8d5614SIntel 		port = &ports[pi];
1498ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1499ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1500ce8d5614SIntel 			continue;
1501ce8d5614SIntel 
1502ce8d5614SIntel 		rte_eth_dev_stop(pi);
1503ce8d5614SIntel 
1504ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1505ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1506ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1507ce8d5614SIntel 		need_check_link_status = 1;
1508ce8d5614SIntel 	}
1509bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1510edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1511ce8d5614SIntel 
1512ce8d5614SIntel 	printf("Done\n");
1513ce8d5614SIntel }
1514ce8d5614SIntel 
1515ce8d5614SIntel void
1516ce8d5614SIntel close_port(portid_t pid)
1517ce8d5614SIntel {
1518ce8d5614SIntel 	portid_t pi;
1519ce8d5614SIntel 	struct rte_port *port;
1520ce8d5614SIntel 
1521ce8d5614SIntel 	if (test_done == 0) {
1522ce8d5614SIntel 		printf("Please stop forwarding first\n");
1523ce8d5614SIntel 		return;
1524ce8d5614SIntel 	}
1525ce8d5614SIntel 
15264468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
15274468635fSMichael Qiu 		return;
15284468635fSMichael Qiu 
1529ce8d5614SIntel 	printf("Closing ports...\n");
1530ce8d5614SIntel 
1531edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
15324468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1533ce8d5614SIntel 			continue;
1534ce8d5614SIntel 
1535ce8d5614SIntel 		port = &ports[pi];
1536ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1537ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1538ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1539ce8d5614SIntel 			continue;
1540ce8d5614SIntel 		}
1541ce8d5614SIntel 
1542ce8d5614SIntel 		rte_eth_dev_close(pi);
1543ce8d5614SIntel 
1544ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1545ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1546ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1547ce8d5614SIntel 	}
1548ce8d5614SIntel 
1549ce8d5614SIntel 	printf("Done\n");
1550ce8d5614SIntel }
1551ce8d5614SIntel 
1552edab33b1STetsuya Mukawa void
1553edab33b1STetsuya Mukawa attach_port(char *identifier)
1554ce8d5614SIntel {
1555edab33b1STetsuya Mukawa 	portid_t i, j, pi = 0;
1556ce8d5614SIntel 
1557edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1558edab33b1STetsuya Mukawa 
1559edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1560edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1561edab33b1STetsuya Mukawa 		return;
1562ce8d5614SIntel 	}
1563ce8d5614SIntel 
1564edab33b1STetsuya Mukawa 	if (test_done == 0) {
1565edab33b1STetsuya Mukawa 		printf("Please stop forwarding first\n");
1566edab33b1STetsuya Mukawa 		return;
1567ce8d5614SIntel 	}
1568ce8d5614SIntel 
1569edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1570edab33b1STetsuya Mukawa 		return;
1571edab33b1STetsuya Mukawa 
1572edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1573edab33b1STetsuya Mukawa 	reconfig(pi, rte_eth_dev_socket_id(pi));
1574edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1575edab33b1STetsuya Mukawa 
1576edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1577edab33b1STetsuya Mukawa 
1578edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1579edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1580edab33b1STetsuya Mukawa 	i = 0;
1581edab33b1STetsuya Mukawa 	FOREACH_PORT(j, ports) {
1582edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = j;
1583edab33b1STetsuya Mukawa 		i++;
1584edab33b1STetsuya Mukawa 	}
1585edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1586edab33b1STetsuya Mukawa 	nb_fwd_ports++;
1587edab33b1STetsuya Mukawa 
1588edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1589edab33b1STetsuya Mukawa 
1590edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1591edab33b1STetsuya Mukawa 	printf("Done\n");
1592edab33b1STetsuya Mukawa }
1593edab33b1STetsuya Mukawa 
1594edab33b1STetsuya Mukawa void
1595edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
15965f4ec54fSChen Jing D(Mark) {
1597edab33b1STetsuya Mukawa 	portid_t i, pi = 0;
1598edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
15995f4ec54fSChen Jing D(Mark) 
1600edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
16015f4ec54fSChen Jing D(Mark) 
1602edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1603edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1604edab33b1STetsuya Mukawa 		return;
1605edab33b1STetsuya Mukawa 	}
1606edab33b1STetsuya Mukawa 
1607edab33b1STetsuya Mukawa 	rte_eth_promiscuous_disable(port_id);
1608edab33b1STetsuya Mukawa 
1609edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1610edab33b1STetsuya Mukawa 		return;
1611edab33b1STetsuya Mukawa 
1612edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1613edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1614edab33b1STetsuya Mukawa 
1615edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1616edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1617edab33b1STetsuya Mukawa 	i = 0;
1618edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1619edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = pi;
1620edab33b1STetsuya Mukawa 		i++;
1621edab33b1STetsuya Mukawa 	}
1622edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1623edab33b1STetsuya Mukawa 	nb_fwd_ports--;
1624edab33b1STetsuya Mukawa 
1625edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1626edab33b1STetsuya Mukawa 			name, nb_ports);
1627edab33b1STetsuya Mukawa 	printf("Done\n");
1628edab33b1STetsuya Mukawa 	return;
16295f4ec54fSChen Jing D(Mark) }
16305f4ec54fSChen Jing D(Mark) 
1631af75078fSIntel void
1632af75078fSIntel pmd_test_exit(void)
1633af75078fSIntel {
1634af75078fSIntel 	portid_t pt_id;
1635af75078fSIntel 
16368210ec25SPablo de Lara 	if (test_done == 0)
16378210ec25SPablo de Lara 		stop_packet_forwarding();
16388210ec25SPablo de Lara 
1639edab33b1STetsuya Mukawa 	FOREACH_PORT(pt_id, ports) {
1640af75078fSIntel 		printf("Stopping port %d...", pt_id);
1641af75078fSIntel 		fflush(stdout);
1642af75078fSIntel 		rte_eth_dev_close(pt_id);
1643af75078fSIntel 		printf("done\n");
1644af75078fSIntel 	}
1645af75078fSIntel 	printf("bye...\n");
1646af75078fSIntel }
1647af75078fSIntel 
1648af75078fSIntel typedef void (*cmd_func_t)(void);
1649af75078fSIntel struct pmd_test_command {
1650af75078fSIntel 	const char *cmd_name;
1651af75078fSIntel 	cmd_func_t cmd_func;
1652af75078fSIntel };
1653af75078fSIntel 
1654af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1655af75078fSIntel 
1656ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1657af75078fSIntel static void
1658edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1659af75078fSIntel {
1660ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1661ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1662ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1663ce8d5614SIntel 	struct rte_eth_link link;
1664ce8d5614SIntel 
1665ce8d5614SIntel 	printf("Checking link statuses...\n");
1666ce8d5614SIntel 	fflush(stdout);
1667ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1668ce8d5614SIntel 		all_ports_up = 1;
1669edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1670ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1671ce8d5614SIntel 				continue;
1672ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1673ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1674ce8d5614SIntel 			/* print link status if flag set */
1675ce8d5614SIntel 			if (print_flag == 1) {
1676ce8d5614SIntel 				if (link.link_status)
1677ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1678ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1679ce8d5614SIntel 						(unsigned)link.link_speed,
1680ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1681ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1682ce8d5614SIntel 				else
1683ce8d5614SIntel 					printf("Port %d Link Down\n",
1684ce8d5614SIntel 						(uint8_t)portid);
1685ce8d5614SIntel 				continue;
1686ce8d5614SIntel 			}
1687ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
1688ce8d5614SIntel 			if (link.link_status == 0) {
1689ce8d5614SIntel 				all_ports_up = 0;
1690ce8d5614SIntel 				break;
1691ce8d5614SIntel 			}
1692ce8d5614SIntel 		}
1693ce8d5614SIntel 		/* after finally printing all link status, get out */
1694ce8d5614SIntel 		if (print_flag == 1)
1695ce8d5614SIntel 			break;
1696ce8d5614SIntel 
1697ce8d5614SIntel 		if (all_ports_up == 0) {
1698ce8d5614SIntel 			fflush(stdout);
1699ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1700ce8d5614SIntel 		}
1701ce8d5614SIntel 
1702ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1703ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1704ce8d5614SIntel 			print_flag = 1;
1705ce8d5614SIntel 		}
1706ce8d5614SIntel 	}
1707af75078fSIntel }
1708af75078fSIntel 
1709013af9b6SIntel static int
1710013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1711af75078fSIntel {
1712013af9b6SIntel 	uint16_t i;
1713af75078fSIntel 	int diag;
1714013af9b6SIntel 	uint8_t mapping_found = 0;
1715af75078fSIntel 
1716013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1717013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1718013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1719013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1720013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1721013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1722013af9b6SIntel 			if (diag != 0)
1723013af9b6SIntel 				return diag;
1724013af9b6SIntel 			mapping_found = 1;
1725af75078fSIntel 		}
1726013af9b6SIntel 	}
1727013af9b6SIntel 	if (mapping_found)
1728013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1729013af9b6SIntel 	return 0;
1730013af9b6SIntel }
1731013af9b6SIntel 
1732013af9b6SIntel static int
1733013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1734013af9b6SIntel {
1735013af9b6SIntel 	uint16_t i;
1736013af9b6SIntel 	int diag;
1737013af9b6SIntel 	uint8_t mapping_found = 0;
1738013af9b6SIntel 
1739013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1740013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1741013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1742013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1743013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1744013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1745013af9b6SIntel 			if (diag != 0)
1746013af9b6SIntel 				return diag;
1747013af9b6SIntel 			mapping_found = 1;
1748013af9b6SIntel 		}
1749013af9b6SIntel 	}
1750013af9b6SIntel 	if (mapping_found)
1751013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1752013af9b6SIntel 	return 0;
1753013af9b6SIntel }
1754013af9b6SIntel 
1755013af9b6SIntel static void
1756013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1757013af9b6SIntel {
1758013af9b6SIntel 	int diag = 0;
1759013af9b6SIntel 
1760013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1761af75078fSIntel 	if (diag != 0) {
1762013af9b6SIntel 		if (diag == -ENOTSUP) {
1763013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1764013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1765013af9b6SIntel 		}
1766013af9b6SIntel 		else
1767013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1768013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1769013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1770af75078fSIntel 					pi, diag);
1771af75078fSIntel 	}
1772013af9b6SIntel 
1773013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1774af75078fSIntel 	if (diag != 0) {
1775013af9b6SIntel 		if (diag == -ENOTSUP) {
1776013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1777013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1778013af9b6SIntel 		}
1779013af9b6SIntel 		else
1780013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1781013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1782013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1783af75078fSIntel 					pi, diag);
1784af75078fSIntel 	}
1785af75078fSIntel }
1786af75078fSIntel 
1787f2c5125aSPablo de Lara static void
1788f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1789f2c5125aSPablo de Lara {
1790f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1791f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1792f2c5125aSPablo de Lara 
1793f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1794f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1795f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1796f2c5125aSPablo de Lara 
1797f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1798f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1799f2c5125aSPablo de Lara 
1800f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1801f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1802f2c5125aSPablo de Lara 
1803f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1804f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1805f2c5125aSPablo de Lara 
1806f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1807f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1808f2c5125aSPablo de Lara 
1809f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1810f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1811f2c5125aSPablo de Lara 
1812f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1813f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1814f2c5125aSPablo de Lara 
1815f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1816f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1817f2c5125aSPablo de Lara 
1818f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1819f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1820f2c5125aSPablo de Lara 
1821f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1822f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1823f2c5125aSPablo de Lara 
1824f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1825f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1826f2c5125aSPablo de Lara }
1827f2c5125aSPablo de Lara 
1828013af9b6SIntel void
1829013af9b6SIntel init_port_config(void)
1830013af9b6SIntel {
1831013af9b6SIntel 	portid_t pid;
1832013af9b6SIntel 	struct rte_port *port;
1833013af9b6SIntel 
1834edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1835013af9b6SIntel 		port = &ports[pid];
1836013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1837013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
18383ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1839013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1840013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1841af75078fSIntel 		} else {
1842013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1843013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1844af75078fSIntel 		}
18453ce690d3SBruce Richardson 
18463ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
18473ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
18483ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
18493ce690d3SBruce Richardson 			else
18503ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
18513ce690d3SBruce Richardson 		}
18523ce690d3SBruce Richardson 
1853a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1854a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1855a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1856a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1857a30979f6SOuyang Changchun 			else
1858a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1859a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1860a30979f6SOuyang Changchun 
1861a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1862a30979f6SOuyang Changchun 		}
1863a30979f6SOuyang Changchun 
1864f2c5125aSPablo de Lara 		rxtx_port_config(port);
1865013af9b6SIntel 
1866013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1867013af9b6SIntel 
1868013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18697b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18707b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18717b7e5ba7SIntel #endif
1872013af9b6SIntel 	}
1873013af9b6SIntel }
1874013af9b6SIntel 
1875013af9b6SIntel const uint16_t vlan_tags[] = {
1876013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1877013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1878013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1879013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1880013af9b6SIntel };
1881013af9b6SIntel 
1882013af9b6SIntel static  int
1883013af9b6SIntel get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1884013af9b6SIntel {
1885013af9b6SIntel         uint8_t i;
1886af75078fSIntel 
1887af75078fSIntel  	/*
1888013af9b6SIntel  	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1889013af9b6SIntel  	 * given above, and the number of traffic classes available for use.
1890af75078fSIntel  	 */
1891013af9b6SIntel 	if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1892013af9b6SIntel 		struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1893013af9b6SIntel 		struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1894013af9b6SIntel 
1895013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
1896013af9b6SIntel 		vmdq_rx_conf.enable_default_pool = 0;
1897013af9b6SIntel 		vmdq_rx_conf.default_pool = 0;
1898013af9b6SIntel 		vmdq_rx_conf.nb_queue_pools =
1899013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1900013af9b6SIntel 		vmdq_tx_conf.nb_queue_pools =
1901013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1902013af9b6SIntel 
1903013af9b6SIntel 		vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1904013af9b6SIntel 		for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1905013af9b6SIntel 			vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1906013af9b6SIntel 			vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1907af75078fSIntel 		}
1908013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1909013af9b6SIntel 			vmdq_rx_conf.dcb_queue[i] = i;
1910013af9b6SIntel 			vmdq_tx_conf.dcb_queue[i] = i;
1911013af9b6SIntel 		}
1912013af9b6SIntel 
1913013af9b6SIntel 		/*set DCB mode of RX and TX of multiple queues*/
191432e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
191532e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1916013af9b6SIntel 		if (dcb_conf->pfc_en)
1917013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1918013af9b6SIntel 		else
1919013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1920013af9b6SIntel 
1921013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1922013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1923013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1924013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1925013af9b6SIntel 	}
1926013af9b6SIntel 	else {
1927013af9b6SIntel 		struct rte_eth_dcb_rx_conf rx_conf;
1928013af9b6SIntel 		struct rte_eth_dcb_tx_conf tx_conf;
1929013af9b6SIntel 
1930013af9b6SIntel 		/* queue mapping configuration of DCB RX and TX */
1931013af9b6SIntel 		if (dcb_conf->num_tcs == ETH_4_TCS)
1932013af9b6SIntel 			dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1933013af9b6SIntel 		else
1934013af9b6SIntel 			dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1935013af9b6SIntel 
1936013af9b6SIntel 		rx_conf.nb_tcs = dcb_conf->num_tcs;
1937013af9b6SIntel 		tx_conf.nb_tcs = dcb_conf->num_tcs;
1938013af9b6SIntel 
1939013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1940013af9b6SIntel 			rx_conf.dcb_queue[i] = i;
1941013af9b6SIntel 			tx_conf.dcb_queue[i] = i;
1942013af9b6SIntel 		}
194332e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
194432e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1945013af9b6SIntel 		if (dcb_conf->pfc_en)
1946013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1947013af9b6SIntel 		else
1948013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1949013af9b6SIntel 
1950013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1951013af9b6SIntel                                 sizeof(struct rte_eth_dcb_rx_conf)));
1952013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1953013af9b6SIntel                                 sizeof(struct rte_eth_dcb_tx_conf)));
1954013af9b6SIntel 	}
1955013af9b6SIntel 
1956013af9b6SIntel 	return 0;
1957013af9b6SIntel }
1958013af9b6SIntel 
1959013af9b6SIntel int
1960013af9b6SIntel init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1961013af9b6SIntel {
1962013af9b6SIntel 	struct rte_eth_conf port_conf;
1963013af9b6SIntel 	struct rte_port *rte_port;
1964013af9b6SIntel 	int retval;
1965013af9b6SIntel 	uint16_t nb_vlan;
1966013af9b6SIntel 	uint16_t i;
1967013af9b6SIntel 
1968013af9b6SIntel 	/* rxq and txq configuration in dcb mode */
1969013af9b6SIntel 	nb_rxq = 128;
1970013af9b6SIntel 	nb_txq = 128;
1971013af9b6SIntel 	rx_free_thresh = 64;
1972013af9b6SIntel 
1973013af9b6SIntel 	memset(&port_conf,0,sizeof(struct rte_eth_conf));
1974013af9b6SIntel 	/* Enter DCB configuration status */
1975013af9b6SIntel 	dcb_config = 1;
1976013af9b6SIntel 
1977013af9b6SIntel 	nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1978013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
1979013af9b6SIntel 	retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1980013af9b6SIntel 	if (retval < 0)
1981013af9b6SIntel 		return retval;
1982013af9b6SIntel 
1983013af9b6SIntel 	rte_port = &ports[pid];
1984013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1985013af9b6SIntel 
1986f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
1987013af9b6SIntel 	/* VLAN filter */
1988013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1989013af9b6SIntel 	for (i = 0; i < nb_vlan; i++){
1990013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1991013af9b6SIntel 	}
1992013af9b6SIntel 
1993013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1994013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1995013af9b6SIntel 
19967741e4cfSIntel 	rte_port->dcb_flag = 1;
19977741e4cfSIntel 
1998013af9b6SIntel 	return 0;
1999af75078fSIntel }
2000af75078fSIntel 
2001ffc468ffSTetsuya Mukawa static void
2002ffc468ffSTetsuya Mukawa init_port(void)
2003ffc468ffSTetsuya Mukawa {
2004ffc468ffSTetsuya Mukawa 	portid_t pid;
2005ffc468ffSTetsuya Mukawa 
2006ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2007ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2008ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2009ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2010ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2011ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2012ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2013ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2014ffc468ffSTetsuya Mukawa 	}
2015ffc468ffSTetsuya Mukawa 
2016ffc468ffSTetsuya Mukawa 	/* enabled allocated ports */
2017ffc468ffSTetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
2018ffc468ffSTetsuya Mukawa 		ports[pid].enabled = 1;
2019ffc468ffSTetsuya Mukawa }
2020ffc468ffSTetsuya Mukawa 
2021af75078fSIntel int
2022af75078fSIntel main(int argc, char** argv)
2023af75078fSIntel {
2024af75078fSIntel 	int  diag;
2025013af9b6SIntel 	uint8_t port_id;
2026af75078fSIntel 
2027af75078fSIntel 	diag = rte_eal_init(argc, argv);
2028af75078fSIntel 	if (diag < 0)
2029af75078fSIntel 		rte_panic("Cannot init EAL\n");
2030af75078fSIntel 
2031af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2032af75078fSIntel 	if (nb_ports == 0)
2033edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2034af75078fSIntel 
2035ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2036ffc468ffSTetsuya Mukawa 	init_port();
2037ffc468ffSTetsuya Mukawa 
2038af75078fSIntel 	set_def_fwd_config();
2039af75078fSIntel 	if (nb_lcores == 0)
2040af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2041af75078fSIntel 			  "core mask supplied in the command parameters\n");
2042af75078fSIntel 
2043af75078fSIntel 	argc -= diag;
2044af75078fSIntel 	argv += diag;
2045af75078fSIntel 	if (argc > 1)
2046af75078fSIntel 		launch_args_parse(argc, argv);
2047af75078fSIntel 
2048af75078fSIntel 	if (nb_rxq > nb_txq)
2049af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2050af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2051af75078fSIntel 		       nb_rxq, nb_txq);
2052af75078fSIntel 
2053af75078fSIntel 	init_config();
2054148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2055148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2056af75078fSIntel 
2057ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
2058edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
2059ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2060af75078fSIntel 
20610d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2062ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2063ca7feb22SCyril Chemparathy 		if (auto_start) {
2064ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2065ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2066ca7feb22SCyril Chemparathy 		}
2067af75078fSIntel 		prompt();
2068ca7feb22SCyril Chemparathy 	} else
20690d56cb81SThomas Monjalon #endif
20700d56cb81SThomas Monjalon 	{
2071af75078fSIntel 		char c;
2072af75078fSIntel 		int rc;
2073af75078fSIntel 
2074af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2075af75078fSIntel 		start_packet_forwarding(0);
2076af75078fSIntel 		printf("Press enter to exit\n");
2077af75078fSIntel 		rc = read(0, &c, 1);
2078af75078fSIntel 		if (rc < 0)
2079af75078fSIntel 			return 1;
2080af75078fSIntel 	}
2081af75078fSIntel 
2082af75078fSIntel 	return 0;
2083af75078fSIntel }
2084