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