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