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 /* BSD LICENSE 34 * 35 * Copyright 2013-2014 6WIND S.A. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 41 * * Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * * Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in 45 * the documentation and/or other materials provided with the 46 * distribution. 47 * * Neither the name of 6WIND S.A. nor the names of its 48 * contributors may be used to endorse or promote products derived 49 * from this software without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 52 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 53 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 54 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 55 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 56 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 61 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 #include <stdarg.h> 65 #include <errno.h> 66 #include <stdio.h> 67 #include <string.h> 68 #include <stdarg.h> 69 #include <stdint.h> 70 #include <inttypes.h> 71 72 #include <sys/queue.h> 73 74 #include <rte_common.h> 75 #include <rte_byteorder.h> 76 #include <rte_debug.h> 77 #include <rte_log.h> 78 #include <rte_memory.h> 79 #include <rte_memcpy.h> 80 #include <rte_memzone.h> 81 #include <rte_launch.h> 82 #include <rte_tailq.h> 83 #include <rte_eal.h> 84 #include <rte_per_lcore.h> 85 #include <rte_lcore.h> 86 #include <rte_atomic.h> 87 #include <rte_branch_prediction.h> 88 #include <rte_ring.h> 89 #include <rte_mempool.h> 90 #include <rte_mbuf.h> 91 #include <rte_interrupts.h> 92 #include <rte_pci.h> 93 #include <rte_ether.h> 94 #include <rte_ethdev.h> 95 #include <rte_string_fns.h> 96 97 #include "testpmd.h" 98 99 static const char *flowtype_str[RTE_ETH_FLOW_TYPE_MAX] = { 100 NULL, 101 "udp4", 102 "tcp4", 103 "sctp4", 104 "ip4", 105 "ip4-frag", 106 "udp6", 107 "tcp6", 108 "sctp6", 109 "ip6", 110 "ip6-frag", 111 }; 112 113 static void 114 print_ethaddr(const char *name, struct ether_addr *eth_addr) 115 { 116 char buf[ETHER_ADDR_FMT_SIZE]; 117 ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr); 118 printf("%s%s", name, buf); 119 } 120 121 void 122 nic_stats_display(portid_t port_id) 123 { 124 struct rte_eth_stats stats; 125 struct rte_port *port = &ports[port_id]; 126 uint8_t i; 127 128 static const char *nic_stats_border = "########################"; 129 130 if (port_id >= nb_ports) { 131 printf("Invalid port, range is [0, %d]\n", nb_ports - 1); 132 return; 133 } 134 rte_eth_stats_get(port_id, &stats); 135 printf("\n %s NIC statistics for port %-2d %s\n", 136 nic_stats_border, port_id, nic_stats_border); 137 138 if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 139 printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: " 140 "%-"PRIu64"\n", 141 stats.ipackets, stats.imissed, stats.ibytes); 142 printf(" RX-badcrc: %-10"PRIu64" RX-badlen: %-10"PRIu64" RX-errors: " 143 "%-"PRIu64"\n", 144 stats.ibadcrc, stats.ibadlen, stats.ierrors); 145 printf(" RX-nombuf: %-10"PRIu64"\n", 146 stats.rx_nombuf); 147 printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: " 148 "%-"PRIu64"\n", 149 stats.opackets, stats.oerrors, stats.obytes); 150 } 151 else { 152 printf(" RX-packets: %10"PRIu64" RX-errors: %10"PRIu64 153 " RX-bytes: %10"PRIu64"\n", 154 stats.ipackets, stats.ierrors, stats.ibytes); 155 printf(" RX-badcrc: %10"PRIu64" RX-badlen: %10"PRIu64 156 " RX-errors: %10"PRIu64"\n", 157 stats.ibadcrc, stats.ibadlen, stats.ierrors); 158 printf(" RX-nombuf: %10"PRIu64"\n", 159 stats.rx_nombuf); 160 printf(" TX-packets: %10"PRIu64" TX-errors: %10"PRIu64 161 " TX-bytes: %10"PRIu64"\n", 162 stats.opackets, stats.oerrors, stats.obytes); 163 } 164 165 /* stats fdir */ 166 if (fdir_conf.mode != RTE_FDIR_MODE_NONE) 167 printf(" Fdirmiss: %-10"PRIu64" Fdirmatch: %-10"PRIu64"\n", 168 stats.fdirmiss, 169 stats.fdirmatch); 170 171 if (port->rx_queue_stats_mapping_enabled) { 172 printf("\n"); 173 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 174 printf(" Stats reg %2d RX-packets: %10"PRIu64 175 " RX-errors: %10"PRIu64 176 " RX-bytes: %10"PRIu64"\n", 177 i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]); 178 } 179 } 180 if (port->tx_queue_stats_mapping_enabled) { 181 printf("\n"); 182 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 183 printf(" Stats reg %2d TX-packets: %10"PRIu64 184 " TX-bytes: %10"PRIu64"\n", 185 i, stats.q_opackets[i], stats.q_obytes[i]); 186 } 187 } 188 189 /* Display statistics of XON/XOFF pause frames, if any. */ 190 if ((stats.tx_pause_xon | stats.rx_pause_xon | 191 stats.tx_pause_xoff | stats.rx_pause_xoff) > 0) { 192 printf(" RX-XOFF: %-10"PRIu64" RX-XON: %-10"PRIu64"\n", 193 stats.rx_pause_xoff, stats.rx_pause_xon); 194 printf(" TX-XOFF: %-10"PRIu64" TX-XON: %-10"PRIu64"\n", 195 stats.tx_pause_xoff, stats.tx_pause_xon); 196 } 197 printf(" %s############################%s\n", 198 nic_stats_border, nic_stats_border); 199 } 200 201 void 202 nic_stats_clear(portid_t port_id) 203 { 204 if (port_id >= nb_ports) { 205 printf("Invalid port, range is [0, %d]\n", nb_ports - 1); 206 return; 207 } 208 rte_eth_stats_reset(port_id); 209 printf("\n NIC statistics for port %d cleared\n", port_id); 210 } 211 212 void 213 nic_xstats_display(portid_t port_id) 214 { 215 struct rte_eth_xstats *xstats; 216 int len, ret, i; 217 218 printf("###### NIC extended statistics for port %-2d\n", port_id); 219 220 len = rte_eth_xstats_get(port_id, NULL, 0); 221 if (len < 0) { 222 printf("Cannot get xstats count\n"); 223 return; 224 } 225 xstats = malloc(sizeof(xstats[0]) * len); 226 if (xstats == NULL) { 227 printf("Cannot allocate memory for xstats\n"); 228 return; 229 } 230 ret = rte_eth_xstats_get(port_id, xstats, len); 231 if (ret < 0 || ret > len) { 232 printf("Cannot get xstats\n"); 233 free(xstats); 234 return; 235 } 236 for (i = 0; i < len; i++) 237 printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); 238 free(xstats); 239 } 240 241 void 242 nic_xstats_clear(portid_t port_id) 243 { 244 rte_eth_xstats_reset(port_id); 245 } 246 247 void 248 nic_stats_mapping_display(portid_t port_id) 249 { 250 struct rte_port *port = &ports[port_id]; 251 uint16_t i; 252 253 static const char *nic_stats_mapping_border = "########################"; 254 255 if (port_id >= nb_ports) { 256 printf("Invalid port, range is [0, %d]\n", nb_ports - 1); 257 return; 258 } 259 260 if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 261 printf("Port id %d - either does not support queue statistic mapping or" 262 " no queue statistic mapping set\n", port_id); 263 return; 264 } 265 266 printf("\n %s NIC statistics mapping for port %-2d %s\n", 267 nic_stats_mapping_border, port_id, nic_stats_mapping_border); 268 269 if (port->rx_queue_stats_mapping_enabled) { 270 for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 271 if (rx_queue_stats_mappings[i].port_id == port_id) { 272 printf(" RX-queue %2d mapped to Stats Reg %2d\n", 273 rx_queue_stats_mappings[i].queue_id, 274 rx_queue_stats_mappings[i].stats_counter_id); 275 } 276 } 277 printf("\n"); 278 } 279 280 281 if (port->tx_queue_stats_mapping_enabled) { 282 for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 283 if (tx_queue_stats_mappings[i].port_id == port_id) { 284 printf(" TX-queue %2d mapped to Stats Reg %2d\n", 285 tx_queue_stats_mappings[i].queue_id, 286 tx_queue_stats_mappings[i].stats_counter_id); 287 } 288 } 289 } 290 291 printf(" %s####################################%s\n", 292 nic_stats_mapping_border, nic_stats_mapping_border); 293 } 294 295 void 296 port_infos_display(portid_t port_id) 297 { 298 struct rte_port *port; 299 struct ether_addr mac_addr; 300 struct rte_eth_link link; 301 struct rte_eth_dev_info dev_info; 302 int vlan_offload; 303 struct rte_mempool * mp; 304 static const char *info_border = "*********************"; 305 306 if (port_id >= nb_ports) { 307 printf("Invalid port, range is [0, %d]\n", nb_ports - 1); 308 return; 309 } 310 port = &ports[port_id]; 311 rte_eth_link_get_nowait(port_id, &link); 312 printf("\n%s Infos for port %-2d %s\n", 313 info_border, port_id, info_border); 314 rte_eth_macaddr_get(port_id, &mac_addr); 315 print_ethaddr("MAC address: ", &mac_addr); 316 printf("\nConnect to socket: %u", port->socket_id); 317 318 if (port_numa[port_id] != NUMA_NO_CONFIG) { 319 mp = mbuf_pool_find(port_numa[port_id]); 320 if (mp) 321 printf("\nmemory allocation on the socket: %d", 322 port_numa[port_id]); 323 } else 324 printf("\nmemory allocation on the socket: %u",port->socket_id); 325 326 printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down")); 327 printf("Link speed: %u Mbps\n", (unsigned) link.link_speed); 328 printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 329 ("full-duplex") : ("half-duplex")); 330 printf("Promiscuous mode: %s\n", 331 rte_eth_promiscuous_get(port_id) ? "enabled" : "disabled"); 332 printf("Allmulticast mode: %s\n", 333 rte_eth_allmulticast_get(port_id) ? "enabled" : "disabled"); 334 printf("Maximum number of MAC addresses: %u\n", 335 (unsigned int)(port->dev_info.max_mac_addrs)); 336 printf("Maximum number of MAC addresses of hash filtering: %u\n", 337 (unsigned int)(port->dev_info.max_hash_mac_addrs)); 338 339 vlan_offload = rte_eth_dev_get_vlan_offload(port_id); 340 if (vlan_offload >= 0){ 341 printf("VLAN offload: \n"); 342 if (vlan_offload & ETH_VLAN_STRIP_OFFLOAD) 343 printf(" strip on \n"); 344 else 345 printf(" strip off \n"); 346 347 if (vlan_offload & ETH_VLAN_FILTER_OFFLOAD) 348 printf(" filter on \n"); 349 else 350 printf(" filter off \n"); 351 352 if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) 353 printf(" qinq(extend) on \n"); 354 else 355 printf(" qinq(extend) off \n"); 356 } 357 358 memset(&dev_info, 0, sizeof(dev_info)); 359 rte_eth_dev_info_get(port_id, &dev_info); 360 if (dev_info.reta_size > 0) 361 printf("Redirection table size: %u\n", dev_info.reta_size); 362 } 363 364 int 365 port_id_is_invalid(portid_t port_id) 366 { 367 if (port_id < nb_ports) 368 return 0; 369 printf("Invalid port %d (must be < nb_ports=%d)\n", port_id, nb_ports); 370 return 1; 371 } 372 373 static int 374 vlan_id_is_invalid(uint16_t vlan_id) 375 { 376 if (vlan_id < 4096) 377 return 0; 378 printf("Invalid vlan_id %d (must be < 4096)\n", vlan_id); 379 return 1; 380 } 381 382 static int 383 port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off) 384 { 385 uint64_t pci_len; 386 387 if (reg_off & 0x3) { 388 printf("Port register offset 0x%X not aligned on a 4-byte " 389 "boundary\n", 390 (unsigned)reg_off); 391 return 1; 392 } 393 pci_len = ports[port_id].dev_info.pci_dev->mem_resource[0].len; 394 if (reg_off >= pci_len) { 395 printf("Port %d: register offset %u (0x%X) out of port PCI " 396 "resource (length=%"PRIu64")\n", 397 port_id, (unsigned)reg_off, (unsigned)reg_off, pci_len); 398 return 1; 399 } 400 return 0; 401 } 402 403 static int 404 reg_bit_pos_is_invalid(uint8_t bit_pos) 405 { 406 if (bit_pos <= 31) 407 return 0; 408 printf("Invalid bit position %d (must be <= 31)\n", bit_pos); 409 return 1; 410 } 411 412 #define display_port_and_reg_off(port_id, reg_off) \ 413 printf("port %d PCI register at offset 0x%X: ", (port_id), (reg_off)) 414 415 static inline void 416 display_port_reg_value(portid_t port_id, uint32_t reg_off, uint32_t reg_v) 417 { 418 display_port_and_reg_off(port_id, (unsigned)reg_off); 419 printf("0x%08X (%u)\n", (unsigned)reg_v, (unsigned)reg_v); 420 } 421 422 void 423 port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x) 424 { 425 uint32_t reg_v; 426 427 428 if (port_id_is_invalid(port_id)) 429 return; 430 if (port_reg_off_is_invalid(port_id, reg_off)) 431 return; 432 if (reg_bit_pos_is_invalid(bit_x)) 433 return; 434 reg_v = port_id_pci_reg_read(port_id, reg_off); 435 display_port_and_reg_off(port_id, (unsigned)reg_off); 436 printf("bit %d=%d\n", bit_x, (int) ((reg_v & (1 << bit_x)) >> bit_x)); 437 } 438 439 void 440 port_reg_bit_field_display(portid_t port_id, uint32_t reg_off, 441 uint8_t bit1_pos, uint8_t bit2_pos) 442 { 443 uint32_t reg_v; 444 uint8_t l_bit; 445 uint8_t h_bit; 446 447 if (port_id_is_invalid(port_id)) 448 return; 449 if (port_reg_off_is_invalid(port_id, reg_off)) 450 return; 451 if (reg_bit_pos_is_invalid(bit1_pos)) 452 return; 453 if (reg_bit_pos_is_invalid(bit2_pos)) 454 return; 455 if (bit1_pos > bit2_pos) 456 l_bit = bit2_pos, h_bit = bit1_pos; 457 else 458 l_bit = bit1_pos, h_bit = bit2_pos; 459 460 reg_v = port_id_pci_reg_read(port_id, reg_off); 461 reg_v >>= l_bit; 462 if (h_bit < 31) 463 reg_v &= ((1 << (h_bit - l_bit + 1)) - 1); 464 display_port_and_reg_off(port_id, (unsigned)reg_off); 465 printf("bits[%d, %d]=0x%0*X (%u)\n", l_bit, h_bit, 466 ((h_bit - l_bit) / 4) + 1, (unsigned)reg_v, (unsigned)reg_v); 467 } 468 469 void 470 port_reg_display(portid_t port_id, uint32_t reg_off) 471 { 472 uint32_t reg_v; 473 474 if (port_id_is_invalid(port_id)) 475 return; 476 if (port_reg_off_is_invalid(port_id, reg_off)) 477 return; 478 reg_v = port_id_pci_reg_read(port_id, reg_off); 479 display_port_reg_value(port_id, reg_off, reg_v); 480 } 481 482 void 483 port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos, 484 uint8_t bit_v) 485 { 486 uint32_t reg_v; 487 488 if (port_id_is_invalid(port_id)) 489 return; 490 if (port_reg_off_is_invalid(port_id, reg_off)) 491 return; 492 if (reg_bit_pos_is_invalid(bit_pos)) 493 return; 494 if (bit_v > 1) { 495 printf("Invalid bit value %d (must be 0 or 1)\n", (int) bit_v); 496 return; 497 } 498 reg_v = port_id_pci_reg_read(port_id, reg_off); 499 if (bit_v == 0) 500 reg_v &= ~(1 << bit_pos); 501 else 502 reg_v |= (1 << bit_pos); 503 port_id_pci_reg_write(port_id, reg_off, reg_v); 504 display_port_reg_value(port_id, reg_off, reg_v); 505 } 506 507 void 508 port_reg_bit_field_set(portid_t port_id, uint32_t reg_off, 509 uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value) 510 { 511 uint32_t max_v; 512 uint32_t reg_v; 513 uint8_t l_bit; 514 uint8_t h_bit; 515 516 if (port_id_is_invalid(port_id)) 517 return; 518 if (port_reg_off_is_invalid(port_id, reg_off)) 519 return; 520 if (reg_bit_pos_is_invalid(bit1_pos)) 521 return; 522 if (reg_bit_pos_is_invalid(bit2_pos)) 523 return; 524 if (bit1_pos > bit2_pos) 525 l_bit = bit2_pos, h_bit = bit1_pos; 526 else 527 l_bit = bit1_pos, h_bit = bit2_pos; 528 529 if ((h_bit - l_bit) < 31) 530 max_v = (1 << (h_bit - l_bit + 1)) - 1; 531 else 532 max_v = 0xFFFFFFFF; 533 534 if (value > max_v) { 535 printf("Invalid value %u (0x%x) must be < %u (0x%x)\n", 536 (unsigned)value, (unsigned)value, 537 (unsigned)max_v, (unsigned)max_v); 538 return; 539 } 540 reg_v = port_id_pci_reg_read(port_id, reg_off); 541 reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */ 542 reg_v |= (value << l_bit); /* Set changed bits */ 543 port_id_pci_reg_write(port_id, reg_off, reg_v); 544 display_port_reg_value(port_id, reg_off, reg_v); 545 } 546 547 void 548 port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v) 549 { 550 if (port_id_is_invalid(port_id)) 551 return; 552 if (port_reg_off_is_invalid(port_id, reg_off)) 553 return; 554 port_id_pci_reg_write(port_id, reg_off, reg_v); 555 display_port_reg_value(port_id, reg_off, reg_v); 556 } 557 558 void 559 port_mtu_set(portid_t port_id, uint16_t mtu) 560 { 561 int diag; 562 563 if (port_id_is_invalid(port_id)) 564 return; 565 diag = rte_eth_dev_set_mtu(port_id, mtu); 566 if (diag == 0) 567 return; 568 printf("Set MTU failed. diag=%d\n", diag); 569 } 570 571 /* 572 * RX/TX ring descriptors display functions. 573 */ 574 int 575 rx_queue_id_is_invalid(queueid_t rxq_id) 576 { 577 if (rxq_id < nb_rxq) 578 return 0; 579 printf("Invalid RX queue %d (must be < nb_rxq=%d)\n", rxq_id, nb_rxq); 580 return 1; 581 } 582 583 int 584 tx_queue_id_is_invalid(queueid_t txq_id) 585 { 586 if (txq_id < nb_txq) 587 return 0; 588 printf("Invalid TX queue %d (must be < nb_rxq=%d)\n", txq_id, nb_txq); 589 return 1; 590 } 591 592 static int 593 rx_desc_id_is_invalid(uint16_t rxdesc_id) 594 { 595 if (rxdesc_id < nb_rxd) 596 return 0; 597 printf("Invalid RX descriptor %d (must be < nb_rxd=%d)\n", 598 rxdesc_id, nb_rxd); 599 return 1; 600 } 601 602 static int 603 tx_desc_id_is_invalid(uint16_t txdesc_id) 604 { 605 if (txdesc_id < nb_txd) 606 return 0; 607 printf("Invalid TX descriptor %d (must be < nb_txd=%d)\n", 608 txdesc_id, nb_txd); 609 return 1; 610 } 611 612 static const struct rte_memzone * 613 ring_dma_zone_lookup(const char *ring_name, uint8_t port_id, uint16_t q_id) 614 { 615 char mz_name[RTE_MEMZONE_NAMESIZE]; 616 const struct rte_memzone *mz; 617 618 snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d", 619 ports[port_id].dev_info.driver_name, ring_name, port_id, q_id); 620 mz = rte_memzone_lookup(mz_name); 621 if (mz == NULL) 622 printf("%s ring memory zoneof (port %d, queue %d) not" 623 "found (zone name = %s\n", 624 ring_name, port_id, q_id, mz_name); 625 return (mz); 626 } 627 628 union igb_ring_dword { 629 uint64_t dword; 630 struct { 631 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 632 uint32_t lo; 633 uint32_t hi; 634 #else 635 uint32_t hi; 636 uint32_t lo; 637 #endif 638 } words; 639 }; 640 641 struct igb_ring_desc_32_bytes { 642 union igb_ring_dword lo_dword; 643 union igb_ring_dword hi_dword; 644 union igb_ring_dword resv1; 645 union igb_ring_dword resv2; 646 }; 647 648 struct igb_ring_desc_16_bytes { 649 union igb_ring_dword lo_dword; 650 union igb_ring_dword hi_dword; 651 }; 652 653 static void 654 ring_rxd_display_dword(union igb_ring_dword dword) 655 { 656 printf(" 0x%08X - 0x%08X\n", (unsigned)dword.words.lo, 657 (unsigned)dword.words.hi); 658 } 659 660 static void 661 ring_rx_descriptor_display(const struct rte_memzone *ring_mz, 662 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC 663 uint8_t port_id, 664 #else 665 __rte_unused uint8_t port_id, 666 #endif 667 uint16_t desc_id) 668 { 669 struct igb_ring_desc_16_bytes *ring = 670 (struct igb_ring_desc_16_bytes *)ring_mz->addr; 671 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC 672 struct rte_eth_dev_info dev_info; 673 674 memset(&dev_info, 0, sizeof(dev_info)); 675 rte_eth_dev_info_get(port_id, &dev_info); 676 if (strstr(dev_info.driver_name, "i40e") != NULL) { 677 /* 32 bytes RX descriptor, i40e only */ 678 struct igb_ring_desc_32_bytes *ring = 679 (struct igb_ring_desc_32_bytes *)ring_mz->addr; 680 ring[desc_id].lo_dword.dword = 681 rte_le_to_cpu_64(ring[desc_id].lo_dword.dword); 682 ring_rxd_display_dword(ring[desc_id].lo_dword); 683 ring[desc_id].hi_dword.dword = 684 rte_le_to_cpu_64(ring[desc_id].hi_dword.dword); 685 ring_rxd_display_dword(ring[desc_id].hi_dword); 686 ring[desc_id].resv1.dword = 687 rte_le_to_cpu_64(ring[desc_id].resv1.dword); 688 ring_rxd_display_dword(ring[desc_id].resv1); 689 ring[desc_id].resv2.dword = 690 rte_le_to_cpu_64(ring[desc_id].resv2.dword); 691 ring_rxd_display_dword(ring[desc_id].resv2); 692 693 return; 694 } 695 #endif 696 /* 16 bytes RX descriptor */ 697 ring[desc_id].lo_dword.dword = 698 rte_le_to_cpu_64(ring[desc_id].lo_dword.dword); 699 ring_rxd_display_dword(ring[desc_id].lo_dword); 700 ring[desc_id].hi_dword.dword = 701 rte_le_to_cpu_64(ring[desc_id].hi_dword.dword); 702 ring_rxd_display_dword(ring[desc_id].hi_dword); 703 } 704 705 static void 706 ring_tx_descriptor_display(const struct rte_memzone *ring_mz, uint16_t desc_id) 707 { 708 struct igb_ring_desc_16_bytes *ring; 709 struct igb_ring_desc_16_bytes txd; 710 711 ring = (struct igb_ring_desc_16_bytes *)ring_mz->addr; 712 txd.lo_dword.dword = rte_le_to_cpu_64(ring[desc_id].lo_dword.dword); 713 txd.hi_dword.dword = rte_le_to_cpu_64(ring[desc_id].hi_dword.dword); 714 printf(" 0x%08X - 0x%08X / 0x%08X - 0x%08X\n", 715 (unsigned)txd.lo_dword.words.lo, 716 (unsigned)txd.lo_dword.words.hi, 717 (unsigned)txd.hi_dword.words.lo, 718 (unsigned)txd.hi_dword.words.hi); 719 } 720 721 void 722 rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id) 723 { 724 const struct rte_memzone *rx_mz; 725 726 if (port_id_is_invalid(port_id)) 727 return; 728 if (rx_queue_id_is_invalid(rxq_id)) 729 return; 730 if (rx_desc_id_is_invalid(rxd_id)) 731 return; 732 rx_mz = ring_dma_zone_lookup("rx_ring", port_id, rxq_id); 733 if (rx_mz == NULL) 734 return; 735 ring_rx_descriptor_display(rx_mz, port_id, rxd_id); 736 } 737 738 void 739 tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id) 740 { 741 const struct rte_memzone *tx_mz; 742 743 if (port_id_is_invalid(port_id)) 744 return; 745 if (tx_queue_id_is_invalid(txq_id)) 746 return; 747 if (tx_desc_id_is_invalid(txd_id)) 748 return; 749 tx_mz = ring_dma_zone_lookup("tx_ring", port_id, txq_id); 750 if (tx_mz == NULL) 751 return; 752 ring_tx_descriptor_display(tx_mz, txd_id); 753 } 754 755 void 756 fwd_lcores_config_display(void) 757 { 758 lcoreid_t lc_id; 759 760 printf("List of forwarding lcores:"); 761 for (lc_id = 0; lc_id < nb_cfg_lcores; lc_id++) 762 printf(" %2u", fwd_lcores_cpuids[lc_id]); 763 printf("\n"); 764 } 765 void 766 rxtx_config_display(void) 767 { 768 printf(" %s packet forwarding - CRC stripping %s - " 769 "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name, 770 rx_mode.hw_strip_crc ? "enabled" : "disabled", 771 nb_pkt_per_burst); 772 773 if (cur_fwd_eng == &tx_only_engine) 774 printf(" packet len=%u - nb packet segments=%d\n", 775 (unsigned)tx_pkt_length, (int) tx_pkt_nb_segs); 776 777 printf(" nb forwarding cores=%d - nb forwarding ports=%d\n", 778 nb_fwd_lcores, nb_fwd_ports); 779 printf(" RX queues=%d - RX desc=%d - RX free threshold=%d\n", 780 nb_rxq, nb_rxd, rx_free_thresh); 781 printf(" RX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n", 782 rx_thresh.pthresh, rx_thresh.hthresh, rx_thresh.wthresh); 783 printf(" TX queues=%d - TX desc=%d - TX free threshold=%d\n", 784 nb_txq, nb_txd, tx_free_thresh); 785 printf(" TX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n", 786 tx_thresh.pthresh, tx_thresh.hthresh, tx_thresh.wthresh); 787 printf(" TX RS bit threshold=%d - TXQ flags=0x%"PRIx32"\n", 788 tx_rs_thresh, txq_flags); 789 } 790 791 void 792 port_rss_reta_info(portid_t port_id, 793 struct rte_eth_rss_reta_entry64 *reta_conf, 794 uint16_t nb_entries) 795 { 796 uint16_t i, idx, shift; 797 int ret; 798 799 if (port_id_is_invalid(port_id)) 800 return; 801 802 ret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries); 803 if (ret != 0) { 804 printf("Failed to get RSS RETA info, return code = %d\n", ret); 805 return; 806 } 807 808 for (i = 0; i < nb_entries; i++) { 809 idx = i / RTE_RETA_GROUP_SIZE; 810 shift = i % RTE_RETA_GROUP_SIZE; 811 if (!(reta_conf[idx].mask & (1ULL << shift))) 812 continue; 813 printf("RSS RETA configuration: hash index=%u, queue=%u\n", 814 i, reta_conf[idx].reta[shift]); 815 } 816 } 817 818 /* 819 * Displays the RSS hash functions of a port, and, optionaly, the RSS hash 820 * key of the port. 821 */ 822 void 823 port_rss_hash_conf_show(portid_t port_id, int show_rss_key) 824 { 825 struct rte_eth_rss_conf rss_conf; 826 uint8_t rss_key[10 * 4]; 827 uint64_t rss_hf; 828 uint8_t i; 829 int diag; 830 831 if (port_id_is_invalid(port_id)) 832 return; 833 /* Get RSS hash key if asked to display it */ 834 rss_conf.rss_key = (show_rss_key) ? rss_key : NULL; 835 diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf); 836 if (diag != 0) { 837 switch (diag) { 838 case -ENODEV: 839 printf("port index %d invalid\n", port_id); 840 break; 841 case -ENOTSUP: 842 printf("operation not supported by device\n"); 843 break; 844 default: 845 printf("operation failed - diag=%d\n", diag); 846 break; 847 } 848 return; 849 } 850 rss_hf = rss_conf.rss_hf; 851 if (rss_hf == 0) { 852 printf("RSS disabled\n"); 853 return; 854 } 855 printf("RSS functions:\n "); 856 if (rss_hf & ETH_RSS_IPV4) 857 printf("ip4"); 858 if (rss_hf & ETH_RSS_IPV4_TCP) 859 printf(" tcp4"); 860 if (rss_hf & ETH_RSS_IPV4_UDP) 861 printf(" udp4"); 862 if (rss_hf & ETH_RSS_IPV6) 863 printf(" ip6"); 864 if (rss_hf & ETH_RSS_IPV6_EX) 865 printf(" ip6-ex"); 866 if (rss_hf & ETH_RSS_IPV6_TCP) 867 printf(" tcp6"); 868 if (rss_hf & ETH_RSS_IPV6_TCP_EX) 869 printf(" tcp6-ex"); 870 if (rss_hf & ETH_RSS_IPV6_UDP) 871 printf(" udp6"); 872 if (rss_hf & ETH_RSS_IPV6_UDP_EX) 873 printf(" udp6-ex"); 874 printf("\n"); 875 if (!show_rss_key) 876 return; 877 printf("RSS key:\n"); 878 for (i = 0; i < sizeof(rss_key); i++) 879 printf("%02X", rss_key[i]); 880 printf("\n"); 881 } 882 883 void 884 port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key) 885 { 886 struct rte_eth_rss_conf rss_conf; 887 int diag; 888 889 rss_conf.rss_key = NULL; 890 diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf); 891 if (diag == 0) { 892 rss_conf.rss_key = hash_key; 893 diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf); 894 } 895 if (diag == 0) 896 return; 897 898 switch (diag) { 899 case -ENODEV: 900 printf("port index %d invalid\n", port_id); 901 break; 902 case -ENOTSUP: 903 printf("operation not supported by device\n"); 904 break; 905 default: 906 printf("operation failed - diag=%d\n", diag); 907 break; 908 } 909 } 910 911 /* 912 * Setup forwarding configuration for each logical core. 913 */ 914 static void 915 setup_fwd_config_of_each_lcore(struct fwd_config *cfg) 916 { 917 streamid_t nb_fs_per_lcore; 918 streamid_t nb_fs; 919 streamid_t sm_id; 920 lcoreid_t nb_extra; 921 lcoreid_t nb_fc; 922 lcoreid_t nb_lc; 923 lcoreid_t lc_id; 924 925 nb_fs = cfg->nb_fwd_streams; 926 nb_fc = cfg->nb_fwd_lcores; 927 if (nb_fs <= nb_fc) { 928 nb_fs_per_lcore = 1; 929 nb_extra = 0; 930 } else { 931 nb_fs_per_lcore = (streamid_t) (nb_fs / nb_fc); 932 nb_extra = (lcoreid_t) (nb_fs % nb_fc); 933 } 934 935 nb_lc = (lcoreid_t) (nb_fc - nb_extra); 936 sm_id = 0; 937 for (lc_id = 0; lc_id < nb_lc; lc_id++) { 938 fwd_lcores[lc_id]->stream_idx = sm_id; 939 fwd_lcores[lc_id]->stream_nb = nb_fs_per_lcore; 940 sm_id = (streamid_t) (sm_id + nb_fs_per_lcore); 941 } 942 943 /* 944 * Assign extra remaining streams, if any. 945 */ 946 nb_fs_per_lcore = (streamid_t) (nb_fs_per_lcore + 1); 947 for (lc_id = 0; lc_id < nb_extra; lc_id++) { 948 fwd_lcores[nb_lc + lc_id]->stream_idx = sm_id; 949 fwd_lcores[nb_lc + lc_id]->stream_nb = nb_fs_per_lcore; 950 sm_id = (streamid_t) (sm_id + nb_fs_per_lcore); 951 } 952 } 953 954 static void 955 simple_fwd_config_setup(void) 956 { 957 portid_t i; 958 portid_t j; 959 portid_t inc = 2; 960 961 if (port_topology == PORT_TOPOLOGY_CHAINED || 962 port_topology == PORT_TOPOLOGY_LOOP) { 963 inc = 1; 964 } else if (nb_fwd_ports % 2) { 965 printf("\nWarning! Cannot handle an odd number of ports " 966 "with the current port topology. Configuration " 967 "must be changed to have an even number of ports, " 968 "or relaunch application with " 969 "--port-topology=chained\n\n"); 970 } 971 972 cur_fwd_config.nb_fwd_ports = (portid_t) nb_fwd_ports; 973 cur_fwd_config.nb_fwd_streams = 974 (streamid_t) cur_fwd_config.nb_fwd_ports; 975 976 /* reinitialize forwarding streams */ 977 init_fwd_streams(); 978 979 /* 980 * In the simple forwarding test, the number of forwarding cores 981 * must be lower or equal to the number of forwarding ports. 982 */ 983 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; 984 if (cur_fwd_config.nb_fwd_lcores > cur_fwd_config.nb_fwd_ports) 985 cur_fwd_config.nb_fwd_lcores = 986 (lcoreid_t) cur_fwd_config.nb_fwd_ports; 987 setup_fwd_config_of_each_lcore(&cur_fwd_config); 988 989 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i = (portid_t) (i + inc)) { 990 if (port_topology != PORT_TOPOLOGY_LOOP) 991 j = (portid_t) ((i + 1) % cur_fwd_config.nb_fwd_ports); 992 else 993 j = i; 994 fwd_streams[i]->rx_port = fwd_ports_ids[i]; 995 fwd_streams[i]->rx_queue = 0; 996 fwd_streams[i]->tx_port = fwd_ports_ids[j]; 997 fwd_streams[i]->tx_queue = 0; 998 fwd_streams[i]->peer_addr = j; 999 1000 if (port_topology == PORT_TOPOLOGY_PAIRED) { 1001 fwd_streams[j]->rx_port = fwd_ports_ids[j]; 1002 fwd_streams[j]->rx_queue = 0; 1003 fwd_streams[j]->tx_port = fwd_ports_ids[i]; 1004 fwd_streams[j]->tx_queue = 0; 1005 fwd_streams[j]->peer_addr = i; 1006 } 1007 } 1008 } 1009 1010 /** 1011 * For the RSS forwarding test, each core is assigned on every port a transmit 1012 * queue whose index is the index of the core itself. This approach limits the 1013 * maximumm number of processing cores of the RSS test to the maximum number of 1014 * TX queues supported by the devices. 1015 * 1016 * Each core is assigned a single stream, each stream being composed of 1017 * a RX queue to poll on a RX port for input messages, associated with 1018 * a TX queue of a TX port where to send forwarded packets. 1019 * All packets received on the RX queue of index "RxQj" of the RX port "RxPi" 1020 * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two 1021 * following rules: 1022 * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd 1023 * - TxQl = RxQj 1024 */ 1025 static void 1026 rss_fwd_config_setup(void) 1027 { 1028 portid_t rxp; 1029 portid_t txp; 1030 queueid_t rxq; 1031 queueid_t nb_q; 1032 lcoreid_t lc_id; 1033 1034 nb_q = nb_rxq; 1035 if (nb_q > nb_txq) 1036 nb_q = nb_txq; 1037 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; 1038 cur_fwd_config.nb_fwd_ports = nb_fwd_ports; 1039 cur_fwd_config.nb_fwd_streams = 1040 (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports); 1041 if (cur_fwd_config.nb_fwd_streams > cur_fwd_config.nb_fwd_lcores) 1042 cur_fwd_config.nb_fwd_streams = 1043 (streamid_t)cur_fwd_config.nb_fwd_lcores; 1044 else 1045 cur_fwd_config.nb_fwd_lcores = 1046 (lcoreid_t)cur_fwd_config.nb_fwd_streams; 1047 1048 /* reinitialize forwarding streams */ 1049 init_fwd_streams(); 1050 1051 setup_fwd_config_of_each_lcore(&cur_fwd_config); 1052 rxp = 0; rxq = 0; 1053 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) { 1054 struct fwd_stream *fs; 1055 1056 fs = fwd_streams[lc_id]; 1057 1058 if ((rxp & 0x1) == 0) 1059 txp = (portid_t) (rxp + 1); 1060 else 1061 txp = (portid_t) (rxp - 1); 1062 /* 1063 * if we are in loopback, simply send stuff out through the 1064 * ingress port 1065 */ 1066 if (port_topology == PORT_TOPOLOGY_LOOP) 1067 txp = rxp; 1068 1069 fs->rx_port = fwd_ports_ids[rxp]; 1070 fs->rx_queue = rxq; 1071 fs->tx_port = fwd_ports_ids[txp]; 1072 fs->tx_queue = rxq; 1073 fs->peer_addr = fs->tx_port; 1074 rxq = (queueid_t) (rxq + 1); 1075 if (rxq < nb_q) 1076 continue; 1077 /* 1078 * rxq == nb_q 1079 * Restart from RX queue 0 on next RX port 1080 */ 1081 rxq = 0; 1082 if (numa_support && (nb_fwd_ports <= (nb_ports >> 1))) 1083 rxp = (portid_t) 1084 (rxp + ((nb_ports >> 1) / nb_fwd_ports)); 1085 else 1086 rxp = (portid_t) (rxp + 1); 1087 } 1088 } 1089 1090 /* 1091 * In DCB and VT on,the mapping of 128 receive queues to 128 transmit queues. 1092 */ 1093 static void 1094 dcb_rxq_2_txq_mapping(queueid_t rxq, queueid_t *txq) 1095 { 1096 if(dcb_q_mapping == DCB_4_TCS_Q_MAPPING) { 1097 1098 if (rxq < 32) 1099 /* tc0: 0-31 */ 1100 *txq = rxq; 1101 else if (rxq < 64) { 1102 /* tc1: 64-95 */ 1103 *txq = (uint16_t)(rxq + 32); 1104 } 1105 else { 1106 /* tc2: 96-111;tc3:112-127 */ 1107 *txq = (uint16_t)(rxq/2 + 64); 1108 } 1109 } 1110 else { 1111 if (rxq < 16) 1112 /* tc0 mapping*/ 1113 *txq = rxq; 1114 else if (rxq < 32) { 1115 /* tc1 mapping*/ 1116 *txq = (uint16_t)(rxq + 16); 1117 } 1118 else if (rxq < 64) { 1119 /*tc2,tc3 mapping */ 1120 *txq = (uint16_t)(rxq + 32); 1121 } 1122 else { 1123 /* tc4,tc5,tc6 and tc7 mapping */ 1124 *txq = (uint16_t)(rxq/2 + 64); 1125 } 1126 } 1127 } 1128 1129 /** 1130 * For the DCB forwarding test, each core is assigned on every port multi-transmit 1131 * queue. 1132 * 1133 * Each core is assigned a multi-stream, each stream being composed of 1134 * a RX queue to poll on a RX port for input messages, associated with 1135 * a TX queue of a TX port where to send forwarded packets. 1136 * All packets received on the RX queue of index "RxQj" of the RX port "RxPi" 1137 * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two 1138 * following rules: 1139 * In VT mode, 1140 * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd 1141 * - TxQl = RxQj 1142 * In non-VT mode, 1143 * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd 1144 * There is a mapping of RxQj to TxQl to be required,and the mapping was implemented 1145 * in dcb_rxq_2_txq_mapping function. 1146 */ 1147 static void 1148 dcb_fwd_config_setup(void) 1149 { 1150 portid_t rxp; 1151 portid_t txp; 1152 queueid_t rxq; 1153 queueid_t nb_q; 1154 lcoreid_t lc_id; 1155 uint16_t sm_id; 1156 1157 nb_q = nb_rxq; 1158 1159 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; 1160 cur_fwd_config.nb_fwd_ports = nb_fwd_ports; 1161 cur_fwd_config.nb_fwd_streams = 1162 (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports); 1163 1164 /* reinitialize forwarding streams */ 1165 init_fwd_streams(); 1166 1167 setup_fwd_config_of_each_lcore(&cur_fwd_config); 1168 rxp = 0; rxq = 0; 1169 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) { 1170 /* a fwd core can run multi-streams */ 1171 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) 1172 { 1173 struct fwd_stream *fs; 1174 fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id]; 1175 if ((rxp & 0x1) == 0) 1176 txp = (portid_t) (rxp + 1); 1177 else 1178 txp = (portid_t) (rxp - 1); 1179 fs->rx_port = fwd_ports_ids[rxp]; 1180 fs->rx_queue = rxq; 1181 fs->tx_port = fwd_ports_ids[txp]; 1182 if (dcb_q_mapping == DCB_VT_Q_MAPPING) 1183 fs->tx_queue = rxq; 1184 else 1185 dcb_rxq_2_txq_mapping(rxq, &fs->tx_queue); 1186 fs->peer_addr = fs->tx_port; 1187 rxq = (queueid_t) (rxq + 1); 1188 if (rxq < nb_q) 1189 continue; 1190 rxq = 0; 1191 if (numa_support && (nb_fwd_ports <= (nb_ports >> 1))) 1192 rxp = (portid_t) 1193 (rxp + ((nb_ports >> 1) / nb_fwd_ports)); 1194 else 1195 rxp = (portid_t) (rxp + 1); 1196 } 1197 } 1198 } 1199 1200 static void 1201 icmp_echo_config_setup(void) 1202 { 1203 portid_t rxp; 1204 queueid_t rxq; 1205 lcoreid_t lc_id; 1206 uint16_t sm_id; 1207 1208 if ((nb_txq * nb_fwd_ports) < nb_fwd_lcores) 1209 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) 1210 (nb_txq * nb_fwd_ports); 1211 else 1212 cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; 1213 cur_fwd_config.nb_fwd_ports = nb_fwd_ports; 1214 cur_fwd_config.nb_fwd_streams = 1215 (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports); 1216 if (cur_fwd_config.nb_fwd_streams < cur_fwd_config.nb_fwd_lcores) 1217 cur_fwd_config.nb_fwd_lcores = 1218 (lcoreid_t)cur_fwd_config.nb_fwd_streams; 1219 if (verbose_level > 0) { 1220 printf("%s fwd_cores=%d fwd_ports=%d fwd_streams=%d\n", 1221 __FUNCTION__, 1222 cur_fwd_config.nb_fwd_lcores, 1223 cur_fwd_config.nb_fwd_ports, 1224 cur_fwd_config.nb_fwd_streams); 1225 } 1226 1227 /* reinitialize forwarding streams */ 1228 init_fwd_streams(); 1229 setup_fwd_config_of_each_lcore(&cur_fwd_config); 1230 rxp = 0; rxq = 0; 1231 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) { 1232 if (verbose_level > 0) 1233 printf(" core=%d: \n", lc_id); 1234 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) { 1235 struct fwd_stream *fs; 1236 fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id]; 1237 fs->rx_port = fwd_ports_ids[rxp]; 1238 fs->rx_queue = rxq; 1239 fs->tx_port = fs->rx_port; 1240 fs->tx_queue = lc_id; 1241 fs->peer_addr = fs->tx_port; 1242 if (verbose_level > 0) 1243 printf(" stream=%d port=%d rxq=%d txq=%d\n", 1244 sm_id, fs->rx_port, fs->rx_queue, 1245 fs->tx_queue); 1246 rxq = (queueid_t) (rxq + 1); 1247 if (rxq == nb_rxq) { 1248 rxq = 0; 1249 rxp = (portid_t) (rxp + 1); 1250 } 1251 } 1252 } 1253 } 1254 1255 void 1256 fwd_config_setup(void) 1257 { 1258 cur_fwd_config.fwd_eng = cur_fwd_eng; 1259 if (strcmp(cur_fwd_eng->fwd_mode_name, "icmpecho") == 0) { 1260 icmp_echo_config_setup(); 1261 return; 1262 } 1263 if ((nb_rxq > 1) && (nb_txq > 1)){ 1264 if (dcb_config) 1265 dcb_fwd_config_setup(); 1266 else 1267 rss_fwd_config_setup(); 1268 } 1269 else 1270 simple_fwd_config_setup(); 1271 } 1272 1273 static void 1274 pkt_fwd_config_display(struct fwd_config *cfg) 1275 { 1276 struct fwd_stream *fs; 1277 lcoreid_t lc_id; 1278 streamid_t sm_id; 1279 1280 printf("%s packet forwarding - ports=%d - cores=%d - streams=%d - " 1281 "NUMA support %s, MP over anonymous pages %s\n", 1282 cfg->fwd_eng->fwd_mode_name, 1283 cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams, 1284 numa_support == 1 ? "enabled" : "disabled", 1285 mp_anon != 0 ? "enabled" : "disabled"); 1286 1287 if (strcmp(cfg->fwd_eng->fwd_mode_name, "mac_retry") == 0) 1288 printf("TX retry num: %u, delay between TX retries: %uus\n", 1289 burst_tx_retry_num, burst_tx_delay_time); 1290 for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) { 1291 printf("Logical Core %u (socket %u) forwards packets on " 1292 "%d streams:", 1293 fwd_lcores_cpuids[lc_id], 1294 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]), 1295 fwd_lcores[lc_id]->stream_nb); 1296 for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) { 1297 fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id]; 1298 printf("\n RX P=%d/Q=%d (socket %u) -> TX " 1299 "P=%d/Q=%d (socket %u) ", 1300 fs->rx_port, fs->rx_queue, 1301 ports[fs->rx_port].socket_id, 1302 fs->tx_port, fs->tx_queue, 1303 ports[fs->tx_port].socket_id); 1304 print_ethaddr("peer=", 1305 &peer_eth_addrs[fs->peer_addr]); 1306 } 1307 printf("\n"); 1308 } 1309 printf("\n"); 1310 } 1311 1312 1313 void 1314 fwd_config_display(void) 1315 { 1316 if((dcb_config) && (nb_fwd_lcores == 1)) { 1317 printf("In DCB mode,the nb forwarding cores should be larger than 1\n"); 1318 return; 1319 } 1320 fwd_config_setup(); 1321 pkt_fwd_config_display(&cur_fwd_config); 1322 } 1323 1324 int 1325 set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc) 1326 { 1327 unsigned int i; 1328 unsigned int lcore_cpuid; 1329 int record_now; 1330 1331 record_now = 0; 1332 again: 1333 for (i = 0; i < nb_lc; i++) { 1334 lcore_cpuid = lcorelist[i]; 1335 if (! rte_lcore_is_enabled(lcore_cpuid)) { 1336 printf("lcore %u not enabled\n", lcore_cpuid); 1337 return -1; 1338 } 1339 if (lcore_cpuid == rte_get_master_lcore()) { 1340 printf("lcore %u cannot be masked on for running " 1341 "packet forwarding, which is the master lcore " 1342 "and reserved for command line parsing only\n", 1343 lcore_cpuid); 1344 return -1; 1345 } 1346 if (record_now) 1347 fwd_lcores_cpuids[i] = lcore_cpuid; 1348 } 1349 if (record_now == 0) { 1350 record_now = 1; 1351 goto again; 1352 } 1353 nb_cfg_lcores = (lcoreid_t) nb_lc; 1354 if (nb_fwd_lcores != (lcoreid_t) nb_lc) { 1355 printf("previous number of forwarding cores %u - changed to " 1356 "number of configured cores %u\n", 1357 (unsigned int) nb_fwd_lcores, nb_lc); 1358 nb_fwd_lcores = (lcoreid_t) nb_lc; 1359 } 1360 1361 return 0; 1362 } 1363 1364 int 1365 set_fwd_lcores_mask(uint64_t lcoremask) 1366 { 1367 unsigned int lcorelist[64]; 1368 unsigned int nb_lc; 1369 unsigned int i; 1370 1371 if (lcoremask == 0) { 1372 printf("Invalid NULL mask of cores\n"); 1373 return -1; 1374 } 1375 nb_lc = 0; 1376 for (i = 0; i < 64; i++) { 1377 if (! ((uint64_t)(1ULL << i) & lcoremask)) 1378 continue; 1379 lcorelist[nb_lc++] = i; 1380 } 1381 return set_fwd_lcores_list(lcorelist, nb_lc); 1382 } 1383 1384 void 1385 set_fwd_lcores_number(uint16_t nb_lc) 1386 { 1387 if (nb_lc > nb_cfg_lcores) { 1388 printf("nb fwd cores %u > %u (max. number of configured " 1389 "lcores) - ignored\n", 1390 (unsigned int) nb_lc, (unsigned int) nb_cfg_lcores); 1391 return; 1392 } 1393 nb_fwd_lcores = (lcoreid_t) nb_lc; 1394 printf("Number of forwarding cores set to %u\n", 1395 (unsigned int) nb_fwd_lcores); 1396 } 1397 1398 void 1399 set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt) 1400 { 1401 unsigned int i; 1402 portid_t port_id; 1403 int record_now; 1404 1405 record_now = 0; 1406 again: 1407 for (i = 0; i < nb_pt; i++) { 1408 port_id = (portid_t) portlist[i]; 1409 if (port_id >= nb_ports) { 1410 printf("Invalid port id %u >= %u\n", 1411 (unsigned int) port_id, 1412 (unsigned int) nb_ports); 1413 return; 1414 } 1415 if (record_now) 1416 fwd_ports_ids[i] = port_id; 1417 } 1418 if (record_now == 0) { 1419 record_now = 1; 1420 goto again; 1421 } 1422 nb_cfg_ports = (portid_t) nb_pt; 1423 if (nb_fwd_ports != (portid_t) nb_pt) { 1424 printf("previous number of forwarding ports %u - changed to " 1425 "number of configured ports %u\n", 1426 (unsigned int) nb_fwd_ports, nb_pt); 1427 nb_fwd_ports = (portid_t) nb_pt; 1428 } 1429 } 1430 1431 void 1432 set_fwd_ports_mask(uint64_t portmask) 1433 { 1434 unsigned int portlist[64]; 1435 unsigned int nb_pt; 1436 unsigned int i; 1437 1438 if (portmask == 0) { 1439 printf("Invalid NULL mask of ports\n"); 1440 return; 1441 } 1442 nb_pt = 0; 1443 for (i = 0; i < (unsigned)RTE_MIN(64, RTE_MAX_ETHPORTS); i++) { 1444 if (! ((uint64_t)(1ULL << i) & portmask)) 1445 continue; 1446 portlist[nb_pt++] = i; 1447 } 1448 set_fwd_ports_list(portlist, nb_pt); 1449 } 1450 1451 void 1452 set_fwd_ports_number(uint16_t nb_pt) 1453 { 1454 if (nb_pt > nb_cfg_ports) { 1455 printf("nb fwd ports %u > %u (number of configured " 1456 "ports) - ignored\n", 1457 (unsigned int) nb_pt, (unsigned int) nb_cfg_ports); 1458 return; 1459 } 1460 nb_fwd_ports = (portid_t) nb_pt; 1461 printf("Number of forwarding ports set to %u\n", 1462 (unsigned int) nb_fwd_ports); 1463 } 1464 1465 void 1466 set_nb_pkt_per_burst(uint16_t nb) 1467 { 1468 if (nb > MAX_PKT_BURST) { 1469 printf("nb pkt per burst: %u > %u (maximum packet per burst) " 1470 " ignored\n", 1471 (unsigned int) nb, (unsigned int) MAX_PKT_BURST); 1472 return; 1473 } 1474 nb_pkt_per_burst = nb; 1475 printf("Number of packets per burst set to %u\n", 1476 (unsigned int) nb_pkt_per_burst); 1477 } 1478 1479 void 1480 set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs) 1481 { 1482 uint16_t tx_pkt_len; 1483 unsigned i; 1484 1485 if (nb_segs >= (unsigned) nb_txd) { 1486 printf("nb segments per TX packets=%u >= nb_txd=%u - ignored\n", 1487 nb_segs, (unsigned int) nb_txd); 1488 return; 1489 } 1490 1491 /* 1492 * Check that each segment length is greater or equal than 1493 * the mbuf data sise. 1494 * Check also that the total packet length is greater or equal than the 1495 * size of an empty UDP/IP packet (sizeof(struct ether_hdr) + 20 + 8). 1496 */ 1497 tx_pkt_len = 0; 1498 for (i = 0; i < nb_segs; i++) { 1499 if (seg_lengths[i] > (unsigned) mbuf_data_size) { 1500 printf("length[%u]=%u > mbuf_data_size=%u - give up\n", 1501 i, seg_lengths[i], (unsigned) mbuf_data_size); 1502 return; 1503 } 1504 tx_pkt_len = (uint16_t)(tx_pkt_len + seg_lengths[i]); 1505 } 1506 if (tx_pkt_len < (sizeof(struct ether_hdr) + 20 + 8)) { 1507 printf("total packet length=%u < %d - give up\n", 1508 (unsigned) tx_pkt_len, 1509 (int)(sizeof(struct ether_hdr) + 20 + 8)); 1510 return; 1511 } 1512 1513 for (i = 0; i < nb_segs; i++) 1514 tx_pkt_seg_lengths[i] = (uint16_t) seg_lengths[i]; 1515 1516 tx_pkt_length = tx_pkt_len; 1517 tx_pkt_nb_segs = (uint8_t) nb_segs; 1518 } 1519 1520 char* 1521 list_pkt_forwarding_modes(void) 1522 { 1523 static char fwd_modes[128] = ""; 1524 const char *separator = "|"; 1525 struct fwd_engine *fwd_eng; 1526 unsigned i = 0; 1527 1528 if (strlen (fwd_modes) == 0) { 1529 while ((fwd_eng = fwd_engines[i++]) != NULL) { 1530 strcat(fwd_modes, fwd_eng->fwd_mode_name); 1531 strcat(fwd_modes, separator); 1532 } 1533 fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0'; 1534 } 1535 1536 return fwd_modes; 1537 } 1538 1539 void 1540 set_pkt_forwarding_mode(const char *fwd_mode_name) 1541 { 1542 struct fwd_engine *fwd_eng; 1543 unsigned i; 1544 1545 i = 0; 1546 while ((fwd_eng = fwd_engines[i]) != NULL) { 1547 if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) { 1548 printf("Set %s packet forwarding mode\n", 1549 fwd_mode_name); 1550 cur_fwd_eng = fwd_eng; 1551 return; 1552 } 1553 i++; 1554 } 1555 printf("Invalid %s packet forwarding mode\n", fwd_mode_name); 1556 } 1557 1558 void 1559 set_verbose_level(uint16_t vb_level) 1560 { 1561 printf("Change verbose level from %u to %u\n", 1562 (unsigned int) verbose_level, (unsigned int) vb_level); 1563 verbose_level = vb_level; 1564 } 1565 1566 void 1567 vlan_extend_set(portid_t port_id, int on) 1568 { 1569 int diag; 1570 int vlan_offload; 1571 1572 if (port_id_is_invalid(port_id)) 1573 return; 1574 1575 vlan_offload = rte_eth_dev_get_vlan_offload(port_id); 1576 1577 if (on) 1578 vlan_offload |= ETH_VLAN_EXTEND_OFFLOAD; 1579 else 1580 vlan_offload &= ~ETH_VLAN_EXTEND_OFFLOAD; 1581 1582 diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); 1583 if (diag < 0) 1584 printf("rx_vlan_extend_set(port_pi=%d, on=%d) failed " 1585 "diag=%d\n", port_id, on, diag); 1586 } 1587 1588 void 1589 rx_vlan_strip_set(portid_t port_id, int on) 1590 { 1591 int diag; 1592 int vlan_offload; 1593 1594 if (port_id_is_invalid(port_id)) 1595 return; 1596 1597 vlan_offload = rte_eth_dev_get_vlan_offload(port_id); 1598 1599 if (on) 1600 vlan_offload |= ETH_VLAN_STRIP_OFFLOAD; 1601 else 1602 vlan_offload &= ~ETH_VLAN_STRIP_OFFLOAD; 1603 1604 diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); 1605 if (diag < 0) 1606 printf("rx_vlan_strip_set(port_pi=%d, on=%d) failed " 1607 "diag=%d\n", port_id, on, diag); 1608 } 1609 1610 void 1611 rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on) 1612 { 1613 int diag; 1614 1615 if (port_id_is_invalid(port_id)) 1616 return; 1617 1618 diag = rte_eth_dev_set_vlan_strip_on_queue(port_id, queue_id, on); 1619 if (diag < 0) 1620 printf("rx_vlan_strip_set_on_queue(port_pi=%d, queue_id=%d, on=%d) failed " 1621 "diag=%d\n", port_id, queue_id, on, diag); 1622 } 1623 1624 void 1625 rx_vlan_filter_set(portid_t port_id, int on) 1626 { 1627 int diag; 1628 int vlan_offload; 1629 1630 if (port_id_is_invalid(port_id)) 1631 return; 1632 1633 vlan_offload = rte_eth_dev_get_vlan_offload(port_id); 1634 1635 if (on) 1636 vlan_offload |= ETH_VLAN_FILTER_OFFLOAD; 1637 else 1638 vlan_offload &= ~ETH_VLAN_FILTER_OFFLOAD; 1639 1640 diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); 1641 if (diag < 0) 1642 printf("rx_vlan_filter_set(port_pi=%d, on=%d) failed " 1643 "diag=%d\n", port_id, on, diag); 1644 } 1645 1646 void 1647 rx_vft_set(portid_t port_id, uint16_t vlan_id, int on) 1648 { 1649 int diag; 1650 1651 if (port_id_is_invalid(port_id)) 1652 return; 1653 if (vlan_id_is_invalid(vlan_id)) 1654 return; 1655 diag = rte_eth_dev_vlan_filter(port_id, vlan_id, on); 1656 if (diag == 0) 1657 return; 1658 printf("rte_eth_dev_vlan_filter(port_pi=%d, vlan_id=%d, on=%d) failed " 1659 "diag=%d\n", 1660 port_id, vlan_id, on, diag); 1661 } 1662 1663 void 1664 rx_vlan_all_filter_set(portid_t port_id, int on) 1665 { 1666 uint16_t vlan_id; 1667 1668 if (port_id_is_invalid(port_id)) 1669 return; 1670 for (vlan_id = 0; vlan_id < 4096; vlan_id++) 1671 rx_vft_set(port_id, vlan_id, on); 1672 } 1673 1674 void 1675 vlan_tpid_set(portid_t port_id, uint16_t tp_id) 1676 { 1677 int diag; 1678 if (port_id_is_invalid(port_id)) 1679 return; 1680 1681 diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id); 1682 if (diag == 0) 1683 return; 1684 1685 printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed " 1686 "diag=%d\n", 1687 port_id, tp_id, diag); 1688 } 1689 1690 void 1691 tx_vlan_set(portid_t port_id, uint16_t vlan_id) 1692 { 1693 if (port_id_is_invalid(port_id)) 1694 return; 1695 if (vlan_id_is_invalid(vlan_id)) 1696 return; 1697 ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_VLAN; 1698 ports[port_id].tx_vlan_id = vlan_id; 1699 } 1700 1701 void 1702 tx_vlan_reset(portid_t port_id) 1703 { 1704 if (port_id_is_invalid(port_id)) 1705 return; 1706 ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_INSERT_VLAN; 1707 } 1708 1709 void 1710 tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on) 1711 { 1712 if (port_id_is_invalid(port_id)) 1713 return; 1714 1715 rte_eth_dev_set_vlan_pvid(port_id, vlan_id, on); 1716 } 1717 1718 void 1719 set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value) 1720 { 1721 uint16_t i; 1722 uint8_t existing_mapping_found = 0; 1723 1724 if (port_id_is_invalid(port_id)) 1725 return; 1726 1727 if (is_rx ? (rx_queue_id_is_invalid(queue_id)) : (tx_queue_id_is_invalid(queue_id))) 1728 return; 1729 1730 if (map_value >= RTE_ETHDEV_QUEUE_STAT_CNTRS) { 1731 printf("map_value not in required range 0..%d\n", 1732 RTE_ETHDEV_QUEUE_STAT_CNTRS - 1); 1733 return; 1734 } 1735 1736 if (!is_rx) { /*then tx*/ 1737 for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 1738 if ((tx_queue_stats_mappings[i].port_id == port_id) && 1739 (tx_queue_stats_mappings[i].queue_id == queue_id)) { 1740 tx_queue_stats_mappings[i].stats_counter_id = map_value; 1741 existing_mapping_found = 1; 1742 break; 1743 } 1744 } 1745 if (!existing_mapping_found) { /* A new additional mapping... */ 1746 tx_queue_stats_mappings[nb_tx_queue_stats_mappings].port_id = port_id; 1747 tx_queue_stats_mappings[nb_tx_queue_stats_mappings].queue_id = queue_id; 1748 tx_queue_stats_mappings[nb_tx_queue_stats_mappings].stats_counter_id = map_value; 1749 nb_tx_queue_stats_mappings++; 1750 } 1751 } 1752 else { /*rx*/ 1753 for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 1754 if ((rx_queue_stats_mappings[i].port_id == port_id) && 1755 (rx_queue_stats_mappings[i].queue_id == queue_id)) { 1756 rx_queue_stats_mappings[i].stats_counter_id = map_value; 1757 existing_mapping_found = 1; 1758 break; 1759 } 1760 } 1761 if (!existing_mapping_found) { /* A new additional mapping... */ 1762 rx_queue_stats_mappings[nb_rx_queue_stats_mappings].port_id = port_id; 1763 rx_queue_stats_mappings[nb_rx_queue_stats_mappings].queue_id = queue_id; 1764 rx_queue_stats_mappings[nb_rx_queue_stats_mappings].stats_counter_id = map_value; 1765 nb_rx_queue_stats_mappings++; 1766 } 1767 } 1768 } 1769 1770 void 1771 fdir_add_signature_filter(portid_t port_id, uint8_t queue_id, 1772 struct rte_fdir_filter *fdir_filter) 1773 { 1774 int diag; 1775 1776 if (port_id_is_invalid(port_id)) 1777 return; 1778 1779 diag = rte_eth_dev_fdir_add_signature_filter(port_id, fdir_filter, 1780 queue_id); 1781 if (diag == 0) 1782 return; 1783 1784 printf("rte_eth_dev_fdir_add_signature_filter for port_id=%d failed " 1785 "diag=%d\n", port_id, diag); 1786 } 1787 1788 void 1789 fdir_update_signature_filter(portid_t port_id, uint8_t queue_id, 1790 struct rte_fdir_filter *fdir_filter) 1791 { 1792 int diag; 1793 1794 if (port_id_is_invalid(port_id)) 1795 return; 1796 1797 diag = rte_eth_dev_fdir_update_signature_filter(port_id, fdir_filter, 1798 queue_id); 1799 if (diag == 0) 1800 return; 1801 1802 printf("rte_eth_dev_fdir_update_signature_filter for port_id=%d failed " 1803 "diag=%d\n", port_id, diag); 1804 } 1805 1806 void 1807 fdir_remove_signature_filter(portid_t port_id, 1808 struct rte_fdir_filter *fdir_filter) 1809 { 1810 int diag; 1811 1812 if (port_id_is_invalid(port_id)) 1813 return; 1814 1815 diag = rte_eth_dev_fdir_remove_signature_filter(port_id, fdir_filter); 1816 if (diag == 0) 1817 return; 1818 1819 printf("rte_eth_dev_fdir_add_signature_filter for port_id=%d failed " 1820 "diag=%d\n", port_id, diag); 1821 1822 } 1823 1824 static inline void 1825 print_fdir_flex_payload(struct rte_eth_fdir_flex_conf *flex_conf) 1826 { 1827 struct rte_eth_flex_payload_cfg *cfg; 1828 int i, j; 1829 1830 for (i = 0; i < flex_conf->nb_payloads; i++) { 1831 cfg = &flex_conf->flex_set[i]; 1832 if (cfg->type == RTE_ETH_L2_PAYLOAD) 1833 printf("\n L2_PAYLOAD: "); 1834 else if (cfg->type == RTE_ETH_L3_PAYLOAD) 1835 printf("\n L3_PAYLOAD: "); 1836 else if (cfg->type == RTE_ETH_L4_PAYLOAD) 1837 printf("\n L4_PAYLOAD: "); 1838 else 1839 printf("\n UNKNOWN PAYLOAD(%u): ", cfg->type); 1840 for (j = 0; j < RTE_ETH_FDIR_MAX_FLEXLEN; j++) 1841 printf(" %-5u", cfg->src_offset[j]); 1842 } 1843 printf("\n"); 1844 } 1845 1846 static inline void 1847 print_fdir_flex_mask(struct rte_eth_fdir_flex_conf *flex_conf) 1848 { 1849 struct rte_eth_fdir_flex_mask *mask; 1850 int i, j; 1851 1852 for (i = 0; i < flex_conf->nb_flexmasks; i++) { 1853 mask = &flex_conf->flex_mask[i]; 1854 printf("\n %s:\t", flowtype_str[mask->flow_type]); 1855 for (j = 0; j < RTE_ETH_FDIR_MAX_FLEXLEN; j++) 1856 printf(" %02x", mask->mask[j]); 1857 } 1858 printf("\n"); 1859 } 1860 1861 static inline void 1862 print_fdir_flow_type(uint32_t flow_types_mask) 1863 { 1864 int i = 0; 1865 1866 for (i = RTE_ETH_FLOW_TYPE_UDPV4; 1867 i <= RTE_ETH_FLOW_TYPE_FRAG_IPV6; 1868 i++) { 1869 if (flow_types_mask & (1 << i)) 1870 printf(" %s", flowtype_str[i]); 1871 } 1872 printf("\n"); 1873 } 1874 1875 void 1876 fdir_get_infos(portid_t port_id) 1877 { 1878 struct rte_eth_fdir_stats fdir_stat; 1879 struct rte_eth_fdir_info fdir_info; 1880 int ret; 1881 1882 static const char *fdir_stats_border = "########################"; 1883 1884 if (port_id_is_invalid(port_id)) 1885 return; 1886 ret = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR); 1887 if (ret < 0) { 1888 /* use the old fdir APIs to get info */ 1889 struct rte_eth_fdir fdir; 1890 memset(&fdir, 0, sizeof(fdir)); 1891 ret = rte_eth_dev_fdir_get_infos(port_id, &fdir); 1892 if (ret < 0) { 1893 printf("\n getting fdir info fails on port %-2d\n", 1894 port_id); 1895 return; 1896 } 1897 printf("\n %s FDIR infos for port %-2d %s\n", 1898 fdir_stats_border, port_id, fdir_stats_border); 1899 printf(" collision: %-10"PRIu64" free: %"PRIu64"\n" 1900 " maxhash: %-10"PRIu64" maxlen: %"PRIu64"\n" 1901 " add: %-10"PRIu64" remove: %"PRIu64"\n" 1902 " f_add: %-10"PRIu64" f_remove: %"PRIu64"\n", 1903 (uint64_t)(fdir.collision), (uint64_t)(fdir.free), 1904 (uint64_t)(fdir.maxhash), (uint64_t)(fdir.maxlen), 1905 fdir.add, fdir.remove, fdir.f_add, fdir.f_remove); 1906 printf(" %s############################%s\n", 1907 fdir_stats_border, fdir_stats_border); 1908 return; 1909 } 1910 1911 memset(&fdir_info, 0, sizeof(fdir_info)); 1912 rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, 1913 RTE_ETH_FILTER_INFO, &fdir_info); 1914 memset(&fdir_stat, 0, sizeof(fdir_stat)); 1915 rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, 1916 RTE_ETH_FILTER_STATS, &fdir_stat); 1917 printf("\n %s FDIR infos for port %-2d %s\n", 1918 fdir_stats_border, port_id, fdir_stats_border); 1919 printf(" MODE: "); 1920 if (fdir_info.mode == RTE_FDIR_MODE_PERFECT) 1921 printf(" PERFECT\n"); 1922 else if (fdir_info.mode == RTE_FDIR_MODE_SIGNATURE) 1923 printf(" SIGNATURE\n"); 1924 else 1925 printf(" DISABLE\n"); 1926 printf(" SUPPORTED FLOW TYPE: "); 1927 print_fdir_flow_type(fdir_info.flow_types_mask[0]); 1928 printf(" FLEX PAYLOAD INFO:\n"); 1929 printf(" max_len: %-10"PRIu32" payload_limit: %-10"PRIu32"\n" 1930 " payload_unit: %-10"PRIu32" payload_seg: %-10"PRIu32"\n" 1931 " bitmask_unit: %-10"PRIu32" bitmask_num: %-10"PRIu32"\n", 1932 fdir_info.max_flexpayload, fdir_info.flex_payload_limit, 1933 fdir_info.flex_payload_unit, 1934 fdir_info.max_flex_payload_segment_num, 1935 fdir_info.flex_bitmask_unit, fdir_info.max_flex_bitmask_num); 1936 if (fdir_info.flex_conf.nb_payloads > 0) { 1937 printf(" FLEX PAYLOAD SRC OFFSET:"); 1938 print_fdir_flex_payload(&fdir_info.flex_conf); 1939 } 1940 if (fdir_info.flex_conf.nb_flexmasks > 0) { 1941 printf(" FLEX MASK CFG:"); 1942 print_fdir_flex_mask(&fdir_info.flex_conf); 1943 } 1944 printf(" guarant_count: %-10"PRIu32" best_count: %-10"PRIu32"\n", 1945 fdir_stat.guarant_cnt, fdir_stat.best_cnt); 1946 printf(" guarant_space: %-10"PRIu32" best_space: %-10"PRIu32"\n", 1947 fdir_info.guarant_spc, fdir_info.guarant_spc); 1948 printf(" %s############################%s\n", 1949 fdir_stats_border, fdir_stats_border); 1950 } 1951 1952 void 1953 fdir_add_perfect_filter(portid_t port_id, uint16_t soft_id, uint8_t queue_id, 1954 uint8_t drop, struct rte_fdir_filter *fdir_filter) 1955 { 1956 int diag; 1957 1958 if (port_id_is_invalid(port_id)) 1959 return; 1960 1961 diag = rte_eth_dev_fdir_add_perfect_filter(port_id, fdir_filter, 1962 soft_id, queue_id, drop); 1963 if (diag == 0) 1964 return; 1965 1966 printf("rte_eth_dev_fdir_add_perfect_filter for port_id=%d failed " 1967 "diag=%d\n", port_id, diag); 1968 } 1969 1970 void 1971 fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id, uint8_t queue_id, 1972 uint8_t drop, struct rte_fdir_filter *fdir_filter) 1973 { 1974 int diag; 1975 1976 if (port_id_is_invalid(port_id)) 1977 return; 1978 1979 diag = rte_eth_dev_fdir_update_perfect_filter(port_id, fdir_filter, 1980 soft_id, queue_id, drop); 1981 if (diag == 0) 1982 return; 1983 1984 printf("rte_eth_dev_fdir_update_perfect_filter for port_id=%d failed " 1985 "diag=%d\n", port_id, diag); 1986 } 1987 1988 void 1989 fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id, 1990 struct rte_fdir_filter *fdir_filter) 1991 { 1992 int diag; 1993 1994 if (port_id_is_invalid(port_id)) 1995 return; 1996 1997 diag = rte_eth_dev_fdir_remove_perfect_filter(port_id, fdir_filter, 1998 soft_id); 1999 if (diag == 0) 2000 return; 2001 2002 printf("rte_eth_dev_fdir_update_perfect_filter for port_id=%d failed " 2003 "diag=%d\n", port_id, diag); 2004 } 2005 2006 void 2007 fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks) 2008 { 2009 int diag; 2010 2011 if (port_id_is_invalid(port_id)) 2012 return; 2013 2014 diag = rte_eth_dev_fdir_set_masks(port_id, fdir_masks); 2015 if (diag == 0) 2016 return; 2017 2018 printf("rte_eth_dev_set_masks_filter for port_id=%d failed " 2019 "diag=%d\n", port_id, diag); 2020 } 2021 2022 void 2023 fdir_set_flex_mask(portid_t port_id, struct rte_eth_fdir_flex_mask *cfg) 2024 { 2025 struct rte_port *port; 2026 struct rte_eth_fdir_flex_conf *flex_conf; 2027 int i, idx = 0; 2028 2029 port = &ports[port_id]; 2030 flex_conf = &port->dev_conf.fdir_conf.flex_conf; 2031 for (i = 0; i < RTE_ETH_FLOW_TYPE_MAX; i++) { 2032 if (cfg->flow_type == flex_conf->flex_mask[i].flow_type) { 2033 idx = i; 2034 break; 2035 } 2036 } 2037 if (i >= RTE_ETH_FLOW_TYPE_MAX) { 2038 if (flex_conf->nb_flexmasks < RTE_DIM(flex_conf->flex_mask)) { 2039 idx = flex_conf->nb_flexmasks; 2040 flex_conf->nb_flexmasks++; 2041 } else { 2042 printf("The flex mask table is full. Can not set flex" 2043 " mask for flow_type(%u).", cfg->flow_type); 2044 return; 2045 } 2046 } 2047 (void)rte_memcpy(&flex_conf->flex_mask[idx], 2048 cfg, 2049 sizeof(struct rte_eth_fdir_flex_mask)); 2050 } 2051 2052 void 2053 fdir_set_flex_payload(portid_t port_id, struct rte_eth_flex_payload_cfg *cfg) 2054 { 2055 struct rte_port *port; 2056 struct rte_eth_fdir_flex_conf *flex_conf; 2057 int i, idx = 0; 2058 2059 port = &ports[port_id]; 2060 flex_conf = &port->dev_conf.fdir_conf.flex_conf; 2061 for (i = 0; i < RTE_ETH_PAYLOAD_MAX; i++) { 2062 if (cfg->type == flex_conf->flex_set[i].type) { 2063 idx = i; 2064 break; 2065 } 2066 } 2067 if (i >= RTE_ETH_PAYLOAD_MAX) { 2068 if (flex_conf->nb_payloads < RTE_DIM(flex_conf->flex_set)) { 2069 idx = flex_conf->nb_payloads; 2070 flex_conf->nb_payloads++; 2071 } else { 2072 printf("The flex payload table is full. Can not set" 2073 " flex payload for type(%u).", cfg->type); 2074 return; 2075 } 2076 } 2077 (void)rte_memcpy(&flex_conf->flex_set[idx], 2078 cfg, 2079 sizeof(struct rte_eth_flex_payload_cfg)); 2080 2081 } 2082 2083 void 2084 set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on) 2085 { 2086 int diag; 2087 2088 if (port_id_is_invalid(port_id)) 2089 return; 2090 if (is_rx) 2091 diag = rte_eth_dev_set_vf_rx(port_id,vf,on); 2092 else 2093 diag = rte_eth_dev_set_vf_tx(port_id,vf,on); 2094 if (diag == 0) 2095 return; 2096 if(is_rx) 2097 printf("rte_eth_dev_set_vf_rx for port_id=%d failed " 2098 "diag=%d\n", port_id, diag); 2099 else 2100 printf("rte_eth_dev_set_vf_tx for port_id=%d failed " 2101 "diag=%d\n", port_id, diag); 2102 2103 } 2104 2105 void 2106 set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on) 2107 { 2108 int diag; 2109 2110 if (port_id_is_invalid(port_id)) 2111 return; 2112 if (vlan_id_is_invalid(vlan_id)) 2113 return; 2114 diag = rte_eth_dev_set_vf_vlan_filter(port_id, vlan_id, vf_mask, on); 2115 if (diag == 0) 2116 return; 2117 printf("rte_eth_dev_set_vf_vlan_filter for port_id=%d failed " 2118 "diag=%d\n", port_id, diag); 2119 } 2120 2121 int 2122 set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate) 2123 { 2124 int diag; 2125 struct rte_eth_link link; 2126 2127 if (port_id_is_invalid(port_id)) 2128 return 1; 2129 rte_eth_link_get_nowait(port_id, &link); 2130 if (rate > link.link_speed) { 2131 printf("Invalid rate value:%u bigger than link speed: %u\n", 2132 rate, link.link_speed); 2133 return 1; 2134 } 2135 diag = rte_eth_set_queue_rate_limit(port_id, queue_idx, rate); 2136 if (diag == 0) 2137 return diag; 2138 printf("rte_eth_set_queue_rate_limit for port_id=%d failed diag=%d\n", 2139 port_id, diag); 2140 return diag; 2141 } 2142 2143 int 2144 set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk) 2145 { 2146 int diag; 2147 struct rte_eth_link link; 2148 2149 if (q_msk == 0) 2150 return 0; 2151 2152 if (port_id_is_invalid(port_id)) 2153 return 1; 2154 rte_eth_link_get_nowait(port_id, &link); 2155 if (rate > link.link_speed) { 2156 printf("Invalid rate value:%u bigger than link speed: %u\n", 2157 rate, link.link_speed); 2158 return 1; 2159 } 2160 diag = rte_eth_set_vf_rate_limit(port_id, vf, rate, q_msk); 2161 if (diag == 0) 2162 return diag; 2163 printf("rte_eth_set_vf_rate_limit for port_id=%d failed diag=%d\n", 2164 port_id, diag); 2165 return diag; 2166 } 2167 2168 void 2169 get_ethertype_filter(uint8_t port_id, uint16_t index) 2170 { 2171 struct rte_ethertype_filter filter; 2172 int ret = 0; 2173 uint16_t rx_queue; 2174 2175 memset(&filter, 0, sizeof(filter)); 2176 ret = rte_eth_dev_get_ethertype_filter(port_id, index, 2177 &filter, &rx_queue); 2178 if (ret < 0) { 2179 if (ret == (-ENOENT)) 2180 printf("filter[%d] is not enabled\n", index); 2181 else 2182 printf("get ethertype filter fails(%s)\n", strerror(-ret)); 2183 return; 2184 } else { 2185 printf("filter[%d]:\n", index); 2186 printf(" ethertype: 0x%04x\n", 2187 rte_le_to_cpu_32(filter.ethertype)); 2188 printf(" priority: %s, %d\n", 2189 filter.priority_en ? "enable" : "disable", 2190 filter.priority); 2191 printf(" queue: %d\n", rx_queue); 2192 } 2193 } 2194 2195 void 2196 get_syn_filter(uint8_t port_id) 2197 { 2198 struct rte_syn_filter filter; 2199 int ret = 0; 2200 uint16_t rx_queue; 2201 2202 memset(&filter, 0, sizeof(filter)); 2203 ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue); 2204 2205 if (ret < 0) { 2206 if (ret == (-ENOENT)) 2207 printf("syn filter is not enabled\n"); 2208 else 2209 printf("get syn filter fails(%s)\n", strerror(-ret)); 2210 return; 2211 } 2212 printf("syn filter: priority: %s, queue: %d\n", 2213 filter.hig_pri ? "high" : "low", 2214 rx_queue); 2215 } 2216 void 2217 get_2tuple_filter(uint8_t port_id, uint16_t index) 2218 { 2219 struct rte_2tuple_filter filter; 2220 int ret = 0; 2221 uint16_t rx_queue; 2222 2223 memset(&filter, 0, sizeof(filter)); 2224 ret = rte_eth_dev_get_2tuple_filter(port_id, index, 2225 &filter, &rx_queue); 2226 if (ret < 0) { 2227 if (ret == (-ENOENT)) 2228 printf("filter[%d] is not enabled\n", index); 2229 else 2230 printf("get 2tuple filter fails(%s)\n", strerror(-ret)); 2231 return; 2232 } else { 2233 printf("filter[%d]:\n", index); 2234 printf(" Destination Port: 0x%04x mask: %d\n", 2235 rte_be_to_cpu_16(filter.dst_port), 2236 filter.dst_port_mask ? 0 : 1); 2237 printf(" protocol: 0x%02x mask:%d tcp_flags: 0x%02x\n", 2238 filter.protocol, filter.protocol_mask ? 0 : 1, 2239 filter.tcp_flags); 2240 printf(" priority: %d queue: %d\n", 2241 filter.priority, rx_queue); 2242 } 2243 } 2244 2245 void 2246 get_5tuple_filter(uint8_t port_id, uint16_t index) 2247 { 2248 struct rte_5tuple_filter filter; 2249 int ret = 0; 2250 uint16_t rx_queue; 2251 2252 memset(&filter, 0, sizeof(filter)); 2253 ret = rte_eth_dev_get_5tuple_filter(port_id, index, 2254 &filter, &rx_queue); 2255 if (ret < 0) { 2256 if (ret == (-ENOENT)) 2257 printf("filter[%d] is not enabled\n", index); 2258 else 2259 printf("get 5tuple filter fails(%s)\n", strerror(-ret)); 2260 return; 2261 } else { 2262 printf("filter[%d]:\n", index); 2263 printf(" Destination IP: 0x%08x mask: %d\n", 2264 (unsigned)rte_be_to_cpu_32(filter.dst_ip), 2265 filter.dst_ip_mask ? 0 : 1); 2266 printf(" Source IP: 0x%08x mask: %d\n", 2267 (unsigned)rte_be_to_cpu_32(filter.src_ip), 2268 filter.src_ip_mask ? 0 : 1); 2269 printf(" Destination Port: 0x%04x mask: %d\n", 2270 rte_be_to_cpu_16(filter.dst_port), 2271 filter.dst_port_mask ? 0 : 1); 2272 printf(" Source Port: 0x%04x mask: %d\n", 2273 rte_be_to_cpu_16(filter.src_port), 2274 filter.src_port_mask ? 0 : 1); 2275 printf(" protocol: 0x%02x mask: %d\n", 2276 filter.protocol, 2277 filter.protocol_mask ? 0 : 1); 2278 printf(" priority: %d flags: 0x%02x queue: %d\n", 2279 filter.priority, filter.tcp_flags, rx_queue); 2280 } 2281 } 2282 void 2283 get_flex_filter(uint8_t port_id, uint16_t index) 2284 2285 { 2286 struct rte_flex_filter filter; 2287 int ret = 0; 2288 uint16_t rx_queue; 2289 int i, j; 2290 2291 memset(&filter, 0, sizeof(filter)); 2292 ret = rte_eth_dev_get_flex_filter(port_id, index, 2293 &filter, &rx_queue); 2294 if (ret < 0) { 2295 if (ret == (-ENOENT)) 2296 printf("filter[%d] is not enabled\n", index); 2297 else 2298 printf("get flex filter fails(%s)\n", strerror(-ret)); 2299 return; 2300 } else { 2301 printf("filter[%d]: ", index); 2302 printf("\n length: %d", filter.len); 2303 printf("\n dword[]: 0x"); 2304 for (i = 0; i < 32; i++) 2305 printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i])); 2306 printf("\n mask[]: 0b"); 2307 for (i = 0; i < 16; i++) { 2308 for (j = 0; j < 8; j++) 2309 printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0'); 2310 } 2311 printf("\n priority: %d queue: %d\n", 2312 filter.priority, rx_queue); 2313 } 2314 } 2315