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 5373f7311baSWei Dai /* 5383f7311baSWei Dai * Get the allowed maximum number of RX queues. 5393f7311baSWei Dai * *pid return the port id which has minimal value of 5403f7311baSWei Dai * max_rx_queues in all ports. 5413f7311baSWei Dai */ 5423f7311baSWei Dai queueid_t 5433f7311baSWei Dai get_allowed_max_nb_rxq(portid_t *pid) 5443f7311baSWei Dai { 5453f7311baSWei Dai queueid_t allowed_max_rxq = MAX_QUEUE_ID; 5463f7311baSWei Dai portid_t pi; 5473f7311baSWei Dai struct rte_eth_dev_info dev_info; 5483f7311baSWei Dai 5493f7311baSWei Dai RTE_ETH_FOREACH_DEV(pi) { 5503f7311baSWei Dai rte_eth_dev_info_get(pi, &dev_info); 5513f7311baSWei Dai if (dev_info.max_rx_queues < allowed_max_rxq) { 5523f7311baSWei Dai allowed_max_rxq = dev_info.max_rx_queues; 5533f7311baSWei Dai *pid = pi; 5543f7311baSWei Dai } 5553f7311baSWei Dai } 5563f7311baSWei Dai return allowed_max_rxq; 5573f7311baSWei Dai } 5583f7311baSWei Dai 5593f7311baSWei Dai /* 5603f7311baSWei Dai * Check input rxq is valid or not. 5613f7311baSWei Dai * If input rxq is not greater than any of maximum number 5623f7311baSWei Dai * of RX queues of all ports, it is valid. 5633f7311baSWei Dai * if valid, return 0, else return -1 5643f7311baSWei Dai */ 5653f7311baSWei Dai int 5663f7311baSWei Dai check_nb_rxq(queueid_t rxq) 5673f7311baSWei Dai { 5683f7311baSWei Dai queueid_t allowed_max_rxq; 5693f7311baSWei Dai portid_t pid = 0; 5703f7311baSWei Dai 5713f7311baSWei Dai allowed_max_rxq = get_allowed_max_nb_rxq(&pid); 5723f7311baSWei Dai if (rxq > allowed_max_rxq) { 5733f7311baSWei Dai printf("Fail: input rxq (%u) can't be greater " 5743f7311baSWei Dai "than max_rx_queues (%u) of port %u\n", 5753f7311baSWei Dai rxq, 5763f7311baSWei Dai allowed_max_rxq, 5773f7311baSWei Dai pid); 5783f7311baSWei Dai return -1; 5793f7311baSWei Dai } 5803f7311baSWei Dai return 0; 5813f7311baSWei Dai } 5823f7311baSWei Dai 583*36db4f6cSWei Dai /* 584*36db4f6cSWei Dai * Get the allowed maximum number of TX queues. 585*36db4f6cSWei Dai * *pid return the port id which has minimal value of 586*36db4f6cSWei Dai * max_tx_queues in all ports. 587*36db4f6cSWei Dai */ 588*36db4f6cSWei Dai queueid_t 589*36db4f6cSWei Dai get_allowed_max_nb_txq(portid_t *pid) 590*36db4f6cSWei Dai { 591*36db4f6cSWei Dai queueid_t allowed_max_txq = MAX_QUEUE_ID; 592*36db4f6cSWei Dai portid_t pi; 593*36db4f6cSWei Dai struct rte_eth_dev_info dev_info; 594*36db4f6cSWei Dai 595*36db4f6cSWei Dai RTE_ETH_FOREACH_DEV(pi) { 596*36db4f6cSWei Dai rte_eth_dev_info_get(pi, &dev_info); 597*36db4f6cSWei Dai if (dev_info.max_tx_queues < allowed_max_txq) { 598*36db4f6cSWei Dai allowed_max_txq = dev_info.max_tx_queues; 599*36db4f6cSWei Dai *pid = pi; 600*36db4f6cSWei Dai } 601*36db4f6cSWei Dai } 602*36db4f6cSWei Dai return allowed_max_txq; 603*36db4f6cSWei Dai } 604*36db4f6cSWei Dai 605*36db4f6cSWei Dai /* 606*36db4f6cSWei Dai * Check input txq is valid or not. 607*36db4f6cSWei Dai * If input txq is not greater than any of maximum number 608*36db4f6cSWei Dai * of TX queues of all ports, it is valid. 609*36db4f6cSWei Dai * if valid, return 0, else return -1 610*36db4f6cSWei Dai */ 611*36db4f6cSWei Dai int 612*36db4f6cSWei Dai check_nb_txq(queueid_t txq) 613*36db4f6cSWei Dai { 614*36db4f6cSWei Dai queueid_t allowed_max_txq; 615*36db4f6cSWei Dai portid_t pid = 0; 616*36db4f6cSWei Dai 617*36db4f6cSWei Dai allowed_max_txq = get_allowed_max_nb_txq(&pid); 618*36db4f6cSWei Dai if (txq > allowed_max_txq) { 619*36db4f6cSWei Dai printf("Fail: input txq (%u) can't be greater " 620*36db4f6cSWei Dai "than max_tx_queues (%u) of port %u\n", 621*36db4f6cSWei Dai txq, 622*36db4f6cSWei Dai allowed_max_txq, 623*36db4f6cSWei Dai pid); 624*36db4f6cSWei Dai return -1; 625*36db4f6cSWei Dai } 626*36db4f6cSWei Dai return 0; 627*36db4f6cSWei Dai } 628*36db4f6cSWei Dai 629af75078fSIntel static void 630af75078fSIntel init_config(void) 631af75078fSIntel { 632ce8d5614SIntel portid_t pid; 633af75078fSIntel struct rte_port *port; 634af75078fSIntel struct rte_mempool *mbp; 635af75078fSIntel unsigned int nb_mbuf_per_pool; 636af75078fSIntel lcoreid_t lc_id; 6377acf894dSStephen Hurd uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; 638b7091f1dSJiayu Hu struct rte_gro_param gro_param; 63952f38a20SJiayu Hu uint32_t gso_types; 640af75078fSIntel 6417acf894dSStephen Hurd memset(port_per_socket,0,RTE_MAX_NUMA_NODES); 642487f9a59SYulong Pei 643487f9a59SYulong Pei if (numa_support) { 644487f9a59SYulong Pei memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 645487f9a59SYulong Pei memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 646487f9a59SYulong Pei memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 647487f9a59SYulong Pei } 648487f9a59SYulong Pei 649af75078fSIntel /* Configuration of logical cores. */ 650af75078fSIntel fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 651af75078fSIntel sizeof(struct fwd_lcore *) * nb_lcores, 652fdf20fa7SSergio Gonzalez Monroy RTE_CACHE_LINE_SIZE); 653af75078fSIntel if (fwd_lcores == NULL) { 654ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 655ce8d5614SIntel "failed\n", nb_lcores); 656af75078fSIntel } 657af75078fSIntel for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 658af75078fSIntel fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 659af75078fSIntel sizeof(struct fwd_lcore), 660fdf20fa7SSergio Gonzalez Monroy RTE_CACHE_LINE_SIZE); 661af75078fSIntel if (fwd_lcores[lc_id] == NULL) { 662ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 663ce8d5614SIntel "failed\n"); 664af75078fSIntel } 665af75078fSIntel fwd_lcores[lc_id]->cpuid_idx = lc_id; 666af75078fSIntel } 667af75078fSIntel 6687d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pid) { 669ce8d5614SIntel port = &ports[pid]; 670fd8c20aaSShahaf Shuler /* Apply default Tx configuration for all ports */ 671fd8c20aaSShahaf Shuler port->dev_conf.txmode = tx_mode; 672384161e0SShahaf Shuler port->dev_conf.rxmode = rx_mode; 673ce8d5614SIntel rte_eth_dev_info_get(pid, &port->dev_info); 67407e5f7bdSShahaf Shuler if (!(port->dev_info.tx_offload_capa & 67507e5f7bdSShahaf Shuler DEV_TX_OFFLOAD_MBUF_FAST_FREE)) 67607e5f7bdSShahaf Shuler port->dev_conf.txmode.offloads &= 67707e5f7bdSShahaf Shuler ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; 678ce8d5614SIntel 679b6ea6408SIntel if (numa_support) { 680b6ea6408SIntel if (port_numa[pid] != NUMA_NO_CONFIG) 681b6ea6408SIntel port_per_socket[port_numa[pid]]++; 682b6ea6408SIntel else { 683b6ea6408SIntel uint32_t socket_id = rte_eth_dev_socket_id(pid); 68420a0286fSLiu Xiaofeng 68520a0286fSLiu Xiaofeng /* if socket_id is invalid, set to 0 */ 68620a0286fSLiu Xiaofeng if (check_socket_id(socket_id) < 0) 68720a0286fSLiu Xiaofeng socket_id = 0; 688b6ea6408SIntel port_per_socket[socket_id]++; 689b6ea6408SIntel } 690b6ea6408SIntel } 691b6ea6408SIntel 692ce8d5614SIntel /* set flag to initialize port/queue */ 693ce8d5614SIntel port->need_reconfig = 1; 694ce8d5614SIntel port->need_reconfig_queues = 1; 695ce8d5614SIntel } 696ce8d5614SIntel 6973ab64341SOlivier Matz /* 6983ab64341SOlivier Matz * Create pools of mbuf. 6993ab64341SOlivier Matz * If NUMA support is disabled, create a single pool of mbuf in 7003ab64341SOlivier Matz * socket 0 memory by default. 7013ab64341SOlivier Matz * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 7023ab64341SOlivier Matz * 7033ab64341SOlivier Matz * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 7043ab64341SOlivier Matz * nb_txd can be configured at run time. 7053ab64341SOlivier Matz */ 7063ab64341SOlivier Matz if (param_total_num_mbufs) 7073ab64341SOlivier Matz nb_mbuf_per_pool = param_total_num_mbufs; 7083ab64341SOlivier Matz else { 7093ab64341SOlivier Matz nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + 7103ab64341SOlivier Matz (nb_lcores * mb_mempool_cache) + 7113ab64341SOlivier Matz RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 7123ab64341SOlivier Matz nb_mbuf_per_pool *= RTE_MAX_ETHPORTS; 7133ab64341SOlivier Matz } 7143ab64341SOlivier Matz 715b6ea6408SIntel if (numa_support) { 716b6ea6408SIntel uint8_t i; 717ce8d5614SIntel 718c9cafcc8SShahaf Shuler for (i = 0; i < num_sockets; i++) 719c9cafcc8SShahaf Shuler mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 720c9cafcc8SShahaf Shuler socket_ids[i]); 7213ab64341SOlivier Matz } else { 7223ab64341SOlivier Matz if (socket_num == UMA_NO_CONFIG) 7233ab64341SOlivier Matz mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 7243ab64341SOlivier Matz else 7253ab64341SOlivier Matz mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 7263ab64341SOlivier Matz socket_num); 7273ab64341SOlivier Matz } 728b6ea6408SIntel 729b6ea6408SIntel init_port_config(); 7305886ae07SAdrien Mazarguil 73152f38a20SJiayu Hu gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 73252f38a20SJiayu Hu DEV_TX_OFFLOAD_GRE_TNL_TSO; 7335886ae07SAdrien Mazarguil /* 7345886ae07SAdrien Mazarguil * Records which Mbuf pool to use by each logical core, if needed. 7355886ae07SAdrien Mazarguil */ 7365886ae07SAdrien Mazarguil for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 7378fd8bebcSAdrien Mazarguil mbp = mbuf_pool_find( 7388fd8bebcSAdrien Mazarguil rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id])); 7398fd8bebcSAdrien Mazarguil 7405886ae07SAdrien Mazarguil if (mbp == NULL) 7415886ae07SAdrien Mazarguil mbp = mbuf_pool_find(0); 7425886ae07SAdrien Mazarguil fwd_lcores[lc_id]->mbp = mbp; 74352f38a20SJiayu Hu /* initialize GSO context */ 74452f38a20SJiayu Hu fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp; 74552f38a20SJiayu Hu fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp; 74652f38a20SJiayu Hu fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types; 74752f38a20SJiayu Hu fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN - 74852f38a20SJiayu Hu ETHER_CRC_LEN; 74952f38a20SJiayu Hu fwd_lcores[lc_id]->gso_ctx.flag = 0; 7505886ae07SAdrien Mazarguil } 7515886ae07SAdrien Mazarguil 752ce8d5614SIntel /* Configuration of packet forwarding streams. */ 753ce8d5614SIntel if (init_fwd_streams() < 0) 754ce8d5614SIntel rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 7550c0db76fSBernard Iremonger 7560c0db76fSBernard Iremonger fwd_config_setup(); 757b7091f1dSJiayu Hu 758b7091f1dSJiayu Hu /* create a gro context for each lcore */ 759b7091f1dSJiayu Hu gro_param.gro_types = RTE_GRO_TCP_IPV4; 760b7091f1dSJiayu Hu gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES; 761b7091f1dSJiayu Hu gro_param.max_item_per_flow = MAX_PKT_BURST; 762b7091f1dSJiayu Hu for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 763b7091f1dSJiayu Hu gro_param.socket_id = rte_lcore_to_socket_id( 764b7091f1dSJiayu Hu fwd_lcores_cpuids[lc_id]); 765b7091f1dSJiayu Hu fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param); 766b7091f1dSJiayu Hu if (fwd_lcores[lc_id]->gro_ctx == NULL) { 767b7091f1dSJiayu Hu rte_exit(EXIT_FAILURE, 768b7091f1dSJiayu Hu "rte_gro_ctx_create() failed\n"); 769b7091f1dSJiayu Hu } 770b7091f1dSJiayu Hu } 771ce8d5614SIntel } 772ce8d5614SIntel 7732950a769SDeclan Doherty 7742950a769SDeclan Doherty void 775a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id) 7762950a769SDeclan Doherty { 7772950a769SDeclan Doherty struct rte_port *port; 7782950a769SDeclan Doherty 7792950a769SDeclan Doherty /* Reconfiguration of Ethernet ports. */ 7802950a769SDeclan Doherty port = &ports[new_port_id]; 7812950a769SDeclan Doherty rte_eth_dev_info_get(new_port_id, &port->dev_info); 7822950a769SDeclan Doherty 7832950a769SDeclan Doherty /* set flag to initialize port/queue */ 7842950a769SDeclan Doherty port->need_reconfig = 1; 7852950a769SDeclan Doherty port->need_reconfig_queues = 1; 786a21d5a4bSDeclan Doherty port->socket_id = socket_id; 7872950a769SDeclan Doherty 7882950a769SDeclan Doherty init_port_config(); 7892950a769SDeclan Doherty } 7902950a769SDeclan Doherty 7912950a769SDeclan Doherty 792ce8d5614SIntel int 793ce8d5614SIntel init_fwd_streams(void) 794ce8d5614SIntel { 795ce8d5614SIntel portid_t pid; 796ce8d5614SIntel struct rte_port *port; 797ce8d5614SIntel streamid_t sm_id, nb_fwd_streams_new; 7985a8fb55cSReshma Pattan queueid_t q; 799ce8d5614SIntel 800ce8d5614SIntel /* set socket id according to numa or not */ 8017d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pid) { 802ce8d5614SIntel port = &ports[pid]; 803ce8d5614SIntel if (nb_rxq > port->dev_info.max_rx_queues) { 804ce8d5614SIntel printf("Fail: nb_rxq(%d) is greater than " 805ce8d5614SIntel "max_rx_queues(%d)\n", nb_rxq, 806ce8d5614SIntel port->dev_info.max_rx_queues); 807ce8d5614SIntel return -1; 808ce8d5614SIntel } 809ce8d5614SIntel if (nb_txq > port->dev_info.max_tx_queues) { 810ce8d5614SIntel printf("Fail: nb_txq(%d) is greater than " 811ce8d5614SIntel "max_tx_queues(%d)\n", nb_txq, 812ce8d5614SIntel port->dev_info.max_tx_queues); 813ce8d5614SIntel return -1; 814ce8d5614SIntel } 81520a0286fSLiu Xiaofeng if (numa_support) { 81620a0286fSLiu Xiaofeng if (port_numa[pid] != NUMA_NO_CONFIG) 81720a0286fSLiu Xiaofeng port->socket_id = port_numa[pid]; 81820a0286fSLiu Xiaofeng else { 819b6ea6408SIntel port->socket_id = rte_eth_dev_socket_id(pid); 82020a0286fSLiu Xiaofeng 82120a0286fSLiu Xiaofeng /* if socket_id is invalid, set to 0 */ 82220a0286fSLiu Xiaofeng if (check_socket_id(port->socket_id) < 0) 82320a0286fSLiu Xiaofeng port->socket_id = 0; 82420a0286fSLiu Xiaofeng } 82520a0286fSLiu Xiaofeng } 826b6ea6408SIntel else { 827b6ea6408SIntel if (socket_num == UMA_NO_CONFIG) 828af75078fSIntel port->socket_id = 0; 829b6ea6408SIntel else 830b6ea6408SIntel port->socket_id = socket_num; 831b6ea6408SIntel } 832af75078fSIntel } 833af75078fSIntel 8345a8fb55cSReshma Pattan q = RTE_MAX(nb_rxq, nb_txq); 8355a8fb55cSReshma Pattan if (q == 0) { 8365a8fb55cSReshma Pattan printf("Fail: Cannot allocate fwd streams as number of queues is 0\n"); 8375a8fb55cSReshma Pattan return -1; 8385a8fb55cSReshma Pattan } 8395a8fb55cSReshma Pattan nb_fwd_streams_new = (streamid_t)(nb_ports * q); 840ce8d5614SIntel if (nb_fwd_streams_new == nb_fwd_streams) 841ce8d5614SIntel return 0; 842ce8d5614SIntel /* clear the old */ 843ce8d5614SIntel if (fwd_streams != NULL) { 844ce8d5614SIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 845ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 846ce8d5614SIntel continue; 847ce8d5614SIntel rte_free(fwd_streams[sm_id]); 848ce8d5614SIntel fwd_streams[sm_id] = NULL; 849af75078fSIntel } 850ce8d5614SIntel rte_free(fwd_streams); 851ce8d5614SIntel fwd_streams = NULL; 852ce8d5614SIntel } 853ce8d5614SIntel 854ce8d5614SIntel /* init new */ 855ce8d5614SIntel nb_fwd_streams = nb_fwd_streams_new; 856ce8d5614SIntel fwd_streams = rte_zmalloc("testpmd: fwd_streams", 857fdf20fa7SSergio Gonzalez Monroy sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE); 858ce8d5614SIntel if (fwd_streams == NULL) 859ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " 860ce8d5614SIntel "failed\n", nb_fwd_streams); 861ce8d5614SIntel 862af75078fSIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 863af75078fSIntel fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", 864fdf20fa7SSergio Gonzalez Monroy sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE); 865ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 866ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" 867ce8d5614SIntel " failed\n"); 868af75078fSIntel } 869ce8d5614SIntel 870ce8d5614SIntel return 0; 871af75078fSIntel } 872af75078fSIntel 873af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 874af75078fSIntel static void 875af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 876af75078fSIntel { 877af75078fSIntel unsigned int total_burst; 878af75078fSIntel unsigned int nb_burst; 879af75078fSIntel unsigned int burst_stats[3]; 880af75078fSIntel uint16_t pktnb_stats[3]; 881af75078fSIntel uint16_t nb_pkt; 882af75078fSIntel int burst_percent[3]; 883af75078fSIntel 884af75078fSIntel /* 885af75078fSIntel * First compute the total number of packet bursts and the 886af75078fSIntel * two highest numbers of bursts of the same number of packets. 887af75078fSIntel */ 888af75078fSIntel total_burst = 0; 889af75078fSIntel burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 890af75078fSIntel pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 891af75078fSIntel for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 892af75078fSIntel nb_burst = pbs->pkt_burst_spread[nb_pkt]; 893af75078fSIntel if (nb_burst == 0) 894af75078fSIntel continue; 895af75078fSIntel total_burst += nb_burst; 896af75078fSIntel if (nb_burst > burst_stats[0]) { 897af75078fSIntel burst_stats[1] = burst_stats[0]; 898af75078fSIntel pktnb_stats[1] = pktnb_stats[0]; 899af75078fSIntel burst_stats[0] = nb_burst; 900af75078fSIntel pktnb_stats[0] = nb_pkt; 901af75078fSIntel } 902af75078fSIntel } 903af75078fSIntel if (total_burst == 0) 904af75078fSIntel return; 905af75078fSIntel burst_percent[0] = (burst_stats[0] * 100) / total_burst; 906af75078fSIntel printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 907af75078fSIntel burst_percent[0], (int) pktnb_stats[0]); 908af75078fSIntel if (burst_stats[0] == total_burst) { 909af75078fSIntel printf("]\n"); 910af75078fSIntel return; 911af75078fSIntel } 912af75078fSIntel if (burst_stats[0] + burst_stats[1] == total_burst) { 913af75078fSIntel printf(" + %d%% of %d pkts]\n", 914af75078fSIntel 100 - burst_percent[0], pktnb_stats[1]); 915af75078fSIntel return; 916af75078fSIntel } 917af75078fSIntel burst_percent[1] = (burst_stats[1] * 100) / total_burst; 918af75078fSIntel burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 919af75078fSIntel if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 920af75078fSIntel printf(" + %d%% of others]\n", 100 - burst_percent[0]); 921af75078fSIntel return; 922af75078fSIntel } 923af75078fSIntel printf(" + %d%% of %d pkts + %d%% of others]\n", 924af75078fSIntel burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 925af75078fSIntel } 926af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 927af75078fSIntel 928af75078fSIntel static void 929af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) 930af75078fSIntel { 931af75078fSIntel struct rte_port *port; 932013af9b6SIntel uint8_t i; 933af75078fSIntel 934af75078fSIntel static const char *fwd_stats_border = "----------------------"; 935af75078fSIntel 936af75078fSIntel port = &ports[port_id]; 937af75078fSIntel printf("\n %s Forward statistics for port %-2d %s\n", 938af75078fSIntel fwd_stats_border, port_id, fwd_stats_border); 939013af9b6SIntel 940013af9b6SIntel if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 941af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 942af75078fSIntel "%-"PRIu64"\n", 94370bdb186SIvan Boule stats->ipackets, stats->imissed, 94470bdb186SIvan Boule (uint64_t) (stats->ipackets + stats->imissed)); 945af75078fSIntel 946af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) 947af75078fSIntel printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n", 948af75078fSIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 94986057c99SIgor Ryzhov if ((stats->ierrors + stats->rx_nombuf) > 0) { 950f72a0fa6SStephen Hemminger printf(" RX-error: %-"PRIu64"\n", stats->ierrors); 95170bdb186SIvan Boule printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf); 95270bdb186SIvan Boule } 953af75078fSIntel 954af75078fSIntel printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 955af75078fSIntel "%-"PRIu64"\n", 956af75078fSIntel stats->opackets, port->tx_dropped, 957af75078fSIntel (uint64_t) (stats->opackets + port->tx_dropped)); 958013af9b6SIntel } 959013af9b6SIntel else { 960013af9b6SIntel printf(" RX-packets: %14"PRIu64" RX-dropped:%14"PRIu64" RX-total:" 961013af9b6SIntel "%14"PRIu64"\n", 96270bdb186SIvan Boule stats->ipackets, stats->imissed, 96370bdb186SIvan Boule (uint64_t) (stats->ipackets + stats->imissed)); 964013af9b6SIntel 965013af9b6SIntel if (cur_fwd_eng == &csum_fwd_engine) 966013af9b6SIntel printf(" Bad-ipcsum:%14"PRIu64" Bad-l4csum:%14"PRIu64"\n", 967013af9b6SIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 96886057c99SIgor Ryzhov if ((stats->ierrors + stats->rx_nombuf) > 0) { 969f72a0fa6SStephen Hemminger printf(" RX-error:%"PRIu64"\n", stats->ierrors); 97070bdb186SIvan Boule printf(" RX-nombufs: %14"PRIu64"\n", 97170bdb186SIvan Boule stats->rx_nombuf); 97270bdb186SIvan Boule } 973013af9b6SIntel 974013af9b6SIntel printf(" TX-packets: %14"PRIu64" TX-dropped:%14"PRIu64" TX-total:" 975013af9b6SIntel "%14"PRIu64"\n", 976013af9b6SIntel stats->opackets, port->tx_dropped, 977013af9b6SIntel (uint64_t) (stats->opackets + port->tx_dropped)); 978013af9b6SIntel } 979e659b6b4SIvan Boule 980af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 981af75078fSIntel if (port->rx_stream) 982013af9b6SIntel pkt_burst_stats_display("RX", 983013af9b6SIntel &port->rx_stream->rx_burst_stats); 984af75078fSIntel if (port->tx_stream) 985013af9b6SIntel pkt_burst_stats_display("TX", 986013af9b6SIntel &port->tx_stream->tx_burst_stats); 987af75078fSIntel #endif 988af75078fSIntel 989013af9b6SIntel if (port->rx_queue_stats_mapping_enabled) { 990013af9b6SIntel printf("\n"); 991013af9b6SIntel for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 992013af9b6SIntel printf(" Stats reg %2d RX-packets:%14"PRIu64 993013af9b6SIntel " RX-errors:%14"PRIu64 994013af9b6SIntel " RX-bytes:%14"PRIu64"\n", 995013af9b6SIntel i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]); 996013af9b6SIntel } 997013af9b6SIntel printf("\n"); 998013af9b6SIntel } 999013af9b6SIntel if (port->tx_queue_stats_mapping_enabled) { 1000013af9b6SIntel for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 1001013af9b6SIntel printf(" Stats reg %2d TX-packets:%14"PRIu64 1002013af9b6SIntel " TX-bytes:%14"PRIu64"\n", 1003013af9b6SIntel i, stats->q_opackets[i], stats->q_obytes[i]); 1004013af9b6SIntel } 1005013af9b6SIntel } 1006013af9b6SIntel 1007af75078fSIntel printf(" %s--------------------------------%s\n", 1008af75078fSIntel fwd_stats_border, fwd_stats_border); 1009af75078fSIntel } 1010af75078fSIntel 1011af75078fSIntel static void 1012af75078fSIntel fwd_stream_stats_display(streamid_t stream_id) 1013af75078fSIntel { 1014af75078fSIntel struct fwd_stream *fs; 1015af75078fSIntel static const char *fwd_top_stats_border = "-------"; 1016af75078fSIntel 1017af75078fSIntel fs = fwd_streams[stream_id]; 1018af75078fSIntel if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 1019af75078fSIntel (fs->fwd_dropped == 0)) 1020af75078fSIntel return; 1021af75078fSIntel printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 1022af75078fSIntel "TX Port=%2d/Queue=%2d %s\n", 1023af75078fSIntel fwd_top_stats_border, fs->rx_port, fs->rx_queue, 1024af75078fSIntel fs->tx_port, fs->tx_queue, fwd_top_stats_border); 1025af75078fSIntel printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u", 1026af75078fSIntel fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 1027af75078fSIntel 1028af75078fSIntel /* if checksum mode */ 1029af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) { 1030013af9b6SIntel printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: " 1031013af9b6SIntel "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum); 1032af75078fSIntel } 1033af75078fSIntel 1034af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1035af75078fSIntel pkt_burst_stats_display("RX", &fs->rx_burst_stats); 1036af75078fSIntel pkt_burst_stats_display("TX", &fs->tx_burst_stats); 1037af75078fSIntel #endif 1038af75078fSIntel } 1039af75078fSIntel 1040af75078fSIntel static void 10417741e4cfSIntel flush_fwd_rx_queues(void) 1042af75078fSIntel { 1043af75078fSIntel struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 1044af75078fSIntel portid_t rxp; 10457741e4cfSIntel portid_t port_id; 1046af75078fSIntel queueid_t rxq; 1047af75078fSIntel uint16_t nb_rx; 1048af75078fSIntel uint16_t i; 1049af75078fSIntel uint8_t j; 1050f487715fSReshma Pattan uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 1051594302c7SJames Poole uint64_t timer_period; 1052f487715fSReshma Pattan 1053f487715fSReshma Pattan /* convert to number of cycles */ 1054594302c7SJames Poole timer_period = rte_get_timer_hz(); /* 1 second timeout */ 1055af75078fSIntel 1056af75078fSIntel for (j = 0; j < 2; j++) { 10577741e4cfSIntel for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { 1058af75078fSIntel for (rxq = 0; rxq < nb_rxq; rxq++) { 10597741e4cfSIntel port_id = fwd_ports_ids[rxp]; 1060f487715fSReshma Pattan /** 1061f487715fSReshma Pattan * testpmd can stuck in the below do while loop 1062f487715fSReshma Pattan * if rte_eth_rx_burst() always returns nonzero 1063f487715fSReshma Pattan * packets. So timer is added to exit this loop 1064f487715fSReshma Pattan * after 1sec timer expiry. 1065f487715fSReshma Pattan */ 1066f487715fSReshma Pattan prev_tsc = rte_rdtsc(); 1067af75078fSIntel do { 10687741e4cfSIntel nb_rx = rte_eth_rx_burst(port_id, rxq, 1069013af9b6SIntel pkts_burst, MAX_PKT_BURST); 1070af75078fSIntel for (i = 0; i < nb_rx; i++) 1071af75078fSIntel rte_pktmbuf_free(pkts_burst[i]); 1072f487715fSReshma Pattan 1073f487715fSReshma Pattan cur_tsc = rte_rdtsc(); 1074f487715fSReshma Pattan diff_tsc = cur_tsc - prev_tsc; 1075f487715fSReshma Pattan timer_tsc += diff_tsc; 1076f487715fSReshma Pattan } while ((nb_rx > 0) && 1077f487715fSReshma Pattan (timer_tsc < timer_period)); 1078f487715fSReshma Pattan timer_tsc = 0; 1079af75078fSIntel } 1080af75078fSIntel } 1081af75078fSIntel rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 1082af75078fSIntel } 1083af75078fSIntel } 1084af75078fSIntel 1085af75078fSIntel static void 1086af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 1087af75078fSIntel { 1088af75078fSIntel struct fwd_stream **fsm; 1089af75078fSIntel streamid_t nb_fs; 1090af75078fSIntel streamid_t sm_id; 10917e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE 10927e4441c8SRemy Horton uint64_t tics_per_1sec; 10937e4441c8SRemy Horton uint64_t tics_datum; 10947e4441c8SRemy Horton uint64_t tics_current; 10957e4441c8SRemy Horton uint8_t idx_port, cnt_ports; 1096af75078fSIntel 10977e4441c8SRemy Horton cnt_ports = rte_eth_dev_count(); 10987e4441c8SRemy Horton tics_datum = rte_rdtsc(); 10997e4441c8SRemy Horton tics_per_1sec = rte_get_timer_hz(); 11007e4441c8SRemy Horton #endif 1101af75078fSIntel fsm = &fwd_streams[fc->stream_idx]; 1102af75078fSIntel nb_fs = fc->stream_nb; 1103af75078fSIntel do { 1104af75078fSIntel for (sm_id = 0; sm_id < nb_fs; sm_id++) 1105af75078fSIntel (*pkt_fwd)(fsm[sm_id]); 11067e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE 1107e25e6c70SRemy Horton if (bitrate_enabled != 0 && 1108e25e6c70SRemy Horton bitrate_lcore_id == rte_lcore_id()) { 11097e4441c8SRemy Horton tics_current = rte_rdtsc(); 11107e4441c8SRemy Horton if (tics_current - tics_datum >= tics_per_1sec) { 11117e4441c8SRemy Horton /* Periodic bitrate calculation */ 1112e25e6c70SRemy Horton for (idx_port = 0; 1113e25e6c70SRemy Horton idx_port < cnt_ports; 1114e25e6c70SRemy Horton idx_port++) 1115e25e6c70SRemy Horton rte_stats_bitrate_calc(bitrate_data, 1116e25e6c70SRemy Horton idx_port); 11177e4441c8SRemy Horton tics_datum = tics_current; 11187e4441c8SRemy Horton } 1119e25e6c70SRemy Horton } 11207e4441c8SRemy Horton #endif 112162d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS 112265eb1e54SPablo de Lara if (latencystats_enabled != 0 && 112365eb1e54SPablo de Lara latencystats_lcore_id == rte_lcore_id()) 112462d3216dSReshma Pattan rte_latencystats_update(); 112562d3216dSReshma Pattan #endif 112662d3216dSReshma Pattan 1127af75078fSIntel } while (! fc->stopped); 1128af75078fSIntel } 1129af75078fSIntel 1130af75078fSIntel static int 1131af75078fSIntel start_pkt_forward_on_core(void *fwd_arg) 1132af75078fSIntel { 1133af75078fSIntel run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 1134af75078fSIntel cur_fwd_config.fwd_eng->packet_fwd); 1135af75078fSIntel return 0; 1136af75078fSIntel } 1137af75078fSIntel 1138af75078fSIntel /* 1139af75078fSIntel * Run the TXONLY packet forwarding engine to send a single burst of packets. 1140af75078fSIntel * Used to start communication flows in network loopback test configurations. 1141af75078fSIntel */ 1142af75078fSIntel static int 1143af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg) 1144af75078fSIntel { 1145af75078fSIntel struct fwd_lcore *fwd_lc; 1146af75078fSIntel struct fwd_lcore tmp_lcore; 1147af75078fSIntel 1148af75078fSIntel fwd_lc = (struct fwd_lcore *) fwd_arg; 1149af75078fSIntel tmp_lcore = *fwd_lc; 1150af75078fSIntel tmp_lcore.stopped = 1; 1151af75078fSIntel run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 1152af75078fSIntel return 0; 1153af75078fSIntel } 1154af75078fSIntel 1155af75078fSIntel /* 1156af75078fSIntel * Launch packet forwarding: 1157af75078fSIntel * - Setup per-port forwarding context. 1158af75078fSIntel * - launch logical cores with their forwarding configuration. 1159af75078fSIntel */ 1160af75078fSIntel static void 1161af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 1162af75078fSIntel { 1163af75078fSIntel port_fwd_begin_t port_fwd_begin; 1164af75078fSIntel unsigned int i; 1165af75078fSIntel unsigned int lc_id; 1166af75078fSIntel int diag; 1167af75078fSIntel 1168af75078fSIntel port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 1169af75078fSIntel if (port_fwd_begin != NULL) { 1170af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1171af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 1172af75078fSIntel } 1173af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 1174af75078fSIntel lc_id = fwd_lcores_cpuids[i]; 1175af75078fSIntel if ((interactive == 0) || (lc_id != rte_lcore_id())) { 1176af75078fSIntel fwd_lcores[i]->stopped = 0; 1177af75078fSIntel diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 1178af75078fSIntel fwd_lcores[i], lc_id); 1179af75078fSIntel if (diag != 0) 1180af75078fSIntel printf("launch lcore %u failed - diag=%d\n", 1181af75078fSIntel lc_id, diag); 1182af75078fSIntel } 1183af75078fSIntel } 1184af75078fSIntel } 1185af75078fSIntel 1186af75078fSIntel /* 1187af75078fSIntel * Launch packet forwarding configuration. 1188af75078fSIntel */ 1189af75078fSIntel void 1190af75078fSIntel start_packet_forwarding(int with_tx_first) 1191af75078fSIntel { 1192af75078fSIntel port_fwd_begin_t port_fwd_begin; 1193af75078fSIntel port_fwd_end_t port_fwd_end; 1194af75078fSIntel struct rte_port *port; 1195af75078fSIntel unsigned int i; 1196af75078fSIntel portid_t pt_id; 1197af75078fSIntel streamid_t sm_id; 1198af75078fSIntel 11995a8fb55cSReshma Pattan if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq) 12005a8fb55cSReshma Pattan rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n"); 12015a8fb55cSReshma Pattan 12025a8fb55cSReshma Pattan if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq) 12035a8fb55cSReshma Pattan rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n"); 12045a8fb55cSReshma Pattan 12055a8fb55cSReshma Pattan if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 && 12065a8fb55cSReshma Pattan strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) && 12075a8fb55cSReshma Pattan (!nb_rxq || !nb_txq)) 12085a8fb55cSReshma Pattan rte_exit(EXIT_FAILURE, 12095a8fb55cSReshma Pattan "Either rxq or txq are 0, cannot use %s fwd mode\n", 12105a8fb55cSReshma Pattan cur_fwd_eng->fwd_mode_name); 12115a8fb55cSReshma Pattan 1212ce8d5614SIntel if (all_ports_started() == 0) { 1213ce8d5614SIntel printf("Not all ports were started\n"); 1214ce8d5614SIntel return; 1215ce8d5614SIntel } 1216af75078fSIntel if (test_done == 0) { 1217af75078fSIntel printf("Packet forwarding already started\n"); 1218af75078fSIntel return; 1219af75078fSIntel } 1220edf87b4aSBernard Iremonger 1221edf87b4aSBernard Iremonger if (init_fwd_streams() < 0) { 1222edf87b4aSBernard Iremonger printf("Fail from init_fwd_streams()\n"); 1223edf87b4aSBernard Iremonger return; 1224edf87b4aSBernard Iremonger } 1225edf87b4aSBernard Iremonger 12267741e4cfSIntel if(dcb_test) { 12277741e4cfSIntel for (i = 0; i < nb_fwd_ports; i++) { 12287741e4cfSIntel pt_id = fwd_ports_ids[i]; 12297741e4cfSIntel port = &ports[pt_id]; 12307741e4cfSIntel if (!port->dcb_flag) { 12317741e4cfSIntel printf("In DCB mode, all forwarding ports must " 12327741e4cfSIntel "be configured in this mode.\n"); 1233013af9b6SIntel return; 1234013af9b6SIntel } 12357741e4cfSIntel } 12367741e4cfSIntel if (nb_fwd_lcores == 1) { 12377741e4cfSIntel printf("In DCB mode,the nb forwarding cores " 12387741e4cfSIntel "should be larger than 1.\n"); 12397741e4cfSIntel return; 12407741e4cfSIntel } 12417741e4cfSIntel } 1242af75078fSIntel test_done = 0; 12437741e4cfSIntel 12447741e4cfSIntel if(!no_flush_rx) 12457741e4cfSIntel flush_fwd_rx_queues(); 12467741e4cfSIntel 1247af75078fSIntel fwd_config_setup(); 1248933617d8SZhihong Wang pkt_fwd_config_display(&cur_fwd_config); 1249af75078fSIntel rxtx_config_display(); 1250af75078fSIntel 1251af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1252af75078fSIntel pt_id = fwd_ports_ids[i]; 1253af75078fSIntel port = &ports[pt_id]; 1254af75078fSIntel rte_eth_stats_get(pt_id, &port->stats); 1255af75078fSIntel port->tx_dropped = 0; 1256013af9b6SIntel 1257013af9b6SIntel map_port_queue_stats_mapping_registers(pt_id, port); 1258af75078fSIntel } 1259af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1260af75078fSIntel fwd_streams[sm_id]->rx_packets = 0; 1261af75078fSIntel fwd_streams[sm_id]->tx_packets = 0; 1262af75078fSIntel fwd_streams[sm_id]->fwd_dropped = 0; 1263af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum = 0; 1264af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum = 0; 1265af75078fSIntel 1266af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1267af75078fSIntel memset(&fwd_streams[sm_id]->rx_burst_stats, 0, 1268af75078fSIntel sizeof(fwd_streams[sm_id]->rx_burst_stats)); 1269af75078fSIntel memset(&fwd_streams[sm_id]->tx_burst_stats, 0, 1270af75078fSIntel sizeof(fwd_streams[sm_id]->tx_burst_stats)); 1271af75078fSIntel #endif 1272af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1273af75078fSIntel fwd_streams[sm_id]->core_cycles = 0; 1274af75078fSIntel #endif 1275af75078fSIntel } 1276af75078fSIntel if (with_tx_first) { 1277af75078fSIntel port_fwd_begin = tx_only_engine.port_fwd_begin; 1278af75078fSIntel if (port_fwd_begin != NULL) { 1279af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1280af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 1281af75078fSIntel } 1282acbf77a6SZhihong Wang while (with_tx_first--) { 1283acbf77a6SZhihong Wang launch_packet_forwarding( 1284acbf77a6SZhihong Wang run_one_txonly_burst_on_core); 1285af75078fSIntel rte_eal_mp_wait_lcore(); 1286acbf77a6SZhihong Wang } 1287af75078fSIntel port_fwd_end = tx_only_engine.port_fwd_end; 1288af75078fSIntel if (port_fwd_end != NULL) { 1289af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1290af75078fSIntel (*port_fwd_end)(fwd_ports_ids[i]); 1291af75078fSIntel } 1292af75078fSIntel } 1293af75078fSIntel launch_packet_forwarding(start_pkt_forward_on_core); 1294af75078fSIntel } 1295af75078fSIntel 1296af75078fSIntel void 1297af75078fSIntel stop_packet_forwarding(void) 1298af75078fSIntel { 1299af75078fSIntel struct rte_eth_stats stats; 1300af75078fSIntel struct rte_port *port; 1301af75078fSIntel port_fwd_end_t port_fwd_end; 1302af75078fSIntel int i; 1303af75078fSIntel portid_t pt_id; 1304af75078fSIntel streamid_t sm_id; 1305af75078fSIntel lcoreid_t lc_id; 1306af75078fSIntel uint64_t total_recv; 1307af75078fSIntel uint64_t total_xmit; 1308af75078fSIntel uint64_t total_rx_dropped; 1309af75078fSIntel uint64_t total_tx_dropped; 1310af75078fSIntel uint64_t total_rx_nombuf; 1311af75078fSIntel uint64_t tx_dropped; 1312af75078fSIntel uint64_t rx_bad_ip_csum; 1313af75078fSIntel uint64_t rx_bad_l4_csum; 1314af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1315af75078fSIntel uint64_t fwd_cycles; 1316af75078fSIntel #endif 1317b7091f1dSJiayu Hu 1318af75078fSIntel static const char *acc_stats_border = "+++++++++++++++"; 1319af75078fSIntel 1320af75078fSIntel if (test_done) { 1321af75078fSIntel printf("Packet forwarding not started\n"); 1322af75078fSIntel return; 1323af75078fSIntel } 1324af75078fSIntel printf("Telling cores to stop..."); 1325af75078fSIntel for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 1326af75078fSIntel fwd_lcores[lc_id]->stopped = 1; 1327af75078fSIntel printf("\nWaiting for lcores to finish...\n"); 1328af75078fSIntel rte_eal_mp_wait_lcore(); 1329af75078fSIntel port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 1330af75078fSIntel if (port_fwd_end != NULL) { 1331af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1332af75078fSIntel pt_id = fwd_ports_ids[i]; 1333af75078fSIntel (*port_fwd_end)(pt_id); 1334af75078fSIntel } 1335af75078fSIntel } 1336af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1337af75078fSIntel fwd_cycles = 0; 1338af75078fSIntel #endif 1339af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1340af75078fSIntel if (cur_fwd_config.nb_fwd_streams > 1341af75078fSIntel cur_fwd_config.nb_fwd_ports) { 1342af75078fSIntel fwd_stream_stats_display(sm_id); 1343af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL; 1344af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL; 1345af75078fSIntel } else { 1346af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = 1347af75078fSIntel fwd_streams[sm_id]; 1348af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = 1349af75078fSIntel fwd_streams[sm_id]; 1350af75078fSIntel } 1351af75078fSIntel tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped; 1352af75078fSIntel tx_dropped = (uint64_t) (tx_dropped + 1353af75078fSIntel fwd_streams[sm_id]->fwd_dropped); 1354af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped; 1355af75078fSIntel 1356013af9b6SIntel rx_bad_ip_csum = 1357013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum; 1358af75078fSIntel rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum + 1359af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum); 1360013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = 1361013af9b6SIntel rx_bad_ip_csum; 1362af75078fSIntel 1363013af9b6SIntel rx_bad_l4_csum = 1364013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum; 1365af75078fSIntel rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum + 1366af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum); 1367013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = 1368013af9b6SIntel rx_bad_l4_csum; 1369af75078fSIntel 1370af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1371af75078fSIntel fwd_cycles = (uint64_t) (fwd_cycles + 1372af75078fSIntel fwd_streams[sm_id]->core_cycles); 1373af75078fSIntel #endif 1374af75078fSIntel } 1375af75078fSIntel total_recv = 0; 1376af75078fSIntel total_xmit = 0; 1377af75078fSIntel total_rx_dropped = 0; 1378af75078fSIntel total_tx_dropped = 0; 1379af75078fSIntel total_rx_nombuf = 0; 13807741e4cfSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1381af75078fSIntel pt_id = fwd_ports_ids[i]; 1382af75078fSIntel 1383af75078fSIntel port = &ports[pt_id]; 1384af75078fSIntel rte_eth_stats_get(pt_id, &stats); 1385af75078fSIntel stats.ipackets -= port->stats.ipackets; 1386af75078fSIntel port->stats.ipackets = 0; 1387af75078fSIntel stats.opackets -= port->stats.opackets; 1388af75078fSIntel port->stats.opackets = 0; 1389af75078fSIntel stats.ibytes -= port->stats.ibytes; 1390af75078fSIntel port->stats.ibytes = 0; 1391af75078fSIntel stats.obytes -= port->stats.obytes; 1392af75078fSIntel port->stats.obytes = 0; 139370bdb186SIvan Boule stats.imissed -= port->stats.imissed; 139470bdb186SIvan Boule port->stats.imissed = 0; 1395af75078fSIntel stats.oerrors -= port->stats.oerrors; 1396af75078fSIntel port->stats.oerrors = 0; 1397af75078fSIntel stats.rx_nombuf -= port->stats.rx_nombuf; 1398af75078fSIntel port->stats.rx_nombuf = 0; 1399af75078fSIntel 1400af75078fSIntel total_recv += stats.ipackets; 1401af75078fSIntel total_xmit += stats.opackets; 140270bdb186SIvan Boule total_rx_dropped += stats.imissed; 1403af75078fSIntel total_tx_dropped += port->tx_dropped; 1404af75078fSIntel total_rx_nombuf += stats.rx_nombuf; 1405af75078fSIntel 1406af75078fSIntel fwd_port_stats_display(pt_id, &stats); 1407af75078fSIntel } 1408b7091f1dSJiayu Hu 1409af75078fSIntel printf("\n %s Accumulated forward statistics for all ports" 1410af75078fSIntel "%s\n", 1411af75078fSIntel acc_stats_border, acc_stats_border); 1412af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 1413af75078fSIntel "%-"PRIu64"\n" 1414af75078fSIntel " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 1415af75078fSIntel "%-"PRIu64"\n", 1416af75078fSIntel total_recv, total_rx_dropped, total_recv + total_rx_dropped, 1417af75078fSIntel total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 1418af75078fSIntel if (total_rx_nombuf > 0) 1419af75078fSIntel printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 1420af75078fSIntel printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 1421af75078fSIntel "%s\n", 1422af75078fSIntel acc_stats_border, acc_stats_border); 1423af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1424af75078fSIntel if (total_recv > 0) 1425af75078fSIntel printf("\n CPU cycles/packet=%u (total cycles=" 1426af75078fSIntel "%"PRIu64" / total RX packets=%"PRIu64")\n", 1427af75078fSIntel (unsigned int)(fwd_cycles / total_recv), 1428af75078fSIntel fwd_cycles, total_recv); 1429af75078fSIntel #endif 1430af75078fSIntel printf("\nDone.\n"); 1431af75078fSIntel test_done = 1; 1432af75078fSIntel } 1433af75078fSIntel 1434cfae07fdSOuyang Changchun void 1435cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid) 1436cfae07fdSOuyang Changchun { 1437492ab604SZhiyong Yang if (rte_eth_dev_set_link_up(pid) < 0) 1438cfae07fdSOuyang Changchun printf("\nSet link up fail.\n"); 1439cfae07fdSOuyang Changchun } 1440cfae07fdSOuyang Changchun 1441cfae07fdSOuyang Changchun void 1442cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid) 1443cfae07fdSOuyang Changchun { 1444492ab604SZhiyong Yang if (rte_eth_dev_set_link_down(pid) < 0) 1445cfae07fdSOuyang Changchun printf("\nSet link down fail.\n"); 1446cfae07fdSOuyang Changchun } 1447cfae07fdSOuyang Changchun 1448ce8d5614SIntel static int 1449ce8d5614SIntel all_ports_started(void) 1450ce8d5614SIntel { 1451ce8d5614SIntel portid_t pi; 1452ce8d5614SIntel struct rte_port *port; 1453ce8d5614SIntel 14547d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pi) { 1455ce8d5614SIntel port = &ports[pi]; 1456ce8d5614SIntel /* Check if there is a port which is not started */ 145741b05095SBernard Iremonger if ((port->port_status != RTE_PORT_STARTED) && 145841b05095SBernard Iremonger (port->slave_flag == 0)) 1459ce8d5614SIntel return 0; 1460ce8d5614SIntel } 1461ce8d5614SIntel 1462ce8d5614SIntel /* No port is not started */ 1463ce8d5614SIntel return 1; 1464ce8d5614SIntel } 1465ce8d5614SIntel 1466148f963fSBruce Richardson int 14676018eb8cSShahaf Shuler port_is_stopped(portid_t port_id) 14686018eb8cSShahaf Shuler { 14696018eb8cSShahaf Shuler struct rte_port *port = &ports[port_id]; 14706018eb8cSShahaf Shuler 14716018eb8cSShahaf Shuler if ((port->port_status != RTE_PORT_STOPPED) && 14726018eb8cSShahaf Shuler (port->slave_flag == 0)) 14736018eb8cSShahaf Shuler return 0; 14746018eb8cSShahaf Shuler return 1; 14756018eb8cSShahaf Shuler } 14766018eb8cSShahaf Shuler 14776018eb8cSShahaf Shuler int 1478edab33b1STetsuya Mukawa all_ports_stopped(void) 1479edab33b1STetsuya Mukawa { 1480edab33b1STetsuya Mukawa portid_t pi; 1481edab33b1STetsuya Mukawa 14827d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pi) { 14836018eb8cSShahaf Shuler if (!port_is_stopped(pi)) 1484edab33b1STetsuya Mukawa return 0; 1485edab33b1STetsuya Mukawa } 1486edab33b1STetsuya Mukawa 1487edab33b1STetsuya Mukawa return 1; 1488edab33b1STetsuya Mukawa } 1489edab33b1STetsuya Mukawa 1490edab33b1STetsuya Mukawa int 1491edab33b1STetsuya Mukawa port_is_started(portid_t port_id) 1492edab33b1STetsuya Mukawa { 1493edab33b1STetsuya Mukawa if (port_id_is_invalid(port_id, ENABLED_WARN)) 1494edab33b1STetsuya Mukawa return 0; 1495edab33b1STetsuya Mukawa 1496edab33b1STetsuya Mukawa if (ports[port_id].port_status != RTE_PORT_STARTED) 1497edab33b1STetsuya Mukawa return 0; 1498edab33b1STetsuya Mukawa 1499edab33b1STetsuya Mukawa return 1; 1500edab33b1STetsuya Mukawa } 1501edab33b1STetsuya Mukawa 1502edab33b1STetsuya Mukawa static int 1503edab33b1STetsuya Mukawa port_is_closed(portid_t port_id) 1504edab33b1STetsuya Mukawa { 1505edab33b1STetsuya Mukawa if (port_id_is_invalid(port_id, ENABLED_WARN)) 1506edab33b1STetsuya Mukawa return 0; 1507edab33b1STetsuya Mukawa 1508edab33b1STetsuya Mukawa if (ports[port_id].port_status != RTE_PORT_CLOSED) 1509edab33b1STetsuya Mukawa return 0; 1510edab33b1STetsuya Mukawa 1511edab33b1STetsuya Mukawa return 1; 1512edab33b1STetsuya Mukawa } 1513edab33b1STetsuya Mukawa 1514edab33b1STetsuya Mukawa int 1515ce8d5614SIntel start_port(portid_t pid) 1516ce8d5614SIntel { 151792d2703eSMichael Qiu int diag, need_check_link_status = -1; 1518ce8d5614SIntel portid_t pi; 1519ce8d5614SIntel queueid_t qi; 1520ce8d5614SIntel struct rte_port *port; 15212950a769SDeclan Doherty struct ether_addr mac_addr; 152276ad4a2dSGaetan Rivet enum rte_eth_event_type event_type; 1523ce8d5614SIntel 15244468635fSMichael Qiu if (port_id_is_invalid(pid, ENABLED_WARN)) 15254468635fSMichael Qiu return 0; 15264468635fSMichael Qiu 1527ce8d5614SIntel if(dcb_config) 1528ce8d5614SIntel dcb_test = 1; 15297d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pi) { 1530edab33b1STetsuya Mukawa if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1531ce8d5614SIntel continue; 1532ce8d5614SIntel 153392d2703eSMichael Qiu need_check_link_status = 0; 1534ce8d5614SIntel port = &ports[pi]; 1535ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 1536ce8d5614SIntel RTE_PORT_HANDLING) == 0) { 1537ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1538ce8d5614SIntel continue; 1539ce8d5614SIntel } 1540ce8d5614SIntel 1541ce8d5614SIntel if (port->need_reconfig > 0) { 1542ce8d5614SIntel port->need_reconfig = 0; 1543ce8d5614SIntel 15447ee3e944SVasily Philipov if (flow_isolate_all) { 15457ee3e944SVasily Philipov int ret = port_flow_isolate(pi, 1); 15467ee3e944SVasily Philipov if (ret) { 15477ee3e944SVasily Philipov printf("Failed to apply isolated" 15487ee3e944SVasily Philipov " mode on port %d\n", pi); 15497ee3e944SVasily Philipov return -1; 15507ee3e944SVasily Philipov } 15517ee3e944SVasily Philipov } 15527ee3e944SVasily Philipov 15535706de65SJulien Cretin printf("Configuring Port %d (socket %u)\n", pi, 155420a0286fSLiu Xiaofeng port->socket_id); 1555ce8d5614SIntel /* configure port */ 1556ce8d5614SIntel diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, 1557ce8d5614SIntel &(port->dev_conf)); 1558ce8d5614SIntel if (diag != 0) { 1559ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1560ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1561ce8d5614SIntel printf("Port %d can not be set back " 1562ce8d5614SIntel "to stopped\n", pi); 1563ce8d5614SIntel printf("Fail to configure port %d\n", pi); 1564ce8d5614SIntel /* try to reconfigure port next time */ 1565ce8d5614SIntel port->need_reconfig = 1; 1566148f963fSBruce Richardson return -1; 1567ce8d5614SIntel } 1568ce8d5614SIntel } 1569ce8d5614SIntel if (port->need_reconfig_queues > 0) { 1570ce8d5614SIntel port->need_reconfig_queues = 0; 1571597f9fafSShahaf Shuler port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE; 1572597f9fafSShahaf Shuler /* Apply Tx offloads configuration */ 1573597f9fafSShahaf Shuler port->tx_conf.offloads = port->dev_conf.txmode.offloads; 1574ce8d5614SIntel /* setup tx queues */ 1575ce8d5614SIntel for (qi = 0; qi < nb_txq; qi++) { 1576b6ea6408SIntel if ((numa_support) && 1577b6ea6408SIntel (txring_numa[pi] != NUMA_NO_CONFIG)) 1578b6ea6408SIntel diag = rte_eth_tx_queue_setup(pi, qi, 1579b6ea6408SIntel nb_txd,txring_numa[pi], 1580b6ea6408SIntel &(port->tx_conf)); 1581b6ea6408SIntel else 1582b6ea6408SIntel diag = rte_eth_tx_queue_setup(pi, qi, 1583b6ea6408SIntel nb_txd,port->socket_id, 1584b6ea6408SIntel &(port->tx_conf)); 1585b6ea6408SIntel 1586ce8d5614SIntel if (diag == 0) 1587ce8d5614SIntel continue; 1588ce8d5614SIntel 1589ce8d5614SIntel /* Fail to setup tx queue, return */ 1590ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1591ce8d5614SIntel RTE_PORT_HANDLING, 1592ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1593ce8d5614SIntel printf("Port %d can not be set back " 1594ce8d5614SIntel "to stopped\n", pi); 1595ce8d5614SIntel printf("Fail to configure port %d tx queues\n", pi); 1596ce8d5614SIntel /* try to reconfigure queues next time */ 1597ce8d5614SIntel port->need_reconfig_queues = 1; 1598148f963fSBruce Richardson return -1; 1599ce8d5614SIntel } 16000074d02fSShahaf Shuler /* Apply Rx offloads configuration */ 16010074d02fSShahaf Shuler port->rx_conf.offloads = port->dev_conf.rxmode.offloads; 1602ce8d5614SIntel /* setup rx queues */ 1603ce8d5614SIntel for (qi = 0; qi < nb_rxq; qi++) { 1604b6ea6408SIntel if ((numa_support) && 1605b6ea6408SIntel (rxring_numa[pi] != NUMA_NO_CONFIG)) { 1606b6ea6408SIntel struct rte_mempool * mp = 1607b6ea6408SIntel mbuf_pool_find(rxring_numa[pi]); 1608b6ea6408SIntel if (mp == NULL) { 1609b6ea6408SIntel printf("Failed to setup RX queue:" 1610b6ea6408SIntel "No mempool allocation" 1611b6ea6408SIntel " on the socket %d\n", 1612b6ea6408SIntel rxring_numa[pi]); 1613148f963fSBruce Richardson return -1; 1614b6ea6408SIntel } 1615b6ea6408SIntel 1616b6ea6408SIntel diag = rte_eth_rx_queue_setup(pi, qi, 1617b6ea6408SIntel nb_rxd,rxring_numa[pi], 1618b6ea6408SIntel &(port->rx_conf),mp); 16191e1d6bddSBernard Iremonger } else { 16201e1d6bddSBernard Iremonger struct rte_mempool *mp = 16211e1d6bddSBernard Iremonger mbuf_pool_find(port->socket_id); 16221e1d6bddSBernard Iremonger if (mp == NULL) { 16231e1d6bddSBernard Iremonger printf("Failed to setup RX queue:" 16241e1d6bddSBernard Iremonger "No mempool allocation" 16251e1d6bddSBernard Iremonger " on the socket %d\n", 16261e1d6bddSBernard Iremonger port->socket_id); 16271e1d6bddSBernard Iremonger return -1; 1628b6ea6408SIntel } 1629b6ea6408SIntel diag = rte_eth_rx_queue_setup(pi, qi, 1630b6ea6408SIntel nb_rxd,port->socket_id, 16311e1d6bddSBernard Iremonger &(port->rx_conf), mp); 16321e1d6bddSBernard Iremonger } 1633ce8d5614SIntel if (diag == 0) 1634ce8d5614SIntel continue; 1635ce8d5614SIntel 1636ce8d5614SIntel /* Fail to setup rx queue, return */ 1637ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1638ce8d5614SIntel RTE_PORT_HANDLING, 1639ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1640ce8d5614SIntel printf("Port %d can not be set back " 1641ce8d5614SIntel "to stopped\n", pi); 1642ce8d5614SIntel printf("Fail to configure port %d rx queues\n", pi); 1643ce8d5614SIntel /* try to reconfigure queues next time */ 1644ce8d5614SIntel port->need_reconfig_queues = 1; 1645148f963fSBruce Richardson return -1; 1646ce8d5614SIntel } 1647ce8d5614SIntel } 164876ad4a2dSGaetan Rivet 1649ce8d5614SIntel /* start port */ 1650ce8d5614SIntel if (rte_eth_dev_start(pi) < 0) { 1651ce8d5614SIntel printf("Fail to start port %d\n", pi); 1652ce8d5614SIntel 1653ce8d5614SIntel /* Fail to setup rx queue, return */ 1654ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1655ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1656ce8d5614SIntel printf("Port %d can not be set back to " 1657ce8d5614SIntel "stopped\n", pi); 1658ce8d5614SIntel continue; 1659ce8d5614SIntel } 1660ce8d5614SIntel 1661ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1662ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 1663ce8d5614SIntel printf("Port %d can not be set into started\n", pi); 1664ce8d5614SIntel 16652950a769SDeclan Doherty rte_eth_macaddr_get(pi, &mac_addr); 1666d8c89163SZijie Pan printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, 16672950a769SDeclan Doherty mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 16682950a769SDeclan Doherty mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 16692950a769SDeclan Doherty mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); 1670d8c89163SZijie Pan 1671ce8d5614SIntel /* at least one port started, need checking link status */ 1672ce8d5614SIntel need_check_link_status = 1; 1673ce8d5614SIntel } 1674ce8d5614SIntel 16754fb82244SMatan Azrad for (event_type = RTE_ETH_EVENT_UNKNOWN; 16764fb82244SMatan Azrad event_type < RTE_ETH_EVENT_MAX; 16774fb82244SMatan Azrad event_type++) { 16784fb82244SMatan Azrad diag = rte_eth_dev_callback_register(RTE_ETH_ALL, 16794fb82244SMatan Azrad event_type, 16804fb82244SMatan Azrad eth_event_callback, 16814fb82244SMatan Azrad NULL); 16824fb82244SMatan Azrad if (diag) { 16834fb82244SMatan Azrad printf("Failed to setup even callback for event %d\n", 16844fb82244SMatan Azrad event_type); 16854fb82244SMatan Azrad return -1; 16864fb82244SMatan Azrad } 16874fb82244SMatan Azrad } 16884fb82244SMatan Azrad 168992d2703eSMichael Qiu if (need_check_link_status == 1 && !no_link_check) 1690edab33b1STetsuya Mukawa check_all_ports_link_status(RTE_PORT_ALL); 169192d2703eSMichael Qiu else if (need_check_link_status == 0) 1692ce8d5614SIntel printf("Please stop the ports first\n"); 1693ce8d5614SIntel 1694ce8d5614SIntel printf("Done\n"); 1695148f963fSBruce Richardson return 0; 1696ce8d5614SIntel } 1697ce8d5614SIntel 1698ce8d5614SIntel void 1699ce8d5614SIntel stop_port(portid_t pid) 1700ce8d5614SIntel { 1701ce8d5614SIntel portid_t pi; 1702ce8d5614SIntel struct rte_port *port; 1703ce8d5614SIntel int need_check_link_status = 0; 1704ce8d5614SIntel 1705ce8d5614SIntel if (dcb_test) { 1706ce8d5614SIntel dcb_test = 0; 1707ce8d5614SIntel dcb_config = 0; 1708ce8d5614SIntel } 17094468635fSMichael Qiu 17104468635fSMichael Qiu if (port_id_is_invalid(pid, ENABLED_WARN)) 17114468635fSMichael Qiu return; 17124468635fSMichael Qiu 1713ce8d5614SIntel printf("Stopping ports...\n"); 1714ce8d5614SIntel 17157d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pi) { 17164468635fSMichael Qiu if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1717ce8d5614SIntel continue; 1718ce8d5614SIntel 1719a8ef3e3aSBernard Iremonger if (port_is_forwarding(pi) != 0 && test_done == 0) { 1720a8ef3e3aSBernard Iremonger printf("Please remove port %d from forwarding configuration.\n", pi); 1721a8ef3e3aSBernard Iremonger continue; 1722a8ef3e3aSBernard Iremonger } 1723a8ef3e3aSBernard Iremonger 17240e545d30SBernard Iremonger if (port_is_bonding_slave(pi)) { 17250e545d30SBernard Iremonger printf("Please remove port %d from bonded device.\n", pi); 17260e545d30SBernard Iremonger continue; 17270e545d30SBernard Iremonger } 17280e545d30SBernard Iremonger 1729ce8d5614SIntel port = &ports[pi]; 1730ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 1731ce8d5614SIntel RTE_PORT_HANDLING) == 0) 1732ce8d5614SIntel continue; 1733ce8d5614SIntel 1734ce8d5614SIntel rte_eth_dev_stop(pi); 1735ce8d5614SIntel 1736ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1737ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1738ce8d5614SIntel printf("Port %d can not be set into stopped\n", pi); 1739ce8d5614SIntel need_check_link_status = 1; 1740ce8d5614SIntel } 1741bc202406SDavid Marchand if (need_check_link_status && !no_link_check) 1742edab33b1STetsuya Mukawa check_all_ports_link_status(RTE_PORT_ALL); 1743ce8d5614SIntel 1744ce8d5614SIntel printf("Done\n"); 1745ce8d5614SIntel } 1746ce8d5614SIntel 1747ce8d5614SIntel void 1748ce8d5614SIntel close_port(portid_t pid) 1749ce8d5614SIntel { 1750ce8d5614SIntel portid_t pi; 1751ce8d5614SIntel struct rte_port *port; 1752ce8d5614SIntel 17534468635fSMichael Qiu if (port_id_is_invalid(pid, ENABLED_WARN)) 17544468635fSMichael Qiu return; 17554468635fSMichael Qiu 1756ce8d5614SIntel printf("Closing ports...\n"); 1757ce8d5614SIntel 17587d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pi) { 17594468635fSMichael Qiu if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1760ce8d5614SIntel continue; 1761ce8d5614SIntel 1762a8ef3e3aSBernard Iremonger if (port_is_forwarding(pi) != 0 && test_done == 0) { 1763a8ef3e3aSBernard Iremonger printf("Please remove port %d from forwarding configuration.\n", pi); 1764a8ef3e3aSBernard Iremonger continue; 1765a8ef3e3aSBernard Iremonger } 1766a8ef3e3aSBernard Iremonger 17670e545d30SBernard Iremonger if (port_is_bonding_slave(pi)) { 17680e545d30SBernard Iremonger printf("Please remove port %d from bonded device.\n", pi); 17690e545d30SBernard Iremonger continue; 17700e545d30SBernard Iremonger } 17710e545d30SBernard Iremonger 1772ce8d5614SIntel port = &ports[pi]; 1773ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1774d4e8ad64SMichael Qiu RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { 1775d4e8ad64SMichael Qiu printf("Port %d is already closed\n", pi); 1776d4e8ad64SMichael Qiu continue; 1777d4e8ad64SMichael Qiu } 1778d4e8ad64SMichael Qiu 1779d4e8ad64SMichael Qiu if (rte_atomic16_cmpset(&(port->port_status), 1780ce8d5614SIntel RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 1781ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1782ce8d5614SIntel continue; 1783ce8d5614SIntel } 1784ce8d5614SIntel 1785938a184aSAdrien Mazarguil if (port->flow_list) 1786938a184aSAdrien Mazarguil port_flow_flush(pi); 1787ce8d5614SIntel rte_eth_dev_close(pi); 1788ce8d5614SIntel 1789ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1790ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 1791b38bb262SPablo de Lara printf("Port %d cannot be set to closed\n", pi); 1792ce8d5614SIntel } 1793ce8d5614SIntel 1794ce8d5614SIntel printf("Done\n"); 1795ce8d5614SIntel } 1796ce8d5614SIntel 1797edab33b1STetsuya Mukawa void 179897f1e196SWei Dai reset_port(portid_t pid) 179997f1e196SWei Dai { 180097f1e196SWei Dai int diag; 180197f1e196SWei Dai portid_t pi; 180297f1e196SWei Dai struct rte_port *port; 180397f1e196SWei Dai 180497f1e196SWei Dai if (port_id_is_invalid(pid, ENABLED_WARN)) 180597f1e196SWei Dai return; 180697f1e196SWei Dai 180797f1e196SWei Dai printf("Resetting ports...\n"); 180897f1e196SWei Dai 180997f1e196SWei Dai RTE_ETH_FOREACH_DEV(pi) { 181097f1e196SWei Dai if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 181197f1e196SWei Dai continue; 181297f1e196SWei Dai 181397f1e196SWei Dai if (port_is_forwarding(pi) != 0 && test_done == 0) { 181497f1e196SWei Dai printf("Please remove port %d from forwarding " 181597f1e196SWei Dai "configuration.\n", pi); 181697f1e196SWei Dai continue; 181797f1e196SWei Dai } 181897f1e196SWei Dai 181997f1e196SWei Dai if (port_is_bonding_slave(pi)) { 182097f1e196SWei Dai printf("Please remove port %d from bonded device.\n", 182197f1e196SWei Dai pi); 182297f1e196SWei Dai continue; 182397f1e196SWei Dai } 182497f1e196SWei Dai 182597f1e196SWei Dai diag = rte_eth_dev_reset(pi); 182697f1e196SWei Dai if (diag == 0) { 182797f1e196SWei Dai port = &ports[pi]; 182897f1e196SWei Dai port->need_reconfig = 1; 182997f1e196SWei Dai port->need_reconfig_queues = 1; 183097f1e196SWei Dai } else { 183197f1e196SWei Dai printf("Failed to reset port %d. diag=%d\n", pi, diag); 183297f1e196SWei Dai } 183397f1e196SWei Dai } 183497f1e196SWei Dai 183597f1e196SWei Dai printf("Done\n"); 183697f1e196SWei Dai } 183797f1e196SWei Dai 183897f1e196SWei Dai void 1839edab33b1STetsuya Mukawa attach_port(char *identifier) 1840ce8d5614SIntel { 1841ebf5e9b7SBernard Iremonger portid_t pi = 0; 1842931126baSBernard Iremonger unsigned int socket_id; 1843ce8d5614SIntel 1844edab33b1STetsuya Mukawa printf("Attaching a new port...\n"); 1845edab33b1STetsuya Mukawa 1846edab33b1STetsuya Mukawa if (identifier == NULL) { 1847edab33b1STetsuya Mukawa printf("Invalid parameters are specified\n"); 1848edab33b1STetsuya Mukawa return; 1849ce8d5614SIntel } 1850ce8d5614SIntel 1851edab33b1STetsuya Mukawa if (rte_eth_dev_attach(identifier, &pi)) 1852edab33b1STetsuya Mukawa return; 1853edab33b1STetsuya Mukawa 1854931126baSBernard Iremonger socket_id = (unsigned)rte_eth_dev_socket_id(pi); 1855931126baSBernard Iremonger /* if socket_id is invalid, set to 0 */ 1856931126baSBernard Iremonger if (check_socket_id(socket_id) < 0) 1857931126baSBernard Iremonger socket_id = 0; 1858931126baSBernard Iremonger reconfig(pi, socket_id); 1859edab33b1STetsuya Mukawa rte_eth_promiscuous_enable(pi); 1860edab33b1STetsuya Mukawa 1861edab33b1STetsuya Mukawa nb_ports = rte_eth_dev_count(); 1862edab33b1STetsuya Mukawa 1863edab33b1STetsuya Mukawa ports[pi].port_status = RTE_PORT_STOPPED; 1864edab33b1STetsuya Mukawa 1865edab33b1STetsuya Mukawa printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); 1866edab33b1STetsuya Mukawa printf("Done\n"); 1867edab33b1STetsuya Mukawa } 1868edab33b1STetsuya Mukawa 1869edab33b1STetsuya Mukawa void 187028caa76aSZhiyong Yang detach_port(portid_t port_id) 18715f4ec54fSChen Jing D(Mark) { 1872edab33b1STetsuya Mukawa char name[RTE_ETH_NAME_MAX_LEN]; 18735f4ec54fSChen Jing D(Mark) 1874edab33b1STetsuya Mukawa printf("Detaching a port...\n"); 18755f4ec54fSChen Jing D(Mark) 1876edab33b1STetsuya Mukawa if (!port_is_closed(port_id)) { 1877edab33b1STetsuya Mukawa printf("Please close port first\n"); 1878edab33b1STetsuya Mukawa return; 1879edab33b1STetsuya Mukawa } 1880edab33b1STetsuya Mukawa 1881938a184aSAdrien Mazarguil if (ports[port_id].flow_list) 1882938a184aSAdrien Mazarguil port_flow_flush(port_id); 1883938a184aSAdrien Mazarguil 18843070419eSGaetan Rivet if (rte_eth_dev_detach(port_id, name)) { 1885285fd101SOlivier Matz TESTPMD_LOG(ERR, "Failed to detach port '%s'\n", name); 1886edab33b1STetsuya Mukawa return; 18873070419eSGaetan Rivet } 1888edab33b1STetsuya Mukawa 1889edab33b1STetsuya Mukawa nb_ports = rte_eth_dev_count(); 1890edab33b1STetsuya Mukawa 1891edab33b1STetsuya Mukawa printf("Port '%s' is detached. Now total ports is %d\n", 1892edab33b1STetsuya Mukawa name, nb_ports); 1893edab33b1STetsuya Mukawa printf("Done\n"); 1894edab33b1STetsuya Mukawa return; 18955f4ec54fSChen Jing D(Mark) } 18965f4ec54fSChen Jing D(Mark) 1897af75078fSIntel void 1898af75078fSIntel pmd_test_exit(void) 1899af75078fSIntel { 1900af75078fSIntel portid_t pt_id; 1901af75078fSIntel 19028210ec25SPablo de Lara if (test_done == 0) 19038210ec25SPablo de Lara stop_packet_forwarding(); 19048210ec25SPablo de Lara 1905d3a274ceSZhihong Wang if (ports != NULL) { 1906d3a274ceSZhihong Wang no_link_check = 1; 19077d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pt_id) { 1908d3a274ceSZhihong Wang printf("\nShutting down port %d...\n", pt_id); 1909af75078fSIntel fflush(stdout); 1910d3a274ceSZhihong Wang stop_port(pt_id); 1911d3a274ceSZhihong Wang close_port(pt_id); 1912af75078fSIntel } 1913d3a274ceSZhihong Wang } 1914d3a274ceSZhihong Wang printf("\nBye...\n"); 1915af75078fSIntel } 1916af75078fSIntel 1917af75078fSIntel typedef void (*cmd_func_t)(void); 1918af75078fSIntel struct pmd_test_command { 1919af75078fSIntel const char *cmd_name; 1920af75078fSIntel cmd_func_t cmd_func; 1921af75078fSIntel }; 1922af75078fSIntel 1923af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) 1924af75078fSIntel 1925ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */ 1926af75078fSIntel static void 1927edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask) 1928af75078fSIntel { 1929ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */ 1930ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1931f8244c63SZhiyong Yang portid_t portid; 1932f8244c63SZhiyong Yang uint8_t count, all_ports_up, print_flag = 0; 1933ce8d5614SIntel struct rte_eth_link link; 1934ce8d5614SIntel 1935ce8d5614SIntel printf("Checking link statuses...\n"); 1936ce8d5614SIntel fflush(stdout); 1937ce8d5614SIntel for (count = 0; count <= MAX_CHECK_TIME; count++) { 1938ce8d5614SIntel all_ports_up = 1; 19397d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(portid) { 1940ce8d5614SIntel if ((port_mask & (1 << portid)) == 0) 1941ce8d5614SIntel continue; 1942ce8d5614SIntel memset(&link, 0, sizeof(link)); 1943ce8d5614SIntel rte_eth_link_get_nowait(portid, &link); 1944ce8d5614SIntel /* print link status if flag set */ 1945ce8d5614SIntel if (print_flag == 1) { 1946ce8d5614SIntel if (link.link_status) 1947f8244c63SZhiyong Yang printf( 1948f8244c63SZhiyong Yang "Port%d Link Up. speed %u Mbps- %s\n", 1949f8244c63SZhiyong Yang portid, link.link_speed, 1950ce8d5614SIntel (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1951ce8d5614SIntel ("full-duplex") : ("half-duplex\n")); 1952ce8d5614SIntel else 1953f8244c63SZhiyong Yang printf("Port %d Link Down\n", portid); 1954ce8d5614SIntel continue; 1955ce8d5614SIntel } 1956ce8d5614SIntel /* clear all_ports_up flag if any link down */ 195709419f23SThomas Monjalon if (link.link_status == ETH_LINK_DOWN) { 1958ce8d5614SIntel all_ports_up = 0; 1959ce8d5614SIntel break; 1960ce8d5614SIntel } 1961ce8d5614SIntel } 1962ce8d5614SIntel /* after finally printing all link status, get out */ 1963ce8d5614SIntel if (print_flag == 1) 1964ce8d5614SIntel break; 1965ce8d5614SIntel 1966ce8d5614SIntel if (all_ports_up == 0) { 1967ce8d5614SIntel fflush(stdout); 1968ce8d5614SIntel rte_delay_ms(CHECK_INTERVAL); 1969ce8d5614SIntel } 1970ce8d5614SIntel 1971ce8d5614SIntel /* set the print_flag if all ports up or timeout */ 1972ce8d5614SIntel if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1973ce8d5614SIntel print_flag = 1; 1974ce8d5614SIntel } 19758ea656f8SGaetan Rivet 19768ea656f8SGaetan Rivet if (lsc_interrupt) 19778ea656f8SGaetan Rivet break; 1978ce8d5614SIntel } 1979af75078fSIntel } 1980af75078fSIntel 1981284c908cSGaetan Rivet static void 1982284c908cSGaetan Rivet rmv_event_callback(void *arg) 1983284c908cSGaetan Rivet { 1984284c908cSGaetan Rivet struct rte_eth_dev *dev; 198528caa76aSZhiyong Yang portid_t port_id = (intptr_t)arg; 1986284c908cSGaetan Rivet 1987284c908cSGaetan Rivet RTE_ETH_VALID_PORTID_OR_RET(port_id); 1988284c908cSGaetan Rivet dev = &rte_eth_devices[port_id]; 1989284c908cSGaetan Rivet 1990284c908cSGaetan Rivet stop_port(port_id); 1991284c908cSGaetan Rivet close_port(port_id); 1992f3a1188cSGaetan Rivet printf("removing device %s\n", dev->device->name); 19933070419eSGaetan Rivet if (rte_eal_dev_detach(dev->device)) 1994285fd101SOlivier Matz TESTPMD_LOG(ERR, "Failed to detach device %s\n", 19953070419eSGaetan Rivet dev->device->name); 1996284c908cSGaetan Rivet } 1997284c908cSGaetan Rivet 199876ad4a2dSGaetan Rivet /* This function is used by the interrupt thread */ 1999d6af1a13SBernard Iremonger static int 2000f8244c63SZhiyong Yang eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param, 2001d6af1a13SBernard Iremonger void *ret_param) 200276ad4a2dSGaetan Rivet { 200376ad4a2dSGaetan Rivet static const char * const event_desc[] = { 200476ad4a2dSGaetan Rivet [RTE_ETH_EVENT_UNKNOWN] = "Unknown", 200576ad4a2dSGaetan Rivet [RTE_ETH_EVENT_INTR_LSC] = "LSC", 200676ad4a2dSGaetan Rivet [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state", 200776ad4a2dSGaetan Rivet [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset", 200876ad4a2dSGaetan Rivet [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox", 200976ad4a2dSGaetan Rivet [RTE_ETH_EVENT_MACSEC] = "MACsec", 201076ad4a2dSGaetan Rivet [RTE_ETH_EVENT_INTR_RMV] = "device removal", 20114fb82244SMatan Azrad [RTE_ETH_EVENT_NEW] = "device probed", 20124fb82244SMatan Azrad [RTE_ETH_EVENT_DESTROY] = "device released", 201376ad4a2dSGaetan Rivet [RTE_ETH_EVENT_MAX] = NULL, 201476ad4a2dSGaetan Rivet }; 201576ad4a2dSGaetan Rivet 201676ad4a2dSGaetan Rivet RTE_SET_USED(param); 2017d6af1a13SBernard Iremonger RTE_SET_USED(ret_param); 201876ad4a2dSGaetan Rivet 201976ad4a2dSGaetan Rivet if (type >= RTE_ETH_EVENT_MAX) { 202076ad4a2dSGaetan Rivet fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n", 202176ad4a2dSGaetan Rivet port_id, __func__, type); 202276ad4a2dSGaetan Rivet fflush(stderr); 20233af72783SGaetan Rivet } else if (event_print_mask & (UINT32_C(1) << type)) { 202476ad4a2dSGaetan Rivet printf("\nPort %" PRIu8 ": %s event\n", port_id, 202576ad4a2dSGaetan Rivet event_desc[type]); 202676ad4a2dSGaetan Rivet fflush(stdout); 202776ad4a2dSGaetan Rivet } 2028284c908cSGaetan Rivet 2029284c908cSGaetan Rivet switch (type) { 2030284c908cSGaetan Rivet case RTE_ETH_EVENT_INTR_RMV: 2031284c908cSGaetan Rivet if (rte_eal_alarm_set(100000, 2032284c908cSGaetan Rivet rmv_event_callback, (void *)(intptr_t)port_id)) 2033284c908cSGaetan Rivet fprintf(stderr, "Could not set up deferred device removal\n"); 2034284c908cSGaetan Rivet break; 2035284c908cSGaetan Rivet default: 2036284c908cSGaetan Rivet break; 2037284c908cSGaetan Rivet } 2038d6af1a13SBernard Iremonger return 0; 203976ad4a2dSGaetan Rivet } 204076ad4a2dSGaetan Rivet 2041013af9b6SIntel static int 204228caa76aSZhiyong Yang set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) 2043af75078fSIntel { 2044013af9b6SIntel uint16_t i; 2045af75078fSIntel int diag; 2046013af9b6SIntel uint8_t mapping_found = 0; 2047af75078fSIntel 2048013af9b6SIntel for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 2049013af9b6SIntel if ((tx_queue_stats_mappings[i].port_id == port_id) && 2050013af9b6SIntel (tx_queue_stats_mappings[i].queue_id < nb_txq )) { 2051013af9b6SIntel diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, 2052013af9b6SIntel tx_queue_stats_mappings[i].queue_id, 2053013af9b6SIntel tx_queue_stats_mappings[i].stats_counter_id); 2054013af9b6SIntel if (diag != 0) 2055013af9b6SIntel return diag; 2056013af9b6SIntel mapping_found = 1; 2057af75078fSIntel } 2058013af9b6SIntel } 2059013af9b6SIntel if (mapping_found) 2060013af9b6SIntel port->tx_queue_stats_mapping_enabled = 1; 2061013af9b6SIntel return 0; 2062013af9b6SIntel } 2063013af9b6SIntel 2064013af9b6SIntel static int 206528caa76aSZhiyong Yang set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) 2066013af9b6SIntel { 2067013af9b6SIntel uint16_t i; 2068013af9b6SIntel int diag; 2069013af9b6SIntel uint8_t mapping_found = 0; 2070013af9b6SIntel 2071013af9b6SIntel for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 2072013af9b6SIntel if ((rx_queue_stats_mappings[i].port_id == port_id) && 2073013af9b6SIntel (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { 2074013af9b6SIntel diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, 2075013af9b6SIntel rx_queue_stats_mappings[i].queue_id, 2076013af9b6SIntel rx_queue_stats_mappings[i].stats_counter_id); 2077013af9b6SIntel if (diag != 0) 2078013af9b6SIntel return diag; 2079013af9b6SIntel mapping_found = 1; 2080013af9b6SIntel } 2081013af9b6SIntel } 2082013af9b6SIntel if (mapping_found) 2083013af9b6SIntel port->rx_queue_stats_mapping_enabled = 1; 2084013af9b6SIntel return 0; 2085013af9b6SIntel } 2086013af9b6SIntel 2087013af9b6SIntel static void 208828caa76aSZhiyong Yang map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port) 2089013af9b6SIntel { 2090013af9b6SIntel int diag = 0; 2091013af9b6SIntel 2092013af9b6SIntel diag = set_tx_queue_stats_mapping_registers(pi, port); 2093af75078fSIntel if (diag != 0) { 2094013af9b6SIntel if (diag == -ENOTSUP) { 2095013af9b6SIntel port->tx_queue_stats_mapping_enabled = 0; 2096013af9b6SIntel printf("TX queue stats mapping not supported port id=%d\n", pi); 2097013af9b6SIntel } 2098013af9b6SIntel else 2099013af9b6SIntel rte_exit(EXIT_FAILURE, 2100013af9b6SIntel "set_tx_queue_stats_mapping_registers " 2101013af9b6SIntel "failed for port id=%d diag=%d\n", 2102af75078fSIntel pi, diag); 2103af75078fSIntel } 2104013af9b6SIntel 2105013af9b6SIntel diag = set_rx_queue_stats_mapping_registers(pi, port); 2106af75078fSIntel if (diag != 0) { 2107013af9b6SIntel if (diag == -ENOTSUP) { 2108013af9b6SIntel port->rx_queue_stats_mapping_enabled = 0; 2109013af9b6SIntel printf("RX queue stats mapping not supported port id=%d\n", pi); 2110013af9b6SIntel } 2111013af9b6SIntel else 2112013af9b6SIntel rte_exit(EXIT_FAILURE, 2113013af9b6SIntel "set_rx_queue_stats_mapping_registers " 2114013af9b6SIntel "failed for port id=%d diag=%d\n", 2115af75078fSIntel pi, diag); 2116af75078fSIntel } 2117af75078fSIntel } 2118af75078fSIntel 2119f2c5125aSPablo de Lara static void 2120f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port) 2121f2c5125aSPablo de Lara { 2122f2c5125aSPablo de Lara port->rx_conf = port->dev_info.default_rxconf; 2123f2c5125aSPablo de Lara port->tx_conf = port->dev_info.default_txconf; 2124f2c5125aSPablo de Lara 2125f2c5125aSPablo de Lara /* Check if any RX/TX parameters have been passed */ 2126f2c5125aSPablo de Lara if (rx_pthresh != RTE_PMD_PARAM_UNSET) 2127f2c5125aSPablo de Lara port->rx_conf.rx_thresh.pthresh = rx_pthresh; 2128f2c5125aSPablo de Lara 2129f2c5125aSPablo de Lara if (rx_hthresh != RTE_PMD_PARAM_UNSET) 2130f2c5125aSPablo de Lara port->rx_conf.rx_thresh.hthresh = rx_hthresh; 2131f2c5125aSPablo de Lara 2132f2c5125aSPablo de Lara if (rx_wthresh != RTE_PMD_PARAM_UNSET) 2133f2c5125aSPablo de Lara port->rx_conf.rx_thresh.wthresh = rx_wthresh; 2134f2c5125aSPablo de Lara 2135f2c5125aSPablo de Lara if (rx_free_thresh != RTE_PMD_PARAM_UNSET) 2136f2c5125aSPablo de Lara port->rx_conf.rx_free_thresh = rx_free_thresh; 2137f2c5125aSPablo de Lara 2138f2c5125aSPablo de Lara if (rx_drop_en != RTE_PMD_PARAM_UNSET) 2139f2c5125aSPablo de Lara port->rx_conf.rx_drop_en = rx_drop_en; 2140f2c5125aSPablo de Lara 2141f2c5125aSPablo de Lara if (tx_pthresh != RTE_PMD_PARAM_UNSET) 2142f2c5125aSPablo de Lara port->tx_conf.tx_thresh.pthresh = tx_pthresh; 2143f2c5125aSPablo de Lara 2144f2c5125aSPablo de Lara if (tx_hthresh != RTE_PMD_PARAM_UNSET) 2145f2c5125aSPablo de Lara port->tx_conf.tx_thresh.hthresh = tx_hthresh; 2146f2c5125aSPablo de Lara 2147f2c5125aSPablo de Lara if (tx_wthresh != RTE_PMD_PARAM_UNSET) 2148f2c5125aSPablo de Lara port->tx_conf.tx_thresh.wthresh = tx_wthresh; 2149f2c5125aSPablo de Lara 2150f2c5125aSPablo de Lara if (tx_rs_thresh != RTE_PMD_PARAM_UNSET) 2151f2c5125aSPablo de Lara port->tx_conf.tx_rs_thresh = tx_rs_thresh; 2152f2c5125aSPablo de Lara 2153f2c5125aSPablo de Lara if (tx_free_thresh != RTE_PMD_PARAM_UNSET) 2154f2c5125aSPablo de Lara port->tx_conf.tx_free_thresh = tx_free_thresh; 2155f2c5125aSPablo de Lara } 2156f2c5125aSPablo de Lara 2157013af9b6SIntel void 2158013af9b6SIntel init_port_config(void) 2159013af9b6SIntel { 2160013af9b6SIntel portid_t pid; 2161013af9b6SIntel struct rte_port *port; 2162013af9b6SIntel 21637d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(pid) { 2164013af9b6SIntel port = &ports[pid]; 2165013af9b6SIntel port->dev_conf.fdir_conf = fdir_conf; 21663ce690d3SBruce Richardson if (nb_rxq > 1) { 2167013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 2168013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf; 2169af75078fSIntel } else { 2170013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 2171013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; 2172af75078fSIntel } 21733ce690d3SBruce Richardson 21745f592039SJingjing Wu if (port->dcb_flag == 0) { 21753ce690d3SBruce Richardson if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 21763ce690d3SBruce Richardson port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 21773ce690d3SBruce Richardson else 21783ce690d3SBruce Richardson port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; 21793ce690d3SBruce Richardson } 21803ce690d3SBruce Richardson 2181f2c5125aSPablo de Lara rxtx_port_config(port); 2182013af9b6SIntel 2183013af9b6SIntel rte_eth_macaddr_get(pid, &port->eth_addr); 2184013af9b6SIntel 2185013af9b6SIntel map_port_queue_stats_mapping_registers(pid, port); 218650c4440eSThomas Monjalon #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS 2187e261265eSRadu Nicolau rte_pmd_ixgbe_bypass_init(pid); 21887b7e5ba7SIntel #endif 21898ea656f8SGaetan Rivet 21908ea656f8SGaetan Rivet if (lsc_interrupt && 21918ea656f8SGaetan Rivet (rte_eth_devices[pid].data->dev_flags & 21928ea656f8SGaetan Rivet RTE_ETH_DEV_INTR_LSC)) 21938ea656f8SGaetan Rivet port->dev_conf.intr_conf.lsc = 1; 2194284c908cSGaetan Rivet if (rmv_interrupt && 2195284c908cSGaetan Rivet (rte_eth_devices[pid].data->dev_flags & 2196284c908cSGaetan Rivet RTE_ETH_DEV_INTR_RMV)) 2197284c908cSGaetan Rivet port->dev_conf.intr_conf.rmv = 1; 21985b590fbeSJasvinder Singh 21995b590fbeSJasvinder Singh #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED 22005b590fbeSJasvinder Singh /* Detect softnic port */ 22015b590fbeSJasvinder Singh if (!strcmp(port->dev_info.driver_name, "net_softnic")) { 22025b590fbeSJasvinder Singh port->softnic_enable = 1; 22035b590fbeSJasvinder Singh memset(&port->softport, 0, sizeof(struct softnic_port)); 22045b590fbeSJasvinder Singh 22055b590fbeSJasvinder Singh if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm")) 22065b590fbeSJasvinder Singh port->softport.tm_flag = 1; 22075b590fbeSJasvinder Singh } 22085b590fbeSJasvinder Singh #endif 2209013af9b6SIntel } 2210013af9b6SIntel } 2211013af9b6SIntel 221241b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid) 221341b05095SBernard Iremonger { 221441b05095SBernard Iremonger struct rte_port *port; 221541b05095SBernard Iremonger 221641b05095SBernard Iremonger port = &ports[slave_pid]; 221741b05095SBernard Iremonger port->slave_flag = 1; 221841b05095SBernard Iremonger } 221941b05095SBernard Iremonger 222041b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid) 222141b05095SBernard Iremonger { 222241b05095SBernard Iremonger struct rte_port *port; 222341b05095SBernard Iremonger 222441b05095SBernard Iremonger port = &ports[slave_pid]; 222541b05095SBernard Iremonger port->slave_flag = 0; 222641b05095SBernard Iremonger } 222741b05095SBernard Iremonger 22280e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid) 22290e545d30SBernard Iremonger { 22300e545d30SBernard Iremonger struct rte_port *port; 22310e545d30SBernard Iremonger 22320e545d30SBernard Iremonger port = &ports[slave_pid]; 22330e545d30SBernard Iremonger return port->slave_flag; 22340e545d30SBernard Iremonger } 22350e545d30SBernard Iremonger 2236013af9b6SIntel const uint16_t vlan_tags[] = { 2237013af9b6SIntel 0, 1, 2, 3, 4, 5, 6, 7, 2238013af9b6SIntel 8, 9, 10, 11, 12, 13, 14, 15, 2239013af9b6SIntel 16, 17, 18, 19, 20, 21, 22, 23, 2240013af9b6SIntel 24, 25, 26, 27, 28, 29, 30, 31 2241013af9b6SIntel }; 2242013af9b6SIntel 2243013af9b6SIntel static int 22441a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf, 22451a572499SJingjing Wu enum dcb_mode_enable dcb_mode, 22461a572499SJingjing Wu enum rte_eth_nb_tcs num_tcs, 22471a572499SJingjing Wu uint8_t pfc_en) 2248013af9b6SIntel { 2249013af9b6SIntel uint8_t i; 2250af75078fSIntel 2251af75078fSIntel /* 2252013af9b6SIntel * Builds up the correct configuration for dcb+vt based on the vlan tags array 2253013af9b6SIntel * given above, and the number of traffic classes available for use. 2254af75078fSIntel */ 22551a572499SJingjing Wu if (dcb_mode == DCB_VT_ENABLED) { 22561a572499SJingjing Wu struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf = 22571a572499SJingjing Wu ð_conf->rx_adv_conf.vmdq_dcb_conf; 22581a572499SJingjing Wu struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf = 22591a572499SJingjing Wu ð_conf->tx_adv_conf.vmdq_dcb_tx_conf; 2260013af9b6SIntel 2261547d946cSNirmoy Das /* VMDQ+DCB RX and TX configurations */ 22621a572499SJingjing Wu vmdq_rx_conf->enable_default_pool = 0; 22631a572499SJingjing Wu vmdq_rx_conf->default_pool = 0; 22641a572499SJingjing Wu vmdq_rx_conf->nb_queue_pools = 22651a572499SJingjing Wu (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 22661a572499SJingjing Wu vmdq_tx_conf->nb_queue_pools = 22671a572499SJingjing Wu (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 2268013af9b6SIntel 22691a572499SJingjing Wu vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools; 22701a572499SJingjing Wu for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) { 22711a572499SJingjing Wu vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i]; 22721a572499SJingjing Wu vmdq_rx_conf->pool_map[i].pools = 22731a572499SJingjing Wu 1 << (i % vmdq_rx_conf->nb_queue_pools); 2274af75078fSIntel } 2275013af9b6SIntel for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 2276f59908feSWei Dai vmdq_rx_conf->dcb_tc[i] = i % num_tcs; 2277f59908feSWei Dai vmdq_tx_conf->dcb_tc[i] = i % num_tcs; 2278013af9b6SIntel } 2279013af9b6SIntel 2280013af9b6SIntel /* set DCB mode of RX and TX of multiple queues */ 228132e7aa0bSIntel eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB; 228232e7aa0bSIntel eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB; 22831a572499SJingjing Wu } else { 22841a572499SJingjing Wu struct rte_eth_dcb_rx_conf *rx_conf = 22851a572499SJingjing Wu ð_conf->rx_adv_conf.dcb_rx_conf; 22861a572499SJingjing Wu struct rte_eth_dcb_tx_conf *tx_conf = 22871a572499SJingjing Wu ð_conf->tx_adv_conf.dcb_tx_conf; 2288013af9b6SIntel 22891a572499SJingjing Wu rx_conf->nb_tcs = num_tcs; 22901a572499SJingjing Wu tx_conf->nb_tcs = num_tcs; 22911a572499SJingjing Wu 2292bcd0e432SJingjing Wu for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 2293bcd0e432SJingjing Wu rx_conf->dcb_tc[i] = i % num_tcs; 2294bcd0e432SJingjing Wu tx_conf->dcb_tc[i] = i % num_tcs; 2295013af9b6SIntel } 22961a572499SJingjing Wu eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS; 22971a572499SJingjing Wu eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf; 229832e7aa0bSIntel eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB; 22991a572499SJingjing Wu } 23001a572499SJingjing Wu 23011a572499SJingjing Wu if (pfc_en) 23021a572499SJingjing Wu eth_conf->dcb_capability_en = 23031a572499SJingjing Wu ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT; 2304013af9b6SIntel else 2305013af9b6SIntel eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 2306013af9b6SIntel 2307013af9b6SIntel return 0; 2308013af9b6SIntel } 2309013af9b6SIntel 2310013af9b6SIntel int 23111a572499SJingjing Wu init_port_dcb_config(portid_t pid, 23121a572499SJingjing Wu enum dcb_mode_enable dcb_mode, 23131a572499SJingjing Wu enum rte_eth_nb_tcs num_tcs, 23141a572499SJingjing Wu uint8_t pfc_en) 2315013af9b6SIntel { 2316013af9b6SIntel struct rte_eth_conf port_conf; 2317013af9b6SIntel struct rte_port *rte_port; 2318013af9b6SIntel int retval; 2319013af9b6SIntel uint16_t i; 2320013af9b6SIntel 23212a977b89SWenzhuo Lu rte_port = &ports[pid]; 2322013af9b6SIntel 2323013af9b6SIntel memset(&port_conf, 0, sizeof(struct rte_eth_conf)); 2324013af9b6SIntel /* Enter DCB configuration status */ 2325013af9b6SIntel dcb_config = 1; 2326013af9b6SIntel 2327013af9b6SIntel /*set configuration of DCB in vt mode and DCB in non-vt mode*/ 23281a572499SJingjing Wu retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en); 2329013af9b6SIntel if (retval < 0) 2330013af9b6SIntel return retval; 23310074d02fSShahaf Shuler port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; 2332013af9b6SIntel 23332a977b89SWenzhuo Lu /** 23342a977b89SWenzhuo Lu * Write the configuration into the device. 23352a977b89SWenzhuo Lu * Set the numbers of RX & TX queues to 0, so 23362a977b89SWenzhuo Lu * the RX & TX queues will not be setup. 23372a977b89SWenzhuo Lu */ 2338c947ef89SStephen Hemminger rte_eth_dev_configure(pid, 0, 0, &port_conf); 23392a977b89SWenzhuo Lu 23402a977b89SWenzhuo Lu rte_eth_dev_info_get(pid, &rte_port->dev_info); 23412a977b89SWenzhuo Lu 23422a977b89SWenzhuo Lu /* If dev_info.vmdq_pool_base is greater than 0, 23432a977b89SWenzhuo Lu * the queue id of vmdq pools is started after pf queues. 23442a977b89SWenzhuo Lu */ 23452a977b89SWenzhuo Lu if (dcb_mode == DCB_VT_ENABLED && 23462a977b89SWenzhuo Lu rte_port->dev_info.vmdq_pool_base > 0) { 23472a977b89SWenzhuo Lu printf("VMDQ_DCB multi-queue mode is nonsensical" 23482a977b89SWenzhuo Lu " for port %d.", pid); 23492a977b89SWenzhuo Lu return -1; 23502a977b89SWenzhuo Lu } 23512a977b89SWenzhuo Lu 23522a977b89SWenzhuo Lu /* Assume the ports in testpmd have the same dcb capability 23532a977b89SWenzhuo Lu * and has the same number of rxq and txq in dcb mode 23542a977b89SWenzhuo Lu */ 23552a977b89SWenzhuo Lu if (dcb_mode == DCB_VT_ENABLED) { 235686ef65eeSBernard Iremonger if (rte_port->dev_info.max_vfs > 0) { 235786ef65eeSBernard Iremonger nb_rxq = rte_port->dev_info.nb_rx_queues; 235886ef65eeSBernard Iremonger nb_txq = rte_port->dev_info.nb_tx_queues; 235986ef65eeSBernard Iremonger } else { 23602a977b89SWenzhuo Lu nb_rxq = rte_port->dev_info.max_rx_queues; 23612a977b89SWenzhuo Lu nb_txq = rte_port->dev_info.max_tx_queues; 236286ef65eeSBernard Iremonger } 23632a977b89SWenzhuo Lu } else { 23642a977b89SWenzhuo Lu /*if vt is disabled, use all pf queues */ 23652a977b89SWenzhuo Lu if (rte_port->dev_info.vmdq_pool_base == 0) { 23662a977b89SWenzhuo Lu nb_rxq = rte_port->dev_info.max_rx_queues; 23672a977b89SWenzhuo Lu nb_txq = rte_port->dev_info.max_tx_queues; 23682a977b89SWenzhuo Lu } else { 23692a977b89SWenzhuo Lu nb_rxq = (queueid_t)num_tcs; 23702a977b89SWenzhuo Lu nb_txq = (queueid_t)num_tcs; 23712a977b89SWenzhuo Lu 23722a977b89SWenzhuo Lu } 23732a977b89SWenzhuo Lu } 23742a977b89SWenzhuo Lu rx_free_thresh = 64; 23752a977b89SWenzhuo Lu 2376013af9b6SIntel memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf)); 2377013af9b6SIntel 2378f2c5125aSPablo de Lara rxtx_port_config(rte_port); 2379013af9b6SIntel /* VLAN filter */ 23800074d02fSShahaf Shuler rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; 23811a572499SJingjing Wu for (i = 0; i < RTE_DIM(vlan_tags); i++) 2382013af9b6SIntel rx_vft_set(pid, vlan_tags[i], 1); 2383013af9b6SIntel 2384013af9b6SIntel rte_eth_macaddr_get(pid, &rte_port->eth_addr); 2385013af9b6SIntel map_port_queue_stats_mapping_registers(pid, rte_port); 2386013af9b6SIntel 23877741e4cfSIntel rte_port->dcb_flag = 1; 23887741e4cfSIntel 2389013af9b6SIntel return 0; 2390af75078fSIntel } 2391af75078fSIntel 2392ffc468ffSTetsuya Mukawa static void 2393ffc468ffSTetsuya Mukawa init_port(void) 2394ffc468ffSTetsuya Mukawa { 2395ffc468ffSTetsuya Mukawa /* Configuration of Ethernet ports. */ 2396ffc468ffSTetsuya Mukawa ports = rte_zmalloc("testpmd: ports", 2397ffc468ffSTetsuya Mukawa sizeof(struct rte_port) * RTE_MAX_ETHPORTS, 2398ffc468ffSTetsuya Mukawa RTE_CACHE_LINE_SIZE); 2399ffc468ffSTetsuya Mukawa if (ports == NULL) { 2400ffc468ffSTetsuya Mukawa rte_exit(EXIT_FAILURE, 2401ffc468ffSTetsuya Mukawa "rte_zmalloc(%d struct rte_port) failed\n", 2402ffc468ffSTetsuya Mukawa RTE_MAX_ETHPORTS); 2403ffc468ffSTetsuya Mukawa } 2404ffc468ffSTetsuya Mukawa } 2405ffc468ffSTetsuya Mukawa 2406d3a274ceSZhihong Wang static void 2407d3a274ceSZhihong Wang force_quit(void) 2408d3a274ceSZhihong Wang { 2409d3a274ceSZhihong Wang pmd_test_exit(); 2410d3a274ceSZhihong Wang prompt_exit(); 2411d3a274ceSZhihong Wang } 2412d3a274ceSZhihong Wang 2413d3a274ceSZhihong Wang static void 2414cfea1f30SPablo de Lara print_stats(void) 2415cfea1f30SPablo de Lara { 2416cfea1f30SPablo de Lara uint8_t i; 2417cfea1f30SPablo de Lara const char clr[] = { 27, '[', '2', 'J', '\0' }; 2418cfea1f30SPablo de Lara const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' }; 2419cfea1f30SPablo de Lara 2420cfea1f30SPablo de Lara /* Clear screen and move to top left */ 2421cfea1f30SPablo de Lara printf("%s%s", clr, top_left); 2422cfea1f30SPablo de Lara 2423cfea1f30SPablo de Lara printf("\nPort statistics ===================================="); 2424cfea1f30SPablo de Lara for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 2425cfea1f30SPablo de Lara nic_stats_display(fwd_ports_ids[i]); 2426cfea1f30SPablo de Lara } 2427cfea1f30SPablo de Lara 2428cfea1f30SPablo de Lara static void 2429d3a274ceSZhihong Wang signal_handler(int signum) 2430d3a274ceSZhihong Wang { 2431d3a274ceSZhihong Wang if (signum == SIGINT || signum == SIGTERM) { 2432d3a274ceSZhihong Wang printf("\nSignal %d received, preparing to exit...\n", 2433d3a274ceSZhihong Wang signum); 2434102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP 2435102b7329SReshma Pattan /* uninitialize packet capture framework */ 2436102b7329SReshma Pattan rte_pdump_uninit(); 2437102b7329SReshma Pattan #endif 243862d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS 243962d3216dSReshma Pattan rte_latencystats_uninit(); 244062d3216dSReshma Pattan #endif 2441d3a274ceSZhihong Wang force_quit(); 2442d9a191a0SPhil Yang /* Set flag to indicate the force termination. */ 2443d9a191a0SPhil Yang f_quit = 1; 2444d3a274ceSZhihong Wang /* exit with the expected status */ 2445d3a274ceSZhihong Wang signal(signum, SIG_DFL); 2446d3a274ceSZhihong Wang kill(getpid(), signum); 2447d3a274ceSZhihong Wang } 2448d3a274ceSZhihong Wang } 2449d3a274ceSZhihong Wang 2450af75078fSIntel int 2451af75078fSIntel main(int argc, char** argv) 2452af75078fSIntel { 2453af75078fSIntel int diag; 2454f8244c63SZhiyong Yang portid_t port_id; 2455af75078fSIntel 2456d3a274ceSZhihong Wang signal(SIGINT, signal_handler); 2457d3a274ceSZhihong Wang signal(SIGTERM, signal_handler); 2458d3a274ceSZhihong Wang 2459af75078fSIntel diag = rte_eal_init(argc, argv); 2460af75078fSIntel if (diag < 0) 2461af75078fSIntel rte_panic("Cannot init EAL\n"); 2462af75078fSIntel 2463285fd101SOlivier Matz testpmd_logtype = rte_log_register("testpmd"); 2464285fd101SOlivier Matz if (testpmd_logtype < 0) 2465285fd101SOlivier Matz rte_panic("Cannot register log type"); 2466285fd101SOlivier Matz rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG); 2467285fd101SOlivier Matz 24681c036b16SEelco Chaudron if (mlockall(MCL_CURRENT | MCL_FUTURE)) { 2469285fd101SOlivier Matz TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n", 24701c036b16SEelco Chaudron strerror(errno)); 24711c036b16SEelco Chaudron } 24721c036b16SEelco Chaudron 2473102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP 2474102b7329SReshma Pattan /* initialize packet capture framework */ 2475102b7329SReshma Pattan rte_pdump_init(NULL); 2476102b7329SReshma Pattan #endif 2477102b7329SReshma Pattan 2478af75078fSIntel nb_ports = (portid_t) rte_eth_dev_count(); 2479af75078fSIntel if (nb_ports == 0) 2480285fd101SOlivier Matz TESTPMD_LOG(WARNING, "No probed ethernet devices\n"); 2481af75078fSIntel 2482ffc468ffSTetsuya Mukawa /* allocate port structures, and init them */ 2483ffc468ffSTetsuya Mukawa init_port(); 2484ffc468ffSTetsuya Mukawa 2485af75078fSIntel set_def_fwd_config(); 2486af75078fSIntel if (nb_lcores == 0) 2487af75078fSIntel rte_panic("Empty set of forwarding logical cores - check the " 2488af75078fSIntel "core mask supplied in the command parameters\n"); 2489af75078fSIntel 249065eb1e54SPablo de Lara /* Bitrate/latency stats disabled by default */ 249130bcc68cSPablo de Lara #ifdef RTE_LIBRTE_BITRATE 2492e25e6c70SRemy Horton bitrate_enabled = 0; 249330bcc68cSPablo de Lara #endif 249465eb1e54SPablo de Lara #ifdef RTE_LIBRTE_LATENCY_STATS 249565eb1e54SPablo de Lara latencystats_enabled = 0; 249665eb1e54SPablo de Lara #endif 2497e25e6c70SRemy Horton 2498af75078fSIntel argc -= diag; 2499af75078fSIntel argv += diag; 2500af75078fSIntel if (argc > 1) 2501af75078fSIntel launch_args_parse(argc, argv); 2502af75078fSIntel 250399cabef0SPablo de Lara if (tx_first && interactive) 250499cabef0SPablo de Lara rte_exit(EXIT_FAILURE, "--tx-first cannot be used on " 250599cabef0SPablo de Lara "interactive mode.\n"); 25068820cba4SDavid Hunt 25078820cba4SDavid Hunt if (tx_first && lsc_interrupt) { 25088820cba4SDavid Hunt printf("Warning: lsc_interrupt needs to be off when " 25098820cba4SDavid Hunt " using tx_first. Disabling.\n"); 25108820cba4SDavid Hunt lsc_interrupt = 0; 25118820cba4SDavid Hunt } 25128820cba4SDavid Hunt 25135a8fb55cSReshma Pattan if (!nb_rxq && !nb_txq) 25145a8fb55cSReshma Pattan printf("Warning: Either rx or tx queues should be non-zero\n"); 25155a8fb55cSReshma Pattan 25165a8fb55cSReshma Pattan if (nb_rxq > 1 && nb_rxq > nb_txq) 2517af75078fSIntel printf("Warning: nb_rxq=%d enables RSS configuration, " 2518af75078fSIntel "but nb_txq=%d will prevent to fully test it.\n", 2519af75078fSIntel nb_rxq, nb_txq); 2520af75078fSIntel 2521af75078fSIntel init_config(); 2522148f963fSBruce Richardson if (start_port(RTE_PORT_ALL) != 0) 2523148f963fSBruce Richardson rte_exit(EXIT_FAILURE, "Start ports failed\n"); 2524af75078fSIntel 2525ce8d5614SIntel /* set all ports to promiscuous mode by default */ 25267d89b261SGaetan Rivet RTE_ETH_FOREACH_DEV(port_id) 2527ce8d5614SIntel rte_eth_promiscuous_enable(port_id); 2528af75078fSIntel 25297e4441c8SRemy Horton /* Init metrics library */ 25307e4441c8SRemy Horton rte_metrics_init(rte_socket_id()); 25317e4441c8SRemy Horton 253262d3216dSReshma Pattan #ifdef RTE_LIBRTE_LATENCY_STATS 253362d3216dSReshma Pattan if (latencystats_enabled != 0) { 253462d3216dSReshma Pattan int ret = rte_latencystats_init(1, NULL); 253562d3216dSReshma Pattan if (ret) 253662d3216dSReshma Pattan printf("Warning: latencystats init()" 253762d3216dSReshma Pattan " returned error %d\n", ret); 253862d3216dSReshma Pattan printf("Latencystats running on lcore %d\n", 253962d3216dSReshma Pattan latencystats_lcore_id); 254062d3216dSReshma Pattan } 254162d3216dSReshma Pattan #endif 254262d3216dSReshma Pattan 25437e4441c8SRemy Horton /* Setup bitrate stats */ 25447e4441c8SRemy Horton #ifdef RTE_LIBRTE_BITRATE 2545e25e6c70SRemy Horton if (bitrate_enabled != 0) { 25467e4441c8SRemy Horton bitrate_data = rte_stats_bitrate_create(); 25477e4441c8SRemy Horton if (bitrate_data == NULL) 2548e25e6c70SRemy Horton rte_exit(EXIT_FAILURE, 2549e25e6c70SRemy Horton "Could not allocate bitrate data.\n"); 25507e4441c8SRemy Horton rte_stats_bitrate_reg(bitrate_data); 2551e25e6c70SRemy Horton } 25527e4441c8SRemy Horton #endif 25537e4441c8SRemy Horton 25540d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE 255581ef862bSAllain Legacy if (strlen(cmdline_filename) != 0) 255681ef862bSAllain Legacy cmdline_read_from_file(cmdline_filename); 255781ef862bSAllain Legacy 2558ca7feb22SCyril Chemparathy if (interactive == 1) { 2559ca7feb22SCyril Chemparathy if (auto_start) { 2560ca7feb22SCyril Chemparathy printf("Start automatic packet forwarding\n"); 2561ca7feb22SCyril Chemparathy start_packet_forwarding(0); 2562ca7feb22SCyril Chemparathy } 2563af75078fSIntel prompt(); 25640de738cfSJiayu Hu pmd_test_exit(); 2565ca7feb22SCyril Chemparathy } else 25660d56cb81SThomas Monjalon #endif 25670d56cb81SThomas Monjalon { 2568af75078fSIntel char c; 2569af75078fSIntel int rc; 2570af75078fSIntel 2571d9a191a0SPhil Yang f_quit = 0; 2572d9a191a0SPhil Yang 2573af75078fSIntel printf("No commandline core given, start packet forwarding\n"); 257499cabef0SPablo de Lara start_packet_forwarding(tx_first); 2575cfea1f30SPablo de Lara if (stats_period != 0) { 2576cfea1f30SPablo de Lara uint64_t prev_time = 0, cur_time, diff_time = 0; 2577cfea1f30SPablo de Lara uint64_t timer_period; 2578cfea1f30SPablo de Lara 2579cfea1f30SPablo de Lara /* Convert to number of cycles */ 2580cfea1f30SPablo de Lara timer_period = stats_period * rte_get_timer_hz(); 2581cfea1f30SPablo de Lara 2582d9a191a0SPhil Yang while (f_quit == 0) { 2583cfea1f30SPablo de Lara cur_time = rte_get_timer_cycles(); 2584cfea1f30SPablo de Lara diff_time += cur_time - prev_time; 2585cfea1f30SPablo de Lara 2586cfea1f30SPablo de Lara if (diff_time >= timer_period) { 2587cfea1f30SPablo de Lara print_stats(); 2588cfea1f30SPablo de Lara /* Reset the timer */ 2589cfea1f30SPablo de Lara diff_time = 0; 2590cfea1f30SPablo de Lara } 2591cfea1f30SPablo de Lara /* Sleep to avoid unnecessary checks */ 2592cfea1f30SPablo de Lara prev_time = cur_time; 2593cfea1f30SPablo de Lara sleep(1); 2594cfea1f30SPablo de Lara } 2595cfea1f30SPablo de Lara } 2596cfea1f30SPablo de Lara 2597af75078fSIntel printf("Press enter to exit\n"); 2598af75078fSIntel rc = read(0, &c, 1); 2599d3a274ceSZhihong Wang pmd_test_exit(); 2600af75078fSIntel if (rc < 0) 2601af75078fSIntel return 1; 2602af75078fSIntel } 2603af75078fSIntel 2604af75078fSIntel return 0; 2605af75078fSIntel } 2606