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