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