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