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