xref: /dpdk/app/test-pmd/testpmd.c (revision 86ef65ee58caace3a54ae94bb5b387070b28d539)
1af75078fSIntel /*-
2af75078fSIntel  *   BSD LICENSE
3af75078fSIntel  *
45a8fb55cSReshma Pattan  *   Copyright(c) 2010-2016 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>
52d1eb542eSOlivier Matz #include <rte_errno.h>
53af75078fSIntel #include <rte_byteorder.h>
54af75078fSIntel #include <rte_log.h>
55af75078fSIntel #include <rte_debug.h>
56af75078fSIntel #include <rte_cycles.h>
57af75078fSIntel #include <rte_memory.h>
58af75078fSIntel #include <rte_memcpy.h>
59af75078fSIntel #include <rte_memzone.h>
60af75078fSIntel #include <rte_launch.h>
61af75078fSIntel #include <rte_eal.h>
62af75078fSIntel #include <rte_per_lcore.h>
63af75078fSIntel #include <rte_lcore.h>
64af75078fSIntel #include <rte_atomic.h>
65af75078fSIntel #include <rte_branch_prediction.h>
66af75078fSIntel #include <rte_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
78102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
79102b7329SReshma Pattan #include <rte_pdump.h>
80102b7329SReshma Pattan #endif
81af75078fSIntel 
82af75078fSIntel #include "testpmd.h"
83af75078fSIntel 
84af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
85af75078fSIntel 
86af75078fSIntel /* use master core for command line ? */
87af75078fSIntel uint8_t interactive = 0;
88ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
89af75078fSIntel 
90af75078fSIntel /*
91af75078fSIntel  * NUMA support configuration.
92af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
93af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
94af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
95af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
96af75078fSIntel  */
97af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */
98af75078fSIntel 
99af75078fSIntel /*
100b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
101b6ea6408SIntel  * not configured.
102b6ea6408SIntel  */
103b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
104b6ea6408SIntel 
105b6ea6408SIntel /*
106148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
107148f963fSBruce Richardson  */
108148f963fSBruce Richardson uint8_t mp_anon = 0;
109148f963fSBruce Richardson 
110148f963fSBruce Richardson /*
111af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
112af75078fSIntel  * forwarded.
113af75078fSIntel  * Must be instanciated with the ethernet addresses of peer traffic generator
114af75078fSIntel  * ports.
115af75078fSIntel  */
116af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
117af75078fSIntel portid_t nb_peer_eth_addrs = 0;
118af75078fSIntel 
119af75078fSIntel /*
120af75078fSIntel  * Probed Target Environment.
121af75078fSIntel  */
122af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
123af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
124af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
125af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
126af75078fSIntel 
127af75078fSIntel /*
128af75078fSIntel  * Test Forwarding Configuration.
129af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
130af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
131af75078fSIntel  */
132af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
133af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
134af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
135af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
136af75078fSIntel 
137af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
138af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
139af75078fSIntel 
140af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
141af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
142af75078fSIntel 
143af75078fSIntel /*
144af75078fSIntel  * Forwarding engines.
145af75078fSIntel  */
146af75078fSIntel struct fwd_engine * fwd_engines[] = {
147af75078fSIntel 	&io_fwd_engine,
148af75078fSIntel 	&mac_fwd_engine,
149d47388f1SCyril Chemparathy 	&mac_swap_engine,
150e9e23a61SCyril Chemparathy 	&flow_gen_engine,
151af75078fSIntel 	&rx_only_engine,
152af75078fSIntel 	&tx_only_engine,
153af75078fSIntel 	&csum_fwd_engine,
154168dfa61SIvan Boule 	&icmp_echo_engine,
155af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
156af75078fSIntel 	&ieee1588_fwd_engine,
157af75078fSIntel #endif
158af75078fSIntel 	NULL,
159af75078fSIntel };
160af75078fSIntel 
161af75078fSIntel struct fwd_config cur_fwd_config;
162af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
163bf56fce1SZhihong Wang uint32_t retry_enabled;
164bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
165bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
166af75078fSIntel 
167af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
168c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
169c8798818SIntel                                       * specified on command-line. */
170af75078fSIntel 
171af75078fSIntel /*
172af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
173af75078fSIntel  */
174af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
175af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
176af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
177af75078fSIntel };
178af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
179af75078fSIntel 
18079bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
18179bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
18279bec05bSKonstantin Ananyev 
183af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
184e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
185af75078fSIntel 
186900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
187900550deSIntel uint8_t dcb_config = 0;
188900550deSIntel 
189900550deSIntel /* Whether the dcb is in testing status */
190900550deSIntel uint8_t dcb_test = 0;
191900550deSIntel 
192af75078fSIntel /*
193af75078fSIntel  * Configurable number of RX/TX queues.
194af75078fSIntel  */
195af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
196af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
197af75078fSIntel 
198af75078fSIntel /*
199af75078fSIntel  * Configurable number of RX/TX ring descriptors.
200af75078fSIntel  */
201af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
202af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
203af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
204af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
205af75078fSIntel 
206f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
207af75078fSIntel /*
208af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
209af75078fSIntel  */
210af75078fSIntel 
211f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
212f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
213f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
214af75078fSIntel 
215f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
216f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
217f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
218af75078fSIntel 
219af75078fSIntel /*
220af75078fSIntel  * Configurable value of RX free threshold.
221af75078fSIntel  */
222f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
223af75078fSIntel 
224af75078fSIntel /*
225ce8d5614SIntel  * Configurable value of RX drop enable.
226ce8d5614SIntel  */
227f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
228ce8d5614SIntel 
229ce8d5614SIntel /*
230af75078fSIntel  * Configurable value of TX free threshold.
231af75078fSIntel  */
232f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
233af75078fSIntel 
234af75078fSIntel /*
235af75078fSIntel  * Configurable value of TX RS bit threshold.
236af75078fSIntel  */
237f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
238af75078fSIntel 
239af75078fSIntel /*
240ce8d5614SIntel  * Configurable value of TX queue flags.
241ce8d5614SIntel  */
242f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
243ce8d5614SIntel 
244ce8d5614SIntel /*
245af75078fSIntel  * Receive Side Scaling (RSS) configuration.
246af75078fSIntel  */
2478a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
248af75078fSIntel 
249af75078fSIntel /*
250af75078fSIntel  * Port topology configuration
251af75078fSIntel  */
252af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
253af75078fSIntel 
2547741e4cfSIntel /*
2557741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2567741e4cfSIntel  */
2577741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2587741e4cfSIntel 
259af75078fSIntel /*
260bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
261bc202406SDavid Marchand  */
262bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
263bc202406SDavid Marchand 
264bc202406SDavid Marchand /*
2657b7e5ba7SIntel  * NIC bypass mode configuration options.
2667b7e5ba7SIntel  */
2677b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
2687b7e5ba7SIntel 
2697b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
2707b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
2717b7e5ba7SIntel 
2727b7e5ba7SIntel #endif
2737b7e5ba7SIntel 
2747b7e5ba7SIntel /*
275af75078fSIntel  * Ethernet device configuration.
276af75078fSIntel  */
277af75078fSIntel struct rte_eth_rxmode rx_mode = {
278af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
279af75078fSIntel 	.split_hdr_size = 0,
280af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
281af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
282af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
283a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
284a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
285af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
286af75078fSIntel 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
287af75078fSIntel };
288af75078fSIntel 
289af75078fSIntel struct rte_fdir_conf fdir_conf = {
290af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
291af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
292af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
293d9d5e6f2SJingjing Wu 	.mask = {
294d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
295d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
296d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
297d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
298d9d5e6f2SJingjing Wu 		},
299d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
300d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
301d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
302d9d5e6f2SJingjing Wu 		},
303d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
304d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
30547b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
30647b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
30747b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
308d9d5e6f2SJingjing Wu 	},
309af75078fSIntel 	.drop_queue = 127,
310af75078fSIntel };
311af75078fSIntel 
3122950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
313af75078fSIntel 
314ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
315ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
316ed30d9b6SIntel 
317ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
318ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
319ed30d9b6SIntel 
320ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
321ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
322ed30d9b6SIntel 
3237acf894dSStephen Hurd unsigned max_socket = 0;
3247acf894dSStephen Hurd 
325ed30d9b6SIntel /* Forward function declarations */
326ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
327edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
328ce8d5614SIntel 
329ce8d5614SIntel /*
330ce8d5614SIntel  * Check if all the ports are started.
331ce8d5614SIntel  * If yes, return positive value. If not, return zero.
332ce8d5614SIntel  */
333ce8d5614SIntel static int all_ports_started(void);
334ed30d9b6SIntel 
335af75078fSIntel /*
336edab33b1STetsuya Mukawa  * Find next enabled port
337edab33b1STetsuya Mukawa  */
338edab33b1STetsuya Mukawa portid_t
339edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
340edab33b1STetsuya Mukawa {
341edab33b1STetsuya Mukawa 	if (ports == NULL)
342edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
343edab33b1STetsuya Mukawa 
34412a8e30fSJulien Cretin 	while ((p < size) && (ports[p].enabled == 0))
345edab33b1STetsuya Mukawa 		p++;
346edab33b1STetsuya Mukawa 	return p;
347edab33b1STetsuya Mukawa }
348edab33b1STetsuya Mukawa 
349edab33b1STetsuya Mukawa /*
350af75078fSIntel  * Setup default configuration.
351af75078fSIntel  */
352af75078fSIntel static void
353af75078fSIntel set_default_fwd_lcores_config(void)
354af75078fSIntel {
355af75078fSIntel 	unsigned int i;
356af75078fSIntel 	unsigned int nb_lc;
3577acf894dSStephen Hurd 	unsigned int sock_num;
358af75078fSIntel 
359af75078fSIntel 	nb_lc = 0;
360af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
3617acf894dSStephen Hurd 		sock_num = rte_lcore_to_socket_id(i) + 1;
3627acf894dSStephen Hurd 		if (sock_num > max_socket) {
3637acf894dSStephen Hurd 			if (sock_num > RTE_MAX_NUMA_NODES)
3647acf894dSStephen Hurd 				rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
3657acf894dSStephen Hurd 			max_socket = sock_num;
3667acf894dSStephen Hurd 		}
367f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
368f54fe5eeSStephen Hurd 			continue;
369f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
370f54fe5eeSStephen Hurd 			continue;
371f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
372af75078fSIntel 	}
373af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
374af75078fSIntel 	nb_cfg_lcores = nb_lcores;
375af75078fSIntel 	nb_fwd_lcores = 1;
376af75078fSIntel }
377af75078fSIntel 
378af75078fSIntel static void
379af75078fSIntel set_def_peer_eth_addrs(void)
380af75078fSIntel {
381af75078fSIntel 	portid_t i;
382af75078fSIntel 
383af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
384af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
385af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
386af75078fSIntel 	}
387af75078fSIntel }
388af75078fSIntel 
389af75078fSIntel static void
390af75078fSIntel set_default_fwd_ports_config(void)
391af75078fSIntel {
392af75078fSIntel 	portid_t pt_id;
393af75078fSIntel 
394af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
395af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
396af75078fSIntel 
397af75078fSIntel 	nb_cfg_ports = nb_ports;
398af75078fSIntel 	nb_fwd_ports = nb_ports;
399af75078fSIntel }
400af75078fSIntel 
401af75078fSIntel void
402af75078fSIntel set_def_fwd_config(void)
403af75078fSIntel {
404af75078fSIntel 	set_default_fwd_lcores_config();
405af75078fSIntel 	set_def_peer_eth_addrs();
406af75078fSIntel 	set_default_fwd_ports_config();
407af75078fSIntel }
408af75078fSIntel 
409af75078fSIntel /*
410af75078fSIntel  * Configuration initialisation done once at init time.
411af75078fSIntel  */
412af75078fSIntel static void
413af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
414af75078fSIntel 		 unsigned int socket_id)
415af75078fSIntel {
416af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
417bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
418af75078fSIntel 	uint32_t mb_size;
419af75078fSIntel 
420dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
421af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
422148f963fSBruce Richardson 
423d1eb542eSOlivier Matz 	RTE_LOG(INFO, USER1,
424d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
425d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
426d1eb542eSOlivier Matz 
427148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
428148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
429af75078fSIntel 		(unsigned) mb_mempool_cache,
430af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
431dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
432dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
433af75078fSIntel 		socket_id, 0);
434bece7b6cSChristian Ehrhardt #endif
435148f963fSBruce Richardson 
436bece7b6cSChristian Ehrhardt 	/* if the former XEN allocation failed fall back to normal allocation */
437bece7b6cSChristian Ehrhardt 	if (rte_mp == NULL) {
438b19a0c75SOlivier Matz 		if (mp_anon != 0) {
439b19a0c75SOlivier Matz 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
440bece7b6cSChristian Ehrhardt 				mb_size, (unsigned) mb_mempool_cache,
441148f963fSBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private),
442148f963fSBruce Richardson 				socket_id, 0);
44324427bb9SOlivier Matz 			if (rte_mp == NULL)
44424427bb9SOlivier Matz 				goto err;
445b19a0c75SOlivier Matz 
446b19a0c75SOlivier Matz 			if (rte_mempool_populate_anon(rte_mp) == 0) {
447b19a0c75SOlivier Matz 				rte_mempool_free(rte_mp);
448b19a0c75SOlivier Matz 				rte_mp = NULL;
44924427bb9SOlivier Matz 				goto err;
450b19a0c75SOlivier Matz 			}
451b19a0c75SOlivier Matz 			rte_pktmbuf_pool_init(rte_mp, NULL);
452b19a0c75SOlivier Matz 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
453b19a0c75SOlivier Matz 		} else {
454ea0c20eaSOlivier Matz 			/* wrapper to rte_mempool_create() */
455ea0c20eaSOlivier Matz 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
456ea0c20eaSOlivier Matz 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
457bece7b6cSChristian Ehrhardt 		}
458b19a0c75SOlivier Matz 	}
459148f963fSBruce Richardson 
46024427bb9SOlivier Matz err:
461af75078fSIntel 	if (rte_mp == NULL) {
462d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
463d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
464d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
465148f963fSBruce Richardson 	} else if (verbose_level > 0) {
466591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
467af75078fSIntel 	}
468af75078fSIntel }
469af75078fSIntel 
47020a0286fSLiu Xiaofeng /*
47120a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
47220a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
47320a0286fSLiu Xiaofeng  */
47420a0286fSLiu Xiaofeng static int
47520a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
47620a0286fSLiu Xiaofeng {
47720a0286fSLiu Xiaofeng 	static int warning_once = 0;
47820a0286fSLiu Xiaofeng 
4797acf894dSStephen Hurd 	if (socket_id >= max_socket) {
48020a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
48120a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
48220a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
48320a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
48420a0286fSLiu Xiaofeng 			       " --numa.\n");
48520a0286fSLiu Xiaofeng 		warning_once = 1;
48620a0286fSLiu Xiaofeng 		return -1;
48720a0286fSLiu Xiaofeng 	}
48820a0286fSLiu Xiaofeng 	return 0;
48920a0286fSLiu Xiaofeng }
49020a0286fSLiu Xiaofeng 
491af75078fSIntel static void
492af75078fSIntel init_config(void)
493af75078fSIntel {
494ce8d5614SIntel 	portid_t pid;
495af75078fSIntel 	struct rte_port *port;
496af75078fSIntel 	struct rte_mempool *mbp;
497af75078fSIntel 	unsigned int nb_mbuf_per_pool;
498af75078fSIntel 	lcoreid_t  lc_id;
4997acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
500af75078fSIntel 
5017acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
502af75078fSIntel 	/* Configuration of logical cores. */
503af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
504af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
505fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
506af75078fSIntel 	if (fwd_lcores == NULL) {
507ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
508ce8d5614SIntel 							"failed\n", nb_lcores);
509af75078fSIntel 	}
510af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
511af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
512af75078fSIntel 					       sizeof(struct fwd_lcore),
513fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
514af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
515ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
516ce8d5614SIntel 								"failed\n");
517af75078fSIntel 		}
518af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
519af75078fSIntel 	}
520af75078fSIntel 
521af75078fSIntel 	/*
522af75078fSIntel 	 * Create pools of mbuf.
523af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
524b6ea6408SIntel 	 * socket 0 memory by default.
525af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
526c8798818SIntel 	 *
527c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
528c8798818SIntel 	 * nb_txd can be configured at run time.
529af75078fSIntel 	 */
530c8798818SIntel 	if (param_total_num_mbufs)
531c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
532c8798818SIntel 	else {
533c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
534c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
535b6ea6408SIntel 
536b6ea6408SIntel 		if (!numa_support)
537edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
538edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
539c8798818SIntel 	}
540af75078fSIntel 
541b6ea6408SIntel 	if (!numa_support) {
542b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
543b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
544b6ea6408SIntel 		else
545b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
546b6ea6408SIntel 						 socket_num);
547b6ea6408SIntel 	}
548af75078fSIntel 
549edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
550ce8d5614SIntel 		port = &ports[pid];
551ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
552ce8d5614SIntel 
553b6ea6408SIntel 		if (numa_support) {
554b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
555b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
556b6ea6408SIntel 			else {
557b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
55820a0286fSLiu Xiaofeng 
55920a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
56020a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
56120a0286fSLiu Xiaofeng 					socket_id = 0;
562b6ea6408SIntel 				port_per_socket[socket_id]++;
563b6ea6408SIntel 			}
564b6ea6408SIntel 		}
565b6ea6408SIntel 
566ce8d5614SIntel 		/* set flag to initialize port/queue */
567ce8d5614SIntel 		port->need_reconfig = 1;
568ce8d5614SIntel 		port->need_reconfig_queues = 1;
569ce8d5614SIntel 	}
570ce8d5614SIntel 
571b6ea6408SIntel 	if (numa_support) {
572b6ea6408SIntel 		uint8_t i;
573b6ea6408SIntel 		unsigned int nb_mbuf;
574ce8d5614SIntel 
575b6ea6408SIntel 		if (param_total_num_mbufs)
576b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
577b6ea6408SIntel 
5787acf894dSStephen Hurd 		for (i = 0; i < max_socket; i++) {
579edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
580b6ea6408SIntel 			if (nb_mbuf)
581b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
582b6ea6408SIntel 						nb_mbuf,i);
583b6ea6408SIntel 		}
584b6ea6408SIntel 	}
585b6ea6408SIntel 	init_port_config();
5865886ae07SAdrien Mazarguil 
5875886ae07SAdrien Mazarguil 	/*
5885886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
5895886ae07SAdrien Mazarguil 	 */
5905886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
5918fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
5928fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
5938fd8bebcSAdrien Mazarguil 
5945886ae07SAdrien Mazarguil 		if (mbp == NULL)
5955886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
5965886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
5975886ae07SAdrien Mazarguil 	}
5985886ae07SAdrien Mazarguil 
599ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
600ce8d5614SIntel 	if (init_fwd_streams() < 0)
601ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
6020c0db76fSBernard Iremonger 
6030c0db76fSBernard Iremonger 	fwd_config_setup();
604ce8d5614SIntel }
605ce8d5614SIntel 
6062950a769SDeclan Doherty 
6072950a769SDeclan Doherty void
608a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6092950a769SDeclan Doherty {
6102950a769SDeclan Doherty 	struct rte_port *port;
6112950a769SDeclan Doherty 
6122950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6132950a769SDeclan Doherty 	port = &ports[new_port_id];
6142950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6152950a769SDeclan Doherty 
6162950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6172950a769SDeclan Doherty 	port->need_reconfig = 1;
6182950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
619a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6202950a769SDeclan Doherty 
6212950a769SDeclan Doherty 	init_port_config();
6222950a769SDeclan Doherty }
6232950a769SDeclan Doherty 
6242950a769SDeclan Doherty 
625ce8d5614SIntel int
626ce8d5614SIntel init_fwd_streams(void)
627ce8d5614SIntel {
628ce8d5614SIntel 	portid_t pid;
629ce8d5614SIntel 	struct rte_port *port;
630ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
6315a8fb55cSReshma Pattan 	queueid_t q;
632ce8d5614SIntel 
633ce8d5614SIntel 	/* set socket id according to numa or not */
634edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
635ce8d5614SIntel 		port = &ports[pid];
636ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
637ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
638ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
639ce8d5614SIntel 				port->dev_info.max_rx_queues);
640ce8d5614SIntel 			return -1;
641ce8d5614SIntel 		}
642ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
643ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
644ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
645ce8d5614SIntel 				port->dev_info.max_tx_queues);
646ce8d5614SIntel 			return -1;
647ce8d5614SIntel 		}
64820a0286fSLiu Xiaofeng 		if (numa_support) {
64920a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
65020a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
65120a0286fSLiu Xiaofeng 			else {
652b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
65320a0286fSLiu Xiaofeng 
65420a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
65520a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
65620a0286fSLiu Xiaofeng 					port->socket_id = 0;
65720a0286fSLiu Xiaofeng 			}
65820a0286fSLiu Xiaofeng 		}
659b6ea6408SIntel 		else {
660b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
661af75078fSIntel 				port->socket_id = 0;
662b6ea6408SIntel 			else
663b6ea6408SIntel 				port->socket_id = socket_num;
664b6ea6408SIntel 		}
665af75078fSIntel 	}
666af75078fSIntel 
6675a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
6685a8fb55cSReshma Pattan 	if (q == 0) {
6695a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
6705a8fb55cSReshma Pattan 		return -1;
6715a8fb55cSReshma Pattan 	}
6725a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
673ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
674ce8d5614SIntel 		return 0;
675ce8d5614SIntel 	/* clear the old */
676ce8d5614SIntel 	if (fwd_streams != NULL) {
677ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
678ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
679ce8d5614SIntel 				continue;
680ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
681ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
682af75078fSIntel 		}
683ce8d5614SIntel 		rte_free(fwd_streams);
684ce8d5614SIntel 		fwd_streams = NULL;
685ce8d5614SIntel 	}
686ce8d5614SIntel 
687ce8d5614SIntel 	/* init new */
688ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
689ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
690fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
691ce8d5614SIntel 	if (fwd_streams == NULL)
692ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
693ce8d5614SIntel 						"failed\n", nb_fwd_streams);
694ce8d5614SIntel 
695af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
696af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
697fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
698ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
699ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
700ce8d5614SIntel 								" failed\n");
701af75078fSIntel 	}
702ce8d5614SIntel 
703ce8d5614SIntel 	return 0;
704af75078fSIntel }
705af75078fSIntel 
706af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
707af75078fSIntel static void
708af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
709af75078fSIntel {
710af75078fSIntel 	unsigned int total_burst;
711af75078fSIntel 	unsigned int nb_burst;
712af75078fSIntel 	unsigned int burst_stats[3];
713af75078fSIntel 	uint16_t pktnb_stats[3];
714af75078fSIntel 	uint16_t nb_pkt;
715af75078fSIntel 	int burst_percent[3];
716af75078fSIntel 
717af75078fSIntel 	/*
718af75078fSIntel 	 * First compute the total number of packet bursts and the
719af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
720af75078fSIntel 	 */
721af75078fSIntel 	total_burst = 0;
722af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
723af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
724af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
725af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
726af75078fSIntel 		if (nb_burst == 0)
727af75078fSIntel 			continue;
728af75078fSIntel 		total_burst += nb_burst;
729af75078fSIntel 		if (nb_burst > burst_stats[0]) {
730af75078fSIntel 			burst_stats[1] = burst_stats[0];
731af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
732af75078fSIntel 			burst_stats[0] = nb_burst;
733af75078fSIntel 			pktnb_stats[0] = nb_pkt;
734af75078fSIntel 		}
735af75078fSIntel 	}
736af75078fSIntel 	if (total_burst == 0)
737af75078fSIntel 		return;
738af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
739af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
740af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
741af75078fSIntel 	if (burst_stats[0] == total_burst) {
742af75078fSIntel 		printf("]\n");
743af75078fSIntel 		return;
744af75078fSIntel 	}
745af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
746af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
747af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
748af75078fSIntel 		return;
749af75078fSIntel 	}
750af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
751af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
752af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
753af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
754af75078fSIntel 		return;
755af75078fSIntel 	}
756af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
757af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
758af75078fSIntel }
759af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
760af75078fSIntel 
761af75078fSIntel static void
762af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
763af75078fSIntel {
764af75078fSIntel 	struct rte_port *port;
765013af9b6SIntel 	uint8_t i;
766af75078fSIntel 
767af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
768af75078fSIntel 
769af75078fSIntel 	port = &ports[port_id];
770af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
771af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
772013af9b6SIntel 
773013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
774af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
775af75078fSIntel 		       "%-"PRIu64"\n",
77670bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
77770bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
778af75078fSIntel 
779af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
780af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
781af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
78286057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
783f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
78470bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
78570bdb186SIvan Boule 		}
786af75078fSIntel 
787af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
788af75078fSIntel 		       "%-"PRIu64"\n",
789af75078fSIntel 		       stats->opackets, port->tx_dropped,
790af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
791013af9b6SIntel 	}
792013af9b6SIntel 	else {
793013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
794013af9b6SIntel 		       "%14"PRIu64"\n",
79570bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
79670bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
797013af9b6SIntel 
798013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
799013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
800013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
80186057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
802f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
80370bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
80470bdb186SIvan Boule 			       stats->rx_nombuf);
80570bdb186SIvan Boule 		}
806013af9b6SIntel 
807013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
808013af9b6SIntel 		       "%14"PRIu64"\n",
809013af9b6SIntel 		       stats->opackets, port->tx_dropped,
810013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
811013af9b6SIntel 	}
812e659b6b4SIvan Boule 
813af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
814af75078fSIntel 	if (port->rx_stream)
815013af9b6SIntel 		pkt_burst_stats_display("RX",
816013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
817af75078fSIntel 	if (port->tx_stream)
818013af9b6SIntel 		pkt_burst_stats_display("TX",
819013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
820af75078fSIntel #endif
821af75078fSIntel 
822013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
823013af9b6SIntel 		printf("\n");
824013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
825013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
826013af9b6SIntel 			       "     RX-errors:%14"PRIu64
827013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
828013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
829013af9b6SIntel 		}
830013af9b6SIntel 		printf("\n");
831013af9b6SIntel 	}
832013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
833013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
834013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
835013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
836013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
837013af9b6SIntel 		}
838013af9b6SIntel 	}
839013af9b6SIntel 
840af75078fSIntel 	printf("  %s--------------------------------%s\n",
841af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
842af75078fSIntel }
843af75078fSIntel 
844af75078fSIntel static void
845af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
846af75078fSIntel {
847af75078fSIntel 	struct fwd_stream *fs;
848af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
849af75078fSIntel 
850af75078fSIntel 	fs = fwd_streams[stream_id];
851af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
852af75078fSIntel 	    (fs->fwd_dropped == 0))
853af75078fSIntel 		return;
854af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
855af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
856af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
857af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
858af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
859af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
860af75078fSIntel 
861af75078fSIntel 	/* if checksum mode */
862af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
863013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
864013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
865af75078fSIntel 	}
866af75078fSIntel 
867af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
868af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
869af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
870af75078fSIntel #endif
871af75078fSIntel }
872af75078fSIntel 
873af75078fSIntel static void
8747741e4cfSIntel flush_fwd_rx_queues(void)
875af75078fSIntel {
876af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
877af75078fSIntel 	portid_t  rxp;
8787741e4cfSIntel 	portid_t port_id;
879af75078fSIntel 	queueid_t rxq;
880af75078fSIntel 	uint16_t  nb_rx;
881af75078fSIntel 	uint16_t  i;
882af75078fSIntel 	uint8_t   j;
883f487715fSReshma Pattan 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
884594302c7SJames Poole 	uint64_t timer_period;
885f487715fSReshma Pattan 
886f487715fSReshma Pattan 	/* convert to number of cycles */
887594302c7SJames Poole 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
888af75078fSIntel 
889af75078fSIntel 	for (j = 0; j < 2; j++) {
8907741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
891af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
8927741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
893f487715fSReshma Pattan 				/**
894f487715fSReshma Pattan 				* testpmd can stuck in the below do while loop
895f487715fSReshma Pattan 				* if rte_eth_rx_burst() always returns nonzero
896f487715fSReshma Pattan 				* packets. So timer is added to exit this loop
897f487715fSReshma Pattan 				* after 1sec timer expiry.
898f487715fSReshma Pattan 				*/
899f487715fSReshma Pattan 				prev_tsc = rte_rdtsc();
900af75078fSIntel 				do {
9017741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
902013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
903af75078fSIntel 					for (i = 0; i < nb_rx; i++)
904af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
905f487715fSReshma Pattan 
906f487715fSReshma Pattan 					cur_tsc = rte_rdtsc();
907f487715fSReshma Pattan 					diff_tsc = cur_tsc - prev_tsc;
908f487715fSReshma Pattan 					timer_tsc += diff_tsc;
909f487715fSReshma Pattan 				} while ((nb_rx > 0) &&
910f487715fSReshma Pattan 					(timer_tsc < timer_period));
911f487715fSReshma Pattan 				timer_tsc = 0;
912af75078fSIntel 			}
913af75078fSIntel 		}
914af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
915af75078fSIntel 	}
916af75078fSIntel }
917af75078fSIntel 
918af75078fSIntel static void
919af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
920af75078fSIntel {
921af75078fSIntel 	struct fwd_stream **fsm;
922af75078fSIntel 	streamid_t nb_fs;
923af75078fSIntel 	streamid_t sm_id;
924af75078fSIntel 
925af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
926af75078fSIntel 	nb_fs = fc->stream_nb;
927af75078fSIntel 	do {
928af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
929af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
930af75078fSIntel 	} while (! fc->stopped);
931af75078fSIntel }
932af75078fSIntel 
933af75078fSIntel static int
934af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
935af75078fSIntel {
936af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
937af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
938af75078fSIntel 	return 0;
939af75078fSIntel }
940af75078fSIntel 
941af75078fSIntel /*
942af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
943af75078fSIntel  * Used to start communication flows in network loopback test configurations.
944af75078fSIntel  */
945af75078fSIntel static int
946af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
947af75078fSIntel {
948af75078fSIntel 	struct fwd_lcore *fwd_lc;
949af75078fSIntel 	struct fwd_lcore tmp_lcore;
950af75078fSIntel 
951af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
952af75078fSIntel 	tmp_lcore = *fwd_lc;
953af75078fSIntel 	tmp_lcore.stopped = 1;
954af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
955af75078fSIntel 	return 0;
956af75078fSIntel }
957af75078fSIntel 
958af75078fSIntel /*
959af75078fSIntel  * Launch packet forwarding:
960af75078fSIntel  *     - Setup per-port forwarding context.
961af75078fSIntel  *     - launch logical cores with their forwarding configuration.
962af75078fSIntel  */
963af75078fSIntel static void
964af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
965af75078fSIntel {
966af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
967af75078fSIntel 	unsigned int i;
968af75078fSIntel 	unsigned int lc_id;
969af75078fSIntel 	int diag;
970af75078fSIntel 
971af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
972af75078fSIntel 	if (port_fwd_begin != NULL) {
973af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
974af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
975af75078fSIntel 	}
976af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
977af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
978af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
979af75078fSIntel 			fwd_lcores[i]->stopped = 0;
980af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
981af75078fSIntel 						     fwd_lcores[i], lc_id);
982af75078fSIntel 			if (diag != 0)
983af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
984af75078fSIntel 				       lc_id, diag);
985af75078fSIntel 		}
986af75078fSIntel 	}
987af75078fSIntel }
988af75078fSIntel 
989af75078fSIntel /*
990af75078fSIntel  * Launch packet forwarding configuration.
991af75078fSIntel  */
992af75078fSIntel void
993af75078fSIntel start_packet_forwarding(int with_tx_first)
994af75078fSIntel {
995af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
996af75078fSIntel 	port_fwd_end_t  port_fwd_end;
997af75078fSIntel 	struct rte_port *port;
998af75078fSIntel 	unsigned int i;
999af75078fSIntel 	portid_t   pt_id;
1000af75078fSIntel 	streamid_t sm_id;
1001af75078fSIntel 
10025a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
10035a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
10045a8fb55cSReshma Pattan 
10055a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
10065a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
10075a8fb55cSReshma Pattan 
10085a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
10095a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
10105a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
10115a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
10125a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
10135a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
10145a8fb55cSReshma Pattan 
1015ce8d5614SIntel 	if (all_ports_started() == 0) {
1016ce8d5614SIntel 		printf("Not all ports were started\n");
1017ce8d5614SIntel 		return;
1018ce8d5614SIntel 	}
1019af75078fSIntel 	if (test_done == 0) {
1020af75078fSIntel 		printf("Packet forwarding already started\n");
1021af75078fSIntel 		return;
1022af75078fSIntel 	}
1023edf87b4aSBernard Iremonger 
1024edf87b4aSBernard Iremonger 	if (init_fwd_streams() < 0) {
1025edf87b4aSBernard Iremonger 		printf("Fail from init_fwd_streams()\n");
1026edf87b4aSBernard Iremonger 		return;
1027edf87b4aSBernard Iremonger 	}
1028edf87b4aSBernard Iremonger 
10297741e4cfSIntel 	if(dcb_test) {
10307741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
10317741e4cfSIntel 			pt_id = fwd_ports_ids[i];
10327741e4cfSIntel 			port = &ports[pt_id];
10337741e4cfSIntel 			if (!port->dcb_flag) {
10347741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
10357741e4cfSIntel                                        "be configured in this mode.\n");
1036013af9b6SIntel 				return;
1037013af9b6SIntel 			}
10387741e4cfSIntel 		}
10397741e4cfSIntel 		if (nb_fwd_lcores == 1) {
10407741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
10417741e4cfSIntel                                "should be larger than 1.\n");
10427741e4cfSIntel 			return;
10437741e4cfSIntel 		}
10447741e4cfSIntel 	}
1045af75078fSIntel 	test_done = 0;
10467741e4cfSIntel 
10477741e4cfSIntel 	if(!no_flush_rx)
10487741e4cfSIntel 		flush_fwd_rx_queues();
10497741e4cfSIntel 
1050af75078fSIntel 	fwd_config_setup();
1051933617d8SZhihong Wang 	pkt_fwd_config_display(&cur_fwd_config);
1052af75078fSIntel 	rxtx_config_display();
1053af75078fSIntel 
1054af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1055af75078fSIntel 		pt_id = fwd_ports_ids[i];
1056af75078fSIntel 		port = &ports[pt_id];
1057af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1058af75078fSIntel 		port->tx_dropped = 0;
1059013af9b6SIntel 
1060013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1061af75078fSIntel 	}
1062af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1063af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1064af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1065af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1066af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1067af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1068af75078fSIntel 
1069af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1070af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1071af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1072af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1073af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1074af75078fSIntel #endif
1075af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1076af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1077af75078fSIntel #endif
1078af75078fSIntel 	}
1079af75078fSIntel 	if (with_tx_first) {
1080af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1081af75078fSIntel 		if (port_fwd_begin != NULL) {
1082af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1083af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1084af75078fSIntel 		}
1085acbf77a6SZhihong Wang 		while (with_tx_first--) {
1086acbf77a6SZhihong Wang 			launch_packet_forwarding(
1087acbf77a6SZhihong Wang 					run_one_txonly_burst_on_core);
1088af75078fSIntel 			rte_eal_mp_wait_lcore();
1089acbf77a6SZhihong Wang 		}
1090af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1091af75078fSIntel 		if (port_fwd_end != NULL) {
1092af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1093af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1094af75078fSIntel 		}
1095af75078fSIntel 	}
1096af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1097af75078fSIntel }
1098af75078fSIntel 
1099af75078fSIntel void
1100af75078fSIntel stop_packet_forwarding(void)
1101af75078fSIntel {
1102af75078fSIntel 	struct rte_eth_stats stats;
1103af75078fSIntel 	struct rte_port *port;
1104af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1105af75078fSIntel 	int i;
1106af75078fSIntel 	portid_t   pt_id;
1107af75078fSIntel 	streamid_t sm_id;
1108af75078fSIntel 	lcoreid_t  lc_id;
1109af75078fSIntel 	uint64_t total_recv;
1110af75078fSIntel 	uint64_t total_xmit;
1111af75078fSIntel 	uint64_t total_rx_dropped;
1112af75078fSIntel 	uint64_t total_tx_dropped;
1113af75078fSIntel 	uint64_t total_rx_nombuf;
1114af75078fSIntel 	uint64_t tx_dropped;
1115af75078fSIntel 	uint64_t rx_bad_ip_csum;
1116af75078fSIntel 	uint64_t rx_bad_l4_csum;
1117af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1118af75078fSIntel 	uint64_t fwd_cycles;
1119af75078fSIntel #endif
1120af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1121af75078fSIntel 
1122af75078fSIntel 	if (test_done) {
1123af75078fSIntel 		printf("Packet forwarding not started\n");
1124af75078fSIntel 		return;
1125af75078fSIntel 	}
1126af75078fSIntel 	printf("Telling cores to stop...");
1127af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1128af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1129af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1130af75078fSIntel 	rte_eal_mp_wait_lcore();
1131af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1132af75078fSIntel 	if (port_fwd_end != NULL) {
1133af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1134af75078fSIntel 			pt_id = fwd_ports_ids[i];
1135af75078fSIntel 			(*port_fwd_end)(pt_id);
1136af75078fSIntel 		}
1137af75078fSIntel 	}
1138af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1139af75078fSIntel 	fwd_cycles = 0;
1140af75078fSIntel #endif
1141af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1142af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1143af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1144af75078fSIntel 			fwd_stream_stats_display(sm_id);
1145af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1146af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1147af75078fSIntel 		} else {
1148af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1149af75078fSIntel 				fwd_streams[sm_id];
1150af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1151af75078fSIntel 				fwd_streams[sm_id];
1152af75078fSIntel 		}
1153af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1154af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1155af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1156af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1157af75078fSIntel 
1158013af9b6SIntel 		rx_bad_ip_csum =
1159013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1160af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1161af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1162013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1163013af9b6SIntel 							rx_bad_ip_csum;
1164af75078fSIntel 
1165013af9b6SIntel 		rx_bad_l4_csum =
1166013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1167af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1168af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1169013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1170013af9b6SIntel 							rx_bad_l4_csum;
1171af75078fSIntel 
1172af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1173af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1174af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1175af75078fSIntel #endif
1176af75078fSIntel 	}
1177af75078fSIntel 	total_recv = 0;
1178af75078fSIntel 	total_xmit = 0;
1179af75078fSIntel 	total_rx_dropped = 0;
1180af75078fSIntel 	total_tx_dropped = 0;
1181af75078fSIntel 	total_rx_nombuf  = 0;
11827741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1183af75078fSIntel 		pt_id = fwd_ports_ids[i];
1184af75078fSIntel 
1185af75078fSIntel 		port = &ports[pt_id];
1186af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1187af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1188af75078fSIntel 		port->stats.ipackets = 0;
1189af75078fSIntel 		stats.opackets -= port->stats.opackets;
1190af75078fSIntel 		port->stats.opackets = 0;
1191af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1192af75078fSIntel 		port->stats.ibytes = 0;
1193af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1194af75078fSIntel 		port->stats.obytes = 0;
119570bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
119670bdb186SIvan Boule 		port->stats.imissed = 0;
1197af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1198af75078fSIntel 		port->stats.oerrors = 0;
1199af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1200af75078fSIntel 		port->stats.rx_nombuf = 0;
1201af75078fSIntel 
1202af75078fSIntel 		total_recv += stats.ipackets;
1203af75078fSIntel 		total_xmit += stats.opackets;
120470bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1205af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1206af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1207af75078fSIntel 
1208af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1209af75078fSIntel 	}
1210af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1211af75078fSIntel 	       "%s\n",
1212af75078fSIntel 	       acc_stats_border, acc_stats_border);
1213af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1214af75078fSIntel 	       "%-"PRIu64"\n"
1215af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1216af75078fSIntel 	       "%-"PRIu64"\n",
1217af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1218af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1219af75078fSIntel 	if (total_rx_nombuf > 0)
1220af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1221af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1222af75078fSIntel 	       "%s\n",
1223af75078fSIntel 	       acc_stats_border, acc_stats_border);
1224af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1225af75078fSIntel 	if (total_recv > 0)
1226af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1227af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1228af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1229af75078fSIntel 		       fwd_cycles, total_recv);
1230af75078fSIntel #endif
1231af75078fSIntel 	printf("\nDone.\n");
1232af75078fSIntel 	test_done = 1;
1233af75078fSIntel }
1234af75078fSIntel 
1235cfae07fdSOuyang Changchun void
1236cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1237cfae07fdSOuyang Changchun {
1238cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1239cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1240cfae07fdSOuyang Changchun }
1241cfae07fdSOuyang Changchun 
1242cfae07fdSOuyang Changchun void
1243cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1244cfae07fdSOuyang Changchun {
1245cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1246cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1247cfae07fdSOuyang Changchun }
1248cfae07fdSOuyang Changchun 
1249ce8d5614SIntel static int
1250ce8d5614SIntel all_ports_started(void)
1251ce8d5614SIntel {
1252ce8d5614SIntel 	portid_t pi;
1253ce8d5614SIntel 	struct rte_port *port;
1254ce8d5614SIntel 
1255edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1256ce8d5614SIntel 		port = &ports[pi];
1257ce8d5614SIntel 		/* Check if there is a port which is not started */
125841b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
125941b05095SBernard Iremonger 			(port->slave_flag == 0))
1260ce8d5614SIntel 			return 0;
1261ce8d5614SIntel 	}
1262ce8d5614SIntel 
1263ce8d5614SIntel 	/* No port is not started */
1264ce8d5614SIntel 	return 1;
1265ce8d5614SIntel }
1266ce8d5614SIntel 
1267148f963fSBruce Richardson int
1268edab33b1STetsuya Mukawa all_ports_stopped(void)
1269edab33b1STetsuya Mukawa {
1270edab33b1STetsuya Mukawa 	portid_t pi;
1271edab33b1STetsuya Mukawa 	struct rte_port *port;
1272edab33b1STetsuya Mukawa 
1273edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1274edab33b1STetsuya Mukawa 		port = &ports[pi];
127541b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
127641b05095SBernard Iremonger 			(port->slave_flag == 0))
1277edab33b1STetsuya Mukawa 			return 0;
1278edab33b1STetsuya Mukawa 	}
1279edab33b1STetsuya Mukawa 
1280edab33b1STetsuya Mukawa 	return 1;
1281edab33b1STetsuya Mukawa }
1282edab33b1STetsuya Mukawa 
1283edab33b1STetsuya Mukawa int
1284edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1285edab33b1STetsuya Mukawa {
1286edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1287edab33b1STetsuya Mukawa 		return 0;
1288edab33b1STetsuya Mukawa 
1289edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1290edab33b1STetsuya Mukawa 		return 0;
1291edab33b1STetsuya Mukawa 
1292edab33b1STetsuya Mukawa 	return 1;
1293edab33b1STetsuya Mukawa }
1294edab33b1STetsuya Mukawa 
1295edab33b1STetsuya Mukawa static int
1296edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1297edab33b1STetsuya Mukawa {
1298edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1299edab33b1STetsuya Mukawa 		return 0;
1300edab33b1STetsuya Mukawa 
1301edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1302edab33b1STetsuya Mukawa 		return 0;
1303edab33b1STetsuya Mukawa 
1304edab33b1STetsuya Mukawa 	return 1;
1305edab33b1STetsuya Mukawa }
1306edab33b1STetsuya Mukawa 
1307edab33b1STetsuya Mukawa int
1308ce8d5614SIntel start_port(portid_t pid)
1309ce8d5614SIntel {
131092d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1311ce8d5614SIntel 	portid_t pi;
1312ce8d5614SIntel 	queueid_t qi;
1313ce8d5614SIntel 	struct rte_port *port;
13142950a769SDeclan Doherty 	struct ether_addr mac_addr;
1315ce8d5614SIntel 
13164468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
13174468635fSMichael Qiu 		return 0;
13184468635fSMichael Qiu 
1319ce8d5614SIntel 	if(dcb_config)
1320ce8d5614SIntel 		dcb_test = 1;
1321edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1322edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1323ce8d5614SIntel 			continue;
1324ce8d5614SIntel 
132592d2703eSMichael Qiu 		need_check_link_status = 0;
1326ce8d5614SIntel 		port = &ports[pi];
1327ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1328ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1329ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1330ce8d5614SIntel 			continue;
1331ce8d5614SIntel 		}
1332ce8d5614SIntel 
1333ce8d5614SIntel 		if (port->need_reconfig > 0) {
1334ce8d5614SIntel 			port->need_reconfig = 0;
1335ce8d5614SIntel 
13365706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
133720a0286fSLiu Xiaofeng 					port->socket_id);
1338ce8d5614SIntel 			/* configure port */
1339ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1340ce8d5614SIntel 						&(port->dev_conf));
1341ce8d5614SIntel 			if (diag != 0) {
1342ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1343ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1344ce8d5614SIntel 					printf("Port %d can not be set back "
1345ce8d5614SIntel 							"to stopped\n", pi);
1346ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1347ce8d5614SIntel 				/* try to reconfigure port next time */
1348ce8d5614SIntel 				port->need_reconfig = 1;
1349148f963fSBruce Richardson 				return -1;
1350ce8d5614SIntel 			}
1351ce8d5614SIntel 		}
1352ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1353ce8d5614SIntel 			port->need_reconfig_queues = 0;
1354ce8d5614SIntel 			/* setup tx queues */
1355ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1356b6ea6408SIntel 				if ((numa_support) &&
1357b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1358b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1359b6ea6408SIntel 						nb_txd,txring_numa[pi],
1360b6ea6408SIntel 						&(port->tx_conf));
1361b6ea6408SIntel 				else
1362b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1363b6ea6408SIntel 						nb_txd,port->socket_id,
1364b6ea6408SIntel 						&(port->tx_conf));
1365b6ea6408SIntel 
1366ce8d5614SIntel 				if (diag == 0)
1367ce8d5614SIntel 					continue;
1368ce8d5614SIntel 
1369ce8d5614SIntel 				/* Fail to setup tx queue, return */
1370ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1371ce8d5614SIntel 							RTE_PORT_HANDLING,
1372ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1373ce8d5614SIntel 					printf("Port %d can not be set back "
1374ce8d5614SIntel 							"to stopped\n", pi);
1375ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1376ce8d5614SIntel 				/* try to reconfigure queues next time */
1377ce8d5614SIntel 				port->need_reconfig_queues = 1;
1378148f963fSBruce Richardson 				return -1;
1379ce8d5614SIntel 			}
1380ce8d5614SIntel 			/* setup rx queues */
1381ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1382b6ea6408SIntel 				if ((numa_support) &&
1383b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1384b6ea6408SIntel 					struct rte_mempool * mp =
1385b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1386b6ea6408SIntel 					if (mp == NULL) {
1387b6ea6408SIntel 						printf("Failed to setup RX queue:"
1388b6ea6408SIntel 							"No mempool allocation"
1389b6ea6408SIntel 							" on the socket %d\n",
1390b6ea6408SIntel 							rxring_numa[pi]);
1391148f963fSBruce Richardson 						return -1;
1392b6ea6408SIntel 					}
1393b6ea6408SIntel 
1394b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1395b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1396b6ea6408SIntel 					     &(port->rx_conf),mp);
13971e1d6bddSBernard Iremonger 				} else {
13981e1d6bddSBernard Iremonger 					struct rte_mempool *mp =
13991e1d6bddSBernard Iremonger 						mbuf_pool_find(port->socket_id);
14001e1d6bddSBernard Iremonger 					if (mp == NULL) {
14011e1d6bddSBernard Iremonger 						printf("Failed to setup RX queue:"
14021e1d6bddSBernard Iremonger 							"No mempool allocation"
14031e1d6bddSBernard Iremonger 							" on the socket %d\n",
14041e1d6bddSBernard Iremonger 							port->socket_id);
14051e1d6bddSBernard Iremonger 						return -1;
1406b6ea6408SIntel 					}
1407b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1408b6ea6408SIntel 					     nb_rxd,port->socket_id,
14091e1d6bddSBernard Iremonger 					     &(port->rx_conf), mp);
14101e1d6bddSBernard Iremonger 				}
1411ce8d5614SIntel 				if (diag == 0)
1412ce8d5614SIntel 					continue;
1413ce8d5614SIntel 
1414ce8d5614SIntel 				/* Fail to setup rx queue, return */
1415ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1416ce8d5614SIntel 							RTE_PORT_HANDLING,
1417ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1418ce8d5614SIntel 					printf("Port %d can not be set back "
1419ce8d5614SIntel 							"to stopped\n", pi);
1420ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1421ce8d5614SIntel 				/* try to reconfigure queues next time */
1422ce8d5614SIntel 				port->need_reconfig_queues = 1;
1423148f963fSBruce Richardson 				return -1;
1424ce8d5614SIntel 			}
1425ce8d5614SIntel 		}
1426ce8d5614SIntel 		/* start port */
1427ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1428ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1429ce8d5614SIntel 
1430ce8d5614SIntel 			/* Fail to setup rx queue, return */
1431ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1432ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1433ce8d5614SIntel 				printf("Port %d can not be set back to "
1434ce8d5614SIntel 							"stopped\n", pi);
1435ce8d5614SIntel 			continue;
1436ce8d5614SIntel 		}
1437ce8d5614SIntel 
1438ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1439ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1440ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1441ce8d5614SIntel 
14422950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1443d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
14442950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
14452950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
14462950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1447d8c89163SZijie Pan 
1448ce8d5614SIntel 		/* at least one port started, need checking link status */
1449ce8d5614SIntel 		need_check_link_status = 1;
1450ce8d5614SIntel 	}
1451ce8d5614SIntel 
145292d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1453edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
145492d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1455ce8d5614SIntel 		printf("Please stop the ports first\n");
1456ce8d5614SIntel 
1457ce8d5614SIntel 	printf("Done\n");
1458148f963fSBruce Richardson 	return 0;
1459ce8d5614SIntel }
1460ce8d5614SIntel 
1461ce8d5614SIntel void
1462ce8d5614SIntel stop_port(portid_t pid)
1463ce8d5614SIntel {
1464ce8d5614SIntel 	portid_t pi;
1465ce8d5614SIntel 	struct rte_port *port;
1466ce8d5614SIntel 	int need_check_link_status = 0;
1467ce8d5614SIntel 
1468ce8d5614SIntel 	if (dcb_test) {
1469ce8d5614SIntel 		dcb_test = 0;
1470ce8d5614SIntel 		dcb_config = 0;
1471ce8d5614SIntel 	}
14724468635fSMichael Qiu 
14734468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14744468635fSMichael Qiu 		return;
14754468635fSMichael Qiu 
1476ce8d5614SIntel 	printf("Stopping ports...\n");
1477ce8d5614SIntel 
1478edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14794468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1480ce8d5614SIntel 			continue;
1481ce8d5614SIntel 
1482a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1483a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1484a8ef3e3aSBernard Iremonger 			continue;
1485a8ef3e3aSBernard Iremonger 		}
1486a8ef3e3aSBernard Iremonger 
14870e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
14880e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
14890e545d30SBernard Iremonger 			continue;
14900e545d30SBernard Iremonger 		}
14910e545d30SBernard Iremonger 
1492ce8d5614SIntel 		port = &ports[pi];
1493ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1494ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1495ce8d5614SIntel 			continue;
1496ce8d5614SIntel 
1497ce8d5614SIntel 		rte_eth_dev_stop(pi);
1498ce8d5614SIntel 
1499ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1500ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1501ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1502ce8d5614SIntel 		need_check_link_status = 1;
1503ce8d5614SIntel 	}
1504bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1505edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1506ce8d5614SIntel 
1507ce8d5614SIntel 	printf("Done\n");
1508ce8d5614SIntel }
1509ce8d5614SIntel 
1510ce8d5614SIntel void
1511ce8d5614SIntel close_port(portid_t pid)
1512ce8d5614SIntel {
1513ce8d5614SIntel 	portid_t pi;
1514ce8d5614SIntel 	struct rte_port *port;
1515ce8d5614SIntel 
15164468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
15174468635fSMichael Qiu 		return;
15184468635fSMichael Qiu 
1519ce8d5614SIntel 	printf("Closing ports...\n");
1520ce8d5614SIntel 
1521edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
15224468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1523ce8d5614SIntel 			continue;
1524ce8d5614SIntel 
1525a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1526a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1527a8ef3e3aSBernard Iremonger 			continue;
1528a8ef3e3aSBernard Iremonger 		}
1529a8ef3e3aSBernard Iremonger 
15300e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
15310e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
15320e545d30SBernard Iremonger 			continue;
15330e545d30SBernard Iremonger 		}
15340e545d30SBernard Iremonger 
1535ce8d5614SIntel 		port = &ports[pi];
1536ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1537d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1538d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1539d4e8ad64SMichael Qiu 			continue;
1540d4e8ad64SMichael Qiu 		}
1541d4e8ad64SMichael Qiu 
1542d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1543ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1544ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1545ce8d5614SIntel 			continue;
1546ce8d5614SIntel 		}
1547ce8d5614SIntel 
1548ce8d5614SIntel 		rte_eth_dev_close(pi);
1549ce8d5614SIntel 
1550ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1551ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1552b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1553ce8d5614SIntel 	}
1554ce8d5614SIntel 
1555ce8d5614SIntel 	printf("Done\n");
1556ce8d5614SIntel }
1557ce8d5614SIntel 
1558edab33b1STetsuya Mukawa void
1559edab33b1STetsuya Mukawa attach_port(char *identifier)
1560ce8d5614SIntel {
1561ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1562931126baSBernard Iremonger 	unsigned int socket_id;
1563ce8d5614SIntel 
1564edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1565edab33b1STetsuya Mukawa 
1566edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1567edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1568edab33b1STetsuya Mukawa 		return;
1569ce8d5614SIntel 	}
1570ce8d5614SIntel 
1571edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1572edab33b1STetsuya Mukawa 		return;
1573edab33b1STetsuya Mukawa 
1574edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1575931126baSBernard Iremonger 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1576931126baSBernard Iremonger 	/* if socket_id is invalid, set to 0 */
1577931126baSBernard Iremonger 	if (check_socket_id(socket_id) < 0)
1578931126baSBernard Iremonger 		socket_id = 0;
1579931126baSBernard Iremonger 	reconfig(pi, socket_id);
1580edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1581edab33b1STetsuya Mukawa 
1582edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1583edab33b1STetsuya Mukawa 
1584edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1585edab33b1STetsuya Mukawa 
1586edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1587edab33b1STetsuya Mukawa 	printf("Done\n");
1588edab33b1STetsuya Mukawa }
1589edab33b1STetsuya Mukawa 
1590edab33b1STetsuya Mukawa void
1591edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
15925f4ec54fSChen Jing D(Mark) {
1593edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
15945f4ec54fSChen Jing D(Mark) 
1595edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
15965f4ec54fSChen Jing D(Mark) 
1597edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1598edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1599edab33b1STetsuya Mukawa 		return;
1600edab33b1STetsuya Mukawa 	}
1601edab33b1STetsuya Mukawa 
1602edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1603edab33b1STetsuya Mukawa 		return;
1604edab33b1STetsuya Mukawa 
1605edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1606edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1607edab33b1STetsuya Mukawa 
1608edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1609edab33b1STetsuya Mukawa 			name, nb_ports);
1610edab33b1STetsuya Mukawa 	printf("Done\n");
1611edab33b1STetsuya Mukawa 	return;
16125f4ec54fSChen Jing D(Mark) }
16135f4ec54fSChen Jing D(Mark) 
1614af75078fSIntel void
1615af75078fSIntel pmd_test_exit(void)
1616af75078fSIntel {
1617af75078fSIntel 	portid_t pt_id;
1618af75078fSIntel 
16198210ec25SPablo de Lara 	if (test_done == 0)
16208210ec25SPablo de Lara 		stop_packet_forwarding();
16218210ec25SPablo de Lara 
1622d3a274ceSZhihong Wang 	if (ports != NULL) {
1623d3a274ceSZhihong Wang 		no_link_check = 1;
1624edab33b1STetsuya Mukawa 		FOREACH_PORT(pt_id, ports) {
1625d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1626af75078fSIntel 			fflush(stdout);
1627d3a274ceSZhihong Wang 			stop_port(pt_id);
1628d3a274ceSZhihong Wang 			close_port(pt_id);
1629af75078fSIntel 		}
1630d3a274ceSZhihong Wang 	}
1631d3a274ceSZhihong Wang 	printf("\nBye...\n");
1632af75078fSIntel }
1633af75078fSIntel 
1634af75078fSIntel typedef void (*cmd_func_t)(void);
1635af75078fSIntel struct pmd_test_command {
1636af75078fSIntel 	const char *cmd_name;
1637af75078fSIntel 	cmd_func_t cmd_func;
1638af75078fSIntel };
1639af75078fSIntel 
1640af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1641af75078fSIntel 
1642ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1643af75078fSIntel static void
1644edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1645af75078fSIntel {
1646ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1647ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1648ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1649ce8d5614SIntel 	struct rte_eth_link link;
1650ce8d5614SIntel 
1651ce8d5614SIntel 	printf("Checking link statuses...\n");
1652ce8d5614SIntel 	fflush(stdout);
1653ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1654ce8d5614SIntel 		all_ports_up = 1;
1655edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1656ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1657ce8d5614SIntel 				continue;
1658ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1659ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1660ce8d5614SIntel 			/* print link status if flag set */
1661ce8d5614SIntel 			if (print_flag == 1) {
1662ce8d5614SIntel 				if (link.link_status)
1663ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1664ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1665ce8d5614SIntel 						(unsigned)link.link_speed,
1666ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1667ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1668ce8d5614SIntel 				else
1669ce8d5614SIntel 					printf("Port %d Link Down\n",
1670ce8d5614SIntel 						(uint8_t)portid);
1671ce8d5614SIntel 				continue;
1672ce8d5614SIntel 			}
1673ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
167409419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1675ce8d5614SIntel 				all_ports_up = 0;
1676ce8d5614SIntel 				break;
1677ce8d5614SIntel 			}
1678ce8d5614SIntel 		}
1679ce8d5614SIntel 		/* after finally printing all link status, get out */
1680ce8d5614SIntel 		if (print_flag == 1)
1681ce8d5614SIntel 			break;
1682ce8d5614SIntel 
1683ce8d5614SIntel 		if (all_ports_up == 0) {
1684ce8d5614SIntel 			fflush(stdout);
1685ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1686ce8d5614SIntel 		}
1687ce8d5614SIntel 
1688ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1689ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1690ce8d5614SIntel 			print_flag = 1;
1691ce8d5614SIntel 		}
1692ce8d5614SIntel 	}
1693af75078fSIntel }
1694af75078fSIntel 
1695013af9b6SIntel static int
1696013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1697af75078fSIntel {
1698013af9b6SIntel 	uint16_t i;
1699af75078fSIntel 	int diag;
1700013af9b6SIntel 	uint8_t mapping_found = 0;
1701af75078fSIntel 
1702013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1703013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1704013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1705013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1706013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1707013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1708013af9b6SIntel 			if (diag != 0)
1709013af9b6SIntel 				return diag;
1710013af9b6SIntel 			mapping_found = 1;
1711af75078fSIntel 		}
1712013af9b6SIntel 	}
1713013af9b6SIntel 	if (mapping_found)
1714013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1715013af9b6SIntel 	return 0;
1716013af9b6SIntel }
1717013af9b6SIntel 
1718013af9b6SIntel static int
1719013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1720013af9b6SIntel {
1721013af9b6SIntel 	uint16_t i;
1722013af9b6SIntel 	int diag;
1723013af9b6SIntel 	uint8_t mapping_found = 0;
1724013af9b6SIntel 
1725013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1726013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1727013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1728013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1729013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1730013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1731013af9b6SIntel 			if (diag != 0)
1732013af9b6SIntel 				return diag;
1733013af9b6SIntel 			mapping_found = 1;
1734013af9b6SIntel 		}
1735013af9b6SIntel 	}
1736013af9b6SIntel 	if (mapping_found)
1737013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1738013af9b6SIntel 	return 0;
1739013af9b6SIntel }
1740013af9b6SIntel 
1741013af9b6SIntel static void
1742013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1743013af9b6SIntel {
1744013af9b6SIntel 	int diag = 0;
1745013af9b6SIntel 
1746013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1747af75078fSIntel 	if (diag != 0) {
1748013af9b6SIntel 		if (diag == -ENOTSUP) {
1749013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1750013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1751013af9b6SIntel 		}
1752013af9b6SIntel 		else
1753013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1754013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1755013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1756af75078fSIntel 					pi, diag);
1757af75078fSIntel 	}
1758013af9b6SIntel 
1759013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1760af75078fSIntel 	if (diag != 0) {
1761013af9b6SIntel 		if (diag == -ENOTSUP) {
1762013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1763013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1764013af9b6SIntel 		}
1765013af9b6SIntel 		else
1766013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1767013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1768013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1769af75078fSIntel 					pi, diag);
1770af75078fSIntel 	}
1771af75078fSIntel }
1772af75078fSIntel 
1773f2c5125aSPablo de Lara static void
1774f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1775f2c5125aSPablo de Lara {
1776f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1777f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1778f2c5125aSPablo de Lara 
1779f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1780f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1781f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1782f2c5125aSPablo de Lara 
1783f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1784f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1785f2c5125aSPablo de Lara 
1786f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1787f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1788f2c5125aSPablo de Lara 
1789f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1790f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1791f2c5125aSPablo de Lara 
1792f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1793f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1794f2c5125aSPablo de Lara 
1795f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1796f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1797f2c5125aSPablo de Lara 
1798f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1799f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1800f2c5125aSPablo de Lara 
1801f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1802f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1803f2c5125aSPablo de Lara 
1804f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1805f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1806f2c5125aSPablo de Lara 
1807f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1808f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1809f2c5125aSPablo de Lara 
1810f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1811f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1812f2c5125aSPablo de Lara }
1813f2c5125aSPablo de Lara 
1814013af9b6SIntel void
1815013af9b6SIntel init_port_config(void)
1816013af9b6SIntel {
1817013af9b6SIntel 	portid_t pid;
1818013af9b6SIntel 	struct rte_port *port;
1819013af9b6SIntel 
1820edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1821013af9b6SIntel 		port = &ports[pid];
1822013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1823013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
18243ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1825013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1826013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1827af75078fSIntel 		} else {
1828013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1829013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1830af75078fSIntel 		}
18313ce690d3SBruce Richardson 
18323ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
18333ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
18343ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
18353ce690d3SBruce Richardson 			else
18363ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
18373ce690d3SBruce Richardson 		}
18383ce690d3SBruce Richardson 
1839a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1840a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1841a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1842a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1843a30979f6SOuyang Changchun 			else
1844a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1845a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1846a30979f6SOuyang Changchun 
1847a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1848a30979f6SOuyang Changchun 		}
1849a30979f6SOuyang Changchun 
1850f2c5125aSPablo de Lara 		rxtx_port_config(port);
1851013af9b6SIntel 
1852013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1853013af9b6SIntel 
1854013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18557b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18567b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18577b7e5ba7SIntel #endif
1858013af9b6SIntel 	}
1859013af9b6SIntel }
1860013af9b6SIntel 
186141b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
186241b05095SBernard Iremonger {
186341b05095SBernard Iremonger 	struct rte_port *port;
186441b05095SBernard Iremonger 
186541b05095SBernard Iremonger 	port = &ports[slave_pid];
186641b05095SBernard Iremonger 	port->slave_flag = 1;
186741b05095SBernard Iremonger }
186841b05095SBernard Iremonger 
186941b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
187041b05095SBernard Iremonger {
187141b05095SBernard Iremonger 	struct rte_port *port;
187241b05095SBernard Iremonger 
187341b05095SBernard Iremonger 	port = &ports[slave_pid];
187441b05095SBernard Iremonger 	port->slave_flag = 0;
187541b05095SBernard Iremonger }
187641b05095SBernard Iremonger 
18770e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
18780e545d30SBernard Iremonger {
18790e545d30SBernard Iremonger 	struct rte_port *port;
18800e545d30SBernard Iremonger 
18810e545d30SBernard Iremonger 	port = &ports[slave_pid];
18820e545d30SBernard Iremonger 	return port->slave_flag;
18830e545d30SBernard Iremonger }
18840e545d30SBernard Iremonger 
1885013af9b6SIntel const uint16_t vlan_tags[] = {
1886013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1887013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1888013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1889013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1890013af9b6SIntel };
1891013af9b6SIntel 
1892013af9b6SIntel static  int
18931a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
18941a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
18951a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
18961a572499SJingjing Wu 		 uint8_t pfc_en)
1897013af9b6SIntel {
1898013af9b6SIntel 	uint8_t i;
1899af75078fSIntel 
1900af75078fSIntel 	/*
1901013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1902013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
1903af75078fSIntel 	 */
19041a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
19051a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
19061a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
19071a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
19081a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
1909013af9b6SIntel 
1910013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
19111a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
19121a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
19131a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
19141a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
19151a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
19161a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1917013af9b6SIntel 
19181a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
19191a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
19201a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
19211a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
19221a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
1923af75078fSIntel 		}
1924013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
19251a572499SJingjing Wu 			vmdq_rx_conf->dcb_tc[i] = i;
19261a572499SJingjing Wu 			vmdq_tx_conf->dcb_tc[i] = i;
1927013af9b6SIntel 		}
1928013af9b6SIntel 
1929013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
193032e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
193132e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
19321a572499SJingjing Wu 	} else {
19331a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
19341a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
19351a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
19361a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
1937013af9b6SIntel 
19381a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
19391a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
19401a572499SJingjing Wu 
19411a572499SJingjing Wu 		for (i = 0; i < num_tcs; i++) {
19421a572499SJingjing Wu 			rx_conf->dcb_tc[i] = i;
19431a572499SJingjing Wu 			tx_conf->dcb_tc[i] = i;
1944013af9b6SIntel 		}
19451a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
19461a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
194732e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
19481a572499SJingjing Wu 	}
19491a572499SJingjing Wu 
19501a572499SJingjing Wu 	if (pfc_en)
19511a572499SJingjing Wu 		eth_conf->dcb_capability_en =
19521a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
1953013af9b6SIntel 	else
1954013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1955013af9b6SIntel 
1956013af9b6SIntel 	return 0;
1957013af9b6SIntel }
1958013af9b6SIntel 
1959013af9b6SIntel int
19601a572499SJingjing Wu init_port_dcb_config(portid_t pid,
19611a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
19621a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
19631a572499SJingjing Wu 		     uint8_t pfc_en)
1964013af9b6SIntel {
1965013af9b6SIntel 	struct rte_eth_conf port_conf;
1966013af9b6SIntel 	struct rte_port *rte_port;
1967013af9b6SIntel 	int retval;
1968013af9b6SIntel 	uint16_t i;
1969013af9b6SIntel 
19702a977b89SWenzhuo Lu 	rte_port = &ports[pid];
1971013af9b6SIntel 
1972013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
1973013af9b6SIntel 	/* Enter DCB configuration status */
1974013af9b6SIntel 	dcb_config = 1;
1975013af9b6SIntel 
1976013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
19771a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
1978013af9b6SIntel 	if (retval < 0)
1979013af9b6SIntel 		return retval;
19802a977b89SWenzhuo Lu 	port_conf.rxmode.hw_vlan_filter = 1;
1981013af9b6SIntel 
19822a977b89SWenzhuo Lu 	/**
19832a977b89SWenzhuo Lu 	 * Write the configuration into the device.
19842a977b89SWenzhuo Lu 	 * Set the numbers of RX & TX queues to 0, so
19852a977b89SWenzhuo Lu 	 * the RX & TX queues will not be setup.
19862a977b89SWenzhuo Lu 	 */
19872a977b89SWenzhuo Lu 	(void)rte_eth_dev_configure(pid, 0, 0, &port_conf);
19882a977b89SWenzhuo Lu 
19892a977b89SWenzhuo Lu 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
19902a977b89SWenzhuo Lu 
19912a977b89SWenzhuo Lu 	/* If dev_info.vmdq_pool_base is greater than 0,
19922a977b89SWenzhuo Lu 	 * the queue id of vmdq pools is started after pf queues.
19932a977b89SWenzhuo Lu 	 */
19942a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED &&
19952a977b89SWenzhuo Lu 	    rte_port->dev_info.vmdq_pool_base > 0) {
19962a977b89SWenzhuo Lu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
19972a977b89SWenzhuo Lu 			" for port %d.", pid);
19982a977b89SWenzhuo Lu 		return -1;
19992a977b89SWenzhuo Lu 	}
20002a977b89SWenzhuo Lu 
20012a977b89SWenzhuo Lu 	/* Assume the ports in testpmd have the same dcb capability
20022a977b89SWenzhuo Lu 	 * and has the same number of rxq and txq in dcb mode
20032a977b89SWenzhuo Lu 	 */
20042a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED) {
2005*86ef65eeSBernard Iremonger 		if (rte_port->dev_info.max_vfs > 0) {
2006*86ef65eeSBernard Iremonger 			nb_rxq = rte_port->dev_info.nb_rx_queues;
2007*86ef65eeSBernard Iremonger 			nb_txq = rte_port->dev_info.nb_tx_queues;
2008*86ef65eeSBernard Iremonger 		} else {
20092a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
20102a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
2011*86ef65eeSBernard Iremonger 		}
20122a977b89SWenzhuo Lu 	} else {
20132a977b89SWenzhuo Lu 		/*if vt is disabled, use all pf queues */
20142a977b89SWenzhuo Lu 		if (rte_port->dev_info.vmdq_pool_base == 0) {
20152a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
20162a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
20172a977b89SWenzhuo Lu 		} else {
20182a977b89SWenzhuo Lu 			nb_rxq = (queueid_t)num_tcs;
20192a977b89SWenzhuo Lu 			nb_txq = (queueid_t)num_tcs;
20202a977b89SWenzhuo Lu 
20212a977b89SWenzhuo Lu 		}
20222a977b89SWenzhuo Lu 	}
20232a977b89SWenzhuo Lu 	rx_free_thresh = 64;
20242a977b89SWenzhuo Lu 
2025013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2026013af9b6SIntel 
2027f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
2028013af9b6SIntel 	/* VLAN filter */
2029013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
20301a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2031013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
2032013af9b6SIntel 
2033013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2034013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
2035013af9b6SIntel 
20367741e4cfSIntel 	rte_port->dcb_flag = 1;
20377741e4cfSIntel 
2038013af9b6SIntel 	return 0;
2039af75078fSIntel }
2040af75078fSIntel 
2041ffc468ffSTetsuya Mukawa static void
2042ffc468ffSTetsuya Mukawa init_port(void)
2043ffc468ffSTetsuya Mukawa {
2044ffc468ffSTetsuya Mukawa 	portid_t pid;
2045ffc468ffSTetsuya Mukawa 
2046ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2047ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2048ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2049ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2050ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2051ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2052ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2053ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2054ffc468ffSTetsuya Mukawa 	}
2055ffc468ffSTetsuya Mukawa 
2056ffc468ffSTetsuya Mukawa 	/* enabled allocated ports */
2057ffc468ffSTetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
2058ffc468ffSTetsuya Mukawa 		ports[pid].enabled = 1;
2059ffc468ffSTetsuya Mukawa }
2060ffc468ffSTetsuya Mukawa 
2061d3a274ceSZhihong Wang static void
2062d3a274ceSZhihong Wang force_quit(void)
2063d3a274ceSZhihong Wang {
2064d3a274ceSZhihong Wang 	pmd_test_exit();
2065d3a274ceSZhihong Wang 	prompt_exit();
2066d3a274ceSZhihong Wang }
2067d3a274ceSZhihong Wang 
2068d3a274ceSZhihong Wang static void
2069d3a274ceSZhihong Wang signal_handler(int signum)
2070d3a274ceSZhihong Wang {
2071d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2072d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2073d3a274ceSZhihong Wang 				signum);
2074102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2075102b7329SReshma Pattan 		/* uninitialize packet capture framework */
2076102b7329SReshma Pattan 		rte_pdump_uninit();
2077102b7329SReshma Pattan #endif
2078d3a274ceSZhihong Wang 		force_quit();
2079d3a274ceSZhihong Wang 		/* exit with the expected status */
2080d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2081d3a274ceSZhihong Wang 		kill(getpid(), signum);
2082d3a274ceSZhihong Wang 	}
2083d3a274ceSZhihong Wang }
2084d3a274ceSZhihong Wang 
2085af75078fSIntel int
2086af75078fSIntel main(int argc, char** argv)
2087af75078fSIntel {
2088af75078fSIntel 	int  diag;
2089013af9b6SIntel 	uint8_t port_id;
2090af75078fSIntel 
2091d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2092d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2093d3a274ceSZhihong Wang 
2094af75078fSIntel 	diag = rte_eal_init(argc, argv);
2095af75078fSIntel 	if (diag < 0)
2096af75078fSIntel 		rte_panic("Cannot init EAL\n");
2097af75078fSIntel 
2098102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2099102b7329SReshma Pattan 	/* initialize packet capture framework */
2100102b7329SReshma Pattan 	rte_pdump_init(NULL);
2101102b7329SReshma Pattan #endif
2102102b7329SReshma Pattan 
2103af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2104af75078fSIntel 	if (nb_ports == 0)
2105edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2106af75078fSIntel 
2107ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2108ffc468ffSTetsuya Mukawa 	init_port();
2109ffc468ffSTetsuya Mukawa 
2110af75078fSIntel 	set_def_fwd_config();
2111af75078fSIntel 	if (nb_lcores == 0)
2112af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2113af75078fSIntel 			  "core mask supplied in the command parameters\n");
2114af75078fSIntel 
2115af75078fSIntel 	argc -= diag;
2116af75078fSIntel 	argv += diag;
2117af75078fSIntel 	if (argc > 1)
2118af75078fSIntel 		launch_args_parse(argc, argv);
2119af75078fSIntel 
21205a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
21215a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
21225a8fb55cSReshma Pattan 
21235a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2124af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2125af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2126af75078fSIntel 		       nb_rxq, nb_txq);
2127af75078fSIntel 
2128af75078fSIntel 	init_config();
2129148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2130148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2131af75078fSIntel 
2132ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
2133edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
2134ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2135af75078fSIntel 
21360d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2137ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2138ca7feb22SCyril Chemparathy 		if (auto_start) {
2139ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2140ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2141ca7feb22SCyril Chemparathy 		}
2142af75078fSIntel 		prompt();
2143ca7feb22SCyril Chemparathy 	} else
21440d56cb81SThomas Monjalon #endif
21450d56cb81SThomas Monjalon 	{
2146af75078fSIntel 		char c;
2147af75078fSIntel 		int rc;
2148af75078fSIntel 
2149af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2150af75078fSIntel 		start_packet_forwarding(0);
2151af75078fSIntel 		printf("Press enter to exit\n");
2152af75078fSIntel 		rc = read(0, &c, 1);
2153d3a274ceSZhihong Wang 		pmd_test_exit();
2154af75078fSIntel 		if (rc < 0)
2155af75078fSIntel 			return 1;
2156af75078fSIntel 	}
2157af75078fSIntel 
2158af75078fSIntel 	return 0;
2159af75078fSIntel }
2160