1af75078fSIntel /*- 2af75078fSIntel * BSD LICENSE 3af75078fSIntel * 4e9d48c00SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5af75078fSIntel * All rights reserved. 6af75078fSIntel * 7af75078fSIntel * Redistribution and use in source and binary forms, with or without 8af75078fSIntel * modification, are permitted provided that the following conditions 9af75078fSIntel * are met: 10af75078fSIntel * 11af75078fSIntel * * Redistributions of source code must retain the above copyright 12af75078fSIntel * notice, this list of conditions and the following disclaimer. 13af75078fSIntel * * Redistributions in binary form must reproduce the above copyright 14af75078fSIntel * notice, this list of conditions and the following disclaimer in 15af75078fSIntel * the documentation and/or other materials provided with the 16af75078fSIntel * distribution. 17af75078fSIntel * * Neither the name of Intel Corporation nor the names of its 18af75078fSIntel * contributors may be used to endorse or promote products derived 19af75078fSIntel * from this software without specific prior written permission. 20af75078fSIntel * 21af75078fSIntel * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22af75078fSIntel * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23af75078fSIntel * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24af75078fSIntel * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25af75078fSIntel * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26af75078fSIntel * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27af75078fSIntel * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28af75078fSIntel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29af75078fSIntel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30af75078fSIntel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31af75078fSIntel * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32af75078fSIntel */ 33af75078fSIntel 34af75078fSIntel #include <stdarg.h> 35af75078fSIntel #include <stdio.h> 36af75078fSIntel #include <stdlib.h> 37af75078fSIntel #include <signal.h> 38af75078fSIntel #include <string.h> 39af75078fSIntel #include <time.h> 40af75078fSIntel #include <fcntl.h> 41af75078fSIntel #include <sys/types.h> 42af75078fSIntel #include <errno.h> 43af75078fSIntel 44af75078fSIntel #include <sys/queue.h> 45af75078fSIntel #include <sys/stat.h> 46af75078fSIntel 47af75078fSIntel #include <stdint.h> 48af75078fSIntel #include <unistd.h> 49af75078fSIntel #include <inttypes.h> 50af75078fSIntel 51af75078fSIntel #include <rte_common.h> 52af75078fSIntel #include <rte_byteorder.h> 53af75078fSIntel #include <rte_log.h> 54af75078fSIntel #include <rte_debug.h> 55af75078fSIntel #include <rte_cycles.h> 56af75078fSIntel #include <rte_memory.h> 57af75078fSIntel #include <rte_memcpy.h> 58af75078fSIntel #include <rte_memzone.h> 59af75078fSIntel #include <rte_launch.h> 60af75078fSIntel #include <rte_tailq.h> 61af75078fSIntel #include <rte_eal.h> 62af75078fSIntel #include <rte_per_lcore.h> 63af75078fSIntel #include <rte_lcore.h> 64af75078fSIntel #include <rte_atomic.h> 65af75078fSIntel #include <rte_branch_prediction.h> 66af75078fSIntel #include <rte_ring.h> 67af75078fSIntel #include <rte_mempool.h> 68af75078fSIntel #include <rte_malloc.h> 69af75078fSIntel #include <rte_mbuf.h> 70af75078fSIntel #include <rte_interrupts.h> 71af75078fSIntel #include <rte_pci.h> 72af75078fSIntel #include <rte_ether.h> 73af75078fSIntel #include <rte_ethdev.h> 74af75078fSIntel #include <rte_string_fns.h> 75148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT 76148f963fSBruce Richardson #include <rte_eth_xenvirt.h> 77148f963fSBruce Richardson #endif 78af75078fSIntel 79af75078fSIntel #include "testpmd.h" 80148f963fSBruce Richardson #include "mempool_osdep.h" 81af75078fSIntel 82af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */ 83af75078fSIntel 84af75078fSIntel /* use master core for command line ? */ 85af75078fSIntel uint8_t interactive = 0; 86ca7feb22SCyril Chemparathy uint8_t auto_start = 0; 87af75078fSIntel 88af75078fSIntel /* 89af75078fSIntel * NUMA support configuration. 90af75078fSIntel * When set, the NUMA support attempts to dispatch the allocation of the 91af75078fSIntel * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the 92af75078fSIntel * probed ports among the CPU sockets 0 and 1. 93af75078fSIntel * Otherwise, all memory is allocated from CPU socket 0. 94af75078fSIntel */ 95af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */ 96af75078fSIntel 97af75078fSIntel /* 98b6ea6408SIntel * In UMA mode,all memory is allocated from socket 0 if --socket-num is 99b6ea6408SIntel * not configured. 100b6ea6408SIntel */ 101b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG; 102b6ea6408SIntel 103b6ea6408SIntel /* 104148f963fSBruce Richardson * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs. 105148f963fSBruce Richardson */ 106148f963fSBruce Richardson uint8_t mp_anon = 0; 107148f963fSBruce Richardson 108148f963fSBruce Richardson /* 109af75078fSIntel * Record the Ethernet address of peer target ports to which packets are 110af75078fSIntel * forwarded. 111af75078fSIntel * Must be instanciated with the ethernet addresses of peer traffic generator 112af75078fSIntel * ports. 113af75078fSIntel */ 114af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; 115af75078fSIntel portid_t nb_peer_eth_addrs = 0; 116af75078fSIntel 117af75078fSIntel /* 118af75078fSIntel * Probed Target Environment. 119af75078fSIntel */ 120af75078fSIntel struct rte_port *ports; /**< For all probed ethernet ports. */ 121af75078fSIntel portid_t nb_ports; /**< Number of probed ethernet ports. */ 122af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */ 123af75078fSIntel lcoreid_t nb_lcores; /**< Number of probed logical cores. */ 124af75078fSIntel 125af75078fSIntel /* 126af75078fSIntel * Test Forwarding Configuration. 127af75078fSIntel * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores 128af75078fSIntel * nb_fwd_ports <= nb_cfg_ports <= nb_ports 129af75078fSIntel */ 130af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */ 131af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */ 132af75078fSIntel portid_t nb_cfg_ports; /**< Number of configured ports. */ 133af75078fSIntel portid_t nb_fwd_ports; /**< Number of forwarding ports. */ 134af75078fSIntel 135af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */ 136af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */ 137af75078fSIntel 138af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */ 139af75078fSIntel streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ 140af75078fSIntel 141af75078fSIntel /* 142af75078fSIntel * Forwarding engines. 143af75078fSIntel */ 144af75078fSIntel struct fwd_engine * fwd_engines[] = { 145af75078fSIntel &io_fwd_engine, 146af75078fSIntel &mac_fwd_engine, 14757e85242SBruce Richardson &mac_retry_fwd_engine, 148d47388f1SCyril Chemparathy &mac_swap_engine, 149e9e23a61SCyril Chemparathy &flow_gen_engine, 150af75078fSIntel &rx_only_engine, 151af75078fSIntel &tx_only_engine, 152af75078fSIntel &csum_fwd_engine, 153168dfa61SIvan Boule &icmp_echo_engine, 154af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588 155af75078fSIntel &ieee1588_fwd_engine, 156af75078fSIntel #endif 157af75078fSIntel NULL, 158af75078fSIntel }; 159af75078fSIntel 160af75078fSIntel struct fwd_config cur_fwd_config; 161af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ 162af75078fSIntel 163af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ 164c8798818SIntel uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if 165c8798818SIntel * specified on command-line. */ 166af75078fSIntel 167af75078fSIntel /* 168af75078fSIntel * Configuration of packet segments used by the "txonly" processing engine. 169af75078fSIntel */ 170af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */ 171af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = { 172af75078fSIntel TXONLY_DEF_PACKET_LEN, 173af75078fSIntel }; 174af75078fSIntel uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */ 175af75078fSIntel 176af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */ 177e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ 178af75078fSIntel 179900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */ 180900550deSIntel uint8_t dcb_config = 0; 181900550deSIntel 182900550deSIntel /* Whether the dcb is in testing status */ 183900550deSIntel uint8_t dcb_test = 0; 184900550deSIntel 185900550deSIntel /* DCB on and VT on mapping is default */ 186900550deSIntel enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING; 187af75078fSIntel 188af75078fSIntel /* 189af75078fSIntel * Configurable number of RX/TX queues. 190af75078fSIntel */ 191af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ 192af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */ 193af75078fSIntel 194af75078fSIntel /* 195af75078fSIntel * Configurable number of RX/TX ring descriptors. 196af75078fSIntel */ 197af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128 198af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512 199af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */ 200af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */ 201af75078fSIntel 202af75078fSIntel /* 203af75078fSIntel * Configurable values of RX and TX ring threshold registers. 204af75078fSIntel */ 205af75078fSIntel #define RX_PTHRESH 8 /**< Default value of RX prefetch threshold register. */ 206af75078fSIntel #define RX_HTHRESH 8 /**< Default value of RX host threshold register. */ 207e9378bbcSCunming Liang #define RX_WTHRESH 0 /**< Default value of RX write-back threshold register. */ 208af75078fSIntel 209e9378bbcSCunming Liang #define TX_PTHRESH 32 /**< Default value of TX prefetch threshold register. */ 210af75078fSIntel #define TX_HTHRESH 0 /**< Default value of TX host threshold register. */ 211af75078fSIntel #define TX_WTHRESH 0 /**< Default value of TX write-back threshold register. */ 212af75078fSIntel 213af75078fSIntel struct rte_eth_thresh rx_thresh = { 214af75078fSIntel .pthresh = RX_PTHRESH, 215af75078fSIntel .hthresh = RX_HTHRESH, 216af75078fSIntel .wthresh = RX_WTHRESH, 217af75078fSIntel }; 218af75078fSIntel 219af75078fSIntel struct rte_eth_thresh tx_thresh = { 220af75078fSIntel .pthresh = TX_PTHRESH, 221af75078fSIntel .hthresh = TX_HTHRESH, 222af75078fSIntel .wthresh = TX_WTHRESH, 223af75078fSIntel }; 224af75078fSIntel 225af75078fSIntel /* 226af75078fSIntel * Configurable value of RX free threshold. 227af75078fSIntel */ 228af75078fSIntel uint16_t rx_free_thresh = 0; /* Immediately free RX descriptors by default. */ 229af75078fSIntel 230af75078fSIntel /* 231ce8d5614SIntel * Configurable value of RX drop enable. 232ce8d5614SIntel */ 233ce8d5614SIntel uint8_t rx_drop_en = 0; /* Drop packets when no descriptors for queue. */ 234ce8d5614SIntel 235ce8d5614SIntel /* 236af75078fSIntel * Configurable value of TX free threshold. 237af75078fSIntel */ 238af75078fSIntel uint16_t tx_free_thresh = 0; /* Use default values. */ 239af75078fSIntel 240af75078fSIntel /* 241af75078fSIntel * Configurable value of TX RS bit threshold. 242af75078fSIntel */ 243af75078fSIntel uint16_t tx_rs_thresh = 0; /* Use default values. */ 244af75078fSIntel 245af75078fSIntel /* 246ce8d5614SIntel * Configurable value of TX queue flags. 247ce8d5614SIntel */ 248ce8d5614SIntel uint32_t txq_flags = 0; /* No flags set. */ 249ce8d5614SIntel 250ce8d5614SIntel /* 251af75078fSIntel * Receive Side Scaling (RSS) configuration. 252af75078fSIntel */ 2538a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */ 254af75078fSIntel 255af75078fSIntel /* 256af75078fSIntel * Port topology configuration 257af75078fSIntel */ 258af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */ 259af75078fSIntel 2607741e4cfSIntel /* 2617741e4cfSIntel * Avoids to flush all the RX streams before starts forwarding. 2627741e4cfSIntel */ 2637741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */ 2647741e4cfSIntel 265af75078fSIntel /* 266bc202406SDavid Marchand * Avoids to check link status when starting/stopping a port. 267bc202406SDavid Marchand */ 268bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */ 269bc202406SDavid Marchand 270bc202406SDavid Marchand /* 2717b7e5ba7SIntel * NIC bypass mode configuration options. 2727b7e5ba7SIntel */ 2737b7e5ba7SIntel #ifdef RTE_NIC_BYPASS 2747b7e5ba7SIntel 2757b7e5ba7SIntel /* The NIC bypass watchdog timeout. */ 2767b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF; 2777b7e5ba7SIntel 2787b7e5ba7SIntel #endif 2797b7e5ba7SIntel 2807b7e5ba7SIntel /* 281af75078fSIntel * Ethernet device configuration. 282af75078fSIntel */ 283af75078fSIntel struct rte_eth_rxmode rx_mode = { 284af75078fSIntel .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ 285af75078fSIntel .split_hdr_size = 0, 286af75078fSIntel .header_split = 0, /**< Header Split disabled. */ 287af75078fSIntel .hw_ip_checksum = 0, /**< IP checksum offload disabled. */ 288af75078fSIntel .hw_vlan_filter = 1, /**< VLAN filtering enabled. */ 289a47aa8b9SIntel .hw_vlan_strip = 1, /**< VLAN strip enabled. */ 290a47aa8b9SIntel .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ 291af75078fSIntel .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ 292af75078fSIntel .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */ 293af75078fSIntel }; 294af75078fSIntel 295af75078fSIntel struct rte_fdir_conf fdir_conf = { 296af75078fSIntel .mode = RTE_FDIR_MODE_NONE, 297af75078fSIntel .pballoc = RTE_FDIR_PBALLOC_64K, 298af75078fSIntel .status = RTE_FDIR_REPORT_STATUS, 299af75078fSIntel .flexbytes_offset = 0x6, 300af75078fSIntel .drop_queue = 127, 301af75078fSIntel }; 302af75078fSIntel 3032950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */ 304af75078fSIntel 305ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; 306ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; 307ed30d9b6SIntel 308ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; 309ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; 310ed30d9b6SIntel 311ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0; 312ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0; 313ed30d9b6SIntel 314ed30d9b6SIntel /* Forward function declarations */ 315ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port); 316ce8d5614SIntel static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask); 317ce8d5614SIntel 318ce8d5614SIntel /* 319ce8d5614SIntel * Check if all the ports are started. 320ce8d5614SIntel * If yes, return positive value. If not, return zero. 321ce8d5614SIntel */ 322ce8d5614SIntel static int all_ports_started(void); 323ed30d9b6SIntel 324af75078fSIntel /* 325af75078fSIntel * Setup default configuration. 326af75078fSIntel */ 327af75078fSIntel static void 328af75078fSIntel set_default_fwd_lcores_config(void) 329af75078fSIntel { 330af75078fSIntel unsigned int i; 331af75078fSIntel unsigned int nb_lc; 332af75078fSIntel 333af75078fSIntel nb_lc = 0; 334af75078fSIntel for (i = 0; i < RTE_MAX_LCORE; i++) { 335af75078fSIntel if (! rte_lcore_is_enabled(i)) 336af75078fSIntel continue; 337af75078fSIntel if (i == rte_get_master_lcore()) 338af75078fSIntel continue; 339af75078fSIntel fwd_lcores_cpuids[nb_lc++] = i; 340af75078fSIntel } 341af75078fSIntel nb_lcores = (lcoreid_t) nb_lc; 342af75078fSIntel nb_cfg_lcores = nb_lcores; 343af75078fSIntel nb_fwd_lcores = 1; 344af75078fSIntel } 345af75078fSIntel 346af75078fSIntel static void 347af75078fSIntel set_def_peer_eth_addrs(void) 348af75078fSIntel { 349af75078fSIntel portid_t i; 350af75078fSIntel 351af75078fSIntel for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 352af75078fSIntel peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR; 353af75078fSIntel peer_eth_addrs[i].addr_bytes[5] = i; 354af75078fSIntel } 355af75078fSIntel } 356af75078fSIntel 357af75078fSIntel static void 358af75078fSIntel set_default_fwd_ports_config(void) 359af75078fSIntel { 360af75078fSIntel portid_t pt_id; 361af75078fSIntel 362af75078fSIntel for (pt_id = 0; pt_id < nb_ports; pt_id++) 363af75078fSIntel fwd_ports_ids[pt_id] = pt_id; 364af75078fSIntel 365af75078fSIntel nb_cfg_ports = nb_ports; 366af75078fSIntel nb_fwd_ports = nb_ports; 367af75078fSIntel } 368af75078fSIntel 369af75078fSIntel void 370af75078fSIntel set_def_fwd_config(void) 371af75078fSIntel { 372af75078fSIntel set_default_fwd_lcores_config(); 373af75078fSIntel set_def_peer_eth_addrs(); 374af75078fSIntel set_default_fwd_ports_config(); 375af75078fSIntel } 376af75078fSIntel 377af75078fSIntel /* 378af75078fSIntel * Configuration initialisation done once at init time. 379af75078fSIntel */ 380af75078fSIntel struct mbuf_ctor_arg { 381af75078fSIntel uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */ 382af75078fSIntel uint16_t seg_buf_size; /**< size of data segment in mbuf. */ 383af75078fSIntel }; 384af75078fSIntel 385af75078fSIntel struct mbuf_pool_ctor_arg { 386af75078fSIntel uint16_t seg_buf_size; /**< size of data segment in mbuf. */ 387af75078fSIntel }; 388af75078fSIntel 389af75078fSIntel static void 390af75078fSIntel testpmd_mbuf_ctor(struct rte_mempool *mp, 391af75078fSIntel void *opaque_arg, 392af75078fSIntel void *raw_mbuf, 393af75078fSIntel __attribute__((unused)) unsigned i) 394af75078fSIntel { 395af75078fSIntel struct mbuf_ctor_arg *mb_ctor_arg; 396af75078fSIntel struct rte_mbuf *mb; 397af75078fSIntel 398af75078fSIntel mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg; 399af75078fSIntel mb = (struct rte_mbuf *) raw_mbuf; 400af75078fSIntel 401af75078fSIntel mb->pool = mp; 402af75078fSIntel mb->buf_addr = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset); 403af75078fSIntel mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) + 404af75078fSIntel mb_ctor_arg->seg_buf_offset); 405af75078fSIntel mb->buf_len = mb_ctor_arg->seg_buf_size; 406af75078fSIntel mb->ol_flags = 0; 407*ea672a8bSOlivier Matz mb->data = (char *) mb->buf_addr + RTE_PKTMBUF_HEADROOM; 408*ea672a8bSOlivier Matz mb->nb_segs = 1; 409*ea672a8bSOlivier Matz mb->vlan_macip.data = 0; 410*ea672a8bSOlivier Matz mb->hash.rss = 0; 411af75078fSIntel } 412af75078fSIntel 413af75078fSIntel static void 414af75078fSIntel testpmd_mbuf_pool_ctor(struct rte_mempool *mp, 415af75078fSIntel void *opaque_arg) 416af75078fSIntel { 417af75078fSIntel struct mbuf_pool_ctor_arg *mbp_ctor_arg; 418af75078fSIntel struct rte_pktmbuf_pool_private *mbp_priv; 419af75078fSIntel 420af75078fSIntel if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) { 421af75078fSIntel printf("%s(%s) private_data_size %d < %d\n", 422af75078fSIntel __func__, mp->name, (int) mp->private_data_size, 423af75078fSIntel (int) sizeof(struct rte_pktmbuf_pool_private)); 424af75078fSIntel return; 425af75078fSIntel } 426af75078fSIntel mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg; 427148f963fSBruce Richardson mbp_priv = rte_mempool_get_priv(mp); 428af75078fSIntel mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size; 429af75078fSIntel } 430af75078fSIntel 431af75078fSIntel static void 432af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, 433af75078fSIntel unsigned int socket_id) 434af75078fSIntel { 435af75078fSIntel char pool_name[RTE_MEMPOOL_NAMESIZE]; 436af75078fSIntel struct rte_mempool *rte_mp; 437af75078fSIntel struct mbuf_pool_ctor_arg mbp_ctor_arg; 438af75078fSIntel struct mbuf_ctor_arg mb_ctor_arg; 439af75078fSIntel uint32_t mb_size; 440af75078fSIntel 441af75078fSIntel mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM + 442af75078fSIntel mbuf_seg_size); 443af75078fSIntel mb_ctor_arg.seg_buf_offset = 444af75078fSIntel (uint16_t) CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf)); 445af75078fSIntel mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size; 446af75078fSIntel mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size; 447af75078fSIntel mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); 448148f963fSBruce Richardson 449148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT 450148f963fSBruce Richardson rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size, 451af75078fSIntel (unsigned) mb_mempool_cache, 452af75078fSIntel sizeof(struct rte_pktmbuf_pool_private), 453af75078fSIntel testpmd_mbuf_pool_ctor, &mbp_ctor_arg, 454af75078fSIntel testpmd_mbuf_ctor, &mb_ctor_arg, 455af75078fSIntel socket_id, 0); 456148f963fSBruce Richardson 457148f963fSBruce Richardson 458148f963fSBruce Richardson 459148f963fSBruce Richardson #else 460148f963fSBruce Richardson if (mp_anon != 0) 461148f963fSBruce Richardson rte_mp = mempool_anon_create(pool_name, nb_mbuf, mb_size, 462148f963fSBruce Richardson (unsigned) mb_mempool_cache, 463148f963fSBruce Richardson sizeof(struct rte_pktmbuf_pool_private), 464148f963fSBruce Richardson testpmd_mbuf_pool_ctor, &mbp_ctor_arg, 465148f963fSBruce Richardson testpmd_mbuf_ctor, &mb_ctor_arg, 466148f963fSBruce Richardson socket_id, 0); 467148f963fSBruce Richardson else 468148f963fSBruce Richardson rte_mp = rte_mempool_create(pool_name, nb_mbuf, mb_size, 469148f963fSBruce Richardson (unsigned) mb_mempool_cache, 470148f963fSBruce Richardson sizeof(struct rte_pktmbuf_pool_private), 471148f963fSBruce Richardson testpmd_mbuf_pool_ctor, &mbp_ctor_arg, 472148f963fSBruce Richardson testpmd_mbuf_ctor, &mb_ctor_arg, 473148f963fSBruce Richardson socket_id, 0); 474148f963fSBruce Richardson 475148f963fSBruce Richardson #endif 476148f963fSBruce Richardson 477af75078fSIntel if (rte_mp == NULL) { 478ce8d5614SIntel rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u " 479ce8d5614SIntel "failed\n", socket_id); 480148f963fSBruce Richardson } else if (verbose_level > 0) { 481591a9d79SStephen Hemminger rte_mempool_dump(stdout, rte_mp); 482af75078fSIntel } 483af75078fSIntel } 484af75078fSIntel 48520a0286fSLiu Xiaofeng /* 48620a0286fSLiu Xiaofeng * Check given socket id is valid or not with NUMA mode, 48720a0286fSLiu Xiaofeng * if valid, return 0, else return -1 48820a0286fSLiu Xiaofeng */ 48920a0286fSLiu Xiaofeng static int 49020a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id) 49120a0286fSLiu Xiaofeng { 49220a0286fSLiu Xiaofeng static int warning_once = 0; 49320a0286fSLiu Xiaofeng 49420a0286fSLiu Xiaofeng if (socket_id >= MAX_SOCKET) { 49520a0286fSLiu Xiaofeng if (!warning_once && numa_support) 49620a0286fSLiu Xiaofeng printf("Warning: NUMA should be configured manually by" 49720a0286fSLiu Xiaofeng " using --port-numa-config and" 49820a0286fSLiu Xiaofeng " --ring-numa-config parameters along with" 49920a0286fSLiu Xiaofeng " --numa.\n"); 50020a0286fSLiu Xiaofeng warning_once = 1; 50120a0286fSLiu Xiaofeng return -1; 50220a0286fSLiu Xiaofeng } 50320a0286fSLiu Xiaofeng return 0; 50420a0286fSLiu Xiaofeng } 50520a0286fSLiu Xiaofeng 506af75078fSIntel static void 507af75078fSIntel init_config(void) 508af75078fSIntel { 509ce8d5614SIntel portid_t pid; 510af75078fSIntel struct rte_port *port; 511af75078fSIntel struct rte_mempool *mbp; 512af75078fSIntel unsigned int nb_mbuf_per_pool; 513af75078fSIntel lcoreid_t lc_id; 514b6ea6408SIntel uint8_t port_per_socket[MAX_SOCKET]; 515af75078fSIntel 516b6ea6408SIntel memset(port_per_socket,0,MAX_SOCKET); 517af75078fSIntel /* Configuration of logical cores. */ 518af75078fSIntel fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 519af75078fSIntel sizeof(struct fwd_lcore *) * nb_lcores, 520af75078fSIntel CACHE_LINE_SIZE); 521af75078fSIntel if (fwd_lcores == NULL) { 522ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 523ce8d5614SIntel "failed\n", nb_lcores); 524af75078fSIntel } 525af75078fSIntel for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 526af75078fSIntel fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 527af75078fSIntel sizeof(struct fwd_lcore), 528af75078fSIntel CACHE_LINE_SIZE); 529af75078fSIntel if (fwd_lcores[lc_id] == NULL) { 530ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 531ce8d5614SIntel "failed\n"); 532af75078fSIntel } 533af75078fSIntel fwd_lcores[lc_id]->cpuid_idx = lc_id; 534af75078fSIntel } 535af75078fSIntel 536af75078fSIntel /* 537af75078fSIntel * Create pools of mbuf. 538af75078fSIntel * If NUMA support is disabled, create a single pool of mbuf in 539b6ea6408SIntel * socket 0 memory by default. 540af75078fSIntel * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 541c8798818SIntel * 542c8798818SIntel * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 543c8798818SIntel * nb_txd can be configured at run time. 544af75078fSIntel */ 545c8798818SIntel if (param_total_num_mbufs) 546c8798818SIntel nb_mbuf_per_pool = param_total_num_mbufs; 547c8798818SIntel else { 548c8798818SIntel nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache) 549c8798818SIntel + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 550b6ea6408SIntel 551b6ea6408SIntel if (!numa_support) 552c8798818SIntel nb_mbuf_per_pool = (nb_mbuf_per_pool * nb_ports); 553c8798818SIntel } 554af75078fSIntel 555b6ea6408SIntel if (!numa_support) { 556b6ea6408SIntel if (socket_num == UMA_NO_CONFIG) 557b6ea6408SIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 558b6ea6408SIntel else 559b6ea6408SIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 560b6ea6408SIntel socket_num); 561b6ea6408SIntel } 562af75078fSIntel 563af75078fSIntel /* Configuration of Ethernet ports. */ 564af75078fSIntel ports = rte_zmalloc("testpmd: ports", 565af75078fSIntel sizeof(struct rte_port) * nb_ports, 566af75078fSIntel CACHE_LINE_SIZE); 567af75078fSIntel if (ports == NULL) { 568ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) " 569ce8d5614SIntel "failed\n", nb_ports); 570af75078fSIntel } 571af75078fSIntel 572ce8d5614SIntel for (pid = 0; pid < nb_ports; pid++) { 573ce8d5614SIntel port = &ports[pid]; 574ce8d5614SIntel rte_eth_dev_info_get(pid, &port->dev_info); 575ce8d5614SIntel 576b6ea6408SIntel if (numa_support) { 577b6ea6408SIntel if (port_numa[pid] != NUMA_NO_CONFIG) 578b6ea6408SIntel port_per_socket[port_numa[pid]]++; 579b6ea6408SIntel else { 580b6ea6408SIntel uint32_t socket_id = rte_eth_dev_socket_id(pid); 58120a0286fSLiu Xiaofeng 58220a0286fSLiu Xiaofeng /* if socket_id is invalid, set to 0 */ 58320a0286fSLiu Xiaofeng if (check_socket_id(socket_id) < 0) 58420a0286fSLiu Xiaofeng socket_id = 0; 585b6ea6408SIntel port_per_socket[socket_id]++; 586b6ea6408SIntel } 587b6ea6408SIntel } 588b6ea6408SIntel 589ce8d5614SIntel /* set flag to initialize port/queue */ 590ce8d5614SIntel port->need_reconfig = 1; 591ce8d5614SIntel port->need_reconfig_queues = 1; 592ce8d5614SIntel } 593ce8d5614SIntel 594b6ea6408SIntel if (numa_support) { 595b6ea6408SIntel uint8_t i; 596b6ea6408SIntel unsigned int nb_mbuf; 597ce8d5614SIntel 598b6ea6408SIntel if (param_total_num_mbufs) 599b6ea6408SIntel nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports; 600b6ea6408SIntel 601b6ea6408SIntel for (i = 0; i < MAX_SOCKET; i++) { 602b6ea6408SIntel nb_mbuf = (nb_mbuf_per_pool * 603b6ea6408SIntel port_per_socket[i]); 604b6ea6408SIntel if (nb_mbuf) 605b6ea6408SIntel mbuf_pool_create(mbuf_data_size, 606b6ea6408SIntel nb_mbuf,i); 607b6ea6408SIntel } 608b6ea6408SIntel } 609b6ea6408SIntel init_port_config(); 6105886ae07SAdrien Mazarguil 6115886ae07SAdrien Mazarguil /* 6125886ae07SAdrien Mazarguil * Records which Mbuf pool to use by each logical core, if needed. 6135886ae07SAdrien Mazarguil */ 6145886ae07SAdrien Mazarguil for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 6158fd8bebcSAdrien Mazarguil mbp = mbuf_pool_find( 6168fd8bebcSAdrien Mazarguil rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id])); 6178fd8bebcSAdrien Mazarguil 6185886ae07SAdrien Mazarguil if (mbp == NULL) 6195886ae07SAdrien Mazarguil mbp = mbuf_pool_find(0); 6205886ae07SAdrien Mazarguil fwd_lcores[lc_id]->mbp = mbp; 6215886ae07SAdrien Mazarguil } 6225886ae07SAdrien Mazarguil 623ce8d5614SIntel /* Configuration of packet forwarding streams. */ 624ce8d5614SIntel if (init_fwd_streams() < 0) 625ce8d5614SIntel rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 626ce8d5614SIntel } 627ce8d5614SIntel 6282950a769SDeclan Doherty 6292950a769SDeclan Doherty void 6302950a769SDeclan Doherty reconfig(portid_t new_port_id) 6312950a769SDeclan Doherty { 6322950a769SDeclan Doherty struct rte_port *port; 6332950a769SDeclan Doherty 6342950a769SDeclan Doherty /* Reconfiguration of Ethernet ports. */ 6352950a769SDeclan Doherty ports = rte_realloc(ports, 6362950a769SDeclan Doherty sizeof(struct rte_port) * nb_ports, 6372950a769SDeclan Doherty CACHE_LINE_SIZE); 6382950a769SDeclan Doherty if (ports == NULL) { 6392950a769SDeclan Doherty rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n", 6402950a769SDeclan Doherty nb_ports); 6412950a769SDeclan Doherty } 6422950a769SDeclan Doherty 6432950a769SDeclan Doherty port = &ports[new_port_id]; 6442950a769SDeclan Doherty rte_eth_dev_info_get(new_port_id, &port->dev_info); 6452950a769SDeclan Doherty 6462950a769SDeclan Doherty /* set flag to initialize port/queue */ 6472950a769SDeclan Doherty port->need_reconfig = 1; 6482950a769SDeclan Doherty port->need_reconfig_queues = 1; 6492950a769SDeclan Doherty 6502950a769SDeclan Doherty init_port_config(); 6512950a769SDeclan Doherty } 6522950a769SDeclan Doherty 6532950a769SDeclan Doherty 654ce8d5614SIntel int 655ce8d5614SIntel init_fwd_streams(void) 656ce8d5614SIntel { 657ce8d5614SIntel portid_t pid; 658ce8d5614SIntel struct rte_port *port; 659ce8d5614SIntel streamid_t sm_id, nb_fwd_streams_new; 660ce8d5614SIntel 661ce8d5614SIntel /* set socket id according to numa or not */ 662ce8d5614SIntel for (pid = 0; pid < nb_ports; pid++) { 663ce8d5614SIntel port = &ports[pid]; 664ce8d5614SIntel if (nb_rxq > port->dev_info.max_rx_queues) { 665ce8d5614SIntel printf("Fail: nb_rxq(%d) is greater than " 666ce8d5614SIntel "max_rx_queues(%d)\n", nb_rxq, 667ce8d5614SIntel port->dev_info.max_rx_queues); 668ce8d5614SIntel return -1; 669ce8d5614SIntel } 670ce8d5614SIntel if (nb_txq > port->dev_info.max_tx_queues) { 671ce8d5614SIntel printf("Fail: nb_txq(%d) is greater than " 672ce8d5614SIntel "max_tx_queues(%d)\n", nb_txq, 673ce8d5614SIntel port->dev_info.max_tx_queues); 674ce8d5614SIntel return -1; 675ce8d5614SIntel } 67620a0286fSLiu Xiaofeng if (numa_support) { 67720a0286fSLiu Xiaofeng if (port_numa[pid] != NUMA_NO_CONFIG) 67820a0286fSLiu Xiaofeng port->socket_id = port_numa[pid]; 67920a0286fSLiu Xiaofeng else { 680b6ea6408SIntel port->socket_id = rte_eth_dev_socket_id(pid); 68120a0286fSLiu Xiaofeng 68220a0286fSLiu Xiaofeng /* if socket_id is invalid, set to 0 */ 68320a0286fSLiu Xiaofeng if (check_socket_id(port->socket_id) < 0) 68420a0286fSLiu Xiaofeng port->socket_id = 0; 68520a0286fSLiu Xiaofeng } 68620a0286fSLiu Xiaofeng } 687b6ea6408SIntel else { 688b6ea6408SIntel if (socket_num == UMA_NO_CONFIG) 689af75078fSIntel port->socket_id = 0; 690b6ea6408SIntel else 691b6ea6408SIntel port->socket_id = socket_num; 692b6ea6408SIntel } 693af75078fSIntel } 694af75078fSIntel 695ce8d5614SIntel nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq); 696ce8d5614SIntel if (nb_fwd_streams_new == nb_fwd_streams) 697ce8d5614SIntel return 0; 698ce8d5614SIntel /* clear the old */ 699ce8d5614SIntel if (fwd_streams != NULL) { 700ce8d5614SIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 701ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 702ce8d5614SIntel continue; 703ce8d5614SIntel rte_free(fwd_streams[sm_id]); 704ce8d5614SIntel fwd_streams[sm_id] = NULL; 705af75078fSIntel } 706ce8d5614SIntel rte_free(fwd_streams); 707ce8d5614SIntel fwd_streams = NULL; 708ce8d5614SIntel } 709ce8d5614SIntel 710ce8d5614SIntel /* init new */ 711ce8d5614SIntel nb_fwd_streams = nb_fwd_streams_new; 712ce8d5614SIntel fwd_streams = rte_zmalloc("testpmd: fwd_streams", 713ce8d5614SIntel sizeof(struct fwd_stream *) * nb_fwd_streams, CACHE_LINE_SIZE); 714ce8d5614SIntel if (fwd_streams == NULL) 715ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " 716ce8d5614SIntel "failed\n", nb_fwd_streams); 717ce8d5614SIntel 718af75078fSIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 719af75078fSIntel fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", 720ce8d5614SIntel sizeof(struct fwd_stream), CACHE_LINE_SIZE); 721ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 722ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" 723ce8d5614SIntel " failed\n"); 724af75078fSIntel } 725ce8d5614SIntel 726ce8d5614SIntel return 0; 727af75078fSIntel } 728af75078fSIntel 729af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 730af75078fSIntel static void 731af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 732af75078fSIntel { 733af75078fSIntel unsigned int total_burst; 734af75078fSIntel unsigned int nb_burst; 735af75078fSIntel unsigned int burst_stats[3]; 736af75078fSIntel uint16_t pktnb_stats[3]; 737af75078fSIntel uint16_t nb_pkt; 738af75078fSIntel int burst_percent[3]; 739af75078fSIntel 740af75078fSIntel /* 741af75078fSIntel * First compute the total number of packet bursts and the 742af75078fSIntel * two highest numbers of bursts of the same number of packets. 743af75078fSIntel */ 744af75078fSIntel total_burst = 0; 745af75078fSIntel burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 746af75078fSIntel pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 747af75078fSIntel for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 748af75078fSIntel nb_burst = pbs->pkt_burst_spread[nb_pkt]; 749af75078fSIntel if (nb_burst == 0) 750af75078fSIntel continue; 751af75078fSIntel total_burst += nb_burst; 752af75078fSIntel if (nb_burst > burst_stats[0]) { 753af75078fSIntel burst_stats[1] = burst_stats[0]; 754af75078fSIntel pktnb_stats[1] = pktnb_stats[0]; 755af75078fSIntel burst_stats[0] = nb_burst; 756af75078fSIntel pktnb_stats[0] = nb_pkt; 757af75078fSIntel } 758af75078fSIntel } 759af75078fSIntel if (total_burst == 0) 760af75078fSIntel return; 761af75078fSIntel burst_percent[0] = (burst_stats[0] * 100) / total_burst; 762af75078fSIntel printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 763af75078fSIntel burst_percent[0], (int) pktnb_stats[0]); 764af75078fSIntel if (burst_stats[0] == total_burst) { 765af75078fSIntel printf("]\n"); 766af75078fSIntel return; 767af75078fSIntel } 768af75078fSIntel if (burst_stats[0] + burst_stats[1] == total_burst) { 769af75078fSIntel printf(" + %d%% of %d pkts]\n", 770af75078fSIntel 100 - burst_percent[0], pktnb_stats[1]); 771af75078fSIntel return; 772af75078fSIntel } 773af75078fSIntel burst_percent[1] = (burst_stats[1] * 100) / total_burst; 774af75078fSIntel burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 775af75078fSIntel if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 776af75078fSIntel printf(" + %d%% of others]\n", 100 - burst_percent[0]); 777af75078fSIntel return; 778af75078fSIntel } 779af75078fSIntel printf(" + %d%% of %d pkts + %d%% of others]\n", 780af75078fSIntel burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 781af75078fSIntel } 782af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 783af75078fSIntel 784af75078fSIntel static void 785af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) 786af75078fSIntel { 787af75078fSIntel struct rte_port *port; 788013af9b6SIntel uint8_t i; 789af75078fSIntel 790af75078fSIntel static const char *fwd_stats_border = "----------------------"; 791af75078fSIntel 792af75078fSIntel port = &ports[port_id]; 793af75078fSIntel printf("\n %s Forward statistics for port %-2d %s\n", 794af75078fSIntel fwd_stats_border, port_id, fwd_stats_border); 795013af9b6SIntel 796013af9b6SIntel if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 797af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 798af75078fSIntel "%-"PRIu64"\n", 79970bdb186SIvan Boule stats->ipackets, stats->imissed, 80070bdb186SIvan Boule (uint64_t) (stats->ipackets + stats->imissed)); 801af75078fSIntel 802af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) 803af75078fSIntel printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n", 804af75078fSIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 80570bdb186SIvan Boule if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) { 80670bdb186SIvan Boule printf(" RX-badcrc: %-14"PRIu64" RX-badlen: %-14"PRIu64 80770bdb186SIvan Boule "RX-error: %-"PRIu64"\n", 80870bdb186SIvan Boule stats->ibadcrc, stats->ibadlen, stats->ierrors); 80970bdb186SIvan Boule printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf); 81070bdb186SIvan Boule } 811af75078fSIntel 812af75078fSIntel printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 813af75078fSIntel "%-"PRIu64"\n", 814af75078fSIntel stats->opackets, port->tx_dropped, 815af75078fSIntel (uint64_t) (stats->opackets + port->tx_dropped)); 816013af9b6SIntel } 817013af9b6SIntel else { 818013af9b6SIntel printf(" RX-packets: %14"PRIu64" RX-dropped:%14"PRIu64" RX-total:" 819013af9b6SIntel "%14"PRIu64"\n", 82070bdb186SIvan Boule stats->ipackets, stats->imissed, 82170bdb186SIvan Boule (uint64_t) (stats->ipackets + stats->imissed)); 822013af9b6SIntel 823013af9b6SIntel if (cur_fwd_eng == &csum_fwd_engine) 824013af9b6SIntel printf(" Bad-ipcsum:%14"PRIu64" Bad-l4csum:%14"PRIu64"\n", 825013af9b6SIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 82670bdb186SIvan Boule if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) { 82770bdb186SIvan Boule printf(" RX-badcrc: %14"PRIu64" RX-badlen: %14"PRIu64 82870bdb186SIvan Boule " RX-error:%"PRIu64"\n", 82970bdb186SIvan Boule stats->ibadcrc, stats->ibadlen, stats->ierrors); 83070bdb186SIvan Boule printf(" RX-nombufs: %14"PRIu64"\n", 83170bdb186SIvan Boule stats->rx_nombuf); 83270bdb186SIvan Boule } 833013af9b6SIntel 834013af9b6SIntel printf(" TX-packets: %14"PRIu64" TX-dropped:%14"PRIu64" TX-total:" 835013af9b6SIntel "%14"PRIu64"\n", 836013af9b6SIntel stats->opackets, port->tx_dropped, 837013af9b6SIntel (uint64_t) (stats->opackets + port->tx_dropped)); 838013af9b6SIntel } 839e659b6b4SIvan Boule 840e659b6b4SIvan Boule /* Display statistics of XON/XOFF pause frames, if any. */ 841e659b6b4SIvan Boule if ((stats->tx_pause_xon | stats->rx_pause_xon | 842e659b6b4SIvan Boule stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) { 843e659b6b4SIvan Boule printf(" RX-XOFF: %-14"PRIu64" RX-XON: %-14"PRIu64"\n", 844e659b6b4SIvan Boule stats->rx_pause_xoff, stats->rx_pause_xon); 845e659b6b4SIvan Boule printf(" TX-XOFF: %-14"PRIu64" TX-XON: %-14"PRIu64"\n", 846e659b6b4SIvan Boule stats->tx_pause_xoff, stats->tx_pause_xon); 847e659b6b4SIvan Boule } 848e659b6b4SIvan Boule 849af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 850af75078fSIntel if (port->rx_stream) 851013af9b6SIntel pkt_burst_stats_display("RX", 852013af9b6SIntel &port->rx_stream->rx_burst_stats); 853af75078fSIntel if (port->tx_stream) 854013af9b6SIntel pkt_burst_stats_display("TX", 855013af9b6SIntel &port->tx_stream->tx_burst_stats); 856af75078fSIntel #endif 857af75078fSIntel /* stats fdir */ 858af75078fSIntel if (fdir_conf.mode != RTE_FDIR_MODE_NONE) 859013af9b6SIntel printf(" Fdirmiss:%14"PRIu64" Fdirmatch:%14"PRIu64"\n", 860af75078fSIntel stats->fdirmiss, 861af75078fSIntel stats->fdirmatch); 862af75078fSIntel 863013af9b6SIntel if (port->rx_queue_stats_mapping_enabled) { 864013af9b6SIntel printf("\n"); 865013af9b6SIntel for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 866013af9b6SIntel printf(" Stats reg %2d RX-packets:%14"PRIu64 867013af9b6SIntel " RX-errors:%14"PRIu64 868013af9b6SIntel " RX-bytes:%14"PRIu64"\n", 869013af9b6SIntel i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]); 870013af9b6SIntel } 871013af9b6SIntel printf("\n"); 872013af9b6SIntel } 873013af9b6SIntel if (port->tx_queue_stats_mapping_enabled) { 874013af9b6SIntel for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 875013af9b6SIntel printf(" Stats reg %2d TX-packets:%14"PRIu64 876013af9b6SIntel " TX-bytes:%14"PRIu64"\n", 877013af9b6SIntel i, stats->q_opackets[i], stats->q_obytes[i]); 878013af9b6SIntel } 879013af9b6SIntel } 880013af9b6SIntel 881af75078fSIntel printf(" %s--------------------------------%s\n", 882af75078fSIntel fwd_stats_border, fwd_stats_border); 883af75078fSIntel } 884af75078fSIntel 885af75078fSIntel static void 886af75078fSIntel fwd_stream_stats_display(streamid_t stream_id) 887af75078fSIntel { 888af75078fSIntel struct fwd_stream *fs; 889af75078fSIntel static const char *fwd_top_stats_border = "-------"; 890af75078fSIntel 891af75078fSIntel fs = fwd_streams[stream_id]; 892af75078fSIntel if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 893af75078fSIntel (fs->fwd_dropped == 0)) 894af75078fSIntel return; 895af75078fSIntel printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 896af75078fSIntel "TX Port=%2d/Queue=%2d %s\n", 897af75078fSIntel fwd_top_stats_border, fs->rx_port, fs->rx_queue, 898af75078fSIntel fs->tx_port, fs->tx_queue, fwd_top_stats_border); 899af75078fSIntel printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u", 900af75078fSIntel fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 901af75078fSIntel 902af75078fSIntel /* if checksum mode */ 903af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) { 904013af9b6SIntel printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: " 905013af9b6SIntel "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum); 906af75078fSIntel } 907af75078fSIntel 908af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 909af75078fSIntel pkt_burst_stats_display("RX", &fs->rx_burst_stats); 910af75078fSIntel pkt_burst_stats_display("TX", &fs->tx_burst_stats); 911af75078fSIntel #endif 912af75078fSIntel } 913af75078fSIntel 914af75078fSIntel static void 9157741e4cfSIntel flush_fwd_rx_queues(void) 916af75078fSIntel { 917af75078fSIntel struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 918af75078fSIntel portid_t rxp; 9197741e4cfSIntel portid_t port_id; 920af75078fSIntel queueid_t rxq; 921af75078fSIntel uint16_t nb_rx; 922af75078fSIntel uint16_t i; 923af75078fSIntel uint8_t j; 924af75078fSIntel 925af75078fSIntel for (j = 0; j < 2; j++) { 9267741e4cfSIntel for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { 927af75078fSIntel for (rxq = 0; rxq < nb_rxq; rxq++) { 9287741e4cfSIntel port_id = fwd_ports_ids[rxp]; 929af75078fSIntel do { 9307741e4cfSIntel nb_rx = rte_eth_rx_burst(port_id, rxq, 931013af9b6SIntel pkts_burst, MAX_PKT_BURST); 932af75078fSIntel for (i = 0; i < nb_rx; i++) 933af75078fSIntel rte_pktmbuf_free(pkts_burst[i]); 934af75078fSIntel } while (nb_rx > 0); 935af75078fSIntel } 936af75078fSIntel } 937af75078fSIntel rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 938af75078fSIntel } 939af75078fSIntel } 940af75078fSIntel 941af75078fSIntel static void 942af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 943af75078fSIntel { 944af75078fSIntel struct fwd_stream **fsm; 945af75078fSIntel streamid_t nb_fs; 946af75078fSIntel streamid_t sm_id; 947af75078fSIntel 948af75078fSIntel fsm = &fwd_streams[fc->stream_idx]; 949af75078fSIntel nb_fs = fc->stream_nb; 950af75078fSIntel do { 951af75078fSIntel for (sm_id = 0; sm_id < nb_fs; sm_id++) 952af75078fSIntel (*pkt_fwd)(fsm[sm_id]); 953af75078fSIntel } while (! fc->stopped); 954af75078fSIntel } 955af75078fSIntel 956af75078fSIntel static int 957af75078fSIntel start_pkt_forward_on_core(void *fwd_arg) 958af75078fSIntel { 959af75078fSIntel run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 960af75078fSIntel cur_fwd_config.fwd_eng->packet_fwd); 961af75078fSIntel return 0; 962af75078fSIntel } 963af75078fSIntel 964af75078fSIntel /* 965af75078fSIntel * Run the TXONLY packet forwarding engine to send a single burst of packets. 966af75078fSIntel * Used to start communication flows in network loopback test configurations. 967af75078fSIntel */ 968af75078fSIntel static int 969af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg) 970af75078fSIntel { 971af75078fSIntel struct fwd_lcore *fwd_lc; 972af75078fSIntel struct fwd_lcore tmp_lcore; 973af75078fSIntel 974af75078fSIntel fwd_lc = (struct fwd_lcore *) fwd_arg; 975af75078fSIntel tmp_lcore = *fwd_lc; 976af75078fSIntel tmp_lcore.stopped = 1; 977af75078fSIntel run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 978af75078fSIntel return 0; 979af75078fSIntel } 980af75078fSIntel 981af75078fSIntel /* 982af75078fSIntel * Launch packet forwarding: 983af75078fSIntel * - Setup per-port forwarding context. 984af75078fSIntel * - launch logical cores with their forwarding configuration. 985af75078fSIntel */ 986af75078fSIntel static void 987af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 988af75078fSIntel { 989af75078fSIntel port_fwd_begin_t port_fwd_begin; 990af75078fSIntel unsigned int i; 991af75078fSIntel unsigned int lc_id; 992af75078fSIntel int diag; 993af75078fSIntel 994af75078fSIntel port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 995af75078fSIntel if (port_fwd_begin != NULL) { 996af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 997af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 998af75078fSIntel } 999af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 1000af75078fSIntel lc_id = fwd_lcores_cpuids[i]; 1001af75078fSIntel if ((interactive == 0) || (lc_id != rte_lcore_id())) { 1002af75078fSIntel fwd_lcores[i]->stopped = 0; 1003af75078fSIntel diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 1004af75078fSIntel fwd_lcores[i], lc_id); 1005af75078fSIntel if (diag != 0) 1006af75078fSIntel printf("launch lcore %u failed - diag=%d\n", 1007af75078fSIntel lc_id, diag); 1008af75078fSIntel } 1009af75078fSIntel } 1010af75078fSIntel } 1011af75078fSIntel 1012af75078fSIntel /* 1013af75078fSIntel * Launch packet forwarding configuration. 1014af75078fSIntel */ 1015af75078fSIntel void 1016af75078fSIntel start_packet_forwarding(int with_tx_first) 1017af75078fSIntel { 1018af75078fSIntel port_fwd_begin_t port_fwd_begin; 1019af75078fSIntel port_fwd_end_t port_fwd_end; 1020af75078fSIntel struct rte_port *port; 1021af75078fSIntel unsigned int i; 1022af75078fSIntel portid_t pt_id; 1023af75078fSIntel streamid_t sm_id; 1024af75078fSIntel 1025ce8d5614SIntel if (all_ports_started() == 0) { 1026ce8d5614SIntel printf("Not all ports were started\n"); 1027ce8d5614SIntel return; 1028ce8d5614SIntel } 1029af75078fSIntel if (test_done == 0) { 1030af75078fSIntel printf("Packet forwarding already started\n"); 1031af75078fSIntel return; 1032af75078fSIntel } 10337741e4cfSIntel if(dcb_test) { 10347741e4cfSIntel for (i = 0; i < nb_fwd_ports; i++) { 10357741e4cfSIntel pt_id = fwd_ports_ids[i]; 10367741e4cfSIntel port = &ports[pt_id]; 10377741e4cfSIntel if (!port->dcb_flag) { 10387741e4cfSIntel printf("In DCB mode, all forwarding ports must " 10397741e4cfSIntel "be configured in this mode.\n"); 1040013af9b6SIntel return; 1041013af9b6SIntel } 10427741e4cfSIntel } 10437741e4cfSIntel if (nb_fwd_lcores == 1) { 10447741e4cfSIntel printf("In DCB mode,the nb forwarding cores " 10457741e4cfSIntel "should be larger than 1.\n"); 10467741e4cfSIntel return; 10477741e4cfSIntel } 10487741e4cfSIntel } 1049af75078fSIntel test_done = 0; 10507741e4cfSIntel 10517741e4cfSIntel if(!no_flush_rx) 10527741e4cfSIntel flush_fwd_rx_queues(); 10537741e4cfSIntel 1054af75078fSIntel fwd_config_setup(); 1055af75078fSIntel rxtx_config_display(); 1056af75078fSIntel 1057af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1058af75078fSIntel pt_id = fwd_ports_ids[i]; 1059af75078fSIntel port = &ports[pt_id]; 1060af75078fSIntel rte_eth_stats_get(pt_id, &port->stats); 1061af75078fSIntel port->tx_dropped = 0; 1062013af9b6SIntel 1063013af9b6SIntel map_port_queue_stats_mapping_registers(pt_id, port); 1064af75078fSIntel } 1065af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1066af75078fSIntel fwd_streams[sm_id]->rx_packets = 0; 1067af75078fSIntel fwd_streams[sm_id]->tx_packets = 0; 1068af75078fSIntel fwd_streams[sm_id]->fwd_dropped = 0; 1069af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum = 0; 1070af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum = 0; 1071af75078fSIntel 1072af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1073af75078fSIntel memset(&fwd_streams[sm_id]->rx_burst_stats, 0, 1074af75078fSIntel sizeof(fwd_streams[sm_id]->rx_burst_stats)); 1075af75078fSIntel memset(&fwd_streams[sm_id]->tx_burst_stats, 0, 1076af75078fSIntel sizeof(fwd_streams[sm_id]->tx_burst_stats)); 1077af75078fSIntel #endif 1078af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1079af75078fSIntel fwd_streams[sm_id]->core_cycles = 0; 1080af75078fSIntel #endif 1081af75078fSIntel } 1082af75078fSIntel if (with_tx_first) { 1083af75078fSIntel port_fwd_begin = tx_only_engine.port_fwd_begin; 1084af75078fSIntel if (port_fwd_begin != NULL) { 1085af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1086af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 1087af75078fSIntel } 1088af75078fSIntel launch_packet_forwarding(run_one_txonly_burst_on_core); 1089af75078fSIntel rte_eal_mp_wait_lcore(); 1090af75078fSIntel port_fwd_end = tx_only_engine.port_fwd_end; 1091af75078fSIntel if (port_fwd_end != NULL) { 1092af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1093af75078fSIntel (*port_fwd_end)(fwd_ports_ids[i]); 1094af75078fSIntel } 1095af75078fSIntel } 1096af75078fSIntel launch_packet_forwarding(start_pkt_forward_on_core); 1097af75078fSIntel } 1098af75078fSIntel 1099af75078fSIntel void 1100af75078fSIntel stop_packet_forwarding(void) 1101af75078fSIntel { 1102af75078fSIntel struct rte_eth_stats stats; 1103af75078fSIntel struct rte_port *port; 1104af75078fSIntel port_fwd_end_t port_fwd_end; 1105af75078fSIntel int i; 1106af75078fSIntel portid_t pt_id; 1107af75078fSIntel streamid_t sm_id; 1108af75078fSIntel lcoreid_t lc_id; 1109af75078fSIntel uint64_t total_recv; 1110af75078fSIntel uint64_t total_xmit; 1111af75078fSIntel uint64_t total_rx_dropped; 1112af75078fSIntel uint64_t total_tx_dropped; 1113af75078fSIntel uint64_t total_rx_nombuf; 1114af75078fSIntel uint64_t tx_dropped; 1115af75078fSIntel uint64_t rx_bad_ip_csum; 1116af75078fSIntel uint64_t rx_bad_l4_csum; 1117af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1118af75078fSIntel uint64_t fwd_cycles; 1119af75078fSIntel #endif 1120af75078fSIntel static const char *acc_stats_border = "+++++++++++++++"; 1121af75078fSIntel 1122ce8d5614SIntel if (all_ports_started() == 0) { 1123ce8d5614SIntel printf("Not all ports were started\n"); 1124ce8d5614SIntel return; 1125ce8d5614SIntel } 1126af75078fSIntel if (test_done) { 1127af75078fSIntel printf("Packet forwarding not started\n"); 1128af75078fSIntel return; 1129af75078fSIntel } 1130af75078fSIntel printf("Telling cores to stop..."); 1131af75078fSIntel for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 1132af75078fSIntel fwd_lcores[lc_id]->stopped = 1; 1133af75078fSIntel printf("\nWaiting for lcores to finish...\n"); 1134af75078fSIntel rte_eal_mp_wait_lcore(); 1135af75078fSIntel port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 1136af75078fSIntel if (port_fwd_end != NULL) { 1137af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1138af75078fSIntel pt_id = fwd_ports_ids[i]; 1139af75078fSIntel (*port_fwd_end)(pt_id); 1140af75078fSIntel } 1141af75078fSIntel } 1142af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1143af75078fSIntel fwd_cycles = 0; 1144af75078fSIntel #endif 1145af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1146af75078fSIntel if (cur_fwd_config.nb_fwd_streams > 1147af75078fSIntel cur_fwd_config.nb_fwd_ports) { 1148af75078fSIntel fwd_stream_stats_display(sm_id); 1149af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL; 1150af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL; 1151af75078fSIntel } else { 1152af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = 1153af75078fSIntel fwd_streams[sm_id]; 1154af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = 1155af75078fSIntel fwd_streams[sm_id]; 1156af75078fSIntel } 1157af75078fSIntel tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped; 1158af75078fSIntel tx_dropped = (uint64_t) (tx_dropped + 1159af75078fSIntel fwd_streams[sm_id]->fwd_dropped); 1160af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped; 1161af75078fSIntel 1162013af9b6SIntel rx_bad_ip_csum = 1163013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum; 1164af75078fSIntel rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum + 1165af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum); 1166013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = 1167013af9b6SIntel rx_bad_ip_csum; 1168af75078fSIntel 1169013af9b6SIntel rx_bad_l4_csum = 1170013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum; 1171af75078fSIntel rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum + 1172af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum); 1173013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = 1174013af9b6SIntel rx_bad_l4_csum; 1175af75078fSIntel 1176af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1177af75078fSIntel fwd_cycles = (uint64_t) (fwd_cycles + 1178af75078fSIntel fwd_streams[sm_id]->core_cycles); 1179af75078fSIntel #endif 1180af75078fSIntel } 1181af75078fSIntel total_recv = 0; 1182af75078fSIntel total_xmit = 0; 1183af75078fSIntel total_rx_dropped = 0; 1184af75078fSIntel total_tx_dropped = 0; 1185af75078fSIntel total_rx_nombuf = 0; 11867741e4cfSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1187af75078fSIntel pt_id = fwd_ports_ids[i]; 1188af75078fSIntel 1189af75078fSIntel port = &ports[pt_id]; 1190af75078fSIntel rte_eth_stats_get(pt_id, &stats); 1191af75078fSIntel stats.ipackets -= port->stats.ipackets; 1192af75078fSIntel port->stats.ipackets = 0; 1193af75078fSIntel stats.opackets -= port->stats.opackets; 1194af75078fSIntel port->stats.opackets = 0; 1195af75078fSIntel stats.ibytes -= port->stats.ibytes; 1196af75078fSIntel port->stats.ibytes = 0; 1197af75078fSIntel stats.obytes -= port->stats.obytes; 1198af75078fSIntel port->stats.obytes = 0; 119970bdb186SIvan Boule stats.imissed -= port->stats.imissed; 120070bdb186SIvan Boule port->stats.imissed = 0; 1201af75078fSIntel stats.oerrors -= port->stats.oerrors; 1202af75078fSIntel port->stats.oerrors = 0; 1203af75078fSIntel stats.rx_nombuf -= port->stats.rx_nombuf; 1204af75078fSIntel port->stats.rx_nombuf = 0; 1205af75078fSIntel stats.fdirmatch -= port->stats.fdirmatch; 1206af75078fSIntel port->stats.rx_nombuf = 0; 1207af75078fSIntel stats.fdirmiss -= port->stats.fdirmiss; 1208af75078fSIntel port->stats.rx_nombuf = 0; 1209af75078fSIntel 1210af75078fSIntel total_recv += stats.ipackets; 1211af75078fSIntel total_xmit += stats.opackets; 121270bdb186SIvan Boule total_rx_dropped += stats.imissed; 1213af75078fSIntel total_tx_dropped += port->tx_dropped; 1214af75078fSIntel total_rx_nombuf += stats.rx_nombuf; 1215af75078fSIntel 1216af75078fSIntel fwd_port_stats_display(pt_id, &stats); 1217af75078fSIntel } 1218af75078fSIntel printf("\n %s Accumulated forward statistics for all ports" 1219af75078fSIntel "%s\n", 1220af75078fSIntel acc_stats_border, acc_stats_border); 1221af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 1222af75078fSIntel "%-"PRIu64"\n" 1223af75078fSIntel " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 1224af75078fSIntel "%-"PRIu64"\n", 1225af75078fSIntel total_recv, total_rx_dropped, total_recv + total_rx_dropped, 1226af75078fSIntel total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 1227af75078fSIntel if (total_rx_nombuf > 0) 1228af75078fSIntel printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 1229af75078fSIntel printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 1230af75078fSIntel "%s\n", 1231af75078fSIntel acc_stats_border, acc_stats_border); 1232af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1233af75078fSIntel if (total_recv > 0) 1234af75078fSIntel printf("\n CPU cycles/packet=%u (total cycles=" 1235af75078fSIntel "%"PRIu64" / total RX packets=%"PRIu64")\n", 1236af75078fSIntel (unsigned int)(fwd_cycles / total_recv), 1237af75078fSIntel fwd_cycles, total_recv); 1238af75078fSIntel #endif 1239af75078fSIntel printf("\nDone.\n"); 1240af75078fSIntel test_done = 1; 1241af75078fSIntel } 1242af75078fSIntel 1243cfae07fdSOuyang Changchun void 1244cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid) 1245cfae07fdSOuyang Changchun { 1246cfae07fdSOuyang Changchun if (rte_eth_dev_set_link_up((uint8_t)pid) < 0) 1247cfae07fdSOuyang Changchun printf("\nSet link up fail.\n"); 1248cfae07fdSOuyang Changchun } 1249cfae07fdSOuyang Changchun 1250cfae07fdSOuyang Changchun void 1251cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid) 1252cfae07fdSOuyang Changchun { 1253cfae07fdSOuyang Changchun if (rte_eth_dev_set_link_down((uint8_t)pid) < 0) 1254cfae07fdSOuyang Changchun printf("\nSet link down fail.\n"); 1255cfae07fdSOuyang Changchun } 1256cfae07fdSOuyang Changchun 1257ce8d5614SIntel static int 1258ce8d5614SIntel all_ports_started(void) 1259ce8d5614SIntel { 1260ce8d5614SIntel portid_t pi; 1261ce8d5614SIntel struct rte_port *port; 1262ce8d5614SIntel 1263ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1264ce8d5614SIntel port = &ports[pi]; 1265ce8d5614SIntel /* Check if there is a port which is not started */ 1266ce8d5614SIntel if (port->port_status != RTE_PORT_STARTED) 1267ce8d5614SIntel return 0; 1268ce8d5614SIntel } 1269ce8d5614SIntel 1270ce8d5614SIntel /* No port is not started */ 1271ce8d5614SIntel return 1; 1272ce8d5614SIntel } 1273ce8d5614SIntel 1274148f963fSBruce Richardson int 1275ce8d5614SIntel start_port(portid_t pid) 1276ce8d5614SIntel { 1277ce8d5614SIntel int diag, need_check_link_status = 0; 1278ce8d5614SIntel portid_t pi; 1279ce8d5614SIntel queueid_t qi; 1280ce8d5614SIntel struct rte_port *port; 12812950a769SDeclan Doherty struct ether_addr mac_addr; 1282ce8d5614SIntel 1283ce8d5614SIntel if (test_done == 0) { 1284ce8d5614SIntel printf("Please stop forwarding first\n"); 1285148f963fSBruce Richardson return -1; 1286ce8d5614SIntel } 1287ce8d5614SIntel 1288ce8d5614SIntel if (init_fwd_streams() < 0) { 1289ce8d5614SIntel printf("Fail from init_fwd_streams()\n"); 1290148f963fSBruce Richardson return -1; 1291ce8d5614SIntel } 1292ce8d5614SIntel 1293ce8d5614SIntel if(dcb_config) 1294ce8d5614SIntel dcb_test = 1; 1295ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1296ce8d5614SIntel if (pid < nb_ports && pid != pi) 1297ce8d5614SIntel continue; 1298ce8d5614SIntel 1299ce8d5614SIntel port = &ports[pi]; 1300ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 1301ce8d5614SIntel RTE_PORT_HANDLING) == 0) { 1302ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1303ce8d5614SIntel continue; 1304ce8d5614SIntel } 1305ce8d5614SIntel 1306ce8d5614SIntel if (port->need_reconfig > 0) { 1307ce8d5614SIntel port->need_reconfig = 0; 1308ce8d5614SIntel 13095706de65SJulien Cretin printf("Configuring Port %d (socket %u)\n", pi, 131020a0286fSLiu Xiaofeng port->socket_id); 1311ce8d5614SIntel /* configure port */ 1312ce8d5614SIntel diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, 1313ce8d5614SIntel &(port->dev_conf)); 1314ce8d5614SIntel if (diag != 0) { 1315ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1316ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1317ce8d5614SIntel printf("Port %d can not be set back " 1318ce8d5614SIntel "to stopped\n", pi); 1319ce8d5614SIntel printf("Fail to configure port %d\n", pi); 1320ce8d5614SIntel /* try to reconfigure port next time */ 1321ce8d5614SIntel port->need_reconfig = 1; 1322148f963fSBruce Richardson return -1; 1323ce8d5614SIntel } 1324ce8d5614SIntel } 1325ce8d5614SIntel if (port->need_reconfig_queues > 0) { 1326ce8d5614SIntel port->need_reconfig_queues = 0; 1327ce8d5614SIntel /* setup tx queues */ 1328ce8d5614SIntel for (qi = 0; qi < nb_txq; qi++) { 1329b6ea6408SIntel if ((numa_support) && 1330b6ea6408SIntel (txring_numa[pi] != NUMA_NO_CONFIG)) 1331b6ea6408SIntel diag = rte_eth_tx_queue_setup(pi, qi, 1332b6ea6408SIntel nb_txd,txring_numa[pi], 1333b6ea6408SIntel &(port->tx_conf)); 1334b6ea6408SIntel else 1335b6ea6408SIntel diag = rte_eth_tx_queue_setup(pi, qi, 1336b6ea6408SIntel nb_txd,port->socket_id, 1337b6ea6408SIntel &(port->tx_conf)); 1338b6ea6408SIntel 1339ce8d5614SIntel if (diag == 0) 1340ce8d5614SIntel continue; 1341ce8d5614SIntel 1342ce8d5614SIntel /* Fail to setup tx queue, return */ 1343ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1344ce8d5614SIntel RTE_PORT_HANDLING, 1345ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1346ce8d5614SIntel printf("Port %d can not be set back " 1347ce8d5614SIntel "to stopped\n", pi); 1348ce8d5614SIntel printf("Fail to configure port %d tx queues\n", pi); 1349ce8d5614SIntel /* try to reconfigure queues next time */ 1350ce8d5614SIntel port->need_reconfig_queues = 1; 1351148f963fSBruce Richardson return -1; 1352ce8d5614SIntel } 1353ce8d5614SIntel /* setup rx queues */ 1354ce8d5614SIntel for (qi = 0; qi < nb_rxq; qi++) { 1355b6ea6408SIntel if ((numa_support) && 1356b6ea6408SIntel (rxring_numa[pi] != NUMA_NO_CONFIG)) { 1357b6ea6408SIntel struct rte_mempool * mp = 1358b6ea6408SIntel mbuf_pool_find(rxring_numa[pi]); 1359b6ea6408SIntel if (mp == NULL) { 1360b6ea6408SIntel printf("Failed to setup RX queue:" 1361b6ea6408SIntel "No mempool allocation" 1362b6ea6408SIntel "on the socket %d\n", 1363b6ea6408SIntel rxring_numa[pi]); 1364148f963fSBruce Richardson return -1; 1365b6ea6408SIntel } 1366b6ea6408SIntel 1367b6ea6408SIntel diag = rte_eth_rx_queue_setup(pi, qi, 1368b6ea6408SIntel nb_rxd,rxring_numa[pi], 1369b6ea6408SIntel &(port->rx_conf),mp); 1370b6ea6408SIntel } 1371b6ea6408SIntel else 1372b6ea6408SIntel diag = rte_eth_rx_queue_setup(pi, qi, 1373b6ea6408SIntel nb_rxd,port->socket_id, 1374b6ea6408SIntel &(port->rx_conf), 1375ce8d5614SIntel mbuf_pool_find(port->socket_id)); 1376b6ea6408SIntel 1377ce8d5614SIntel if (diag == 0) 1378ce8d5614SIntel continue; 1379ce8d5614SIntel 1380b6ea6408SIntel 1381ce8d5614SIntel /* Fail to setup rx queue, return */ 1382ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1383ce8d5614SIntel RTE_PORT_HANDLING, 1384ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1385ce8d5614SIntel printf("Port %d can not be set back " 1386ce8d5614SIntel "to stopped\n", pi); 1387ce8d5614SIntel printf("Fail to configure port %d rx queues\n", pi); 1388ce8d5614SIntel /* try to reconfigure queues next time */ 1389ce8d5614SIntel port->need_reconfig_queues = 1; 1390148f963fSBruce Richardson return -1; 1391ce8d5614SIntel } 1392ce8d5614SIntel } 1393ce8d5614SIntel /* start port */ 1394ce8d5614SIntel if (rte_eth_dev_start(pi) < 0) { 1395ce8d5614SIntel printf("Fail to start port %d\n", pi); 1396ce8d5614SIntel 1397ce8d5614SIntel /* Fail to setup rx queue, return */ 1398ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1399ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1400ce8d5614SIntel printf("Port %d can not be set back to " 1401ce8d5614SIntel "stopped\n", pi); 1402ce8d5614SIntel continue; 1403ce8d5614SIntel } 1404ce8d5614SIntel 1405ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1406ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 1407ce8d5614SIntel printf("Port %d can not be set into started\n", pi); 1408ce8d5614SIntel 14092950a769SDeclan Doherty rte_eth_macaddr_get(pi, &mac_addr); 1410d8c89163SZijie Pan printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, 14112950a769SDeclan Doherty mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 14122950a769SDeclan Doherty mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 14132950a769SDeclan Doherty mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); 1414d8c89163SZijie Pan 1415ce8d5614SIntel /* at least one port started, need checking link status */ 1416ce8d5614SIntel need_check_link_status = 1; 1417ce8d5614SIntel } 1418ce8d5614SIntel 1419bc202406SDavid Marchand if (need_check_link_status && !no_link_check) 1420ce8d5614SIntel check_all_ports_link_status(nb_ports, RTE_PORT_ALL); 1421ce8d5614SIntel else 1422ce8d5614SIntel printf("Please stop the ports first\n"); 1423ce8d5614SIntel 1424ce8d5614SIntel printf("Done\n"); 1425148f963fSBruce Richardson return 0; 1426ce8d5614SIntel } 1427ce8d5614SIntel 1428ce8d5614SIntel void 1429ce8d5614SIntel stop_port(portid_t pid) 1430ce8d5614SIntel { 1431ce8d5614SIntel portid_t pi; 1432ce8d5614SIntel struct rte_port *port; 1433ce8d5614SIntel int need_check_link_status = 0; 1434ce8d5614SIntel 1435ce8d5614SIntel if (test_done == 0) { 1436ce8d5614SIntel printf("Please stop forwarding first\n"); 1437ce8d5614SIntel return; 1438ce8d5614SIntel } 1439ce8d5614SIntel if (dcb_test) { 1440ce8d5614SIntel dcb_test = 0; 1441ce8d5614SIntel dcb_config = 0; 1442ce8d5614SIntel } 1443ce8d5614SIntel printf("Stopping ports...\n"); 1444ce8d5614SIntel 1445ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1446ce8d5614SIntel if (pid < nb_ports && pid != pi) 1447ce8d5614SIntel continue; 1448ce8d5614SIntel 1449ce8d5614SIntel port = &ports[pi]; 1450ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 1451ce8d5614SIntel RTE_PORT_HANDLING) == 0) 1452ce8d5614SIntel continue; 1453ce8d5614SIntel 1454ce8d5614SIntel rte_eth_dev_stop(pi); 1455ce8d5614SIntel 1456ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1457ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1458ce8d5614SIntel printf("Port %d can not be set into stopped\n", pi); 1459ce8d5614SIntel need_check_link_status = 1; 1460ce8d5614SIntel } 1461bc202406SDavid Marchand if (need_check_link_status && !no_link_check) 1462ce8d5614SIntel check_all_ports_link_status(nb_ports, RTE_PORT_ALL); 1463ce8d5614SIntel 1464ce8d5614SIntel printf("Done\n"); 1465ce8d5614SIntel } 1466ce8d5614SIntel 1467ce8d5614SIntel void 1468ce8d5614SIntel close_port(portid_t pid) 1469ce8d5614SIntel { 1470ce8d5614SIntel portid_t pi; 1471ce8d5614SIntel struct rte_port *port; 1472ce8d5614SIntel 1473ce8d5614SIntel if (test_done == 0) { 1474ce8d5614SIntel printf("Please stop forwarding first\n"); 1475ce8d5614SIntel return; 1476ce8d5614SIntel } 1477ce8d5614SIntel 1478ce8d5614SIntel printf("Closing ports...\n"); 1479ce8d5614SIntel 1480ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1481ce8d5614SIntel if (pid < nb_ports && pid != pi) 1482ce8d5614SIntel continue; 1483ce8d5614SIntel 1484ce8d5614SIntel port = &ports[pi]; 1485ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1486ce8d5614SIntel RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 1487ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1488ce8d5614SIntel continue; 1489ce8d5614SIntel } 1490ce8d5614SIntel 1491ce8d5614SIntel rte_eth_dev_close(pi); 1492ce8d5614SIntel 1493ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1494ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 1495ce8d5614SIntel printf("Port %d can not be set into stopped\n", pi); 1496ce8d5614SIntel } 1497ce8d5614SIntel 1498ce8d5614SIntel printf("Done\n"); 1499ce8d5614SIntel } 1500ce8d5614SIntel 1501ce8d5614SIntel int 1502ce8d5614SIntel all_ports_stopped(void) 1503ce8d5614SIntel { 1504ce8d5614SIntel portid_t pi; 1505ce8d5614SIntel struct rte_port *port; 1506ce8d5614SIntel 1507ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1508ce8d5614SIntel port = &ports[pi]; 1509ce8d5614SIntel if (port->port_status != RTE_PORT_STOPPED) 1510ce8d5614SIntel return 0; 1511ce8d5614SIntel } 1512ce8d5614SIntel 1513ce8d5614SIntel return 1; 1514ce8d5614SIntel } 1515ce8d5614SIntel 15165f4ec54fSChen Jing D(Mark) int 15175f4ec54fSChen Jing D(Mark) port_is_started(portid_t port_id) 15185f4ec54fSChen Jing D(Mark) { 15195f4ec54fSChen Jing D(Mark) if (port_id_is_invalid(port_id)) 15205f4ec54fSChen Jing D(Mark) return -1; 15215f4ec54fSChen Jing D(Mark) 15225f4ec54fSChen Jing D(Mark) if (ports[port_id].port_status != RTE_PORT_STARTED) 15235f4ec54fSChen Jing D(Mark) return 0; 15245f4ec54fSChen Jing D(Mark) 15255f4ec54fSChen Jing D(Mark) return 1; 15265f4ec54fSChen Jing D(Mark) } 15275f4ec54fSChen Jing D(Mark) 1528af75078fSIntel void 1529af75078fSIntel pmd_test_exit(void) 1530af75078fSIntel { 1531af75078fSIntel portid_t pt_id; 1532af75078fSIntel 1533af75078fSIntel for (pt_id = 0; pt_id < nb_ports; pt_id++) { 1534af75078fSIntel printf("Stopping port %d...", pt_id); 1535af75078fSIntel fflush(stdout); 1536af75078fSIntel rte_eth_dev_close(pt_id); 1537af75078fSIntel printf("done\n"); 1538af75078fSIntel } 1539af75078fSIntel printf("bye...\n"); 1540af75078fSIntel } 1541af75078fSIntel 1542af75078fSIntel typedef void (*cmd_func_t)(void); 1543af75078fSIntel struct pmd_test_command { 1544af75078fSIntel const char *cmd_name; 1545af75078fSIntel cmd_func_t cmd_func; 1546af75078fSIntel }; 1547af75078fSIntel 1548af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) 1549af75078fSIntel 1550ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */ 1551af75078fSIntel static void 1552ce8d5614SIntel check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) 1553af75078fSIntel { 1554ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */ 1555ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1556ce8d5614SIntel uint8_t portid, count, all_ports_up, print_flag = 0; 1557ce8d5614SIntel struct rte_eth_link link; 1558ce8d5614SIntel 1559ce8d5614SIntel printf("Checking link statuses...\n"); 1560ce8d5614SIntel fflush(stdout); 1561ce8d5614SIntel for (count = 0; count <= MAX_CHECK_TIME; count++) { 1562ce8d5614SIntel all_ports_up = 1; 1563ce8d5614SIntel for (portid = 0; portid < port_num; portid++) { 1564ce8d5614SIntel if ((port_mask & (1 << portid)) == 0) 1565ce8d5614SIntel continue; 1566ce8d5614SIntel memset(&link, 0, sizeof(link)); 1567ce8d5614SIntel rte_eth_link_get_nowait(portid, &link); 1568ce8d5614SIntel /* print link status if flag set */ 1569ce8d5614SIntel if (print_flag == 1) { 1570ce8d5614SIntel if (link.link_status) 1571ce8d5614SIntel printf("Port %d Link Up - speed %u " 1572ce8d5614SIntel "Mbps - %s\n", (uint8_t)portid, 1573ce8d5614SIntel (unsigned)link.link_speed, 1574ce8d5614SIntel (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1575ce8d5614SIntel ("full-duplex") : ("half-duplex\n")); 1576ce8d5614SIntel else 1577ce8d5614SIntel printf("Port %d Link Down\n", 1578ce8d5614SIntel (uint8_t)portid); 1579ce8d5614SIntel continue; 1580ce8d5614SIntel } 1581ce8d5614SIntel /* clear all_ports_up flag if any link down */ 1582ce8d5614SIntel if (link.link_status == 0) { 1583ce8d5614SIntel all_ports_up = 0; 1584ce8d5614SIntel break; 1585ce8d5614SIntel } 1586ce8d5614SIntel } 1587ce8d5614SIntel /* after finally printing all link status, get out */ 1588ce8d5614SIntel if (print_flag == 1) 1589ce8d5614SIntel break; 1590ce8d5614SIntel 1591ce8d5614SIntel if (all_ports_up == 0) { 1592ce8d5614SIntel fflush(stdout); 1593ce8d5614SIntel rte_delay_ms(CHECK_INTERVAL); 1594ce8d5614SIntel } 1595ce8d5614SIntel 1596ce8d5614SIntel /* set the print_flag if all ports up or timeout */ 1597ce8d5614SIntel if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1598ce8d5614SIntel print_flag = 1; 1599ce8d5614SIntel } 1600ce8d5614SIntel } 1601af75078fSIntel } 1602af75078fSIntel 1603013af9b6SIntel static int 1604013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) 1605af75078fSIntel { 1606013af9b6SIntel uint16_t i; 1607af75078fSIntel int diag; 1608013af9b6SIntel uint8_t mapping_found = 0; 1609af75078fSIntel 1610013af9b6SIntel for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 1611013af9b6SIntel if ((tx_queue_stats_mappings[i].port_id == port_id) && 1612013af9b6SIntel (tx_queue_stats_mappings[i].queue_id < nb_txq )) { 1613013af9b6SIntel diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, 1614013af9b6SIntel tx_queue_stats_mappings[i].queue_id, 1615013af9b6SIntel tx_queue_stats_mappings[i].stats_counter_id); 1616013af9b6SIntel if (diag != 0) 1617013af9b6SIntel return diag; 1618013af9b6SIntel mapping_found = 1; 1619af75078fSIntel } 1620013af9b6SIntel } 1621013af9b6SIntel if (mapping_found) 1622013af9b6SIntel port->tx_queue_stats_mapping_enabled = 1; 1623013af9b6SIntel return 0; 1624013af9b6SIntel } 1625013af9b6SIntel 1626013af9b6SIntel static int 1627013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) 1628013af9b6SIntel { 1629013af9b6SIntel uint16_t i; 1630013af9b6SIntel int diag; 1631013af9b6SIntel uint8_t mapping_found = 0; 1632013af9b6SIntel 1633013af9b6SIntel for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 1634013af9b6SIntel if ((rx_queue_stats_mappings[i].port_id == port_id) && 1635013af9b6SIntel (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { 1636013af9b6SIntel diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, 1637013af9b6SIntel rx_queue_stats_mappings[i].queue_id, 1638013af9b6SIntel rx_queue_stats_mappings[i].stats_counter_id); 1639013af9b6SIntel if (diag != 0) 1640013af9b6SIntel return diag; 1641013af9b6SIntel mapping_found = 1; 1642013af9b6SIntel } 1643013af9b6SIntel } 1644013af9b6SIntel if (mapping_found) 1645013af9b6SIntel port->rx_queue_stats_mapping_enabled = 1; 1646013af9b6SIntel return 0; 1647013af9b6SIntel } 1648013af9b6SIntel 1649013af9b6SIntel static void 1650013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port) 1651013af9b6SIntel { 1652013af9b6SIntel int diag = 0; 1653013af9b6SIntel 1654013af9b6SIntel diag = set_tx_queue_stats_mapping_registers(pi, port); 1655af75078fSIntel if (diag != 0) { 1656013af9b6SIntel if (diag == -ENOTSUP) { 1657013af9b6SIntel port->tx_queue_stats_mapping_enabled = 0; 1658013af9b6SIntel printf("TX queue stats mapping not supported port id=%d\n", pi); 1659013af9b6SIntel } 1660013af9b6SIntel else 1661013af9b6SIntel rte_exit(EXIT_FAILURE, 1662013af9b6SIntel "set_tx_queue_stats_mapping_registers " 1663013af9b6SIntel "failed for port id=%d diag=%d\n", 1664af75078fSIntel pi, diag); 1665af75078fSIntel } 1666013af9b6SIntel 1667013af9b6SIntel diag = set_rx_queue_stats_mapping_registers(pi, port); 1668af75078fSIntel if (diag != 0) { 1669013af9b6SIntel if (diag == -ENOTSUP) { 1670013af9b6SIntel port->rx_queue_stats_mapping_enabled = 0; 1671013af9b6SIntel printf("RX queue stats mapping not supported port id=%d\n", pi); 1672013af9b6SIntel } 1673013af9b6SIntel else 1674013af9b6SIntel rte_exit(EXIT_FAILURE, 1675013af9b6SIntel "set_rx_queue_stats_mapping_registers " 1676013af9b6SIntel "failed for port id=%d diag=%d\n", 1677af75078fSIntel pi, diag); 1678af75078fSIntel } 1679af75078fSIntel } 1680af75078fSIntel 1681013af9b6SIntel void 1682013af9b6SIntel init_port_config(void) 1683013af9b6SIntel { 1684013af9b6SIntel portid_t pid; 1685013af9b6SIntel struct rte_port *port; 1686013af9b6SIntel 1687013af9b6SIntel for (pid = 0; pid < nb_ports; pid++) { 1688013af9b6SIntel port = &ports[pid]; 1689013af9b6SIntel port->dev_conf.rxmode = rx_mode; 1690013af9b6SIntel port->dev_conf.fdir_conf = fdir_conf; 16913ce690d3SBruce Richardson if (nb_rxq > 1) { 1692013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1693013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf; 1694af75078fSIntel } else { 1695013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1696013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; 1697af75078fSIntel } 16983ce690d3SBruce Richardson 16993ce690d3SBruce Richardson /* In SR-IOV mode, RSS mode is not available */ 17003ce690d3SBruce Richardson if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) { 17013ce690d3SBruce Richardson if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 17023ce690d3SBruce Richardson port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 17033ce690d3SBruce Richardson else 17043ce690d3SBruce Richardson port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; 17053ce690d3SBruce Richardson } 17063ce690d3SBruce Richardson 1707013af9b6SIntel port->rx_conf.rx_thresh = rx_thresh; 1708013af9b6SIntel port->rx_conf.rx_free_thresh = rx_free_thresh; 1709013af9b6SIntel port->rx_conf.rx_drop_en = rx_drop_en; 1710013af9b6SIntel port->tx_conf.tx_thresh = tx_thresh; 1711013af9b6SIntel port->tx_conf.tx_rs_thresh = tx_rs_thresh; 1712013af9b6SIntel port->tx_conf.tx_free_thresh = tx_free_thresh; 1713013af9b6SIntel port->tx_conf.txq_flags = txq_flags; 1714013af9b6SIntel 1715013af9b6SIntel rte_eth_macaddr_get(pid, &port->eth_addr); 1716013af9b6SIntel 1717013af9b6SIntel map_port_queue_stats_mapping_registers(pid, port); 17187b7e5ba7SIntel #ifdef RTE_NIC_BYPASS 17197b7e5ba7SIntel rte_eth_dev_bypass_init(pid); 17207b7e5ba7SIntel #endif 1721013af9b6SIntel } 1722013af9b6SIntel } 1723013af9b6SIntel 1724013af9b6SIntel const uint16_t vlan_tags[] = { 1725013af9b6SIntel 0, 1, 2, 3, 4, 5, 6, 7, 1726013af9b6SIntel 8, 9, 10, 11, 12, 13, 14, 15, 1727013af9b6SIntel 16, 17, 18, 19, 20, 21, 22, 23, 1728013af9b6SIntel 24, 25, 26, 27, 28, 29, 30, 31 1729013af9b6SIntel }; 1730013af9b6SIntel 1731013af9b6SIntel static int 1732013af9b6SIntel get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf) 1733013af9b6SIntel { 1734013af9b6SIntel uint8_t i; 1735af75078fSIntel 1736af75078fSIntel /* 1737013af9b6SIntel * Builds up the correct configuration for dcb+vt based on the vlan tags array 1738013af9b6SIntel * given above, and the number of traffic classes available for use. 1739af75078fSIntel */ 1740013af9b6SIntel if (dcb_conf->dcb_mode == DCB_VT_ENABLED) { 1741013af9b6SIntel struct rte_eth_vmdq_dcb_conf vmdq_rx_conf; 1742013af9b6SIntel struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf; 1743013af9b6SIntel 1744013af9b6SIntel /* VMDQ+DCB RX and TX configrations */ 1745013af9b6SIntel vmdq_rx_conf.enable_default_pool = 0; 1746013af9b6SIntel vmdq_rx_conf.default_pool = 0; 1747013af9b6SIntel vmdq_rx_conf.nb_queue_pools = 1748013af9b6SIntel (dcb_conf->num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 1749013af9b6SIntel vmdq_tx_conf.nb_queue_pools = 1750013af9b6SIntel (dcb_conf->num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 1751013af9b6SIntel 1752013af9b6SIntel vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]); 1753013af9b6SIntel for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) { 1754013af9b6SIntel vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ]; 1755013af9b6SIntel vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools); 1756af75078fSIntel } 1757013af9b6SIntel for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 1758013af9b6SIntel vmdq_rx_conf.dcb_queue[i] = i; 1759013af9b6SIntel vmdq_tx_conf.dcb_queue[i] = i; 1760013af9b6SIntel } 1761013af9b6SIntel 1762013af9b6SIntel /*set DCB mode of RX and TX of multiple queues*/ 176332e7aa0bSIntel eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB; 176432e7aa0bSIntel eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB; 1765013af9b6SIntel if (dcb_conf->pfc_en) 1766013af9b6SIntel eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT; 1767013af9b6SIntel else 1768013af9b6SIntel eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 1769013af9b6SIntel 1770013af9b6SIntel (void)(rte_memcpy(ð_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf, 1771013af9b6SIntel sizeof(struct rte_eth_vmdq_dcb_conf))); 1772013af9b6SIntel (void)(rte_memcpy(ð_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf, 1773013af9b6SIntel sizeof(struct rte_eth_vmdq_dcb_tx_conf))); 1774013af9b6SIntel } 1775013af9b6SIntel else { 1776013af9b6SIntel struct rte_eth_dcb_rx_conf rx_conf; 1777013af9b6SIntel struct rte_eth_dcb_tx_conf tx_conf; 1778013af9b6SIntel 1779013af9b6SIntel /* queue mapping configuration of DCB RX and TX */ 1780013af9b6SIntel if (dcb_conf->num_tcs == ETH_4_TCS) 1781013af9b6SIntel dcb_q_mapping = DCB_4_TCS_Q_MAPPING; 1782013af9b6SIntel else 1783013af9b6SIntel dcb_q_mapping = DCB_8_TCS_Q_MAPPING; 1784013af9b6SIntel 1785013af9b6SIntel rx_conf.nb_tcs = dcb_conf->num_tcs; 1786013af9b6SIntel tx_conf.nb_tcs = dcb_conf->num_tcs; 1787013af9b6SIntel 1788013af9b6SIntel for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){ 1789013af9b6SIntel rx_conf.dcb_queue[i] = i; 1790013af9b6SIntel tx_conf.dcb_queue[i] = i; 1791013af9b6SIntel } 179232e7aa0bSIntel eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB; 179332e7aa0bSIntel eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB; 1794013af9b6SIntel if (dcb_conf->pfc_en) 1795013af9b6SIntel eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT; 1796013af9b6SIntel else 1797013af9b6SIntel eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 1798013af9b6SIntel 1799013af9b6SIntel (void)(rte_memcpy(ð_conf->rx_adv_conf.dcb_rx_conf, &rx_conf, 1800013af9b6SIntel sizeof(struct rte_eth_dcb_rx_conf))); 1801013af9b6SIntel (void)(rte_memcpy(ð_conf->tx_adv_conf.dcb_tx_conf, &tx_conf, 1802013af9b6SIntel sizeof(struct rte_eth_dcb_tx_conf))); 1803013af9b6SIntel } 1804013af9b6SIntel 1805013af9b6SIntel return 0; 1806013af9b6SIntel } 1807013af9b6SIntel 1808013af9b6SIntel int 1809013af9b6SIntel init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf) 1810013af9b6SIntel { 1811013af9b6SIntel struct rte_eth_conf port_conf; 1812013af9b6SIntel struct rte_port *rte_port; 1813013af9b6SIntel int retval; 1814013af9b6SIntel uint16_t nb_vlan; 1815013af9b6SIntel uint16_t i; 1816013af9b6SIntel 1817013af9b6SIntel /* rxq and txq configuration in dcb mode */ 1818013af9b6SIntel nb_rxq = 128; 1819013af9b6SIntel nb_txq = 128; 1820013af9b6SIntel rx_free_thresh = 64; 1821013af9b6SIntel 1822013af9b6SIntel memset(&port_conf,0,sizeof(struct rte_eth_conf)); 1823013af9b6SIntel /* Enter DCB configuration status */ 1824013af9b6SIntel dcb_config = 1; 1825013af9b6SIntel 1826013af9b6SIntel nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]); 1827013af9b6SIntel /*set configuration of DCB in vt mode and DCB in non-vt mode*/ 1828013af9b6SIntel retval = get_eth_dcb_conf(&port_conf, dcb_conf); 1829013af9b6SIntel if (retval < 0) 1830013af9b6SIntel return retval; 1831013af9b6SIntel 1832013af9b6SIntel rte_port = &ports[pid]; 1833013af9b6SIntel memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf)); 1834013af9b6SIntel 1835013af9b6SIntel rte_port->rx_conf.rx_thresh = rx_thresh; 1836013af9b6SIntel rte_port->rx_conf.rx_free_thresh = rx_free_thresh; 1837013af9b6SIntel rte_port->tx_conf.tx_thresh = tx_thresh; 1838013af9b6SIntel rte_port->tx_conf.tx_rs_thresh = tx_rs_thresh; 1839013af9b6SIntel rte_port->tx_conf.tx_free_thresh = tx_free_thresh; 1840013af9b6SIntel /* VLAN filter */ 1841013af9b6SIntel rte_port->dev_conf.rxmode.hw_vlan_filter = 1; 1842013af9b6SIntel for (i = 0; i < nb_vlan; i++){ 1843013af9b6SIntel rx_vft_set(pid, vlan_tags[i], 1); 1844013af9b6SIntel } 1845013af9b6SIntel 1846013af9b6SIntel rte_eth_macaddr_get(pid, &rte_port->eth_addr); 1847013af9b6SIntel map_port_queue_stats_mapping_registers(pid, rte_port); 1848013af9b6SIntel 18497741e4cfSIntel rte_port->dcb_flag = 1; 18507741e4cfSIntel 1851013af9b6SIntel return 0; 1852af75078fSIntel } 1853af75078fSIntel 1854af75078fSIntel #ifdef RTE_EXEC_ENV_BAREMETAL 1855af75078fSIntel #define main _main 1856af75078fSIntel #endif 1857af75078fSIntel 1858af75078fSIntel int 1859af75078fSIntel main(int argc, char** argv) 1860af75078fSIntel { 1861af75078fSIntel int diag; 1862013af9b6SIntel uint8_t port_id; 1863af75078fSIntel 1864af75078fSIntel diag = rte_eal_init(argc, argv); 1865af75078fSIntel if (diag < 0) 1866af75078fSIntel rte_panic("Cannot init EAL\n"); 1867af75078fSIntel 1868af75078fSIntel nb_ports = (portid_t) rte_eth_dev_count(); 1869af75078fSIntel if (nb_ports == 0) 1870013af9b6SIntel rte_exit(EXIT_FAILURE, "No probed ethernet devices - " 1871013af9b6SIntel "check that " 1872af75078fSIntel "CONFIG_RTE_LIBRTE_IGB_PMD=y and that " 187369d22b8eSIntel "CONFIG_RTE_LIBRTE_EM_PMD=y and that " 1874af75078fSIntel "CONFIG_RTE_LIBRTE_IXGBE_PMD=y in your " 1875af75078fSIntel "configuration file\n"); 1876af75078fSIntel 1877af75078fSIntel set_def_fwd_config(); 1878af75078fSIntel if (nb_lcores == 0) 1879af75078fSIntel rte_panic("Empty set of forwarding logical cores - check the " 1880af75078fSIntel "core mask supplied in the command parameters\n"); 1881af75078fSIntel 1882af75078fSIntel argc -= diag; 1883af75078fSIntel argv += diag; 1884af75078fSIntel if (argc > 1) 1885af75078fSIntel launch_args_parse(argc, argv); 1886af75078fSIntel 1887af75078fSIntel if (nb_rxq > nb_txq) 1888af75078fSIntel printf("Warning: nb_rxq=%d enables RSS configuration, " 1889af75078fSIntel "but nb_txq=%d will prevent to fully test it.\n", 1890af75078fSIntel nb_rxq, nb_txq); 1891af75078fSIntel 1892af75078fSIntel init_config(); 1893148f963fSBruce Richardson if (start_port(RTE_PORT_ALL) != 0) 1894148f963fSBruce Richardson rte_exit(EXIT_FAILURE, "Start ports failed\n"); 1895af75078fSIntel 1896ce8d5614SIntel /* set all ports to promiscuous mode by default */ 1897ce8d5614SIntel for (port_id = 0; port_id < nb_ports; port_id++) 1898ce8d5614SIntel rte_eth_promiscuous_enable(port_id); 1899af75078fSIntel 19000d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE 1901ca7feb22SCyril Chemparathy if (interactive == 1) { 1902ca7feb22SCyril Chemparathy if (auto_start) { 1903ca7feb22SCyril Chemparathy printf("Start automatic packet forwarding\n"); 1904ca7feb22SCyril Chemparathy start_packet_forwarding(0); 1905ca7feb22SCyril Chemparathy } 1906af75078fSIntel prompt(); 1907ca7feb22SCyril Chemparathy } else 19080d56cb81SThomas Monjalon #endif 19090d56cb81SThomas Monjalon { 1910af75078fSIntel char c; 1911af75078fSIntel int rc; 1912af75078fSIntel 1913af75078fSIntel printf("No commandline core given, start packet forwarding\n"); 1914af75078fSIntel start_packet_forwarding(0); 1915af75078fSIntel printf("Press enter to exit\n"); 1916af75078fSIntel rc = read(0, &c, 1); 1917af75078fSIntel if (rc < 0) 1918af75078fSIntel return 1; 1919af75078fSIntel } 1920af75078fSIntel 1921af75078fSIntel return 0; 1922af75078fSIntel } 1923