1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <stdarg.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <signal.h> 38 #include <string.h> 39 #include <time.h> 40 #include <fcntl.h> 41 #include <sys/types.h> 42 #include <errno.h> 43 44 #include <sys/queue.h> 45 #include <sys/stat.h> 46 47 #include <stdint.h> 48 #include <unistd.h> 49 #include <inttypes.h> 50 51 #include <rte_common.h> 52 #include <rte_errno.h> 53 #include <rte_byteorder.h> 54 #include <rte_log.h> 55 #include <rte_debug.h> 56 #include <rte_cycles.h> 57 #include <rte_memory.h> 58 #include <rte_memcpy.h> 59 #include <rte_memzone.h> 60 #include <rte_launch.h> 61 #include <rte_eal.h> 62 #include <rte_per_lcore.h> 63 #include <rte_lcore.h> 64 #include <rte_atomic.h> 65 #include <rte_branch_prediction.h> 66 #include <rte_mempool.h> 67 #include <rte_malloc.h> 68 #include <rte_mbuf.h> 69 #include <rte_interrupts.h> 70 #include <rte_pci.h> 71 #include <rte_ether.h> 72 #include <rte_ethdev.h> 73 #include <rte_dev.h> 74 #include <rte_string_fns.h> 75 #ifdef RTE_LIBRTE_PMD_XENVIRT 76 #include <rte_eth_xenvirt.h> 77 #endif 78 #ifdef RTE_LIBRTE_PDUMP 79 #include <rte_pdump.h> 80 #endif 81 #include <rte_flow.h> 82 #include <rte_metrics.h> 83 #ifdef RTE_LIBRTE_BITRATE 84 #include <rte_bitrate.h> 85 #endif 86 #include <rte_metrics.h> 87 #ifdef RTE_LIBRTE_LATENCY_STATS 88 #include <rte_latencystats.h> 89 #endif 90 91 #include "testpmd.h" 92 93 uint16_t verbose_level = 0; /**< Silent by default. */ 94 95 /* use master core for command line ? */ 96 uint8_t interactive = 0; 97 uint8_t auto_start = 0; 98 99 /* 100 * NUMA support configuration. 101 * When set, the NUMA support attempts to dispatch the allocation of the 102 * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the 103 * probed ports among the CPU sockets 0 and 1. 104 * Otherwise, all memory is allocated from CPU socket 0. 105 */ 106 uint8_t numa_support = 0; /**< No numa support by default */ 107 108 /* 109 * In UMA mode,all memory is allocated from socket 0 if --socket-num is 110 * not configured. 111 */ 112 uint8_t socket_num = UMA_NO_CONFIG; 113 114 /* 115 * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs. 116 */ 117 uint8_t mp_anon = 0; 118 119 /* 120 * Record the Ethernet address of peer target ports to which packets are 121 * forwarded. 122 * Must be instantiated with the ethernet addresses of peer traffic generator 123 * ports. 124 */ 125 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; 126 portid_t nb_peer_eth_addrs = 0; 127 128 /* 129 * Probed Target Environment. 130 */ 131 struct rte_port *ports; /**< For all probed ethernet ports. */ 132 portid_t nb_ports; /**< Number of probed ethernet ports. */ 133 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */ 134 lcoreid_t nb_lcores; /**< Number of probed logical cores. */ 135 136 /* 137 * Test Forwarding Configuration. 138 * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores 139 * nb_fwd_ports <= nb_cfg_ports <= nb_ports 140 */ 141 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */ 142 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */ 143 portid_t nb_cfg_ports; /**< Number of configured ports. */ 144 portid_t nb_fwd_ports; /**< Number of forwarding ports. */ 145 146 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */ 147 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */ 148 149 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */ 150 streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ 151 152 /* 153 * Forwarding engines. 154 */ 155 struct fwd_engine * fwd_engines[] = { 156 &io_fwd_engine, 157 &mac_fwd_engine, 158 &mac_swap_engine, 159 &flow_gen_engine, 160 &rx_only_engine, 161 &tx_only_engine, 162 &csum_fwd_engine, 163 &icmp_echo_engine, 164 #ifdef RTE_LIBRTE_IEEE1588 165 &ieee1588_fwd_engine, 166 #endif 167 NULL, 168 }; 169 170 struct fwd_config cur_fwd_config; 171 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ 172 uint32_t retry_enabled; 173 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; 174 uint32_t burst_tx_retry_num = BURST_TX_RETRIES; 175 176 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ 177 uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if 178 * specified on command-line. */ 179 180 /* 181 * Configuration of packet segments used by the "txonly" processing engine. 182 */ 183 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */ 184 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = { 185 TXONLY_DEF_PACKET_LEN, 186 }; 187 uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */ 188 189 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF; 190 /**< Split policy for packets to TX. */ 191 192 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */ 193 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ 194 195 /* current configuration is in DCB or not,0 means it is not in DCB mode */ 196 uint8_t dcb_config = 0; 197 198 /* Whether the dcb is in testing status */ 199 uint8_t dcb_test = 0; 200 201 /* 202 * Configurable number of RX/TX queues. 203 */ 204 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ 205 queueid_t nb_txq = 1; /**< Number of TX queues per port. */ 206 207 /* 208 * Configurable number of RX/TX ring descriptors. 209 */ 210 #define RTE_TEST_RX_DESC_DEFAULT 128 211 #define RTE_TEST_TX_DESC_DEFAULT 512 212 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */ 213 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */ 214 215 #define RTE_PMD_PARAM_UNSET -1 216 /* 217 * Configurable values of RX and TX ring threshold registers. 218 */ 219 220 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET; 221 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET; 222 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET; 223 224 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET; 225 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET; 226 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET; 227 228 /* 229 * Configurable value of RX free threshold. 230 */ 231 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET; 232 233 /* 234 * Configurable value of RX drop enable. 235 */ 236 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET; 237 238 /* 239 * Configurable value of TX free threshold. 240 */ 241 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET; 242 243 /* 244 * Configurable value of TX RS bit threshold. 245 */ 246 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET; 247 248 /* 249 * Configurable value of TX queue flags. 250 */ 251 int32_t txq_flags = RTE_PMD_PARAM_UNSET; 252 253 /* 254 * Receive Side Scaling (RSS) configuration. 255 */ 256 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */ 257 258 /* 259 * Port topology configuration 260 */ 261 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */ 262 263 /* 264 * Avoids to flush all the RX streams before starts forwarding. 265 */ 266 uint8_t no_flush_rx = 0; /* flush by default */ 267 268 /* 269 * Avoids to check link status when starting/stopping a port. 270 */ 271 uint8_t no_link_check = 0; /* check by default */ 272 273 /* 274 * NIC bypass mode configuration options. 275 */ 276 #ifdef RTE_NIC_BYPASS 277 278 /* The NIC bypass watchdog timeout. */ 279 uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF; 280 281 #endif 282 283 #ifdef RTE_LIBRTE_LATENCY_STATS 284 285 /* 286 * Set when latency stats is enabled in the commandline 287 */ 288 uint8_t latencystats_enabled; 289 290 /* 291 * Lcore ID to serive latency statistics. 292 */ 293 lcoreid_t latencystats_lcore_id = -1; 294 295 #endif 296 297 /* 298 * Ethernet device configuration. 299 */ 300 struct rte_eth_rxmode rx_mode = { 301 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ 302 .split_hdr_size = 0, 303 .header_split = 0, /**< Header Split disabled. */ 304 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */ 305 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */ 306 .hw_vlan_strip = 1, /**< VLAN strip enabled. */ 307 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ 308 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ 309 .hw_strip_crc = 1, /**< CRC stripping by hardware enabled. */ 310 }; 311 312 struct rte_fdir_conf fdir_conf = { 313 .mode = RTE_FDIR_MODE_NONE, 314 .pballoc = RTE_FDIR_PBALLOC_64K, 315 .status = RTE_FDIR_REPORT_STATUS, 316 .mask = { 317 .vlan_tci_mask = 0x0, 318 .ipv4_mask = { 319 .src_ip = 0xFFFFFFFF, 320 .dst_ip = 0xFFFFFFFF, 321 }, 322 .ipv6_mask = { 323 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 324 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 325 }, 326 .src_port_mask = 0xFFFF, 327 .dst_port_mask = 0xFFFF, 328 .mac_addr_byte_mask = 0xFF, 329 .tunnel_type_mask = 1, 330 .tunnel_id_mask = 0xFFFFFFFF, 331 }, 332 .drop_queue = 127, 333 }; 334 335 volatile int test_done = 1; /* stop packet forwarding when set to 1. */ 336 337 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; 338 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; 339 340 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; 341 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; 342 343 uint16_t nb_tx_queue_stats_mappings = 0; 344 uint16_t nb_rx_queue_stats_mappings = 0; 345 346 unsigned max_socket = 0; 347 348 /* Bitrate statistics */ 349 struct rte_stats_bitrates *bitrate_data; 350 351 /* Forward function declarations */ 352 static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port); 353 static void check_all_ports_link_status(uint32_t port_mask); 354 static void eth_event_callback(uint8_t port_id, 355 enum rte_eth_event_type type, 356 void *param); 357 358 /* 359 * Check if all the ports are started. 360 * If yes, return positive value. If not, return zero. 361 */ 362 static int all_ports_started(void); 363 364 /* 365 * Setup default configuration. 366 */ 367 static void 368 set_default_fwd_lcores_config(void) 369 { 370 unsigned int i; 371 unsigned int nb_lc; 372 unsigned int sock_num; 373 374 nb_lc = 0; 375 for (i = 0; i < RTE_MAX_LCORE; i++) { 376 sock_num = rte_lcore_to_socket_id(i) + 1; 377 if (sock_num > max_socket) { 378 if (sock_num > RTE_MAX_NUMA_NODES) 379 rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES); 380 max_socket = sock_num; 381 } 382 if (!rte_lcore_is_enabled(i)) 383 continue; 384 if (i == rte_get_master_lcore()) 385 continue; 386 fwd_lcores_cpuids[nb_lc++] = i; 387 } 388 nb_lcores = (lcoreid_t) nb_lc; 389 nb_cfg_lcores = nb_lcores; 390 nb_fwd_lcores = 1; 391 } 392 393 static void 394 set_def_peer_eth_addrs(void) 395 { 396 portid_t i; 397 398 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 399 peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR; 400 peer_eth_addrs[i].addr_bytes[5] = i; 401 } 402 } 403 404 static void 405 set_default_fwd_ports_config(void) 406 { 407 portid_t pt_id; 408 409 for (pt_id = 0; pt_id < nb_ports; pt_id++) 410 fwd_ports_ids[pt_id] = pt_id; 411 412 nb_cfg_ports = nb_ports; 413 nb_fwd_ports = nb_ports; 414 } 415 416 void 417 set_def_fwd_config(void) 418 { 419 set_default_fwd_lcores_config(); 420 set_def_peer_eth_addrs(); 421 set_default_fwd_ports_config(); 422 } 423 424 /* 425 * Configuration initialisation done once at init time. 426 */ 427 static void 428 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, 429 unsigned int socket_id) 430 { 431 char pool_name[RTE_MEMPOOL_NAMESIZE]; 432 struct rte_mempool *rte_mp = NULL; 433 uint32_t mb_size; 434 435 mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size; 436 mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); 437 438 RTE_LOG(INFO, USER1, 439 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n", 440 pool_name, nb_mbuf, mbuf_seg_size, socket_id); 441 442 #ifdef RTE_LIBRTE_PMD_XENVIRT 443 rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size, 444 (unsigned) mb_mempool_cache, 445 sizeof(struct rte_pktmbuf_pool_private), 446 rte_pktmbuf_pool_init, NULL, 447 rte_pktmbuf_init, NULL, 448 socket_id, 0); 449 #endif 450 451 /* if the former XEN allocation failed fall back to normal allocation */ 452 if (rte_mp == NULL) { 453 if (mp_anon != 0) { 454 rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf, 455 mb_size, (unsigned) mb_mempool_cache, 456 sizeof(struct rte_pktmbuf_pool_private), 457 socket_id, 0); 458 if (rte_mp == NULL) 459 goto err; 460 461 if (rte_mempool_populate_anon(rte_mp) == 0) { 462 rte_mempool_free(rte_mp); 463 rte_mp = NULL; 464 goto err; 465 } 466 rte_pktmbuf_pool_init(rte_mp, NULL); 467 rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL); 468 } else { 469 /* wrapper to rte_mempool_create() */ 470 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, 471 mb_mempool_cache, 0, mbuf_seg_size, socket_id); 472 } 473 } 474 475 err: 476 if (rte_mp == NULL) { 477 rte_exit(EXIT_FAILURE, 478 "Creation of mbuf pool for socket %u failed: %s\n", 479 socket_id, rte_strerror(rte_errno)); 480 } else if (verbose_level > 0) { 481 rte_mempool_dump(stdout, rte_mp); 482 } 483 } 484 485 /* 486 * Check given socket id is valid or not with NUMA mode, 487 * if valid, return 0, else return -1 488 */ 489 static int 490 check_socket_id(const unsigned int socket_id) 491 { 492 static int warning_once = 0; 493 494 if (socket_id >= max_socket) { 495 if (!warning_once && numa_support) 496 printf("Warning: NUMA should be configured manually by" 497 " using --port-numa-config and" 498 " --ring-numa-config parameters along with" 499 " --numa.\n"); 500 warning_once = 1; 501 return -1; 502 } 503 return 0; 504 } 505 506 static void 507 init_config(void) 508 { 509 portid_t pid; 510 struct rte_port *port; 511 struct rte_mempool *mbp; 512 unsigned int nb_mbuf_per_pool; 513 lcoreid_t lc_id; 514 uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; 515 516 memset(port_per_socket,0,RTE_MAX_NUMA_NODES); 517 /* Configuration of logical cores. */ 518 fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 519 sizeof(struct fwd_lcore *) * nb_lcores, 520 RTE_CACHE_LINE_SIZE); 521 if (fwd_lcores == NULL) { 522 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 523 "failed\n", nb_lcores); 524 } 525 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 526 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 527 sizeof(struct fwd_lcore), 528 RTE_CACHE_LINE_SIZE); 529 if (fwd_lcores[lc_id] == NULL) { 530 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 531 "failed\n"); 532 } 533 fwd_lcores[lc_id]->cpuid_idx = lc_id; 534 } 535 536 /* 537 * Create pools of mbuf. 538 * If NUMA support is disabled, create a single pool of mbuf in 539 * socket 0 memory by default. 540 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 541 * 542 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 543 * nb_txd can be configured at run time. 544 */ 545 if (param_total_num_mbufs) 546 nb_mbuf_per_pool = param_total_num_mbufs; 547 else { 548 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache) 549 + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 550 551 if (!numa_support) 552 nb_mbuf_per_pool = 553 (nb_mbuf_per_pool * RTE_MAX_ETHPORTS); 554 } 555 556 if (!numa_support) { 557 if (socket_num == UMA_NO_CONFIG) 558 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 559 else 560 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 561 socket_num); 562 } 563 564 RTE_ETH_FOREACH_DEV(pid) { 565 port = &ports[pid]; 566 rte_eth_dev_info_get(pid, &port->dev_info); 567 568 if (numa_support) { 569 if (port_numa[pid] != NUMA_NO_CONFIG) 570 port_per_socket[port_numa[pid]]++; 571 else { 572 uint32_t socket_id = rte_eth_dev_socket_id(pid); 573 574 /* if socket_id is invalid, set to 0 */ 575 if (check_socket_id(socket_id) < 0) 576 socket_id = 0; 577 port_per_socket[socket_id]++; 578 } 579 } 580 581 /* set flag to initialize port/queue */ 582 port->need_reconfig = 1; 583 port->need_reconfig_queues = 1; 584 } 585 586 if (numa_support) { 587 uint8_t i; 588 unsigned int nb_mbuf; 589 590 if (param_total_num_mbufs) 591 nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports; 592 593 for (i = 0; i < max_socket; i++) { 594 nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS); 595 if (nb_mbuf) 596 mbuf_pool_create(mbuf_data_size, 597 nb_mbuf,i); 598 } 599 } 600 init_port_config(); 601 602 /* 603 * Records which Mbuf pool to use by each logical core, if needed. 604 */ 605 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 606 mbp = mbuf_pool_find( 607 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id])); 608 609 if (mbp == NULL) 610 mbp = mbuf_pool_find(0); 611 fwd_lcores[lc_id]->mbp = mbp; 612 } 613 614 /* Configuration of packet forwarding streams. */ 615 if (init_fwd_streams() < 0) 616 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 617 618 fwd_config_setup(); 619 } 620 621 622 void 623 reconfig(portid_t new_port_id, unsigned socket_id) 624 { 625 struct rte_port *port; 626 627 /* Reconfiguration of Ethernet ports. */ 628 port = &ports[new_port_id]; 629 rte_eth_dev_info_get(new_port_id, &port->dev_info); 630 631 /* set flag to initialize port/queue */ 632 port->need_reconfig = 1; 633 port->need_reconfig_queues = 1; 634 port->socket_id = socket_id; 635 636 init_port_config(); 637 } 638 639 640 int 641 init_fwd_streams(void) 642 { 643 portid_t pid; 644 struct rte_port *port; 645 streamid_t sm_id, nb_fwd_streams_new; 646 queueid_t q; 647 648 /* set socket id according to numa or not */ 649 RTE_ETH_FOREACH_DEV(pid) { 650 port = &ports[pid]; 651 if (nb_rxq > port->dev_info.max_rx_queues) { 652 printf("Fail: nb_rxq(%d) is greater than " 653 "max_rx_queues(%d)\n", nb_rxq, 654 port->dev_info.max_rx_queues); 655 return -1; 656 } 657 if (nb_txq > port->dev_info.max_tx_queues) { 658 printf("Fail: nb_txq(%d) is greater than " 659 "max_tx_queues(%d)\n", nb_txq, 660 port->dev_info.max_tx_queues); 661 return -1; 662 } 663 if (numa_support) { 664 if (port_numa[pid] != NUMA_NO_CONFIG) 665 port->socket_id = port_numa[pid]; 666 else { 667 port->socket_id = rte_eth_dev_socket_id(pid); 668 669 /* if socket_id is invalid, set to 0 */ 670 if (check_socket_id(port->socket_id) < 0) 671 port->socket_id = 0; 672 } 673 } 674 else { 675 if (socket_num == UMA_NO_CONFIG) 676 port->socket_id = 0; 677 else 678 port->socket_id = socket_num; 679 } 680 } 681 682 q = RTE_MAX(nb_rxq, nb_txq); 683 if (q == 0) { 684 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n"); 685 return -1; 686 } 687 nb_fwd_streams_new = (streamid_t)(nb_ports * q); 688 if (nb_fwd_streams_new == nb_fwd_streams) 689 return 0; 690 /* clear the old */ 691 if (fwd_streams != NULL) { 692 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 693 if (fwd_streams[sm_id] == NULL) 694 continue; 695 rte_free(fwd_streams[sm_id]); 696 fwd_streams[sm_id] = NULL; 697 } 698 rte_free(fwd_streams); 699 fwd_streams = NULL; 700 } 701 702 /* init new */ 703 nb_fwd_streams = nb_fwd_streams_new; 704 fwd_streams = rte_zmalloc("testpmd: fwd_streams", 705 sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE); 706 if (fwd_streams == NULL) 707 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " 708 "failed\n", nb_fwd_streams); 709 710 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 711 fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", 712 sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE); 713 if (fwd_streams[sm_id] == NULL) 714 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" 715 " failed\n"); 716 } 717 718 return 0; 719 } 720 721 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 722 static void 723 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 724 { 725 unsigned int total_burst; 726 unsigned int nb_burst; 727 unsigned int burst_stats[3]; 728 uint16_t pktnb_stats[3]; 729 uint16_t nb_pkt; 730 int burst_percent[3]; 731 732 /* 733 * First compute the total number of packet bursts and the 734 * two highest numbers of bursts of the same number of packets. 735 */ 736 total_burst = 0; 737 burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 738 pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 739 for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 740 nb_burst = pbs->pkt_burst_spread[nb_pkt]; 741 if (nb_burst == 0) 742 continue; 743 total_burst += nb_burst; 744 if (nb_burst > burst_stats[0]) { 745 burst_stats[1] = burst_stats[0]; 746 pktnb_stats[1] = pktnb_stats[0]; 747 burst_stats[0] = nb_burst; 748 pktnb_stats[0] = nb_pkt; 749 } 750 } 751 if (total_burst == 0) 752 return; 753 burst_percent[0] = (burst_stats[0] * 100) / total_burst; 754 printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 755 burst_percent[0], (int) pktnb_stats[0]); 756 if (burst_stats[0] == total_burst) { 757 printf("]\n"); 758 return; 759 } 760 if (burst_stats[0] + burst_stats[1] == total_burst) { 761 printf(" + %d%% of %d pkts]\n", 762 100 - burst_percent[0], pktnb_stats[1]); 763 return; 764 } 765 burst_percent[1] = (burst_stats[1] * 100) / total_burst; 766 burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 767 if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 768 printf(" + %d%% of others]\n", 100 - burst_percent[0]); 769 return; 770 } 771 printf(" + %d%% of %d pkts + %d%% of others]\n", 772 burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 773 } 774 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 775 776 static void 777 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) 778 { 779 struct rte_port *port; 780 uint8_t i; 781 782 static const char *fwd_stats_border = "----------------------"; 783 784 port = &ports[port_id]; 785 printf("\n %s Forward statistics for port %-2d %s\n", 786 fwd_stats_border, port_id, fwd_stats_border); 787 788 if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 789 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 790 "%-"PRIu64"\n", 791 stats->ipackets, stats->imissed, 792 (uint64_t) (stats->ipackets + stats->imissed)); 793 794 if (cur_fwd_eng == &csum_fwd_engine) 795 printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n", 796 port->rx_bad_ip_csum, port->rx_bad_l4_csum); 797 if ((stats->ierrors + stats->rx_nombuf) > 0) { 798 printf(" RX-error: %-"PRIu64"\n", stats->ierrors); 799 printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf); 800 } 801 802 printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 803 "%-"PRIu64"\n", 804 stats->opackets, port->tx_dropped, 805 (uint64_t) (stats->opackets + port->tx_dropped)); 806 } 807 else { 808 printf(" RX-packets: %14"PRIu64" RX-dropped:%14"PRIu64" RX-total:" 809 "%14"PRIu64"\n", 810 stats->ipackets, stats->imissed, 811 (uint64_t) (stats->ipackets + stats->imissed)); 812 813 if (cur_fwd_eng == &csum_fwd_engine) 814 printf(" Bad-ipcsum:%14"PRIu64" Bad-l4csum:%14"PRIu64"\n", 815 port->rx_bad_ip_csum, port->rx_bad_l4_csum); 816 if ((stats->ierrors + stats->rx_nombuf) > 0) { 817 printf(" RX-error:%"PRIu64"\n", stats->ierrors); 818 printf(" RX-nombufs: %14"PRIu64"\n", 819 stats->rx_nombuf); 820 } 821 822 printf(" TX-packets: %14"PRIu64" TX-dropped:%14"PRIu64" TX-total:" 823 "%14"PRIu64"\n", 824 stats->opackets, port->tx_dropped, 825 (uint64_t) (stats->opackets + port->tx_dropped)); 826 } 827 828 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 829 if (port->rx_stream) 830 pkt_burst_stats_display("RX", 831 &port->rx_stream->rx_burst_stats); 832 if (port->tx_stream) 833 pkt_burst_stats_display("TX", 834 &port->tx_stream->tx_burst_stats); 835 #endif 836 837 if (port->rx_queue_stats_mapping_enabled) { 838 printf("\n"); 839 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 840 printf(" Stats reg %2d RX-packets:%14"PRIu64 841 " RX-errors:%14"PRIu64 842 " RX-bytes:%14"PRIu64"\n", 843 i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]); 844 } 845 printf("\n"); 846 } 847 if (port->tx_queue_stats_mapping_enabled) { 848 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 849 printf(" Stats reg %2d TX-packets:%14"PRIu64 850 " TX-bytes:%14"PRIu64"\n", 851 i, stats->q_opackets[i], stats->q_obytes[i]); 852 } 853 } 854 855 printf(" %s--------------------------------%s\n", 856 fwd_stats_border, fwd_stats_border); 857 } 858 859 static void 860 fwd_stream_stats_display(streamid_t stream_id) 861 { 862 struct fwd_stream *fs; 863 static const char *fwd_top_stats_border = "-------"; 864 865 fs = fwd_streams[stream_id]; 866 if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 867 (fs->fwd_dropped == 0)) 868 return; 869 printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 870 "TX Port=%2d/Queue=%2d %s\n", 871 fwd_top_stats_border, fs->rx_port, fs->rx_queue, 872 fs->tx_port, fs->tx_queue, fwd_top_stats_border); 873 printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u", 874 fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 875 876 /* if checksum mode */ 877 if (cur_fwd_eng == &csum_fwd_engine) { 878 printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: " 879 "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum); 880 } 881 882 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 883 pkt_burst_stats_display("RX", &fs->rx_burst_stats); 884 pkt_burst_stats_display("TX", &fs->tx_burst_stats); 885 #endif 886 } 887 888 static void 889 flush_fwd_rx_queues(void) 890 { 891 struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 892 portid_t rxp; 893 portid_t port_id; 894 queueid_t rxq; 895 uint16_t nb_rx; 896 uint16_t i; 897 uint8_t j; 898 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 899 uint64_t timer_period; 900 901 /* convert to number of cycles */ 902 timer_period = rte_get_timer_hz(); /* 1 second timeout */ 903 904 for (j = 0; j < 2; j++) { 905 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { 906 for (rxq = 0; rxq < nb_rxq; rxq++) { 907 port_id = fwd_ports_ids[rxp]; 908 /** 909 * testpmd can stuck in the below do while loop 910 * if rte_eth_rx_burst() always returns nonzero 911 * packets. So timer is added to exit this loop 912 * after 1sec timer expiry. 913 */ 914 prev_tsc = rte_rdtsc(); 915 do { 916 nb_rx = rte_eth_rx_burst(port_id, rxq, 917 pkts_burst, MAX_PKT_BURST); 918 for (i = 0; i < nb_rx; i++) 919 rte_pktmbuf_free(pkts_burst[i]); 920 921 cur_tsc = rte_rdtsc(); 922 diff_tsc = cur_tsc - prev_tsc; 923 timer_tsc += diff_tsc; 924 } while ((nb_rx > 0) && 925 (timer_tsc < timer_period)); 926 timer_tsc = 0; 927 } 928 } 929 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 930 } 931 } 932 933 static void 934 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 935 { 936 struct fwd_stream **fsm; 937 streamid_t nb_fs; 938 streamid_t sm_id; 939 #ifdef RTE_LIBRTE_BITRATE 940 uint64_t tics_per_1sec; 941 uint64_t tics_datum; 942 uint64_t tics_current; 943 uint8_t idx_port, cnt_ports; 944 945 cnt_ports = rte_eth_dev_count(); 946 tics_datum = rte_rdtsc(); 947 tics_per_1sec = rte_get_timer_hz(); 948 #endif 949 fsm = &fwd_streams[fc->stream_idx]; 950 nb_fs = fc->stream_nb; 951 do { 952 for (sm_id = 0; sm_id < nb_fs; sm_id++) 953 (*pkt_fwd)(fsm[sm_id]); 954 #ifdef RTE_LIBRTE_BITRATE 955 tics_current = rte_rdtsc(); 956 if (tics_current - tics_datum >= tics_per_1sec) { 957 /* Periodic bitrate calculation */ 958 for (idx_port = 0; idx_port < cnt_ports; idx_port++) 959 rte_stats_bitrate_calc(bitrate_data, idx_port); 960 tics_datum = tics_current; 961 } 962 #endif 963 #ifdef RTE_LIBRTE_LATENCY_STATS 964 if (latencystats_lcore_id == rte_lcore_id()) 965 rte_latencystats_update(); 966 #endif 967 968 } while (! fc->stopped); 969 } 970 971 static int 972 start_pkt_forward_on_core(void *fwd_arg) 973 { 974 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 975 cur_fwd_config.fwd_eng->packet_fwd); 976 return 0; 977 } 978 979 /* 980 * Run the TXONLY packet forwarding engine to send a single burst of packets. 981 * Used to start communication flows in network loopback test configurations. 982 */ 983 static int 984 run_one_txonly_burst_on_core(void *fwd_arg) 985 { 986 struct fwd_lcore *fwd_lc; 987 struct fwd_lcore tmp_lcore; 988 989 fwd_lc = (struct fwd_lcore *) fwd_arg; 990 tmp_lcore = *fwd_lc; 991 tmp_lcore.stopped = 1; 992 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 993 return 0; 994 } 995 996 /* 997 * Launch packet forwarding: 998 * - Setup per-port forwarding context. 999 * - launch logical cores with their forwarding configuration. 1000 */ 1001 static void 1002 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 1003 { 1004 port_fwd_begin_t port_fwd_begin; 1005 unsigned int i; 1006 unsigned int lc_id; 1007 int diag; 1008 1009 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 1010 if (port_fwd_begin != NULL) { 1011 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1012 (*port_fwd_begin)(fwd_ports_ids[i]); 1013 } 1014 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 1015 lc_id = fwd_lcores_cpuids[i]; 1016 if ((interactive == 0) || (lc_id != rte_lcore_id())) { 1017 fwd_lcores[i]->stopped = 0; 1018 diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 1019 fwd_lcores[i], lc_id); 1020 if (diag != 0) 1021 printf("launch lcore %u failed - diag=%d\n", 1022 lc_id, diag); 1023 } 1024 } 1025 } 1026 1027 /* 1028 * Launch packet forwarding configuration. 1029 */ 1030 void 1031 start_packet_forwarding(int with_tx_first) 1032 { 1033 port_fwd_begin_t port_fwd_begin; 1034 port_fwd_end_t port_fwd_end; 1035 struct rte_port *port; 1036 unsigned int i; 1037 portid_t pt_id; 1038 streamid_t sm_id; 1039 1040 if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq) 1041 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n"); 1042 1043 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq) 1044 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n"); 1045 1046 if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 && 1047 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) && 1048 (!nb_rxq || !nb_txq)) 1049 rte_exit(EXIT_FAILURE, 1050 "Either rxq or txq are 0, cannot use %s fwd mode\n", 1051 cur_fwd_eng->fwd_mode_name); 1052 1053 if (all_ports_started() == 0) { 1054 printf("Not all ports were started\n"); 1055 return; 1056 } 1057 if (test_done == 0) { 1058 printf("Packet forwarding already started\n"); 1059 return; 1060 } 1061 1062 if (init_fwd_streams() < 0) { 1063 printf("Fail from init_fwd_streams()\n"); 1064 return; 1065 } 1066 1067 if(dcb_test) { 1068 for (i = 0; i < nb_fwd_ports; i++) { 1069 pt_id = fwd_ports_ids[i]; 1070 port = &ports[pt_id]; 1071 if (!port->dcb_flag) { 1072 printf("In DCB mode, all forwarding ports must " 1073 "be configured in this mode.\n"); 1074 return; 1075 } 1076 } 1077 if (nb_fwd_lcores == 1) { 1078 printf("In DCB mode,the nb forwarding cores " 1079 "should be larger than 1.\n"); 1080 return; 1081 } 1082 } 1083 test_done = 0; 1084 1085 if(!no_flush_rx) 1086 flush_fwd_rx_queues(); 1087 1088 fwd_config_setup(); 1089 pkt_fwd_config_display(&cur_fwd_config); 1090 rxtx_config_display(); 1091 1092 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1093 pt_id = fwd_ports_ids[i]; 1094 port = &ports[pt_id]; 1095 rte_eth_stats_get(pt_id, &port->stats); 1096 port->tx_dropped = 0; 1097 1098 map_port_queue_stats_mapping_registers(pt_id, port); 1099 } 1100 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1101 fwd_streams[sm_id]->rx_packets = 0; 1102 fwd_streams[sm_id]->tx_packets = 0; 1103 fwd_streams[sm_id]->fwd_dropped = 0; 1104 fwd_streams[sm_id]->rx_bad_ip_csum = 0; 1105 fwd_streams[sm_id]->rx_bad_l4_csum = 0; 1106 1107 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1108 memset(&fwd_streams[sm_id]->rx_burst_stats, 0, 1109 sizeof(fwd_streams[sm_id]->rx_burst_stats)); 1110 memset(&fwd_streams[sm_id]->tx_burst_stats, 0, 1111 sizeof(fwd_streams[sm_id]->tx_burst_stats)); 1112 #endif 1113 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1114 fwd_streams[sm_id]->core_cycles = 0; 1115 #endif 1116 } 1117 if (with_tx_first) { 1118 port_fwd_begin = tx_only_engine.port_fwd_begin; 1119 if (port_fwd_begin != NULL) { 1120 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1121 (*port_fwd_begin)(fwd_ports_ids[i]); 1122 } 1123 while (with_tx_first--) { 1124 launch_packet_forwarding( 1125 run_one_txonly_burst_on_core); 1126 rte_eal_mp_wait_lcore(); 1127 } 1128 port_fwd_end = tx_only_engine.port_fwd_end; 1129 if (port_fwd_end != NULL) { 1130 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1131 (*port_fwd_end)(fwd_ports_ids[i]); 1132 } 1133 } 1134 launch_packet_forwarding(start_pkt_forward_on_core); 1135 } 1136 1137 void 1138 stop_packet_forwarding(void) 1139 { 1140 struct rte_eth_stats stats; 1141 struct rte_port *port; 1142 port_fwd_end_t port_fwd_end; 1143 int i; 1144 portid_t pt_id; 1145 streamid_t sm_id; 1146 lcoreid_t lc_id; 1147 uint64_t total_recv; 1148 uint64_t total_xmit; 1149 uint64_t total_rx_dropped; 1150 uint64_t total_tx_dropped; 1151 uint64_t total_rx_nombuf; 1152 uint64_t tx_dropped; 1153 uint64_t rx_bad_ip_csum; 1154 uint64_t rx_bad_l4_csum; 1155 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1156 uint64_t fwd_cycles; 1157 #endif 1158 static const char *acc_stats_border = "+++++++++++++++"; 1159 1160 if (test_done) { 1161 printf("Packet forwarding not started\n"); 1162 return; 1163 } 1164 printf("Telling cores to stop..."); 1165 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 1166 fwd_lcores[lc_id]->stopped = 1; 1167 printf("\nWaiting for lcores to finish...\n"); 1168 rte_eal_mp_wait_lcore(); 1169 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 1170 if (port_fwd_end != NULL) { 1171 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1172 pt_id = fwd_ports_ids[i]; 1173 (*port_fwd_end)(pt_id); 1174 } 1175 } 1176 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1177 fwd_cycles = 0; 1178 #endif 1179 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1180 if (cur_fwd_config.nb_fwd_streams > 1181 cur_fwd_config.nb_fwd_ports) { 1182 fwd_stream_stats_display(sm_id); 1183 ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL; 1184 ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL; 1185 } else { 1186 ports[fwd_streams[sm_id]->tx_port].tx_stream = 1187 fwd_streams[sm_id]; 1188 ports[fwd_streams[sm_id]->rx_port].rx_stream = 1189 fwd_streams[sm_id]; 1190 } 1191 tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped; 1192 tx_dropped = (uint64_t) (tx_dropped + 1193 fwd_streams[sm_id]->fwd_dropped); 1194 ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped; 1195 1196 rx_bad_ip_csum = 1197 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum; 1198 rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum + 1199 fwd_streams[sm_id]->rx_bad_ip_csum); 1200 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = 1201 rx_bad_ip_csum; 1202 1203 rx_bad_l4_csum = 1204 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum; 1205 rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum + 1206 fwd_streams[sm_id]->rx_bad_l4_csum); 1207 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = 1208 rx_bad_l4_csum; 1209 1210 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1211 fwd_cycles = (uint64_t) (fwd_cycles + 1212 fwd_streams[sm_id]->core_cycles); 1213 #endif 1214 } 1215 total_recv = 0; 1216 total_xmit = 0; 1217 total_rx_dropped = 0; 1218 total_tx_dropped = 0; 1219 total_rx_nombuf = 0; 1220 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1221 pt_id = fwd_ports_ids[i]; 1222 1223 port = &ports[pt_id]; 1224 rte_eth_stats_get(pt_id, &stats); 1225 stats.ipackets -= port->stats.ipackets; 1226 port->stats.ipackets = 0; 1227 stats.opackets -= port->stats.opackets; 1228 port->stats.opackets = 0; 1229 stats.ibytes -= port->stats.ibytes; 1230 port->stats.ibytes = 0; 1231 stats.obytes -= port->stats.obytes; 1232 port->stats.obytes = 0; 1233 stats.imissed -= port->stats.imissed; 1234 port->stats.imissed = 0; 1235 stats.oerrors -= port->stats.oerrors; 1236 port->stats.oerrors = 0; 1237 stats.rx_nombuf -= port->stats.rx_nombuf; 1238 port->stats.rx_nombuf = 0; 1239 1240 total_recv += stats.ipackets; 1241 total_xmit += stats.opackets; 1242 total_rx_dropped += stats.imissed; 1243 total_tx_dropped += port->tx_dropped; 1244 total_rx_nombuf += stats.rx_nombuf; 1245 1246 fwd_port_stats_display(pt_id, &stats); 1247 } 1248 printf("\n %s Accumulated forward statistics for all ports" 1249 "%s\n", 1250 acc_stats_border, acc_stats_border); 1251 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 1252 "%-"PRIu64"\n" 1253 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 1254 "%-"PRIu64"\n", 1255 total_recv, total_rx_dropped, total_recv + total_rx_dropped, 1256 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 1257 if (total_rx_nombuf > 0) 1258 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 1259 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 1260 "%s\n", 1261 acc_stats_border, acc_stats_border); 1262 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1263 if (total_recv > 0) 1264 printf("\n CPU cycles/packet=%u (total cycles=" 1265 "%"PRIu64" / total RX packets=%"PRIu64")\n", 1266 (unsigned int)(fwd_cycles / total_recv), 1267 fwd_cycles, total_recv); 1268 #endif 1269 printf("\nDone.\n"); 1270 test_done = 1; 1271 } 1272 1273 void 1274 dev_set_link_up(portid_t pid) 1275 { 1276 if (rte_eth_dev_set_link_up((uint8_t)pid) < 0) 1277 printf("\nSet link up fail.\n"); 1278 } 1279 1280 void 1281 dev_set_link_down(portid_t pid) 1282 { 1283 if (rte_eth_dev_set_link_down((uint8_t)pid) < 0) 1284 printf("\nSet link down fail.\n"); 1285 } 1286 1287 static int 1288 all_ports_started(void) 1289 { 1290 portid_t pi; 1291 struct rte_port *port; 1292 1293 RTE_ETH_FOREACH_DEV(pi) { 1294 port = &ports[pi]; 1295 /* Check if there is a port which is not started */ 1296 if ((port->port_status != RTE_PORT_STARTED) && 1297 (port->slave_flag == 0)) 1298 return 0; 1299 } 1300 1301 /* No port is not started */ 1302 return 1; 1303 } 1304 1305 int 1306 all_ports_stopped(void) 1307 { 1308 portid_t pi; 1309 struct rte_port *port; 1310 1311 RTE_ETH_FOREACH_DEV(pi) { 1312 port = &ports[pi]; 1313 if ((port->port_status != RTE_PORT_STOPPED) && 1314 (port->slave_flag == 0)) 1315 return 0; 1316 } 1317 1318 return 1; 1319 } 1320 1321 int 1322 port_is_started(portid_t port_id) 1323 { 1324 if (port_id_is_invalid(port_id, ENABLED_WARN)) 1325 return 0; 1326 1327 if (ports[port_id].port_status != RTE_PORT_STARTED) 1328 return 0; 1329 1330 return 1; 1331 } 1332 1333 static int 1334 port_is_closed(portid_t port_id) 1335 { 1336 if (port_id_is_invalid(port_id, ENABLED_WARN)) 1337 return 0; 1338 1339 if (ports[port_id].port_status != RTE_PORT_CLOSED) 1340 return 0; 1341 1342 return 1; 1343 } 1344 1345 int 1346 start_port(portid_t pid) 1347 { 1348 int diag, need_check_link_status = -1; 1349 portid_t pi; 1350 queueid_t qi; 1351 struct rte_port *port; 1352 struct ether_addr mac_addr; 1353 enum rte_eth_event_type event_type; 1354 1355 if (port_id_is_invalid(pid, ENABLED_WARN)) 1356 return 0; 1357 1358 if(dcb_config) 1359 dcb_test = 1; 1360 RTE_ETH_FOREACH_DEV(pi) { 1361 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1362 continue; 1363 1364 need_check_link_status = 0; 1365 port = &ports[pi]; 1366 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 1367 RTE_PORT_HANDLING) == 0) { 1368 printf("Port %d is now not stopped\n", pi); 1369 continue; 1370 } 1371 1372 if (port->need_reconfig > 0) { 1373 port->need_reconfig = 0; 1374 1375 printf("Configuring Port %d (socket %u)\n", pi, 1376 port->socket_id); 1377 /* configure port */ 1378 diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, 1379 &(port->dev_conf)); 1380 if (diag != 0) { 1381 if (rte_atomic16_cmpset(&(port->port_status), 1382 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1383 printf("Port %d can not be set back " 1384 "to stopped\n", pi); 1385 printf("Fail to configure port %d\n", pi); 1386 /* try to reconfigure port next time */ 1387 port->need_reconfig = 1; 1388 return -1; 1389 } 1390 } 1391 if (port->need_reconfig_queues > 0) { 1392 port->need_reconfig_queues = 0; 1393 /* setup tx queues */ 1394 for (qi = 0; qi < nb_txq; qi++) { 1395 if ((numa_support) && 1396 (txring_numa[pi] != NUMA_NO_CONFIG)) 1397 diag = rte_eth_tx_queue_setup(pi, qi, 1398 nb_txd,txring_numa[pi], 1399 &(port->tx_conf)); 1400 else 1401 diag = rte_eth_tx_queue_setup(pi, qi, 1402 nb_txd,port->socket_id, 1403 &(port->tx_conf)); 1404 1405 if (diag == 0) 1406 continue; 1407 1408 /* Fail to setup tx queue, return */ 1409 if (rte_atomic16_cmpset(&(port->port_status), 1410 RTE_PORT_HANDLING, 1411 RTE_PORT_STOPPED) == 0) 1412 printf("Port %d can not be set back " 1413 "to stopped\n", pi); 1414 printf("Fail to configure port %d tx queues\n", pi); 1415 /* try to reconfigure queues next time */ 1416 port->need_reconfig_queues = 1; 1417 return -1; 1418 } 1419 /* setup rx queues */ 1420 for (qi = 0; qi < nb_rxq; qi++) { 1421 if ((numa_support) && 1422 (rxring_numa[pi] != NUMA_NO_CONFIG)) { 1423 struct rte_mempool * mp = 1424 mbuf_pool_find(rxring_numa[pi]); 1425 if (mp == NULL) { 1426 printf("Failed to setup RX queue:" 1427 "No mempool allocation" 1428 " on the socket %d\n", 1429 rxring_numa[pi]); 1430 return -1; 1431 } 1432 1433 diag = rte_eth_rx_queue_setup(pi, qi, 1434 nb_rxd,rxring_numa[pi], 1435 &(port->rx_conf),mp); 1436 } else { 1437 struct rte_mempool *mp = 1438 mbuf_pool_find(port->socket_id); 1439 if (mp == NULL) { 1440 printf("Failed to setup RX queue:" 1441 "No mempool allocation" 1442 " on the socket %d\n", 1443 port->socket_id); 1444 return -1; 1445 } 1446 diag = rte_eth_rx_queue_setup(pi, qi, 1447 nb_rxd,port->socket_id, 1448 &(port->rx_conf), mp); 1449 } 1450 if (diag == 0) 1451 continue; 1452 1453 /* Fail to setup rx queue, return */ 1454 if (rte_atomic16_cmpset(&(port->port_status), 1455 RTE_PORT_HANDLING, 1456 RTE_PORT_STOPPED) == 0) 1457 printf("Port %d can not be set back " 1458 "to stopped\n", pi); 1459 printf("Fail to configure port %d rx queues\n", pi); 1460 /* try to reconfigure queues next time */ 1461 port->need_reconfig_queues = 1; 1462 return -1; 1463 } 1464 } 1465 1466 for (event_type = RTE_ETH_EVENT_UNKNOWN; 1467 event_type < RTE_ETH_EVENT_MAX; 1468 event_type++) { 1469 diag = rte_eth_dev_callback_register(pi, 1470 event_type, 1471 eth_event_callback, 1472 NULL); 1473 if (diag) { 1474 printf("Failed to setup even callback for event %d\n", 1475 event_type); 1476 return -1; 1477 } 1478 } 1479 1480 /* start port */ 1481 if (rte_eth_dev_start(pi) < 0) { 1482 printf("Fail to start port %d\n", pi); 1483 1484 /* Fail to setup rx queue, return */ 1485 if (rte_atomic16_cmpset(&(port->port_status), 1486 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1487 printf("Port %d can not be set back to " 1488 "stopped\n", pi); 1489 continue; 1490 } 1491 1492 if (rte_atomic16_cmpset(&(port->port_status), 1493 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 1494 printf("Port %d can not be set into started\n", pi); 1495 1496 rte_eth_macaddr_get(pi, &mac_addr); 1497 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, 1498 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 1499 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 1500 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); 1501 1502 /* at least one port started, need checking link status */ 1503 need_check_link_status = 1; 1504 } 1505 1506 if (need_check_link_status == 1 && !no_link_check) 1507 check_all_ports_link_status(RTE_PORT_ALL); 1508 else if (need_check_link_status == 0) 1509 printf("Please stop the ports first\n"); 1510 1511 printf("Done\n"); 1512 return 0; 1513 } 1514 1515 void 1516 stop_port(portid_t pid) 1517 { 1518 portid_t pi; 1519 struct rte_port *port; 1520 int need_check_link_status = 0; 1521 1522 if (dcb_test) { 1523 dcb_test = 0; 1524 dcb_config = 0; 1525 } 1526 1527 if (port_id_is_invalid(pid, ENABLED_WARN)) 1528 return; 1529 1530 printf("Stopping ports...\n"); 1531 1532 RTE_ETH_FOREACH_DEV(pi) { 1533 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1534 continue; 1535 1536 if (port_is_forwarding(pi) != 0 && test_done == 0) { 1537 printf("Please remove port %d from forwarding configuration.\n", pi); 1538 continue; 1539 } 1540 1541 if (port_is_bonding_slave(pi)) { 1542 printf("Please remove port %d from bonded device.\n", pi); 1543 continue; 1544 } 1545 1546 port = &ports[pi]; 1547 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 1548 RTE_PORT_HANDLING) == 0) 1549 continue; 1550 1551 rte_eth_dev_stop(pi); 1552 1553 if (rte_atomic16_cmpset(&(port->port_status), 1554 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1555 printf("Port %d can not be set into stopped\n", pi); 1556 need_check_link_status = 1; 1557 } 1558 if (need_check_link_status && !no_link_check) 1559 check_all_ports_link_status(RTE_PORT_ALL); 1560 1561 printf("Done\n"); 1562 } 1563 1564 void 1565 close_port(portid_t pid) 1566 { 1567 portid_t pi; 1568 struct rte_port *port; 1569 1570 if (port_id_is_invalid(pid, ENABLED_WARN)) 1571 return; 1572 1573 printf("Closing ports...\n"); 1574 1575 RTE_ETH_FOREACH_DEV(pi) { 1576 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1577 continue; 1578 1579 if (port_is_forwarding(pi) != 0 && test_done == 0) { 1580 printf("Please remove port %d from forwarding configuration.\n", pi); 1581 continue; 1582 } 1583 1584 if (port_is_bonding_slave(pi)) { 1585 printf("Please remove port %d from bonded device.\n", pi); 1586 continue; 1587 } 1588 1589 port = &ports[pi]; 1590 if (rte_atomic16_cmpset(&(port->port_status), 1591 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { 1592 printf("Port %d is already closed\n", pi); 1593 continue; 1594 } 1595 1596 if (rte_atomic16_cmpset(&(port->port_status), 1597 RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 1598 printf("Port %d is now not stopped\n", pi); 1599 continue; 1600 } 1601 1602 if (port->flow_list) 1603 port_flow_flush(pi); 1604 rte_eth_dev_close(pi); 1605 1606 if (rte_atomic16_cmpset(&(port->port_status), 1607 RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 1608 printf("Port %d cannot be set to closed\n", pi); 1609 } 1610 1611 printf("Done\n"); 1612 } 1613 1614 void 1615 attach_port(char *identifier) 1616 { 1617 portid_t pi = 0; 1618 unsigned int socket_id; 1619 1620 printf("Attaching a new port...\n"); 1621 1622 if (identifier == NULL) { 1623 printf("Invalid parameters are specified\n"); 1624 return; 1625 } 1626 1627 if (rte_eth_dev_attach(identifier, &pi)) 1628 return; 1629 1630 socket_id = (unsigned)rte_eth_dev_socket_id(pi); 1631 /* if socket_id is invalid, set to 0 */ 1632 if (check_socket_id(socket_id) < 0) 1633 socket_id = 0; 1634 reconfig(pi, socket_id); 1635 rte_eth_promiscuous_enable(pi); 1636 1637 nb_ports = rte_eth_dev_count(); 1638 1639 ports[pi].port_status = RTE_PORT_STOPPED; 1640 1641 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); 1642 printf("Done\n"); 1643 } 1644 1645 void 1646 detach_port(uint8_t port_id) 1647 { 1648 char name[RTE_ETH_NAME_MAX_LEN]; 1649 1650 printf("Detaching a port...\n"); 1651 1652 if (!port_is_closed(port_id)) { 1653 printf("Please close port first\n"); 1654 return; 1655 } 1656 1657 if (ports[port_id].flow_list) 1658 port_flow_flush(port_id); 1659 1660 if (rte_eth_dev_detach(port_id, name)) 1661 return; 1662 1663 nb_ports = rte_eth_dev_count(); 1664 1665 printf("Port '%s' is detached. Now total ports is %d\n", 1666 name, nb_ports); 1667 printf("Done\n"); 1668 return; 1669 } 1670 1671 void 1672 pmd_test_exit(void) 1673 { 1674 portid_t pt_id; 1675 1676 if (test_done == 0) 1677 stop_packet_forwarding(); 1678 1679 if (ports != NULL) { 1680 no_link_check = 1; 1681 RTE_ETH_FOREACH_DEV(pt_id) { 1682 printf("\nShutting down port %d...\n", pt_id); 1683 fflush(stdout); 1684 stop_port(pt_id); 1685 close_port(pt_id); 1686 } 1687 } 1688 printf("\nBye...\n"); 1689 } 1690 1691 typedef void (*cmd_func_t)(void); 1692 struct pmd_test_command { 1693 const char *cmd_name; 1694 cmd_func_t cmd_func; 1695 }; 1696 1697 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) 1698 1699 /* Check the link status of all ports in up to 9s, and print them finally */ 1700 static void 1701 check_all_ports_link_status(uint32_t port_mask) 1702 { 1703 #define CHECK_INTERVAL 100 /* 100ms */ 1704 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1705 uint8_t portid, count, all_ports_up, print_flag = 0; 1706 struct rte_eth_link link; 1707 1708 printf("Checking link statuses...\n"); 1709 fflush(stdout); 1710 for (count = 0; count <= MAX_CHECK_TIME; count++) { 1711 all_ports_up = 1; 1712 RTE_ETH_FOREACH_DEV(portid) { 1713 if ((port_mask & (1 << portid)) == 0) 1714 continue; 1715 memset(&link, 0, sizeof(link)); 1716 rte_eth_link_get_nowait(portid, &link); 1717 /* print link status if flag set */ 1718 if (print_flag == 1) { 1719 if (link.link_status) 1720 printf("Port %d Link Up - speed %u " 1721 "Mbps - %s\n", (uint8_t)portid, 1722 (unsigned)link.link_speed, 1723 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1724 ("full-duplex") : ("half-duplex\n")); 1725 else 1726 printf("Port %d Link Down\n", 1727 (uint8_t)portid); 1728 continue; 1729 } 1730 /* clear all_ports_up flag if any link down */ 1731 if (link.link_status == ETH_LINK_DOWN) { 1732 all_ports_up = 0; 1733 break; 1734 } 1735 } 1736 /* after finally printing all link status, get out */ 1737 if (print_flag == 1) 1738 break; 1739 1740 if (all_ports_up == 0) { 1741 fflush(stdout); 1742 rte_delay_ms(CHECK_INTERVAL); 1743 } 1744 1745 /* set the print_flag if all ports up or timeout */ 1746 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1747 print_flag = 1; 1748 } 1749 } 1750 } 1751 1752 /* This function is used by the interrupt thread */ 1753 static void 1754 eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param) 1755 { 1756 static const char * const event_desc[] = { 1757 [RTE_ETH_EVENT_UNKNOWN] = "Unknown", 1758 [RTE_ETH_EVENT_INTR_LSC] = "LSC", 1759 [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state", 1760 [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset", 1761 [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox", 1762 [RTE_ETH_EVENT_MACSEC] = "MACsec", 1763 [RTE_ETH_EVENT_INTR_RMV] = "device removal", 1764 [RTE_ETH_EVENT_MAX] = NULL, 1765 }; 1766 1767 RTE_SET_USED(param); 1768 1769 if (type >= RTE_ETH_EVENT_MAX) { 1770 fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n", 1771 port_id, __func__, type); 1772 fflush(stderr); 1773 } else { 1774 printf("\nPort %" PRIu8 ": %s event\n", port_id, 1775 event_desc[type]); 1776 fflush(stdout); 1777 } 1778 } 1779 1780 static int 1781 set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) 1782 { 1783 uint16_t i; 1784 int diag; 1785 uint8_t mapping_found = 0; 1786 1787 for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 1788 if ((tx_queue_stats_mappings[i].port_id == port_id) && 1789 (tx_queue_stats_mappings[i].queue_id < nb_txq )) { 1790 diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, 1791 tx_queue_stats_mappings[i].queue_id, 1792 tx_queue_stats_mappings[i].stats_counter_id); 1793 if (diag != 0) 1794 return diag; 1795 mapping_found = 1; 1796 } 1797 } 1798 if (mapping_found) 1799 port->tx_queue_stats_mapping_enabled = 1; 1800 return 0; 1801 } 1802 1803 static int 1804 set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) 1805 { 1806 uint16_t i; 1807 int diag; 1808 uint8_t mapping_found = 0; 1809 1810 for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 1811 if ((rx_queue_stats_mappings[i].port_id == port_id) && 1812 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { 1813 diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, 1814 rx_queue_stats_mappings[i].queue_id, 1815 rx_queue_stats_mappings[i].stats_counter_id); 1816 if (diag != 0) 1817 return diag; 1818 mapping_found = 1; 1819 } 1820 } 1821 if (mapping_found) 1822 port->rx_queue_stats_mapping_enabled = 1; 1823 return 0; 1824 } 1825 1826 static void 1827 map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port) 1828 { 1829 int diag = 0; 1830 1831 diag = set_tx_queue_stats_mapping_registers(pi, port); 1832 if (diag != 0) { 1833 if (diag == -ENOTSUP) { 1834 port->tx_queue_stats_mapping_enabled = 0; 1835 printf("TX queue stats mapping not supported port id=%d\n", pi); 1836 } 1837 else 1838 rte_exit(EXIT_FAILURE, 1839 "set_tx_queue_stats_mapping_registers " 1840 "failed for port id=%d diag=%d\n", 1841 pi, diag); 1842 } 1843 1844 diag = set_rx_queue_stats_mapping_registers(pi, port); 1845 if (diag != 0) { 1846 if (diag == -ENOTSUP) { 1847 port->rx_queue_stats_mapping_enabled = 0; 1848 printf("RX queue stats mapping not supported port id=%d\n", pi); 1849 } 1850 else 1851 rte_exit(EXIT_FAILURE, 1852 "set_rx_queue_stats_mapping_registers " 1853 "failed for port id=%d diag=%d\n", 1854 pi, diag); 1855 } 1856 } 1857 1858 static void 1859 rxtx_port_config(struct rte_port *port) 1860 { 1861 port->rx_conf = port->dev_info.default_rxconf; 1862 port->tx_conf = port->dev_info.default_txconf; 1863 1864 /* Check if any RX/TX parameters have been passed */ 1865 if (rx_pthresh != RTE_PMD_PARAM_UNSET) 1866 port->rx_conf.rx_thresh.pthresh = rx_pthresh; 1867 1868 if (rx_hthresh != RTE_PMD_PARAM_UNSET) 1869 port->rx_conf.rx_thresh.hthresh = rx_hthresh; 1870 1871 if (rx_wthresh != RTE_PMD_PARAM_UNSET) 1872 port->rx_conf.rx_thresh.wthresh = rx_wthresh; 1873 1874 if (rx_free_thresh != RTE_PMD_PARAM_UNSET) 1875 port->rx_conf.rx_free_thresh = rx_free_thresh; 1876 1877 if (rx_drop_en != RTE_PMD_PARAM_UNSET) 1878 port->rx_conf.rx_drop_en = rx_drop_en; 1879 1880 if (tx_pthresh != RTE_PMD_PARAM_UNSET) 1881 port->tx_conf.tx_thresh.pthresh = tx_pthresh; 1882 1883 if (tx_hthresh != RTE_PMD_PARAM_UNSET) 1884 port->tx_conf.tx_thresh.hthresh = tx_hthresh; 1885 1886 if (tx_wthresh != RTE_PMD_PARAM_UNSET) 1887 port->tx_conf.tx_thresh.wthresh = tx_wthresh; 1888 1889 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET) 1890 port->tx_conf.tx_rs_thresh = tx_rs_thresh; 1891 1892 if (tx_free_thresh != RTE_PMD_PARAM_UNSET) 1893 port->tx_conf.tx_free_thresh = tx_free_thresh; 1894 1895 if (txq_flags != RTE_PMD_PARAM_UNSET) 1896 port->tx_conf.txq_flags = txq_flags; 1897 } 1898 1899 void 1900 init_port_config(void) 1901 { 1902 portid_t pid; 1903 struct rte_port *port; 1904 1905 RTE_ETH_FOREACH_DEV(pid) { 1906 port = &ports[pid]; 1907 port->dev_conf.rxmode = rx_mode; 1908 port->dev_conf.fdir_conf = fdir_conf; 1909 if (nb_rxq > 1) { 1910 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1911 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf; 1912 } else { 1913 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 1914 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; 1915 } 1916 1917 if (port->dcb_flag == 0) { 1918 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 1919 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 1920 else 1921 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; 1922 } 1923 1924 rxtx_port_config(port); 1925 1926 rte_eth_macaddr_get(pid, &port->eth_addr); 1927 1928 map_port_queue_stats_mapping_registers(pid, port); 1929 #ifdef RTE_NIC_BYPASS 1930 rte_eth_dev_bypass_init(pid); 1931 #endif 1932 } 1933 } 1934 1935 void set_port_slave_flag(portid_t slave_pid) 1936 { 1937 struct rte_port *port; 1938 1939 port = &ports[slave_pid]; 1940 port->slave_flag = 1; 1941 } 1942 1943 void clear_port_slave_flag(portid_t slave_pid) 1944 { 1945 struct rte_port *port; 1946 1947 port = &ports[slave_pid]; 1948 port->slave_flag = 0; 1949 } 1950 1951 uint8_t port_is_bonding_slave(portid_t slave_pid) 1952 { 1953 struct rte_port *port; 1954 1955 port = &ports[slave_pid]; 1956 return port->slave_flag; 1957 } 1958 1959 const uint16_t vlan_tags[] = { 1960 0, 1, 2, 3, 4, 5, 6, 7, 1961 8, 9, 10, 11, 12, 13, 14, 15, 1962 16, 17, 18, 19, 20, 21, 22, 23, 1963 24, 25, 26, 27, 28, 29, 30, 31 1964 }; 1965 1966 static int 1967 get_eth_dcb_conf(struct rte_eth_conf *eth_conf, 1968 enum dcb_mode_enable dcb_mode, 1969 enum rte_eth_nb_tcs num_tcs, 1970 uint8_t pfc_en) 1971 { 1972 uint8_t i; 1973 1974 /* 1975 * Builds up the correct configuration for dcb+vt based on the vlan tags array 1976 * given above, and the number of traffic classes available for use. 1977 */ 1978 if (dcb_mode == DCB_VT_ENABLED) { 1979 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf = 1980 ð_conf->rx_adv_conf.vmdq_dcb_conf; 1981 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf = 1982 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf; 1983 1984 /* VMDQ+DCB RX and TX configurations */ 1985 vmdq_rx_conf->enable_default_pool = 0; 1986 vmdq_rx_conf->default_pool = 0; 1987 vmdq_rx_conf->nb_queue_pools = 1988 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 1989 vmdq_tx_conf->nb_queue_pools = 1990 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 1991 1992 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools; 1993 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) { 1994 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i]; 1995 vmdq_rx_conf->pool_map[i].pools = 1996 1 << (i % vmdq_rx_conf->nb_queue_pools); 1997 } 1998 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 1999 vmdq_rx_conf->dcb_tc[i] = i; 2000 vmdq_tx_conf->dcb_tc[i] = i; 2001 } 2002 2003 /* set DCB mode of RX and TX of multiple queues */ 2004 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB; 2005 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB; 2006 } else { 2007 struct rte_eth_dcb_rx_conf *rx_conf = 2008 ð_conf->rx_adv_conf.dcb_rx_conf; 2009 struct rte_eth_dcb_tx_conf *tx_conf = 2010 ð_conf->tx_adv_conf.dcb_tx_conf; 2011 2012 rx_conf->nb_tcs = num_tcs; 2013 tx_conf->nb_tcs = num_tcs; 2014 2015 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 2016 rx_conf->dcb_tc[i] = i % num_tcs; 2017 tx_conf->dcb_tc[i] = i % num_tcs; 2018 } 2019 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS; 2020 eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf; 2021 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB; 2022 } 2023 2024 if (pfc_en) 2025 eth_conf->dcb_capability_en = 2026 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT; 2027 else 2028 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 2029 2030 return 0; 2031 } 2032 2033 int 2034 init_port_dcb_config(portid_t pid, 2035 enum dcb_mode_enable dcb_mode, 2036 enum rte_eth_nb_tcs num_tcs, 2037 uint8_t pfc_en) 2038 { 2039 struct rte_eth_conf port_conf; 2040 struct rte_port *rte_port; 2041 int retval; 2042 uint16_t i; 2043 2044 rte_port = &ports[pid]; 2045 2046 memset(&port_conf, 0, sizeof(struct rte_eth_conf)); 2047 /* Enter DCB configuration status */ 2048 dcb_config = 1; 2049 2050 /*set configuration of DCB in vt mode and DCB in non-vt mode*/ 2051 retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en); 2052 if (retval < 0) 2053 return retval; 2054 port_conf.rxmode.hw_vlan_filter = 1; 2055 2056 /** 2057 * Write the configuration into the device. 2058 * Set the numbers of RX & TX queues to 0, so 2059 * the RX & TX queues will not be setup. 2060 */ 2061 (void)rte_eth_dev_configure(pid, 0, 0, &port_conf); 2062 2063 rte_eth_dev_info_get(pid, &rte_port->dev_info); 2064 2065 /* If dev_info.vmdq_pool_base is greater than 0, 2066 * the queue id of vmdq pools is started after pf queues. 2067 */ 2068 if (dcb_mode == DCB_VT_ENABLED && 2069 rte_port->dev_info.vmdq_pool_base > 0) { 2070 printf("VMDQ_DCB multi-queue mode is nonsensical" 2071 " for port %d.", pid); 2072 return -1; 2073 } 2074 2075 /* Assume the ports in testpmd have the same dcb capability 2076 * and has the same number of rxq and txq in dcb mode 2077 */ 2078 if (dcb_mode == DCB_VT_ENABLED) { 2079 if (rte_port->dev_info.max_vfs > 0) { 2080 nb_rxq = rte_port->dev_info.nb_rx_queues; 2081 nb_txq = rte_port->dev_info.nb_tx_queues; 2082 } else { 2083 nb_rxq = rte_port->dev_info.max_rx_queues; 2084 nb_txq = rte_port->dev_info.max_tx_queues; 2085 } 2086 } else { 2087 /*if vt is disabled, use all pf queues */ 2088 if (rte_port->dev_info.vmdq_pool_base == 0) { 2089 nb_rxq = rte_port->dev_info.max_rx_queues; 2090 nb_txq = rte_port->dev_info.max_tx_queues; 2091 } else { 2092 nb_rxq = (queueid_t)num_tcs; 2093 nb_txq = (queueid_t)num_tcs; 2094 2095 } 2096 } 2097 rx_free_thresh = 64; 2098 2099 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf)); 2100 2101 rxtx_port_config(rte_port); 2102 /* VLAN filter */ 2103 rte_port->dev_conf.rxmode.hw_vlan_filter = 1; 2104 for (i = 0; i < RTE_DIM(vlan_tags); i++) 2105 rx_vft_set(pid, vlan_tags[i], 1); 2106 2107 rte_eth_macaddr_get(pid, &rte_port->eth_addr); 2108 map_port_queue_stats_mapping_registers(pid, rte_port); 2109 2110 rte_port->dcb_flag = 1; 2111 2112 return 0; 2113 } 2114 2115 static void 2116 init_port(void) 2117 { 2118 /* Configuration of Ethernet ports. */ 2119 ports = rte_zmalloc("testpmd: ports", 2120 sizeof(struct rte_port) * RTE_MAX_ETHPORTS, 2121 RTE_CACHE_LINE_SIZE); 2122 if (ports == NULL) { 2123 rte_exit(EXIT_FAILURE, 2124 "rte_zmalloc(%d struct rte_port) failed\n", 2125 RTE_MAX_ETHPORTS); 2126 } 2127 } 2128 2129 static void 2130 force_quit(void) 2131 { 2132 pmd_test_exit(); 2133 prompt_exit(); 2134 } 2135 2136 static void 2137 signal_handler(int signum) 2138 { 2139 if (signum == SIGINT || signum == SIGTERM) { 2140 printf("\nSignal %d received, preparing to exit...\n", 2141 signum); 2142 #ifdef RTE_LIBRTE_PDUMP 2143 /* uninitialize packet capture framework */ 2144 rte_pdump_uninit(); 2145 #endif 2146 #ifdef RTE_LIBRTE_LATENCY_STATS 2147 rte_latencystats_uninit(); 2148 #endif 2149 force_quit(); 2150 /* exit with the expected status */ 2151 signal(signum, SIG_DFL); 2152 kill(getpid(), signum); 2153 } 2154 } 2155 2156 int 2157 main(int argc, char** argv) 2158 { 2159 int diag; 2160 uint8_t port_id; 2161 2162 signal(SIGINT, signal_handler); 2163 signal(SIGTERM, signal_handler); 2164 2165 diag = rte_eal_init(argc, argv); 2166 if (diag < 0) 2167 rte_panic("Cannot init EAL\n"); 2168 2169 #ifdef RTE_LIBRTE_PDUMP 2170 /* initialize packet capture framework */ 2171 rte_pdump_init(NULL); 2172 #endif 2173 2174 nb_ports = (portid_t) rte_eth_dev_count(); 2175 if (nb_ports == 0) 2176 RTE_LOG(WARNING, EAL, "No probed ethernet devices\n"); 2177 2178 /* allocate port structures, and init them */ 2179 init_port(); 2180 2181 set_def_fwd_config(); 2182 if (nb_lcores == 0) 2183 rte_panic("Empty set of forwarding logical cores - check the " 2184 "core mask supplied in the command parameters\n"); 2185 2186 argc -= diag; 2187 argv += diag; 2188 if (argc > 1) 2189 launch_args_parse(argc, argv); 2190 2191 if (!nb_rxq && !nb_txq) 2192 printf("Warning: Either rx or tx queues should be non-zero\n"); 2193 2194 if (nb_rxq > 1 && nb_rxq > nb_txq) 2195 printf("Warning: nb_rxq=%d enables RSS configuration, " 2196 "but nb_txq=%d will prevent to fully test it.\n", 2197 nb_rxq, nb_txq); 2198 2199 init_config(); 2200 if (start_port(RTE_PORT_ALL) != 0) 2201 rte_exit(EXIT_FAILURE, "Start ports failed\n"); 2202 2203 /* set all ports to promiscuous mode by default */ 2204 RTE_ETH_FOREACH_DEV(port_id) 2205 rte_eth_promiscuous_enable(port_id); 2206 2207 /* Init metrics library */ 2208 rte_metrics_init(rte_socket_id()); 2209 2210 #ifdef RTE_LIBRTE_LATENCY_STATS 2211 if (latencystats_enabled != 0) { 2212 int ret = rte_latencystats_init(1, NULL); 2213 if (ret) 2214 printf("Warning: latencystats init()" 2215 " returned error %d\n", ret); 2216 printf("Latencystats running on lcore %d\n", 2217 latencystats_lcore_id); 2218 } 2219 #endif 2220 2221 /* Setup bitrate stats */ 2222 #ifdef RTE_LIBRTE_BITRATE 2223 bitrate_data = rte_stats_bitrate_create(); 2224 if (bitrate_data == NULL) 2225 rte_exit(EXIT_FAILURE, "Could not allocate bitrate data.\n"); 2226 rte_stats_bitrate_reg(bitrate_data); 2227 #endif 2228 2229 2230 #ifdef RTE_LIBRTE_CMDLINE 2231 if (interactive == 1) { 2232 if (auto_start) { 2233 printf("Start automatic packet forwarding\n"); 2234 start_packet_forwarding(0); 2235 } 2236 prompt(); 2237 } else 2238 #endif 2239 { 2240 char c; 2241 int rc; 2242 2243 printf("No commandline core given, start packet forwarding\n"); 2244 start_packet_forwarding(0); 2245 printf("Press enter to exit\n"); 2246 rc = read(0, &c, 1); 2247 pmd_test_exit(); 2248 if (rc < 0) 2249 return 1; 2250 } 2251 2252 return 0; 2253 } 2254