1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2015 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <cmdline_parse.h> 35 #include <cmdline_parse_num.h> 36 #include <cmdline_parse_string.h> 37 #include <cmdline_parse_etheraddr.h> 38 #include <cmdline_socket.h> 39 #include <cmdline.h> 40 41 #include "rte_ethtool.h" 42 #include "ethapp.h" 43 44 #define EEPROM_DUMP_CHUNKSIZE 1024 45 46 47 struct pcmd_get_params { 48 cmdline_fixed_string_t cmd; 49 }; 50 struct pcmd_int_params { 51 cmdline_fixed_string_t cmd; 52 uint16_t port; 53 }; 54 struct pcmd_intstr_params { 55 cmdline_fixed_string_t cmd; 56 uint16_t port; 57 cmdline_fixed_string_t opt; 58 }; 59 struct pcmd_intmac_params { 60 cmdline_fixed_string_t cmd; 61 uint16_t port; 62 struct ether_addr mac; 63 }; 64 struct pcmd_str_params { 65 cmdline_fixed_string_t cmd; 66 cmdline_fixed_string_t opt; 67 }; 68 struct pcmd_vlan_params { 69 cmdline_fixed_string_t cmd; 70 uint16_t port; 71 cmdline_fixed_string_t mode; 72 uint16_t vid; 73 }; 74 struct pcmd_intintint_params { 75 cmdline_fixed_string_t cmd; 76 uint16_t port; 77 uint16_t tx; 78 uint16_t rx; 79 }; 80 81 82 /* Parameter-less commands */ 83 cmdline_parse_token_string_t pcmd_quit_token_cmd = 84 TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "quit"); 85 cmdline_parse_token_string_t pcmd_stats_token_cmd = 86 TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "stats"); 87 cmdline_parse_token_string_t pcmd_drvinfo_token_cmd = 88 TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "drvinfo"); 89 cmdline_parse_token_string_t pcmd_link_token_cmd = 90 TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "link"); 91 92 /* Commands taking just port id */ 93 cmdline_parse_token_string_t pcmd_open_token_cmd = 94 TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "open"); 95 cmdline_parse_token_string_t pcmd_stop_token_cmd = 96 TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "stop"); 97 cmdline_parse_token_string_t pcmd_rxmode_token_cmd = 98 TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode"); 99 cmdline_parse_token_string_t pcmd_portstats_token_cmd = 100 TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats"); 101 cmdline_parse_token_num_t pcmd_int_token_port = 102 TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16); 103 104 /* Commands taking port id and string */ 105 cmdline_parse_token_string_t pcmd_eeprom_token_cmd = 106 TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "eeprom"); 107 cmdline_parse_token_string_t pcmd_mtu_token_cmd = 108 TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "mtu"); 109 cmdline_parse_token_string_t pcmd_regs_token_cmd = 110 TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "regs"); 111 112 cmdline_parse_token_num_t pcmd_intstr_token_port = 113 TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16); 114 cmdline_parse_token_string_t pcmd_intstr_token_opt = 115 TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, opt, NULL); 116 117 /* Commands taking port id and a MAC address string */ 118 cmdline_parse_token_string_t pcmd_macaddr_token_cmd = 119 TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "macaddr"); 120 cmdline_parse_token_num_t pcmd_intmac_token_port = 121 TOKEN_NUM_INITIALIZER(struct pcmd_intmac_params, port, UINT16); 122 cmdline_parse_token_etheraddr_t pcmd_intmac_token_mac = 123 TOKEN_ETHERADDR_INITIALIZER(struct pcmd_intmac_params, mac); 124 125 /* Command taking just a MAC address */ 126 cmdline_parse_token_string_t pcmd_validate_token_cmd = 127 TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "validate"); 128 129 130 /* Commands taking port id and two integers */ 131 cmdline_parse_token_string_t pcmd_ringparam_token_cmd = 132 TOKEN_STRING_INITIALIZER(struct pcmd_intintint_params, cmd, 133 "ringparam"); 134 cmdline_parse_token_num_t pcmd_intintint_token_port = 135 TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, port, UINT16); 136 cmdline_parse_token_num_t pcmd_intintint_token_tx = 137 TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, tx, UINT16); 138 cmdline_parse_token_num_t pcmd_intintint_token_rx = 139 TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, rx, UINT16); 140 141 142 /* Pause commands */ 143 cmdline_parse_token_string_t pcmd_pause_token_cmd = 144 TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "pause"); 145 cmdline_parse_token_num_t pcmd_pause_token_port = 146 TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16); 147 cmdline_parse_token_string_t pcmd_pause_token_opt = 148 TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, 149 opt, "all#tx#rx#none"); 150 151 /* VLAN commands */ 152 cmdline_parse_token_string_t pcmd_vlan_token_cmd = 153 TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, cmd, "vlan"); 154 cmdline_parse_token_num_t pcmd_vlan_token_port = 155 TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, port, UINT16); 156 cmdline_parse_token_string_t pcmd_vlan_token_mode = 157 TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, mode, "add#del"); 158 cmdline_parse_token_num_t pcmd_vlan_token_vid = 159 TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, vid, UINT16); 160 161 162 static void 163 pcmd_quit_callback(__rte_unused void *ptr_params, 164 struct cmdline *ctx, 165 __rte_unused void *ptr_data) 166 { 167 cmdline_quit(ctx); 168 } 169 170 171 static void 172 pcmd_drvinfo_callback(__rte_unused void *ptr_params, 173 __rte_unused struct cmdline *ctx, 174 __rte_unused void *ptr_data) 175 { 176 struct ethtool_drvinfo info; 177 int id_port; 178 179 for (id_port = 0; id_port < rte_eth_dev_count(); id_port++) { 180 memset(&info, 0, sizeof(info)); 181 if (rte_ethtool_get_drvinfo(id_port, &info)) { 182 printf("Error getting info for port %i\n", id_port); 183 return; 184 } 185 printf("Port %i driver: %s (ver: %s)\n", 186 id_port, info.driver, info.version 187 ); 188 printf("firmware-version: %s\n", info.fw_version); 189 printf("bus-info: %s\n", info.bus_info); 190 } 191 } 192 193 194 static void 195 pcmd_link_callback(__rte_unused void *ptr_params, 196 __rte_unused struct cmdline *ctx, 197 __rte_unused void *ptr_data) 198 { 199 int num_ports = rte_eth_dev_count(); 200 int id_port, stat_port; 201 202 for (id_port = 0; id_port < num_ports; id_port++) { 203 if (!rte_eth_dev_is_valid_port(id_port)) 204 continue; 205 stat_port = rte_ethtool_get_link(id_port); 206 switch (stat_port) { 207 case 0: 208 printf("Port %i: Down\n", id_port); 209 break; 210 case 1: 211 printf("Port %i: Up\n", id_port); 212 break; 213 default: 214 printf("Port %i: Error getting link status\n", 215 id_port 216 ); 217 break; 218 } 219 } 220 printf("\n"); 221 } 222 223 224 static void 225 pcmd_regs_callback(void *ptr_params, 226 __rte_unused struct cmdline *ctx, 227 __rte_unused void *ptr_data) 228 { 229 struct pcmd_intstr_params *params = ptr_params; 230 int len_regs; 231 struct ethtool_regs regs; 232 unsigned char *buf_data; 233 FILE *fp_regs; 234 235 if (!rte_eth_dev_is_valid_port(params->port)) { 236 printf("Error: Invalid port number %i\n", params->port); 237 return; 238 } 239 len_regs = rte_ethtool_get_regs_len(params->port); 240 if (len_regs > 0) { 241 printf("Port %i: %i bytes\n", params->port, len_regs); 242 buf_data = malloc(len_regs); 243 if (buf_data == NULL) { 244 printf("Error allocating %i bytes for buffer\n", 245 len_regs); 246 return; 247 } 248 if (!rte_ethtool_get_regs(params->port, ®s, buf_data)) { 249 fp_regs = fopen(params->opt, "wb"); 250 if (fp_regs == NULL) { 251 printf("Error opening '%s' for writing\n", 252 params->opt); 253 } else { 254 if ((int)fwrite(buf_data, 255 1, len_regs, 256 fp_regs) != len_regs) 257 printf("Error writing '%s'\n", 258 params->opt); 259 fclose(fp_regs); 260 } 261 } 262 free(buf_data); 263 } else if (len_regs == -ENOTSUP) 264 printf("Port %i: Operation not supported\n", params->port); 265 else 266 printf("Port %i: Error getting registers\n", params->port); 267 } 268 269 270 static void 271 pcmd_eeprom_callback(void *ptr_params, 272 __rte_unused struct cmdline *ctx, 273 __rte_unused void *ptr_data) 274 { 275 struct pcmd_intstr_params *params = ptr_params; 276 struct ethtool_eeprom info_eeprom; 277 int len_eeprom; 278 int pos_eeprom; 279 int stat; 280 unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE]; 281 FILE *fp_eeprom; 282 283 if (!rte_eth_dev_is_valid_port(params->port)) { 284 printf("Error: Invalid port number %i\n", params->port); 285 return; 286 } 287 len_eeprom = rte_ethtool_get_eeprom_len(params->port); 288 if (len_eeprom > 0) { 289 fp_eeprom = fopen(params->opt, "wb"); 290 if (fp_eeprom == NULL) { 291 printf("Error opening '%s' for writing\n", 292 params->opt); 293 return; 294 } 295 printf("Total EEPROM length: %i bytes\n", len_eeprom); 296 info_eeprom.len = EEPROM_DUMP_CHUNKSIZE; 297 for (pos_eeprom = 0; 298 pos_eeprom < len_eeprom; 299 pos_eeprom += EEPROM_DUMP_CHUNKSIZE) { 300 info_eeprom.offset = pos_eeprom; 301 if (pos_eeprom + EEPROM_DUMP_CHUNKSIZE > len_eeprom) 302 info_eeprom.len = len_eeprom - pos_eeprom; 303 else 304 info_eeprom.len = EEPROM_DUMP_CHUNKSIZE; 305 stat = rte_ethtool_get_eeprom( 306 params->port, &info_eeprom, bytes_eeprom 307 ); 308 if (stat != 0) { 309 printf("EEPROM read error %i\n", stat); 310 break; 311 } 312 if (fwrite(bytes_eeprom, 313 1, info_eeprom.len, 314 fp_eeprom) != info_eeprom.len) { 315 printf("Error writing '%s'\n", params->opt); 316 break; 317 } 318 } 319 fclose(fp_eeprom); 320 } else if (len_eeprom == 0) 321 printf("Port %i: Device does not have EEPROM\n", params->port); 322 else if (len_eeprom == -ENOTSUP) 323 printf("Port %i: Operation not supported\n", params->port); 324 else 325 printf("Port %i: Error getting EEPROM\n", params->port); 326 } 327 328 329 static void 330 pcmd_pause_callback(void *ptr_params, 331 __rte_unused struct cmdline *ctx, 332 void *ptr_data) 333 { 334 struct pcmd_intstr_params *params = ptr_params; 335 struct ethtool_pauseparam info; 336 int stat; 337 338 if (!rte_eth_dev_is_valid_port(params->port)) { 339 printf("Error: Invalid port number %i\n", params->port); 340 return; 341 } 342 if (ptr_data != NULL) { 343 stat = rte_ethtool_get_pauseparam(params->port, &info); 344 } else { 345 memset(&info, 0, sizeof(info)); 346 if (strcasecmp("all", params->opt) == 0) { 347 info.tx_pause = 1; 348 info.rx_pause = 1; 349 } else if (strcasecmp("tx", params->opt) == 0) { 350 info.tx_pause = 1; 351 info.rx_pause = 0; 352 } else if (strcasecmp("rx", params->opt) == 0) { 353 info.tx_pause = 0; 354 info.rx_pause = 1; 355 } else { 356 info.tx_pause = 0; 357 info.rx_pause = 0; 358 } 359 /* Assume auto-negotiation wanted */ 360 info.autoneg = 1; 361 stat = rte_ethtool_set_pauseparam(params->port, &info); 362 } 363 if (stat == 0) { 364 if (info.rx_pause && info.tx_pause) 365 printf("Port %i: Tx & Rx Paused\n", params->port); 366 else if (info.rx_pause) 367 printf("Port %i: Rx Paused\n", params->port); 368 else if (info.tx_pause) 369 printf("Port %i: Tx Paused\n", params->port); 370 else 371 printf("Port %i: Tx & Rx not paused\n", params->port); 372 } else if (stat == -ENOTSUP) 373 printf("Port %i: Operation not supported\n", params->port); 374 else 375 printf("Port %i: Error %i\n", params->port, stat); 376 } 377 378 379 static void 380 pcmd_open_callback(__rte_unused void *ptr_params, 381 __rte_unused struct cmdline *ctx, 382 __rte_unused void *ptr_data) 383 { 384 struct pcmd_int_params *params = ptr_params; 385 int stat; 386 387 if (!rte_eth_dev_is_valid_port(params->port)) { 388 printf("Error: Invalid port number %i\n", params->port); 389 return; 390 } 391 lock_port(params->port); 392 stat = rte_ethtool_net_open(params->port); 393 mark_port_active(params->port); 394 unlock_port(params->port); 395 if (stat == 0) 396 return; 397 else if (stat == -ENOTSUP) 398 printf("Port %i: Operation not supported\n", params->port); 399 else 400 printf("Port %i: Error opening device\n", params->port); 401 } 402 403 static void 404 pcmd_stop_callback(__rte_unused void *ptr_params, 405 __rte_unused struct cmdline *ctx, 406 __rte_unused void *ptr_data) 407 { 408 struct pcmd_int_params *params = ptr_params; 409 int stat; 410 411 if (!rte_eth_dev_is_valid_port(params->port)) { 412 printf("Error: Invalid port number %i\n", params->port); 413 return; 414 } 415 lock_port(params->port); 416 stat = rte_ethtool_net_stop(params->port); 417 mark_port_inactive(params->port); 418 unlock_port(params->port); 419 if (stat == 0) 420 return; 421 else if (stat == -ENOTSUP) 422 printf("Port %i: Operation not supported\n", params->port); 423 else 424 printf("Port %i: Error stopping device\n", params->port); 425 } 426 427 428 static void 429 pcmd_rxmode_callback(void *ptr_params, 430 __rte_unused struct cmdline *ctx, 431 __rte_unused void *ptr_data) 432 { 433 struct pcmd_intstr_params *params = ptr_params; 434 int stat; 435 436 if (!rte_eth_dev_is_valid_port(params->port)) { 437 printf("Error: Invalid port number %i\n", params->port); 438 return; 439 } 440 stat = rte_ethtool_net_set_rx_mode(params->port); 441 if (stat == 0) 442 return; 443 else if (stat == -ENOTSUP) 444 printf("Port %i: Operation not supported\n", params->port); 445 else 446 printf("Port %i: Error setting rx mode\n", params->port); 447 } 448 449 450 static void 451 pcmd_macaddr_callback(void *ptr_params, 452 __rte_unused struct cmdline *ctx, 453 void *ptr_data) 454 { 455 struct pcmd_intmac_params *params = ptr_params; 456 struct ether_addr mac_addr; 457 int stat; 458 459 stat = 0; 460 if (!rte_eth_dev_is_valid_port(params->port)) { 461 printf("Error: Invalid port number %i\n", params->port); 462 return; 463 } 464 if (ptr_data != NULL) { 465 lock_port(params->port); 466 stat = rte_ethtool_net_set_mac_addr(params->port, 467 ¶ms->mac); 468 mark_port_newmac(params->port); 469 unlock_port(params->port); 470 if (stat == 0) { 471 printf("MAC address changed\n"); 472 return; 473 } 474 } else { 475 stat = rte_ethtool_net_get_mac_addr(params->port, &mac_addr); 476 if (stat == 0) { 477 printf( 478 "Port %i MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", 479 params->port, 480 mac_addr.addr_bytes[0], 481 mac_addr.addr_bytes[1], 482 mac_addr.addr_bytes[2], 483 mac_addr.addr_bytes[3], 484 mac_addr.addr_bytes[4], 485 mac_addr.addr_bytes[5]); 486 return; 487 } 488 } 489 490 printf("Port %i: Error %s\n", params->port, 491 strerror(-stat)); 492 } 493 494 static void 495 pcmd_mtu_callback(void *ptr_params, 496 __rte_unused struct cmdline *ctx, 497 __rte_unused void *ptr_data) 498 { 499 struct pcmd_intstr_params *params = ptr_params; 500 int stat; 501 int new_mtu; 502 char *ptr_parse_end; 503 504 if (!rte_eth_dev_is_valid_port(params->port)) { 505 printf("Error: Invalid port number %i\n", params->port); 506 return; 507 } 508 new_mtu = atoi(params->opt); 509 new_mtu = strtoul(params->opt, &ptr_parse_end, 10); 510 if (*ptr_parse_end != '\0' || 511 new_mtu < ETHER_MIN_MTU || 512 new_mtu > ETHER_MAX_JUMBO_FRAME_LEN) { 513 printf("Port %i: Invalid MTU value\n", params->port); 514 return; 515 } 516 stat = rte_ethtool_net_change_mtu(params->port, new_mtu); 517 if (stat == 0) 518 printf("Port %i: MTU set to %i\n", params->port, new_mtu); 519 else if (stat == -ENOTSUP) 520 printf("Port %i: Operation not supported\n", params->port); 521 else 522 printf("Port %i: Error setting MTU\n", params->port); 523 } 524 525 526 527 static void pcmd_portstats_callback(__rte_unused void *ptr_params, 528 __rte_unused struct cmdline *ctx, 529 __rte_unused void *ptr_data) 530 { 531 struct pcmd_int_params *params = ptr_params; 532 struct rte_eth_stats stat_info; 533 int stat; 534 535 if (!rte_eth_dev_is_valid_port(params->port)) { 536 printf("Error: Invalid port number %i\n", params->port); 537 return; 538 } 539 stat = rte_ethtool_net_get_stats64(params->port, &stat_info); 540 if (stat == 0) { 541 printf("Port %i stats\n", params->port); 542 printf(" In: %" PRIu64 " (%" PRIu64 " bytes)\n" 543 " Out: %"PRIu64" (%"PRIu64 " bytes)\n" 544 " Err: %"PRIu64"\n", 545 stat_info.ipackets, 546 stat_info.ibytes, 547 stat_info.opackets, 548 stat_info.obytes, 549 stat_info.ierrors+stat_info.oerrors 550 ); 551 } else if (stat == -ENOTSUP) 552 printf("Port %i: Operation not supported\n", params->port); 553 else 554 printf("Port %i: Error fetching statistics\n", params->port); 555 } 556 557 static void pcmd_ringparam_callback(__rte_unused void *ptr_params, 558 __rte_unused struct cmdline *ctx, 559 void *ptr_data) 560 { 561 struct pcmd_intintint_params *params = ptr_params; 562 struct ethtool_ringparam ring_data; 563 struct ethtool_ringparam ring_params; 564 int stat; 565 566 if (!rte_eth_dev_is_valid_port(params->port)) { 567 printf("Error: Invalid port number %i\n", params->port); 568 return; 569 } 570 if (ptr_data == NULL) { 571 stat = rte_ethtool_get_ringparam(params->port, &ring_data); 572 if (stat == 0) { 573 printf("Port %i ring parameters\n" 574 " Rx Pending: %i (%i max)\n" 575 " Tx Pending: %i (%i max)\n", 576 params->port, 577 ring_data.rx_pending, 578 ring_data.rx_max_pending, 579 ring_data.tx_pending, 580 ring_data.tx_max_pending); 581 } 582 } else { 583 if (params->tx < 1 || params->rx < 1) { 584 printf("Error: Invalid parameters\n"); 585 return; 586 } 587 memset(&ring_params, 0, sizeof(struct ethtool_ringparam)); 588 ring_params.tx_pending = params->tx; 589 ring_params.rx_pending = params->rx; 590 lock_port(params->port); 591 stat = rte_ethtool_set_ringparam(params->port, &ring_params); 592 unlock_port(params->port); 593 } 594 if (stat == 0) 595 return; 596 else if (stat == -ENOTSUP) 597 printf("Port %i: Operation not supported\n", params->port); 598 else 599 printf("Port %i: Error fetching statistics\n", params->port); 600 } 601 602 static void pcmd_validate_callback(void *ptr_params, 603 __rte_unused struct cmdline *ctx, 604 __rte_unused void *ptr_data) 605 { 606 struct pcmd_intmac_params *params = ptr_params; 607 608 if (rte_ethtool_net_validate_addr(0, ¶ms->mac)) 609 printf("Address is unicast\n"); 610 else 611 printf("Address is not unicast\n"); 612 } 613 614 615 static void pcmd_vlan_callback(__rte_unused void *ptr_params, 616 __rte_unused struct cmdline *ctx, 617 __rte_unused void *ptr_data) 618 { 619 struct pcmd_vlan_params *params = ptr_params; 620 int stat; 621 622 if (!rte_eth_dev_is_valid_port(params->port)) { 623 printf("Error: Invalid port number %i\n", params->port); 624 return; 625 } 626 stat = 0; 627 628 if (strcasecmp("add", params->mode) == 0) { 629 stat = rte_ethtool_net_vlan_rx_add_vid( 630 params->port, params->vid 631 ); 632 if (stat == 0) 633 printf("VLAN vid %i added\n", params->vid); 634 635 } else if (strcasecmp("del", params->mode) == 0) { 636 stat = rte_ethtool_net_vlan_rx_kill_vid( 637 params->port, params->vid 638 ); 639 if (stat == 0) 640 printf("VLAN vid %i removed\n", params->vid); 641 } else { 642 /* Should not happen! */ 643 printf("Error: Bad mode %s\n", params->mode); 644 } 645 if (stat == -ENOTSUP) 646 printf("Port %i: Operation not supported\n", params->port); 647 else if (stat == -ENOSYS) 648 printf("Port %i: VLAN filtering disabled\n", params->port); 649 else if (stat != 0) 650 printf("Port %i: Error changing VLAN setup (code %i)\n", 651 params->port, -stat); 652 } 653 654 655 cmdline_parse_inst_t pcmd_quit = { 656 .f = pcmd_quit_callback, 657 .data = NULL, 658 .help_str = "quit\n Exit program", 659 .tokens = {(void *)&pcmd_quit_token_cmd, NULL}, 660 }; 661 cmdline_parse_inst_t pcmd_drvinfo = { 662 .f = pcmd_drvinfo_callback, 663 .data = NULL, 664 .help_str = "drvinfo\n Print driver info", 665 .tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL}, 666 }; 667 cmdline_parse_inst_t pcmd_link = { 668 .f = pcmd_link_callback, 669 .data = NULL, 670 .help_str = "link\n Print port link states", 671 .tokens = {(void *)&pcmd_link_token_cmd, NULL}, 672 }; 673 cmdline_parse_inst_t pcmd_regs = { 674 .f = pcmd_regs_callback, 675 .data = NULL, 676 .help_str = "regs <port_id> <filename>\n" 677 " Dump port register(s) to file", 678 .tokens = { 679 (void *)&pcmd_regs_token_cmd, 680 (void *)&pcmd_intstr_token_port, 681 (void *)&pcmd_intstr_token_opt, 682 NULL 683 }, 684 }; 685 cmdline_parse_inst_t pcmd_eeprom = { 686 .f = pcmd_eeprom_callback, 687 .data = NULL, 688 .help_str = "eeprom <port_id> <filename>\n Dump EEPROM to file", 689 .tokens = { 690 (void *)&pcmd_eeprom_token_cmd, 691 (void *)&pcmd_intstr_token_port, 692 (void *)&pcmd_intstr_token_opt, 693 NULL 694 }, 695 }; 696 cmdline_parse_inst_t pcmd_pause_noopt = { 697 .f = pcmd_pause_callback, 698 .data = (void *)0x01, 699 .help_str = "pause <port_id>\n Print port pause state", 700 .tokens = { 701 (void *)&pcmd_pause_token_cmd, 702 (void *)&pcmd_pause_token_port, 703 NULL 704 }, 705 }; 706 cmdline_parse_inst_t pcmd_pause = { 707 .f = pcmd_pause_callback, 708 .data = NULL, 709 .help_str = 710 "pause <port_id> <all|tx|rx|none>\n Pause/unpause port", 711 .tokens = { 712 (void *)&pcmd_pause_token_cmd, 713 (void *)&pcmd_pause_token_port, 714 (void *)&pcmd_pause_token_opt, 715 NULL 716 }, 717 }; 718 cmdline_parse_inst_t pcmd_open = { 719 .f = pcmd_open_callback, 720 .data = NULL, 721 .help_str = "open <port_id>\n Open port", 722 .tokens = { 723 (void *)&pcmd_open_token_cmd, 724 (void *)&pcmd_int_token_port, 725 NULL 726 }, 727 }; 728 cmdline_parse_inst_t pcmd_stop = { 729 .f = pcmd_stop_callback, 730 .data = NULL, 731 .help_str = "stop <port_id>\n Stop port", 732 .tokens = { 733 (void *)&pcmd_stop_token_cmd, 734 (void *)&pcmd_int_token_port, 735 NULL 736 }, 737 }; 738 cmdline_parse_inst_t pcmd_rxmode = { 739 .f = pcmd_rxmode_callback, 740 .data = NULL, 741 .help_str = "rxmode <port_id>\n Toggle port Rx mode", 742 .tokens = { 743 (void *)&pcmd_rxmode_token_cmd, 744 (void *)&pcmd_int_token_port, 745 NULL 746 }, 747 }; 748 cmdline_parse_inst_t pcmd_macaddr_get = { 749 .f = pcmd_macaddr_callback, 750 .data = NULL, 751 .help_str = "macaddr <port_id>\n" 752 " Get MAC address", 753 .tokens = { 754 (void *)&pcmd_macaddr_token_cmd, 755 (void *)&pcmd_intstr_token_port, 756 NULL 757 }, 758 }; 759 cmdline_parse_inst_t pcmd_macaddr = { 760 .f = pcmd_macaddr_callback, 761 .data = (void *)0x01, 762 .help_str = 763 "macaddr <port_id> <mac_addr>\n" 764 " Set MAC address", 765 .tokens = { 766 (void *)&pcmd_macaddr_token_cmd, 767 (void *)&pcmd_intmac_token_port, 768 (void *)&pcmd_intmac_token_mac, 769 NULL 770 }, 771 }; 772 cmdline_parse_inst_t pcmd_mtu = { 773 .f = pcmd_mtu_callback, 774 .data = NULL, 775 .help_str = "mtu <port_id> <mtu_value>\n" 776 " Change MTU", 777 .tokens = { 778 (void *)&pcmd_mtu_token_cmd, 779 (void *)&pcmd_intstr_token_port, 780 (void *)&pcmd_intstr_token_opt, 781 NULL 782 }, 783 }; 784 cmdline_parse_inst_t pcmd_portstats = { 785 .f = pcmd_portstats_callback, 786 .data = NULL, 787 .help_str = "portstats <port_id>\n" 788 " Print port eth statistics", 789 .tokens = { 790 (void *)&pcmd_portstats_token_cmd, 791 (void *)&pcmd_int_token_port, 792 NULL 793 }, 794 }; 795 cmdline_parse_inst_t pcmd_ringparam = { 796 .f = pcmd_ringparam_callback, 797 .data = NULL, 798 .help_str = "ringparam <port_id>\n" 799 " Print ring parameters", 800 .tokens = { 801 (void *)&pcmd_ringparam_token_cmd, 802 (void *)&pcmd_intintint_token_port, 803 NULL 804 }, 805 }; 806 cmdline_parse_inst_t pcmd_ringparam_set = { 807 .f = pcmd_ringparam_callback, 808 .data = (void *)1, 809 .help_str = "ringparam <port_id> <tx_param> <rx_param>\n" 810 " Set ring parameters", 811 .tokens = { 812 (void *)&pcmd_ringparam_token_cmd, 813 (void *)&pcmd_intintint_token_port, 814 (void *)&pcmd_intintint_token_tx, 815 (void *)&pcmd_intintint_token_rx, 816 NULL 817 }, 818 }; 819 cmdline_parse_inst_t pcmd_validate = { 820 .f = pcmd_validate_callback, 821 .data = NULL, 822 .help_str = "validate <mac_addr>\n" 823 " Check that MAC address is valid unicast address", 824 .tokens = { 825 (void *)&pcmd_validate_token_cmd, 826 (void *)&pcmd_intmac_token_mac, 827 NULL 828 }, 829 }; 830 cmdline_parse_inst_t pcmd_vlan = { 831 .f = pcmd_vlan_callback, 832 .data = NULL, 833 .help_str = "vlan <port_id> <add|del> <vlan_id>\n" 834 " Add/remove VLAN id", 835 .tokens = { 836 (void *)&pcmd_vlan_token_cmd, 837 (void *)&pcmd_vlan_token_port, 838 (void *)&pcmd_vlan_token_mode, 839 (void *)&pcmd_vlan_token_vid, 840 NULL 841 }, 842 }; 843 844 845 cmdline_parse_ctx_t list_prompt_commands[] = { 846 (cmdline_parse_inst_t *)&pcmd_drvinfo, 847 (cmdline_parse_inst_t *)&pcmd_eeprom, 848 (cmdline_parse_inst_t *)&pcmd_link, 849 (cmdline_parse_inst_t *)&pcmd_macaddr_get, 850 (cmdline_parse_inst_t *)&pcmd_macaddr, 851 (cmdline_parse_inst_t *)&pcmd_mtu, 852 (cmdline_parse_inst_t *)&pcmd_open, 853 (cmdline_parse_inst_t *)&pcmd_pause_noopt, 854 (cmdline_parse_inst_t *)&pcmd_pause, 855 (cmdline_parse_inst_t *)&pcmd_portstats, 856 (cmdline_parse_inst_t *)&pcmd_regs, 857 (cmdline_parse_inst_t *)&pcmd_ringparam, 858 (cmdline_parse_inst_t *)&pcmd_ringparam_set, 859 (cmdline_parse_inst_t *)&pcmd_rxmode, 860 (cmdline_parse_inst_t *)&pcmd_stop, 861 (cmdline_parse_inst_t *)&pcmd_validate, 862 (cmdline_parse_inst_t *)&pcmd_vlan, 863 (cmdline_parse_inst_t *)&pcmd_quit, 864 NULL 865 }; 866 867 868 void ethapp_main(void) 869 { 870 struct cmdline *ctx_cmdline; 871 872 ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> "); 873 cmdline_interact(ctx_cmdline); 874 cmdline_stdin_exit(ctx_cmdline); 875 } 876