xref: /dpdk/app/test-pmd/testpmd.c (revision ea0c20ea95fd5d71a10757e6598ac66233ea1495)
1af75078fSIntel /*-
2af75078fSIntel  *   BSD LICENSE
3af75078fSIntel  *
4e9d48c00SBruce Richardson  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5af75078fSIntel  *   All rights reserved.
6af75078fSIntel  *
7af75078fSIntel  *   Redistribution and use in source and binary forms, with or without
8af75078fSIntel  *   modification, are permitted provided that the following conditions
9af75078fSIntel  *   are met:
10af75078fSIntel  *
11af75078fSIntel  *     * Redistributions of source code must retain the above copyright
12af75078fSIntel  *       notice, this list of conditions and the following disclaimer.
13af75078fSIntel  *     * Redistributions in binary form must reproduce the above copyright
14af75078fSIntel  *       notice, this list of conditions and the following disclaimer in
15af75078fSIntel  *       the documentation and/or other materials provided with the
16af75078fSIntel  *       distribution.
17af75078fSIntel  *     * Neither the name of Intel Corporation nor the names of its
18af75078fSIntel  *       contributors may be used to endorse or promote products derived
19af75078fSIntel  *       from this software without specific prior written permission.
20af75078fSIntel  *
21af75078fSIntel  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22af75078fSIntel  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23af75078fSIntel  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24af75078fSIntel  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25af75078fSIntel  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26af75078fSIntel  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27af75078fSIntel  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28af75078fSIntel  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29af75078fSIntel  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30af75078fSIntel  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31af75078fSIntel  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32af75078fSIntel  */
33af75078fSIntel 
34af75078fSIntel #include <stdarg.h>
35af75078fSIntel #include <stdio.h>
36af75078fSIntel #include <stdlib.h>
37af75078fSIntel #include <signal.h>
38af75078fSIntel #include <string.h>
39af75078fSIntel #include <time.h>
40af75078fSIntel #include <fcntl.h>
41af75078fSIntel #include <sys/types.h>
42af75078fSIntel #include <errno.h>
43af75078fSIntel 
44af75078fSIntel #include <sys/queue.h>
45af75078fSIntel #include <sys/stat.h>
46af75078fSIntel 
47af75078fSIntel #include <stdint.h>
48af75078fSIntel #include <unistd.h>
49af75078fSIntel #include <inttypes.h>
50af75078fSIntel 
51af75078fSIntel #include <rte_common.h>
52af75078fSIntel #include <rte_byteorder.h>
53af75078fSIntel #include <rte_log.h>
54af75078fSIntel #include <rte_debug.h>
55af75078fSIntel #include <rte_cycles.h>
56af75078fSIntel #include <rte_memory.h>
57af75078fSIntel #include <rte_memcpy.h>
58af75078fSIntel #include <rte_memzone.h>
59af75078fSIntel #include <rte_launch.h>
60af75078fSIntel #include <rte_eal.h>
61af75078fSIntel #include <rte_per_lcore.h>
62af75078fSIntel #include <rte_lcore.h>
63af75078fSIntel #include <rte_atomic.h>
64af75078fSIntel #include <rte_branch_prediction.h>
65af75078fSIntel #include <rte_ring.h>
66af75078fSIntel #include <rte_mempool.h>
67af75078fSIntel #include <rte_malloc.h>
68af75078fSIntel #include <rte_mbuf.h>
69af75078fSIntel #include <rte_interrupts.h>
70af75078fSIntel #include <rte_pci.h>
71af75078fSIntel #include <rte_ether.h>
72af75078fSIntel #include <rte_ethdev.h>
73edab33b1STetsuya Mukawa #include <rte_dev.h>
74af75078fSIntel #include <rte_string_fns.h>
75148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
76148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
77148f963fSBruce Richardson #endif
78af75078fSIntel 
79af75078fSIntel #include "testpmd.h"
80148f963fSBruce Richardson #include "mempool_osdep.h"
81af75078fSIntel 
82af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
83af75078fSIntel 
84af75078fSIntel /* use master core for command line ? */
85af75078fSIntel uint8_t interactive = 0;
86ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
87af75078fSIntel 
88af75078fSIntel /*
89af75078fSIntel  * NUMA support configuration.
90af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
91af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
92af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
93af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
94af75078fSIntel  */
95af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */
96af75078fSIntel 
97af75078fSIntel /*
98b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
99b6ea6408SIntel  * not configured.
100b6ea6408SIntel  */
101b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
102b6ea6408SIntel 
103b6ea6408SIntel /*
104148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
105148f963fSBruce Richardson  */
106148f963fSBruce Richardson uint8_t mp_anon = 0;
107148f963fSBruce Richardson 
108148f963fSBruce Richardson /*
109af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
110af75078fSIntel  * forwarded.
111af75078fSIntel  * Must be instanciated with the ethernet addresses of peer traffic generator
112af75078fSIntel  * ports.
113af75078fSIntel  */
114af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
115af75078fSIntel portid_t nb_peer_eth_addrs = 0;
116af75078fSIntel 
117af75078fSIntel /*
118af75078fSIntel  * Probed Target Environment.
119af75078fSIntel  */
120af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
121af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
122af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
123af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
124af75078fSIntel 
125af75078fSIntel /*
126af75078fSIntel  * Test Forwarding Configuration.
127af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
128af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
129af75078fSIntel  */
130af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
131af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
132af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
133af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
134af75078fSIntel 
135af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
136af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
137af75078fSIntel 
138af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
139af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
140af75078fSIntel 
141af75078fSIntel /*
142af75078fSIntel  * Forwarding engines.
143af75078fSIntel  */
144af75078fSIntel struct fwd_engine * fwd_engines[] = {
145af75078fSIntel 	&io_fwd_engine,
146af75078fSIntel 	&mac_fwd_engine,
14757e85242SBruce Richardson 	&mac_retry_fwd_engine,
148d47388f1SCyril Chemparathy 	&mac_swap_engine,
149e9e23a61SCyril Chemparathy 	&flow_gen_engine,
150af75078fSIntel 	&rx_only_engine,
151af75078fSIntel 	&tx_only_engine,
152af75078fSIntel 	&csum_fwd_engine,
153168dfa61SIvan Boule 	&icmp_echo_engine,
154af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
155af75078fSIntel 	&ieee1588_fwd_engine,
156af75078fSIntel #endif
157af75078fSIntel 	NULL,
158af75078fSIntel };
159af75078fSIntel 
160af75078fSIntel struct fwd_config cur_fwd_config;
161af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
162af75078fSIntel 
163af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
164c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
165c8798818SIntel                                       * specified on command-line. */
166af75078fSIntel 
167af75078fSIntel /*
168af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
169af75078fSIntel  */
170af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
171af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
172af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
173af75078fSIntel };
174af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
175af75078fSIntel 
176af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
177e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
178af75078fSIntel 
179900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
180900550deSIntel uint8_t dcb_config = 0;
181900550deSIntel 
182900550deSIntel /* Whether the dcb is in testing status */
183900550deSIntel uint8_t dcb_test = 0;
184900550deSIntel 
185900550deSIntel /* DCB on and VT on mapping is default */
186900550deSIntel enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
187af75078fSIntel 
188af75078fSIntel /*
189af75078fSIntel  * Configurable number of RX/TX queues.
190af75078fSIntel  */
191af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
192af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
193af75078fSIntel 
194af75078fSIntel /*
195af75078fSIntel  * Configurable number of RX/TX ring descriptors.
196af75078fSIntel  */
197af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
198af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
199af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
200af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
201af75078fSIntel 
202f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
203af75078fSIntel /*
204af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
205af75078fSIntel  */
206af75078fSIntel 
207f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
208f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
209f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
210af75078fSIntel 
211f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
212f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
213f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
214af75078fSIntel 
215af75078fSIntel /*
216af75078fSIntel  * Configurable value of RX free threshold.
217af75078fSIntel  */
218f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
219af75078fSIntel 
220af75078fSIntel /*
221ce8d5614SIntel  * Configurable value of RX drop enable.
222ce8d5614SIntel  */
223f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
224ce8d5614SIntel 
225ce8d5614SIntel /*
226af75078fSIntel  * Configurable value of TX free threshold.
227af75078fSIntel  */
228f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
229af75078fSIntel 
230af75078fSIntel /*
231af75078fSIntel  * Configurable value of TX RS bit threshold.
232af75078fSIntel  */
233f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
234af75078fSIntel 
235af75078fSIntel /*
236ce8d5614SIntel  * Configurable value of TX queue flags.
237ce8d5614SIntel  */
238f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
239ce8d5614SIntel 
240ce8d5614SIntel /*
241af75078fSIntel  * Receive Side Scaling (RSS) configuration.
242af75078fSIntel  */
2438a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
244af75078fSIntel 
245af75078fSIntel /*
246af75078fSIntel  * Port topology configuration
247af75078fSIntel  */
248af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
249af75078fSIntel 
2507741e4cfSIntel /*
2517741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2527741e4cfSIntel  */
2537741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2547741e4cfSIntel 
255af75078fSIntel /*
256bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
257bc202406SDavid Marchand  */
258bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
259bc202406SDavid Marchand 
260bc202406SDavid Marchand /*
2617b7e5ba7SIntel  * NIC bypass mode configuration options.
2627b7e5ba7SIntel  */
2637b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
2647b7e5ba7SIntel 
2657b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
2667b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
2677b7e5ba7SIntel 
2687b7e5ba7SIntel #endif
2697b7e5ba7SIntel 
2707b7e5ba7SIntel /*
271af75078fSIntel  * Ethernet device configuration.
272af75078fSIntel  */
273af75078fSIntel struct rte_eth_rxmode rx_mode = {
274af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
275af75078fSIntel 	.split_hdr_size = 0,
276af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
277af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
278af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
279a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
280a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
281af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
282af75078fSIntel 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
283af75078fSIntel };
284af75078fSIntel 
285af75078fSIntel struct rte_fdir_conf fdir_conf = {
286af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
287af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
288af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
289d9d5e6f2SJingjing Wu 	.mask = {
290d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
291d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
292d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
293d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
294d9d5e6f2SJingjing Wu 		},
295d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
296d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
297d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
298d9d5e6f2SJingjing Wu 		},
299d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
300d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
301d9d5e6f2SJingjing Wu 	},
302af75078fSIntel 	.drop_queue = 127,
303af75078fSIntel };
304af75078fSIntel 
3052950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
306af75078fSIntel 
307ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
308ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
309ed30d9b6SIntel 
310ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
311ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
312ed30d9b6SIntel 
313ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
314ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
315ed30d9b6SIntel 
316ed30d9b6SIntel /* Forward function declarations */
317ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
318edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
319ce8d5614SIntel 
320ce8d5614SIntel /*
321ce8d5614SIntel  * Check if all the ports are started.
322ce8d5614SIntel  * If yes, return positive value. If not, return zero.
323ce8d5614SIntel  */
324ce8d5614SIntel static int all_ports_started(void);
325ed30d9b6SIntel 
326af75078fSIntel /*
327edab33b1STetsuya Mukawa  * Find next enabled port
328edab33b1STetsuya Mukawa  */
329edab33b1STetsuya Mukawa portid_t
330edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
331edab33b1STetsuya Mukawa {
332edab33b1STetsuya Mukawa 	if (ports == NULL)
333edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
334edab33b1STetsuya Mukawa 
33512a8e30fSJulien Cretin 	while ((p < size) && (ports[p].enabled == 0))
336edab33b1STetsuya Mukawa 		p++;
337edab33b1STetsuya Mukawa 	return p;
338edab33b1STetsuya Mukawa }
339edab33b1STetsuya Mukawa 
340edab33b1STetsuya Mukawa /*
341af75078fSIntel  * Setup default configuration.
342af75078fSIntel  */
343af75078fSIntel static void
344af75078fSIntel set_default_fwd_lcores_config(void)
345af75078fSIntel {
346af75078fSIntel 	unsigned int i;
347af75078fSIntel 	unsigned int nb_lc;
348af75078fSIntel 
349af75078fSIntel 	nb_lc = 0;
350af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
351af75078fSIntel 		if (! rte_lcore_is_enabled(i))
352af75078fSIntel 			continue;
353af75078fSIntel 		if (i == rte_get_master_lcore())
354af75078fSIntel 			continue;
355af75078fSIntel 		fwd_lcores_cpuids[nb_lc++] = i;
356af75078fSIntel 	}
357af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
358af75078fSIntel 	nb_cfg_lcores = nb_lcores;
359af75078fSIntel 	nb_fwd_lcores = 1;
360af75078fSIntel }
361af75078fSIntel 
362af75078fSIntel static void
363af75078fSIntel set_def_peer_eth_addrs(void)
364af75078fSIntel {
365af75078fSIntel 	portid_t i;
366af75078fSIntel 
367af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
368af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
369af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
370af75078fSIntel 	}
371af75078fSIntel }
372af75078fSIntel 
373af75078fSIntel static void
374af75078fSIntel set_default_fwd_ports_config(void)
375af75078fSIntel {
376af75078fSIntel 	portid_t pt_id;
377af75078fSIntel 
378af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
379af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
380af75078fSIntel 
381af75078fSIntel 	nb_cfg_ports = nb_ports;
382af75078fSIntel 	nb_fwd_ports = nb_ports;
383af75078fSIntel }
384af75078fSIntel 
385af75078fSIntel void
386af75078fSIntel set_def_fwd_config(void)
387af75078fSIntel {
388af75078fSIntel 	set_default_fwd_lcores_config();
389af75078fSIntel 	set_def_peer_eth_addrs();
390af75078fSIntel 	set_default_fwd_ports_config();
391af75078fSIntel }
392af75078fSIntel 
393af75078fSIntel /*
394af75078fSIntel  * Configuration initialisation done once at init time.
395af75078fSIntel  */
396af75078fSIntel static void
397af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
398af75078fSIntel 		 unsigned int socket_id)
399af75078fSIntel {
400af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
401af75078fSIntel 	struct rte_mempool *rte_mp;
402af75078fSIntel 	uint32_t mb_size;
403af75078fSIntel 
404dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
405af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
406148f963fSBruce Richardson 
407148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
408148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
409af75078fSIntel 		(unsigned) mb_mempool_cache,
410af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
411dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
412dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
413af75078fSIntel 		socket_id, 0);
414148f963fSBruce Richardson 
415148f963fSBruce Richardson 
416148f963fSBruce Richardson 
417148f963fSBruce Richardson #else
418148f963fSBruce Richardson 	if (mp_anon != 0)
419148f963fSBruce Richardson 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
420148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
421148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
422dfb03bbeSOlivier Matz 				    rte_pktmbuf_pool_init, NULL,
423dfb03bbeSOlivier Matz 				    rte_pktmbuf_init, NULL,
424148f963fSBruce Richardson 				    socket_id, 0);
425148f963fSBruce Richardson 	else
426*ea0c20eaSOlivier Matz 		/* wrapper to rte_mempool_create() */
427*ea0c20eaSOlivier Matz 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
428*ea0c20eaSOlivier Matz 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
429148f963fSBruce Richardson 
430148f963fSBruce Richardson #endif
431148f963fSBruce Richardson 
432af75078fSIntel 	if (rte_mp == NULL) {
433ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
434ce8d5614SIntel 						"failed\n", socket_id);
435148f963fSBruce Richardson 	} else if (verbose_level > 0) {
436591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
437af75078fSIntel 	}
438af75078fSIntel }
439af75078fSIntel 
44020a0286fSLiu Xiaofeng /*
44120a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
44220a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
44320a0286fSLiu Xiaofeng  */
44420a0286fSLiu Xiaofeng static int
44520a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
44620a0286fSLiu Xiaofeng {
44720a0286fSLiu Xiaofeng 	static int warning_once = 0;
44820a0286fSLiu Xiaofeng 
44920a0286fSLiu Xiaofeng 	if (socket_id >= MAX_SOCKET) {
45020a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
45120a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
45220a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
45320a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
45420a0286fSLiu Xiaofeng 			       " --numa.\n");
45520a0286fSLiu Xiaofeng 		warning_once = 1;
45620a0286fSLiu Xiaofeng 		return -1;
45720a0286fSLiu Xiaofeng 	}
45820a0286fSLiu Xiaofeng 	return 0;
45920a0286fSLiu Xiaofeng }
46020a0286fSLiu Xiaofeng 
461af75078fSIntel static void
462af75078fSIntel init_config(void)
463af75078fSIntel {
464ce8d5614SIntel 	portid_t pid;
465af75078fSIntel 	struct rte_port *port;
466af75078fSIntel 	struct rte_mempool *mbp;
467af75078fSIntel 	unsigned int nb_mbuf_per_pool;
468af75078fSIntel 	lcoreid_t  lc_id;
469b6ea6408SIntel 	uint8_t port_per_socket[MAX_SOCKET];
470af75078fSIntel 
471b6ea6408SIntel 	memset(port_per_socket,0,MAX_SOCKET);
472af75078fSIntel 	/* Configuration of logical cores. */
473af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
474af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
475fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
476af75078fSIntel 	if (fwd_lcores == NULL) {
477ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
478ce8d5614SIntel 							"failed\n", nb_lcores);
479af75078fSIntel 	}
480af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
481af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
482af75078fSIntel 					       sizeof(struct fwd_lcore),
483fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
484af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
485ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
486ce8d5614SIntel 								"failed\n");
487af75078fSIntel 		}
488af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
489af75078fSIntel 	}
490af75078fSIntel 
491af75078fSIntel 	/*
492af75078fSIntel 	 * Create pools of mbuf.
493af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
494b6ea6408SIntel 	 * socket 0 memory by default.
495af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
496c8798818SIntel 	 *
497c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
498c8798818SIntel 	 * nb_txd can be configured at run time.
499af75078fSIntel 	 */
500c8798818SIntel 	if (param_total_num_mbufs)
501c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
502c8798818SIntel 	else {
503c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
504c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
505b6ea6408SIntel 
506b6ea6408SIntel 		if (!numa_support)
507edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
508edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
509c8798818SIntel 	}
510af75078fSIntel 
511b6ea6408SIntel 	if (!numa_support) {
512b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
513b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
514b6ea6408SIntel 		else
515b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
516b6ea6408SIntel 						 socket_num);
517b6ea6408SIntel 	}
518af75078fSIntel 
519edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
520ce8d5614SIntel 		port = &ports[pid];
521ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
522ce8d5614SIntel 
523b6ea6408SIntel 		if (numa_support) {
524b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
525b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
526b6ea6408SIntel 			else {
527b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
52820a0286fSLiu Xiaofeng 
52920a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
53020a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
53120a0286fSLiu Xiaofeng 					socket_id = 0;
532b6ea6408SIntel 				port_per_socket[socket_id]++;
533b6ea6408SIntel 			}
534b6ea6408SIntel 		}
535b6ea6408SIntel 
536ce8d5614SIntel 		/* set flag to initialize port/queue */
537ce8d5614SIntel 		port->need_reconfig = 1;
538ce8d5614SIntel 		port->need_reconfig_queues = 1;
539ce8d5614SIntel 	}
540ce8d5614SIntel 
541b6ea6408SIntel 	if (numa_support) {
542b6ea6408SIntel 		uint8_t i;
543b6ea6408SIntel 		unsigned int nb_mbuf;
544ce8d5614SIntel 
545b6ea6408SIntel 		if (param_total_num_mbufs)
546b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
547b6ea6408SIntel 
548b6ea6408SIntel 		for (i = 0; i < MAX_SOCKET; i++) {
549edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
550b6ea6408SIntel 			if (nb_mbuf)
551b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
552b6ea6408SIntel 						nb_mbuf,i);
553b6ea6408SIntel 		}
554b6ea6408SIntel 	}
555b6ea6408SIntel 	init_port_config();
5565886ae07SAdrien Mazarguil 
5575886ae07SAdrien Mazarguil 	/*
5585886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
5595886ae07SAdrien Mazarguil 	 */
5605886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
5618fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
5628fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
5638fd8bebcSAdrien Mazarguil 
5645886ae07SAdrien Mazarguil 		if (mbp == NULL)
5655886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
5665886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
5675886ae07SAdrien Mazarguil 	}
5685886ae07SAdrien Mazarguil 
569ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
570ce8d5614SIntel 	if (init_fwd_streams() < 0)
571ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
572ce8d5614SIntel }
573ce8d5614SIntel 
5742950a769SDeclan Doherty 
5752950a769SDeclan Doherty void
576a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
5772950a769SDeclan Doherty {
5782950a769SDeclan Doherty 	struct rte_port *port;
5792950a769SDeclan Doherty 
5802950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
5812950a769SDeclan Doherty 	port = &ports[new_port_id];
5822950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
5832950a769SDeclan Doherty 
5842950a769SDeclan Doherty 	/* set flag to initialize port/queue */
5852950a769SDeclan Doherty 	port->need_reconfig = 1;
5862950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
587a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
5882950a769SDeclan Doherty 
5892950a769SDeclan Doherty 	init_port_config();
5902950a769SDeclan Doherty }
5912950a769SDeclan Doherty 
5922950a769SDeclan Doherty 
593ce8d5614SIntel int
594ce8d5614SIntel init_fwd_streams(void)
595ce8d5614SIntel {
596ce8d5614SIntel 	portid_t pid;
597ce8d5614SIntel 	struct rte_port *port;
598ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
599ce8d5614SIntel 
600ce8d5614SIntel 	/* set socket id according to numa or not */
601edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
602ce8d5614SIntel 		port = &ports[pid];
603ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
604ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
605ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
606ce8d5614SIntel 				port->dev_info.max_rx_queues);
607ce8d5614SIntel 			return -1;
608ce8d5614SIntel 		}
609ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
610ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
611ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
612ce8d5614SIntel 				port->dev_info.max_tx_queues);
613ce8d5614SIntel 			return -1;
614ce8d5614SIntel 		}
61520a0286fSLiu Xiaofeng 		if (numa_support) {
61620a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
61720a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
61820a0286fSLiu Xiaofeng 			else {
619b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
62020a0286fSLiu Xiaofeng 
62120a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
62220a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
62320a0286fSLiu Xiaofeng 					port->socket_id = 0;
62420a0286fSLiu Xiaofeng 			}
62520a0286fSLiu Xiaofeng 		}
626b6ea6408SIntel 		else {
627b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
628af75078fSIntel 				port->socket_id = 0;
629b6ea6408SIntel 			else
630b6ea6408SIntel 				port->socket_id = socket_num;
631b6ea6408SIntel 		}
632af75078fSIntel 	}
633af75078fSIntel 
634ce8d5614SIntel 	nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
635ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
636ce8d5614SIntel 		return 0;
637ce8d5614SIntel 	/* clear the old */
638ce8d5614SIntel 	if (fwd_streams != NULL) {
639ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
640ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
641ce8d5614SIntel 				continue;
642ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
643ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
644af75078fSIntel 		}
645ce8d5614SIntel 		rte_free(fwd_streams);
646ce8d5614SIntel 		fwd_streams = NULL;
647ce8d5614SIntel 	}
648ce8d5614SIntel 
649ce8d5614SIntel 	/* init new */
650ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
651ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
652fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
653ce8d5614SIntel 	if (fwd_streams == NULL)
654ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
655ce8d5614SIntel 						"failed\n", nb_fwd_streams);
656ce8d5614SIntel 
657af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
658af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
659fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
660ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
661ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
662ce8d5614SIntel 								" failed\n");
663af75078fSIntel 	}
664ce8d5614SIntel 
665ce8d5614SIntel 	return 0;
666af75078fSIntel }
667af75078fSIntel 
668af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
669af75078fSIntel static void
670af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
671af75078fSIntel {
672af75078fSIntel 	unsigned int total_burst;
673af75078fSIntel 	unsigned int nb_burst;
674af75078fSIntel 	unsigned int burst_stats[3];
675af75078fSIntel 	uint16_t pktnb_stats[3];
676af75078fSIntel 	uint16_t nb_pkt;
677af75078fSIntel 	int burst_percent[3];
678af75078fSIntel 
679af75078fSIntel 	/*
680af75078fSIntel 	 * First compute the total number of packet bursts and the
681af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
682af75078fSIntel 	 */
683af75078fSIntel 	total_burst = 0;
684af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
685af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
686af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
687af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
688af75078fSIntel 		if (nb_burst == 0)
689af75078fSIntel 			continue;
690af75078fSIntel 		total_burst += nb_burst;
691af75078fSIntel 		if (nb_burst > burst_stats[0]) {
692af75078fSIntel 			burst_stats[1] = burst_stats[0];
693af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
694af75078fSIntel 			burst_stats[0] = nb_burst;
695af75078fSIntel 			pktnb_stats[0] = nb_pkt;
696af75078fSIntel 		}
697af75078fSIntel 	}
698af75078fSIntel 	if (total_burst == 0)
699af75078fSIntel 		return;
700af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
701af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
702af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
703af75078fSIntel 	if (burst_stats[0] == total_burst) {
704af75078fSIntel 		printf("]\n");
705af75078fSIntel 		return;
706af75078fSIntel 	}
707af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
708af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
709af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
710af75078fSIntel 		return;
711af75078fSIntel 	}
712af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
713af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
714af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
715af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
716af75078fSIntel 		return;
717af75078fSIntel 	}
718af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
719af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
720af75078fSIntel }
721af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
722af75078fSIntel 
723af75078fSIntel static void
724af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
725af75078fSIntel {
726af75078fSIntel 	struct rte_port *port;
727013af9b6SIntel 	uint8_t i;
728af75078fSIntel 
729af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
730af75078fSIntel 
731af75078fSIntel 	port = &ports[port_id];
732af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
733af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
734013af9b6SIntel 
735013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
736af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
737af75078fSIntel 		       "%-"PRIu64"\n",
73870bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
73970bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
740af75078fSIntel 
741af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
742af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
743af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
74470bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
74570bdb186SIvan Boule 			printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
74670bdb186SIvan Boule 			       "RX-error: %-"PRIu64"\n",
74770bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
74870bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
74970bdb186SIvan Boule 		}
750af75078fSIntel 
751af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
752af75078fSIntel 		       "%-"PRIu64"\n",
753af75078fSIntel 		       stats->opackets, port->tx_dropped,
754af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
755013af9b6SIntel 	}
756013af9b6SIntel 	else {
757013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
758013af9b6SIntel 		       "%14"PRIu64"\n",
75970bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
76070bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
761013af9b6SIntel 
762013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
763013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
764013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
76570bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
76670bdb186SIvan Boule 			printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
76770bdb186SIvan Boule 			       "    RX-error:%"PRIu64"\n",
76870bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
76970bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
77070bdb186SIvan Boule 			       stats->rx_nombuf);
77170bdb186SIvan Boule 		}
772013af9b6SIntel 
773013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
774013af9b6SIntel 		       "%14"PRIu64"\n",
775013af9b6SIntel 		       stats->opackets, port->tx_dropped,
776013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
777013af9b6SIntel 	}
778e659b6b4SIvan Boule 
779e659b6b4SIvan Boule 	/* Display statistics of XON/XOFF pause frames, if any. */
780e659b6b4SIvan Boule 	if ((stats->tx_pause_xon  | stats->rx_pause_xon |
781e659b6b4SIvan Boule 	     stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
782e659b6b4SIvan Boule 		printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
783e659b6b4SIvan Boule 		       stats->rx_pause_xoff, stats->rx_pause_xon);
784e659b6b4SIvan Boule 		printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
785e659b6b4SIvan Boule 		       stats->tx_pause_xoff, stats->tx_pause_xon);
786e659b6b4SIvan Boule 	}
787e659b6b4SIvan Boule 
788af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
789af75078fSIntel 	if (port->rx_stream)
790013af9b6SIntel 		pkt_burst_stats_display("RX",
791013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
792af75078fSIntel 	if (port->tx_stream)
793013af9b6SIntel 		pkt_burst_stats_display("TX",
794013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
795af75078fSIntel #endif
796af75078fSIntel 	/* stats fdir */
797af75078fSIntel 	if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
798013af9b6SIntel 		printf("  Fdirmiss:%14"PRIu64"	  Fdirmatch:%14"PRIu64"\n",
799af75078fSIntel 		       stats->fdirmiss,
800af75078fSIntel 		       stats->fdirmatch);
801af75078fSIntel 
802013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
803013af9b6SIntel 		printf("\n");
804013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
805013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
806013af9b6SIntel 			       "     RX-errors:%14"PRIu64
807013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
808013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
809013af9b6SIntel 		}
810013af9b6SIntel 		printf("\n");
811013af9b6SIntel 	}
812013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
813013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
814013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
815013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
816013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
817013af9b6SIntel 		}
818013af9b6SIntel 	}
819013af9b6SIntel 
820af75078fSIntel 	printf("  %s--------------------------------%s\n",
821af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
822af75078fSIntel }
823af75078fSIntel 
824af75078fSIntel static void
825af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
826af75078fSIntel {
827af75078fSIntel 	struct fwd_stream *fs;
828af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
829af75078fSIntel 
830af75078fSIntel 	fs = fwd_streams[stream_id];
831af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
832af75078fSIntel 	    (fs->fwd_dropped == 0))
833af75078fSIntel 		return;
834af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
835af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
836af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
837af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
838af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
839af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
840af75078fSIntel 
841af75078fSIntel 	/* if checksum mode */
842af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
843013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
844013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
845af75078fSIntel 	}
846af75078fSIntel 
847af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
848af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
849af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
850af75078fSIntel #endif
851af75078fSIntel }
852af75078fSIntel 
853af75078fSIntel static void
8547741e4cfSIntel flush_fwd_rx_queues(void)
855af75078fSIntel {
856af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
857af75078fSIntel 	portid_t  rxp;
8587741e4cfSIntel 	portid_t port_id;
859af75078fSIntel 	queueid_t rxq;
860af75078fSIntel 	uint16_t  nb_rx;
861af75078fSIntel 	uint16_t  i;
862af75078fSIntel 	uint8_t   j;
863af75078fSIntel 
864af75078fSIntel 	for (j = 0; j < 2; j++) {
8657741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
866af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
8677741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
868af75078fSIntel 				do {
8697741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
870013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
871af75078fSIntel 					for (i = 0; i < nb_rx; i++)
872af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
873af75078fSIntel 				} while (nb_rx > 0);
874af75078fSIntel 			}
875af75078fSIntel 		}
876af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
877af75078fSIntel 	}
878af75078fSIntel }
879af75078fSIntel 
880af75078fSIntel static void
881af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
882af75078fSIntel {
883af75078fSIntel 	struct fwd_stream **fsm;
884af75078fSIntel 	streamid_t nb_fs;
885af75078fSIntel 	streamid_t sm_id;
886af75078fSIntel 
887af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
888af75078fSIntel 	nb_fs = fc->stream_nb;
889af75078fSIntel 	do {
890af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
891af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
892af75078fSIntel 	} while (! fc->stopped);
893af75078fSIntel }
894af75078fSIntel 
895af75078fSIntel static int
896af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
897af75078fSIntel {
898af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
899af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
900af75078fSIntel 	return 0;
901af75078fSIntel }
902af75078fSIntel 
903af75078fSIntel /*
904af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
905af75078fSIntel  * Used to start communication flows in network loopback test configurations.
906af75078fSIntel  */
907af75078fSIntel static int
908af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
909af75078fSIntel {
910af75078fSIntel 	struct fwd_lcore *fwd_lc;
911af75078fSIntel 	struct fwd_lcore tmp_lcore;
912af75078fSIntel 
913af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
914af75078fSIntel 	tmp_lcore = *fwd_lc;
915af75078fSIntel 	tmp_lcore.stopped = 1;
916af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
917af75078fSIntel 	return 0;
918af75078fSIntel }
919af75078fSIntel 
920af75078fSIntel /*
921af75078fSIntel  * Launch packet forwarding:
922af75078fSIntel  *     - Setup per-port forwarding context.
923af75078fSIntel  *     - launch logical cores with their forwarding configuration.
924af75078fSIntel  */
925af75078fSIntel static void
926af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
927af75078fSIntel {
928af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
929af75078fSIntel 	unsigned int i;
930af75078fSIntel 	unsigned int lc_id;
931af75078fSIntel 	int diag;
932af75078fSIntel 
933af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
934af75078fSIntel 	if (port_fwd_begin != NULL) {
935af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
936af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
937af75078fSIntel 	}
938af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
939af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
940af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
941af75078fSIntel 			fwd_lcores[i]->stopped = 0;
942af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
943af75078fSIntel 						     fwd_lcores[i], lc_id);
944af75078fSIntel 			if (diag != 0)
945af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
946af75078fSIntel 				       lc_id, diag);
947af75078fSIntel 		}
948af75078fSIntel 	}
949af75078fSIntel }
950af75078fSIntel 
951af75078fSIntel /*
952af75078fSIntel  * Launch packet forwarding configuration.
953af75078fSIntel  */
954af75078fSIntel void
955af75078fSIntel start_packet_forwarding(int with_tx_first)
956af75078fSIntel {
957af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
958af75078fSIntel 	port_fwd_end_t  port_fwd_end;
959af75078fSIntel 	struct rte_port *port;
960af75078fSIntel 	unsigned int i;
961af75078fSIntel 	portid_t   pt_id;
962af75078fSIntel 	streamid_t sm_id;
963af75078fSIntel 
964ce8d5614SIntel 	if (all_ports_started() == 0) {
965ce8d5614SIntel 		printf("Not all ports were started\n");
966ce8d5614SIntel 		return;
967ce8d5614SIntel 	}
968af75078fSIntel 	if (test_done == 0) {
969af75078fSIntel 		printf("Packet forwarding already started\n");
970af75078fSIntel 		return;
971af75078fSIntel 	}
9727741e4cfSIntel 	if(dcb_test) {
9737741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
9747741e4cfSIntel 			pt_id = fwd_ports_ids[i];
9757741e4cfSIntel 			port = &ports[pt_id];
9767741e4cfSIntel 			if (!port->dcb_flag) {
9777741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
9787741e4cfSIntel                                        "be configured in this mode.\n");
979013af9b6SIntel 				return;
980013af9b6SIntel 			}
9817741e4cfSIntel 		}
9827741e4cfSIntel 		if (nb_fwd_lcores == 1) {
9837741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
9847741e4cfSIntel                                "should be larger than 1.\n");
9857741e4cfSIntel 			return;
9867741e4cfSIntel 		}
9877741e4cfSIntel 	}
988af75078fSIntel 	test_done = 0;
9897741e4cfSIntel 
9907741e4cfSIntel 	if(!no_flush_rx)
9917741e4cfSIntel 		flush_fwd_rx_queues();
9927741e4cfSIntel 
993af75078fSIntel 	fwd_config_setup();
994af75078fSIntel 	rxtx_config_display();
995af75078fSIntel 
996af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
997af75078fSIntel 		pt_id = fwd_ports_ids[i];
998af75078fSIntel 		port = &ports[pt_id];
999af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1000af75078fSIntel 		port->tx_dropped = 0;
1001013af9b6SIntel 
1002013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1003af75078fSIntel 	}
1004af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1005af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1006af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1007af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1008af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1009af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1010af75078fSIntel 
1011af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1012af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1013af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1014af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1015af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1016af75078fSIntel #endif
1017af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1018af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1019af75078fSIntel #endif
1020af75078fSIntel 	}
1021af75078fSIntel 	if (with_tx_first) {
1022af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1023af75078fSIntel 		if (port_fwd_begin != NULL) {
1024af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1025af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1026af75078fSIntel 		}
1027af75078fSIntel 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1028af75078fSIntel 		rte_eal_mp_wait_lcore();
1029af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1030af75078fSIntel 		if (port_fwd_end != NULL) {
1031af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1032af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1033af75078fSIntel 		}
1034af75078fSIntel 	}
1035af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1036af75078fSIntel }
1037af75078fSIntel 
1038af75078fSIntel void
1039af75078fSIntel stop_packet_forwarding(void)
1040af75078fSIntel {
1041af75078fSIntel 	struct rte_eth_stats stats;
1042af75078fSIntel 	struct rte_port *port;
1043af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1044af75078fSIntel 	int i;
1045af75078fSIntel 	portid_t   pt_id;
1046af75078fSIntel 	streamid_t sm_id;
1047af75078fSIntel 	lcoreid_t  lc_id;
1048af75078fSIntel 	uint64_t total_recv;
1049af75078fSIntel 	uint64_t total_xmit;
1050af75078fSIntel 	uint64_t total_rx_dropped;
1051af75078fSIntel 	uint64_t total_tx_dropped;
1052af75078fSIntel 	uint64_t total_rx_nombuf;
1053af75078fSIntel 	uint64_t tx_dropped;
1054af75078fSIntel 	uint64_t rx_bad_ip_csum;
1055af75078fSIntel 	uint64_t rx_bad_l4_csum;
1056af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1057af75078fSIntel 	uint64_t fwd_cycles;
1058af75078fSIntel #endif
1059af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1060af75078fSIntel 
1061ce8d5614SIntel 	if (all_ports_started() == 0) {
1062ce8d5614SIntel 		printf("Not all ports were started\n");
1063ce8d5614SIntel 		return;
1064ce8d5614SIntel 	}
1065af75078fSIntel 	if (test_done) {
1066af75078fSIntel 		printf("Packet forwarding not started\n");
1067af75078fSIntel 		return;
1068af75078fSIntel 	}
1069af75078fSIntel 	printf("Telling cores to stop...");
1070af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1071af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1072af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1073af75078fSIntel 	rte_eal_mp_wait_lcore();
1074af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1075af75078fSIntel 	if (port_fwd_end != NULL) {
1076af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1077af75078fSIntel 			pt_id = fwd_ports_ids[i];
1078af75078fSIntel 			(*port_fwd_end)(pt_id);
1079af75078fSIntel 		}
1080af75078fSIntel 	}
1081af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1082af75078fSIntel 	fwd_cycles = 0;
1083af75078fSIntel #endif
1084af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1085af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1086af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1087af75078fSIntel 			fwd_stream_stats_display(sm_id);
1088af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1089af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1090af75078fSIntel 		} else {
1091af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1092af75078fSIntel 				fwd_streams[sm_id];
1093af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1094af75078fSIntel 				fwd_streams[sm_id];
1095af75078fSIntel 		}
1096af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1097af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1098af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1099af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1100af75078fSIntel 
1101013af9b6SIntel 		rx_bad_ip_csum =
1102013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1103af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1104af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1105013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1106013af9b6SIntel 							rx_bad_ip_csum;
1107af75078fSIntel 
1108013af9b6SIntel 		rx_bad_l4_csum =
1109013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1110af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1111af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1112013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1113013af9b6SIntel 							rx_bad_l4_csum;
1114af75078fSIntel 
1115af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1116af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1117af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1118af75078fSIntel #endif
1119af75078fSIntel 	}
1120af75078fSIntel 	total_recv = 0;
1121af75078fSIntel 	total_xmit = 0;
1122af75078fSIntel 	total_rx_dropped = 0;
1123af75078fSIntel 	total_tx_dropped = 0;
1124af75078fSIntel 	total_rx_nombuf  = 0;
11257741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1126af75078fSIntel 		pt_id = fwd_ports_ids[i];
1127af75078fSIntel 
1128af75078fSIntel 		port = &ports[pt_id];
1129af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1130af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1131af75078fSIntel 		port->stats.ipackets = 0;
1132af75078fSIntel 		stats.opackets -= port->stats.opackets;
1133af75078fSIntel 		port->stats.opackets = 0;
1134af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1135af75078fSIntel 		port->stats.ibytes = 0;
1136af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1137af75078fSIntel 		port->stats.obytes = 0;
113870bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
113970bdb186SIvan Boule 		port->stats.imissed = 0;
1140af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1141af75078fSIntel 		port->stats.oerrors = 0;
1142af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1143af75078fSIntel 		port->stats.rx_nombuf = 0;
1144af75078fSIntel 		stats.fdirmatch -= port->stats.fdirmatch;
1145af75078fSIntel 		port->stats.rx_nombuf = 0;
1146af75078fSIntel 		stats.fdirmiss -= port->stats.fdirmiss;
1147af75078fSIntel 		port->stats.rx_nombuf = 0;
1148af75078fSIntel 
1149af75078fSIntel 		total_recv += stats.ipackets;
1150af75078fSIntel 		total_xmit += stats.opackets;
115170bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1152af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1153af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1154af75078fSIntel 
1155af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1156af75078fSIntel 	}
1157af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1158af75078fSIntel 	       "%s\n",
1159af75078fSIntel 	       acc_stats_border, acc_stats_border);
1160af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1161af75078fSIntel 	       "%-"PRIu64"\n"
1162af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1163af75078fSIntel 	       "%-"PRIu64"\n",
1164af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1165af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1166af75078fSIntel 	if (total_rx_nombuf > 0)
1167af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1168af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1169af75078fSIntel 	       "%s\n",
1170af75078fSIntel 	       acc_stats_border, acc_stats_border);
1171af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1172af75078fSIntel 	if (total_recv > 0)
1173af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1174af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1175af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1176af75078fSIntel 		       fwd_cycles, total_recv);
1177af75078fSIntel #endif
1178af75078fSIntel 	printf("\nDone.\n");
1179af75078fSIntel 	test_done = 1;
1180af75078fSIntel }
1181af75078fSIntel 
1182cfae07fdSOuyang Changchun void
1183cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1184cfae07fdSOuyang Changchun {
1185cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1186cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1187cfae07fdSOuyang Changchun }
1188cfae07fdSOuyang Changchun 
1189cfae07fdSOuyang Changchun void
1190cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1191cfae07fdSOuyang Changchun {
1192cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1193cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1194cfae07fdSOuyang Changchun }
1195cfae07fdSOuyang Changchun 
1196ce8d5614SIntel static int
1197ce8d5614SIntel all_ports_started(void)
1198ce8d5614SIntel {
1199ce8d5614SIntel 	portid_t pi;
1200ce8d5614SIntel 	struct rte_port *port;
1201ce8d5614SIntel 
1202edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1203ce8d5614SIntel 		port = &ports[pi];
1204ce8d5614SIntel 		/* Check if there is a port which is not started */
1205ce8d5614SIntel 		if (port->port_status != RTE_PORT_STARTED)
1206ce8d5614SIntel 			return 0;
1207ce8d5614SIntel 	}
1208ce8d5614SIntel 
1209ce8d5614SIntel 	/* No port is not started */
1210ce8d5614SIntel 	return 1;
1211ce8d5614SIntel }
1212ce8d5614SIntel 
1213148f963fSBruce Richardson int
1214edab33b1STetsuya Mukawa all_ports_stopped(void)
1215edab33b1STetsuya Mukawa {
1216edab33b1STetsuya Mukawa 	portid_t pi;
1217edab33b1STetsuya Mukawa 	struct rte_port *port;
1218edab33b1STetsuya Mukawa 
1219edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1220edab33b1STetsuya Mukawa 		port = &ports[pi];
1221edab33b1STetsuya Mukawa 		if (port->port_status != RTE_PORT_STOPPED)
1222edab33b1STetsuya Mukawa 			return 0;
1223edab33b1STetsuya Mukawa 	}
1224edab33b1STetsuya Mukawa 
1225edab33b1STetsuya Mukawa 	return 1;
1226edab33b1STetsuya Mukawa }
1227edab33b1STetsuya Mukawa 
1228edab33b1STetsuya Mukawa int
1229edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1230edab33b1STetsuya Mukawa {
1231edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1232edab33b1STetsuya Mukawa 		return 0;
1233edab33b1STetsuya Mukawa 
1234edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1235edab33b1STetsuya Mukawa 		return 0;
1236edab33b1STetsuya Mukawa 
1237edab33b1STetsuya Mukawa 	return 1;
1238edab33b1STetsuya Mukawa }
1239edab33b1STetsuya Mukawa 
1240edab33b1STetsuya Mukawa static int
1241edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1242edab33b1STetsuya Mukawa {
1243edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1244edab33b1STetsuya Mukawa 		return 0;
1245edab33b1STetsuya Mukawa 
1246edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1247edab33b1STetsuya Mukawa 		return 0;
1248edab33b1STetsuya Mukawa 
1249edab33b1STetsuya Mukawa 	return 1;
1250edab33b1STetsuya Mukawa }
1251edab33b1STetsuya Mukawa 
1252edab33b1STetsuya Mukawa int
1253ce8d5614SIntel start_port(portid_t pid)
1254ce8d5614SIntel {
125592d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1256ce8d5614SIntel 	portid_t pi;
1257ce8d5614SIntel 	queueid_t qi;
1258ce8d5614SIntel 	struct rte_port *port;
12592950a769SDeclan Doherty 	struct ether_addr mac_addr;
1260ce8d5614SIntel 
1261ce8d5614SIntel 	if (test_done == 0) {
1262ce8d5614SIntel 		printf("Please stop forwarding first\n");
1263148f963fSBruce Richardson 		return -1;
1264ce8d5614SIntel 	}
1265ce8d5614SIntel 
12664468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
12674468635fSMichael Qiu 		return 0;
12684468635fSMichael Qiu 
1269ce8d5614SIntel 	if (init_fwd_streams() < 0) {
1270ce8d5614SIntel 		printf("Fail from init_fwd_streams()\n");
1271148f963fSBruce Richardson 		return -1;
1272ce8d5614SIntel 	}
1273ce8d5614SIntel 
1274ce8d5614SIntel 	if(dcb_config)
1275ce8d5614SIntel 		dcb_test = 1;
1276edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1277edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1278ce8d5614SIntel 			continue;
1279ce8d5614SIntel 
128092d2703eSMichael Qiu 		need_check_link_status = 0;
1281ce8d5614SIntel 		port = &ports[pi];
1282ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1283ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1284ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1285ce8d5614SIntel 			continue;
1286ce8d5614SIntel 		}
1287ce8d5614SIntel 
1288ce8d5614SIntel 		if (port->need_reconfig > 0) {
1289ce8d5614SIntel 			port->need_reconfig = 0;
1290ce8d5614SIntel 
12915706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
129220a0286fSLiu Xiaofeng 					port->socket_id);
1293ce8d5614SIntel 			/* configure port */
1294ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1295ce8d5614SIntel 						&(port->dev_conf));
1296ce8d5614SIntel 			if (diag != 0) {
1297ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1298ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1299ce8d5614SIntel 					printf("Port %d can not be set back "
1300ce8d5614SIntel 							"to stopped\n", pi);
1301ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1302ce8d5614SIntel 				/* try to reconfigure port next time */
1303ce8d5614SIntel 				port->need_reconfig = 1;
1304148f963fSBruce Richardson 				return -1;
1305ce8d5614SIntel 			}
1306ce8d5614SIntel 		}
1307ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1308ce8d5614SIntel 			port->need_reconfig_queues = 0;
1309ce8d5614SIntel 			/* setup tx queues */
1310ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1311b6ea6408SIntel 				if ((numa_support) &&
1312b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1313b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1314b6ea6408SIntel 						nb_txd,txring_numa[pi],
1315b6ea6408SIntel 						&(port->tx_conf));
1316b6ea6408SIntel 				else
1317b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1318b6ea6408SIntel 						nb_txd,port->socket_id,
1319b6ea6408SIntel 						&(port->tx_conf));
1320b6ea6408SIntel 
1321ce8d5614SIntel 				if (diag == 0)
1322ce8d5614SIntel 					continue;
1323ce8d5614SIntel 
1324ce8d5614SIntel 				/* Fail to setup tx queue, return */
1325ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1326ce8d5614SIntel 							RTE_PORT_HANDLING,
1327ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1328ce8d5614SIntel 					printf("Port %d can not be set back "
1329ce8d5614SIntel 							"to stopped\n", pi);
1330ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1331ce8d5614SIntel 				/* try to reconfigure queues next time */
1332ce8d5614SIntel 				port->need_reconfig_queues = 1;
1333148f963fSBruce Richardson 				return -1;
1334ce8d5614SIntel 			}
1335ce8d5614SIntel 			/* setup rx queues */
1336ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1337b6ea6408SIntel 				if ((numa_support) &&
1338b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1339b6ea6408SIntel 					struct rte_mempool * mp =
1340b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1341b6ea6408SIntel 					if (mp == NULL) {
1342b6ea6408SIntel 						printf("Failed to setup RX queue:"
1343b6ea6408SIntel 							"No mempool allocation"
1344b6ea6408SIntel 							"on the socket %d\n",
1345b6ea6408SIntel 							rxring_numa[pi]);
1346148f963fSBruce Richardson 						return -1;
1347b6ea6408SIntel 					}
1348b6ea6408SIntel 
1349b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1350b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1351b6ea6408SIntel 					     &(port->rx_conf),mp);
1352b6ea6408SIntel 				}
1353b6ea6408SIntel 				else
1354b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1355b6ea6408SIntel 					     nb_rxd,port->socket_id,
1356b6ea6408SIntel 					     &(port->rx_conf),
1357ce8d5614SIntel 				             mbuf_pool_find(port->socket_id));
1358b6ea6408SIntel 
1359ce8d5614SIntel 				if (diag == 0)
1360ce8d5614SIntel 					continue;
1361ce8d5614SIntel 
1362b6ea6408SIntel 
1363ce8d5614SIntel 				/* Fail to setup rx queue, return */
1364ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1365ce8d5614SIntel 							RTE_PORT_HANDLING,
1366ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1367ce8d5614SIntel 					printf("Port %d can not be set back "
1368ce8d5614SIntel 							"to stopped\n", pi);
1369ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1370ce8d5614SIntel 				/* try to reconfigure queues next time */
1371ce8d5614SIntel 				port->need_reconfig_queues = 1;
1372148f963fSBruce Richardson 				return -1;
1373ce8d5614SIntel 			}
1374ce8d5614SIntel 		}
1375ce8d5614SIntel 		/* start port */
1376ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1377ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1378ce8d5614SIntel 
1379ce8d5614SIntel 			/* Fail to setup rx queue, return */
1380ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1381ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1382ce8d5614SIntel 				printf("Port %d can not be set back to "
1383ce8d5614SIntel 							"stopped\n", pi);
1384ce8d5614SIntel 			continue;
1385ce8d5614SIntel 		}
1386ce8d5614SIntel 
1387ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1388ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1389ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1390ce8d5614SIntel 
13912950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1392d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
13932950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
13942950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
13952950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1396d8c89163SZijie Pan 
1397ce8d5614SIntel 		/* at least one port started, need checking link status */
1398ce8d5614SIntel 		need_check_link_status = 1;
1399ce8d5614SIntel 	}
1400ce8d5614SIntel 
140192d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1402edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
140392d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1404ce8d5614SIntel 		printf("Please stop the ports first\n");
1405ce8d5614SIntel 
1406ce8d5614SIntel 	printf("Done\n");
1407148f963fSBruce Richardson 	return 0;
1408ce8d5614SIntel }
1409ce8d5614SIntel 
1410ce8d5614SIntel void
1411ce8d5614SIntel stop_port(portid_t pid)
1412ce8d5614SIntel {
1413ce8d5614SIntel 	portid_t pi;
1414ce8d5614SIntel 	struct rte_port *port;
1415ce8d5614SIntel 	int need_check_link_status = 0;
1416ce8d5614SIntel 
1417ce8d5614SIntel 	if (test_done == 0) {
1418ce8d5614SIntel 		printf("Please stop forwarding first\n");
1419ce8d5614SIntel 		return;
1420ce8d5614SIntel 	}
1421ce8d5614SIntel 	if (dcb_test) {
1422ce8d5614SIntel 		dcb_test = 0;
1423ce8d5614SIntel 		dcb_config = 0;
1424ce8d5614SIntel 	}
14254468635fSMichael Qiu 
14264468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14274468635fSMichael Qiu 		return;
14284468635fSMichael Qiu 
1429ce8d5614SIntel 	printf("Stopping ports...\n");
1430ce8d5614SIntel 
1431edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14324468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1433ce8d5614SIntel 			continue;
1434ce8d5614SIntel 
1435ce8d5614SIntel 		port = &ports[pi];
1436ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1437ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1438ce8d5614SIntel 			continue;
1439ce8d5614SIntel 
1440ce8d5614SIntel 		rte_eth_dev_stop(pi);
1441ce8d5614SIntel 
1442ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1443ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1444ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1445ce8d5614SIntel 		need_check_link_status = 1;
1446ce8d5614SIntel 	}
1447bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1448edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1449ce8d5614SIntel 
1450ce8d5614SIntel 	printf("Done\n");
1451ce8d5614SIntel }
1452ce8d5614SIntel 
1453ce8d5614SIntel void
1454ce8d5614SIntel close_port(portid_t pid)
1455ce8d5614SIntel {
1456ce8d5614SIntel 	portid_t pi;
1457ce8d5614SIntel 	struct rte_port *port;
1458ce8d5614SIntel 
1459ce8d5614SIntel 	if (test_done == 0) {
1460ce8d5614SIntel 		printf("Please stop forwarding first\n");
1461ce8d5614SIntel 		return;
1462ce8d5614SIntel 	}
1463ce8d5614SIntel 
14644468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14654468635fSMichael Qiu 		return;
14664468635fSMichael Qiu 
1467ce8d5614SIntel 	printf("Closing ports...\n");
1468ce8d5614SIntel 
1469edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14704468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1471ce8d5614SIntel 			continue;
1472ce8d5614SIntel 
1473ce8d5614SIntel 		port = &ports[pi];
1474ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1475ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1476ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1477ce8d5614SIntel 			continue;
1478ce8d5614SIntel 		}
1479ce8d5614SIntel 
1480ce8d5614SIntel 		rte_eth_dev_close(pi);
1481ce8d5614SIntel 
1482ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1483ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1484ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1485ce8d5614SIntel 	}
1486ce8d5614SIntel 
1487ce8d5614SIntel 	printf("Done\n");
1488ce8d5614SIntel }
1489ce8d5614SIntel 
1490edab33b1STetsuya Mukawa void
1491edab33b1STetsuya Mukawa attach_port(char *identifier)
1492ce8d5614SIntel {
1493edab33b1STetsuya Mukawa 	portid_t i, j, pi = 0;
1494ce8d5614SIntel 
1495edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1496edab33b1STetsuya Mukawa 
1497edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1498edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1499edab33b1STetsuya Mukawa 		return;
1500ce8d5614SIntel 	}
1501ce8d5614SIntel 
1502edab33b1STetsuya Mukawa 	if (test_done == 0) {
1503edab33b1STetsuya Mukawa 		printf("Please stop forwarding first\n");
1504edab33b1STetsuya Mukawa 		return;
1505ce8d5614SIntel 	}
1506ce8d5614SIntel 
1507edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1508edab33b1STetsuya Mukawa 		return;
1509edab33b1STetsuya Mukawa 
1510edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1511edab33b1STetsuya Mukawa 	reconfig(pi, rte_eth_dev_socket_id(pi));
1512edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1513edab33b1STetsuya Mukawa 
1514edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1515edab33b1STetsuya Mukawa 
1516edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1517edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1518edab33b1STetsuya Mukawa 	i = 0;
1519edab33b1STetsuya Mukawa 	FOREACH_PORT(j, ports) {
1520edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = j;
1521edab33b1STetsuya Mukawa 		i++;
1522edab33b1STetsuya Mukawa 	}
1523edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1524edab33b1STetsuya Mukawa 	nb_fwd_ports++;
1525edab33b1STetsuya Mukawa 
1526edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1527edab33b1STetsuya Mukawa 
1528edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1529edab33b1STetsuya Mukawa 	printf("Done\n");
1530edab33b1STetsuya Mukawa }
1531edab33b1STetsuya Mukawa 
1532edab33b1STetsuya Mukawa void
1533edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
15345f4ec54fSChen Jing D(Mark) {
1535edab33b1STetsuya Mukawa 	portid_t i, pi = 0;
1536edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
15375f4ec54fSChen Jing D(Mark) 
1538edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
15395f4ec54fSChen Jing D(Mark) 
1540edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1541edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1542edab33b1STetsuya Mukawa 		return;
1543edab33b1STetsuya Mukawa 	}
1544edab33b1STetsuya Mukawa 
1545edab33b1STetsuya Mukawa 	rte_eth_promiscuous_disable(port_id);
1546edab33b1STetsuya Mukawa 
1547edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1548edab33b1STetsuya Mukawa 		return;
1549edab33b1STetsuya Mukawa 
1550edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1551edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1552edab33b1STetsuya Mukawa 
1553edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1554edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1555edab33b1STetsuya Mukawa 	i = 0;
1556edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1557edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = pi;
1558edab33b1STetsuya Mukawa 		i++;
1559edab33b1STetsuya Mukawa 	}
1560edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1561edab33b1STetsuya Mukawa 	nb_fwd_ports--;
1562edab33b1STetsuya Mukawa 
1563edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1564edab33b1STetsuya Mukawa 			name, nb_ports);
1565edab33b1STetsuya Mukawa 	printf("Done\n");
1566edab33b1STetsuya Mukawa 	return;
15675f4ec54fSChen Jing D(Mark) }
15685f4ec54fSChen Jing D(Mark) 
1569af75078fSIntel void
1570af75078fSIntel pmd_test_exit(void)
1571af75078fSIntel {
1572af75078fSIntel 	portid_t pt_id;
1573af75078fSIntel 
15748210ec25SPablo de Lara 	if (test_done == 0)
15758210ec25SPablo de Lara 		stop_packet_forwarding();
15768210ec25SPablo de Lara 
1577edab33b1STetsuya Mukawa 	FOREACH_PORT(pt_id, ports) {
1578af75078fSIntel 		printf("Stopping port %d...", pt_id);
1579af75078fSIntel 		fflush(stdout);
1580af75078fSIntel 		rte_eth_dev_close(pt_id);
1581af75078fSIntel 		printf("done\n");
1582af75078fSIntel 	}
1583af75078fSIntel 	printf("bye...\n");
1584af75078fSIntel }
1585af75078fSIntel 
1586af75078fSIntel typedef void (*cmd_func_t)(void);
1587af75078fSIntel struct pmd_test_command {
1588af75078fSIntel 	const char *cmd_name;
1589af75078fSIntel 	cmd_func_t cmd_func;
1590af75078fSIntel };
1591af75078fSIntel 
1592af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1593af75078fSIntel 
1594ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1595af75078fSIntel static void
1596edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1597af75078fSIntel {
1598ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1599ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1600ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1601ce8d5614SIntel 	struct rte_eth_link link;
1602ce8d5614SIntel 
1603ce8d5614SIntel 	printf("Checking link statuses...\n");
1604ce8d5614SIntel 	fflush(stdout);
1605ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1606ce8d5614SIntel 		all_ports_up = 1;
1607edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1608ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1609ce8d5614SIntel 				continue;
1610ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1611ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1612ce8d5614SIntel 			/* print link status if flag set */
1613ce8d5614SIntel 			if (print_flag == 1) {
1614ce8d5614SIntel 				if (link.link_status)
1615ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1616ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1617ce8d5614SIntel 						(unsigned)link.link_speed,
1618ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1619ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1620ce8d5614SIntel 				else
1621ce8d5614SIntel 					printf("Port %d Link Down\n",
1622ce8d5614SIntel 						(uint8_t)portid);
1623ce8d5614SIntel 				continue;
1624ce8d5614SIntel 			}
1625ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
1626ce8d5614SIntel 			if (link.link_status == 0) {
1627ce8d5614SIntel 				all_ports_up = 0;
1628ce8d5614SIntel 				break;
1629ce8d5614SIntel 			}
1630ce8d5614SIntel 		}
1631ce8d5614SIntel 		/* after finally printing all link status, get out */
1632ce8d5614SIntel 		if (print_flag == 1)
1633ce8d5614SIntel 			break;
1634ce8d5614SIntel 
1635ce8d5614SIntel 		if (all_ports_up == 0) {
1636ce8d5614SIntel 			fflush(stdout);
1637ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1638ce8d5614SIntel 		}
1639ce8d5614SIntel 
1640ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1641ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1642ce8d5614SIntel 			print_flag = 1;
1643ce8d5614SIntel 		}
1644ce8d5614SIntel 	}
1645af75078fSIntel }
1646af75078fSIntel 
1647013af9b6SIntel static int
1648013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1649af75078fSIntel {
1650013af9b6SIntel 	uint16_t i;
1651af75078fSIntel 	int diag;
1652013af9b6SIntel 	uint8_t mapping_found = 0;
1653af75078fSIntel 
1654013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1655013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1656013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1657013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1658013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1659013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1660013af9b6SIntel 			if (diag != 0)
1661013af9b6SIntel 				return diag;
1662013af9b6SIntel 			mapping_found = 1;
1663af75078fSIntel 		}
1664013af9b6SIntel 	}
1665013af9b6SIntel 	if (mapping_found)
1666013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1667013af9b6SIntel 	return 0;
1668013af9b6SIntel }
1669013af9b6SIntel 
1670013af9b6SIntel static int
1671013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1672013af9b6SIntel {
1673013af9b6SIntel 	uint16_t i;
1674013af9b6SIntel 	int diag;
1675013af9b6SIntel 	uint8_t mapping_found = 0;
1676013af9b6SIntel 
1677013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1678013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1679013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1680013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1681013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1682013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1683013af9b6SIntel 			if (diag != 0)
1684013af9b6SIntel 				return diag;
1685013af9b6SIntel 			mapping_found = 1;
1686013af9b6SIntel 		}
1687013af9b6SIntel 	}
1688013af9b6SIntel 	if (mapping_found)
1689013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1690013af9b6SIntel 	return 0;
1691013af9b6SIntel }
1692013af9b6SIntel 
1693013af9b6SIntel static void
1694013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1695013af9b6SIntel {
1696013af9b6SIntel 	int diag = 0;
1697013af9b6SIntel 
1698013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1699af75078fSIntel 	if (diag != 0) {
1700013af9b6SIntel 		if (diag == -ENOTSUP) {
1701013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1702013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1703013af9b6SIntel 		}
1704013af9b6SIntel 		else
1705013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1706013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1707013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1708af75078fSIntel 					pi, diag);
1709af75078fSIntel 	}
1710013af9b6SIntel 
1711013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1712af75078fSIntel 	if (diag != 0) {
1713013af9b6SIntel 		if (diag == -ENOTSUP) {
1714013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1715013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1716013af9b6SIntel 		}
1717013af9b6SIntel 		else
1718013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1719013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1720013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1721af75078fSIntel 					pi, diag);
1722af75078fSIntel 	}
1723af75078fSIntel }
1724af75078fSIntel 
1725f2c5125aSPablo de Lara static void
1726f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1727f2c5125aSPablo de Lara {
1728f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1729f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1730f2c5125aSPablo de Lara 
1731f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1732f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1733f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1734f2c5125aSPablo de Lara 
1735f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1736f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1737f2c5125aSPablo de Lara 
1738f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1739f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1740f2c5125aSPablo de Lara 
1741f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1742f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1743f2c5125aSPablo de Lara 
1744f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1745f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1746f2c5125aSPablo de Lara 
1747f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1748f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1749f2c5125aSPablo de Lara 
1750f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1751f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1752f2c5125aSPablo de Lara 
1753f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1754f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1755f2c5125aSPablo de Lara 
1756f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1757f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1758f2c5125aSPablo de Lara 
1759f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1760f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1761f2c5125aSPablo de Lara 
1762f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1763f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1764f2c5125aSPablo de Lara }
1765f2c5125aSPablo de Lara 
1766013af9b6SIntel void
1767013af9b6SIntel init_port_config(void)
1768013af9b6SIntel {
1769013af9b6SIntel 	portid_t pid;
1770013af9b6SIntel 	struct rte_port *port;
1771013af9b6SIntel 
1772edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1773013af9b6SIntel 		port = &ports[pid];
1774013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1775013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
17763ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1777013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1778013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1779af75078fSIntel 		} else {
1780013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1781013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1782af75078fSIntel 		}
17833ce690d3SBruce Richardson 
17843ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
17853ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
17863ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
17873ce690d3SBruce Richardson 			else
17883ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
17893ce690d3SBruce Richardson 		}
17903ce690d3SBruce Richardson 
1791a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1792a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1793a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1794a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1795a30979f6SOuyang Changchun 			else
1796a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1797a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1798a30979f6SOuyang Changchun 
1799a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1800a30979f6SOuyang Changchun 		}
1801a30979f6SOuyang Changchun 
1802f2c5125aSPablo de Lara 		rxtx_port_config(port);
1803013af9b6SIntel 
1804013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1805013af9b6SIntel 
1806013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18077b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18087b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18097b7e5ba7SIntel #endif
1810013af9b6SIntel 	}
1811013af9b6SIntel }
1812013af9b6SIntel 
1813013af9b6SIntel const uint16_t vlan_tags[] = {
1814013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1815013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1816013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1817013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1818013af9b6SIntel };
1819013af9b6SIntel 
1820013af9b6SIntel static  int
1821013af9b6SIntel get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1822013af9b6SIntel {
1823013af9b6SIntel         uint8_t i;
1824af75078fSIntel 
1825af75078fSIntel  	/*
1826013af9b6SIntel  	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1827013af9b6SIntel  	 * given above, and the number of traffic classes available for use.
1828af75078fSIntel  	 */
1829013af9b6SIntel 	if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1830013af9b6SIntel 		struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1831013af9b6SIntel 		struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1832013af9b6SIntel 
1833013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
1834013af9b6SIntel 		vmdq_rx_conf.enable_default_pool = 0;
1835013af9b6SIntel 		vmdq_rx_conf.default_pool = 0;
1836013af9b6SIntel 		vmdq_rx_conf.nb_queue_pools =
1837013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1838013af9b6SIntel 		vmdq_tx_conf.nb_queue_pools =
1839013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1840013af9b6SIntel 
1841013af9b6SIntel 		vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1842013af9b6SIntel 		for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1843013af9b6SIntel 			vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1844013af9b6SIntel 			vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1845af75078fSIntel 		}
1846013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1847013af9b6SIntel 			vmdq_rx_conf.dcb_queue[i] = i;
1848013af9b6SIntel 			vmdq_tx_conf.dcb_queue[i] = i;
1849013af9b6SIntel 		}
1850013af9b6SIntel 
1851013af9b6SIntel 		/*set DCB mode of RX and TX of multiple queues*/
185232e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
185332e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1854013af9b6SIntel 		if (dcb_conf->pfc_en)
1855013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1856013af9b6SIntel 		else
1857013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1858013af9b6SIntel 
1859013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1860013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1861013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1862013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1863013af9b6SIntel 	}
1864013af9b6SIntel 	else {
1865013af9b6SIntel 		struct rte_eth_dcb_rx_conf rx_conf;
1866013af9b6SIntel 		struct rte_eth_dcb_tx_conf tx_conf;
1867013af9b6SIntel 
1868013af9b6SIntel 		/* queue mapping configuration of DCB RX and TX */
1869013af9b6SIntel 		if (dcb_conf->num_tcs == ETH_4_TCS)
1870013af9b6SIntel 			dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1871013af9b6SIntel 		else
1872013af9b6SIntel 			dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1873013af9b6SIntel 
1874013af9b6SIntel 		rx_conf.nb_tcs = dcb_conf->num_tcs;
1875013af9b6SIntel 		tx_conf.nb_tcs = dcb_conf->num_tcs;
1876013af9b6SIntel 
1877013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1878013af9b6SIntel 			rx_conf.dcb_queue[i] = i;
1879013af9b6SIntel 			tx_conf.dcb_queue[i] = i;
1880013af9b6SIntel 		}
188132e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
188232e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1883013af9b6SIntel 		if (dcb_conf->pfc_en)
1884013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1885013af9b6SIntel 		else
1886013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1887013af9b6SIntel 
1888013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1889013af9b6SIntel                                 sizeof(struct rte_eth_dcb_rx_conf)));
1890013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1891013af9b6SIntel                                 sizeof(struct rte_eth_dcb_tx_conf)));
1892013af9b6SIntel 	}
1893013af9b6SIntel 
1894013af9b6SIntel 	return 0;
1895013af9b6SIntel }
1896013af9b6SIntel 
1897013af9b6SIntel int
1898013af9b6SIntel init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1899013af9b6SIntel {
1900013af9b6SIntel 	struct rte_eth_conf port_conf;
1901013af9b6SIntel 	struct rte_port *rte_port;
1902013af9b6SIntel 	int retval;
1903013af9b6SIntel 	uint16_t nb_vlan;
1904013af9b6SIntel 	uint16_t i;
1905013af9b6SIntel 
1906013af9b6SIntel 	/* rxq and txq configuration in dcb mode */
1907013af9b6SIntel 	nb_rxq = 128;
1908013af9b6SIntel 	nb_txq = 128;
1909013af9b6SIntel 	rx_free_thresh = 64;
1910013af9b6SIntel 
1911013af9b6SIntel 	memset(&port_conf,0,sizeof(struct rte_eth_conf));
1912013af9b6SIntel 	/* Enter DCB configuration status */
1913013af9b6SIntel 	dcb_config = 1;
1914013af9b6SIntel 
1915013af9b6SIntel 	nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1916013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
1917013af9b6SIntel 	retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1918013af9b6SIntel 	if (retval < 0)
1919013af9b6SIntel 		return retval;
1920013af9b6SIntel 
1921013af9b6SIntel 	rte_port = &ports[pid];
1922013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1923013af9b6SIntel 
1924f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
1925013af9b6SIntel 	/* VLAN filter */
1926013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1927013af9b6SIntel 	for (i = 0; i < nb_vlan; i++){
1928013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1929013af9b6SIntel 	}
1930013af9b6SIntel 
1931013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1932013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1933013af9b6SIntel 
19347741e4cfSIntel 	rte_port->dcb_flag = 1;
19357741e4cfSIntel 
1936013af9b6SIntel 	return 0;
1937af75078fSIntel }
1938af75078fSIntel 
1939ffc468ffSTetsuya Mukawa static void
1940ffc468ffSTetsuya Mukawa init_port(void)
1941ffc468ffSTetsuya Mukawa {
1942ffc468ffSTetsuya Mukawa 	portid_t pid;
1943ffc468ffSTetsuya Mukawa 
1944ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
1945ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
1946ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
1947ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
1948ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
1949ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
1950ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
1951ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
1952ffc468ffSTetsuya Mukawa 	}
1953ffc468ffSTetsuya Mukawa 
1954ffc468ffSTetsuya Mukawa 	/* enabled allocated ports */
1955ffc468ffSTetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
1956ffc468ffSTetsuya Mukawa 		ports[pid].enabled = 1;
1957ffc468ffSTetsuya Mukawa }
1958ffc468ffSTetsuya Mukawa 
1959af75078fSIntel int
1960af75078fSIntel main(int argc, char** argv)
1961af75078fSIntel {
1962af75078fSIntel 	int  diag;
1963013af9b6SIntel 	uint8_t port_id;
1964af75078fSIntel 
1965af75078fSIntel 	diag = rte_eal_init(argc, argv);
1966af75078fSIntel 	if (diag < 0)
1967af75078fSIntel 		rte_panic("Cannot init EAL\n");
1968af75078fSIntel 
1969af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
1970af75078fSIntel 	if (nb_ports == 0)
1971edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
1972af75078fSIntel 
1973ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
1974ffc468ffSTetsuya Mukawa 	init_port();
1975ffc468ffSTetsuya Mukawa 
1976af75078fSIntel 	set_def_fwd_config();
1977af75078fSIntel 	if (nb_lcores == 0)
1978af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
1979af75078fSIntel 			  "core mask supplied in the command parameters\n");
1980af75078fSIntel 
1981af75078fSIntel 	argc -= diag;
1982af75078fSIntel 	argv += diag;
1983af75078fSIntel 	if (argc > 1)
1984af75078fSIntel 		launch_args_parse(argc, argv);
1985af75078fSIntel 
1986af75078fSIntel 	if (nb_rxq > nb_txq)
1987af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
1988af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
1989af75078fSIntel 		       nb_rxq, nb_txq);
1990af75078fSIntel 
1991af75078fSIntel 	init_config();
1992148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
1993148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
1994af75078fSIntel 
1995ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
1996edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
1997ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
1998af75078fSIntel 
19990d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2000ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2001ca7feb22SCyril Chemparathy 		if (auto_start) {
2002ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2003ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2004ca7feb22SCyril Chemparathy 		}
2005af75078fSIntel 		prompt();
2006ca7feb22SCyril Chemparathy 	} else
20070d56cb81SThomas Monjalon #endif
20080d56cb81SThomas Monjalon 	{
2009af75078fSIntel 		char c;
2010af75078fSIntel 		int rc;
2011af75078fSIntel 
2012af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2013af75078fSIntel 		start_packet_forwarding(0);
2014af75078fSIntel 		printf("Press enter to exit\n");
2015af75078fSIntel 		rc = read(0, &c, 1);
2016af75078fSIntel 		if (rc < 0)
2017af75078fSIntel 			return 1;
2018af75078fSIntel 	}
2019af75078fSIntel 
2020af75078fSIntel 	return 0;
2021af75078fSIntel }
2022