1af75078fSIntel /*- 2af75078fSIntel * BSD LICENSE 3af75078fSIntel * 4af75078fSIntel * Copyright(c) 2010-2012 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 35af75078fSIntel #include <stdarg.h> 36af75078fSIntel #include <stdio.h> 37af75078fSIntel #include <stdlib.h> 38af75078fSIntel #include <signal.h> 39af75078fSIntel #include <string.h> 40af75078fSIntel #include <time.h> 41af75078fSIntel #include <fcntl.h> 42af75078fSIntel #include <sys/types.h> 43af75078fSIntel #include <errno.h> 44af75078fSIntel 45af75078fSIntel #include <sys/queue.h> 46af75078fSIntel #include <sys/stat.h> 47af75078fSIntel 48af75078fSIntel #include <stdint.h> 49af75078fSIntel #include <unistd.h> 50af75078fSIntel #include <inttypes.h> 51af75078fSIntel 52af75078fSIntel #include <rte_common.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_tailq.h> 62af75078fSIntel #include <rte_eal.h> 63af75078fSIntel #include <rte_per_lcore.h> 64af75078fSIntel #include <rte_lcore.h> 65af75078fSIntel #include <rte_atomic.h> 66af75078fSIntel #include <rte_branch_prediction.h> 67af75078fSIntel #include <rte_ring.h> 68af75078fSIntel #include <rte_mempool.h> 69af75078fSIntel #include <rte_malloc.h> 70af75078fSIntel #include <rte_mbuf.h> 71af75078fSIntel #include <rte_interrupts.h> 72af75078fSIntel #include <rte_pci.h> 73af75078fSIntel #include <rte_ether.h> 74af75078fSIntel #include <rte_ethdev.h> 75af75078fSIntel #include <rte_string_fns.h> 76af75078fSIntel 77af75078fSIntel #include "testpmd.h" 78af75078fSIntel 79af75078fSIntel uint16_t verbose_level = 0; /**< Silent by default. */ 80af75078fSIntel 81af75078fSIntel /* use master core for command line ? */ 82af75078fSIntel uint8_t interactive = 0; 83af75078fSIntel 84af75078fSIntel /* 85af75078fSIntel * NUMA support configuration. 86af75078fSIntel * When set, the NUMA support attempts to dispatch the allocation of the 87af75078fSIntel * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the 88af75078fSIntel * probed ports among the CPU sockets 0 and 1. 89af75078fSIntel * Otherwise, all memory is allocated from CPU socket 0. 90af75078fSIntel */ 91af75078fSIntel uint8_t numa_support = 0; /**< No numa support by default */ 92af75078fSIntel 93af75078fSIntel /* 94af75078fSIntel * Record the Ethernet address of peer target ports to which packets are 95af75078fSIntel * forwarded. 96af75078fSIntel * Must be instanciated with the ethernet addresses of peer traffic generator 97af75078fSIntel * ports. 98af75078fSIntel */ 99af75078fSIntel struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; 100af75078fSIntel portid_t nb_peer_eth_addrs = 0; 101af75078fSIntel 102af75078fSIntel /* 103af75078fSIntel * Probed Target Environment. 104af75078fSIntel */ 105af75078fSIntel struct rte_port *ports; /**< For all probed ethernet ports. */ 106af75078fSIntel portid_t nb_ports; /**< Number of probed ethernet ports. */ 107af75078fSIntel struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */ 108af75078fSIntel lcoreid_t nb_lcores; /**< Number of probed logical cores. */ 109af75078fSIntel 110af75078fSIntel /* 111af75078fSIntel * Test Forwarding Configuration. 112af75078fSIntel * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores 113af75078fSIntel * nb_fwd_ports <= nb_cfg_ports <= nb_ports 114af75078fSIntel */ 115af75078fSIntel lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */ 116af75078fSIntel lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */ 117af75078fSIntel portid_t nb_cfg_ports; /**< Number of configured ports. */ 118af75078fSIntel portid_t nb_fwd_ports; /**< Number of forwarding ports. */ 119af75078fSIntel 120af75078fSIntel unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */ 121af75078fSIntel portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */ 122af75078fSIntel 123af75078fSIntel struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */ 124af75078fSIntel streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ 125af75078fSIntel 126af75078fSIntel /* 127af75078fSIntel * Forwarding engines. 128af75078fSIntel */ 129af75078fSIntel struct fwd_engine * fwd_engines[] = { 130af75078fSIntel &io_fwd_engine, 131af75078fSIntel &mac_fwd_engine, 132af75078fSIntel &rx_only_engine, 133af75078fSIntel &tx_only_engine, 134af75078fSIntel &csum_fwd_engine, 135af75078fSIntel #ifdef RTE_LIBRTE_IEEE1588 136af75078fSIntel &ieee1588_fwd_engine, 137af75078fSIntel #endif 138af75078fSIntel NULL, 139af75078fSIntel }; 140af75078fSIntel 141af75078fSIntel struct fwd_config cur_fwd_config; 142af75078fSIntel struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ 143af75078fSIntel 144af75078fSIntel uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ 145c8798818SIntel uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if 146c8798818SIntel * specified on command-line. */ 147af75078fSIntel 148af75078fSIntel /* 149af75078fSIntel * Configuration of packet segments used by the "txonly" processing engine. 150af75078fSIntel */ 151af75078fSIntel uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */ 152af75078fSIntel uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = { 153af75078fSIntel TXONLY_DEF_PACKET_LEN, 154af75078fSIntel }; 155af75078fSIntel uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */ 156af75078fSIntel 157af75078fSIntel uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */ 158af75078fSIntel uint16_t mb_mempool_cache = DEF_PKT_BURST; /**< Size of mbuf mempool cache. */ 159af75078fSIntel 160*900550deSIntel /* current configuration is in DCB or not,0 means it is not in DCB mode */ 161*900550deSIntel uint8_t dcb_config = 0; 162*900550deSIntel 163*900550deSIntel /* Whether the dcb is in testing status */ 164*900550deSIntel uint8_t dcb_test = 0; 165*900550deSIntel 166*900550deSIntel /* DCB on and VT on mapping is default */ 167*900550deSIntel enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING; 168af75078fSIntel 169af75078fSIntel /* 170af75078fSIntel * Configurable number of RX/TX queues. 171af75078fSIntel */ 172af75078fSIntel queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ 173af75078fSIntel queueid_t nb_txq = 1; /**< Number of TX queues per port. */ 174af75078fSIntel 175af75078fSIntel /* 176af75078fSIntel * Configurable number of RX/TX ring descriptors. 177af75078fSIntel */ 178af75078fSIntel #define RTE_TEST_RX_DESC_DEFAULT 128 179af75078fSIntel #define RTE_TEST_TX_DESC_DEFAULT 512 180af75078fSIntel uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */ 181af75078fSIntel uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */ 182af75078fSIntel 183af75078fSIntel /* 184af75078fSIntel * Configurable values of RX and TX ring threshold registers. 185af75078fSIntel */ 186af75078fSIntel #define RX_PTHRESH 8 /**< Default value of RX prefetch threshold register. */ 187af75078fSIntel #define RX_HTHRESH 8 /**< Default value of RX host threshold register. */ 188af75078fSIntel #define RX_WTHRESH 4 /**< Default value of RX write-back threshold register. */ 189af75078fSIntel 190af75078fSIntel #define TX_PTHRESH 36 /**< Default value of TX prefetch threshold register. */ 191af75078fSIntel #define TX_HTHRESH 0 /**< Default value of TX host threshold register. */ 192af75078fSIntel #define TX_WTHRESH 0 /**< Default value of TX write-back threshold register. */ 193af75078fSIntel 194af75078fSIntel struct rte_eth_thresh rx_thresh = { 195af75078fSIntel .pthresh = RX_PTHRESH, 196af75078fSIntel .hthresh = RX_HTHRESH, 197af75078fSIntel .wthresh = RX_WTHRESH, 198af75078fSIntel }; 199af75078fSIntel 200af75078fSIntel struct rte_eth_thresh tx_thresh = { 201af75078fSIntel .pthresh = TX_PTHRESH, 202af75078fSIntel .hthresh = TX_HTHRESH, 203af75078fSIntel .wthresh = TX_WTHRESH, 204af75078fSIntel }; 205af75078fSIntel 206af75078fSIntel /* 207af75078fSIntel * Configurable value of RX free threshold. 208af75078fSIntel */ 209af75078fSIntel uint16_t rx_free_thresh = 0; /* Immediately free RX descriptors by default. */ 210af75078fSIntel 211af75078fSIntel /* 212ce8d5614SIntel * Configurable value of RX drop enable. 213ce8d5614SIntel */ 214ce8d5614SIntel uint8_t rx_drop_en = 0; /* Drop packets when no descriptors for queue. */ 215ce8d5614SIntel 216ce8d5614SIntel /* 217af75078fSIntel * Configurable value of TX free threshold. 218af75078fSIntel */ 219af75078fSIntel uint16_t tx_free_thresh = 0; /* Use default values. */ 220af75078fSIntel 221af75078fSIntel /* 222af75078fSIntel * Configurable value of TX RS bit threshold. 223af75078fSIntel */ 224af75078fSIntel uint16_t tx_rs_thresh = 0; /* Use default values. */ 225af75078fSIntel 226af75078fSIntel /* 227ce8d5614SIntel * Configurable value of TX queue flags. 228ce8d5614SIntel */ 229ce8d5614SIntel uint32_t txq_flags = 0; /* No flags set. */ 230ce8d5614SIntel 231ce8d5614SIntel /* 232af75078fSIntel * Receive Side Scaling (RSS) configuration. 233af75078fSIntel */ 234af75078fSIntel uint16_t rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6; /* RSS IP by default. */ 235af75078fSIntel 236af75078fSIntel /* 237af75078fSIntel * Port topology configuration 238af75078fSIntel */ 239af75078fSIntel uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */ 240af75078fSIntel 241af75078fSIntel /* 242af75078fSIntel * Ethernet device configuration. 243af75078fSIntel */ 244af75078fSIntel struct rte_eth_rxmode rx_mode = { 245af75078fSIntel .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ 246af75078fSIntel .split_hdr_size = 0, 247af75078fSIntel .header_split = 0, /**< Header Split disabled. */ 248af75078fSIntel .hw_ip_checksum = 0, /**< IP checksum offload disabled. */ 249af75078fSIntel .hw_vlan_filter = 1, /**< VLAN filtering enabled. */ 250a47aa8b9SIntel .hw_vlan_strip = 1, /**< VLAN strip enabled. */ 251a47aa8b9SIntel .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ 252af75078fSIntel .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ 253af75078fSIntel .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */ 254af75078fSIntel }; 255af75078fSIntel 256af75078fSIntel struct rte_fdir_conf fdir_conf = { 257af75078fSIntel .mode = RTE_FDIR_MODE_NONE, 258af75078fSIntel .pballoc = RTE_FDIR_PBALLOC_64K, 259af75078fSIntel .status = RTE_FDIR_REPORT_STATUS, 260af75078fSIntel .flexbytes_offset = 0x6, 261af75078fSIntel .drop_queue = 127, 262af75078fSIntel }; 263af75078fSIntel 264af75078fSIntel static volatile int test_done = 1; /* stop packet forwarding when set to 1. */ 265af75078fSIntel 266ed30d9b6SIntel struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; 267ed30d9b6SIntel struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; 268ed30d9b6SIntel 269ed30d9b6SIntel struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; 270ed30d9b6SIntel struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; 271ed30d9b6SIntel 272ed30d9b6SIntel uint16_t nb_tx_queue_stats_mappings = 0; 273ed30d9b6SIntel uint16_t nb_rx_queue_stats_mappings = 0; 274ed30d9b6SIntel 275ed30d9b6SIntel /* Forward function declarations */ 276ed30d9b6SIntel static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port); 277ce8d5614SIntel static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask); 278ce8d5614SIntel 279ce8d5614SIntel /* 280ce8d5614SIntel * Check if all the ports are started. 281ce8d5614SIntel * If yes, return positive value. If not, return zero. 282ce8d5614SIntel */ 283ce8d5614SIntel static int all_ports_started(void); 284ed30d9b6SIntel 285af75078fSIntel /* 286af75078fSIntel * Setup default configuration. 287af75078fSIntel */ 288af75078fSIntel static void 289af75078fSIntel set_default_fwd_lcores_config(void) 290af75078fSIntel { 291af75078fSIntel unsigned int i; 292af75078fSIntel unsigned int nb_lc; 293af75078fSIntel 294af75078fSIntel nb_lc = 0; 295af75078fSIntel for (i = 0; i < RTE_MAX_LCORE; i++) { 296af75078fSIntel if (! rte_lcore_is_enabled(i)) 297af75078fSIntel continue; 298af75078fSIntel if (i == rte_get_master_lcore()) 299af75078fSIntel continue; 300af75078fSIntel fwd_lcores_cpuids[nb_lc++] = i; 301af75078fSIntel } 302af75078fSIntel nb_lcores = (lcoreid_t) nb_lc; 303af75078fSIntel nb_cfg_lcores = nb_lcores; 304af75078fSIntel nb_fwd_lcores = 1; 305af75078fSIntel } 306af75078fSIntel 307af75078fSIntel static void 308af75078fSIntel set_def_peer_eth_addrs(void) 309af75078fSIntel { 310af75078fSIntel portid_t i; 311af75078fSIntel 312af75078fSIntel for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 313af75078fSIntel peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR; 314af75078fSIntel peer_eth_addrs[i].addr_bytes[5] = i; 315af75078fSIntel } 316af75078fSIntel } 317af75078fSIntel 318af75078fSIntel static void 319af75078fSIntel set_default_fwd_ports_config(void) 320af75078fSIntel { 321af75078fSIntel portid_t pt_id; 322af75078fSIntel 323af75078fSIntel for (pt_id = 0; pt_id < nb_ports; pt_id++) 324af75078fSIntel fwd_ports_ids[pt_id] = pt_id; 325af75078fSIntel 326af75078fSIntel nb_cfg_ports = nb_ports; 327af75078fSIntel nb_fwd_ports = nb_ports; 328af75078fSIntel } 329af75078fSIntel 330af75078fSIntel void 331af75078fSIntel set_def_fwd_config(void) 332af75078fSIntel { 333af75078fSIntel set_default_fwd_lcores_config(); 334af75078fSIntel set_def_peer_eth_addrs(); 335af75078fSIntel set_default_fwd_ports_config(); 336af75078fSIntel } 337af75078fSIntel 338af75078fSIntel /* 339af75078fSIntel * Configuration initialisation done once at init time. 340af75078fSIntel */ 341af75078fSIntel struct mbuf_ctor_arg { 342af75078fSIntel uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */ 343af75078fSIntel uint16_t seg_buf_size; /**< size of data segment in mbuf. */ 344af75078fSIntel }; 345af75078fSIntel 346af75078fSIntel struct mbuf_pool_ctor_arg { 347af75078fSIntel uint16_t seg_buf_size; /**< size of data segment in mbuf. */ 348af75078fSIntel }; 349af75078fSIntel 350af75078fSIntel static void 351af75078fSIntel testpmd_mbuf_ctor(struct rte_mempool *mp, 352af75078fSIntel void *opaque_arg, 353af75078fSIntel void *raw_mbuf, 354af75078fSIntel __attribute__((unused)) unsigned i) 355af75078fSIntel { 356af75078fSIntel struct mbuf_ctor_arg *mb_ctor_arg; 357af75078fSIntel struct rte_mbuf *mb; 358af75078fSIntel 359af75078fSIntel mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg; 360af75078fSIntel mb = (struct rte_mbuf *) raw_mbuf; 361af75078fSIntel 362af75078fSIntel mb->pool = mp; 363af75078fSIntel mb->buf_addr = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset); 364af75078fSIntel mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) + 365af75078fSIntel mb_ctor_arg->seg_buf_offset); 366af75078fSIntel mb->buf_len = mb_ctor_arg->seg_buf_size; 367af75078fSIntel mb->type = RTE_MBUF_PKT; 368af75078fSIntel mb->ol_flags = 0; 369af75078fSIntel mb->pkt.data = (char *) mb->buf_addr + RTE_PKTMBUF_HEADROOM; 370af75078fSIntel mb->pkt.nb_segs = 1; 37142d71416SIntel mb->pkt.vlan_macip.data = 0; 372af75078fSIntel mb->pkt.hash.rss = 0; 373af75078fSIntel } 374af75078fSIntel 375af75078fSIntel static void 376af75078fSIntel testpmd_mbuf_pool_ctor(struct rte_mempool *mp, 377af75078fSIntel void *opaque_arg) 378af75078fSIntel { 379af75078fSIntel struct mbuf_pool_ctor_arg *mbp_ctor_arg; 380af75078fSIntel struct rte_pktmbuf_pool_private *mbp_priv; 381af75078fSIntel 382af75078fSIntel if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) { 383af75078fSIntel printf("%s(%s) private_data_size %d < %d\n", 384af75078fSIntel __func__, mp->name, (int) mp->private_data_size, 385af75078fSIntel (int) sizeof(struct rte_pktmbuf_pool_private)); 386af75078fSIntel return; 387af75078fSIntel } 388af75078fSIntel mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg; 389af75078fSIntel mbp_priv = (struct rte_pktmbuf_pool_private *) 390af75078fSIntel ((char *)mp + sizeof(struct rte_mempool)); 391af75078fSIntel mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size; 392af75078fSIntel } 393af75078fSIntel 394af75078fSIntel static void 395af75078fSIntel mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, 396af75078fSIntel unsigned int socket_id) 397af75078fSIntel { 398af75078fSIntel char pool_name[RTE_MEMPOOL_NAMESIZE]; 399af75078fSIntel struct rte_mempool *rte_mp; 400af75078fSIntel struct mbuf_pool_ctor_arg mbp_ctor_arg; 401af75078fSIntel struct mbuf_ctor_arg mb_ctor_arg; 402af75078fSIntel uint32_t mb_size; 403af75078fSIntel 404af75078fSIntel mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM + 405af75078fSIntel mbuf_seg_size); 406af75078fSIntel mb_ctor_arg.seg_buf_offset = 407af75078fSIntel (uint16_t) CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf)); 408af75078fSIntel mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size; 409af75078fSIntel mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size; 410af75078fSIntel mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); 411af75078fSIntel rte_mp = rte_mempool_create(pool_name, nb_mbuf, (unsigned) mb_size, 412af75078fSIntel (unsigned) mb_mempool_cache, 413af75078fSIntel sizeof(struct rte_pktmbuf_pool_private), 414af75078fSIntel testpmd_mbuf_pool_ctor, &mbp_ctor_arg, 415af75078fSIntel testpmd_mbuf_ctor, &mb_ctor_arg, 416af75078fSIntel socket_id, 0); 417af75078fSIntel if (rte_mp == NULL) { 418ce8d5614SIntel rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u " 419ce8d5614SIntel "failed\n", socket_id); 420af75078fSIntel } 421af75078fSIntel } 422af75078fSIntel 423af75078fSIntel static void 424af75078fSIntel init_config(void) 425af75078fSIntel { 426ce8d5614SIntel portid_t pid; 427af75078fSIntel struct rte_port *port; 428af75078fSIntel struct rte_mempool *mbp; 429af75078fSIntel unsigned int nb_mbuf_per_pool; 430af75078fSIntel lcoreid_t lc_id; 431af75078fSIntel 432af75078fSIntel /* Configuration of logical cores. */ 433af75078fSIntel fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 434af75078fSIntel sizeof(struct fwd_lcore *) * nb_lcores, 435af75078fSIntel CACHE_LINE_SIZE); 436af75078fSIntel if (fwd_lcores == NULL) { 437ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 438ce8d5614SIntel "failed\n", nb_lcores); 439af75078fSIntel } 440af75078fSIntel for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 441af75078fSIntel fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 442af75078fSIntel sizeof(struct fwd_lcore), 443af75078fSIntel CACHE_LINE_SIZE); 444af75078fSIntel if (fwd_lcores[lc_id] == NULL) { 445ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 446ce8d5614SIntel "failed\n"); 447af75078fSIntel } 448af75078fSIntel fwd_lcores[lc_id]->cpuid_idx = lc_id; 449af75078fSIntel } 450af75078fSIntel 451af75078fSIntel /* 452af75078fSIntel * Create pools of mbuf. 453af75078fSIntel * If NUMA support is disabled, create a single pool of mbuf in 454af75078fSIntel * socket 0 memory. 455af75078fSIntel * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 456c8798818SIntel * 457c8798818SIntel * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 458c8798818SIntel * nb_txd can be configured at run time. 459af75078fSIntel */ 460c8798818SIntel if (param_total_num_mbufs) 461c8798818SIntel nb_mbuf_per_pool = param_total_num_mbufs; 462c8798818SIntel else { 463c8798818SIntel nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache) 464c8798818SIntel + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 465c8798818SIntel nb_mbuf_per_pool = (nb_mbuf_per_pool * nb_ports); 466c8798818SIntel } 467af75078fSIntel if (numa_support) { 468c8798818SIntel nb_mbuf_per_pool /= 2; 469af75078fSIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 470af75078fSIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 1); 471af75078fSIntel } else { 472af75078fSIntel mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 473af75078fSIntel } 474af75078fSIntel 475af75078fSIntel /* 476af75078fSIntel * Records which Mbuf pool to use by each logical core, if needed. 477af75078fSIntel */ 478af75078fSIntel for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 479af75078fSIntel mbp = mbuf_pool_find(rte_lcore_to_socket_id(lc_id)); 480af75078fSIntel if (mbp == NULL) 481af75078fSIntel mbp = mbuf_pool_find(0); 482af75078fSIntel fwd_lcores[lc_id]->mbp = mbp; 483af75078fSIntel } 484af75078fSIntel 485af75078fSIntel /* Configuration of Ethernet ports. */ 486af75078fSIntel ports = rte_zmalloc("testpmd: ports", 487af75078fSIntel sizeof(struct rte_port) * nb_ports, 488af75078fSIntel CACHE_LINE_SIZE); 489af75078fSIntel if (ports == NULL) { 490ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) " 491ce8d5614SIntel "failed\n", nb_ports); 492af75078fSIntel } 493af75078fSIntel 494ce8d5614SIntel for (pid = 0; pid < nb_ports; pid++) { 495ce8d5614SIntel port = &ports[pid]; 496ce8d5614SIntel rte_eth_dev_info_get(pid, &port->dev_info); 497ce8d5614SIntel 498ce8d5614SIntel /* set flag to initialize port/queue */ 499ce8d5614SIntel port->need_reconfig = 1; 500ce8d5614SIntel port->need_reconfig_queues = 1; 501ce8d5614SIntel } 502ce8d5614SIntel 503ce8d5614SIntel init_port_config(); 504ce8d5614SIntel 505ce8d5614SIntel /* Configuration of packet forwarding streams. */ 506ce8d5614SIntel if (init_fwd_streams() < 0) 507ce8d5614SIntel rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 508ce8d5614SIntel } 509ce8d5614SIntel 510ce8d5614SIntel int 511ce8d5614SIntel init_fwd_streams(void) 512ce8d5614SIntel { 513ce8d5614SIntel portid_t pid; 514ce8d5614SIntel struct rte_port *port; 515ce8d5614SIntel streamid_t sm_id, nb_fwd_streams_new; 516ce8d5614SIntel 517ce8d5614SIntel /* set socket id according to numa or not */ 518ce8d5614SIntel for (pid = 0; pid < nb_ports; pid++) { 519ce8d5614SIntel port = &ports[pid]; 520ce8d5614SIntel if (nb_rxq > port->dev_info.max_rx_queues) { 521ce8d5614SIntel printf("Fail: nb_rxq(%d) is greater than " 522ce8d5614SIntel "max_rx_queues(%d)\n", nb_rxq, 523ce8d5614SIntel port->dev_info.max_rx_queues); 524ce8d5614SIntel return -1; 525ce8d5614SIntel } 526ce8d5614SIntel if (nb_txq > port->dev_info.max_tx_queues) { 527ce8d5614SIntel printf("Fail: nb_txq(%d) is greater than " 528ce8d5614SIntel "max_tx_queues(%d)\n", nb_txq, 529ce8d5614SIntel port->dev_info.max_tx_queues); 530ce8d5614SIntel return -1; 531ce8d5614SIntel } 532af75078fSIntel if (numa_support) 533ce8d5614SIntel port->socket_id = (pid < (nb_ports >> 1)) ? 0 : 1; 534af75078fSIntel else 535af75078fSIntel port->socket_id = 0; 536af75078fSIntel } 537af75078fSIntel 538ce8d5614SIntel nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq); 539ce8d5614SIntel if (nb_fwd_streams_new == nb_fwd_streams) 540ce8d5614SIntel return 0; 541ce8d5614SIntel /* clear the old */ 542ce8d5614SIntel if (fwd_streams != NULL) { 543ce8d5614SIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 544ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 545ce8d5614SIntel continue; 546ce8d5614SIntel rte_free(fwd_streams[sm_id]); 547ce8d5614SIntel fwd_streams[sm_id] = NULL; 548af75078fSIntel } 549ce8d5614SIntel rte_free(fwd_streams); 550ce8d5614SIntel fwd_streams = NULL; 551ce8d5614SIntel } 552ce8d5614SIntel 553ce8d5614SIntel /* init new */ 554ce8d5614SIntel nb_fwd_streams = nb_fwd_streams_new; 555ce8d5614SIntel fwd_streams = rte_zmalloc("testpmd: fwd_streams", 556ce8d5614SIntel sizeof(struct fwd_stream *) * nb_fwd_streams, CACHE_LINE_SIZE); 557ce8d5614SIntel if (fwd_streams == NULL) 558ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " 559ce8d5614SIntel "failed\n", nb_fwd_streams); 560ce8d5614SIntel 561af75078fSIntel for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 562af75078fSIntel fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", 563ce8d5614SIntel sizeof(struct fwd_stream), CACHE_LINE_SIZE); 564ce8d5614SIntel if (fwd_streams[sm_id] == NULL) 565ce8d5614SIntel rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" 566ce8d5614SIntel " failed\n"); 567af75078fSIntel } 568ce8d5614SIntel 569ce8d5614SIntel return 0; 570af75078fSIntel } 571af75078fSIntel 572af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 573af75078fSIntel static void 574af75078fSIntel pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 575af75078fSIntel { 576af75078fSIntel unsigned int total_burst; 577af75078fSIntel unsigned int nb_burst; 578af75078fSIntel unsigned int burst_stats[3]; 579af75078fSIntel uint16_t pktnb_stats[3]; 580af75078fSIntel uint16_t nb_pkt; 581af75078fSIntel int burst_percent[3]; 582af75078fSIntel 583af75078fSIntel /* 584af75078fSIntel * First compute the total number of packet bursts and the 585af75078fSIntel * two highest numbers of bursts of the same number of packets. 586af75078fSIntel */ 587af75078fSIntel total_burst = 0; 588af75078fSIntel burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 589af75078fSIntel pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 590af75078fSIntel for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 591af75078fSIntel nb_burst = pbs->pkt_burst_spread[nb_pkt]; 592af75078fSIntel if (nb_burst == 0) 593af75078fSIntel continue; 594af75078fSIntel total_burst += nb_burst; 595af75078fSIntel if (nb_burst > burst_stats[0]) { 596af75078fSIntel burst_stats[1] = burst_stats[0]; 597af75078fSIntel pktnb_stats[1] = pktnb_stats[0]; 598af75078fSIntel burst_stats[0] = nb_burst; 599af75078fSIntel pktnb_stats[0] = nb_pkt; 600af75078fSIntel } 601af75078fSIntel } 602af75078fSIntel if (total_burst == 0) 603af75078fSIntel return; 604af75078fSIntel burst_percent[0] = (burst_stats[0] * 100) / total_burst; 605af75078fSIntel printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 606af75078fSIntel burst_percent[0], (int) pktnb_stats[0]); 607af75078fSIntel if (burst_stats[0] == total_burst) { 608af75078fSIntel printf("]\n"); 609af75078fSIntel return; 610af75078fSIntel } 611af75078fSIntel if (burst_stats[0] + burst_stats[1] == total_burst) { 612af75078fSIntel printf(" + %d%% of %d pkts]\n", 613af75078fSIntel 100 - burst_percent[0], pktnb_stats[1]); 614af75078fSIntel return; 615af75078fSIntel } 616af75078fSIntel burst_percent[1] = (burst_stats[1] * 100) / total_burst; 617af75078fSIntel burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 618af75078fSIntel if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 619af75078fSIntel printf(" + %d%% of others]\n", 100 - burst_percent[0]); 620af75078fSIntel return; 621af75078fSIntel } 622af75078fSIntel printf(" + %d%% of %d pkts + %d%% of others]\n", 623af75078fSIntel burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 624af75078fSIntel } 625af75078fSIntel #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 626af75078fSIntel 627af75078fSIntel static void 628af75078fSIntel fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) 629af75078fSIntel { 630af75078fSIntel struct rte_port *port; 631af75078fSIntel 632af75078fSIntel static const char *fwd_stats_border = "----------------------"; 633af75078fSIntel 634af75078fSIntel port = &ports[port_id]; 635af75078fSIntel printf("\n %s Forward statistics for port %-2d %s\n", 636af75078fSIntel fwd_stats_border, port_id, fwd_stats_border); 637af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 638af75078fSIntel "%-"PRIu64"\n", 639af75078fSIntel stats->ipackets, stats->ierrors, 640af75078fSIntel (uint64_t) (stats->ipackets + stats->ierrors)); 641af75078fSIntel 642af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) 643af75078fSIntel printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n", 644af75078fSIntel port->rx_bad_ip_csum, port->rx_bad_l4_csum); 645af75078fSIntel 646af75078fSIntel printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 647af75078fSIntel "%-"PRIu64"\n", 648af75078fSIntel stats->opackets, port->tx_dropped, 649af75078fSIntel (uint64_t) (stats->opackets + port->tx_dropped)); 650af75078fSIntel 651af75078fSIntel if (stats->rx_nombuf > 0) 652af75078fSIntel printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf); 653af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 654af75078fSIntel if (port->rx_stream) 655af75078fSIntel pkt_burst_stats_display("RX", &port->rx_stream->rx_burst_stats); 656af75078fSIntel if (port->tx_stream) 657af75078fSIntel pkt_burst_stats_display("TX", &port->tx_stream->tx_burst_stats); 658af75078fSIntel #endif 659af75078fSIntel /* stats fdir */ 660af75078fSIntel if (fdir_conf.mode != RTE_FDIR_MODE_NONE) 661af75078fSIntel printf(" Fdirmiss: %-14"PRIu64" Fdirmatch: %-14"PRIu64"\n", 662af75078fSIntel stats->fdirmiss, 663af75078fSIntel stats->fdirmatch); 664af75078fSIntel 665af75078fSIntel printf(" %s--------------------------------%s\n", 666af75078fSIntel fwd_stats_border, fwd_stats_border); 667af75078fSIntel } 668af75078fSIntel 669af75078fSIntel static void 670af75078fSIntel fwd_stream_stats_display(streamid_t stream_id) 671af75078fSIntel { 672af75078fSIntel struct fwd_stream *fs; 673af75078fSIntel static const char *fwd_top_stats_border = "-------"; 674af75078fSIntel 675af75078fSIntel fs = fwd_streams[stream_id]; 676af75078fSIntel if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 677af75078fSIntel (fs->fwd_dropped == 0)) 678af75078fSIntel return; 679af75078fSIntel printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 680af75078fSIntel "TX Port=%2d/Queue=%2d %s\n", 681af75078fSIntel fwd_top_stats_border, fs->rx_port, fs->rx_queue, 682af75078fSIntel fs->tx_port, fs->tx_queue, fwd_top_stats_border); 683af75078fSIntel printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u", 684af75078fSIntel fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 685af75078fSIntel 686af75078fSIntel /* if checksum mode */ 687af75078fSIntel if (cur_fwd_eng == &csum_fwd_engine) { 688af75078fSIntel printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: %-14u\n", 689af75078fSIntel fs->rx_bad_ip_csum, fs->rx_bad_l4_csum); 690af75078fSIntel } 691af75078fSIntel 692af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 693af75078fSIntel pkt_burst_stats_display("RX", &fs->rx_burst_stats); 694af75078fSIntel pkt_burst_stats_display("TX", &fs->tx_burst_stats); 695af75078fSIntel #endif 696af75078fSIntel } 697af75078fSIntel 698af75078fSIntel static void 699af75078fSIntel flush_all_rx_queues(void) 700af75078fSIntel { 701af75078fSIntel struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 702af75078fSIntel portid_t rxp; 703af75078fSIntel queueid_t rxq; 704af75078fSIntel uint16_t nb_rx; 705af75078fSIntel uint16_t i; 706af75078fSIntel uint8_t j; 707af75078fSIntel 708af75078fSIntel for (j = 0; j < 2; j++) { 709af75078fSIntel for (rxp = 0; rxp < nb_ports; rxp++) { 710af75078fSIntel for (rxq = 0; rxq < nb_rxq; rxq++) { 711af75078fSIntel do { 712af75078fSIntel nb_rx = rte_eth_rx_burst(rxp, rxq, 713af75078fSIntel pkts_burst, 714af75078fSIntel MAX_PKT_BURST); 715af75078fSIntel for (i = 0; i < nb_rx; i++) 716af75078fSIntel rte_pktmbuf_free(pkts_burst[i]); 717af75078fSIntel } while (nb_rx > 0); 718af75078fSIntel } 719af75078fSIntel } 720af75078fSIntel rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 721af75078fSIntel } 722af75078fSIntel } 723af75078fSIntel 724af75078fSIntel static void 725af75078fSIntel run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 726af75078fSIntel { 727af75078fSIntel struct fwd_stream **fsm; 728af75078fSIntel streamid_t nb_fs; 729af75078fSIntel streamid_t sm_id; 730af75078fSIntel 731af75078fSIntel fsm = &fwd_streams[fc->stream_idx]; 732af75078fSIntel nb_fs = fc->stream_nb; 733af75078fSIntel do { 734af75078fSIntel for (sm_id = 0; sm_id < nb_fs; sm_id++) 735af75078fSIntel (*pkt_fwd)(fsm[sm_id]); 736af75078fSIntel } while (! fc->stopped); 737af75078fSIntel } 738af75078fSIntel 739af75078fSIntel static int 740af75078fSIntel start_pkt_forward_on_core(void *fwd_arg) 741af75078fSIntel { 742af75078fSIntel run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 743af75078fSIntel cur_fwd_config.fwd_eng->packet_fwd); 744af75078fSIntel return 0; 745af75078fSIntel } 746af75078fSIntel 747af75078fSIntel /* 748af75078fSIntel * Run the TXONLY packet forwarding engine to send a single burst of packets. 749af75078fSIntel * Used to start communication flows in network loopback test configurations. 750af75078fSIntel */ 751af75078fSIntel static int 752af75078fSIntel run_one_txonly_burst_on_core(void *fwd_arg) 753af75078fSIntel { 754af75078fSIntel struct fwd_lcore *fwd_lc; 755af75078fSIntel struct fwd_lcore tmp_lcore; 756af75078fSIntel 757af75078fSIntel fwd_lc = (struct fwd_lcore *) fwd_arg; 758af75078fSIntel tmp_lcore = *fwd_lc; 759af75078fSIntel tmp_lcore.stopped = 1; 760af75078fSIntel run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 761af75078fSIntel return 0; 762af75078fSIntel } 763af75078fSIntel 764af75078fSIntel /* 765af75078fSIntel * Launch packet forwarding: 766af75078fSIntel * - Setup per-port forwarding context. 767af75078fSIntel * - launch logical cores with their forwarding configuration. 768af75078fSIntel */ 769af75078fSIntel static void 770af75078fSIntel launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 771af75078fSIntel { 772af75078fSIntel port_fwd_begin_t port_fwd_begin; 773af75078fSIntel unsigned int i; 774af75078fSIntel unsigned int lc_id; 775af75078fSIntel int diag; 776af75078fSIntel 777af75078fSIntel port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 778af75078fSIntel if (port_fwd_begin != NULL) { 779af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 780af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 781af75078fSIntel } 782af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 783af75078fSIntel lc_id = fwd_lcores_cpuids[i]; 784af75078fSIntel if ((interactive == 0) || (lc_id != rte_lcore_id())) { 785af75078fSIntel fwd_lcores[i]->stopped = 0; 786af75078fSIntel diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 787af75078fSIntel fwd_lcores[i], lc_id); 788af75078fSIntel if (diag != 0) 789af75078fSIntel printf("launch lcore %u failed - diag=%d\n", 790af75078fSIntel lc_id, diag); 791af75078fSIntel } 792af75078fSIntel } 793af75078fSIntel } 794af75078fSIntel 795af75078fSIntel /* 796af75078fSIntel * Launch packet forwarding configuration. 797af75078fSIntel */ 798af75078fSIntel void 799af75078fSIntel start_packet_forwarding(int with_tx_first) 800af75078fSIntel { 801af75078fSIntel port_fwd_begin_t port_fwd_begin; 802af75078fSIntel port_fwd_end_t port_fwd_end; 803af75078fSIntel struct rte_port *port; 804af75078fSIntel unsigned int i; 805af75078fSIntel portid_t pt_id; 806af75078fSIntel streamid_t sm_id; 807af75078fSIntel 808ce8d5614SIntel if (all_ports_started() == 0) { 809ce8d5614SIntel printf("Not all ports were started\n"); 810ce8d5614SIntel return; 811ce8d5614SIntel } 812af75078fSIntel if (test_done == 0) { 813af75078fSIntel printf("Packet forwarding already started\n"); 814af75078fSIntel return; 815af75078fSIntel } 816af75078fSIntel test_done = 0; 817af75078fSIntel flush_all_rx_queues(); 818af75078fSIntel fwd_config_setup(); 819af75078fSIntel rxtx_config_display(); 820af75078fSIntel 821af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 822af75078fSIntel pt_id = fwd_ports_ids[i]; 823af75078fSIntel port = &ports[pt_id]; 824af75078fSIntel rte_eth_stats_get(pt_id, &port->stats); 825af75078fSIntel port->tx_dropped = 0; 826af75078fSIntel } 827af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 828af75078fSIntel fwd_streams[sm_id]->rx_packets = 0; 829af75078fSIntel fwd_streams[sm_id]->tx_packets = 0; 830af75078fSIntel fwd_streams[sm_id]->fwd_dropped = 0; 831af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum = 0; 832af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum = 0; 833af75078fSIntel 834af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 835af75078fSIntel memset(&fwd_streams[sm_id]->rx_burst_stats, 0, 836af75078fSIntel sizeof(fwd_streams[sm_id]->rx_burst_stats)); 837af75078fSIntel memset(&fwd_streams[sm_id]->tx_burst_stats, 0, 838af75078fSIntel sizeof(fwd_streams[sm_id]->tx_burst_stats)); 839af75078fSIntel #endif 840af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 841af75078fSIntel fwd_streams[sm_id]->core_cycles = 0; 842af75078fSIntel #endif 843af75078fSIntel } 844af75078fSIntel if (with_tx_first) { 845af75078fSIntel port_fwd_begin = tx_only_engine.port_fwd_begin; 846af75078fSIntel if (port_fwd_begin != NULL) { 847af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 848af75078fSIntel (*port_fwd_begin)(fwd_ports_ids[i]); 849af75078fSIntel } 850af75078fSIntel launch_packet_forwarding(run_one_txonly_burst_on_core); 851af75078fSIntel rte_eal_mp_wait_lcore(); 852af75078fSIntel port_fwd_end = tx_only_engine.port_fwd_end; 853af75078fSIntel if (port_fwd_end != NULL) { 854af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 855af75078fSIntel (*port_fwd_end)(fwd_ports_ids[i]); 856af75078fSIntel } 857af75078fSIntel } 858af75078fSIntel launch_packet_forwarding(start_pkt_forward_on_core); 859af75078fSIntel } 860af75078fSIntel 861af75078fSIntel void 862af75078fSIntel stop_packet_forwarding(void) 863af75078fSIntel { 864af75078fSIntel struct rte_eth_stats stats; 865af75078fSIntel struct rte_port *port; 866af75078fSIntel port_fwd_end_t port_fwd_end; 867af75078fSIntel int i; 868af75078fSIntel portid_t pt_id; 869af75078fSIntel streamid_t sm_id; 870af75078fSIntel lcoreid_t lc_id; 871af75078fSIntel uint64_t total_recv; 872af75078fSIntel uint64_t total_xmit; 873af75078fSIntel uint64_t total_rx_dropped; 874af75078fSIntel uint64_t total_tx_dropped; 875af75078fSIntel uint64_t total_rx_nombuf; 876af75078fSIntel uint64_t tx_dropped; 877af75078fSIntel uint64_t rx_bad_ip_csum; 878af75078fSIntel uint64_t rx_bad_l4_csum; 879af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 880af75078fSIntel uint64_t fwd_cycles; 881af75078fSIntel #endif 882af75078fSIntel static const char *acc_stats_border = "+++++++++++++++"; 883af75078fSIntel 884ce8d5614SIntel if (all_ports_started() == 0) { 885ce8d5614SIntel printf("Not all ports were started\n"); 886ce8d5614SIntel return; 887ce8d5614SIntel } 888af75078fSIntel if (test_done) { 889af75078fSIntel printf("Packet forwarding not started\n"); 890af75078fSIntel return; 891af75078fSIntel } 892af75078fSIntel printf("Telling cores to stop..."); 893af75078fSIntel for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 894af75078fSIntel fwd_lcores[lc_id]->stopped = 1; 895af75078fSIntel printf("\nWaiting for lcores to finish...\n"); 896af75078fSIntel rte_eal_mp_wait_lcore(); 897af75078fSIntel port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 898af75078fSIntel if (port_fwd_end != NULL) { 899af75078fSIntel for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 900af75078fSIntel pt_id = fwd_ports_ids[i]; 901af75078fSIntel (*port_fwd_end)(pt_id); 902af75078fSIntel } 903af75078fSIntel } 904af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 905af75078fSIntel fwd_cycles = 0; 906af75078fSIntel #endif 907af75078fSIntel for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 908af75078fSIntel if (cur_fwd_config.nb_fwd_streams > 909af75078fSIntel cur_fwd_config.nb_fwd_ports) { 910af75078fSIntel fwd_stream_stats_display(sm_id); 911af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL; 912af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL; 913af75078fSIntel } else { 914af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_stream = 915af75078fSIntel fwd_streams[sm_id]; 916af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_stream = 917af75078fSIntel fwd_streams[sm_id]; 918af75078fSIntel } 919af75078fSIntel tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped; 920af75078fSIntel tx_dropped = (uint64_t) (tx_dropped + 921af75078fSIntel fwd_streams[sm_id]->fwd_dropped); 922af75078fSIntel ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped; 923af75078fSIntel 924af75078fSIntel rx_bad_ip_csum = ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum; 925af75078fSIntel rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum + 926af75078fSIntel fwd_streams[sm_id]->rx_bad_ip_csum); 927af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = rx_bad_ip_csum; 928af75078fSIntel 929af75078fSIntel rx_bad_l4_csum = ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum; 930af75078fSIntel rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum + 931af75078fSIntel fwd_streams[sm_id]->rx_bad_l4_csum); 932af75078fSIntel ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = rx_bad_l4_csum; 933af75078fSIntel 934af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 935af75078fSIntel fwd_cycles = (uint64_t) (fwd_cycles + 936af75078fSIntel fwd_streams[sm_id]->core_cycles); 937af75078fSIntel #endif 938af75078fSIntel } 939af75078fSIntel total_recv = 0; 940af75078fSIntel total_xmit = 0; 941af75078fSIntel total_rx_dropped = 0; 942af75078fSIntel total_tx_dropped = 0; 943af75078fSIntel total_rx_nombuf = 0; 944af75078fSIntel for (i = 0; i < ((cur_fwd_config.nb_fwd_ports + 1) & ~0x1); i++) { 945af75078fSIntel pt_id = fwd_ports_ids[i]; 946af75078fSIntel 947af75078fSIntel port = &ports[pt_id]; 948af75078fSIntel rte_eth_stats_get(pt_id, &stats); 949af75078fSIntel stats.ipackets -= port->stats.ipackets; 950af75078fSIntel port->stats.ipackets = 0; 951af75078fSIntel stats.opackets -= port->stats.opackets; 952af75078fSIntel port->stats.opackets = 0; 953af75078fSIntel stats.ibytes -= port->stats.ibytes; 954af75078fSIntel port->stats.ibytes = 0; 955af75078fSIntel stats.obytes -= port->stats.obytes; 956af75078fSIntel port->stats.obytes = 0; 957af75078fSIntel stats.ierrors -= port->stats.ierrors; 958af75078fSIntel port->stats.ierrors = 0; 959af75078fSIntel stats.oerrors -= port->stats.oerrors; 960af75078fSIntel port->stats.oerrors = 0; 961af75078fSIntel stats.rx_nombuf -= port->stats.rx_nombuf; 962af75078fSIntel port->stats.rx_nombuf = 0; 963af75078fSIntel stats.fdirmatch -= port->stats.fdirmatch; 964af75078fSIntel port->stats.rx_nombuf = 0; 965af75078fSIntel stats.fdirmiss -= port->stats.fdirmiss; 966af75078fSIntel port->stats.rx_nombuf = 0; 967af75078fSIntel 968af75078fSIntel total_recv += stats.ipackets; 969af75078fSIntel total_xmit += stats.opackets; 970af75078fSIntel total_rx_dropped += stats.ierrors; 971af75078fSIntel total_tx_dropped += port->tx_dropped; 972af75078fSIntel total_rx_nombuf += stats.rx_nombuf; 973af75078fSIntel 974af75078fSIntel fwd_port_stats_display(pt_id, &stats); 975af75078fSIntel } 976af75078fSIntel printf("\n %s Accumulated forward statistics for all ports" 977af75078fSIntel "%s\n", 978af75078fSIntel acc_stats_border, acc_stats_border); 979af75078fSIntel printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 980af75078fSIntel "%-"PRIu64"\n" 981af75078fSIntel " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 982af75078fSIntel "%-"PRIu64"\n", 983af75078fSIntel total_recv, total_rx_dropped, total_recv + total_rx_dropped, 984af75078fSIntel total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 985af75078fSIntel if (total_rx_nombuf > 0) 986af75078fSIntel printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 987af75078fSIntel printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 988af75078fSIntel "%s\n", 989af75078fSIntel acc_stats_border, acc_stats_border); 990af75078fSIntel #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 991af75078fSIntel if (total_recv > 0) 992af75078fSIntel printf("\n CPU cycles/packet=%u (total cycles=" 993af75078fSIntel "%"PRIu64" / total RX packets=%"PRIu64")\n", 994af75078fSIntel (unsigned int)(fwd_cycles / total_recv), 995af75078fSIntel fwd_cycles, total_recv); 996af75078fSIntel #endif 997af75078fSIntel printf("\nDone.\n"); 998af75078fSIntel test_done = 1; 999af75078fSIntel } 1000af75078fSIntel 1001ce8d5614SIntel static int 1002ce8d5614SIntel all_ports_started(void) 1003ce8d5614SIntel { 1004ce8d5614SIntel portid_t pi; 1005ce8d5614SIntel struct rte_port *port; 1006ce8d5614SIntel 1007ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1008ce8d5614SIntel port = &ports[pi]; 1009ce8d5614SIntel /* Check if there is a port which is not started */ 1010ce8d5614SIntel if (port->port_status != RTE_PORT_STARTED) 1011ce8d5614SIntel return 0; 1012ce8d5614SIntel } 1013ce8d5614SIntel 1014ce8d5614SIntel /* No port is not started */ 1015ce8d5614SIntel return 1; 1016ce8d5614SIntel } 1017ce8d5614SIntel 1018ce8d5614SIntel void 1019ce8d5614SIntel start_port(portid_t pid) 1020ce8d5614SIntel { 1021ce8d5614SIntel int diag, need_check_link_status = 0; 1022ce8d5614SIntel portid_t pi; 1023ce8d5614SIntel queueid_t qi; 1024ce8d5614SIntel struct rte_port *port; 1025ce8d5614SIntel 1026ce8d5614SIntel if (test_done == 0) { 1027ce8d5614SIntel printf("Please stop forwarding first\n"); 1028ce8d5614SIntel return; 1029ce8d5614SIntel } 1030ce8d5614SIntel 1031ce8d5614SIntel if (init_fwd_streams() < 0) { 1032ce8d5614SIntel printf("Fail from init_fwd_streams()\n"); 1033ce8d5614SIntel return; 1034ce8d5614SIntel } 1035ce8d5614SIntel 1036ce8d5614SIntel if(dcb_config) 1037ce8d5614SIntel dcb_test = 1; 1038ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1039ce8d5614SIntel if (pid < nb_ports && pid != pi) 1040ce8d5614SIntel continue; 1041ce8d5614SIntel 1042ce8d5614SIntel port = &ports[pi]; 1043ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 1044ce8d5614SIntel RTE_PORT_HANDLING) == 0) { 1045ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1046ce8d5614SIntel continue; 1047ce8d5614SIntel } 1048ce8d5614SIntel 1049ce8d5614SIntel if (port->need_reconfig > 0) { 1050ce8d5614SIntel port->need_reconfig = 0; 1051ce8d5614SIntel 1052ce8d5614SIntel printf("Configuring Port %d\n", pi); 1053ce8d5614SIntel /* configure port */ 1054ce8d5614SIntel diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, 1055ce8d5614SIntel &(port->dev_conf)); 1056ce8d5614SIntel if (diag != 0) { 1057ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1058ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1059ce8d5614SIntel printf("Port %d can not be set back " 1060ce8d5614SIntel "to stopped\n", pi); 1061ce8d5614SIntel printf("Fail to configure port %d\n", pi); 1062ce8d5614SIntel /* try to reconfigure port next time */ 1063ce8d5614SIntel port->need_reconfig = 1; 1064ce8d5614SIntel return; 1065ce8d5614SIntel } 1066ce8d5614SIntel } 1067ce8d5614SIntel 1068ce8d5614SIntel if (port->need_reconfig_queues > 0) { 1069ce8d5614SIntel port->need_reconfig_queues = 0; 1070ce8d5614SIntel 1071ce8d5614SIntel /* setup tx queues */ 1072ce8d5614SIntel for (qi = 0; qi < nb_txq; qi++) { 1073ce8d5614SIntel diag = rte_eth_tx_queue_setup(pi, qi, nb_txd, 1074ce8d5614SIntel port->socket_id, &(port->tx_conf)); 1075ce8d5614SIntel if (diag == 0) 1076ce8d5614SIntel continue; 1077ce8d5614SIntel 1078ce8d5614SIntel /* Fail to setup tx queue, return */ 1079ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1080ce8d5614SIntel RTE_PORT_HANDLING, 1081ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1082ce8d5614SIntel printf("Port %d can not be set back " 1083ce8d5614SIntel "to stopped\n", pi); 1084ce8d5614SIntel printf("Fail to configure port %d tx queues\n", pi); 1085ce8d5614SIntel /* try to reconfigure queues next time */ 1086ce8d5614SIntel port->need_reconfig_queues = 1; 1087ce8d5614SIntel return; 1088ce8d5614SIntel } 1089ce8d5614SIntel /* setup rx queues */ 1090ce8d5614SIntel for (qi = 0; qi < nb_rxq; qi++) { 1091ce8d5614SIntel diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd, 1092ce8d5614SIntel port->socket_id, &(port->rx_conf), 1093ce8d5614SIntel mbuf_pool_find(port->socket_id)); 1094ce8d5614SIntel if (diag == 0) 1095ce8d5614SIntel continue; 1096ce8d5614SIntel 1097ce8d5614SIntel /* Fail to setup rx queue, return */ 1098ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1099ce8d5614SIntel RTE_PORT_HANDLING, 1100ce8d5614SIntel RTE_PORT_STOPPED) == 0) 1101ce8d5614SIntel printf("Port %d can not be set back " 1102ce8d5614SIntel "to stopped\n", pi); 1103ce8d5614SIntel printf("Fail to configure port %d rx queues\n", pi); 1104ce8d5614SIntel /* try to reconfigure queues next time */ 1105ce8d5614SIntel port->need_reconfig_queues = 1; 1106ce8d5614SIntel return; 1107ce8d5614SIntel } 1108ce8d5614SIntel } 1109ce8d5614SIntel 1110ce8d5614SIntel /* start port */ 1111ce8d5614SIntel if (rte_eth_dev_start(pi) < 0) { 1112ce8d5614SIntel printf("Fail to start port %d\n", pi); 1113ce8d5614SIntel 1114ce8d5614SIntel /* Fail to setup rx queue, return */ 1115ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1116ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1117ce8d5614SIntel printf("Port %d can not be set back to " 1118ce8d5614SIntel "stopped\n", pi); 1119ce8d5614SIntel continue; 1120ce8d5614SIntel } 1121ce8d5614SIntel 1122ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1123ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 1124ce8d5614SIntel printf("Port %d can not be set into started\n", pi); 1125ce8d5614SIntel 1126ce8d5614SIntel /* at least one port started, need checking link status */ 1127ce8d5614SIntel need_check_link_status = 1; 1128ce8d5614SIntel } 1129ce8d5614SIntel 1130ce8d5614SIntel if (need_check_link_status) 1131ce8d5614SIntel check_all_ports_link_status(nb_ports, RTE_PORT_ALL); 1132ce8d5614SIntel else 1133ce8d5614SIntel printf("Please stop the ports first\n"); 1134ce8d5614SIntel 1135ce8d5614SIntel printf("Done\n"); 1136ce8d5614SIntel } 1137ce8d5614SIntel 1138ce8d5614SIntel void 1139ce8d5614SIntel stop_port(portid_t pid) 1140ce8d5614SIntel { 1141ce8d5614SIntel portid_t pi; 1142ce8d5614SIntel struct rte_port *port; 1143ce8d5614SIntel int need_check_link_status = 0; 1144ce8d5614SIntel 1145ce8d5614SIntel if (test_done == 0) { 1146ce8d5614SIntel printf("Please stop forwarding first\n"); 1147ce8d5614SIntel return; 1148ce8d5614SIntel } 1149ce8d5614SIntel if (dcb_test) { 1150ce8d5614SIntel dcb_test = 0; 1151ce8d5614SIntel dcb_config = 0; 1152ce8d5614SIntel } 1153ce8d5614SIntel printf("Stopping ports...\n"); 1154ce8d5614SIntel 1155ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1156ce8d5614SIntel if (pid < nb_ports && pid != pi) 1157ce8d5614SIntel continue; 1158ce8d5614SIntel 1159ce8d5614SIntel port = &ports[pi]; 1160ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 1161ce8d5614SIntel RTE_PORT_HANDLING) == 0) 1162ce8d5614SIntel continue; 1163ce8d5614SIntel 1164ce8d5614SIntel rte_eth_dev_stop(pi); 1165ce8d5614SIntel 1166ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1167ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1168ce8d5614SIntel printf("Port %d can not be set into stopped\n", pi); 1169ce8d5614SIntel need_check_link_status = 1; 1170ce8d5614SIntel } 1171ce8d5614SIntel if (need_check_link_status) 1172ce8d5614SIntel check_all_ports_link_status(nb_ports, RTE_PORT_ALL); 1173ce8d5614SIntel 1174ce8d5614SIntel printf("Done\n"); 1175ce8d5614SIntel } 1176ce8d5614SIntel 1177ce8d5614SIntel void 1178ce8d5614SIntel close_port(portid_t pid) 1179ce8d5614SIntel { 1180ce8d5614SIntel portid_t pi; 1181ce8d5614SIntel struct rte_port *port; 1182ce8d5614SIntel 1183ce8d5614SIntel if (test_done == 0) { 1184ce8d5614SIntel printf("Please stop forwarding first\n"); 1185ce8d5614SIntel return; 1186ce8d5614SIntel } 1187ce8d5614SIntel 1188ce8d5614SIntel printf("Closing ports...\n"); 1189ce8d5614SIntel 1190ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1191ce8d5614SIntel if (pid < nb_ports && pid != pi) 1192ce8d5614SIntel continue; 1193ce8d5614SIntel 1194ce8d5614SIntel port = &ports[pi]; 1195ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1196ce8d5614SIntel RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 1197ce8d5614SIntel printf("Port %d is now not stopped\n", pi); 1198ce8d5614SIntel continue; 1199ce8d5614SIntel } 1200ce8d5614SIntel 1201ce8d5614SIntel rte_eth_dev_close(pi); 1202ce8d5614SIntel 1203ce8d5614SIntel if (rte_atomic16_cmpset(&(port->port_status), 1204ce8d5614SIntel RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 1205ce8d5614SIntel printf("Port %d can not be set into stopped\n", pi); 1206ce8d5614SIntel } 1207ce8d5614SIntel 1208ce8d5614SIntel printf("Done\n"); 1209ce8d5614SIntel } 1210ce8d5614SIntel 1211ce8d5614SIntel int 1212ce8d5614SIntel all_ports_stopped(void) 1213ce8d5614SIntel { 1214ce8d5614SIntel portid_t pi; 1215ce8d5614SIntel struct rte_port *port; 1216ce8d5614SIntel 1217ce8d5614SIntel for (pi = 0; pi < nb_ports; pi++) { 1218ce8d5614SIntel port = &ports[pi]; 1219ce8d5614SIntel if (port->port_status != RTE_PORT_STOPPED) 1220ce8d5614SIntel return 0; 1221ce8d5614SIntel } 1222ce8d5614SIntel 1223ce8d5614SIntel return 1; 1224ce8d5614SIntel } 1225ce8d5614SIntel 1226af75078fSIntel void 1227af75078fSIntel pmd_test_exit(void) 1228af75078fSIntel { 1229af75078fSIntel portid_t pt_id; 1230af75078fSIntel 1231af75078fSIntel for (pt_id = 0; pt_id < nb_ports; pt_id++) { 1232af75078fSIntel printf("Stopping port %d...", pt_id); 1233af75078fSIntel fflush(stdout); 1234af75078fSIntel rte_eth_dev_close(pt_id); 1235af75078fSIntel printf("done\n"); 1236af75078fSIntel } 1237af75078fSIntel printf("bye...\n"); 1238af75078fSIntel } 1239af75078fSIntel 1240af75078fSIntel typedef void (*cmd_func_t)(void); 1241af75078fSIntel struct pmd_test_command { 1242af75078fSIntel const char *cmd_name; 1243af75078fSIntel cmd_func_t cmd_func; 1244af75078fSIntel }; 1245af75078fSIntel 1246af75078fSIntel #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) 1247af75078fSIntel 1248ce8d5614SIntel /* Check the link status of all ports in up to 9s, and print them finally */ 1249af75078fSIntel static void 1250ce8d5614SIntel check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) 1251af75078fSIntel { 1252ce8d5614SIntel #define CHECK_INTERVAL 100 /* 100ms */ 1253ce8d5614SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1254ce8d5614SIntel uint8_t portid, count, all_ports_up, print_flag = 0; 1255ce8d5614SIntel struct rte_eth_link link; 1256ce8d5614SIntel 1257ce8d5614SIntel printf("Checking link statuses...\n"); 1258ce8d5614SIntel fflush(stdout); 1259ce8d5614SIntel for (count = 0; count <= MAX_CHECK_TIME; count++) { 1260ce8d5614SIntel all_ports_up = 1; 1261ce8d5614SIntel for (portid = 0; portid < port_num; portid++) { 1262ce8d5614SIntel if ((port_mask & (1 << portid)) == 0) 1263ce8d5614SIntel continue; 1264ce8d5614SIntel memset(&link, 0, sizeof(link)); 1265ce8d5614SIntel rte_eth_link_get_nowait(portid, &link); 1266ce8d5614SIntel /* print link status if flag set */ 1267ce8d5614SIntel if (print_flag == 1) { 1268ce8d5614SIntel if (link.link_status) 1269ce8d5614SIntel printf("Port %d Link Up - speed %u " 1270ce8d5614SIntel "Mbps - %s\n", (uint8_t)portid, 1271ce8d5614SIntel (unsigned)link.link_speed, 1272ce8d5614SIntel (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1273ce8d5614SIntel ("full-duplex") : ("half-duplex\n")); 1274ce8d5614SIntel else 1275ce8d5614SIntel printf("Port %d Link Down\n", 1276ce8d5614SIntel (uint8_t)portid); 1277ce8d5614SIntel continue; 1278ce8d5614SIntel } 1279ce8d5614SIntel /* clear all_ports_up flag if any link down */ 1280ce8d5614SIntel if (link.link_status == 0) { 1281ce8d5614SIntel all_ports_up = 0; 1282ce8d5614SIntel break; 1283ce8d5614SIntel } 1284ce8d5614SIntel } 1285ce8d5614SIntel /* after finally printing all link status, get out */ 1286ce8d5614SIntel if (print_flag == 1) 1287ce8d5614SIntel break; 1288ce8d5614SIntel 1289ce8d5614SIntel if (all_ports_up == 0) { 1290ce8d5614SIntel fflush(stdout); 1291ce8d5614SIntel rte_delay_ms(CHECK_INTERVAL); 1292ce8d5614SIntel } 1293ce8d5614SIntel 1294ce8d5614SIntel /* set the print_flag if all ports up or timeout */ 1295ce8d5614SIntel if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1296ce8d5614SIntel print_flag = 1; 1297ce8d5614SIntel } 1298ce8d5614SIntel } 1299af75078fSIntel } 1300af75078fSIntel 1301af75078fSIntel static void 1302af75078fSIntel init_ports(void) 1303af75078fSIntel { 1304af75078fSIntel struct rte_eth_link link; 1305af75078fSIntel struct rte_eth_conf port_conf = { 1306af75078fSIntel .intr_conf = { 1307af75078fSIntel .lsc = 0, 1308af75078fSIntel }, 1309af75078fSIntel }; 1310af75078fSIntel struct rte_eth_rxconf rx_conf; 1311af75078fSIntel struct rte_eth_txconf tx_conf; 1312af75078fSIntel struct rte_port *port; 1313af75078fSIntel unsigned int sock_id; 1314af75078fSIntel portid_t pi; 1315af75078fSIntel queueid_t qi; 1316af75078fSIntel int diag; 1317af75078fSIntel 1318af75078fSIntel port_conf.rxmode = rx_mode; 1319af75078fSIntel port_conf.fdir_conf = fdir_conf; 1320af75078fSIntel 1321af75078fSIntel if (nb_rxq > 0) { /* configure RSS */ 1322af75078fSIntel port_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1323af75078fSIntel /* use default hash key */ 1324af75078fSIntel port_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf; 1325af75078fSIntel } else 1326af75078fSIntel port_conf.rx_adv_conf.rss_conf.rss_hf = 0; 1327af75078fSIntel rx_conf.rx_thresh = rx_thresh; 1328af75078fSIntel rx_conf.rx_free_thresh = rx_free_thresh; 1329af75078fSIntel tx_conf.tx_thresh = tx_thresh; 1330af75078fSIntel tx_conf.tx_rs_thresh = tx_rs_thresh; 1331af75078fSIntel tx_conf.tx_free_thresh = tx_free_thresh; 1332af75078fSIntel 1333af75078fSIntel for (pi = 0; pi < nb_ports; pi++) { 1334af75078fSIntel port = &ports[pi]; 1335af75078fSIntel memcpy(&port->dev_conf, &port_conf, sizeof(port_conf)); 1336af75078fSIntel sock_id = port->socket_id; 1337af75078fSIntel printf("Initializing port %d... ", pi); 1338af75078fSIntel fflush(stdout); 1339af75078fSIntel diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, &port_conf); 1340af75078fSIntel if (diag != 0) { 1341af75078fSIntel fatal_init_error("rte_eth_dev_configure", pi, diag); 1342af75078fSIntel /* NOT REACHED */ 1343af75078fSIntel } 1344af75078fSIntel rte_eth_macaddr_get(pi, &port->eth_addr); 1345af75078fSIntel for (qi = 0; qi < nb_txq; qi++) { 1346af75078fSIntel diag = rte_eth_tx_queue_setup(pi, qi, nb_txd, 1347af75078fSIntel sock_id, 1348af75078fSIntel &tx_conf); 1349af75078fSIntel if (diag != 0) { 1350af75078fSIntel fatal_init_error("rte_eth_tx_queue_setup", 1351af75078fSIntel pi, diag); 1352af75078fSIntel /* NOT REACHED */ 1353af75078fSIntel } 1354af75078fSIntel } 1355af75078fSIntel for (qi = 0; qi < nb_rxq; qi++) { 1356af75078fSIntel diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd, sock_id, 1357af75078fSIntel &rx_conf, 1358af75078fSIntel mbuf_pool_find(sock_id)); 1359af75078fSIntel if (diag != 0) { 1360af75078fSIntel fatal_init_error("rte_eth_rx_queue_setup", 1361af75078fSIntel pi , diag); 1362af75078fSIntel /* NOT REACHED */ 1363af75078fSIntel } 1364af75078fSIntel } 1365af75078fSIntel 1366af75078fSIntel /* Start device */ 1367af75078fSIntel diag = rte_eth_dev_start(pi); 1368af75078fSIntel if (diag != 0) { 1369af75078fSIntel fatal_init_error("rte_eth_dev_start", pi, diag); 1370af75078fSIntel /* NOT REACHED */ 1371af75078fSIntel } 1372af75078fSIntel printf("done: "); 1373af75078fSIntel rte_eth_link_get(pi, &link); 1374af75078fSIntel if (link.link_status) { 1375af75078fSIntel printf(" Link Up - speed %u Mbps - %s\n", 1376af75078fSIntel (unsigned) link.link_speed, 1377af75078fSIntel (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1378af75078fSIntel ("full-duplex") : ("half-duplex\n")); 1379af75078fSIntel } else { 1380af75078fSIntel printf(" Link Down\n"); 1381af75078fSIntel } 1382af75078fSIntel 1383af75078fSIntel /* 1384af75078fSIntel * If enabled, put device in promiscuous mode. 1385af75078fSIntel * This allows the PMD test in IO forwarding mode to forward 1386af75078fSIntel * packets to itself through 2 cross-connected ports of the 1387af75078fSIntel * target machine. 1388af75078fSIntel */ 1389af75078fSIntel if (promiscuous_on) 1390af75078fSIntel rte_eth_promiscuous_enable(pi); 1391af75078fSIntel } 1392af75078fSIntel } 1393af75078fSIntel 1394af75078fSIntel #ifdef RTE_EXEC_ENV_BAREMETAL 1395af75078fSIntel #define main _main 1396af75078fSIntel #endif 1397af75078fSIntel 1398af75078fSIntel int 1399af75078fSIntel main(int argc, char** argv) 1400af75078fSIntel { 1401af75078fSIntel int diag; 1402af75078fSIntel 1403af75078fSIntel diag = rte_eal_init(argc, argv); 1404af75078fSIntel if (diag < 0) 1405af75078fSIntel rte_panic("Cannot init EAL\n"); 1406af75078fSIntel 140769d22b8eSIntel if (rte_pmd_init_all()) 140869d22b8eSIntel rte_panic("Cannot init PMD\n"); 1409af75078fSIntel 1410af75078fSIntel if (rte_eal_pci_probe()) 1411af75078fSIntel rte_panic("Cannot probe PCI\n"); 1412af75078fSIntel 1413af75078fSIntel nb_ports = (portid_t) rte_eth_dev_count(); 1414af75078fSIntel if (nb_ports == 0) 1415af75078fSIntel rte_exit(EXIT_FAILURE, "No probed ethernet devices - check that " 1416af75078fSIntel "CONFIG_RTE_LIBRTE_IGB_PMD=y and that " 141769d22b8eSIntel "CONFIG_RTE_LIBRTE_EM_PMD=y and that " 1418af75078fSIntel "CONFIG_RTE_LIBRTE_IXGBE_PMD=y in your " 1419af75078fSIntel "configuration file\n"); 1420af75078fSIntel 1421af75078fSIntel set_def_fwd_config(); 1422af75078fSIntel if (nb_lcores == 0) 1423af75078fSIntel rte_panic("Empty set of forwarding logical cores - check the " 1424af75078fSIntel "core mask supplied in the command parameters\n"); 1425af75078fSIntel 1426af75078fSIntel argc -= diag; 1427af75078fSIntel argv += diag; 1428af75078fSIntel if (argc > 1) 1429af75078fSIntel launch_args_parse(argc, argv); 1430af75078fSIntel 1431af75078fSIntel if (nb_rxq > nb_txq) 1432af75078fSIntel printf("Warning: nb_rxq=%d enables RSS configuration, " 1433af75078fSIntel "but nb_txq=%d will prevent to fully test it.\n", 1434af75078fSIntel nb_rxq, nb_txq); 1435af75078fSIntel 1436af75078fSIntel init_config(); 1437ce8d5614SIntel start_port(RTE_PORT_ALL); 1438af75078fSIntel 1439ce8d5614SIntel /* set all ports to promiscuous mode by default */ 1440ce8d5614SIntel for (port_id = 0; port_id < nb_ports; port_id++) 1441ce8d5614SIntel rte_eth_promiscuous_enable(port_id); 1442af75078fSIntel 1443af75078fSIntel if (interactive == 1) 1444af75078fSIntel prompt(); 1445af75078fSIntel else { 1446af75078fSIntel char c; 1447af75078fSIntel int rc; 1448af75078fSIntel 1449af75078fSIntel printf("No commandline core given, start packet forwarding\n"); 1450af75078fSIntel start_packet_forwarding(0); 1451af75078fSIntel printf("Press enter to exit\n"); 1452af75078fSIntel rc = read(0, &c, 1); 1453af75078fSIntel if (rc < 0) 1454af75078fSIntel return 1; 1455af75078fSIntel } 1456af75078fSIntel 1457af75078fSIntel return 0; 1458af75078fSIntel } 1459