xref: /dpdk/app/test-pmd/testpmd.c (revision 4fb82244b3940f9afad21b1fd45bc0c0bceaa44a)
1174a1631SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2174a1631SBruce Richardson  * Copyright(c) 2010-2017 Intel Corporation
3af75078fSIntel  */
4af75078fSIntel 
5af75078fSIntel #include <stdarg.h>
6af75078fSIntel #include <stdio.h>
7af75078fSIntel #include <stdlib.h>
8af75078fSIntel #include <signal.h>
9af75078fSIntel #include <string.h>
10af75078fSIntel #include <time.h>
11af75078fSIntel #include <fcntl.h>
121c036b16SEelco Chaudron #include <sys/mman.h>
13af75078fSIntel #include <sys/types.h>
14af75078fSIntel #include <errno.h>
15af75078fSIntel 
16af75078fSIntel #include <sys/queue.h>
17af75078fSIntel #include <sys/stat.h>
18af75078fSIntel 
19af75078fSIntel #include <stdint.h>
20af75078fSIntel #include <unistd.h>
21af75078fSIntel #include <inttypes.h>
22af75078fSIntel 
23af75078fSIntel #include <rte_common.h>
24d1eb542eSOlivier Matz #include <rte_errno.h>
25af75078fSIntel #include <rte_byteorder.h>
26af75078fSIntel #include <rte_log.h>
27af75078fSIntel #include <rte_debug.h>
28af75078fSIntel #include <rte_cycles.h>
29af75078fSIntel #include <rte_memory.h>
30af75078fSIntel #include <rte_memcpy.h>
31af75078fSIntel #include <rte_launch.h>
32af75078fSIntel #include <rte_eal.h>
33284c908cSGaetan Rivet #include <rte_alarm.h>
34af75078fSIntel #include <rte_per_lcore.h>
35af75078fSIntel #include <rte_lcore.h>
36af75078fSIntel #include <rte_atomic.h>
37af75078fSIntel #include <rte_branch_prediction.h>
38af75078fSIntel #include <rte_mempool.h>
39af75078fSIntel #include <rte_malloc.h>
40af75078fSIntel #include <rte_mbuf.h>
41af75078fSIntel #include <rte_interrupts.h>
42af75078fSIntel #include <rte_pci.h>
43af75078fSIntel #include <rte_ether.h>
44af75078fSIntel #include <rte_ethdev.h>
45edab33b1STetsuya Mukawa #include <rte_dev.h>
46af75078fSIntel #include <rte_string_fns.h>
47e261265eSRadu Nicolau #ifdef RTE_LIBRTE_IXGBE_PMD
48e261265eSRadu Nicolau #include <rte_pmd_ixgbe.h>
49e261265eSRadu Nicolau #endif
50102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
51102b7329SReshma Pattan #include <rte_pdump.h>
52102b7329SReshma Pattan #endif
53938a184aSAdrien Mazarguil #include <rte_flow.h>
547e4441c8SRemy Horton #include <rte_metrics.h>
557e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
567e4441c8SRemy Horton #include <rte_bitrate.h>
577e4441c8SRemy Horton #endif
5862d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
5962d3216dSReshma Pattan #include <rte_latencystats.h>
6062d3216dSReshma Pattan #endif
61af75078fSIntel 
62af75078fSIntel #include "testpmd.h"
63af75078fSIntel 
64af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */
65285fd101SOlivier Matz int testpmd_logtype; /**< Log type for testpmd logs */
66af75078fSIntel 
67af75078fSIntel /* use master core for command line ? */
68af75078fSIntel uint8_t interactive = 0;
69ca7feb22SCyril Chemparathy uint8_t auto_start = 0;
7099cabef0SPablo de Lara uint8_t tx_first;
7181ef862bSAllain Legacy char cmdline_filename[PATH_MAX] = {0};
72af75078fSIntel 
73af75078fSIntel /*
74af75078fSIntel  * NUMA support configuration.
75af75078fSIntel  * When set, the NUMA support attempts to dispatch the allocation of the
76af75078fSIntel  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
77af75078fSIntel  * probed ports among the CPU sockets 0 and 1.
78af75078fSIntel  * Otherwise, all memory is allocated from CPU socket 0.
79af75078fSIntel  */
80999b2ee0SBruce Richardson uint8_t numa_support = 1; /**< numa enabled by default */
81af75078fSIntel 
82af75078fSIntel /*
83b6ea6408SIntel  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
84b6ea6408SIntel  * not configured.
85b6ea6408SIntel  */
86b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG;
87b6ea6408SIntel 
88b6ea6408SIntel /*
89148f963fSBruce Richardson  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
90148f963fSBruce Richardson  */
91148f963fSBruce Richardson uint8_t mp_anon = 0;
92148f963fSBruce Richardson 
93148f963fSBruce Richardson /*
94af75078fSIntel  * Record the Ethernet address of peer target ports to which packets are
95af75078fSIntel  * forwarded.
96547d946cSNirmoy Das  * Must be instantiated with the ethernet addresses of peer traffic generator
97af75078fSIntel  * ports.
98af75078fSIntel  */
99af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
100af75078fSIntel portid_t nb_peer_eth_addrs = 0;
101af75078fSIntel 
102af75078fSIntel /*
103af75078fSIntel  * Probed Target Environment.
104af75078fSIntel  */
105af75078fSIntel struct rte_port *ports;	       /**< For all probed ethernet ports. */
106af75078fSIntel portid_t nb_ports;             /**< Number of probed ethernet ports. */
107af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
108af75078fSIntel lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
109af75078fSIntel 
110af75078fSIntel /*
111af75078fSIntel  * Test Forwarding Configuration.
112af75078fSIntel  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
113af75078fSIntel  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
114af75078fSIntel  */
115af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
116af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
117af75078fSIntel portid_t  nb_cfg_ports;  /**< Number of configured ports. */
118af75078fSIntel portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
119af75078fSIntel 
120af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
121af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
122af75078fSIntel 
123af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
124af75078fSIntel streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
125af75078fSIntel 
126af75078fSIntel /*
127af75078fSIntel  * Forwarding engines.
128af75078fSIntel  */
129af75078fSIntel struct fwd_engine * fwd_engines[] = {
130af75078fSIntel 	&io_fwd_engine,
131af75078fSIntel 	&mac_fwd_engine,
132d47388f1SCyril Chemparathy 	&mac_swap_engine,
133e9e23a61SCyril Chemparathy 	&flow_gen_engine,
134af75078fSIntel 	&rx_only_engine,
135af75078fSIntel 	&tx_only_engine,
136af75078fSIntel 	&csum_fwd_engine,
137168dfa61SIvan Boule 	&icmp_echo_engine,
1385b590fbeSJasvinder Singh #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
1395b590fbeSJasvinder Singh 	&softnic_tm_engine,
1405b590fbeSJasvinder Singh 	&softnic_tm_bypass_engine,
1415b590fbeSJasvinder Singh #endif
142af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588
143af75078fSIntel 	&ieee1588_fwd_engine,
144af75078fSIntel #endif
145af75078fSIntel 	NULL,
146af75078fSIntel };
147af75078fSIntel 
148af75078fSIntel struct fwd_config cur_fwd_config;
149af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
150bf56fce1SZhihong Wang uint32_t retry_enabled;
151bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
152bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
153af75078fSIntel 
154af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
155c8798818SIntel uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
156c8798818SIntel                                       * specified on command-line. */
157cfea1f30SPablo de Lara uint16_t stats_period; /**< Period to show statistics (disabled by default) */
158d9a191a0SPhil Yang 
159d9a191a0SPhil Yang /*
160d9a191a0SPhil Yang  * In container, it cannot terminate the process which running with 'stats-period'
161d9a191a0SPhil Yang  * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
162d9a191a0SPhil Yang  */
163d9a191a0SPhil Yang uint8_t f_quit;
164d9a191a0SPhil Yang 
165af75078fSIntel /*
166af75078fSIntel  * Configuration of packet segments used by the "txonly" processing engine.
167af75078fSIntel  */
168af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
169af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
170af75078fSIntel 	TXONLY_DEF_PACKET_LEN,
171af75078fSIntel };
172af75078fSIntel uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
173af75078fSIntel 
17479bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
17579bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */
17679bec05bSKonstantin Ananyev 
177af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
178e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
179af75078fSIntel 
180900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */
181900550deSIntel uint8_t dcb_config = 0;
182900550deSIntel 
183900550deSIntel /* Whether the dcb is in testing status */
184900550deSIntel uint8_t dcb_test = 0;
185900550deSIntel 
186af75078fSIntel /*
187af75078fSIntel  * Configurable number of RX/TX queues.
188af75078fSIntel  */
189af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
190af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */
191af75078fSIntel 
192af75078fSIntel /*
193af75078fSIntel  * Configurable number of RX/TX ring descriptors.
194af75078fSIntel  */
195af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128
196af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512
197af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
198af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
199af75078fSIntel 
200f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1
201af75078fSIntel /*
202af75078fSIntel  * Configurable values of RX and TX ring threshold registers.
203af75078fSIntel  */
204af75078fSIntel 
205f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
206f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
207f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
208af75078fSIntel 
209f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
210f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
211f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
212af75078fSIntel 
213af75078fSIntel /*
214af75078fSIntel  * Configurable value of RX free threshold.
215af75078fSIntel  */
216f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
217af75078fSIntel 
218af75078fSIntel /*
219ce8d5614SIntel  * Configurable value of RX drop enable.
220ce8d5614SIntel  */
221f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
222ce8d5614SIntel 
223ce8d5614SIntel /*
224af75078fSIntel  * Configurable value of TX free threshold.
225af75078fSIntel  */
226f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
227af75078fSIntel 
228af75078fSIntel /*
229af75078fSIntel  * Configurable value of TX RS bit threshold.
230af75078fSIntel  */
231f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
232af75078fSIntel 
233af75078fSIntel /*
234af75078fSIntel  * Receive Side Scaling (RSS) configuration.
235af75078fSIntel  */
2368a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
237af75078fSIntel 
238af75078fSIntel /*
239af75078fSIntel  * Port topology configuration
240af75078fSIntel  */
241af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
242af75078fSIntel 
2437741e4cfSIntel /*
2447741e4cfSIntel  * Avoids to flush all the RX streams before starts forwarding.
2457741e4cfSIntel  */
2467741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */
2477741e4cfSIntel 
248af75078fSIntel /*
2497ee3e944SVasily Philipov  * Flow API isolated mode.
2507ee3e944SVasily Philipov  */
2517ee3e944SVasily Philipov uint8_t flow_isolate_all;
2527ee3e944SVasily Philipov 
2537ee3e944SVasily Philipov /*
254bc202406SDavid Marchand  * Avoids to check link status when starting/stopping a port.
255bc202406SDavid Marchand  */
256bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */
257bc202406SDavid Marchand 
258bc202406SDavid Marchand /*
2598ea656f8SGaetan Rivet  * Enable link status change notification
2608ea656f8SGaetan Rivet  */
2618ea656f8SGaetan Rivet uint8_t lsc_interrupt = 1; /* enabled by default */
2628ea656f8SGaetan Rivet 
2638ea656f8SGaetan Rivet /*
264284c908cSGaetan Rivet  * Enable device removal notification.
265284c908cSGaetan Rivet  */
266284c908cSGaetan Rivet uint8_t rmv_interrupt = 1; /* enabled by default */
267284c908cSGaetan Rivet 
268284c908cSGaetan Rivet /*
2693af72783SGaetan Rivet  * Display or mask ether events
2703af72783SGaetan Rivet  * Default to all events except VF_MBOX
2713af72783SGaetan Rivet  */
2723af72783SGaetan Rivet uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
2733af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
2743af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
2753af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
2763af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
2773af72783SGaetan Rivet 			    (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
2783af72783SGaetan Rivet 
2793af72783SGaetan Rivet /*
2807b7e5ba7SIntel  * NIC bypass mode configuration options.
2817b7e5ba7SIntel  */
2827b7e5ba7SIntel 
28350c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2847b7e5ba7SIntel /* The NIC bypass watchdog timeout. */
285e261265eSRadu Nicolau uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
2867b7e5ba7SIntel #endif
2877b7e5ba7SIntel 
288e261265eSRadu Nicolau 
28962d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
29062d3216dSReshma Pattan 
29162d3216dSReshma Pattan /*
29262d3216dSReshma Pattan  * Set when latency stats is enabled in the commandline
29362d3216dSReshma Pattan  */
29462d3216dSReshma Pattan uint8_t latencystats_enabled;
29562d3216dSReshma Pattan 
29662d3216dSReshma Pattan /*
29762d3216dSReshma Pattan  * Lcore ID to serive latency statistics.
29862d3216dSReshma Pattan  */
29962d3216dSReshma Pattan lcoreid_t latencystats_lcore_id = -1;
30062d3216dSReshma Pattan 
30162d3216dSReshma Pattan #endif
30262d3216dSReshma Pattan 
3037b7e5ba7SIntel /*
304af75078fSIntel  * Ethernet device configuration.
305af75078fSIntel  */
306af75078fSIntel struct rte_eth_rxmode rx_mode = {
307af75078fSIntel 	.max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
3080074d02fSShahaf Shuler 	.offloads = (DEV_RX_OFFLOAD_VLAN_FILTER |
3090074d02fSShahaf Shuler 		     DEV_RX_OFFLOAD_VLAN_STRIP |
3100074d02fSShahaf Shuler 		     DEV_RX_OFFLOAD_CRC_STRIP),
3110074d02fSShahaf Shuler 	.ignore_offload_bitfield = 1,
312af75078fSIntel };
313af75078fSIntel 
31407e5f7bdSShahaf Shuler struct rte_eth_txmode tx_mode = {
31507e5f7bdSShahaf Shuler 	.offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
31607e5f7bdSShahaf Shuler };
317fd8c20aaSShahaf Shuler 
318af75078fSIntel struct rte_fdir_conf fdir_conf = {
319af75078fSIntel 	.mode = RTE_FDIR_MODE_NONE,
320af75078fSIntel 	.pballoc = RTE_FDIR_PBALLOC_64K,
321af75078fSIntel 	.status = RTE_FDIR_REPORT_STATUS,
322d9d5e6f2SJingjing Wu 	.mask = {
323d9d5e6f2SJingjing Wu 		.vlan_tci_mask = 0x0,
324d9d5e6f2SJingjing Wu 		.ipv4_mask     = {
325d9d5e6f2SJingjing Wu 			.src_ip = 0xFFFFFFFF,
326d9d5e6f2SJingjing Wu 			.dst_ip = 0xFFFFFFFF,
327d9d5e6f2SJingjing Wu 		},
328d9d5e6f2SJingjing Wu 		.ipv6_mask     = {
329d9d5e6f2SJingjing Wu 			.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
330d9d5e6f2SJingjing Wu 			.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
331d9d5e6f2SJingjing Wu 		},
332d9d5e6f2SJingjing Wu 		.src_port_mask = 0xFFFF,
333d9d5e6f2SJingjing Wu 		.dst_port_mask = 0xFFFF,
33447b3ac6bSWenzhuo Lu 		.mac_addr_byte_mask = 0xFF,
33547b3ac6bSWenzhuo Lu 		.tunnel_type_mask = 1,
33647b3ac6bSWenzhuo Lu 		.tunnel_id_mask = 0xFFFFFFFF,
337d9d5e6f2SJingjing Wu 	},
338af75078fSIntel 	.drop_queue = 127,
339af75078fSIntel };
340af75078fSIntel 
3412950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */
342af75078fSIntel 
343ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
344ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
345ed30d9b6SIntel 
346ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
347ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
348ed30d9b6SIntel 
349ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0;
350ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0;
351ed30d9b6SIntel 
352a4fd5eeeSElza Mathew /*
353a4fd5eeeSElza Mathew  * Display zero values by default for xstats
354a4fd5eeeSElza Mathew  */
355a4fd5eeeSElza Mathew uint8_t xstats_hide_zero;
356a4fd5eeeSElza Mathew 
357c9cafcc8SShahaf Shuler unsigned int num_sockets = 0;
358c9cafcc8SShahaf Shuler unsigned int socket_ids[RTE_MAX_NUMA_NODES];
3597acf894dSStephen Hurd 
360e25e6c70SRemy Horton #ifdef RTE_LIBRTE_BITRATE
3617e4441c8SRemy Horton /* Bitrate statistics */
3627e4441c8SRemy Horton struct rte_stats_bitrates *bitrate_data;
363e25e6c70SRemy Horton lcoreid_t bitrate_lcore_id;
364e25e6c70SRemy Horton uint8_t bitrate_enabled;
365e25e6c70SRemy Horton #endif
3667e4441c8SRemy Horton 
367b40f8d78SJiayu Hu struct gro_status gro_ports[RTE_MAX_ETHPORTS];
368b7091f1dSJiayu Hu uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
369b40f8d78SJiayu Hu 
370ed30d9b6SIntel /* Forward function declarations */
37128caa76aSZhiyong Yang static void map_port_queue_stats_mapping_registers(portid_t pi,
37228caa76aSZhiyong Yang 						   struct rte_port *port);
373edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask);
374f8244c63SZhiyong Yang static int eth_event_callback(portid_t port_id,
37576ad4a2dSGaetan Rivet 			      enum rte_eth_event_type type,
376d6af1a13SBernard Iremonger 			      void *param, void *ret_param);
377ce8d5614SIntel 
378ce8d5614SIntel /*
379ce8d5614SIntel  * Check if all the ports are started.
380ce8d5614SIntel  * If yes, return positive value. If not, return zero.
381ce8d5614SIntel  */
382ce8d5614SIntel static int all_ports_started(void);
383ed30d9b6SIntel 
38452f38a20SJiayu Hu struct gso_status gso_ports[RTE_MAX_ETHPORTS];
38552f38a20SJiayu Hu uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
38652f38a20SJiayu Hu 
387af75078fSIntel /*
38898a7ea33SJerin Jacob  * Helper function to check if socket is already discovered.
389c9cafcc8SShahaf Shuler  * If yes, return positive value. If not, return zero.
390c9cafcc8SShahaf Shuler  */
391c9cafcc8SShahaf Shuler int
392c9cafcc8SShahaf Shuler new_socket_id(unsigned int socket_id)
393c9cafcc8SShahaf Shuler {
394c9cafcc8SShahaf Shuler 	unsigned int i;
395c9cafcc8SShahaf Shuler 
396c9cafcc8SShahaf Shuler 	for (i = 0; i < num_sockets; i++) {
397c9cafcc8SShahaf Shuler 		if (socket_ids[i] == socket_id)
398c9cafcc8SShahaf Shuler 			return 0;
399c9cafcc8SShahaf Shuler 	}
400c9cafcc8SShahaf Shuler 	return 1;
401c9cafcc8SShahaf Shuler }
402c9cafcc8SShahaf Shuler 
403c9cafcc8SShahaf Shuler /*
404af75078fSIntel  * Setup default configuration.
405af75078fSIntel  */
406af75078fSIntel static void
407af75078fSIntel set_default_fwd_lcores_config(void)
408af75078fSIntel {
409af75078fSIntel 	unsigned int i;
410af75078fSIntel 	unsigned int nb_lc;
4117acf894dSStephen Hurd 	unsigned int sock_num;
412af75078fSIntel 
413af75078fSIntel 	nb_lc = 0;
414af75078fSIntel 	for (i = 0; i < RTE_MAX_LCORE; i++) {
415c9cafcc8SShahaf Shuler 		sock_num = rte_lcore_to_socket_id(i);
416c9cafcc8SShahaf Shuler 		if (new_socket_id(sock_num)) {
417c9cafcc8SShahaf Shuler 			if (num_sockets >= RTE_MAX_NUMA_NODES) {
418c9cafcc8SShahaf Shuler 				rte_exit(EXIT_FAILURE,
419c9cafcc8SShahaf Shuler 					 "Total sockets greater than %u\n",
420c9cafcc8SShahaf Shuler 					 RTE_MAX_NUMA_NODES);
421c9cafcc8SShahaf Shuler 			}
422c9cafcc8SShahaf Shuler 			socket_ids[num_sockets++] = sock_num;
4237acf894dSStephen Hurd 		}
424f54fe5eeSStephen Hurd 		if (!rte_lcore_is_enabled(i))
425f54fe5eeSStephen Hurd 			continue;
426f54fe5eeSStephen Hurd 		if (i == rte_get_master_lcore())
427f54fe5eeSStephen Hurd 			continue;
428f54fe5eeSStephen Hurd 		fwd_lcores_cpuids[nb_lc++] = i;
429af75078fSIntel 	}
430af75078fSIntel 	nb_lcores = (lcoreid_t) nb_lc;
431af75078fSIntel 	nb_cfg_lcores = nb_lcores;
432af75078fSIntel 	nb_fwd_lcores = 1;
433af75078fSIntel }
434af75078fSIntel 
435af75078fSIntel static void
436af75078fSIntel set_def_peer_eth_addrs(void)
437af75078fSIntel {
438af75078fSIntel 	portid_t i;
439af75078fSIntel 
440af75078fSIntel 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
441af75078fSIntel 		peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
442af75078fSIntel 		peer_eth_addrs[i].addr_bytes[5] = i;
443af75078fSIntel 	}
444af75078fSIntel }
445af75078fSIntel 
446af75078fSIntel static void
447af75078fSIntel set_default_fwd_ports_config(void)
448af75078fSIntel {
449af75078fSIntel 	portid_t pt_id;
45065a7360cSMatan Azrad 	int i = 0;
451af75078fSIntel 
45265a7360cSMatan Azrad 	RTE_ETH_FOREACH_DEV(pt_id)
45365a7360cSMatan Azrad 		fwd_ports_ids[i++] = pt_id;
454af75078fSIntel 
455af75078fSIntel 	nb_cfg_ports = nb_ports;
456af75078fSIntel 	nb_fwd_ports = nb_ports;
457af75078fSIntel }
458af75078fSIntel 
459af75078fSIntel void
460af75078fSIntel set_def_fwd_config(void)
461af75078fSIntel {
462af75078fSIntel 	set_default_fwd_lcores_config();
463af75078fSIntel 	set_def_peer_eth_addrs();
464af75078fSIntel 	set_default_fwd_ports_config();
465af75078fSIntel }
466af75078fSIntel 
467af75078fSIntel /*
468af75078fSIntel  * Configuration initialisation done once at init time.
469af75078fSIntel  */
470af75078fSIntel static void
471af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
472af75078fSIntel 		 unsigned int socket_id)
473af75078fSIntel {
474af75078fSIntel 	char pool_name[RTE_MEMPOOL_NAMESIZE];
475bece7b6cSChristian Ehrhardt 	struct rte_mempool *rte_mp = NULL;
476af75078fSIntel 	uint32_t mb_size;
477af75078fSIntel 
478dfb03bbeSOlivier Matz 	mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
479af75078fSIntel 	mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
480148f963fSBruce Richardson 
481285fd101SOlivier Matz 	TESTPMD_LOG(INFO,
482d1eb542eSOlivier Matz 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
483d1eb542eSOlivier Matz 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
484d1eb542eSOlivier Matz 
485b19a0c75SOlivier Matz 	if (mp_anon != 0) {
486b19a0c75SOlivier Matz 		rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
487bece7b6cSChristian Ehrhardt 			mb_size, (unsigned) mb_mempool_cache,
488148f963fSBruce Richardson 			sizeof(struct rte_pktmbuf_pool_private),
489148f963fSBruce Richardson 			socket_id, 0);
49024427bb9SOlivier Matz 		if (rte_mp == NULL)
49124427bb9SOlivier Matz 			goto err;
492b19a0c75SOlivier Matz 
493b19a0c75SOlivier Matz 		if (rte_mempool_populate_anon(rte_mp) == 0) {
494b19a0c75SOlivier Matz 			rte_mempool_free(rte_mp);
495b19a0c75SOlivier Matz 			rte_mp = NULL;
49624427bb9SOlivier Matz 			goto err;
497b19a0c75SOlivier Matz 		}
498b19a0c75SOlivier Matz 		rte_pktmbuf_pool_init(rte_mp, NULL);
499b19a0c75SOlivier Matz 		rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
500b19a0c75SOlivier Matz 	} else {
501ea0c20eaSOlivier Matz 		/* wrapper to rte_mempool_create() */
502ea0c20eaSOlivier Matz 		rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
503ea0c20eaSOlivier Matz 			mb_mempool_cache, 0, mbuf_seg_size, socket_id);
504bece7b6cSChristian Ehrhardt 	}
505148f963fSBruce Richardson 
50624427bb9SOlivier Matz err:
507af75078fSIntel 	if (rte_mp == NULL) {
508d1eb542eSOlivier Matz 		rte_exit(EXIT_FAILURE,
509d1eb542eSOlivier Matz 			"Creation of mbuf pool for socket %u failed: %s\n",
510d1eb542eSOlivier Matz 			socket_id, rte_strerror(rte_errno));
511148f963fSBruce Richardson 	} else if (verbose_level > 0) {
512591a9d79SStephen Hemminger 		rte_mempool_dump(stdout, rte_mp);
513af75078fSIntel 	}
514af75078fSIntel }
515af75078fSIntel 
51620a0286fSLiu Xiaofeng /*
51720a0286fSLiu Xiaofeng  * Check given socket id is valid or not with NUMA mode,
51820a0286fSLiu Xiaofeng  * if valid, return 0, else return -1
51920a0286fSLiu Xiaofeng  */
52020a0286fSLiu Xiaofeng static int
52120a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id)
52220a0286fSLiu Xiaofeng {
52320a0286fSLiu Xiaofeng 	static int warning_once = 0;
52420a0286fSLiu Xiaofeng 
525c9cafcc8SShahaf Shuler 	if (new_socket_id(socket_id)) {
52620a0286fSLiu Xiaofeng 		if (!warning_once && numa_support)
52720a0286fSLiu Xiaofeng 			printf("Warning: NUMA should be configured manually by"
52820a0286fSLiu Xiaofeng 			       " using --port-numa-config and"
52920a0286fSLiu Xiaofeng 			       " --ring-numa-config parameters along with"
53020a0286fSLiu Xiaofeng 			       " --numa.\n");
53120a0286fSLiu Xiaofeng 		warning_once = 1;
53220a0286fSLiu Xiaofeng 		return -1;
53320a0286fSLiu Xiaofeng 	}
53420a0286fSLiu Xiaofeng 	return 0;
53520a0286fSLiu Xiaofeng }
53620a0286fSLiu Xiaofeng 
537af75078fSIntel static void
538af75078fSIntel init_config(void)
539af75078fSIntel {
540ce8d5614SIntel 	portid_t pid;
541af75078fSIntel 	struct rte_port *port;
542af75078fSIntel 	struct rte_mempool *mbp;
543af75078fSIntel 	unsigned int nb_mbuf_per_pool;
544af75078fSIntel 	lcoreid_t  lc_id;
5457acf894dSStephen Hurd 	uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
546b7091f1dSJiayu Hu 	struct rte_gro_param gro_param;
54752f38a20SJiayu Hu 	uint32_t gso_types;
548af75078fSIntel 
5497acf894dSStephen Hurd 	memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
550487f9a59SYulong Pei 
551487f9a59SYulong Pei 	if (numa_support) {
552487f9a59SYulong Pei 		memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
553487f9a59SYulong Pei 		memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
554487f9a59SYulong Pei 		memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
555487f9a59SYulong Pei 	}
556487f9a59SYulong Pei 
557af75078fSIntel 	/* Configuration of logical cores. */
558af75078fSIntel 	fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
559af75078fSIntel 				sizeof(struct fwd_lcore *) * nb_lcores,
560fdf20fa7SSergio Gonzalez Monroy 				RTE_CACHE_LINE_SIZE);
561af75078fSIntel 	if (fwd_lcores == NULL) {
562ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
563ce8d5614SIntel 							"failed\n", nb_lcores);
564af75078fSIntel 	}
565af75078fSIntel 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
566af75078fSIntel 		fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
567af75078fSIntel 					       sizeof(struct fwd_lcore),
568fdf20fa7SSergio Gonzalez Monroy 					       RTE_CACHE_LINE_SIZE);
569af75078fSIntel 		if (fwd_lcores[lc_id] == NULL) {
570ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
571ce8d5614SIntel 								"failed\n");
572af75078fSIntel 		}
573af75078fSIntel 		fwd_lcores[lc_id]->cpuid_idx = lc_id;
574af75078fSIntel 	}
575af75078fSIntel 
5767d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
577ce8d5614SIntel 		port = &ports[pid];
578fd8c20aaSShahaf Shuler 		/* Apply default Tx configuration for all ports */
579fd8c20aaSShahaf Shuler 		port->dev_conf.txmode = tx_mode;
580384161e0SShahaf Shuler 		port->dev_conf.rxmode = rx_mode;
581ce8d5614SIntel 		rte_eth_dev_info_get(pid, &port->dev_info);
58207e5f7bdSShahaf Shuler 		if (!(port->dev_info.tx_offload_capa &
58307e5f7bdSShahaf Shuler 		      DEV_TX_OFFLOAD_MBUF_FAST_FREE))
58407e5f7bdSShahaf Shuler 			port->dev_conf.txmode.offloads &=
58507e5f7bdSShahaf Shuler 				~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
586ce8d5614SIntel 
587b6ea6408SIntel 		if (numa_support) {
588b6ea6408SIntel 			if (port_numa[pid] != NUMA_NO_CONFIG)
589b6ea6408SIntel 				port_per_socket[port_numa[pid]]++;
590b6ea6408SIntel 			else {
591b6ea6408SIntel 				uint32_t socket_id = rte_eth_dev_socket_id(pid);
59220a0286fSLiu Xiaofeng 
59320a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
59420a0286fSLiu Xiaofeng 				if (check_socket_id(socket_id) < 0)
59520a0286fSLiu Xiaofeng 					socket_id = 0;
596b6ea6408SIntel 				port_per_socket[socket_id]++;
597b6ea6408SIntel 			}
598b6ea6408SIntel 		}
599b6ea6408SIntel 
600ce8d5614SIntel 		/* set flag to initialize port/queue */
601ce8d5614SIntel 		port->need_reconfig = 1;
602ce8d5614SIntel 		port->need_reconfig_queues = 1;
603ce8d5614SIntel 	}
604ce8d5614SIntel 
6053ab64341SOlivier Matz 	/*
6063ab64341SOlivier Matz 	 * Create pools of mbuf.
6073ab64341SOlivier Matz 	 * If NUMA support is disabled, create a single pool of mbuf in
6083ab64341SOlivier Matz 	 * socket 0 memory by default.
6093ab64341SOlivier Matz 	 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
6103ab64341SOlivier Matz 	 *
6113ab64341SOlivier Matz 	 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
6123ab64341SOlivier Matz 	 * nb_txd can be configured at run time.
6133ab64341SOlivier Matz 	 */
6143ab64341SOlivier Matz 	if (param_total_num_mbufs)
6153ab64341SOlivier Matz 		nb_mbuf_per_pool = param_total_num_mbufs;
6163ab64341SOlivier Matz 	else {
6173ab64341SOlivier Matz 		nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
6183ab64341SOlivier Matz 			(nb_lcores * mb_mempool_cache) +
6193ab64341SOlivier Matz 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
6203ab64341SOlivier Matz 		nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
6213ab64341SOlivier Matz 	}
6223ab64341SOlivier Matz 
623b6ea6408SIntel 	if (numa_support) {
624b6ea6408SIntel 		uint8_t i;
625ce8d5614SIntel 
626c9cafcc8SShahaf Shuler 		for (i = 0; i < num_sockets; i++)
627c9cafcc8SShahaf Shuler 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
628c9cafcc8SShahaf Shuler 					 socket_ids[i]);
6293ab64341SOlivier Matz 	} else {
6303ab64341SOlivier Matz 		if (socket_num == UMA_NO_CONFIG)
6313ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
6323ab64341SOlivier Matz 		else
6333ab64341SOlivier Matz 			mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
6343ab64341SOlivier Matz 						 socket_num);
6353ab64341SOlivier Matz 	}
636b6ea6408SIntel 
637b6ea6408SIntel 	init_port_config();
6385886ae07SAdrien Mazarguil 
63952f38a20SJiayu Hu 	gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
64052f38a20SJiayu Hu 		DEV_TX_OFFLOAD_GRE_TNL_TSO;
6415886ae07SAdrien Mazarguil 	/*
6425886ae07SAdrien Mazarguil 	 * Records which Mbuf pool to use by each logical core, if needed.
6435886ae07SAdrien Mazarguil 	 */
6445886ae07SAdrien Mazarguil 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
6458fd8bebcSAdrien Mazarguil 		mbp = mbuf_pool_find(
6468fd8bebcSAdrien Mazarguil 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
6478fd8bebcSAdrien Mazarguil 
6485886ae07SAdrien Mazarguil 		if (mbp == NULL)
6495886ae07SAdrien Mazarguil 			mbp = mbuf_pool_find(0);
6505886ae07SAdrien Mazarguil 		fwd_lcores[lc_id]->mbp = mbp;
65152f38a20SJiayu Hu 		/* initialize GSO context */
65252f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
65352f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
65452f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
65552f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
65652f38a20SJiayu Hu 			ETHER_CRC_LEN;
65752f38a20SJiayu Hu 		fwd_lcores[lc_id]->gso_ctx.flag = 0;
6585886ae07SAdrien Mazarguil 	}
6595886ae07SAdrien Mazarguil 
660ce8d5614SIntel 	/* Configuration of packet forwarding streams. */
661ce8d5614SIntel 	if (init_fwd_streams() < 0)
662ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
6630c0db76fSBernard Iremonger 
6640c0db76fSBernard Iremonger 	fwd_config_setup();
665b7091f1dSJiayu Hu 
666b7091f1dSJiayu Hu 	/* create a gro context for each lcore */
667b7091f1dSJiayu Hu 	gro_param.gro_types = RTE_GRO_TCP_IPV4;
668b7091f1dSJiayu Hu 	gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
669b7091f1dSJiayu Hu 	gro_param.max_item_per_flow = MAX_PKT_BURST;
670b7091f1dSJiayu Hu 	for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
671b7091f1dSJiayu Hu 		gro_param.socket_id = rte_lcore_to_socket_id(
672b7091f1dSJiayu Hu 				fwd_lcores_cpuids[lc_id]);
673b7091f1dSJiayu Hu 		fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
674b7091f1dSJiayu Hu 		if (fwd_lcores[lc_id]->gro_ctx == NULL) {
675b7091f1dSJiayu Hu 			rte_exit(EXIT_FAILURE,
676b7091f1dSJiayu Hu 					"rte_gro_ctx_create() failed\n");
677b7091f1dSJiayu Hu 		}
678b7091f1dSJiayu Hu 	}
679ce8d5614SIntel }
680ce8d5614SIntel 
6812950a769SDeclan Doherty 
6822950a769SDeclan Doherty void
683a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id)
6842950a769SDeclan Doherty {
6852950a769SDeclan Doherty 	struct rte_port *port;
6862950a769SDeclan Doherty 
6872950a769SDeclan Doherty 	/* Reconfiguration of Ethernet ports. */
6882950a769SDeclan Doherty 	port = &ports[new_port_id];
6892950a769SDeclan Doherty 	rte_eth_dev_info_get(new_port_id, &port->dev_info);
6902950a769SDeclan Doherty 
6912950a769SDeclan Doherty 	/* set flag to initialize port/queue */
6922950a769SDeclan Doherty 	port->need_reconfig = 1;
6932950a769SDeclan Doherty 	port->need_reconfig_queues = 1;
694a21d5a4bSDeclan Doherty 	port->socket_id = socket_id;
6952950a769SDeclan Doherty 
6962950a769SDeclan Doherty 	init_port_config();
6972950a769SDeclan Doherty }
6982950a769SDeclan Doherty 
6992950a769SDeclan Doherty 
700ce8d5614SIntel int
701ce8d5614SIntel init_fwd_streams(void)
702ce8d5614SIntel {
703ce8d5614SIntel 	portid_t pid;
704ce8d5614SIntel 	struct rte_port *port;
705ce8d5614SIntel 	streamid_t sm_id, nb_fwd_streams_new;
7065a8fb55cSReshma Pattan 	queueid_t q;
707ce8d5614SIntel 
708ce8d5614SIntel 	/* set socket id according to numa or not */
7097d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
710ce8d5614SIntel 		port = &ports[pid];
711ce8d5614SIntel 		if (nb_rxq > port->dev_info.max_rx_queues) {
712ce8d5614SIntel 			printf("Fail: nb_rxq(%d) is greater than "
713ce8d5614SIntel 				"max_rx_queues(%d)\n", nb_rxq,
714ce8d5614SIntel 				port->dev_info.max_rx_queues);
715ce8d5614SIntel 			return -1;
716ce8d5614SIntel 		}
717ce8d5614SIntel 		if (nb_txq > port->dev_info.max_tx_queues) {
718ce8d5614SIntel 			printf("Fail: nb_txq(%d) is greater than "
719ce8d5614SIntel 				"max_tx_queues(%d)\n", nb_txq,
720ce8d5614SIntel 				port->dev_info.max_tx_queues);
721ce8d5614SIntel 			return -1;
722ce8d5614SIntel 		}
72320a0286fSLiu Xiaofeng 		if (numa_support) {
72420a0286fSLiu Xiaofeng 			if (port_numa[pid] != NUMA_NO_CONFIG)
72520a0286fSLiu Xiaofeng 				port->socket_id = port_numa[pid];
72620a0286fSLiu Xiaofeng 			else {
727b6ea6408SIntel 				port->socket_id = rte_eth_dev_socket_id(pid);
72820a0286fSLiu Xiaofeng 
72920a0286fSLiu Xiaofeng 				/* if socket_id is invalid, set to 0 */
73020a0286fSLiu Xiaofeng 				if (check_socket_id(port->socket_id) < 0)
73120a0286fSLiu Xiaofeng 					port->socket_id = 0;
73220a0286fSLiu Xiaofeng 			}
73320a0286fSLiu Xiaofeng 		}
734b6ea6408SIntel 		else {
735b6ea6408SIntel 			if (socket_num == UMA_NO_CONFIG)
736af75078fSIntel 				port->socket_id = 0;
737b6ea6408SIntel 			else
738b6ea6408SIntel 				port->socket_id = socket_num;
739b6ea6408SIntel 		}
740af75078fSIntel 	}
741af75078fSIntel 
7425a8fb55cSReshma Pattan 	q = RTE_MAX(nb_rxq, nb_txq);
7435a8fb55cSReshma Pattan 	if (q == 0) {
7445a8fb55cSReshma Pattan 		printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
7455a8fb55cSReshma Pattan 		return -1;
7465a8fb55cSReshma Pattan 	}
7475a8fb55cSReshma Pattan 	nb_fwd_streams_new = (streamid_t)(nb_ports * q);
748ce8d5614SIntel 	if (nb_fwd_streams_new == nb_fwd_streams)
749ce8d5614SIntel 		return 0;
750ce8d5614SIntel 	/* clear the old */
751ce8d5614SIntel 	if (fwd_streams != NULL) {
752ce8d5614SIntel 		for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
753ce8d5614SIntel 			if (fwd_streams[sm_id] == NULL)
754ce8d5614SIntel 				continue;
755ce8d5614SIntel 			rte_free(fwd_streams[sm_id]);
756ce8d5614SIntel 			fwd_streams[sm_id] = NULL;
757af75078fSIntel 		}
758ce8d5614SIntel 		rte_free(fwd_streams);
759ce8d5614SIntel 		fwd_streams = NULL;
760ce8d5614SIntel 	}
761ce8d5614SIntel 
762ce8d5614SIntel 	/* init new */
763ce8d5614SIntel 	nb_fwd_streams = nb_fwd_streams_new;
764ce8d5614SIntel 	fwd_streams = rte_zmalloc("testpmd: fwd_streams",
765fdf20fa7SSergio Gonzalez Monroy 		sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
766ce8d5614SIntel 	if (fwd_streams == NULL)
767ce8d5614SIntel 		rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
768ce8d5614SIntel 						"failed\n", nb_fwd_streams);
769ce8d5614SIntel 
770af75078fSIntel 	for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
771af75078fSIntel 		fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
772fdf20fa7SSergio Gonzalez Monroy 				sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
773ce8d5614SIntel 		if (fwd_streams[sm_id] == NULL)
774ce8d5614SIntel 			rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
775ce8d5614SIntel 								" failed\n");
776af75078fSIntel 	}
777ce8d5614SIntel 
778ce8d5614SIntel 	return 0;
779af75078fSIntel }
780af75078fSIntel 
781af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
782af75078fSIntel static void
783af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
784af75078fSIntel {
785af75078fSIntel 	unsigned int total_burst;
786af75078fSIntel 	unsigned int nb_burst;
787af75078fSIntel 	unsigned int burst_stats[3];
788af75078fSIntel 	uint16_t pktnb_stats[3];
789af75078fSIntel 	uint16_t nb_pkt;
790af75078fSIntel 	int burst_percent[3];
791af75078fSIntel 
792af75078fSIntel 	/*
793af75078fSIntel 	 * First compute the total number of packet bursts and the
794af75078fSIntel 	 * two highest numbers of bursts of the same number of packets.
795af75078fSIntel 	 */
796af75078fSIntel 	total_burst = 0;
797af75078fSIntel 	burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
798af75078fSIntel 	pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
799af75078fSIntel 	for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
800af75078fSIntel 		nb_burst = pbs->pkt_burst_spread[nb_pkt];
801af75078fSIntel 		if (nb_burst == 0)
802af75078fSIntel 			continue;
803af75078fSIntel 		total_burst += nb_burst;
804af75078fSIntel 		if (nb_burst > burst_stats[0]) {
805af75078fSIntel 			burst_stats[1] = burst_stats[0];
806af75078fSIntel 			pktnb_stats[1] = pktnb_stats[0];
807af75078fSIntel 			burst_stats[0] = nb_burst;
808af75078fSIntel 			pktnb_stats[0] = nb_pkt;
809af75078fSIntel 		}
810af75078fSIntel 	}
811af75078fSIntel 	if (total_burst == 0)
812af75078fSIntel 		return;
813af75078fSIntel 	burst_percent[0] = (burst_stats[0] * 100) / total_burst;
814af75078fSIntel 	printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
815af75078fSIntel 	       burst_percent[0], (int) pktnb_stats[0]);
816af75078fSIntel 	if (burst_stats[0] == total_burst) {
817af75078fSIntel 		printf("]\n");
818af75078fSIntel 		return;
819af75078fSIntel 	}
820af75078fSIntel 	if (burst_stats[0] + burst_stats[1] == total_burst) {
821af75078fSIntel 		printf(" + %d%% of %d pkts]\n",
822af75078fSIntel 		       100 - burst_percent[0], pktnb_stats[1]);
823af75078fSIntel 		return;
824af75078fSIntel 	}
825af75078fSIntel 	burst_percent[1] = (burst_stats[1] * 100) / total_burst;
826af75078fSIntel 	burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
827af75078fSIntel 	if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
828af75078fSIntel 		printf(" + %d%% of others]\n", 100 - burst_percent[0]);
829af75078fSIntel 		return;
830af75078fSIntel 	}
831af75078fSIntel 	printf(" + %d%% of %d pkts + %d%% of others]\n",
832af75078fSIntel 	       burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
833af75078fSIntel }
834af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
835af75078fSIntel 
836af75078fSIntel static void
837af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
838af75078fSIntel {
839af75078fSIntel 	struct rte_port *port;
840013af9b6SIntel 	uint8_t i;
841af75078fSIntel 
842af75078fSIntel 	static const char *fwd_stats_border = "----------------------";
843af75078fSIntel 
844af75078fSIntel 	port = &ports[port_id];
845af75078fSIntel 	printf("\n  %s Forward statistics for port %-2d %s\n",
846af75078fSIntel 	       fwd_stats_border, port_id, fwd_stats_border);
847013af9b6SIntel 
848013af9b6SIntel 	if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
849af75078fSIntel 		printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
850af75078fSIntel 		       "%-"PRIu64"\n",
85170bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
85270bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
853af75078fSIntel 
854af75078fSIntel 		if (cur_fwd_eng == &csum_fwd_engine)
855af75078fSIntel 			printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
856af75078fSIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
85786057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
858f72a0fa6SStephen Hemminger 			printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
85970bdb186SIvan Boule 			printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
86070bdb186SIvan Boule 		}
861af75078fSIntel 
862af75078fSIntel 		printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
863af75078fSIntel 		       "%-"PRIu64"\n",
864af75078fSIntel 		       stats->opackets, port->tx_dropped,
865af75078fSIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
866013af9b6SIntel 	}
867013af9b6SIntel 	else {
868013af9b6SIntel 		printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
869013af9b6SIntel 		       "%14"PRIu64"\n",
87070bdb186SIvan Boule 		       stats->ipackets, stats->imissed,
87170bdb186SIvan Boule 		       (uint64_t) (stats->ipackets + stats->imissed));
872013af9b6SIntel 
873013af9b6SIntel 		if (cur_fwd_eng == &csum_fwd_engine)
874013af9b6SIntel 			printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
875013af9b6SIntel 			       port->rx_bad_ip_csum, port->rx_bad_l4_csum);
87686057c99SIgor Ryzhov 		if ((stats->ierrors + stats->rx_nombuf) > 0) {
877f72a0fa6SStephen Hemminger 			printf("  RX-error:%"PRIu64"\n", stats->ierrors);
87870bdb186SIvan Boule 			printf("  RX-nombufs:             %14"PRIu64"\n",
87970bdb186SIvan Boule 			       stats->rx_nombuf);
88070bdb186SIvan Boule 		}
881013af9b6SIntel 
882013af9b6SIntel 		printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
883013af9b6SIntel 		       "%14"PRIu64"\n",
884013af9b6SIntel 		       stats->opackets, port->tx_dropped,
885013af9b6SIntel 		       (uint64_t) (stats->opackets + port->tx_dropped));
886013af9b6SIntel 	}
887e659b6b4SIvan Boule 
888af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
889af75078fSIntel 	if (port->rx_stream)
890013af9b6SIntel 		pkt_burst_stats_display("RX",
891013af9b6SIntel 			&port->rx_stream->rx_burst_stats);
892af75078fSIntel 	if (port->tx_stream)
893013af9b6SIntel 		pkt_burst_stats_display("TX",
894013af9b6SIntel 			&port->tx_stream->tx_burst_stats);
895af75078fSIntel #endif
896af75078fSIntel 
897013af9b6SIntel 	if (port->rx_queue_stats_mapping_enabled) {
898013af9b6SIntel 		printf("\n");
899013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
900013af9b6SIntel 			printf("  Stats reg %2d RX-packets:%14"PRIu64
901013af9b6SIntel 			       "     RX-errors:%14"PRIu64
902013af9b6SIntel 			       "    RX-bytes:%14"PRIu64"\n",
903013af9b6SIntel 			       i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
904013af9b6SIntel 		}
905013af9b6SIntel 		printf("\n");
906013af9b6SIntel 	}
907013af9b6SIntel 	if (port->tx_queue_stats_mapping_enabled) {
908013af9b6SIntel 		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
909013af9b6SIntel 			printf("  Stats reg %2d TX-packets:%14"PRIu64
910013af9b6SIntel 			       "                                 TX-bytes:%14"PRIu64"\n",
911013af9b6SIntel 			       i, stats->q_opackets[i], stats->q_obytes[i]);
912013af9b6SIntel 		}
913013af9b6SIntel 	}
914013af9b6SIntel 
915af75078fSIntel 	printf("  %s--------------------------------%s\n",
916af75078fSIntel 	       fwd_stats_border, fwd_stats_border);
917af75078fSIntel }
918af75078fSIntel 
919af75078fSIntel static void
920af75078fSIntel fwd_stream_stats_display(streamid_t stream_id)
921af75078fSIntel {
922af75078fSIntel 	struct fwd_stream *fs;
923af75078fSIntel 	static const char *fwd_top_stats_border = "-------";
924af75078fSIntel 
925af75078fSIntel 	fs = fwd_streams[stream_id];
926af75078fSIntel 	if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
927af75078fSIntel 	    (fs->fwd_dropped == 0))
928af75078fSIntel 		return;
929af75078fSIntel 	printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
930af75078fSIntel 	       "TX Port=%2d/Queue=%2d %s\n",
931af75078fSIntel 	       fwd_top_stats_border, fs->rx_port, fs->rx_queue,
932af75078fSIntel 	       fs->tx_port, fs->tx_queue, fwd_top_stats_border);
933af75078fSIntel 	printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
934af75078fSIntel 	       fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
935af75078fSIntel 
936af75078fSIntel 	/* if checksum mode */
937af75078fSIntel 	if (cur_fwd_eng == &csum_fwd_engine) {
938013af9b6SIntel 	       printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
939013af9b6SIntel 			"%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
940af75078fSIntel 	}
941af75078fSIntel 
942af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
943af75078fSIntel 	pkt_burst_stats_display("RX", &fs->rx_burst_stats);
944af75078fSIntel 	pkt_burst_stats_display("TX", &fs->tx_burst_stats);
945af75078fSIntel #endif
946af75078fSIntel }
947af75078fSIntel 
948af75078fSIntel static void
9497741e4cfSIntel flush_fwd_rx_queues(void)
950af75078fSIntel {
951af75078fSIntel 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
952af75078fSIntel 	portid_t  rxp;
9537741e4cfSIntel 	portid_t port_id;
954af75078fSIntel 	queueid_t rxq;
955af75078fSIntel 	uint16_t  nb_rx;
956af75078fSIntel 	uint16_t  i;
957af75078fSIntel 	uint8_t   j;
958f487715fSReshma Pattan 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
959594302c7SJames Poole 	uint64_t timer_period;
960f487715fSReshma Pattan 
961f487715fSReshma Pattan 	/* convert to number of cycles */
962594302c7SJames Poole 	timer_period = rte_get_timer_hz(); /* 1 second timeout */
963af75078fSIntel 
964af75078fSIntel 	for (j = 0; j < 2; j++) {
9657741e4cfSIntel 		for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
966af75078fSIntel 			for (rxq = 0; rxq < nb_rxq; rxq++) {
9677741e4cfSIntel 				port_id = fwd_ports_ids[rxp];
968f487715fSReshma Pattan 				/**
969f487715fSReshma Pattan 				* testpmd can stuck in the below do while loop
970f487715fSReshma Pattan 				* if rte_eth_rx_burst() always returns nonzero
971f487715fSReshma Pattan 				* packets. So timer is added to exit this loop
972f487715fSReshma Pattan 				* after 1sec timer expiry.
973f487715fSReshma Pattan 				*/
974f487715fSReshma Pattan 				prev_tsc = rte_rdtsc();
975af75078fSIntel 				do {
9767741e4cfSIntel 					nb_rx = rte_eth_rx_burst(port_id, rxq,
977013af9b6SIntel 						pkts_burst, MAX_PKT_BURST);
978af75078fSIntel 					for (i = 0; i < nb_rx; i++)
979af75078fSIntel 						rte_pktmbuf_free(pkts_burst[i]);
980f487715fSReshma Pattan 
981f487715fSReshma Pattan 					cur_tsc = rte_rdtsc();
982f487715fSReshma Pattan 					diff_tsc = cur_tsc - prev_tsc;
983f487715fSReshma Pattan 					timer_tsc += diff_tsc;
984f487715fSReshma Pattan 				} while ((nb_rx > 0) &&
985f487715fSReshma Pattan 					(timer_tsc < timer_period));
986f487715fSReshma Pattan 				timer_tsc = 0;
987af75078fSIntel 			}
988af75078fSIntel 		}
989af75078fSIntel 		rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
990af75078fSIntel 	}
991af75078fSIntel }
992af75078fSIntel 
993af75078fSIntel static void
994af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
995af75078fSIntel {
996af75078fSIntel 	struct fwd_stream **fsm;
997af75078fSIntel 	streamid_t nb_fs;
998af75078fSIntel 	streamid_t sm_id;
9997e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
10007e4441c8SRemy Horton 	uint64_t tics_per_1sec;
10017e4441c8SRemy Horton 	uint64_t tics_datum;
10027e4441c8SRemy Horton 	uint64_t tics_current;
10037e4441c8SRemy Horton 	uint8_t idx_port, cnt_ports;
1004af75078fSIntel 
10057e4441c8SRemy Horton 	cnt_ports = rte_eth_dev_count();
10067e4441c8SRemy Horton 	tics_datum = rte_rdtsc();
10077e4441c8SRemy Horton 	tics_per_1sec = rte_get_timer_hz();
10087e4441c8SRemy Horton #endif
1009af75078fSIntel 	fsm = &fwd_streams[fc->stream_idx];
1010af75078fSIntel 	nb_fs = fc->stream_nb;
1011af75078fSIntel 	do {
1012af75078fSIntel 		for (sm_id = 0; sm_id < nb_fs; sm_id++)
1013af75078fSIntel 			(*pkt_fwd)(fsm[sm_id]);
10147e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
1015e25e6c70SRemy Horton 		if (bitrate_enabled != 0 &&
1016e25e6c70SRemy Horton 				bitrate_lcore_id == rte_lcore_id()) {
10177e4441c8SRemy Horton 			tics_current = rte_rdtsc();
10187e4441c8SRemy Horton 			if (tics_current - tics_datum >= tics_per_1sec) {
10197e4441c8SRemy Horton 				/* Periodic bitrate calculation */
1020e25e6c70SRemy Horton 				for (idx_port = 0;
1021e25e6c70SRemy Horton 						idx_port < cnt_ports;
1022e25e6c70SRemy Horton 						idx_port++)
1023e25e6c70SRemy Horton 					rte_stats_bitrate_calc(bitrate_data,
1024e25e6c70SRemy Horton 						idx_port);
10257e4441c8SRemy Horton 				tics_datum = tics_current;
10267e4441c8SRemy Horton 			}
1027e25e6c70SRemy Horton 		}
10287e4441c8SRemy Horton #endif
102962d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
103065eb1e54SPablo de Lara 		if (latencystats_enabled != 0 &&
103165eb1e54SPablo de Lara 				latencystats_lcore_id == rte_lcore_id())
103262d3216dSReshma Pattan 			rte_latencystats_update();
103362d3216dSReshma Pattan #endif
103462d3216dSReshma Pattan 
1035af75078fSIntel 	} while (! fc->stopped);
1036af75078fSIntel }
1037af75078fSIntel 
1038af75078fSIntel static int
1039af75078fSIntel start_pkt_forward_on_core(void *fwd_arg)
1040af75078fSIntel {
1041af75078fSIntel 	run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1042af75078fSIntel 			     cur_fwd_config.fwd_eng->packet_fwd);
1043af75078fSIntel 	return 0;
1044af75078fSIntel }
1045af75078fSIntel 
1046af75078fSIntel /*
1047af75078fSIntel  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1048af75078fSIntel  * Used to start communication flows in network loopback test configurations.
1049af75078fSIntel  */
1050af75078fSIntel static int
1051af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg)
1052af75078fSIntel {
1053af75078fSIntel 	struct fwd_lcore *fwd_lc;
1054af75078fSIntel 	struct fwd_lcore tmp_lcore;
1055af75078fSIntel 
1056af75078fSIntel 	fwd_lc = (struct fwd_lcore *) fwd_arg;
1057af75078fSIntel 	tmp_lcore = *fwd_lc;
1058af75078fSIntel 	tmp_lcore.stopped = 1;
1059af75078fSIntel 	run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1060af75078fSIntel 	return 0;
1061af75078fSIntel }
1062af75078fSIntel 
1063af75078fSIntel /*
1064af75078fSIntel  * Launch packet forwarding:
1065af75078fSIntel  *     - Setup per-port forwarding context.
1066af75078fSIntel  *     - launch logical cores with their forwarding configuration.
1067af75078fSIntel  */
1068af75078fSIntel static void
1069af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1070af75078fSIntel {
1071af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1072af75078fSIntel 	unsigned int i;
1073af75078fSIntel 	unsigned int lc_id;
1074af75078fSIntel 	int diag;
1075af75078fSIntel 
1076af75078fSIntel 	port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1077af75078fSIntel 	if (port_fwd_begin != NULL) {
1078af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1079af75078fSIntel 			(*port_fwd_begin)(fwd_ports_ids[i]);
1080af75078fSIntel 	}
1081af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1082af75078fSIntel 		lc_id = fwd_lcores_cpuids[i];
1083af75078fSIntel 		if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1084af75078fSIntel 			fwd_lcores[i]->stopped = 0;
1085af75078fSIntel 			diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1086af75078fSIntel 						     fwd_lcores[i], lc_id);
1087af75078fSIntel 			if (diag != 0)
1088af75078fSIntel 				printf("launch lcore %u failed - diag=%d\n",
1089af75078fSIntel 				       lc_id, diag);
1090af75078fSIntel 		}
1091af75078fSIntel 	}
1092af75078fSIntel }
1093af75078fSIntel 
1094af75078fSIntel /*
1095af75078fSIntel  * Launch packet forwarding configuration.
1096af75078fSIntel  */
1097af75078fSIntel void
1098af75078fSIntel start_packet_forwarding(int with_tx_first)
1099af75078fSIntel {
1100af75078fSIntel 	port_fwd_begin_t port_fwd_begin;
1101af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1102af75078fSIntel 	struct rte_port *port;
1103af75078fSIntel 	unsigned int i;
1104af75078fSIntel 	portid_t   pt_id;
1105af75078fSIntel 	streamid_t sm_id;
1106af75078fSIntel 
11075a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
11085a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
11095a8fb55cSReshma Pattan 
11105a8fb55cSReshma Pattan 	if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
11115a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
11125a8fb55cSReshma Pattan 
11135a8fb55cSReshma Pattan 	if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
11145a8fb55cSReshma Pattan 		strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
11155a8fb55cSReshma Pattan 		(!nb_rxq || !nb_txq))
11165a8fb55cSReshma Pattan 		rte_exit(EXIT_FAILURE,
11175a8fb55cSReshma Pattan 			"Either rxq or txq are 0, cannot use %s fwd mode\n",
11185a8fb55cSReshma Pattan 			cur_fwd_eng->fwd_mode_name);
11195a8fb55cSReshma Pattan 
1120ce8d5614SIntel 	if (all_ports_started() == 0) {
1121ce8d5614SIntel 		printf("Not all ports were started\n");
1122ce8d5614SIntel 		return;
1123ce8d5614SIntel 	}
1124af75078fSIntel 	if (test_done == 0) {
1125af75078fSIntel 		printf("Packet forwarding already started\n");
1126af75078fSIntel 		return;
1127af75078fSIntel 	}
1128edf87b4aSBernard Iremonger 
1129edf87b4aSBernard Iremonger 	if (init_fwd_streams() < 0) {
1130edf87b4aSBernard Iremonger 		printf("Fail from init_fwd_streams()\n");
1131edf87b4aSBernard Iremonger 		return;
1132edf87b4aSBernard Iremonger 	}
1133edf87b4aSBernard Iremonger 
11347741e4cfSIntel 	if(dcb_test) {
11357741e4cfSIntel 		for (i = 0; i < nb_fwd_ports; i++) {
11367741e4cfSIntel 			pt_id = fwd_ports_ids[i];
11377741e4cfSIntel 			port = &ports[pt_id];
11387741e4cfSIntel 			if (!port->dcb_flag) {
11397741e4cfSIntel 				printf("In DCB mode, all forwarding ports must "
11407741e4cfSIntel                                        "be configured in this mode.\n");
1141013af9b6SIntel 				return;
1142013af9b6SIntel 			}
11437741e4cfSIntel 		}
11447741e4cfSIntel 		if (nb_fwd_lcores == 1) {
11457741e4cfSIntel 			printf("In DCB mode,the nb forwarding cores "
11467741e4cfSIntel                                "should be larger than 1.\n");
11477741e4cfSIntel 			return;
11487741e4cfSIntel 		}
11497741e4cfSIntel 	}
1150af75078fSIntel 	test_done = 0;
11517741e4cfSIntel 
11527741e4cfSIntel 	if(!no_flush_rx)
11537741e4cfSIntel 		flush_fwd_rx_queues();
11547741e4cfSIntel 
1155af75078fSIntel 	fwd_config_setup();
1156933617d8SZhihong Wang 	pkt_fwd_config_display(&cur_fwd_config);
1157af75078fSIntel 	rxtx_config_display();
1158af75078fSIntel 
1159af75078fSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1160af75078fSIntel 		pt_id = fwd_ports_ids[i];
1161af75078fSIntel 		port = &ports[pt_id];
1162af75078fSIntel 		rte_eth_stats_get(pt_id, &port->stats);
1163af75078fSIntel 		port->tx_dropped = 0;
1164013af9b6SIntel 
1165013af9b6SIntel 		map_port_queue_stats_mapping_registers(pt_id, port);
1166af75078fSIntel 	}
1167af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1168af75078fSIntel 		fwd_streams[sm_id]->rx_packets = 0;
1169af75078fSIntel 		fwd_streams[sm_id]->tx_packets = 0;
1170af75078fSIntel 		fwd_streams[sm_id]->fwd_dropped = 0;
1171af75078fSIntel 		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1172af75078fSIntel 		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1173af75078fSIntel 
1174af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1175af75078fSIntel 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1176af75078fSIntel 		       sizeof(fwd_streams[sm_id]->rx_burst_stats));
1177af75078fSIntel 		memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1178af75078fSIntel 		       sizeof(fwd_streams[sm_id]->tx_burst_stats));
1179af75078fSIntel #endif
1180af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1181af75078fSIntel 		fwd_streams[sm_id]->core_cycles = 0;
1182af75078fSIntel #endif
1183af75078fSIntel 	}
1184af75078fSIntel 	if (with_tx_first) {
1185af75078fSIntel 		port_fwd_begin = tx_only_engine.port_fwd_begin;
1186af75078fSIntel 		if (port_fwd_begin != NULL) {
1187af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1188af75078fSIntel 				(*port_fwd_begin)(fwd_ports_ids[i]);
1189af75078fSIntel 		}
1190acbf77a6SZhihong Wang 		while (with_tx_first--) {
1191acbf77a6SZhihong Wang 			launch_packet_forwarding(
1192acbf77a6SZhihong Wang 					run_one_txonly_burst_on_core);
1193af75078fSIntel 			rte_eal_mp_wait_lcore();
1194acbf77a6SZhihong Wang 		}
1195af75078fSIntel 		port_fwd_end = tx_only_engine.port_fwd_end;
1196af75078fSIntel 		if (port_fwd_end != NULL) {
1197af75078fSIntel 			for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1198af75078fSIntel 				(*port_fwd_end)(fwd_ports_ids[i]);
1199af75078fSIntel 		}
1200af75078fSIntel 	}
1201af75078fSIntel 	launch_packet_forwarding(start_pkt_forward_on_core);
1202af75078fSIntel }
1203af75078fSIntel 
1204af75078fSIntel void
1205af75078fSIntel stop_packet_forwarding(void)
1206af75078fSIntel {
1207af75078fSIntel 	struct rte_eth_stats stats;
1208af75078fSIntel 	struct rte_port *port;
1209af75078fSIntel 	port_fwd_end_t  port_fwd_end;
1210af75078fSIntel 	int i;
1211af75078fSIntel 	portid_t   pt_id;
1212af75078fSIntel 	streamid_t sm_id;
1213af75078fSIntel 	lcoreid_t  lc_id;
1214af75078fSIntel 	uint64_t total_recv;
1215af75078fSIntel 	uint64_t total_xmit;
1216af75078fSIntel 	uint64_t total_rx_dropped;
1217af75078fSIntel 	uint64_t total_tx_dropped;
1218af75078fSIntel 	uint64_t total_rx_nombuf;
1219af75078fSIntel 	uint64_t tx_dropped;
1220af75078fSIntel 	uint64_t rx_bad_ip_csum;
1221af75078fSIntel 	uint64_t rx_bad_l4_csum;
1222af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1223af75078fSIntel 	uint64_t fwd_cycles;
1224af75078fSIntel #endif
1225b7091f1dSJiayu Hu 
1226af75078fSIntel 	static const char *acc_stats_border = "+++++++++++++++";
1227af75078fSIntel 
1228af75078fSIntel 	if (test_done) {
1229af75078fSIntel 		printf("Packet forwarding not started\n");
1230af75078fSIntel 		return;
1231af75078fSIntel 	}
1232af75078fSIntel 	printf("Telling cores to stop...");
1233af75078fSIntel 	for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1234af75078fSIntel 		fwd_lcores[lc_id]->stopped = 1;
1235af75078fSIntel 	printf("\nWaiting for lcores to finish...\n");
1236af75078fSIntel 	rte_eal_mp_wait_lcore();
1237af75078fSIntel 	port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1238af75078fSIntel 	if (port_fwd_end != NULL) {
1239af75078fSIntel 		for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1240af75078fSIntel 			pt_id = fwd_ports_ids[i];
1241af75078fSIntel 			(*port_fwd_end)(pt_id);
1242af75078fSIntel 		}
1243af75078fSIntel 	}
1244af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1245af75078fSIntel 	fwd_cycles = 0;
1246af75078fSIntel #endif
1247af75078fSIntel 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1248af75078fSIntel 		if (cur_fwd_config.nb_fwd_streams >
1249af75078fSIntel 		    cur_fwd_config.nb_fwd_ports) {
1250af75078fSIntel 			fwd_stream_stats_display(sm_id);
1251af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1252af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1253af75078fSIntel 		} else {
1254af75078fSIntel 			ports[fwd_streams[sm_id]->tx_port].tx_stream =
1255af75078fSIntel 				fwd_streams[sm_id];
1256af75078fSIntel 			ports[fwd_streams[sm_id]->rx_port].rx_stream =
1257af75078fSIntel 				fwd_streams[sm_id];
1258af75078fSIntel 		}
1259af75078fSIntel 		tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1260af75078fSIntel 		tx_dropped = (uint64_t) (tx_dropped +
1261af75078fSIntel 					 fwd_streams[sm_id]->fwd_dropped);
1262af75078fSIntel 		ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1263af75078fSIntel 
1264013af9b6SIntel 		rx_bad_ip_csum =
1265013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1266af75078fSIntel 		rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1267af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_ip_csum);
1268013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1269013af9b6SIntel 							rx_bad_ip_csum;
1270af75078fSIntel 
1271013af9b6SIntel 		rx_bad_l4_csum =
1272013af9b6SIntel 			ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1273af75078fSIntel 		rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1274af75078fSIntel 					 fwd_streams[sm_id]->rx_bad_l4_csum);
1275013af9b6SIntel 		ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1276013af9b6SIntel 							rx_bad_l4_csum;
1277af75078fSIntel 
1278af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1279af75078fSIntel 		fwd_cycles = (uint64_t) (fwd_cycles +
1280af75078fSIntel 					 fwd_streams[sm_id]->core_cycles);
1281af75078fSIntel #endif
1282af75078fSIntel 	}
1283af75078fSIntel 	total_recv = 0;
1284af75078fSIntel 	total_xmit = 0;
1285af75078fSIntel 	total_rx_dropped = 0;
1286af75078fSIntel 	total_tx_dropped = 0;
1287af75078fSIntel 	total_rx_nombuf  = 0;
12887741e4cfSIntel 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1289af75078fSIntel 		pt_id = fwd_ports_ids[i];
1290af75078fSIntel 
1291af75078fSIntel 		port = &ports[pt_id];
1292af75078fSIntel 		rte_eth_stats_get(pt_id, &stats);
1293af75078fSIntel 		stats.ipackets -= port->stats.ipackets;
1294af75078fSIntel 		port->stats.ipackets = 0;
1295af75078fSIntel 		stats.opackets -= port->stats.opackets;
1296af75078fSIntel 		port->stats.opackets = 0;
1297af75078fSIntel 		stats.ibytes   -= port->stats.ibytes;
1298af75078fSIntel 		port->stats.ibytes = 0;
1299af75078fSIntel 		stats.obytes   -= port->stats.obytes;
1300af75078fSIntel 		port->stats.obytes = 0;
130170bdb186SIvan Boule 		stats.imissed  -= port->stats.imissed;
130270bdb186SIvan Boule 		port->stats.imissed = 0;
1303af75078fSIntel 		stats.oerrors  -= port->stats.oerrors;
1304af75078fSIntel 		port->stats.oerrors = 0;
1305af75078fSIntel 		stats.rx_nombuf -= port->stats.rx_nombuf;
1306af75078fSIntel 		port->stats.rx_nombuf = 0;
1307af75078fSIntel 
1308af75078fSIntel 		total_recv += stats.ipackets;
1309af75078fSIntel 		total_xmit += stats.opackets;
131070bdb186SIvan Boule 		total_rx_dropped += stats.imissed;
1311af75078fSIntel 		total_tx_dropped += port->tx_dropped;
1312af75078fSIntel 		total_rx_nombuf  += stats.rx_nombuf;
1313af75078fSIntel 
1314af75078fSIntel 		fwd_port_stats_display(pt_id, &stats);
1315af75078fSIntel 	}
1316b7091f1dSJiayu Hu 
1317af75078fSIntel 	printf("\n  %s Accumulated forward statistics for all ports"
1318af75078fSIntel 	       "%s\n",
1319af75078fSIntel 	       acc_stats_border, acc_stats_border);
1320af75078fSIntel 	printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1321af75078fSIntel 	       "%-"PRIu64"\n"
1322af75078fSIntel 	       "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1323af75078fSIntel 	       "%-"PRIu64"\n",
1324af75078fSIntel 	       total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1325af75078fSIntel 	       total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1326af75078fSIntel 	if (total_rx_nombuf > 0)
1327af75078fSIntel 		printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1328af75078fSIntel 	printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1329af75078fSIntel 	       "%s\n",
1330af75078fSIntel 	       acc_stats_border, acc_stats_border);
1331af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1332af75078fSIntel 	if (total_recv > 0)
1333af75078fSIntel 		printf("\n  CPU cycles/packet=%u (total cycles="
1334af75078fSIntel 		       "%"PRIu64" / total RX packets=%"PRIu64")\n",
1335af75078fSIntel 		       (unsigned int)(fwd_cycles / total_recv),
1336af75078fSIntel 		       fwd_cycles, total_recv);
1337af75078fSIntel #endif
1338af75078fSIntel 	printf("\nDone.\n");
1339af75078fSIntel 	test_done = 1;
1340af75078fSIntel }
1341af75078fSIntel 
1342cfae07fdSOuyang Changchun void
1343cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid)
1344cfae07fdSOuyang Changchun {
1345492ab604SZhiyong Yang 	if (rte_eth_dev_set_link_up(pid) < 0)
1346cfae07fdSOuyang Changchun 		printf("\nSet link up fail.\n");
1347cfae07fdSOuyang Changchun }
1348cfae07fdSOuyang Changchun 
1349cfae07fdSOuyang Changchun void
1350cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid)
1351cfae07fdSOuyang Changchun {
1352492ab604SZhiyong Yang 	if (rte_eth_dev_set_link_down(pid) < 0)
1353cfae07fdSOuyang Changchun 		printf("\nSet link down fail.\n");
1354cfae07fdSOuyang Changchun }
1355cfae07fdSOuyang Changchun 
1356ce8d5614SIntel static int
1357ce8d5614SIntel all_ports_started(void)
1358ce8d5614SIntel {
1359ce8d5614SIntel 	portid_t pi;
1360ce8d5614SIntel 	struct rte_port *port;
1361ce8d5614SIntel 
13627d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1363ce8d5614SIntel 		port = &ports[pi];
1364ce8d5614SIntel 		/* Check if there is a port which is not started */
136541b05095SBernard Iremonger 		if ((port->port_status != RTE_PORT_STARTED) &&
136641b05095SBernard Iremonger 			(port->slave_flag == 0))
1367ce8d5614SIntel 			return 0;
1368ce8d5614SIntel 	}
1369ce8d5614SIntel 
1370ce8d5614SIntel 	/* No port is not started */
1371ce8d5614SIntel 	return 1;
1372ce8d5614SIntel }
1373ce8d5614SIntel 
1374148f963fSBruce Richardson int
13756018eb8cSShahaf Shuler port_is_stopped(portid_t port_id)
13766018eb8cSShahaf Shuler {
13776018eb8cSShahaf Shuler 	struct rte_port *port = &ports[port_id];
13786018eb8cSShahaf Shuler 
13796018eb8cSShahaf Shuler 	if ((port->port_status != RTE_PORT_STOPPED) &&
13806018eb8cSShahaf Shuler 	    (port->slave_flag == 0))
13816018eb8cSShahaf Shuler 		return 0;
13826018eb8cSShahaf Shuler 	return 1;
13836018eb8cSShahaf Shuler }
13846018eb8cSShahaf Shuler 
13856018eb8cSShahaf Shuler int
1386edab33b1STetsuya Mukawa all_ports_stopped(void)
1387edab33b1STetsuya Mukawa {
1388edab33b1STetsuya Mukawa 	portid_t pi;
1389edab33b1STetsuya Mukawa 
13907d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
13916018eb8cSShahaf Shuler 		if (!port_is_stopped(pi))
1392edab33b1STetsuya Mukawa 			return 0;
1393edab33b1STetsuya Mukawa 	}
1394edab33b1STetsuya Mukawa 
1395edab33b1STetsuya Mukawa 	return 1;
1396edab33b1STetsuya Mukawa }
1397edab33b1STetsuya Mukawa 
1398edab33b1STetsuya Mukawa int
1399edab33b1STetsuya Mukawa port_is_started(portid_t port_id)
1400edab33b1STetsuya Mukawa {
1401edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1402edab33b1STetsuya Mukawa 		return 0;
1403edab33b1STetsuya Mukawa 
1404edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_STARTED)
1405edab33b1STetsuya Mukawa 		return 0;
1406edab33b1STetsuya Mukawa 
1407edab33b1STetsuya Mukawa 	return 1;
1408edab33b1STetsuya Mukawa }
1409edab33b1STetsuya Mukawa 
1410edab33b1STetsuya Mukawa static int
1411edab33b1STetsuya Mukawa port_is_closed(portid_t port_id)
1412edab33b1STetsuya Mukawa {
1413edab33b1STetsuya Mukawa 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1414edab33b1STetsuya Mukawa 		return 0;
1415edab33b1STetsuya Mukawa 
1416edab33b1STetsuya Mukawa 	if (ports[port_id].port_status != RTE_PORT_CLOSED)
1417edab33b1STetsuya Mukawa 		return 0;
1418edab33b1STetsuya Mukawa 
1419edab33b1STetsuya Mukawa 	return 1;
1420edab33b1STetsuya Mukawa }
1421edab33b1STetsuya Mukawa 
1422edab33b1STetsuya Mukawa int
1423ce8d5614SIntel start_port(portid_t pid)
1424ce8d5614SIntel {
142592d2703eSMichael Qiu 	int diag, need_check_link_status = -1;
1426ce8d5614SIntel 	portid_t pi;
1427ce8d5614SIntel 	queueid_t qi;
1428ce8d5614SIntel 	struct rte_port *port;
14292950a769SDeclan Doherty 	struct ether_addr mac_addr;
143076ad4a2dSGaetan Rivet 	enum rte_eth_event_type event_type;
1431ce8d5614SIntel 
14324468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
14334468635fSMichael Qiu 		return 0;
14344468635fSMichael Qiu 
1435ce8d5614SIntel 	if(dcb_config)
1436ce8d5614SIntel 		dcb_test = 1;
14377d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
1438edab33b1STetsuya Mukawa 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1439ce8d5614SIntel 			continue;
1440ce8d5614SIntel 
144192d2703eSMichael Qiu 		need_check_link_status = 0;
1442ce8d5614SIntel 		port = &ports[pi];
1443ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1444ce8d5614SIntel 						 RTE_PORT_HANDLING) == 0) {
1445ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1446ce8d5614SIntel 			continue;
1447ce8d5614SIntel 		}
1448ce8d5614SIntel 
1449ce8d5614SIntel 		if (port->need_reconfig > 0) {
1450ce8d5614SIntel 			port->need_reconfig = 0;
1451ce8d5614SIntel 
14527ee3e944SVasily Philipov 			if (flow_isolate_all) {
14537ee3e944SVasily Philipov 				int ret = port_flow_isolate(pi, 1);
14547ee3e944SVasily Philipov 				if (ret) {
14557ee3e944SVasily Philipov 					printf("Failed to apply isolated"
14567ee3e944SVasily Philipov 					       " mode on port %d\n", pi);
14577ee3e944SVasily Philipov 					return -1;
14587ee3e944SVasily Philipov 				}
14597ee3e944SVasily Philipov 			}
14607ee3e944SVasily Philipov 
14615706de65SJulien Cretin 			printf("Configuring Port %d (socket %u)\n", pi,
146220a0286fSLiu Xiaofeng 					port->socket_id);
1463ce8d5614SIntel 			/* configure port */
1464ce8d5614SIntel 			diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1465ce8d5614SIntel 						&(port->dev_conf));
1466ce8d5614SIntel 			if (diag != 0) {
1467ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1468ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1469ce8d5614SIntel 					printf("Port %d can not be set back "
1470ce8d5614SIntel 							"to stopped\n", pi);
1471ce8d5614SIntel 				printf("Fail to configure port %d\n", pi);
1472ce8d5614SIntel 				/* try to reconfigure port next time */
1473ce8d5614SIntel 				port->need_reconfig = 1;
1474148f963fSBruce Richardson 				return -1;
1475ce8d5614SIntel 			}
1476ce8d5614SIntel 		}
1477ce8d5614SIntel 		if (port->need_reconfig_queues > 0) {
1478ce8d5614SIntel 			port->need_reconfig_queues = 0;
1479597f9fafSShahaf Shuler 			port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
1480597f9fafSShahaf Shuler 			/* Apply Tx offloads configuration */
1481597f9fafSShahaf Shuler 			port->tx_conf.offloads = port->dev_conf.txmode.offloads;
1482ce8d5614SIntel 			/* setup tx queues */
1483ce8d5614SIntel 			for (qi = 0; qi < nb_txq; qi++) {
1484b6ea6408SIntel 				if ((numa_support) &&
1485b6ea6408SIntel 					(txring_numa[pi] != NUMA_NO_CONFIG))
1486b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1487b6ea6408SIntel 						nb_txd,txring_numa[pi],
1488b6ea6408SIntel 						&(port->tx_conf));
1489b6ea6408SIntel 				else
1490b6ea6408SIntel 					diag = rte_eth_tx_queue_setup(pi, qi,
1491b6ea6408SIntel 						nb_txd,port->socket_id,
1492b6ea6408SIntel 						&(port->tx_conf));
1493b6ea6408SIntel 
1494ce8d5614SIntel 				if (diag == 0)
1495ce8d5614SIntel 					continue;
1496ce8d5614SIntel 
1497ce8d5614SIntel 				/* Fail to setup tx queue, return */
1498ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1499ce8d5614SIntel 							RTE_PORT_HANDLING,
1500ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1501ce8d5614SIntel 					printf("Port %d can not be set back "
1502ce8d5614SIntel 							"to stopped\n", pi);
1503ce8d5614SIntel 				printf("Fail to configure port %d tx queues\n", pi);
1504ce8d5614SIntel 				/* try to reconfigure queues next time */
1505ce8d5614SIntel 				port->need_reconfig_queues = 1;
1506148f963fSBruce Richardson 				return -1;
1507ce8d5614SIntel 			}
15080074d02fSShahaf Shuler 			/* Apply Rx offloads configuration */
15090074d02fSShahaf Shuler 			port->rx_conf.offloads = port->dev_conf.rxmode.offloads;
1510ce8d5614SIntel 			/* setup rx queues */
1511ce8d5614SIntel 			for (qi = 0; qi < nb_rxq; qi++) {
1512b6ea6408SIntel 				if ((numa_support) &&
1513b6ea6408SIntel 					(rxring_numa[pi] != NUMA_NO_CONFIG)) {
1514b6ea6408SIntel 					struct rte_mempool * mp =
1515b6ea6408SIntel 						mbuf_pool_find(rxring_numa[pi]);
1516b6ea6408SIntel 					if (mp == NULL) {
1517b6ea6408SIntel 						printf("Failed to setup RX queue:"
1518b6ea6408SIntel 							"No mempool allocation"
1519b6ea6408SIntel 							" on the socket %d\n",
1520b6ea6408SIntel 							rxring_numa[pi]);
1521148f963fSBruce Richardson 						return -1;
1522b6ea6408SIntel 					}
1523b6ea6408SIntel 
1524b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1525b6ea6408SIntel 					     nb_rxd,rxring_numa[pi],
1526b6ea6408SIntel 					     &(port->rx_conf),mp);
15271e1d6bddSBernard Iremonger 				} else {
15281e1d6bddSBernard Iremonger 					struct rte_mempool *mp =
15291e1d6bddSBernard Iremonger 						mbuf_pool_find(port->socket_id);
15301e1d6bddSBernard Iremonger 					if (mp == NULL) {
15311e1d6bddSBernard Iremonger 						printf("Failed to setup RX queue:"
15321e1d6bddSBernard Iremonger 							"No mempool allocation"
15331e1d6bddSBernard Iremonger 							" on the socket %d\n",
15341e1d6bddSBernard Iremonger 							port->socket_id);
15351e1d6bddSBernard Iremonger 						return -1;
1536b6ea6408SIntel 					}
1537b6ea6408SIntel 					diag = rte_eth_rx_queue_setup(pi, qi,
1538b6ea6408SIntel 					     nb_rxd,port->socket_id,
15391e1d6bddSBernard Iremonger 					     &(port->rx_conf), mp);
15401e1d6bddSBernard Iremonger 				}
1541ce8d5614SIntel 				if (diag == 0)
1542ce8d5614SIntel 					continue;
1543ce8d5614SIntel 
1544ce8d5614SIntel 				/* Fail to setup rx queue, return */
1545ce8d5614SIntel 				if (rte_atomic16_cmpset(&(port->port_status),
1546ce8d5614SIntel 							RTE_PORT_HANDLING,
1547ce8d5614SIntel 							RTE_PORT_STOPPED) == 0)
1548ce8d5614SIntel 					printf("Port %d can not be set back "
1549ce8d5614SIntel 							"to stopped\n", pi);
1550ce8d5614SIntel 				printf("Fail to configure port %d rx queues\n", pi);
1551ce8d5614SIntel 				/* try to reconfigure queues next time */
1552ce8d5614SIntel 				port->need_reconfig_queues = 1;
1553148f963fSBruce Richardson 				return -1;
1554ce8d5614SIntel 			}
1555ce8d5614SIntel 		}
155676ad4a2dSGaetan Rivet 
1557ce8d5614SIntel 		/* start port */
1558ce8d5614SIntel 		if (rte_eth_dev_start(pi) < 0) {
1559ce8d5614SIntel 			printf("Fail to start port %d\n", pi);
1560ce8d5614SIntel 
1561ce8d5614SIntel 			/* Fail to setup rx queue, return */
1562ce8d5614SIntel 			if (rte_atomic16_cmpset(&(port->port_status),
1563ce8d5614SIntel 				RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1564ce8d5614SIntel 				printf("Port %d can not be set back to "
1565ce8d5614SIntel 							"stopped\n", pi);
1566ce8d5614SIntel 			continue;
1567ce8d5614SIntel 		}
1568ce8d5614SIntel 
1569ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1570ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1571ce8d5614SIntel 			printf("Port %d can not be set into started\n", pi);
1572ce8d5614SIntel 
15732950a769SDeclan Doherty 		rte_eth_macaddr_get(pi, &mac_addr);
1574d8c89163SZijie Pan 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
15752950a769SDeclan Doherty 				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
15762950a769SDeclan Doherty 				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
15772950a769SDeclan Doherty 				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1578d8c89163SZijie Pan 
1579ce8d5614SIntel 		/* at least one port started, need checking link status */
1580ce8d5614SIntel 		need_check_link_status = 1;
1581ce8d5614SIntel 	}
1582ce8d5614SIntel 
1583*4fb82244SMatan Azrad 	for (event_type = RTE_ETH_EVENT_UNKNOWN;
1584*4fb82244SMatan Azrad 	     event_type < RTE_ETH_EVENT_MAX;
1585*4fb82244SMatan Azrad 	     event_type++) {
1586*4fb82244SMatan Azrad 		diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
1587*4fb82244SMatan Azrad 						event_type,
1588*4fb82244SMatan Azrad 						eth_event_callback,
1589*4fb82244SMatan Azrad 						NULL);
1590*4fb82244SMatan Azrad 		if (diag) {
1591*4fb82244SMatan Azrad 			printf("Failed to setup even callback for event %d\n",
1592*4fb82244SMatan Azrad 				event_type);
1593*4fb82244SMatan Azrad 			return -1;
1594*4fb82244SMatan Azrad 		}
1595*4fb82244SMatan Azrad 	}
1596*4fb82244SMatan Azrad 
159792d2703eSMichael Qiu 	if (need_check_link_status == 1 && !no_link_check)
1598edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
159992d2703eSMichael Qiu 	else if (need_check_link_status == 0)
1600ce8d5614SIntel 		printf("Please stop the ports first\n");
1601ce8d5614SIntel 
1602ce8d5614SIntel 	printf("Done\n");
1603148f963fSBruce Richardson 	return 0;
1604ce8d5614SIntel }
1605ce8d5614SIntel 
1606ce8d5614SIntel void
1607ce8d5614SIntel stop_port(portid_t pid)
1608ce8d5614SIntel {
1609ce8d5614SIntel 	portid_t pi;
1610ce8d5614SIntel 	struct rte_port *port;
1611ce8d5614SIntel 	int need_check_link_status = 0;
1612ce8d5614SIntel 
1613ce8d5614SIntel 	if (dcb_test) {
1614ce8d5614SIntel 		dcb_test = 0;
1615ce8d5614SIntel 		dcb_config = 0;
1616ce8d5614SIntel 	}
16174468635fSMichael Qiu 
16184468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
16194468635fSMichael Qiu 		return;
16204468635fSMichael Qiu 
1621ce8d5614SIntel 	printf("Stopping ports...\n");
1622ce8d5614SIntel 
16237d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16244468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1625ce8d5614SIntel 			continue;
1626ce8d5614SIntel 
1627a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1628a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1629a8ef3e3aSBernard Iremonger 			continue;
1630a8ef3e3aSBernard Iremonger 		}
1631a8ef3e3aSBernard Iremonger 
16320e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16330e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16340e545d30SBernard Iremonger 			continue;
16350e545d30SBernard Iremonger 		}
16360e545d30SBernard Iremonger 
1637ce8d5614SIntel 		port = &ports[pi];
1638ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1639ce8d5614SIntel 						RTE_PORT_HANDLING) == 0)
1640ce8d5614SIntel 			continue;
1641ce8d5614SIntel 
1642ce8d5614SIntel 		rte_eth_dev_stop(pi);
1643ce8d5614SIntel 
1644ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1645ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1646ce8d5614SIntel 			printf("Port %d can not be set into stopped\n", pi);
1647ce8d5614SIntel 		need_check_link_status = 1;
1648ce8d5614SIntel 	}
1649bc202406SDavid Marchand 	if (need_check_link_status && !no_link_check)
1650edab33b1STetsuya Mukawa 		check_all_ports_link_status(RTE_PORT_ALL);
1651ce8d5614SIntel 
1652ce8d5614SIntel 	printf("Done\n");
1653ce8d5614SIntel }
1654ce8d5614SIntel 
1655ce8d5614SIntel void
1656ce8d5614SIntel close_port(portid_t pid)
1657ce8d5614SIntel {
1658ce8d5614SIntel 	portid_t pi;
1659ce8d5614SIntel 	struct rte_port *port;
1660ce8d5614SIntel 
16614468635fSMichael Qiu 	if (port_id_is_invalid(pid, ENABLED_WARN))
16624468635fSMichael Qiu 		return;
16634468635fSMichael Qiu 
1664ce8d5614SIntel 	printf("Closing ports...\n");
1665ce8d5614SIntel 
16667d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pi) {
16674468635fSMichael Qiu 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1668ce8d5614SIntel 			continue;
1669ce8d5614SIntel 
1670a8ef3e3aSBernard Iremonger 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
1671a8ef3e3aSBernard Iremonger 			printf("Please remove port %d from forwarding configuration.\n", pi);
1672a8ef3e3aSBernard Iremonger 			continue;
1673a8ef3e3aSBernard Iremonger 		}
1674a8ef3e3aSBernard Iremonger 
16750e545d30SBernard Iremonger 		if (port_is_bonding_slave(pi)) {
16760e545d30SBernard Iremonger 			printf("Please remove port %d from bonded device.\n", pi);
16770e545d30SBernard Iremonger 			continue;
16780e545d30SBernard Iremonger 		}
16790e545d30SBernard Iremonger 
1680ce8d5614SIntel 		port = &ports[pi];
1681ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1682d4e8ad64SMichael Qiu 			RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1683d4e8ad64SMichael Qiu 			printf("Port %d is already closed\n", pi);
1684d4e8ad64SMichael Qiu 			continue;
1685d4e8ad64SMichael Qiu 		}
1686d4e8ad64SMichael Qiu 
1687d4e8ad64SMichael Qiu 		if (rte_atomic16_cmpset(&(port->port_status),
1688ce8d5614SIntel 			RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1689ce8d5614SIntel 			printf("Port %d is now not stopped\n", pi);
1690ce8d5614SIntel 			continue;
1691ce8d5614SIntel 		}
1692ce8d5614SIntel 
1693938a184aSAdrien Mazarguil 		if (port->flow_list)
1694938a184aSAdrien Mazarguil 			port_flow_flush(pi);
1695ce8d5614SIntel 		rte_eth_dev_close(pi);
1696ce8d5614SIntel 
1697ce8d5614SIntel 		if (rte_atomic16_cmpset(&(port->port_status),
1698ce8d5614SIntel 			RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1699b38bb262SPablo de Lara 			printf("Port %d cannot be set to closed\n", pi);
1700ce8d5614SIntel 	}
1701ce8d5614SIntel 
1702ce8d5614SIntel 	printf("Done\n");
1703ce8d5614SIntel }
1704ce8d5614SIntel 
1705edab33b1STetsuya Mukawa void
170697f1e196SWei Dai reset_port(portid_t pid)
170797f1e196SWei Dai {
170897f1e196SWei Dai 	int diag;
170997f1e196SWei Dai 	portid_t pi;
171097f1e196SWei Dai 	struct rte_port *port;
171197f1e196SWei Dai 
171297f1e196SWei Dai 	if (port_id_is_invalid(pid, ENABLED_WARN))
171397f1e196SWei Dai 		return;
171497f1e196SWei Dai 
171597f1e196SWei Dai 	printf("Resetting ports...\n");
171697f1e196SWei Dai 
171797f1e196SWei Dai 	RTE_ETH_FOREACH_DEV(pi) {
171897f1e196SWei Dai 		if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
171997f1e196SWei Dai 			continue;
172097f1e196SWei Dai 
172197f1e196SWei Dai 		if (port_is_forwarding(pi) != 0 && test_done == 0) {
172297f1e196SWei Dai 			printf("Please remove port %d from forwarding "
172397f1e196SWei Dai 			       "configuration.\n", pi);
172497f1e196SWei Dai 			continue;
172597f1e196SWei Dai 		}
172697f1e196SWei Dai 
172797f1e196SWei Dai 		if (port_is_bonding_slave(pi)) {
172897f1e196SWei Dai 			printf("Please remove port %d from bonded device.\n",
172997f1e196SWei Dai 			       pi);
173097f1e196SWei Dai 			continue;
173197f1e196SWei Dai 		}
173297f1e196SWei Dai 
173397f1e196SWei Dai 		diag = rte_eth_dev_reset(pi);
173497f1e196SWei Dai 		if (diag == 0) {
173597f1e196SWei Dai 			port = &ports[pi];
173697f1e196SWei Dai 			port->need_reconfig = 1;
173797f1e196SWei Dai 			port->need_reconfig_queues = 1;
173897f1e196SWei Dai 		} else {
173997f1e196SWei Dai 			printf("Failed to reset port %d. diag=%d\n", pi, diag);
174097f1e196SWei Dai 		}
174197f1e196SWei Dai 	}
174297f1e196SWei Dai 
174397f1e196SWei Dai 	printf("Done\n");
174497f1e196SWei Dai }
174597f1e196SWei Dai 
174697f1e196SWei Dai void
1747edab33b1STetsuya Mukawa attach_port(char *identifier)
1748ce8d5614SIntel {
1749ebf5e9b7SBernard Iremonger 	portid_t pi = 0;
1750931126baSBernard Iremonger 	unsigned int socket_id;
1751ce8d5614SIntel 
1752edab33b1STetsuya Mukawa 	printf("Attaching a new port...\n");
1753edab33b1STetsuya Mukawa 
1754edab33b1STetsuya Mukawa 	if (identifier == NULL) {
1755edab33b1STetsuya Mukawa 		printf("Invalid parameters are specified\n");
1756edab33b1STetsuya Mukawa 		return;
1757ce8d5614SIntel 	}
1758ce8d5614SIntel 
1759edab33b1STetsuya Mukawa 	if (rte_eth_dev_attach(identifier, &pi))
1760edab33b1STetsuya Mukawa 		return;
1761edab33b1STetsuya Mukawa 
1762931126baSBernard Iremonger 	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1763931126baSBernard Iremonger 	/* if socket_id is invalid, set to 0 */
1764931126baSBernard Iremonger 	if (check_socket_id(socket_id) < 0)
1765931126baSBernard Iremonger 		socket_id = 0;
1766931126baSBernard Iremonger 	reconfig(pi, socket_id);
1767edab33b1STetsuya Mukawa 	rte_eth_promiscuous_enable(pi);
1768edab33b1STetsuya Mukawa 
1769edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1770edab33b1STetsuya Mukawa 
1771edab33b1STetsuya Mukawa 	ports[pi].port_status = RTE_PORT_STOPPED;
1772edab33b1STetsuya Mukawa 
1773edab33b1STetsuya Mukawa 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1774edab33b1STetsuya Mukawa 	printf("Done\n");
1775edab33b1STetsuya Mukawa }
1776edab33b1STetsuya Mukawa 
1777edab33b1STetsuya Mukawa void
177828caa76aSZhiyong Yang detach_port(portid_t port_id)
17795f4ec54fSChen Jing D(Mark) {
1780edab33b1STetsuya Mukawa 	char name[RTE_ETH_NAME_MAX_LEN];
17815f4ec54fSChen Jing D(Mark) 
1782edab33b1STetsuya Mukawa 	printf("Detaching a port...\n");
17835f4ec54fSChen Jing D(Mark) 
1784edab33b1STetsuya Mukawa 	if (!port_is_closed(port_id)) {
1785edab33b1STetsuya Mukawa 		printf("Please close port first\n");
1786edab33b1STetsuya Mukawa 		return;
1787edab33b1STetsuya Mukawa 	}
1788edab33b1STetsuya Mukawa 
1789938a184aSAdrien Mazarguil 	if (ports[port_id].flow_list)
1790938a184aSAdrien Mazarguil 		port_flow_flush(port_id);
1791938a184aSAdrien Mazarguil 
17923070419eSGaetan Rivet 	if (rte_eth_dev_detach(port_id, name)) {
1793285fd101SOlivier Matz 		TESTPMD_LOG(ERR, "Failed to detach port '%s'\n", name);
1794edab33b1STetsuya Mukawa 		return;
17953070419eSGaetan Rivet 	}
1796edab33b1STetsuya Mukawa 
1797edab33b1STetsuya Mukawa 	nb_ports = rte_eth_dev_count();
1798edab33b1STetsuya Mukawa 
1799edab33b1STetsuya Mukawa 	printf("Port '%s' is detached. Now total ports is %d\n",
1800edab33b1STetsuya Mukawa 			name, nb_ports);
1801edab33b1STetsuya Mukawa 	printf("Done\n");
1802edab33b1STetsuya Mukawa 	return;
18035f4ec54fSChen Jing D(Mark) }
18045f4ec54fSChen Jing D(Mark) 
1805af75078fSIntel void
1806af75078fSIntel pmd_test_exit(void)
1807af75078fSIntel {
1808af75078fSIntel 	portid_t pt_id;
1809af75078fSIntel 
18108210ec25SPablo de Lara 	if (test_done == 0)
18118210ec25SPablo de Lara 		stop_packet_forwarding();
18128210ec25SPablo de Lara 
1813d3a274ceSZhihong Wang 	if (ports != NULL) {
1814d3a274ceSZhihong Wang 		no_link_check = 1;
18157d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(pt_id) {
1816d3a274ceSZhihong Wang 			printf("\nShutting down port %d...\n", pt_id);
1817af75078fSIntel 			fflush(stdout);
1818d3a274ceSZhihong Wang 			stop_port(pt_id);
1819d3a274ceSZhihong Wang 			close_port(pt_id);
1820af75078fSIntel 		}
1821d3a274ceSZhihong Wang 	}
1822d3a274ceSZhihong Wang 	printf("\nBye...\n");
1823af75078fSIntel }
1824af75078fSIntel 
1825af75078fSIntel typedef void (*cmd_func_t)(void);
1826af75078fSIntel struct pmd_test_command {
1827af75078fSIntel 	const char *cmd_name;
1828af75078fSIntel 	cmd_func_t cmd_func;
1829af75078fSIntel };
1830af75078fSIntel 
1831af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1832af75078fSIntel 
1833ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */
1834af75078fSIntel static void
1835edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask)
1836af75078fSIntel {
1837ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */
1838ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1839f8244c63SZhiyong Yang 	portid_t portid;
1840f8244c63SZhiyong Yang 	uint8_t count, all_ports_up, print_flag = 0;
1841ce8d5614SIntel 	struct rte_eth_link link;
1842ce8d5614SIntel 
1843ce8d5614SIntel 	printf("Checking link statuses...\n");
1844ce8d5614SIntel 	fflush(stdout);
1845ce8d5614SIntel 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
1846ce8d5614SIntel 		all_ports_up = 1;
18477d89b261SGaetan Rivet 		RTE_ETH_FOREACH_DEV(portid) {
1848ce8d5614SIntel 			if ((port_mask & (1 << portid)) == 0)
1849ce8d5614SIntel 				continue;
1850ce8d5614SIntel 			memset(&link, 0, sizeof(link));
1851ce8d5614SIntel 			rte_eth_link_get_nowait(portid, &link);
1852ce8d5614SIntel 			/* print link status if flag set */
1853ce8d5614SIntel 			if (print_flag == 1) {
1854ce8d5614SIntel 				if (link.link_status)
1855f8244c63SZhiyong Yang 					printf(
1856f8244c63SZhiyong Yang 					"Port%d Link Up. speed %u Mbps- %s\n",
1857f8244c63SZhiyong Yang 					portid, link.link_speed,
1858ce8d5614SIntel 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1859ce8d5614SIntel 					("full-duplex") : ("half-duplex\n"));
1860ce8d5614SIntel 				else
1861f8244c63SZhiyong Yang 					printf("Port %d Link Down\n", portid);
1862ce8d5614SIntel 				continue;
1863ce8d5614SIntel 			}
1864ce8d5614SIntel 			/* clear all_ports_up flag if any link down */
186509419f23SThomas Monjalon 			if (link.link_status == ETH_LINK_DOWN) {
1866ce8d5614SIntel 				all_ports_up = 0;
1867ce8d5614SIntel 				break;
1868ce8d5614SIntel 			}
1869ce8d5614SIntel 		}
1870ce8d5614SIntel 		/* after finally printing all link status, get out */
1871ce8d5614SIntel 		if (print_flag == 1)
1872ce8d5614SIntel 			break;
1873ce8d5614SIntel 
1874ce8d5614SIntel 		if (all_ports_up == 0) {
1875ce8d5614SIntel 			fflush(stdout);
1876ce8d5614SIntel 			rte_delay_ms(CHECK_INTERVAL);
1877ce8d5614SIntel 		}
1878ce8d5614SIntel 
1879ce8d5614SIntel 		/* set the print_flag if all ports up or timeout */
1880ce8d5614SIntel 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1881ce8d5614SIntel 			print_flag = 1;
1882ce8d5614SIntel 		}
18838ea656f8SGaetan Rivet 
18848ea656f8SGaetan Rivet 		if (lsc_interrupt)
18858ea656f8SGaetan Rivet 			break;
1886ce8d5614SIntel 	}
1887af75078fSIntel }
1888af75078fSIntel 
1889284c908cSGaetan Rivet static void
1890284c908cSGaetan Rivet rmv_event_callback(void *arg)
1891284c908cSGaetan Rivet {
1892284c908cSGaetan Rivet 	struct rte_eth_dev *dev;
189328caa76aSZhiyong Yang 	portid_t port_id = (intptr_t)arg;
1894284c908cSGaetan Rivet 
1895284c908cSGaetan Rivet 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
1896284c908cSGaetan Rivet 	dev = &rte_eth_devices[port_id];
1897284c908cSGaetan Rivet 
1898284c908cSGaetan Rivet 	stop_port(port_id);
1899284c908cSGaetan Rivet 	close_port(port_id);
1900f3a1188cSGaetan Rivet 	printf("removing device %s\n", dev->device->name);
19013070419eSGaetan Rivet 	if (rte_eal_dev_detach(dev->device))
1902285fd101SOlivier Matz 		TESTPMD_LOG(ERR, "Failed to detach device %s\n",
19033070419eSGaetan Rivet 			dev->device->name);
1904284c908cSGaetan Rivet }
1905284c908cSGaetan Rivet 
190676ad4a2dSGaetan Rivet /* This function is used by the interrupt thread */
1907d6af1a13SBernard Iremonger static int
1908f8244c63SZhiyong Yang eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
1909d6af1a13SBernard Iremonger 		  void *ret_param)
191076ad4a2dSGaetan Rivet {
191176ad4a2dSGaetan Rivet 	static const char * const event_desc[] = {
191276ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
191376ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_LSC] = "LSC",
191476ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
191576ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
191676ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
191776ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MACSEC] = "MACsec",
191876ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_INTR_RMV] = "device removal",
1919*4fb82244SMatan Azrad 		[RTE_ETH_EVENT_NEW] = "device probed",
1920*4fb82244SMatan Azrad 		[RTE_ETH_EVENT_DESTROY] = "device released",
192176ad4a2dSGaetan Rivet 		[RTE_ETH_EVENT_MAX] = NULL,
192276ad4a2dSGaetan Rivet 	};
192376ad4a2dSGaetan Rivet 
192476ad4a2dSGaetan Rivet 	RTE_SET_USED(param);
1925d6af1a13SBernard Iremonger 	RTE_SET_USED(ret_param);
192676ad4a2dSGaetan Rivet 
192776ad4a2dSGaetan Rivet 	if (type >= RTE_ETH_EVENT_MAX) {
192876ad4a2dSGaetan Rivet 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
192976ad4a2dSGaetan Rivet 			port_id, __func__, type);
193076ad4a2dSGaetan Rivet 		fflush(stderr);
19313af72783SGaetan Rivet 	} else if (event_print_mask & (UINT32_C(1) << type)) {
193276ad4a2dSGaetan Rivet 		printf("\nPort %" PRIu8 ": %s event\n", port_id,
193376ad4a2dSGaetan Rivet 			event_desc[type]);
193476ad4a2dSGaetan Rivet 		fflush(stdout);
193576ad4a2dSGaetan Rivet 	}
1936284c908cSGaetan Rivet 
1937284c908cSGaetan Rivet 	switch (type) {
1938284c908cSGaetan Rivet 	case RTE_ETH_EVENT_INTR_RMV:
1939284c908cSGaetan Rivet 		if (rte_eal_alarm_set(100000,
1940284c908cSGaetan Rivet 				rmv_event_callback, (void *)(intptr_t)port_id))
1941284c908cSGaetan Rivet 			fprintf(stderr, "Could not set up deferred device removal\n");
1942284c908cSGaetan Rivet 		break;
1943284c908cSGaetan Rivet 	default:
1944284c908cSGaetan Rivet 		break;
1945284c908cSGaetan Rivet 	}
1946d6af1a13SBernard Iremonger 	return 0;
194776ad4a2dSGaetan Rivet }
194876ad4a2dSGaetan Rivet 
1949013af9b6SIntel static int
195028caa76aSZhiyong Yang set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
1951af75078fSIntel {
1952013af9b6SIntel 	uint16_t i;
1953af75078fSIntel 	int diag;
1954013af9b6SIntel 	uint8_t mapping_found = 0;
1955af75078fSIntel 
1956013af9b6SIntel 	for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1957013af9b6SIntel 		if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1958013af9b6SIntel 				(tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1959013af9b6SIntel 			diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1960013af9b6SIntel 					tx_queue_stats_mappings[i].queue_id,
1961013af9b6SIntel 					tx_queue_stats_mappings[i].stats_counter_id);
1962013af9b6SIntel 			if (diag != 0)
1963013af9b6SIntel 				return diag;
1964013af9b6SIntel 			mapping_found = 1;
1965af75078fSIntel 		}
1966013af9b6SIntel 	}
1967013af9b6SIntel 	if (mapping_found)
1968013af9b6SIntel 		port->tx_queue_stats_mapping_enabled = 1;
1969013af9b6SIntel 	return 0;
1970013af9b6SIntel }
1971013af9b6SIntel 
1972013af9b6SIntel static int
197328caa76aSZhiyong Yang set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
1974013af9b6SIntel {
1975013af9b6SIntel 	uint16_t i;
1976013af9b6SIntel 	int diag;
1977013af9b6SIntel 	uint8_t mapping_found = 0;
1978013af9b6SIntel 
1979013af9b6SIntel 	for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1980013af9b6SIntel 		if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1981013af9b6SIntel 				(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1982013af9b6SIntel 			diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1983013af9b6SIntel 					rx_queue_stats_mappings[i].queue_id,
1984013af9b6SIntel 					rx_queue_stats_mappings[i].stats_counter_id);
1985013af9b6SIntel 			if (diag != 0)
1986013af9b6SIntel 				return diag;
1987013af9b6SIntel 			mapping_found = 1;
1988013af9b6SIntel 		}
1989013af9b6SIntel 	}
1990013af9b6SIntel 	if (mapping_found)
1991013af9b6SIntel 		port->rx_queue_stats_mapping_enabled = 1;
1992013af9b6SIntel 	return 0;
1993013af9b6SIntel }
1994013af9b6SIntel 
1995013af9b6SIntel static void
199628caa76aSZhiyong Yang map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
1997013af9b6SIntel {
1998013af9b6SIntel 	int diag = 0;
1999013af9b6SIntel 
2000013af9b6SIntel 	diag = set_tx_queue_stats_mapping_registers(pi, port);
2001af75078fSIntel 	if (diag != 0) {
2002013af9b6SIntel 		if (diag == -ENOTSUP) {
2003013af9b6SIntel 			port->tx_queue_stats_mapping_enabled = 0;
2004013af9b6SIntel 			printf("TX queue stats mapping not supported port id=%d\n", pi);
2005013af9b6SIntel 		}
2006013af9b6SIntel 		else
2007013af9b6SIntel 			rte_exit(EXIT_FAILURE,
2008013af9b6SIntel 					"set_tx_queue_stats_mapping_registers "
2009013af9b6SIntel 					"failed for port id=%d diag=%d\n",
2010af75078fSIntel 					pi, diag);
2011af75078fSIntel 	}
2012013af9b6SIntel 
2013013af9b6SIntel 	diag = set_rx_queue_stats_mapping_registers(pi, port);
2014af75078fSIntel 	if (diag != 0) {
2015013af9b6SIntel 		if (diag == -ENOTSUP) {
2016013af9b6SIntel 			port->rx_queue_stats_mapping_enabled = 0;
2017013af9b6SIntel 			printf("RX queue stats mapping not supported port id=%d\n", pi);
2018013af9b6SIntel 		}
2019013af9b6SIntel 		else
2020013af9b6SIntel 			rte_exit(EXIT_FAILURE,
2021013af9b6SIntel 					"set_rx_queue_stats_mapping_registers "
2022013af9b6SIntel 					"failed for port id=%d diag=%d\n",
2023af75078fSIntel 					pi, diag);
2024af75078fSIntel 	}
2025af75078fSIntel }
2026af75078fSIntel 
2027f2c5125aSPablo de Lara static void
2028f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port)
2029f2c5125aSPablo de Lara {
2030f2c5125aSPablo de Lara 	port->rx_conf = port->dev_info.default_rxconf;
2031f2c5125aSPablo de Lara 	port->tx_conf = port->dev_info.default_txconf;
2032f2c5125aSPablo de Lara 
2033f2c5125aSPablo de Lara 	/* Check if any RX/TX parameters have been passed */
2034f2c5125aSPablo de Lara 	if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2035f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.pthresh = rx_pthresh;
2036f2c5125aSPablo de Lara 
2037f2c5125aSPablo de Lara 	if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2038f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.hthresh = rx_hthresh;
2039f2c5125aSPablo de Lara 
2040f2c5125aSPablo de Lara 	if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2041f2c5125aSPablo de Lara 		port->rx_conf.rx_thresh.wthresh = rx_wthresh;
2042f2c5125aSPablo de Lara 
2043f2c5125aSPablo de Lara 	if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2044f2c5125aSPablo de Lara 		port->rx_conf.rx_free_thresh = rx_free_thresh;
2045f2c5125aSPablo de Lara 
2046f2c5125aSPablo de Lara 	if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2047f2c5125aSPablo de Lara 		port->rx_conf.rx_drop_en = rx_drop_en;
2048f2c5125aSPablo de Lara 
2049f2c5125aSPablo de Lara 	if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2050f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.pthresh = tx_pthresh;
2051f2c5125aSPablo de Lara 
2052f2c5125aSPablo de Lara 	if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2053f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.hthresh = tx_hthresh;
2054f2c5125aSPablo de Lara 
2055f2c5125aSPablo de Lara 	if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2056f2c5125aSPablo de Lara 		port->tx_conf.tx_thresh.wthresh = tx_wthresh;
2057f2c5125aSPablo de Lara 
2058f2c5125aSPablo de Lara 	if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2059f2c5125aSPablo de Lara 		port->tx_conf.tx_rs_thresh = tx_rs_thresh;
2060f2c5125aSPablo de Lara 
2061f2c5125aSPablo de Lara 	if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2062f2c5125aSPablo de Lara 		port->tx_conf.tx_free_thresh = tx_free_thresh;
2063f2c5125aSPablo de Lara }
2064f2c5125aSPablo de Lara 
2065013af9b6SIntel void
2066013af9b6SIntel init_port_config(void)
2067013af9b6SIntel {
2068013af9b6SIntel 	portid_t pid;
2069013af9b6SIntel 	struct rte_port *port;
2070013af9b6SIntel 
20717d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(pid) {
2072013af9b6SIntel 		port = &ports[pid];
2073013af9b6SIntel 		port->dev_conf.fdir_conf = fdir_conf;
20743ce690d3SBruce Richardson 		if (nb_rxq > 1) {
2075013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2076013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
2077af75078fSIntel 		} else {
2078013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2079013af9b6SIntel 			port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2080af75078fSIntel 		}
20813ce690d3SBruce Richardson 
20825f592039SJingjing Wu 		if (port->dcb_flag == 0) {
20833ce690d3SBruce Richardson 			if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
20843ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
20853ce690d3SBruce Richardson 			else
20863ce690d3SBruce Richardson 				port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
20873ce690d3SBruce Richardson 		}
20883ce690d3SBruce Richardson 
2089f2c5125aSPablo de Lara 		rxtx_port_config(port);
2090013af9b6SIntel 
2091013af9b6SIntel 		rte_eth_macaddr_get(pid, &port->eth_addr);
2092013af9b6SIntel 
2093013af9b6SIntel 		map_port_queue_stats_mapping_registers(pid, port);
209450c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2095e261265eSRadu Nicolau 		rte_pmd_ixgbe_bypass_init(pid);
20967b7e5ba7SIntel #endif
20978ea656f8SGaetan Rivet 
20988ea656f8SGaetan Rivet 		if (lsc_interrupt &&
20998ea656f8SGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
21008ea656f8SGaetan Rivet 		     RTE_ETH_DEV_INTR_LSC))
21018ea656f8SGaetan Rivet 			port->dev_conf.intr_conf.lsc = 1;
2102284c908cSGaetan Rivet 		if (rmv_interrupt &&
2103284c908cSGaetan Rivet 		    (rte_eth_devices[pid].data->dev_flags &
2104284c908cSGaetan Rivet 		     RTE_ETH_DEV_INTR_RMV))
2105284c908cSGaetan Rivet 			port->dev_conf.intr_conf.rmv = 1;
21065b590fbeSJasvinder Singh 
21075b590fbeSJasvinder Singh #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
21085b590fbeSJasvinder Singh 		/* Detect softnic port */
21095b590fbeSJasvinder Singh 		if (!strcmp(port->dev_info.driver_name, "net_softnic")) {
21105b590fbeSJasvinder Singh 			port->softnic_enable = 1;
21115b590fbeSJasvinder Singh 			memset(&port->softport, 0, sizeof(struct softnic_port));
21125b590fbeSJasvinder Singh 
21135b590fbeSJasvinder Singh 			if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm"))
21145b590fbeSJasvinder Singh 				port->softport.tm_flag = 1;
21155b590fbeSJasvinder Singh 		}
21165b590fbeSJasvinder Singh #endif
2117013af9b6SIntel 	}
2118013af9b6SIntel }
2119013af9b6SIntel 
212041b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid)
212141b05095SBernard Iremonger {
212241b05095SBernard Iremonger 	struct rte_port *port;
212341b05095SBernard Iremonger 
212441b05095SBernard Iremonger 	port = &ports[slave_pid];
212541b05095SBernard Iremonger 	port->slave_flag = 1;
212641b05095SBernard Iremonger }
212741b05095SBernard Iremonger 
212841b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid)
212941b05095SBernard Iremonger {
213041b05095SBernard Iremonger 	struct rte_port *port;
213141b05095SBernard Iremonger 
213241b05095SBernard Iremonger 	port = &ports[slave_pid];
213341b05095SBernard Iremonger 	port->slave_flag = 0;
213441b05095SBernard Iremonger }
213541b05095SBernard Iremonger 
21360e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid)
21370e545d30SBernard Iremonger {
21380e545d30SBernard Iremonger 	struct rte_port *port;
21390e545d30SBernard Iremonger 
21400e545d30SBernard Iremonger 	port = &ports[slave_pid];
21410e545d30SBernard Iremonger 	return port->slave_flag;
21420e545d30SBernard Iremonger }
21430e545d30SBernard Iremonger 
2144013af9b6SIntel const uint16_t vlan_tags[] = {
2145013af9b6SIntel 		0,  1,  2,  3,  4,  5,  6,  7,
2146013af9b6SIntel 		8,  9, 10, 11,  12, 13, 14, 15,
2147013af9b6SIntel 		16, 17, 18, 19, 20, 21, 22, 23,
2148013af9b6SIntel 		24, 25, 26, 27, 28, 29, 30, 31
2149013af9b6SIntel };
2150013af9b6SIntel 
2151013af9b6SIntel static  int
21521a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
21531a572499SJingjing Wu 		 enum dcb_mode_enable dcb_mode,
21541a572499SJingjing Wu 		 enum rte_eth_nb_tcs num_tcs,
21551a572499SJingjing Wu 		 uint8_t pfc_en)
2156013af9b6SIntel {
2157013af9b6SIntel 	uint8_t i;
2158af75078fSIntel 
2159af75078fSIntel 	/*
2160013af9b6SIntel 	 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2161013af9b6SIntel 	 * given above, and the number of traffic classes available for use.
2162af75078fSIntel 	 */
21631a572499SJingjing Wu 	if (dcb_mode == DCB_VT_ENABLED) {
21641a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
21651a572499SJingjing Wu 				&eth_conf->rx_adv_conf.vmdq_dcb_conf;
21661a572499SJingjing Wu 		struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
21671a572499SJingjing Wu 				&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2168013af9b6SIntel 
2169547d946cSNirmoy Das 		/* VMDQ+DCB RX and TX configurations */
21701a572499SJingjing Wu 		vmdq_rx_conf->enable_default_pool = 0;
21711a572499SJingjing Wu 		vmdq_rx_conf->default_pool = 0;
21721a572499SJingjing Wu 		vmdq_rx_conf->nb_queue_pools =
21731a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
21741a572499SJingjing Wu 		vmdq_tx_conf->nb_queue_pools =
21751a572499SJingjing Wu 			(num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2176013af9b6SIntel 
21771a572499SJingjing Wu 		vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
21781a572499SJingjing Wu 		for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
21791a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
21801a572499SJingjing Wu 			vmdq_rx_conf->pool_map[i].pools =
21811a572499SJingjing Wu 				1 << (i % vmdq_rx_conf->nb_queue_pools);
2182af75078fSIntel 		}
2183013af9b6SIntel 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2184f59908feSWei Dai 			vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2185f59908feSWei Dai 			vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2186013af9b6SIntel 		}
2187013af9b6SIntel 
2188013af9b6SIntel 		/* set DCB mode of RX and TX of multiple queues */
218932e7aa0bSIntel 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
219032e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
21911a572499SJingjing Wu 	} else {
21921a572499SJingjing Wu 		struct rte_eth_dcb_rx_conf *rx_conf =
21931a572499SJingjing Wu 				&eth_conf->rx_adv_conf.dcb_rx_conf;
21941a572499SJingjing Wu 		struct rte_eth_dcb_tx_conf *tx_conf =
21951a572499SJingjing Wu 				&eth_conf->tx_adv_conf.dcb_tx_conf;
2196013af9b6SIntel 
21971a572499SJingjing Wu 		rx_conf->nb_tcs = num_tcs;
21981a572499SJingjing Wu 		tx_conf->nb_tcs = num_tcs;
21991a572499SJingjing Wu 
2200bcd0e432SJingjing Wu 		for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2201bcd0e432SJingjing Wu 			rx_conf->dcb_tc[i] = i % num_tcs;
2202bcd0e432SJingjing Wu 			tx_conf->dcb_tc[i] = i % num_tcs;
2203013af9b6SIntel 		}
22041a572499SJingjing Wu 		eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
22051a572499SJingjing Wu 		eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
220632e7aa0bSIntel 		eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
22071a572499SJingjing Wu 	}
22081a572499SJingjing Wu 
22091a572499SJingjing Wu 	if (pfc_en)
22101a572499SJingjing Wu 		eth_conf->dcb_capability_en =
22111a572499SJingjing Wu 				ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2212013af9b6SIntel 	else
2213013af9b6SIntel 		eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2214013af9b6SIntel 
2215013af9b6SIntel 	return 0;
2216013af9b6SIntel }
2217013af9b6SIntel 
2218013af9b6SIntel int
22191a572499SJingjing Wu init_port_dcb_config(portid_t pid,
22201a572499SJingjing Wu 		     enum dcb_mode_enable dcb_mode,
22211a572499SJingjing Wu 		     enum rte_eth_nb_tcs num_tcs,
22221a572499SJingjing Wu 		     uint8_t pfc_en)
2223013af9b6SIntel {
2224013af9b6SIntel 	struct rte_eth_conf port_conf;
2225013af9b6SIntel 	struct rte_port *rte_port;
2226013af9b6SIntel 	int retval;
2227013af9b6SIntel 	uint16_t i;
2228013af9b6SIntel 
22292a977b89SWenzhuo Lu 	rte_port = &ports[pid];
2230013af9b6SIntel 
2231013af9b6SIntel 	memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2232013af9b6SIntel 	/* Enter DCB configuration status */
2233013af9b6SIntel 	dcb_config = 1;
2234013af9b6SIntel 
2235013af9b6SIntel 	/*set configuration of DCB in vt mode and DCB in non-vt mode*/
22361a572499SJingjing Wu 	retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2237013af9b6SIntel 	if (retval < 0)
2238013af9b6SIntel 		return retval;
22390074d02fSShahaf Shuler 	port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2240013af9b6SIntel 
22412a977b89SWenzhuo Lu 	/**
22422a977b89SWenzhuo Lu 	 * Write the configuration into the device.
22432a977b89SWenzhuo Lu 	 * Set the numbers of RX & TX queues to 0, so
22442a977b89SWenzhuo Lu 	 * the RX & TX queues will not be setup.
22452a977b89SWenzhuo Lu 	 */
2246c947ef89SStephen Hemminger 	rte_eth_dev_configure(pid, 0, 0, &port_conf);
22472a977b89SWenzhuo Lu 
22482a977b89SWenzhuo Lu 	rte_eth_dev_info_get(pid, &rte_port->dev_info);
22492a977b89SWenzhuo Lu 
22502a977b89SWenzhuo Lu 	/* If dev_info.vmdq_pool_base is greater than 0,
22512a977b89SWenzhuo Lu 	 * the queue id of vmdq pools is started after pf queues.
22522a977b89SWenzhuo Lu 	 */
22532a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED &&
22542a977b89SWenzhuo Lu 	    rte_port->dev_info.vmdq_pool_base > 0) {
22552a977b89SWenzhuo Lu 		printf("VMDQ_DCB multi-queue mode is nonsensical"
22562a977b89SWenzhuo Lu 			" for port %d.", pid);
22572a977b89SWenzhuo Lu 		return -1;
22582a977b89SWenzhuo Lu 	}
22592a977b89SWenzhuo Lu 
22602a977b89SWenzhuo Lu 	/* Assume the ports in testpmd have the same dcb capability
22612a977b89SWenzhuo Lu 	 * and has the same number of rxq and txq in dcb mode
22622a977b89SWenzhuo Lu 	 */
22632a977b89SWenzhuo Lu 	if (dcb_mode == DCB_VT_ENABLED) {
226486ef65eeSBernard Iremonger 		if (rte_port->dev_info.max_vfs > 0) {
226586ef65eeSBernard Iremonger 			nb_rxq = rte_port->dev_info.nb_rx_queues;
226686ef65eeSBernard Iremonger 			nb_txq = rte_port->dev_info.nb_tx_queues;
226786ef65eeSBernard Iremonger 		} else {
22682a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
22692a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
227086ef65eeSBernard Iremonger 		}
22712a977b89SWenzhuo Lu 	} else {
22722a977b89SWenzhuo Lu 		/*if vt is disabled, use all pf queues */
22732a977b89SWenzhuo Lu 		if (rte_port->dev_info.vmdq_pool_base == 0) {
22742a977b89SWenzhuo Lu 			nb_rxq = rte_port->dev_info.max_rx_queues;
22752a977b89SWenzhuo Lu 			nb_txq = rte_port->dev_info.max_tx_queues;
22762a977b89SWenzhuo Lu 		} else {
22772a977b89SWenzhuo Lu 			nb_rxq = (queueid_t)num_tcs;
22782a977b89SWenzhuo Lu 			nb_txq = (queueid_t)num_tcs;
22792a977b89SWenzhuo Lu 
22802a977b89SWenzhuo Lu 		}
22812a977b89SWenzhuo Lu 	}
22822a977b89SWenzhuo Lu 	rx_free_thresh = 64;
22832a977b89SWenzhuo Lu 
2284013af9b6SIntel 	memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2285013af9b6SIntel 
2286f2c5125aSPablo de Lara 	rxtx_port_config(rte_port);
2287013af9b6SIntel 	/* VLAN filter */
22880074d02fSShahaf Shuler 	rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
22891a572499SJingjing Wu 	for (i = 0; i < RTE_DIM(vlan_tags); i++)
2290013af9b6SIntel 		rx_vft_set(pid, vlan_tags[i], 1);
2291013af9b6SIntel 
2292013af9b6SIntel 	rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2293013af9b6SIntel 	map_port_queue_stats_mapping_registers(pid, rte_port);
2294013af9b6SIntel 
22957741e4cfSIntel 	rte_port->dcb_flag = 1;
22967741e4cfSIntel 
2297013af9b6SIntel 	return 0;
2298af75078fSIntel }
2299af75078fSIntel 
2300ffc468ffSTetsuya Mukawa static void
2301ffc468ffSTetsuya Mukawa init_port(void)
2302ffc468ffSTetsuya Mukawa {
2303ffc468ffSTetsuya Mukawa 	/* Configuration of Ethernet ports. */
2304ffc468ffSTetsuya Mukawa 	ports = rte_zmalloc("testpmd: ports",
2305ffc468ffSTetsuya Mukawa 			    sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2306ffc468ffSTetsuya Mukawa 			    RTE_CACHE_LINE_SIZE);
2307ffc468ffSTetsuya Mukawa 	if (ports == NULL) {
2308ffc468ffSTetsuya Mukawa 		rte_exit(EXIT_FAILURE,
2309ffc468ffSTetsuya Mukawa 				"rte_zmalloc(%d struct rte_port) failed\n",
2310ffc468ffSTetsuya Mukawa 				RTE_MAX_ETHPORTS);
2311ffc468ffSTetsuya Mukawa 	}
2312ffc468ffSTetsuya Mukawa }
2313ffc468ffSTetsuya Mukawa 
2314d3a274ceSZhihong Wang static void
2315d3a274ceSZhihong Wang force_quit(void)
2316d3a274ceSZhihong Wang {
2317d3a274ceSZhihong Wang 	pmd_test_exit();
2318d3a274ceSZhihong Wang 	prompt_exit();
2319d3a274ceSZhihong Wang }
2320d3a274ceSZhihong Wang 
2321d3a274ceSZhihong Wang static void
2322cfea1f30SPablo de Lara print_stats(void)
2323cfea1f30SPablo de Lara {
2324cfea1f30SPablo de Lara 	uint8_t i;
2325cfea1f30SPablo de Lara 	const char clr[] = { 27, '[', '2', 'J', '\0' };
2326cfea1f30SPablo de Lara 	const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2327cfea1f30SPablo de Lara 
2328cfea1f30SPablo de Lara 	/* Clear screen and move to top left */
2329cfea1f30SPablo de Lara 	printf("%s%s", clr, top_left);
2330cfea1f30SPablo de Lara 
2331cfea1f30SPablo de Lara 	printf("\nPort statistics ====================================");
2332cfea1f30SPablo de Lara 	for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2333cfea1f30SPablo de Lara 		nic_stats_display(fwd_ports_ids[i]);
2334cfea1f30SPablo de Lara }
2335cfea1f30SPablo de Lara 
2336cfea1f30SPablo de Lara static void
2337d3a274ceSZhihong Wang signal_handler(int signum)
2338d3a274ceSZhihong Wang {
2339d3a274ceSZhihong Wang 	if (signum == SIGINT || signum == SIGTERM) {
2340d3a274ceSZhihong Wang 		printf("\nSignal %d received, preparing to exit...\n",
2341d3a274ceSZhihong Wang 				signum);
2342102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2343102b7329SReshma Pattan 		/* uninitialize packet capture framework */
2344102b7329SReshma Pattan 		rte_pdump_uninit();
2345102b7329SReshma Pattan #endif
234662d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
234762d3216dSReshma Pattan 		rte_latencystats_uninit();
234862d3216dSReshma Pattan #endif
2349d3a274ceSZhihong Wang 		force_quit();
2350d9a191a0SPhil Yang 		/* Set flag to indicate the force termination. */
2351d9a191a0SPhil Yang 		f_quit = 1;
2352d3a274ceSZhihong Wang 		/* exit with the expected status */
2353d3a274ceSZhihong Wang 		signal(signum, SIG_DFL);
2354d3a274ceSZhihong Wang 		kill(getpid(), signum);
2355d3a274ceSZhihong Wang 	}
2356d3a274ceSZhihong Wang }
2357d3a274ceSZhihong Wang 
2358af75078fSIntel int
2359af75078fSIntel main(int argc, char** argv)
2360af75078fSIntel {
2361af75078fSIntel 	int  diag;
2362f8244c63SZhiyong Yang 	portid_t port_id;
2363af75078fSIntel 
2364d3a274ceSZhihong Wang 	signal(SIGINT, signal_handler);
2365d3a274ceSZhihong Wang 	signal(SIGTERM, signal_handler);
2366d3a274ceSZhihong Wang 
2367af75078fSIntel 	diag = rte_eal_init(argc, argv);
2368af75078fSIntel 	if (diag < 0)
2369af75078fSIntel 		rte_panic("Cannot init EAL\n");
2370af75078fSIntel 
2371285fd101SOlivier Matz 	testpmd_logtype = rte_log_register("testpmd");
2372285fd101SOlivier Matz 	if (testpmd_logtype < 0)
2373285fd101SOlivier Matz 		rte_panic("Cannot register log type");
2374285fd101SOlivier Matz 	rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
2375285fd101SOlivier Matz 
23761c036b16SEelco Chaudron 	if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
2377285fd101SOlivier Matz 		TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
23781c036b16SEelco Chaudron 			strerror(errno));
23791c036b16SEelco Chaudron 	}
23801c036b16SEelco Chaudron 
2381102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP
2382102b7329SReshma Pattan 	/* initialize packet capture framework */
2383102b7329SReshma Pattan 	rte_pdump_init(NULL);
2384102b7329SReshma Pattan #endif
2385102b7329SReshma Pattan 
2386af75078fSIntel 	nb_ports = (portid_t) rte_eth_dev_count();
2387af75078fSIntel 	if (nb_ports == 0)
2388285fd101SOlivier Matz 		TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
2389af75078fSIntel 
2390ffc468ffSTetsuya Mukawa 	/* allocate port structures, and init them */
2391ffc468ffSTetsuya Mukawa 	init_port();
2392ffc468ffSTetsuya Mukawa 
2393af75078fSIntel 	set_def_fwd_config();
2394af75078fSIntel 	if (nb_lcores == 0)
2395af75078fSIntel 		rte_panic("Empty set of forwarding logical cores - check the "
2396af75078fSIntel 			  "core mask supplied in the command parameters\n");
2397af75078fSIntel 
239865eb1e54SPablo de Lara 	/* Bitrate/latency stats disabled by default */
239930bcc68cSPablo de Lara #ifdef RTE_LIBRTE_BITRATE
2400e25e6c70SRemy Horton 	bitrate_enabled = 0;
240130bcc68cSPablo de Lara #endif
240265eb1e54SPablo de Lara #ifdef RTE_LIBRTE_LATENCY_STATS
240365eb1e54SPablo de Lara 	latencystats_enabled = 0;
240465eb1e54SPablo de Lara #endif
2405e25e6c70SRemy Horton 
2406af75078fSIntel 	argc -= diag;
2407af75078fSIntel 	argv += diag;
2408af75078fSIntel 	if (argc > 1)
2409af75078fSIntel 		launch_args_parse(argc, argv);
2410af75078fSIntel 
241199cabef0SPablo de Lara 	if (tx_first && interactive)
241299cabef0SPablo de Lara 		rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
241399cabef0SPablo de Lara 				"interactive mode.\n");
24148820cba4SDavid Hunt 
24158820cba4SDavid Hunt 	if (tx_first && lsc_interrupt) {
24168820cba4SDavid Hunt 		printf("Warning: lsc_interrupt needs to be off when "
24178820cba4SDavid Hunt 				" using tx_first. Disabling.\n");
24188820cba4SDavid Hunt 		lsc_interrupt = 0;
24198820cba4SDavid Hunt 	}
24208820cba4SDavid Hunt 
24215a8fb55cSReshma Pattan 	if (!nb_rxq && !nb_txq)
24225a8fb55cSReshma Pattan 		printf("Warning: Either rx or tx queues should be non-zero\n");
24235a8fb55cSReshma Pattan 
24245a8fb55cSReshma Pattan 	if (nb_rxq > 1 && nb_rxq > nb_txq)
2425af75078fSIntel 		printf("Warning: nb_rxq=%d enables RSS configuration, "
2426af75078fSIntel 		       "but nb_txq=%d will prevent to fully test it.\n",
2427af75078fSIntel 		       nb_rxq, nb_txq);
2428af75078fSIntel 
2429af75078fSIntel 	init_config();
2430148f963fSBruce Richardson 	if (start_port(RTE_PORT_ALL) != 0)
2431148f963fSBruce Richardson 		rte_exit(EXIT_FAILURE, "Start ports failed\n");
2432af75078fSIntel 
2433ce8d5614SIntel 	/* set all ports to promiscuous mode by default */
24347d89b261SGaetan Rivet 	RTE_ETH_FOREACH_DEV(port_id)
2435ce8d5614SIntel 		rte_eth_promiscuous_enable(port_id);
2436af75078fSIntel 
24377e4441c8SRemy Horton 	/* Init metrics library */
24387e4441c8SRemy Horton 	rte_metrics_init(rte_socket_id());
24397e4441c8SRemy Horton 
244062d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS
244162d3216dSReshma Pattan 	if (latencystats_enabled != 0) {
244262d3216dSReshma Pattan 		int ret = rte_latencystats_init(1, NULL);
244362d3216dSReshma Pattan 		if (ret)
244462d3216dSReshma Pattan 			printf("Warning: latencystats init()"
244562d3216dSReshma Pattan 				" returned error %d\n",	ret);
244662d3216dSReshma Pattan 		printf("Latencystats running on lcore %d\n",
244762d3216dSReshma Pattan 			latencystats_lcore_id);
244862d3216dSReshma Pattan 	}
244962d3216dSReshma Pattan #endif
245062d3216dSReshma Pattan 
24517e4441c8SRemy Horton 	/* Setup bitrate stats */
24527e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE
2453e25e6c70SRemy Horton 	if (bitrate_enabled != 0) {
24547e4441c8SRemy Horton 		bitrate_data = rte_stats_bitrate_create();
24557e4441c8SRemy Horton 		if (bitrate_data == NULL)
2456e25e6c70SRemy Horton 			rte_exit(EXIT_FAILURE,
2457e25e6c70SRemy Horton 				"Could not allocate bitrate data.\n");
24587e4441c8SRemy Horton 		rte_stats_bitrate_reg(bitrate_data);
2459e25e6c70SRemy Horton 	}
24607e4441c8SRemy Horton #endif
24617e4441c8SRemy Horton 
24620d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE
246381ef862bSAllain Legacy 	if (strlen(cmdline_filename) != 0)
246481ef862bSAllain Legacy 		cmdline_read_from_file(cmdline_filename);
246581ef862bSAllain Legacy 
2466ca7feb22SCyril Chemparathy 	if (interactive == 1) {
2467ca7feb22SCyril Chemparathy 		if (auto_start) {
2468ca7feb22SCyril Chemparathy 			printf("Start automatic packet forwarding\n");
2469ca7feb22SCyril Chemparathy 			start_packet_forwarding(0);
2470ca7feb22SCyril Chemparathy 		}
2471af75078fSIntel 		prompt();
24720de738cfSJiayu Hu 		pmd_test_exit();
2473ca7feb22SCyril Chemparathy 	} else
24740d56cb81SThomas Monjalon #endif
24750d56cb81SThomas Monjalon 	{
2476af75078fSIntel 		char c;
2477af75078fSIntel 		int rc;
2478af75078fSIntel 
2479d9a191a0SPhil Yang 		f_quit = 0;
2480d9a191a0SPhil Yang 
2481af75078fSIntel 		printf("No commandline core given, start packet forwarding\n");
248299cabef0SPablo de Lara 		start_packet_forwarding(tx_first);
2483cfea1f30SPablo de Lara 		if (stats_period != 0) {
2484cfea1f30SPablo de Lara 			uint64_t prev_time = 0, cur_time, diff_time = 0;
2485cfea1f30SPablo de Lara 			uint64_t timer_period;
2486cfea1f30SPablo de Lara 
2487cfea1f30SPablo de Lara 			/* Convert to number of cycles */
2488cfea1f30SPablo de Lara 			timer_period = stats_period * rte_get_timer_hz();
2489cfea1f30SPablo de Lara 
2490d9a191a0SPhil Yang 			while (f_quit == 0) {
2491cfea1f30SPablo de Lara 				cur_time = rte_get_timer_cycles();
2492cfea1f30SPablo de Lara 				diff_time += cur_time - prev_time;
2493cfea1f30SPablo de Lara 
2494cfea1f30SPablo de Lara 				if (diff_time >= timer_period) {
2495cfea1f30SPablo de Lara 					print_stats();
2496cfea1f30SPablo de Lara 					/* Reset the timer */
2497cfea1f30SPablo de Lara 					diff_time = 0;
2498cfea1f30SPablo de Lara 				}
2499cfea1f30SPablo de Lara 				/* Sleep to avoid unnecessary checks */
2500cfea1f30SPablo de Lara 				prev_time = cur_time;
2501cfea1f30SPablo de Lara 				sleep(1);
2502cfea1f30SPablo de Lara 			}
2503cfea1f30SPablo de Lara 		}
2504cfea1f30SPablo de Lara 
2505af75078fSIntel 		printf("Press enter to exit\n");
2506af75078fSIntel 		rc = read(0, &c, 1);
2507d3a274ceSZhihong Wang 		pmd_test_exit();
2508af75078fSIntel 		if (rc < 0)
2509af75078fSIntel 			return 1;
2510af75078fSIntel 	}
2511af75078fSIntel 
2512af75078fSIntel 	return 0;
2513af75078fSIntel }
2514