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