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