xref: /dpdk/app/test-pmd/testpmd.c (revision 3070419e84e578ec7bf1e02555d88b26ce7d9fc2)
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
93b40f8d78SJiayu Hu #include <rte_gro.h>
94af75078fSIntel 
95af75078fSIntel #include "testpmd.h"
96af75078fSIntel 
97af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
98af75078fSIntel 
99af75078fSIntel /* use master core for command line ? */
100af75078fSIntel uint8_t interactive = 0;
101ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
10299cabef0SPablo de Lara uint8_t tx_first;
10381ef862bSAllain Legacy char cmdline_filename[PATH_MAX] = {0};
104af75078fSIntel 
105af75078fSIntel /*
106af75078fSIntel  * NUMA support configuration.
107af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
108af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
109af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
110af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
111af75078fSIntel  */
112999b2ee0SBruce Richardson uint8_t numa_support = 1; /**< numa enabled by default */
113af75078fSIntel 
114af75078fSIntel /*
115b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
116b6ea6408SIntel  * not configured.
117b6ea6408SIntel  */
118b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
119b6ea6408SIntel 
120b6ea6408SIntel /*
121148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
122148f963fSBruce Richardson  */
123148f963fSBruce Richardson uint8_t mp_anon = 0;
124148f963fSBruce Richardson 
125148f963fSBruce Richardson /*
126af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
127af75078fSIntel  * forwarded.
128547d946cSNirmoy Das  * Must be instantiated with the ethernet addresses of peer traffic generator
129af75078fSIntel  * ports.
130af75078fSIntel  */
131af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
132af75078fSIntel portid_t nb_peer_eth_addrs = 0;
133af75078fSIntel 
134af75078fSIntel /*
135af75078fSIntel  * Probed Target Environment.
136af75078fSIntel  */
137af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
138af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
139af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
140af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
141af75078fSIntel 
142af75078fSIntel /*
143af75078fSIntel  * Test Forwarding Configuration.
144af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
145af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
146af75078fSIntel  */
147af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
148af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
149af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
150af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
151af75078fSIntel 
152af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
153af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
154af75078fSIntel 
155af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
156af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
157af75078fSIntel 
158af75078fSIntel /*
159af75078fSIntel  * Forwarding engines.
160af75078fSIntel  */
161af75078fSIntel struct fwd_engine * fwd_engines[] = {
162af75078fSIntel 	&io_fwd_engine,
163af75078fSIntel 	&mac_fwd_engine,
164d47388f1SCyril Chemparathy 	&mac_swap_engine,
165e9e23a61SCyril Chemparathy 	&flow_gen_engine,
166af75078fSIntel 	&rx_only_engine,
167af75078fSIntel 	&tx_only_engine,
168af75078fSIntel 	&csum_fwd_engine,
169168dfa61SIvan Boule 	&icmp_echo_engine,
170af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
171af75078fSIntel 	&ieee1588_fwd_engine,
172af75078fSIntel #endif
173af75078fSIntel 	NULL,
174af75078fSIntel };
175af75078fSIntel 
176af75078fSIntel struct fwd_config cur_fwd_config;
177af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
178bf56fce1SZhihong Wang uint32_t retry_enabled;
179bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
180bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
181af75078fSIntel 
182af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
183c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
184c8798818SIntel                                       * specified on command-line. */
185cfea1f30SPablo de Lara uint16_t stats_period; /**< Period to show statistics (disabled by default) */
186af75078fSIntel /*
187af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
188af75078fSIntel  */
189af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
190af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
191af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
192af75078fSIntel };
193af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
194af75078fSIntel 
19579bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
19679bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
19779bec05bSKonstantin Ananyev 
198af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
199e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
200af75078fSIntel 
201900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
202900550deSIntel uint8_t dcb_config = 0;
203900550deSIntel 
204900550deSIntel /* Whether the dcb is in testing status */
205900550deSIntel uint8_t dcb_test = 0;
206900550deSIntel 
207af75078fSIntel /*
208af75078fSIntel  * Configurable number of RX/TX queues.
209af75078fSIntel  */
210af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
211af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
212af75078fSIntel 
213af75078fSIntel /*
214af75078fSIntel  * Configurable number of RX/TX ring descriptors.
215af75078fSIntel  */
216af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
217af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
218af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
219af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
220af75078fSIntel 
221f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
222af75078fSIntel /*
223af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
224af75078fSIntel  */
225af75078fSIntel 
226f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
227f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
228f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
229af75078fSIntel 
230f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
231f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
232f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
233af75078fSIntel 
234af75078fSIntel /*
235af75078fSIntel  * Configurable value of RX free threshold.
236af75078fSIntel  */
237f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
238af75078fSIntel 
239af75078fSIntel /*
240ce8d5614SIntel  * Configurable value of RX drop enable.
241ce8d5614SIntel  */
242f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
243ce8d5614SIntel 
244ce8d5614SIntel /*
245af75078fSIntel  * Configurable value of TX free threshold.
246af75078fSIntel  */
247f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
248af75078fSIntel 
249af75078fSIntel /*
250af75078fSIntel  * Configurable value of TX RS bit threshold.
251af75078fSIntel  */
252f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
253af75078fSIntel 
254af75078fSIntel /*
255ce8d5614SIntel  * Configurable value of TX queue flags.
256ce8d5614SIntel  */
257f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET;
258ce8d5614SIntel 
259ce8d5614SIntel /*
260af75078fSIntel  * Receive Side Scaling (RSS) configuration.
261af75078fSIntel  */
2628a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
263af75078fSIntel 
264af75078fSIntel /*
265af75078fSIntel  * Port topology configuration
266af75078fSIntel  */
267af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
268af75078fSIntel 
2697741e4cfSIntel /*
2707741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2717741e4cfSIntel  */
2727741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2737741e4cfSIntel 
274af75078fSIntel /*
2757ee3e944SVasily Philipov  * Flow API isolated mode.
2767ee3e944SVasily Philipov  */
2777ee3e944SVasily Philipov uint8_t flow_isolate_all;
2787ee3e944SVasily Philipov 
2797ee3e944SVasily Philipov /*
280bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
281bc202406SDavid Marchand  */
282bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
283bc202406SDavid Marchand 
284bc202406SDavid Marchand /*
2858ea656f8SGaetan Rivet  * Enable link status change notification
2868ea656f8SGaetan Rivet  */
2878ea656f8SGaetan Rivet uint8_t lsc_interrupt = 1; /* enabled by default */
2888ea656f8SGaetan Rivet 
2898ea656f8SGaetan Rivet /*
290284c908cSGaetan Rivet  * Enable device removal notification.
291284c908cSGaetan Rivet  */
292284c908cSGaetan Rivet uint8_t rmv_interrupt = 1; /* enabled by default */
293284c908cSGaetan Rivet 
294284c908cSGaetan Rivet /*
2953af72783SGaetan Rivet  * Display or mask ether events
2963af72783SGaetan Rivet  * Default to all events except VF_MBOX
2973af72783SGaetan Rivet  */
2983af72783SGaetan Rivet uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
2993af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
3003af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
3013af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
3023af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
3033af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
3043af72783SGaetan Rivet 
3053af72783SGaetan Rivet /*
3067b7e5ba7SIntel  * NIC bypass mode configuration options.
3077b7e5ba7SIntel  */
3087b7e5ba7SIntel 
30950c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
3107b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
311e261265eSRadu Nicolau uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
3127b7e5ba7SIntel #endif
3137b7e5ba7SIntel 
314e261265eSRadu Nicolau 
31562d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
31662d3216dSReshma Pattan 
31762d3216dSReshma Pattan /*
31862d3216dSReshma Pattan  * Set when latency stats is enabled in the commandline
31962d3216dSReshma Pattan  */
32062d3216dSReshma Pattan uint8_t latencystats_enabled;
32162d3216dSReshma Pattan 
32262d3216dSReshma Pattan /*
32362d3216dSReshma Pattan  * Lcore ID to serive latency statistics.
32462d3216dSReshma Pattan  */
32562d3216dSReshma Pattan lcoreid_t latencystats_lcore_id = -1;
32662d3216dSReshma Pattan 
32762d3216dSReshma Pattan #endif
32862d3216dSReshma Pattan 
3297b7e5ba7SIntel /*
330af75078fSIntel  * Ethernet device configuration.
331af75078fSIntel  */
332af75078fSIntel struct rte_eth_rxmode rx_mode = {
333af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
334af75078fSIntel 	.split_hdr_size = 0,
335af75078fSIntel 	.header_split   = 0, /**< Header Split disabled. */
336af75078fSIntel 	.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
337af75078fSIntel 	.hw_vlan_filter = 1, /**< VLAN filtering enabled. */
338a47aa8b9SIntel 	.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
339a47aa8b9SIntel 	.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
340af75078fSIntel 	.jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
34179dd163fSJeff Guo 	.hw_strip_crc   = 1, /**< CRC stripping by hardware enabled. */
342af75078fSIntel };
343af75078fSIntel 
344af75078fSIntel struct rte_fdir_conf fdir_conf = {
345af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
346af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
347af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
348d9d5e6f2SJingjing Wu 	.mask = {
349d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
350d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
351d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
352d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
353d9d5e6f2SJingjing Wu 		},
354d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
355d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
356d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
357d9d5e6f2SJingjing Wu 		},
358d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
359d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
36047b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
36147b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
36247b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
363d9d5e6f2SJingjing Wu 	},
364af75078fSIntel 	.drop_queue = 127,
365af75078fSIntel };
366af75078fSIntel 
3672950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
368af75078fSIntel 
369ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
370ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
371ed30d9b6SIntel 
372ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
373ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
374ed30d9b6SIntel 
375ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
376ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
377ed30d9b6SIntel 
378c9cafcc8SShahaf Shuler unsigned int num_sockets = 0;
379c9cafcc8SShahaf Shuler unsigned int socket_ids[RTE_MAX_NUMA_NODES];
3807acf894dSStephen Hurd 
381e25e6c70SRemy Horton #ifdef RTE_LIBRTE_BITRATE
3827e4441c8SRemy Horton /* Bitrate statistics */
3837e4441c8SRemy Horton struct rte_stats_bitrates *bitrate_data;
384e25e6c70SRemy Horton lcoreid_t bitrate_lcore_id;
385e25e6c70SRemy Horton uint8_t bitrate_enabled;
386e25e6c70SRemy Horton #endif
3877e4441c8SRemy Horton 
388b40f8d78SJiayu Hu struct gro_status gro_ports[RTE_MAX_ETHPORTS];
389b40f8d78SJiayu Hu 
390ed30d9b6SIntel /* Forward function declarations */
391ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
392edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
393d6af1a13SBernard Iremonger static int eth_event_callback(uint8_t port_id,
39476ad4a2dSGaetan Rivet 			      enum rte_eth_event_type type,
395d6af1a13SBernard Iremonger 			      void *param, void *ret_param);
396ce8d5614SIntel 
397ce8d5614SIntel /*
398ce8d5614SIntel  * Check if all the ports are started.
399ce8d5614SIntel  * If yes, return positive value. If not, return zero.
400ce8d5614SIntel  */
401ce8d5614SIntel static int all_ports_started(void);
402ed30d9b6SIntel 
403af75078fSIntel /*
40498a7ea33SJerin Jacob  * Helper function to check if socket is already discovered.
405c9cafcc8SShahaf Shuler  * If yes, return positive value. If not, return zero.
406c9cafcc8SShahaf Shuler  */
407c9cafcc8SShahaf Shuler int
408c9cafcc8SShahaf Shuler new_socket_id(unsigned int socket_id)
409c9cafcc8SShahaf Shuler {
410c9cafcc8SShahaf Shuler 	unsigned int i;
411c9cafcc8SShahaf Shuler 
412c9cafcc8SShahaf Shuler 	for (i = 0; i < num_sockets; i++) {
413c9cafcc8SShahaf Shuler 		if (socket_ids[i] == socket_id)
414c9cafcc8SShahaf Shuler 			return 0;
415c9cafcc8SShahaf Shuler 	}
416c9cafcc8SShahaf Shuler 	return 1;
417c9cafcc8SShahaf Shuler }
418c9cafcc8SShahaf Shuler 
419c9cafcc8SShahaf Shuler /*
420af75078fSIntel  * Setup default configuration.
421af75078fSIntel  */
422af75078fSIntel static void
423af75078fSIntel set_default_fwd_lcores_config(void)
424af75078fSIntel {
425af75078fSIntel 	unsigned int i;
426af75078fSIntel 	unsigned int nb_lc;
4277acf894dSStephen Hurd 	unsigned int sock_num;
428af75078fSIntel 
429af75078fSIntel 	nb_lc = 0;
430af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
431c9cafcc8SShahaf Shuler 		sock_num = rte_lcore_to_socket_id(i);
432c9cafcc8SShahaf Shuler 		if (new_socket_id(sock_num)) {
433c9cafcc8SShahaf Shuler 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
434c9cafcc8SShahaf Shuler 				rte_exit(EXIT_FAILURE,
435c9cafcc8SShahaf Shuler 					 "Total sockets greater than %u\n",
436c9cafcc8SShahaf Shuler 					 RTE_MAX_NUMA_NODES);
437c9cafcc8SShahaf Shuler 			}
438c9cafcc8SShahaf Shuler 			socket_ids[num_sockets++] = sock_num;
4397acf894dSStephen Hurd 		}
440f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
441f54fe5eeSStephen Hurd 			continue;
442f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
443f54fe5eeSStephen Hurd 			continue;
444f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
445af75078fSIntel 	}
446af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
447af75078fSIntel 	nb_cfg_lcores = nb_lcores;
448af75078fSIntel 	nb_fwd_lcores = 1;
449af75078fSIntel }
450af75078fSIntel 
451af75078fSIntel static void
452af75078fSIntel set_def_peer_eth_addrs(void)
453af75078fSIntel {
454af75078fSIntel 	portid_t i;
455af75078fSIntel 
456af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
457af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
458af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
459af75078fSIntel 	}
460af75078fSIntel }
461af75078fSIntel 
462af75078fSIntel static void
463af75078fSIntel set_default_fwd_ports_config(void)
464af75078fSIntel {
465af75078fSIntel 	portid_t pt_id;
466af75078fSIntel 
467af75078fSIntel 	for (pt_id = 0; pt_id < nb_ports; pt_id++)
468af75078fSIntel 		fwd_ports_ids[pt_id] = pt_id;
469af75078fSIntel 
470af75078fSIntel 	nb_cfg_ports = nb_ports;
471af75078fSIntel 	nb_fwd_ports = nb_ports;
472af75078fSIntel }
473af75078fSIntel 
474af75078fSIntel void
475af75078fSIntel set_def_fwd_config(void)
476af75078fSIntel {
477af75078fSIntel 	set_default_fwd_lcores_config();
478af75078fSIntel 	set_def_peer_eth_addrs();
479af75078fSIntel 	set_default_fwd_ports_config();
480af75078fSIntel }
481af75078fSIntel 
482af75078fSIntel /*
483af75078fSIntel  * Configuration initialisation done once at init time.
484af75078fSIntel  */
485af75078fSIntel static void
486af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
487af75078fSIntel 		 unsigned int socket_id)
488af75078fSIntel {
489af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
490bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
491af75078fSIntel 	uint32_t mb_size;
492af75078fSIntel 
493dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
494af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
495148f963fSBruce Richardson 
496d1eb542eSOlivier Matz 	RTE_LOG(INFO, USER1,
497d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
498d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
499d1eb542eSOlivier Matz 
500148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT
501148f963fSBruce Richardson 	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
502af75078fSIntel 		(unsigned) mb_mempool_cache,
503af75078fSIntel 		sizeof(struct rte_pktmbuf_pool_private),
504dfb03bbeSOlivier Matz 		rte_pktmbuf_pool_init, NULL,
505dfb03bbeSOlivier Matz 		rte_pktmbuf_init, NULL,
506af75078fSIntel 		socket_id, 0);
507bece7b6cSChristian Ehrhardt #endif
508148f963fSBruce Richardson 
509bece7b6cSChristian Ehrhardt 	/* if the former XEN allocation failed fall back to normal allocation */
510bece7b6cSChristian Ehrhardt 	if (rte_mp == NULL) {
511b19a0c75SOlivier Matz 		if (mp_anon != 0) {
512b19a0c75SOlivier Matz 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
513bece7b6cSChristian Ehrhardt 				mb_size, (unsigned) mb_mempool_cache,
514148f963fSBruce Richardson 				sizeof(struct rte_pktmbuf_pool_private),
515148f963fSBruce Richardson 				socket_id, 0);
51624427bb9SOlivier Matz 			if (rte_mp == NULL)
51724427bb9SOlivier Matz 				goto err;
518b19a0c75SOlivier Matz 
519b19a0c75SOlivier Matz 			if (rte_mempool_populate_anon(rte_mp) == 0) {
520b19a0c75SOlivier Matz 				rte_mempool_free(rte_mp);
521b19a0c75SOlivier Matz 				rte_mp = NULL;
52224427bb9SOlivier Matz 				goto err;
523b19a0c75SOlivier Matz 			}
524b19a0c75SOlivier Matz 			rte_pktmbuf_pool_init(rte_mp, NULL);
525b19a0c75SOlivier Matz 			rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
526b19a0c75SOlivier Matz 		} else {
527ea0c20eaSOlivier Matz 			/* wrapper to rte_mempool_create() */
528ea0c20eaSOlivier Matz 			rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
529ea0c20eaSOlivier Matz 				mb_mempool_cache, 0, mbuf_seg_size, socket_id);
530bece7b6cSChristian Ehrhardt 		}
531b19a0c75SOlivier Matz 	}
532148f963fSBruce Richardson 
53324427bb9SOlivier Matz err:
534af75078fSIntel 	if (rte_mp == NULL) {
535d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
536d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
537d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
538148f963fSBruce Richardson 	} else if (verbose_level > 0) {
539591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
540af75078fSIntel 	}
541af75078fSIntel }
542af75078fSIntel 
54320a0286fSLiu Xiaofeng /*
54420a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
54520a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
54620a0286fSLiu Xiaofeng  */
54720a0286fSLiu Xiaofeng static int
54820a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
54920a0286fSLiu Xiaofeng {
55020a0286fSLiu Xiaofeng 	static int warning_once = 0;
55120a0286fSLiu Xiaofeng 
552c9cafcc8SShahaf Shuler 	if (new_socket_id(socket_id)) {
55320a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
55420a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
55520a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
55620a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
55720a0286fSLiu Xiaofeng 			       " --numa.\n");
55820a0286fSLiu Xiaofeng 		warning_once = 1;
55920a0286fSLiu Xiaofeng 		return -1;
56020a0286fSLiu Xiaofeng 	}
56120a0286fSLiu Xiaofeng 	return 0;
56220a0286fSLiu Xiaofeng }
56320a0286fSLiu Xiaofeng 
564af75078fSIntel static void
565af75078fSIntel init_config(void)
566af75078fSIntel {
567ce8d5614SIntel 	portid_t pid;
568af75078fSIntel 	struct rte_port *port;
569af75078fSIntel 	struct rte_mempool *mbp;
570af75078fSIntel 	unsigned int nb_mbuf_per_pool;
571af75078fSIntel 	lcoreid_t  lc_id;
5727acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
573af75078fSIntel 
5747acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
575487f9a59SYulong Pei 
576487f9a59SYulong Pei 	if (numa_support) {
577487f9a59SYulong Pei 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
578487f9a59SYulong Pei 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
579487f9a59SYulong Pei 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
580487f9a59SYulong Pei 	}
581487f9a59SYulong Pei 
582af75078fSIntel 	/* Configuration of logical cores. */
583af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
584af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
585fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
586af75078fSIntel 	if (fwd_lcores == NULL) {
587ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
588ce8d5614SIntel 							"failed\n", nb_lcores);
589af75078fSIntel 	}
590af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
591af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
592af75078fSIntel 					       sizeof(struct fwd_lcore),
593fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
594af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
595ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
596ce8d5614SIntel 								"failed\n");
597af75078fSIntel 		}
598af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
599af75078fSIntel 	}
600af75078fSIntel 
6017d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
602ce8d5614SIntel 		port = &ports[pid];
603ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
604ce8d5614SIntel 
605b6ea6408SIntel 		if (numa_support) {
606b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
607b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
608b6ea6408SIntel 			else {
609b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
61020a0286fSLiu Xiaofeng 
61120a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
61220a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
61320a0286fSLiu Xiaofeng 					socket_id = 0;
614b6ea6408SIntel 				port_per_socket[socket_id]++;
615b6ea6408SIntel 			}
616b6ea6408SIntel 		}
617b6ea6408SIntel 
618ce8d5614SIntel 		/* set flag to initialize port/queue */
619ce8d5614SIntel 		port->need_reconfig = 1;
620ce8d5614SIntel 		port->need_reconfig_queues = 1;
621ce8d5614SIntel 	}
622ce8d5614SIntel 
6233ab64341SOlivier Matz 	/*
6243ab64341SOlivier Matz 	 * Create pools of mbuf.
6253ab64341SOlivier Matz 	 * If NUMA support is disabled, create a single pool of mbuf in
6263ab64341SOlivier Matz 	 * socket 0 memory by default.
6273ab64341SOlivier Matz 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
6283ab64341SOlivier Matz 	 *
6293ab64341SOlivier Matz 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
6303ab64341SOlivier Matz 	 * nb_txd can be configured at run time.
6313ab64341SOlivier Matz 	 */
6323ab64341SOlivier Matz 	if (param_total_num_mbufs)
6333ab64341SOlivier Matz 		nb_mbuf_per_pool = param_total_num_mbufs;
6343ab64341SOlivier Matz 	else {
6353ab64341SOlivier Matz 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
6363ab64341SOlivier Matz 			(nb_lcores * mb_mempool_cache) +
6373ab64341SOlivier Matz 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
6383ab64341SOlivier Matz 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
6393ab64341SOlivier Matz 	}
6403ab64341SOlivier Matz 
641b6ea6408SIntel 	if (numa_support) {
642b6ea6408SIntel 		uint8_t i;
643ce8d5614SIntel 
644c9cafcc8SShahaf Shuler 		for (i = 0; i < num_sockets; i++)
645c9cafcc8SShahaf Shuler 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
646c9cafcc8SShahaf Shuler 					 socket_ids[i]);
6473ab64341SOlivier Matz 	} else {
6483ab64341SOlivier Matz 		if (socket_num == UMA_NO_CONFIG)
6493ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
6503ab64341SOlivier Matz 		else
6513ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
6523ab64341SOlivier Matz 						 socket_num);
6533ab64341SOlivier Matz 	}
654b6ea6408SIntel 
655b6ea6408SIntel 	init_port_config();
6565886ae07SAdrien Mazarguil 
6575886ae07SAdrien Mazarguil 	/*
6585886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6595886ae07SAdrien Mazarguil 	 */
6605886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6618fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
6628fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
6638fd8bebcSAdrien Mazarguil 
6645886ae07SAdrien Mazarguil 		if (mbp == NULL)
6655886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6665886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
6675886ae07SAdrien Mazarguil 	}
6685886ae07SAdrien Mazarguil 
669ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
670ce8d5614SIntel 	if (init_fwd_streams() < 0)
671ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
6720c0db76fSBernard Iremonger 
6730c0db76fSBernard Iremonger 	fwd_config_setup();
674ce8d5614SIntel }
675ce8d5614SIntel 
6762950a769SDeclan Doherty 
6772950a769SDeclan Doherty void
678a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6792950a769SDeclan Doherty {
6802950a769SDeclan Doherty 	struct rte_port *port;
6812950a769SDeclan Doherty 
6822950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6832950a769SDeclan Doherty 	port = &ports[new_port_id];
6842950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6852950a769SDeclan Doherty 
6862950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6872950a769SDeclan Doherty 	port->need_reconfig = 1;
6882950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
689a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6902950a769SDeclan Doherty 
6912950a769SDeclan Doherty 	init_port_config();
6922950a769SDeclan Doherty }
6932950a769SDeclan Doherty 
6942950a769SDeclan Doherty 
695ce8d5614SIntel int
696ce8d5614SIntel init_fwd_streams(void)
697ce8d5614SIntel {
698ce8d5614SIntel 	portid_t pid;
699ce8d5614SIntel 	struct rte_port *port;
700ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
7015a8fb55cSReshma Pattan 	queueid_t q;
702ce8d5614SIntel 
703ce8d5614SIntel 	/* set socket id according to numa or not */
7047d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
705ce8d5614SIntel 		port = &ports[pid];
706ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
707ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
708ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
709ce8d5614SIntel 				port->dev_info.max_rx_queues);
710ce8d5614SIntel 			return -1;
711ce8d5614SIntel 		}
712ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
713ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
714ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
715ce8d5614SIntel 				port->dev_info.max_tx_queues);
716ce8d5614SIntel 			return -1;
717ce8d5614SIntel 		}
71820a0286fSLiu Xiaofeng 		if (numa_support) {
71920a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
72020a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
72120a0286fSLiu Xiaofeng 			else {
722b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
72320a0286fSLiu Xiaofeng 
72420a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
72520a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
72620a0286fSLiu Xiaofeng 					port->socket_id = 0;
72720a0286fSLiu Xiaofeng 			}
72820a0286fSLiu Xiaofeng 		}
729b6ea6408SIntel 		else {
730b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
731af75078fSIntel 				port->socket_id = 0;
732b6ea6408SIntel 			else
733b6ea6408SIntel 				port->socket_id = socket_num;
734b6ea6408SIntel 		}
735af75078fSIntel 	}
736af75078fSIntel 
7375a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
7385a8fb55cSReshma Pattan 	if (q == 0) {
7395a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
7405a8fb55cSReshma Pattan 		return -1;
7415a8fb55cSReshma Pattan 	}
7425a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
743ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
744ce8d5614SIntel 		return 0;
745ce8d5614SIntel 	/* clear the old */
746ce8d5614SIntel 	if (fwd_streams != NULL) {
747ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
748ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
749ce8d5614SIntel 				continue;
750ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
751ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
752af75078fSIntel 		}
753ce8d5614SIntel 		rte_free(fwd_streams);
754ce8d5614SIntel 		fwd_streams = NULL;
755ce8d5614SIntel 	}
756ce8d5614SIntel 
757ce8d5614SIntel 	/* init new */
758ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
759ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
760fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
761ce8d5614SIntel 	if (fwd_streams == NULL)
762ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
763ce8d5614SIntel 						"failed\n", nb_fwd_streams);
764ce8d5614SIntel 
765af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
766af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
767fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
768ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
769ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
770ce8d5614SIntel 								" failed\n");
771af75078fSIntel 	}
772ce8d5614SIntel 
773ce8d5614SIntel 	return 0;
774af75078fSIntel }
775af75078fSIntel 
776af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
777af75078fSIntel static void
778af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
779af75078fSIntel {
780af75078fSIntel 	unsigned int total_burst;
781af75078fSIntel 	unsigned int nb_burst;
782af75078fSIntel 	unsigned int burst_stats[3];
783af75078fSIntel 	uint16_t pktnb_stats[3];
784af75078fSIntel 	uint16_t nb_pkt;
785af75078fSIntel 	int burst_percent[3];
786af75078fSIntel 
787af75078fSIntel 	/*
788af75078fSIntel 	 * First compute the total number of packet bursts and the
789af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
790af75078fSIntel 	 */
791af75078fSIntel 	total_burst = 0;
792af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
793af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
794af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
795af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
796af75078fSIntel 		if (nb_burst == 0)
797af75078fSIntel 			continue;
798af75078fSIntel 		total_burst += nb_burst;
799af75078fSIntel 		if (nb_burst > burst_stats[0]) {
800af75078fSIntel 			burst_stats[1] = burst_stats[0];
801af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
802af75078fSIntel 			burst_stats[0] = nb_burst;
803af75078fSIntel 			pktnb_stats[0] = nb_pkt;
804af75078fSIntel 		}
805af75078fSIntel 	}
806af75078fSIntel 	if (total_burst == 0)
807af75078fSIntel 		return;
808af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
809af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
810af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
811af75078fSIntel 	if (burst_stats[0] == total_burst) {
812af75078fSIntel 		printf("]\n");
813af75078fSIntel 		return;
814af75078fSIntel 	}
815af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
816af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
817af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
818af75078fSIntel 		return;
819af75078fSIntel 	}
820af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
821af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
822af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
823af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
824af75078fSIntel 		return;
825af75078fSIntel 	}
826af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
827af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
828af75078fSIntel }
829af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
830af75078fSIntel 
831af75078fSIntel static void
832af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
833af75078fSIntel {
834af75078fSIntel 	struct rte_port *port;
835013af9b6SIntel 	uint8_t i;
836af75078fSIntel 
837af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
838af75078fSIntel 
839af75078fSIntel 	port = &ports[port_id];
840af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
841af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
842013af9b6SIntel 
843013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
844af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
845af75078fSIntel 		       "%-"PRIu64"\n",
84670bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
84770bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
848af75078fSIntel 
849af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
850af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
851af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
85286057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
853f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
85470bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
85570bdb186SIvan Boule 		}
856af75078fSIntel 
857af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
858af75078fSIntel 		       "%-"PRIu64"\n",
859af75078fSIntel 		       stats->opackets, port->tx_dropped,
860af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
861013af9b6SIntel 	}
862013af9b6SIntel 	else {
863013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
864013af9b6SIntel 		       "%14"PRIu64"\n",
86570bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
86670bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
867013af9b6SIntel 
868013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
869013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
870013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
87186057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
872f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
87370bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
87470bdb186SIvan Boule 			       stats->rx_nombuf);
87570bdb186SIvan Boule 		}
876013af9b6SIntel 
877013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
878013af9b6SIntel 		       "%14"PRIu64"\n",
879013af9b6SIntel 		       stats->opackets, port->tx_dropped,
880013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
881013af9b6SIntel 	}
882e659b6b4SIvan Boule 
883af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
884af75078fSIntel 	if (port->rx_stream)
885013af9b6SIntel 		pkt_burst_stats_display("RX",
886013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
887af75078fSIntel 	if (port->tx_stream)
888013af9b6SIntel 		pkt_burst_stats_display("TX",
889013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
890af75078fSIntel #endif
891af75078fSIntel 
892013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
893013af9b6SIntel 		printf("\n");
894013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
895013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
896013af9b6SIntel 			       "     RX-errors:%14"PRIu64
897013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
898013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
899013af9b6SIntel 		}
900013af9b6SIntel 		printf("\n");
901013af9b6SIntel 	}
902013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
903013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
904013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
905013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
906013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
907013af9b6SIntel 		}
908013af9b6SIntel 	}
909013af9b6SIntel 
910af75078fSIntel 	printf("  %s--------------------------------%s\n",
911af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
912af75078fSIntel }
913af75078fSIntel 
914af75078fSIntel static void
915af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
916af75078fSIntel {
917af75078fSIntel 	struct fwd_stream *fs;
918af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
919af75078fSIntel 
920af75078fSIntel 	fs = fwd_streams[stream_id];
921af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
922af75078fSIntel 	    (fs->fwd_dropped == 0))
923af75078fSIntel 		return;
924af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
925af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
926af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
927af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
928af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
929af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
930af75078fSIntel 
931af75078fSIntel 	/* if checksum mode */
932af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
933013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
934013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
935af75078fSIntel 	}
936af75078fSIntel 
937af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
938af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
939af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
940af75078fSIntel #endif
941af75078fSIntel }
942af75078fSIntel 
943af75078fSIntel static void
9447741e4cfSIntel flush_fwd_rx_queues(void)
945af75078fSIntel {
946af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
947af75078fSIntel 	portid_t  rxp;
9487741e4cfSIntel 	portid_t port_id;
949af75078fSIntel 	queueid_t rxq;
950af75078fSIntel 	uint16_t  nb_rx;
951af75078fSIntel 	uint16_t  i;
952af75078fSIntel 	uint8_t   j;
953f487715fSReshma Pattan 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
954594302c7SJames Poole 	uint64_t timer_period;
955f487715fSReshma Pattan 
956f487715fSReshma Pattan 	/* convert to number of cycles */
957594302c7SJames Poole 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
958af75078fSIntel 
959af75078fSIntel 	for (j = 0; j < 2; j++) {
9607741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
961af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
9627741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
963f487715fSReshma Pattan 				/**
964f487715fSReshma Pattan 				* testpmd can stuck in the below do while loop
965f487715fSReshma Pattan 				* if rte_eth_rx_burst() always returns nonzero
966f487715fSReshma Pattan 				* packets. So timer is added to exit this loop
967f487715fSReshma Pattan 				* after 1sec timer expiry.
968f487715fSReshma Pattan 				*/
969f487715fSReshma Pattan 				prev_tsc = rte_rdtsc();
970af75078fSIntel 				do {
9717741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
972013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
973af75078fSIntel 					for (i = 0; i < nb_rx; i++)
974af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
975f487715fSReshma Pattan 
976f487715fSReshma Pattan 					cur_tsc = rte_rdtsc();
977f487715fSReshma Pattan 					diff_tsc = cur_tsc - prev_tsc;
978f487715fSReshma Pattan 					timer_tsc += diff_tsc;
979f487715fSReshma Pattan 				} while ((nb_rx > 0) &&
980f487715fSReshma Pattan 					(timer_tsc < timer_period));
981f487715fSReshma Pattan 				timer_tsc = 0;
982af75078fSIntel 			}
983af75078fSIntel 		}
984af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
985af75078fSIntel 	}
986af75078fSIntel }
987af75078fSIntel 
988af75078fSIntel static void
989af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
990af75078fSIntel {
991af75078fSIntel 	struct fwd_stream **fsm;
992af75078fSIntel 	streamid_t nb_fs;
993af75078fSIntel 	streamid_t sm_id;
9947e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
9957e4441c8SRemy Horton 	uint64_t tics_per_1sec;
9967e4441c8SRemy Horton 	uint64_t tics_datum;
9977e4441c8SRemy Horton 	uint64_t tics_current;
9987e4441c8SRemy Horton 	uint8_t idx_port, cnt_ports;
999af75078fSIntel 
10007e4441c8SRemy Horton 	cnt_ports = rte_eth_dev_count();
10017e4441c8SRemy Horton 	tics_datum = rte_rdtsc();
10027e4441c8SRemy Horton 	tics_per_1sec = rte_get_timer_hz();
10037e4441c8SRemy Horton #endif
1004af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
1005af75078fSIntel 	nb_fs = fc->stream_nb;
1006af75078fSIntel 	do {
1007af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1008af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
10097e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
1010e25e6c70SRemy Horton 		if (bitrate_enabled != 0 &&
1011e25e6c70SRemy Horton 				bitrate_lcore_id == rte_lcore_id()) {
10127e4441c8SRemy Horton 			tics_current = rte_rdtsc();
10137e4441c8SRemy Horton 			if (tics_current - tics_datum >= tics_per_1sec) {
10147e4441c8SRemy Horton 				/* Periodic bitrate calculation */
1015e25e6c70SRemy Horton 				for (idx_port = 0;
1016e25e6c70SRemy Horton 						idx_port < cnt_ports;
1017e25e6c70SRemy Horton 						idx_port++)
1018e25e6c70SRemy Horton 					rte_stats_bitrate_calc(bitrate_data,
1019e25e6c70SRemy Horton 						idx_port);
10207e4441c8SRemy Horton 				tics_datum = tics_current;
10217e4441c8SRemy Horton 			}
1022e25e6c70SRemy Horton 		}
10237e4441c8SRemy Horton #endif
102462d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
102565eb1e54SPablo de Lara 		if (latencystats_enabled != 0 &&
102665eb1e54SPablo de Lara 				latencystats_lcore_id == rte_lcore_id())
102762d3216dSReshma Pattan 			rte_latencystats_update();
102862d3216dSReshma Pattan #endif
102962d3216dSReshma Pattan 
1030af75078fSIntel 	} while (! fc->stopped);
1031af75078fSIntel }
1032af75078fSIntel 
1033af75078fSIntel static int
1034af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
1035af75078fSIntel {
1036af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1037af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
1038af75078fSIntel 	return 0;
1039af75078fSIntel }
1040af75078fSIntel 
1041af75078fSIntel /*
1042af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1043af75078fSIntel  * Used to start communication flows in network loopback test configurations.
1044af75078fSIntel  */
1045af75078fSIntel static int
1046af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
1047af75078fSIntel {
1048af75078fSIntel 	struct fwd_lcore *fwd_lc;
1049af75078fSIntel 	struct fwd_lcore tmp_lcore;
1050af75078fSIntel 
1051af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1052af75078fSIntel 	tmp_lcore = *fwd_lc;
1053af75078fSIntel 	tmp_lcore.stopped = 1;
1054af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1055af75078fSIntel 	return 0;
1056af75078fSIntel }
1057af75078fSIntel 
1058af75078fSIntel /*
1059af75078fSIntel  * Launch packet forwarding:
1060af75078fSIntel  *     - Setup per-port forwarding context.
1061af75078fSIntel  *     - launch logical cores with their forwarding configuration.
1062af75078fSIntel  */
1063af75078fSIntel static void
1064af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1065af75078fSIntel {
1066af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1067af75078fSIntel 	unsigned int i;
1068af75078fSIntel 	unsigned int lc_id;
1069af75078fSIntel 	int diag;
1070af75078fSIntel 
1071af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1072af75078fSIntel 	if (port_fwd_begin != NULL) {
1073af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1074af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
1075af75078fSIntel 	}
1076af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1077af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
1078af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1079af75078fSIntel 			fwd_lcores[i]->stopped = 0;
1080af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1081af75078fSIntel 						     fwd_lcores[i], lc_id);
1082af75078fSIntel 			if (diag != 0)
1083af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
1084af75078fSIntel 				       lc_id, diag);
1085af75078fSIntel 		}
1086af75078fSIntel 	}
1087af75078fSIntel }
1088af75078fSIntel 
1089af75078fSIntel /*
1090af75078fSIntel  * Launch packet forwarding configuration.
1091af75078fSIntel  */
1092af75078fSIntel void
1093af75078fSIntel start_packet_forwarding(int with_tx_first)
1094af75078fSIntel {
1095af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1096af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1097af75078fSIntel 	struct rte_port *port;
1098af75078fSIntel 	unsigned int i;
1099af75078fSIntel 	portid_t   pt_id;
1100af75078fSIntel 	streamid_t sm_id;
1101af75078fSIntel 
11025a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
11035a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
11045a8fb55cSReshma Pattan 
11055a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
11065a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
11075a8fb55cSReshma Pattan 
11085a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
11095a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
11105a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
11115a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
11125a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
11135a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
11145a8fb55cSReshma Pattan 
1115ce8d5614SIntel 	if (all_ports_started() == 0) {
1116ce8d5614SIntel 		printf("Not all ports were started\n");
1117ce8d5614SIntel 		return;
1118ce8d5614SIntel 	}
1119af75078fSIntel 	if (test_done == 0) {
1120af75078fSIntel 		printf("Packet forwarding already started\n");
1121af75078fSIntel 		return;
1122af75078fSIntel 	}
1123edf87b4aSBernard Iremonger 
1124edf87b4aSBernard Iremonger 	if (init_fwd_streams() < 0) {
1125edf87b4aSBernard Iremonger 		printf("Fail from init_fwd_streams()\n");
1126edf87b4aSBernard Iremonger 		return;
1127edf87b4aSBernard Iremonger 	}
1128edf87b4aSBernard Iremonger 
11297741e4cfSIntel 	if(dcb_test) {
11307741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
11317741e4cfSIntel 			pt_id = fwd_ports_ids[i];
11327741e4cfSIntel 			port = &ports[pt_id];
11337741e4cfSIntel 			if (!port->dcb_flag) {
11347741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
11357741e4cfSIntel                                        "be configured in this mode.\n");
1136013af9b6SIntel 				return;
1137013af9b6SIntel 			}
11387741e4cfSIntel 		}
11397741e4cfSIntel 		if (nb_fwd_lcores == 1) {
11407741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
11417741e4cfSIntel                                "should be larger than 1.\n");
11427741e4cfSIntel 			return;
11437741e4cfSIntel 		}
11447741e4cfSIntel 	}
1145af75078fSIntel 	test_done = 0;
11467741e4cfSIntel 
11477741e4cfSIntel 	if(!no_flush_rx)
11487741e4cfSIntel 		flush_fwd_rx_queues();
11497741e4cfSIntel 
1150af75078fSIntel 	fwd_config_setup();
1151933617d8SZhihong Wang 	pkt_fwd_config_display(&cur_fwd_config);
1152af75078fSIntel 	rxtx_config_display();
1153af75078fSIntel 
1154af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1155af75078fSIntel 		pt_id = fwd_ports_ids[i];
1156af75078fSIntel 		port = &ports[pt_id];
1157af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1158af75078fSIntel 		port->tx_dropped = 0;
1159013af9b6SIntel 
1160013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1161af75078fSIntel 	}
1162af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1163af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1164af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1165af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1166af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1167af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1168af75078fSIntel 
1169af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1170af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1171af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1172af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1173af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1174af75078fSIntel #endif
1175af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1176af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1177af75078fSIntel #endif
1178af75078fSIntel 	}
1179af75078fSIntel 	if (with_tx_first) {
1180af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1181af75078fSIntel 		if (port_fwd_begin != NULL) {
1182af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1183af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1184af75078fSIntel 		}
1185acbf77a6SZhihong Wang 		while (with_tx_first--) {
1186acbf77a6SZhihong Wang 			launch_packet_forwarding(
1187acbf77a6SZhihong Wang 					run_one_txonly_burst_on_core);
1188af75078fSIntel 			rte_eal_mp_wait_lcore();
1189acbf77a6SZhihong Wang 		}
1190af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1191af75078fSIntel 		if (port_fwd_end != NULL) {
1192af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1193af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1194af75078fSIntel 		}
1195af75078fSIntel 	}
1196af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1197af75078fSIntel }
1198af75078fSIntel 
1199af75078fSIntel void
1200af75078fSIntel stop_packet_forwarding(void)
1201af75078fSIntel {
1202af75078fSIntel 	struct rte_eth_stats stats;
1203af75078fSIntel 	struct rte_port *port;
1204af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1205af75078fSIntel 	int i;
1206af75078fSIntel 	portid_t   pt_id;
1207af75078fSIntel 	streamid_t sm_id;
1208af75078fSIntel 	lcoreid_t  lc_id;
1209af75078fSIntel 	uint64_t total_recv;
1210af75078fSIntel 	uint64_t total_xmit;
1211af75078fSIntel 	uint64_t total_rx_dropped;
1212af75078fSIntel 	uint64_t total_tx_dropped;
1213af75078fSIntel 	uint64_t total_rx_nombuf;
1214af75078fSIntel 	uint64_t tx_dropped;
1215af75078fSIntel 	uint64_t rx_bad_ip_csum;
1216af75078fSIntel 	uint64_t rx_bad_l4_csum;
1217af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1218af75078fSIntel 	uint64_t fwd_cycles;
1219af75078fSIntel #endif
1220af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1221af75078fSIntel 
1222af75078fSIntel 	if (test_done) {
1223af75078fSIntel 		printf("Packet forwarding not started\n");
1224af75078fSIntel 		return;
1225af75078fSIntel 	}
1226af75078fSIntel 	printf("Telling cores to stop...");
1227af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1228af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1229af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1230af75078fSIntel 	rte_eal_mp_wait_lcore();
1231af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1232af75078fSIntel 	if (port_fwd_end != NULL) {
1233af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1234af75078fSIntel 			pt_id = fwd_ports_ids[i];
1235af75078fSIntel 			(*port_fwd_end)(pt_id);
1236af75078fSIntel 		}
1237af75078fSIntel 	}
1238af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1239af75078fSIntel 	fwd_cycles = 0;
1240af75078fSIntel #endif
1241af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1242af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1243af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1244af75078fSIntel 			fwd_stream_stats_display(sm_id);
1245af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1246af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1247af75078fSIntel 		} else {
1248af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1249af75078fSIntel 				fwd_streams[sm_id];
1250af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1251af75078fSIntel 				fwd_streams[sm_id];
1252af75078fSIntel 		}
1253af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1254af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1255af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1256af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1257af75078fSIntel 
1258013af9b6SIntel 		rx_bad_ip_csum =
1259013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1260af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1261af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1262013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1263013af9b6SIntel 							rx_bad_ip_csum;
1264af75078fSIntel 
1265013af9b6SIntel 		rx_bad_l4_csum =
1266013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1267af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1268af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1269013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1270013af9b6SIntel 							rx_bad_l4_csum;
1271af75078fSIntel 
1272af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1273af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1274af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1275af75078fSIntel #endif
1276af75078fSIntel 	}
1277af75078fSIntel 	total_recv = 0;
1278af75078fSIntel 	total_xmit = 0;
1279af75078fSIntel 	total_rx_dropped = 0;
1280af75078fSIntel 	total_tx_dropped = 0;
1281af75078fSIntel 	total_rx_nombuf  = 0;
12827741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1283af75078fSIntel 		pt_id = fwd_ports_ids[i];
1284af75078fSIntel 
1285af75078fSIntel 		port = &ports[pt_id];
1286af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1287af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1288af75078fSIntel 		port->stats.ipackets = 0;
1289af75078fSIntel 		stats.opackets -= port->stats.opackets;
1290af75078fSIntel 		port->stats.opackets = 0;
1291af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1292af75078fSIntel 		port->stats.ibytes = 0;
1293af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1294af75078fSIntel 		port->stats.obytes = 0;
129570bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
129670bdb186SIvan Boule 		port->stats.imissed = 0;
1297af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1298af75078fSIntel 		port->stats.oerrors = 0;
1299af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1300af75078fSIntel 		port->stats.rx_nombuf = 0;
1301af75078fSIntel 
1302af75078fSIntel 		total_recv += stats.ipackets;
1303af75078fSIntel 		total_xmit += stats.opackets;
130470bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1305af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1306af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1307af75078fSIntel 
1308af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1309af75078fSIntel 	}
1310af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1311af75078fSIntel 	       "%s\n",
1312af75078fSIntel 	       acc_stats_border, acc_stats_border);
1313af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1314af75078fSIntel 	       "%-"PRIu64"\n"
1315af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1316af75078fSIntel 	       "%-"PRIu64"\n",
1317af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1318af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1319af75078fSIntel 	if (total_rx_nombuf > 0)
1320af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1321af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1322af75078fSIntel 	       "%s\n",
1323af75078fSIntel 	       acc_stats_border, acc_stats_border);
1324af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1325af75078fSIntel 	if (total_recv > 0)
1326af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1327af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1328af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1329af75078fSIntel 		       fwd_cycles, total_recv);
1330af75078fSIntel #endif
1331af75078fSIntel 	printf("\nDone.\n");
1332af75078fSIntel 	test_done = 1;
1333af75078fSIntel }
1334af75078fSIntel 
1335cfae07fdSOuyang Changchun void
1336cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1337cfae07fdSOuyang Changchun {
1338cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1339cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1340cfae07fdSOuyang Changchun }
1341cfae07fdSOuyang Changchun 
1342cfae07fdSOuyang Changchun void
1343cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1344cfae07fdSOuyang Changchun {
1345cfae07fdSOuyang Changchun 	if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1346cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1347cfae07fdSOuyang Changchun }
1348cfae07fdSOuyang Changchun 
1349ce8d5614SIntel static int
1350ce8d5614SIntel all_ports_started(void)
1351ce8d5614SIntel {
1352ce8d5614SIntel 	portid_t pi;
1353ce8d5614SIntel 	struct rte_port *port;
1354ce8d5614SIntel 
13557d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1356ce8d5614SIntel 		port = &ports[pi];
1357ce8d5614SIntel 		/* Check if there is a port which is not started */
135841b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
135941b05095SBernard Iremonger 			(port->slave_flag == 0))
1360ce8d5614SIntel 			return 0;
1361ce8d5614SIntel 	}
1362ce8d5614SIntel 
1363ce8d5614SIntel 	/* No port is not started */
1364ce8d5614SIntel 	return 1;
1365ce8d5614SIntel }
1366ce8d5614SIntel 
1367148f963fSBruce Richardson int
1368edab33b1STetsuya Mukawa all_ports_stopped(void)
1369edab33b1STetsuya Mukawa {
1370edab33b1STetsuya Mukawa 	portid_t pi;
1371edab33b1STetsuya Mukawa 	struct rte_port *port;
1372edab33b1STetsuya Mukawa 
13737d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1374edab33b1STetsuya Mukawa 		port = &ports[pi];
137541b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STOPPED) &&
137641b05095SBernard Iremonger 			(port->slave_flag == 0))
1377edab33b1STetsuya Mukawa 			return 0;
1378edab33b1STetsuya Mukawa 	}
1379edab33b1STetsuya Mukawa 
1380edab33b1STetsuya Mukawa 	return 1;
1381edab33b1STetsuya Mukawa }
1382edab33b1STetsuya Mukawa 
1383edab33b1STetsuya Mukawa int
1384edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1385edab33b1STetsuya Mukawa {
1386edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1387edab33b1STetsuya Mukawa 		return 0;
1388edab33b1STetsuya Mukawa 
1389edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1390edab33b1STetsuya Mukawa 		return 0;
1391edab33b1STetsuya Mukawa 
1392edab33b1STetsuya Mukawa 	return 1;
1393edab33b1STetsuya Mukawa }
1394edab33b1STetsuya Mukawa 
1395edab33b1STetsuya Mukawa static int
1396edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1397edab33b1STetsuya Mukawa {
1398edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1399edab33b1STetsuya Mukawa 		return 0;
1400edab33b1STetsuya Mukawa 
1401edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1402edab33b1STetsuya Mukawa 		return 0;
1403edab33b1STetsuya Mukawa 
1404edab33b1STetsuya Mukawa 	return 1;
1405edab33b1STetsuya Mukawa }
1406edab33b1STetsuya Mukawa 
1407edab33b1STetsuya Mukawa int
1408ce8d5614SIntel start_port(portid_t pid)
1409ce8d5614SIntel {
141092d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1411ce8d5614SIntel 	portid_t pi;
1412ce8d5614SIntel 	queueid_t qi;
1413ce8d5614SIntel 	struct rte_port *port;
14142950a769SDeclan Doherty 	struct ether_addr mac_addr;
141576ad4a2dSGaetan Rivet 	enum rte_eth_event_type event_type;
1416ce8d5614SIntel 
14174468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14184468635fSMichael Qiu 		return 0;
14194468635fSMichael Qiu 
1420ce8d5614SIntel 	if(dcb_config)
1421ce8d5614SIntel 		dcb_test = 1;
14227d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1423edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1424ce8d5614SIntel 			continue;
1425ce8d5614SIntel 
142692d2703eSMichael Qiu 		need_check_link_status = 0;
1427ce8d5614SIntel 		port = &ports[pi];
1428ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1429ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1430ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1431ce8d5614SIntel 			continue;
1432ce8d5614SIntel 		}
1433ce8d5614SIntel 
1434ce8d5614SIntel 		if (port->need_reconfig > 0) {
1435ce8d5614SIntel 			port->need_reconfig = 0;
1436ce8d5614SIntel 
14377ee3e944SVasily Philipov 			if (flow_isolate_all) {
14387ee3e944SVasily Philipov 				int ret = port_flow_isolate(pi, 1);
14397ee3e944SVasily Philipov 				if (ret) {
14407ee3e944SVasily Philipov 					printf("Failed to apply isolated"
14417ee3e944SVasily Philipov 					       " mode on port %d\n", pi);
14427ee3e944SVasily Philipov 					return -1;
14437ee3e944SVasily Philipov 				}
14447ee3e944SVasily Philipov 			}
14457ee3e944SVasily Philipov 
14465706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
144720a0286fSLiu Xiaofeng 					port->socket_id);
1448ce8d5614SIntel 			/* configure port */
1449ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1450ce8d5614SIntel 						&(port->dev_conf));
1451ce8d5614SIntel 			if (diag != 0) {
1452ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1453ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1454ce8d5614SIntel 					printf("Port %d can not be set back "
1455ce8d5614SIntel 							"to stopped\n", pi);
1456ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1457ce8d5614SIntel 				/* try to reconfigure port next time */
1458ce8d5614SIntel 				port->need_reconfig = 1;
1459148f963fSBruce Richardson 				return -1;
1460ce8d5614SIntel 			}
1461ce8d5614SIntel 		}
1462ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1463ce8d5614SIntel 			port->need_reconfig_queues = 0;
1464ce8d5614SIntel 			/* setup tx queues */
1465ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1466b6ea6408SIntel 				if ((numa_support) &&
1467b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1468b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1469b6ea6408SIntel 						nb_txd,txring_numa[pi],
1470b6ea6408SIntel 						&(port->tx_conf));
1471b6ea6408SIntel 				else
1472b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1473b6ea6408SIntel 						nb_txd,port->socket_id,
1474b6ea6408SIntel 						&(port->tx_conf));
1475b6ea6408SIntel 
1476ce8d5614SIntel 				if (diag == 0)
1477ce8d5614SIntel 					continue;
1478ce8d5614SIntel 
1479ce8d5614SIntel 				/* Fail to setup tx queue, return */
1480ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1481ce8d5614SIntel 							RTE_PORT_HANDLING,
1482ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1483ce8d5614SIntel 					printf("Port %d can not be set back "
1484ce8d5614SIntel 							"to stopped\n", pi);
1485ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1486ce8d5614SIntel 				/* try to reconfigure queues next time */
1487ce8d5614SIntel 				port->need_reconfig_queues = 1;
1488148f963fSBruce Richardson 				return -1;
1489ce8d5614SIntel 			}
1490ce8d5614SIntel 			/* setup rx queues */
1491ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1492b6ea6408SIntel 				if ((numa_support) &&
1493b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1494b6ea6408SIntel 					struct rte_mempool * mp =
1495b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1496b6ea6408SIntel 					if (mp == NULL) {
1497b6ea6408SIntel 						printf("Failed to setup RX queue:"
1498b6ea6408SIntel 							"No mempool allocation"
1499b6ea6408SIntel 							" on the socket %d\n",
1500b6ea6408SIntel 							rxring_numa[pi]);
1501148f963fSBruce Richardson 						return -1;
1502b6ea6408SIntel 					}
1503b6ea6408SIntel 
1504b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1505b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1506b6ea6408SIntel 					     &(port->rx_conf),mp);
15071e1d6bddSBernard Iremonger 				} else {
15081e1d6bddSBernard Iremonger 					struct rte_mempool *mp =
15091e1d6bddSBernard Iremonger 						mbuf_pool_find(port->socket_id);
15101e1d6bddSBernard Iremonger 					if (mp == NULL) {
15111e1d6bddSBernard Iremonger 						printf("Failed to setup RX queue:"
15121e1d6bddSBernard Iremonger 							"No mempool allocation"
15131e1d6bddSBernard Iremonger 							" on the socket %d\n",
15141e1d6bddSBernard Iremonger 							port->socket_id);
15151e1d6bddSBernard Iremonger 						return -1;
1516b6ea6408SIntel 					}
1517b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1518b6ea6408SIntel 					     nb_rxd,port->socket_id,
15191e1d6bddSBernard Iremonger 					     &(port->rx_conf), mp);
15201e1d6bddSBernard Iremonger 				}
1521ce8d5614SIntel 				if (diag == 0)
1522ce8d5614SIntel 					continue;
1523ce8d5614SIntel 
1524ce8d5614SIntel 				/* Fail to setup rx queue, return */
1525ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1526ce8d5614SIntel 							RTE_PORT_HANDLING,
1527ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1528ce8d5614SIntel 					printf("Port %d can not be set back "
1529ce8d5614SIntel 							"to stopped\n", pi);
1530ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1531ce8d5614SIntel 				/* try to reconfigure queues next time */
1532ce8d5614SIntel 				port->need_reconfig_queues = 1;
1533148f963fSBruce Richardson 				return -1;
1534ce8d5614SIntel 			}
1535ce8d5614SIntel 		}
153676ad4a2dSGaetan Rivet 
153776ad4a2dSGaetan Rivet 		for (event_type = RTE_ETH_EVENT_UNKNOWN;
153876ad4a2dSGaetan Rivet 		     event_type < RTE_ETH_EVENT_MAX;
153976ad4a2dSGaetan Rivet 		     event_type++) {
154076ad4a2dSGaetan Rivet 			diag = rte_eth_dev_callback_register(pi,
154176ad4a2dSGaetan Rivet 							event_type,
154276ad4a2dSGaetan Rivet 							eth_event_callback,
154376ad4a2dSGaetan Rivet 							NULL);
154476ad4a2dSGaetan Rivet 			if (diag) {
154576ad4a2dSGaetan Rivet 				printf("Failed to setup even callback for event %d\n",
154676ad4a2dSGaetan Rivet 					event_type);
154776ad4a2dSGaetan Rivet 				return -1;
154876ad4a2dSGaetan Rivet 			}
154976ad4a2dSGaetan Rivet 		}
155076ad4a2dSGaetan Rivet 
1551ce8d5614SIntel 		/* start port */
1552ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1553ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1554ce8d5614SIntel 
1555ce8d5614SIntel 			/* Fail to setup rx queue, return */
1556ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1557ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1558ce8d5614SIntel 				printf("Port %d can not be set back to "
1559ce8d5614SIntel 							"stopped\n", pi);
1560ce8d5614SIntel 			continue;
1561ce8d5614SIntel 		}
1562ce8d5614SIntel 
1563ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1564ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1565ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1566ce8d5614SIntel 
15672950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1568d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
15692950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
15702950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
15712950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1572d8c89163SZijie Pan 
1573ce8d5614SIntel 		/* at least one port started, need checking link status */
1574ce8d5614SIntel 		need_check_link_status = 1;
1575ce8d5614SIntel 	}
1576ce8d5614SIntel 
157792d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1578edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
157992d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1580ce8d5614SIntel 		printf("Please stop the ports first\n");
1581ce8d5614SIntel 
1582ce8d5614SIntel 	printf("Done\n");
1583148f963fSBruce Richardson 	return 0;
1584ce8d5614SIntel }
1585ce8d5614SIntel 
1586ce8d5614SIntel void
1587ce8d5614SIntel stop_port(portid_t pid)
1588ce8d5614SIntel {
1589ce8d5614SIntel 	portid_t pi;
1590ce8d5614SIntel 	struct rte_port *port;
1591ce8d5614SIntel 	int need_check_link_status = 0;
1592ce8d5614SIntel 
1593ce8d5614SIntel 	if (dcb_test) {
1594ce8d5614SIntel 		dcb_test = 0;
1595ce8d5614SIntel 		dcb_config = 0;
1596ce8d5614SIntel 	}
15974468635fSMichael Qiu 
15984468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
15994468635fSMichael Qiu 		return;
16004468635fSMichael Qiu 
1601ce8d5614SIntel 	printf("Stopping ports...\n");
1602ce8d5614SIntel 
16037d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16044468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1605ce8d5614SIntel 			continue;
1606ce8d5614SIntel 
1607a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1608a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1609a8ef3e3aSBernard Iremonger 			continue;
1610a8ef3e3aSBernard Iremonger 		}
1611a8ef3e3aSBernard Iremonger 
16120e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16130e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16140e545d30SBernard Iremonger 			continue;
16150e545d30SBernard Iremonger 		}
16160e545d30SBernard Iremonger 
1617ce8d5614SIntel 		port = &ports[pi];
1618ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1619ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1620ce8d5614SIntel 			continue;
1621ce8d5614SIntel 
1622ce8d5614SIntel 		rte_eth_dev_stop(pi);
1623ce8d5614SIntel 
1624ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1625ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1626ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1627ce8d5614SIntel 		need_check_link_status = 1;
1628ce8d5614SIntel 	}
1629bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1630edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1631ce8d5614SIntel 
1632ce8d5614SIntel 	printf("Done\n");
1633ce8d5614SIntel }
1634ce8d5614SIntel 
1635ce8d5614SIntel void
1636ce8d5614SIntel close_port(portid_t pid)
1637ce8d5614SIntel {
1638ce8d5614SIntel 	portid_t pi;
1639ce8d5614SIntel 	struct rte_port *port;
1640ce8d5614SIntel 
16414468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
16424468635fSMichael Qiu 		return;
16434468635fSMichael Qiu 
1644ce8d5614SIntel 	printf("Closing ports...\n");
1645ce8d5614SIntel 
16467d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16474468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1648ce8d5614SIntel 			continue;
1649ce8d5614SIntel 
1650a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1651a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1652a8ef3e3aSBernard Iremonger 			continue;
1653a8ef3e3aSBernard Iremonger 		}
1654a8ef3e3aSBernard Iremonger 
16550e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16560e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16570e545d30SBernard Iremonger 			continue;
16580e545d30SBernard Iremonger 		}
16590e545d30SBernard Iremonger 
1660ce8d5614SIntel 		port = &ports[pi];
1661ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1662d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1663d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1664d4e8ad64SMichael Qiu 			continue;
1665d4e8ad64SMichael Qiu 		}
1666d4e8ad64SMichael Qiu 
1667d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1668ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1669ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1670ce8d5614SIntel 			continue;
1671ce8d5614SIntel 		}
1672ce8d5614SIntel 
1673938a184aSAdrien Mazarguil 		if (port->flow_list)
1674938a184aSAdrien Mazarguil 			port_flow_flush(pi);
1675ce8d5614SIntel 		rte_eth_dev_close(pi);
1676ce8d5614SIntel 
1677ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1678ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1679b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1680ce8d5614SIntel 	}
1681ce8d5614SIntel 
1682ce8d5614SIntel 	printf("Done\n");
1683ce8d5614SIntel }
1684ce8d5614SIntel 
1685edab33b1STetsuya Mukawa void
1686edab33b1STetsuya Mukawa attach_port(char *identifier)
1687ce8d5614SIntel {
1688ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1689931126baSBernard Iremonger 	unsigned int socket_id;
1690ce8d5614SIntel 
1691edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1692edab33b1STetsuya Mukawa 
1693edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1694edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1695edab33b1STetsuya Mukawa 		return;
1696ce8d5614SIntel 	}
1697ce8d5614SIntel 
1698edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1699edab33b1STetsuya Mukawa 		return;
1700edab33b1STetsuya Mukawa 
1701931126baSBernard Iremonger 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1702931126baSBernard Iremonger 	/* if socket_id is invalid, set to 0 */
1703931126baSBernard Iremonger 	if (check_socket_id(socket_id) < 0)
1704931126baSBernard Iremonger 		socket_id = 0;
1705931126baSBernard Iremonger 	reconfig(pi, socket_id);
1706edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1707edab33b1STetsuya Mukawa 
1708edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1709edab33b1STetsuya Mukawa 
1710edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1711edab33b1STetsuya Mukawa 
1712edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1713edab33b1STetsuya Mukawa 	printf("Done\n");
1714edab33b1STetsuya Mukawa }
1715edab33b1STetsuya Mukawa 
1716edab33b1STetsuya Mukawa void
1717edab33b1STetsuya Mukawa detach_port(uint8_t port_id)
17185f4ec54fSChen Jing D(Mark) {
1719edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
17205f4ec54fSChen Jing D(Mark) 
1721edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
17225f4ec54fSChen Jing D(Mark) 
1723edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1724edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1725edab33b1STetsuya Mukawa 		return;
1726edab33b1STetsuya Mukawa 	}
1727edab33b1STetsuya Mukawa 
1728938a184aSAdrien Mazarguil 	if (ports[port_id].flow_list)
1729938a184aSAdrien Mazarguil 		port_flow_flush(port_id);
1730938a184aSAdrien Mazarguil 
1731*3070419eSGaetan Rivet 	if (rte_eth_dev_detach(port_id, name)) {
1732*3070419eSGaetan Rivet 		RTE_LOG(ERR, USER1, "Failed to detach port '%s'\n", name);
1733edab33b1STetsuya Mukawa 		return;
1734*3070419eSGaetan Rivet 	}
1735edab33b1STetsuya Mukawa 
1736edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1737edab33b1STetsuya Mukawa 
1738edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1739edab33b1STetsuya Mukawa 			name, nb_ports);
1740edab33b1STetsuya Mukawa 	printf("Done\n");
1741edab33b1STetsuya Mukawa 	return;
17425f4ec54fSChen Jing D(Mark) }
17435f4ec54fSChen Jing D(Mark) 
1744af75078fSIntel void
1745af75078fSIntel pmd_test_exit(void)
1746af75078fSIntel {
1747af75078fSIntel 	portid_t pt_id;
1748af75078fSIntel 
17498210ec25SPablo de Lara 	if (test_done == 0)
17508210ec25SPablo de Lara 		stop_packet_forwarding();
17518210ec25SPablo de Lara 
1752d3a274ceSZhihong Wang 	if (ports != NULL) {
1753d3a274ceSZhihong Wang 		no_link_check = 1;
17547d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(pt_id) {
1755d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1756af75078fSIntel 			fflush(stdout);
1757d3a274ceSZhihong Wang 			stop_port(pt_id);
1758d3a274ceSZhihong Wang 			close_port(pt_id);
1759af75078fSIntel 		}
1760d3a274ceSZhihong Wang 	}
1761d3a274ceSZhihong Wang 	printf("\nBye...\n");
1762af75078fSIntel }
1763af75078fSIntel 
1764af75078fSIntel typedef void (*cmd_func_t)(void);
1765af75078fSIntel struct pmd_test_command {
1766af75078fSIntel 	const char *cmd_name;
1767af75078fSIntel 	cmd_func_t cmd_func;
1768af75078fSIntel };
1769af75078fSIntel 
1770af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1771af75078fSIntel 
1772ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1773af75078fSIntel static void
1774edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1775af75078fSIntel {
1776ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1777ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1778ce8d5614SIntel 	uint8_t portid, count, all_ports_up, print_flag = 0;
1779ce8d5614SIntel 	struct rte_eth_link link;
1780ce8d5614SIntel 
1781ce8d5614SIntel 	printf("Checking link statuses...\n");
1782ce8d5614SIntel 	fflush(stdout);
1783ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1784ce8d5614SIntel 		all_ports_up = 1;
17857d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(portid) {
1786ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1787ce8d5614SIntel 				continue;
1788ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1789ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1790ce8d5614SIntel 			/* print link status if flag set */
1791ce8d5614SIntel 			if (print_flag == 1) {
1792ce8d5614SIntel 				if (link.link_status)
1793ce8d5614SIntel 					printf("Port %d Link Up - speed %u "
1794ce8d5614SIntel 						"Mbps - %s\n", (uint8_t)portid,
1795ce8d5614SIntel 						(unsigned)link.link_speed,
1796ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1797ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1798ce8d5614SIntel 				else
1799ce8d5614SIntel 					printf("Port %d Link Down\n",
1800ce8d5614SIntel 						(uint8_t)portid);
1801ce8d5614SIntel 				continue;
1802ce8d5614SIntel 			}
1803ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
180409419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1805ce8d5614SIntel 				all_ports_up = 0;
1806ce8d5614SIntel 				break;
1807ce8d5614SIntel 			}
1808ce8d5614SIntel 		}
1809ce8d5614SIntel 		/* after finally printing all link status, get out */
1810ce8d5614SIntel 		if (print_flag == 1)
1811ce8d5614SIntel 			break;
1812ce8d5614SIntel 
1813ce8d5614SIntel 		if (all_ports_up == 0) {
1814ce8d5614SIntel 			fflush(stdout);
1815ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1816ce8d5614SIntel 		}
1817ce8d5614SIntel 
1818ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1819ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1820ce8d5614SIntel 			print_flag = 1;
1821ce8d5614SIntel 		}
18228ea656f8SGaetan Rivet 
18238ea656f8SGaetan Rivet 		if (lsc_interrupt)
18248ea656f8SGaetan Rivet 			break;
1825ce8d5614SIntel 	}
1826af75078fSIntel }
1827af75078fSIntel 
1828284c908cSGaetan Rivet static void
1829284c908cSGaetan Rivet rmv_event_callback(void *arg)
1830284c908cSGaetan Rivet {
1831284c908cSGaetan Rivet 	struct rte_eth_dev *dev;
1832284c908cSGaetan Rivet 	uint8_t port_id = (intptr_t)arg;
1833284c908cSGaetan Rivet 
1834284c908cSGaetan Rivet 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
1835284c908cSGaetan Rivet 	dev = &rte_eth_devices[port_id];
1836284c908cSGaetan Rivet 
1837284c908cSGaetan Rivet 	stop_port(port_id);
1838284c908cSGaetan Rivet 	close_port(port_id);
1839f3a1188cSGaetan Rivet 	printf("removing device %s\n", dev->device->name);
1840*3070419eSGaetan Rivet 	if (rte_eal_dev_detach(dev->device))
1841*3070419eSGaetan Rivet 		RTE_LOG(ERR, USER1, "Failed to detach device %s\n",
1842*3070419eSGaetan Rivet 			dev->device->name);
1843284c908cSGaetan Rivet }
1844284c908cSGaetan Rivet 
184576ad4a2dSGaetan Rivet /* This function is used by the interrupt thread */
1846d6af1a13SBernard Iremonger static int
1847d6af1a13SBernard Iremonger eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param,
1848d6af1a13SBernard Iremonger 		  void *ret_param)
184976ad4a2dSGaetan Rivet {
185076ad4a2dSGaetan Rivet 	static const char * const event_desc[] = {
185176ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
185276ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
185376ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
185476ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
185576ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
185676ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
185776ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
185876ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MAX] = NULL,
185976ad4a2dSGaetan Rivet 	};
186076ad4a2dSGaetan Rivet 
186176ad4a2dSGaetan Rivet 	RTE_SET_USED(param);
1862d6af1a13SBernard Iremonger 	RTE_SET_USED(ret_param);
186376ad4a2dSGaetan Rivet 
186476ad4a2dSGaetan Rivet 	if (type >= RTE_ETH_EVENT_MAX) {
186576ad4a2dSGaetan Rivet 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
186676ad4a2dSGaetan Rivet 			port_id, __func__, type);
186776ad4a2dSGaetan Rivet 		fflush(stderr);
18683af72783SGaetan Rivet 	} else if (event_print_mask & (UINT32_C(1) << type)) {
186976ad4a2dSGaetan Rivet 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
187076ad4a2dSGaetan Rivet 			event_desc[type]);
187176ad4a2dSGaetan Rivet 		fflush(stdout);
187276ad4a2dSGaetan Rivet 	}
1873284c908cSGaetan Rivet 
1874284c908cSGaetan Rivet 	switch (type) {
1875284c908cSGaetan Rivet 	case RTE_ETH_EVENT_INTR_RMV:
1876284c908cSGaetan Rivet 		if (rte_eal_alarm_set(100000,
1877284c908cSGaetan Rivet 				rmv_event_callback, (void *)(intptr_t)port_id))
1878284c908cSGaetan Rivet 			fprintf(stderr, "Could not set up deferred device removal\n");
1879284c908cSGaetan Rivet 		break;
1880284c908cSGaetan Rivet 	default:
1881284c908cSGaetan Rivet 		break;
1882284c908cSGaetan Rivet 	}
1883d6af1a13SBernard Iremonger 	return 0;
188476ad4a2dSGaetan Rivet }
188576ad4a2dSGaetan Rivet 
1886013af9b6SIntel static int
1887013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1888af75078fSIntel {
1889013af9b6SIntel 	uint16_t i;
1890af75078fSIntel 	int diag;
1891013af9b6SIntel 	uint8_t mapping_found = 0;
1892af75078fSIntel 
1893013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1894013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1895013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1896013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1897013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1898013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1899013af9b6SIntel 			if (diag != 0)
1900013af9b6SIntel 				return diag;
1901013af9b6SIntel 			mapping_found = 1;
1902af75078fSIntel 		}
1903013af9b6SIntel 	}
1904013af9b6SIntel 	if (mapping_found)
1905013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1906013af9b6SIntel 	return 0;
1907013af9b6SIntel }
1908013af9b6SIntel 
1909013af9b6SIntel static int
1910013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1911013af9b6SIntel {
1912013af9b6SIntel 	uint16_t i;
1913013af9b6SIntel 	int diag;
1914013af9b6SIntel 	uint8_t mapping_found = 0;
1915013af9b6SIntel 
1916013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1917013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1918013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1919013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1920013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1921013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1922013af9b6SIntel 			if (diag != 0)
1923013af9b6SIntel 				return diag;
1924013af9b6SIntel 			mapping_found = 1;
1925013af9b6SIntel 		}
1926013af9b6SIntel 	}
1927013af9b6SIntel 	if (mapping_found)
1928013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1929013af9b6SIntel 	return 0;
1930013af9b6SIntel }
1931013af9b6SIntel 
1932013af9b6SIntel static void
1933013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1934013af9b6SIntel {
1935013af9b6SIntel 	int diag = 0;
1936013af9b6SIntel 
1937013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
1938af75078fSIntel 	if (diag != 0) {
1939013af9b6SIntel 		if (diag == -ENOTSUP) {
1940013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
1941013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
1942013af9b6SIntel 		}
1943013af9b6SIntel 		else
1944013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1945013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
1946013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1947af75078fSIntel 					pi, diag);
1948af75078fSIntel 	}
1949013af9b6SIntel 
1950013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
1951af75078fSIntel 	if (diag != 0) {
1952013af9b6SIntel 		if (diag == -ENOTSUP) {
1953013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
1954013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
1955013af9b6SIntel 		}
1956013af9b6SIntel 		else
1957013af9b6SIntel 			rte_exit(EXIT_FAILURE,
1958013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
1959013af9b6SIntel 					"failed for port id=%d diag=%d\n",
1960af75078fSIntel 					pi, diag);
1961af75078fSIntel 	}
1962af75078fSIntel }
1963af75078fSIntel 
1964f2c5125aSPablo de Lara static void
1965f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
1966f2c5125aSPablo de Lara {
1967f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
1968f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
1969f2c5125aSPablo de Lara 
1970f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
1971f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1972f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1973f2c5125aSPablo de Lara 
1974f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1975f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1976f2c5125aSPablo de Lara 
1977f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1978f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1979f2c5125aSPablo de Lara 
1980f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1981f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
1982f2c5125aSPablo de Lara 
1983f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1984f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
1985f2c5125aSPablo de Lara 
1986f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1987f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1988f2c5125aSPablo de Lara 
1989f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1990f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1991f2c5125aSPablo de Lara 
1992f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1993f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1994f2c5125aSPablo de Lara 
1995f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1996f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1997f2c5125aSPablo de Lara 
1998f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1999f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
2000f2c5125aSPablo de Lara 
2001f2c5125aSPablo de Lara 	if (txq_flags != RTE_PMD_PARAM_UNSET)
2002f2c5125aSPablo de Lara 		port->tx_conf.txq_flags = txq_flags;
2003f2c5125aSPablo de Lara }
2004f2c5125aSPablo de Lara 
2005013af9b6SIntel void
2006013af9b6SIntel init_port_config(void)
2007013af9b6SIntel {
2008013af9b6SIntel 	portid_t pid;
2009013af9b6SIntel 	struct rte_port *port;
2010013af9b6SIntel 
20117d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
2012013af9b6SIntel 		port = &ports[pid];
2013013af9b6SIntel 		port->dev_conf.rxmode = rx_mode;
2014013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
20153ce690d3SBruce Richardson 		if (nb_rxq > 1) {
2016013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2017013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2018af75078fSIntel 		} else {
2019013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2020013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2021af75078fSIntel 		}
20223ce690d3SBruce Richardson 
20235f592039SJingjing Wu 		if (port->dcb_flag == 0) {
20243ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
20253ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
20263ce690d3SBruce Richardson 			else
20273ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
20283ce690d3SBruce Richardson 		}
20293ce690d3SBruce Richardson 
2030f2c5125aSPablo de Lara 		rxtx_port_config(port);
2031013af9b6SIntel 
2032013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
2033013af9b6SIntel 
2034013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
203550c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2036e261265eSRadu Nicolau 		rte_pmd_ixgbe_bypass_init(pid);
20377b7e5ba7SIntel #endif
20388ea656f8SGaetan Rivet 
20398ea656f8SGaetan Rivet 		if (lsc_interrupt &&
20408ea656f8SGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
20418ea656f8SGaetan Rivet 		     RTE_ETH_DEV_INTR_LSC))
20428ea656f8SGaetan Rivet 			port->dev_conf.intr_conf.lsc = 1;
2043284c908cSGaetan Rivet 		if (rmv_interrupt &&
2044284c908cSGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
2045284c908cSGaetan Rivet 		     RTE_ETH_DEV_INTR_RMV))
2046284c908cSGaetan Rivet 			port->dev_conf.intr_conf.rmv = 1;
2047013af9b6SIntel 	}
2048013af9b6SIntel }
2049013af9b6SIntel 
205041b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
205141b05095SBernard Iremonger {
205241b05095SBernard Iremonger 	struct rte_port *port;
205341b05095SBernard Iremonger 
205441b05095SBernard Iremonger 	port = &ports[slave_pid];
205541b05095SBernard Iremonger 	port->slave_flag = 1;
205641b05095SBernard Iremonger }
205741b05095SBernard Iremonger 
205841b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
205941b05095SBernard Iremonger {
206041b05095SBernard Iremonger 	struct rte_port *port;
206141b05095SBernard Iremonger 
206241b05095SBernard Iremonger 	port = &ports[slave_pid];
206341b05095SBernard Iremonger 	port->slave_flag = 0;
206441b05095SBernard Iremonger }
206541b05095SBernard Iremonger 
20660e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
20670e545d30SBernard Iremonger {
20680e545d30SBernard Iremonger 	struct rte_port *port;
20690e545d30SBernard Iremonger 
20700e545d30SBernard Iremonger 	port = &ports[slave_pid];
20710e545d30SBernard Iremonger 	return port->slave_flag;
20720e545d30SBernard Iremonger }
20730e545d30SBernard Iremonger 
2074013af9b6SIntel const uint16_t vlan_tags[] = {
2075013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
2076013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
2077013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
2078013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
2079013af9b6SIntel };
2080013af9b6SIntel 
2081013af9b6SIntel static  int
20821a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
20831a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
20841a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
20851a572499SJingjing Wu 		 uint8_t pfc_en)
2086013af9b6SIntel {
2087013af9b6SIntel 	uint8_t i;
2088af75078fSIntel 
2089af75078fSIntel 	/*
2090013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2091013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
2092af75078fSIntel 	 */
20931a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
20941a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
20951a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
20961a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
20971a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2098013af9b6SIntel 
2099547d946cSNirmoy Das 		/* VMDQ+DCB RX and TX configurations */
21001a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
21011a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
21021a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
21031a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
21041a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
21051a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2106013af9b6SIntel 
21071a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
21081a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
21091a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
21101a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
21111a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2112af75078fSIntel 		}
2113013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
21141a572499SJingjing Wu 			vmdq_rx_conf->dcb_tc[i] = i;
21151a572499SJingjing Wu 			vmdq_tx_conf->dcb_tc[i] = i;
2116013af9b6SIntel 		}
2117013af9b6SIntel 
2118013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
211932e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
212032e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
21211a572499SJingjing Wu 	} else {
21221a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
21231a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
21241a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
21251a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2126013af9b6SIntel 
21271a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
21281a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
21291a572499SJingjing Wu 
2130bcd0e432SJingjing Wu 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2131bcd0e432SJingjing Wu 			rx_conf->dcb_tc[i] = i % num_tcs;
2132bcd0e432SJingjing Wu 			tx_conf->dcb_tc[i] = i % num_tcs;
2133013af9b6SIntel 		}
21341a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
21351a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
213632e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
21371a572499SJingjing Wu 	}
21381a572499SJingjing Wu 
21391a572499SJingjing Wu 	if (pfc_en)
21401a572499SJingjing Wu 		eth_conf->dcb_capability_en =
21411a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2142013af9b6SIntel 	else
2143013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2144013af9b6SIntel 
2145013af9b6SIntel 	return 0;
2146013af9b6SIntel }
2147013af9b6SIntel 
2148013af9b6SIntel int
21491a572499SJingjing Wu init_port_dcb_config(portid_t pid,
21501a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
21511a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
21521a572499SJingjing Wu 		     uint8_t pfc_en)
2153013af9b6SIntel {
2154013af9b6SIntel 	struct rte_eth_conf port_conf;
2155013af9b6SIntel 	struct rte_port *rte_port;
2156013af9b6SIntel 	int retval;
2157013af9b6SIntel 	uint16_t i;
2158013af9b6SIntel 
21592a977b89SWenzhuo Lu 	rte_port = &ports[pid];
2160013af9b6SIntel 
2161013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2162013af9b6SIntel 	/* Enter DCB configuration status */
2163013af9b6SIntel 	dcb_config = 1;
2164013af9b6SIntel 
2165013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
21661a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2167013af9b6SIntel 	if (retval < 0)
2168013af9b6SIntel 		return retval;
21692a977b89SWenzhuo Lu 	port_conf.rxmode.hw_vlan_filter = 1;
2170013af9b6SIntel 
21712a977b89SWenzhuo Lu 	/**
21722a977b89SWenzhuo Lu 	 * Write the configuration into the device.
21732a977b89SWenzhuo Lu 	 * Set the numbers of RX & TX queues to 0, so
21742a977b89SWenzhuo Lu 	 * the RX & TX queues will not be setup.
21752a977b89SWenzhuo Lu 	 */
21762a977b89SWenzhuo Lu 	(void)rte_eth_dev_configure(pid, 0, 0, &port_conf);
21772a977b89SWenzhuo Lu 
21782a977b89SWenzhuo Lu 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
21792a977b89SWenzhuo Lu 
21802a977b89SWenzhuo Lu 	/* If dev_info.vmdq_pool_base is greater than 0,
21812a977b89SWenzhuo Lu 	 * the queue id of vmdq pools is started after pf queues.
21822a977b89SWenzhuo Lu 	 */
21832a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED &&
21842a977b89SWenzhuo Lu 	    rte_port->dev_info.vmdq_pool_base > 0) {
21852a977b89SWenzhuo Lu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
21862a977b89SWenzhuo Lu 			" for port %d.", pid);
21872a977b89SWenzhuo Lu 		return -1;
21882a977b89SWenzhuo Lu 	}
21892a977b89SWenzhuo Lu 
21902a977b89SWenzhuo Lu 	/* Assume the ports in testpmd have the same dcb capability
21912a977b89SWenzhuo Lu 	 * and has the same number of rxq and txq in dcb mode
21922a977b89SWenzhuo Lu 	 */
21932a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED) {
219486ef65eeSBernard Iremonger 		if (rte_port->dev_info.max_vfs > 0) {
219586ef65eeSBernard Iremonger 			nb_rxq = rte_port->dev_info.nb_rx_queues;
219686ef65eeSBernard Iremonger 			nb_txq = rte_port->dev_info.nb_tx_queues;
219786ef65eeSBernard Iremonger 		} else {
21982a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
21992a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
220086ef65eeSBernard Iremonger 		}
22012a977b89SWenzhuo Lu 	} else {
22022a977b89SWenzhuo Lu 		/*if vt is disabled, use all pf queues */
22032a977b89SWenzhuo Lu 		if (rte_port->dev_info.vmdq_pool_base == 0) {
22042a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
22052a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
22062a977b89SWenzhuo Lu 		} else {
22072a977b89SWenzhuo Lu 			nb_rxq = (queueid_t)num_tcs;
22082a977b89SWenzhuo Lu 			nb_txq = (queueid_t)num_tcs;
22092a977b89SWenzhuo Lu 
22102a977b89SWenzhuo Lu 		}
22112a977b89SWenzhuo Lu 	}
22122a977b89SWenzhuo Lu 	rx_free_thresh = 64;
22132a977b89SWenzhuo Lu 
2214013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2215013af9b6SIntel 
2216f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
2217013af9b6SIntel 	/* VLAN filter */
2218013af9b6SIntel 	rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
22191a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2220013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
2221013af9b6SIntel 
2222013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2223013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
2224013af9b6SIntel 
22257741e4cfSIntel 	rte_port->dcb_flag = 1;
22267741e4cfSIntel 
2227013af9b6SIntel 	return 0;
2228af75078fSIntel }
2229af75078fSIntel 
2230ffc468ffSTetsuya Mukawa static void
2231ffc468ffSTetsuya Mukawa init_port(void)
2232ffc468ffSTetsuya Mukawa {
2233ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2234ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2235ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2236ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2237ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2238ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2239ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2240ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2241ffc468ffSTetsuya Mukawa 	}
2242ffc468ffSTetsuya Mukawa }
2243ffc468ffSTetsuya Mukawa 
2244d3a274ceSZhihong Wang static void
2245d3a274ceSZhihong Wang force_quit(void)
2246d3a274ceSZhihong Wang {
2247d3a274ceSZhihong Wang 	pmd_test_exit();
2248d3a274ceSZhihong Wang 	prompt_exit();
2249d3a274ceSZhihong Wang }
2250d3a274ceSZhihong Wang 
2251d3a274ceSZhihong Wang static void
2252cfea1f30SPablo de Lara print_stats(void)
2253cfea1f30SPablo de Lara {
2254cfea1f30SPablo de Lara 	uint8_t i;
2255cfea1f30SPablo de Lara 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2256cfea1f30SPablo de Lara 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2257cfea1f30SPablo de Lara 
2258cfea1f30SPablo de Lara 	/* Clear screen and move to top left */
2259cfea1f30SPablo de Lara 	printf("%s%s", clr, top_left);
2260cfea1f30SPablo de Lara 
2261cfea1f30SPablo de Lara 	printf("\nPort statistics ====================================");
2262cfea1f30SPablo de Lara 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2263cfea1f30SPablo de Lara 		nic_stats_display(fwd_ports_ids[i]);
2264cfea1f30SPablo de Lara }
2265cfea1f30SPablo de Lara 
2266cfea1f30SPablo de Lara static void
2267d3a274ceSZhihong Wang signal_handler(int signum)
2268d3a274ceSZhihong Wang {
2269d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2270d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2271d3a274ceSZhihong Wang 				signum);
2272102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2273102b7329SReshma Pattan 		/* uninitialize packet capture framework */
2274102b7329SReshma Pattan 		rte_pdump_uninit();
2275102b7329SReshma Pattan #endif
227662d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
227762d3216dSReshma Pattan 		rte_latencystats_uninit();
227862d3216dSReshma Pattan #endif
2279d3a274ceSZhihong Wang 		force_quit();
2280d3a274ceSZhihong Wang 		/* exit with the expected status */
2281d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2282d3a274ceSZhihong Wang 		kill(getpid(), signum);
2283d3a274ceSZhihong Wang 	}
2284d3a274ceSZhihong Wang }
2285d3a274ceSZhihong Wang 
2286af75078fSIntel int
2287af75078fSIntel main(int argc, char** argv)
2288af75078fSIntel {
2289af75078fSIntel 	int  diag;
2290013af9b6SIntel 	uint8_t port_id;
2291af75078fSIntel 
2292d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2293d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2294d3a274ceSZhihong Wang 
2295af75078fSIntel 	diag = rte_eal_init(argc, argv);
2296af75078fSIntel 	if (diag < 0)
2297af75078fSIntel 		rte_panic("Cannot init EAL\n");
2298af75078fSIntel 
2299102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2300102b7329SReshma Pattan 	/* initialize packet capture framework */
2301102b7329SReshma Pattan 	rte_pdump_init(NULL);
2302102b7329SReshma Pattan #endif
2303102b7329SReshma Pattan 
2304af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2305af75078fSIntel 	if (nb_ports == 0)
2306edab33b1STetsuya Mukawa 		RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2307af75078fSIntel 
2308ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2309ffc468ffSTetsuya Mukawa 	init_port();
2310ffc468ffSTetsuya Mukawa 
2311af75078fSIntel 	set_def_fwd_config();
2312af75078fSIntel 	if (nb_lcores == 0)
2313af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2314af75078fSIntel 			  "core mask supplied in the command parameters\n");
2315af75078fSIntel 
231665eb1e54SPablo de Lara 	/* Bitrate/latency stats disabled by default */
231730bcc68cSPablo de Lara #ifdef RTE_LIBRTE_BITRATE
2318e25e6c70SRemy Horton 	bitrate_enabled = 0;
231930bcc68cSPablo de Lara #endif
232065eb1e54SPablo de Lara #ifdef RTE_LIBRTE_LATENCY_STATS
232165eb1e54SPablo de Lara 	latencystats_enabled = 0;
232265eb1e54SPablo de Lara #endif
2323e25e6c70SRemy Horton 
2324af75078fSIntel 	argc -= diag;
2325af75078fSIntel 	argv += diag;
2326af75078fSIntel 	if (argc > 1)
2327af75078fSIntel 		launch_args_parse(argc, argv);
2328af75078fSIntel 
232999cabef0SPablo de Lara 	if (tx_first && interactive)
233099cabef0SPablo de Lara 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
233199cabef0SPablo de Lara 				"interactive mode.\n");
23325a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
23335a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
23345a8fb55cSReshma Pattan 
23355a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2336af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2337af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2338af75078fSIntel 		       nb_rxq, nb_txq);
2339af75078fSIntel 
2340af75078fSIntel 	init_config();
2341148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2342148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2343af75078fSIntel 
2344ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
23457d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(port_id)
2346ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2347af75078fSIntel 
23487e4441c8SRemy Horton 	/* Init metrics library */
23497e4441c8SRemy Horton 	rte_metrics_init(rte_socket_id());
23507e4441c8SRemy Horton 
235162d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
235262d3216dSReshma Pattan 	if (latencystats_enabled != 0) {
235362d3216dSReshma Pattan 		int ret = rte_latencystats_init(1, NULL);
235462d3216dSReshma Pattan 		if (ret)
235562d3216dSReshma Pattan 			printf("Warning: latencystats init()"
235662d3216dSReshma Pattan 				" returned error %d\n",	ret);
235762d3216dSReshma Pattan 		printf("Latencystats running on lcore %d\n",
235862d3216dSReshma Pattan 			latencystats_lcore_id);
235962d3216dSReshma Pattan 	}
236062d3216dSReshma Pattan #endif
236162d3216dSReshma Pattan 
23627e4441c8SRemy Horton 	/* Setup bitrate stats */
23637e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
2364e25e6c70SRemy Horton 	if (bitrate_enabled != 0) {
23657e4441c8SRemy Horton 		bitrate_data = rte_stats_bitrate_create();
23667e4441c8SRemy Horton 		if (bitrate_data == NULL)
2367e25e6c70SRemy Horton 			rte_exit(EXIT_FAILURE,
2368e25e6c70SRemy Horton 				"Could not allocate bitrate data.\n");
23697e4441c8SRemy Horton 		rte_stats_bitrate_reg(bitrate_data);
2370e25e6c70SRemy Horton 	}
23717e4441c8SRemy Horton #endif
23727e4441c8SRemy Horton 
23730d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
237481ef862bSAllain Legacy 	if (strlen(cmdline_filename) != 0)
237581ef862bSAllain Legacy 		cmdline_read_from_file(cmdline_filename);
237681ef862bSAllain Legacy 
2377ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2378ca7feb22SCyril Chemparathy 		if (auto_start) {
2379ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2380ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2381ca7feb22SCyril Chemparathy 		}
2382af75078fSIntel 		prompt();
23830de738cfSJiayu Hu 		pmd_test_exit();
2384ca7feb22SCyril Chemparathy 	} else
23850d56cb81SThomas Monjalon #endif
23860d56cb81SThomas Monjalon 	{
2387af75078fSIntel 		char c;
2388af75078fSIntel 		int rc;
2389af75078fSIntel 
2390af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
239199cabef0SPablo de Lara 		start_packet_forwarding(tx_first);
2392cfea1f30SPablo de Lara 		if (stats_period != 0) {
2393cfea1f30SPablo de Lara 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2394cfea1f30SPablo de Lara 			uint64_t timer_period;
2395cfea1f30SPablo de Lara 
2396cfea1f30SPablo de Lara 			/* Convert to number of cycles */
2397cfea1f30SPablo de Lara 			timer_period = stats_period * rte_get_timer_hz();
2398cfea1f30SPablo de Lara 
2399cfea1f30SPablo de Lara 			while (1) {
2400cfea1f30SPablo de Lara 				cur_time = rte_get_timer_cycles();
2401cfea1f30SPablo de Lara 				diff_time += cur_time - prev_time;
2402cfea1f30SPablo de Lara 
2403cfea1f30SPablo de Lara 				if (diff_time >= timer_period) {
2404cfea1f30SPablo de Lara 					print_stats();
2405cfea1f30SPablo de Lara 					/* Reset the timer */
2406cfea1f30SPablo de Lara 					diff_time = 0;
2407cfea1f30SPablo de Lara 				}
2408cfea1f30SPablo de Lara 				/* Sleep to avoid unnecessary checks */
2409cfea1f30SPablo de Lara 				prev_time = cur_time;
2410cfea1f30SPablo de Lara 				sleep(1);
2411cfea1f30SPablo de Lara 			}
2412cfea1f30SPablo de Lara 		}
2413cfea1f30SPablo de Lara 
2414af75078fSIntel 		printf("Press enter to exit\n");
2415af75078fSIntel 		rc = read(0, &c, 1);
2416d3a274ceSZhihong Wang 		pmd_test_exit();
2417af75078fSIntel 		if (rc < 0)
2418af75078fSIntel 			return 1;
2419af75078fSIntel 	}
2420af75078fSIntel 
2421af75078fSIntel 	return 0;
2422af75078fSIntel }
2423