xref: /dpdk/app/test-pmd/testpmd.c (revision 933617d87eed576b3626b92882bb178a0d0494f9)
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_ring.h>
67af75078fSIntel #include <rte_mempool.h>
68af75078fSIntel #include <rte_malloc.h>
69af75078fSIntel #include <rte_mbuf.h>
70af75078fSIntel #include <rte_interrupts.h>
71af75078fSIntel #include <rte_pci.h>
72af75078fSIntel #include <rte_ether.h>
73af75078fSIntel #include <rte_ethdev.h>
74edab33b1STetsuya Mukawa #include <rte_dev.h>
75af75078fSIntel #include <rte_string_fns.h>
76148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
77148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
78148f963fSBruce Richardson #endif
79af75078fSIntel 
80af75078fSIntel #include "testpmd.h"
81af75078fSIntel 
82af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
83af75078fSIntel 
84af75078fSIntel /* use master core for command line ? */
85af75078fSIntel uint8_t interactive = 0;
86ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
87af75078fSIntel 
88af75078fSIntel /*
89af75078fSIntel  * NUMA support configuration.
90af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
91af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
92af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
93af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
94af75078fSIntel  */
95af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */
96af75078fSIntel 
97af75078fSIntel /*
98b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
99b6ea6408SIntel  * not configured.
100b6ea6408SIntel  */
101b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
102b6ea6408SIntel 
103b6ea6408SIntel /*
104148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
105148f963fSBruce Richardson  */
106148f963fSBruce Richardson uint8_t mp_anon = 0;
107148f963fSBruce Richardson 
108148f963fSBruce Richardson /*
109af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
110af75078fSIntel  * forwarded.
111af75078fSIntel  * Must be instanciated with the ethernet addresses of peer traffic generator
112af75078fSIntel  * ports.
113af75078fSIntel  */
114af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
115af75078fSIntel portid_t nb_peer_eth_addrs = 0;
116af75078fSIntel 
117af75078fSIntel /*
118af75078fSIntel  * Probed Target Environment.
119af75078fSIntel  */
120af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
121af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
122af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
123af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
124af75078fSIntel 
125af75078fSIntel /*
126af75078fSIntel  * Test Forwarding Configuration.
127af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
128af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
129af75078fSIntel  */
130af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
131af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
132af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
133af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
134af75078fSIntel 
135af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
136af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
137af75078fSIntel 
138af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
139af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
140af75078fSIntel 
141af75078fSIntel /*
142af75078fSIntel  * Forwarding engines.
143af75078fSIntel  */
144af75078fSIntel struct fwd_engine * fwd_engines[] = {
145af75078fSIntel 	&io_fwd_engine,
146af75078fSIntel 	&mac_fwd_engine,
147d47388f1SCyril Chemparathy 	&mac_swap_engine,
148e9e23a61SCyril Chemparathy 	&flow_gen_engine,
149af75078fSIntel 	&rx_only_engine,
150af75078fSIntel 	&tx_only_engine,
151af75078fSIntel 	&csum_fwd_engine,
152168dfa61SIvan Boule 	&icmp_echo_engine,
153af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
154af75078fSIntel 	&ieee1588_fwd_engine,
155af75078fSIntel #endif
156af75078fSIntel 	NULL,
157af75078fSIntel };
158af75078fSIntel 
159af75078fSIntel struct fwd_config cur_fwd_config;
160af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
161bf56fce1SZhihong Wang uint32_t retry_enabled;
162bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
163bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
164af75078fSIntel 
165af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
166c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
167c8798818SIntel                                       * specified on command-line. */
168af75078fSIntel 
169af75078fSIntel /*
170af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
171af75078fSIntel  */
172af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
173af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
174af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
175af75078fSIntel };
176af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
177af75078fSIntel 
17879bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
17979bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
18079bec05bSKonstantin Ananyev 
181af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
182e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
183af75078fSIntel 
184900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
185900550deSIntel uint8_t dcb_config = 0;
186900550deSIntel 
187900550deSIntel /* Whether the dcb is in testing status */
188900550deSIntel uint8_t dcb_test = 0;
189900550deSIntel 
190af75078fSIntel /*
191af75078fSIntel  * Configurable number of RX/TX queues.
192af75078fSIntel  */
193af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
194af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
195af75078fSIntel 
196af75078fSIntel /*
197af75078fSIntel  * Configurable number of RX/TX ring descriptors.
198af75078fSIntel  */
199af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
200af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
201af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
202af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
203af75078fSIntel 
204f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
205af75078fSIntel /*
206af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
207af75078fSIntel  */
208af75078fSIntel 
209f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
210f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
211f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
212af75078fSIntel 
213f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
214f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
215f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
216af75078fSIntel 
217af75078fSIntel /*
218af75078fSIntel  * Configurable value of RX free threshold.
219af75078fSIntel  */
220f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
221af75078fSIntel 
222af75078fSIntel /*
223ce8d5614SIntel  * Configurable value of RX drop enable.
224ce8d5614SIntel  */
225f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
226ce8d5614SIntel 
227ce8d5614SIntel /*
228af75078fSIntel  * Configurable value of TX free threshold.
229af75078fSIntel  */
230f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
231af75078fSIntel 
232af75078fSIntel /*
233af75078fSIntel  * Configurable value of TX RS bit threshold.
234af75078fSIntel  */
235f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
236af75078fSIntel 
237af75078fSIntel /*
238ce8d5614SIntel  * Configurable value of TX queue flags.
239ce8d5614SIntel  */
240f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
241ce8d5614SIntel 
242ce8d5614SIntel /*
243af75078fSIntel  * Receive Side Scaling (RSS) configuration.
244af75078fSIntel  */
2458a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
246af75078fSIntel 
247af75078fSIntel /*
248af75078fSIntel  * Port topology configuration
249af75078fSIntel  */
250af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
251af75078fSIntel 
2527741e4cfSIntel /*
2537741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2547741e4cfSIntel  */
2557741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2567741e4cfSIntel 
257af75078fSIntel /*
258bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
259bc202406SDavid Marchand  */
260bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
261bc202406SDavid Marchand 
262bc202406SDavid Marchand /*
2637b7e5ba7SIntel  * NIC bypass mode configuration options.
2647b7e5ba7SIntel  */
2657b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
2667b7e5ba7SIntel 
2677b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
2687b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
2697b7e5ba7SIntel 
2707b7e5ba7SIntel #endif
2717b7e5ba7SIntel 
2727b7e5ba7SIntel /*
273af75078fSIntel  * Ethernet device configuration.
274af75078fSIntel  */
275af75078fSIntel struct rte_eth_rxmode rx_mode = {
276af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
277af75078fSIntel 	.split_hdr_size = 0,
278af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
279af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
280af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
281a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
282a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
283af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
284af75078fSIntel 	.hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
285af75078fSIntel };
286af75078fSIntel 
287af75078fSIntel struct rte_fdir_conf fdir_conf = {
288af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
289af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
290af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
291d9d5e6f2SJingjing Wu 	.mask = {
292d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
293d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
294d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
295d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
296d9d5e6f2SJingjing Wu 		},
297d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
298d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
299d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
300d9d5e6f2SJingjing Wu 		},
301d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
302d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
30347b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
30447b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
30547b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
306d9d5e6f2SJingjing Wu 	},
307af75078fSIntel 	.drop_queue = 127,
308af75078fSIntel };
309af75078fSIntel 
3102950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
311af75078fSIntel 
312ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
313ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
314ed30d9b6SIntel 
315ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
316ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
317ed30d9b6SIntel 
318ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
319ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
320ed30d9b6SIntel 
3217acf894dSStephen Hurd unsigned max_socket = 0;
3227acf894dSStephen Hurd 
323ed30d9b6SIntel /* Forward function declarations */
324ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
325edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
326ce8d5614SIntel 
327ce8d5614SIntel /*
328ce8d5614SIntel  * Check if all the ports are started.
329ce8d5614SIntel  * If yes, return positive value. If not, return zero.
330ce8d5614SIntel  */
331ce8d5614SIntel static int all_ports_started(void);
332ed30d9b6SIntel 
333af75078fSIntel /*
334edab33b1STetsuya Mukawa  * Find next enabled port
335edab33b1STetsuya Mukawa  */
336edab33b1STetsuya Mukawa portid_t
337edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size)
338edab33b1STetsuya Mukawa {
339edab33b1STetsuya Mukawa 	if (ports == NULL)
340edab33b1STetsuya Mukawa 		rte_exit(-EINVAL, "failed to find a next port id\n");
341edab33b1STetsuya Mukawa 
34212a8e30fSJulien Cretin 	while ((p < size) && (ports[p].enabled == 0))
343edab33b1STetsuya Mukawa 		p++;
344edab33b1STetsuya Mukawa 	return p;
345edab33b1STetsuya Mukawa }
346edab33b1STetsuya Mukawa 
347edab33b1STetsuya Mukawa /*
348af75078fSIntel  * Setup default configuration.
349af75078fSIntel  */
350af75078fSIntel static void
351af75078fSIntel set_default_fwd_lcores_config(void)
352af75078fSIntel {
353af75078fSIntel 	unsigned int i;
354af75078fSIntel 	unsigned int nb_lc;
3557acf894dSStephen Hurd 	unsigned int sock_num;
356af75078fSIntel 
357af75078fSIntel 	nb_lc = 0;
358af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
3597acf894dSStephen Hurd 		sock_num = rte_lcore_to_socket_id(i) + 1;
3607acf894dSStephen Hurd 		if (sock_num > max_socket) {
3617acf894dSStephen Hurd 			if (sock_num > RTE_MAX_NUMA_NODES)
3627acf894dSStephen Hurd 				rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
3637acf894dSStephen Hurd 			max_socket = sock_num;
3647acf894dSStephen Hurd 		}
365f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
366f54fe5eeSStephen Hurd 			continue;
367f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
368f54fe5eeSStephen Hurd 			continue;
369f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
370af75078fSIntel 	}
371af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
372af75078fSIntel 	nb_cfg_lcores = nb_lcores;
373af75078fSIntel 	nb_fwd_lcores = 1;
374af75078fSIntel }
375af75078fSIntel 
376af75078fSIntel static void
377af75078fSIntel set_def_peer_eth_addrs(void)
378af75078fSIntel {
379af75078fSIntel 	portid_t i;
380af75078fSIntel 
381af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
382af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
383af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
384af75078fSIntel 	}
385af75078fSIntel }
386af75078fSIntel 
387af75078fSIntel static void
388af75078fSIntel set_default_fwd_ports_config(void)
389af75078fSIntel {
390af75078fSIntel 	portid_t pt_id;
391af75078fSIntel 
392af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
393af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
394af75078fSIntel 
395af75078fSIntel 	nb_cfg_ports = nb_ports;
396af75078fSIntel 	nb_fwd_ports = nb_ports;
397af75078fSIntel }
398af75078fSIntel 
399af75078fSIntel void
400af75078fSIntel set_def_fwd_config(void)
401af75078fSIntel {
402af75078fSIntel 	set_default_fwd_lcores_config();
403af75078fSIntel 	set_def_peer_eth_addrs();
404af75078fSIntel 	set_default_fwd_ports_config();
405af75078fSIntel }
406af75078fSIntel 
407af75078fSIntel /*
408af75078fSIntel  * Configuration initialisation done once at init time.
409af75078fSIntel  */
410af75078fSIntel static void
411af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
412af75078fSIntel 		 unsigned int socket_id)
413af75078fSIntel {
414af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
415bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
416af75078fSIntel 	uint32_t mb_size;
417af75078fSIntel 
418dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
419af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
420148f963fSBruce Richardson 
421d1eb542eSOlivier Matz 	RTE_LOG(INFO, USER1,
422d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
423d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
424d1eb542eSOlivier Matz 
425148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
426148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
427af75078fSIntel 		(unsigned) mb_mempool_cache,
428af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
429dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
430dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
431af75078fSIntel 		socket_id, 0);
432bece7b6cSChristian Ehrhardt #endif
433148f963fSBruce Richardson 
434bece7b6cSChristian Ehrhardt 	/* if the former XEN allocation failed fall back to normal allocation */
435bece7b6cSChristian Ehrhardt 	if (rte_mp == NULL) {
436b19a0c75SOlivier Matz 		if (mp_anon != 0) {
437b19a0c75SOlivier Matz 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
438bece7b6cSChristian Ehrhardt 				mb_size, (unsigned) mb_mempool_cache,
439148f963fSBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private),
440148f963fSBruce Richardson 				socket_id, 0);
441b19a0c75SOlivier Matz 
442b19a0c75SOlivier Matz 			if (rte_mempool_populate_anon(rte_mp) == 0) {
443b19a0c75SOlivier Matz 				rte_mempool_free(rte_mp);
444b19a0c75SOlivier Matz 				rte_mp = NULL;
445b19a0c75SOlivier Matz 			}
446b19a0c75SOlivier Matz 			rte_pktmbuf_pool_init(rte_mp, NULL);
447b19a0c75SOlivier Matz 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
448b19a0c75SOlivier Matz 		} else {
449ea0c20eaSOlivier Matz 			/* wrapper to rte_mempool_create() */
450ea0c20eaSOlivier Matz 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
451ea0c20eaSOlivier Matz 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
452bece7b6cSChristian Ehrhardt 		}
453b19a0c75SOlivier Matz 	}
454148f963fSBruce Richardson 
455af75078fSIntel 	if (rte_mp == NULL) {
456d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
457d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
458d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
459148f963fSBruce Richardson 	} else if (verbose_level > 0) {
460591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
461af75078fSIntel 	}
462af75078fSIntel }
463af75078fSIntel 
46420a0286fSLiu Xiaofeng /*
46520a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
46620a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
46720a0286fSLiu Xiaofeng  */
46820a0286fSLiu Xiaofeng static int
46920a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
47020a0286fSLiu Xiaofeng {
47120a0286fSLiu Xiaofeng 	static int warning_once = 0;
47220a0286fSLiu Xiaofeng 
4737acf894dSStephen Hurd 	if (socket_id >= max_socket) {
47420a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
47520a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
47620a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
47720a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
47820a0286fSLiu Xiaofeng 			       " --numa.\n");
47920a0286fSLiu Xiaofeng 		warning_once = 1;
48020a0286fSLiu Xiaofeng 		return -1;
48120a0286fSLiu Xiaofeng 	}
48220a0286fSLiu Xiaofeng 	return 0;
48320a0286fSLiu Xiaofeng }
48420a0286fSLiu Xiaofeng 
485af75078fSIntel static void
486af75078fSIntel init_config(void)
487af75078fSIntel {
488ce8d5614SIntel 	portid_t pid;
489af75078fSIntel 	struct rte_port *port;
490af75078fSIntel 	struct rte_mempool *mbp;
491af75078fSIntel 	unsigned int nb_mbuf_per_pool;
492af75078fSIntel 	lcoreid_t  lc_id;
4937acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
494af75078fSIntel 
4957acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
496af75078fSIntel 	/* Configuration of logical cores. */
497af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
498af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
499fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
500af75078fSIntel 	if (fwd_lcores == NULL) {
501ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
502ce8d5614SIntel 							"failed\n", nb_lcores);
503af75078fSIntel 	}
504af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
505af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
506af75078fSIntel 					       sizeof(struct fwd_lcore),
507fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
508af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
509ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
510ce8d5614SIntel 								"failed\n");
511af75078fSIntel 		}
512af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
513af75078fSIntel 	}
514af75078fSIntel 
515af75078fSIntel 	/*
516af75078fSIntel 	 * Create pools of mbuf.
517af75078fSIntel 	 * If NUMA support is disabled, create a single pool of mbuf in
518b6ea6408SIntel 	 * socket 0 memory by default.
519af75078fSIntel 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
520c8798818SIntel 	 *
521c8798818SIntel 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
522c8798818SIntel 	 * nb_txd can be configured at run time.
523af75078fSIntel 	 */
524c8798818SIntel 	if (param_total_num_mbufs)
525c8798818SIntel 		nb_mbuf_per_pool = param_total_num_mbufs;
526c8798818SIntel 	else {
527c8798818SIntel 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
528c8798818SIntel 				+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
529b6ea6408SIntel 
530b6ea6408SIntel 		if (!numa_support)
531edab33b1STetsuya Mukawa 			nb_mbuf_per_pool =
532edab33b1STetsuya Mukawa 				(nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
533c8798818SIntel 	}
534af75078fSIntel 
535b6ea6408SIntel 	if (!numa_support) {
536b6ea6408SIntel 		if (socket_num == UMA_NO_CONFIG)
537b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
538b6ea6408SIntel 		else
539b6ea6408SIntel 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
540b6ea6408SIntel 						 socket_num);
541b6ea6408SIntel 	}
542af75078fSIntel 
543edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
544ce8d5614SIntel 		port = &ports[pid];
545ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
546ce8d5614SIntel 
547b6ea6408SIntel 		if (numa_support) {
548b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
549b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
550b6ea6408SIntel 			else {
551b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
55220a0286fSLiu Xiaofeng 
55320a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
55420a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
55520a0286fSLiu Xiaofeng 					socket_id = 0;
556b6ea6408SIntel 				port_per_socket[socket_id]++;
557b6ea6408SIntel 			}
558b6ea6408SIntel 		}
559b6ea6408SIntel 
560ce8d5614SIntel 		/* set flag to initialize port/queue */
561ce8d5614SIntel 		port->need_reconfig = 1;
562ce8d5614SIntel 		port->need_reconfig_queues = 1;
563ce8d5614SIntel 	}
564ce8d5614SIntel 
565b6ea6408SIntel 	if (numa_support) {
566b6ea6408SIntel 		uint8_t i;
567b6ea6408SIntel 		unsigned int nb_mbuf;
568ce8d5614SIntel 
569b6ea6408SIntel 		if (param_total_num_mbufs)
570b6ea6408SIntel 			nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
571b6ea6408SIntel 
5727acf894dSStephen Hurd 		for (i = 0; i < max_socket; i++) {
573edab33b1STetsuya Mukawa 			nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
574b6ea6408SIntel 			if (nb_mbuf)
575b6ea6408SIntel 				mbuf_pool_create(mbuf_data_size,
576b6ea6408SIntel 						nb_mbuf,i);
577b6ea6408SIntel 		}
578b6ea6408SIntel 	}
579b6ea6408SIntel 	init_port_config();
5805886ae07SAdrien Mazarguil 
5815886ae07SAdrien Mazarguil 	/*
5825886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
5835886ae07SAdrien Mazarguil 	 */
5845886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
5858fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
5868fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
5878fd8bebcSAdrien Mazarguil 
5885886ae07SAdrien Mazarguil 		if (mbp == NULL)
5895886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
5905886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
5915886ae07SAdrien Mazarguil 	}
5925886ae07SAdrien Mazarguil 
593ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
594ce8d5614SIntel 	if (init_fwd_streams() < 0)
595ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
5960c0db76fSBernard Iremonger 
5970c0db76fSBernard Iremonger 	fwd_config_setup();
598ce8d5614SIntel }
599ce8d5614SIntel 
6002950a769SDeclan Doherty 
6012950a769SDeclan Doherty void
602a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6032950a769SDeclan Doherty {
6042950a769SDeclan Doherty 	struct rte_port *port;
6052950a769SDeclan Doherty 
6062950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6072950a769SDeclan Doherty 	port = &ports[new_port_id];
6082950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6092950a769SDeclan Doherty 
6102950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6112950a769SDeclan Doherty 	port->need_reconfig = 1;
6122950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
613a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6142950a769SDeclan Doherty 
6152950a769SDeclan Doherty 	init_port_config();
6162950a769SDeclan Doherty }
6172950a769SDeclan Doherty 
6182950a769SDeclan Doherty 
619ce8d5614SIntel int
620ce8d5614SIntel init_fwd_streams(void)
621ce8d5614SIntel {
622ce8d5614SIntel 	portid_t pid;
623ce8d5614SIntel 	struct rte_port *port;
624ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
6255a8fb55cSReshma Pattan 	queueid_t q;
626ce8d5614SIntel 
627ce8d5614SIntel 	/* set socket id according to numa or not */
628edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
629ce8d5614SIntel 		port = &ports[pid];
630ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
631ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
632ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
633ce8d5614SIntel 				port->dev_info.max_rx_queues);
634ce8d5614SIntel 			return -1;
635ce8d5614SIntel 		}
636ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
637ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
638ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
639ce8d5614SIntel 				port->dev_info.max_tx_queues);
640ce8d5614SIntel 			return -1;
641ce8d5614SIntel 		}
64220a0286fSLiu Xiaofeng 		if (numa_support) {
64320a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
64420a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
64520a0286fSLiu Xiaofeng 			else {
646b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
64720a0286fSLiu Xiaofeng 
64820a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
64920a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
65020a0286fSLiu Xiaofeng 					port->socket_id = 0;
65120a0286fSLiu Xiaofeng 			}
65220a0286fSLiu Xiaofeng 		}
653b6ea6408SIntel 		else {
654b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
655af75078fSIntel 				port->socket_id = 0;
656b6ea6408SIntel 			else
657b6ea6408SIntel 				port->socket_id = socket_num;
658b6ea6408SIntel 		}
659af75078fSIntel 	}
660af75078fSIntel 
6615a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
6625a8fb55cSReshma Pattan 	if (q == 0) {
6635a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
6645a8fb55cSReshma Pattan 		return -1;
6655a8fb55cSReshma Pattan 	}
6665a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
667ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
668ce8d5614SIntel 		return 0;
669ce8d5614SIntel 	/* clear the old */
670ce8d5614SIntel 	if (fwd_streams != NULL) {
671ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
672ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
673ce8d5614SIntel 				continue;
674ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
675ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
676af75078fSIntel 		}
677ce8d5614SIntel 		rte_free(fwd_streams);
678ce8d5614SIntel 		fwd_streams = NULL;
679ce8d5614SIntel 	}
680ce8d5614SIntel 
681ce8d5614SIntel 	/* init new */
682ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
683ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
684fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
685ce8d5614SIntel 	if (fwd_streams == NULL)
686ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
687ce8d5614SIntel 						"failed\n", nb_fwd_streams);
688ce8d5614SIntel 
689af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
690af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
691fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
692ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
693ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
694ce8d5614SIntel 								" failed\n");
695af75078fSIntel 	}
696ce8d5614SIntel 
697ce8d5614SIntel 	return 0;
698af75078fSIntel }
699af75078fSIntel 
700af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
701af75078fSIntel static void
702af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
703af75078fSIntel {
704af75078fSIntel 	unsigned int total_burst;
705af75078fSIntel 	unsigned int nb_burst;
706af75078fSIntel 	unsigned int burst_stats[3];
707af75078fSIntel 	uint16_t pktnb_stats[3];
708af75078fSIntel 	uint16_t nb_pkt;
709af75078fSIntel 	int burst_percent[3];
710af75078fSIntel 
711af75078fSIntel 	/*
712af75078fSIntel 	 * First compute the total number of packet bursts and the
713af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
714af75078fSIntel 	 */
715af75078fSIntel 	total_burst = 0;
716af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
717af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
718af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
719af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
720af75078fSIntel 		if (nb_burst == 0)
721af75078fSIntel 			continue;
722af75078fSIntel 		total_burst += nb_burst;
723af75078fSIntel 		if (nb_burst > burst_stats[0]) {
724af75078fSIntel 			burst_stats[1] = burst_stats[0];
725af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
726af75078fSIntel 			burst_stats[0] = nb_burst;
727af75078fSIntel 			pktnb_stats[0] = nb_pkt;
728af75078fSIntel 		}
729af75078fSIntel 	}
730af75078fSIntel 	if (total_burst == 0)
731af75078fSIntel 		return;
732af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
733af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
734af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
735af75078fSIntel 	if (burst_stats[0] == total_burst) {
736af75078fSIntel 		printf("]\n");
737af75078fSIntel 		return;
738af75078fSIntel 	}
739af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
740af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
741af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
742af75078fSIntel 		return;
743af75078fSIntel 	}
744af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
745af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
746af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
747af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
748af75078fSIntel 		return;
749af75078fSIntel 	}
750af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
751af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
752af75078fSIntel }
753af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
754af75078fSIntel 
755af75078fSIntel static void
756af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
757af75078fSIntel {
758af75078fSIntel 	struct rte_port *port;
759013af9b6SIntel 	uint8_t i;
760af75078fSIntel 
761af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
762af75078fSIntel 
763af75078fSIntel 	port = &ports[port_id];
764af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
765af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
766013af9b6SIntel 
767013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
768af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
769af75078fSIntel 		       "%-"PRIu64"\n",
77070bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
77170bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
772af75078fSIntel 
773af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
774af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
775af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
77686057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
777f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
77870bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
77970bdb186SIvan Boule 		}
780af75078fSIntel 
781af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
782af75078fSIntel 		       "%-"PRIu64"\n",
783af75078fSIntel 		       stats->opackets, port->tx_dropped,
784af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
785013af9b6SIntel 	}
786013af9b6SIntel 	else {
787013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
788013af9b6SIntel 		       "%14"PRIu64"\n",
78970bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
79070bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
791013af9b6SIntel 
792013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
793013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
794013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
79586057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
796f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
79770bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
79870bdb186SIvan Boule 			       stats->rx_nombuf);
79970bdb186SIvan Boule 		}
800013af9b6SIntel 
801013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
802013af9b6SIntel 		       "%14"PRIu64"\n",
803013af9b6SIntel 		       stats->opackets, port->tx_dropped,
804013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
805013af9b6SIntel 	}
806e659b6b4SIvan Boule 
807af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
808af75078fSIntel 	if (port->rx_stream)
809013af9b6SIntel 		pkt_burst_stats_display("RX",
810013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
811af75078fSIntel 	if (port->tx_stream)
812013af9b6SIntel 		pkt_burst_stats_display("TX",
813013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
814af75078fSIntel #endif
815af75078fSIntel 
816013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
817013af9b6SIntel 		printf("\n");
818013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
819013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
820013af9b6SIntel 			       "     RX-errors:%14"PRIu64
821013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
822013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
823013af9b6SIntel 		}
824013af9b6SIntel 		printf("\n");
825013af9b6SIntel 	}
826013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
827013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
828013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
829013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
830013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
831013af9b6SIntel 		}
832013af9b6SIntel 	}
833013af9b6SIntel 
834af75078fSIntel 	printf("  %s--------------------------------%s\n",
835af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
836af75078fSIntel }
837af75078fSIntel 
838af75078fSIntel static void
839af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
840af75078fSIntel {
841af75078fSIntel 	struct fwd_stream *fs;
842af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
843af75078fSIntel 
844af75078fSIntel 	fs = fwd_streams[stream_id];
845af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
846af75078fSIntel 	    (fs->fwd_dropped == 0))
847af75078fSIntel 		return;
848af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
849af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
850af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
851af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
852af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
853af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
854af75078fSIntel 
855af75078fSIntel 	/* if checksum mode */
856af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
857013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
858013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
859af75078fSIntel 	}
860af75078fSIntel 
861af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
862af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
863af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
864af75078fSIntel #endif
865af75078fSIntel }
866af75078fSIntel 
867af75078fSIntel static void
8687741e4cfSIntel flush_fwd_rx_queues(void)
869af75078fSIntel {
870af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
871af75078fSIntel 	portid_t  rxp;
8727741e4cfSIntel 	portid_t port_id;
873af75078fSIntel 	queueid_t rxq;
874af75078fSIntel 	uint16_t  nb_rx;
875af75078fSIntel 	uint16_t  i;
876af75078fSIntel 	uint8_t   j;
877af75078fSIntel 
878af75078fSIntel 	for (j = 0; j < 2; j++) {
8797741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
880af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
8817741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
882af75078fSIntel 				do {
8837741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
884013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
885af75078fSIntel 					for (i = 0; i < nb_rx; i++)
886af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
887af75078fSIntel 				} while (nb_rx > 0);
888af75078fSIntel 			}
889af75078fSIntel 		}
890af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
891af75078fSIntel 	}
892af75078fSIntel }
893af75078fSIntel 
894af75078fSIntel static void
895af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
896af75078fSIntel {
897af75078fSIntel 	struct fwd_stream **fsm;
898af75078fSIntel 	streamid_t nb_fs;
899af75078fSIntel 	streamid_t sm_id;
900af75078fSIntel 
901af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
902af75078fSIntel 	nb_fs = fc->stream_nb;
903af75078fSIntel 	do {
904af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
905af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
906af75078fSIntel 	} while (! fc->stopped);
907af75078fSIntel }
908af75078fSIntel 
909af75078fSIntel static int
910af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
911af75078fSIntel {
912af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
913af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
914af75078fSIntel 	return 0;
915af75078fSIntel }
916af75078fSIntel 
917af75078fSIntel /*
918af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
919af75078fSIntel  * Used to start communication flows in network loopback test configurations.
920af75078fSIntel  */
921af75078fSIntel static int
922af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
923af75078fSIntel {
924af75078fSIntel 	struct fwd_lcore *fwd_lc;
925af75078fSIntel 	struct fwd_lcore tmp_lcore;
926af75078fSIntel 
927af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
928af75078fSIntel 	tmp_lcore = *fwd_lc;
929af75078fSIntel 	tmp_lcore.stopped = 1;
930af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
931af75078fSIntel 	return 0;
932af75078fSIntel }
933af75078fSIntel 
934af75078fSIntel /*
935af75078fSIntel  * Launch packet forwarding:
936af75078fSIntel  *     - Setup per-port forwarding context.
937af75078fSIntel  *     - launch logical cores with their forwarding configuration.
938af75078fSIntel  */
939af75078fSIntel static void
940af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
941af75078fSIntel {
942af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
943af75078fSIntel 	unsigned int i;
944af75078fSIntel 	unsigned int lc_id;
945af75078fSIntel 	int diag;
946af75078fSIntel 
947af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
948af75078fSIntel 	if (port_fwd_begin != NULL) {
949af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
950af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
951af75078fSIntel 	}
952af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
953af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
954af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
955af75078fSIntel 			fwd_lcores[i]->stopped = 0;
956af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
957af75078fSIntel 						     fwd_lcores[i], lc_id);
958af75078fSIntel 			if (diag != 0)
959af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
960af75078fSIntel 				       lc_id, diag);
961af75078fSIntel 		}
962af75078fSIntel 	}
963af75078fSIntel }
964af75078fSIntel 
965af75078fSIntel /*
966af75078fSIntel  * Launch packet forwarding configuration.
967af75078fSIntel  */
968af75078fSIntel void
969af75078fSIntel start_packet_forwarding(int with_tx_first)
970af75078fSIntel {
971af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
972af75078fSIntel 	port_fwd_end_t  port_fwd_end;
973af75078fSIntel 	struct rte_port *port;
974af75078fSIntel 	unsigned int i;
975af75078fSIntel 	portid_t   pt_id;
976af75078fSIntel 	streamid_t sm_id;
977af75078fSIntel 
9785a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
9795a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
9805a8fb55cSReshma Pattan 
9815a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
9825a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
9835a8fb55cSReshma Pattan 
9845a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
9855a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
9865a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
9875a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
9885a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
9895a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
9905a8fb55cSReshma Pattan 
991ce8d5614SIntel 	if (all_ports_started() == 0) {
992ce8d5614SIntel 		printf("Not all ports were started\n");
993ce8d5614SIntel 		return;
994ce8d5614SIntel 	}
995af75078fSIntel 	if (test_done == 0) {
996af75078fSIntel 		printf("Packet forwarding already started\n");
997af75078fSIntel 		return;
998af75078fSIntel 	}
999edf87b4aSBernard Iremonger 
1000edf87b4aSBernard Iremonger 	if (init_fwd_streams() < 0) {
1001edf87b4aSBernard Iremonger 		printf("Fail from init_fwd_streams()\n");
1002edf87b4aSBernard Iremonger 		return;
1003edf87b4aSBernard Iremonger 	}
1004edf87b4aSBernard Iremonger 
10057741e4cfSIntel 	if(dcb_test) {
10067741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
10077741e4cfSIntel 			pt_id = fwd_ports_ids[i];
10087741e4cfSIntel 			port = &ports[pt_id];
10097741e4cfSIntel 			if (!port->dcb_flag) {
10107741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
10117741e4cfSIntel                                        "be configured in this mode.\n");
1012013af9b6SIntel 				return;
1013013af9b6SIntel 			}
10147741e4cfSIntel 		}
10157741e4cfSIntel 		if (nb_fwd_lcores == 1) {
10167741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
10177741e4cfSIntel                                "should be larger than 1.\n");
10187741e4cfSIntel 			return;
10197741e4cfSIntel 		}
10207741e4cfSIntel 	}
1021af75078fSIntel 	test_done = 0;
10227741e4cfSIntel 
10237741e4cfSIntel 	if(!no_flush_rx)
10247741e4cfSIntel 		flush_fwd_rx_queues();
10257741e4cfSIntel 
1026af75078fSIntel 	fwd_config_setup();
1027*933617d8SZhihong Wang 	pkt_fwd_config_display(&cur_fwd_config);
1028af75078fSIntel 	rxtx_config_display();
1029af75078fSIntel 
1030af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1031af75078fSIntel 		pt_id = fwd_ports_ids[i];
1032af75078fSIntel 		port = &ports[pt_id];
1033af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1034af75078fSIntel 		port->tx_dropped = 0;
1035013af9b6SIntel 
1036013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1037af75078fSIntel 	}
1038af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1039af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1040af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1041af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1042af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1043af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1044af75078fSIntel 
1045af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1046af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1047af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1048af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1049af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1050af75078fSIntel #endif
1051af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1052af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1053af75078fSIntel #endif
1054af75078fSIntel 	}
1055af75078fSIntel 	if (with_tx_first) {
1056af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1057af75078fSIntel 		if (port_fwd_begin != NULL) {
1058af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1059af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1060af75078fSIntel 		}
1061acbf77a6SZhihong Wang 		while (with_tx_first--) {
1062acbf77a6SZhihong Wang 			launch_packet_forwarding(
1063acbf77a6SZhihong Wang 					run_one_txonly_burst_on_core);
1064af75078fSIntel 			rte_eal_mp_wait_lcore();
1065acbf77a6SZhihong Wang 		}
1066af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1067af75078fSIntel 		if (port_fwd_end != NULL) {
1068af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1069af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1070af75078fSIntel 		}
1071af75078fSIntel 	}
1072af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1073af75078fSIntel }
1074af75078fSIntel 
1075af75078fSIntel void
1076af75078fSIntel stop_packet_forwarding(void)
1077af75078fSIntel {
1078af75078fSIntel 	struct rte_eth_stats stats;
1079af75078fSIntel 	struct rte_port *port;
1080af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1081af75078fSIntel 	int i;
1082af75078fSIntel 	portid_t   pt_id;
1083af75078fSIntel 	streamid_t sm_id;
1084af75078fSIntel 	lcoreid_t  lc_id;
1085af75078fSIntel 	uint64_t total_recv;
1086af75078fSIntel 	uint64_t total_xmit;
1087af75078fSIntel 	uint64_t total_rx_dropped;
1088af75078fSIntel 	uint64_t total_tx_dropped;
1089af75078fSIntel 	uint64_t total_rx_nombuf;
1090af75078fSIntel 	uint64_t tx_dropped;
1091af75078fSIntel 	uint64_t rx_bad_ip_csum;
1092af75078fSIntel 	uint64_t rx_bad_l4_csum;
1093af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1094af75078fSIntel 	uint64_t fwd_cycles;
1095af75078fSIntel #endif
1096af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1097af75078fSIntel 
1098af75078fSIntel 	if (test_done) {
1099af75078fSIntel 		printf("Packet forwarding not started\n");
1100af75078fSIntel 		return;
1101af75078fSIntel 	}
1102af75078fSIntel 	printf("Telling cores to stop...");
1103af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1104af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1105af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1106af75078fSIntel 	rte_eal_mp_wait_lcore();
1107af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1108af75078fSIntel 	if (port_fwd_end != NULL) {
1109af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1110af75078fSIntel 			pt_id = fwd_ports_ids[i];
1111af75078fSIntel 			(*port_fwd_end)(pt_id);
1112af75078fSIntel 		}
1113af75078fSIntel 	}
1114af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1115af75078fSIntel 	fwd_cycles = 0;
1116af75078fSIntel #endif
1117af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1118af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1119af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1120af75078fSIntel 			fwd_stream_stats_display(sm_id);
1121af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1122af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1123af75078fSIntel 		} else {
1124af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1125af75078fSIntel 				fwd_streams[sm_id];
1126af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1127af75078fSIntel 				fwd_streams[sm_id];
1128af75078fSIntel 		}
1129af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1130af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1131af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1132af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1133af75078fSIntel 
1134013af9b6SIntel 		rx_bad_ip_csum =
1135013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1136af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1137af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1138013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1139013af9b6SIntel 							rx_bad_ip_csum;
1140af75078fSIntel 
1141013af9b6SIntel 		rx_bad_l4_csum =
1142013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1143af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1144af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1145013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1146013af9b6SIntel 							rx_bad_l4_csum;
1147af75078fSIntel 
1148af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1149af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1150af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1151af75078fSIntel #endif
1152af75078fSIntel 	}
1153af75078fSIntel 	total_recv = 0;
1154af75078fSIntel 	total_xmit = 0;
1155af75078fSIntel 	total_rx_dropped = 0;
1156af75078fSIntel 	total_tx_dropped = 0;
1157af75078fSIntel 	total_rx_nombuf  = 0;
11587741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1159af75078fSIntel 		pt_id = fwd_ports_ids[i];
1160af75078fSIntel 
1161af75078fSIntel 		port = &ports[pt_id];
1162af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1163af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1164af75078fSIntel 		port->stats.ipackets = 0;
1165af75078fSIntel 		stats.opackets -= port->stats.opackets;
1166af75078fSIntel 		port->stats.opackets = 0;
1167af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1168af75078fSIntel 		port->stats.ibytes = 0;
1169af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1170af75078fSIntel 		port->stats.obytes = 0;
117170bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
117270bdb186SIvan Boule 		port->stats.imissed = 0;
1173af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1174af75078fSIntel 		port->stats.oerrors = 0;
1175af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1176af75078fSIntel 		port->stats.rx_nombuf = 0;
1177af75078fSIntel 
1178af75078fSIntel 		total_recv += stats.ipackets;
1179af75078fSIntel 		total_xmit += stats.opackets;
118070bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1181af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1182af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1183af75078fSIntel 
1184af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1185af75078fSIntel 	}
1186af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1187af75078fSIntel 	       "%s\n",
1188af75078fSIntel 	       acc_stats_border, acc_stats_border);
1189af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1190af75078fSIntel 	       "%-"PRIu64"\n"
1191af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1192af75078fSIntel 	       "%-"PRIu64"\n",
1193af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1194af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1195af75078fSIntel 	if (total_rx_nombuf > 0)
1196af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1197af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1198af75078fSIntel 	       "%s\n",
1199af75078fSIntel 	       acc_stats_border, acc_stats_border);
1200af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1201af75078fSIntel 	if (total_recv > 0)
1202af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1203af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1204af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1205af75078fSIntel 		       fwd_cycles, total_recv);
1206af75078fSIntel #endif
1207af75078fSIntel 	printf("\nDone.\n");
1208af75078fSIntel 	test_done = 1;
1209af75078fSIntel }
1210af75078fSIntel 
1211cfae07fdSOuyang Changchun void
1212cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1213cfae07fdSOuyang Changchun {
1214cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1215cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1216cfae07fdSOuyang Changchun }
1217cfae07fdSOuyang Changchun 
1218cfae07fdSOuyang Changchun void
1219cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1220cfae07fdSOuyang Changchun {
1221cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1222cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1223cfae07fdSOuyang Changchun }
1224cfae07fdSOuyang Changchun 
1225ce8d5614SIntel static int
1226ce8d5614SIntel all_ports_started(void)
1227ce8d5614SIntel {
1228ce8d5614SIntel 	portid_t pi;
1229ce8d5614SIntel 	struct rte_port *port;
1230ce8d5614SIntel 
1231edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1232ce8d5614SIntel 		port = &ports[pi];
1233ce8d5614SIntel 		/* Check if there is a port which is not started */
123441b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
123541b05095SBernard Iremonger 			(port->slave_flag == 0))
1236ce8d5614SIntel 			return 0;
1237ce8d5614SIntel 	}
1238ce8d5614SIntel 
1239ce8d5614SIntel 	/* No port is not started */
1240ce8d5614SIntel 	return 1;
1241ce8d5614SIntel }
1242ce8d5614SIntel 
1243148f963fSBruce Richardson int
1244edab33b1STetsuya Mukawa all_ports_stopped(void)
1245edab33b1STetsuya Mukawa {
1246edab33b1STetsuya Mukawa 	portid_t pi;
1247edab33b1STetsuya Mukawa 	struct rte_port *port;
1248edab33b1STetsuya Mukawa 
1249edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1250edab33b1STetsuya Mukawa 		port = &ports[pi];
125141b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
125241b05095SBernard Iremonger 			(port->slave_flag == 0))
1253edab33b1STetsuya Mukawa 			return 0;
1254edab33b1STetsuya Mukawa 	}
1255edab33b1STetsuya Mukawa 
1256edab33b1STetsuya Mukawa 	return 1;
1257edab33b1STetsuya Mukawa }
1258edab33b1STetsuya Mukawa 
1259edab33b1STetsuya Mukawa int
1260edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1261edab33b1STetsuya Mukawa {
1262edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1263edab33b1STetsuya Mukawa 		return 0;
1264edab33b1STetsuya Mukawa 
1265edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1266edab33b1STetsuya Mukawa 		return 0;
1267edab33b1STetsuya Mukawa 
1268edab33b1STetsuya Mukawa 	return 1;
1269edab33b1STetsuya Mukawa }
1270edab33b1STetsuya Mukawa 
1271edab33b1STetsuya Mukawa static int
1272edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1273edab33b1STetsuya Mukawa {
1274edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1275edab33b1STetsuya Mukawa 		return 0;
1276edab33b1STetsuya Mukawa 
1277edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1278edab33b1STetsuya Mukawa 		return 0;
1279edab33b1STetsuya Mukawa 
1280edab33b1STetsuya Mukawa 	return 1;
1281edab33b1STetsuya Mukawa }
1282edab33b1STetsuya Mukawa 
1283edab33b1STetsuya Mukawa int
1284ce8d5614SIntel start_port(portid_t pid)
1285ce8d5614SIntel {
128692d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1287ce8d5614SIntel 	portid_t pi;
1288ce8d5614SIntel 	queueid_t qi;
1289ce8d5614SIntel 	struct rte_port *port;
12902950a769SDeclan Doherty 	struct ether_addr mac_addr;
1291ce8d5614SIntel 
12924468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
12934468635fSMichael Qiu 		return 0;
12944468635fSMichael Qiu 
1295ce8d5614SIntel 	if(dcb_config)
1296ce8d5614SIntel 		dcb_test = 1;
1297edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
1298edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1299ce8d5614SIntel 			continue;
1300ce8d5614SIntel 
130192d2703eSMichael Qiu 		need_check_link_status = 0;
1302ce8d5614SIntel 		port = &ports[pi];
1303ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1304ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1305ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1306ce8d5614SIntel 			continue;
1307ce8d5614SIntel 		}
1308ce8d5614SIntel 
1309ce8d5614SIntel 		if (port->need_reconfig > 0) {
1310ce8d5614SIntel 			port->need_reconfig = 0;
1311ce8d5614SIntel 
13125706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
131320a0286fSLiu Xiaofeng 					port->socket_id);
1314ce8d5614SIntel 			/* configure port */
1315ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1316ce8d5614SIntel 						&(port->dev_conf));
1317ce8d5614SIntel 			if (diag != 0) {
1318ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1319ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1320ce8d5614SIntel 					printf("Port %d can not be set back "
1321ce8d5614SIntel 							"to stopped\n", pi);
1322ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1323ce8d5614SIntel 				/* try to reconfigure port next time */
1324ce8d5614SIntel 				port->need_reconfig = 1;
1325148f963fSBruce Richardson 				return -1;
1326ce8d5614SIntel 			}
1327ce8d5614SIntel 		}
1328ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1329ce8d5614SIntel 			port->need_reconfig_queues = 0;
1330ce8d5614SIntel 			/* setup tx queues */
1331ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1332b6ea6408SIntel 				if ((numa_support) &&
1333b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1334b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1335b6ea6408SIntel 						nb_txd,txring_numa[pi],
1336b6ea6408SIntel 						&(port->tx_conf));
1337b6ea6408SIntel 				else
1338b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1339b6ea6408SIntel 						nb_txd,port->socket_id,
1340b6ea6408SIntel 						&(port->tx_conf));
1341b6ea6408SIntel 
1342ce8d5614SIntel 				if (diag == 0)
1343ce8d5614SIntel 					continue;
1344ce8d5614SIntel 
1345ce8d5614SIntel 				/* Fail to setup tx queue, return */
1346ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1347ce8d5614SIntel 							RTE_PORT_HANDLING,
1348ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1349ce8d5614SIntel 					printf("Port %d can not be set back "
1350ce8d5614SIntel 							"to stopped\n", pi);
1351ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1352ce8d5614SIntel 				/* try to reconfigure queues next time */
1353ce8d5614SIntel 				port->need_reconfig_queues = 1;
1354148f963fSBruce Richardson 				return -1;
1355ce8d5614SIntel 			}
1356ce8d5614SIntel 			/* setup rx queues */
1357ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1358b6ea6408SIntel 				if ((numa_support) &&
1359b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1360b6ea6408SIntel 					struct rte_mempool * mp =
1361b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1362b6ea6408SIntel 					if (mp == NULL) {
1363b6ea6408SIntel 						printf("Failed to setup RX queue:"
1364b6ea6408SIntel 							"No mempool allocation"
1365b6ea6408SIntel 							" on the socket %d\n",
1366b6ea6408SIntel 							rxring_numa[pi]);
1367148f963fSBruce Richardson 						return -1;
1368b6ea6408SIntel 					}
1369b6ea6408SIntel 
1370b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1371b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1372b6ea6408SIntel 					     &(port->rx_conf),mp);
13731e1d6bddSBernard Iremonger 				} else {
13741e1d6bddSBernard Iremonger 					struct rte_mempool *mp =
13751e1d6bddSBernard Iremonger 						mbuf_pool_find(port->socket_id);
13761e1d6bddSBernard Iremonger 					if (mp == NULL) {
13771e1d6bddSBernard Iremonger 						printf("Failed to setup RX queue:"
13781e1d6bddSBernard Iremonger 							"No mempool allocation"
13791e1d6bddSBernard Iremonger 							" on the socket %d\n",
13801e1d6bddSBernard Iremonger 							port->socket_id);
13811e1d6bddSBernard Iremonger 						return -1;
1382b6ea6408SIntel 					}
1383b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1384b6ea6408SIntel 					     nb_rxd,port->socket_id,
13851e1d6bddSBernard Iremonger 					     &(port->rx_conf), mp);
13861e1d6bddSBernard Iremonger 				}
1387ce8d5614SIntel 				if (diag == 0)
1388ce8d5614SIntel 					continue;
1389ce8d5614SIntel 
1390ce8d5614SIntel 				/* Fail to setup rx queue, return */
1391ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1392ce8d5614SIntel 							RTE_PORT_HANDLING,
1393ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1394ce8d5614SIntel 					printf("Port %d can not be set back "
1395ce8d5614SIntel 							"to stopped\n", pi);
1396ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1397ce8d5614SIntel 				/* try to reconfigure queues next time */
1398ce8d5614SIntel 				port->need_reconfig_queues = 1;
1399148f963fSBruce Richardson 				return -1;
1400ce8d5614SIntel 			}
1401ce8d5614SIntel 		}
1402ce8d5614SIntel 		/* start port */
1403ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1404ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1405ce8d5614SIntel 
1406ce8d5614SIntel 			/* Fail to setup rx queue, return */
1407ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1408ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1409ce8d5614SIntel 				printf("Port %d can not be set back to "
1410ce8d5614SIntel 							"stopped\n", pi);
1411ce8d5614SIntel 			continue;
1412ce8d5614SIntel 		}
1413ce8d5614SIntel 
1414ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1415ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1416ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1417ce8d5614SIntel 
14182950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1419d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
14202950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
14212950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
14222950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1423d8c89163SZijie Pan 
1424ce8d5614SIntel 		/* at least one port started, need checking link status */
1425ce8d5614SIntel 		need_check_link_status = 1;
1426ce8d5614SIntel 	}
1427ce8d5614SIntel 
142892d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1429edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
143092d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1431ce8d5614SIntel 		printf("Please stop the ports first\n");
1432ce8d5614SIntel 
1433ce8d5614SIntel 	printf("Done\n");
1434148f963fSBruce Richardson 	return 0;
1435ce8d5614SIntel }
1436ce8d5614SIntel 
1437ce8d5614SIntel void
1438ce8d5614SIntel stop_port(portid_t pid)
1439ce8d5614SIntel {
1440ce8d5614SIntel 	portid_t pi;
1441ce8d5614SIntel 	struct rte_port *port;
1442ce8d5614SIntel 	int need_check_link_status = 0;
1443ce8d5614SIntel 
1444ce8d5614SIntel 	if (dcb_test) {
1445ce8d5614SIntel 		dcb_test = 0;
1446ce8d5614SIntel 		dcb_config = 0;
1447ce8d5614SIntel 	}
14484468635fSMichael Qiu 
14494468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14504468635fSMichael Qiu 		return;
14514468635fSMichael Qiu 
1452ce8d5614SIntel 	printf("Stopping ports...\n");
1453ce8d5614SIntel 
1454edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14554468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1456ce8d5614SIntel 			continue;
1457ce8d5614SIntel 
1458a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1459a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1460a8ef3e3aSBernard Iremonger 			continue;
1461a8ef3e3aSBernard Iremonger 		}
1462a8ef3e3aSBernard Iremonger 
14630e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
14640e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
14650e545d30SBernard Iremonger 			continue;
14660e545d30SBernard Iremonger 		}
14670e545d30SBernard Iremonger 
1468ce8d5614SIntel 		port = &ports[pi];
1469ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1470ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1471ce8d5614SIntel 			continue;
1472ce8d5614SIntel 
1473ce8d5614SIntel 		rte_eth_dev_stop(pi);
1474ce8d5614SIntel 
1475ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1476ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1477ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1478ce8d5614SIntel 		need_check_link_status = 1;
1479ce8d5614SIntel 	}
1480bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1481edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1482ce8d5614SIntel 
1483ce8d5614SIntel 	printf("Done\n");
1484ce8d5614SIntel }
1485ce8d5614SIntel 
1486ce8d5614SIntel void
1487ce8d5614SIntel close_port(portid_t pid)
1488ce8d5614SIntel {
1489ce8d5614SIntel 	portid_t pi;
1490ce8d5614SIntel 	struct rte_port *port;
1491ce8d5614SIntel 
14924468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14934468635fSMichael Qiu 		return;
14944468635fSMichael Qiu 
1495ce8d5614SIntel 	printf("Closing ports...\n");
1496ce8d5614SIntel 
1497edab33b1STetsuya Mukawa 	FOREACH_PORT(pi, ports) {
14984468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1499ce8d5614SIntel 			continue;
1500ce8d5614SIntel 
1501a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1502a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1503a8ef3e3aSBernard Iremonger 			continue;
1504a8ef3e3aSBernard Iremonger 		}
1505a8ef3e3aSBernard Iremonger 
15060e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
15070e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
15080e545d30SBernard Iremonger 			continue;
15090e545d30SBernard Iremonger 		}
15100e545d30SBernard Iremonger 
1511ce8d5614SIntel 		port = &ports[pi];
1512ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1513d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1514d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1515d4e8ad64SMichael Qiu 			continue;
1516d4e8ad64SMichael Qiu 		}
1517d4e8ad64SMichael Qiu 
1518d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1519ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1520ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1521ce8d5614SIntel 			continue;
1522ce8d5614SIntel 		}
1523ce8d5614SIntel 
1524ce8d5614SIntel 		rte_eth_dev_close(pi);
1525ce8d5614SIntel 
1526ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1527ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1528b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1529ce8d5614SIntel 	}
1530ce8d5614SIntel 
1531ce8d5614SIntel 	printf("Done\n");
1532ce8d5614SIntel }
1533ce8d5614SIntel 
1534edab33b1STetsuya Mukawa void
1535edab33b1STetsuya Mukawa attach_port(char *identifier)
1536ce8d5614SIntel {
1537ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1538931126baSBernard Iremonger 	unsigned int socket_id;
1539ce8d5614SIntel 
1540edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1541edab33b1STetsuya Mukawa 
1542edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1543edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1544edab33b1STetsuya Mukawa 		return;
1545ce8d5614SIntel 	}
1546ce8d5614SIntel 
1547edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1548edab33b1STetsuya Mukawa 		return;
1549edab33b1STetsuya Mukawa 
1550edab33b1STetsuya Mukawa 	ports[pi].enabled = 1;
1551931126baSBernard Iremonger 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1552931126baSBernard Iremonger 	/* if socket_id is invalid, set to 0 */
1553931126baSBernard Iremonger 	if (check_socket_id(socket_id) < 0)
1554931126baSBernard Iremonger 		socket_id = 0;
1555931126baSBernard Iremonger 	reconfig(pi, socket_id);
1556edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1557edab33b1STetsuya Mukawa 
1558edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1559edab33b1STetsuya Mukawa 
1560edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1561edab33b1STetsuya Mukawa 
1562edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1563edab33b1STetsuya Mukawa 	printf("Done\n");
1564edab33b1STetsuya Mukawa }
1565edab33b1STetsuya Mukawa 
1566edab33b1STetsuya Mukawa void
1567edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
15685f4ec54fSChen Jing D(Mark) {
1569edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
15705f4ec54fSChen Jing D(Mark) 
1571edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
15725f4ec54fSChen Jing D(Mark) 
1573edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1574edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1575edab33b1STetsuya Mukawa 		return;
1576edab33b1STetsuya Mukawa 	}
1577edab33b1STetsuya Mukawa 
1578edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1579edab33b1STetsuya Mukawa 		return;
1580edab33b1STetsuya Mukawa 
1581edab33b1STetsuya Mukawa 	ports[port_id].enabled = 0;
1582edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1583edab33b1STetsuya Mukawa 
1584edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1585edab33b1STetsuya Mukawa 			name, nb_ports);
1586edab33b1STetsuya Mukawa 	printf("Done\n");
1587edab33b1STetsuya Mukawa 	return;
15885f4ec54fSChen Jing D(Mark) }
15895f4ec54fSChen Jing D(Mark) 
1590af75078fSIntel void
1591af75078fSIntel pmd_test_exit(void)
1592af75078fSIntel {
1593af75078fSIntel 	portid_t pt_id;
1594af75078fSIntel 
15958210ec25SPablo de Lara 	if (test_done == 0)
15968210ec25SPablo de Lara 		stop_packet_forwarding();
15978210ec25SPablo de Lara 
1598d3a274ceSZhihong Wang 	if (ports != NULL) {
1599d3a274ceSZhihong Wang 		no_link_check = 1;
1600edab33b1STetsuya Mukawa 		FOREACH_PORT(pt_id, ports) {
1601d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1602af75078fSIntel 			fflush(stdout);
1603d3a274ceSZhihong Wang 			stop_port(pt_id);
1604d3a274ceSZhihong Wang 			close_port(pt_id);
1605af75078fSIntel 		}
1606d3a274ceSZhihong Wang 	}
1607d3a274ceSZhihong Wang 	printf("\nBye...\n");
1608af75078fSIntel }
1609af75078fSIntel 
1610af75078fSIntel typedef void (*cmd_func_t)(void);
1611af75078fSIntel struct pmd_test_command {
1612af75078fSIntel 	const char *cmd_name;
1613af75078fSIntel 	cmd_func_t cmd_func;
1614af75078fSIntel };
1615af75078fSIntel 
1616af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1617af75078fSIntel 
1618ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1619af75078fSIntel static void
1620edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1621af75078fSIntel {
1622ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1623ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1624ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1625ce8d5614SIntel 	struct rte_eth_link link;
1626ce8d5614SIntel 
1627ce8d5614SIntel 	printf("Checking link statuses...\n");
1628ce8d5614SIntel 	fflush(stdout);
1629ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1630ce8d5614SIntel 		all_ports_up = 1;
1631edab33b1STetsuya Mukawa 		FOREACH_PORT(portid, ports) {
1632ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1633ce8d5614SIntel 				continue;
1634ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1635ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1636ce8d5614SIntel 			/* print link status if flag set */
1637ce8d5614SIntel 			if (print_flag == 1) {
1638ce8d5614SIntel 				if (link.link_status)
1639ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1640ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1641ce8d5614SIntel 						(unsigned)link.link_speed,
1642ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1643ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1644ce8d5614SIntel 				else
1645ce8d5614SIntel 					printf("Port %d Link Down\n",
1646ce8d5614SIntel 						(uint8_t)portid);
1647ce8d5614SIntel 				continue;
1648ce8d5614SIntel 			}
1649ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
165009419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1651ce8d5614SIntel 				all_ports_up = 0;
1652ce8d5614SIntel 				break;
1653ce8d5614SIntel 			}
1654ce8d5614SIntel 		}
1655ce8d5614SIntel 		/* after finally printing all link status, get out */
1656ce8d5614SIntel 		if (print_flag == 1)
1657ce8d5614SIntel 			break;
1658ce8d5614SIntel 
1659ce8d5614SIntel 		if (all_ports_up == 0) {
1660ce8d5614SIntel 			fflush(stdout);
1661ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1662ce8d5614SIntel 		}
1663ce8d5614SIntel 
1664ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1665ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1666ce8d5614SIntel 			print_flag = 1;
1667ce8d5614SIntel 		}
1668ce8d5614SIntel 	}
1669af75078fSIntel }
1670af75078fSIntel 
1671013af9b6SIntel static int
1672013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1673af75078fSIntel {
1674013af9b6SIntel 	uint16_t i;
1675af75078fSIntel 	int diag;
1676013af9b6SIntel 	uint8_t mapping_found = 0;
1677af75078fSIntel 
1678013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1679013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1680013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1681013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1682013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1683013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1684013af9b6SIntel 			if (diag != 0)
1685013af9b6SIntel 				return diag;
1686013af9b6SIntel 			mapping_found = 1;
1687af75078fSIntel 		}
1688013af9b6SIntel 	}
1689013af9b6SIntel 	if (mapping_found)
1690013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1691013af9b6SIntel 	return 0;
1692013af9b6SIntel }
1693013af9b6SIntel 
1694013af9b6SIntel static int
1695013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1696013af9b6SIntel {
1697013af9b6SIntel 	uint16_t i;
1698013af9b6SIntel 	int diag;
1699013af9b6SIntel 	uint8_t mapping_found = 0;
1700013af9b6SIntel 
1701013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1702013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1703013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1704013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1705013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1706013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1707013af9b6SIntel 			if (diag != 0)
1708013af9b6SIntel 				return diag;
1709013af9b6SIntel 			mapping_found = 1;
1710013af9b6SIntel 		}
1711013af9b6SIntel 	}
1712013af9b6SIntel 	if (mapping_found)
1713013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1714013af9b6SIntel 	return 0;
1715013af9b6SIntel }
1716013af9b6SIntel 
1717013af9b6SIntel static void
1718013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1719013af9b6SIntel {
1720013af9b6SIntel 	int diag = 0;
1721013af9b6SIntel 
1722013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1723af75078fSIntel 	if (diag != 0) {
1724013af9b6SIntel 		if (diag == -ENOTSUP) {
1725013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1726013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1727013af9b6SIntel 		}
1728013af9b6SIntel 		else
1729013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1730013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1731013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1732af75078fSIntel 					pi, diag);
1733af75078fSIntel 	}
1734013af9b6SIntel 
1735013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1736af75078fSIntel 	if (diag != 0) {
1737013af9b6SIntel 		if (diag == -ENOTSUP) {
1738013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1739013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1740013af9b6SIntel 		}
1741013af9b6SIntel 		else
1742013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1743013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1744013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1745af75078fSIntel 					pi, diag);
1746af75078fSIntel 	}
1747af75078fSIntel }
1748af75078fSIntel 
1749f2c5125aSPablo de Lara static void
1750f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1751f2c5125aSPablo de Lara {
1752f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1753f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1754f2c5125aSPablo de Lara 
1755f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1756f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1757f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1758f2c5125aSPablo de Lara 
1759f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1760f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1761f2c5125aSPablo de Lara 
1762f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1763f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1764f2c5125aSPablo de Lara 
1765f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1766f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1767f2c5125aSPablo de Lara 
1768f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1769f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1770f2c5125aSPablo de Lara 
1771f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1772f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1773f2c5125aSPablo de Lara 
1774f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1775f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1776f2c5125aSPablo de Lara 
1777f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1778f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1779f2c5125aSPablo de Lara 
1780f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1781f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1782f2c5125aSPablo de Lara 
1783f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1784f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1785f2c5125aSPablo de Lara 
1786f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1787f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1788f2c5125aSPablo de Lara }
1789f2c5125aSPablo de Lara 
1790013af9b6SIntel void
1791013af9b6SIntel init_port_config(void)
1792013af9b6SIntel {
1793013af9b6SIntel 	portid_t pid;
1794013af9b6SIntel 	struct rte_port *port;
1795013af9b6SIntel 
1796edab33b1STetsuya Mukawa 	FOREACH_PORT(pid, ports) {
1797013af9b6SIntel 		port = &ports[pid];
1798013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
1799013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
18003ce690d3SBruce Richardson 		if (nb_rxq > 1) {
1801013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1802013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1803af75078fSIntel 		} else {
1804013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1805013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1806af75078fSIntel 		}
18073ce690d3SBruce Richardson 
18083ce690d3SBruce Richardson 		if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
18093ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
18103ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
18113ce690d3SBruce Richardson 			else
18123ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
18133ce690d3SBruce Richardson 		}
18143ce690d3SBruce Richardson 
1815a30979f6SOuyang Changchun 		if (port->dev_info.max_vfs != 0) {
1816a30979f6SOuyang Changchun 			if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1817a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1818a30979f6SOuyang Changchun 					ETH_MQ_RX_VMDQ_RSS;
1819a30979f6SOuyang Changchun 			else
1820a30979f6SOuyang Changchun 				port->dev_conf.rxmode.mq_mode =
1821a30979f6SOuyang Changchun 					ETH_MQ_RX_NONE;
1822a30979f6SOuyang Changchun 
1823a30979f6SOuyang Changchun 			port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
1824a30979f6SOuyang Changchun 		}
1825a30979f6SOuyang Changchun 
1826f2c5125aSPablo de Lara 		rxtx_port_config(port);
1827013af9b6SIntel 
1828013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
1829013af9b6SIntel 
1830013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
18317b7e5ba7SIntel #ifdef RTE_NIC_BYPASS
18327b7e5ba7SIntel 		rte_eth_dev_bypass_init(pid);
18337b7e5ba7SIntel #endif
1834013af9b6SIntel 	}
1835013af9b6SIntel }
1836013af9b6SIntel 
183741b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
183841b05095SBernard Iremonger {
183941b05095SBernard Iremonger 	struct rte_port *port;
184041b05095SBernard Iremonger 
184141b05095SBernard Iremonger 	port = &ports[slave_pid];
184241b05095SBernard Iremonger 	port->slave_flag = 1;
184341b05095SBernard Iremonger }
184441b05095SBernard Iremonger 
184541b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
184641b05095SBernard Iremonger {
184741b05095SBernard Iremonger 	struct rte_port *port;
184841b05095SBernard Iremonger 
184941b05095SBernard Iremonger 	port = &ports[slave_pid];
185041b05095SBernard Iremonger 	port->slave_flag = 0;
185141b05095SBernard Iremonger }
185241b05095SBernard Iremonger 
18530e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
18540e545d30SBernard Iremonger {
18550e545d30SBernard Iremonger 	struct rte_port *port;
18560e545d30SBernard Iremonger 
18570e545d30SBernard Iremonger 	port = &ports[slave_pid];
18580e545d30SBernard Iremonger 	return port->slave_flag;
18590e545d30SBernard Iremonger }
18600e545d30SBernard Iremonger 
1861013af9b6SIntel const uint16_t vlan_tags[] = {
1862013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
1863013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
1864013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
1865013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
1866013af9b6SIntel };
1867013af9b6SIntel 
1868013af9b6SIntel static  int
18691a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
18701a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
18711a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
18721a572499SJingjing Wu 		 uint8_t pfc_en)
1873013af9b6SIntel {
1874013af9b6SIntel 	uint8_t i;
1875af75078fSIntel 
1876af75078fSIntel 	/*
1877013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
1878013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
1879af75078fSIntel 	 */
18801a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
18811a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
18821a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
18831a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
18841a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
1885013af9b6SIntel 
1886013af9b6SIntel 		/* VMDQ+DCB RX and TX configrations */
18871a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
18881a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
18891a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
18901a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
18911a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
18921a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1893013af9b6SIntel 
18941a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
18951a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
18961a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
18971a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
18981a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
1899af75078fSIntel 		}
1900013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
19011a572499SJingjing Wu 			vmdq_rx_conf->dcb_tc[i] = i;
19021a572499SJingjing Wu 			vmdq_tx_conf->dcb_tc[i] = i;
1903013af9b6SIntel 		}
1904013af9b6SIntel 
1905013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
190632e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
190732e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
19081a572499SJingjing Wu 	} else {
19091a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
19101a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
19111a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
19121a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
1913013af9b6SIntel 
19141a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
19151a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
19161a572499SJingjing Wu 
19171a572499SJingjing Wu 		for (i = 0; i < num_tcs; i++) {
19181a572499SJingjing Wu 			rx_conf->dcb_tc[i] = i;
19191a572499SJingjing Wu 			tx_conf->dcb_tc[i] = i;
1920013af9b6SIntel 		}
19211a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
19221a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
192332e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
19241a572499SJingjing Wu 	}
19251a572499SJingjing Wu 
19261a572499SJingjing Wu 	if (pfc_en)
19271a572499SJingjing Wu 		eth_conf->dcb_capability_en =
19281a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
1929013af9b6SIntel 	else
1930013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1931013af9b6SIntel 
1932013af9b6SIntel 	return 0;
1933013af9b6SIntel }
1934013af9b6SIntel 
1935013af9b6SIntel int
19361a572499SJingjing Wu init_port_dcb_config(portid_t pid,
19371a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
19381a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
19391a572499SJingjing Wu 		     uint8_t pfc_en)
1940013af9b6SIntel {
1941013af9b6SIntel 	struct rte_eth_conf port_conf;
19421a572499SJingjing Wu 	struct rte_eth_dev_info dev_info;
1943013af9b6SIntel 	struct rte_port *rte_port;
1944013af9b6SIntel 	int retval;
1945013af9b6SIntel 	uint16_t i;
1946013af9b6SIntel 
19471a572499SJingjing Wu 	rte_eth_dev_info_get(pid, &dev_info);
19481a572499SJingjing Wu 
19491a572499SJingjing Wu 	/* If dev_info.vmdq_pool_base is greater than 0,
19501a572499SJingjing Wu 	 * the queue id of vmdq pools is started after pf queues.
19511a572499SJingjing Wu 	 */
19521a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED && dev_info.vmdq_pool_base > 0) {
19531a572499SJingjing Wu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
19541a572499SJingjing Wu 			" for port %d.", pid);
19551a572499SJingjing Wu 		return -1;
19561a572499SJingjing Wu 	}
19571a572499SJingjing Wu 
19581a572499SJingjing Wu 	/* Assume the ports in testpmd have the same dcb capability
19591a572499SJingjing Wu 	 * and has the same number of rxq and txq in dcb mode
19601a572499SJingjing Wu 	 */
19611a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
19621a572499SJingjing Wu 		nb_rxq = dev_info.max_rx_queues;
19631a572499SJingjing Wu 		nb_txq = dev_info.max_tx_queues;
19641a572499SJingjing Wu 	} else {
19651a572499SJingjing Wu 		/*if vt is disabled, use all pf queues */
19661a572499SJingjing Wu 		if (dev_info.vmdq_pool_base == 0) {
19671a572499SJingjing Wu 			nb_rxq = dev_info.max_rx_queues;
19681a572499SJingjing Wu 			nb_txq = dev_info.max_tx_queues;
19691a572499SJingjing Wu 		} else {
19701a572499SJingjing Wu 			nb_rxq = (queueid_t)num_tcs;
19711a572499SJingjing Wu 			nb_txq = (queueid_t)num_tcs;
19721a572499SJingjing Wu 
19731a572499SJingjing Wu 		}
19741a572499SJingjing Wu 	}
1975013af9b6SIntel 	rx_free_thresh = 64;
1976013af9b6SIntel 
1977013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
1978013af9b6SIntel 	/* Enter DCB configuration status */
1979013af9b6SIntel 	dcb_config = 1;
1980013af9b6SIntel 
1981013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
19821a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
1983013af9b6SIntel 	if (retval < 0)
1984013af9b6SIntel 		return retval;
1985013af9b6SIntel 
1986013af9b6SIntel 	rte_port = &ports[pid];
1987013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
1988013af9b6SIntel 
1989f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
1990013af9b6SIntel 	/* VLAN filter */
1991013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
19921a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
1993013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
1994013af9b6SIntel 
1995013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
1996013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
1997013af9b6SIntel 
19987741e4cfSIntel 	rte_port->dcb_flag = 1;
19997741e4cfSIntel 
2000013af9b6SIntel 	return 0;
2001af75078fSIntel }
2002af75078fSIntel 
2003ffc468ffSTetsuya Mukawa static void
2004ffc468ffSTetsuya Mukawa init_port(void)
2005ffc468ffSTetsuya Mukawa {
2006ffc468ffSTetsuya Mukawa 	portid_t pid;
2007ffc468ffSTetsuya Mukawa 
2008ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2009ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2010ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2011ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2012ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2013ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2014ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2015ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2016ffc468ffSTetsuya Mukawa 	}
2017ffc468ffSTetsuya Mukawa 
2018ffc468ffSTetsuya Mukawa 	/* enabled allocated ports */
2019ffc468ffSTetsuya Mukawa 	for (pid = 0; pid < nb_ports; pid++)
2020ffc468ffSTetsuya Mukawa 		ports[pid].enabled = 1;
2021ffc468ffSTetsuya Mukawa }
2022ffc468ffSTetsuya Mukawa 
2023d3a274ceSZhihong Wang static void
2024d3a274ceSZhihong Wang force_quit(void)
2025d3a274ceSZhihong Wang {
2026d3a274ceSZhihong Wang 	pmd_test_exit();
2027d3a274ceSZhihong Wang 	prompt_exit();
2028d3a274ceSZhihong Wang }
2029d3a274ceSZhihong Wang 
2030d3a274ceSZhihong Wang static void
2031d3a274ceSZhihong Wang signal_handler(int signum)
2032d3a274ceSZhihong Wang {
2033d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2034d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2035d3a274ceSZhihong Wang 				signum);
2036d3a274ceSZhihong Wang 		force_quit();
2037d3a274ceSZhihong Wang 		/* exit with the expected status */
2038d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2039d3a274ceSZhihong Wang 		kill(getpid(), signum);
2040d3a274ceSZhihong Wang 	}
2041d3a274ceSZhihong Wang }
2042d3a274ceSZhihong Wang 
2043af75078fSIntel int
2044af75078fSIntel main(int argc, char** argv)
2045af75078fSIntel {
2046af75078fSIntel 	int  diag;
2047013af9b6SIntel 	uint8_t port_id;
2048af75078fSIntel 
2049d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2050d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2051d3a274ceSZhihong Wang 
2052af75078fSIntel 	diag = rte_eal_init(argc, argv);
2053af75078fSIntel 	if (diag < 0)
2054af75078fSIntel 		rte_panic("Cannot init EAL\n");
2055af75078fSIntel 
2056af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2057af75078fSIntel 	if (nb_ports == 0)
2058edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2059af75078fSIntel 
2060ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2061ffc468ffSTetsuya Mukawa 	init_port();
2062ffc468ffSTetsuya Mukawa 
2063af75078fSIntel 	set_def_fwd_config();
2064af75078fSIntel 	if (nb_lcores == 0)
2065af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2066af75078fSIntel 			  "core mask supplied in the command parameters\n");
2067af75078fSIntel 
2068af75078fSIntel 	argc -= diag;
2069af75078fSIntel 	argv += diag;
2070af75078fSIntel 	if (argc > 1)
2071af75078fSIntel 		launch_args_parse(argc, argv);
2072af75078fSIntel 
20735a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
20745a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
20755a8fb55cSReshma Pattan 
20765a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2077af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2078af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2079af75078fSIntel 		       nb_rxq, nb_txq);
2080af75078fSIntel 
2081af75078fSIntel 	init_config();
2082148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2083148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2084af75078fSIntel 
2085ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
2086edab33b1STetsuya Mukawa 	FOREACH_PORT(port_id, ports)
2087ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2088af75078fSIntel 
20890d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
2090ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2091ca7feb22SCyril Chemparathy 		if (auto_start) {
2092ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2093ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2094ca7feb22SCyril Chemparathy 		}
2095af75078fSIntel 		prompt();
2096ca7feb22SCyril Chemparathy 	} else
20970d56cb81SThomas Monjalon #endif
20980d56cb81SThomas Monjalon 	{
2099af75078fSIntel 		char c;
2100af75078fSIntel 		int rc;
2101af75078fSIntel 
2102af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
2103af75078fSIntel 		start_packet_forwarding(0);
2104af75078fSIntel 		printf("Press enter to exit\n");
2105af75078fSIntel 		rc = read(0, &c, 1);
2106d3a274ceSZhihong Wang 		pmd_test_exit();
2107af75078fSIntel 		if (rc < 0)
2108af75078fSIntel 			return 1;
2109af75078fSIntel 	}
2110af75078fSIntel 
2111af75078fSIntel 	return 0;
2112af75078fSIntel }
2113