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