xref: /dpdk/app/test-pmd/testpmd.c (revision 47b3ac6b45a1c2bef5b620d3bf67a7ffeb545319)
1af75078fSIntel /*-
2af75078fSIntel  *   BSD LICENSE
3af75078fSIntel  *
420718201SBernard Iremonger  *   Copyright(c) 2010-2015 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,
301*47b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
302*47b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
303*47b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
304d9d5e6f2SJingjing Wu 	},
305af75078fSIntel 	.drop_queue = 127,
306af75078fSIntel };
307af75078fSIntel 
3082950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
309af75078fSIntel 
310ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
311ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
312ed30d9b6SIntel 
313ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
314ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
315ed30d9b6SIntel 
316ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
317ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
318ed30d9b6SIntel 
3197acf894dSStephen Hurd unsigned max_socket = 0;
3207acf894dSStephen Hurd 
321ed30d9b6SIntel /* Forward function declarations */
322ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
323edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
324ce8d5614SIntel 
325ce8d5614SIntel /*
326ce8d5614SIntel  * Check if all the ports are started.
327ce8d5614SIntel  * If yes, return positive value. If not, return zero.
328ce8d5614SIntel  */
329ce8d5614SIntel static int all_ports_started(void);
330ed30d9b6SIntel 
331af75078fSIntel /*
332edab33b1STetsuya Mukawa  * Find next enabled port
333edab33b1STetsuya Mukawa  */
334edab33b1STetsuya Mukawa portid_t
335edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
336edab33b1STetsuya Mukawa {
337edab33b1STetsuya Mukawa 	if (ports == NULL)
338edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
339edab33b1STetsuya Mukawa 
34012a8e30fSJulien Cretin 	while ((p < size) && (ports[p].enabled == 0))
341edab33b1STetsuya Mukawa 		p++;
342edab33b1STetsuya Mukawa 	return p;
343edab33b1STetsuya Mukawa }
344edab33b1STetsuya Mukawa 
345edab33b1STetsuya Mukawa /*
346af75078fSIntel  * Setup default configuration.
347af75078fSIntel  */
348af75078fSIntel static void
349af75078fSIntel set_default_fwd_lcores_config(void)
350af75078fSIntel {
351af75078fSIntel 	unsigned int i;
352af75078fSIntel 	unsigned int nb_lc;
3537acf894dSStephen Hurd 	unsigned int sock_num;
354af75078fSIntel 
355af75078fSIntel 	nb_lc = 0;
356af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
357af75078fSIntel 		if (! rte_lcore_is_enabled(i))
358af75078fSIntel 			continue;
359af75078fSIntel 		if (i == rte_get_master_lcore())
360af75078fSIntel 			continue;
361af75078fSIntel 		fwd_lcores_cpuids[nb_lc++] = i;
3627acf894dSStephen Hurd 		sock_num = rte_lcore_to_socket_id(i) + 1;
3637acf894dSStephen Hurd 		if (sock_num > max_socket) {
3647acf894dSStephen Hurd 			if (sock_num > RTE_MAX_NUMA_NODES)
3657acf894dSStephen Hurd 				rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
3667acf894dSStephen Hurd 			max_socket = sock_num;
3677acf894dSStephen Hurd 		}
368af75078fSIntel 	}
369af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
370af75078fSIntel 	nb_cfg_lcores = nb_lcores;
371af75078fSIntel 	nb_fwd_lcores = 1;
372af75078fSIntel }
373af75078fSIntel 
374af75078fSIntel static void
375af75078fSIntel set_def_peer_eth_addrs(void)
376af75078fSIntel {
377af75078fSIntel 	portid_t i;
378af75078fSIntel 
379af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
380af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
381af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
382af75078fSIntel 	}
383af75078fSIntel }
384af75078fSIntel 
385af75078fSIntel static void
386af75078fSIntel set_default_fwd_ports_config(void)
387af75078fSIntel {
388af75078fSIntel 	portid_t pt_id;
389af75078fSIntel 
390af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
391af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
392af75078fSIntel 
393af75078fSIntel 	nb_cfg_ports = nb_ports;
394af75078fSIntel 	nb_fwd_ports = nb_ports;
395af75078fSIntel }
396af75078fSIntel 
397af75078fSIntel void
398af75078fSIntel set_def_fwd_config(void)
399af75078fSIntel {
400af75078fSIntel 	set_default_fwd_lcores_config();
401af75078fSIntel 	set_def_peer_eth_addrs();
402af75078fSIntel 	set_default_fwd_ports_config();
403af75078fSIntel }
404af75078fSIntel 
405af75078fSIntel /*
406af75078fSIntel  * Configuration initialisation done once at init time.
407af75078fSIntel  */
408af75078fSIntel static void
409af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
410af75078fSIntel 		 unsigned int socket_id)
411af75078fSIntel {
412af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
413af75078fSIntel 	struct rte_mempool *rte_mp;
414af75078fSIntel 	uint32_t mb_size;
415af75078fSIntel 
416dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
417af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
418148f963fSBruce Richardson 
419148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
420148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
421af75078fSIntel 		(unsigned) mb_mempool_cache,
422af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
423dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
424dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
425af75078fSIntel 		socket_id, 0);
426148f963fSBruce Richardson 
427148f963fSBruce Richardson 
428148f963fSBruce Richardson 
429148f963fSBruce Richardson #else
430148f963fSBruce Richardson 	if (mp_anon != 0)
431148f963fSBruce Richardson 		rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size,
432148f963fSBruce Richardson 				    (unsigned) mb_mempool_cache,
433148f963fSBruce Richardson 				    sizeof(struct rte_pktmbuf_pool_private),
434dfb03bbeSOlivier Matz 				    rte_pktmbuf_pool_init, NULL,
435dfb03bbeSOlivier Matz 				    rte_pktmbuf_init, NULL,
436148f963fSBruce Richardson 				    socket_id, 0);
437148f963fSBruce Richardson 	else
438ea0c20eaSOlivier Matz 		/* wrapper to rte_mempool_create() */
439ea0c20eaSOlivier Matz 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
440ea0c20eaSOlivier Matz 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
441148f963fSBruce Richardson 
442148f963fSBruce Richardson #endif
443148f963fSBruce Richardson 
444af75078fSIntel 	if (rte_mp == NULL) {
445ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u "
446ce8d5614SIntel 						"failed\n", socket_id);
447148f963fSBruce Richardson 	} else if (verbose_level > 0) {
448591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
449af75078fSIntel 	}
450af75078fSIntel }
451af75078fSIntel 
45220a0286fSLiu Xiaofeng /*
45320a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
45420a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
45520a0286fSLiu Xiaofeng  */
45620a0286fSLiu Xiaofeng static int
45720a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
45820a0286fSLiu Xiaofeng {
45920a0286fSLiu Xiaofeng 	static int warning_once = 0;
46020a0286fSLiu Xiaofeng 
4617acf894dSStephen Hurd 	if (socket_id >= max_socket) {
46220a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
46320a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
46420a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
46520a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
46620a0286fSLiu Xiaofeng 			       " --numa.\n");
46720a0286fSLiu Xiaofeng 		warning_once = 1;
46820a0286fSLiu Xiaofeng 		return -1;
46920a0286fSLiu Xiaofeng 	}
47020a0286fSLiu Xiaofeng 	return 0;
47120a0286fSLiu Xiaofeng }
47220a0286fSLiu Xiaofeng 
473af75078fSIntel static void
474af75078fSIntel init_config(void)
475af75078fSIntel {
476ce8d5614SIntel 	portid_t pid;
477af75078fSIntel 	struct rte_port *port;
478af75078fSIntel 	struct rte_mempool *mbp;
479af75078fSIntel 	unsigned int nb_mbuf_per_pool;
480af75078fSIntel 	lcoreid_t  lc_id;
4817acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
482af75078fSIntel 
4837acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
484af75078fSIntel 	/* Configuration of logical cores. */
485af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
486af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
487fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
488af75078fSIntel 	if (fwd_lcores == NULL) {
489ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
490ce8d5614SIntel 							"failed\n", nb_lcores);
491af75078fSIntel 	}
492af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
493af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
494af75078fSIntel 					       sizeof(struct fwd_lcore),
495fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
496af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
497ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
498ce8d5614SIntel 								"failed\n");
499af75078fSIntel 		}
500af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
501af75078fSIntel 	}
502af75078fSIntel 
503af75078fSIntel 	/*
504af75078fSIntel 	 * Create pools of mbuf.
505af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
506b6ea6408SIntel 	 * socket 0 memory by default.
507af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
508c8798818SIntel 	 *
509c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
510c8798818SIntel 	 * nb_txd can be configured at run time.
511af75078fSIntel 	 */
512c8798818SIntel 	if (param_total_num_mbufs)
513c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
514c8798818SIntel 	else {
515c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
516c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
517b6ea6408SIntel 
518b6ea6408SIntel 		if (!numa_support)
519edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
520edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
521c8798818SIntel 	}
522af75078fSIntel 
523b6ea6408SIntel 	if (!numa_support) {
524b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
525b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
526b6ea6408SIntel 		else
527b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
528b6ea6408SIntel 						 socket_num);
529b6ea6408SIntel 	}
530af75078fSIntel 
531edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
532ce8d5614SIntel 		port = &ports[pid];
533ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
534ce8d5614SIntel 
535b6ea6408SIntel 		if (numa_support) {
536b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
537b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
538b6ea6408SIntel 			else {
539b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
54020a0286fSLiu Xiaofeng 
54120a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
54220a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
54320a0286fSLiu Xiaofeng 					socket_id = 0;
544b6ea6408SIntel 				port_per_socket[socket_id]++;
545b6ea6408SIntel 			}
546b6ea6408SIntel 		}
547b6ea6408SIntel 
548ce8d5614SIntel 		/* set flag to initialize port/queue */
549ce8d5614SIntel 		port->need_reconfig = 1;
550ce8d5614SIntel 		port->need_reconfig_queues = 1;
551ce8d5614SIntel 	}
552ce8d5614SIntel 
553b6ea6408SIntel 	if (numa_support) {
554b6ea6408SIntel 		uint8_t i;
555b6ea6408SIntel 		unsigned int nb_mbuf;
556ce8d5614SIntel 
557b6ea6408SIntel 		if (param_total_num_mbufs)
558b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
559b6ea6408SIntel 
5607acf894dSStephen Hurd 		for (i = 0; i < max_socket; i++) {
561edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
562b6ea6408SIntel 			if (nb_mbuf)
563b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
564b6ea6408SIntel 						nb_mbuf,i);
565b6ea6408SIntel 		}
566b6ea6408SIntel 	}
567b6ea6408SIntel 	init_port_config();
5685886ae07SAdrien Mazarguil 
5695886ae07SAdrien Mazarguil 	/*
5705886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
5715886ae07SAdrien Mazarguil 	 */
5725886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
5738fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
5748fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
5758fd8bebcSAdrien Mazarguil 
5765886ae07SAdrien Mazarguil 		if (mbp == NULL)
5775886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
5785886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
5795886ae07SAdrien Mazarguil 	}
5805886ae07SAdrien Mazarguil 
581ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
582ce8d5614SIntel 	if (init_fwd_streams() < 0)
583ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
584ce8d5614SIntel }
585ce8d5614SIntel 
5862950a769SDeclan Doherty 
5872950a769SDeclan Doherty void
588a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
5892950a769SDeclan Doherty {
5902950a769SDeclan Doherty 	struct rte_port *port;
5912950a769SDeclan Doherty 
5922950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
5932950a769SDeclan Doherty 	port = &ports[new_port_id];
5942950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
5952950a769SDeclan Doherty 
5962950a769SDeclan Doherty 	/* set flag to initialize port/queue */
5972950a769SDeclan Doherty 	port->need_reconfig = 1;
5982950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
599a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6002950a769SDeclan Doherty 
6012950a769SDeclan Doherty 	init_port_config();
6022950a769SDeclan Doherty }
6032950a769SDeclan Doherty 
6042950a769SDeclan Doherty 
605ce8d5614SIntel int
606ce8d5614SIntel init_fwd_streams(void)
607ce8d5614SIntel {
608ce8d5614SIntel 	portid_t pid;
609ce8d5614SIntel 	struct rte_port *port;
610ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
611ce8d5614SIntel 
612ce8d5614SIntel 	/* set socket id according to numa or not */
613edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
614ce8d5614SIntel 		port = &ports[pid];
615ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
616ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
617ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
618ce8d5614SIntel 				port->dev_info.max_rx_queues);
619ce8d5614SIntel 			return -1;
620ce8d5614SIntel 		}
621ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
622ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
623ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
624ce8d5614SIntel 				port->dev_info.max_tx_queues);
625ce8d5614SIntel 			return -1;
626ce8d5614SIntel 		}
62720a0286fSLiu Xiaofeng 		if (numa_support) {
62820a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
62920a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
63020a0286fSLiu Xiaofeng 			else {
631b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
63220a0286fSLiu Xiaofeng 
63320a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
63420a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
63520a0286fSLiu Xiaofeng 					port->socket_id = 0;
63620a0286fSLiu Xiaofeng 			}
63720a0286fSLiu Xiaofeng 		}
638b6ea6408SIntel 		else {
639b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
640af75078fSIntel 				port->socket_id = 0;
641b6ea6408SIntel 			else
642b6ea6408SIntel 				port->socket_id = socket_num;
643b6ea6408SIntel 		}
644af75078fSIntel 	}
645af75078fSIntel 
646ce8d5614SIntel 	nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq);
647ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
648ce8d5614SIntel 		return 0;
649ce8d5614SIntel 	/* clear the old */
650ce8d5614SIntel 	if (fwd_streams != NULL) {
651ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
652ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
653ce8d5614SIntel 				continue;
654ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
655ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
656af75078fSIntel 		}
657ce8d5614SIntel 		rte_free(fwd_streams);
658ce8d5614SIntel 		fwd_streams = NULL;
659ce8d5614SIntel 	}
660ce8d5614SIntel 
661ce8d5614SIntel 	/* init new */
662ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
663ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
664fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
665ce8d5614SIntel 	if (fwd_streams == NULL)
666ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
667ce8d5614SIntel 						"failed\n", nb_fwd_streams);
668ce8d5614SIntel 
669af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
670af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
671fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
672ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
673ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
674ce8d5614SIntel 								" failed\n");
675af75078fSIntel 	}
676ce8d5614SIntel 
677ce8d5614SIntel 	return 0;
678af75078fSIntel }
679af75078fSIntel 
680af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
681af75078fSIntel static void
682af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
683af75078fSIntel {
684af75078fSIntel 	unsigned int total_burst;
685af75078fSIntel 	unsigned int nb_burst;
686af75078fSIntel 	unsigned int burst_stats[3];
687af75078fSIntel 	uint16_t pktnb_stats[3];
688af75078fSIntel 	uint16_t nb_pkt;
689af75078fSIntel 	int burst_percent[3];
690af75078fSIntel 
691af75078fSIntel 	/*
692af75078fSIntel 	 * First compute the total number of packet bursts and the
693af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
694af75078fSIntel 	 */
695af75078fSIntel 	total_burst = 0;
696af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
697af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
698af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
699af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
700af75078fSIntel 		if (nb_burst == 0)
701af75078fSIntel 			continue;
702af75078fSIntel 		total_burst += nb_burst;
703af75078fSIntel 		if (nb_burst > burst_stats[0]) {
704af75078fSIntel 			burst_stats[1] = burst_stats[0];
705af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
706af75078fSIntel 			burst_stats[0] = nb_burst;
707af75078fSIntel 			pktnb_stats[0] = nb_pkt;
708af75078fSIntel 		}
709af75078fSIntel 	}
710af75078fSIntel 	if (total_burst == 0)
711af75078fSIntel 		return;
712af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
713af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
714af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
715af75078fSIntel 	if (burst_stats[0] == total_burst) {
716af75078fSIntel 		printf("]\n");
717af75078fSIntel 		return;
718af75078fSIntel 	}
719af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
720af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
721af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
722af75078fSIntel 		return;
723af75078fSIntel 	}
724af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
725af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
726af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
727af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
728af75078fSIntel 		return;
729af75078fSIntel 	}
730af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
731af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
732af75078fSIntel }
733af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
734af75078fSIntel 
735af75078fSIntel static void
736af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
737af75078fSIntel {
738af75078fSIntel 	struct rte_port *port;
739013af9b6SIntel 	uint8_t i;
740af75078fSIntel 
741af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
742af75078fSIntel 
743af75078fSIntel 	port = &ports[port_id];
744af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
745af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
746013af9b6SIntel 
747013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
748af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
749af75078fSIntel 		       "%-"PRIu64"\n",
75070bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
75170bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
752af75078fSIntel 
753af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
754af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
755af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
75670bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
75770bdb186SIvan Boule 			printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
75870bdb186SIvan Boule 			       "RX-error: %-"PRIu64"\n",
75970bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
76070bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
76170bdb186SIvan Boule 		}
762af75078fSIntel 
763af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
764af75078fSIntel 		       "%-"PRIu64"\n",
765af75078fSIntel 		       stats->opackets, port->tx_dropped,
766af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
767013af9b6SIntel 	}
768013af9b6SIntel 	else {
769013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
770013af9b6SIntel 		       "%14"PRIu64"\n",
77170bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
77270bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
773013af9b6SIntel 
774013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
775013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
776013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
77770bdb186SIvan Boule 		if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
77870bdb186SIvan Boule 			printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
77970bdb186SIvan Boule 			       "    RX-error:%"PRIu64"\n",
78070bdb186SIvan Boule 			       stats->ibadcrc, stats->ibadlen, stats->ierrors);
78170bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
78270bdb186SIvan Boule 			       stats->rx_nombuf);
78370bdb186SIvan Boule 		}
784013af9b6SIntel 
785013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
786013af9b6SIntel 		       "%14"PRIu64"\n",
787013af9b6SIntel 		       stats->opackets, port->tx_dropped,
788013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
789013af9b6SIntel 	}
790e659b6b4SIvan Boule 
791e659b6b4SIvan Boule 	/* Display statistics of XON/XOFF pause frames, if any. */
792e659b6b4SIvan Boule 	if ((stats->tx_pause_xon  | stats->rx_pause_xon |
793e659b6b4SIvan Boule 	     stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
794e659b6b4SIvan Boule 		printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
795e659b6b4SIvan Boule 		       stats->rx_pause_xoff, stats->rx_pause_xon);
796e659b6b4SIvan Boule 		printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
797e659b6b4SIvan Boule 		       stats->tx_pause_xoff, stats->tx_pause_xon);
798e659b6b4SIvan Boule 	}
799e659b6b4SIvan Boule 
800af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
801af75078fSIntel 	if (port->rx_stream)
802013af9b6SIntel 		pkt_burst_stats_display("RX",
803013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
804af75078fSIntel 	if (port->tx_stream)
805013af9b6SIntel 		pkt_burst_stats_display("TX",
806013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
807af75078fSIntel #endif
808af75078fSIntel 	/* stats fdir */
809af75078fSIntel 	if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
810013af9b6SIntel 		printf("  Fdirmiss:%14"PRIu64"	  Fdirmatch:%14"PRIu64"\n",
811af75078fSIntel 		       stats->fdirmiss,
812af75078fSIntel 		       stats->fdirmatch);
813af75078fSIntel 
814013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
815013af9b6SIntel 		printf("\n");
816013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
817013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
818013af9b6SIntel 			       "     RX-errors:%14"PRIu64
819013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
820013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
821013af9b6SIntel 		}
822013af9b6SIntel 		printf("\n");
823013af9b6SIntel 	}
824013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
825013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
826013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
827013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
828013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
829013af9b6SIntel 		}
830013af9b6SIntel 	}
831013af9b6SIntel 
832af75078fSIntel 	printf("  %s--------------------------------%s\n",
833af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
834af75078fSIntel }
835af75078fSIntel 
836af75078fSIntel static void
837af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
838af75078fSIntel {
839af75078fSIntel 	struct fwd_stream *fs;
840af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
841af75078fSIntel 
842af75078fSIntel 	fs = fwd_streams[stream_id];
843af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
844af75078fSIntel 	    (fs->fwd_dropped == 0))
845af75078fSIntel 		return;
846af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
847af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
848af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
849af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
850af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
851af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
852af75078fSIntel 
853af75078fSIntel 	/* if checksum mode */
854af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
855013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
856013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
857af75078fSIntel 	}
858af75078fSIntel 
859af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
860af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
861af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
862af75078fSIntel #endif
863af75078fSIntel }
864af75078fSIntel 
865af75078fSIntel static void
8667741e4cfSIntel flush_fwd_rx_queues(void)
867af75078fSIntel {
868af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
869af75078fSIntel 	portid_t  rxp;
8707741e4cfSIntel 	portid_t port_id;
871af75078fSIntel 	queueid_t rxq;
872af75078fSIntel 	uint16_t  nb_rx;
873af75078fSIntel 	uint16_t  i;
874af75078fSIntel 	uint8_t   j;
875af75078fSIntel 
876af75078fSIntel 	for (j = 0; j < 2; j++) {
8777741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
878af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
8797741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
880af75078fSIntel 				do {
8817741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
882013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
883af75078fSIntel 					for (i = 0; i < nb_rx; i++)
884af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
885af75078fSIntel 				} while (nb_rx > 0);
886af75078fSIntel 			}
887af75078fSIntel 		}
888af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
889af75078fSIntel 	}
890af75078fSIntel }
891af75078fSIntel 
892af75078fSIntel static void
893af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
894af75078fSIntel {
895af75078fSIntel 	struct fwd_stream **fsm;
896af75078fSIntel 	streamid_t nb_fs;
897af75078fSIntel 	streamid_t sm_id;
898af75078fSIntel 
899af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
900af75078fSIntel 	nb_fs = fc->stream_nb;
901af75078fSIntel 	do {
902af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
903af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
904af75078fSIntel 	} while (! fc->stopped);
905af75078fSIntel }
906af75078fSIntel 
907af75078fSIntel static int
908af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
909af75078fSIntel {
910af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
911af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
912af75078fSIntel 	return 0;
913af75078fSIntel }
914af75078fSIntel 
915af75078fSIntel /*
916af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
917af75078fSIntel  * Used to start communication flows in network loopback test configurations.
918af75078fSIntel  */
919af75078fSIntel static int
920af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
921af75078fSIntel {
922af75078fSIntel 	struct fwd_lcore *fwd_lc;
923af75078fSIntel 	struct fwd_lcore tmp_lcore;
924af75078fSIntel 
925af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
926af75078fSIntel 	tmp_lcore = *fwd_lc;
927af75078fSIntel 	tmp_lcore.stopped = 1;
928af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
929af75078fSIntel 	return 0;
930af75078fSIntel }
931af75078fSIntel 
932af75078fSIntel /*
933af75078fSIntel  * Launch packet forwarding:
934af75078fSIntel  *     - Setup per-port forwarding context.
935af75078fSIntel  *     - launch logical cores with their forwarding configuration.
936af75078fSIntel  */
937af75078fSIntel static void
938af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
939af75078fSIntel {
940af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
941af75078fSIntel 	unsigned int i;
942af75078fSIntel 	unsigned int lc_id;
943af75078fSIntel 	int diag;
944af75078fSIntel 
945af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
946af75078fSIntel 	if (port_fwd_begin != NULL) {
947af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
948af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
949af75078fSIntel 	}
950af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
951af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
952af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
953af75078fSIntel 			fwd_lcores[i]->stopped = 0;
954af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
955af75078fSIntel 						     fwd_lcores[i], lc_id);
956af75078fSIntel 			if (diag != 0)
957af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
958af75078fSIntel 				       lc_id, diag);
959af75078fSIntel 		}
960af75078fSIntel 	}
961af75078fSIntel }
962af75078fSIntel 
963af75078fSIntel /*
964af75078fSIntel  * Launch packet forwarding configuration.
965af75078fSIntel  */
966af75078fSIntel void
967af75078fSIntel start_packet_forwarding(int with_tx_first)
968af75078fSIntel {
969af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
970af75078fSIntel 	port_fwd_end_t  port_fwd_end;
971af75078fSIntel 	struct rte_port *port;
972af75078fSIntel 	unsigned int i;
973af75078fSIntel 	portid_t   pt_id;
974af75078fSIntel 	streamid_t sm_id;
975af75078fSIntel 
976ce8d5614SIntel 	if (all_ports_started() == 0) {
977ce8d5614SIntel 		printf("Not all ports were started\n");
978ce8d5614SIntel 		return;
979ce8d5614SIntel 	}
980af75078fSIntel 	if (test_done == 0) {
981af75078fSIntel 		printf("Packet forwarding already started\n");
982af75078fSIntel 		return;
983af75078fSIntel 	}
9847741e4cfSIntel 	if(dcb_test) {
9857741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
9867741e4cfSIntel 			pt_id = fwd_ports_ids[i];
9877741e4cfSIntel 			port = &ports[pt_id];
9887741e4cfSIntel 			if (!port->dcb_flag) {
9897741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
9907741e4cfSIntel                                        "be configured in this mode.\n");
991013af9b6SIntel 				return;
992013af9b6SIntel 			}
9937741e4cfSIntel 		}
9947741e4cfSIntel 		if (nb_fwd_lcores == 1) {
9957741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
9967741e4cfSIntel                                "should be larger than 1.\n");
9977741e4cfSIntel 			return;
9987741e4cfSIntel 		}
9997741e4cfSIntel 	}
1000af75078fSIntel 	test_done = 0;
10017741e4cfSIntel 
10027741e4cfSIntel 	if(!no_flush_rx)
10037741e4cfSIntel 		flush_fwd_rx_queues();
10047741e4cfSIntel 
1005af75078fSIntel 	fwd_config_setup();
1006af75078fSIntel 	rxtx_config_display();
1007af75078fSIntel 
1008af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1009af75078fSIntel 		pt_id = fwd_ports_ids[i];
1010af75078fSIntel 		port = &ports[pt_id];
1011af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1012af75078fSIntel 		port->tx_dropped = 0;
1013013af9b6SIntel 
1014013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1015af75078fSIntel 	}
1016af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1017af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1018af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1019af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1020af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1021af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1022af75078fSIntel 
1023af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1024af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1025af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1026af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1027af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1028af75078fSIntel #endif
1029af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1030af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1031af75078fSIntel #endif
1032af75078fSIntel 	}
1033af75078fSIntel 	if (with_tx_first) {
1034af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1035af75078fSIntel 		if (port_fwd_begin != NULL) {
1036af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1037af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1038af75078fSIntel 		}
1039af75078fSIntel 		launch_packet_forwarding(run_one_txonly_burst_on_core);
1040af75078fSIntel 		rte_eal_mp_wait_lcore();
1041af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1042af75078fSIntel 		if (port_fwd_end != NULL) {
1043af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1044af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1045af75078fSIntel 		}
1046af75078fSIntel 	}
1047af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1048af75078fSIntel }
1049af75078fSIntel 
1050af75078fSIntel void
1051af75078fSIntel stop_packet_forwarding(void)
1052af75078fSIntel {
1053af75078fSIntel 	struct rte_eth_stats stats;
1054af75078fSIntel 	struct rte_port *port;
1055af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1056af75078fSIntel 	int i;
1057af75078fSIntel 	portid_t   pt_id;
1058af75078fSIntel 	streamid_t sm_id;
1059af75078fSIntel 	lcoreid_t  lc_id;
1060af75078fSIntel 	uint64_t total_recv;
1061af75078fSIntel 	uint64_t total_xmit;
1062af75078fSIntel 	uint64_t total_rx_dropped;
1063af75078fSIntel 	uint64_t total_tx_dropped;
1064af75078fSIntel 	uint64_t total_rx_nombuf;
1065af75078fSIntel 	uint64_t tx_dropped;
1066af75078fSIntel 	uint64_t rx_bad_ip_csum;
1067af75078fSIntel 	uint64_t rx_bad_l4_csum;
1068af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1069af75078fSIntel 	uint64_t fwd_cycles;
1070af75078fSIntel #endif
1071af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1072af75078fSIntel 
1073ce8d5614SIntel 	if (all_ports_started() == 0) {
1074ce8d5614SIntel 		printf("Not all ports were started\n");
1075ce8d5614SIntel 		return;
1076ce8d5614SIntel 	}
1077af75078fSIntel 	if (test_done) {
1078af75078fSIntel 		printf("Packet forwarding not started\n");
1079af75078fSIntel 		return;
1080af75078fSIntel 	}
1081af75078fSIntel 	printf("Telling cores to stop...");
1082af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1083af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1084af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1085af75078fSIntel 	rte_eal_mp_wait_lcore();
1086af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1087af75078fSIntel 	if (port_fwd_end != NULL) {
1088af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1089af75078fSIntel 			pt_id = fwd_ports_ids[i];
1090af75078fSIntel 			(*port_fwd_end)(pt_id);
1091af75078fSIntel 		}
1092af75078fSIntel 	}
1093af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1094af75078fSIntel 	fwd_cycles = 0;
1095af75078fSIntel #endif
1096af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1097af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1098af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1099af75078fSIntel 			fwd_stream_stats_display(sm_id);
1100af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1101af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1102af75078fSIntel 		} else {
1103af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1104af75078fSIntel 				fwd_streams[sm_id];
1105af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1106af75078fSIntel 				fwd_streams[sm_id];
1107af75078fSIntel 		}
1108af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1109af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1110af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1111af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1112af75078fSIntel 
1113013af9b6SIntel 		rx_bad_ip_csum =
1114013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1115af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1116af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1117013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1118013af9b6SIntel 							rx_bad_ip_csum;
1119af75078fSIntel 
1120013af9b6SIntel 		rx_bad_l4_csum =
1121013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1122af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1123af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1124013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1125013af9b6SIntel 							rx_bad_l4_csum;
1126af75078fSIntel 
1127af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1128af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1129af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1130af75078fSIntel #endif
1131af75078fSIntel 	}
1132af75078fSIntel 	total_recv = 0;
1133af75078fSIntel 	total_xmit = 0;
1134af75078fSIntel 	total_rx_dropped = 0;
1135af75078fSIntel 	total_tx_dropped = 0;
1136af75078fSIntel 	total_rx_nombuf  = 0;
11377741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1138af75078fSIntel 		pt_id = fwd_ports_ids[i];
1139af75078fSIntel 
1140af75078fSIntel 		port = &ports[pt_id];
1141af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1142af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1143af75078fSIntel 		port->stats.ipackets = 0;
1144af75078fSIntel 		stats.opackets -= port->stats.opackets;
1145af75078fSIntel 		port->stats.opackets = 0;
1146af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1147af75078fSIntel 		port->stats.ibytes = 0;
1148af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1149af75078fSIntel 		port->stats.obytes = 0;
115070bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
115170bdb186SIvan Boule 		port->stats.imissed = 0;
1152af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1153af75078fSIntel 		port->stats.oerrors = 0;
1154af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1155af75078fSIntel 		port->stats.rx_nombuf = 0;
1156af75078fSIntel 		stats.fdirmatch -= port->stats.fdirmatch;
1157af75078fSIntel 		port->stats.rx_nombuf = 0;
1158af75078fSIntel 		stats.fdirmiss -= port->stats.fdirmiss;
1159af75078fSIntel 		port->stats.rx_nombuf = 0;
1160af75078fSIntel 
1161af75078fSIntel 		total_recv += stats.ipackets;
1162af75078fSIntel 		total_xmit += stats.opackets;
116370bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1164af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1165af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1166af75078fSIntel 
1167af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1168af75078fSIntel 	}
1169af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1170af75078fSIntel 	       "%s\n",
1171af75078fSIntel 	       acc_stats_border, acc_stats_border);
1172af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1173af75078fSIntel 	       "%-"PRIu64"\n"
1174af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1175af75078fSIntel 	       "%-"PRIu64"\n",
1176af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1177af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1178af75078fSIntel 	if (total_rx_nombuf > 0)
1179af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1180af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1181af75078fSIntel 	       "%s\n",
1182af75078fSIntel 	       acc_stats_border, acc_stats_border);
1183af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1184af75078fSIntel 	if (total_recv > 0)
1185af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1186af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1187af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1188af75078fSIntel 		       fwd_cycles, total_recv);
1189af75078fSIntel #endif
1190af75078fSIntel 	printf("\nDone.\n");
1191af75078fSIntel 	test_done = 1;
1192af75078fSIntel }
1193af75078fSIntel 
1194cfae07fdSOuyang Changchun void
1195cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1196cfae07fdSOuyang Changchun {
1197cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1198cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1199cfae07fdSOuyang Changchun }
1200cfae07fdSOuyang Changchun 
1201cfae07fdSOuyang Changchun void
1202cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1203cfae07fdSOuyang Changchun {
1204cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1205cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1206cfae07fdSOuyang Changchun }
1207cfae07fdSOuyang Changchun 
1208ce8d5614SIntel static int
1209ce8d5614SIntel all_ports_started(void)
1210ce8d5614SIntel {
1211ce8d5614SIntel 	portid_t pi;
1212ce8d5614SIntel 	struct rte_port *port;
1213ce8d5614SIntel 
1214edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1215ce8d5614SIntel 		port = &ports[pi];
1216ce8d5614SIntel 		/* Check if there is a port which is not started */
121741b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
121841b05095SBernard Iremonger 			(port->slave_flag == 0))
1219ce8d5614SIntel 			return 0;
1220ce8d5614SIntel 	}
1221ce8d5614SIntel 
1222ce8d5614SIntel 	/* No port is not started */
1223ce8d5614SIntel 	return 1;
1224ce8d5614SIntel }
1225ce8d5614SIntel 
1226148f963fSBruce Richardson int
1227edab33b1STetsuya Mukawa all_ports_stopped(void)
1228edab33b1STetsuya Mukawa {
1229edab33b1STetsuya Mukawa 	portid_t pi;
1230edab33b1STetsuya Mukawa 	struct rte_port *port;
1231edab33b1STetsuya Mukawa 
1232edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1233edab33b1STetsuya Mukawa 		port = &ports[pi];
123441b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
123541b05095SBernard Iremonger 			(port->slave_flag == 0))
1236edab33b1STetsuya Mukawa 			return 0;
1237edab33b1STetsuya Mukawa 	}
1238edab33b1STetsuya Mukawa 
1239edab33b1STetsuya Mukawa 	return 1;
1240edab33b1STetsuya Mukawa }
1241edab33b1STetsuya Mukawa 
1242edab33b1STetsuya Mukawa int
1243edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1244edab33b1STetsuya Mukawa {
1245edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1246edab33b1STetsuya Mukawa 		return 0;
1247edab33b1STetsuya Mukawa 
1248edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1249edab33b1STetsuya Mukawa 		return 0;
1250edab33b1STetsuya Mukawa 
1251edab33b1STetsuya Mukawa 	return 1;
1252edab33b1STetsuya Mukawa }
1253edab33b1STetsuya Mukawa 
1254edab33b1STetsuya Mukawa static int
1255edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1256edab33b1STetsuya Mukawa {
1257edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1258edab33b1STetsuya Mukawa 		return 0;
1259edab33b1STetsuya Mukawa 
1260edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1261edab33b1STetsuya Mukawa 		return 0;
1262edab33b1STetsuya Mukawa 
1263edab33b1STetsuya Mukawa 	return 1;
1264edab33b1STetsuya Mukawa }
1265edab33b1STetsuya Mukawa 
1266edab33b1STetsuya Mukawa int
1267ce8d5614SIntel start_port(portid_t pid)
1268ce8d5614SIntel {
126992d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1270ce8d5614SIntel 	portid_t pi;
1271ce8d5614SIntel 	queueid_t qi;
1272ce8d5614SIntel 	struct rte_port *port;
12732950a769SDeclan Doherty 	struct ether_addr mac_addr;
1274ce8d5614SIntel 
1275ce8d5614SIntel 	if (test_done == 0) {
1276ce8d5614SIntel 		printf("Please stop forwarding first\n");
1277148f963fSBruce Richardson 		return -1;
1278ce8d5614SIntel 	}
1279ce8d5614SIntel 
12804468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
12814468635fSMichael Qiu 		return 0;
12824468635fSMichael Qiu 
1283ce8d5614SIntel 	if (init_fwd_streams() < 0) {
1284ce8d5614SIntel 		printf("Fail from init_fwd_streams()\n");
1285148f963fSBruce Richardson 		return -1;
1286ce8d5614SIntel 	}
1287ce8d5614SIntel 
1288ce8d5614SIntel 	if(dcb_config)
1289ce8d5614SIntel 		dcb_test = 1;
1290edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1291edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1292ce8d5614SIntel 			continue;
1293ce8d5614SIntel 
129492d2703eSMichael Qiu 		need_check_link_status = 0;
1295ce8d5614SIntel 		port = &ports[pi];
1296ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1297ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1298ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1299ce8d5614SIntel 			continue;
1300ce8d5614SIntel 		}
1301ce8d5614SIntel 
1302ce8d5614SIntel 		if (port->need_reconfig > 0) {
1303ce8d5614SIntel 			port->need_reconfig = 0;
1304ce8d5614SIntel 
13055706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
130620a0286fSLiu Xiaofeng 					port->socket_id);
1307ce8d5614SIntel 			/* configure port */
1308ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1309ce8d5614SIntel 						&(port->dev_conf));
1310ce8d5614SIntel 			if (diag != 0) {
1311ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1312ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1313ce8d5614SIntel 					printf("Port %d can not be set back "
1314ce8d5614SIntel 							"to stopped\n", pi);
1315ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1316ce8d5614SIntel 				/* try to reconfigure port next time */
1317ce8d5614SIntel 				port->need_reconfig = 1;
1318148f963fSBruce Richardson 				return -1;
1319ce8d5614SIntel 			}
1320ce8d5614SIntel 		}
1321ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1322ce8d5614SIntel 			port->need_reconfig_queues = 0;
1323ce8d5614SIntel 			/* setup tx queues */
1324ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1325b6ea6408SIntel 				if ((numa_support) &&
1326b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1327b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1328b6ea6408SIntel 						nb_txd,txring_numa[pi],
1329b6ea6408SIntel 						&(port->tx_conf));
1330b6ea6408SIntel 				else
1331b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1332b6ea6408SIntel 						nb_txd,port->socket_id,
1333b6ea6408SIntel 						&(port->tx_conf));
1334b6ea6408SIntel 
1335ce8d5614SIntel 				if (diag == 0)
1336ce8d5614SIntel 					continue;
1337ce8d5614SIntel 
1338ce8d5614SIntel 				/* Fail to setup tx queue, return */
1339ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1340ce8d5614SIntel 							RTE_PORT_HANDLING,
1341ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1342ce8d5614SIntel 					printf("Port %d can not be set back "
1343ce8d5614SIntel 							"to stopped\n", pi);
1344ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1345ce8d5614SIntel 				/* try to reconfigure queues next time */
1346ce8d5614SIntel 				port->need_reconfig_queues = 1;
1347148f963fSBruce Richardson 				return -1;
1348ce8d5614SIntel 			}
1349ce8d5614SIntel 			/* setup rx queues */
1350ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1351b6ea6408SIntel 				if ((numa_support) &&
1352b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1353b6ea6408SIntel 					struct rte_mempool * mp =
1354b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1355b6ea6408SIntel 					if (mp == NULL) {
1356b6ea6408SIntel 						printf("Failed to setup RX queue:"
1357b6ea6408SIntel 							"No mempool allocation"
1358b6ea6408SIntel 							"on the socket %d\n",
1359b6ea6408SIntel 							rxring_numa[pi]);
1360148f963fSBruce Richardson 						return -1;
1361b6ea6408SIntel 					}
1362b6ea6408SIntel 
1363b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1364b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1365b6ea6408SIntel 					     &(port->rx_conf),mp);
1366b6ea6408SIntel 				}
1367b6ea6408SIntel 				else
1368b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1369b6ea6408SIntel 					     nb_rxd,port->socket_id,
1370b6ea6408SIntel 					     &(port->rx_conf),
1371ce8d5614SIntel 				             mbuf_pool_find(port->socket_id));
1372b6ea6408SIntel 
1373ce8d5614SIntel 				if (diag == 0)
1374ce8d5614SIntel 					continue;
1375ce8d5614SIntel 
1376b6ea6408SIntel 
1377ce8d5614SIntel 				/* Fail to setup rx queue, return */
1378ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1379ce8d5614SIntel 							RTE_PORT_HANDLING,
1380ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1381ce8d5614SIntel 					printf("Port %d can not be set back "
1382ce8d5614SIntel 							"to stopped\n", pi);
1383ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1384ce8d5614SIntel 				/* try to reconfigure queues next time */
1385ce8d5614SIntel 				port->need_reconfig_queues = 1;
1386148f963fSBruce Richardson 				return -1;
1387ce8d5614SIntel 			}
1388ce8d5614SIntel 		}
1389ce8d5614SIntel 		/* start port */
1390ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1391ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1392ce8d5614SIntel 
1393ce8d5614SIntel 			/* Fail to setup rx queue, return */
1394ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1395ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1396ce8d5614SIntel 				printf("Port %d can not be set back to "
1397ce8d5614SIntel 							"stopped\n", pi);
1398ce8d5614SIntel 			continue;
1399ce8d5614SIntel 		}
1400ce8d5614SIntel 
1401ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1402ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1403ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1404ce8d5614SIntel 
14052950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1406d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
14072950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
14082950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
14092950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1410d8c89163SZijie Pan 
1411ce8d5614SIntel 		/* at least one port started, need checking link status */
1412ce8d5614SIntel 		need_check_link_status = 1;
1413ce8d5614SIntel 	}
1414ce8d5614SIntel 
141592d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1416edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
141792d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1418ce8d5614SIntel 		printf("Please stop the ports first\n");
1419ce8d5614SIntel 
1420ce8d5614SIntel 	printf("Done\n");
1421148f963fSBruce Richardson 	return 0;
1422ce8d5614SIntel }
1423ce8d5614SIntel 
1424ce8d5614SIntel void
1425ce8d5614SIntel stop_port(portid_t pid)
1426ce8d5614SIntel {
1427ce8d5614SIntel 	portid_t pi;
1428ce8d5614SIntel 	struct rte_port *port;
1429ce8d5614SIntel 	int need_check_link_status = 0;
1430ce8d5614SIntel 
1431ce8d5614SIntel 	if (test_done == 0) {
1432ce8d5614SIntel 		printf("Please stop forwarding first\n");
1433ce8d5614SIntel 		return;
1434ce8d5614SIntel 	}
1435ce8d5614SIntel 	if (dcb_test) {
1436ce8d5614SIntel 		dcb_test = 0;
1437ce8d5614SIntel 		dcb_config = 0;
1438ce8d5614SIntel 	}
14394468635fSMichael Qiu 
14404468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14414468635fSMichael Qiu 		return;
14424468635fSMichael Qiu 
1443ce8d5614SIntel 	printf("Stopping ports...\n");
1444ce8d5614SIntel 
1445edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14464468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1447ce8d5614SIntel 			continue;
1448ce8d5614SIntel 
1449ce8d5614SIntel 		port = &ports[pi];
1450ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1451ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1452ce8d5614SIntel 			continue;
1453ce8d5614SIntel 
1454ce8d5614SIntel 		rte_eth_dev_stop(pi);
1455ce8d5614SIntel 
1456ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1457ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1458ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1459ce8d5614SIntel 		need_check_link_status = 1;
1460ce8d5614SIntel 	}
1461bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1462edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1463ce8d5614SIntel 
1464ce8d5614SIntel 	printf("Done\n");
1465ce8d5614SIntel }
1466ce8d5614SIntel 
1467ce8d5614SIntel void
1468ce8d5614SIntel close_port(portid_t pid)
1469ce8d5614SIntel {
1470ce8d5614SIntel 	portid_t pi;
1471ce8d5614SIntel 	struct rte_port *port;
1472ce8d5614SIntel 
1473ce8d5614SIntel 	if (test_done == 0) {
1474ce8d5614SIntel 		printf("Please stop forwarding first\n");
1475ce8d5614SIntel 		return;
1476ce8d5614SIntel 	}
1477ce8d5614SIntel 
14784468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14794468635fSMichael Qiu 		return;
14804468635fSMichael Qiu 
1481ce8d5614SIntel 	printf("Closing ports...\n");
1482ce8d5614SIntel 
1483edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14844468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1485ce8d5614SIntel 			continue;
1486ce8d5614SIntel 
1487ce8d5614SIntel 		port = &ports[pi];
1488ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1489d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1490d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1491d4e8ad64SMichael Qiu 			continue;
1492d4e8ad64SMichael Qiu 		}
1493d4e8ad64SMichael Qiu 
1494d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1495ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1496ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1497ce8d5614SIntel 			continue;
1498ce8d5614SIntel 		}
1499ce8d5614SIntel 
1500ce8d5614SIntel 		rte_eth_dev_close(pi);
1501ce8d5614SIntel 
1502ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1503ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1504ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1505ce8d5614SIntel 	}
1506ce8d5614SIntel 
1507ce8d5614SIntel 	printf("Done\n");
1508ce8d5614SIntel }
1509ce8d5614SIntel 
1510edab33b1STetsuya Mukawa void
1511edab33b1STetsuya Mukawa attach_port(char *identifier)
1512ce8d5614SIntel {
1513edab33b1STetsuya Mukawa 	portid_t i, j, pi = 0;
1514ce8d5614SIntel 
1515edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1516edab33b1STetsuya Mukawa 
1517edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1518edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1519edab33b1STetsuya Mukawa 		return;
1520ce8d5614SIntel 	}
1521ce8d5614SIntel 
1522edab33b1STetsuya Mukawa 	if (test_done == 0) {
1523edab33b1STetsuya Mukawa 		printf("Please stop forwarding first\n");
1524edab33b1STetsuya Mukawa 		return;
1525ce8d5614SIntel 	}
1526ce8d5614SIntel 
1527edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1528edab33b1STetsuya Mukawa 		return;
1529edab33b1STetsuya Mukawa 
1530edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1531edab33b1STetsuya Mukawa 	reconfig(pi, rte_eth_dev_socket_id(pi));
1532edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1533edab33b1STetsuya Mukawa 
1534edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1535edab33b1STetsuya Mukawa 
1536edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1537edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1538edab33b1STetsuya Mukawa 	i = 0;
1539edab33b1STetsuya Mukawa 	FOREACH_PORT(j, ports) {
1540edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = j;
1541edab33b1STetsuya Mukawa 		i++;
1542edab33b1STetsuya Mukawa 	}
1543edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1544edab33b1STetsuya Mukawa 	nb_fwd_ports++;
1545edab33b1STetsuya Mukawa 
1546edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1547edab33b1STetsuya Mukawa 
1548edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1549edab33b1STetsuya Mukawa 	printf("Done\n");
1550edab33b1STetsuya Mukawa }
1551edab33b1STetsuya Mukawa 
1552edab33b1STetsuya Mukawa void
1553edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
15545f4ec54fSChen Jing D(Mark) {
1555edab33b1STetsuya Mukawa 	portid_t i, pi = 0;
1556edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
15575f4ec54fSChen Jing D(Mark) 
1558edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
15595f4ec54fSChen Jing D(Mark) 
1560edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1561edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1562edab33b1STetsuya Mukawa 		return;
1563edab33b1STetsuya Mukawa 	}
1564edab33b1STetsuya Mukawa 
1565edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1566edab33b1STetsuya Mukawa 		return;
1567edab33b1STetsuya Mukawa 
1568edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1569edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1570edab33b1STetsuya Mukawa 
1571edab33b1STetsuya Mukawa 	/* set_default_fwd_ports_config(); */
1572edab33b1STetsuya Mukawa 	bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
1573edab33b1STetsuya Mukawa 	i = 0;
1574edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1575edab33b1STetsuya Mukawa 		fwd_ports_ids[i] = pi;
1576edab33b1STetsuya Mukawa 		i++;
1577edab33b1STetsuya Mukawa 	}
1578edab33b1STetsuya Mukawa 	nb_cfg_ports = nb_ports;
1579edab33b1STetsuya Mukawa 	nb_fwd_ports--;
1580edab33b1STetsuya Mukawa 
1581edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1582edab33b1STetsuya Mukawa 			name, nb_ports);
1583edab33b1STetsuya Mukawa 	printf("Done\n");
1584edab33b1STetsuya Mukawa 	return;
15855f4ec54fSChen Jing D(Mark) }
15865f4ec54fSChen Jing D(Mark) 
1587af75078fSIntel void
1588af75078fSIntel pmd_test_exit(void)
1589af75078fSIntel {
1590af75078fSIntel 	portid_t pt_id;
1591af75078fSIntel 
15928210ec25SPablo de Lara 	if (test_done == 0)
15938210ec25SPablo de Lara 		stop_packet_forwarding();
15948210ec25SPablo de Lara 
1595edab33b1STetsuya Mukawa 	FOREACH_PORT(pt_id, ports) {
1596af75078fSIntel 		printf("Stopping port %d...", pt_id);
1597af75078fSIntel 		fflush(stdout);
1598af75078fSIntel 		rte_eth_dev_close(pt_id);
1599af75078fSIntel 		printf("done\n");
1600af75078fSIntel 	}
1601af75078fSIntel 	printf("bye...\n");
1602af75078fSIntel }
1603af75078fSIntel 
1604af75078fSIntel typedef void (*cmd_func_t)(void);
1605af75078fSIntel struct pmd_test_command {
1606af75078fSIntel 	const char *cmd_name;
1607af75078fSIntel 	cmd_func_t cmd_func;
1608af75078fSIntel };
1609af75078fSIntel 
1610af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1611af75078fSIntel 
1612ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1613af75078fSIntel static void
1614edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1615af75078fSIntel {
1616ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1617ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1618ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1619ce8d5614SIntel 	struct rte_eth_link link;
1620ce8d5614SIntel 
1621ce8d5614SIntel 	printf("Checking link statuses...\n");
1622ce8d5614SIntel 	fflush(stdout);
1623ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1624ce8d5614SIntel 		all_ports_up = 1;
1625edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1626ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1627ce8d5614SIntel 				continue;
1628ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1629ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1630ce8d5614SIntel 			/* print link status if flag set */
1631ce8d5614SIntel 			if (print_flag == 1) {
1632ce8d5614SIntel 				if (link.link_status)
1633ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1634ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1635ce8d5614SIntel 						(unsigned)link.link_speed,
1636ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1637ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1638ce8d5614SIntel 				else
1639ce8d5614SIntel 					printf("Port %d Link Down\n",
1640ce8d5614SIntel 						(uint8_t)portid);
1641ce8d5614SIntel 				continue;
1642ce8d5614SIntel 			}
1643ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
1644ce8d5614SIntel 			if (link.link_status == 0) {
1645ce8d5614SIntel 				all_ports_up = 0;
1646ce8d5614SIntel 				break;
1647ce8d5614SIntel 			}
1648ce8d5614SIntel 		}
1649ce8d5614SIntel 		/* after finally printing all link status, get out */
1650ce8d5614SIntel 		if (print_flag == 1)
1651ce8d5614SIntel 			break;
1652ce8d5614SIntel 
1653ce8d5614SIntel 		if (all_ports_up == 0) {
1654ce8d5614SIntel 			fflush(stdout);
1655ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1656ce8d5614SIntel 		}
1657ce8d5614SIntel 
1658ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1659ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1660ce8d5614SIntel 			print_flag = 1;
1661ce8d5614SIntel 		}
1662ce8d5614SIntel 	}
1663af75078fSIntel }
1664af75078fSIntel 
1665013af9b6SIntel static int
1666013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1667af75078fSIntel {
1668013af9b6SIntel 	uint16_t i;
1669af75078fSIntel 	int diag;
1670013af9b6SIntel 	uint8_t mapping_found = 0;
1671af75078fSIntel 
1672013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1673013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1674013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1675013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1676013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1677013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1678013af9b6SIntel 			if (diag != 0)
1679013af9b6SIntel 				return diag;
1680013af9b6SIntel 			mapping_found = 1;
1681af75078fSIntel 		}
1682013af9b6SIntel 	}
1683013af9b6SIntel 	if (mapping_found)
1684013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1685013af9b6SIntel 	return 0;
1686013af9b6SIntel }
1687013af9b6SIntel 
1688013af9b6SIntel static int
1689013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1690013af9b6SIntel {
1691013af9b6SIntel 	uint16_t i;
1692013af9b6SIntel 	int diag;
1693013af9b6SIntel 	uint8_t mapping_found = 0;
1694013af9b6SIntel 
1695013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1696013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1697013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1698013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1699013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1700013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1701013af9b6SIntel 			if (diag != 0)
1702013af9b6SIntel 				return diag;
1703013af9b6SIntel 			mapping_found = 1;
1704013af9b6SIntel 		}
1705013af9b6SIntel 	}
1706013af9b6SIntel 	if (mapping_found)
1707013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1708013af9b6SIntel 	return 0;
1709013af9b6SIntel }
1710013af9b6SIntel 
1711013af9b6SIntel static void
1712013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1713013af9b6SIntel {
1714013af9b6SIntel 	int diag = 0;
1715013af9b6SIntel 
1716013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1717af75078fSIntel 	if (diag != 0) {
1718013af9b6SIntel 		if (diag == -ENOTSUP) {
1719013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1720013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1721013af9b6SIntel 		}
1722013af9b6SIntel 		else
1723013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1724013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1725013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1726af75078fSIntel 					pi, diag);
1727af75078fSIntel 	}
1728013af9b6SIntel 
1729013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1730af75078fSIntel 	if (diag != 0) {
1731013af9b6SIntel 		if (diag == -ENOTSUP) {
1732013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1733013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1734013af9b6SIntel 		}
1735013af9b6SIntel 		else
1736013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1737013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1738013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1739af75078fSIntel 					pi, diag);
1740af75078fSIntel 	}
1741af75078fSIntel }
1742af75078fSIntel 
1743f2c5125aSPablo de Lara static void
1744f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1745f2c5125aSPablo de Lara {
1746f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1747f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1748f2c5125aSPablo de Lara 
1749f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1750f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1751f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1752f2c5125aSPablo de Lara 
1753f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1754f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1755f2c5125aSPablo de Lara 
1756f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1757f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1758f2c5125aSPablo de Lara 
1759f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1760f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1761f2c5125aSPablo de Lara 
1762f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1763f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1764f2c5125aSPablo de Lara 
1765f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1766f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1767f2c5125aSPablo de Lara 
1768f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1769f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1770f2c5125aSPablo de Lara 
1771f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1772f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1773f2c5125aSPablo de Lara 
1774f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1775f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1776f2c5125aSPablo de Lara 
1777f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1778f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1779f2c5125aSPablo de Lara 
1780f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1781f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1782f2c5125aSPablo de Lara }
1783f2c5125aSPablo de Lara 
1784013af9b6SIntel void
1785013af9b6SIntel init_port_config(void)
1786013af9b6SIntel {
1787013af9b6SIntel 	portid_t pid;
1788013af9b6SIntel 	struct rte_port *port;
1789013af9b6SIntel 
1790edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1791013af9b6SIntel 		port = &ports[pid];
1792013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1793013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
17943ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1795013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1796013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1797af75078fSIntel 		} else {
1798013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1799013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1800af75078fSIntel 		}
18013ce690d3SBruce Richardson 
18023ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
18033ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
18043ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
18053ce690d3SBruce Richardson 			else
18063ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
18073ce690d3SBruce Richardson 		}
18083ce690d3SBruce Richardson 
1809a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1810a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1811a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1812a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1813a30979f6SOuyang Changchun 			else
1814a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1815a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1816a30979f6SOuyang Changchun 
1817a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1818a30979f6SOuyang Changchun 		}
1819a30979f6SOuyang Changchun 
1820f2c5125aSPablo de Lara 		rxtx_port_config(port);
1821013af9b6SIntel 
1822013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1823013af9b6SIntel 
1824013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18257b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18267b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18277b7e5ba7SIntel #endif
1828013af9b6SIntel 	}
1829013af9b6SIntel }
1830013af9b6SIntel 
183141b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
183241b05095SBernard Iremonger {
183341b05095SBernard Iremonger 	struct rte_port *port;
183441b05095SBernard Iremonger 
183541b05095SBernard Iremonger 	port = &ports[slave_pid];
183641b05095SBernard Iremonger 	port->slave_flag = 1;
183741b05095SBernard Iremonger }
183841b05095SBernard Iremonger 
183941b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
184041b05095SBernard Iremonger {
184141b05095SBernard Iremonger 	struct rte_port *port;
184241b05095SBernard Iremonger 
184341b05095SBernard Iremonger 	port = &ports[slave_pid];
184441b05095SBernard Iremonger 	port->slave_flag = 0;
184541b05095SBernard Iremonger }
184641b05095SBernard Iremonger 
1847013af9b6SIntel const uint16_t vlan_tags[] = {
1848013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1849013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1850013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1851013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1852013af9b6SIntel };
1853013af9b6SIntel 
1854013af9b6SIntel static  int
1855013af9b6SIntel get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
1856013af9b6SIntel {
1857013af9b6SIntel         uint8_t i;
1858af75078fSIntel 
1859af75078fSIntel 	/*
1860013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1861013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
1862af75078fSIntel 	 */
1863013af9b6SIntel 	if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
1864013af9b6SIntel 		struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
1865013af9b6SIntel 		struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
1866013af9b6SIntel 
1867013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
1868013af9b6SIntel 		vmdq_rx_conf.enable_default_pool = 0;
1869013af9b6SIntel 		vmdq_rx_conf.default_pool = 0;
1870013af9b6SIntel 		vmdq_rx_conf.nb_queue_pools =
1871013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1872013af9b6SIntel 		vmdq_tx_conf.nb_queue_pools =
1873013af9b6SIntel 			(dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1874013af9b6SIntel 
1875013af9b6SIntel 		vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1876013af9b6SIntel 		for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
1877013af9b6SIntel 			vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
1878013af9b6SIntel 			vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
1879af75078fSIntel 		}
1880013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1881013af9b6SIntel 			vmdq_rx_conf.dcb_queue[i] = i;
1882013af9b6SIntel 			vmdq_tx_conf.dcb_queue[i] = i;
1883013af9b6SIntel 		}
1884013af9b6SIntel 
1885013af9b6SIntel 		/*set DCB mode of RX and TX of multiple queues*/
188632e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
188732e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1888013af9b6SIntel 		if (dcb_conf->pfc_en)
1889013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1890013af9b6SIntel 		else
1891013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1892013af9b6SIntel 
1893013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
1894013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_conf)));
1895013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
1896013af9b6SIntel                                 sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
1897013af9b6SIntel 	}
1898013af9b6SIntel 	else {
1899013af9b6SIntel 		struct rte_eth_dcb_rx_conf rx_conf;
1900013af9b6SIntel 		struct rte_eth_dcb_tx_conf tx_conf;
1901013af9b6SIntel 
1902013af9b6SIntel 		/* queue mapping configuration of DCB RX and TX */
1903013af9b6SIntel 		if (dcb_conf->num_tcs == ETH_4_TCS)
1904013af9b6SIntel 			dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
1905013af9b6SIntel 		else
1906013af9b6SIntel 			dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
1907013af9b6SIntel 
1908013af9b6SIntel 		rx_conf.nb_tcs = dcb_conf->num_tcs;
1909013af9b6SIntel 		tx_conf.nb_tcs = dcb_conf->num_tcs;
1910013af9b6SIntel 
1911013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
1912013af9b6SIntel 			rx_conf.dcb_queue[i] = i;
1913013af9b6SIntel 			tx_conf.dcb_queue[i] = i;
1914013af9b6SIntel 		}
191532e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
191632e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1917013af9b6SIntel 		if (dcb_conf->pfc_en)
1918013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
1919013af9b6SIntel 		else
1920013af9b6SIntel 			eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1921013af9b6SIntel 
1922013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
1923013af9b6SIntel                                 sizeof(struct rte_eth_dcb_rx_conf)));
1924013af9b6SIntel 		(void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
1925013af9b6SIntel                                 sizeof(struct rte_eth_dcb_tx_conf)));
1926013af9b6SIntel 	}
1927013af9b6SIntel 
1928013af9b6SIntel 	return 0;
1929013af9b6SIntel }
1930013af9b6SIntel 
1931013af9b6SIntel int
1932013af9b6SIntel init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
1933013af9b6SIntel {
1934013af9b6SIntel 	struct rte_eth_conf port_conf;
1935013af9b6SIntel 	struct rte_port *rte_port;
1936013af9b6SIntel 	int retval;
1937013af9b6SIntel 	uint16_t nb_vlan;
1938013af9b6SIntel 	uint16_t i;
1939013af9b6SIntel 
1940013af9b6SIntel 	/* rxq and txq configuration in dcb mode */
1941013af9b6SIntel 	nb_rxq = 128;
1942013af9b6SIntel 	nb_txq = 128;
1943013af9b6SIntel 	rx_free_thresh = 64;
1944013af9b6SIntel 
1945013af9b6SIntel 	memset(&port_conf,0,sizeof(struct rte_eth_conf));
1946013af9b6SIntel 	/* Enter DCB configuration status */
1947013af9b6SIntel 	dcb_config = 1;
1948013af9b6SIntel 
1949013af9b6SIntel 	nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
1950013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
1951013af9b6SIntel 	retval = get_eth_dcb_conf(&port_conf, dcb_conf);
1952013af9b6SIntel 	if (retval < 0)
1953013af9b6SIntel 		return retval;
1954013af9b6SIntel 
1955013af9b6SIntel 	rte_port = &ports[pid];
1956013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
1957013af9b6SIntel 
1958f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
1959013af9b6SIntel 	/* VLAN filter */
1960013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
1961013af9b6SIntel 	for (i = 0; i < nb_vlan; i++){
1962013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1963013af9b6SIntel 	}
1964013af9b6SIntel 
1965013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1966013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1967013af9b6SIntel 
19687741e4cfSIntel 	rte_port->dcb_flag = 1;
19697741e4cfSIntel 
1970013af9b6SIntel 	return 0;
1971af75078fSIntel }
1972af75078fSIntel 
1973ffc468ffSTetsuya Mukawa static void
1974ffc468ffSTetsuya Mukawa init_port(void)
1975ffc468ffSTetsuya Mukawa {
1976ffc468ffSTetsuya Mukawa 	portid_t pid;
1977ffc468ffSTetsuya Mukawa 
1978ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
1979ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
1980ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
1981ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
1982ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
1983ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
1984ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
1985ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
1986ffc468ffSTetsuya Mukawa 	}
1987ffc468ffSTetsuya Mukawa 
1988ffc468ffSTetsuya Mukawa 	/* enabled allocated ports */
1989ffc468ffSTetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
1990ffc468ffSTetsuya Mukawa 		ports[pid].enabled = 1;
1991ffc468ffSTetsuya Mukawa }
1992ffc468ffSTetsuya Mukawa 
1993af75078fSIntel int
1994af75078fSIntel main(int argc, char** argv)
1995af75078fSIntel {
1996af75078fSIntel 	int  diag;
1997013af9b6SIntel 	uint8_t port_id;
1998af75078fSIntel 
1999af75078fSIntel 	diag = rte_eal_init(argc, argv);
2000af75078fSIntel 	if (diag < 0)
2001af75078fSIntel 		rte_panic("Cannot init EAL\n");
2002af75078fSIntel 
2003af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2004af75078fSIntel 	if (nb_ports == 0)
2005edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2006af75078fSIntel 
2007ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2008ffc468ffSTetsuya Mukawa 	init_port();
2009ffc468ffSTetsuya Mukawa 
2010af75078fSIntel 	set_def_fwd_config();
2011af75078fSIntel 	if (nb_lcores == 0)
2012af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2013af75078fSIntel 			  "core mask supplied in the command parameters\n");
2014af75078fSIntel 
2015af75078fSIntel 	argc -= diag;
2016af75078fSIntel 	argv += diag;
2017af75078fSIntel 	if (argc > 1)
2018af75078fSIntel 		launch_args_parse(argc, argv);
2019af75078fSIntel 
2020af75078fSIntel 	if (nb_rxq > nb_txq)
2021af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2022af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2023af75078fSIntel 		       nb_rxq, nb_txq);
2024af75078fSIntel 
2025af75078fSIntel 	init_config();
2026148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2027148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2028af75078fSIntel 
2029ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
2030edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
2031ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2032af75078fSIntel 
20330d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2034ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2035ca7feb22SCyril Chemparathy 		if (auto_start) {
2036ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2037ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2038ca7feb22SCyril Chemparathy 		}
2039af75078fSIntel 		prompt();
2040ca7feb22SCyril Chemparathy 	} else
20410d56cb81SThomas Monjalon #endif
20420d56cb81SThomas Monjalon 	{
2043af75078fSIntel 		char c;
2044af75078fSIntel 		int rc;
2045af75078fSIntel 
2046af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2047af75078fSIntel 		start_packet_forwarding(0);
2048af75078fSIntel 		printf("Press enter to exit\n");
2049af75078fSIntel 		rc = read(0, &c, 1);
2050af75078fSIntel 		if (rc < 0)
2051af75078fSIntel 			return 1;
2052af75078fSIntel 	}
2053af75078fSIntel 
2054af75078fSIntel 	return 0;
2055af75078fSIntel }
2056