xref: /dpdk/app/test-pmd/testpmd.c (revision 912267a33eede1427e865fc591e3ee2645cd596c)
1af75078fSIntel /*-
2af75078fSIntel  *   BSD LICENSE
3af75078fSIntel  *
47e4441c8SRemy Horton  *   Copyright(c) 2010-2017 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>
411c036b16SEelco Chaudron #include <sys/mman.h>
42af75078fSIntel #include <sys/types.h>
43af75078fSIntel #include <errno.h>
44af75078fSIntel 
45af75078fSIntel #include <sys/queue.h>
46af75078fSIntel #include <sys/stat.h>
47af75078fSIntel 
48af75078fSIntel #include <stdint.h>
49af75078fSIntel #include <unistd.h>
50af75078fSIntel #include <inttypes.h>
51af75078fSIntel 
52af75078fSIntel #include <rte_common.h>
53d1eb542eSOlivier Matz #include <rte_errno.h>
54af75078fSIntel #include <rte_byteorder.h>
55af75078fSIntel #include <rte_log.h>
56af75078fSIntel #include <rte_debug.h>
57af75078fSIntel #include <rte_cycles.h>
58af75078fSIntel #include <rte_memory.h>
59af75078fSIntel #include <rte_memcpy.h>
60af75078fSIntel #include <rte_memzone.h>
61af75078fSIntel #include <rte_launch.h>
62af75078fSIntel #include <rte_eal.h>
63284c908cSGaetan Rivet #include <rte_alarm.h>
64af75078fSIntel #include <rte_per_lcore.h>
65af75078fSIntel #include <rte_lcore.h>
66af75078fSIntel #include <rte_atomic.h>
67af75078fSIntel #include <rte_branch_prediction.h>
68af75078fSIntel #include <rte_mempool.h>
69af75078fSIntel #include <rte_malloc.h>
70af75078fSIntel #include <rte_mbuf.h>
71af75078fSIntel #include <rte_interrupts.h>
72af75078fSIntel #include <rte_pci.h>
73af75078fSIntel #include <rte_ether.h>
74af75078fSIntel #include <rte_ethdev.h>
75edab33b1STetsuya Mukawa #include <rte_dev.h>
76af75078fSIntel #include <rte_string_fns.h>
77e261265eSRadu Nicolau #ifdef RTE_LIBRTE_IXGBE_PMD
78e261265eSRadu Nicolau #include <rte_pmd_ixgbe.h>
79e261265eSRadu Nicolau #endif
80102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
81102b7329SReshma Pattan #include <rte_pdump.h>
82102b7329SReshma Pattan #endif
83938a184aSAdrien Mazarguil #include <rte_flow.h>
847e4441c8SRemy Horton #include <rte_metrics.h>
857e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
867e4441c8SRemy Horton #include <rte_bitrate.h>
877e4441c8SRemy Horton #endif
8862d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
8962d3216dSReshma Pattan #include <rte_latencystats.h>
9062d3216dSReshma Pattan #endif
91af75078fSIntel 
92af75078fSIntel #include "testpmd.h"
93af75078fSIntel 
94af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
95af75078fSIntel 
96af75078fSIntel /* use master core for command line ? */
97af75078fSIntel uint8_t interactive = 0;
98ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
9999cabef0SPablo de Lara uint8_t tx_first;
10081ef862bSAllain Legacy char cmdline_filename[PATH_MAX] = {0};
101af75078fSIntel 
102af75078fSIntel /*
103af75078fSIntel  * NUMA support configuration.
104af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
105af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
106af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
107af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
108af75078fSIntel  */
109999b2ee0SBruce Richardson uint8_t numa_support = 1; /**< numa enabled by default */
110af75078fSIntel 
111af75078fSIntel /*
112b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
113b6ea6408SIntel  * not configured.
114b6ea6408SIntel  */
115b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
116b6ea6408SIntel 
117b6ea6408SIntel /*
118148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
119148f963fSBruce Richardson  */
120148f963fSBruce Richardson uint8_t mp_anon = 0;
121148f963fSBruce Richardson 
122148f963fSBruce Richardson /*
123af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
124af75078fSIntel  * forwarded.
125547d946cSNirmoy Das  * Must be instantiated with the ethernet addresses of peer traffic generator
126af75078fSIntel  * ports.
127af75078fSIntel  */
128af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
129af75078fSIntel portid_t nb_peer_eth_addrs = 0;
130af75078fSIntel 
131af75078fSIntel /*
132af75078fSIntel  * Probed Target Environment.
133af75078fSIntel  */
134af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
135af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
136af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
137af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
138af75078fSIntel 
139af75078fSIntel /*
140af75078fSIntel  * Test Forwarding Configuration.
141af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
142af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
143af75078fSIntel  */
144af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
145af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
146af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
147af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
148af75078fSIntel 
149af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
150af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
151af75078fSIntel 
152af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
153af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
154af75078fSIntel 
155af75078fSIntel /*
156af75078fSIntel  * Forwarding engines.
157af75078fSIntel  */
158af75078fSIntel struct fwd_engine * fwd_engines[] = {
159af75078fSIntel 	&io_fwd_engine,
160af75078fSIntel 	&mac_fwd_engine,
161d47388f1SCyril Chemparathy 	&mac_swap_engine,
162e9e23a61SCyril Chemparathy 	&flow_gen_engine,
163af75078fSIntel 	&rx_only_engine,
164af75078fSIntel 	&tx_only_engine,
165af75078fSIntel 	&csum_fwd_engine,
166168dfa61SIvan Boule 	&icmp_echo_engine,
1675b590fbeSJasvinder Singh #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
1685b590fbeSJasvinder Singh 	&softnic_tm_engine,
1695b590fbeSJasvinder Singh 	&softnic_tm_bypass_engine,
1705b590fbeSJasvinder Singh #endif
171af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
172af75078fSIntel 	&ieee1588_fwd_engine,
173af75078fSIntel #endif
174af75078fSIntel 	NULL,
175af75078fSIntel };
176af75078fSIntel 
177af75078fSIntel struct fwd_config cur_fwd_config;
178af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
179bf56fce1SZhihong Wang uint32_t retry_enabled;
180bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
181bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
182af75078fSIntel 
183af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
184c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
185c8798818SIntel                                       * specified on command-line. */
186cfea1f30SPablo de Lara uint16_t stats_period; /**< Period to show statistics (disabled by default) */
187d9a191a0SPhil Yang 
188d9a191a0SPhil Yang /*
189d9a191a0SPhil Yang  * In container, it cannot terminate the process which running with 'stats-period'
190d9a191a0SPhil Yang  * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
191d9a191a0SPhil Yang  */
192d9a191a0SPhil Yang uint8_t f_quit;
193d9a191a0SPhil Yang 
194af75078fSIntel /*
195af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
196af75078fSIntel  */
197af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
198af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
199af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
200af75078fSIntel };
201af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
202af75078fSIntel 
20379bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
20479bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
20579bec05bSKonstantin Ananyev 
206af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
207e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
208af75078fSIntel 
209900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
210900550deSIntel uint8_t dcb_config = 0;
211900550deSIntel 
212900550deSIntel /* Whether the dcb is in testing status */
213900550deSIntel uint8_t dcb_test = 0;
214900550deSIntel 
215af75078fSIntel /*
216af75078fSIntel  * Configurable number of RX/TX queues.
217af75078fSIntel  */
218af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
219af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
220af75078fSIntel 
221af75078fSIntel /*
222af75078fSIntel  * Configurable number of RX/TX ring descriptors.
223af75078fSIntel  */
224af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
225af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
226af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
227af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
228af75078fSIntel 
229f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
230af75078fSIntel /*
231af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
232af75078fSIntel  */
233af75078fSIntel 
234f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
235f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
236f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
237af75078fSIntel 
238f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
239f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
240f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
241af75078fSIntel 
242af75078fSIntel /*
243af75078fSIntel  * Configurable value of RX free threshold.
244af75078fSIntel  */
245f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
246af75078fSIntel 
247af75078fSIntel /*
248ce8d5614SIntel  * Configurable value of RX drop enable.
249ce8d5614SIntel  */
250f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
251ce8d5614SIntel 
252ce8d5614SIntel /*
253af75078fSIntel  * Configurable value of TX free threshold.
254af75078fSIntel  */
255f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
256af75078fSIntel 
257af75078fSIntel /*
258af75078fSIntel  * Configurable value of TX RS bit threshold.
259af75078fSIntel  */
260f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
261af75078fSIntel 
262af75078fSIntel /*
263ce8d5614SIntel  * Configurable value of TX queue flags.
264ce8d5614SIntel  */
265f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
266ce8d5614SIntel 
267ce8d5614SIntel /*
268af75078fSIntel  * Receive Side Scaling (RSS) configuration.
269af75078fSIntel  */
2708a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
271af75078fSIntel 
272af75078fSIntel /*
273af75078fSIntel  * Port topology configuration
274af75078fSIntel  */
275af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
276af75078fSIntel 
2777741e4cfSIntel /*
2787741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2797741e4cfSIntel  */
2807741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2817741e4cfSIntel 
282af75078fSIntel /*
2837ee3e944SVasily Philipov  * Flow API isolated mode.
2847ee3e944SVasily Philipov  */
2857ee3e944SVasily Philipov uint8_t flow_isolate_all;
2867ee3e944SVasily Philipov 
2877ee3e944SVasily Philipov /*
288bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
289bc202406SDavid Marchand  */
290bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
291bc202406SDavid Marchand 
292bc202406SDavid Marchand /*
2938ea656f8SGaetan Rivet  * Enable link status change notification
2948ea656f8SGaetan Rivet  */
2958ea656f8SGaetan Rivet uint8_t lsc_interrupt = 1; /* enabled by default */
2968ea656f8SGaetan Rivet 
2978ea656f8SGaetan Rivet /*
298284c908cSGaetan Rivet  * Enable device removal notification.
299284c908cSGaetan Rivet  */
300284c908cSGaetan Rivet uint8_t rmv_interrupt = 1; /* enabled by default */
301284c908cSGaetan Rivet 
302284c908cSGaetan Rivet /*
3033af72783SGaetan Rivet  * Display or mask ether events
3043af72783SGaetan Rivet  * Default to all events except VF_MBOX
3053af72783SGaetan Rivet  */
3063af72783SGaetan Rivet uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
3073af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
3083af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
3093af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
3103af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
3113af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
3123af72783SGaetan Rivet 
3133af72783SGaetan Rivet /*
3147b7e5ba7SIntel  * NIC bypass mode configuration options.
3157b7e5ba7SIntel  */
3167b7e5ba7SIntel 
31750c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
3187b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
319e261265eSRadu Nicolau uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
3207b7e5ba7SIntel #endif
3217b7e5ba7SIntel 
322e261265eSRadu Nicolau 
32362d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
32462d3216dSReshma Pattan 
32562d3216dSReshma Pattan /*
32662d3216dSReshma Pattan  * Set when latency stats is enabled in the commandline
32762d3216dSReshma Pattan  */
32862d3216dSReshma Pattan uint8_t latencystats_enabled;
32962d3216dSReshma Pattan 
33062d3216dSReshma Pattan /*
33162d3216dSReshma Pattan  * Lcore ID to serive latency statistics.
33262d3216dSReshma Pattan  */
33362d3216dSReshma Pattan lcoreid_t latencystats_lcore_id = -1;
33462d3216dSReshma Pattan 
33562d3216dSReshma Pattan #endif
33662d3216dSReshma Pattan 
3377b7e5ba7SIntel /*
338af75078fSIntel  * Ethernet device configuration.
339af75078fSIntel  */
340af75078fSIntel struct rte_eth_rxmode rx_mode = {
341af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
342af75078fSIntel 	.split_hdr_size = 0,
343af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
344af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
345af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
346a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
347a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
348af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
34979dd163fSJeff Guo 	.hw_strip_crc   = 1, /**< CRC stripping by hardware enabled. */
350*912267a3SRaslan Darawsheh 	.hw_timestamp   = 0, /**< HW timestamp enabled. */
351af75078fSIntel };
352af75078fSIntel 
353af75078fSIntel struct rte_fdir_conf fdir_conf = {
354af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
355af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
356af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
357d9d5e6f2SJingjing Wu 	.mask = {
358d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
359d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
360d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
361d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
362d9d5e6f2SJingjing Wu 		},
363d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
364d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
365d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
366d9d5e6f2SJingjing Wu 		},
367d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
368d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
36947b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
37047b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
37147b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
372d9d5e6f2SJingjing Wu 	},
373af75078fSIntel 	.drop_queue = 127,
374af75078fSIntel };
375af75078fSIntel 
3762950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
377af75078fSIntel 
378ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
379ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
380ed30d9b6SIntel 
381ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
382ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
383ed30d9b6SIntel 
384ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
385ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
386ed30d9b6SIntel 
387c9cafcc8SShahaf Shuler unsigned int num_sockets = 0;
388c9cafcc8SShahaf Shuler unsigned int socket_ids[RTE_MAX_NUMA_NODES];
3897acf894dSStephen Hurd 
390e25e6c70SRemy Horton #ifdef RTE_LIBRTE_BITRATE
3917e4441c8SRemy Horton /* Bitrate statistics */
3927e4441c8SRemy Horton struct rte_stats_bitrates *bitrate_data;
393e25e6c70SRemy Horton lcoreid_t bitrate_lcore_id;
394e25e6c70SRemy Horton uint8_t bitrate_enabled;
395e25e6c70SRemy Horton #endif
3967e4441c8SRemy Horton 
397b40f8d78SJiayu Hu struct gro_status gro_ports[RTE_MAX_ETHPORTS];
398b7091f1dSJiayu Hu uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
399b40f8d78SJiayu Hu 
400ed30d9b6SIntel /* Forward function declarations */
401ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
402edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
403f8244c63SZhiyong Yang static int eth_event_callback(portid_t port_id,
40476ad4a2dSGaetan Rivet 			      enum rte_eth_event_type type,
405d6af1a13SBernard Iremonger 			      void *param, void *ret_param);
406ce8d5614SIntel 
407ce8d5614SIntel /*
408ce8d5614SIntel  * Check if all the ports are started.
409ce8d5614SIntel  * If yes, return positive value. If not, return zero.
410ce8d5614SIntel  */
411ce8d5614SIntel static int all_ports_started(void);
412ed30d9b6SIntel 
41352f38a20SJiayu Hu struct gso_status gso_ports[RTE_MAX_ETHPORTS];
41452f38a20SJiayu Hu uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
41552f38a20SJiayu Hu 
416af75078fSIntel /*
41798a7ea33SJerin Jacob  * Helper function to check if socket is already discovered.
418c9cafcc8SShahaf Shuler  * If yes, return positive value. If not, return zero.
419c9cafcc8SShahaf Shuler  */
420c9cafcc8SShahaf Shuler int
421c9cafcc8SShahaf Shuler new_socket_id(unsigned int socket_id)
422c9cafcc8SShahaf Shuler {
423c9cafcc8SShahaf Shuler 	unsigned int i;
424c9cafcc8SShahaf Shuler 
425c9cafcc8SShahaf Shuler 	for (i = 0; i < num_sockets; i++) {
426c9cafcc8SShahaf Shuler 		if (socket_ids[i] == socket_id)
427c9cafcc8SShahaf Shuler 			return 0;
428c9cafcc8SShahaf Shuler 	}
429c9cafcc8SShahaf Shuler 	return 1;
430c9cafcc8SShahaf Shuler }
431c9cafcc8SShahaf Shuler 
432c9cafcc8SShahaf Shuler /*
433af75078fSIntel  * Setup default configuration.
434af75078fSIntel  */
435af75078fSIntel static void
436af75078fSIntel set_default_fwd_lcores_config(void)
437af75078fSIntel {
438af75078fSIntel 	unsigned int i;
439af75078fSIntel 	unsigned int nb_lc;
4407acf894dSStephen Hurd 	unsigned int sock_num;
441af75078fSIntel 
442af75078fSIntel 	nb_lc = 0;
443af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
444c9cafcc8SShahaf Shuler 		sock_num = rte_lcore_to_socket_id(i);
445c9cafcc8SShahaf Shuler 		if (new_socket_id(sock_num)) {
446c9cafcc8SShahaf Shuler 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
447c9cafcc8SShahaf Shuler 				rte_exit(EXIT_FAILURE,
448c9cafcc8SShahaf Shuler 					 "Total sockets greater than %u\n",
449c9cafcc8SShahaf Shuler 					 RTE_MAX_NUMA_NODES);
450c9cafcc8SShahaf Shuler 			}
451c9cafcc8SShahaf Shuler 			socket_ids[num_sockets++] = sock_num;
4527acf894dSStephen Hurd 		}
453f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
454f54fe5eeSStephen Hurd 			continue;
455f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
456f54fe5eeSStephen Hurd 			continue;
457f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
458af75078fSIntel 	}
459af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
460af75078fSIntel 	nb_cfg_lcores = nb_lcores;
461af75078fSIntel 	nb_fwd_lcores = 1;
462af75078fSIntel }
463af75078fSIntel 
464af75078fSIntel static void
465af75078fSIntel set_def_peer_eth_addrs(void)
466af75078fSIntel {
467af75078fSIntel 	portid_t i;
468af75078fSIntel 
469af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
470af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
471af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
472af75078fSIntel 	}
473af75078fSIntel }
474af75078fSIntel 
475af75078fSIntel static void
476af75078fSIntel set_default_fwd_ports_config(void)
477af75078fSIntel {
478af75078fSIntel 	portid_t pt_id;
47965a7360cSMatan Azrad 	int i = 0;
480af75078fSIntel 
48165a7360cSMatan Azrad 	RTE_ETH_FOREACH_DEV(pt_id)
48265a7360cSMatan Azrad 		fwd_ports_ids[i++] = pt_id;
483af75078fSIntel 
484af75078fSIntel 	nb_cfg_ports = nb_ports;
485af75078fSIntel 	nb_fwd_ports = nb_ports;
486af75078fSIntel }
487af75078fSIntel 
488af75078fSIntel void
489af75078fSIntel set_def_fwd_config(void)
490af75078fSIntel {
491af75078fSIntel 	set_default_fwd_lcores_config();
492af75078fSIntel 	set_def_peer_eth_addrs();
493af75078fSIntel 	set_default_fwd_ports_config();
494af75078fSIntel }
495af75078fSIntel 
496af75078fSIntel /*
497af75078fSIntel  * Configuration initialisation done once at init time.
498af75078fSIntel  */
499af75078fSIntel static void
500af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
501af75078fSIntel 		 unsigned int socket_id)
502af75078fSIntel {
503af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
504bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
505af75078fSIntel 	uint32_t mb_size;
506af75078fSIntel 
507dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
508af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
509148f963fSBruce Richardson 
510d1eb542eSOlivier Matz 	RTE_LOG(INFO, USER1,
511d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
512d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
513d1eb542eSOlivier Matz 
514b19a0c75SOlivier Matz 	if (mp_anon != 0) {
515b19a0c75SOlivier Matz 		rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
516bece7b6cSChristian Ehrhardt 			mb_size, (unsigned) mb_mempool_cache,
517148f963fSBruce Richardson 			sizeof(struct rte_pktmbuf_pool_private),
518148f963fSBruce Richardson 			socket_id, 0);
51924427bb9SOlivier Matz 		if (rte_mp == NULL)
52024427bb9SOlivier Matz 			goto err;
521b19a0c75SOlivier Matz 
522b19a0c75SOlivier Matz 		if (rte_mempool_populate_anon(rte_mp) == 0) {
523b19a0c75SOlivier Matz 			rte_mempool_free(rte_mp);
524b19a0c75SOlivier Matz 			rte_mp = NULL;
52524427bb9SOlivier Matz 			goto err;
526b19a0c75SOlivier Matz 		}
527b19a0c75SOlivier Matz 		rte_pktmbuf_pool_init(rte_mp, NULL);
528b19a0c75SOlivier Matz 		rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
529b19a0c75SOlivier Matz 	} else {
530ea0c20eaSOlivier Matz 		/* wrapper to rte_mempool_create() */
531ea0c20eaSOlivier Matz 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
532ea0c20eaSOlivier Matz 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
533bece7b6cSChristian Ehrhardt 	}
534148f963fSBruce Richardson 
53524427bb9SOlivier Matz err:
536af75078fSIntel 	if (rte_mp == NULL) {
537d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
538d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
539d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
540148f963fSBruce Richardson 	} else if (verbose_level > 0) {
541591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
542af75078fSIntel 	}
543af75078fSIntel }
544af75078fSIntel 
54520a0286fSLiu Xiaofeng /*
54620a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
54720a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
54820a0286fSLiu Xiaofeng  */
54920a0286fSLiu Xiaofeng static int
55020a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
55120a0286fSLiu Xiaofeng {
55220a0286fSLiu Xiaofeng 	static int warning_once = 0;
55320a0286fSLiu Xiaofeng 
554c9cafcc8SShahaf Shuler 	if (new_socket_id(socket_id)) {
55520a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
55620a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
55720a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
55820a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
55920a0286fSLiu Xiaofeng 			       " --numa.\n");
56020a0286fSLiu Xiaofeng 		warning_once = 1;
56120a0286fSLiu Xiaofeng 		return -1;
56220a0286fSLiu Xiaofeng 	}
56320a0286fSLiu Xiaofeng 	return 0;
56420a0286fSLiu Xiaofeng }
56520a0286fSLiu Xiaofeng 
566af75078fSIntel static void
567af75078fSIntel init_config(void)
568af75078fSIntel {
569ce8d5614SIntel 	portid_t pid;
570af75078fSIntel 	struct rte_port *port;
571af75078fSIntel 	struct rte_mempool *mbp;
572af75078fSIntel 	unsigned int nb_mbuf_per_pool;
573af75078fSIntel 	lcoreid_t  lc_id;
5747acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
575b7091f1dSJiayu Hu 	struct rte_gro_param gro_param;
57652f38a20SJiayu Hu 	uint32_t gso_types;
577af75078fSIntel 
5787acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
579487f9a59SYulong Pei 
580487f9a59SYulong Pei 	if (numa_support) {
581487f9a59SYulong Pei 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
582487f9a59SYulong Pei 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
583487f9a59SYulong Pei 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
584487f9a59SYulong Pei 	}
585487f9a59SYulong Pei 
586af75078fSIntel 	/* Configuration of logical cores. */
587af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
588af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
589fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
590af75078fSIntel 	if (fwd_lcores == NULL) {
591ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
592ce8d5614SIntel 							"failed\n", nb_lcores);
593af75078fSIntel 	}
594af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
595af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
596af75078fSIntel 					       sizeof(struct fwd_lcore),
597fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
598af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
599ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
600ce8d5614SIntel 								"failed\n");
601af75078fSIntel 		}
602af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
603af75078fSIntel 	}
604af75078fSIntel 
6057d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
606ce8d5614SIntel 		port = &ports[pid];
607ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
608ce8d5614SIntel 
609b6ea6408SIntel 		if (numa_support) {
610b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
611b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
612b6ea6408SIntel 			else {
613b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
61420a0286fSLiu Xiaofeng 
61520a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
61620a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
61720a0286fSLiu Xiaofeng 					socket_id = 0;
618b6ea6408SIntel 				port_per_socket[socket_id]++;
619b6ea6408SIntel 			}
620b6ea6408SIntel 		}
621b6ea6408SIntel 
622ce8d5614SIntel 		/* set flag to initialize port/queue */
623ce8d5614SIntel 		port->need_reconfig = 1;
624ce8d5614SIntel 		port->need_reconfig_queues = 1;
625ce8d5614SIntel 	}
626ce8d5614SIntel 
6273ab64341SOlivier Matz 	/*
6283ab64341SOlivier Matz 	 * Create pools of mbuf.
6293ab64341SOlivier Matz 	 * If NUMA support is disabled, create a single pool of mbuf in
6303ab64341SOlivier Matz 	 * socket 0 memory by default.
6313ab64341SOlivier Matz 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
6323ab64341SOlivier Matz 	 *
6333ab64341SOlivier Matz 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
6343ab64341SOlivier Matz 	 * nb_txd can be configured at run time.
6353ab64341SOlivier Matz 	 */
6363ab64341SOlivier Matz 	if (param_total_num_mbufs)
6373ab64341SOlivier Matz 		nb_mbuf_per_pool = param_total_num_mbufs;
6383ab64341SOlivier Matz 	else {
6393ab64341SOlivier Matz 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
6403ab64341SOlivier Matz 			(nb_lcores * mb_mempool_cache) +
6413ab64341SOlivier Matz 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
6423ab64341SOlivier Matz 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
6433ab64341SOlivier Matz 	}
6443ab64341SOlivier Matz 
645b6ea6408SIntel 	if (numa_support) {
646b6ea6408SIntel 		uint8_t i;
647ce8d5614SIntel 
648c9cafcc8SShahaf Shuler 		for (i = 0; i < num_sockets; i++)
649c9cafcc8SShahaf Shuler 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
650c9cafcc8SShahaf Shuler 					 socket_ids[i]);
6513ab64341SOlivier Matz 	} else {
6523ab64341SOlivier Matz 		if (socket_num == UMA_NO_CONFIG)
6533ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
6543ab64341SOlivier Matz 		else
6553ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
6563ab64341SOlivier Matz 						 socket_num);
6573ab64341SOlivier Matz 	}
658b6ea6408SIntel 
659b6ea6408SIntel 	init_port_config();
6605886ae07SAdrien Mazarguil 
66152f38a20SJiayu Hu 	gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
66252f38a20SJiayu Hu 		DEV_TX_OFFLOAD_GRE_TNL_TSO;
6635886ae07SAdrien Mazarguil 	/*
6645886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6655886ae07SAdrien Mazarguil 	 */
6665886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6678fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
6688fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
6698fd8bebcSAdrien Mazarguil 
6705886ae07SAdrien Mazarguil 		if (mbp == NULL)
6715886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6725886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
67352f38a20SJiayu Hu 		/* initialize GSO context */
67452f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
67552f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
67652f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
67752f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
67852f38a20SJiayu Hu 			ETHER_CRC_LEN;
67952f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.flag = 0;
6805886ae07SAdrien Mazarguil 	}
6815886ae07SAdrien Mazarguil 
682ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
683ce8d5614SIntel 	if (init_fwd_streams() < 0)
684ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
6850c0db76fSBernard Iremonger 
6860c0db76fSBernard Iremonger 	fwd_config_setup();
687b7091f1dSJiayu Hu 
688b7091f1dSJiayu Hu 	/* create a gro context for each lcore */
689b7091f1dSJiayu Hu 	gro_param.gro_types = RTE_GRO_TCP_IPV4;
690b7091f1dSJiayu Hu 	gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
691b7091f1dSJiayu Hu 	gro_param.max_item_per_flow = MAX_PKT_BURST;
692b7091f1dSJiayu Hu 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
693b7091f1dSJiayu Hu 		gro_param.socket_id = rte_lcore_to_socket_id(
694b7091f1dSJiayu Hu 				fwd_lcores_cpuids[lc_id]);
695b7091f1dSJiayu Hu 		fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
696b7091f1dSJiayu Hu 		if (fwd_lcores[lc_id]->gro_ctx == NULL) {
697b7091f1dSJiayu Hu 			rte_exit(EXIT_FAILURE,
698b7091f1dSJiayu Hu 					"rte_gro_ctx_create() failed\n");
699b7091f1dSJiayu Hu 		}
700b7091f1dSJiayu Hu 	}
701ce8d5614SIntel }
702ce8d5614SIntel 
7032950a769SDeclan Doherty 
7042950a769SDeclan Doherty void
705a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
7062950a769SDeclan Doherty {
7072950a769SDeclan Doherty 	struct rte_port *port;
7082950a769SDeclan Doherty 
7092950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
7102950a769SDeclan Doherty 	port = &ports[new_port_id];
7112950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
7122950a769SDeclan Doherty 
7132950a769SDeclan Doherty 	/* set flag to initialize port/queue */
7142950a769SDeclan Doherty 	port->need_reconfig = 1;
7152950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
716a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
7172950a769SDeclan Doherty 
7182950a769SDeclan Doherty 	init_port_config();
7192950a769SDeclan Doherty }
7202950a769SDeclan Doherty 
7212950a769SDeclan Doherty 
722ce8d5614SIntel int
723ce8d5614SIntel init_fwd_streams(void)
724ce8d5614SIntel {
725ce8d5614SIntel 	portid_t pid;
726ce8d5614SIntel 	struct rte_port *port;
727ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
7285a8fb55cSReshma Pattan 	queueid_t q;
729ce8d5614SIntel 
730ce8d5614SIntel 	/* set socket id according to numa or not */
7317d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
732ce8d5614SIntel 		port = &ports[pid];
733ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
734ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
735ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
736ce8d5614SIntel 				port->dev_info.max_rx_queues);
737ce8d5614SIntel 			return -1;
738ce8d5614SIntel 		}
739ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
740ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
741ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
742ce8d5614SIntel 				port->dev_info.max_tx_queues);
743ce8d5614SIntel 			return -1;
744ce8d5614SIntel 		}
74520a0286fSLiu Xiaofeng 		if (numa_support) {
74620a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
74720a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
74820a0286fSLiu Xiaofeng 			else {
749b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
75020a0286fSLiu Xiaofeng 
75120a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
75220a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
75320a0286fSLiu Xiaofeng 					port->socket_id = 0;
75420a0286fSLiu Xiaofeng 			}
75520a0286fSLiu Xiaofeng 		}
756b6ea6408SIntel 		else {
757b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
758af75078fSIntel 				port->socket_id = 0;
759b6ea6408SIntel 			else
760b6ea6408SIntel 				port->socket_id = socket_num;
761b6ea6408SIntel 		}
762af75078fSIntel 	}
763af75078fSIntel 
7645a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
7655a8fb55cSReshma Pattan 	if (q == 0) {
7665a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
7675a8fb55cSReshma Pattan 		return -1;
7685a8fb55cSReshma Pattan 	}
7695a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
770ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
771ce8d5614SIntel 		return 0;
772ce8d5614SIntel 	/* clear the old */
773ce8d5614SIntel 	if (fwd_streams != NULL) {
774ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
775ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
776ce8d5614SIntel 				continue;
777ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
778ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
779af75078fSIntel 		}
780ce8d5614SIntel 		rte_free(fwd_streams);
781ce8d5614SIntel 		fwd_streams = NULL;
782ce8d5614SIntel 	}
783ce8d5614SIntel 
784ce8d5614SIntel 	/* init new */
785ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
786ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
787fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
788ce8d5614SIntel 	if (fwd_streams == NULL)
789ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
790ce8d5614SIntel 						"failed\n", nb_fwd_streams);
791ce8d5614SIntel 
792af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
793af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
794fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
795ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
796ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
797ce8d5614SIntel 								" failed\n");
798af75078fSIntel 	}
799ce8d5614SIntel 
800ce8d5614SIntel 	return 0;
801af75078fSIntel }
802af75078fSIntel 
803af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
804af75078fSIntel static void
805af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
806af75078fSIntel {
807af75078fSIntel 	unsigned int total_burst;
808af75078fSIntel 	unsigned int nb_burst;
809af75078fSIntel 	unsigned int burst_stats[3];
810af75078fSIntel 	uint16_t pktnb_stats[3];
811af75078fSIntel 	uint16_t nb_pkt;
812af75078fSIntel 	int burst_percent[3];
813af75078fSIntel 
814af75078fSIntel 	/*
815af75078fSIntel 	 * First compute the total number of packet bursts and the
816af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
817af75078fSIntel 	 */
818af75078fSIntel 	total_burst = 0;
819af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
820af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
821af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
822af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
823af75078fSIntel 		if (nb_burst == 0)
824af75078fSIntel 			continue;
825af75078fSIntel 		total_burst += nb_burst;
826af75078fSIntel 		if (nb_burst > burst_stats[0]) {
827af75078fSIntel 			burst_stats[1] = burst_stats[0];
828af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
829af75078fSIntel 			burst_stats[0] = nb_burst;
830af75078fSIntel 			pktnb_stats[0] = nb_pkt;
831af75078fSIntel 		}
832af75078fSIntel 	}
833af75078fSIntel 	if (total_burst == 0)
834af75078fSIntel 		return;
835af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
836af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
837af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
838af75078fSIntel 	if (burst_stats[0] == total_burst) {
839af75078fSIntel 		printf("]\n");
840af75078fSIntel 		return;
841af75078fSIntel 	}
842af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
843af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
844af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
845af75078fSIntel 		return;
846af75078fSIntel 	}
847af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
848af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
849af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
850af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
851af75078fSIntel 		return;
852af75078fSIntel 	}
853af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
854af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
855af75078fSIntel }
856af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
857af75078fSIntel 
858af75078fSIntel static void
859af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
860af75078fSIntel {
861af75078fSIntel 	struct rte_port *port;
862013af9b6SIntel 	uint8_t i;
863af75078fSIntel 
864af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
865af75078fSIntel 
866af75078fSIntel 	port = &ports[port_id];
867af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
868af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
869013af9b6SIntel 
870013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
871af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
872af75078fSIntel 		       "%-"PRIu64"\n",
87370bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
87470bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
875af75078fSIntel 
876af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
877af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
878af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
87986057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
880f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
88170bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
88270bdb186SIvan Boule 		}
883af75078fSIntel 
884af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
885af75078fSIntel 		       "%-"PRIu64"\n",
886af75078fSIntel 		       stats->opackets, port->tx_dropped,
887af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
888013af9b6SIntel 	}
889013af9b6SIntel 	else {
890013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
891013af9b6SIntel 		       "%14"PRIu64"\n",
89270bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
89370bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
894013af9b6SIntel 
895013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
896013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
897013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
89886057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
899f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
90070bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
90170bdb186SIvan Boule 			       stats->rx_nombuf);
90270bdb186SIvan Boule 		}
903013af9b6SIntel 
904013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
905013af9b6SIntel 		       "%14"PRIu64"\n",
906013af9b6SIntel 		       stats->opackets, port->tx_dropped,
907013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
908013af9b6SIntel 	}
909e659b6b4SIvan Boule 
910af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
911af75078fSIntel 	if (port->rx_stream)
912013af9b6SIntel 		pkt_burst_stats_display("RX",
913013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
914af75078fSIntel 	if (port->tx_stream)
915013af9b6SIntel 		pkt_burst_stats_display("TX",
916013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
917af75078fSIntel #endif
918af75078fSIntel 
919013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
920013af9b6SIntel 		printf("\n");
921013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
922013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
923013af9b6SIntel 			       "     RX-errors:%14"PRIu64
924013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
925013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
926013af9b6SIntel 		}
927013af9b6SIntel 		printf("\n");
928013af9b6SIntel 	}
929013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
930013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
931013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
932013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
933013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
934013af9b6SIntel 		}
935013af9b6SIntel 	}
936013af9b6SIntel 
937af75078fSIntel 	printf("  %s--------------------------------%s\n",
938af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
939af75078fSIntel }
940af75078fSIntel 
941af75078fSIntel static void
942af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
943af75078fSIntel {
944af75078fSIntel 	struct fwd_stream *fs;
945af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
946af75078fSIntel 
947af75078fSIntel 	fs = fwd_streams[stream_id];
948af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
949af75078fSIntel 	    (fs->fwd_dropped == 0))
950af75078fSIntel 		return;
951af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
952af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
953af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
954af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
955af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
956af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
957af75078fSIntel 
958af75078fSIntel 	/* if checksum mode */
959af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
960013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
961013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
962af75078fSIntel 	}
963af75078fSIntel 
964af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
965af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
966af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
967af75078fSIntel #endif
968af75078fSIntel }
969af75078fSIntel 
970af75078fSIntel static void
9717741e4cfSIntel flush_fwd_rx_queues(void)
972af75078fSIntel {
973af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
974af75078fSIntel 	portid_t  rxp;
9757741e4cfSIntel 	portid_t port_id;
976af75078fSIntel 	queueid_t rxq;
977af75078fSIntel 	uint16_t  nb_rx;
978af75078fSIntel 	uint16_t  i;
979af75078fSIntel 	uint8_t   j;
980f487715fSReshma Pattan 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
981594302c7SJames Poole 	uint64_t timer_period;
982f487715fSReshma Pattan 
983f487715fSReshma Pattan 	/* convert to number of cycles */
984594302c7SJames Poole 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
985af75078fSIntel 
986af75078fSIntel 	for (j = 0; j < 2; j++) {
9877741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
988af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
9897741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
990f487715fSReshma Pattan 				/**
991f487715fSReshma Pattan 				* testpmd can stuck in the below do while loop
992f487715fSReshma Pattan 				* if rte_eth_rx_burst() always returns nonzero
993f487715fSReshma Pattan 				* packets. So timer is added to exit this loop
994f487715fSReshma Pattan 				* after 1sec timer expiry.
995f487715fSReshma Pattan 				*/
996f487715fSReshma Pattan 				prev_tsc = rte_rdtsc();
997af75078fSIntel 				do {
9987741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
999013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
1000af75078fSIntel 					for (i = 0; i < nb_rx; i++)
1001af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
1002f487715fSReshma Pattan 
1003f487715fSReshma Pattan 					cur_tsc = rte_rdtsc();
1004f487715fSReshma Pattan 					diff_tsc = cur_tsc - prev_tsc;
1005f487715fSReshma Pattan 					timer_tsc += diff_tsc;
1006f487715fSReshma Pattan 				} while ((nb_rx > 0) &&
1007f487715fSReshma Pattan 					(timer_tsc < timer_period));
1008f487715fSReshma Pattan 				timer_tsc = 0;
1009af75078fSIntel 			}
1010af75078fSIntel 		}
1011af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1012af75078fSIntel 	}
1013af75078fSIntel }
1014af75078fSIntel 
1015af75078fSIntel static void
1016af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1017af75078fSIntel {
1018af75078fSIntel 	struct fwd_stream **fsm;
1019af75078fSIntel 	streamid_t nb_fs;
1020af75078fSIntel 	streamid_t sm_id;
10217e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
10227e4441c8SRemy Horton 	uint64_t tics_per_1sec;
10237e4441c8SRemy Horton 	uint64_t tics_datum;
10247e4441c8SRemy Horton 	uint64_t tics_current;
10257e4441c8SRemy Horton 	uint8_t idx_port, cnt_ports;
1026af75078fSIntel 
10277e4441c8SRemy Horton 	cnt_ports = rte_eth_dev_count();
10287e4441c8SRemy Horton 	tics_datum = rte_rdtsc();
10297e4441c8SRemy Horton 	tics_per_1sec = rte_get_timer_hz();
10307e4441c8SRemy Horton #endif
1031af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
1032af75078fSIntel 	nb_fs = fc->stream_nb;
1033af75078fSIntel 	do {
1034af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1035af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
10367e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
1037e25e6c70SRemy Horton 		if (bitrate_enabled != 0 &&
1038e25e6c70SRemy Horton 				bitrate_lcore_id == rte_lcore_id()) {
10397e4441c8SRemy Horton 			tics_current = rte_rdtsc();
10407e4441c8SRemy Horton 			if (tics_current - tics_datum >= tics_per_1sec) {
10417e4441c8SRemy Horton 				/* Periodic bitrate calculation */
1042e25e6c70SRemy Horton 				for (idx_port = 0;
1043e25e6c70SRemy Horton 						idx_port < cnt_ports;
1044e25e6c70SRemy Horton 						idx_port++)
1045e25e6c70SRemy Horton 					rte_stats_bitrate_calc(bitrate_data,
1046e25e6c70SRemy Horton 						idx_port);
10477e4441c8SRemy Horton 				tics_datum = tics_current;
10487e4441c8SRemy Horton 			}
1049e25e6c70SRemy Horton 		}
10507e4441c8SRemy Horton #endif
105162d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
105265eb1e54SPablo de Lara 		if (latencystats_enabled != 0 &&
105365eb1e54SPablo de Lara 				latencystats_lcore_id == rte_lcore_id())
105462d3216dSReshma Pattan 			rte_latencystats_update();
105562d3216dSReshma Pattan #endif
105662d3216dSReshma Pattan 
1057af75078fSIntel 	} while (! fc->stopped);
1058af75078fSIntel }
1059af75078fSIntel 
1060af75078fSIntel static int
1061af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
1062af75078fSIntel {
1063af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1064af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
1065af75078fSIntel 	return 0;
1066af75078fSIntel }
1067af75078fSIntel 
1068af75078fSIntel /*
1069af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1070af75078fSIntel  * Used to start communication flows in network loopback test configurations.
1071af75078fSIntel  */
1072af75078fSIntel static int
1073af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
1074af75078fSIntel {
1075af75078fSIntel 	struct fwd_lcore *fwd_lc;
1076af75078fSIntel 	struct fwd_lcore tmp_lcore;
1077af75078fSIntel 
1078af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1079af75078fSIntel 	tmp_lcore = *fwd_lc;
1080af75078fSIntel 	tmp_lcore.stopped = 1;
1081af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1082af75078fSIntel 	return 0;
1083af75078fSIntel }
1084af75078fSIntel 
1085af75078fSIntel /*
1086af75078fSIntel  * Launch packet forwarding:
1087af75078fSIntel  *     - Setup per-port forwarding context.
1088af75078fSIntel  *     - launch logical cores with their forwarding configuration.
1089af75078fSIntel  */
1090af75078fSIntel static void
1091af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1092af75078fSIntel {
1093af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1094af75078fSIntel 	unsigned int i;
1095af75078fSIntel 	unsigned int lc_id;
1096af75078fSIntel 	int diag;
1097af75078fSIntel 
1098af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1099af75078fSIntel 	if (port_fwd_begin != NULL) {
1100af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1101af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
1102af75078fSIntel 	}
1103af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1104af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
1105af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1106af75078fSIntel 			fwd_lcores[i]->stopped = 0;
1107af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1108af75078fSIntel 						     fwd_lcores[i], lc_id);
1109af75078fSIntel 			if (diag != 0)
1110af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
1111af75078fSIntel 				       lc_id, diag);
1112af75078fSIntel 		}
1113af75078fSIntel 	}
1114af75078fSIntel }
1115af75078fSIntel 
1116af75078fSIntel /*
1117af75078fSIntel  * Launch packet forwarding configuration.
1118af75078fSIntel  */
1119af75078fSIntel void
1120af75078fSIntel start_packet_forwarding(int with_tx_first)
1121af75078fSIntel {
1122af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1123af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1124af75078fSIntel 	struct rte_port *port;
1125af75078fSIntel 	unsigned int i;
1126af75078fSIntel 	portid_t   pt_id;
1127af75078fSIntel 	streamid_t sm_id;
1128af75078fSIntel 
11295a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
11305a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
11315a8fb55cSReshma Pattan 
11325a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
11335a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
11345a8fb55cSReshma Pattan 
11355a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
11365a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
11375a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
11385a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
11395a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
11405a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
11415a8fb55cSReshma Pattan 
1142ce8d5614SIntel 	if (all_ports_started() == 0) {
1143ce8d5614SIntel 		printf("Not all ports were started\n");
1144ce8d5614SIntel 		return;
1145ce8d5614SIntel 	}
1146af75078fSIntel 	if (test_done == 0) {
1147af75078fSIntel 		printf("Packet forwarding already started\n");
1148af75078fSIntel 		return;
1149af75078fSIntel 	}
1150edf87b4aSBernard Iremonger 
1151edf87b4aSBernard Iremonger 	if (init_fwd_streams() < 0) {
1152edf87b4aSBernard Iremonger 		printf("Fail from init_fwd_streams()\n");
1153edf87b4aSBernard Iremonger 		return;
1154edf87b4aSBernard Iremonger 	}
1155edf87b4aSBernard Iremonger 
11567741e4cfSIntel 	if(dcb_test) {
11577741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
11587741e4cfSIntel 			pt_id = fwd_ports_ids[i];
11597741e4cfSIntel 			port = &ports[pt_id];
11607741e4cfSIntel 			if (!port->dcb_flag) {
11617741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
11627741e4cfSIntel                                        "be configured in this mode.\n");
1163013af9b6SIntel 				return;
1164013af9b6SIntel 			}
11657741e4cfSIntel 		}
11667741e4cfSIntel 		if (nb_fwd_lcores == 1) {
11677741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
11687741e4cfSIntel                                "should be larger than 1.\n");
11697741e4cfSIntel 			return;
11707741e4cfSIntel 		}
11717741e4cfSIntel 	}
1172af75078fSIntel 	test_done = 0;
11737741e4cfSIntel 
11747741e4cfSIntel 	if(!no_flush_rx)
11757741e4cfSIntel 		flush_fwd_rx_queues();
11767741e4cfSIntel 
1177af75078fSIntel 	fwd_config_setup();
1178933617d8SZhihong Wang 	pkt_fwd_config_display(&cur_fwd_config);
1179af75078fSIntel 	rxtx_config_display();
1180af75078fSIntel 
1181af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1182af75078fSIntel 		pt_id = fwd_ports_ids[i];
1183af75078fSIntel 		port = &ports[pt_id];
1184af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1185af75078fSIntel 		port->tx_dropped = 0;
1186013af9b6SIntel 
1187013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1188af75078fSIntel 	}
1189af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1190af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1191af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1192af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1193af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1194af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1195af75078fSIntel 
1196af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1197af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1198af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1199af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1200af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1201af75078fSIntel #endif
1202af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1203af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1204af75078fSIntel #endif
1205af75078fSIntel 	}
1206af75078fSIntel 	if (with_tx_first) {
1207af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1208af75078fSIntel 		if (port_fwd_begin != NULL) {
1209af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1210af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1211af75078fSIntel 		}
1212acbf77a6SZhihong Wang 		while (with_tx_first--) {
1213acbf77a6SZhihong Wang 			launch_packet_forwarding(
1214acbf77a6SZhihong Wang 					run_one_txonly_burst_on_core);
1215af75078fSIntel 			rte_eal_mp_wait_lcore();
1216acbf77a6SZhihong Wang 		}
1217af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1218af75078fSIntel 		if (port_fwd_end != NULL) {
1219af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1220af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1221af75078fSIntel 		}
1222af75078fSIntel 	}
1223af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1224af75078fSIntel }
1225af75078fSIntel 
1226af75078fSIntel void
1227af75078fSIntel stop_packet_forwarding(void)
1228af75078fSIntel {
1229af75078fSIntel 	struct rte_eth_stats stats;
1230af75078fSIntel 	struct rte_port *port;
1231af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1232af75078fSIntel 	int i;
1233af75078fSIntel 	portid_t   pt_id;
1234af75078fSIntel 	streamid_t sm_id;
1235af75078fSIntel 	lcoreid_t  lc_id;
1236af75078fSIntel 	uint64_t total_recv;
1237af75078fSIntel 	uint64_t total_xmit;
1238af75078fSIntel 	uint64_t total_rx_dropped;
1239af75078fSIntel 	uint64_t total_tx_dropped;
1240af75078fSIntel 	uint64_t total_rx_nombuf;
1241af75078fSIntel 	uint64_t tx_dropped;
1242af75078fSIntel 	uint64_t rx_bad_ip_csum;
1243af75078fSIntel 	uint64_t rx_bad_l4_csum;
1244af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1245af75078fSIntel 	uint64_t fwd_cycles;
1246af75078fSIntel #endif
1247b7091f1dSJiayu Hu 
1248af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1249af75078fSIntel 
1250af75078fSIntel 	if (test_done) {
1251af75078fSIntel 		printf("Packet forwarding not started\n");
1252af75078fSIntel 		return;
1253af75078fSIntel 	}
1254af75078fSIntel 	printf("Telling cores to stop...");
1255af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1256af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1257af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1258af75078fSIntel 	rte_eal_mp_wait_lcore();
1259af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1260af75078fSIntel 	if (port_fwd_end != NULL) {
1261af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1262af75078fSIntel 			pt_id = fwd_ports_ids[i];
1263af75078fSIntel 			(*port_fwd_end)(pt_id);
1264af75078fSIntel 		}
1265af75078fSIntel 	}
1266af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1267af75078fSIntel 	fwd_cycles = 0;
1268af75078fSIntel #endif
1269af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1270af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1271af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1272af75078fSIntel 			fwd_stream_stats_display(sm_id);
1273af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1274af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1275af75078fSIntel 		} else {
1276af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1277af75078fSIntel 				fwd_streams[sm_id];
1278af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1279af75078fSIntel 				fwd_streams[sm_id];
1280af75078fSIntel 		}
1281af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1282af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1283af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1284af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1285af75078fSIntel 
1286013af9b6SIntel 		rx_bad_ip_csum =
1287013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1288af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1289af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1290013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1291013af9b6SIntel 							rx_bad_ip_csum;
1292af75078fSIntel 
1293013af9b6SIntel 		rx_bad_l4_csum =
1294013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1295af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1296af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1297013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1298013af9b6SIntel 							rx_bad_l4_csum;
1299af75078fSIntel 
1300af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1301af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1302af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1303af75078fSIntel #endif
1304af75078fSIntel 	}
1305af75078fSIntel 	total_recv = 0;
1306af75078fSIntel 	total_xmit = 0;
1307af75078fSIntel 	total_rx_dropped = 0;
1308af75078fSIntel 	total_tx_dropped = 0;
1309af75078fSIntel 	total_rx_nombuf  = 0;
13107741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1311af75078fSIntel 		pt_id = fwd_ports_ids[i];
1312af75078fSIntel 
1313af75078fSIntel 		port = &ports[pt_id];
1314af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1315af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1316af75078fSIntel 		port->stats.ipackets = 0;
1317af75078fSIntel 		stats.opackets -= port->stats.opackets;
1318af75078fSIntel 		port->stats.opackets = 0;
1319af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1320af75078fSIntel 		port->stats.ibytes = 0;
1321af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1322af75078fSIntel 		port->stats.obytes = 0;
132370bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
132470bdb186SIvan Boule 		port->stats.imissed = 0;
1325af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1326af75078fSIntel 		port->stats.oerrors = 0;
1327af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1328af75078fSIntel 		port->stats.rx_nombuf = 0;
1329af75078fSIntel 
1330af75078fSIntel 		total_recv += stats.ipackets;
1331af75078fSIntel 		total_xmit += stats.opackets;
133270bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1333af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1334af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1335af75078fSIntel 
1336af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1337af75078fSIntel 	}
1338b7091f1dSJiayu Hu 
1339af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1340af75078fSIntel 	       "%s\n",
1341af75078fSIntel 	       acc_stats_border, acc_stats_border);
1342af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1343af75078fSIntel 	       "%-"PRIu64"\n"
1344af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1345af75078fSIntel 	       "%-"PRIu64"\n",
1346af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1347af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1348af75078fSIntel 	if (total_rx_nombuf > 0)
1349af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1350af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1351af75078fSIntel 	       "%s\n",
1352af75078fSIntel 	       acc_stats_border, acc_stats_border);
1353af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1354af75078fSIntel 	if (total_recv > 0)
1355af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1356af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1357af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1358af75078fSIntel 		       fwd_cycles, total_recv);
1359af75078fSIntel #endif
1360af75078fSIntel 	printf("\nDone.\n");
1361af75078fSIntel 	test_done = 1;
1362af75078fSIntel }
1363af75078fSIntel 
1364cfae07fdSOuyang Changchun void
1365cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1366cfae07fdSOuyang Changchun {
1367cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1368cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1369cfae07fdSOuyang Changchun }
1370cfae07fdSOuyang Changchun 
1371cfae07fdSOuyang Changchun void
1372cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1373cfae07fdSOuyang Changchun {
1374cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1375cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1376cfae07fdSOuyang Changchun }
1377cfae07fdSOuyang Changchun 
1378ce8d5614SIntel static int
1379ce8d5614SIntel all_ports_started(void)
1380ce8d5614SIntel {
1381ce8d5614SIntel 	portid_t pi;
1382ce8d5614SIntel 	struct rte_port *port;
1383ce8d5614SIntel 
13847d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1385ce8d5614SIntel 		port = &ports[pi];
1386ce8d5614SIntel 		/* Check if there is a port which is not started */
138741b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
138841b05095SBernard Iremonger 			(port->slave_flag == 0))
1389ce8d5614SIntel 			return 0;
1390ce8d5614SIntel 	}
1391ce8d5614SIntel 
1392ce8d5614SIntel 	/* No port is not started */
1393ce8d5614SIntel 	return 1;
1394ce8d5614SIntel }
1395ce8d5614SIntel 
1396148f963fSBruce Richardson int
1397edab33b1STetsuya Mukawa all_ports_stopped(void)
1398edab33b1STetsuya Mukawa {
1399edab33b1STetsuya Mukawa 	portid_t pi;
1400edab33b1STetsuya Mukawa 	struct rte_port *port;
1401edab33b1STetsuya Mukawa 
14027d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1403edab33b1STetsuya Mukawa 		port = &ports[pi];
140441b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
140541b05095SBernard Iremonger 			(port->slave_flag == 0))
1406edab33b1STetsuya Mukawa 			return 0;
1407edab33b1STetsuya Mukawa 	}
1408edab33b1STetsuya Mukawa 
1409edab33b1STetsuya Mukawa 	return 1;
1410edab33b1STetsuya Mukawa }
1411edab33b1STetsuya Mukawa 
1412edab33b1STetsuya Mukawa int
1413edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1414edab33b1STetsuya Mukawa {
1415edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1416edab33b1STetsuya Mukawa 		return 0;
1417edab33b1STetsuya Mukawa 
1418edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1419edab33b1STetsuya Mukawa 		return 0;
1420edab33b1STetsuya Mukawa 
1421edab33b1STetsuya Mukawa 	return 1;
1422edab33b1STetsuya Mukawa }
1423edab33b1STetsuya Mukawa 
1424edab33b1STetsuya Mukawa static int
1425edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1426edab33b1STetsuya Mukawa {
1427edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1428edab33b1STetsuya Mukawa 		return 0;
1429edab33b1STetsuya Mukawa 
1430edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1431edab33b1STetsuya Mukawa 		return 0;
1432edab33b1STetsuya Mukawa 
1433edab33b1STetsuya Mukawa 	return 1;
1434edab33b1STetsuya Mukawa }
1435edab33b1STetsuya Mukawa 
1436edab33b1STetsuya Mukawa int
1437ce8d5614SIntel start_port(portid_t pid)
1438ce8d5614SIntel {
143992d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1440ce8d5614SIntel 	portid_t pi;
1441ce8d5614SIntel 	queueid_t qi;
1442ce8d5614SIntel 	struct rte_port *port;
14432950a769SDeclan Doherty 	struct ether_addr mac_addr;
144476ad4a2dSGaetan Rivet 	enum rte_eth_event_type event_type;
1445ce8d5614SIntel 
14464468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14474468635fSMichael Qiu 		return 0;
14484468635fSMichael Qiu 
1449ce8d5614SIntel 	if(dcb_config)
1450ce8d5614SIntel 		dcb_test = 1;
14517d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1452edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1453ce8d5614SIntel 			continue;
1454ce8d5614SIntel 
145592d2703eSMichael Qiu 		need_check_link_status = 0;
1456ce8d5614SIntel 		port = &ports[pi];
1457ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1458ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1459ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1460ce8d5614SIntel 			continue;
1461ce8d5614SIntel 		}
1462ce8d5614SIntel 
1463ce8d5614SIntel 		if (port->need_reconfig > 0) {
1464ce8d5614SIntel 			port->need_reconfig = 0;
1465ce8d5614SIntel 
14667ee3e944SVasily Philipov 			if (flow_isolate_all) {
14677ee3e944SVasily Philipov 				int ret = port_flow_isolate(pi, 1);
14687ee3e944SVasily Philipov 				if (ret) {
14697ee3e944SVasily Philipov 					printf("Failed to apply isolated"
14707ee3e944SVasily Philipov 					       " mode on port %d\n", pi);
14717ee3e944SVasily Philipov 					return -1;
14727ee3e944SVasily Philipov 				}
14737ee3e944SVasily Philipov 			}
14747ee3e944SVasily Philipov 
14755706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
147620a0286fSLiu Xiaofeng 					port->socket_id);
1477ce8d5614SIntel 			/* configure port */
1478ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1479ce8d5614SIntel 						&(port->dev_conf));
1480ce8d5614SIntel 			if (diag != 0) {
1481ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1482ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1483ce8d5614SIntel 					printf("Port %d can not be set back "
1484ce8d5614SIntel 							"to stopped\n", pi);
1485ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1486ce8d5614SIntel 				/* try to reconfigure port next time */
1487ce8d5614SIntel 				port->need_reconfig = 1;
1488148f963fSBruce Richardson 				return -1;
1489ce8d5614SIntel 			}
1490ce8d5614SIntel 		}
1491ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1492ce8d5614SIntel 			port->need_reconfig_queues = 0;
1493ce8d5614SIntel 			/* setup tx queues */
1494ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1495b6ea6408SIntel 				if ((numa_support) &&
1496b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1497b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1498b6ea6408SIntel 						nb_txd,txring_numa[pi],
1499b6ea6408SIntel 						&(port->tx_conf));
1500b6ea6408SIntel 				else
1501b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1502b6ea6408SIntel 						nb_txd,port->socket_id,
1503b6ea6408SIntel 						&(port->tx_conf));
1504b6ea6408SIntel 
1505ce8d5614SIntel 				if (diag == 0)
1506ce8d5614SIntel 					continue;
1507ce8d5614SIntel 
1508ce8d5614SIntel 				/* Fail to setup tx queue, return */
1509ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1510ce8d5614SIntel 							RTE_PORT_HANDLING,
1511ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1512ce8d5614SIntel 					printf("Port %d can not be set back "
1513ce8d5614SIntel 							"to stopped\n", pi);
1514ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1515ce8d5614SIntel 				/* try to reconfigure queues next time */
1516ce8d5614SIntel 				port->need_reconfig_queues = 1;
1517148f963fSBruce Richardson 				return -1;
1518ce8d5614SIntel 			}
1519ce8d5614SIntel 			/* setup rx queues */
1520ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1521b6ea6408SIntel 				if ((numa_support) &&
1522b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1523b6ea6408SIntel 					struct rte_mempool * mp =
1524b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1525b6ea6408SIntel 					if (mp == NULL) {
1526b6ea6408SIntel 						printf("Failed to setup RX queue:"
1527b6ea6408SIntel 							"No mempool allocation"
1528b6ea6408SIntel 							" on the socket %d\n",
1529b6ea6408SIntel 							rxring_numa[pi]);
1530148f963fSBruce Richardson 						return -1;
1531b6ea6408SIntel 					}
1532b6ea6408SIntel 
1533b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1534b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1535b6ea6408SIntel 					     &(port->rx_conf),mp);
15361e1d6bddSBernard Iremonger 				} else {
15371e1d6bddSBernard Iremonger 					struct rte_mempool *mp =
15381e1d6bddSBernard Iremonger 						mbuf_pool_find(port->socket_id);
15391e1d6bddSBernard Iremonger 					if (mp == NULL) {
15401e1d6bddSBernard Iremonger 						printf("Failed to setup RX queue:"
15411e1d6bddSBernard Iremonger 							"No mempool allocation"
15421e1d6bddSBernard Iremonger 							" on the socket %d\n",
15431e1d6bddSBernard Iremonger 							port->socket_id);
15441e1d6bddSBernard Iremonger 						return -1;
1545b6ea6408SIntel 					}
1546b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1547b6ea6408SIntel 					     nb_rxd,port->socket_id,
15481e1d6bddSBernard Iremonger 					     &(port->rx_conf), mp);
15491e1d6bddSBernard Iremonger 				}
1550ce8d5614SIntel 				if (diag == 0)
1551ce8d5614SIntel 					continue;
1552ce8d5614SIntel 
1553ce8d5614SIntel 				/* Fail to setup rx queue, return */
1554ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1555ce8d5614SIntel 							RTE_PORT_HANDLING,
1556ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1557ce8d5614SIntel 					printf("Port %d can not be set back "
1558ce8d5614SIntel 							"to stopped\n", pi);
1559ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1560ce8d5614SIntel 				/* try to reconfigure queues next time */
1561ce8d5614SIntel 				port->need_reconfig_queues = 1;
1562148f963fSBruce Richardson 				return -1;
1563ce8d5614SIntel 			}
1564ce8d5614SIntel 		}
156576ad4a2dSGaetan Rivet 
156676ad4a2dSGaetan Rivet 		for (event_type = RTE_ETH_EVENT_UNKNOWN;
156776ad4a2dSGaetan Rivet 		     event_type < RTE_ETH_EVENT_MAX;
156876ad4a2dSGaetan Rivet 		     event_type++) {
156976ad4a2dSGaetan Rivet 			diag = rte_eth_dev_callback_register(pi,
157076ad4a2dSGaetan Rivet 							event_type,
157176ad4a2dSGaetan Rivet 							eth_event_callback,
157276ad4a2dSGaetan Rivet 							NULL);
157376ad4a2dSGaetan Rivet 			if (diag) {
157476ad4a2dSGaetan Rivet 				printf("Failed to setup even callback for event %d\n",
157576ad4a2dSGaetan Rivet 					event_type);
157676ad4a2dSGaetan Rivet 				return -1;
157776ad4a2dSGaetan Rivet 			}
157876ad4a2dSGaetan Rivet 		}
157976ad4a2dSGaetan Rivet 
1580ce8d5614SIntel 		/* start port */
1581ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1582ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1583ce8d5614SIntel 
1584ce8d5614SIntel 			/* Fail to setup rx queue, return */
1585ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1586ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1587ce8d5614SIntel 				printf("Port %d can not be set back to "
1588ce8d5614SIntel 							"stopped\n", pi);
1589ce8d5614SIntel 			continue;
1590ce8d5614SIntel 		}
1591ce8d5614SIntel 
1592ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1593ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1594ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1595ce8d5614SIntel 
15962950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1597d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
15982950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
15992950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
16002950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1601d8c89163SZijie Pan 
1602ce8d5614SIntel 		/* at least one port started, need checking link status */
1603ce8d5614SIntel 		need_check_link_status = 1;
1604ce8d5614SIntel 	}
1605ce8d5614SIntel 
160692d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1607edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
160892d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1609ce8d5614SIntel 		printf("Please stop the ports first\n");
1610ce8d5614SIntel 
1611ce8d5614SIntel 	printf("Done\n");
1612148f963fSBruce Richardson 	return 0;
1613ce8d5614SIntel }
1614ce8d5614SIntel 
1615ce8d5614SIntel void
1616ce8d5614SIntel stop_port(portid_t pid)
1617ce8d5614SIntel {
1618ce8d5614SIntel 	portid_t pi;
1619ce8d5614SIntel 	struct rte_port *port;
1620ce8d5614SIntel 	int need_check_link_status = 0;
1621ce8d5614SIntel 
1622ce8d5614SIntel 	if (dcb_test) {
1623ce8d5614SIntel 		dcb_test = 0;
1624ce8d5614SIntel 		dcb_config = 0;
1625ce8d5614SIntel 	}
16264468635fSMichael Qiu 
16274468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
16284468635fSMichael Qiu 		return;
16294468635fSMichael Qiu 
1630ce8d5614SIntel 	printf("Stopping ports...\n");
1631ce8d5614SIntel 
16327d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16334468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1634ce8d5614SIntel 			continue;
1635ce8d5614SIntel 
1636a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1637a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1638a8ef3e3aSBernard Iremonger 			continue;
1639a8ef3e3aSBernard Iremonger 		}
1640a8ef3e3aSBernard Iremonger 
16410e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16420e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16430e545d30SBernard Iremonger 			continue;
16440e545d30SBernard Iremonger 		}
16450e545d30SBernard Iremonger 
1646ce8d5614SIntel 		port = &ports[pi];
1647ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1648ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1649ce8d5614SIntel 			continue;
1650ce8d5614SIntel 
1651ce8d5614SIntel 		rte_eth_dev_stop(pi);
1652ce8d5614SIntel 
1653ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1654ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1655ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1656ce8d5614SIntel 		need_check_link_status = 1;
1657ce8d5614SIntel 	}
1658bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1659edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1660ce8d5614SIntel 
1661ce8d5614SIntel 	printf("Done\n");
1662ce8d5614SIntel }
1663ce8d5614SIntel 
1664ce8d5614SIntel void
1665ce8d5614SIntel close_port(portid_t pid)
1666ce8d5614SIntel {
1667ce8d5614SIntel 	portid_t pi;
1668ce8d5614SIntel 	struct rte_port *port;
1669ce8d5614SIntel 
16704468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
16714468635fSMichael Qiu 		return;
16724468635fSMichael Qiu 
1673ce8d5614SIntel 	printf("Closing ports...\n");
1674ce8d5614SIntel 
16757d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16764468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1677ce8d5614SIntel 			continue;
1678ce8d5614SIntel 
1679a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1680a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1681a8ef3e3aSBernard Iremonger 			continue;
1682a8ef3e3aSBernard Iremonger 		}
1683a8ef3e3aSBernard Iremonger 
16840e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16850e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16860e545d30SBernard Iremonger 			continue;
16870e545d30SBernard Iremonger 		}
16880e545d30SBernard Iremonger 
1689ce8d5614SIntel 		port = &ports[pi];
1690ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1691d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1692d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1693d4e8ad64SMichael Qiu 			continue;
1694d4e8ad64SMichael Qiu 		}
1695d4e8ad64SMichael Qiu 
1696d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1697ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1698ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1699ce8d5614SIntel 			continue;
1700ce8d5614SIntel 		}
1701ce8d5614SIntel 
1702938a184aSAdrien Mazarguil 		if (port->flow_list)
1703938a184aSAdrien Mazarguil 			port_flow_flush(pi);
1704ce8d5614SIntel 		rte_eth_dev_close(pi);
1705ce8d5614SIntel 
1706ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1707ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1708b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1709ce8d5614SIntel 	}
1710ce8d5614SIntel 
1711ce8d5614SIntel 	printf("Done\n");
1712ce8d5614SIntel }
1713ce8d5614SIntel 
1714edab33b1STetsuya Mukawa void
171597f1e196SWei Dai reset_port(portid_t pid)
171697f1e196SWei Dai {
171797f1e196SWei Dai 	int diag;
171897f1e196SWei Dai 	portid_t pi;
171997f1e196SWei Dai 	struct rte_port *port;
172097f1e196SWei Dai 
172197f1e196SWei Dai 	if (port_id_is_invalid(pid, ENABLED_WARN))
172297f1e196SWei Dai 		return;
172397f1e196SWei Dai 
172497f1e196SWei Dai 	printf("Resetting ports...\n");
172597f1e196SWei Dai 
172697f1e196SWei Dai 	RTE_ETH_FOREACH_DEV(pi) {
172797f1e196SWei Dai 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
172897f1e196SWei Dai 			continue;
172997f1e196SWei Dai 
173097f1e196SWei Dai 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
173197f1e196SWei Dai 			printf("Please remove port %d from forwarding "
173297f1e196SWei Dai 			       "configuration.\n", pi);
173397f1e196SWei Dai 			continue;
173497f1e196SWei Dai 		}
173597f1e196SWei Dai 
173697f1e196SWei Dai 		if (port_is_bonding_slave(pi)) {
173797f1e196SWei Dai 			printf("Please remove port %d from bonded device.\n",
173897f1e196SWei Dai 			       pi);
173997f1e196SWei Dai 			continue;
174097f1e196SWei Dai 		}
174197f1e196SWei Dai 
174297f1e196SWei Dai 		diag = rte_eth_dev_reset(pi);
174397f1e196SWei Dai 		if (diag == 0) {
174497f1e196SWei Dai 			port = &ports[pi];
174597f1e196SWei Dai 			port->need_reconfig = 1;
174697f1e196SWei Dai 			port->need_reconfig_queues = 1;
174797f1e196SWei Dai 		} else {
174897f1e196SWei Dai 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
174997f1e196SWei Dai 		}
175097f1e196SWei Dai 	}
175197f1e196SWei Dai 
175297f1e196SWei Dai 	printf("Done\n");
175397f1e196SWei Dai }
175497f1e196SWei Dai 
175597f1e196SWei Dai void
1756edab33b1STetsuya Mukawa attach_port(char *identifier)
1757ce8d5614SIntel {
1758ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1759931126baSBernard Iremonger 	unsigned int socket_id;
1760ce8d5614SIntel 
1761edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1762edab33b1STetsuya Mukawa 
1763edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1764edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1765edab33b1STetsuya Mukawa 		return;
1766ce8d5614SIntel 	}
1767ce8d5614SIntel 
1768edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1769edab33b1STetsuya Mukawa 		return;
1770edab33b1STetsuya Mukawa 
1771931126baSBernard Iremonger 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1772931126baSBernard Iremonger 	/* if socket_id is invalid, set to 0 */
1773931126baSBernard Iremonger 	if (check_socket_id(socket_id) < 0)
1774931126baSBernard Iremonger 		socket_id = 0;
1775931126baSBernard Iremonger 	reconfig(pi, socket_id);
1776edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1777edab33b1STetsuya Mukawa 
1778edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1779edab33b1STetsuya Mukawa 
1780edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1781edab33b1STetsuya Mukawa 
1782edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1783edab33b1STetsuya Mukawa 	printf("Done\n");
1784edab33b1STetsuya Mukawa }
1785edab33b1STetsuya Mukawa 
1786edab33b1STetsuya Mukawa void
1787edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
17885f4ec54fSChen Jing D(Mark) {
1789edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
17905f4ec54fSChen Jing D(Mark) 
1791edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
17925f4ec54fSChen Jing D(Mark) 
1793edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1794edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1795edab33b1STetsuya Mukawa 		return;
1796edab33b1STetsuya Mukawa 	}
1797edab33b1STetsuya Mukawa 
1798938a184aSAdrien Mazarguil 	if (ports[port_id].flow_list)
1799938a184aSAdrien Mazarguil 		port_flow_flush(port_id);
1800938a184aSAdrien Mazarguil 
18013070419eSGaetan Rivet 	if (rte_eth_dev_detach(port_id, name)) {
18023070419eSGaetan Rivet 		RTE_LOG(ERR, USER1, "Failed to detach port '%s'\n", name);
1803edab33b1STetsuya Mukawa 		return;
18043070419eSGaetan Rivet 	}
1805edab33b1STetsuya Mukawa 
1806edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1807edab33b1STetsuya Mukawa 
1808edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1809edab33b1STetsuya Mukawa 			name, nb_ports);
1810edab33b1STetsuya Mukawa 	printf("Done\n");
1811edab33b1STetsuya Mukawa 	return;
18125f4ec54fSChen Jing D(Mark) }
18135f4ec54fSChen Jing D(Mark) 
1814af75078fSIntel void
1815af75078fSIntel pmd_test_exit(void)
1816af75078fSIntel {
1817af75078fSIntel 	portid_t pt_id;
1818af75078fSIntel 
18198210ec25SPablo de Lara 	if (test_done == 0)
18208210ec25SPablo de Lara 		stop_packet_forwarding();
18218210ec25SPablo de Lara 
1822d3a274ceSZhihong Wang 	if (ports != NULL) {
1823d3a274ceSZhihong Wang 		no_link_check = 1;
18247d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(pt_id) {
1825d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1826af75078fSIntel 			fflush(stdout);
1827d3a274ceSZhihong Wang 			stop_port(pt_id);
1828d3a274ceSZhihong Wang 			close_port(pt_id);
1829af75078fSIntel 		}
1830d3a274ceSZhihong Wang 	}
1831d3a274ceSZhihong Wang 	printf("\nBye...\n");
1832af75078fSIntel }
1833af75078fSIntel 
1834af75078fSIntel typedef void (*cmd_func_t)(void);
1835af75078fSIntel struct pmd_test_command {
1836af75078fSIntel 	const char *cmd_name;
1837af75078fSIntel 	cmd_func_t cmd_func;
1838af75078fSIntel };
1839af75078fSIntel 
1840af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1841af75078fSIntel 
1842ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1843af75078fSIntel static void
1844edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1845af75078fSIntel {
1846ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1847ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1848f8244c63SZhiyong Yang 	portid_t portid;
1849f8244c63SZhiyong Yang 	uint8_t count, all_ports_up, print_flag = 0;
1850ce8d5614SIntel 	struct rte_eth_link link;
1851ce8d5614SIntel 
1852ce8d5614SIntel 	printf("Checking link statuses...\n");
1853ce8d5614SIntel 	fflush(stdout);
1854ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1855ce8d5614SIntel 		all_ports_up = 1;
18567d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(portid) {
1857ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1858ce8d5614SIntel 				continue;
1859ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1860ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1861ce8d5614SIntel 			/* print link status if flag set */
1862ce8d5614SIntel 			if (print_flag == 1) {
1863ce8d5614SIntel 				if (link.link_status)
1864f8244c63SZhiyong Yang 					printf(
1865f8244c63SZhiyong Yang 					"Port%d Link Up. speed %u Mbps- %s\n",
1866f8244c63SZhiyong Yang 					portid, link.link_speed,
1867ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1868ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1869ce8d5614SIntel 				else
1870f8244c63SZhiyong Yang 					printf("Port %d Link Down\n", portid);
1871ce8d5614SIntel 				continue;
1872ce8d5614SIntel 			}
1873ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
187409419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1875ce8d5614SIntel 				all_ports_up = 0;
1876ce8d5614SIntel 				break;
1877ce8d5614SIntel 			}
1878ce8d5614SIntel 		}
1879ce8d5614SIntel 		/* after finally printing all link status, get out */
1880ce8d5614SIntel 		if (print_flag == 1)
1881ce8d5614SIntel 			break;
1882ce8d5614SIntel 
1883ce8d5614SIntel 		if (all_ports_up == 0) {
1884ce8d5614SIntel 			fflush(stdout);
1885ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1886ce8d5614SIntel 		}
1887ce8d5614SIntel 
1888ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1889ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1890ce8d5614SIntel 			print_flag = 1;
1891ce8d5614SIntel 		}
18928ea656f8SGaetan Rivet 
18938ea656f8SGaetan Rivet 		if (lsc_interrupt)
18948ea656f8SGaetan Rivet 			break;
1895ce8d5614SIntel 	}
1896af75078fSIntel }
1897af75078fSIntel 
1898284c908cSGaetan Rivet static void
1899284c908cSGaetan Rivet rmv_event_callback(void *arg)
1900284c908cSGaetan Rivet {
1901284c908cSGaetan Rivet 	struct rte_eth_dev *dev;
1902284c908cSGaetan Rivet 	uint8_t port_id = (intptr_t)arg;
1903284c908cSGaetan Rivet 
1904284c908cSGaetan Rivet 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
1905284c908cSGaetan Rivet 	dev = &rte_eth_devices[port_id];
1906284c908cSGaetan Rivet 
1907284c908cSGaetan Rivet 	stop_port(port_id);
1908284c908cSGaetan Rivet 	close_port(port_id);
1909f3a1188cSGaetan Rivet 	printf("removing device %s\n", dev->device->name);
19103070419eSGaetan Rivet 	if (rte_eal_dev_detach(dev->device))
19113070419eSGaetan Rivet 		RTE_LOG(ERR, USER1, "Failed to detach device %s\n",
19123070419eSGaetan Rivet 			dev->device->name);
1913284c908cSGaetan Rivet }
1914284c908cSGaetan Rivet 
191576ad4a2dSGaetan Rivet /* This function is used by the interrupt thread */
1916d6af1a13SBernard Iremonger static int
1917f8244c63SZhiyong Yang eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
1918d6af1a13SBernard Iremonger 		  void *ret_param)
191976ad4a2dSGaetan Rivet {
192076ad4a2dSGaetan Rivet 	static const char * const event_desc[] = {
192176ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
192276ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
192376ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
192476ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
192576ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
192676ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
192776ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
192876ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MAX] = NULL,
192976ad4a2dSGaetan Rivet 	};
193076ad4a2dSGaetan Rivet 
193176ad4a2dSGaetan Rivet 	RTE_SET_USED(param);
1932d6af1a13SBernard Iremonger 	RTE_SET_USED(ret_param);
193376ad4a2dSGaetan Rivet 
193476ad4a2dSGaetan Rivet 	if (type >= RTE_ETH_EVENT_MAX) {
193576ad4a2dSGaetan Rivet 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
193676ad4a2dSGaetan Rivet 			port_id, __func__, type);
193776ad4a2dSGaetan Rivet 		fflush(stderr);
19383af72783SGaetan Rivet 	} else if (event_print_mask & (UINT32_C(1) << type)) {
193976ad4a2dSGaetan Rivet 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
194076ad4a2dSGaetan Rivet 			event_desc[type]);
194176ad4a2dSGaetan Rivet 		fflush(stdout);
194276ad4a2dSGaetan Rivet 	}
1943284c908cSGaetan Rivet 
1944284c908cSGaetan Rivet 	switch (type) {
1945284c908cSGaetan Rivet 	case RTE_ETH_EVENT_INTR_RMV:
1946284c908cSGaetan Rivet 		if (rte_eal_alarm_set(100000,
1947284c908cSGaetan Rivet 				rmv_event_callback, (void *)(intptr_t)port_id))
1948284c908cSGaetan Rivet 			fprintf(stderr, "Could not set up deferred device removal\n");
1949284c908cSGaetan Rivet 		break;
1950284c908cSGaetan Rivet 	default:
1951284c908cSGaetan Rivet 		break;
1952284c908cSGaetan Rivet 	}
1953d6af1a13SBernard Iremonger 	return 0;
195476ad4a2dSGaetan Rivet }
195576ad4a2dSGaetan Rivet 
1956013af9b6SIntel static int
1957013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1958af75078fSIntel {
1959013af9b6SIntel 	uint16_t i;
1960af75078fSIntel 	int diag;
1961013af9b6SIntel 	uint8_t mapping_found = 0;
1962af75078fSIntel 
1963013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1964013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1965013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1966013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1967013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1968013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1969013af9b6SIntel 			if (diag != 0)
1970013af9b6SIntel 				return diag;
1971013af9b6SIntel 			mapping_found = 1;
1972af75078fSIntel 		}
1973013af9b6SIntel 	}
1974013af9b6SIntel 	if (mapping_found)
1975013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1976013af9b6SIntel 	return 0;
1977013af9b6SIntel }
1978013af9b6SIntel 
1979013af9b6SIntel static int
1980013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1981013af9b6SIntel {
1982013af9b6SIntel 	uint16_t i;
1983013af9b6SIntel 	int diag;
1984013af9b6SIntel 	uint8_t mapping_found = 0;
1985013af9b6SIntel 
1986013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1987013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1988013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1989013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1990013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1991013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1992013af9b6SIntel 			if (diag != 0)
1993013af9b6SIntel 				return diag;
1994013af9b6SIntel 			mapping_found = 1;
1995013af9b6SIntel 		}
1996013af9b6SIntel 	}
1997013af9b6SIntel 	if (mapping_found)
1998013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1999013af9b6SIntel 	return 0;
2000013af9b6SIntel }
2001013af9b6SIntel 
2002013af9b6SIntel static void
2003013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
2004013af9b6SIntel {
2005013af9b6SIntel 	int diag = 0;
2006013af9b6SIntel 
2007013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2008af75078fSIntel 	if (diag != 0) {
2009013af9b6SIntel 		if (diag == -ENOTSUP) {
2010013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
2011013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2012013af9b6SIntel 		}
2013013af9b6SIntel 		else
2014013af9b6SIntel 			rte_exit(EXIT_FAILURE,
2015013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
2016013af9b6SIntel 					"failed for port id=%d diag=%d\n",
2017af75078fSIntel 					pi, diag);
2018af75078fSIntel 	}
2019013af9b6SIntel 
2020013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2021af75078fSIntel 	if (diag != 0) {
2022013af9b6SIntel 		if (diag == -ENOTSUP) {
2023013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
2024013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2025013af9b6SIntel 		}
2026013af9b6SIntel 		else
2027013af9b6SIntel 			rte_exit(EXIT_FAILURE,
2028013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
2029013af9b6SIntel 					"failed for port id=%d diag=%d\n",
2030af75078fSIntel 					pi, diag);
2031af75078fSIntel 	}
2032af75078fSIntel }
2033af75078fSIntel 
2034f2c5125aSPablo de Lara static void
2035f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
2036f2c5125aSPablo de Lara {
2037f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
2038f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
2039f2c5125aSPablo de Lara 
2040f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
2041f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2042f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
2043f2c5125aSPablo de Lara 
2044f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2045f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
2046f2c5125aSPablo de Lara 
2047f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2048f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
2049f2c5125aSPablo de Lara 
2050f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2051f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
2052f2c5125aSPablo de Lara 
2053f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2054f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
2055f2c5125aSPablo de Lara 
2056f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2057f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
2058f2c5125aSPablo de Lara 
2059f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2060f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
2061f2c5125aSPablo de Lara 
2062f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2063f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
2064f2c5125aSPablo de Lara 
2065f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2066f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
2067f2c5125aSPablo de Lara 
2068f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2069f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
2070f2c5125aSPablo de Lara 
2071f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
2072f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
2073f2c5125aSPablo de Lara }
2074f2c5125aSPablo de Lara 
2075013af9b6SIntel void
2076013af9b6SIntel init_port_config(void)
2077013af9b6SIntel {
2078013af9b6SIntel 	portid_t pid;
2079013af9b6SIntel 	struct rte_port *port;
2080013af9b6SIntel 
20817d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
2082013af9b6SIntel 		port = &ports[pid];
2083013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
2084013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
20853ce690d3SBruce Richardson 		if (nb_rxq > 1) {
2086013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2087013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2088af75078fSIntel 		} else {
2089013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2090013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2091af75078fSIntel 		}
20923ce690d3SBruce Richardson 
20935f592039SJingjing Wu 		if (port->dcb_flag == 0) {
20943ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
20953ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
20963ce690d3SBruce Richardson 			else
20973ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
20983ce690d3SBruce Richardson 		}
20993ce690d3SBruce Richardson 
2100f2c5125aSPablo de Lara 		rxtx_port_config(port);
2101013af9b6SIntel 
2102013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
2103013af9b6SIntel 
2104013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
210550c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2106e261265eSRadu Nicolau 		rte_pmd_ixgbe_bypass_init(pid);
21077b7e5ba7SIntel #endif
21088ea656f8SGaetan Rivet 
21098ea656f8SGaetan Rivet 		if (lsc_interrupt &&
21108ea656f8SGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
21118ea656f8SGaetan Rivet 		     RTE_ETH_DEV_INTR_LSC))
21128ea656f8SGaetan Rivet 			port->dev_conf.intr_conf.lsc = 1;
2113284c908cSGaetan Rivet 		if (rmv_interrupt &&
2114284c908cSGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
2115284c908cSGaetan Rivet 		     RTE_ETH_DEV_INTR_RMV))
2116284c908cSGaetan Rivet 			port->dev_conf.intr_conf.rmv = 1;
21175b590fbeSJasvinder Singh 
21185b590fbeSJasvinder Singh #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
21195b590fbeSJasvinder Singh 		/* Detect softnic port */
21205b590fbeSJasvinder Singh 		if (!strcmp(port->dev_info.driver_name, "net_softnic")) {
21215b590fbeSJasvinder Singh 			port->softnic_enable = 1;
21225b590fbeSJasvinder Singh 			memset(&port->softport, 0, sizeof(struct softnic_port));
21235b590fbeSJasvinder Singh 
21245b590fbeSJasvinder Singh 			if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm"))
21255b590fbeSJasvinder Singh 				port->softport.tm_flag = 1;
21265b590fbeSJasvinder Singh 		}
21275b590fbeSJasvinder Singh #endif
2128013af9b6SIntel 	}
2129013af9b6SIntel }
2130013af9b6SIntel 
213141b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
213241b05095SBernard Iremonger {
213341b05095SBernard Iremonger 	struct rte_port *port;
213441b05095SBernard Iremonger 
213541b05095SBernard Iremonger 	port = &ports[slave_pid];
213641b05095SBernard Iremonger 	port->slave_flag = 1;
213741b05095SBernard Iremonger }
213841b05095SBernard Iremonger 
213941b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
214041b05095SBernard Iremonger {
214141b05095SBernard Iremonger 	struct rte_port *port;
214241b05095SBernard Iremonger 
214341b05095SBernard Iremonger 	port = &ports[slave_pid];
214441b05095SBernard Iremonger 	port->slave_flag = 0;
214541b05095SBernard Iremonger }
214641b05095SBernard Iremonger 
21470e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
21480e545d30SBernard Iremonger {
21490e545d30SBernard Iremonger 	struct rte_port *port;
21500e545d30SBernard Iremonger 
21510e545d30SBernard Iremonger 	port = &ports[slave_pid];
21520e545d30SBernard Iremonger 	return port->slave_flag;
21530e545d30SBernard Iremonger }
21540e545d30SBernard Iremonger 
2155013af9b6SIntel const uint16_t vlan_tags[] = {
2156013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
2157013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
2158013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
2159013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
2160013af9b6SIntel };
2161013af9b6SIntel 
2162013af9b6SIntel static  int
21631a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
21641a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
21651a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
21661a572499SJingjing Wu 		 uint8_t pfc_en)
2167013af9b6SIntel {
2168013af9b6SIntel 	uint8_t i;
2169af75078fSIntel 
2170af75078fSIntel 	/*
2171013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2172013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
2173af75078fSIntel 	 */
21741a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
21751a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
21761a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
21771a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
21781a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2179013af9b6SIntel 
2180547d946cSNirmoy Das 		/* VMDQ+DCB RX and TX configurations */
21811a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
21821a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
21831a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
21841a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
21851a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
21861a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2187013af9b6SIntel 
21881a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
21891a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
21901a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
21911a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
21921a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2193af75078fSIntel 		}
2194013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
21951a572499SJingjing Wu 			vmdq_rx_conf->dcb_tc[i] = i;
21961a572499SJingjing Wu 			vmdq_tx_conf->dcb_tc[i] = i;
2197013af9b6SIntel 		}
2198013af9b6SIntel 
2199013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
220032e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
220132e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
22021a572499SJingjing Wu 	} else {
22031a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
22041a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
22051a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
22061a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2207013af9b6SIntel 
22081a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
22091a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
22101a572499SJingjing Wu 
2211bcd0e432SJingjing Wu 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2212bcd0e432SJingjing Wu 			rx_conf->dcb_tc[i] = i % num_tcs;
2213bcd0e432SJingjing Wu 			tx_conf->dcb_tc[i] = i % num_tcs;
2214013af9b6SIntel 		}
22151a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
22161a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
221732e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
22181a572499SJingjing Wu 	}
22191a572499SJingjing Wu 
22201a572499SJingjing Wu 	if (pfc_en)
22211a572499SJingjing Wu 		eth_conf->dcb_capability_en =
22221a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2223013af9b6SIntel 	else
2224013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2225013af9b6SIntel 
2226013af9b6SIntel 	return 0;
2227013af9b6SIntel }
2228013af9b6SIntel 
2229013af9b6SIntel int
22301a572499SJingjing Wu init_port_dcb_config(portid_t pid,
22311a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
22321a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
22331a572499SJingjing Wu 		     uint8_t pfc_en)
2234013af9b6SIntel {
2235013af9b6SIntel 	struct rte_eth_conf port_conf;
2236013af9b6SIntel 	struct rte_port *rte_port;
2237013af9b6SIntel 	int retval;
2238013af9b6SIntel 	uint16_t i;
2239013af9b6SIntel 
22402a977b89SWenzhuo Lu 	rte_port = &ports[pid];
2241013af9b6SIntel 
2242013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2243013af9b6SIntel 	/* Enter DCB configuration status */
2244013af9b6SIntel 	dcb_config = 1;
2245013af9b6SIntel 
2246013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
22471a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2248013af9b6SIntel 	if (retval < 0)
2249013af9b6SIntel 		return retval;
22502a977b89SWenzhuo Lu 	port_conf.rxmode.hw_vlan_filter = 1;
2251013af9b6SIntel 
22522a977b89SWenzhuo Lu 	/**
22532a977b89SWenzhuo Lu 	 * Write the configuration into the device.
22542a977b89SWenzhuo Lu 	 * Set the numbers of RX & TX queues to 0, so
22552a977b89SWenzhuo Lu 	 * the RX & TX queues will not be setup.
22562a977b89SWenzhuo Lu 	 */
2257c947ef89SStephen Hemminger 	rte_eth_dev_configure(pid, 0, 0, &port_conf);
22582a977b89SWenzhuo Lu 
22592a977b89SWenzhuo Lu 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
22602a977b89SWenzhuo Lu 
22612a977b89SWenzhuo Lu 	/* If dev_info.vmdq_pool_base is greater than 0,
22622a977b89SWenzhuo Lu 	 * the queue id of vmdq pools is started after pf queues.
22632a977b89SWenzhuo Lu 	 */
22642a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED &&
22652a977b89SWenzhuo Lu 	    rte_port->dev_info.vmdq_pool_base > 0) {
22662a977b89SWenzhuo Lu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
22672a977b89SWenzhuo Lu 			" for port %d.", pid);
22682a977b89SWenzhuo Lu 		return -1;
22692a977b89SWenzhuo Lu 	}
22702a977b89SWenzhuo Lu 
22712a977b89SWenzhuo Lu 	/* Assume the ports in testpmd have the same dcb capability
22722a977b89SWenzhuo Lu 	 * and has the same number of rxq and txq in dcb mode
22732a977b89SWenzhuo Lu 	 */
22742a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED) {
227586ef65eeSBernard Iremonger 		if (rte_port->dev_info.max_vfs > 0) {
227686ef65eeSBernard Iremonger 			nb_rxq = rte_port->dev_info.nb_rx_queues;
227786ef65eeSBernard Iremonger 			nb_txq = rte_port->dev_info.nb_tx_queues;
227886ef65eeSBernard Iremonger 		} else {
22792a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
22802a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
228186ef65eeSBernard Iremonger 		}
22822a977b89SWenzhuo Lu 	} else {
22832a977b89SWenzhuo Lu 		/*if vt is disabled, use all pf queues */
22842a977b89SWenzhuo Lu 		if (rte_port->dev_info.vmdq_pool_base == 0) {
22852a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
22862a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
22872a977b89SWenzhuo Lu 		} else {
22882a977b89SWenzhuo Lu 			nb_rxq = (queueid_t)num_tcs;
22892a977b89SWenzhuo Lu 			nb_txq = (queueid_t)num_tcs;
22902a977b89SWenzhuo Lu 
22912a977b89SWenzhuo Lu 		}
22922a977b89SWenzhuo Lu 	}
22932a977b89SWenzhuo Lu 	rx_free_thresh = 64;
22942a977b89SWenzhuo Lu 
2295013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2296013af9b6SIntel 
2297f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
2298013af9b6SIntel 	/* VLAN filter */
2299013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
23001a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2301013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
2302013af9b6SIntel 
2303013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2304013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
2305013af9b6SIntel 
23067741e4cfSIntel 	rte_port->dcb_flag = 1;
23077741e4cfSIntel 
2308013af9b6SIntel 	return 0;
2309af75078fSIntel }
2310af75078fSIntel 
2311ffc468ffSTetsuya Mukawa static void
2312ffc468ffSTetsuya Mukawa init_port(void)
2313ffc468ffSTetsuya Mukawa {
2314ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2315ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2316ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2317ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2318ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2319ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2320ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2321ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2322ffc468ffSTetsuya Mukawa 	}
2323ffc468ffSTetsuya Mukawa }
2324ffc468ffSTetsuya Mukawa 
2325d3a274ceSZhihong Wang static void
2326d3a274ceSZhihong Wang force_quit(void)
2327d3a274ceSZhihong Wang {
2328d3a274ceSZhihong Wang 	pmd_test_exit();
2329d3a274ceSZhihong Wang 	prompt_exit();
2330d3a274ceSZhihong Wang }
2331d3a274ceSZhihong Wang 
2332d3a274ceSZhihong Wang static void
2333cfea1f30SPablo de Lara print_stats(void)
2334cfea1f30SPablo de Lara {
2335cfea1f30SPablo de Lara 	uint8_t i;
2336cfea1f30SPablo de Lara 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2337cfea1f30SPablo de Lara 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2338cfea1f30SPablo de Lara 
2339cfea1f30SPablo de Lara 	/* Clear screen and move to top left */
2340cfea1f30SPablo de Lara 	printf("%s%s", clr, top_left);
2341cfea1f30SPablo de Lara 
2342cfea1f30SPablo de Lara 	printf("\nPort statistics ====================================");
2343cfea1f30SPablo de Lara 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2344cfea1f30SPablo de Lara 		nic_stats_display(fwd_ports_ids[i]);
2345cfea1f30SPablo de Lara }
2346cfea1f30SPablo de Lara 
2347cfea1f30SPablo de Lara static void
2348d3a274ceSZhihong Wang signal_handler(int signum)
2349d3a274ceSZhihong Wang {
2350d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2351d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2352d3a274ceSZhihong Wang 				signum);
2353102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2354102b7329SReshma Pattan 		/* uninitialize packet capture framework */
2355102b7329SReshma Pattan 		rte_pdump_uninit();
2356102b7329SReshma Pattan #endif
235762d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
235862d3216dSReshma Pattan 		rte_latencystats_uninit();
235962d3216dSReshma Pattan #endif
2360d3a274ceSZhihong Wang 		force_quit();
2361d9a191a0SPhil Yang 		/* Set flag to indicate the force termination. */
2362d9a191a0SPhil Yang 		f_quit = 1;
2363d3a274ceSZhihong Wang 		/* exit with the expected status */
2364d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2365d3a274ceSZhihong Wang 		kill(getpid(), signum);
2366d3a274ceSZhihong Wang 	}
2367d3a274ceSZhihong Wang }
2368d3a274ceSZhihong Wang 
2369af75078fSIntel int
2370af75078fSIntel main(int argc, char** argv)
2371af75078fSIntel {
2372af75078fSIntel 	int  diag;
2373f8244c63SZhiyong Yang 	portid_t port_id;
2374af75078fSIntel 
2375d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2376d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2377d3a274ceSZhihong Wang 
2378af75078fSIntel 	diag = rte_eal_init(argc, argv);
2379af75078fSIntel 	if (diag < 0)
2380af75078fSIntel 		rte_panic("Cannot init EAL\n");
2381af75078fSIntel 
23821c036b16SEelco Chaudron 	if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
23831c036b16SEelco Chaudron 		RTE_LOG(NOTICE, USER1, "mlockall() failed with error \"%s\"\n",
23841c036b16SEelco Chaudron 			strerror(errno));
23851c036b16SEelco Chaudron 	}
23861c036b16SEelco Chaudron 
2387102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2388102b7329SReshma Pattan 	/* initialize packet capture framework */
2389102b7329SReshma Pattan 	rte_pdump_init(NULL);
2390102b7329SReshma Pattan #endif
2391102b7329SReshma Pattan 
2392af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2393af75078fSIntel 	if (nb_ports == 0)
2394edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2395af75078fSIntel 
2396ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2397ffc468ffSTetsuya Mukawa 	init_port();
2398ffc468ffSTetsuya Mukawa 
2399af75078fSIntel 	set_def_fwd_config();
2400af75078fSIntel 	if (nb_lcores == 0)
2401af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2402af75078fSIntel 			  "core mask supplied in the command parameters\n");
2403af75078fSIntel 
240465eb1e54SPablo de Lara 	/* Bitrate/latency stats disabled by default */
240530bcc68cSPablo de Lara #ifdef RTE_LIBRTE_BITRATE
2406e25e6c70SRemy Horton 	bitrate_enabled = 0;
240730bcc68cSPablo de Lara #endif
240865eb1e54SPablo de Lara #ifdef RTE_LIBRTE_LATENCY_STATS
240965eb1e54SPablo de Lara 	latencystats_enabled = 0;
241065eb1e54SPablo de Lara #endif
2411e25e6c70SRemy Horton 
2412af75078fSIntel 	argc -= diag;
2413af75078fSIntel 	argv += diag;
2414af75078fSIntel 	if (argc > 1)
2415af75078fSIntel 		launch_args_parse(argc, argv);
2416af75078fSIntel 
241799cabef0SPablo de Lara 	if (tx_first && interactive)
241899cabef0SPablo de Lara 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
241999cabef0SPablo de Lara 				"interactive mode.\n");
24208820cba4SDavid Hunt 
24218820cba4SDavid Hunt 	if (tx_first && lsc_interrupt) {
24228820cba4SDavid Hunt 		printf("Warning: lsc_interrupt needs to be off when "
24238820cba4SDavid Hunt 				" using tx_first. Disabling.\n");
24248820cba4SDavid Hunt 		lsc_interrupt = 0;
24258820cba4SDavid Hunt 	}
24268820cba4SDavid Hunt 
24275a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
24285a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
24295a8fb55cSReshma Pattan 
24305a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2431af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2432af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2433af75078fSIntel 		       nb_rxq, nb_txq);
2434af75078fSIntel 
2435af75078fSIntel 	init_config();
2436148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2437148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2438af75078fSIntel 
2439ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
24407d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(port_id)
2441ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2442af75078fSIntel 
24437e4441c8SRemy Horton 	/* Init metrics library */
24447e4441c8SRemy Horton 	rte_metrics_init(rte_socket_id());
24457e4441c8SRemy Horton 
244662d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
244762d3216dSReshma Pattan 	if (latencystats_enabled != 0) {
244862d3216dSReshma Pattan 		int ret = rte_latencystats_init(1, NULL);
244962d3216dSReshma Pattan 		if (ret)
245062d3216dSReshma Pattan 			printf("Warning: latencystats init()"
245162d3216dSReshma Pattan 				" returned error %d\n",	ret);
245262d3216dSReshma Pattan 		printf("Latencystats running on lcore %d\n",
245362d3216dSReshma Pattan 			latencystats_lcore_id);
245462d3216dSReshma Pattan 	}
245562d3216dSReshma Pattan #endif
245662d3216dSReshma Pattan 
24577e4441c8SRemy Horton 	/* Setup bitrate stats */
24587e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
2459e25e6c70SRemy Horton 	if (bitrate_enabled != 0) {
24607e4441c8SRemy Horton 		bitrate_data = rte_stats_bitrate_create();
24617e4441c8SRemy Horton 		if (bitrate_data == NULL)
2462e25e6c70SRemy Horton 			rte_exit(EXIT_FAILURE,
2463e25e6c70SRemy Horton 				"Could not allocate bitrate data.\n");
24647e4441c8SRemy Horton 		rte_stats_bitrate_reg(bitrate_data);
2465e25e6c70SRemy Horton 	}
24667e4441c8SRemy Horton #endif
24677e4441c8SRemy Horton 
24680d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
246981ef862bSAllain Legacy 	if (strlen(cmdline_filename) != 0)
247081ef862bSAllain Legacy 		cmdline_read_from_file(cmdline_filename);
247181ef862bSAllain Legacy 
2472ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2473ca7feb22SCyril Chemparathy 		if (auto_start) {
2474ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2475ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2476ca7feb22SCyril Chemparathy 		}
2477af75078fSIntel 		prompt();
24780de738cfSJiayu Hu 		pmd_test_exit();
2479ca7feb22SCyril Chemparathy 	} else
24800d56cb81SThomas Monjalon #endif
24810d56cb81SThomas Monjalon 	{
2482af75078fSIntel 		char c;
2483af75078fSIntel 		int rc;
2484af75078fSIntel 
2485d9a191a0SPhil Yang 		f_quit = 0;
2486d9a191a0SPhil Yang 
2487af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
248899cabef0SPablo de Lara 		start_packet_forwarding(tx_first);
2489cfea1f30SPablo de Lara 		if (stats_period != 0) {
2490cfea1f30SPablo de Lara 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2491cfea1f30SPablo de Lara 			uint64_t timer_period;
2492cfea1f30SPablo de Lara 
2493cfea1f30SPablo de Lara 			/* Convert to number of cycles */
2494cfea1f30SPablo de Lara 			timer_period = stats_period * rte_get_timer_hz();
2495cfea1f30SPablo de Lara 
2496d9a191a0SPhil Yang 			while (f_quit == 0) {
2497cfea1f30SPablo de Lara 				cur_time = rte_get_timer_cycles();
2498cfea1f30SPablo de Lara 				diff_time += cur_time - prev_time;
2499cfea1f30SPablo de Lara 
2500cfea1f30SPablo de Lara 				if (diff_time >= timer_period) {
2501cfea1f30SPablo de Lara 					print_stats();
2502cfea1f30SPablo de Lara 					/* Reset the timer */
2503cfea1f30SPablo de Lara 					diff_time = 0;
2504cfea1f30SPablo de Lara 				}
2505cfea1f30SPablo de Lara 				/* Sleep to avoid unnecessary checks */
2506cfea1f30SPablo de Lara 				prev_time = cur_time;
2507cfea1f30SPablo de Lara 				sleep(1);
2508cfea1f30SPablo de Lara 			}
2509cfea1f30SPablo de Lara 		}
2510cfea1f30SPablo de Lara 
2511af75078fSIntel 		printf("Press enter to exit\n");
2512af75078fSIntel 		rc = read(0, &c, 1);
2513d3a274ceSZhihong Wang 		pmd_test_exit();
2514af75078fSIntel 		if (rc < 0)
2515af75078fSIntel 			return 1;
2516af75078fSIntel 	}
2517af75078fSIntel 
2518af75078fSIntel 	return 0;
2519af75078fSIntel }
2520