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