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: " RTE_ETHER_ADDR_PRT_FMT "\n", 502 params->port, RTE_ETHER_ADDR_BYTES(&mac_addr)); 503 return; 504 } 505 } 506 507 printf("Port %i: Error %s\n", params->port, 508 strerror(-stat)); 509 } 510 511 static void 512 pcmd_mtu_callback(void *ptr_params, 513 __rte_unused struct cmdline *ctx, 514 __rte_unused void *ptr_data) 515 { 516 struct pcmd_intstr_params *params = ptr_params; 517 int stat; 518 int new_mtu; 519 char *ptr_parse_end; 520 521 if (!rte_eth_dev_is_valid_port(params->port)) { 522 printf("Error: Invalid port number %i\n", params->port); 523 return; 524 } 525 new_mtu = strtoul(params->opt, &ptr_parse_end, 10); 526 if (*ptr_parse_end != '\0' || 527 new_mtu < RTE_ETHER_MIN_MTU || 528 new_mtu > RTE_ETHER_MAX_JUMBO_FRAME_LEN) { 529 printf("Port %i: Invalid MTU value\n", params->port); 530 return; 531 } 532 stat = rte_ethtool_net_change_mtu(params->port, new_mtu); 533 if (stat == 0) 534 printf("Port %i: MTU set to %i\n", params->port, new_mtu); 535 else if (stat == -ENOTSUP) 536 printf("Port %i: Operation not supported\n", params->port); 537 else 538 printf("Port %i: Error setting MTU\n", params->port); 539 } 540 541 542 543 static void pcmd_portstats_callback(__rte_unused void *ptr_params, 544 __rte_unused struct cmdline *ctx, 545 __rte_unused void *ptr_data) 546 { 547 struct pcmd_int_params *params = ptr_params; 548 struct rte_eth_stats stat_info; 549 int stat; 550 551 if (!rte_eth_dev_is_valid_port(params->port)) { 552 printf("Error: Invalid port number %i\n", params->port); 553 return; 554 } 555 stat = rte_ethtool_net_get_stats64(params->port, &stat_info); 556 if (stat == 0) { 557 printf("Port %i stats\n", params->port); 558 printf(" In: %" PRIu64 " (%" PRIu64 " bytes)\n" 559 " Out: %"PRIu64" (%"PRIu64 " bytes)\n" 560 " Err: %"PRIu64"\n", 561 stat_info.ipackets, 562 stat_info.ibytes, 563 stat_info.opackets, 564 stat_info.obytes, 565 stat_info.ierrors+stat_info.oerrors 566 ); 567 } else if (stat == -ENOTSUP) 568 printf("Port %i: Operation not supported\n", params->port); 569 else 570 printf("Port %i: Error fetching statistics\n", params->port); 571 } 572 573 static void pcmd_ringparam_callback(__rte_unused void *ptr_params, 574 __rte_unused struct cmdline *ctx, 575 void *ptr_data) 576 { 577 struct pcmd_intintint_params *params = ptr_params; 578 struct ethtool_ringparam ring_data; 579 struct ethtool_ringparam ring_params; 580 int stat; 581 582 if (!rte_eth_dev_is_valid_port(params->port)) { 583 printf("Error: Invalid port number %i\n", params->port); 584 return; 585 } 586 if (ptr_data == NULL) { 587 stat = rte_ethtool_get_ringparam(params->port, &ring_data); 588 if (stat == 0) { 589 printf("Port %i ring parameters\n" 590 " Rx Pending: %i (%i max)\n" 591 " Tx Pending: %i (%i max)\n", 592 params->port, 593 ring_data.rx_pending, 594 ring_data.rx_max_pending, 595 ring_data.tx_pending, 596 ring_data.tx_max_pending); 597 } 598 } else { 599 if (params->tx < 1 || params->rx < 1) { 600 printf("Error: Invalid parameters\n"); 601 return; 602 } 603 memset(&ring_params, 0, sizeof(struct ethtool_ringparam)); 604 ring_params.tx_pending = params->tx; 605 ring_params.rx_pending = params->rx; 606 lock_port(params->port); 607 stat = rte_ethtool_set_ringparam(params->port, &ring_params); 608 unlock_port(params->port); 609 } 610 if (stat == 0) 611 return; 612 else if (stat == -ENOTSUP) 613 printf("Port %i: Operation not supported\n", params->port); 614 else 615 printf("Port %i: Error fetching statistics\n", params->port); 616 } 617 618 static void pcmd_validate_callback(void *ptr_params, 619 __rte_unused struct cmdline *ctx, 620 __rte_unused void *ptr_data) 621 { 622 struct pcmd_intmac_params *params = ptr_params; 623 624 if (rte_ethtool_net_validate_addr(0, ¶ms->mac)) 625 printf("Address is unicast\n"); 626 else 627 printf("Address is not unicast\n"); 628 } 629 630 631 static void pcmd_vlan_callback(__rte_unused void *ptr_params, 632 __rte_unused struct cmdline *ctx, 633 __rte_unused void *ptr_data) 634 { 635 struct pcmd_vlan_params *params = ptr_params; 636 int stat; 637 638 if (!rte_eth_dev_is_valid_port(params->port)) { 639 printf("Error: Invalid port number %i\n", params->port); 640 return; 641 } 642 stat = 0; 643 644 if (strcasecmp("add", params->mode) == 0) { 645 stat = rte_ethtool_net_vlan_rx_add_vid( 646 params->port, params->vid 647 ); 648 if (stat == 0) 649 printf("VLAN vid %i added\n", params->vid); 650 651 } else if (strcasecmp("del", params->mode) == 0) { 652 stat = rte_ethtool_net_vlan_rx_kill_vid( 653 params->port, params->vid 654 ); 655 if (stat == 0) 656 printf("VLAN vid %i removed\n", params->vid); 657 } else { 658 /* Should not happen! */ 659 printf("Error: Bad mode %s\n", params->mode); 660 } 661 if (stat == -ENOTSUP) 662 printf("Port %i: Operation not supported\n", params->port); 663 else if (stat == -ENOSYS) 664 printf("Port %i: VLAN filtering disabled\n", params->port); 665 else if (stat != 0) 666 printf("Port %i: Error changing VLAN setup (code %i)\n", 667 params->port, -stat); 668 } 669 670 671 cmdline_parse_inst_t pcmd_quit = { 672 .f = pcmd_quit_callback, 673 .data = NULL, 674 .help_str = "quit\n Exit program", 675 .tokens = {(void *)&pcmd_quit_token_cmd, NULL}, 676 }; 677 cmdline_parse_inst_t pcmd_drvinfo = { 678 .f = pcmd_drvinfo_callback, 679 .data = NULL, 680 .help_str = "drvinfo\n Print driver info", 681 .tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL}, 682 }; 683 cmdline_parse_inst_t pcmd_link = { 684 .f = pcmd_link_callback, 685 .data = NULL, 686 .help_str = "link\n Print port link states", 687 .tokens = {(void *)&pcmd_link_token_cmd, NULL}, 688 }; 689 cmdline_parse_inst_t pcmd_regs = { 690 .f = pcmd_regs_callback, 691 .data = NULL, 692 .help_str = "regs <port_id> <filename>\n" 693 " Dump port register(s) to file", 694 .tokens = { 695 (void *)&pcmd_regs_token_cmd, 696 (void *)&pcmd_intstr_token_port, 697 (void *)&pcmd_intstr_token_opt, 698 NULL 699 }, 700 }; 701 cmdline_parse_inst_t pcmd_eeprom = { 702 .f = pcmd_eeprom_callback, 703 .data = NULL, 704 .help_str = "eeprom <port_id> <filename>\n Dump EEPROM to file", 705 .tokens = { 706 (void *)&pcmd_eeprom_token_cmd, 707 (void *)&pcmd_intstr_token_port, 708 (void *)&pcmd_intstr_token_opt, 709 NULL 710 }, 711 }; 712 cmdline_parse_inst_t pcmd_module_eeprom = { 713 .f = pcmd_module_eeprom_callback, 714 .data = NULL, 715 .help_str = "module-eeprom <port_id> <filename>\n" 716 " Dump plugin module EEPROM to file", 717 .tokens = { 718 (void *)&pcmd_module_eeprom_token_cmd, 719 (void *)&pcmd_intstr_token_port, 720 (void *)&pcmd_intstr_token_opt, 721 NULL 722 }, 723 }; 724 cmdline_parse_inst_t pcmd_pause_noopt = { 725 .f = pcmd_pause_callback, 726 .data = (void *)0x01, 727 .help_str = "pause <port_id>\n Print port pause state", 728 .tokens = { 729 (void *)&pcmd_pause_token_cmd, 730 (void *)&pcmd_pause_token_port, 731 NULL 732 }, 733 }; 734 cmdline_parse_inst_t pcmd_pause = { 735 .f = pcmd_pause_callback, 736 .data = NULL, 737 .help_str = 738 "pause <port_id> <all|tx|rx|none>\n Pause/unpause port", 739 .tokens = { 740 (void *)&pcmd_pause_token_cmd, 741 (void *)&pcmd_pause_token_port, 742 (void *)&pcmd_pause_token_opt, 743 NULL 744 }, 745 }; 746 cmdline_parse_inst_t pcmd_open = { 747 .f = pcmd_open_callback, 748 .data = NULL, 749 .help_str = "open <port_id>\n Open port", 750 .tokens = { 751 (void *)&pcmd_open_token_cmd, 752 (void *)&pcmd_int_token_port, 753 NULL 754 }, 755 }; 756 cmdline_parse_inst_t pcmd_stop = { 757 .f = pcmd_stop_callback, 758 .data = NULL, 759 .help_str = "stop <port_id>\n Stop port", 760 .tokens = { 761 (void *)&pcmd_stop_token_cmd, 762 (void *)&pcmd_int_token_port, 763 NULL 764 }, 765 }; 766 cmdline_parse_inst_t pcmd_rxmode = { 767 .f = pcmd_rxmode_callback, 768 .data = NULL, 769 .help_str = "rxmode <port_id>\n Toggle port Rx mode", 770 .tokens = { 771 (void *)&pcmd_rxmode_token_cmd, 772 (void *)&pcmd_int_token_port, 773 NULL 774 }, 775 }; 776 cmdline_parse_inst_t pcmd_macaddr_get = { 777 .f = pcmd_macaddr_callback, 778 .data = NULL, 779 .help_str = "macaddr <port_id>\n" 780 " Get MAC address", 781 .tokens = { 782 (void *)&pcmd_macaddr_token_cmd, 783 (void *)&pcmd_intstr_token_port, 784 NULL 785 }, 786 }; 787 cmdline_parse_inst_t pcmd_macaddr = { 788 .f = pcmd_macaddr_callback, 789 .data = (void *)0x01, 790 .help_str = 791 "macaddr <port_id> <mac_addr>\n" 792 " Set MAC address", 793 .tokens = { 794 (void *)&pcmd_macaddr_token_cmd, 795 (void *)&pcmd_intmac_token_port, 796 (void *)&pcmd_intmac_token_mac, 797 NULL 798 }, 799 }; 800 cmdline_parse_inst_t pcmd_mtu = { 801 .f = pcmd_mtu_callback, 802 .data = NULL, 803 .help_str = "mtu <port_id> <mtu_value>\n" 804 " Change MTU", 805 .tokens = { 806 (void *)&pcmd_mtu_token_cmd, 807 (void *)&pcmd_intstr_token_port, 808 (void *)&pcmd_intstr_token_opt, 809 NULL 810 }, 811 }; 812 cmdline_parse_inst_t pcmd_portstats = { 813 .f = pcmd_portstats_callback, 814 .data = NULL, 815 .help_str = "portstats <port_id>\n" 816 " Print port eth statistics", 817 .tokens = { 818 (void *)&pcmd_portstats_token_cmd, 819 (void *)&pcmd_int_token_port, 820 NULL 821 }, 822 }; 823 cmdline_parse_inst_t pcmd_ringparam = { 824 .f = pcmd_ringparam_callback, 825 .data = NULL, 826 .help_str = "ringparam <port_id>\n" 827 " Print ring parameters", 828 .tokens = { 829 (void *)&pcmd_ringparam_token_cmd, 830 (void *)&pcmd_intintint_token_port, 831 NULL 832 }, 833 }; 834 cmdline_parse_inst_t pcmd_ringparam_set = { 835 .f = pcmd_ringparam_callback, 836 .data = (void *)1, 837 .help_str = "ringparam <port_id> <tx_param> <rx_param>\n" 838 " Set ring parameters", 839 .tokens = { 840 (void *)&pcmd_ringparam_token_cmd, 841 (void *)&pcmd_intintint_token_port, 842 (void *)&pcmd_intintint_token_tx, 843 (void *)&pcmd_intintint_token_rx, 844 NULL 845 }, 846 }; 847 cmdline_parse_inst_t pcmd_validate = { 848 .f = pcmd_validate_callback, 849 .data = NULL, 850 .help_str = "validate <mac_addr>\n" 851 " Check that MAC address is valid unicast address", 852 .tokens = { 853 (void *)&pcmd_validate_token_cmd, 854 (void *)&pcmd_intmac_token_mac, 855 NULL 856 }, 857 }; 858 cmdline_parse_inst_t pcmd_vlan = { 859 .f = pcmd_vlan_callback, 860 .data = NULL, 861 .help_str = "vlan <port_id> <add|del> <vlan_id>\n" 862 " Add/remove VLAN id", 863 .tokens = { 864 (void *)&pcmd_vlan_token_cmd, 865 (void *)&pcmd_vlan_token_port, 866 (void *)&pcmd_vlan_token_mode, 867 (void *)&pcmd_vlan_token_vid, 868 NULL 869 }, 870 }; 871 872 873 cmdline_parse_ctx_t list_prompt_commands[] = { 874 (cmdline_parse_inst_t *)&pcmd_drvinfo, 875 (cmdline_parse_inst_t *)&pcmd_eeprom, 876 (cmdline_parse_inst_t *)&pcmd_module_eeprom, 877 (cmdline_parse_inst_t *)&pcmd_link, 878 (cmdline_parse_inst_t *)&pcmd_macaddr_get, 879 (cmdline_parse_inst_t *)&pcmd_macaddr, 880 (cmdline_parse_inst_t *)&pcmd_mtu, 881 (cmdline_parse_inst_t *)&pcmd_open, 882 (cmdline_parse_inst_t *)&pcmd_pause_noopt, 883 (cmdline_parse_inst_t *)&pcmd_pause, 884 (cmdline_parse_inst_t *)&pcmd_portstats, 885 (cmdline_parse_inst_t *)&pcmd_regs, 886 (cmdline_parse_inst_t *)&pcmd_ringparam, 887 (cmdline_parse_inst_t *)&pcmd_ringparam_set, 888 (cmdline_parse_inst_t *)&pcmd_rxmode, 889 (cmdline_parse_inst_t *)&pcmd_stop, 890 (cmdline_parse_inst_t *)&pcmd_validate, 891 (cmdline_parse_inst_t *)&pcmd_vlan, 892 (cmdline_parse_inst_t *)&pcmd_quit, 893 NULL 894 }; 895 896 897 void ethapp_main(void) 898 { 899 struct cmdline *ctx_cmdline; 900 901 ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> "); 902 cmdline_interact(ctx_cmdline); 903 cmdline_stdin_exit(ctx_cmdline); 904 } 905