xref: /dpdk/app/test-pmd/testpmd.c (revision cfea1f3048d1bfda61036e6f823949fba4d692d4)
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>
41af75078fSIntel #include <sys/types.h>
42af75078fSIntel #include <errno.h>
43af75078fSIntel 
44af75078fSIntel #include <sys/queue.h>
45af75078fSIntel #include <sys/stat.h>
46af75078fSIntel 
47af75078fSIntel #include <stdint.h>
48af75078fSIntel #include <unistd.h>
49af75078fSIntel #include <inttypes.h>
50af75078fSIntel 
51af75078fSIntel #include <rte_common.h>
52d1eb542eSOlivier Matz #include <rte_errno.h>
53af75078fSIntel #include <rte_byteorder.h>
54af75078fSIntel #include <rte_log.h>
55af75078fSIntel #include <rte_debug.h>
56af75078fSIntel #include <rte_cycles.h>
57af75078fSIntel #include <rte_memory.h>
58af75078fSIntel #include <rte_memcpy.h>
59af75078fSIntel #include <rte_memzone.h>
60af75078fSIntel #include <rte_launch.h>
61af75078fSIntel #include <rte_eal.h>
62284c908cSGaetan Rivet #include <rte_alarm.h>
63af75078fSIntel #include <rte_per_lcore.h>
64af75078fSIntel #include <rte_lcore.h>
65af75078fSIntel #include <rte_atomic.h>
66af75078fSIntel #include <rte_branch_prediction.h>
67af75078fSIntel #include <rte_mempool.h>
68af75078fSIntel #include <rte_malloc.h>
69af75078fSIntel #include <rte_mbuf.h>
70af75078fSIntel #include <rte_interrupts.h>
71af75078fSIntel #include <rte_pci.h>
72af75078fSIntel #include <rte_ether.h>
73af75078fSIntel #include <rte_ethdev.h>
74edab33b1STetsuya Mukawa #include <rte_dev.h>
75af75078fSIntel #include <rte_string_fns.h>
76e261265eSRadu Nicolau #ifdef RTE_LIBRTE_IXGBE_PMD
77e261265eSRadu Nicolau #include <rte_pmd_ixgbe.h>
78e261265eSRadu Nicolau #endif
79148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
80148f963fSBruce Richardson #include <rte_eth_xenvirt.h>
81148f963fSBruce Richardson #endif
82102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
83102b7329SReshma Pattan #include <rte_pdump.h>
84102b7329SReshma Pattan #endif
85938a184aSAdrien Mazarguil #include <rte_flow.h>
867e4441c8SRemy Horton #include <rte_metrics.h>
877e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
887e4441c8SRemy Horton #include <rte_bitrate.h>
897e4441c8SRemy Horton #endif
9062d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
9162d3216dSReshma Pattan #include <rte_latencystats.h>
9262d3216dSReshma Pattan #endif
93af75078fSIntel 
94af75078fSIntel #include "testpmd.h"
95af75078fSIntel 
96af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
97af75078fSIntel 
98af75078fSIntel /* use master core for command line ? */
99af75078fSIntel uint8_t interactive = 0;
100ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
10199cabef0SPablo de Lara uint8_t tx_first;
10281ef862bSAllain Legacy char cmdline_filename[PATH_MAX] = {0};
103af75078fSIntel 
104af75078fSIntel /*
105af75078fSIntel  * NUMA support configuration.
106af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
107af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
108af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
109af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
110af75078fSIntel  */
111999b2ee0SBruce Richardson uint8_t numa_support = 1; /**< numa enabled by default */
112af75078fSIntel 
113af75078fSIntel /*
114b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
115b6ea6408SIntel  * not configured.
116b6ea6408SIntel  */
117b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
118b6ea6408SIntel 
119b6ea6408SIntel /*
120148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
121148f963fSBruce Richardson  */
122148f963fSBruce Richardson uint8_t mp_anon = 0;
123148f963fSBruce Richardson 
124148f963fSBruce Richardson /*
125af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
126af75078fSIntel  * forwarded.
127547d946cSNirmoy Das  * Must be instantiated with the ethernet addresses of peer traffic generator
128af75078fSIntel  * ports.
129af75078fSIntel  */
130af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
131af75078fSIntel portid_t nb_peer_eth_addrs = 0;
132af75078fSIntel 
133af75078fSIntel /*
134af75078fSIntel  * Probed Target Environment.
135af75078fSIntel  */
136af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
137af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
138af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
139af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
140af75078fSIntel 
141af75078fSIntel /*
142af75078fSIntel  * Test Forwarding Configuration.
143af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
144af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
145af75078fSIntel  */
146af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
147af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
148af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
149af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
150af75078fSIntel 
151af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
152af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
153af75078fSIntel 
154af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
155af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
156af75078fSIntel 
157af75078fSIntel /*
158af75078fSIntel  * Forwarding engines.
159af75078fSIntel  */
160af75078fSIntel struct fwd_engine * fwd_engines[] = {
161af75078fSIntel 	&io_fwd_engine,
162af75078fSIntel 	&mac_fwd_engine,
163d47388f1SCyril Chemparathy 	&mac_swap_engine,
164e9e23a61SCyril Chemparathy 	&flow_gen_engine,
165af75078fSIntel 	&rx_only_engine,
166af75078fSIntel 	&tx_only_engine,
167af75078fSIntel 	&csum_fwd_engine,
168168dfa61SIvan Boule 	&icmp_echo_engine,
169af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
170af75078fSIntel 	&ieee1588_fwd_engine,
171af75078fSIntel #endif
172af75078fSIntel 	NULL,
173af75078fSIntel };
174af75078fSIntel 
175af75078fSIntel struct fwd_config cur_fwd_config;
176af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
177bf56fce1SZhihong Wang uint32_t retry_enabled;
178bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
179bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
180af75078fSIntel 
181af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
182c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
183c8798818SIntel                                       * specified on command-line. */
184*cfea1f30SPablo de Lara uint16_t stats_period; /**< Period to show statistics (disabled by default) */
185af75078fSIntel /*
186af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
187af75078fSIntel  */
188af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
189af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
190af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
191af75078fSIntel };
192af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
193af75078fSIntel 
19479bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
19579bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
19679bec05bSKonstantin Ananyev 
197af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
198e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
199af75078fSIntel 
200900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
201900550deSIntel uint8_t dcb_config = 0;
202900550deSIntel 
203900550deSIntel /* Whether the dcb is in testing status */
204900550deSIntel uint8_t dcb_test = 0;
205900550deSIntel 
206af75078fSIntel /*
207af75078fSIntel  * Configurable number of RX/TX queues.
208af75078fSIntel  */
209af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
210af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
211af75078fSIntel 
212af75078fSIntel /*
213af75078fSIntel  * Configurable number of RX/TX ring descriptors.
214af75078fSIntel  */
215af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
216af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
217af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
218af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
219af75078fSIntel 
220f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
221af75078fSIntel /*
222af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
223af75078fSIntel  */
224af75078fSIntel 
225f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
226f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
227f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
228af75078fSIntel 
229f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
230f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
231f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
232af75078fSIntel 
233af75078fSIntel /*
234af75078fSIntel  * Configurable value of RX free threshold.
235af75078fSIntel  */
236f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
237af75078fSIntel 
238af75078fSIntel /*
239ce8d5614SIntel  * Configurable value of RX drop enable.
240ce8d5614SIntel  */
241f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
242ce8d5614SIntel 
243ce8d5614SIntel /*
244af75078fSIntel  * Configurable value of TX free threshold.
245af75078fSIntel  */
246f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
247af75078fSIntel 
248af75078fSIntel /*
249af75078fSIntel  * Configurable value of TX RS bit threshold.
250af75078fSIntel  */
251f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
252af75078fSIntel 
253af75078fSIntel /*
254ce8d5614SIntel  * Configurable value of TX queue flags.
255ce8d5614SIntel  */
256f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
257ce8d5614SIntel 
258ce8d5614SIntel /*
259af75078fSIntel  * Receive Side Scaling (RSS) configuration.
260af75078fSIntel  */
2618a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
262af75078fSIntel 
263af75078fSIntel /*
264af75078fSIntel  * Port topology configuration
265af75078fSIntel  */
266af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
267af75078fSIntel 
2687741e4cfSIntel /*
2697741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2707741e4cfSIntel  */
2717741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2727741e4cfSIntel 
273af75078fSIntel /*
274bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
275bc202406SDavid Marchand  */
276bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
277bc202406SDavid Marchand 
278bc202406SDavid Marchand /*
2798ea656f8SGaetan Rivet  * Enable link status change notification
2808ea656f8SGaetan Rivet  */
2818ea656f8SGaetan Rivet uint8_t lsc_interrupt = 1; /* enabled by default */
2828ea656f8SGaetan Rivet 
2838ea656f8SGaetan Rivet /*
284284c908cSGaetan Rivet  * Enable device removal notification.
285284c908cSGaetan Rivet  */
286284c908cSGaetan Rivet uint8_t rmv_interrupt = 1; /* enabled by default */
287284c908cSGaetan Rivet 
288284c908cSGaetan Rivet /*
2893af72783SGaetan Rivet  * Display or mask ether events
2903af72783SGaetan Rivet  * Default to all events except VF_MBOX
2913af72783SGaetan Rivet  */
2923af72783SGaetan Rivet uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
2933af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
2943af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
2953af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
2963af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
2973af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
2983af72783SGaetan Rivet 
2993af72783SGaetan Rivet /*
3007b7e5ba7SIntel  * NIC bypass mode configuration options.
3017b7e5ba7SIntel  */
3027b7e5ba7SIntel 
30350c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
3047b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
305e261265eSRadu Nicolau uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
3067b7e5ba7SIntel #endif
3077b7e5ba7SIntel 
308e261265eSRadu Nicolau 
30962d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
31062d3216dSReshma Pattan 
31162d3216dSReshma Pattan /*
31262d3216dSReshma Pattan  * Set when latency stats is enabled in the commandline
31362d3216dSReshma Pattan  */
31462d3216dSReshma Pattan uint8_t latencystats_enabled;
31562d3216dSReshma Pattan 
31662d3216dSReshma Pattan /*
31762d3216dSReshma Pattan  * Lcore ID to serive latency statistics.
31862d3216dSReshma Pattan  */
31962d3216dSReshma Pattan lcoreid_t latencystats_lcore_id = -1;
32062d3216dSReshma Pattan 
32162d3216dSReshma Pattan #endif
32262d3216dSReshma Pattan 
3237b7e5ba7SIntel /*
324af75078fSIntel  * Ethernet device configuration.
325af75078fSIntel  */
326af75078fSIntel struct rte_eth_rxmode rx_mode = {
327af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
328af75078fSIntel 	.split_hdr_size = 0,
329af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
330af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
331af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
332a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
333a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
334af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
33579dd163fSJeff Guo 	.hw_strip_crc   = 1, /**< CRC stripping by hardware enabled. */
336af75078fSIntel };
337af75078fSIntel 
338af75078fSIntel struct rte_fdir_conf fdir_conf = {
339af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
340af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
341af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
342d9d5e6f2SJingjing Wu 	.mask = {
343d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
344d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
345d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
346d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
347d9d5e6f2SJingjing Wu 		},
348d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
349d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
350d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
351d9d5e6f2SJingjing Wu 		},
352d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
353d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
35447b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
35547b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
35647b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
357d9d5e6f2SJingjing Wu 	},
358af75078fSIntel 	.drop_queue = 127,
359af75078fSIntel };
360af75078fSIntel 
3612950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
362af75078fSIntel 
363ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
364ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
365ed30d9b6SIntel 
366ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
367ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
368ed30d9b6SIntel 
369ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
370ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
371ed30d9b6SIntel 
372c9cafcc8SShahaf Shuler unsigned int num_sockets = 0;
373c9cafcc8SShahaf Shuler unsigned int socket_ids[RTE_MAX_NUMA_NODES];
3747acf894dSStephen Hurd 
375e25e6c70SRemy Horton #ifdef RTE_LIBRTE_BITRATE
3767e4441c8SRemy Horton /* Bitrate statistics */
3777e4441c8SRemy Horton struct rte_stats_bitrates *bitrate_data;
378e25e6c70SRemy Horton lcoreid_t bitrate_lcore_id;
379e25e6c70SRemy Horton uint8_t bitrate_enabled;
380e25e6c70SRemy Horton #endif
3817e4441c8SRemy Horton 
382ed30d9b6SIntel /* Forward function declarations */
383ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
384edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
385d6af1a13SBernard Iremonger static int eth_event_callback(uint8_t port_id,
38676ad4a2dSGaetan Rivet 			      enum rte_eth_event_type type,
387d6af1a13SBernard Iremonger 			      void *param, void *ret_param);
388ce8d5614SIntel 
389ce8d5614SIntel /*
390ce8d5614SIntel  * Check if all the ports are started.
391ce8d5614SIntel  * If yes, return positive value. If not, return zero.
392ce8d5614SIntel  */
393ce8d5614SIntel static int all_ports_started(void);
394ed30d9b6SIntel 
395af75078fSIntel /*
39698a7ea33SJerin Jacob  * Helper function to check if socket is already discovered.
397c9cafcc8SShahaf Shuler  * If yes, return positive value. If not, return zero.
398c9cafcc8SShahaf Shuler  */
399c9cafcc8SShahaf Shuler int
400c9cafcc8SShahaf Shuler new_socket_id(unsigned int socket_id)
401c9cafcc8SShahaf Shuler {
402c9cafcc8SShahaf Shuler 	unsigned int i;
403c9cafcc8SShahaf Shuler 
404c9cafcc8SShahaf Shuler 	for (i = 0; i < num_sockets; i++) {
405c9cafcc8SShahaf Shuler 		if (socket_ids[i] == socket_id)
406c9cafcc8SShahaf Shuler 			return 0;
407c9cafcc8SShahaf Shuler 	}
408c9cafcc8SShahaf Shuler 	return 1;
409c9cafcc8SShahaf Shuler }
410c9cafcc8SShahaf Shuler 
411c9cafcc8SShahaf Shuler /*
412af75078fSIntel  * Setup default configuration.
413af75078fSIntel  */
414af75078fSIntel static void
415af75078fSIntel set_default_fwd_lcores_config(void)
416af75078fSIntel {
417af75078fSIntel 	unsigned int i;
418af75078fSIntel 	unsigned int nb_lc;
4197acf894dSStephen Hurd 	unsigned int sock_num;
420af75078fSIntel 
421af75078fSIntel 	nb_lc = 0;
422af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
423c9cafcc8SShahaf Shuler 		sock_num = rte_lcore_to_socket_id(i);
424c9cafcc8SShahaf Shuler 		if (new_socket_id(sock_num)) {
425c9cafcc8SShahaf Shuler 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
426c9cafcc8SShahaf Shuler 				rte_exit(EXIT_FAILURE,
427c9cafcc8SShahaf Shuler 					 "Total sockets greater than %u\n",
428c9cafcc8SShahaf Shuler 					 RTE_MAX_NUMA_NODES);
429c9cafcc8SShahaf Shuler 			}
430c9cafcc8SShahaf Shuler 			socket_ids[num_sockets++] = sock_num;
4317acf894dSStephen Hurd 		}
432f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
433f54fe5eeSStephen Hurd 			continue;
434f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
435f54fe5eeSStephen Hurd 			continue;
436f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
437af75078fSIntel 	}
438af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
439af75078fSIntel 	nb_cfg_lcores = nb_lcores;
440af75078fSIntel 	nb_fwd_lcores = 1;
441af75078fSIntel }
442af75078fSIntel 
443af75078fSIntel static void
444af75078fSIntel set_def_peer_eth_addrs(void)
445af75078fSIntel {
446af75078fSIntel 	portid_t i;
447af75078fSIntel 
448af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
449af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
450af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
451af75078fSIntel 	}
452af75078fSIntel }
453af75078fSIntel 
454af75078fSIntel static void
455af75078fSIntel set_default_fwd_ports_config(void)
456af75078fSIntel {
457af75078fSIntel 	portid_t pt_id;
458af75078fSIntel 
459af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
460af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
461af75078fSIntel 
462af75078fSIntel 	nb_cfg_ports = nb_ports;
463af75078fSIntel 	nb_fwd_ports = nb_ports;
464af75078fSIntel }
465af75078fSIntel 
466af75078fSIntel void
467af75078fSIntel set_def_fwd_config(void)
468af75078fSIntel {
469af75078fSIntel 	set_default_fwd_lcores_config();
470af75078fSIntel 	set_def_peer_eth_addrs();
471af75078fSIntel 	set_default_fwd_ports_config();
472af75078fSIntel }
473af75078fSIntel 
474af75078fSIntel /*
475af75078fSIntel  * Configuration initialisation done once at init time.
476af75078fSIntel  */
477af75078fSIntel static void
478af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
479af75078fSIntel 		 unsigned int socket_id)
480af75078fSIntel {
481af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
482bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
483af75078fSIntel 	uint32_t mb_size;
484af75078fSIntel 
485dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
486af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
487148f963fSBruce Richardson 
488d1eb542eSOlivier Matz 	RTE_LOG(INFO, USER1,
489d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
490d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
491d1eb542eSOlivier Matz 
492148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
493148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
494af75078fSIntel 		(unsigned) mb_mempool_cache,
495af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
496dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
497dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
498af75078fSIntel 		socket_id, 0);
499bece7b6cSChristian Ehrhardt #endif
500148f963fSBruce Richardson 
501bece7b6cSChristian Ehrhardt 	/* if the former XEN allocation failed fall back to normal allocation */
502bece7b6cSChristian Ehrhardt 	if (rte_mp == NULL) {
503b19a0c75SOlivier Matz 		if (mp_anon != 0) {
504b19a0c75SOlivier Matz 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
505bece7b6cSChristian Ehrhardt 				mb_size, (unsigned) mb_mempool_cache,
506148f963fSBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private),
507148f963fSBruce Richardson 				socket_id, 0);
50824427bb9SOlivier Matz 			if (rte_mp == NULL)
50924427bb9SOlivier Matz 				goto err;
510b19a0c75SOlivier Matz 
511b19a0c75SOlivier Matz 			if (rte_mempool_populate_anon(rte_mp) == 0) {
512b19a0c75SOlivier Matz 				rte_mempool_free(rte_mp);
513b19a0c75SOlivier Matz 				rte_mp = NULL;
51424427bb9SOlivier Matz 				goto err;
515b19a0c75SOlivier Matz 			}
516b19a0c75SOlivier Matz 			rte_pktmbuf_pool_init(rte_mp, NULL);
517b19a0c75SOlivier Matz 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
518b19a0c75SOlivier Matz 		} else {
519ea0c20eaSOlivier Matz 			/* wrapper to rte_mempool_create() */
520ea0c20eaSOlivier Matz 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
521ea0c20eaSOlivier Matz 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
522bece7b6cSChristian Ehrhardt 		}
523b19a0c75SOlivier Matz 	}
524148f963fSBruce Richardson 
52524427bb9SOlivier Matz err:
526af75078fSIntel 	if (rte_mp == NULL) {
527d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
528d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
529d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
530148f963fSBruce Richardson 	} else if (verbose_level > 0) {
531591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
532af75078fSIntel 	}
533af75078fSIntel }
534af75078fSIntel 
53520a0286fSLiu Xiaofeng /*
53620a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
53720a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
53820a0286fSLiu Xiaofeng  */
53920a0286fSLiu Xiaofeng static int
54020a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
54120a0286fSLiu Xiaofeng {
54220a0286fSLiu Xiaofeng 	static int warning_once = 0;
54320a0286fSLiu Xiaofeng 
544c9cafcc8SShahaf Shuler 	if (new_socket_id(socket_id)) {
54520a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
54620a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
54720a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
54820a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
54920a0286fSLiu Xiaofeng 			       " --numa.\n");
55020a0286fSLiu Xiaofeng 		warning_once = 1;
55120a0286fSLiu Xiaofeng 		return -1;
55220a0286fSLiu Xiaofeng 	}
55320a0286fSLiu Xiaofeng 	return 0;
55420a0286fSLiu Xiaofeng }
55520a0286fSLiu Xiaofeng 
556af75078fSIntel static void
557af75078fSIntel init_config(void)
558af75078fSIntel {
559ce8d5614SIntel 	portid_t pid;
560af75078fSIntel 	struct rte_port *port;
561af75078fSIntel 	struct rte_mempool *mbp;
562af75078fSIntel 	unsigned int nb_mbuf_per_pool;
563af75078fSIntel 	lcoreid_t  lc_id;
5647acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
565af75078fSIntel 
5667acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
567487f9a59SYulong Pei 
568487f9a59SYulong Pei 	if (numa_support) {
569487f9a59SYulong Pei 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
570487f9a59SYulong Pei 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
571487f9a59SYulong Pei 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
572487f9a59SYulong Pei 	}
573487f9a59SYulong Pei 
574af75078fSIntel 	/* Configuration of logical cores. */
575af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
576af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
577fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
578af75078fSIntel 	if (fwd_lcores == NULL) {
579ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
580ce8d5614SIntel 							"failed\n", nb_lcores);
581af75078fSIntel 	}
582af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
583af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
584af75078fSIntel 					       sizeof(struct fwd_lcore),
585fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
586af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
587ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
588ce8d5614SIntel 								"failed\n");
589af75078fSIntel 		}
590af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
591af75078fSIntel 	}
592af75078fSIntel 
5937d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
594ce8d5614SIntel 		port = &ports[pid];
595ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
596ce8d5614SIntel 
597b6ea6408SIntel 		if (numa_support) {
598b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
599b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
600b6ea6408SIntel 			else {
601b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
60220a0286fSLiu Xiaofeng 
60320a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
60420a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
60520a0286fSLiu Xiaofeng 					socket_id = 0;
606b6ea6408SIntel 				port_per_socket[socket_id]++;
607b6ea6408SIntel 			}
608b6ea6408SIntel 		}
609b6ea6408SIntel 
610ce8d5614SIntel 		/* set flag to initialize port/queue */
611ce8d5614SIntel 		port->need_reconfig = 1;
612ce8d5614SIntel 		port->need_reconfig_queues = 1;
613ce8d5614SIntel 	}
614ce8d5614SIntel 
6153ab64341SOlivier Matz 	/*
6163ab64341SOlivier Matz 	 * Create pools of mbuf.
6173ab64341SOlivier Matz 	 * If NUMA support is disabled, create a single pool of mbuf in
6183ab64341SOlivier Matz 	 * socket 0 memory by default.
6193ab64341SOlivier Matz 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
6203ab64341SOlivier Matz 	 *
6213ab64341SOlivier Matz 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
6223ab64341SOlivier Matz 	 * nb_txd can be configured at run time.
6233ab64341SOlivier Matz 	 */
6243ab64341SOlivier Matz 	if (param_total_num_mbufs)
6253ab64341SOlivier Matz 		nb_mbuf_per_pool = param_total_num_mbufs;
6263ab64341SOlivier Matz 	else {
6273ab64341SOlivier Matz 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
6283ab64341SOlivier Matz 			(nb_lcores * mb_mempool_cache) +
6293ab64341SOlivier Matz 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
6303ab64341SOlivier Matz 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
6313ab64341SOlivier Matz 	}
6323ab64341SOlivier Matz 
633b6ea6408SIntel 	if (numa_support) {
634b6ea6408SIntel 		uint8_t i;
635ce8d5614SIntel 
636c9cafcc8SShahaf Shuler 		for (i = 0; i < num_sockets; i++)
637c9cafcc8SShahaf Shuler 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
638c9cafcc8SShahaf Shuler 					 socket_ids[i]);
6393ab64341SOlivier Matz 	} else {
6403ab64341SOlivier Matz 		if (socket_num == UMA_NO_CONFIG)
6413ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
6423ab64341SOlivier Matz 		else
6433ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
6443ab64341SOlivier Matz 						 socket_num);
6453ab64341SOlivier Matz 	}
646b6ea6408SIntel 
647b6ea6408SIntel 	init_port_config();
6485886ae07SAdrien Mazarguil 
6495886ae07SAdrien Mazarguil 	/*
6505886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6515886ae07SAdrien Mazarguil 	 */
6525886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6538fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
6548fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
6558fd8bebcSAdrien Mazarguil 
6565886ae07SAdrien Mazarguil 		if (mbp == NULL)
6575886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6585886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
6595886ae07SAdrien Mazarguil 	}
6605886ae07SAdrien Mazarguil 
661ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
662ce8d5614SIntel 	if (init_fwd_streams() < 0)
663ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
6640c0db76fSBernard Iremonger 
6650c0db76fSBernard Iremonger 	fwd_config_setup();
666ce8d5614SIntel }
667ce8d5614SIntel 
6682950a769SDeclan Doherty 
6692950a769SDeclan Doherty void
670a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6712950a769SDeclan Doherty {
6722950a769SDeclan Doherty 	struct rte_port *port;
6732950a769SDeclan Doherty 
6742950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6752950a769SDeclan Doherty 	port = &ports[new_port_id];
6762950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6772950a769SDeclan Doherty 
6782950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6792950a769SDeclan Doherty 	port->need_reconfig = 1;
6802950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
681a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6822950a769SDeclan Doherty 
6832950a769SDeclan Doherty 	init_port_config();
6842950a769SDeclan Doherty }
6852950a769SDeclan Doherty 
6862950a769SDeclan Doherty 
687ce8d5614SIntel int
688ce8d5614SIntel init_fwd_streams(void)
689ce8d5614SIntel {
690ce8d5614SIntel 	portid_t pid;
691ce8d5614SIntel 	struct rte_port *port;
692ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
6935a8fb55cSReshma Pattan 	queueid_t q;
694ce8d5614SIntel 
695ce8d5614SIntel 	/* set socket id according to numa or not */
6967d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
697ce8d5614SIntel 		port = &ports[pid];
698ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
699ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
700ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
701ce8d5614SIntel 				port->dev_info.max_rx_queues);
702ce8d5614SIntel 			return -1;
703ce8d5614SIntel 		}
704ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
705ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
706ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
707ce8d5614SIntel 				port->dev_info.max_tx_queues);
708ce8d5614SIntel 			return -1;
709ce8d5614SIntel 		}
71020a0286fSLiu Xiaofeng 		if (numa_support) {
71120a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
71220a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
71320a0286fSLiu Xiaofeng 			else {
714b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
71520a0286fSLiu Xiaofeng 
71620a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
71720a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
71820a0286fSLiu Xiaofeng 					port->socket_id = 0;
71920a0286fSLiu Xiaofeng 			}
72020a0286fSLiu Xiaofeng 		}
721b6ea6408SIntel 		else {
722b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
723af75078fSIntel 				port->socket_id = 0;
724b6ea6408SIntel 			else
725b6ea6408SIntel 				port->socket_id = socket_num;
726b6ea6408SIntel 		}
727af75078fSIntel 	}
728af75078fSIntel 
7295a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
7305a8fb55cSReshma Pattan 	if (q == 0) {
7315a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
7325a8fb55cSReshma Pattan 		return -1;
7335a8fb55cSReshma Pattan 	}
7345a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
735ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
736ce8d5614SIntel 		return 0;
737ce8d5614SIntel 	/* clear the old */
738ce8d5614SIntel 	if (fwd_streams != NULL) {
739ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
740ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
741ce8d5614SIntel 				continue;
742ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
743ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
744af75078fSIntel 		}
745ce8d5614SIntel 		rte_free(fwd_streams);
746ce8d5614SIntel 		fwd_streams = NULL;
747ce8d5614SIntel 	}
748ce8d5614SIntel 
749ce8d5614SIntel 	/* init new */
750ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
751ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
752fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
753ce8d5614SIntel 	if (fwd_streams == NULL)
754ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
755ce8d5614SIntel 						"failed\n", nb_fwd_streams);
756ce8d5614SIntel 
757af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
758af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
759fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
760ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
761ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
762ce8d5614SIntel 								" failed\n");
763af75078fSIntel 	}
764ce8d5614SIntel 
765ce8d5614SIntel 	return 0;
766af75078fSIntel }
767af75078fSIntel 
768af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
769af75078fSIntel static void
770af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
771af75078fSIntel {
772af75078fSIntel 	unsigned int total_burst;
773af75078fSIntel 	unsigned int nb_burst;
774af75078fSIntel 	unsigned int burst_stats[3];
775af75078fSIntel 	uint16_t pktnb_stats[3];
776af75078fSIntel 	uint16_t nb_pkt;
777af75078fSIntel 	int burst_percent[3];
778af75078fSIntel 
779af75078fSIntel 	/*
780af75078fSIntel 	 * First compute the total number of packet bursts and the
781af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
782af75078fSIntel 	 */
783af75078fSIntel 	total_burst = 0;
784af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
785af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
786af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
787af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
788af75078fSIntel 		if (nb_burst == 0)
789af75078fSIntel 			continue;
790af75078fSIntel 		total_burst += nb_burst;
791af75078fSIntel 		if (nb_burst > burst_stats[0]) {
792af75078fSIntel 			burst_stats[1] = burst_stats[0];
793af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
794af75078fSIntel 			burst_stats[0] = nb_burst;
795af75078fSIntel 			pktnb_stats[0] = nb_pkt;
796af75078fSIntel 		}
797af75078fSIntel 	}
798af75078fSIntel 	if (total_burst == 0)
799af75078fSIntel 		return;
800af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
801af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
802af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
803af75078fSIntel 	if (burst_stats[0] == total_burst) {
804af75078fSIntel 		printf("]\n");
805af75078fSIntel 		return;
806af75078fSIntel 	}
807af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
808af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
809af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
810af75078fSIntel 		return;
811af75078fSIntel 	}
812af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
813af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
814af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
815af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
816af75078fSIntel 		return;
817af75078fSIntel 	}
818af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
819af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
820af75078fSIntel }
821af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
822af75078fSIntel 
823af75078fSIntel static void
824af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
825af75078fSIntel {
826af75078fSIntel 	struct rte_port *port;
827013af9b6SIntel 	uint8_t i;
828af75078fSIntel 
829af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
830af75078fSIntel 
831af75078fSIntel 	port = &ports[port_id];
832af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
833af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
834013af9b6SIntel 
835013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
836af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
837af75078fSIntel 		       "%-"PRIu64"\n",
83870bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
83970bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
840af75078fSIntel 
841af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
842af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
843af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
84486057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
845f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
84670bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
84770bdb186SIvan Boule 		}
848af75078fSIntel 
849af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
850af75078fSIntel 		       "%-"PRIu64"\n",
851af75078fSIntel 		       stats->opackets, port->tx_dropped,
852af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
853013af9b6SIntel 	}
854013af9b6SIntel 	else {
855013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
856013af9b6SIntel 		       "%14"PRIu64"\n",
85770bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
85870bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
859013af9b6SIntel 
860013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
861013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
862013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
86386057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
864f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
86570bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
86670bdb186SIvan Boule 			       stats->rx_nombuf);
86770bdb186SIvan Boule 		}
868013af9b6SIntel 
869013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
870013af9b6SIntel 		       "%14"PRIu64"\n",
871013af9b6SIntel 		       stats->opackets, port->tx_dropped,
872013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
873013af9b6SIntel 	}
874e659b6b4SIvan Boule 
875af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
876af75078fSIntel 	if (port->rx_stream)
877013af9b6SIntel 		pkt_burst_stats_display("RX",
878013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
879af75078fSIntel 	if (port->tx_stream)
880013af9b6SIntel 		pkt_burst_stats_display("TX",
881013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
882af75078fSIntel #endif
883af75078fSIntel 
884013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
885013af9b6SIntel 		printf("\n");
886013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
887013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
888013af9b6SIntel 			       "     RX-errors:%14"PRIu64
889013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
890013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
891013af9b6SIntel 		}
892013af9b6SIntel 		printf("\n");
893013af9b6SIntel 	}
894013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
895013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
896013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
897013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
898013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
899013af9b6SIntel 		}
900013af9b6SIntel 	}
901013af9b6SIntel 
902af75078fSIntel 	printf("  %s--------------------------------%s\n",
903af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
904af75078fSIntel }
905af75078fSIntel 
906af75078fSIntel static void
907af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
908af75078fSIntel {
909af75078fSIntel 	struct fwd_stream *fs;
910af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
911af75078fSIntel 
912af75078fSIntel 	fs = fwd_streams[stream_id];
913af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
914af75078fSIntel 	    (fs->fwd_dropped == 0))
915af75078fSIntel 		return;
916af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
917af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
918af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
919af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
920af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
921af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
922af75078fSIntel 
923af75078fSIntel 	/* if checksum mode */
924af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
925013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
926013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
927af75078fSIntel 	}
928af75078fSIntel 
929af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
930af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
931af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
932af75078fSIntel #endif
933af75078fSIntel }
934af75078fSIntel 
935af75078fSIntel static void
9367741e4cfSIntel flush_fwd_rx_queues(void)
937af75078fSIntel {
938af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
939af75078fSIntel 	portid_t  rxp;
9407741e4cfSIntel 	portid_t port_id;
941af75078fSIntel 	queueid_t rxq;
942af75078fSIntel 	uint16_t  nb_rx;
943af75078fSIntel 	uint16_t  i;
944af75078fSIntel 	uint8_t   j;
945f487715fSReshma Pattan 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
946594302c7SJames Poole 	uint64_t timer_period;
947f487715fSReshma Pattan 
948f487715fSReshma Pattan 	/* convert to number of cycles */
949594302c7SJames Poole 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
950af75078fSIntel 
951af75078fSIntel 	for (j = 0; j < 2; j++) {
9527741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
953af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
9547741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
955f487715fSReshma Pattan 				/**
956f487715fSReshma Pattan 				* testpmd can stuck in the below do while loop
957f487715fSReshma Pattan 				* if rte_eth_rx_burst() always returns nonzero
958f487715fSReshma Pattan 				* packets. So timer is added to exit this loop
959f487715fSReshma Pattan 				* after 1sec timer expiry.
960f487715fSReshma Pattan 				*/
961f487715fSReshma Pattan 				prev_tsc = rte_rdtsc();
962af75078fSIntel 				do {
9637741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
964013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
965af75078fSIntel 					for (i = 0; i < nb_rx; i++)
966af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
967f487715fSReshma Pattan 
968f487715fSReshma Pattan 					cur_tsc = rte_rdtsc();
969f487715fSReshma Pattan 					diff_tsc = cur_tsc - prev_tsc;
970f487715fSReshma Pattan 					timer_tsc += diff_tsc;
971f487715fSReshma Pattan 				} while ((nb_rx > 0) &&
972f487715fSReshma Pattan 					(timer_tsc < timer_period));
973f487715fSReshma Pattan 				timer_tsc = 0;
974af75078fSIntel 			}
975af75078fSIntel 		}
976af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
977af75078fSIntel 	}
978af75078fSIntel }
979af75078fSIntel 
980af75078fSIntel static void
981af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
982af75078fSIntel {
983af75078fSIntel 	struct fwd_stream **fsm;
984af75078fSIntel 	streamid_t nb_fs;
985af75078fSIntel 	streamid_t sm_id;
9867e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
9877e4441c8SRemy Horton 	uint64_t tics_per_1sec;
9887e4441c8SRemy Horton 	uint64_t tics_datum;
9897e4441c8SRemy Horton 	uint64_t tics_current;
9907e4441c8SRemy Horton 	uint8_t idx_port, cnt_ports;
991af75078fSIntel 
9927e4441c8SRemy Horton 	cnt_ports = rte_eth_dev_count();
9937e4441c8SRemy Horton 	tics_datum = rte_rdtsc();
9947e4441c8SRemy Horton 	tics_per_1sec = rte_get_timer_hz();
9957e4441c8SRemy Horton #endif
996af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
997af75078fSIntel 	nb_fs = fc->stream_nb;
998af75078fSIntel 	do {
999af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1000af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
10017e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
1002e25e6c70SRemy Horton 		if (bitrate_enabled != 0 &&
1003e25e6c70SRemy Horton 				bitrate_lcore_id == rte_lcore_id()) {
10047e4441c8SRemy Horton 			tics_current = rte_rdtsc();
10057e4441c8SRemy Horton 			if (tics_current - tics_datum >= tics_per_1sec) {
10067e4441c8SRemy Horton 				/* Periodic bitrate calculation */
1007e25e6c70SRemy Horton 				for (idx_port = 0;
1008e25e6c70SRemy Horton 						idx_port < cnt_ports;
1009e25e6c70SRemy Horton 						idx_port++)
1010e25e6c70SRemy Horton 					rte_stats_bitrate_calc(bitrate_data,
1011e25e6c70SRemy Horton 						idx_port);
10127e4441c8SRemy Horton 				tics_datum = tics_current;
10137e4441c8SRemy Horton 			}
1014e25e6c70SRemy Horton 		}
10157e4441c8SRemy Horton #endif
101662d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
101765eb1e54SPablo de Lara 		if (latencystats_enabled != 0 &&
101865eb1e54SPablo de Lara 				latencystats_lcore_id == rte_lcore_id())
101962d3216dSReshma Pattan 			rte_latencystats_update();
102062d3216dSReshma Pattan #endif
102162d3216dSReshma Pattan 
1022af75078fSIntel 	} while (! fc->stopped);
1023af75078fSIntel }
1024af75078fSIntel 
1025af75078fSIntel static int
1026af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
1027af75078fSIntel {
1028af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1029af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
1030af75078fSIntel 	return 0;
1031af75078fSIntel }
1032af75078fSIntel 
1033af75078fSIntel /*
1034af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1035af75078fSIntel  * Used to start communication flows in network loopback test configurations.
1036af75078fSIntel  */
1037af75078fSIntel static int
1038af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
1039af75078fSIntel {
1040af75078fSIntel 	struct fwd_lcore *fwd_lc;
1041af75078fSIntel 	struct fwd_lcore tmp_lcore;
1042af75078fSIntel 
1043af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1044af75078fSIntel 	tmp_lcore = *fwd_lc;
1045af75078fSIntel 	tmp_lcore.stopped = 1;
1046af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1047af75078fSIntel 	return 0;
1048af75078fSIntel }
1049af75078fSIntel 
1050af75078fSIntel /*
1051af75078fSIntel  * Launch packet forwarding:
1052af75078fSIntel  *     - Setup per-port forwarding context.
1053af75078fSIntel  *     - launch logical cores with their forwarding configuration.
1054af75078fSIntel  */
1055af75078fSIntel static void
1056af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1057af75078fSIntel {
1058af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1059af75078fSIntel 	unsigned int i;
1060af75078fSIntel 	unsigned int lc_id;
1061af75078fSIntel 	int diag;
1062af75078fSIntel 
1063af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1064af75078fSIntel 	if (port_fwd_begin != NULL) {
1065af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1066af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
1067af75078fSIntel 	}
1068af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1069af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
1070af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1071af75078fSIntel 			fwd_lcores[i]->stopped = 0;
1072af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1073af75078fSIntel 						     fwd_lcores[i], lc_id);
1074af75078fSIntel 			if (diag != 0)
1075af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
1076af75078fSIntel 				       lc_id, diag);
1077af75078fSIntel 		}
1078af75078fSIntel 	}
1079af75078fSIntel }
1080af75078fSIntel 
1081af75078fSIntel /*
1082af75078fSIntel  * Launch packet forwarding configuration.
1083af75078fSIntel  */
1084af75078fSIntel void
1085af75078fSIntel start_packet_forwarding(int with_tx_first)
1086af75078fSIntel {
1087af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1088af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1089af75078fSIntel 	struct rte_port *port;
1090af75078fSIntel 	unsigned int i;
1091af75078fSIntel 	portid_t   pt_id;
1092af75078fSIntel 	streamid_t sm_id;
1093af75078fSIntel 
10945a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
10955a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
10965a8fb55cSReshma Pattan 
10975a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
10985a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
10995a8fb55cSReshma Pattan 
11005a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
11015a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
11025a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
11035a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
11045a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
11055a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
11065a8fb55cSReshma Pattan 
1107ce8d5614SIntel 	if (all_ports_started() == 0) {
1108ce8d5614SIntel 		printf("Not all ports were started\n");
1109ce8d5614SIntel 		return;
1110ce8d5614SIntel 	}
1111af75078fSIntel 	if (test_done == 0) {
1112af75078fSIntel 		printf("Packet forwarding already started\n");
1113af75078fSIntel 		return;
1114af75078fSIntel 	}
1115edf87b4aSBernard Iremonger 
1116edf87b4aSBernard Iremonger 	if (init_fwd_streams() < 0) {
1117edf87b4aSBernard Iremonger 		printf("Fail from init_fwd_streams()\n");
1118edf87b4aSBernard Iremonger 		return;
1119edf87b4aSBernard Iremonger 	}
1120edf87b4aSBernard Iremonger 
11217741e4cfSIntel 	if(dcb_test) {
11227741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
11237741e4cfSIntel 			pt_id = fwd_ports_ids[i];
11247741e4cfSIntel 			port = &ports[pt_id];
11257741e4cfSIntel 			if (!port->dcb_flag) {
11267741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
11277741e4cfSIntel                                        "be configured in this mode.\n");
1128013af9b6SIntel 				return;
1129013af9b6SIntel 			}
11307741e4cfSIntel 		}
11317741e4cfSIntel 		if (nb_fwd_lcores == 1) {
11327741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
11337741e4cfSIntel                                "should be larger than 1.\n");
11347741e4cfSIntel 			return;
11357741e4cfSIntel 		}
11367741e4cfSIntel 	}
1137af75078fSIntel 	test_done = 0;
11387741e4cfSIntel 
11397741e4cfSIntel 	if(!no_flush_rx)
11407741e4cfSIntel 		flush_fwd_rx_queues();
11417741e4cfSIntel 
1142af75078fSIntel 	fwd_config_setup();
1143933617d8SZhihong Wang 	pkt_fwd_config_display(&cur_fwd_config);
1144af75078fSIntel 	rxtx_config_display();
1145af75078fSIntel 
1146af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1147af75078fSIntel 		pt_id = fwd_ports_ids[i];
1148af75078fSIntel 		port = &ports[pt_id];
1149af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1150af75078fSIntel 		port->tx_dropped = 0;
1151013af9b6SIntel 
1152013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1153af75078fSIntel 	}
1154af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1155af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1156af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1157af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1158af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1159af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1160af75078fSIntel 
1161af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1162af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1163af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1164af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1165af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1166af75078fSIntel #endif
1167af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1168af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1169af75078fSIntel #endif
1170af75078fSIntel 	}
1171af75078fSIntel 	if (with_tx_first) {
1172af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1173af75078fSIntel 		if (port_fwd_begin != NULL) {
1174af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1175af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1176af75078fSIntel 		}
1177acbf77a6SZhihong Wang 		while (with_tx_first--) {
1178acbf77a6SZhihong Wang 			launch_packet_forwarding(
1179acbf77a6SZhihong Wang 					run_one_txonly_burst_on_core);
1180af75078fSIntel 			rte_eal_mp_wait_lcore();
1181acbf77a6SZhihong Wang 		}
1182af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1183af75078fSIntel 		if (port_fwd_end != NULL) {
1184af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1185af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1186af75078fSIntel 		}
1187af75078fSIntel 	}
1188af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1189af75078fSIntel }
1190af75078fSIntel 
1191af75078fSIntel void
1192af75078fSIntel stop_packet_forwarding(void)
1193af75078fSIntel {
1194af75078fSIntel 	struct rte_eth_stats stats;
1195af75078fSIntel 	struct rte_port *port;
1196af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1197af75078fSIntel 	int i;
1198af75078fSIntel 	portid_t   pt_id;
1199af75078fSIntel 	streamid_t sm_id;
1200af75078fSIntel 	lcoreid_t  lc_id;
1201af75078fSIntel 	uint64_t total_recv;
1202af75078fSIntel 	uint64_t total_xmit;
1203af75078fSIntel 	uint64_t total_rx_dropped;
1204af75078fSIntel 	uint64_t total_tx_dropped;
1205af75078fSIntel 	uint64_t total_rx_nombuf;
1206af75078fSIntel 	uint64_t tx_dropped;
1207af75078fSIntel 	uint64_t rx_bad_ip_csum;
1208af75078fSIntel 	uint64_t rx_bad_l4_csum;
1209af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1210af75078fSIntel 	uint64_t fwd_cycles;
1211af75078fSIntel #endif
1212af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1213af75078fSIntel 
1214af75078fSIntel 	if (test_done) {
1215af75078fSIntel 		printf("Packet forwarding not started\n");
1216af75078fSIntel 		return;
1217af75078fSIntel 	}
1218af75078fSIntel 	printf("Telling cores to stop...");
1219af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1220af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1221af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1222af75078fSIntel 	rte_eal_mp_wait_lcore();
1223af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1224af75078fSIntel 	if (port_fwd_end != NULL) {
1225af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1226af75078fSIntel 			pt_id = fwd_ports_ids[i];
1227af75078fSIntel 			(*port_fwd_end)(pt_id);
1228af75078fSIntel 		}
1229af75078fSIntel 	}
1230af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1231af75078fSIntel 	fwd_cycles = 0;
1232af75078fSIntel #endif
1233af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1234af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1235af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1236af75078fSIntel 			fwd_stream_stats_display(sm_id);
1237af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1238af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1239af75078fSIntel 		} else {
1240af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1241af75078fSIntel 				fwd_streams[sm_id];
1242af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1243af75078fSIntel 				fwd_streams[sm_id];
1244af75078fSIntel 		}
1245af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1246af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1247af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1248af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1249af75078fSIntel 
1250013af9b6SIntel 		rx_bad_ip_csum =
1251013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1252af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1253af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1254013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1255013af9b6SIntel 							rx_bad_ip_csum;
1256af75078fSIntel 
1257013af9b6SIntel 		rx_bad_l4_csum =
1258013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1259af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1260af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1261013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1262013af9b6SIntel 							rx_bad_l4_csum;
1263af75078fSIntel 
1264af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1265af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1266af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1267af75078fSIntel #endif
1268af75078fSIntel 	}
1269af75078fSIntel 	total_recv = 0;
1270af75078fSIntel 	total_xmit = 0;
1271af75078fSIntel 	total_rx_dropped = 0;
1272af75078fSIntel 	total_tx_dropped = 0;
1273af75078fSIntel 	total_rx_nombuf  = 0;
12747741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1275af75078fSIntel 		pt_id = fwd_ports_ids[i];
1276af75078fSIntel 
1277af75078fSIntel 		port = &ports[pt_id];
1278af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1279af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1280af75078fSIntel 		port->stats.ipackets = 0;
1281af75078fSIntel 		stats.opackets -= port->stats.opackets;
1282af75078fSIntel 		port->stats.opackets = 0;
1283af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1284af75078fSIntel 		port->stats.ibytes = 0;
1285af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1286af75078fSIntel 		port->stats.obytes = 0;
128770bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
128870bdb186SIvan Boule 		port->stats.imissed = 0;
1289af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1290af75078fSIntel 		port->stats.oerrors = 0;
1291af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1292af75078fSIntel 		port->stats.rx_nombuf = 0;
1293af75078fSIntel 
1294af75078fSIntel 		total_recv += stats.ipackets;
1295af75078fSIntel 		total_xmit += stats.opackets;
129670bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1297af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1298af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1299af75078fSIntel 
1300af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1301af75078fSIntel 	}
1302af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1303af75078fSIntel 	       "%s\n",
1304af75078fSIntel 	       acc_stats_border, acc_stats_border);
1305af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1306af75078fSIntel 	       "%-"PRIu64"\n"
1307af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1308af75078fSIntel 	       "%-"PRIu64"\n",
1309af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1310af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1311af75078fSIntel 	if (total_rx_nombuf > 0)
1312af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1313af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1314af75078fSIntel 	       "%s\n",
1315af75078fSIntel 	       acc_stats_border, acc_stats_border);
1316af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1317af75078fSIntel 	if (total_recv > 0)
1318af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1319af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1320af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1321af75078fSIntel 		       fwd_cycles, total_recv);
1322af75078fSIntel #endif
1323af75078fSIntel 	printf("\nDone.\n");
1324af75078fSIntel 	test_done = 1;
1325af75078fSIntel }
1326af75078fSIntel 
1327cfae07fdSOuyang Changchun void
1328cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1329cfae07fdSOuyang Changchun {
1330cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1331cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1332cfae07fdSOuyang Changchun }
1333cfae07fdSOuyang Changchun 
1334cfae07fdSOuyang Changchun void
1335cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1336cfae07fdSOuyang Changchun {
1337cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1338cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1339cfae07fdSOuyang Changchun }
1340cfae07fdSOuyang Changchun 
1341ce8d5614SIntel static int
1342ce8d5614SIntel all_ports_started(void)
1343ce8d5614SIntel {
1344ce8d5614SIntel 	portid_t pi;
1345ce8d5614SIntel 	struct rte_port *port;
1346ce8d5614SIntel 
13477d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1348ce8d5614SIntel 		port = &ports[pi];
1349ce8d5614SIntel 		/* Check if there is a port which is not started */
135041b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
135141b05095SBernard Iremonger 			(port->slave_flag == 0))
1352ce8d5614SIntel 			return 0;
1353ce8d5614SIntel 	}
1354ce8d5614SIntel 
1355ce8d5614SIntel 	/* No port is not started */
1356ce8d5614SIntel 	return 1;
1357ce8d5614SIntel }
1358ce8d5614SIntel 
1359148f963fSBruce Richardson int
1360edab33b1STetsuya Mukawa all_ports_stopped(void)
1361edab33b1STetsuya Mukawa {
1362edab33b1STetsuya Mukawa 	portid_t pi;
1363edab33b1STetsuya Mukawa 	struct rte_port *port;
1364edab33b1STetsuya Mukawa 
13657d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1366edab33b1STetsuya Mukawa 		port = &ports[pi];
136741b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
136841b05095SBernard Iremonger 			(port->slave_flag == 0))
1369edab33b1STetsuya Mukawa 			return 0;
1370edab33b1STetsuya Mukawa 	}
1371edab33b1STetsuya Mukawa 
1372edab33b1STetsuya Mukawa 	return 1;
1373edab33b1STetsuya Mukawa }
1374edab33b1STetsuya Mukawa 
1375edab33b1STetsuya Mukawa int
1376edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1377edab33b1STetsuya Mukawa {
1378edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1379edab33b1STetsuya Mukawa 		return 0;
1380edab33b1STetsuya Mukawa 
1381edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1382edab33b1STetsuya Mukawa 		return 0;
1383edab33b1STetsuya Mukawa 
1384edab33b1STetsuya Mukawa 	return 1;
1385edab33b1STetsuya Mukawa }
1386edab33b1STetsuya Mukawa 
1387edab33b1STetsuya Mukawa static int
1388edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1389edab33b1STetsuya Mukawa {
1390edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1391edab33b1STetsuya Mukawa 		return 0;
1392edab33b1STetsuya Mukawa 
1393edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1394edab33b1STetsuya Mukawa 		return 0;
1395edab33b1STetsuya Mukawa 
1396edab33b1STetsuya Mukawa 	return 1;
1397edab33b1STetsuya Mukawa }
1398edab33b1STetsuya Mukawa 
1399edab33b1STetsuya Mukawa int
1400ce8d5614SIntel start_port(portid_t pid)
1401ce8d5614SIntel {
140292d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1403ce8d5614SIntel 	portid_t pi;
1404ce8d5614SIntel 	queueid_t qi;
1405ce8d5614SIntel 	struct rte_port *port;
14062950a769SDeclan Doherty 	struct ether_addr mac_addr;
140776ad4a2dSGaetan Rivet 	enum rte_eth_event_type event_type;
1408ce8d5614SIntel 
14094468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14104468635fSMichael Qiu 		return 0;
14114468635fSMichael Qiu 
1412ce8d5614SIntel 	if(dcb_config)
1413ce8d5614SIntel 		dcb_test = 1;
14147d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1415edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1416ce8d5614SIntel 			continue;
1417ce8d5614SIntel 
141892d2703eSMichael Qiu 		need_check_link_status = 0;
1419ce8d5614SIntel 		port = &ports[pi];
1420ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1421ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1422ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1423ce8d5614SIntel 			continue;
1424ce8d5614SIntel 		}
1425ce8d5614SIntel 
1426ce8d5614SIntel 		if (port->need_reconfig > 0) {
1427ce8d5614SIntel 			port->need_reconfig = 0;
1428ce8d5614SIntel 
14295706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
143020a0286fSLiu Xiaofeng 					port->socket_id);
1431ce8d5614SIntel 			/* configure port */
1432ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1433ce8d5614SIntel 						&(port->dev_conf));
1434ce8d5614SIntel 			if (diag != 0) {
1435ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1436ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1437ce8d5614SIntel 					printf("Port %d can not be set back "
1438ce8d5614SIntel 							"to stopped\n", pi);
1439ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1440ce8d5614SIntel 				/* try to reconfigure port next time */
1441ce8d5614SIntel 				port->need_reconfig = 1;
1442148f963fSBruce Richardson 				return -1;
1443ce8d5614SIntel 			}
1444ce8d5614SIntel 		}
1445ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1446ce8d5614SIntel 			port->need_reconfig_queues = 0;
1447ce8d5614SIntel 			/* setup tx queues */
1448ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1449b6ea6408SIntel 				if ((numa_support) &&
1450b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1451b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1452b6ea6408SIntel 						nb_txd,txring_numa[pi],
1453b6ea6408SIntel 						&(port->tx_conf));
1454b6ea6408SIntel 				else
1455b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1456b6ea6408SIntel 						nb_txd,port->socket_id,
1457b6ea6408SIntel 						&(port->tx_conf));
1458b6ea6408SIntel 
1459ce8d5614SIntel 				if (diag == 0)
1460ce8d5614SIntel 					continue;
1461ce8d5614SIntel 
1462ce8d5614SIntel 				/* Fail to setup tx queue, return */
1463ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1464ce8d5614SIntel 							RTE_PORT_HANDLING,
1465ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1466ce8d5614SIntel 					printf("Port %d can not be set back "
1467ce8d5614SIntel 							"to stopped\n", pi);
1468ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1469ce8d5614SIntel 				/* try to reconfigure queues next time */
1470ce8d5614SIntel 				port->need_reconfig_queues = 1;
1471148f963fSBruce Richardson 				return -1;
1472ce8d5614SIntel 			}
1473ce8d5614SIntel 			/* setup rx queues */
1474ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1475b6ea6408SIntel 				if ((numa_support) &&
1476b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1477b6ea6408SIntel 					struct rte_mempool * mp =
1478b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1479b6ea6408SIntel 					if (mp == NULL) {
1480b6ea6408SIntel 						printf("Failed to setup RX queue:"
1481b6ea6408SIntel 							"No mempool allocation"
1482b6ea6408SIntel 							" on the socket %d\n",
1483b6ea6408SIntel 							rxring_numa[pi]);
1484148f963fSBruce Richardson 						return -1;
1485b6ea6408SIntel 					}
1486b6ea6408SIntel 
1487b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1488b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1489b6ea6408SIntel 					     &(port->rx_conf),mp);
14901e1d6bddSBernard Iremonger 				} else {
14911e1d6bddSBernard Iremonger 					struct rte_mempool *mp =
14921e1d6bddSBernard Iremonger 						mbuf_pool_find(port->socket_id);
14931e1d6bddSBernard Iremonger 					if (mp == NULL) {
14941e1d6bddSBernard Iremonger 						printf("Failed to setup RX queue:"
14951e1d6bddSBernard Iremonger 							"No mempool allocation"
14961e1d6bddSBernard Iremonger 							" on the socket %d\n",
14971e1d6bddSBernard Iremonger 							port->socket_id);
14981e1d6bddSBernard Iremonger 						return -1;
1499b6ea6408SIntel 					}
1500b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1501b6ea6408SIntel 					     nb_rxd,port->socket_id,
15021e1d6bddSBernard Iremonger 					     &(port->rx_conf), mp);
15031e1d6bddSBernard Iremonger 				}
1504ce8d5614SIntel 				if (diag == 0)
1505ce8d5614SIntel 					continue;
1506ce8d5614SIntel 
1507ce8d5614SIntel 				/* Fail to setup rx queue, return */
1508ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1509ce8d5614SIntel 							RTE_PORT_HANDLING,
1510ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1511ce8d5614SIntel 					printf("Port %d can not be set back "
1512ce8d5614SIntel 							"to stopped\n", pi);
1513ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1514ce8d5614SIntel 				/* try to reconfigure queues next time */
1515ce8d5614SIntel 				port->need_reconfig_queues = 1;
1516148f963fSBruce Richardson 				return -1;
1517ce8d5614SIntel 			}
1518ce8d5614SIntel 		}
151976ad4a2dSGaetan Rivet 
152076ad4a2dSGaetan Rivet 		for (event_type = RTE_ETH_EVENT_UNKNOWN;
152176ad4a2dSGaetan Rivet 		     event_type < RTE_ETH_EVENT_MAX;
152276ad4a2dSGaetan Rivet 		     event_type++) {
152376ad4a2dSGaetan Rivet 			diag = rte_eth_dev_callback_register(pi,
152476ad4a2dSGaetan Rivet 							event_type,
152576ad4a2dSGaetan Rivet 							eth_event_callback,
152676ad4a2dSGaetan Rivet 							NULL);
152776ad4a2dSGaetan Rivet 			if (diag) {
152876ad4a2dSGaetan Rivet 				printf("Failed to setup even callback for event %d\n",
152976ad4a2dSGaetan Rivet 					event_type);
153076ad4a2dSGaetan Rivet 				return -1;
153176ad4a2dSGaetan Rivet 			}
153276ad4a2dSGaetan Rivet 		}
153376ad4a2dSGaetan Rivet 
1534ce8d5614SIntel 		/* start port */
1535ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1536ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1537ce8d5614SIntel 
1538ce8d5614SIntel 			/* Fail to setup rx queue, return */
1539ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1540ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1541ce8d5614SIntel 				printf("Port %d can not be set back to "
1542ce8d5614SIntel 							"stopped\n", pi);
1543ce8d5614SIntel 			continue;
1544ce8d5614SIntel 		}
1545ce8d5614SIntel 
1546ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1547ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1548ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1549ce8d5614SIntel 
15502950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1551d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
15522950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
15532950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
15542950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1555d8c89163SZijie Pan 
1556ce8d5614SIntel 		/* at least one port started, need checking link status */
1557ce8d5614SIntel 		need_check_link_status = 1;
1558ce8d5614SIntel 	}
1559ce8d5614SIntel 
156092d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1561edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
156292d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1563ce8d5614SIntel 		printf("Please stop the ports first\n");
1564ce8d5614SIntel 
1565ce8d5614SIntel 	printf("Done\n");
1566148f963fSBruce Richardson 	return 0;
1567ce8d5614SIntel }
1568ce8d5614SIntel 
1569ce8d5614SIntel void
1570ce8d5614SIntel stop_port(portid_t pid)
1571ce8d5614SIntel {
1572ce8d5614SIntel 	portid_t pi;
1573ce8d5614SIntel 	struct rte_port *port;
1574ce8d5614SIntel 	int need_check_link_status = 0;
1575ce8d5614SIntel 
1576ce8d5614SIntel 	if (dcb_test) {
1577ce8d5614SIntel 		dcb_test = 0;
1578ce8d5614SIntel 		dcb_config = 0;
1579ce8d5614SIntel 	}
15804468635fSMichael Qiu 
15814468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
15824468635fSMichael Qiu 		return;
15834468635fSMichael Qiu 
1584ce8d5614SIntel 	printf("Stopping ports...\n");
1585ce8d5614SIntel 
15867d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
15874468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1588ce8d5614SIntel 			continue;
1589ce8d5614SIntel 
1590a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1591a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1592a8ef3e3aSBernard Iremonger 			continue;
1593a8ef3e3aSBernard Iremonger 		}
1594a8ef3e3aSBernard Iremonger 
15950e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
15960e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
15970e545d30SBernard Iremonger 			continue;
15980e545d30SBernard Iremonger 		}
15990e545d30SBernard Iremonger 
1600ce8d5614SIntel 		port = &ports[pi];
1601ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1602ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1603ce8d5614SIntel 			continue;
1604ce8d5614SIntel 
1605ce8d5614SIntel 		rte_eth_dev_stop(pi);
1606ce8d5614SIntel 
1607ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1608ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1609ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1610ce8d5614SIntel 		need_check_link_status = 1;
1611ce8d5614SIntel 	}
1612bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1613edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1614ce8d5614SIntel 
1615ce8d5614SIntel 	printf("Done\n");
1616ce8d5614SIntel }
1617ce8d5614SIntel 
1618ce8d5614SIntel void
1619ce8d5614SIntel close_port(portid_t pid)
1620ce8d5614SIntel {
1621ce8d5614SIntel 	portid_t pi;
1622ce8d5614SIntel 	struct rte_port *port;
1623ce8d5614SIntel 
16244468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
16254468635fSMichael Qiu 		return;
16264468635fSMichael Qiu 
1627ce8d5614SIntel 	printf("Closing ports...\n");
1628ce8d5614SIntel 
16297d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16304468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1631ce8d5614SIntel 			continue;
1632ce8d5614SIntel 
1633a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1634a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1635a8ef3e3aSBernard Iremonger 			continue;
1636a8ef3e3aSBernard Iremonger 		}
1637a8ef3e3aSBernard Iremonger 
16380e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16390e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16400e545d30SBernard Iremonger 			continue;
16410e545d30SBernard Iremonger 		}
16420e545d30SBernard Iremonger 
1643ce8d5614SIntel 		port = &ports[pi];
1644ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1645d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1646d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1647d4e8ad64SMichael Qiu 			continue;
1648d4e8ad64SMichael Qiu 		}
1649d4e8ad64SMichael Qiu 
1650d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1651ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1652ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1653ce8d5614SIntel 			continue;
1654ce8d5614SIntel 		}
1655ce8d5614SIntel 
1656938a184aSAdrien Mazarguil 		if (port->flow_list)
1657938a184aSAdrien Mazarguil 			port_flow_flush(pi);
1658ce8d5614SIntel 		rte_eth_dev_close(pi);
1659ce8d5614SIntel 
1660ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1661ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1662b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1663ce8d5614SIntel 	}
1664ce8d5614SIntel 
1665ce8d5614SIntel 	printf("Done\n");
1666ce8d5614SIntel }
1667ce8d5614SIntel 
1668edab33b1STetsuya Mukawa void
1669edab33b1STetsuya Mukawa attach_port(char *identifier)
1670ce8d5614SIntel {
1671ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1672931126baSBernard Iremonger 	unsigned int socket_id;
1673ce8d5614SIntel 
1674edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1675edab33b1STetsuya Mukawa 
1676edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1677edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1678edab33b1STetsuya Mukawa 		return;
1679ce8d5614SIntel 	}
1680ce8d5614SIntel 
1681edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1682edab33b1STetsuya Mukawa 		return;
1683edab33b1STetsuya Mukawa 
1684931126baSBernard Iremonger 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1685931126baSBernard Iremonger 	/* if socket_id is invalid, set to 0 */
1686931126baSBernard Iremonger 	if (check_socket_id(socket_id) < 0)
1687931126baSBernard Iremonger 		socket_id = 0;
1688931126baSBernard Iremonger 	reconfig(pi, socket_id);
1689edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1690edab33b1STetsuya Mukawa 
1691edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1692edab33b1STetsuya Mukawa 
1693edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1694edab33b1STetsuya Mukawa 
1695edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1696edab33b1STetsuya Mukawa 	printf("Done\n");
1697edab33b1STetsuya Mukawa }
1698edab33b1STetsuya Mukawa 
1699edab33b1STetsuya Mukawa void
1700edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
17015f4ec54fSChen Jing D(Mark) {
1702edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
17035f4ec54fSChen Jing D(Mark) 
1704edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
17055f4ec54fSChen Jing D(Mark) 
1706edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1707edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1708edab33b1STetsuya Mukawa 		return;
1709edab33b1STetsuya Mukawa 	}
1710edab33b1STetsuya Mukawa 
1711938a184aSAdrien Mazarguil 	if (ports[port_id].flow_list)
1712938a184aSAdrien Mazarguil 		port_flow_flush(port_id);
1713938a184aSAdrien Mazarguil 
1714edab33b1STetsuya Mukawa 	if (rte_eth_dev_detach(port_id, name))
1715edab33b1STetsuya Mukawa 		return;
1716edab33b1STetsuya Mukawa 
1717edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1718edab33b1STetsuya Mukawa 
1719edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1720edab33b1STetsuya Mukawa 			name, nb_ports);
1721edab33b1STetsuya Mukawa 	printf("Done\n");
1722edab33b1STetsuya Mukawa 	return;
17235f4ec54fSChen Jing D(Mark) }
17245f4ec54fSChen Jing D(Mark) 
1725af75078fSIntel void
1726af75078fSIntel pmd_test_exit(void)
1727af75078fSIntel {
1728af75078fSIntel 	portid_t pt_id;
1729af75078fSIntel 
17308210ec25SPablo de Lara 	if (test_done == 0)
17318210ec25SPablo de Lara 		stop_packet_forwarding();
17328210ec25SPablo de Lara 
1733d3a274ceSZhihong Wang 	if (ports != NULL) {
1734d3a274ceSZhihong Wang 		no_link_check = 1;
17357d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(pt_id) {
1736d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1737af75078fSIntel 			fflush(stdout);
1738d3a274ceSZhihong Wang 			stop_port(pt_id);
1739d3a274ceSZhihong Wang 			close_port(pt_id);
1740af75078fSIntel 		}
1741d3a274ceSZhihong Wang 	}
1742d3a274ceSZhihong Wang 	printf("\nBye...\n");
1743af75078fSIntel }
1744af75078fSIntel 
1745af75078fSIntel typedef void (*cmd_func_t)(void);
1746af75078fSIntel struct pmd_test_command {
1747af75078fSIntel 	const char *cmd_name;
1748af75078fSIntel 	cmd_func_t cmd_func;
1749af75078fSIntel };
1750af75078fSIntel 
1751af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1752af75078fSIntel 
1753ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1754af75078fSIntel static void
1755edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1756af75078fSIntel {
1757ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1758ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1759ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1760ce8d5614SIntel 	struct rte_eth_link link;
1761ce8d5614SIntel 
1762ce8d5614SIntel 	printf("Checking link statuses...\n");
1763ce8d5614SIntel 	fflush(stdout);
1764ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1765ce8d5614SIntel 		all_ports_up = 1;
17667d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(portid) {
1767ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1768ce8d5614SIntel 				continue;
1769ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1770ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1771ce8d5614SIntel 			/* print link status if flag set */
1772ce8d5614SIntel 			if (print_flag == 1) {
1773ce8d5614SIntel 				if (link.link_status)
1774ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1775ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1776ce8d5614SIntel 						(unsigned)link.link_speed,
1777ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1778ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1779ce8d5614SIntel 				else
1780ce8d5614SIntel 					printf("Port %d Link Down\n",
1781ce8d5614SIntel 						(uint8_t)portid);
1782ce8d5614SIntel 				continue;
1783ce8d5614SIntel 			}
1784ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
178509419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1786ce8d5614SIntel 				all_ports_up = 0;
1787ce8d5614SIntel 				break;
1788ce8d5614SIntel 			}
1789ce8d5614SIntel 		}
1790ce8d5614SIntel 		/* after finally printing all link status, get out */
1791ce8d5614SIntel 		if (print_flag == 1)
1792ce8d5614SIntel 			break;
1793ce8d5614SIntel 
1794ce8d5614SIntel 		if (all_ports_up == 0) {
1795ce8d5614SIntel 			fflush(stdout);
1796ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1797ce8d5614SIntel 		}
1798ce8d5614SIntel 
1799ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1800ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1801ce8d5614SIntel 			print_flag = 1;
1802ce8d5614SIntel 		}
18038ea656f8SGaetan Rivet 
18048ea656f8SGaetan Rivet 		if (lsc_interrupt)
18058ea656f8SGaetan Rivet 			break;
1806ce8d5614SIntel 	}
1807af75078fSIntel }
1808af75078fSIntel 
1809284c908cSGaetan Rivet static void
1810284c908cSGaetan Rivet rmv_event_callback(void *arg)
1811284c908cSGaetan Rivet {
1812284c908cSGaetan Rivet 	struct rte_eth_dev *dev;
1813284c908cSGaetan Rivet 	struct rte_devargs *da;
1814284c908cSGaetan Rivet 	char name[32] = "";
1815284c908cSGaetan Rivet 	uint8_t port_id = (intptr_t)arg;
1816284c908cSGaetan Rivet 
1817284c908cSGaetan Rivet 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
1818284c908cSGaetan Rivet 	dev = &rte_eth_devices[port_id];
1819284c908cSGaetan Rivet 	da = dev->device->devargs;
1820284c908cSGaetan Rivet 
1821284c908cSGaetan Rivet 	stop_port(port_id);
1822284c908cSGaetan Rivet 	close_port(port_id);
1823284c908cSGaetan Rivet 	if (da->type == RTE_DEVTYPE_VIRTUAL)
1824284c908cSGaetan Rivet 		snprintf(name, sizeof(name), "%s", da->virt.drv_name);
1825284c908cSGaetan Rivet 	else if (da->type == RTE_DEVTYPE_WHITELISTED_PCI)
18263dcfe039SThomas Monjalon 		rte_pci_device_name(&da->pci.addr, name, sizeof(name));
1827284c908cSGaetan Rivet 	printf("removing device %s\n", name);
1828cbb4c648SJan Blunck 	rte_eal_dev_detach(dev->device);
1829284c908cSGaetan Rivet 	dev->state = RTE_ETH_DEV_UNUSED;
1830284c908cSGaetan Rivet }
1831284c908cSGaetan Rivet 
183276ad4a2dSGaetan Rivet /* This function is used by the interrupt thread */
1833d6af1a13SBernard Iremonger static int
1834d6af1a13SBernard Iremonger eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param,
1835d6af1a13SBernard Iremonger 		  void *ret_param)
183676ad4a2dSGaetan Rivet {
183776ad4a2dSGaetan Rivet 	static const char * const event_desc[] = {
183876ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
183976ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
184076ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
184176ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
184276ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
184376ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
184476ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
184576ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MAX] = NULL,
184676ad4a2dSGaetan Rivet 	};
184776ad4a2dSGaetan Rivet 
184876ad4a2dSGaetan Rivet 	RTE_SET_USED(param);
1849d6af1a13SBernard Iremonger 	RTE_SET_USED(ret_param);
185076ad4a2dSGaetan Rivet 
185176ad4a2dSGaetan Rivet 	if (type >= RTE_ETH_EVENT_MAX) {
185276ad4a2dSGaetan Rivet 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
185376ad4a2dSGaetan Rivet 			port_id, __func__, type);
185476ad4a2dSGaetan Rivet 		fflush(stderr);
18553af72783SGaetan Rivet 	} else if (event_print_mask & (UINT32_C(1) << type)) {
185676ad4a2dSGaetan Rivet 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
185776ad4a2dSGaetan Rivet 			event_desc[type]);
185876ad4a2dSGaetan Rivet 		fflush(stdout);
185976ad4a2dSGaetan Rivet 	}
1860284c908cSGaetan Rivet 
1861284c908cSGaetan Rivet 	switch (type) {
1862284c908cSGaetan Rivet 	case RTE_ETH_EVENT_INTR_RMV:
1863284c908cSGaetan Rivet 		if (rte_eal_alarm_set(100000,
1864284c908cSGaetan Rivet 				rmv_event_callback, (void *)(intptr_t)port_id))
1865284c908cSGaetan Rivet 			fprintf(stderr, "Could not set up deferred device removal\n");
1866284c908cSGaetan Rivet 		break;
1867284c908cSGaetan Rivet 	default:
1868284c908cSGaetan Rivet 		break;
1869284c908cSGaetan Rivet 	}
1870d6af1a13SBernard Iremonger 	return 0;
187176ad4a2dSGaetan Rivet }
187276ad4a2dSGaetan Rivet 
1873013af9b6SIntel static int
1874013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1875af75078fSIntel {
1876013af9b6SIntel 	uint16_t i;
1877af75078fSIntel 	int diag;
1878013af9b6SIntel 	uint8_t mapping_found = 0;
1879af75078fSIntel 
1880013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1881013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1882013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1883013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1884013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1885013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1886013af9b6SIntel 			if (diag != 0)
1887013af9b6SIntel 				return diag;
1888013af9b6SIntel 			mapping_found = 1;
1889af75078fSIntel 		}
1890013af9b6SIntel 	}
1891013af9b6SIntel 	if (mapping_found)
1892013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1893013af9b6SIntel 	return 0;
1894013af9b6SIntel }
1895013af9b6SIntel 
1896013af9b6SIntel static int
1897013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1898013af9b6SIntel {
1899013af9b6SIntel 	uint16_t i;
1900013af9b6SIntel 	int diag;
1901013af9b6SIntel 	uint8_t mapping_found = 0;
1902013af9b6SIntel 
1903013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1904013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1905013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1906013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1907013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1908013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1909013af9b6SIntel 			if (diag != 0)
1910013af9b6SIntel 				return diag;
1911013af9b6SIntel 			mapping_found = 1;
1912013af9b6SIntel 		}
1913013af9b6SIntel 	}
1914013af9b6SIntel 	if (mapping_found)
1915013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1916013af9b6SIntel 	return 0;
1917013af9b6SIntel }
1918013af9b6SIntel 
1919013af9b6SIntel static void
1920013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1921013af9b6SIntel {
1922013af9b6SIntel 	int diag = 0;
1923013af9b6SIntel 
1924013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1925af75078fSIntel 	if (diag != 0) {
1926013af9b6SIntel 		if (diag == -ENOTSUP) {
1927013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1928013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1929013af9b6SIntel 		}
1930013af9b6SIntel 		else
1931013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1932013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1933013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1934af75078fSIntel 					pi, diag);
1935af75078fSIntel 	}
1936013af9b6SIntel 
1937013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1938af75078fSIntel 	if (diag != 0) {
1939013af9b6SIntel 		if (diag == -ENOTSUP) {
1940013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1941013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1942013af9b6SIntel 		}
1943013af9b6SIntel 		else
1944013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1945013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1946013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1947af75078fSIntel 					pi, diag);
1948af75078fSIntel 	}
1949af75078fSIntel }
1950af75078fSIntel 
1951f2c5125aSPablo de Lara static void
1952f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1953f2c5125aSPablo de Lara {
1954f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1955f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1956f2c5125aSPablo de Lara 
1957f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1958f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1959f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1960f2c5125aSPablo de Lara 
1961f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1962f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1963f2c5125aSPablo de Lara 
1964f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1965f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1966f2c5125aSPablo de Lara 
1967f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1968f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1969f2c5125aSPablo de Lara 
1970f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1971f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1972f2c5125aSPablo de Lara 
1973f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1974f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1975f2c5125aSPablo de Lara 
1976f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1977f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1978f2c5125aSPablo de Lara 
1979f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1980f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1981f2c5125aSPablo de Lara 
1982f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1983f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1984f2c5125aSPablo de Lara 
1985f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1986f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
1987f2c5125aSPablo de Lara 
1988f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
1989f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
1990f2c5125aSPablo de Lara }
1991f2c5125aSPablo de Lara 
1992013af9b6SIntel void
1993013af9b6SIntel init_port_config(void)
1994013af9b6SIntel {
1995013af9b6SIntel 	portid_t pid;
1996013af9b6SIntel 	struct rte_port *port;
1997013af9b6SIntel 
19987d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
1999013af9b6SIntel 		port = &ports[pid];
2000013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
2001013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
20023ce690d3SBruce Richardson 		if (nb_rxq > 1) {
2003013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2004013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2005af75078fSIntel 		} else {
2006013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2007013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2008af75078fSIntel 		}
20093ce690d3SBruce Richardson 
20105f592039SJingjing Wu 		if (port->dcb_flag == 0) {
20113ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
20123ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
20133ce690d3SBruce Richardson 			else
20143ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
20153ce690d3SBruce Richardson 		}
20163ce690d3SBruce Richardson 
2017f2c5125aSPablo de Lara 		rxtx_port_config(port);
2018013af9b6SIntel 
2019013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
2020013af9b6SIntel 
2021013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
202250c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2023e261265eSRadu Nicolau 		rte_pmd_ixgbe_bypass_init(pid);
20247b7e5ba7SIntel #endif
20258ea656f8SGaetan Rivet 
20268ea656f8SGaetan Rivet 		if (lsc_interrupt &&
20278ea656f8SGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
20288ea656f8SGaetan Rivet 		     RTE_ETH_DEV_INTR_LSC))
20298ea656f8SGaetan Rivet 			port->dev_conf.intr_conf.lsc = 1;
2030284c908cSGaetan Rivet 		if (rmv_interrupt &&
2031284c908cSGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
2032284c908cSGaetan Rivet 		     RTE_ETH_DEV_INTR_RMV))
2033284c908cSGaetan Rivet 			port->dev_conf.intr_conf.rmv = 1;
2034013af9b6SIntel 	}
2035013af9b6SIntel }
2036013af9b6SIntel 
203741b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
203841b05095SBernard Iremonger {
203941b05095SBernard Iremonger 	struct rte_port *port;
204041b05095SBernard Iremonger 
204141b05095SBernard Iremonger 	port = &ports[slave_pid];
204241b05095SBernard Iremonger 	port->slave_flag = 1;
204341b05095SBernard Iremonger }
204441b05095SBernard Iremonger 
204541b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
204641b05095SBernard Iremonger {
204741b05095SBernard Iremonger 	struct rte_port *port;
204841b05095SBernard Iremonger 
204941b05095SBernard Iremonger 	port = &ports[slave_pid];
205041b05095SBernard Iremonger 	port->slave_flag = 0;
205141b05095SBernard Iremonger }
205241b05095SBernard Iremonger 
20530e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
20540e545d30SBernard Iremonger {
20550e545d30SBernard Iremonger 	struct rte_port *port;
20560e545d30SBernard Iremonger 
20570e545d30SBernard Iremonger 	port = &ports[slave_pid];
20580e545d30SBernard Iremonger 	return port->slave_flag;
20590e545d30SBernard Iremonger }
20600e545d30SBernard Iremonger 
2061013af9b6SIntel const uint16_t vlan_tags[] = {
2062013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
2063013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
2064013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
2065013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
2066013af9b6SIntel };
2067013af9b6SIntel 
2068013af9b6SIntel static  int
20691a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
20701a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
20711a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
20721a572499SJingjing Wu 		 uint8_t pfc_en)
2073013af9b6SIntel {
2074013af9b6SIntel 	uint8_t i;
2075af75078fSIntel 
2076af75078fSIntel 	/*
2077013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2078013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
2079af75078fSIntel 	 */
20801a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
20811a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
20821a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
20831a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
20841a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2085013af9b6SIntel 
2086547d946cSNirmoy Das 		/* VMDQ+DCB RX and TX configurations */
20871a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
20881a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
20891a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
20901a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
20911a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
20921a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2093013af9b6SIntel 
20941a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
20951a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
20961a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
20971a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
20981a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2099af75078fSIntel 		}
2100013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
21011a572499SJingjing Wu 			vmdq_rx_conf->dcb_tc[i] = i;
21021a572499SJingjing Wu 			vmdq_tx_conf->dcb_tc[i] = i;
2103013af9b6SIntel 		}
2104013af9b6SIntel 
2105013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
210632e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
210732e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
21081a572499SJingjing Wu 	} else {
21091a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
21101a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
21111a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
21121a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2113013af9b6SIntel 
21141a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
21151a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
21161a572499SJingjing Wu 
2117bcd0e432SJingjing Wu 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2118bcd0e432SJingjing Wu 			rx_conf->dcb_tc[i] = i % num_tcs;
2119bcd0e432SJingjing Wu 			tx_conf->dcb_tc[i] = i % num_tcs;
2120013af9b6SIntel 		}
21211a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
21221a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
212332e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
21241a572499SJingjing Wu 	}
21251a572499SJingjing Wu 
21261a572499SJingjing Wu 	if (pfc_en)
21271a572499SJingjing Wu 		eth_conf->dcb_capability_en =
21281a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2129013af9b6SIntel 	else
2130013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2131013af9b6SIntel 
2132013af9b6SIntel 	return 0;
2133013af9b6SIntel }
2134013af9b6SIntel 
2135013af9b6SIntel int
21361a572499SJingjing Wu init_port_dcb_config(portid_t pid,
21371a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
21381a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
21391a572499SJingjing Wu 		     uint8_t pfc_en)
2140013af9b6SIntel {
2141013af9b6SIntel 	struct rte_eth_conf port_conf;
2142013af9b6SIntel 	struct rte_port *rte_port;
2143013af9b6SIntel 	int retval;
2144013af9b6SIntel 	uint16_t i;
2145013af9b6SIntel 
21462a977b89SWenzhuo Lu 	rte_port = &ports[pid];
2147013af9b6SIntel 
2148013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2149013af9b6SIntel 	/* Enter DCB configuration status */
2150013af9b6SIntel 	dcb_config = 1;
2151013af9b6SIntel 
2152013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
21531a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2154013af9b6SIntel 	if (retval < 0)
2155013af9b6SIntel 		return retval;
21562a977b89SWenzhuo Lu 	port_conf.rxmode.hw_vlan_filter = 1;
2157013af9b6SIntel 
21582a977b89SWenzhuo Lu 	/**
21592a977b89SWenzhuo Lu 	 * Write the configuration into the device.
21602a977b89SWenzhuo Lu 	 * Set the numbers of RX & TX queues to 0, so
21612a977b89SWenzhuo Lu 	 * the RX & TX queues will not be setup.
21622a977b89SWenzhuo Lu 	 */
21632a977b89SWenzhuo Lu 	(void)rte_eth_dev_configure(pid, 0, 0, &port_conf);
21642a977b89SWenzhuo Lu 
21652a977b89SWenzhuo Lu 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
21662a977b89SWenzhuo Lu 
21672a977b89SWenzhuo Lu 	/* If dev_info.vmdq_pool_base is greater than 0,
21682a977b89SWenzhuo Lu 	 * the queue id of vmdq pools is started after pf queues.
21692a977b89SWenzhuo Lu 	 */
21702a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED &&
21712a977b89SWenzhuo Lu 	    rte_port->dev_info.vmdq_pool_base > 0) {
21722a977b89SWenzhuo Lu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
21732a977b89SWenzhuo Lu 			" for port %d.", pid);
21742a977b89SWenzhuo Lu 		return -1;
21752a977b89SWenzhuo Lu 	}
21762a977b89SWenzhuo Lu 
21772a977b89SWenzhuo Lu 	/* Assume the ports in testpmd have the same dcb capability
21782a977b89SWenzhuo Lu 	 * and has the same number of rxq and txq in dcb mode
21792a977b89SWenzhuo Lu 	 */
21802a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED) {
218186ef65eeSBernard Iremonger 		if (rte_port->dev_info.max_vfs > 0) {
218286ef65eeSBernard Iremonger 			nb_rxq = rte_port->dev_info.nb_rx_queues;
218386ef65eeSBernard Iremonger 			nb_txq = rte_port->dev_info.nb_tx_queues;
218486ef65eeSBernard Iremonger 		} else {
21852a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
21862a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
218786ef65eeSBernard Iremonger 		}
21882a977b89SWenzhuo Lu 	} else {
21892a977b89SWenzhuo Lu 		/*if vt is disabled, use all pf queues */
21902a977b89SWenzhuo Lu 		if (rte_port->dev_info.vmdq_pool_base == 0) {
21912a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
21922a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
21932a977b89SWenzhuo Lu 		} else {
21942a977b89SWenzhuo Lu 			nb_rxq = (queueid_t)num_tcs;
21952a977b89SWenzhuo Lu 			nb_txq = (queueid_t)num_tcs;
21962a977b89SWenzhuo Lu 
21972a977b89SWenzhuo Lu 		}
21982a977b89SWenzhuo Lu 	}
21992a977b89SWenzhuo Lu 	rx_free_thresh = 64;
22002a977b89SWenzhuo Lu 
2201013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2202013af9b6SIntel 
2203f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
2204013af9b6SIntel 	/* VLAN filter */
2205013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
22061a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2207013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
2208013af9b6SIntel 
2209013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2210013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
2211013af9b6SIntel 
22127741e4cfSIntel 	rte_port->dcb_flag = 1;
22137741e4cfSIntel 
2214013af9b6SIntel 	return 0;
2215af75078fSIntel }
2216af75078fSIntel 
2217ffc468ffSTetsuya Mukawa static void
2218ffc468ffSTetsuya Mukawa init_port(void)
2219ffc468ffSTetsuya Mukawa {
2220ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2221ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2222ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2223ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2224ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2225ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2226ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2227ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2228ffc468ffSTetsuya Mukawa 	}
2229ffc468ffSTetsuya Mukawa }
2230ffc468ffSTetsuya Mukawa 
2231d3a274ceSZhihong Wang static void
2232d3a274ceSZhihong Wang force_quit(void)
2233d3a274ceSZhihong Wang {
2234d3a274ceSZhihong Wang 	pmd_test_exit();
2235d3a274ceSZhihong Wang 	prompt_exit();
2236d3a274ceSZhihong Wang }
2237d3a274ceSZhihong Wang 
2238d3a274ceSZhihong Wang static void
2239*cfea1f30SPablo de Lara print_stats(void)
2240*cfea1f30SPablo de Lara {
2241*cfea1f30SPablo de Lara 	uint8_t i;
2242*cfea1f30SPablo de Lara 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2243*cfea1f30SPablo de Lara 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2244*cfea1f30SPablo de Lara 
2245*cfea1f30SPablo de Lara 	/* Clear screen and move to top left */
2246*cfea1f30SPablo de Lara 	printf("%s%s", clr, top_left);
2247*cfea1f30SPablo de Lara 
2248*cfea1f30SPablo de Lara 	printf("\nPort statistics ====================================");
2249*cfea1f30SPablo de Lara 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2250*cfea1f30SPablo de Lara 		nic_stats_display(fwd_ports_ids[i]);
2251*cfea1f30SPablo de Lara }
2252*cfea1f30SPablo de Lara 
2253*cfea1f30SPablo de Lara static void
2254d3a274ceSZhihong Wang signal_handler(int signum)
2255d3a274ceSZhihong Wang {
2256d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2257d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2258d3a274ceSZhihong Wang 				signum);
2259102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2260102b7329SReshma Pattan 		/* uninitialize packet capture framework */
2261102b7329SReshma Pattan 		rte_pdump_uninit();
2262102b7329SReshma Pattan #endif
226362d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
226462d3216dSReshma Pattan 		rte_latencystats_uninit();
226562d3216dSReshma Pattan #endif
2266d3a274ceSZhihong Wang 		force_quit();
2267d3a274ceSZhihong Wang 		/* exit with the expected status */
2268d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2269d3a274ceSZhihong Wang 		kill(getpid(), signum);
2270d3a274ceSZhihong Wang 	}
2271d3a274ceSZhihong Wang }
2272d3a274ceSZhihong Wang 
2273af75078fSIntel int
2274af75078fSIntel main(int argc, char** argv)
2275af75078fSIntel {
2276af75078fSIntel 	int  diag;
2277013af9b6SIntel 	uint8_t port_id;
2278af75078fSIntel 
2279d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2280d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2281d3a274ceSZhihong Wang 
2282af75078fSIntel 	diag = rte_eal_init(argc, argv);
2283af75078fSIntel 	if (diag < 0)
2284af75078fSIntel 		rte_panic("Cannot init EAL\n");
2285af75078fSIntel 
2286102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2287102b7329SReshma Pattan 	/* initialize packet capture framework */
2288102b7329SReshma Pattan 	rte_pdump_init(NULL);
2289102b7329SReshma Pattan #endif
2290102b7329SReshma Pattan 
2291af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2292af75078fSIntel 	if (nb_ports == 0)
2293edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2294af75078fSIntel 
2295ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2296ffc468ffSTetsuya Mukawa 	init_port();
2297ffc468ffSTetsuya Mukawa 
2298af75078fSIntel 	set_def_fwd_config();
2299af75078fSIntel 	if (nb_lcores == 0)
2300af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2301af75078fSIntel 			  "core mask supplied in the command parameters\n");
2302af75078fSIntel 
230365eb1e54SPablo de Lara 	/* Bitrate/latency stats disabled by default */
230430bcc68cSPablo de Lara #ifdef RTE_LIBRTE_BITRATE
2305e25e6c70SRemy Horton 	bitrate_enabled = 0;
230630bcc68cSPablo de Lara #endif
230765eb1e54SPablo de Lara #ifdef RTE_LIBRTE_LATENCY_STATS
230865eb1e54SPablo de Lara 	latencystats_enabled = 0;
230965eb1e54SPablo de Lara #endif
2310e25e6c70SRemy Horton 
2311af75078fSIntel 	argc -= diag;
2312af75078fSIntel 	argv += diag;
2313af75078fSIntel 	if (argc > 1)
2314af75078fSIntel 		launch_args_parse(argc, argv);
2315af75078fSIntel 
231699cabef0SPablo de Lara 	if (tx_first && interactive)
231799cabef0SPablo de Lara 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
231899cabef0SPablo de Lara 				"interactive mode.\n");
23195a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
23205a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
23215a8fb55cSReshma Pattan 
23225a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2323af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2324af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2325af75078fSIntel 		       nb_rxq, nb_txq);
2326af75078fSIntel 
2327af75078fSIntel 	init_config();
2328148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2329148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2330af75078fSIntel 
2331ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
23327d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(port_id)
2333ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2334af75078fSIntel 
23357e4441c8SRemy Horton 	/* Init metrics library */
23367e4441c8SRemy Horton 	rte_metrics_init(rte_socket_id());
23377e4441c8SRemy Horton 
233862d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
233962d3216dSReshma Pattan 	if (latencystats_enabled != 0) {
234062d3216dSReshma Pattan 		int ret = rte_latencystats_init(1, NULL);
234162d3216dSReshma Pattan 		if (ret)
234262d3216dSReshma Pattan 			printf("Warning: latencystats init()"
234362d3216dSReshma Pattan 				" returned error %d\n",	ret);
234462d3216dSReshma Pattan 		printf("Latencystats running on lcore %d\n",
234562d3216dSReshma Pattan 			latencystats_lcore_id);
234662d3216dSReshma Pattan 	}
234762d3216dSReshma Pattan #endif
234862d3216dSReshma Pattan 
23497e4441c8SRemy Horton 	/* Setup bitrate stats */
23507e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
2351e25e6c70SRemy Horton 	if (bitrate_enabled != 0) {
23527e4441c8SRemy Horton 		bitrate_data = rte_stats_bitrate_create();
23537e4441c8SRemy Horton 		if (bitrate_data == NULL)
2354e25e6c70SRemy Horton 			rte_exit(EXIT_FAILURE,
2355e25e6c70SRemy Horton 				"Could not allocate bitrate data.\n");
23567e4441c8SRemy Horton 		rte_stats_bitrate_reg(bitrate_data);
2357e25e6c70SRemy Horton 	}
23587e4441c8SRemy Horton #endif
23597e4441c8SRemy Horton 
23600d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
236181ef862bSAllain Legacy 	if (strlen(cmdline_filename) != 0)
236281ef862bSAllain Legacy 		cmdline_read_from_file(cmdline_filename);
236381ef862bSAllain Legacy 
2364ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2365ca7feb22SCyril Chemparathy 		if (auto_start) {
2366ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2367ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2368ca7feb22SCyril Chemparathy 		}
2369af75078fSIntel 		prompt();
23700de738cfSJiayu Hu 		pmd_test_exit();
2371ca7feb22SCyril Chemparathy 	} else
23720d56cb81SThomas Monjalon #endif
23730d56cb81SThomas Monjalon 	{
2374af75078fSIntel 		char c;
2375af75078fSIntel 		int rc;
2376af75078fSIntel 
2377af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
237899cabef0SPablo de Lara 		start_packet_forwarding(tx_first);
2379*cfea1f30SPablo de Lara 		if (stats_period != 0) {
2380*cfea1f30SPablo de Lara 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2381*cfea1f30SPablo de Lara 			uint64_t timer_period;
2382*cfea1f30SPablo de Lara 
2383*cfea1f30SPablo de Lara 			/* Convert to number of cycles */
2384*cfea1f30SPablo de Lara 			timer_period = stats_period * rte_get_timer_hz();
2385*cfea1f30SPablo de Lara 
2386*cfea1f30SPablo de Lara 			while (1) {
2387*cfea1f30SPablo de Lara 				cur_time = rte_get_timer_cycles();
2388*cfea1f30SPablo de Lara 				diff_time += cur_time - prev_time;
2389*cfea1f30SPablo de Lara 
2390*cfea1f30SPablo de Lara 				if (diff_time >= timer_period) {
2391*cfea1f30SPablo de Lara 					print_stats();
2392*cfea1f30SPablo de Lara 					/* Reset the timer */
2393*cfea1f30SPablo de Lara 					diff_time = 0;
2394*cfea1f30SPablo de Lara 				}
2395*cfea1f30SPablo de Lara 				/* Sleep to avoid unnecessary checks */
2396*cfea1f30SPablo de Lara 				prev_time = cur_time;
2397*cfea1f30SPablo de Lara 				sleep(1);
2398*cfea1f30SPablo de Lara 			}
2399*cfea1f30SPablo de Lara 		}
2400*cfea1f30SPablo de Lara 
2401af75078fSIntel 		printf("Press enter to exit\n");
2402af75078fSIntel 		rc = read(0, &c, 1);
2403d3a274ceSZhihong Wang 		pmd_test_exit();
2404af75078fSIntel 		if (rc < 0)
2405af75078fSIntel 			return 1;
2406af75078fSIntel 	}
2407af75078fSIntel 
2408af75078fSIntel 	return 0;
2409af75078fSIntel }
2410