1af75078fSIntel /*- 2af75078fSIntel * BSD LICENSE 3af75078fSIntel * 45a8fb55cSReshma Pattan * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. 5af75078fSIntel * All rights reserved. 6af75078fSIntel * 7af75078fSIntel * Redistribution and use in source and binary forms, with or without 8af75078fSIntel * modification, are permitted provided that the following conditions 9af75078fSIntel * are met: 10af75078fSIntel * 11af75078fSIntel * * Redistributions of source code must retain the above copyright 12af75078fSIntel * notice, this list of conditions and the following disclaimer. 13af75078fSIntel * * Redistributions in binary form must reproduce the above copyright 14af75078fSIntel * notice, this list of conditions and the following disclaimer in 15af75078fSIntel * the documentation and/or other materials provided with the 16af75078fSIntel * distribution. 17af75078fSIntel * * Neither the name of Intel Corporation nor the names of its 18af75078fSIntel * contributors may be used to endorse or promote products derived 19af75078fSIntel * from this software without specific prior written permission. 20af75078fSIntel * 21af75078fSIntel * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22af75078fSIntel * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23af75078fSIntel * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24af75078fSIntel * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25af75078fSIntel * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26af75078fSIntel * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27af75078fSIntel * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28af75078fSIntel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29af75078fSIntel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30af75078fSIntel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31af75078fSIntel * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32af75078fSIntel */ 33af75078fSIntel 34af75078fSIntel #include <stdarg.h> 35af75078fSIntel #include <stdio.h> 36af75078fSIntel #include <stdlib.h> 37af75078fSIntel #include <signal.h> 38af75078fSIntel #include <string.h> 39af75078fSIntel #include <time.h> 40af75078fSIntel #include <fcntl.h> 41af75078fSIntel #include <sys/types.h> 42af75078fSIntel #include <errno.h> 43af75078fSIntel 44af75078fSIntel #include <sys/queue.h> 45af75078fSIntel #include <sys/stat.h> 46af75078fSIntel 47af75078fSIntel #include <stdint.h> 48af75078fSIntel #include <unistd.h> 49af75078fSIntel #include <inttypes.h> 50af75078fSIntel 51af75078fSIntel #include <rte_common.h> 52d1eb542eSOlivier Matz #include <rte_errno.h> 53af75078fSIntel #include <rte_byteorder.h> 54af75078fSIntel #include <rte_log.h> 55af75078fSIntel #include <rte_debug.h> 56af75078fSIntel #include <rte_cycles.h> 57af75078fSIntel #include <rte_memory.h> 58af75078fSIntel #include <rte_memcpy.h> 59af75078fSIntel #include <rte_memzone.h> 60af75078fSIntel #include <rte_launch.h> 61af75078fSIntel #include <rte_eal.h> 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_mempool.h> 67af75078fSIntel #include <rte_malloc.h> 68af75078fSIntel #include <rte_mbuf.h> 69af75078fSIntel #include <rte_interrupts.h> 70af75078fSIntel #include <rte_pci.h> 71af75078fSIntel #include <rte_ether.h> 72af75078fSIntel #include <rte_ethdev.h> 73edab33b1STetsuya Mukawa #include <rte_dev.h> 74af75078fSIntel #include <rte_string_fns.h> 75148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT 76148f963fSBruce Richardson #include <rte_eth_xenvirt.h> 77148f963fSBruce Richardson #endif 78102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP 79102b7329SReshma Pattan #include <rte_pdump.h> 80102b7329SReshma Pattan #endif 81*938a184aSAdrien Mazarguil #include <rte_flow.h> 82af75078fSIntel 83af75078fSIntel #include "testpmd.h" 84af75078fSIntel 85af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */ 86af75078fSIntel 87af75078fSIntel /* use master core for command line ? */ 88af75078fSIntel uint8_t interactive = 0; 89ca7feb22SCyril Chemparathy uint8_t auto_start = 0; 90af75078fSIntel 91af75078fSIntel /* 92af75078fSIntel * NUMA support configuration. 93af75078fSIntel * When set, the NUMA support attempts to dispatch the allocation of the 94af75078fSIntel * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the 95af75078fSIntel * probed ports among the CPU sockets 0 and 1. 96af75078fSIntel * Otherwise, all memory is allocated from CPU socket 0. 97af75078fSIntel */ 98af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */ 99af75078fSIntel 100af75078fSIntel /* 101b6ea6408SIntel * In UMA mode,all memory is allocated from socket 0 if --socket-num is 102b6ea6408SIntel * not configured. 103b6ea6408SIntel */ 104b6ea6408SIntel uint8_t socket_num = UMA_NO_CONFIG; 105b6ea6408SIntel 106b6ea6408SIntel /* 107148f963fSBruce Richardson * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs. 108148f963fSBruce Richardson */ 109148f963fSBruce Richardson uint8_t mp_anon = 0; 110148f963fSBruce Richardson 111148f963fSBruce Richardson /* 112af75078fSIntel * Record the Ethernet address of peer target ports to which packets are 113af75078fSIntel * forwarded. 114af75078fSIntel * Must be instanciated with the ethernet addresses of peer traffic generator 115af75078fSIntel * ports. 116af75078fSIntel */ 117af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; 118af75078fSIntel portid_t nb_peer_eth_addrs = 0; 119af75078fSIntel 120af75078fSIntel /* 121af75078fSIntel * Probed Target Environment. 122af75078fSIntel */ 123af75078fSIntel struct rte_port *ports; /**< For all probed ethernet ports. */ 124af75078fSIntel portid_t nb_ports; /**< Number of probed ethernet ports. */ 125af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */ 126af75078fSIntel lcoreid_t nb_lcores; /**< Number of probed logical cores. */ 127af75078fSIntel 128af75078fSIntel /* 129af75078fSIntel * Test Forwarding Configuration. 130af75078fSIntel * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores 131af75078fSIntel * nb_fwd_ports <= nb_cfg_ports <= nb_ports 132af75078fSIntel */ 133af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */ 134af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */ 135af75078fSIntel portid_t nb_cfg_ports; /**< Number of configured ports. */ 136af75078fSIntel portid_t nb_fwd_ports; /**< Number of forwarding ports. */ 137af75078fSIntel 138af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */ 139af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */ 140af75078fSIntel 141af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */ 142af75078fSIntel streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ 143af75078fSIntel 144af75078fSIntel /* 145af75078fSIntel * Forwarding engines. 146af75078fSIntel */ 147af75078fSIntel struct fwd_engine * fwd_engines[] = { 148af75078fSIntel &io_fwd_engine, 149af75078fSIntel &mac_fwd_engine, 150d47388f1SCyril Chemparathy &mac_swap_engine, 151e9e23a61SCyril Chemparathy &flow_gen_engine, 152af75078fSIntel &rx_only_engine, 153af75078fSIntel &tx_only_engine, 154af75078fSIntel &csum_fwd_engine, 155168dfa61SIvan Boule &icmp_echo_engine, 156af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588 157af75078fSIntel &ieee1588_fwd_engine, 158af75078fSIntel #endif 159af75078fSIntel NULL, 160af75078fSIntel }; 161af75078fSIntel 162af75078fSIntel struct fwd_config cur_fwd_config; 163af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ 164bf56fce1SZhihong Wang uint32_t retry_enabled; 165bf56fce1SZhihong Wang uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; 166bf56fce1SZhihong Wang uint32_t burst_tx_retry_num = BURST_TX_RETRIES; 167af75078fSIntel 168af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ 169c8798818SIntel uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if 170c8798818SIntel * specified on command-line. */ 171af75078fSIntel 172af75078fSIntel /* 173af75078fSIntel * Configuration of packet segments used by the "txonly" processing engine. 174af75078fSIntel */ 175af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */ 176af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = { 177af75078fSIntel TXONLY_DEF_PACKET_LEN, 178af75078fSIntel }; 179af75078fSIntel uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */ 180af75078fSIntel 18179bec05bSKonstantin Ananyev enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF; 18279bec05bSKonstantin Ananyev /**< Split policy for packets to TX. */ 18379bec05bSKonstantin Ananyev 184af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */ 185e9378bbcSCunming Liang uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ 186af75078fSIntel 187900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */ 188900550deSIntel uint8_t dcb_config = 0; 189900550deSIntel 190900550deSIntel /* Whether the dcb is in testing status */ 191900550deSIntel uint8_t dcb_test = 0; 192900550deSIntel 193af75078fSIntel /* 194af75078fSIntel * Configurable number of RX/TX queues. 195af75078fSIntel */ 196af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ 197af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */ 198af75078fSIntel 199af75078fSIntel /* 200af75078fSIntel * Configurable number of RX/TX ring descriptors. 201af75078fSIntel */ 202af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128 203af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512 204af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */ 205af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */ 206af75078fSIntel 207f2c5125aSPablo de Lara #define RTE_PMD_PARAM_UNSET -1 208af75078fSIntel /* 209af75078fSIntel * Configurable values of RX and TX ring threshold registers. 210af75078fSIntel */ 211af75078fSIntel 212f2c5125aSPablo de Lara int8_t rx_pthresh = RTE_PMD_PARAM_UNSET; 213f2c5125aSPablo de Lara int8_t rx_hthresh = RTE_PMD_PARAM_UNSET; 214f2c5125aSPablo de Lara int8_t rx_wthresh = RTE_PMD_PARAM_UNSET; 215af75078fSIntel 216f2c5125aSPablo de Lara int8_t tx_pthresh = RTE_PMD_PARAM_UNSET; 217f2c5125aSPablo de Lara int8_t tx_hthresh = RTE_PMD_PARAM_UNSET; 218f2c5125aSPablo de Lara int8_t tx_wthresh = RTE_PMD_PARAM_UNSET; 219af75078fSIntel 220af75078fSIntel /* 221af75078fSIntel * Configurable value of RX free threshold. 222af75078fSIntel */ 223f2c5125aSPablo de Lara int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET; 224af75078fSIntel 225af75078fSIntel /* 226ce8d5614SIntel * Configurable value of RX drop enable. 227ce8d5614SIntel */ 228f2c5125aSPablo de Lara int8_t rx_drop_en = RTE_PMD_PARAM_UNSET; 229ce8d5614SIntel 230ce8d5614SIntel /* 231af75078fSIntel * Configurable value of TX free threshold. 232af75078fSIntel */ 233f2c5125aSPablo de Lara int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET; 234af75078fSIntel 235af75078fSIntel /* 236af75078fSIntel * Configurable value of TX RS bit threshold. 237af75078fSIntel */ 238f2c5125aSPablo de Lara int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET; 239af75078fSIntel 240af75078fSIntel /* 241ce8d5614SIntel * Configurable value of TX queue flags. 242ce8d5614SIntel */ 243f2c5125aSPablo de Lara int32_t txq_flags = RTE_PMD_PARAM_UNSET; 244ce8d5614SIntel 245ce8d5614SIntel /* 246af75078fSIntel * Receive Side Scaling (RSS) configuration. 247af75078fSIntel */ 2488a387fa8SHelin Zhang uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */ 249af75078fSIntel 250af75078fSIntel /* 251af75078fSIntel * Port topology configuration 252af75078fSIntel */ 253af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */ 254af75078fSIntel 2557741e4cfSIntel /* 2567741e4cfSIntel * Avoids to flush all the RX streams before starts forwarding. 2577741e4cfSIntel */ 2587741e4cfSIntel uint8_t no_flush_rx = 0; /* flush by default */ 2597741e4cfSIntel 260af75078fSIntel /* 261bc202406SDavid Marchand * Avoids to check link status when starting/stopping a port. 262bc202406SDavid Marchand */ 263bc202406SDavid Marchand uint8_t no_link_check = 0; /* check by default */ 264bc202406SDavid Marchand 265bc202406SDavid Marchand /* 2667b7e5ba7SIntel * NIC bypass mode configuration options. 2677b7e5ba7SIntel */ 2687b7e5ba7SIntel #ifdef RTE_NIC_BYPASS 2697b7e5ba7SIntel 2707b7e5ba7SIntel /* The NIC bypass watchdog timeout. */ 2717b7e5ba7SIntel uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF; 2727b7e5ba7SIntel 2737b7e5ba7SIntel #endif 2747b7e5ba7SIntel 2757b7e5ba7SIntel /* 276af75078fSIntel * Ethernet device configuration. 277af75078fSIntel */ 278af75078fSIntel struct rte_eth_rxmode rx_mode = { 279af75078fSIntel .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ 280af75078fSIntel .split_hdr_size = 0, 281af75078fSIntel .header_split = 0, /**< Header Split disabled. */ 282af75078fSIntel .hw_ip_checksum = 0, /**< IP checksum offload disabled. */ 283af75078fSIntel .hw_vlan_filter = 1, /**< VLAN filtering enabled. */ 284a47aa8b9SIntel .hw_vlan_strip = 1, /**< VLAN strip enabled. */ 285a47aa8b9SIntel .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ 286af75078fSIntel .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ 287af75078fSIntel .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */ 288af75078fSIntel }; 289af75078fSIntel 290af75078fSIntel struct rte_fdir_conf fdir_conf = { 291af75078fSIntel .mode = RTE_FDIR_MODE_NONE, 292af75078fSIntel .pballoc = RTE_FDIR_PBALLOC_64K, 293af75078fSIntel .status = RTE_FDIR_REPORT_STATUS, 294d9d5e6f2SJingjing Wu .mask = { 295d9d5e6f2SJingjing Wu .vlan_tci_mask = 0x0, 296d9d5e6f2SJingjing Wu .ipv4_mask = { 297d9d5e6f2SJingjing Wu .src_ip = 0xFFFFFFFF, 298d9d5e6f2SJingjing Wu .dst_ip = 0xFFFFFFFF, 299d9d5e6f2SJingjing Wu }, 300d9d5e6f2SJingjing Wu .ipv6_mask = { 301d9d5e6f2SJingjing Wu .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 302d9d5e6f2SJingjing Wu .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 303d9d5e6f2SJingjing Wu }, 304d9d5e6f2SJingjing Wu .src_port_mask = 0xFFFF, 305d9d5e6f2SJingjing Wu .dst_port_mask = 0xFFFF, 30647b3ac6bSWenzhuo Lu .mac_addr_byte_mask = 0xFF, 30747b3ac6bSWenzhuo Lu .tunnel_type_mask = 1, 30847b3ac6bSWenzhuo Lu .tunnel_id_mask = 0xFFFFFFFF, 309d9d5e6f2SJingjing Wu }, 310af75078fSIntel .drop_queue = 127, 311af75078fSIntel }; 312af75078fSIntel 3132950a769SDeclan Doherty volatile int test_done = 1; /* stop packet forwarding when set to 1. */ 314af75078fSIntel 315ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; 316ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; 317ed30d9b6SIntel 318ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; 319ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; 320ed30d9b6SIntel 321ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0; 322ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0; 323ed30d9b6SIntel 3247acf894dSStephen Hurd unsigned max_socket = 0; 3257acf894dSStephen Hurd 326ed30d9b6SIntel /* Forward function declarations */ 327ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port); 328edab33b1STetsuya Mukawa static void check_all_ports_link_status(uint32_t port_mask); 329ce8d5614SIntel 330ce8d5614SIntel /* 331ce8d5614SIntel * Check if all the ports are started. 332ce8d5614SIntel * If yes, return positive value. If not, return zero. 333ce8d5614SIntel */ 334ce8d5614SIntel static int all_ports_started(void); 335ed30d9b6SIntel 336af75078fSIntel /* 337edab33b1STetsuya Mukawa * Find next enabled port 338edab33b1STetsuya Mukawa */ 339edab33b1STetsuya Mukawa portid_t 340edab33b1STetsuya Mukawa find_next_port(portid_t p, struct rte_port *ports, int size) 341edab33b1STetsuya Mukawa { 342edab33b1STetsuya Mukawa if (ports == NULL) 343edab33b1STetsuya Mukawa rte_exit(-EINVAL, "failed to find a next port id\n"); 344edab33b1STetsuya Mukawa 34512a8e30fSJulien Cretin while ((p < size) && (ports[p].enabled == 0)) 346edab33b1STetsuya Mukawa p++; 347edab33b1STetsuya Mukawa return p; 348edab33b1STetsuya Mukawa } 349edab33b1STetsuya Mukawa 350edab33b1STetsuya Mukawa /* 351af75078fSIntel * Setup default configuration. 352af75078fSIntel */ 353af75078fSIntel static void 354af75078fSIntel set_default_fwd_lcores_config(void) 355af75078fSIntel { 356af75078fSIntel unsigned int i; 357af75078fSIntel unsigned int nb_lc; 3587acf894dSStephen Hurd unsigned int sock_num; 359af75078fSIntel 360af75078fSIntel nb_lc = 0; 361af75078fSIntel for (i = 0; i < RTE_MAX_LCORE; i++) { 3627acf894dSStephen Hurd sock_num = rte_lcore_to_socket_id(i) + 1; 3637acf894dSStephen Hurd if (sock_num > max_socket) { 3647acf894dSStephen Hurd if (sock_num > RTE_MAX_NUMA_NODES) 3657acf894dSStephen Hurd rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES); 3667acf894dSStephen Hurd max_socket = sock_num; 3677acf894dSStephen Hurd } 368f54fe5eeSStephen Hurd if (!rte_lcore_is_enabled(i)) 369f54fe5eeSStephen Hurd continue; 370f54fe5eeSStephen Hurd if (i == rte_get_master_lcore()) 371f54fe5eeSStephen Hurd continue; 372f54fe5eeSStephen Hurd fwd_lcores_cpuids[nb_lc++] = i; 373af75078fSIntel } 374af75078fSIntel nb_lcores = (lcoreid_t) nb_lc; 375af75078fSIntel nb_cfg_lcores = nb_lcores; 376af75078fSIntel nb_fwd_lcores = 1; 377af75078fSIntel } 378af75078fSIntel 379af75078fSIntel static void 380af75078fSIntel set_def_peer_eth_addrs(void) 381af75078fSIntel { 382af75078fSIntel portid_t i; 383af75078fSIntel 384af75078fSIntel for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 385af75078fSIntel peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR; 386af75078fSIntel peer_eth_addrs[i].addr_bytes[5] = i; 387af75078fSIntel } 388af75078fSIntel } 389af75078fSIntel 390af75078fSIntel static void 391af75078fSIntel set_default_fwd_ports_config(void) 392af75078fSIntel { 393af75078fSIntel portid_t pt_id; 394af75078fSIntel 395af75078fSIntel for (pt_id = 0; pt_id < nb_ports; pt_id++) 396af75078fSIntel fwd_ports_ids[pt_id] = pt_id; 397af75078fSIntel 398af75078fSIntel nb_cfg_ports = nb_ports; 399af75078fSIntel nb_fwd_ports = nb_ports; 400af75078fSIntel } 401af75078fSIntel 402af75078fSIntel void 403af75078fSIntel set_def_fwd_config(void) 404af75078fSIntel { 405af75078fSIntel set_default_fwd_lcores_config(); 406af75078fSIntel set_def_peer_eth_addrs(); 407af75078fSIntel set_default_fwd_ports_config(); 408af75078fSIntel } 409af75078fSIntel 410af75078fSIntel /* 411af75078fSIntel * Configuration initialisation done once at init time. 412af75078fSIntel */ 413af75078fSIntel static void 414af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, 415af75078fSIntel unsigned int socket_id) 416af75078fSIntel { 417af75078fSIntel char pool_name[RTE_MEMPOOL_NAMESIZE]; 418bece7b6cSChristian Ehrhardt struct rte_mempool *rte_mp = NULL; 419af75078fSIntel uint32_t mb_size; 420af75078fSIntel 421dfb03bbeSOlivier Matz mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size; 422af75078fSIntel mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); 423148f963fSBruce Richardson 424d1eb542eSOlivier Matz RTE_LOG(INFO, USER1, 425d1eb542eSOlivier Matz "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n", 426d1eb542eSOlivier Matz pool_name, nb_mbuf, mbuf_seg_size, socket_id); 427d1eb542eSOlivier Matz 428148f963fSBruce Richardson #ifdef RTE_LIBRTE_PMD_XENVIRT 429148f963fSBruce Richardson rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size, 430af75078fSIntel (unsigned) mb_mempool_cache, 431af75078fSIntel sizeof(struct rte_pktmbuf_pool_private), 432dfb03bbeSOlivier Matz rte_pktmbuf_pool_init, NULL, 433dfb03bbeSOlivier Matz rte_pktmbuf_init, NULL, 434af75078fSIntel socket_id, 0); 435bece7b6cSChristian Ehrhardt #endif 436148f963fSBruce Richardson 437bece7b6cSChristian Ehrhardt /* if the former XEN allocation failed fall back to normal allocation */ 438bece7b6cSChristian Ehrhardt if (rte_mp == NULL) { 439b19a0c75SOlivier Matz if (mp_anon != 0) { 440b19a0c75SOlivier Matz rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf, 441bece7b6cSChristian Ehrhardt mb_size, (unsigned) mb_mempool_cache, 442148f963fSBruce Richardson sizeof(struct rte_pktmbuf_pool_private), 443148f963fSBruce Richardson socket_id, 0); 44424427bb9SOlivier Matz if (rte_mp == NULL) 44524427bb9SOlivier Matz goto err; 446b19a0c75SOlivier Matz 447b19a0c75SOlivier Matz if (rte_mempool_populate_anon(rte_mp) == 0) { 448b19a0c75SOlivier Matz rte_mempool_free(rte_mp); 449b19a0c75SOlivier Matz rte_mp = NULL; 45024427bb9SOlivier Matz goto err; 451b19a0c75SOlivier Matz } 452b19a0c75SOlivier Matz rte_pktmbuf_pool_init(rte_mp, NULL); 453b19a0c75SOlivier Matz rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL); 454b19a0c75SOlivier Matz } else { 455ea0c20eaSOlivier Matz /* wrapper to rte_mempool_create() */ 456ea0c20eaSOlivier Matz rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, 457ea0c20eaSOlivier Matz mb_mempool_cache, 0, mbuf_seg_size, socket_id); 458bece7b6cSChristian Ehrhardt } 459b19a0c75SOlivier Matz } 460148f963fSBruce Richardson 46124427bb9SOlivier Matz err: 462af75078fSIntel if (rte_mp == NULL) { 463d1eb542eSOlivier Matz rte_exit(EXIT_FAILURE, 464d1eb542eSOlivier Matz "Creation of mbuf pool for socket %u failed: %s\n", 465d1eb542eSOlivier Matz socket_id, rte_strerror(rte_errno)); 466148f963fSBruce Richardson } else if (verbose_level > 0) { 467591a9d79SStephen Hemminger rte_mempool_dump(stdout, rte_mp); 468af75078fSIntel } 469af75078fSIntel } 470af75078fSIntel 47120a0286fSLiu Xiaofeng /* 47220a0286fSLiu Xiaofeng * Check given socket id is valid or not with NUMA mode, 47320a0286fSLiu Xiaofeng * if valid, return 0, else return -1 47420a0286fSLiu Xiaofeng */ 47520a0286fSLiu Xiaofeng static int 47620a0286fSLiu Xiaofeng check_socket_id(const unsigned int socket_id) 47720a0286fSLiu Xiaofeng { 47820a0286fSLiu Xiaofeng static int warning_once = 0; 47920a0286fSLiu Xiaofeng 4807acf894dSStephen Hurd if (socket_id >= max_socket) { 48120a0286fSLiu Xiaofeng if (!warning_once && numa_support) 48220a0286fSLiu Xiaofeng printf("Warning: NUMA should be configured manually by" 48320a0286fSLiu Xiaofeng " using --port-numa-config and" 48420a0286fSLiu Xiaofeng " --ring-numa-config parameters along with" 48520a0286fSLiu Xiaofeng " --numa.\n"); 48620a0286fSLiu Xiaofeng warning_once = 1; 48720a0286fSLiu Xiaofeng return -1; 48820a0286fSLiu Xiaofeng } 48920a0286fSLiu Xiaofeng return 0; 49020a0286fSLiu Xiaofeng } 49120a0286fSLiu Xiaofeng 492af75078fSIntel static void 493af75078fSIntel init_config(void) 494af75078fSIntel { 495ce8d5614SIntel portid_t pid; 496af75078fSIntel struct rte_port *port; 497af75078fSIntel struct rte_mempool *mbp; 498af75078fSIntel unsigned int nb_mbuf_per_pool; 499af75078fSIntel lcoreid_t lc_id; 5007acf894dSStephen Hurd uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; 501af75078fSIntel 5027acf894dSStephen Hurd memset(port_per_socket,0,RTE_MAX_NUMA_NODES); 503af75078fSIntel /* Configuration of logical cores. */ 504af75078fSIntel fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 505af75078fSIntel sizeof(struct fwd_lcore *) * nb_lcores, 506fdf20fa7SSergio Gonzalez Monroy RTE_CACHE_LINE_SIZE); 507af75078fSIntel if (fwd_lcores == NULL) { 508ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 509ce8d5614SIntel "failed\n", nb_lcores); 510af75078fSIntel } 511af75078fSIntel for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 512af75078fSIntel fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 513af75078fSIntel sizeof(struct fwd_lcore), 514fdf20fa7SSergio Gonzalez Monroy RTE_CACHE_LINE_SIZE); 515af75078fSIntel if (fwd_lcores[lc_id] == NULL) { 516ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 517ce8d5614SIntel "failed\n"); 518af75078fSIntel } 519af75078fSIntel fwd_lcores[lc_id]->cpuid_idx = lc_id; 520af75078fSIntel } 521af75078fSIntel 522af75078fSIntel /* 523af75078fSIntel * Create pools of mbuf. 524af75078fSIntel * If NUMA support is disabled, create a single pool of mbuf in 525b6ea6408SIntel * socket 0 memory by default. 526af75078fSIntel * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 527c8798818SIntel * 528c8798818SIntel * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 529c8798818SIntel * nb_txd can be configured at run time. 530af75078fSIntel */ 531c8798818SIntel if (param_total_num_mbufs) 532c8798818SIntel nb_mbuf_per_pool = param_total_num_mbufs; 533c8798818SIntel else { 534c8798818SIntel nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache) 535c8798818SIntel + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 536b6ea6408SIntel 537b6ea6408SIntel if (!numa_support) 538edab33b1STetsuya Mukawa nb_mbuf_per_pool = 539edab33b1STetsuya Mukawa (nb_mbuf_per_pool * RTE_MAX_ETHPORTS); 540c8798818SIntel } 541af75078fSIntel 542b6ea6408SIntel if (!numa_support) { 543b6ea6408SIntel if (socket_num == UMA_NO_CONFIG) 544b6ea6408SIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 545b6ea6408SIntel else 546b6ea6408SIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 547b6ea6408SIntel socket_num); 548b6ea6408SIntel } 549af75078fSIntel 550edab33b1STetsuya Mukawa FOREACH_PORT(pid, ports) { 551ce8d5614SIntel port = &ports[pid]; 552ce8d5614SIntel rte_eth_dev_info_get(pid, &port->dev_info); 553ce8d5614SIntel 554b6ea6408SIntel if (numa_support) { 555b6ea6408SIntel if (port_numa[pid] != NUMA_NO_CONFIG) 556b6ea6408SIntel port_per_socket[port_numa[pid]]++; 557b6ea6408SIntel else { 558b6ea6408SIntel uint32_t socket_id = rte_eth_dev_socket_id(pid); 55920a0286fSLiu Xiaofeng 56020a0286fSLiu Xiaofeng /* if socket_id is invalid, set to 0 */ 56120a0286fSLiu Xiaofeng if (check_socket_id(socket_id) < 0) 56220a0286fSLiu Xiaofeng socket_id = 0; 563b6ea6408SIntel port_per_socket[socket_id]++; 564b6ea6408SIntel } 565b6ea6408SIntel } 566b6ea6408SIntel 567ce8d5614SIntel /* set flag to initialize port/queue */ 568ce8d5614SIntel port->need_reconfig = 1; 569ce8d5614SIntel port->need_reconfig_queues = 1; 570ce8d5614SIntel } 571ce8d5614SIntel 572b6ea6408SIntel if (numa_support) { 573b6ea6408SIntel uint8_t i; 574b6ea6408SIntel unsigned int nb_mbuf; 575ce8d5614SIntel 576b6ea6408SIntel if (param_total_num_mbufs) 577b6ea6408SIntel nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports; 578b6ea6408SIntel 5797acf894dSStephen Hurd for (i = 0; i < max_socket; i++) { 580edab33b1STetsuya Mukawa nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS); 581b6ea6408SIntel if (nb_mbuf) 582b6ea6408SIntel mbuf_pool_create(mbuf_data_size, 583b6ea6408SIntel nb_mbuf,i); 584b6ea6408SIntel } 585b6ea6408SIntel } 586b6ea6408SIntel init_port_config(); 5875886ae07SAdrien Mazarguil 5885886ae07SAdrien Mazarguil /* 5895886ae07SAdrien Mazarguil * Records which Mbuf pool to use by each logical core, if needed. 5905886ae07SAdrien Mazarguil */ 5915886ae07SAdrien Mazarguil for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 5928fd8bebcSAdrien Mazarguil mbp = mbuf_pool_find( 5938fd8bebcSAdrien Mazarguil rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id])); 5948fd8bebcSAdrien Mazarguil 5955886ae07SAdrien Mazarguil if (mbp == NULL) 5965886ae07SAdrien Mazarguil mbp = mbuf_pool_find(0); 5975886ae07SAdrien Mazarguil fwd_lcores[lc_id]->mbp = mbp; 5985886ae07SAdrien Mazarguil } 5995886ae07SAdrien Mazarguil 600ce8d5614SIntel /* Configuration of packet forwarding streams. */ 601ce8d5614SIntel if (init_fwd_streams() < 0) 602ce8d5614SIntel rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 6030c0db76fSBernard Iremonger 6040c0db76fSBernard Iremonger fwd_config_setup(); 605ce8d5614SIntel } 606ce8d5614SIntel 6072950a769SDeclan Doherty 6082950a769SDeclan Doherty void 609a21d5a4bSDeclan Doherty reconfig(portid_t new_port_id, unsigned socket_id) 6102950a769SDeclan Doherty { 6112950a769SDeclan Doherty struct rte_port *port; 6122950a769SDeclan Doherty 6132950a769SDeclan Doherty /* Reconfiguration of Ethernet ports. */ 6142950a769SDeclan Doherty port = &ports[new_port_id]; 6152950a769SDeclan Doherty rte_eth_dev_info_get(new_port_id, &port->dev_info); 6162950a769SDeclan Doherty 6172950a769SDeclan Doherty /* set flag to initialize port/queue */ 6182950a769SDeclan Doherty port->need_reconfig = 1; 6192950a769SDeclan Doherty port->need_reconfig_queues = 1; 620a21d5a4bSDeclan Doherty port->socket_id = socket_id; 6212950a769SDeclan Doherty 6222950a769SDeclan Doherty init_port_config(); 6232950a769SDeclan Doherty } 6242950a769SDeclan Doherty 6252950a769SDeclan Doherty 626ce8d5614SIntel int 627ce8d5614SIntel init_fwd_streams(void) 628ce8d5614SIntel { 629ce8d5614SIntel portid_t pid; 630ce8d5614SIntel struct rte_port *port; 631ce8d5614SIntel streamid_t sm_id, nb_fwd_streams_new; 6325a8fb55cSReshma Pattan queueid_t q; 633ce8d5614SIntel 634ce8d5614SIntel /* set socket id according to numa or not */ 635edab33b1STetsuya Mukawa FOREACH_PORT(pid, ports) { 636ce8d5614SIntel port = &ports[pid]; 637ce8d5614SIntel if (nb_rxq > port->dev_info.max_rx_queues) { 638ce8d5614SIntel printf("Fail: nb_rxq(%d) is greater than " 639ce8d5614SIntel "max_rx_queues(%d)\n", nb_rxq, 640ce8d5614SIntel port->dev_info.max_rx_queues); 641ce8d5614SIntel return -1; 642ce8d5614SIntel } 643ce8d5614SIntel if (nb_txq > port->dev_info.max_tx_queues) { 644ce8d5614SIntel printf("Fail: nb_txq(%d) is greater than " 645ce8d5614SIntel "max_tx_queues(%d)\n", nb_txq, 646ce8d5614SIntel port->dev_info.max_tx_queues); 647ce8d5614SIntel return -1; 648ce8d5614SIntel } 64920a0286fSLiu Xiaofeng if (numa_support) { 65020a0286fSLiu Xiaofeng if (port_numa[pid] != NUMA_NO_CONFIG) 65120a0286fSLiu Xiaofeng port->socket_id = port_numa[pid]; 65220a0286fSLiu Xiaofeng else { 653b6ea6408SIntel port->socket_id = rte_eth_dev_socket_id(pid); 65420a0286fSLiu Xiaofeng 65520a0286fSLiu Xiaofeng /* if socket_id is invalid, set to 0 */ 65620a0286fSLiu Xiaofeng if (check_socket_id(port->socket_id) < 0) 65720a0286fSLiu Xiaofeng port->socket_id = 0; 65820a0286fSLiu Xiaofeng } 65920a0286fSLiu Xiaofeng } 660b6ea6408SIntel else { 661b6ea6408SIntel if (socket_num == UMA_NO_CONFIG) 662af75078fSIntel port->socket_id = 0; 663b6ea6408SIntel else 664b6ea6408SIntel port->socket_id = socket_num; 665b6ea6408SIntel } 666af75078fSIntel } 667af75078fSIntel 6685a8fb55cSReshma Pattan q = RTE_MAX(nb_rxq, nb_txq); 6695a8fb55cSReshma Pattan if (q == 0) { 6705a8fb55cSReshma Pattan printf("Fail: Cannot allocate fwd streams as number of queues is 0\n"); 6715a8fb55cSReshma Pattan return -1; 6725a8fb55cSReshma Pattan } 6735a8fb55cSReshma Pattan nb_fwd_streams_new = (streamid_t)(nb_ports * q); 674ce8d5614SIntel if (nb_fwd_streams_new == nb_fwd_streams) 675ce8d5614SIntel return 0; 676ce8d5614SIntel /* clear the old */ 677ce8d5614SIntel if (fwd_streams != NULL) { 678ce8d5614SIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 679ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 680ce8d5614SIntel continue; 681ce8d5614SIntel rte_free(fwd_streams[sm_id]); 682ce8d5614SIntel fwd_streams[sm_id] = NULL; 683af75078fSIntel } 684ce8d5614SIntel rte_free(fwd_streams); 685ce8d5614SIntel fwd_streams = NULL; 686ce8d5614SIntel } 687ce8d5614SIntel 688ce8d5614SIntel /* init new */ 689ce8d5614SIntel nb_fwd_streams = nb_fwd_streams_new; 690ce8d5614SIntel fwd_streams = rte_zmalloc("testpmd: fwd_streams", 691fdf20fa7SSergio Gonzalez Monroy sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE); 692ce8d5614SIntel if (fwd_streams == NULL) 693ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " 694ce8d5614SIntel "failed\n", nb_fwd_streams); 695ce8d5614SIntel 696af75078fSIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 697af75078fSIntel fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", 698fdf20fa7SSergio Gonzalez Monroy sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE); 699ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 700ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" 701ce8d5614SIntel " failed\n"); 702af75078fSIntel } 703ce8d5614SIntel 704ce8d5614SIntel return 0; 705af75078fSIntel } 706af75078fSIntel 707af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 708af75078fSIntel static void 709af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 710af75078fSIntel { 711af75078fSIntel unsigned int total_burst; 712af75078fSIntel unsigned int nb_burst; 713af75078fSIntel unsigned int burst_stats[3]; 714af75078fSIntel uint16_t pktnb_stats[3]; 715af75078fSIntel uint16_t nb_pkt; 716af75078fSIntel int burst_percent[3]; 717af75078fSIntel 718af75078fSIntel /* 719af75078fSIntel * First compute the total number of packet bursts and the 720af75078fSIntel * two highest numbers of bursts of the same number of packets. 721af75078fSIntel */ 722af75078fSIntel total_burst = 0; 723af75078fSIntel burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 724af75078fSIntel pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 725af75078fSIntel for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 726af75078fSIntel nb_burst = pbs->pkt_burst_spread[nb_pkt]; 727af75078fSIntel if (nb_burst == 0) 728af75078fSIntel continue; 729af75078fSIntel total_burst += nb_burst; 730af75078fSIntel if (nb_burst > burst_stats[0]) { 731af75078fSIntel burst_stats[1] = burst_stats[0]; 732af75078fSIntel pktnb_stats[1] = pktnb_stats[0]; 733af75078fSIntel burst_stats[0] = nb_burst; 734af75078fSIntel pktnb_stats[0] = nb_pkt; 735af75078fSIntel } 736af75078fSIntel } 737af75078fSIntel if (total_burst == 0) 738af75078fSIntel return; 739af75078fSIntel burst_percent[0] = (burst_stats[0] * 100) / total_burst; 740af75078fSIntel printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 741af75078fSIntel burst_percent[0], (int) pktnb_stats[0]); 742af75078fSIntel if (burst_stats[0] == total_burst) { 743af75078fSIntel printf("]\n"); 744af75078fSIntel return; 745af75078fSIntel } 746af75078fSIntel if (burst_stats[0] + burst_stats[1] == total_burst) { 747af75078fSIntel printf(" + %d%% of %d pkts]\n", 748af75078fSIntel 100 - burst_percent[0], pktnb_stats[1]); 749af75078fSIntel return; 750af75078fSIntel } 751af75078fSIntel burst_percent[1] = (burst_stats[1] * 100) / total_burst; 752af75078fSIntel burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 753af75078fSIntel if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 754af75078fSIntel printf(" + %d%% of others]\n", 100 - burst_percent[0]); 755af75078fSIntel return; 756af75078fSIntel } 757af75078fSIntel printf(" + %d%% of %d pkts + %d%% of others]\n", 758af75078fSIntel burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 759af75078fSIntel } 760af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 761af75078fSIntel 762af75078fSIntel static void 763af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) 764af75078fSIntel { 765af75078fSIntel struct rte_port *port; 766013af9b6SIntel uint8_t i; 767af75078fSIntel 768af75078fSIntel static const char *fwd_stats_border = "----------------------"; 769af75078fSIntel 770af75078fSIntel port = &ports[port_id]; 771af75078fSIntel printf("\n %s Forward statistics for port %-2d %s\n", 772af75078fSIntel fwd_stats_border, port_id, fwd_stats_border); 773013af9b6SIntel 774013af9b6SIntel if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 775af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 776af75078fSIntel "%-"PRIu64"\n", 77770bdb186SIvan Boule stats->ipackets, stats->imissed, 77870bdb186SIvan Boule (uint64_t) (stats->ipackets + stats->imissed)); 779af75078fSIntel 780af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) 781af75078fSIntel printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n", 782af75078fSIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 78386057c99SIgor Ryzhov if ((stats->ierrors + stats->rx_nombuf) > 0) { 784f72a0fa6SStephen Hemminger printf(" RX-error: %-"PRIu64"\n", stats->ierrors); 78570bdb186SIvan Boule printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf); 78670bdb186SIvan Boule } 787af75078fSIntel 788af75078fSIntel printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 789af75078fSIntel "%-"PRIu64"\n", 790af75078fSIntel stats->opackets, port->tx_dropped, 791af75078fSIntel (uint64_t) (stats->opackets + port->tx_dropped)); 792013af9b6SIntel } 793013af9b6SIntel else { 794013af9b6SIntel printf(" RX-packets: %14"PRIu64" RX-dropped:%14"PRIu64" RX-total:" 795013af9b6SIntel "%14"PRIu64"\n", 79670bdb186SIvan Boule stats->ipackets, stats->imissed, 79770bdb186SIvan Boule (uint64_t) (stats->ipackets + stats->imissed)); 798013af9b6SIntel 799013af9b6SIntel if (cur_fwd_eng == &csum_fwd_engine) 800013af9b6SIntel printf(" Bad-ipcsum:%14"PRIu64" Bad-l4csum:%14"PRIu64"\n", 801013af9b6SIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 80286057c99SIgor Ryzhov if ((stats->ierrors + stats->rx_nombuf) > 0) { 803f72a0fa6SStephen Hemminger printf(" RX-error:%"PRIu64"\n", stats->ierrors); 80470bdb186SIvan Boule printf(" RX-nombufs: %14"PRIu64"\n", 80570bdb186SIvan Boule stats->rx_nombuf); 80670bdb186SIvan Boule } 807013af9b6SIntel 808013af9b6SIntel printf(" TX-packets: %14"PRIu64" TX-dropped:%14"PRIu64" TX-total:" 809013af9b6SIntel "%14"PRIu64"\n", 810013af9b6SIntel stats->opackets, port->tx_dropped, 811013af9b6SIntel (uint64_t) (stats->opackets + port->tx_dropped)); 812013af9b6SIntel } 813e659b6b4SIvan Boule 814af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 815af75078fSIntel if (port->rx_stream) 816013af9b6SIntel pkt_burst_stats_display("RX", 817013af9b6SIntel &port->rx_stream->rx_burst_stats); 818af75078fSIntel if (port->tx_stream) 819013af9b6SIntel pkt_burst_stats_display("TX", 820013af9b6SIntel &port->tx_stream->tx_burst_stats); 821af75078fSIntel #endif 822af75078fSIntel 823013af9b6SIntel if (port->rx_queue_stats_mapping_enabled) { 824013af9b6SIntel printf("\n"); 825013af9b6SIntel for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 826013af9b6SIntel printf(" Stats reg %2d RX-packets:%14"PRIu64 827013af9b6SIntel " RX-errors:%14"PRIu64 828013af9b6SIntel " RX-bytes:%14"PRIu64"\n", 829013af9b6SIntel i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]); 830013af9b6SIntel } 831013af9b6SIntel printf("\n"); 832013af9b6SIntel } 833013af9b6SIntel if (port->tx_queue_stats_mapping_enabled) { 834013af9b6SIntel for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 835013af9b6SIntel printf(" Stats reg %2d TX-packets:%14"PRIu64 836013af9b6SIntel " TX-bytes:%14"PRIu64"\n", 837013af9b6SIntel i, stats->q_opackets[i], stats->q_obytes[i]); 838013af9b6SIntel } 839013af9b6SIntel } 840013af9b6SIntel 841af75078fSIntel printf(" %s--------------------------------%s\n", 842af75078fSIntel fwd_stats_border, fwd_stats_border); 843af75078fSIntel } 844af75078fSIntel 845af75078fSIntel static void 846af75078fSIntel fwd_stream_stats_display(streamid_t stream_id) 847af75078fSIntel { 848af75078fSIntel struct fwd_stream *fs; 849af75078fSIntel static const char *fwd_top_stats_border = "-------"; 850af75078fSIntel 851af75078fSIntel fs = fwd_streams[stream_id]; 852af75078fSIntel if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 853af75078fSIntel (fs->fwd_dropped == 0)) 854af75078fSIntel return; 855af75078fSIntel printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 856af75078fSIntel "TX Port=%2d/Queue=%2d %s\n", 857af75078fSIntel fwd_top_stats_border, fs->rx_port, fs->rx_queue, 858af75078fSIntel fs->tx_port, fs->tx_queue, fwd_top_stats_border); 859af75078fSIntel printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u", 860af75078fSIntel fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 861af75078fSIntel 862af75078fSIntel /* if checksum mode */ 863af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) { 864013af9b6SIntel printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: " 865013af9b6SIntel "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum); 866af75078fSIntel } 867af75078fSIntel 868af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 869af75078fSIntel pkt_burst_stats_display("RX", &fs->rx_burst_stats); 870af75078fSIntel pkt_burst_stats_display("TX", &fs->tx_burst_stats); 871af75078fSIntel #endif 872af75078fSIntel } 873af75078fSIntel 874af75078fSIntel static void 8757741e4cfSIntel flush_fwd_rx_queues(void) 876af75078fSIntel { 877af75078fSIntel struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 878af75078fSIntel portid_t rxp; 8797741e4cfSIntel portid_t port_id; 880af75078fSIntel queueid_t rxq; 881af75078fSIntel uint16_t nb_rx; 882af75078fSIntel uint16_t i; 883af75078fSIntel uint8_t j; 884f487715fSReshma Pattan uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 885594302c7SJames Poole uint64_t timer_period; 886f487715fSReshma Pattan 887f487715fSReshma Pattan /* convert to number of cycles */ 888594302c7SJames Poole timer_period = rte_get_timer_hz(); /* 1 second timeout */ 889af75078fSIntel 890af75078fSIntel for (j = 0; j < 2; j++) { 8917741e4cfSIntel for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { 892af75078fSIntel for (rxq = 0; rxq < nb_rxq; rxq++) { 8937741e4cfSIntel port_id = fwd_ports_ids[rxp]; 894f487715fSReshma Pattan /** 895f487715fSReshma Pattan * testpmd can stuck in the below do while loop 896f487715fSReshma Pattan * if rte_eth_rx_burst() always returns nonzero 897f487715fSReshma Pattan * packets. So timer is added to exit this loop 898f487715fSReshma Pattan * after 1sec timer expiry. 899f487715fSReshma Pattan */ 900f487715fSReshma Pattan prev_tsc = rte_rdtsc(); 901af75078fSIntel do { 9027741e4cfSIntel nb_rx = rte_eth_rx_burst(port_id, rxq, 903013af9b6SIntel pkts_burst, MAX_PKT_BURST); 904af75078fSIntel for (i = 0; i < nb_rx; i++) 905af75078fSIntel rte_pktmbuf_free(pkts_burst[i]); 906f487715fSReshma Pattan 907f487715fSReshma Pattan cur_tsc = rte_rdtsc(); 908f487715fSReshma Pattan diff_tsc = cur_tsc - prev_tsc; 909f487715fSReshma Pattan timer_tsc += diff_tsc; 910f487715fSReshma Pattan } while ((nb_rx > 0) && 911f487715fSReshma Pattan (timer_tsc < timer_period)); 912f487715fSReshma Pattan timer_tsc = 0; 913af75078fSIntel } 914af75078fSIntel } 915af75078fSIntel rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 916af75078fSIntel } 917af75078fSIntel } 918af75078fSIntel 919af75078fSIntel static void 920af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 921af75078fSIntel { 922af75078fSIntel struct fwd_stream **fsm; 923af75078fSIntel streamid_t nb_fs; 924af75078fSIntel streamid_t sm_id; 925af75078fSIntel 926af75078fSIntel fsm = &fwd_streams[fc->stream_idx]; 927af75078fSIntel nb_fs = fc->stream_nb; 928af75078fSIntel do { 929af75078fSIntel for (sm_id = 0; sm_id < nb_fs; sm_id++) 930af75078fSIntel (*pkt_fwd)(fsm[sm_id]); 931af75078fSIntel } while (! fc->stopped); 932af75078fSIntel } 933af75078fSIntel 934af75078fSIntel static int 935af75078fSIntel start_pkt_forward_on_core(void *fwd_arg) 936af75078fSIntel { 937af75078fSIntel run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 938af75078fSIntel cur_fwd_config.fwd_eng->packet_fwd); 939af75078fSIntel return 0; 940af75078fSIntel } 941af75078fSIntel 942af75078fSIntel /* 943af75078fSIntel * Run the TXONLY packet forwarding engine to send a single burst of packets. 944af75078fSIntel * Used to start communication flows in network loopback test configurations. 945af75078fSIntel */ 946af75078fSIntel static int 947af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg) 948af75078fSIntel { 949af75078fSIntel struct fwd_lcore *fwd_lc; 950af75078fSIntel struct fwd_lcore tmp_lcore; 951af75078fSIntel 952af75078fSIntel fwd_lc = (struct fwd_lcore *) fwd_arg; 953af75078fSIntel tmp_lcore = *fwd_lc; 954af75078fSIntel tmp_lcore.stopped = 1; 955af75078fSIntel run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 956af75078fSIntel return 0; 957af75078fSIntel } 958af75078fSIntel 959af75078fSIntel /* 960af75078fSIntel * Launch packet forwarding: 961af75078fSIntel * - Setup per-port forwarding context. 962af75078fSIntel * - launch logical cores with their forwarding configuration. 963af75078fSIntel */ 964af75078fSIntel static void 965af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 966af75078fSIntel { 967af75078fSIntel port_fwd_begin_t port_fwd_begin; 968af75078fSIntel unsigned int i; 969af75078fSIntel unsigned int lc_id; 970af75078fSIntel int diag; 971af75078fSIntel 972af75078fSIntel port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 973af75078fSIntel if (port_fwd_begin != NULL) { 974af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 975af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 976af75078fSIntel } 977af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 978af75078fSIntel lc_id = fwd_lcores_cpuids[i]; 979af75078fSIntel if ((interactive == 0) || (lc_id != rte_lcore_id())) { 980af75078fSIntel fwd_lcores[i]->stopped = 0; 981af75078fSIntel diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 982af75078fSIntel fwd_lcores[i], lc_id); 983af75078fSIntel if (diag != 0) 984af75078fSIntel printf("launch lcore %u failed - diag=%d\n", 985af75078fSIntel lc_id, diag); 986af75078fSIntel } 987af75078fSIntel } 988af75078fSIntel } 989af75078fSIntel 990af75078fSIntel /* 991af75078fSIntel * Launch packet forwarding configuration. 992af75078fSIntel */ 993af75078fSIntel void 994af75078fSIntel start_packet_forwarding(int with_tx_first) 995af75078fSIntel { 996af75078fSIntel port_fwd_begin_t port_fwd_begin; 997af75078fSIntel port_fwd_end_t port_fwd_end; 998af75078fSIntel struct rte_port *port; 999af75078fSIntel unsigned int i; 1000af75078fSIntel portid_t pt_id; 1001af75078fSIntel streamid_t sm_id; 1002af75078fSIntel 10035a8fb55cSReshma Pattan if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq) 10045a8fb55cSReshma Pattan rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n"); 10055a8fb55cSReshma Pattan 10065a8fb55cSReshma Pattan if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq) 10075a8fb55cSReshma Pattan rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n"); 10085a8fb55cSReshma Pattan 10095a8fb55cSReshma Pattan if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 && 10105a8fb55cSReshma Pattan strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) && 10115a8fb55cSReshma Pattan (!nb_rxq || !nb_txq)) 10125a8fb55cSReshma Pattan rte_exit(EXIT_FAILURE, 10135a8fb55cSReshma Pattan "Either rxq or txq are 0, cannot use %s fwd mode\n", 10145a8fb55cSReshma Pattan cur_fwd_eng->fwd_mode_name); 10155a8fb55cSReshma Pattan 1016ce8d5614SIntel if (all_ports_started() == 0) { 1017ce8d5614SIntel printf("Not all ports were started\n"); 1018ce8d5614SIntel return; 1019ce8d5614SIntel } 1020af75078fSIntel if (test_done == 0) { 1021af75078fSIntel printf("Packet forwarding already started\n"); 1022af75078fSIntel return; 1023af75078fSIntel } 1024edf87b4aSBernard Iremonger 1025edf87b4aSBernard Iremonger if (init_fwd_streams() < 0) { 1026edf87b4aSBernard Iremonger printf("Fail from init_fwd_streams()\n"); 1027edf87b4aSBernard Iremonger return; 1028edf87b4aSBernard Iremonger } 1029edf87b4aSBernard Iremonger 10307741e4cfSIntel if(dcb_test) { 10317741e4cfSIntel for (i = 0; i < nb_fwd_ports; i++) { 10327741e4cfSIntel pt_id = fwd_ports_ids[i]; 10337741e4cfSIntel port = &ports[pt_id]; 10347741e4cfSIntel if (!port->dcb_flag) { 10357741e4cfSIntel printf("In DCB mode, all forwarding ports must " 10367741e4cfSIntel "be configured in this mode.\n"); 1037013af9b6SIntel return; 1038013af9b6SIntel } 10397741e4cfSIntel } 10407741e4cfSIntel if (nb_fwd_lcores == 1) { 10417741e4cfSIntel printf("In DCB mode,the nb forwarding cores " 10427741e4cfSIntel "should be larger than 1.\n"); 10437741e4cfSIntel return; 10447741e4cfSIntel } 10457741e4cfSIntel } 1046af75078fSIntel test_done = 0; 10477741e4cfSIntel 10487741e4cfSIntel if(!no_flush_rx) 10497741e4cfSIntel flush_fwd_rx_queues(); 10507741e4cfSIntel 1051af75078fSIntel fwd_config_setup(); 1052933617d8SZhihong Wang pkt_fwd_config_display(&cur_fwd_config); 1053af75078fSIntel rxtx_config_display(); 1054af75078fSIntel 1055af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1056af75078fSIntel pt_id = fwd_ports_ids[i]; 1057af75078fSIntel port = &ports[pt_id]; 1058af75078fSIntel rte_eth_stats_get(pt_id, &port->stats); 1059af75078fSIntel port->tx_dropped = 0; 1060013af9b6SIntel 1061013af9b6SIntel map_port_queue_stats_mapping_registers(pt_id, port); 1062af75078fSIntel } 1063af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1064af75078fSIntel fwd_streams[sm_id]->rx_packets = 0; 1065af75078fSIntel fwd_streams[sm_id]->tx_packets = 0; 1066af75078fSIntel fwd_streams[sm_id]->fwd_dropped = 0; 1067af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum = 0; 1068af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum = 0; 1069af75078fSIntel 1070af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1071af75078fSIntel memset(&fwd_streams[sm_id]->rx_burst_stats, 0, 1072af75078fSIntel sizeof(fwd_streams[sm_id]->rx_burst_stats)); 1073af75078fSIntel memset(&fwd_streams[sm_id]->tx_burst_stats, 0, 1074af75078fSIntel sizeof(fwd_streams[sm_id]->tx_burst_stats)); 1075af75078fSIntel #endif 1076af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1077af75078fSIntel fwd_streams[sm_id]->core_cycles = 0; 1078af75078fSIntel #endif 1079af75078fSIntel } 1080af75078fSIntel if (with_tx_first) { 1081af75078fSIntel port_fwd_begin = tx_only_engine.port_fwd_begin; 1082af75078fSIntel if (port_fwd_begin != NULL) { 1083af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1084af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 1085af75078fSIntel } 1086acbf77a6SZhihong Wang while (with_tx_first--) { 1087acbf77a6SZhihong Wang launch_packet_forwarding( 1088acbf77a6SZhihong Wang run_one_txonly_burst_on_core); 1089af75078fSIntel rte_eal_mp_wait_lcore(); 1090acbf77a6SZhihong Wang } 1091af75078fSIntel port_fwd_end = tx_only_engine.port_fwd_end; 1092af75078fSIntel if (port_fwd_end != NULL) { 1093af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1094af75078fSIntel (*port_fwd_end)(fwd_ports_ids[i]); 1095af75078fSIntel } 1096af75078fSIntel } 1097af75078fSIntel launch_packet_forwarding(start_pkt_forward_on_core); 1098af75078fSIntel } 1099af75078fSIntel 1100af75078fSIntel void 1101af75078fSIntel stop_packet_forwarding(void) 1102af75078fSIntel { 1103af75078fSIntel struct rte_eth_stats stats; 1104af75078fSIntel struct rte_port *port; 1105af75078fSIntel port_fwd_end_t port_fwd_end; 1106af75078fSIntel int i; 1107af75078fSIntel portid_t pt_id; 1108af75078fSIntel streamid_t sm_id; 1109af75078fSIntel lcoreid_t lc_id; 1110af75078fSIntel uint64_t total_recv; 1111af75078fSIntel uint64_t total_xmit; 1112af75078fSIntel uint64_t total_rx_dropped; 1113af75078fSIntel uint64_t total_tx_dropped; 1114af75078fSIntel uint64_t total_rx_nombuf; 1115af75078fSIntel uint64_t tx_dropped; 1116af75078fSIntel uint64_t rx_bad_ip_csum; 1117af75078fSIntel uint64_t rx_bad_l4_csum; 1118af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1119af75078fSIntel uint64_t fwd_cycles; 1120af75078fSIntel #endif 1121af75078fSIntel static const char *acc_stats_border = "+++++++++++++++"; 1122af75078fSIntel 1123af75078fSIntel if (test_done) { 1124af75078fSIntel printf("Packet forwarding not started\n"); 1125af75078fSIntel return; 1126af75078fSIntel } 1127af75078fSIntel printf("Telling cores to stop..."); 1128af75078fSIntel for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 1129af75078fSIntel fwd_lcores[lc_id]->stopped = 1; 1130af75078fSIntel printf("\nWaiting for lcores to finish...\n"); 1131af75078fSIntel rte_eal_mp_wait_lcore(); 1132af75078fSIntel port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 1133af75078fSIntel if (port_fwd_end != NULL) { 1134af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1135af75078fSIntel pt_id = fwd_ports_ids[i]; 1136af75078fSIntel (*port_fwd_end)(pt_id); 1137af75078fSIntel } 1138af75078fSIntel } 1139af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1140af75078fSIntel fwd_cycles = 0; 1141af75078fSIntel #endif 1142af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1143af75078fSIntel if (cur_fwd_config.nb_fwd_streams > 1144af75078fSIntel cur_fwd_config.nb_fwd_ports) { 1145af75078fSIntel fwd_stream_stats_display(sm_id); 1146af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL; 1147af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL; 1148af75078fSIntel } else { 1149af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = 1150af75078fSIntel fwd_streams[sm_id]; 1151af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = 1152af75078fSIntel fwd_streams[sm_id]; 1153af75078fSIntel } 1154af75078fSIntel tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped; 1155af75078fSIntel tx_dropped = (uint64_t) (tx_dropped + 1156af75078fSIntel fwd_streams[sm_id]->fwd_dropped); 1157af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped; 1158af75078fSIntel 1159013af9b6SIntel rx_bad_ip_csum = 1160013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum; 1161af75078fSIntel rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum + 1162af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum); 1163013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = 1164013af9b6SIntel rx_bad_ip_csum; 1165af75078fSIntel 1166013af9b6SIntel rx_bad_l4_csum = 1167013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum; 1168af75078fSIntel rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum + 1169af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum); 1170013af9b6SIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = 1171013af9b6SIntel rx_bad_l4_csum; 1172af75078fSIntel 1173af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1174af75078fSIntel fwd_cycles = (uint64_t) (fwd_cycles + 1175af75078fSIntel fwd_streams[sm_id]->core_cycles); 1176af75078fSIntel #endif 1177af75078fSIntel } 1178af75078fSIntel total_recv = 0; 1179af75078fSIntel total_xmit = 0; 1180af75078fSIntel total_rx_dropped = 0; 1181af75078fSIntel total_tx_dropped = 0; 1182af75078fSIntel total_rx_nombuf = 0; 11837741e4cfSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1184af75078fSIntel pt_id = fwd_ports_ids[i]; 1185af75078fSIntel 1186af75078fSIntel port = &ports[pt_id]; 1187af75078fSIntel rte_eth_stats_get(pt_id, &stats); 1188af75078fSIntel stats.ipackets -= port->stats.ipackets; 1189af75078fSIntel port->stats.ipackets = 0; 1190af75078fSIntel stats.opackets -= port->stats.opackets; 1191af75078fSIntel port->stats.opackets = 0; 1192af75078fSIntel stats.ibytes -= port->stats.ibytes; 1193af75078fSIntel port->stats.ibytes = 0; 1194af75078fSIntel stats.obytes -= port->stats.obytes; 1195af75078fSIntel port->stats.obytes = 0; 119670bdb186SIvan Boule stats.imissed -= port->stats.imissed; 119770bdb186SIvan Boule port->stats.imissed = 0; 1198af75078fSIntel stats.oerrors -= port->stats.oerrors; 1199af75078fSIntel port->stats.oerrors = 0; 1200af75078fSIntel stats.rx_nombuf -= port->stats.rx_nombuf; 1201af75078fSIntel port->stats.rx_nombuf = 0; 1202af75078fSIntel 1203af75078fSIntel total_recv += stats.ipackets; 1204af75078fSIntel total_xmit += stats.opackets; 120570bdb186SIvan Boule total_rx_dropped += stats.imissed; 1206af75078fSIntel total_tx_dropped += port->tx_dropped; 1207af75078fSIntel total_rx_nombuf += stats.rx_nombuf; 1208af75078fSIntel 1209af75078fSIntel fwd_port_stats_display(pt_id, &stats); 1210af75078fSIntel } 1211af75078fSIntel printf("\n %s Accumulated forward statistics for all ports" 1212af75078fSIntel "%s\n", 1213af75078fSIntel acc_stats_border, acc_stats_border); 1214af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 1215af75078fSIntel "%-"PRIu64"\n" 1216af75078fSIntel " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 1217af75078fSIntel "%-"PRIu64"\n", 1218af75078fSIntel total_recv, total_rx_dropped, total_recv + total_rx_dropped, 1219af75078fSIntel total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 1220af75078fSIntel if (total_rx_nombuf > 0) 1221af75078fSIntel printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 1222af75078fSIntel printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 1223af75078fSIntel "%s\n", 1224af75078fSIntel acc_stats_border, acc_stats_border); 1225af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1226af75078fSIntel if (total_recv > 0) 1227af75078fSIntel printf("\n CPU cycles/packet=%u (total cycles=" 1228af75078fSIntel "%"PRIu64" / total RX packets=%"PRIu64")\n", 1229af75078fSIntel (unsigned int)(fwd_cycles / total_recv), 1230af75078fSIntel fwd_cycles, total_recv); 1231af75078fSIntel #endif 1232af75078fSIntel printf("\nDone.\n"); 1233af75078fSIntel test_done = 1; 1234af75078fSIntel } 1235af75078fSIntel 1236cfae07fdSOuyang Changchun void 1237cfae07fdSOuyang Changchun dev_set_link_up(portid_t pid) 1238cfae07fdSOuyang Changchun { 1239cfae07fdSOuyang Changchun if (rte_eth_dev_set_link_up((uint8_t)pid) < 0) 1240cfae07fdSOuyang Changchun printf("\nSet link up fail.\n"); 1241cfae07fdSOuyang Changchun } 1242cfae07fdSOuyang Changchun 1243cfae07fdSOuyang Changchun void 1244cfae07fdSOuyang Changchun dev_set_link_down(portid_t pid) 1245cfae07fdSOuyang Changchun { 1246cfae07fdSOuyang Changchun if (rte_eth_dev_set_link_down((uint8_t)pid) < 0) 1247cfae07fdSOuyang Changchun printf("\nSet link down fail.\n"); 1248cfae07fdSOuyang Changchun } 1249cfae07fdSOuyang Changchun 1250ce8d5614SIntel static int 1251ce8d5614SIntel all_ports_started(void) 1252ce8d5614SIntel { 1253ce8d5614SIntel portid_t pi; 1254ce8d5614SIntel struct rte_port *port; 1255ce8d5614SIntel 1256edab33b1STetsuya Mukawa FOREACH_PORT(pi, ports) { 1257ce8d5614SIntel port = &ports[pi]; 1258ce8d5614SIntel /* Check if there is a port which is not started */ 125941b05095SBernard Iremonger if ((port->port_status != RTE_PORT_STARTED) && 126041b05095SBernard Iremonger (port->slave_flag == 0)) 1261ce8d5614SIntel return 0; 1262ce8d5614SIntel } 1263ce8d5614SIntel 1264ce8d5614SIntel /* No port is not started */ 1265ce8d5614SIntel return 1; 1266ce8d5614SIntel } 1267ce8d5614SIntel 1268148f963fSBruce Richardson int 1269edab33b1STetsuya Mukawa all_ports_stopped(void) 1270edab33b1STetsuya Mukawa { 1271edab33b1STetsuya Mukawa portid_t pi; 1272edab33b1STetsuya Mukawa struct rte_port *port; 1273edab33b1STetsuya Mukawa 1274edab33b1STetsuya Mukawa FOREACH_PORT(pi, ports) { 1275edab33b1STetsuya Mukawa port = &ports[pi]; 127641b05095SBernard Iremonger if ((port->port_status != RTE_PORT_STOPPED) && 127741b05095SBernard Iremonger (port->slave_flag == 0)) 1278edab33b1STetsuya Mukawa return 0; 1279edab33b1STetsuya Mukawa } 1280edab33b1STetsuya Mukawa 1281edab33b1STetsuya Mukawa return 1; 1282edab33b1STetsuya Mukawa } 1283edab33b1STetsuya Mukawa 1284edab33b1STetsuya Mukawa int 1285edab33b1STetsuya Mukawa port_is_started(portid_t port_id) 1286edab33b1STetsuya Mukawa { 1287edab33b1STetsuya Mukawa if (port_id_is_invalid(port_id, ENABLED_WARN)) 1288edab33b1STetsuya Mukawa return 0; 1289edab33b1STetsuya Mukawa 1290edab33b1STetsuya Mukawa if (ports[port_id].port_status != RTE_PORT_STARTED) 1291edab33b1STetsuya Mukawa return 0; 1292edab33b1STetsuya Mukawa 1293edab33b1STetsuya Mukawa return 1; 1294edab33b1STetsuya Mukawa } 1295edab33b1STetsuya Mukawa 1296edab33b1STetsuya Mukawa static int 1297edab33b1STetsuya Mukawa port_is_closed(portid_t port_id) 1298edab33b1STetsuya Mukawa { 1299edab33b1STetsuya Mukawa if (port_id_is_invalid(port_id, ENABLED_WARN)) 1300edab33b1STetsuya Mukawa return 0; 1301edab33b1STetsuya Mukawa 1302edab33b1STetsuya Mukawa if (ports[port_id].port_status != RTE_PORT_CLOSED) 1303edab33b1STetsuya Mukawa return 0; 1304edab33b1STetsuya Mukawa 1305edab33b1STetsuya Mukawa return 1; 1306edab33b1STetsuya Mukawa } 1307edab33b1STetsuya Mukawa 1308edab33b1STetsuya Mukawa int 1309ce8d5614SIntel start_port(portid_t pid) 1310ce8d5614SIntel { 131192d2703eSMichael Qiu int diag, need_check_link_status = -1; 1312ce8d5614SIntel portid_t pi; 1313ce8d5614SIntel queueid_t qi; 1314ce8d5614SIntel struct rte_port *port; 13152950a769SDeclan Doherty struct ether_addr mac_addr; 1316ce8d5614SIntel 13174468635fSMichael Qiu if (port_id_is_invalid(pid, ENABLED_WARN)) 13184468635fSMichael Qiu return 0; 13194468635fSMichael Qiu 1320ce8d5614SIntel if(dcb_config) 1321ce8d5614SIntel dcb_test = 1; 1322edab33b1STetsuya Mukawa FOREACH_PORT(pi, ports) { 1323edab33b1STetsuya Mukawa if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1324ce8d5614SIntel continue; 1325ce8d5614SIntel 132692d2703eSMichael Qiu need_check_link_status = 0; 1327ce8d5614SIntel port = &ports[pi]; 1328ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 1329ce8d5614SIntel RTE_PORT_HANDLING) == 0) { 1330ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1331ce8d5614SIntel continue; 1332ce8d5614SIntel } 1333ce8d5614SIntel 1334ce8d5614SIntel if (port->need_reconfig > 0) { 1335ce8d5614SIntel port->need_reconfig = 0; 1336ce8d5614SIntel 13375706de65SJulien Cretin printf("Configuring Port %d (socket %u)\n", pi, 133820a0286fSLiu Xiaofeng port->socket_id); 1339ce8d5614SIntel /* configure port */ 1340ce8d5614SIntel diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, 1341ce8d5614SIntel &(port->dev_conf)); 1342ce8d5614SIntel if (diag != 0) { 1343ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1344ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1345ce8d5614SIntel printf("Port %d can not be set back " 1346ce8d5614SIntel "to stopped\n", pi); 1347ce8d5614SIntel printf("Fail to configure port %d\n", pi); 1348ce8d5614SIntel /* try to reconfigure port next time */ 1349ce8d5614SIntel port->need_reconfig = 1; 1350148f963fSBruce Richardson return -1; 1351ce8d5614SIntel } 1352ce8d5614SIntel } 1353ce8d5614SIntel if (port->need_reconfig_queues > 0) { 1354ce8d5614SIntel port->need_reconfig_queues = 0; 1355ce8d5614SIntel /* setup tx queues */ 1356ce8d5614SIntel for (qi = 0; qi < nb_txq; qi++) { 1357b6ea6408SIntel if ((numa_support) && 1358b6ea6408SIntel (txring_numa[pi] != NUMA_NO_CONFIG)) 1359b6ea6408SIntel diag = rte_eth_tx_queue_setup(pi, qi, 1360b6ea6408SIntel nb_txd,txring_numa[pi], 1361b6ea6408SIntel &(port->tx_conf)); 1362b6ea6408SIntel else 1363b6ea6408SIntel diag = rte_eth_tx_queue_setup(pi, qi, 1364b6ea6408SIntel nb_txd,port->socket_id, 1365b6ea6408SIntel &(port->tx_conf)); 1366b6ea6408SIntel 1367ce8d5614SIntel if (diag == 0) 1368ce8d5614SIntel continue; 1369ce8d5614SIntel 1370ce8d5614SIntel /* Fail to setup tx queue, return */ 1371ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1372ce8d5614SIntel RTE_PORT_HANDLING, 1373ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1374ce8d5614SIntel printf("Port %d can not be set back " 1375ce8d5614SIntel "to stopped\n", pi); 1376ce8d5614SIntel printf("Fail to configure port %d tx queues\n", pi); 1377ce8d5614SIntel /* try to reconfigure queues next time */ 1378ce8d5614SIntel port->need_reconfig_queues = 1; 1379148f963fSBruce Richardson return -1; 1380ce8d5614SIntel } 1381ce8d5614SIntel /* setup rx queues */ 1382ce8d5614SIntel for (qi = 0; qi < nb_rxq; qi++) { 1383b6ea6408SIntel if ((numa_support) && 1384b6ea6408SIntel (rxring_numa[pi] != NUMA_NO_CONFIG)) { 1385b6ea6408SIntel struct rte_mempool * mp = 1386b6ea6408SIntel mbuf_pool_find(rxring_numa[pi]); 1387b6ea6408SIntel if (mp == NULL) { 1388b6ea6408SIntel printf("Failed to setup RX queue:" 1389b6ea6408SIntel "No mempool allocation" 1390b6ea6408SIntel " on the socket %d\n", 1391b6ea6408SIntel rxring_numa[pi]); 1392148f963fSBruce Richardson return -1; 1393b6ea6408SIntel } 1394b6ea6408SIntel 1395b6ea6408SIntel diag = rte_eth_rx_queue_setup(pi, qi, 1396b6ea6408SIntel nb_rxd,rxring_numa[pi], 1397b6ea6408SIntel &(port->rx_conf),mp); 13981e1d6bddSBernard Iremonger } else { 13991e1d6bddSBernard Iremonger struct rte_mempool *mp = 14001e1d6bddSBernard Iremonger mbuf_pool_find(port->socket_id); 14011e1d6bddSBernard Iremonger if (mp == NULL) { 14021e1d6bddSBernard Iremonger printf("Failed to setup RX queue:" 14031e1d6bddSBernard Iremonger "No mempool allocation" 14041e1d6bddSBernard Iremonger " on the socket %d\n", 14051e1d6bddSBernard Iremonger port->socket_id); 14061e1d6bddSBernard Iremonger return -1; 1407b6ea6408SIntel } 1408b6ea6408SIntel diag = rte_eth_rx_queue_setup(pi, qi, 1409b6ea6408SIntel nb_rxd,port->socket_id, 14101e1d6bddSBernard Iremonger &(port->rx_conf), mp); 14111e1d6bddSBernard Iremonger } 1412ce8d5614SIntel if (diag == 0) 1413ce8d5614SIntel continue; 1414ce8d5614SIntel 1415ce8d5614SIntel /* Fail to setup rx queue, return */ 1416ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1417ce8d5614SIntel RTE_PORT_HANDLING, 1418ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1419ce8d5614SIntel printf("Port %d can not be set back " 1420ce8d5614SIntel "to stopped\n", pi); 1421ce8d5614SIntel printf("Fail to configure port %d rx queues\n", pi); 1422ce8d5614SIntel /* try to reconfigure queues next time */ 1423ce8d5614SIntel port->need_reconfig_queues = 1; 1424148f963fSBruce Richardson return -1; 1425ce8d5614SIntel } 1426ce8d5614SIntel } 1427ce8d5614SIntel /* start port */ 1428ce8d5614SIntel if (rte_eth_dev_start(pi) < 0) { 1429ce8d5614SIntel printf("Fail to start port %d\n", pi); 1430ce8d5614SIntel 1431ce8d5614SIntel /* Fail to setup rx queue, return */ 1432ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1433ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1434ce8d5614SIntel printf("Port %d can not be set back to " 1435ce8d5614SIntel "stopped\n", pi); 1436ce8d5614SIntel continue; 1437ce8d5614SIntel } 1438ce8d5614SIntel 1439ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1440ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 1441ce8d5614SIntel printf("Port %d can not be set into started\n", pi); 1442ce8d5614SIntel 14432950a769SDeclan Doherty rte_eth_macaddr_get(pi, &mac_addr); 1444d8c89163SZijie Pan printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, 14452950a769SDeclan Doherty mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 14462950a769SDeclan Doherty mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 14472950a769SDeclan Doherty mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); 1448d8c89163SZijie Pan 1449ce8d5614SIntel /* at least one port started, need checking link status */ 1450ce8d5614SIntel need_check_link_status = 1; 1451ce8d5614SIntel } 1452ce8d5614SIntel 145392d2703eSMichael Qiu if (need_check_link_status == 1 && !no_link_check) 1454edab33b1STetsuya Mukawa check_all_ports_link_status(RTE_PORT_ALL); 145592d2703eSMichael Qiu else if (need_check_link_status == 0) 1456ce8d5614SIntel printf("Please stop the ports first\n"); 1457ce8d5614SIntel 1458ce8d5614SIntel printf("Done\n"); 1459148f963fSBruce Richardson return 0; 1460ce8d5614SIntel } 1461ce8d5614SIntel 1462ce8d5614SIntel void 1463ce8d5614SIntel stop_port(portid_t pid) 1464ce8d5614SIntel { 1465ce8d5614SIntel portid_t pi; 1466ce8d5614SIntel struct rte_port *port; 1467ce8d5614SIntel int need_check_link_status = 0; 1468ce8d5614SIntel 1469ce8d5614SIntel if (dcb_test) { 1470ce8d5614SIntel dcb_test = 0; 1471ce8d5614SIntel dcb_config = 0; 1472ce8d5614SIntel } 14734468635fSMichael Qiu 14744468635fSMichael Qiu if (port_id_is_invalid(pid, ENABLED_WARN)) 14754468635fSMichael Qiu return; 14764468635fSMichael Qiu 1477ce8d5614SIntel printf("Stopping ports...\n"); 1478ce8d5614SIntel 1479edab33b1STetsuya Mukawa FOREACH_PORT(pi, ports) { 14804468635fSMichael Qiu if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1481ce8d5614SIntel continue; 1482ce8d5614SIntel 1483a8ef3e3aSBernard Iremonger if (port_is_forwarding(pi) != 0 && test_done == 0) { 1484a8ef3e3aSBernard Iremonger printf("Please remove port %d from forwarding configuration.\n", pi); 1485a8ef3e3aSBernard Iremonger continue; 1486a8ef3e3aSBernard Iremonger } 1487a8ef3e3aSBernard Iremonger 14880e545d30SBernard Iremonger if (port_is_bonding_slave(pi)) { 14890e545d30SBernard Iremonger printf("Please remove port %d from bonded device.\n", pi); 14900e545d30SBernard Iremonger continue; 14910e545d30SBernard Iremonger } 14920e545d30SBernard Iremonger 1493ce8d5614SIntel port = &ports[pi]; 1494ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 1495ce8d5614SIntel RTE_PORT_HANDLING) == 0) 1496ce8d5614SIntel continue; 1497ce8d5614SIntel 1498ce8d5614SIntel rte_eth_dev_stop(pi); 1499ce8d5614SIntel 1500ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1501ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1502ce8d5614SIntel printf("Port %d can not be set into stopped\n", pi); 1503ce8d5614SIntel need_check_link_status = 1; 1504ce8d5614SIntel } 1505bc202406SDavid Marchand if (need_check_link_status && !no_link_check) 1506edab33b1STetsuya Mukawa check_all_ports_link_status(RTE_PORT_ALL); 1507ce8d5614SIntel 1508ce8d5614SIntel printf("Done\n"); 1509ce8d5614SIntel } 1510ce8d5614SIntel 1511ce8d5614SIntel void 1512ce8d5614SIntel close_port(portid_t pid) 1513ce8d5614SIntel { 1514ce8d5614SIntel portid_t pi; 1515ce8d5614SIntel struct rte_port *port; 1516ce8d5614SIntel 15174468635fSMichael Qiu if (port_id_is_invalid(pid, ENABLED_WARN)) 15184468635fSMichael Qiu return; 15194468635fSMichael Qiu 1520ce8d5614SIntel printf("Closing ports...\n"); 1521ce8d5614SIntel 1522edab33b1STetsuya Mukawa FOREACH_PORT(pi, ports) { 15234468635fSMichael Qiu if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1524ce8d5614SIntel continue; 1525ce8d5614SIntel 1526a8ef3e3aSBernard Iremonger if (port_is_forwarding(pi) != 0 && test_done == 0) { 1527a8ef3e3aSBernard Iremonger printf("Please remove port %d from forwarding configuration.\n", pi); 1528a8ef3e3aSBernard Iremonger continue; 1529a8ef3e3aSBernard Iremonger } 1530a8ef3e3aSBernard Iremonger 15310e545d30SBernard Iremonger if (port_is_bonding_slave(pi)) { 15320e545d30SBernard Iremonger printf("Please remove port %d from bonded device.\n", pi); 15330e545d30SBernard Iremonger continue; 15340e545d30SBernard Iremonger } 15350e545d30SBernard Iremonger 1536ce8d5614SIntel port = &ports[pi]; 1537ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1538d4e8ad64SMichael Qiu RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { 1539d4e8ad64SMichael Qiu printf("Port %d is already closed\n", pi); 1540d4e8ad64SMichael Qiu continue; 1541d4e8ad64SMichael Qiu } 1542d4e8ad64SMichael Qiu 1543d4e8ad64SMichael Qiu if (rte_atomic16_cmpset(&(port->port_status), 1544ce8d5614SIntel RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 1545ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1546ce8d5614SIntel continue; 1547ce8d5614SIntel } 1548ce8d5614SIntel 1549*938a184aSAdrien Mazarguil if (port->flow_list) 1550*938a184aSAdrien Mazarguil port_flow_flush(pi); 1551ce8d5614SIntel rte_eth_dev_close(pi); 1552ce8d5614SIntel 1553ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1554ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 1555b38bb262SPablo de Lara printf("Port %d cannot be set to closed\n", pi); 1556ce8d5614SIntel } 1557ce8d5614SIntel 1558ce8d5614SIntel printf("Done\n"); 1559ce8d5614SIntel } 1560ce8d5614SIntel 1561edab33b1STetsuya Mukawa void 1562edab33b1STetsuya Mukawa attach_port(char *identifier) 1563ce8d5614SIntel { 1564ebf5e9b7SBernard Iremonger portid_t pi = 0; 1565931126baSBernard Iremonger unsigned int socket_id; 1566ce8d5614SIntel 1567edab33b1STetsuya Mukawa printf("Attaching a new port...\n"); 1568edab33b1STetsuya Mukawa 1569edab33b1STetsuya Mukawa if (identifier == NULL) { 1570edab33b1STetsuya Mukawa printf("Invalid parameters are specified\n"); 1571edab33b1STetsuya Mukawa return; 1572ce8d5614SIntel } 1573ce8d5614SIntel 1574edab33b1STetsuya Mukawa if (rte_eth_dev_attach(identifier, &pi)) 1575edab33b1STetsuya Mukawa return; 1576edab33b1STetsuya Mukawa 1577edab33b1STetsuya Mukawa ports[pi].enabled = 1; 1578931126baSBernard Iremonger socket_id = (unsigned)rte_eth_dev_socket_id(pi); 1579931126baSBernard Iremonger /* if socket_id is invalid, set to 0 */ 1580931126baSBernard Iremonger if (check_socket_id(socket_id) < 0) 1581931126baSBernard Iremonger socket_id = 0; 1582931126baSBernard Iremonger reconfig(pi, socket_id); 1583edab33b1STetsuya Mukawa rte_eth_promiscuous_enable(pi); 1584edab33b1STetsuya Mukawa 1585edab33b1STetsuya Mukawa nb_ports = rte_eth_dev_count(); 1586edab33b1STetsuya Mukawa 1587edab33b1STetsuya Mukawa ports[pi].port_status = RTE_PORT_STOPPED; 1588edab33b1STetsuya Mukawa 1589edab33b1STetsuya Mukawa printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); 1590edab33b1STetsuya Mukawa printf("Done\n"); 1591edab33b1STetsuya Mukawa } 1592edab33b1STetsuya Mukawa 1593edab33b1STetsuya Mukawa void 1594edab33b1STetsuya Mukawa detach_port(uint8_t port_id) 15955f4ec54fSChen Jing D(Mark) { 1596edab33b1STetsuya Mukawa char name[RTE_ETH_NAME_MAX_LEN]; 15975f4ec54fSChen Jing D(Mark) 1598edab33b1STetsuya Mukawa printf("Detaching a port...\n"); 15995f4ec54fSChen Jing D(Mark) 1600edab33b1STetsuya Mukawa if (!port_is_closed(port_id)) { 1601edab33b1STetsuya Mukawa printf("Please close port first\n"); 1602edab33b1STetsuya Mukawa return; 1603edab33b1STetsuya Mukawa } 1604edab33b1STetsuya Mukawa 1605*938a184aSAdrien Mazarguil if (ports[port_id].flow_list) 1606*938a184aSAdrien Mazarguil port_flow_flush(port_id); 1607*938a184aSAdrien Mazarguil 1608edab33b1STetsuya Mukawa if (rte_eth_dev_detach(port_id, name)) 1609edab33b1STetsuya Mukawa return; 1610edab33b1STetsuya Mukawa 1611edab33b1STetsuya Mukawa ports[port_id].enabled = 0; 1612edab33b1STetsuya Mukawa nb_ports = rte_eth_dev_count(); 1613edab33b1STetsuya Mukawa 1614edab33b1STetsuya Mukawa printf("Port '%s' is detached. Now total ports is %d\n", 1615edab33b1STetsuya Mukawa name, nb_ports); 1616edab33b1STetsuya Mukawa printf("Done\n"); 1617edab33b1STetsuya Mukawa return; 16185f4ec54fSChen Jing D(Mark) } 16195f4ec54fSChen Jing D(Mark) 1620af75078fSIntel void 1621af75078fSIntel pmd_test_exit(void) 1622af75078fSIntel { 1623af75078fSIntel portid_t pt_id; 1624af75078fSIntel 16258210ec25SPablo de Lara if (test_done == 0) 16268210ec25SPablo de Lara stop_packet_forwarding(); 16278210ec25SPablo de Lara 1628d3a274ceSZhihong Wang if (ports != NULL) { 1629d3a274ceSZhihong Wang no_link_check = 1; 1630edab33b1STetsuya Mukawa FOREACH_PORT(pt_id, ports) { 1631d3a274ceSZhihong Wang printf("\nShutting down port %d...\n", pt_id); 1632af75078fSIntel fflush(stdout); 1633d3a274ceSZhihong Wang stop_port(pt_id); 1634d3a274ceSZhihong Wang close_port(pt_id); 1635af75078fSIntel } 1636d3a274ceSZhihong Wang } 1637d3a274ceSZhihong Wang printf("\nBye...\n"); 1638af75078fSIntel } 1639af75078fSIntel 1640af75078fSIntel typedef void (*cmd_func_t)(void); 1641af75078fSIntel struct pmd_test_command { 1642af75078fSIntel const char *cmd_name; 1643af75078fSIntel cmd_func_t cmd_func; 1644af75078fSIntel }; 1645af75078fSIntel 1646af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) 1647af75078fSIntel 1648ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */ 1649af75078fSIntel static void 1650edab33b1STetsuya Mukawa check_all_ports_link_status(uint32_t port_mask) 1651af75078fSIntel { 1652ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */ 1653ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1654ce8d5614SIntel uint8_t portid, count, all_ports_up, print_flag = 0; 1655ce8d5614SIntel struct rte_eth_link link; 1656ce8d5614SIntel 1657ce8d5614SIntel printf("Checking link statuses...\n"); 1658ce8d5614SIntel fflush(stdout); 1659ce8d5614SIntel for (count = 0; count <= MAX_CHECK_TIME; count++) { 1660ce8d5614SIntel all_ports_up = 1; 1661edab33b1STetsuya Mukawa FOREACH_PORT(portid, ports) { 1662ce8d5614SIntel if ((port_mask & (1 << portid)) == 0) 1663ce8d5614SIntel continue; 1664ce8d5614SIntel memset(&link, 0, sizeof(link)); 1665ce8d5614SIntel rte_eth_link_get_nowait(portid, &link); 1666ce8d5614SIntel /* print link status if flag set */ 1667ce8d5614SIntel if (print_flag == 1) { 1668ce8d5614SIntel if (link.link_status) 1669ce8d5614SIntel printf("Port %d Link Up - speed %u " 1670ce8d5614SIntel "Mbps - %s\n", (uint8_t)portid, 1671ce8d5614SIntel (unsigned)link.link_speed, 1672ce8d5614SIntel (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1673ce8d5614SIntel ("full-duplex") : ("half-duplex\n")); 1674ce8d5614SIntel else 1675ce8d5614SIntel printf("Port %d Link Down\n", 1676ce8d5614SIntel (uint8_t)portid); 1677ce8d5614SIntel continue; 1678ce8d5614SIntel } 1679ce8d5614SIntel /* clear all_ports_up flag if any link down */ 168009419f23SThomas Monjalon if (link.link_status == ETH_LINK_DOWN) { 1681ce8d5614SIntel all_ports_up = 0; 1682ce8d5614SIntel break; 1683ce8d5614SIntel } 1684ce8d5614SIntel } 1685ce8d5614SIntel /* after finally printing all link status, get out */ 1686ce8d5614SIntel if (print_flag == 1) 1687ce8d5614SIntel break; 1688ce8d5614SIntel 1689ce8d5614SIntel if (all_ports_up == 0) { 1690ce8d5614SIntel fflush(stdout); 1691ce8d5614SIntel rte_delay_ms(CHECK_INTERVAL); 1692ce8d5614SIntel } 1693ce8d5614SIntel 1694ce8d5614SIntel /* set the print_flag if all ports up or timeout */ 1695ce8d5614SIntel if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1696ce8d5614SIntel print_flag = 1; 1697ce8d5614SIntel } 1698ce8d5614SIntel } 1699af75078fSIntel } 1700af75078fSIntel 1701013af9b6SIntel static int 1702013af9b6SIntel set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) 1703af75078fSIntel { 1704013af9b6SIntel uint16_t i; 1705af75078fSIntel int diag; 1706013af9b6SIntel uint8_t mapping_found = 0; 1707af75078fSIntel 1708013af9b6SIntel for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 1709013af9b6SIntel if ((tx_queue_stats_mappings[i].port_id == port_id) && 1710013af9b6SIntel (tx_queue_stats_mappings[i].queue_id < nb_txq )) { 1711013af9b6SIntel diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, 1712013af9b6SIntel tx_queue_stats_mappings[i].queue_id, 1713013af9b6SIntel tx_queue_stats_mappings[i].stats_counter_id); 1714013af9b6SIntel if (diag != 0) 1715013af9b6SIntel return diag; 1716013af9b6SIntel mapping_found = 1; 1717af75078fSIntel } 1718013af9b6SIntel } 1719013af9b6SIntel if (mapping_found) 1720013af9b6SIntel port->tx_queue_stats_mapping_enabled = 1; 1721013af9b6SIntel return 0; 1722013af9b6SIntel } 1723013af9b6SIntel 1724013af9b6SIntel static int 1725013af9b6SIntel set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) 1726013af9b6SIntel { 1727013af9b6SIntel uint16_t i; 1728013af9b6SIntel int diag; 1729013af9b6SIntel uint8_t mapping_found = 0; 1730013af9b6SIntel 1731013af9b6SIntel for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 1732013af9b6SIntel if ((rx_queue_stats_mappings[i].port_id == port_id) && 1733013af9b6SIntel (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { 1734013af9b6SIntel diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, 1735013af9b6SIntel rx_queue_stats_mappings[i].queue_id, 1736013af9b6SIntel rx_queue_stats_mappings[i].stats_counter_id); 1737013af9b6SIntel if (diag != 0) 1738013af9b6SIntel return diag; 1739013af9b6SIntel mapping_found = 1; 1740013af9b6SIntel } 1741013af9b6SIntel } 1742013af9b6SIntel if (mapping_found) 1743013af9b6SIntel port->rx_queue_stats_mapping_enabled = 1; 1744013af9b6SIntel return 0; 1745013af9b6SIntel } 1746013af9b6SIntel 1747013af9b6SIntel static void 1748013af9b6SIntel map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port) 1749013af9b6SIntel { 1750013af9b6SIntel int diag = 0; 1751013af9b6SIntel 1752013af9b6SIntel diag = set_tx_queue_stats_mapping_registers(pi, port); 1753af75078fSIntel if (diag != 0) { 1754013af9b6SIntel if (diag == -ENOTSUP) { 1755013af9b6SIntel port->tx_queue_stats_mapping_enabled = 0; 1756013af9b6SIntel printf("TX queue stats mapping not supported port id=%d\n", pi); 1757013af9b6SIntel } 1758013af9b6SIntel else 1759013af9b6SIntel rte_exit(EXIT_FAILURE, 1760013af9b6SIntel "set_tx_queue_stats_mapping_registers " 1761013af9b6SIntel "failed for port id=%d diag=%d\n", 1762af75078fSIntel pi, diag); 1763af75078fSIntel } 1764013af9b6SIntel 1765013af9b6SIntel diag = set_rx_queue_stats_mapping_registers(pi, port); 1766af75078fSIntel if (diag != 0) { 1767013af9b6SIntel if (diag == -ENOTSUP) { 1768013af9b6SIntel port->rx_queue_stats_mapping_enabled = 0; 1769013af9b6SIntel printf("RX queue stats mapping not supported port id=%d\n", pi); 1770013af9b6SIntel } 1771013af9b6SIntel else 1772013af9b6SIntel rte_exit(EXIT_FAILURE, 1773013af9b6SIntel "set_rx_queue_stats_mapping_registers " 1774013af9b6SIntel "failed for port id=%d diag=%d\n", 1775af75078fSIntel pi, diag); 1776af75078fSIntel } 1777af75078fSIntel } 1778af75078fSIntel 1779f2c5125aSPablo de Lara static void 1780f2c5125aSPablo de Lara rxtx_port_config(struct rte_port *port) 1781f2c5125aSPablo de Lara { 1782f2c5125aSPablo de Lara port->rx_conf = port->dev_info.default_rxconf; 1783f2c5125aSPablo de Lara port->tx_conf = port->dev_info.default_txconf; 1784f2c5125aSPablo de Lara 1785f2c5125aSPablo de Lara /* Check if any RX/TX parameters have been passed */ 1786f2c5125aSPablo de Lara if (rx_pthresh != RTE_PMD_PARAM_UNSET) 1787f2c5125aSPablo de Lara port->rx_conf.rx_thresh.pthresh = rx_pthresh; 1788f2c5125aSPablo de Lara 1789f2c5125aSPablo de Lara if (rx_hthresh != RTE_PMD_PARAM_UNSET) 1790f2c5125aSPablo de Lara port->rx_conf.rx_thresh.hthresh = rx_hthresh; 1791f2c5125aSPablo de Lara 1792f2c5125aSPablo de Lara if (rx_wthresh != RTE_PMD_PARAM_UNSET) 1793f2c5125aSPablo de Lara port->rx_conf.rx_thresh.wthresh = rx_wthresh; 1794f2c5125aSPablo de Lara 1795f2c5125aSPablo de Lara if (rx_free_thresh != RTE_PMD_PARAM_UNSET) 1796f2c5125aSPablo de Lara port->rx_conf.rx_free_thresh = rx_free_thresh; 1797f2c5125aSPablo de Lara 1798f2c5125aSPablo de Lara if (rx_drop_en != RTE_PMD_PARAM_UNSET) 1799f2c5125aSPablo de Lara port->rx_conf.rx_drop_en = rx_drop_en; 1800f2c5125aSPablo de Lara 1801f2c5125aSPablo de Lara if (tx_pthresh != RTE_PMD_PARAM_UNSET) 1802f2c5125aSPablo de Lara port->tx_conf.tx_thresh.pthresh = tx_pthresh; 1803f2c5125aSPablo de Lara 1804f2c5125aSPablo de Lara if (tx_hthresh != RTE_PMD_PARAM_UNSET) 1805f2c5125aSPablo de Lara port->tx_conf.tx_thresh.hthresh = tx_hthresh; 1806f2c5125aSPablo de Lara 1807f2c5125aSPablo de Lara if (tx_wthresh != RTE_PMD_PARAM_UNSET) 1808f2c5125aSPablo de Lara port->tx_conf.tx_thresh.wthresh = tx_wthresh; 1809f2c5125aSPablo de Lara 1810f2c5125aSPablo de Lara if (tx_rs_thresh != RTE_PMD_PARAM_UNSET) 1811f2c5125aSPablo de Lara port->tx_conf.tx_rs_thresh = tx_rs_thresh; 1812f2c5125aSPablo de Lara 1813f2c5125aSPablo de Lara if (tx_free_thresh != RTE_PMD_PARAM_UNSET) 1814f2c5125aSPablo de Lara port->tx_conf.tx_free_thresh = tx_free_thresh; 1815f2c5125aSPablo de Lara 1816f2c5125aSPablo de Lara if (txq_flags != RTE_PMD_PARAM_UNSET) 1817f2c5125aSPablo de Lara port->tx_conf.txq_flags = txq_flags; 1818f2c5125aSPablo de Lara } 1819f2c5125aSPablo de Lara 1820013af9b6SIntel void 1821013af9b6SIntel init_port_config(void) 1822013af9b6SIntel { 1823013af9b6SIntel portid_t pid; 1824013af9b6SIntel struct rte_port *port; 1825013af9b6SIntel 1826edab33b1STetsuya Mukawa FOREACH_PORT(pid, ports) { 1827013af9b6SIntel port = &ports[pid]; 1828013af9b6SIntel port->dev_conf.rxmode = rx_mode; 1829013af9b6SIntel port->dev_conf.fdir_conf = fdir_conf; 18303ce690d3SBruce Richardson if (nb_rxq > 1) { 1831013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1832013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf; 1833af75078fSIntel } else { 1834013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1835013af9b6SIntel port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; 1836af75078fSIntel } 18373ce690d3SBruce Richardson 18383ce690d3SBruce Richardson if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) { 18393ce690d3SBruce Richardson if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 18403ce690d3SBruce Richardson port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 18413ce690d3SBruce Richardson else 18423ce690d3SBruce Richardson port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; 18433ce690d3SBruce Richardson } 18443ce690d3SBruce Richardson 1845a30979f6SOuyang Changchun if (port->dev_info.max_vfs != 0) { 1846a30979f6SOuyang Changchun if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 1847a30979f6SOuyang Changchun port->dev_conf.rxmode.mq_mode = 1848a30979f6SOuyang Changchun ETH_MQ_RX_VMDQ_RSS; 1849a30979f6SOuyang Changchun else 1850a30979f6SOuyang Changchun port->dev_conf.rxmode.mq_mode = 1851a30979f6SOuyang Changchun ETH_MQ_RX_NONE; 1852a30979f6SOuyang Changchun 1853a30979f6SOuyang Changchun port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE; 1854a30979f6SOuyang Changchun } 1855a30979f6SOuyang Changchun 1856f2c5125aSPablo de Lara rxtx_port_config(port); 1857013af9b6SIntel 1858013af9b6SIntel rte_eth_macaddr_get(pid, &port->eth_addr); 1859013af9b6SIntel 1860013af9b6SIntel map_port_queue_stats_mapping_registers(pid, port); 18617b7e5ba7SIntel #ifdef RTE_NIC_BYPASS 18627b7e5ba7SIntel rte_eth_dev_bypass_init(pid); 18637b7e5ba7SIntel #endif 1864013af9b6SIntel } 1865013af9b6SIntel } 1866013af9b6SIntel 186741b05095SBernard Iremonger void set_port_slave_flag(portid_t slave_pid) 186841b05095SBernard Iremonger { 186941b05095SBernard Iremonger struct rte_port *port; 187041b05095SBernard Iremonger 187141b05095SBernard Iremonger port = &ports[slave_pid]; 187241b05095SBernard Iremonger port->slave_flag = 1; 187341b05095SBernard Iremonger } 187441b05095SBernard Iremonger 187541b05095SBernard Iremonger void clear_port_slave_flag(portid_t slave_pid) 187641b05095SBernard Iremonger { 187741b05095SBernard Iremonger struct rte_port *port; 187841b05095SBernard Iremonger 187941b05095SBernard Iremonger port = &ports[slave_pid]; 188041b05095SBernard Iremonger port->slave_flag = 0; 188141b05095SBernard Iremonger } 188241b05095SBernard Iremonger 18830e545d30SBernard Iremonger uint8_t port_is_bonding_slave(portid_t slave_pid) 18840e545d30SBernard Iremonger { 18850e545d30SBernard Iremonger struct rte_port *port; 18860e545d30SBernard Iremonger 18870e545d30SBernard Iremonger port = &ports[slave_pid]; 18880e545d30SBernard Iremonger return port->slave_flag; 18890e545d30SBernard Iremonger } 18900e545d30SBernard Iremonger 1891013af9b6SIntel const uint16_t vlan_tags[] = { 1892013af9b6SIntel 0, 1, 2, 3, 4, 5, 6, 7, 1893013af9b6SIntel 8, 9, 10, 11, 12, 13, 14, 15, 1894013af9b6SIntel 16, 17, 18, 19, 20, 21, 22, 23, 1895013af9b6SIntel 24, 25, 26, 27, 28, 29, 30, 31 1896013af9b6SIntel }; 1897013af9b6SIntel 1898013af9b6SIntel static int 18991a572499SJingjing Wu get_eth_dcb_conf(struct rte_eth_conf *eth_conf, 19001a572499SJingjing Wu enum dcb_mode_enable dcb_mode, 19011a572499SJingjing Wu enum rte_eth_nb_tcs num_tcs, 19021a572499SJingjing Wu uint8_t pfc_en) 1903013af9b6SIntel { 1904013af9b6SIntel uint8_t i; 1905af75078fSIntel 1906af75078fSIntel /* 1907013af9b6SIntel * Builds up the correct configuration for dcb+vt based on the vlan tags array 1908013af9b6SIntel * given above, and the number of traffic classes available for use. 1909af75078fSIntel */ 19101a572499SJingjing Wu if (dcb_mode == DCB_VT_ENABLED) { 19111a572499SJingjing Wu struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf = 19121a572499SJingjing Wu ð_conf->rx_adv_conf.vmdq_dcb_conf; 19131a572499SJingjing Wu struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf = 19141a572499SJingjing Wu ð_conf->tx_adv_conf.vmdq_dcb_tx_conf; 1915013af9b6SIntel 1916013af9b6SIntel /* VMDQ+DCB RX and TX configrations */ 19171a572499SJingjing Wu vmdq_rx_conf->enable_default_pool = 0; 19181a572499SJingjing Wu vmdq_rx_conf->default_pool = 0; 19191a572499SJingjing Wu vmdq_rx_conf->nb_queue_pools = 19201a572499SJingjing Wu (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 19211a572499SJingjing Wu vmdq_tx_conf->nb_queue_pools = 19221a572499SJingjing Wu (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 1923013af9b6SIntel 19241a572499SJingjing Wu vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools; 19251a572499SJingjing Wu for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) { 19261a572499SJingjing Wu vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i]; 19271a572499SJingjing Wu vmdq_rx_conf->pool_map[i].pools = 19281a572499SJingjing Wu 1 << (i % vmdq_rx_conf->nb_queue_pools); 1929af75078fSIntel } 1930013af9b6SIntel for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 19311a572499SJingjing Wu vmdq_rx_conf->dcb_tc[i] = i; 19321a572499SJingjing Wu vmdq_tx_conf->dcb_tc[i] = i; 1933013af9b6SIntel } 1934013af9b6SIntel 1935013af9b6SIntel /* set DCB mode of RX and TX of multiple queues */ 193632e7aa0bSIntel eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB; 193732e7aa0bSIntel eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB; 19381a572499SJingjing Wu } else { 19391a572499SJingjing Wu struct rte_eth_dcb_rx_conf *rx_conf = 19401a572499SJingjing Wu ð_conf->rx_adv_conf.dcb_rx_conf; 19411a572499SJingjing Wu struct rte_eth_dcb_tx_conf *tx_conf = 19421a572499SJingjing Wu ð_conf->tx_adv_conf.dcb_tx_conf; 1943013af9b6SIntel 19441a572499SJingjing Wu rx_conf->nb_tcs = num_tcs; 19451a572499SJingjing Wu tx_conf->nb_tcs = num_tcs; 19461a572499SJingjing Wu 19471a572499SJingjing Wu for (i = 0; i < num_tcs; i++) { 19481a572499SJingjing Wu rx_conf->dcb_tc[i] = i; 19491a572499SJingjing Wu tx_conf->dcb_tc[i] = i; 1950013af9b6SIntel } 19511a572499SJingjing Wu eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS; 19521a572499SJingjing Wu eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf; 195332e7aa0bSIntel eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB; 19541a572499SJingjing Wu } 19551a572499SJingjing Wu 19561a572499SJingjing Wu if (pfc_en) 19571a572499SJingjing Wu eth_conf->dcb_capability_en = 19581a572499SJingjing Wu ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT; 1959013af9b6SIntel else 1960013af9b6SIntel eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 1961013af9b6SIntel 1962013af9b6SIntel return 0; 1963013af9b6SIntel } 1964013af9b6SIntel 1965013af9b6SIntel int 19661a572499SJingjing Wu init_port_dcb_config(portid_t pid, 19671a572499SJingjing Wu enum dcb_mode_enable dcb_mode, 19681a572499SJingjing Wu enum rte_eth_nb_tcs num_tcs, 19691a572499SJingjing Wu uint8_t pfc_en) 1970013af9b6SIntel { 1971013af9b6SIntel struct rte_eth_conf port_conf; 1972013af9b6SIntel struct rte_port *rte_port; 1973013af9b6SIntel int retval; 1974013af9b6SIntel uint16_t i; 1975013af9b6SIntel 19762a977b89SWenzhuo Lu rte_port = &ports[pid]; 1977013af9b6SIntel 1978013af9b6SIntel memset(&port_conf, 0, sizeof(struct rte_eth_conf)); 1979013af9b6SIntel /* Enter DCB configuration status */ 1980013af9b6SIntel dcb_config = 1; 1981013af9b6SIntel 1982013af9b6SIntel /*set configuration of DCB in vt mode and DCB in non-vt mode*/ 19831a572499SJingjing Wu retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en); 1984013af9b6SIntel if (retval < 0) 1985013af9b6SIntel return retval; 19862a977b89SWenzhuo Lu port_conf.rxmode.hw_vlan_filter = 1; 1987013af9b6SIntel 19882a977b89SWenzhuo Lu /** 19892a977b89SWenzhuo Lu * Write the configuration into the device. 19902a977b89SWenzhuo Lu * Set the numbers of RX & TX queues to 0, so 19912a977b89SWenzhuo Lu * the RX & TX queues will not be setup. 19922a977b89SWenzhuo Lu */ 19932a977b89SWenzhuo Lu (void)rte_eth_dev_configure(pid, 0, 0, &port_conf); 19942a977b89SWenzhuo Lu 19952a977b89SWenzhuo Lu rte_eth_dev_info_get(pid, &rte_port->dev_info); 19962a977b89SWenzhuo Lu 19972a977b89SWenzhuo Lu /* If dev_info.vmdq_pool_base is greater than 0, 19982a977b89SWenzhuo Lu * the queue id of vmdq pools is started after pf queues. 19992a977b89SWenzhuo Lu */ 20002a977b89SWenzhuo Lu if (dcb_mode == DCB_VT_ENABLED && 20012a977b89SWenzhuo Lu rte_port->dev_info.vmdq_pool_base > 0) { 20022a977b89SWenzhuo Lu printf("VMDQ_DCB multi-queue mode is nonsensical" 20032a977b89SWenzhuo Lu " for port %d.", pid); 20042a977b89SWenzhuo Lu return -1; 20052a977b89SWenzhuo Lu } 20062a977b89SWenzhuo Lu 20072a977b89SWenzhuo Lu /* Assume the ports in testpmd have the same dcb capability 20082a977b89SWenzhuo Lu * and has the same number of rxq and txq in dcb mode 20092a977b89SWenzhuo Lu */ 20102a977b89SWenzhuo Lu if (dcb_mode == DCB_VT_ENABLED) { 201186ef65eeSBernard Iremonger if (rte_port->dev_info.max_vfs > 0) { 201286ef65eeSBernard Iremonger nb_rxq = rte_port->dev_info.nb_rx_queues; 201386ef65eeSBernard Iremonger nb_txq = rte_port->dev_info.nb_tx_queues; 201486ef65eeSBernard Iremonger } else { 20152a977b89SWenzhuo Lu nb_rxq = rte_port->dev_info.max_rx_queues; 20162a977b89SWenzhuo Lu nb_txq = rte_port->dev_info.max_tx_queues; 201786ef65eeSBernard Iremonger } 20182a977b89SWenzhuo Lu } else { 20192a977b89SWenzhuo Lu /*if vt is disabled, use all pf queues */ 20202a977b89SWenzhuo Lu if (rte_port->dev_info.vmdq_pool_base == 0) { 20212a977b89SWenzhuo Lu nb_rxq = rte_port->dev_info.max_rx_queues; 20222a977b89SWenzhuo Lu nb_txq = rte_port->dev_info.max_tx_queues; 20232a977b89SWenzhuo Lu } else { 20242a977b89SWenzhuo Lu nb_rxq = (queueid_t)num_tcs; 20252a977b89SWenzhuo Lu nb_txq = (queueid_t)num_tcs; 20262a977b89SWenzhuo Lu 20272a977b89SWenzhuo Lu } 20282a977b89SWenzhuo Lu } 20292a977b89SWenzhuo Lu rx_free_thresh = 64; 20302a977b89SWenzhuo Lu 2031013af9b6SIntel memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf)); 2032013af9b6SIntel 2033f2c5125aSPablo de Lara rxtx_port_config(rte_port); 2034013af9b6SIntel /* VLAN filter */ 2035013af9b6SIntel rte_port->dev_conf.rxmode.hw_vlan_filter = 1; 20361a572499SJingjing Wu for (i = 0; i < RTE_DIM(vlan_tags); i++) 2037013af9b6SIntel rx_vft_set(pid, vlan_tags[i], 1); 2038013af9b6SIntel 2039013af9b6SIntel rte_eth_macaddr_get(pid, &rte_port->eth_addr); 2040013af9b6SIntel map_port_queue_stats_mapping_registers(pid, rte_port); 2041013af9b6SIntel 20427741e4cfSIntel rte_port->dcb_flag = 1; 20437741e4cfSIntel 2044013af9b6SIntel return 0; 2045af75078fSIntel } 2046af75078fSIntel 2047ffc468ffSTetsuya Mukawa static void 2048ffc468ffSTetsuya Mukawa init_port(void) 2049ffc468ffSTetsuya Mukawa { 2050ffc468ffSTetsuya Mukawa portid_t pid; 2051ffc468ffSTetsuya Mukawa 2052ffc468ffSTetsuya Mukawa /* Configuration of Ethernet ports. */ 2053ffc468ffSTetsuya Mukawa ports = rte_zmalloc("testpmd: ports", 2054ffc468ffSTetsuya Mukawa sizeof(struct rte_port) * RTE_MAX_ETHPORTS, 2055ffc468ffSTetsuya Mukawa RTE_CACHE_LINE_SIZE); 2056ffc468ffSTetsuya Mukawa if (ports == NULL) { 2057ffc468ffSTetsuya Mukawa rte_exit(EXIT_FAILURE, 2058ffc468ffSTetsuya Mukawa "rte_zmalloc(%d struct rte_port) failed\n", 2059ffc468ffSTetsuya Mukawa RTE_MAX_ETHPORTS); 2060ffc468ffSTetsuya Mukawa } 2061ffc468ffSTetsuya Mukawa 2062ffc468ffSTetsuya Mukawa /* enabled allocated ports */ 2063ffc468ffSTetsuya Mukawa for (pid = 0; pid < nb_ports; pid++) 2064ffc468ffSTetsuya Mukawa ports[pid].enabled = 1; 2065ffc468ffSTetsuya Mukawa } 2066ffc468ffSTetsuya Mukawa 2067d3a274ceSZhihong Wang static void 2068d3a274ceSZhihong Wang force_quit(void) 2069d3a274ceSZhihong Wang { 2070d3a274ceSZhihong Wang pmd_test_exit(); 2071d3a274ceSZhihong Wang prompt_exit(); 2072d3a274ceSZhihong Wang } 2073d3a274ceSZhihong Wang 2074d3a274ceSZhihong Wang static void 2075d3a274ceSZhihong Wang signal_handler(int signum) 2076d3a274ceSZhihong Wang { 2077d3a274ceSZhihong Wang if (signum == SIGINT || signum == SIGTERM) { 2078d3a274ceSZhihong Wang printf("\nSignal %d received, preparing to exit...\n", 2079d3a274ceSZhihong Wang signum); 2080102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP 2081102b7329SReshma Pattan /* uninitialize packet capture framework */ 2082102b7329SReshma Pattan rte_pdump_uninit(); 2083102b7329SReshma Pattan #endif 2084d3a274ceSZhihong Wang force_quit(); 2085d3a274ceSZhihong Wang /* exit with the expected status */ 2086d3a274ceSZhihong Wang signal(signum, SIG_DFL); 2087d3a274ceSZhihong Wang kill(getpid(), signum); 2088d3a274ceSZhihong Wang } 2089d3a274ceSZhihong Wang } 2090d3a274ceSZhihong Wang 2091af75078fSIntel int 2092af75078fSIntel main(int argc, char** argv) 2093af75078fSIntel { 2094af75078fSIntel int diag; 2095013af9b6SIntel uint8_t port_id; 2096af75078fSIntel 2097d3a274ceSZhihong Wang signal(SIGINT, signal_handler); 2098d3a274ceSZhihong Wang signal(SIGTERM, signal_handler); 2099d3a274ceSZhihong Wang 2100af75078fSIntel diag = rte_eal_init(argc, argv); 2101af75078fSIntel if (diag < 0) 2102af75078fSIntel rte_panic("Cannot init EAL\n"); 2103af75078fSIntel 2104102b7329SReshma Pattan #ifdef RTE_LIBRTE_PDUMP 2105102b7329SReshma Pattan /* initialize packet capture framework */ 2106102b7329SReshma Pattan rte_pdump_init(NULL); 2107102b7329SReshma Pattan #endif 2108102b7329SReshma Pattan 2109af75078fSIntel nb_ports = (portid_t) rte_eth_dev_count(); 2110af75078fSIntel if (nb_ports == 0) 2111edab33b1STetsuya Mukawa RTE_LOG(WARNING, EAL, "No probed ethernet devices\n"); 2112af75078fSIntel 2113ffc468ffSTetsuya Mukawa /* allocate port structures, and init them */ 2114ffc468ffSTetsuya Mukawa init_port(); 2115ffc468ffSTetsuya Mukawa 2116af75078fSIntel set_def_fwd_config(); 2117af75078fSIntel if (nb_lcores == 0) 2118af75078fSIntel rte_panic("Empty set of forwarding logical cores - check the " 2119af75078fSIntel "core mask supplied in the command parameters\n"); 2120af75078fSIntel 2121af75078fSIntel argc -= diag; 2122af75078fSIntel argv += diag; 2123af75078fSIntel if (argc > 1) 2124af75078fSIntel launch_args_parse(argc, argv); 2125af75078fSIntel 21265a8fb55cSReshma Pattan if (!nb_rxq && !nb_txq) 21275a8fb55cSReshma Pattan printf("Warning: Either rx or tx queues should be non-zero\n"); 21285a8fb55cSReshma Pattan 21295a8fb55cSReshma Pattan if (nb_rxq > 1 && nb_rxq > nb_txq) 2130af75078fSIntel printf("Warning: nb_rxq=%d enables RSS configuration, " 2131af75078fSIntel "but nb_txq=%d will prevent to fully test it.\n", 2132af75078fSIntel nb_rxq, nb_txq); 2133af75078fSIntel 2134af75078fSIntel init_config(); 2135148f963fSBruce Richardson if (start_port(RTE_PORT_ALL) != 0) 2136148f963fSBruce Richardson rte_exit(EXIT_FAILURE, "Start ports failed\n"); 2137af75078fSIntel 2138ce8d5614SIntel /* set all ports to promiscuous mode by default */ 2139edab33b1STetsuya Mukawa FOREACH_PORT(port_id, ports) 2140ce8d5614SIntel rte_eth_promiscuous_enable(port_id); 2141af75078fSIntel 21420d56cb81SThomas Monjalon #ifdef RTE_LIBRTE_CMDLINE 2143ca7feb22SCyril Chemparathy if (interactive == 1) { 2144ca7feb22SCyril Chemparathy if (auto_start) { 2145ca7feb22SCyril Chemparathy printf("Start automatic packet forwarding\n"); 2146ca7feb22SCyril Chemparathy start_packet_forwarding(0); 2147ca7feb22SCyril Chemparathy } 2148af75078fSIntel prompt(); 2149ca7feb22SCyril Chemparathy } else 21500d56cb81SThomas Monjalon #endif 21510d56cb81SThomas Monjalon { 2152af75078fSIntel char c; 2153af75078fSIntel int rc; 2154af75078fSIntel 2155af75078fSIntel printf("No commandline core given, start packet forwarding\n"); 2156af75078fSIntel start_packet_forwarding(0); 2157af75078fSIntel printf("Press enter to exit\n"); 2158af75078fSIntel rc = read(0, &c, 1); 2159d3a274ceSZhihong Wang pmd_test_exit(); 2160af75078fSIntel if (rc < 0) 2161af75078fSIntel return 1; 2162af75078fSIntel } 2163af75078fSIntel 2164af75078fSIntel return 0; 2165af75078fSIntel } 2166