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