xref: /dpdk/app/test-pmd/testpmd.c (revision edab33b1c01d508fdd934c06ee27f84250d2749a)
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_tailq.h>
61af75078fSIntel #include <rte_eal.h>
62af75078fSIntel #include <rte_per_lcore.h>
63af75078fSIntel #include <rte_lcore.h>
64af75078fSIntel #include <rte_atomic.h>
65af75078fSIntel #include <rte_branch_prediction.h>
66af75078fSIntel #include <rte_ring.h>
67af75078fSIntel #include <rte_mempool.h>
68af75078fSIntel #include <rte_malloc.h>
69af75078fSIntel #include <rte_mbuf.h>
70af75078fSIntel #include <rte_interrupts.h>
71af75078fSIntel #include <rte_pci.h>
72af75078fSIntel #include <rte_ether.h>
73af75078fSIntel #include <rte_ethdev.h>
74*edab33b1STetsuya Mukawa #include <rte_dev.h>
75af75078fSIntel #include <rte_string_fns.h>
76148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
77148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
78148f963fSBruce Richardson #endif
79af75078fSIntel 
80af75078fSIntel #include "testpmd.h"
81148f963fSBruce Richardson #include "mempool_osdep.h"
82af75078fSIntel 
83af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
84af75078fSIntel 
85af75078fSIntel /* use master core for command line ? */
86af75078fSIntel uint8_t interactive = 0;
87ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
88af75078fSIntel 
89af75078fSIntel /*
90af75078fSIntel  * NUMA support configuration.
91af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
92af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
93af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
94af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
95af75078fSIntel  */
96af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */
97af75078fSIntel 
98af75078fSIntel /*
99b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
100b6ea6408SIntel  * not configured.
101b6ea6408SIntel  */
102b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
103b6ea6408SIntel 
104b6ea6408SIntel /*
105148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
106148f963fSBruce Richardson  */
107148f963fSBruce Richardson uint8_t mp_anon = 0;
108148f963fSBruce Richardson 
109148f963fSBruce Richardson /*
110af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
111af75078fSIntel  * forwarded.
112af75078fSIntel  * Must be instanciated with the ethernet addresses of peer traffic generator
113af75078fSIntel  * ports.
114af75078fSIntel  */
115af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
116af75078fSIntel portid_t nb_peer_eth_addrs = 0;
117af75078fSIntel 
118af75078fSIntel /*
119af75078fSIntel  * Probed Target Environment.
120af75078fSIntel  */
121af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
122af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
123af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
124af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
125af75078fSIntel 
126af75078fSIntel /*
127af75078fSIntel  * Test Forwarding Configuration.
128af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
129af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
130af75078fSIntel  */
131af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
132af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
133af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
134af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
135af75078fSIntel 
136af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
137af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
138af75078fSIntel 
139af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
140af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
141af75078fSIntel 
142af75078fSIntel /*
143af75078fSIntel  * Forwarding engines.
144af75078fSIntel  */
145af75078fSIntel struct fwd_engine * fwd_engines[] = {
146af75078fSIntel 	&io_fwd_engine,
147af75078fSIntel 	&mac_fwd_engine,
14857e85242SBruce Richardson 	&mac_retry_fwd_engine,
149d47388f1SCyril Chemparathy 	&mac_swap_engine,
150e9e23a61SCyril Chemparathy 	&flow_gen_engine,
151af75078fSIntel 	&rx_only_engine,
152af75078fSIntel 	&tx_only_engine,
153af75078fSIntel 	&csum_fwd_engine,
154168dfa61SIvan Boule 	&icmp_echo_engine,
155af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
156af75078fSIntel 	&ieee1588_fwd_engine,
157af75078fSIntel #endif
158af75078fSIntel 	NULL,
159af75078fSIntel };
160af75078fSIntel 
161af75078fSIntel struct fwd_config cur_fwd_config;
162af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
163af75078fSIntel 
164af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
165c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
166c8798818SIntel                                       * specified on command-line. */
167af75078fSIntel 
168af75078fSIntel /*
169af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
170af75078fSIntel  */
171af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
172af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
173af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
174af75078fSIntel };
175af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
176af75078fSIntel 
177af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
178e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
179af75078fSIntel 
180900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
181900550deSIntel uint8_t dcb_config = 0;
182900550deSIntel 
183900550deSIntel /* Whether the dcb is in testing status */
184900550deSIntel uint8_t dcb_test = 0;
185900550deSIntel 
186900550deSIntel /* DCB on and VT on mapping is default */
187900550deSIntel enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
188af75078fSIntel 
189af75078fSIntel /*
190af75078fSIntel  * Configurable number of RX/TX queues.
191af75078fSIntel  */
192af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
193af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
194af75078fSIntel 
195af75078fSIntel /*
196af75078fSIntel  * Configurable number of RX/TX ring descriptors.
197af75078fSIntel  */
198af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
199af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
200af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
201af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
202af75078fSIntel 
203f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
204af75078fSIntel /*
205af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
206af75078fSIntel  */
207af75078fSIntel 
208f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
209f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
210f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
211af75078fSIntel 
212f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
213f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
214f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
215af75078fSIntel 
216af75078fSIntel /*
217af75078fSIntel  * Configurable value of RX free threshold.
218af75078fSIntel  */
219f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
220af75078fSIntel 
221af75078fSIntel /*
222ce8d5614SIntel  * Configurable value of RX drop enable.
223ce8d5614SIntel  */
224f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
225ce8d5614SIntel 
226ce8d5614SIntel /*
227af75078fSIntel  * Configurable value of TX free threshold.
228af75078fSIntel  */
229f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
230af75078fSIntel 
231af75078fSIntel /*
232af75078fSIntel  * Configurable value of TX RS bit threshold.
233af75078fSIntel  */
234f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
235af75078fSIntel 
236af75078fSIntel /*
237ce8d5614SIntel  * Configurable value of TX queue flags.
238ce8d5614SIntel  */
239f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
240ce8d5614SIntel 
241ce8d5614SIntel /*
242af75078fSIntel  * Receive Side Scaling (RSS) configuration.
243af75078fSIntel  */
2448a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
245af75078fSIntel 
246af75078fSIntel /*
247af75078fSIntel  * Port topology configuration
248af75078fSIntel  */
249af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
250af75078fSIntel 
2517741e4cfSIntel /*
2527741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2537741e4cfSIntel  */
2547741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2557741e4cfSIntel 
256af75078fSIntel /*
257bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
258bc202406SDavid Marchand  */
259bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
260bc202406SDavid Marchand 
261bc202406SDavid Marchand /*
2627b7e5ba7SIntel  * NIC bypass mode configuration options.
2637b7e5ba7SIntel  */
2647b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
2657b7e5ba7SIntel 
2667b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
2677b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
2687b7e5ba7SIntel 
2697b7e5ba7SIntel #endif
2707b7e5ba7SIntel 
2717b7e5ba7SIntel /*
272af75078fSIntel  * Ethernet device configuration.
273af75078fSIntel  */
274af75078fSIntel struct rte_eth_rxmode rx_mode = {
275af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
276af75078fSIntel 	.split_hdr_size = 0,
277af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
278af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
279af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
280a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
281a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
282af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
283af75078fSIntel 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
284af75078fSIntel };
285af75078fSIntel 
286af75078fSIntel struct rte_fdir_conf fdir_conf = {
287af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
288af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
289af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
290d9d5e6f2SJingjing Wu 	.mask = {
291d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
292d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
293d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
294d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
295d9d5e6f2SJingjing Wu 		},
296d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
297d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
298d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
299d9d5e6f2SJingjing Wu 		},
300d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
301d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
302d9d5e6f2SJingjing Wu 	},
303af75078fSIntel 	.drop_queue = 127,
304af75078fSIntel };
305af75078fSIntel 
3062950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
307af75078fSIntel 
308ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
309ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
310ed30d9b6SIntel 
311ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
312ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
313ed30d9b6SIntel 
314ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
315ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
316ed30d9b6SIntel 
317ed30d9b6SIntel /* Forward function declarations */
318ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
319*edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
320ce8d5614SIntel 
321ce8d5614SIntel /*
322ce8d5614SIntel  * Check if all the ports are started.
323ce8d5614SIntel  * If yes, return positive value. If not, return zero.
324ce8d5614SIntel  */
325ce8d5614SIntel static int all_ports_started(void);
326ed30d9b6SIntel 
327af75078fSIntel /*
328*edab33b1STetsuya Mukawa  * Find next enabled port
329*edab33b1STetsuya Mukawa  */
330*edab33b1STetsuya Mukawa portid_t
331*edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
332*edab33b1STetsuya Mukawa {
333*edab33b1STetsuya Mukawa 	if (ports == NULL)
334*edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
335*edab33b1STetsuya Mukawa 
336*edab33b1STetsuya Mukawa 	while ((ports[p].enabled == 0) && (p < size))
337*edab33b1STetsuya Mukawa 		p++;
338*edab33b1STetsuya Mukawa 	return p;
339*edab33b1STetsuya Mukawa }
340*edab33b1STetsuya Mukawa 
341*edab33b1STetsuya Mukawa /*
342af75078fSIntel  * Setup default configuration.
343af75078fSIntel  */
344af75078fSIntel static void
345af75078fSIntel set_default_fwd_lcores_config(void)
346af75078fSIntel {
347af75078fSIntel 	unsigned int i;
348af75078fSIntel 	unsigned int nb_lc;
349af75078fSIntel 
350af75078fSIntel 	nb_lc = 0;
351af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
352af75078fSIntel 		if (! rte_lcore_is_enabled(i))
353af75078fSIntel 			continue;
354af75078fSIntel 		if (i == rte_get_master_lcore())
355af75078fSIntel 			continue;
356af75078fSIntel 		fwd_lcores_cpuids[nb_lc++] = i;
357af75078fSIntel 	}
358af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
359af75078fSIntel 	nb_cfg_lcores = nb_lcores;
360af75078fSIntel 	nb_fwd_lcores = 1;
361af75078fSIntel }
362af75078fSIntel 
363af75078fSIntel static void
364af75078fSIntel set_def_peer_eth_addrs(void)
365af75078fSIntel {
366af75078fSIntel 	portid_t i;
367af75078fSIntel 
368af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
369af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
370af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
371af75078fSIntel 	}
372af75078fSIntel }
373af75078fSIntel 
374af75078fSIntel static void
375af75078fSIntel set_default_fwd_ports_config(void)
376af75078fSIntel {
377af75078fSIntel 	portid_t pt_id;
378af75078fSIntel 
379af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
380af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
381af75078fSIntel 
382af75078fSIntel 	nb_cfg_ports = nb_ports;
383af75078fSIntel 	nb_fwd_ports = nb_ports;
384af75078fSIntel }
385af75078fSIntel 
386af75078fSIntel void
387af75078fSIntel set_def_fwd_config(void)
388af75078fSIntel {
389af75078fSIntel 	set_default_fwd_lcores_config();
390af75078fSIntel 	set_def_peer_eth_addrs();
391af75078fSIntel 	set_default_fwd_ports_config();
392af75078fSIntel }
393af75078fSIntel 
394af75078fSIntel /*
395af75078fSIntel  * Configuration initialisation done once at init time.
396af75078fSIntel  */
397af75078fSIntel struct mbuf_ctor_arg {
398af75078fSIntel 	uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
399af75078fSIntel 	uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
400af75078fSIntel };
401af75078fSIntel 
402af75078fSIntel struct mbuf_pool_ctor_arg {
403af75078fSIntel 	uint16_t seg_buf_size; /**< size of data segment in mbuf. */
404af75078fSIntel };
405af75078fSIntel 
406af75078fSIntel static void
407af75078fSIntel testpmd_mbuf_ctor(struct rte_mempool *mp,
408af75078fSIntel 		  void *opaque_arg,
409af75078fSIntel 		  void *raw_mbuf,
410af75078fSIntel 		  __attribute__((unused)) unsigned i)
411af75078fSIntel {
412af75078fSIntel 	struct mbuf_ctor_arg *mb_ctor_arg;
413af75078fSIntel 	struct rte_mbuf    *mb;
414af75078fSIntel 
415af75078fSIntel 	mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
416af75078fSIntel 	mb = (struct rte_mbuf *) raw_mbuf;
417af75078fSIntel 
418af75078fSIntel 	mb->pool         = mp;
419af75078fSIntel 	mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
420af75078fSIntel 	mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
421af75078fSIntel 			mb_ctor_arg->seg_buf_offset);
422af75078fSIntel 	mb->buf_len      = mb_ctor_arg->seg_buf_size;
423af75078fSIntel 	mb->ol_flags     = 0;
42408b563ffSOlivier Matz 	mb->data_off     = RTE_PKTMBUF_HEADROOM;
425ea672a8bSOlivier Matz 	mb->nb_segs      = 1;
4264199fdeaSOlivier Matz 	mb->tx_offload   = 0;
4277869536fSBruce Richardson 	mb->vlan_tci     = 0;
428ea672a8bSOlivier Matz 	mb->hash.rss     = 0;
429af75078fSIntel }
430af75078fSIntel 
431af75078fSIntel static void
432af75078fSIntel testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
433af75078fSIntel 		       void *opaque_arg)
434af75078fSIntel {
435af75078fSIntel 	struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
436af75078fSIntel 	struct rte_pktmbuf_pool_private *mbp_priv;
437af75078fSIntel 
438af75078fSIntel 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
439af75078fSIntel 		printf("%s(%s) private_data_size %d < %d\n",
440af75078fSIntel 		       __func__, mp->name, (int) mp->private_data_size,
441af75078fSIntel 		       (int) sizeof(struct rte_pktmbuf_pool_private));
442af75078fSIntel 		return;
443af75078fSIntel 	}
444af75078fSIntel 	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
445148f963fSBruce Richardson 	mbp_priv = rte_mempool_get_priv(mp);
446af75078fSIntel 	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
447af75078fSIntel }
448af75078fSIntel 
449af75078fSIntel static void
450af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
451af75078fSIntel 		 unsigned int socket_id)
452af75078fSIntel {
453af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
454af75078fSIntel 	struct rte_mempool *rte_mp;
455af75078fSIntel 	struct mbuf_pool_ctor_arg mbp_ctor_arg;
456af75078fSIntel 	struct mbuf_ctor_arg mb_ctor_arg;
457af75078fSIntel 	uint32_t mb_size;
458af75078fSIntel 
459af75078fSIntel 	mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
460af75078fSIntel 						mbuf_seg_size);
461af75078fSIntel 	mb_ctor_arg.seg_buf_offset =
462fdf20fa7SSergio Gonzalez Monroy 		(uint16_t) RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
463af75078fSIntel 	mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
464af75078fSIntel 	mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
465af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
466148f963fSBruce Richardson 
467148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
468148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
469af75078fSIntel                                    (unsigned) mb_mempool_cache,
470af75078fSIntel                                    sizeof(struct rte_pktmbuf_pool_private),
471af75078fSIntel                                    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
472af75078fSIntel                                    testpmd_mbuf_ctor, &mb_ctor_arg,
473af75078fSIntel                                    socket_id, 0);
474148f963fSBruce Richardson 
475148f963fSBruce Richardson 
476148f963fSBruce Richardson 
477148f963fSBruce Richardson #else
478148f963fSBruce Richardson 	if (mp_anon != 0)
479148f963fSBruce Richardson 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
480148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
481148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
482148f963fSBruce Richardson 				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
483148f963fSBruce Richardson 				    testpmd_mbuf_ctor, &mb_ctor_arg,
484148f963fSBruce Richardson 				    socket_id, 0);
485148f963fSBruce Richardson 	else
486148f963fSBruce Richardson 		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
487148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
488148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
489148f963fSBruce Richardson 				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
490148f963fSBruce Richardson 				    testpmd_mbuf_ctor, &mb_ctor_arg,
491148f963fSBruce Richardson 				    socket_id, 0);
492148f963fSBruce Richardson 
493148f963fSBruce Richardson #endif
494148f963fSBruce Richardson 
495af75078fSIntel 	if (rte_mp == NULL) {
496ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
497ce8d5614SIntel 						"failed\n", socket_id);
498148f963fSBruce Richardson 	} else if (verbose_level > 0) {
499591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
500af75078fSIntel 	}
501af75078fSIntel }
502af75078fSIntel 
50320a0286fSLiu Xiaofeng /*
50420a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
50520a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
50620a0286fSLiu Xiaofeng  */
50720a0286fSLiu Xiaofeng static int
50820a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
50920a0286fSLiu Xiaofeng {
51020a0286fSLiu Xiaofeng 	static int warning_once = 0;
51120a0286fSLiu Xiaofeng 
51220a0286fSLiu Xiaofeng 	if (socket_id >= MAX_SOCKET) {
51320a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
51420a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
51520a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
51620a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
51720a0286fSLiu Xiaofeng 			       " --numa.\n");
51820a0286fSLiu Xiaofeng 		warning_once = 1;
51920a0286fSLiu Xiaofeng 		return -1;
52020a0286fSLiu Xiaofeng 	}
52120a0286fSLiu Xiaofeng 	return 0;
52220a0286fSLiu Xiaofeng }
52320a0286fSLiu Xiaofeng 
524af75078fSIntel static void
525af75078fSIntel init_config(void)
526af75078fSIntel {
527ce8d5614SIntel 	portid_t pid;
528af75078fSIntel 	struct rte_port *port;
529af75078fSIntel 	struct rte_mempool *mbp;
530af75078fSIntel 	unsigned int nb_mbuf_per_pool;
531af75078fSIntel 	lcoreid_t  lc_id;
532b6ea6408SIntel 	uint8_t port_per_socket[MAX_SOCKET];
533af75078fSIntel 
534b6ea6408SIntel 	memset(port_per_socket,0,MAX_SOCKET);
535af75078fSIntel 	/* Configuration of logical cores. */
536af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
537af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
538fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
539af75078fSIntel 	if (fwd_lcores == NULL) {
540ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
541ce8d5614SIntel 							"failed\n", nb_lcores);
542af75078fSIntel 	}
543af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
544af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
545af75078fSIntel 					       sizeof(struct fwd_lcore),
546fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
547af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
548ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
549ce8d5614SIntel 								"failed\n");
550af75078fSIntel 		}
551af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
552af75078fSIntel 	}
553af75078fSIntel 
554af75078fSIntel 	/*
555af75078fSIntel 	 * Create pools of mbuf.
556af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
557b6ea6408SIntel 	 * socket 0 memory by default.
558af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
559c8798818SIntel 	 *
560c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
561c8798818SIntel 	 * nb_txd can be configured at run time.
562af75078fSIntel 	 */
563c8798818SIntel 	if (param_total_num_mbufs)
564c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
565c8798818SIntel 	else {
566c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
567c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
568b6ea6408SIntel 
569b6ea6408SIntel 		if (!numa_support)
570*edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
571*edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
572c8798818SIntel 	}
573af75078fSIntel 
574b6ea6408SIntel 	if (!numa_support) {
575b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
576b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
577b6ea6408SIntel 		else
578b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
579b6ea6408SIntel 						 socket_num);
580b6ea6408SIntel 	}
581af75078fSIntel 
582af75078fSIntel 	/* Configuration of Ethernet ports. */
583af75078fSIntel 	ports = rte_zmalloc("testpmd: ports",
584*edab33b1STetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
585fdf20fa7SSergio Gonzalez Monroy 			    RTE_CACHE_LINE_SIZE);
586af75078fSIntel 	if (ports == NULL) {
587*edab33b1STetsuya Mukawa 		rte_exit(EXIT_FAILURE,
588*edab33b1STetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
589*edab33b1STetsuya Mukawa 				RTE_MAX_ETHPORTS);
590af75078fSIntel 	}
591af75078fSIntel 
592*edab33b1STetsuya Mukawa 	/* enabled allocated ports */
593*edab33b1STetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
594*edab33b1STetsuya Mukawa 		ports[pid].enabled = 1;
595*edab33b1STetsuya Mukawa 
596*edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
597ce8d5614SIntel 		port = &ports[pid];
598ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
599ce8d5614SIntel 
600b6ea6408SIntel 		if (numa_support) {
601b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
602b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
603b6ea6408SIntel 			else {
604b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
60520a0286fSLiu Xiaofeng 
60620a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
60720a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
60820a0286fSLiu Xiaofeng 					socket_id = 0;
609b6ea6408SIntel 				port_per_socket[socket_id]++;
610b6ea6408SIntel 			}
611b6ea6408SIntel 		}
612b6ea6408SIntel 
613ce8d5614SIntel 		/* set flag to initialize port/queue */
614ce8d5614SIntel 		port->need_reconfig = 1;
615ce8d5614SIntel 		port->need_reconfig_queues = 1;
616ce8d5614SIntel 	}
617ce8d5614SIntel 
618b6ea6408SIntel 	if (numa_support) {
619b6ea6408SIntel 		uint8_t i;
620b6ea6408SIntel 		unsigned int nb_mbuf;
621ce8d5614SIntel 
622b6ea6408SIntel 		if (param_total_num_mbufs)
623b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
624b6ea6408SIntel 
625b6ea6408SIntel 		for (i = 0; i < MAX_SOCKET; i++) {
626*edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
627b6ea6408SIntel 			if (nb_mbuf)
628b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
629b6ea6408SIntel 						nb_mbuf,i);
630b6ea6408SIntel 		}
631b6ea6408SIntel 	}
632b6ea6408SIntel 	init_port_config();
6335886ae07SAdrien Mazarguil 
6345886ae07SAdrien Mazarguil 	/*
6355886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6365886ae07SAdrien Mazarguil 	 */
6375886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6388fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
6398fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
6408fd8bebcSAdrien Mazarguil 
6415886ae07SAdrien Mazarguil 		if (mbp == NULL)
6425886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6435886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
6445886ae07SAdrien Mazarguil 	}
6455886ae07SAdrien Mazarguil 
646ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
647ce8d5614SIntel 	if (init_fwd_streams() < 0)
648ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
649ce8d5614SIntel }
650ce8d5614SIntel 
6512950a769SDeclan Doherty 
6522950a769SDeclan Doherty void
653a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6542950a769SDeclan Doherty {
6552950a769SDeclan Doherty 	struct rte_port *port;
6562950a769SDeclan Doherty 
6572950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6582950a769SDeclan Doherty 	port = &ports[new_port_id];
6592950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6602950a769SDeclan Doherty 
6612950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6622950a769SDeclan Doherty 	port->need_reconfig = 1;
6632950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
664a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6652950a769SDeclan Doherty 
6662950a769SDeclan Doherty 	init_port_config();
6672950a769SDeclan Doherty }
6682950a769SDeclan Doherty 
6692950a769SDeclan Doherty 
670ce8d5614SIntel int
671ce8d5614SIntel init_fwd_streams(void)
672ce8d5614SIntel {
673ce8d5614SIntel 	portid_t pid;
674ce8d5614SIntel 	struct rte_port *port;
675ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
676ce8d5614SIntel 
677ce8d5614SIntel 	/* set socket id according to numa or not */
678*edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
679ce8d5614SIntel 		port = &ports[pid];
680ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
681ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
682ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
683ce8d5614SIntel 				port->dev_info.max_rx_queues);
684ce8d5614SIntel 			return -1;
685ce8d5614SIntel 		}
686ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
687ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
688ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
689ce8d5614SIntel 				port->dev_info.max_tx_queues);
690ce8d5614SIntel 			return -1;
691ce8d5614SIntel 		}
69220a0286fSLiu Xiaofeng 		if (numa_support) {
69320a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
69420a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
69520a0286fSLiu Xiaofeng 			else {
696b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
69720a0286fSLiu Xiaofeng 
69820a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
69920a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
70020a0286fSLiu Xiaofeng 					port->socket_id = 0;
70120a0286fSLiu Xiaofeng 			}
70220a0286fSLiu Xiaofeng 		}
703b6ea6408SIntel 		else {
704b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
705af75078fSIntel 				port->socket_id = 0;
706b6ea6408SIntel 			else
707b6ea6408SIntel 				port->socket_id = socket_num;
708b6ea6408SIntel 		}
709af75078fSIntel 	}
710af75078fSIntel 
711ce8d5614SIntel 	nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
712ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
713ce8d5614SIntel 		return 0;
714ce8d5614SIntel 	/* clear the old */
715ce8d5614SIntel 	if (fwd_streams != NULL) {
716ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
717ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
718ce8d5614SIntel 				continue;
719ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
720ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
721af75078fSIntel 		}
722ce8d5614SIntel 		rte_free(fwd_streams);
723ce8d5614SIntel 		fwd_streams = NULL;
724ce8d5614SIntel 	}
725ce8d5614SIntel 
726ce8d5614SIntel 	/* init new */
727ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
728ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
729fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
730ce8d5614SIntel 	if (fwd_streams == NULL)
731ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
732ce8d5614SIntel 						"failed\n", nb_fwd_streams);
733ce8d5614SIntel 
734af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
735af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
736fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
737ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
738ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
739ce8d5614SIntel 								" failed\n");
740af75078fSIntel 	}
741ce8d5614SIntel 
742ce8d5614SIntel 	return 0;
743af75078fSIntel }
744af75078fSIntel 
745af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
746af75078fSIntel static void
747af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
748af75078fSIntel {
749af75078fSIntel 	unsigned int total_burst;
750af75078fSIntel 	unsigned int nb_burst;
751af75078fSIntel 	unsigned int burst_stats[3];
752af75078fSIntel 	uint16_t pktnb_stats[3];
753af75078fSIntel 	uint16_t nb_pkt;
754af75078fSIntel 	int burst_percent[3];
755af75078fSIntel 
756af75078fSIntel 	/*
757af75078fSIntel 	 * First compute the total number of packet bursts and the
758af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
759af75078fSIntel 	 */
760af75078fSIntel 	total_burst = 0;
761af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
762af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
763af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
764af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
765af75078fSIntel 		if (nb_burst == 0)
766af75078fSIntel 			continue;
767af75078fSIntel 		total_burst += nb_burst;
768af75078fSIntel 		if (nb_burst > burst_stats[0]) {
769af75078fSIntel 			burst_stats[1] = burst_stats[0];
770af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
771af75078fSIntel 			burst_stats[0] = nb_burst;
772af75078fSIntel 			pktnb_stats[0] = nb_pkt;
773af75078fSIntel 		}
774af75078fSIntel 	}
775af75078fSIntel 	if (total_burst == 0)
776af75078fSIntel 		return;
777af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
778af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
779af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
780af75078fSIntel 	if (burst_stats[0] == total_burst) {
781af75078fSIntel 		printf("]\n");
782af75078fSIntel 		return;
783af75078fSIntel 	}
784af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
785af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
786af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
787af75078fSIntel 		return;
788af75078fSIntel 	}
789af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
790af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
791af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
792af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
793af75078fSIntel 		return;
794af75078fSIntel 	}
795af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
796af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
797af75078fSIntel }
798af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
799af75078fSIntel 
800af75078fSIntel static void
801af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
802af75078fSIntel {
803af75078fSIntel 	struct rte_port *port;
804013af9b6SIntel 	uint8_t i;
805af75078fSIntel 
806af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
807af75078fSIntel 
808af75078fSIntel 	port = &ports[port_id];
809af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
810af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
811013af9b6SIntel 
812013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
813af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
814af75078fSIntel 		       "%-"PRIu64"\n",
81570bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
81670bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
817af75078fSIntel 
818af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
819af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
820af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
82170bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
82270bdb186SIvan Boule 			printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
82370bdb186SIvan Boule 			       "RX-error: %-"PRIu64"\n",
82470bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
82570bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
82670bdb186SIvan Boule 		}
827af75078fSIntel 
828af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
829af75078fSIntel 		       "%-"PRIu64"\n",
830af75078fSIntel 		       stats->opackets, port->tx_dropped,
831af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
832013af9b6SIntel 	}
833013af9b6SIntel 	else {
834013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
835013af9b6SIntel 		       "%14"PRIu64"\n",
83670bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
83770bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
838013af9b6SIntel 
839013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
840013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
841013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
84270bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
84370bdb186SIvan Boule 			printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
84470bdb186SIvan Boule 			       "    RX-error:%"PRIu64"\n",
84570bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
84670bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
84770bdb186SIvan Boule 			       stats->rx_nombuf);
84870bdb186SIvan Boule 		}
849013af9b6SIntel 
850013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
851013af9b6SIntel 		       "%14"PRIu64"\n",
852013af9b6SIntel 		       stats->opackets, port->tx_dropped,
853013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
854013af9b6SIntel 	}
855e659b6b4SIvan Boule 
856e659b6b4SIvan Boule 	/* Display statistics of XON/XOFF pause frames, if any. */
857e659b6b4SIvan Boule 	if ((stats->tx_pause_xon  | stats->rx_pause_xon |
858e659b6b4SIvan Boule 	     stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
859e659b6b4SIvan Boule 		printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
860e659b6b4SIvan Boule 		       stats->rx_pause_xoff, stats->rx_pause_xon);
861e659b6b4SIvan Boule 		printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
862e659b6b4SIvan Boule 		       stats->tx_pause_xoff, stats->tx_pause_xon);
863e659b6b4SIvan Boule 	}
864e659b6b4SIvan Boule 
865af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
866af75078fSIntel 	if (port->rx_stream)
867013af9b6SIntel 		pkt_burst_stats_display("RX",
868013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
869af75078fSIntel 	if (port->tx_stream)
870013af9b6SIntel 		pkt_burst_stats_display("TX",
871013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
872af75078fSIntel #endif
873af75078fSIntel 	/* stats fdir */
874af75078fSIntel 	if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
875013af9b6SIntel 		printf("  Fdirmiss:%14"PRIu64"	  Fdirmatch:%14"PRIu64"\n",
876af75078fSIntel 		       stats->fdirmiss,
877af75078fSIntel 		       stats->fdirmatch);
878af75078fSIntel 
879013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
880013af9b6SIntel 		printf("\n");
881013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
882013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
883013af9b6SIntel 			       "     RX-errors:%14"PRIu64
884013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
885013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
886013af9b6SIntel 		}
887013af9b6SIntel 		printf("\n");
888013af9b6SIntel 	}
889013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
890013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
891013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
892013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
893013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
894013af9b6SIntel 		}
895013af9b6SIntel 	}
896013af9b6SIntel 
897af75078fSIntel 	printf("  %s--------------------------------%s\n",
898af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
899af75078fSIntel }
900af75078fSIntel 
901af75078fSIntel static void
902af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
903af75078fSIntel {
904af75078fSIntel 	struct fwd_stream *fs;
905af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
906af75078fSIntel 
907af75078fSIntel 	fs = fwd_streams[stream_id];
908af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
909af75078fSIntel 	    (fs->fwd_dropped == 0))
910af75078fSIntel 		return;
911af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
912af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
913af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
914af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
915af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
916af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
917af75078fSIntel 
918af75078fSIntel 	/* if checksum mode */
919af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
920013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
921013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
922af75078fSIntel 	}
923af75078fSIntel 
924af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
925af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
926af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
927af75078fSIntel #endif
928af75078fSIntel }
929af75078fSIntel 
930af75078fSIntel static void
9317741e4cfSIntel flush_fwd_rx_queues(void)
932af75078fSIntel {
933af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
934af75078fSIntel 	portid_t  rxp;
9357741e4cfSIntel 	portid_t port_id;
936af75078fSIntel 	queueid_t rxq;
937af75078fSIntel 	uint16_t  nb_rx;
938af75078fSIntel 	uint16_t  i;
939af75078fSIntel 	uint8_t   j;
940af75078fSIntel 
941af75078fSIntel 	for (j = 0; j < 2; j++) {
9427741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
943af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
9447741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
945af75078fSIntel 				do {
9467741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
947013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
948af75078fSIntel 					for (i = 0; i < nb_rx; i++)
949af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
950af75078fSIntel 				} while (nb_rx > 0);
951af75078fSIntel 			}
952af75078fSIntel 		}
953af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
954af75078fSIntel 	}
955af75078fSIntel }
956af75078fSIntel 
957af75078fSIntel static void
958af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
959af75078fSIntel {
960af75078fSIntel 	struct fwd_stream **fsm;
961af75078fSIntel 	streamid_t nb_fs;
962af75078fSIntel 	streamid_t sm_id;
963af75078fSIntel 
964af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
965af75078fSIntel 	nb_fs = fc->stream_nb;
966af75078fSIntel 	do {
967af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
968af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
969af75078fSIntel 	} while (! fc->stopped);
970af75078fSIntel }
971af75078fSIntel 
972af75078fSIntel static int
973af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
974af75078fSIntel {
975af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
976af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
977af75078fSIntel 	return 0;
978af75078fSIntel }
979af75078fSIntel 
980af75078fSIntel /*
981af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
982af75078fSIntel  * Used to start communication flows in network loopback test configurations.
983af75078fSIntel  */
984af75078fSIntel static int
985af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
986af75078fSIntel {
987af75078fSIntel 	struct fwd_lcore *fwd_lc;
988af75078fSIntel 	struct fwd_lcore tmp_lcore;
989af75078fSIntel 
990af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
991af75078fSIntel 	tmp_lcore = *fwd_lc;
992af75078fSIntel 	tmp_lcore.stopped = 1;
993af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
994af75078fSIntel 	return 0;
995af75078fSIntel }
996af75078fSIntel 
997af75078fSIntel /*
998af75078fSIntel  * Launch packet forwarding:
999af75078fSIntel  *     - Setup per-port forwarding context.
1000af75078fSIntel  *     - launch logical cores with their forwarding configuration.
1001af75078fSIntel  */
1002af75078fSIntel static void
1003af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1004af75078fSIntel {
1005af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1006af75078fSIntel 	unsigned int i;
1007af75078fSIntel 	unsigned int lc_id;
1008af75078fSIntel 	int diag;
1009af75078fSIntel 
1010af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1011af75078fSIntel 	if (port_fwd_begin != NULL) {
1012af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1013af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
1014af75078fSIntel 	}
1015af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1016af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
1017af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1018af75078fSIntel 			fwd_lcores[i]->stopped = 0;
1019af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1020af75078fSIntel 						     fwd_lcores[i], lc_id);
1021af75078fSIntel 			if (diag != 0)
1022af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
1023af75078fSIntel 				       lc_id, diag);
1024af75078fSIntel 		}
1025af75078fSIntel 	}
1026af75078fSIntel }
1027af75078fSIntel 
1028af75078fSIntel /*
1029af75078fSIntel  * Launch packet forwarding configuration.
1030af75078fSIntel  */
1031af75078fSIntel void
1032af75078fSIntel start_packet_forwarding(int with_tx_first)
1033af75078fSIntel {
1034af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1035af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1036af75078fSIntel 	struct rte_port *port;
1037af75078fSIntel 	unsigned int i;
1038af75078fSIntel 	portid_t   pt_id;
1039af75078fSIntel 	streamid_t sm_id;
1040af75078fSIntel 
1041ce8d5614SIntel 	if (all_ports_started() == 0) {
1042ce8d5614SIntel 		printf("Not all ports were started\n");
1043ce8d5614SIntel 		return;
1044ce8d5614SIntel 	}
1045af75078fSIntel 	if (test_done == 0) {
1046af75078fSIntel 		printf("Packet forwarding already started\n");
1047af75078fSIntel 		return;
1048af75078fSIntel 	}
10497741e4cfSIntel 	if(dcb_test) {
10507741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
10517741e4cfSIntel 			pt_id = fwd_ports_ids[i];
10527741e4cfSIntel 			port = &ports[pt_id];
10537741e4cfSIntel 			if (!port->dcb_flag) {
10547741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
10557741e4cfSIntel                                        "be configured in this mode.\n");
1056013af9b6SIntel 				return;
1057013af9b6SIntel 			}
10587741e4cfSIntel 		}
10597741e4cfSIntel 		if (nb_fwd_lcores == 1) {
10607741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
10617741e4cfSIntel                                "should be larger than 1.\n");
10627741e4cfSIntel 			return;
10637741e4cfSIntel 		}
10647741e4cfSIntel 	}
1065af75078fSIntel 	test_done = 0;
10667741e4cfSIntel 
10677741e4cfSIntel 	if(!no_flush_rx)
10687741e4cfSIntel 		flush_fwd_rx_queues();
10697741e4cfSIntel 
1070af75078fSIntel 	fwd_config_setup();
1071af75078fSIntel 	rxtx_config_display();
1072af75078fSIntel 
1073af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1074af75078fSIntel 		pt_id = fwd_ports_ids[i];
1075af75078fSIntel 		port = &ports[pt_id];
1076af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1077af75078fSIntel 		port->tx_dropped = 0;
1078013af9b6SIntel 
1079013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1080af75078fSIntel 	}
1081af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1082af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1083af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1084af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1085af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1086af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1087af75078fSIntel 
1088af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1089af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1090af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1091af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1092af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1093af75078fSIntel #endif
1094af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1095af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1096af75078fSIntel #endif
1097af75078fSIntel 	}
1098af75078fSIntel 	if (with_tx_first) {
1099af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1100af75078fSIntel 		if (port_fwd_begin != NULL) {
1101af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1102af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1103af75078fSIntel 		}
1104af75078fSIntel 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1105af75078fSIntel 		rte_eal_mp_wait_lcore();
1106af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1107af75078fSIntel 		if (port_fwd_end != NULL) {
1108af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1109af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1110af75078fSIntel 		}
1111af75078fSIntel 	}
1112af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1113af75078fSIntel }
1114af75078fSIntel 
1115af75078fSIntel void
1116af75078fSIntel stop_packet_forwarding(void)
1117af75078fSIntel {
1118af75078fSIntel 	struct rte_eth_stats stats;
1119af75078fSIntel 	struct rte_port *port;
1120af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1121af75078fSIntel 	int i;
1122af75078fSIntel 	portid_t   pt_id;
1123af75078fSIntel 	streamid_t sm_id;
1124af75078fSIntel 	lcoreid_t  lc_id;
1125af75078fSIntel 	uint64_t total_recv;
1126af75078fSIntel 	uint64_t total_xmit;
1127af75078fSIntel 	uint64_t total_rx_dropped;
1128af75078fSIntel 	uint64_t total_tx_dropped;
1129af75078fSIntel 	uint64_t total_rx_nombuf;
1130af75078fSIntel 	uint64_t tx_dropped;
1131af75078fSIntel 	uint64_t rx_bad_ip_csum;
1132af75078fSIntel 	uint64_t rx_bad_l4_csum;
1133af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1134af75078fSIntel 	uint64_t fwd_cycles;
1135af75078fSIntel #endif
1136af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1137af75078fSIntel 
1138ce8d5614SIntel 	if (all_ports_started() == 0) {
1139ce8d5614SIntel 		printf("Not all ports were started\n");
1140ce8d5614SIntel 		return;
1141ce8d5614SIntel 	}
1142af75078fSIntel 	if (test_done) {
1143af75078fSIntel 		printf("Packet forwarding not started\n");
1144af75078fSIntel 		return;
1145af75078fSIntel 	}
1146af75078fSIntel 	printf("Telling cores to stop...");
1147af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1148af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1149af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1150af75078fSIntel 	rte_eal_mp_wait_lcore();
1151af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1152af75078fSIntel 	if (port_fwd_end != NULL) {
1153af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1154af75078fSIntel 			pt_id = fwd_ports_ids[i];
1155af75078fSIntel 			(*port_fwd_end)(pt_id);
1156af75078fSIntel 		}
1157af75078fSIntel 	}
1158af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1159af75078fSIntel 	fwd_cycles = 0;
1160af75078fSIntel #endif
1161af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1162af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1163af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1164af75078fSIntel 			fwd_stream_stats_display(sm_id);
1165af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1166af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1167af75078fSIntel 		} else {
1168af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1169af75078fSIntel 				fwd_streams[sm_id];
1170af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1171af75078fSIntel 				fwd_streams[sm_id];
1172af75078fSIntel 		}
1173af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1174af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1175af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1176af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1177af75078fSIntel 
1178013af9b6SIntel 		rx_bad_ip_csum =
1179013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1180af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1181af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1182013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1183013af9b6SIntel 							rx_bad_ip_csum;
1184af75078fSIntel 
1185013af9b6SIntel 		rx_bad_l4_csum =
1186013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1187af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1188af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1189013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1190013af9b6SIntel 							rx_bad_l4_csum;
1191af75078fSIntel 
1192af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1193af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1194af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1195af75078fSIntel #endif
1196af75078fSIntel 	}
1197af75078fSIntel 	total_recv = 0;
1198af75078fSIntel 	total_xmit = 0;
1199af75078fSIntel 	total_rx_dropped = 0;
1200af75078fSIntel 	total_tx_dropped = 0;
1201af75078fSIntel 	total_rx_nombuf  = 0;
12027741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1203af75078fSIntel 		pt_id = fwd_ports_ids[i];
1204af75078fSIntel 
1205af75078fSIntel 		port = &ports[pt_id];
1206af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1207af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1208af75078fSIntel 		port->stats.ipackets = 0;
1209af75078fSIntel 		stats.opackets -= port->stats.opackets;
1210af75078fSIntel 		port->stats.opackets = 0;
1211af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1212af75078fSIntel 		port->stats.ibytes = 0;
1213af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1214af75078fSIntel 		port->stats.obytes = 0;
121570bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
121670bdb186SIvan Boule 		port->stats.imissed = 0;
1217af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1218af75078fSIntel 		port->stats.oerrors = 0;
1219af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1220af75078fSIntel 		port->stats.rx_nombuf = 0;
1221af75078fSIntel 		stats.fdirmatch -= port->stats.fdirmatch;
1222af75078fSIntel 		port->stats.rx_nombuf = 0;
1223af75078fSIntel 		stats.fdirmiss -= port->stats.fdirmiss;
1224af75078fSIntel 		port->stats.rx_nombuf = 0;
1225af75078fSIntel 
1226af75078fSIntel 		total_recv += stats.ipackets;
1227af75078fSIntel 		total_xmit += stats.opackets;
122870bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1229af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1230af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1231af75078fSIntel 
1232af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1233af75078fSIntel 	}
1234af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1235af75078fSIntel 	       "%s\n",
1236af75078fSIntel 	       acc_stats_border, acc_stats_border);
1237af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1238af75078fSIntel 	       "%-"PRIu64"\n"
1239af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1240af75078fSIntel 	       "%-"PRIu64"\n",
1241af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1242af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1243af75078fSIntel 	if (total_rx_nombuf > 0)
1244af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1245af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1246af75078fSIntel 	       "%s\n",
1247af75078fSIntel 	       acc_stats_border, acc_stats_border);
1248af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1249af75078fSIntel 	if (total_recv > 0)
1250af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1251af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1252af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1253af75078fSIntel 		       fwd_cycles, total_recv);
1254af75078fSIntel #endif
1255af75078fSIntel 	printf("\nDone.\n");
1256af75078fSIntel 	test_done = 1;
1257af75078fSIntel }
1258af75078fSIntel 
1259cfae07fdSOuyang Changchun void
1260cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1261cfae07fdSOuyang Changchun {
1262cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1263cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1264cfae07fdSOuyang Changchun }
1265cfae07fdSOuyang Changchun 
1266cfae07fdSOuyang Changchun void
1267cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1268cfae07fdSOuyang Changchun {
1269cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1270cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1271cfae07fdSOuyang Changchun }
1272cfae07fdSOuyang Changchun 
1273ce8d5614SIntel static int
1274ce8d5614SIntel all_ports_started(void)
1275ce8d5614SIntel {
1276ce8d5614SIntel 	portid_t pi;
1277ce8d5614SIntel 	struct rte_port *port;
1278ce8d5614SIntel 
1279*edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1280ce8d5614SIntel 		port = &ports[pi];
1281ce8d5614SIntel 		/* Check if there is a port which is not started */
1282ce8d5614SIntel 		if (port->port_status != RTE_PORT_STARTED)
1283ce8d5614SIntel 			return 0;
1284ce8d5614SIntel 	}
1285ce8d5614SIntel 
1286ce8d5614SIntel 	/* No port is not started */
1287ce8d5614SIntel 	return 1;
1288ce8d5614SIntel }
1289ce8d5614SIntel 
1290148f963fSBruce Richardson int
1291*edab33b1STetsuya Mukawa all_ports_stopped(void)
1292*edab33b1STetsuya Mukawa {
1293*edab33b1STetsuya Mukawa 	portid_t pi;
1294*edab33b1STetsuya Mukawa 	struct rte_port *port;
1295*edab33b1STetsuya Mukawa 
1296*edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1297*edab33b1STetsuya Mukawa 		port = &ports[pi];
1298*edab33b1STetsuya Mukawa 		if (port->port_status != RTE_PORT_STOPPED)
1299*edab33b1STetsuya Mukawa 			return 0;
1300*edab33b1STetsuya Mukawa 	}
1301*edab33b1STetsuya Mukawa 
1302*edab33b1STetsuya Mukawa 	return 1;
1303*edab33b1STetsuya Mukawa }
1304*edab33b1STetsuya Mukawa 
1305*edab33b1STetsuya Mukawa int
1306*edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1307*edab33b1STetsuya Mukawa {
1308*edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1309*edab33b1STetsuya Mukawa 		return 0;
1310*edab33b1STetsuya Mukawa 
1311*edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1312*edab33b1STetsuya Mukawa 		return 0;
1313*edab33b1STetsuya Mukawa 
1314*edab33b1STetsuya Mukawa 	return 1;
1315*edab33b1STetsuya Mukawa }
1316*edab33b1STetsuya Mukawa 
1317*edab33b1STetsuya Mukawa static int
1318*edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1319*edab33b1STetsuya Mukawa {
1320*edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1321*edab33b1STetsuya Mukawa 		return 0;
1322*edab33b1STetsuya Mukawa 
1323*edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1324*edab33b1STetsuya Mukawa 		return 0;
1325*edab33b1STetsuya Mukawa 
1326*edab33b1STetsuya Mukawa 	return 1;
1327*edab33b1STetsuya Mukawa }
1328*edab33b1STetsuya Mukawa 
1329*edab33b1STetsuya Mukawa int
1330ce8d5614SIntel start_port(portid_t pid)
1331ce8d5614SIntel {
1332ce8d5614SIntel 	int diag, need_check_link_status = 0;
1333ce8d5614SIntel 	portid_t pi;
1334ce8d5614SIntel 	queueid_t qi;
1335ce8d5614SIntel 	struct rte_port *port;
13362950a769SDeclan Doherty 	struct ether_addr mac_addr;
1337ce8d5614SIntel 
1338ce8d5614SIntel 	if (test_done == 0) {
1339ce8d5614SIntel 		printf("Please stop forwarding first\n");
1340148f963fSBruce Richardson 		return -1;
1341ce8d5614SIntel 	}
1342ce8d5614SIntel 
1343ce8d5614SIntel 	if (init_fwd_streams() < 0) {
1344ce8d5614SIntel 		printf("Fail from init_fwd_streams()\n");
1345148f963fSBruce Richardson 		return -1;
1346ce8d5614SIntel 	}
1347ce8d5614SIntel 
1348ce8d5614SIntel 	if(dcb_config)
1349ce8d5614SIntel 		dcb_test = 1;
1350*edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1351*edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1352ce8d5614SIntel 			continue;
1353ce8d5614SIntel 
1354ce8d5614SIntel 		port = &ports[pi];
1355ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1356ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1357ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1358ce8d5614SIntel 			continue;
1359ce8d5614SIntel 		}
1360ce8d5614SIntel 
1361ce8d5614SIntel 		if (port->need_reconfig > 0) {
1362ce8d5614SIntel 			port->need_reconfig = 0;
1363ce8d5614SIntel 
13645706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
136520a0286fSLiu Xiaofeng 					port->socket_id);
1366ce8d5614SIntel 			/* configure port */
1367ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1368ce8d5614SIntel 						&(port->dev_conf));
1369ce8d5614SIntel 			if (diag != 0) {
1370ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1371ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1372ce8d5614SIntel 					printf("Port %d can not be set back "
1373ce8d5614SIntel 							"to stopped\n", pi);
1374ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1375ce8d5614SIntel 				/* try to reconfigure port next time */
1376ce8d5614SIntel 				port->need_reconfig = 1;
1377148f963fSBruce Richardson 				return -1;
1378ce8d5614SIntel 			}
1379ce8d5614SIntel 		}
1380ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1381ce8d5614SIntel 			port->need_reconfig_queues = 0;
1382ce8d5614SIntel 			/* setup tx queues */
1383ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1384b6ea6408SIntel 				if ((numa_support) &&
1385b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1386b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1387b6ea6408SIntel 						nb_txd,txring_numa[pi],
1388b6ea6408SIntel 						&(port->tx_conf));
1389b6ea6408SIntel 				else
1390b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1391b6ea6408SIntel 						nb_txd,port->socket_id,
1392b6ea6408SIntel 						&(port->tx_conf));
1393b6ea6408SIntel 
1394ce8d5614SIntel 				if (diag == 0)
1395ce8d5614SIntel 					continue;
1396ce8d5614SIntel 
1397ce8d5614SIntel 				/* Fail to setup tx queue, return */
1398ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1399ce8d5614SIntel 							RTE_PORT_HANDLING,
1400ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1401ce8d5614SIntel 					printf("Port %d can not be set back "
1402ce8d5614SIntel 							"to stopped\n", pi);
1403ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1404ce8d5614SIntel 				/* try to reconfigure queues next time */
1405ce8d5614SIntel 				port->need_reconfig_queues = 1;
1406148f963fSBruce Richardson 				return -1;
1407ce8d5614SIntel 			}
1408ce8d5614SIntel 			/* setup rx queues */
1409ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1410b6ea6408SIntel 				if ((numa_support) &&
1411b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1412b6ea6408SIntel 					struct rte_mempool * mp =
1413b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1414b6ea6408SIntel 					if (mp == NULL) {
1415b6ea6408SIntel 						printf("Failed to setup RX queue:"
1416b6ea6408SIntel 							"No mempool allocation"
1417b6ea6408SIntel 							"on the socket %d\n",
1418b6ea6408SIntel 							rxring_numa[pi]);
1419148f963fSBruce Richardson 						return -1;
1420b6ea6408SIntel 					}
1421b6ea6408SIntel 
1422b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1423b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1424b6ea6408SIntel 					     &(port->rx_conf),mp);
1425b6ea6408SIntel 				}
1426b6ea6408SIntel 				else
1427b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1428b6ea6408SIntel 					     nb_rxd,port->socket_id,
1429b6ea6408SIntel 					     &(port->rx_conf),
1430ce8d5614SIntel 				             mbuf_pool_find(port->socket_id));
1431b6ea6408SIntel 
1432ce8d5614SIntel 				if (diag == 0)
1433ce8d5614SIntel 					continue;
1434ce8d5614SIntel 
1435b6ea6408SIntel 
1436ce8d5614SIntel 				/* Fail to setup rx queue, return */
1437ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1438ce8d5614SIntel 							RTE_PORT_HANDLING,
1439ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1440ce8d5614SIntel 					printf("Port %d can not be set back "
1441ce8d5614SIntel 							"to stopped\n", pi);
1442ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1443ce8d5614SIntel 				/* try to reconfigure queues next time */
1444ce8d5614SIntel 				port->need_reconfig_queues = 1;
1445148f963fSBruce Richardson 				return -1;
1446ce8d5614SIntel 			}
1447ce8d5614SIntel 		}
1448ce8d5614SIntel 		/* start port */
1449ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1450ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1451ce8d5614SIntel 
1452ce8d5614SIntel 			/* Fail to setup rx queue, return */
1453ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1454ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1455ce8d5614SIntel 				printf("Port %d can not be set back to "
1456ce8d5614SIntel 							"stopped\n", pi);
1457ce8d5614SIntel 			continue;
1458ce8d5614SIntel 		}
1459ce8d5614SIntel 
1460ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1461ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1462ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1463ce8d5614SIntel 
14642950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1465d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
14662950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
14672950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
14682950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1469d8c89163SZijie Pan 
1470ce8d5614SIntel 		/* at least one port started, need checking link status */
1471ce8d5614SIntel 		need_check_link_status = 1;
1472ce8d5614SIntel 	}
1473ce8d5614SIntel 
1474bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1475*edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1476ce8d5614SIntel 	else
1477ce8d5614SIntel 		printf("Please stop the ports first\n");
1478ce8d5614SIntel 
1479ce8d5614SIntel 	printf("Done\n");
1480148f963fSBruce Richardson 	return 0;
1481ce8d5614SIntel }
1482ce8d5614SIntel 
1483ce8d5614SIntel void
1484ce8d5614SIntel stop_port(portid_t pid)
1485ce8d5614SIntel {
1486ce8d5614SIntel 	portid_t pi;
1487ce8d5614SIntel 	struct rte_port *port;
1488ce8d5614SIntel 	int need_check_link_status = 0;
1489ce8d5614SIntel 
1490ce8d5614SIntel 	if (test_done == 0) {
1491ce8d5614SIntel 		printf("Please stop forwarding first\n");
1492ce8d5614SIntel 		return;
1493ce8d5614SIntel 	}
1494ce8d5614SIntel 	if (dcb_test) {
1495ce8d5614SIntel 		dcb_test = 0;
1496ce8d5614SIntel 		dcb_config = 0;
1497ce8d5614SIntel 	}
1498ce8d5614SIntel 	printf("Stopping ports...\n");
1499ce8d5614SIntel 
1500*edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1501*edab33b1STetsuya Mukawa 		if (!port_id_is_invalid(pid, DISABLED_WARN) && pid != pi)
1502ce8d5614SIntel 			continue;
1503ce8d5614SIntel 
1504ce8d5614SIntel 		port = &ports[pi];
1505ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1506ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1507ce8d5614SIntel 			continue;
1508ce8d5614SIntel 
1509ce8d5614SIntel 		rte_eth_dev_stop(pi);
1510ce8d5614SIntel 
1511ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1512ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1513ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1514ce8d5614SIntel 		need_check_link_status = 1;
1515ce8d5614SIntel 	}
1516bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1517*edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1518ce8d5614SIntel 
1519ce8d5614SIntel 	printf("Done\n");
1520ce8d5614SIntel }
1521ce8d5614SIntel 
1522ce8d5614SIntel void
1523ce8d5614SIntel close_port(portid_t pid)
1524ce8d5614SIntel {
1525ce8d5614SIntel 	portid_t pi;
1526ce8d5614SIntel 	struct rte_port *port;
1527ce8d5614SIntel 
1528ce8d5614SIntel 	if (test_done == 0) {
1529ce8d5614SIntel 		printf("Please stop forwarding first\n");
1530ce8d5614SIntel 		return;
1531ce8d5614SIntel 	}
1532ce8d5614SIntel 
1533ce8d5614SIntel 	printf("Closing ports...\n");
1534ce8d5614SIntel 
1535*edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1536*edab33b1STetsuya Mukawa 		if (!port_id_is_invalid(pid, DISABLED_WARN) && pid != pi)
1537ce8d5614SIntel 			continue;
1538ce8d5614SIntel 
1539ce8d5614SIntel 		port = &ports[pi];
1540ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1541ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1542ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1543ce8d5614SIntel 			continue;
1544ce8d5614SIntel 		}
1545ce8d5614SIntel 
1546ce8d5614SIntel 		rte_eth_dev_close(pi);
1547ce8d5614SIntel 
1548ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1549ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1550ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1551ce8d5614SIntel 	}
1552ce8d5614SIntel 
1553ce8d5614SIntel 	printf("Done\n");
1554ce8d5614SIntel }
1555ce8d5614SIntel 
1556*edab33b1STetsuya Mukawa void
1557*edab33b1STetsuya Mukawa attach_port(char *identifier)
1558ce8d5614SIntel {
1559*edab33b1STetsuya Mukawa 	portid_t i, j, pi = 0;
1560ce8d5614SIntel 
1561*edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1562*edab33b1STetsuya Mukawa 
1563*edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1564*edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1565*edab33b1STetsuya Mukawa 		return;
1566ce8d5614SIntel 	}
1567ce8d5614SIntel 
1568*edab33b1STetsuya Mukawa 	if (test_done == 0) {
1569*edab33b1STetsuya Mukawa 		printf("Please stop forwarding first\n");
1570*edab33b1STetsuya Mukawa 		return;
1571ce8d5614SIntel 	}
1572ce8d5614SIntel 
1573*edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1574*edab33b1STetsuya Mukawa 		return;
1575*edab33b1STetsuya Mukawa 
1576*edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1577*edab33b1STetsuya Mukawa 	reconfig(pi, rte_eth_dev_socket_id(pi));
1578*edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1579*edab33b1STetsuya Mukawa 
1580*edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1581*edab33b1STetsuya Mukawa 
1582*edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1583*edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1584*edab33b1STetsuya Mukawa 	i = 0;
1585*edab33b1STetsuya Mukawa 	FOREACH_PORT(j, ports) {
1586*edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = j;
1587*edab33b1STetsuya Mukawa 		i++;
1588*edab33b1STetsuya Mukawa 	}
1589*edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1590*edab33b1STetsuya Mukawa 	nb_fwd_ports++;
1591*edab33b1STetsuya Mukawa 
1592*edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1593*edab33b1STetsuya Mukawa 
1594*edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1595*edab33b1STetsuya Mukawa 	printf("Done\n");
1596*edab33b1STetsuya Mukawa }
1597*edab33b1STetsuya Mukawa 
1598*edab33b1STetsuya Mukawa void
1599*edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
16005f4ec54fSChen Jing D(Mark) {
1601*edab33b1STetsuya Mukawa 	portid_t i, pi = 0;
1602*edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
16035f4ec54fSChen Jing D(Mark) 
1604*edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
16055f4ec54fSChen Jing D(Mark) 
1606*edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1607*edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1608*edab33b1STetsuya Mukawa 		return;
1609*edab33b1STetsuya Mukawa 	}
1610*edab33b1STetsuya Mukawa 
1611*edab33b1STetsuya Mukawa 	rte_eth_promiscuous_disable(port_id);
1612*edab33b1STetsuya Mukawa 
1613*edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1614*edab33b1STetsuya Mukawa 		return;
1615*edab33b1STetsuya Mukawa 
1616*edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1617*edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1618*edab33b1STetsuya Mukawa 
1619*edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1620*edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1621*edab33b1STetsuya Mukawa 	i = 0;
1622*edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1623*edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = pi;
1624*edab33b1STetsuya Mukawa 		i++;
1625*edab33b1STetsuya Mukawa 	}
1626*edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1627*edab33b1STetsuya Mukawa 	nb_fwd_ports--;
1628*edab33b1STetsuya Mukawa 
1629*edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1630*edab33b1STetsuya Mukawa 			name, nb_ports);
1631*edab33b1STetsuya Mukawa 	printf("Done\n");
1632*edab33b1STetsuya Mukawa 	return;
16335f4ec54fSChen Jing D(Mark) }
16345f4ec54fSChen Jing D(Mark) 
1635af75078fSIntel void
1636af75078fSIntel pmd_test_exit(void)
1637af75078fSIntel {
1638af75078fSIntel 	portid_t pt_id;
1639af75078fSIntel 
1640*edab33b1STetsuya Mukawa 	FOREACH_PORT(pt_id, ports) {
1641af75078fSIntel 		printf("Stopping port %d...", pt_id);
1642af75078fSIntel 		fflush(stdout);
1643af75078fSIntel 		rte_eth_dev_close(pt_id);
1644af75078fSIntel 		printf("done\n");
1645af75078fSIntel 	}
1646af75078fSIntel 	printf("bye...\n");
1647af75078fSIntel }
1648af75078fSIntel 
1649af75078fSIntel typedef void (*cmd_func_t)(void);
1650af75078fSIntel struct pmd_test_command {
1651af75078fSIntel 	const char *cmd_name;
1652af75078fSIntel 	cmd_func_t cmd_func;
1653af75078fSIntel };
1654af75078fSIntel 
1655af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1656af75078fSIntel 
1657ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1658af75078fSIntel static void
1659*edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1660af75078fSIntel {
1661ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1662ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1663ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1664ce8d5614SIntel 	struct rte_eth_link link;
1665ce8d5614SIntel 
1666ce8d5614SIntel 	printf("Checking link statuses...\n");
1667ce8d5614SIntel 	fflush(stdout);
1668ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1669ce8d5614SIntel 		all_ports_up = 1;
1670*edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1671ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1672ce8d5614SIntel 				continue;
1673ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1674ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1675ce8d5614SIntel 			/* print link status if flag set */
1676ce8d5614SIntel 			if (print_flag == 1) {
1677ce8d5614SIntel 				if (link.link_status)
1678ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1679ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1680ce8d5614SIntel 						(unsigned)link.link_speed,
1681ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1682ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1683ce8d5614SIntel 				else
1684ce8d5614SIntel 					printf("Port %d Link Down\n",
1685ce8d5614SIntel 						(uint8_t)portid);
1686ce8d5614SIntel 				continue;
1687ce8d5614SIntel 			}
1688ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
1689ce8d5614SIntel 			if (link.link_status == 0) {
1690ce8d5614SIntel 				all_ports_up = 0;
1691ce8d5614SIntel 				break;
1692ce8d5614SIntel 			}
1693ce8d5614SIntel 		}
1694ce8d5614SIntel 		/* after finally printing all link status, get out */
1695ce8d5614SIntel 		if (print_flag == 1)
1696ce8d5614SIntel 			break;
1697ce8d5614SIntel 
1698ce8d5614SIntel 		if (all_ports_up == 0) {
1699ce8d5614SIntel 			fflush(stdout);
1700ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1701ce8d5614SIntel 		}
1702ce8d5614SIntel 
1703ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1704ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1705ce8d5614SIntel 			print_flag = 1;
1706ce8d5614SIntel 		}
1707ce8d5614SIntel 	}
1708af75078fSIntel }
1709af75078fSIntel 
1710013af9b6SIntel static int
1711013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1712af75078fSIntel {
1713013af9b6SIntel 	uint16_t i;
1714af75078fSIntel 	int diag;
1715013af9b6SIntel 	uint8_t mapping_found = 0;
1716af75078fSIntel 
1717013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1718013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1719013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1720013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1721013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1722013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1723013af9b6SIntel 			if (diag != 0)
1724013af9b6SIntel 				return diag;
1725013af9b6SIntel 			mapping_found = 1;
1726af75078fSIntel 		}
1727013af9b6SIntel 	}
1728013af9b6SIntel 	if (mapping_found)
1729013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1730013af9b6SIntel 	return 0;
1731013af9b6SIntel }
1732013af9b6SIntel 
1733013af9b6SIntel static int
1734013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1735013af9b6SIntel {
1736013af9b6SIntel 	uint16_t i;
1737013af9b6SIntel 	int diag;
1738013af9b6SIntel 	uint8_t mapping_found = 0;
1739013af9b6SIntel 
1740013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1741013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1742013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1743013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1744013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1745013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1746013af9b6SIntel 			if (diag != 0)
1747013af9b6SIntel 				return diag;
1748013af9b6SIntel 			mapping_found = 1;
1749013af9b6SIntel 		}
1750013af9b6SIntel 	}
1751013af9b6SIntel 	if (mapping_found)
1752013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1753013af9b6SIntel 	return 0;
1754013af9b6SIntel }
1755013af9b6SIntel 
1756013af9b6SIntel static void
1757013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1758013af9b6SIntel {
1759013af9b6SIntel 	int diag = 0;
1760013af9b6SIntel 
1761013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1762af75078fSIntel 	if (diag != 0) {
1763013af9b6SIntel 		if (diag == -ENOTSUP) {
1764013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1765013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1766013af9b6SIntel 		}
1767013af9b6SIntel 		else
1768013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1769013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1770013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1771af75078fSIntel 					pi, diag);
1772af75078fSIntel 	}
1773013af9b6SIntel 
1774013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1775af75078fSIntel 	if (diag != 0) {
1776013af9b6SIntel 		if (diag == -ENOTSUP) {
1777013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1778013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1779013af9b6SIntel 		}
1780013af9b6SIntel 		else
1781013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1782013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1783013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1784af75078fSIntel 					pi, diag);
1785af75078fSIntel 	}
1786af75078fSIntel }
1787af75078fSIntel 
1788f2c5125aSPablo de Lara static void
1789f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1790f2c5125aSPablo de Lara {
1791f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1792f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1793f2c5125aSPablo de Lara 
1794f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1795f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1796f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1797f2c5125aSPablo de Lara 
1798f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1799f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1800f2c5125aSPablo de Lara 
1801f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1802f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1803f2c5125aSPablo de Lara 
1804f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1805f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1806f2c5125aSPablo de Lara 
1807f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1808f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1809f2c5125aSPablo de Lara 
1810f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1811f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1812f2c5125aSPablo de Lara 
1813f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1814f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1815f2c5125aSPablo de Lara 
1816f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1817f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1818f2c5125aSPablo de Lara 
1819f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1820f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1821f2c5125aSPablo de Lara 
1822f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1823f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1824f2c5125aSPablo de Lara 
1825f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1826f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1827f2c5125aSPablo de Lara }
1828f2c5125aSPablo de Lara 
1829013af9b6SIntel void
1830013af9b6SIntel init_port_config(void)
1831013af9b6SIntel {
1832013af9b6SIntel 	portid_t pid;
1833013af9b6SIntel 	struct rte_port *port;
1834013af9b6SIntel 
1835*edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1836013af9b6SIntel 		port = &ports[pid];
1837013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1838013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
18393ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1840013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1841013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1842af75078fSIntel 		} else {
1843013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1844013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1845af75078fSIntel 		}
18463ce690d3SBruce Richardson 
18473ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
18483ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
18493ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
18503ce690d3SBruce Richardson 			else
18513ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
18523ce690d3SBruce Richardson 		}
18533ce690d3SBruce Richardson 
1854a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1855a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1856a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1857a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1858a30979f6SOuyang Changchun 			else
1859a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1860a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1861a30979f6SOuyang Changchun 
1862a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1863a30979f6SOuyang Changchun 		}
1864a30979f6SOuyang Changchun 
1865f2c5125aSPablo de Lara 		rxtx_port_config(port);
1866013af9b6SIntel 
1867013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1868013af9b6SIntel 
1869013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18707b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18717b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18727b7e5ba7SIntel #endif
1873013af9b6SIntel 	}
1874013af9b6SIntel }
1875013af9b6SIntel 
1876013af9b6SIntel const uint16_t vlan_tags[] = {
1877013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1878013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1879013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1880013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1881013af9b6SIntel };
1882013af9b6SIntel 
1883013af9b6SIntel static  int
1884013af9b6SIntel get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1885013af9b6SIntel {
1886013af9b6SIntel         uint8_t i;
1887af75078fSIntel 
1888af75078fSIntel  	/*
1889013af9b6SIntel  	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1890013af9b6SIntel  	 * given above, and the number of traffic classes available for use.
1891af75078fSIntel  	 */
1892013af9b6SIntel 	if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1893013af9b6SIntel 		struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1894013af9b6SIntel 		struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1895013af9b6SIntel 
1896013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
1897013af9b6SIntel 		vmdq_rx_conf.enable_default_pool = 0;
1898013af9b6SIntel 		vmdq_rx_conf.default_pool = 0;
1899013af9b6SIntel 		vmdq_rx_conf.nb_queue_pools =
1900013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1901013af9b6SIntel 		vmdq_tx_conf.nb_queue_pools =
1902013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1903013af9b6SIntel 
1904013af9b6SIntel 		vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1905013af9b6SIntel 		for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1906013af9b6SIntel 			vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1907013af9b6SIntel 			vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1908af75078fSIntel 		}
1909013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1910013af9b6SIntel 			vmdq_rx_conf.dcb_queue[i] = i;
1911013af9b6SIntel 			vmdq_tx_conf.dcb_queue[i] = i;
1912013af9b6SIntel 		}
1913013af9b6SIntel 
1914013af9b6SIntel 		/*set DCB mode of RX and TX of multiple queues*/
191532e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
191632e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1917013af9b6SIntel 		if (dcb_conf->pfc_en)
1918013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1919013af9b6SIntel 		else
1920013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1921013af9b6SIntel 
1922013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1923013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1924013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1925013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1926013af9b6SIntel 	}
1927013af9b6SIntel 	else {
1928013af9b6SIntel 		struct rte_eth_dcb_rx_conf rx_conf;
1929013af9b6SIntel 		struct rte_eth_dcb_tx_conf tx_conf;
1930013af9b6SIntel 
1931013af9b6SIntel 		/* queue mapping configuration of DCB RX and TX */
1932013af9b6SIntel 		if (dcb_conf->num_tcs == ETH_4_TCS)
1933013af9b6SIntel 			dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1934013af9b6SIntel 		else
1935013af9b6SIntel 			dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1936013af9b6SIntel 
1937013af9b6SIntel 		rx_conf.nb_tcs = dcb_conf->num_tcs;
1938013af9b6SIntel 		tx_conf.nb_tcs = dcb_conf->num_tcs;
1939013af9b6SIntel 
1940013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1941013af9b6SIntel 			rx_conf.dcb_queue[i] = i;
1942013af9b6SIntel 			tx_conf.dcb_queue[i] = i;
1943013af9b6SIntel 		}
194432e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
194532e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1946013af9b6SIntel 		if (dcb_conf->pfc_en)
1947013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1948013af9b6SIntel 		else
1949013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1950013af9b6SIntel 
1951013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1952013af9b6SIntel                                 sizeof(struct rte_eth_dcb_rx_conf)));
1953013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1954013af9b6SIntel                                 sizeof(struct rte_eth_dcb_tx_conf)));
1955013af9b6SIntel 	}
1956013af9b6SIntel 
1957013af9b6SIntel 	return 0;
1958013af9b6SIntel }
1959013af9b6SIntel 
1960013af9b6SIntel int
1961013af9b6SIntel init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1962013af9b6SIntel {
1963013af9b6SIntel 	struct rte_eth_conf port_conf;
1964013af9b6SIntel 	struct rte_port *rte_port;
1965013af9b6SIntel 	int retval;
1966013af9b6SIntel 	uint16_t nb_vlan;
1967013af9b6SIntel 	uint16_t i;
1968013af9b6SIntel 
1969013af9b6SIntel 	/* rxq and txq configuration in dcb mode */
1970013af9b6SIntel 	nb_rxq = 128;
1971013af9b6SIntel 	nb_txq = 128;
1972013af9b6SIntel 	rx_free_thresh = 64;
1973013af9b6SIntel 
1974013af9b6SIntel 	memset(&port_conf,0,sizeof(struct rte_eth_conf));
1975013af9b6SIntel 	/* Enter DCB configuration status */
1976013af9b6SIntel 	dcb_config = 1;
1977013af9b6SIntel 
1978013af9b6SIntel 	nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1979013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
1980013af9b6SIntel 	retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1981013af9b6SIntel 	if (retval < 0)
1982013af9b6SIntel 		return retval;
1983013af9b6SIntel 
1984013af9b6SIntel 	rte_port = &ports[pid];
1985013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1986013af9b6SIntel 
1987f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
1988013af9b6SIntel 	/* VLAN filter */
1989013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1990013af9b6SIntel 	for (i = 0; i < nb_vlan; i++){
1991013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1992013af9b6SIntel 	}
1993013af9b6SIntel 
1994013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1995013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1996013af9b6SIntel 
19977741e4cfSIntel 	rte_port->dcb_flag = 1;
19987741e4cfSIntel 
1999013af9b6SIntel 	return 0;
2000af75078fSIntel }
2001af75078fSIntel 
2002af75078fSIntel int
2003af75078fSIntel main(int argc, char** argv)
2004af75078fSIntel {
2005af75078fSIntel 	int  diag;
2006013af9b6SIntel 	uint8_t port_id;
2007af75078fSIntel 
2008af75078fSIntel 	diag = rte_eal_init(argc, argv);
2009af75078fSIntel 	if (diag < 0)
2010af75078fSIntel 		rte_panic("Cannot init EAL\n");
2011af75078fSIntel 
2012af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2013af75078fSIntel 	if (nb_ports == 0)
2014*edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2015af75078fSIntel 
2016af75078fSIntel 	set_def_fwd_config();
2017af75078fSIntel 	if (nb_lcores == 0)
2018af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2019af75078fSIntel 			  "core mask supplied in the command parameters\n");
2020af75078fSIntel 
2021af75078fSIntel 	argc -= diag;
2022af75078fSIntel 	argv += diag;
2023af75078fSIntel 	if (argc > 1)
2024af75078fSIntel 		launch_args_parse(argc, argv);
2025af75078fSIntel 
2026af75078fSIntel 	if (nb_rxq > nb_txq)
2027af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2028af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2029af75078fSIntel 		       nb_rxq, nb_txq);
2030af75078fSIntel 
2031af75078fSIntel 	init_config();
2032148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2033148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2034af75078fSIntel 
2035ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
2036*edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
2037ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2038af75078fSIntel 
20390d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2040ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2041ca7feb22SCyril Chemparathy 		if (auto_start) {
2042ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2043ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2044ca7feb22SCyril Chemparathy 		}
2045af75078fSIntel 		prompt();
2046ca7feb22SCyril Chemparathy 	} else
20470d56cb81SThomas Monjalon #endif
20480d56cb81SThomas Monjalon 	{
2049af75078fSIntel 		char c;
2050af75078fSIntel 		int rc;
2051af75078fSIntel 
2052af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2053af75078fSIntel 		start_packet_forwarding(0);
2054af75078fSIntel 		printf("Press enter to exit\n");
2055af75078fSIntel 		rc = read(0, &c, 1);
2056af75078fSIntel 		if (rc < 0)
2057af75078fSIntel 			return 1;
2058af75078fSIntel 	}
2059af75078fSIntel 
2060af75078fSIntel 	return 0;
2061af75078fSIntel }
2062