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