xref: /dpdk/app/test-pmd/testpmd.c (revision cfae07fdaa3e71ca9fafbc3e22fcf66d2f97e9ba)
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>
74af75078fSIntel #include <rte_string_fns.h>
75148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
76148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
77148f963fSBruce Richardson #endif
78af75078fSIntel 
79af75078fSIntel #include "testpmd.h"
80148f963fSBruce Richardson #include "mempool_osdep.h"
81af75078fSIntel 
82af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
83af75078fSIntel 
84af75078fSIntel /* use master core for command line ? */
85af75078fSIntel uint8_t interactive = 0;
86ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
87af75078fSIntel 
88af75078fSIntel /*
89af75078fSIntel  * NUMA support configuration.
90af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
91af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
92af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
93af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
94af75078fSIntel  */
95af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */
96af75078fSIntel 
97af75078fSIntel /*
98b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
99b6ea6408SIntel  * not configured.
100b6ea6408SIntel  */
101b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
102b6ea6408SIntel 
103b6ea6408SIntel /*
104148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
105148f963fSBruce Richardson  */
106148f963fSBruce Richardson uint8_t mp_anon = 0;
107148f963fSBruce Richardson 
108148f963fSBruce Richardson /*
109af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
110af75078fSIntel  * forwarded.
111af75078fSIntel  * Must be instanciated with the ethernet addresses of peer traffic generator
112af75078fSIntel  * ports.
113af75078fSIntel  */
114af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
115af75078fSIntel portid_t nb_peer_eth_addrs = 0;
116af75078fSIntel 
117af75078fSIntel /*
118af75078fSIntel  * Probed Target Environment.
119af75078fSIntel  */
120af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
121af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
122af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
123af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
124af75078fSIntel 
125af75078fSIntel /*
126af75078fSIntel  * Test Forwarding Configuration.
127af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
128af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
129af75078fSIntel  */
130af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
131af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
132af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
133af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
134af75078fSIntel 
135af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
136af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
137af75078fSIntel 
138af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
139af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
140af75078fSIntel 
141af75078fSIntel /*
142af75078fSIntel  * Forwarding engines.
143af75078fSIntel  */
144af75078fSIntel struct fwd_engine * fwd_engines[] = {
145af75078fSIntel 	&io_fwd_engine,
146af75078fSIntel 	&mac_fwd_engine,
14757e85242SBruce Richardson 	&mac_retry_fwd_engine,
148d47388f1SCyril Chemparathy 	&mac_swap_engine,
149e9e23a61SCyril Chemparathy 	&flow_gen_engine,
150af75078fSIntel 	&rx_only_engine,
151af75078fSIntel 	&tx_only_engine,
152af75078fSIntel 	&csum_fwd_engine,
153168dfa61SIvan Boule 	&icmp_echo_engine,
154af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
155af75078fSIntel 	&ieee1588_fwd_engine,
156af75078fSIntel #endif
157af75078fSIntel 	NULL,
158af75078fSIntel };
159af75078fSIntel 
160af75078fSIntel struct fwd_config cur_fwd_config;
161af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
162af75078fSIntel 
163af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
164c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
165c8798818SIntel                                       * specified on command-line. */
166af75078fSIntel 
167af75078fSIntel /*
168af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
169af75078fSIntel  */
170af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
171af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
172af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
173af75078fSIntel };
174af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
175af75078fSIntel 
176af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
177af75078fSIntel uint16_t mb_mempool_cache = DEF_PKT_BURST; /**< Size of mbuf mempool cache. */
178af75078fSIntel 
179900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
180900550deSIntel uint8_t dcb_config = 0;
181900550deSIntel 
182900550deSIntel /* Whether the dcb is in testing status */
183900550deSIntel uint8_t dcb_test = 0;
184900550deSIntel 
185900550deSIntel /* DCB on and VT on mapping is default */
186900550deSIntel enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
187af75078fSIntel 
188af75078fSIntel /*
189af75078fSIntel  * Configurable number of RX/TX queues.
190af75078fSIntel  */
191af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
192af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
193af75078fSIntel 
194af75078fSIntel /*
195af75078fSIntel  * Configurable number of RX/TX ring descriptors.
196af75078fSIntel  */
197af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
198af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
199af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
200af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
201af75078fSIntel 
202af75078fSIntel /*
203af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
204af75078fSIntel  */
205af75078fSIntel #define RX_PTHRESH 8 /**< Default value of RX prefetch threshold register. */
206af75078fSIntel #define RX_HTHRESH 8 /**< Default value of RX host threshold register. */
207af75078fSIntel #define RX_WTHRESH 4 /**< Default value of RX write-back threshold register. */
208af75078fSIntel 
209af75078fSIntel #define TX_PTHRESH 36 /**< Default value of TX prefetch threshold register. */
210af75078fSIntel #define TX_HTHRESH 0 /**< Default value of TX host threshold register. */
211af75078fSIntel #define TX_WTHRESH 0 /**< Default value of TX write-back threshold register. */
212af75078fSIntel 
213af75078fSIntel struct rte_eth_thresh rx_thresh = {
214af75078fSIntel 	.pthresh = RX_PTHRESH,
215af75078fSIntel 	.hthresh = RX_HTHRESH,
216af75078fSIntel 	.wthresh = RX_WTHRESH,
217af75078fSIntel };
218af75078fSIntel 
219af75078fSIntel struct rte_eth_thresh tx_thresh = {
220af75078fSIntel 	.pthresh = TX_PTHRESH,
221af75078fSIntel 	.hthresh = TX_HTHRESH,
222af75078fSIntel 	.wthresh = TX_WTHRESH,
223af75078fSIntel };
224af75078fSIntel 
225af75078fSIntel /*
226af75078fSIntel  * Configurable value of RX free threshold.
227af75078fSIntel  */
228af75078fSIntel uint16_t rx_free_thresh = 0; /* Immediately free RX descriptors by default. */
229af75078fSIntel 
230af75078fSIntel /*
231ce8d5614SIntel  * Configurable value of RX drop enable.
232ce8d5614SIntel  */
233ce8d5614SIntel uint8_t rx_drop_en = 0; /* Drop packets when no descriptors for queue. */
234ce8d5614SIntel 
235ce8d5614SIntel /*
236af75078fSIntel  * Configurable value of TX free threshold.
237af75078fSIntel  */
238af75078fSIntel uint16_t tx_free_thresh = 0; /* Use default values. */
239af75078fSIntel 
240af75078fSIntel /*
241af75078fSIntel  * Configurable value of TX RS bit threshold.
242af75078fSIntel  */
243af75078fSIntel uint16_t tx_rs_thresh = 0; /* Use default values. */
244af75078fSIntel 
245af75078fSIntel /*
246ce8d5614SIntel  * Configurable value of TX queue flags.
247ce8d5614SIntel  */
248ce8d5614SIntel uint32_t txq_flags = 0; /* No flags set. */
249ce8d5614SIntel 
250ce8d5614SIntel /*
251af75078fSIntel  * Receive Side Scaling (RSS) configuration.
252af75078fSIntel  */
253af75078fSIntel uint16_t rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6; /* RSS IP by default. */
254af75078fSIntel 
255af75078fSIntel /*
256af75078fSIntel  * Port topology configuration
257af75078fSIntel  */
258af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
259af75078fSIntel 
2607741e4cfSIntel /*
2617741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2627741e4cfSIntel  */
2637741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2647741e4cfSIntel 
265af75078fSIntel /*
266bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
267bc202406SDavid Marchand  */
268bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
269bc202406SDavid Marchand 
270bc202406SDavid Marchand /*
2717b7e5ba7SIntel  * NIC bypass mode configuration options.
2727b7e5ba7SIntel  */
2737b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
2747b7e5ba7SIntel 
2757b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
2767b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
2777b7e5ba7SIntel 
2787b7e5ba7SIntel #endif
2797b7e5ba7SIntel 
2807b7e5ba7SIntel /*
281af75078fSIntel  * Ethernet device configuration.
282af75078fSIntel  */
283af75078fSIntel struct rte_eth_rxmode rx_mode = {
284af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
285af75078fSIntel 	.split_hdr_size = 0,
286af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
287af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
288af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
289a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
290a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
291af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
292af75078fSIntel 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
293af75078fSIntel };
294af75078fSIntel 
295af75078fSIntel struct rte_fdir_conf fdir_conf = {
296af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
297af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
298af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
299af75078fSIntel 	.flexbytes_offset = 0x6,
300af75078fSIntel 	.drop_queue = 127,
301af75078fSIntel };
302af75078fSIntel 
303af75078fSIntel static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
304af75078fSIntel 
305ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
306ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
307ed30d9b6SIntel 
308ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
309ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
310ed30d9b6SIntel 
311ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
312ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
313ed30d9b6SIntel 
314ed30d9b6SIntel /* Forward function declarations */
315ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
316ce8d5614SIntel static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask);
317ce8d5614SIntel 
318ce8d5614SIntel /*
319ce8d5614SIntel  * Check if all the ports are started.
320ce8d5614SIntel  * If yes, return positive value. If not, return zero.
321ce8d5614SIntel  */
322ce8d5614SIntel static int all_ports_started(void);
323ed30d9b6SIntel 
324af75078fSIntel /*
325af75078fSIntel  * Setup default configuration.
326af75078fSIntel  */
327af75078fSIntel static void
328af75078fSIntel set_default_fwd_lcores_config(void)
329af75078fSIntel {
330af75078fSIntel 	unsigned int i;
331af75078fSIntel 	unsigned int nb_lc;
332af75078fSIntel 
333af75078fSIntel 	nb_lc = 0;
334af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
335af75078fSIntel 		if (! rte_lcore_is_enabled(i))
336af75078fSIntel 			continue;
337af75078fSIntel 		if (i == rte_get_master_lcore())
338af75078fSIntel 			continue;
339af75078fSIntel 		fwd_lcores_cpuids[nb_lc++] = i;
340af75078fSIntel 	}
341af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
342af75078fSIntel 	nb_cfg_lcores = nb_lcores;
343af75078fSIntel 	nb_fwd_lcores = 1;
344af75078fSIntel }
345af75078fSIntel 
346af75078fSIntel static void
347af75078fSIntel set_def_peer_eth_addrs(void)
348af75078fSIntel {
349af75078fSIntel 	portid_t i;
350af75078fSIntel 
351af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
352af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
353af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
354af75078fSIntel 	}
355af75078fSIntel }
356af75078fSIntel 
357af75078fSIntel static void
358af75078fSIntel set_default_fwd_ports_config(void)
359af75078fSIntel {
360af75078fSIntel 	portid_t pt_id;
361af75078fSIntel 
362af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
363af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
364af75078fSIntel 
365af75078fSIntel 	nb_cfg_ports = nb_ports;
366af75078fSIntel 	nb_fwd_ports = nb_ports;
367af75078fSIntel }
368af75078fSIntel 
369af75078fSIntel void
370af75078fSIntel set_def_fwd_config(void)
371af75078fSIntel {
372af75078fSIntel 	set_default_fwd_lcores_config();
373af75078fSIntel 	set_def_peer_eth_addrs();
374af75078fSIntel 	set_default_fwd_ports_config();
375af75078fSIntel }
376af75078fSIntel 
377af75078fSIntel /*
378af75078fSIntel  * Configuration initialisation done once at init time.
379af75078fSIntel  */
380af75078fSIntel struct mbuf_ctor_arg {
381af75078fSIntel 	uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
382af75078fSIntel 	uint16_t seg_buf_size;   /**< size of data segment in mbuf. */
383af75078fSIntel };
384af75078fSIntel 
385af75078fSIntel struct mbuf_pool_ctor_arg {
386af75078fSIntel 	uint16_t seg_buf_size; /**< size of data segment in mbuf. */
387af75078fSIntel };
388af75078fSIntel 
389af75078fSIntel static void
390af75078fSIntel testpmd_mbuf_ctor(struct rte_mempool *mp,
391af75078fSIntel 		  void *opaque_arg,
392af75078fSIntel 		  void *raw_mbuf,
393af75078fSIntel 		  __attribute__((unused)) unsigned i)
394af75078fSIntel {
395af75078fSIntel 	struct mbuf_ctor_arg *mb_ctor_arg;
396af75078fSIntel 	struct rte_mbuf    *mb;
397af75078fSIntel 
398af75078fSIntel 	mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
399af75078fSIntel 	mb = (struct rte_mbuf *) raw_mbuf;
400af75078fSIntel 
401e788fe1cSIvan Boule 	mb->type         = RTE_MBUF_PKT;
402af75078fSIntel 	mb->pool         = mp;
403af75078fSIntel 	mb->buf_addr     = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
404af75078fSIntel 	mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
405af75078fSIntel 			mb_ctor_arg->seg_buf_offset);
406af75078fSIntel 	mb->buf_len      = mb_ctor_arg->seg_buf_size;
407af75078fSIntel 	mb->type         = RTE_MBUF_PKT;
408af75078fSIntel 	mb->ol_flags     = 0;
409af75078fSIntel 	mb->pkt.data     = (char *) mb->buf_addr + RTE_PKTMBUF_HEADROOM;
410af75078fSIntel 	mb->pkt.nb_segs  = 1;
41142d71416SIntel 	mb->pkt.vlan_macip.data = 0;
412af75078fSIntel 	mb->pkt.hash.rss = 0;
413af75078fSIntel }
414af75078fSIntel 
415af75078fSIntel static void
416af75078fSIntel testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
417af75078fSIntel 		       void *opaque_arg)
418af75078fSIntel {
419af75078fSIntel 	struct mbuf_pool_ctor_arg      *mbp_ctor_arg;
420af75078fSIntel 	struct rte_pktmbuf_pool_private *mbp_priv;
421af75078fSIntel 
422af75078fSIntel 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
423af75078fSIntel 		printf("%s(%s) private_data_size %d < %d\n",
424af75078fSIntel 		       __func__, mp->name, (int) mp->private_data_size,
425af75078fSIntel 		       (int) sizeof(struct rte_pktmbuf_pool_private));
426af75078fSIntel 		return;
427af75078fSIntel 	}
428af75078fSIntel 	mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
429148f963fSBruce Richardson 	mbp_priv = rte_mempool_get_priv(mp);
430af75078fSIntel 	mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
431af75078fSIntel }
432af75078fSIntel 
433af75078fSIntel static void
434af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
435af75078fSIntel 		 unsigned int socket_id)
436af75078fSIntel {
437af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
438af75078fSIntel 	struct rte_mempool *rte_mp;
439af75078fSIntel 	struct mbuf_pool_ctor_arg mbp_ctor_arg;
440af75078fSIntel 	struct mbuf_ctor_arg mb_ctor_arg;
441af75078fSIntel 	uint32_t mb_size;
442af75078fSIntel 
443af75078fSIntel 	mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
444af75078fSIntel 						mbuf_seg_size);
445af75078fSIntel 	mb_ctor_arg.seg_buf_offset =
446af75078fSIntel 		(uint16_t) CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
447af75078fSIntel 	mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
448af75078fSIntel 	mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
449af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
450148f963fSBruce Richardson 
451148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
452148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
453af75078fSIntel                                    (unsigned) mb_mempool_cache,
454af75078fSIntel                                    sizeof(struct rte_pktmbuf_pool_private),
455af75078fSIntel                                    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
456af75078fSIntel                                    testpmd_mbuf_ctor, &mb_ctor_arg,
457af75078fSIntel                                    socket_id, 0);
458148f963fSBruce Richardson 
459148f963fSBruce Richardson 
460148f963fSBruce Richardson 
461148f963fSBruce Richardson #else
462148f963fSBruce Richardson 	if (mp_anon != 0)
463148f963fSBruce Richardson 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
464148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
465148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
466148f963fSBruce Richardson 				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
467148f963fSBruce Richardson 				    testpmd_mbuf_ctor, &mb_ctor_arg,
468148f963fSBruce Richardson 				    socket_id, 0);
469148f963fSBruce Richardson 	else
470148f963fSBruce Richardson 		rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size,
471148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
472148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
473148f963fSBruce Richardson 				    testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
474148f963fSBruce Richardson 				    testpmd_mbuf_ctor, &mb_ctor_arg,
475148f963fSBruce Richardson 				    socket_id, 0);
476148f963fSBruce Richardson 
477148f963fSBruce Richardson #endif
478148f963fSBruce Richardson 
479af75078fSIntel 	if (rte_mp == NULL) {
480ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
481ce8d5614SIntel 						"failed\n", socket_id);
482148f963fSBruce Richardson 	} else if (verbose_level > 0) {
483591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
484af75078fSIntel 	}
485af75078fSIntel }
486af75078fSIntel 
48720a0286fSLiu Xiaofeng /*
48820a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
48920a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
49020a0286fSLiu Xiaofeng  */
49120a0286fSLiu Xiaofeng static int
49220a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
49320a0286fSLiu Xiaofeng {
49420a0286fSLiu Xiaofeng 	static int warning_once = 0;
49520a0286fSLiu Xiaofeng 
49620a0286fSLiu Xiaofeng 	if (socket_id >= MAX_SOCKET) {
49720a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
49820a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
49920a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
50020a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
50120a0286fSLiu Xiaofeng 			       " --numa.\n");
50220a0286fSLiu Xiaofeng 		warning_once = 1;
50320a0286fSLiu Xiaofeng 		return -1;
50420a0286fSLiu Xiaofeng 	}
50520a0286fSLiu Xiaofeng 	return 0;
50620a0286fSLiu Xiaofeng }
50720a0286fSLiu Xiaofeng 
508af75078fSIntel static void
509af75078fSIntel init_config(void)
510af75078fSIntel {
511ce8d5614SIntel 	portid_t pid;
512af75078fSIntel 	struct rte_port *port;
513af75078fSIntel 	struct rte_mempool *mbp;
514af75078fSIntel 	unsigned int nb_mbuf_per_pool;
515af75078fSIntel 	lcoreid_t  lc_id;
516b6ea6408SIntel 	uint8_t port_per_socket[MAX_SOCKET];
517af75078fSIntel 
518b6ea6408SIntel 	memset(port_per_socket,0,MAX_SOCKET);
519af75078fSIntel 	/* Configuration of logical cores. */
520af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
521af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
522af75078fSIntel 				CACHE_LINE_SIZE);
523af75078fSIntel 	if (fwd_lcores == NULL) {
524ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
525ce8d5614SIntel 							"failed\n", nb_lcores);
526af75078fSIntel 	}
527af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
528af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
529af75078fSIntel 					       sizeof(struct fwd_lcore),
530af75078fSIntel 					       CACHE_LINE_SIZE);
531af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
532ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
533ce8d5614SIntel 								"failed\n");
534af75078fSIntel 		}
535af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
536af75078fSIntel 	}
537af75078fSIntel 
538af75078fSIntel 	/*
539af75078fSIntel 	 * Create pools of mbuf.
540af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
541b6ea6408SIntel 	 * socket 0 memory by default.
542af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
543c8798818SIntel 	 *
544c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
545c8798818SIntel 	 * nb_txd can be configured at run time.
546af75078fSIntel 	 */
547c8798818SIntel 	if (param_total_num_mbufs)
548c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
549c8798818SIntel 	else {
550c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
551c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
552b6ea6408SIntel 
553b6ea6408SIntel 		if (!numa_support)
554c8798818SIntel 			nb_mbuf_per_pool = (nb_mbuf_per_pool * nb_ports);
555c8798818SIntel 	}
556af75078fSIntel 
557b6ea6408SIntel 	if (!numa_support) {
558b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
559b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
560b6ea6408SIntel 		else
561b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
562b6ea6408SIntel 						 socket_num);
563b6ea6408SIntel 	}
564af75078fSIntel 
565af75078fSIntel 	/* Configuration of Ethernet ports. */
566af75078fSIntel 	ports = rte_zmalloc("testpmd: ports",
567af75078fSIntel 			    sizeof(struct rte_port) * nb_ports,
568af75078fSIntel 			    CACHE_LINE_SIZE);
569af75078fSIntel 	if (ports == NULL) {
570ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) "
571ce8d5614SIntel 							"failed\n", nb_ports);
572af75078fSIntel 	}
573af75078fSIntel 
574ce8d5614SIntel 	for (pid = 0; pid < nb_ports; pid++) {
575ce8d5614SIntel 		port = &ports[pid];
576ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
577ce8d5614SIntel 
578b6ea6408SIntel 		if (numa_support) {
579b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
580b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
581b6ea6408SIntel 			else {
582b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
58320a0286fSLiu Xiaofeng 
58420a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
58520a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
58620a0286fSLiu Xiaofeng 					socket_id = 0;
587b6ea6408SIntel 				port_per_socket[socket_id]++;
588b6ea6408SIntel 			}
589b6ea6408SIntel 		}
590b6ea6408SIntel 
591ce8d5614SIntel 		/* set flag to initialize port/queue */
592ce8d5614SIntel 		port->need_reconfig = 1;
593ce8d5614SIntel 		port->need_reconfig_queues = 1;
594ce8d5614SIntel 	}
595ce8d5614SIntel 
596b6ea6408SIntel 	if (numa_support) {
597b6ea6408SIntel 		uint8_t i;
598b6ea6408SIntel 		unsigned int nb_mbuf;
599ce8d5614SIntel 
600b6ea6408SIntel 		if (param_total_num_mbufs)
601b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
602b6ea6408SIntel 
603b6ea6408SIntel 		for (i = 0; i < MAX_SOCKET; i++) {
604b6ea6408SIntel 			nb_mbuf = (nb_mbuf_per_pool *
605b6ea6408SIntel 						port_per_socket[i]);
606b6ea6408SIntel 			if (nb_mbuf)
607b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
608b6ea6408SIntel 						nb_mbuf,i);
609b6ea6408SIntel 		}
610b6ea6408SIntel 	}
611b6ea6408SIntel 	init_port_config();
6125886ae07SAdrien Mazarguil 
6135886ae07SAdrien Mazarguil 	/*
6145886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6155886ae07SAdrien Mazarguil 	 */
6165886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6175886ae07SAdrien Mazarguil 		mbp = mbuf_pool_find(rte_lcore_to_socket_id(lc_id));
6185886ae07SAdrien Mazarguil 		if (mbp == NULL)
6195886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6205886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
6215886ae07SAdrien Mazarguil 	}
6225886ae07SAdrien Mazarguil 
623ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
624ce8d5614SIntel 	if (init_fwd_streams() < 0)
625ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
626ce8d5614SIntel }
627ce8d5614SIntel 
628ce8d5614SIntel int
629ce8d5614SIntel init_fwd_streams(void)
630ce8d5614SIntel {
631ce8d5614SIntel 	portid_t pid;
632ce8d5614SIntel 	struct rte_port *port;
633ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
634ce8d5614SIntel 
635ce8d5614SIntel 	/* set socket id according to numa or not */
636ce8d5614SIntel 	for (pid = 0; pid < nb_ports; pid++) {
637ce8d5614SIntel 		port = &ports[pid];
638ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
639ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
640ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
641ce8d5614SIntel 				port->dev_info.max_rx_queues);
642ce8d5614SIntel 			return -1;
643ce8d5614SIntel 		}
644ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
645ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
646ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
647ce8d5614SIntel 				port->dev_info.max_tx_queues);
648ce8d5614SIntel 			return -1;
649ce8d5614SIntel 		}
65020a0286fSLiu Xiaofeng 		if (numa_support) {
65120a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
65220a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
65320a0286fSLiu Xiaofeng 			else {
654b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
65520a0286fSLiu Xiaofeng 
65620a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
65720a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
65820a0286fSLiu Xiaofeng 					port->socket_id = 0;
65920a0286fSLiu Xiaofeng 			}
66020a0286fSLiu Xiaofeng 		}
661b6ea6408SIntel 		else {
662b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
663af75078fSIntel 				port->socket_id = 0;
664b6ea6408SIntel 			else
665b6ea6408SIntel 				port->socket_id = socket_num;
666b6ea6408SIntel 		}
667af75078fSIntel 	}
668af75078fSIntel 
669ce8d5614SIntel 	nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
670ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
671ce8d5614SIntel 		return 0;
672ce8d5614SIntel 	/* clear the old */
673ce8d5614SIntel 	if (fwd_streams != NULL) {
674ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
675ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
676ce8d5614SIntel 				continue;
677ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
678ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
679af75078fSIntel 		}
680ce8d5614SIntel 		rte_free(fwd_streams);
681ce8d5614SIntel 		fwd_streams = NULL;
682ce8d5614SIntel 	}
683ce8d5614SIntel 
684ce8d5614SIntel 	/* init new */
685ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
686ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
687ce8d5614SIntel 		sizeof(struct fwd_stream *) * nb_fwd_streams, CACHE_LINE_SIZE);
688ce8d5614SIntel 	if (fwd_streams == NULL)
689ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
690ce8d5614SIntel 						"failed\n", nb_fwd_streams);
691ce8d5614SIntel 
692af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
693af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
694ce8d5614SIntel 				sizeof(struct fwd_stream), CACHE_LINE_SIZE);
695ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
696ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
697ce8d5614SIntel 								" failed\n");
698af75078fSIntel 	}
699ce8d5614SIntel 
700ce8d5614SIntel 	return 0;
701af75078fSIntel }
702af75078fSIntel 
703af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
704af75078fSIntel static void
705af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
706af75078fSIntel {
707af75078fSIntel 	unsigned int total_burst;
708af75078fSIntel 	unsigned int nb_burst;
709af75078fSIntel 	unsigned int burst_stats[3];
710af75078fSIntel 	uint16_t pktnb_stats[3];
711af75078fSIntel 	uint16_t nb_pkt;
712af75078fSIntel 	int burst_percent[3];
713af75078fSIntel 
714af75078fSIntel 	/*
715af75078fSIntel 	 * First compute the total number of packet bursts and the
716af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
717af75078fSIntel 	 */
718af75078fSIntel 	total_burst = 0;
719af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
720af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
721af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
722af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
723af75078fSIntel 		if (nb_burst == 0)
724af75078fSIntel 			continue;
725af75078fSIntel 		total_burst += nb_burst;
726af75078fSIntel 		if (nb_burst > burst_stats[0]) {
727af75078fSIntel 			burst_stats[1] = burst_stats[0];
728af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
729af75078fSIntel 			burst_stats[0] = nb_burst;
730af75078fSIntel 			pktnb_stats[0] = nb_pkt;
731af75078fSIntel 		}
732af75078fSIntel 	}
733af75078fSIntel 	if (total_burst == 0)
734af75078fSIntel 		return;
735af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
736af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
737af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
738af75078fSIntel 	if (burst_stats[0] == total_burst) {
739af75078fSIntel 		printf("]\n");
740af75078fSIntel 		return;
741af75078fSIntel 	}
742af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
743af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
744af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
745af75078fSIntel 		return;
746af75078fSIntel 	}
747af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
748af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
749af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
750af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
751af75078fSIntel 		return;
752af75078fSIntel 	}
753af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
754af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
755af75078fSIntel }
756af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
757af75078fSIntel 
758af75078fSIntel static void
759af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
760af75078fSIntel {
761af75078fSIntel 	struct rte_port *port;
762013af9b6SIntel 	uint8_t i;
763af75078fSIntel 
764af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
765af75078fSIntel 
766af75078fSIntel 	port = &ports[port_id];
767af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
768af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
769013af9b6SIntel 
770013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
771af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
772af75078fSIntel 		       "%-"PRIu64"\n",
773af75078fSIntel 		       stats->ipackets, stats->ierrors,
774af75078fSIntel 		       (uint64_t) (stats->ipackets + stats->ierrors));
775af75078fSIntel 
776af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
777af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
778af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
779af75078fSIntel 
780af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
781af75078fSIntel 		       "%-"PRIu64"\n",
782af75078fSIntel 		       stats->opackets, port->tx_dropped,
783af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
784af75078fSIntel 
785af75078fSIntel 		if (stats->rx_nombuf > 0)
786af75078fSIntel 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
787013af9b6SIntel 
788013af9b6SIntel 	}
789013af9b6SIntel 	else {
790013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
791013af9b6SIntel 		       "%14"PRIu64"\n",
792013af9b6SIntel 		       stats->ipackets, stats->ierrors,
793013af9b6SIntel 		       (uint64_t) (stats->ipackets + stats->ierrors));
794013af9b6SIntel 
795013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
796013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
797013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
798013af9b6SIntel 
799013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
800013af9b6SIntel 		       "%14"PRIu64"\n",
801013af9b6SIntel 		       stats->opackets, port->tx_dropped,
802013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
803013af9b6SIntel 
804013af9b6SIntel 		if (stats->rx_nombuf > 0)
805013af9b6SIntel 			printf("  RX-nombufs:%14"PRIu64"\n", stats->rx_nombuf);
806013af9b6SIntel 	}
807e659b6b4SIvan Boule 
808e659b6b4SIvan Boule 	/* Display statistics of XON/XOFF pause frames, if any. */
809e659b6b4SIvan Boule 	if ((stats->tx_pause_xon  | stats->rx_pause_xon |
810e659b6b4SIvan Boule 	     stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
811e659b6b4SIvan Boule 		printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
812e659b6b4SIvan Boule 		       stats->rx_pause_xoff, stats->rx_pause_xon);
813e659b6b4SIvan Boule 		printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
814e659b6b4SIvan Boule 		       stats->tx_pause_xoff, stats->tx_pause_xon);
815e659b6b4SIvan Boule 	}
816e659b6b4SIvan Boule 
817af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
818af75078fSIntel 	if (port->rx_stream)
819013af9b6SIntel 		pkt_burst_stats_display("RX",
820013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
821af75078fSIntel 	if (port->tx_stream)
822013af9b6SIntel 		pkt_burst_stats_display("TX",
823013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
824af75078fSIntel #endif
825af75078fSIntel 	/* stats fdir */
826af75078fSIntel 	if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
827013af9b6SIntel 		printf("  Fdirmiss:%14"PRIu64"	  Fdirmatch:%14"PRIu64"\n",
828af75078fSIntel 		       stats->fdirmiss,
829af75078fSIntel 		       stats->fdirmatch);
830af75078fSIntel 
831013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
832013af9b6SIntel 		printf("\n");
833013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
834013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
835013af9b6SIntel 			       "     RX-errors:%14"PRIu64
836013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
837013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
838013af9b6SIntel 		}
839013af9b6SIntel 		printf("\n");
840013af9b6SIntel 	}
841013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
842013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
843013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
844013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
845013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
846013af9b6SIntel 		}
847013af9b6SIntel 	}
848013af9b6SIntel 
849af75078fSIntel 	printf("  %s--------------------------------%s\n",
850af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
851af75078fSIntel }
852af75078fSIntel 
853af75078fSIntel static void
854af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
855af75078fSIntel {
856af75078fSIntel 	struct fwd_stream *fs;
857af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
858af75078fSIntel 
859af75078fSIntel 	fs = fwd_streams[stream_id];
860af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
861af75078fSIntel 	    (fs->fwd_dropped == 0))
862af75078fSIntel 		return;
863af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
864af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
865af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
866af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
867af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
868af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
869af75078fSIntel 
870af75078fSIntel 	/* if checksum mode */
871af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
872013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
873013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
874af75078fSIntel 	}
875af75078fSIntel 
876af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
877af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
878af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
879af75078fSIntel #endif
880af75078fSIntel }
881af75078fSIntel 
882af75078fSIntel static void
8837741e4cfSIntel flush_fwd_rx_queues(void)
884af75078fSIntel {
885af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
886af75078fSIntel 	portid_t  rxp;
8877741e4cfSIntel 	portid_t port_id;
888af75078fSIntel 	queueid_t rxq;
889af75078fSIntel 	uint16_t  nb_rx;
890af75078fSIntel 	uint16_t  i;
891af75078fSIntel 	uint8_t   j;
892af75078fSIntel 
893af75078fSIntel 	for (j = 0; j < 2; j++) {
8947741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
895af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
8967741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
897af75078fSIntel 				do {
8987741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
899013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
900af75078fSIntel 					for (i = 0; i < nb_rx; i++)
901af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
902af75078fSIntel 				} while (nb_rx > 0);
903af75078fSIntel 			}
904af75078fSIntel 		}
905af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
906af75078fSIntel 	}
907af75078fSIntel }
908af75078fSIntel 
909af75078fSIntel static void
910af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
911af75078fSIntel {
912af75078fSIntel 	struct fwd_stream **fsm;
913af75078fSIntel 	streamid_t nb_fs;
914af75078fSIntel 	streamid_t sm_id;
915af75078fSIntel 
916af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
917af75078fSIntel 	nb_fs = fc->stream_nb;
918af75078fSIntel 	do {
919af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
920af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
921af75078fSIntel 	} while (! fc->stopped);
922af75078fSIntel }
923af75078fSIntel 
924af75078fSIntel static int
925af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
926af75078fSIntel {
927af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
928af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
929af75078fSIntel 	return 0;
930af75078fSIntel }
931af75078fSIntel 
932af75078fSIntel /*
933af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
934af75078fSIntel  * Used to start communication flows in network loopback test configurations.
935af75078fSIntel  */
936af75078fSIntel static int
937af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
938af75078fSIntel {
939af75078fSIntel 	struct fwd_lcore *fwd_lc;
940af75078fSIntel 	struct fwd_lcore tmp_lcore;
941af75078fSIntel 
942af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
943af75078fSIntel 	tmp_lcore = *fwd_lc;
944af75078fSIntel 	tmp_lcore.stopped = 1;
945af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
946af75078fSIntel 	return 0;
947af75078fSIntel }
948af75078fSIntel 
949af75078fSIntel /*
950af75078fSIntel  * Launch packet forwarding:
951af75078fSIntel  *     - Setup per-port forwarding context.
952af75078fSIntel  *     - launch logical cores with their forwarding configuration.
953af75078fSIntel  */
954af75078fSIntel static void
955af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
956af75078fSIntel {
957af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
958af75078fSIntel 	unsigned int i;
959af75078fSIntel 	unsigned int lc_id;
960af75078fSIntel 	int diag;
961af75078fSIntel 
962af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
963af75078fSIntel 	if (port_fwd_begin != NULL) {
964af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
965af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
966af75078fSIntel 	}
967af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
968af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
969af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
970af75078fSIntel 			fwd_lcores[i]->stopped = 0;
971af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
972af75078fSIntel 						     fwd_lcores[i], lc_id);
973af75078fSIntel 			if (diag != 0)
974af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
975af75078fSIntel 				       lc_id, diag);
976af75078fSIntel 		}
977af75078fSIntel 	}
978af75078fSIntel }
979af75078fSIntel 
980af75078fSIntel /*
981af75078fSIntel  * Launch packet forwarding configuration.
982af75078fSIntel  */
983af75078fSIntel void
984af75078fSIntel start_packet_forwarding(int with_tx_first)
985af75078fSIntel {
986af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
987af75078fSIntel 	port_fwd_end_t  port_fwd_end;
988af75078fSIntel 	struct rte_port *port;
989af75078fSIntel 	unsigned int i;
990af75078fSIntel 	portid_t   pt_id;
991af75078fSIntel 	streamid_t sm_id;
992af75078fSIntel 
993ce8d5614SIntel 	if (all_ports_started() == 0) {
994ce8d5614SIntel 		printf("Not all ports were started\n");
995ce8d5614SIntel 		return;
996ce8d5614SIntel 	}
997af75078fSIntel 	if (test_done == 0) {
998af75078fSIntel 		printf("Packet forwarding already started\n");
999af75078fSIntel 		return;
1000af75078fSIntel 	}
10017741e4cfSIntel 	if(dcb_test) {
10027741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
10037741e4cfSIntel 			pt_id = fwd_ports_ids[i];
10047741e4cfSIntel 			port = &ports[pt_id];
10057741e4cfSIntel 			if (!port->dcb_flag) {
10067741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
10077741e4cfSIntel                                        "be configured in this mode.\n");
1008013af9b6SIntel 				return;
1009013af9b6SIntel 			}
10107741e4cfSIntel 		}
10117741e4cfSIntel 		if (nb_fwd_lcores == 1) {
10127741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
10137741e4cfSIntel                                "should be larger than 1.\n");
10147741e4cfSIntel 			return;
10157741e4cfSIntel 		}
10167741e4cfSIntel 	}
1017af75078fSIntel 	test_done = 0;
10187741e4cfSIntel 
10197741e4cfSIntel 	if(!no_flush_rx)
10207741e4cfSIntel 		flush_fwd_rx_queues();
10217741e4cfSIntel 
1022af75078fSIntel 	fwd_config_setup();
1023af75078fSIntel 	rxtx_config_display();
1024af75078fSIntel 
1025af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1026af75078fSIntel 		pt_id = fwd_ports_ids[i];
1027af75078fSIntel 		port = &ports[pt_id];
1028af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1029af75078fSIntel 		port->tx_dropped = 0;
1030013af9b6SIntel 
1031013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1032af75078fSIntel 	}
1033af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1034af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1035af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1036af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1037af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1038af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1039af75078fSIntel 
1040af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1041af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1042af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1043af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1044af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1045af75078fSIntel #endif
1046af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1047af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1048af75078fSIntel #endif
1049af75078fSIntel 	}
1050af75078fSIntel 	if (with_tx_first) {
1051af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1052af75078fSIntel 		if (port_fwd_begin != NULL) {
1053af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1054af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1055af75078fSIntel 		}
1056af75078fSIntel 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1057af75078fSIntel 		rte_eal_mp_wait_lcore();
1058af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1059af75078fSIntel 		if (port_fwd_end != NULL) {
1060af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1061af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1062af75078fSIntel 		}
1063af75078fSIntel 	}
1064af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1065af75078fSIntel }
1066af75078fSIntel 
1067af75078fSIntel void
1068af75078fSIntel stop_packet_forwarding(void)
1069af75078fSIntel {
1070af75078fSIntel 	struct rte_eth_stats stats;
1071af75078fSIntel 	struct rte_port *port;
1072af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1073af75078fSIntel 	int i;
1074af75078fSIntel 	portid_t   pt_id;
1075af75078fSIntel 	streamid_t sm_id;
1076af75078fSIntel 	lcoreid_t  lc_id;
1077af75078fSIntel 	uint64_t total_recv;
1078af75078fSIntel 	uint64_t total_xmit;
1079af75078fSIntel 	uint64_t total_rx_dropped;
1080af75078fSIntel 	uint64_t total_tx_dropped;
1081af75078fSIntel 	uint64_t total_rx_nombuf;
1082af75078fSIntel 	uint64_t tx_dropped;
1083af75078fSIntel 	uint64_t rx_bad_ip_csum;
1084af75078fSIntel 	uint64_t rx_bad_l4_csum;
1085af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1086af75078fSIntel 	uint64_t fwd_cycles;
1087af75078fSIntel #endif
1088af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1089af75078fSIntel 
1090ce8d5614SIntel 	if (all_ports_started() == 0) {
1091ce8d5614SIntel 		printf("Not all ports were started\n");
1092ce8d5614SIntel 		return;
1093ce8d5614SIntel 	}
1094af75078fSIntel 	if (test_done) {
1095af75078fSIntel 		printf("Packet forwarding not started\n");
1096af75078fSIntel 		return;
1097af75078fSIntel 	}
1098af75078fSIntel 	printf("Telling cores to stop...");
1099af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1100af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1101af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1102af75078fSIntel 	rte_eal_mp_wait_lcore();
1103af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1104af75078fSIntel 	if (port_fwd_end != NULL) {
1105af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1106af75078fSIntel 			pt_id = fwd_ports_ids[i];
1107af75078fSIntel 			(*port_fwd_end)(pt_id);
1108af75078fSIntel 		}
1109af75078fSIntel 	}
1110af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1111af75078fSIntel 	fwd_cycles = 0;
1112af75078fSIntel #endif
1113af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1114af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1115af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1116af75078fSIntel 			fwd_stream_stats_display(sm_id);
1117af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1118af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1119af75078fSIntel 		} else {
1120af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1121af75078fSIntel 				fwd_streams[sm_id];
1122af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1123af75078fSIntel 				fwd_streams[sm_id];
1124af75078fSIntel 		}
1125af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1126af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1127af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1128af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1129af75078fSIntel 
1130013af9b6SIntel 		rx_bad_ip_csum =
1131013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1132af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1133af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1134013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1135013af9b6SIntel 							rx_bad_ip_csum;
1136af75078fSIntel 
1137013af9b6SIntel 		rx_bad_l4_csum =
1138013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1139af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1140af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1141013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1142013af9b6SIntel 							rx_bad_l4_csum;
1143af75078fSIntel 
1144af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1145af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1146af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1147af75078fSIntel #endif
1148af75078fSIntel 	}
1149af75078fSIntel 	total_recv = 0;
1150af75078fSIntel 	total_xmit = 0;
1151af75078fSIntel 	total_rx_dropped = 0;
1152af75078fSIntel 	total_tx_dropped = 0;
1153af75078fSIntel 	total_rx_nombuf  = 0;
11547741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1155af75078fSIntel 		pt_id = fwd_ports_ids[i];
1156af75078fSIntel 
1157af75078fSIntel 		port = &ports[pt_id];
1158af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1159af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1160af75078fSIntel 		port->stats.ipackets = 0;
1161af75078fSIntel 		stats.opackets -= port->stats.opackets;
1162af75078fSIntel 		port->stats.opackets = 0;
1163af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1164af75078fSIntel 		port->stats.ibytes = 0;
1165af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1166af75078fSIntel 		port->stats.obytes = 0;
1167af75078fSIntel 		stats.ierrors  -= port->stats.ierrors;
1168af75078fSIntel 		port->stats.ierrors = 0;
1169af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1170af75078fSIntel 		port->stats.oerrors = 0;
1171af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1172af75078fSIntel 		port->stats.rx_nombuf = 0;
1173af75078fSIntel 		stats.fdirmatch -= port->stats.fdirmatch;
1174af75078fSIntel 		port->stats.rx_nombuf = 0;
1175af75078fSIntel 		stats.fdirmiss -= port->stats.fdirmiss;
1176af75078fSIntel 		port->stats.rx_nombuf = 0;
1177af75078fSIntel 
1178af75078fSIntel 		total_recv += stats.ipackets;
1179af75078fSIntel 		total_xmit += stats.opackets;
1180af75078fSIntel 		total_rx_dropped += stats.ierrors;
1181af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1182af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1183af75078fSIntel 
1184af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1185af75078fSIntel 	}
1186af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1187af75078fSIntel 	       "%s\n",
1188af75078fSIntel 	       acc_stats_border, acc_stats_border);
1189af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1190af75078fSIntel 	       "%-"PRIu64"\n"
1191af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1192af75078fSIntel 	       "%-"PRIu64"\n",
1193af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1194af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1195af75078fSIntel 	if (total_rx_nombuf > 0)
1196af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1197af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1198af75078fSIntel 	       "%s\n",
1199af75078fSIntel 	       acc_stats_border, acc_stats_border);
1200af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1201af75078fSIntel 	if (total_recv > 0)
1202af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1203af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1204af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1205af75078fSIntel 		       fwd_cycles, total_recv);
1206af75078fSIntel #endif
1207af75078fSIntel 	printf("\nDone.\n");
1208af75078fSIntel 	test_done = 1;
1209af75078fSIntel }
1210af75078fSIntel 
1211*cfae07fdSOuyang Changchun void
1212*cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1213*cfae07fdSOuyang Changchun {
1214*cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1215*cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1216*cfae07fdSOuyang Changchun }
1217*cfae07fdSOuyang Changchun 
1218*cfae07fdSOuyang Changchun void
1219*cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1220*cfae07fdSOuyang Changchun {
1221*cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1222*cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1223*cfae07fdSOuyang Changchun }
1224*cfae07fdSOuyang Changchun 
1225ce8d5614SIntel static int
1226ce8d5614SIntel all_ports_started(void)
1227ce8d5614SIntel {
1228ce8d5614SIntel 	portid_t pi;
1229ce8d5614SIntel 	struct rte_port *port;
1230ce8d5614SIntel 
1231ce8d5614SIntel 	for (pi = 0; pi < nb_ports; pi++) {
1232ce8d5614SIntel 		port = &ports[pi];
1233ce8d5614SIntel 		/* Check if there is a port which is not started */
1234ce8d5614SIntel 		if (port->port_status != RTE_PORT_STARTED)
1235ce8d5614SIntel 			return 0;
1236ce8d5614SIntel 	}
1237ce8d5614SIntel 
1238ce8d5614SIntel 	/* No port is not started */
1239ce8d5614SIntel 	return 1;
1240ce8d5614SIntel }
1241ce8d5614SIntel 
1242148f963fSBruce Richardson int
1243ce8d5614SIntel start_port(portid_t pid)
1244ce8d5614SIntel {
1245ce8d5614SIntel 	int diag, need_check_link_status = 0;
1246ce8d5614SIntel 	portid_t pi;
1247ce8d5614SIntel 	queueid_t qi;
1248ce8d5614SIntel 	struct rte_port *port;
1249d8c89163SZijie Pan 	uint8_t *mac_addr;
1250ce8d5614SIntel 
1251ce8d5614SIntel 	if (test_done == 0) {
1252ce8d5614SIntel 		printf("Please stop forwarding first\n");
1253148f963fSBruce Richardson 		return -1;
1254ce8d5614SIntel 	}
1255ce8d5614SIntel 
1256ce8d5614SIntel 	if (init_fwd_streams() < 0) {
1257ce8d5614SIntel 		printf("Fail from init_fwd_streams()\n");
1258148f963fSBruce Richardson 		return -1;
1259ce8d5614SIntel 	}
1260ce8d5614SIntel 
1261ce8d5614SIntel 	if(dcb_config)
1262ce8d5614SIntel 		dcb_test = 1;
1263ce8d5614SIntel 	for (pi = 0; pi < nb_ports; pi++) {
1264ce8d5614SIntel 		if (pid < nb_ports && pid != pi)
1265ce8d5614SIntel 			continue;
1266ce8d5614SIntel 
1267ce8d5614SIntel 		port = &ports[pi];
1268ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1269ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1270ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1271ce8d5614SIntel 			continue;
1272ce8d5614SIntel 		}
1273ce8d5614SIntel 
1274ce8d5614SIntel 		if (port->need_reconfig > 0) {
1275ce8d5614SIntel 			port->need_reconfig = 0;
1276ce8d5614SIntel 
12775706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
127820a0286fSLiu Xiaofeng 					port->socket_id);
1279ce8d5614SIntel 			/* configure port */
1280ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1281ce8d5614SIntel 						&(port->dev_conf));
1282ce8d5614SIntel 			if (diag != 0) {
1283ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1284ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1285ce8d5614SIntel 					printf("Port %d can not be set back "
1286ce8d5614SIntel 							"to stopped\n", pi);
1287ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1288ce8d5614SIntel 				/* try to reconfigure port next time */
1289ce8d5614SIntel 				port->need_reconfig = 1;
1290148f963fSBruce Richardson 				return -1;
1291ce8d5614SIntel 			}
1292ce8d5614SIntel 		}
1293ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1294ce8d5614SIntel 			port->need_reconfig_queues = 0;
1295ce8d5614SIntel 			/* setup tx queues */
1296ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1297b6ea6408SIntel 				if ((numa_support) &&
1298b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1299b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1300b6ea6408SIntel 						nb_txd,txring_numa[pi],
1301b6ea6408SIntel 						&(port->tx_conf));
1302b6ea6408SIntel 				else
1303b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1304b6ea6408SIntel 						nb_txd,port->socket_id,
1305b6ea6408SIntel 						&(port->tx_conf));
1306b6ea6408SIntel 
1307ce8d5614SIntel 				if (diag == 0)
1308ce8d5614SIntel 					continue;
1309ce8d5614SIntel 
1310ce8d5614SIntel 				/* Fail to setup tx queue, return */
1311ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1312ce8d5614SIntel 							RTE_PORT_HANDLING,
1313ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1314ce8d5614SIntel 					printf("Port %d can not be set back "
1315ce8d5614SIntel 							"to stopped\n", pi);
1316ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1317ce8d5614SIntel 				/* try to reconfigure queues next time */
1318ce8d5614SIntel 				port->need_reconfig_queues = 1;
1319148f963fSBruce Richardson 				return -1;
1320ce8d5614SIntel 			}
1321ce8d5614SIntel 			/* setup rx queues */
1322ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1323b6ea6408SIntel 				if ((numa_support) &&
1324b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1325b6ea6408SIntel 					struct rte_mempool * mp =
1326b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1327b6ea6408SIntel 					if (mp == NULL) {
1328b6ea6408SIntel 						printf("Failed to setup RX queue:"
1329b6ea6408SIntel 							"No mempool allocation"
1330b6ea6408SIntel 							"on the socket %d\n",
1331b6ea6408SIntel 							rxring_numa[pi]);
1332148f963fSBruce Richardson 						return -1;
1333b6ea6408SIntel 					}
1334b6ea6408SIntel 
1335b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1336b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1337b6ea6408SIntel 					     &(port->rx_conf),mp);
1338b6ea6408SIntel 				}
1339b6ea6408SIntel 				else
1340b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1341b6ea6408SIntel 					     nb_rxd,port->socket_id,
1342b6ea6408SIntel 					     &(port->rx_conf),
1343ce8d5614SIntel 				             mbuf_pool_find(port->socket_id));
1344b6ea6408SIntel 
1345ce8d5614SIntel 				if (diag == 0)
1346ce8d5614SIntel 					continue;
1347ce8d5614SIntel 
1348b6ea6408SIntel 
1349ce8d5614SIntel 				/* Fail to setup rx queue, return */
1350ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1351ce8d5614SIntel 							RTE_PORT_HANDLING,
1352ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1353ce8d5614SIntel 					printf("Port %d can not be set back "
1354ce8d5614SIntel 							"to stopped\n", pi);
1355ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1356ce8d5614SIntel 				/* try to reconfigure queues next time */
1357ce8d5614SIntel 				port->need_reconfig_queues = 1;
1358148f963fSBruce Richardson 				return -1;
1359ce8d5614SIntel 			}
1360ce8d5614SIntel 		}
1361ce8d5614SIntel 		/* start port */
1362ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1363ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1364ce8d5614SIntel 
1365ce8d5614SIntel 			/* Fail to setup rx queue, return */
1366ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1367ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1368ce8d5614SIntel 				printf("Port %d can not be set back to "
1369ce8d5614SIntel 							"stopped\n", pi);
1370ce8d5614SIntel 			continue;
1371ce8d5614SIntel 		}
1372ce8d5614SIntel 
1373ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1374ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1375ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1376ce8d5614SIntel 
1377d8c89163SZijie Pan 		mac_addr = port->eth_addr.addr_bytes;
1378d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1379d8c89163SZijie Pan 		       mac_addr[0], mac_addr[1], mac_addr[2],
1380d8c89163SZijie Pan 		       mac_addr[3], mac_addr[4], mac_addr[5]);
1381d8c89163SZijie Pan 
1382ce8d5614SIntel 		/* at least one port started, need checking link status */
1383ce8d5614SIntel 		need_check_link_status = 1;
1384ce8d5614SIntel 	}
1385ce8d5614SIntel 
1386bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1387ce8d5614SIntel 		check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
1388ce8d5614SIntel 	else
1389ce8d5614SIntel 		printf("Please stop the ports first\n");
1390ce8d5614SIntel 
1391ce8d5614SIntel 	printf("Done\n");
1392148f963fSBruce Richardson 	return 0;
1393ce8d5614SIntel }
1394ce8d5614SIntel 
1395ce8d5614SIntel void
1396ce8d5614SIntel stop_port(portid_t pid)
1397ce8d5614SIntel {
1398ce8d5614SIntel 	portid_t pi;
1399ce8d5614SIntel 	struct rte_port *port;
1400ce8d5614SIntel 	int need_check_link_status = 0;
1401ce8d5614SIntel 
1402ce8d5614SIntel 	if (test_done == 0) {
1403ce8d5614SIntel 		printf("Please stop forwarding first\n");
1404ce8d5614SIntel 		return;
1405ce8d5614SIntel 	}
1406ce8d5614SIntel 	if (dcb_test) {
1407ce8d5614SIntel 		dcb_test = 0;
1408ce8d5614SIntel 		dcb_config = 0;
1409ce8d5614SIntel 	}
1410ce8d5614SIntel 	printf("Stopping ports...\n");
1411ce8d5614SIntel 
1412ce8d5614SIntel 	for (pi = 0; pi < nb_ports; pi++) {
1413ce8d5614SIntel 		if (pid < nb_ports && pid != pi)
1414ce8d5614SIntel 			continue;
1415ce8d5614SIntel 
1416ce8d5614SIntel 		port = &ports[pi];
1417ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1418ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1419ce8d5614SIntel 			continue;
1420ce8d5614SIntel 
1421ce8d5614SIntel 		rte_eth_dev_stop(pi);
1422ce8d5614SIntel 
1423ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1424ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1425ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1426ce8d5614SIntel 		need_check_link_status = 1;
1427ce8d5614SIntel 	}
1428bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1429ce8d5614SIntel 		check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
1430ce8d5614SIntel 
1431ce8d5614SIntel 	printf("Done\n");
1432ce8d5614SIntel }
1433ce8d5614SIntel 
1434ce8d5614SIntel void
1435ce8d5614SIntel close_port(portid_t pid)
1436ce8d5614SIntel {
1437ce8d5614SIntel 	portid_t pi;
1438ce8d5614SIntel 	struct rte_port *port;
1439ce8d5614SIntel 
1440ce8d5614SIntel 	if (test_done == 0) {
1441ce8d5614SIntel 		printf("Please stop forwarding first\n");
1442ce8d5614SIntel 		return;
1443ce8d5614SIntel 	}
1444ce8d5614SIntel 
1445ce8d5614SIntel 	printf("Closing ports...\n");
1446ce8d5614SIntel 
1447ce8d5614SIntel 	for (pi = 0; pi < nb_ports; pi++) {
1448ce8d5614SIntel 		if (pid < nb_ports && pid != pi)
1449ce8d5614SIntel 			continue;
1450ce8d5614SIntel 
1451ce8d5614SIntel 		port = &ports[pi];
1452ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1453ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1454ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1455ce8d5614SIntel 			continue;
1456ce8d5614SIntel 		}
1457ce8d5614SIntel 
1458ce8d5614SIntel 		rte_eth_dev_close(pi);
1459ce8d5614SIntel 
1460ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1461ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1462ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1463ce8d5614SIntel 	}
1464ce8d5614SIntel 
1465ce8d5614SIntel 	printf("Done\n");
1466ce8d5614SIntel }
1467ce8d5614SIntel 
1468ce8d5614SIntel int
1469ce8d5614SIntel all_ports_stopped(void)
1470ce8d5614SIntel {
1471ce8d5614SIntel 	portid_t pi;
1472ce8d5614SIntel 	struct rte_port *port;
1473ce8d5614SIntel 
1474ce8d5614SIntel 	for (pi = 0; pi < nb_ports; pi++) {
1475ce8d5614SIntel 		port = &ports[pi];
1476ce8d5614SIntel 		if (port->port_status != RTE_PORT_STOPPED)
1477ce8d5614SIntel 			return 0;
1478ce8d5614SIntel 	}
1479ce8d5614SIntel 
1480ce8d5614SIntel 	return 1;
1481ce8d5614SIntel }
1482ce8d5614SIntel 
1483af75078fSIntel void
1484af75078fSIntel pmd_test_exit(void)
1485af75078fSIntel {
1486af75078fSIntel 	portid_t pt_id;
1487af75078fSIntel 
1488af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++) {
1489af75078fSIntel 		printf("Stopping port %d...", pt_id);
1490af75078fSIntel 		fflush(stdout);
1491af75078fSIntel 		rte_eth_dev_close(pt_id);
1492af75078fSIntel 		printf("done\n");
1493af75078fSIntel 	}
1494af75078fSIntel 	printf("bye...\n");
1495af75078fSIntel }
1496af75078fSIntel 
1497af75078fSIntel typedef void (*cmd_func_t)(void);
1498af75078fSIntel struct pmd_test_command {
1499af75078fSIntel 	const char *cmd_name;
1500af75078fSIntel 	cmd_func_t cmd_func;
1501af75078fSIntel };
1502af75078fSIntel 
1503af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1504af75078fSIntel 
1505ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1506af75078fSIntel static void
1507ce8d5614SIntel check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
1508af75078fSIntel {
1509ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1510ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1511ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1512ce8d5614SIntel 	struct rte_eth_link link;
1513ce8d5614SIntel 
1514ce8d5614SIntel 	printf("Checking link statuses...\n");
1515ce8d5614SIntel 	fflush(stdout);
1516ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1517ce8d5614SIntel 		all_ports_up = 1;
1518ce8d5614SIntel 		for (portid = 0; portid < port_num; portid++) {
1519ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1520ce8d5614SIntel 				continue;
1521ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1522ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1523ce8d5614SIntel 			/* print link status if flag set */
1524ce8d5614SIntel 			if (print_flag == 1) {
1525ce8d5614SIntel 				if (link.link_status)
1526ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1527ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1528ce8d5614SIntel 						(unsigned)link.link_speed,
1529ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1530ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1531ce8d5614SIntel 				else
1532ce8d5614SIntel 					printf("Port %d Link Down\n",
1533ce8d5614SIntel 						(uint8_t)portid);
1534ce8d5614SIntel 				continue;
1535ce8d5614SIntel 			}
1536ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
1537ce8d5614SIntel 			if (link.link_status == 0) {
1538ce8d5614SIntel 				all_ports_up = 0;
1539ce8d5614SIntel 				break;
1540ce8d5614SIntel 			}
1541ce8d5614SIntel 		}
1542ce8d5614SIntel 		/* after finally printing all link status, get out */
1543ce8d5614SIntel 		if (print_flag == 1)
1544ce8d5614SIntel 			break;
1545ce8d5614SIntel 
1546ce8d5614SIntel 		if (all_ports_up == 0) {
1547ce8d5614SIntel 			fflush(stdout);
1548ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1549ce8d5614SIntel 		}
1550ce8d5614SIntel 
1551ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1552ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1553ce8d5614SIntel 			print_flag = 1;
1554ce8d5614SIntel 		}
1555ce8d5614SIntel 	}
1556af75078fSIntel }
1557af75078fSIntel 
1558013af9b6SIntel static int
1559013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1560af75078fSIntel {
1561013af9b6SIntel 	uint16_t i;
1562af75078fSIntel 	int diag;
1563013af9b6SIntel 	uint8_t mapping_found = 0;
1564af75078fSIntel 
1565013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1566013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1567013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1568013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1569013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1570013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1571013af9b6SIntel 			if (diag != 0)
1572013af9b6SIntel 				return diag;
1573013af9b6SIntel 			mapping_found = 1;
1574af75078fSIntel 		}
1575013af9b6SIntel 	}
1576013af9b6SIntel 	if (mapping_found)
1577013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1578013af9b6SIntel 	return 0;
1579013af9b6SIntel }
1580013af9b6SIntel 
1581013af9b6SIntel static int
1582013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1583013af9b6SIntel {
1584013af9b6SIntel 	uint16_t i;
1585013af9b6SIntel 	int diag;
1586013af9b6SIntel 	uint8_t mapping_found = 0;
1587013af9b6SIntel 
1588013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1589013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1590013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1591013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1592013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1593013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1594013af9b6SIntel 			if (diag != 0)
1595013af9b6SIntel 				return diag;
1596013af9b6SIntel 			mapping_found = 1;
1597013af9b6SIntel 		}
1598013af9b6SIntel 	}
1599013af9b6SIntel 	if (mapping_found)
1600013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1601013af9b6SIntel 	return 0;
1602013af9b6SIntel }
1603013af9b6SIntel 
1604013af9b6SIntel static void
1605013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1606013af9b6SIntel {
1607013af9b6SIntel 	int diag = 0;
1608013af9b6SIntel 
1609013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1610af75078fSIntel 	if (diag != 0) {
1611013af9b6SIntel 		if (diag == -ENOTSUP) {
1612013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1613013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1614013af9b6SIntel 		}
1615013af9b6SIntel 		else
1616013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1617013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1618013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1619af75078fSIntel 					pi, diag);
1620af75078fSIntel 	}
1621013af9b6SIntel 
1622013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1623af75078fSIntel 	if (diag != 0) {
1624013af9b6SIntel 		if (diag == -ENOTSUP) {
1625013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1626013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1627013af9b6SIntel 		}
1628013af9b6SIntel 		else
1629013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1630013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1631013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1632af75078fSIntel 					pi, diag);
1633af75078fSIntel 	}
1634af75078fSIntel }
1635af75078fSIntel 
1636013af9b6SIntel void
1637013af9b6SIntel init_port_config(void)
1638013af9b6SIntel {
1639013af9b6SIntel 	portid_t pid;
1640013af9b6SIntel 	struct rte_port *port;
1641013af9b6SIntel 
1642013af9b6SIntel 	for (pid = 0; pid < nb_ports; pid++) {
1643013af9b6SIntel 		port = &ports[pid];
1644013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1645013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
16463ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1647013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1648013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1649af75078fSIntel 		} else {
1650013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1651013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1652af75078fSIntel 		}
16533ce690d3SBruce Richardson 
16543ce690d3SBruce Richardson 		/* In SR-IOV mode, RSS mode is not available */
16553ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
16563ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
16573ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
16583ce690d3SBruce Richardson 			else
16593ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
16603ce690d3SBruce Richardson 		}
16613ce690d3SBruce Richardson 
1662013af9b6SIntel 		port->rx_conf.rx_thresh = rx_thresh;
1663013af9b6SIntel 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1664013af9b6SIntel 		port->rx_conf.rx_drop_en = rx_drop_en;
1665013af9b6SIntel 		port->tx_conf.tx_thresh = tx_thresh;
1666013af9b6SIntel 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1667013af9b6SIntel 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1668013af9b6SIntel 		port->tx_conf.txq_flags = txq_flags;
1669013af9b6SIntel 
1670013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1671013af9b6SIntel 
1672013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
16737b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
16747b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
16757b7e5ba7SIntel #endif
1676013af9b6SIntel 	}
1677013af9b6SIntel }
1678013af9b6SIntel 
1679013af9b6SIntel const uint16_t vlan_tags[] = {
1680013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1681013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1682013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1683013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1684013af9b6SIntel };
1685013af9b6SIntel 
1686013af9b6SIntel static  int
1687013af9b6SIntel get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1688013af9b6SIntel {
1689013af9b6SIntel         uint8_t i;
1690af75078fSIntel 
1691af75078fSIntel  	/*
1692013af9b6SIntel  	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1693013af9b6SIntel  	 * given above, and the number of traffic classes available for use.
1694af75078fSIntel  	 */
1695013af9b6SIntel 	if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1696013af9b6SIntel 		struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1697013af9b6SIntel 		struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1698013af9b6SIntel 
1699013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
1700013af9b6SIntel 		vmdq_rx_conf.enable_default_pool = 0;
1701013af9b6SIntel 		vmdq_rx_conf.default_pool = 0;
1702013af9b6SIntel 		vmdq_rx_conf.nb_queue_pools =
1703013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1704013af9b6SIntel 		vmdq_tx_conf.nb_queue_pools =
1705013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1706013af9b6SIntel 
1707013af9b6SIntel 		vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1708013af9b6SIntel 		for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1709013af9b6SIntel 			vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1710013af9b6SIntel 			vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1711af75078fSIntel 		}
1712013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1713013af9b6SIntel 			vmdq_rx_conf.dcb_queue[i] = i;
1714013af9b6SIntel 			vmdq_tx_conf.dcb_queue[i] = i;
1715013af9b6SIntel 		}
1716013af9b6SIntel 
1717013af9b6SIntel 		/*set DCB mode of RX and TX of multiple queues*/
171832e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
171932e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1720013af9b6SIntel 		if (dcb_conf->pfc_en)
1721013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1722013af9b6SIntel 		else
1723013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1724013af9b6SIntel 
1725013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1726013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1727013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1728013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1729013af9b6SIntel 	}
1730013af9b6SIntel 	else {
1731013af9b6SIntel 		struct rte_eth_dcb_rx_conf rx_conf;
1732013af9b6SIntel 		struct rte_eth_dcb_tx_conf tx_conf;
1733013af9b6SIntel 
1734013af9b6SIntel 		/* queue mapping configuration of DCB RX and TX */
1735013af9b6SIntel 		if (dcb_conf->num_tcs == ETH_4_TCS)
1736013af9b6SIntel 			dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1737013af9b6SIntel 		else
1738013af9b6SIntel 			dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1739013af9b6SIntel 
1740013af9b6SIntel 		rx_conf.nb_tcs = dcb_conf->num_tcs;
1741013af9b6SIntel 		tx_conf.nb_tcs = dcb_conf->num_tcs;
1742013af9b6SIntel 
1743013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1744013af9b6SIntel 			rx_conf.dcb_queue[i] = i;
1745013af9b6SIntel 			tx_conf.dcb_queue[i] = i;
1746013af9b6SIntel 		}
174732e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
174832e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1749013af9b6SIntel 		if (dcb_conf->pfc_en)
1750013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1751013af9b6SIntel 		else
1752013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1753013af9b6SIntel 
1754013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1755013af9b6SIntel                                 sizeof(struct rte_eth_dcb_rx_conf)));
1756013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1757013af9b6SIntel                                 sizeof(struct rte_eth_dcb_tx_conf)));
1758013af9b6SIntel 	}
1759013af9b6SIntel 
1760013af9b6SIntel 	return 0;
1761013af9b6SIntel }
1762013af9b6SIntel 
1763013af9b6SIntel int
1764013af9b6SIntel init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1765013af9b6SIntel {
1766013af9b6SIntel 	struct rte_eth_conf port_conf;
1767013af9b6SIntel 	struct rte_port *rte_port;
1768013af9b6SIntel 	int retval;
1769013af9b6SIntel 	uint16_t nb_vlan;
1770013af9b6SIntel 	uint16_t i;
1771013af9b6SIntel 
1772013af9b6SIntel 	/* rxq and txq configuration in dcb mode */
1773013af9b6SIntel 	nb_rxq = 128;
1774013af9b6SIntel 	nb_txq = 128;
1775013af9b6SIntel 	rx_free_thresh = 64;
1776013af9b6SIntel 
1777013af9b6SIntel 	memset(&port_conf,0,sizeof(struct rte_eth_conf));
1778013af9b6SIntel 	/* Enter DCB configuration status */
1779013af9b6SIntel 	dcb_config = 1;
1780013af9b6SIntel 
1781013af9b6SIntel 	nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1782013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
1783013af9b6SIntel 	retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1784013af9b6SIntel 	if (retval < 0)
1785013af9b6SIntel 		return retval;
1786013af9b6SIntel 
1787013af9b6SIntel 	rte_port = &ports[pid];
1788013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1789013af9b6SIntel 
1790013af9b6SIntel 	rte_port->rx_conf.rx_thresh = rx_thresh;
1791013af9b6SIntel 	rte_port->rx_conf.rx_free_thresh = rx_free_thresh;
1792013af9b6SIntel 	rte_port->tx_conf.tx_thresh = tx_thresh;
1793013af9b6SIntel 	rte_port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1794013af9b6SIntel 	rte_port->tx_conf.tx_free_thresh = tx_free_thresh;
1795013af9b6SIntel 	/* VLAN filter */
1796013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1797013af9b6SIntel 	for (i = 0; i < nb_vlan; i++){
1798013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1799013af9b6SIntel 	}
1800013af9b6SIntel 
1801013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1802013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1803013af9b6SIntel 
18047741e4cfSIntel 	rte_port->dcb_flag = 1;
18057741e4cfSIntel 
1806013af9b6SIntel 	return 0;
1807af75078fSIntel }
1808af75078fSIntel 
1809af75078fSIntel #ifdef RTE_EXEC_ENV_BAREMETAL
1810af75078fSIntel #define main _main
1811af75078fSIntel #endif
1812af75078fSIntel 
1813af75078fSIntel int
1814af75078fSIntel main(int argc, char** argv)
1815af75078fSIntel {
1816af75078fSIntel 	int  diag;
1817013af9b6SIntel 	uint8_t port_id;
1818af75078fSIntel 
1819af75078fSIntel 	diag = rte_eal_init(argc, argv);
1820af75078fSIntel 	if (diag < 0)
1821af75078fSIntel 		rte_panic("Cannot init EAL\n");
1822af75078fSIntel 
1823af75078fSIntel 	if (rte_eal_pci_probe())
1824af75078fSIntel 		rte_panic("Cannot probe PCI\n");
1825af75078fSIntel 
1826af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
1827af75078fSIntel 	if (nb_ports == 0)
1828013af9b6SIntel 		rte_exit(EXIT_FAILURE, "No probed ethernet devices - "
1829013af9b6SIntel 							"check that "
1830af75078fSIntel 			  "CONFIG_RTE_LIBRTE_IGB_PMD=y and that "
183169d22b8eSIntel 			  "CONFIG_RTE_LIBRTE_EM_PMD=y and that "
1832af75078fSIntel 			  "CONFIG_RTE_LIBRTE_IXGBE_PMD=y in your "
1833af75078fSIntel 			  "configuration file\n");
1834af75078fSIntel 
1835af75078fSIntel 	set_def_fwd_config();
1836af75078fSIntel 	if (nb_lcores == 0)
1837af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
1838af75078fSIntel 			  "core mask supplied in the command parameters\n");
1839af75078fSIntel 
1840af75078fSIntel 	argc -= diag;
1841af75078fSIntel 	argv += diag;
1842af75078fSIntel 	if (argc > 1)
1843af75078fSIntel 		launch_args_parse(argc, argv);
1844af75078fSIntel 
1845af75078fSIntel 	if (nb_rxq > nb_txq)
1846af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
1847af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
1848af75078fSIntel 		       nb_rxq, nb_txq);
1849af75078fSIntel 
1850af75078fSIntel 	init_config();
1851148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
1852148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
1853af75078fSIntel 
1854ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
1855ce8d5614SIntel 	for (port_id = 0; port_id < nb_ports; port_id++)
1856ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
1857af75078fSIntel 
18580d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
1859ca7feb22SCyril Chemparathy 	if (interactive == 1) {
1860ca7feb22SCyril Chemparathy 		if (auto_start) {
1861ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
1862ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
1863ca7feb22SCyril Chemparathy 		}
1864af75078fSIntel 		prompt();
1865ca7feb22SCyril Chemparathy 	} else
18660d56cb81SThomas Monjalon #endif
18670d56cb81SThomas Monjalon 	{
1868af75078fSIntel 		char c;
1869af75078fSIntel 		int rc;
1870af75078fSIntel 
1871af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
1872af75078fSIntel 		start_packet_forwarding(0);
1873af75078fSIntel 		printf("Press enter to exit\n");
1874af75078fSIntel 		rc = read(0, &c, 1);
1875af75078fSIntel 		if (rc < 0)
1876af75078fSIntel 			return 1;
1877af75078fSIntel 	}
1878af75078fSIntel 
1879af75078fSIntel 	return 0;
1880af75078fSIntel }
1881