field.c (41846B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: field.c 8 * Purpose: BCMX Field commands 9 */ 10 11 #include <sal/appl/io.h> 12 #include <shared/bsl.h> 13 #include <bcm/error.h> 14 15 #include <bcmx/bcmx.h> 16 #include <bcmx/field.h> 17 18 #include <appl/diag/shell.h> 19 #include <appl/diag/system.h> 20 #include <appl/diag/parse.h> 21 22 #ifdef INCLUDE_BCMX 23 24 #include "bcmx.h" 25 #include <appl/diag/diag.h> 26 27 #ifdef BCM_FIELD_SUPPORT 28 29 char bcmx_cmd_field_usage[] = 30 "\n" 31 #ifdef COMPILER_STRING_CONST_LIMIT 32 " field {action | counter | entry | group | list| init | meter | qset} " 33 "<args>\n" 34 #else 35 " field action {add | remove | show} <args> " 36 "- Set actions for a field entry\n" 37 " field counter {create | destroy | set | " 38 "- Manage a field counter\n" 39 " share | show} <args>\n" 40 " field entry {copy | create | destroy | " 41 "- Manage a field entry\n" 42 " install | qualify |\n" 43 " reinstall | remove} <args>\n" 44 " field group {create | destroy | " 45 "- Manage a field group\n" 46 " set | show} <args>\n" 47 " field list {actions | qualifiers} " 48 "- Display action or qualifier names\n" 49 " field init " 50 "- Initialize the Field subsystem\n" 51 " field range {create | show | destroy} " 52 "- Manage a TCP/UDP port range checker\n" 53 " field meter {create | destroy | set | " 54 "- Manage a field meter\n" 55 " share | show} <args>\n" 56 " field qset {create | destroy | set | " 57 "- Manage a field qualifier set\n" 58 " show} <args>\n" 59 #endif 60 ; 61 62 static cmd_result_t action_cmd(int unit, args_t *args); 63 static cmd_result_t action_add_cmd(int unit, args_t *args); 64 static cmd_result_t action_remove_cmd(int unit, args_t *args); 65 static cmd_result_t action_show_cmd(int unit, args_t *args); 66 67 static cmd_result_t entry_cmd(int unit, args_t *args); 68 static cmd_result_t entry_copy_cmd(int unit, args_t *args); 69 static cmd_result_t entry_create_cmd(int unit, args_t *args); 70 static cmd_result_t entry_destroy_cmd(int unit, args_t *args); 71 static cmd_result_t entry_install_cmd(int unit, args_t *args); 72 static cmd_result_t entry_qualify_cmd(int unit, args_t *args); 73 static cmd_result_t entry_reinstall_cmd(int unit, args_t *args); 74 static cmd_result_t entry_remove_cmd(int unit, args_t *args); 75 76 static cmd_result_t group_cmd(int unit, args_t *args); 77 static cmd_result_t group_create_cmd(int unit, args_t *args); 78 static cmd_result_t group_destroy_cmd(int unit, args_t *args); 79 static cmd_result_t group_set_cmd(int unit, args_t *args); 80 static cmd_result_t group_show_cmd(int unit, args_t *args); 81 82 static cmd_result_t init_cmd(int unit, args_t *args); 83 84 static cmd_result_t list_cmd(int unit, args_t *args); 85 static cmd_result_t list_actions_cmd(int unit, args_t *args); 86 static cmd_result_t list_quals_cmd(int unit, args_t *args); 87 88 static cmd_result_t range_cmd(int unit, args_t *args); 89 90 static cmd_result_t qset_cmd(int unit, args_t *args); 91 static cmd_result_t qset_create_cmd(int unit, args_t *args); 92 static cmd_result_t qset_destroy_cmd(int unit, args_t *args); 93 static cmd_result_t qset_set_cmd(int unit, args_t *args); 94 static cmd_result_t qset_show_cmd(int unit, args_t *args); 95 96 static cmd_t field_cmd_list[] = { 97 {"Action", action_cmd, 98 "field action {add | remove | show} <args>", 99 "Set actions for a field processor entry."}, 100 {"Entry", entry_cmd, 101 "field entry {copy | create | destroy | install | qualify |\n" 102 " reinstall | remove} <args>", 103 "Manage a field processor entry."}, 104 105 {"Group", group_cmd, 106 "field group {create | destroy | set | show} <args>", 107 "Manage a field processor group."}, 108 109 {"Init", init_cmd, 110 "field init", 111 "Initialize the Field Processor subsystem."}, 112 113 {"List", list_cmd, 114 "field list {actions | qualifiers}", 115 "List action or qualfier names"}, 116 117 {"Range", range_cmd, 118 "field range {create <flags> [Min= ] [Max= ] | show <range-id> | destroy <range-id>} ", 119 "Create, destroy or display range checks."}, 120 {"QSET", qset_cmd, 121 "field qset {create | destroy | set | show} <args>", 122 "Manage a field qualifier set."} 123 }; 124 125 static cmd_t field_action_cmd_list[] = { 126 {"Add", action_add_cmd, 127 "field action add <entry-id> Action=<action-name> Param0=<value> " 128 "Param1=<value>", 129 "Add an action for the specified field entry."}, 130 131 {"Remove", action_remove_cmd, 132 "field action remove <entry-id> Action=<action-name>", 133 "Remove the action(s) from the specified field entry."}, 134 135 {"SHOW", action_show_cmd, 136 "field action show <entry-id> Action=<action-name>", 137 "Display the parameter values of the specified action for a field entry."} 138 }; 139 140 static cmd_t field_entry_cmd_list[] = { 141 {"CoPy", entry_copy_cmd, 142 "field entry copy <entry-id>", 143 "Create a copy of an existing field entry."}, 144 145 {"Create", entry_create_cmd, 146 "field entry create <group-id>", 147 "Create an empty field entry based on a field group."}, 148 149 {"Destroy", entry_destroy_cmd, 150 "field entry destroy {<entry-id> | ALL}", 151 "Destroy a field entry or all existing field entries."}, 152 153 {"Install", entry_install_cmd, 154 "field entry install <entry-id>", 155 "Install a field entry into the hardware tables."}, 156 157 {"Qualify", entry_qualify_cmd, 158 "field entry qualify <entry-id> FieldQualifier=<qualifier-name>\n" 159 " <data> [<mask>]", 160 "Set data and mask for the specified field qualifier."}, 161 162 {"ReInstall", entry_reinstall_cmd, 163 "field entry reinstall <entry-id>", 164 "Re-install a field entry into the hardware tables."}, 165 166 {"ReMove", entry_remove_cmd, 167 "field entry remove <entry-id>", 168 "Remove a field entry from the hardware tables."} 169 }; 170 171 static cmd_t field_group_cmd_list[] = { 172 {"Create", group_create_cmd, 173 "field group create QSET=<qset-number> PRI=<number>", 174 "Create a field group with specified priority and qualifier set."}, 175 176 {"Destroy", group_destroy_cmd, 177 "field group destroy <group-id>", 178 "Deallocate a field group. All entries for this\n" 179 " group must have been previously destroyed."}, 180 181 {"Set", group_set_cmd, 182 "field group set <group-id> QSET=<qset-number>", 183 "Set the qualifier set for a field group."}, 184 185 {"SHOW", group_show_cmd, 186 "field group show <group-id>", 187 "Display the qualifier set for a field group."} 188 }; 189 190 static cmd_t field_list_cmd_list[] = { 191 {"ACTions", list_actions_cmd, 192 "field list actions", 193 "Display Field actions."}, 194 195 {"QUALifiers", list_quals_cmd, 196 "field list qualifiers", 197 "Display Field qualifiers."}, 198 }; 199 200 static cmd_t field_qset_cmd_list[] = { 201 {"Create", qset_create_cmd, 202 "field qset create", 203 "Create a field qualifier set. No field qualifier will be selected\n" 204 " for the new set."}, 205 206 {"Destroy", qset_destroy_cmd, 207 "field qset destroy <qset-number>", 208 "Destroys a field qualifier set."}, 209 210 {"Set", qset_set_cmd, 211 "field qset set <qset-number> {<qualifier-name>=<on|off> ...}", 212 "Set or clear field qualifiers for the specified field qualifier set.\n" 213 " One or more qualifiers can be specified. Qualifiers not\n" 214 " specified are left unchanged."}, 215 216 {"SHOW", qset_show_cmd, 217 "field qset show <qset-number>", 218 "Display a field qualifier set attributes."} 219 }; 220 221 222 /* Static Globals and Defines */ 223 224 /* FP Qualifiers */ 225 #define FP_QUALIFIER_CNT bcmFieldQualifyCount 226 static char *fp_qualifier_names[FP_QUALIFIER_CNT+1] = BCM_FIELD_QUALIFY_STRINGS; 227 #define FP_QUALIFIER_NAME_GET(qid) \ 228 ((((qid) < 0) || ((qid) >= FP_QUALIFIER_CNT)) ? \ 229 NULL : fp_qualifier_names[qid]) 230 231 /* FP Actions */ 232 #define FP_ACTION_CNT bcmFieldActionCount 233 static char *fp_action_names[FP_ACTION_CNT+1] = BCM_FIELD_ACTION_STRINGS; 234 #define FP_ACTION_NAME_GET(action) \ 235 ((((action) < 0) || ((action) >= FP_ACTION_CNT)) ? \ 236 NULL : fp_action_names[action]) 237 238 /* 239 * Table: 240 * Array of SETS of field qualifier. 241 * Element: 242 * A set of field qualifiers contains the selection of qualifiers 243 * for the the specified set, and a flag indicating if the set was 244 * created. 245 */ 246 typedef struct fp_qset_s { 247 bcm_field_qset_t qset; 248 int created; /* Qset is used and create */ 249 } fp_qset_t; 250 251 #define MAX_QSETS 100 252 static fp_qset_t fp_qset_tbl[MAX_QSETS]; 253 254 255 /* 256 * Function: 257 * get_integer 258 * Purpose: 259 * Gets an integer value from a string, and, if specified, 260 * checks that value is within allowed range. 261 * Parameters: 262 * cmd - Command name string 263 * subcmd_str - Subcommand name string 264 * param - String that contains number to be parsed 265 * number - Returns number parsed 266 * number_str - Name of number (to use when displaying error message) 267 * check_range - Indicates whether to check value within range 268 * min - Minimum value allowed 269 * max - Maximum value allowed 270 * Returns: 271 * CMD_OK - Success, valid integer 272 * CMD_FAIL - Failure, could not parse integer from string, 273 * or value is out of range. 274 */ 275 static cmd_result_t 276 get_integer(char *cmd, char *subcmd_str, 277 char *param, int *number, char *number_str, 278 int check_range, int min, int max) 279 { 280 if (param == NULL) { 281 sal_printf("%s: Need %s\n", cmd, number_str); 282 return CMD_FAIL; 283 } 284 285 if (!isint(param)) { 286 sal_printf("%s: Invalid %s '%s'\n", cmd, number_str, param); 287 return CMD_FAIL; 288 } 289 *number = parse_integer(param); 290 291 if (check_range) { 292 if ((*number < min) || (*number > max)) { 293 sal_printf("%s: %s failed: %s must be %d..%d\n", 294 cmd, subcmd_str, number_str, min, max); 295 return CMD_FAIL; 296 } 297 } 298 299 return CMD_OK; 300 } 301 302 303 static void 304 display_qset(bcm_field_qset_t qset) 305 { 306 bcm_field_qualify_t qid; 307 char *qname_ptr; 308 char *set = "X"; 309 char *clear = "-"; 310 char *str; 311 int num_qualifiers_row = 3; 312 313 sal_printf(" Qualifier settings ('X'= set '-'= clear)\n"); 314 sal_printf(" +---------------------+---------------------+" 315 "---------------------+"); 316 317 for (qid = (bcm_field_qualify_t)0; qid < FP_QUALIFIER_CNT; qid++) { 318 if ((qname_ptr = FP_QUALIFIER_NAME_GET(qid)) == NULL) { 319 sal_printf("Could not find qualifier=%d\n", qid); 320 continue; 321 } 322 323 if ((qid % num_qualifiers_row) == 0) { 324 sal_printf("\n |"); 325 } 326 if (BCM_FIELD_QSET_TEST(qset, qid)) { 327 str = set; 328 } else { 329 str = clear; 330 } 331 sal_printf(" %-18s%1s |", qname_ptr, str); 332 } 333 334 while ((qid++ % num_qualifiers_row) != 0) { 335 sal_printf("%21s|", " "); 336 } 337 sal_printf("\n +---------------------+---------------------+" 338 "---------------------+\n\n"); 339 340 return; 341 } 342 343 cmd_result_t 344 bcmx_cmd_field(int unit, args_t *args) 345 { 346 static int first_time = TRUE; 347 348 if (first_time) { 349 memset(fp_qset_tbl, 0, sizeof(fp_qset_tbl)); 350 fp_qualifier_names[FP_QUALIFIER_CNT] = NULL; 351 fp_action_names[FP_ACTION_CNT] = NULL; 352 first_time = FALSE; 353 } 354 355 return subcommand_execute(unit, args, 356 field_cmd_list, COUNTOF(field_cmd_list)); 357 } 358 359 static cmd_result_t 360 init_cmd(int unit, args_t *args) 361 { 362 int rv; 363 char *cmd; 364 365 cmd = ARG_CMD(args); 366 367 if (ARG_CNT(args)) { 368 sal_printf("%s: Invalid option %s\n", cmd, ARG_CUR(args)); 369 return CMD_FAIL; 370 } 371 372 rv = bcmx_field_init(); 373 374 if (BCM_FAILURE(rv)) { 375 sal_printf("%s: Subsystem initialization failed: %s\n", cmd, 376 bcm_errmsg(rv)); 377 return CMD_FAIL; 378 } 379 380 return CMD_OK; 381 } 382 383 static cmd_result_t 384 list_cmd(int unit, args_t *args) 385 { 386 return subcommand_execute(unit, args, 387 field_list_cmd_list, 388 COUNTOF(field_list_cmd_list)); 389 } 390 391 static cmd_result_t 392 list_actions_cmd(int unit, args_t *args) 393 { 394 bcm_field_action_t action; 395 char buf[BCM_FIELD_ACTION_WIDTH_MAX]; 396 397 for (action = (bcm_field_action_t)0; action < bcmFieldActionCount; action++) { 398 cli_out("\t%s\n", format_field_action(buf, action, 0)); 399 } 400 return CMD_OK; 401 } 402 403 static cmd_result_t 404 list_quals_cmd(int unit, args_t *args) 405 { 406 bcm_field_qualify_t qual; 407 char buf[BCM_FIELD_QUALIFY_WIDTH_MAX]; 408 409 for (qual = (bcm_field_qualify_t)0; qual < bcmFieldQualifyCount; qual++) { 410 cli_out("\t%s\n", format_field_qualifier(buf, qual, 0)); 411 } 412 return CMD_OK; 413 } 414 415 416 static cmd_result_t 417 action_cmd(int unit, args_t *args) 418 { 419 return subcommand_execute(unit, args, 420 field_action_cmd_list, 421 COUNTOF(field_action_cmd_list)); 422 } 423 424 static cmd_result_t 425 action_add_cmd(int unit, args_t *args) 426 { 427 int rv; 428 char *cmd; 429 cmd_result_t ret_code; 430 bcm_field_entry_t entry; 431 uint32 param0 = 0, param1 = 0; 432 int action = -1; 433 bcm_field_action_t action_id; 434 parse_table_t pt; 435 436 cmd = ARG_CMD(args); 437 438 if (get_integer(cmd, "Action add", 439 ARG_GET(args), &entry, "entry id", 440 FALSE, 0, 0) != CMD_OK) { 441 return CMD_FAIL; 442 } 443 444 /* Parse option */ 445 parse_table_init(0, &pt); 446 parse_table_add(&pt, "Action", PQ_DFL | PQ_MULTI, 447 0, &action, fp_action_names); 448 parse_table_add(&pt, "Param0", PQ_DFL | PQ_INT, 449 0, ¶m0, NULL); 450 parse_table_add(&pt, "Param1", PQ_DFL | PQ_INT, 451 0, ¶m1, NULL); 452 if (!parseEndOk(args, &pt, &ret_code)) { 453 return ret_code; 454 } 455 456 if ((action < 0) || (action >= FP_ACTION_CNT)) { 457 sal_printf("%s: Invalid Field Action selection (%d)\n", cmd, action); 458 return CMD_FAIL; 459 } 460 461 action_id = (bcm_field_action_t)action; 462 463 rv = bcmx_field_action_add(entry, action_id, param0, param1); 464 465 if (BCM_FAILURE(rv)) { 466 sal_printf("%s: Action add failed: %s\n", cmd, bcm_errmsg(rv)); 467 return CMD_FAIL; 468 } 469 470 return CMD_OK; 471 } 472 473 static cmd_result_t 474 action_remove_cmd(int unit, args_t *args) 475 { 476 int rv; 477 char *cmd; 478 char *param; 479 bcm_field_entry_t entry; 480 int action = -1; 481 parse_table_t pt; 482 483 484 cmd = ARG_CMD(args); 485 486 if (get_integer(cmd, "Action remove", 487 ARG_GET(args), &entry, "entry id", 488 FALSE, 0, 0) != CMD_OK) { 489 return CMD_FAIL; 490 } 491 492 if (!ARG_CNT(args)) { 493 sal_printf("%s: Need option\n", cmd); 494 return CMD_FAIL; 495 } 496 497 /* Parse option */ 498 parse_table_init(0, &pt); 499 parse_table_add(&pt, "Action", PQ_DFL | PQ_MULTI, 500 0, &action, fp_action_names); 501 if ((parse_arg_eq(args, &pt) < 0)) { 502 sal_printf("%s: Invalid option %s\n", cmd, ARG_CUR(args)); 503 parse_arg_eq_done(&pt); 504 return CMD_FAIL; 505 } 506 507 parse_arg_eq_done(&pt); /* No longer needed */ 508 509 if (action == -1) { /* Check if 'ALL' was specified */ 510 param = ARG_GET(args); 511 if (sal_strcasecmp(param, "all")) { 512 sal_printf("%s: Invalid option %s\n", cmd, param); 513 return CMD_FAIL; 514 } 515 rv = bcmx_field_action_remove_all(entry); 516 } else { 517 if ((action < 0) || (action >= FP_ACTION_CNT)) { 518 sal_printf("%s: Invalid Field Action selection (%d)\n", 519 cmd, action); 520 return CMD_FAIL; 521 } 522 rv = bcmx_field_action_remove(entry, (bcm_field_action_t)action); 523 } 524 525 if (BCM_FAILURE(rv)) { 526 sal_printf("%s: Action remove failed: %s\n", cmd, bcm_errmsg(rv)); 527 return CMD_FAIL; 528 } 529 530 return CMD_OK; 531 } 532 533 static cmd_result_t 534 action_show_cmd(int unit, args_t *args) 535 { 536 int rv; 537 char *cmd; 538 cmd_result_t ret_code; 539 bcm_field_entry_t entry; 540 uint32 param0 = 0, param1 = 0; 541 int action = -1; 542 bcm_field_action_t action_id; 543 parse_table_t pt; 544 545 cmd = ARG_CMD(args); 546 547 if (get_integer(cmd, "Action show", 548 ARG_GET(args), &entry, "entry id", 549 FALSE, 0, 0) != CMD_OK) { 550 return CMD_FAIL; 551 } 552 553 /* Parse option */ 554 parse_table_init(0, &pt); 555 parse_table_add(&pt, "Action", PQ_DFL | PQ_MULTI, 556 0, &action, fp_action_names); 557 if (!parseEndOk(args, &pt, &ret_code)) { 558 return ret_code; 559 } 560 561 if ((action < 0) || (action >= FP_ACTION_CNT)) { 562 sal_printf("%s: Invalid Field Action selection (%d)\n", cmd, action); 563 return CMD_FAIL; 564 } 565 566 action_id = (bcm_field_action_t)action; 567 568 rv = bcmx_field_action_get(entry, action_id, ¶m0, ¶m1); 569 570 if (BCM_FAILURE(rv)) { 571 sal_printf("%s: Action show failed: %s\n", cmd, bcm_errmsg(rv)); 572 return CMD_FAIL; 573 } 574 575 sal_printf("%s: Parameter values for Entry=%d(0x%x), Action=%s are:\n" 576 " Param0=%u\n" 577 " Param1=%u\n", 578 cmd, entry, entry, FP_ACTION_NAME_GET(action), 579 param0, param1); 580 581 return CMD_OK; 582 } 583 584 static cmd_result_t 585 entry_cmd(int unit, args_t *args) 586 { 587 return subcommand_execute(unit, args, 588 field_entry_cmd_list, 589 COUNTOF(field_entry_cmd_list)); 590 } 591 592 static cmd_result_t 593 entry_create_cmd(int unit, args_t *args) 594 { 595 int rv; 596 char *cmd; 597 bcm_field_group_t group; 598 bcm_field_entry_t entry = 0; 599 600 cmd = ARG_CMD(args); 601 602 if (get_integer(cmd, "Entry create", 603 ARG_GET(args), &group, "group id", 604 FALSE, 0, 0) != CMD_OK) { 605 return CMD_FAIL; 606 } 607 608 rv = bcmx_field_entry_create(group, &entry); 609 610 if (BCM_FAILURE(rv)) { 611 sal_printf("%s: Entry create failed: %s\n", cmd, bcm_errmsg(rv)); 612 return CMD_FAIL; 613 } 614 615 sal_printf("%s: Entry=%d(0x%x) created for group=%d(0x%x)\n", 616 cmd, entry, entry, group, group); 617 618 return CMD_OK; 619 } 620 621 static cmd_result_t 622 entry_destroy_cmd(int unit, args_t *args) 623 { 624 int rv; 625 char *cmd; 626 char *param; 627 bcm_field_entry_t entry; 628 629 cmd = ARG_CMD(args); 630 631 if ((param = ARG_GET(args)) == NULL) { 632 sal_printf("%s: Entry destroy failed: Entry id needed\n", cmd); 633 return CMD_FAIL; 634 } 635 636 if (sal_strcasecmp(param, "all") == 0) { 637 if (ARG_CNT(args)) { 638 sal_printf("%s: Invalid option %s\n", cmd, ARG_CUR(args)); 639 return CMD_FAIL; 640 } 641 rv = bcmx_field_entry_destroy_all(); 642 } else { 643 if (get_integer(cmd, "Entry destroy", 644 param, &entry, "entry id", 645 FALSE, 0, 0) != CMD_OK) { 646 return CMD_FAIL; 647 } 648 649 rv = bcmx_field_entry_destroy(entry); 650 } 651 652 if (BCM_FAILURE(rv)) { 653 sal_printf("%s: Entry destroy failed: %s\n", cmd, bcm_errmsg(rv)); 654 return CMD_FAIL; 655 } 656 657 return CMD_OK; 658 } 659 660 static cmd_result_t 661 entry_copy_cmd(int unit, args_t *args) 662 { 663 int rv; 664 char *cmd; 665 bcm_field_entry_t src_entry, dst_entry = 0; 666 667 cmd = ARG_CMD(args); 668 669 if (get_integer(cmd, "Entry copy", 670 ARG_GET(args), &src_entry, "entry id", 671 FALSE, 0, 0) != CMD_OK) { 672 return CMD_FAIL; 673 } 674 675 rv = bcmx_field_entry_copy(src_entry, &dst_entry); 676 677 if (BCM_FAILURE(rv)) { 678 sal_printf("%s: Entry copy failed: %s\n", cmd, bcm_errmsg(rv)); 679 return CMD_FAIL; 680 } 681 682 sal_printf("%s: src-entry=%d(0x%x) copied to dst-entry=%d(0x%x)\n", 683 cmd, src_entry, src_entry, dst_entry, dst_entry); 684 685 return CMD_OK; 686 } 687 688 static cmd_result_t 689 entry_install_cmd(int unit, args_t *args) 690 { 691 int rv; 692 char *cmd; 693 bcm_field_entry_t entry; 694 695 cmd = ARG_CMD(args); 696 697 if (get_integer(cmd, "Entry install", 698 ARG_GET(args), &entry, "entry id", 699 FALSE, 0, 0) != CMD_OK) { 700 return CMD_FAIL; 701 } 702 703 rv = bcmx_field_entry_install(entry); 704 705 if (BCM_FAILURE(rv)) { 706 sal_printf("%s: Entry install failed: %s\n", cmd, bcm_errmsg(rv)); 707 return CMD_FAIL; 708 } 709 710 return CMD_OK; 711 } 712 713 static cmd_result_t 714 entry_qualify_cmd(int unit, args_t *args) 715 { 716 int rv = BCM_E_NONE; 717 char *cmd; 718 char *param; 719 bcm_field_entry_t entry; 720 int qualifier = -1; 721 bcm_field_qualify_t qid; 722 int data, mask; 723 bcmx_lplist_t lplist; 724 bcm_trunk_t trunk; 725 bcmx_lport_t lport; 726 bcm_ip_t ipaddr, ipaddr_mask; 727 bcm_ip6_t ip6addr, ip6addr_mask; 728 bcm_mac_t macaddr, macaddr_mask; 729 parse_table_t pt; 730 731 cmd = ARG_CMD(args); 732 733 if (get_integer(cmd, "Entry qualify", 734 ARG_GET(args), &entry, "entry id", 735 FALSE, 0, 0) != CMD_OK) { 736 return CMD_FAIL; 737 } 738 739 /* Parse option */ 740 parse_table_init(0, &pt); 741 parse_table_add(&pt, "FieldQualifier", PQ_DFL | PQ_MULTI, 742 0, &qualifier, fp_qualifier_names); 743 if ((parse_arg_eq(args, &pt) < 0)) { 744 sal_printf("%s: Invalid option %s\n", cmd, ARG_CUR(args)); 745 parse_arg_eq_done(&pt); 746 return CMD_FAIL; 747 } 748 749 parse_arg_eq_done(&pt); /* No longer needed */ 750 751 if ((qualifier < 0) || (qualifier >= FP_QUALIFIER_CNT)) { 752 sal_printf("%s: Invalid Field Qualifier selection (%d)\n", 753 cmd, qualifier); 754 return CMD_FAIL; 755 } 756 757 qid = (bcm_field_qualify_t)qualifier; 758 759 switch (qid) { 760 case bcmFieldQualifyInPorts: 761 if ((param = ARG_GET(args)) == NULL) { 762 sal_printf("%s: Need user port list\n", cmd); 763 return CMD_FAIL; 764 } 765 bcmx_lplist_init(&lplist, 0, 0); 766 if (bcmx_lplist_parse(&lplist, param) < 0) { 767 sal_printf("%s: Invalid user port list %s\n", cmd, param); 768 return CMD_FAIL; 769 } 770 rv = bcmx_field_qualify_InPorts(entry, lplist); 771 break; 772 773 case bcmFieldQualifySrcPort: 774 if ((param = ARG_GET(args)) == NULL) { 775 sal_printf("%s: Need source user port\n", cmd); 776 return CMD_FAIL; 777 } 778 lport = bcmx_uport_to_lport(bcmx_uport_parse(param, NULL)); 779 if (lport == BCMX_NO_SUCH_LPORT) { 780 sal_printf("%s: Invalid source user port %s\n", cmd, 781 bcmx_lport_to_uport_str(lport)); 782 return CMD_FAIL; 783 } 784 rv = bcmx_field_qualify_SrcPort(entry, lport); 785 break; 786 787 case bcmFieldQualifySrcTrunk: 788 if (get_integer(cmd, "Entry qualify", 789 ARG_GET(args), &trunk, "source trunk id", 790 FALSE, 0, 0) != CMD_OK) { 791 return CMD_FAIL; 792 } 793 rv = bcmx_field_qualify_SrcTrunk(entry, trunk); 794 break; 795 796 case bcmFieldQualifyDstPort: 797 if ((param = ARG_GET(args)) == NULL) { 798 sal_printf("%s: Need destination user port\n", cmd); 799 return CMD_FAIL; 800 } 801 lport = bcmx_uport_to_lport(bcmx_uport_parse(param, NULL)); 802 if (lport == BCMX_NO_SUCH_LPORT) { 803 sal_printf("%s: Invalid destination user port %s\n", cmd, 804 bcmx_lport_to_uport_str(lport)); 805 return CMD_FAIL; 806 } 807 rv = bcmx_field_qualify_DstPort(entry, lport); 808 break; 809 810 case bcmFieldQualifyDstTrunk: 811 if (get_integer(cmd, "Entry qualify", 812 ARG_GET(args), &trunk, "destination trunk id", 813 FALSE, 0, 0) != CMD_OK) { 814 return CMD_FAIL; 815 } 816 rv = bcmx_field_qualify_DstTrunk(entry, trunk); 817 break; 818 819 case bcmFieldQualifyEtherType: 820 case bcmFieldQualifyIpProtocol: 821 case bcmFieldQualifyIpInfo: 822 case bcmFieldQualifyPacketRes: 823 case bcmFieldQualifyDSCP: 824 case bcmFieldQualifyIpFlags: 825 case bcmFieldQualifyTcpControl: 826 case bcmFieldQualifyTtl: 827 case bcmFieldQualifyIp6FlowLabel: 828 case bcmFieldQualifyMHOpcode: 829 case bcmFieldQualifyL4SrcPort: 830 case bcmFieldQualifyL4DstPort: 831 case bcmFieldQualifyRangeCheck: 832 case bcmFieldQualifyOuterVlan: 833 case bcmFieldQualifyInnerVlan: 834 835 836 if (get_integer(cmd, "Entry qualify", 837 ARG_GET(args), &data, "data", 838 FALSE, 0, 0) != CMD_OK) { 839 return CMD_FAIL; 840 } 841 if (get_integer(cmd, "Entry qualify", 842 ARG_GET(args), &mask, "mask", 843 FALSE, 0, 0) != CMD_OK) { 844 return CMD_FAIL; 845 } 846 847 if (qid == bcmFieldQualifyEtherType) { 848 rv = bcmx_field_qualify_EtherType(entry, data, mask); 849 } else if (qid == bcmFieldQualifyIpProtocol) { 850 rv = bcmx_field_qualify_IpProtocol(entry, data, mask); 851 } else if (qid == bcmFieldQualifyIpInfo) { 852 rv = bcmx_field_qualify_IpInfo(entry, data, mask); 853 } else if (qid == bcmFieldQualifyPacketRes) { 854 rv = bcmx_field_qualify_PacketRes(entry, data, mask); 855 } else if (qid == bcmFieldQualifyDSCP) { 856 rv = bcmx_field_qualify_DSCP(entry, data, mask); 857 } else if (qid == bcmFieldQualifyIpFlags) { 858 rv = bcmx_field_qualify_IpFlags(entry, data, mask); 859 } else if (qid == bcmFieldQualifyTcpControl) { 860 rv = bcmx_field_qualify_TcpControl(entry, data, mask); 861 } else if (qid == bcmFieldQualifyTtl) { 862 rv = bcmx_field_qualify_Ttl(entry, data, mask); 863 } else if (qid == bcmFieldQualifyIp6FlowLabel) { 864 rv = bcmx_field_qualify_Ip6FlowLabel(entry, data, mask); 865 } else if (qid == bcmFieldQualifyMHOpcode) { 866 rv = bcmx_field_qualify_MHOpcode(entry, data, mask); 867 } else if (qid == bcmFieldQualifyL4SrcPort) { 868 rv = bcmx_field_qualify_L4SrcPort(entry, data, mask); 869 } else if (qid == bcmFieldQualifyL4DstPort) { 870 rv = bcmx_field_qualify_L4DstPort(entry, data, mask); 871 } else if (qid == bcmFieldQualifyRangeCheck) { 872 rv = bcmx_field_qualify_RangeCheck(entry, data, mask); 873 } else if (qid == bcmFieldQualifyOuterVlan) { 874 rv = bcmx_field_qualify_OuterVlan(entry, data, mask); 875 } else if (qid == bcmFieldQualifyInnerVlan) { 876 rv = bcmx_field_qualify_InnerVlan(entry, data, mask); 877 } 878 879 break; 880 881 case bcmFieldQualifySrcIp: 882 case bcmFieldQualifyDstIp: 883 if ((param = ARG_GET(args)) == NULL) { 884 sal_printf("%s: IP address required\n", cmd); 885 return CMD_FAIL; 886 } 887 if (parse_ipaddr(param, &ipaddr)) { 888 sal_printf("%s: Invalid IP address %s\n", cmd, param); 889 return CMD_FAIL; 890 } 891 892 if ((param = ARG_GET(args)) == NULL) { 893 sal_printf("%s: IP address mask required\n", cmd); 894 return CMD_FAIL; 895 } 896 if (parse_ipaddr(param, &ipaddr_mask)) { 897 sal_printf("%s: Invalid IP address mask %s\n", cmd, param); 898 return CMD_FAIL; 899 } 900 901 if (qid == bcmFieldQualifySrcIp) { 902 rv = bcmx_field_qualify_SrcIp(entry, ipaddr, ipaddr_mask); 903 } else if (qid == bcmFieldQualifyDstIp) { 904 rv = bcmx_field_qualify_DstIp(entry, ipaddr, ipaddr_mask); 905 } 906 907 break; 908 909 case bcmFieldQualifySrcIp6: 910 case bcmFieldQualifyDstIp6: 911 case bcmFieldQualifyDstIp6High: 912 if ((param = ARG_GET(args)) == NULL) { 913 sal_printf("%s: IPv6 address required\n", cmd); 914 return CMD_FAIL; 915 } 916 if (parse_ip6addr(param, ip6addr)) { 917 sal_printf("%s: Invalid IPv6 address %s\n", cmd, param); 918 return CMD_FAIL; 919 } 920 921 if ((param = ARG_GET(args)) == NULL) { 922 sal_printf("%s: IPv6 address mask required\n", cmd); 923 return CMD_FAIL; 924 } 925 if (parse_ip6addr(param, ip6addr_mask)) { 926 sal_printf("%s: Invalid IPv6 address mask %s\n", cmd, param); 927 return CMD_FAIL; 928 } 929 930 if (qid == bcmFieldQualifySrcIp6) { 931 rv = bcmx_field_qualify_SrcIp6(entry, ip6addr, ip6addr_mask); 932 } else if (qid == bcmFieldQualifyDstIp6) { 933 rv = bcmx_field_qualify_DstIp6(entry, ip6addr, ip6addr_mask); 934 } else if (qid == bcmFieldQualifyDstIp6High) { 935 rv = bcmx_field_qualify_DstIp6High(entry, ip6addr, ip6addr_mask); 936 } 937 938 break; 939 940 941 case bcmFieldQualifySrcMac: 942 case bcmFieldQualifyDstMac: 943 if ((param = ARG_GET(args)) == NULL) { 944 sal_printf("%s: MAC address required\n", cmd); 945 return CMD_FAIL; 946 } 947 if (parse_macaddr(param, macaddr)) { 948 sal_printf("%s: Invalid MAC address %s\n", cmd, param); 949 return CMD_FAIL; 950 } 951 952 if ((param = ARG_GET(args)) == NULL) { 953 sal_printf("%s: MAC address mask required\n", cmd); 954 return CMD_FAIL; 955 } 956 if (parse_macaddr(param, macaddr_mask)) { 957 sal_printf("%s: Invalid MAC address mask %s\n", cmd, param); 958 return CMD_FAIL; 959 } 960 961 if (qid == bcmFieldQualifySrcMac) { 962 rv = bcmx_field_qualify_SrcMac(entry, macaddr, macaddr_mask); 963 } else if (qid == bcmFieldQualifyDstMac) { 964 rv = bcmx_field_qualify_DstMac(entry, macaddr, macaddr_mask); 965 } 966 967 break; 968 969 default: 970 sal_printf("%s: Invalid Field Qualifier selection\n", cmd); 971 return CMD_FAIL; 972 973 } 974 975 if (BCM_FAILURE(rv)) { 976 sal_printf("%s: Entry qualify failed: %s\n", cmd, bcm_errmsg(rv)); 977 return CMD_FAIL; 978 } 979 980 return CMD_OK; 981 } 982 983 static cmd_result_t 984 entry_reinstall_cmd(int unit, args_t *args) 985 { 986 int rv; 987 char *cmd; 988 bcm_field_entry_t entry; 989 990 cmd = ARG_CMD(args); 991 992 if (get_integer(cmd, "Entry re-install", 993 ARG_GET(args), &entry, "entry id", 994 FALSE, 0, 0) != CMD_OK) { 995 return CMD_FAIL; 996 } 997 998 rv = bcmx_field_entry_reinstall(entry); 999 1000 if (BCM_FAILURE(rv)) { 1001 sal_printf("%s: Entry re-install failed: %s\n", cmd, bcm_errmsg(rv)); 1002 return CMD_FAIL; 1003 } 1004 1005 return CMD_OK; 1006 } 1007 1008 static cmd_result_t 1009 entry_remove_cmd(int unit, args_t *args) 1010 { 1011 int rv; 1012 char *cmd; 1013 bcm_field_entry_t entry; 1014 1015 cmd = ARG_CMD(args); 1016 1017 if (get_integer(cmd, "Entry remove", 1018 ARG_GET(args), &entry, "entry id", 1019 FALSE, 0, 0) != CMD_OK) { 1020 return CMD_FAIL; 1021 } 1022 1023 rv = bcmx_field_entry_remove(entry); 1024 1025 if (BCM_FAILURE(rv)) { 1026 sal_printf("%s: Entry remove failed: %s\n", cmd, bcm_errmsg(rv)); 1027 return CMD_FAIL; 1028 } 1029 1030 return CMD_OK; 1031 } 1032 1033 static cmd_result_t 1034 group_cmd(int unit, args_t *args) 1035 { 1036 return subcommand_execute(unit, args, 1037 field_group_cmd_list, 1038 COUNTOF(field_group_cmd_list)); 1039 1040 } 1041 1042 static cmd_result_t 1043 group_create_cmd(int unit, args_t *args) 1044 { 1045 int rv; 1046 char *cmd; 1047 cmd_result_t ret_code; 1048 bcm_field_group_t group = 0; 1049 int qset_num = -1; 1050 int pri = 0; 1051 parse_table_t pt; 1052 1053 cmd = ARG_CMD(args); 1054 1055 /* Parse option */ 1056 parse_table_init(0, &pt); 1057 parse_table_add(&pt, "QSET", PQ_DFL | PQ_INT, 0, &qset_num, NULL); 1058 parse_table_add(&pt, "PRI", PQ_DFL | PQ_INT, 0, &pri, NULL); 1059 if (!parseEndOk(args, &pt, &ret_code)) { 1060 return ret_code; 1061 } 1062 1063 if ((qset_num < 0) || (qset_num >= MAX_QSETS)) { 1064 sal_printf("%s: Group create failed: Qualifier set number must be " 1065 "0..%d\n", cmd, (MAX_QSETS - 1)); 1066 return CMD_FAIL; 1067 } 1068 1069 if (!fp_qset_tbl[qset_num].created) { 1070 sal_printf("%s: Group create failed: qset=%d has not been " 1071 "created\n", cmd, qset_num); 1072 return CMD_FAIL; 1073 } 1074 1075 rv = bcmx_field_group_create(fp_qset_tbl[qset_num].qset, pri, &group); 1076 1077 if (BCM_FAILURE(rv)) { 1078 sal_printf("%s: Group create failed: %s\n", cmd, bcm_errmsg(rv)); 1079 return CMD_FAIL; 1080 } 1081 1082 sal_printf("%s: Group=%d(0x%x) created\n", cmd, group, group); 1083 1084 return CMD_OK; 1085 } 1086 1087 static cmd_result_t 1088 group_destroy_cmd(int unit, args_t *args) 1089 { 1090 int rv; 1091 char *cmd; 1092 bcm_field_group_t group; 1093 1094 cmd = ARG_CMD(args); 1095 1096 if (get_integer(cmd, "Group destroy", 1097 ARG_GET(args), &group, "group id", 1098 FALSE, 0, 0) != CMD_OK) { 1099 return CMD_FAIL; 1100 } 1101 1102 rv = bcmx_field_group_destroy(group); 1103 1104 if (BCM_FAILURE(rv)) { 1105 sal_printf("%s: Group destroy failed: %s\n", cmd, bcm_errmsg(rv)); 1106 return CMD_FAIL; 1107 } 1108 1109 return CMD_OK; 1110 } 1111 1112 static cmd_result_t 1113 group_set_cmd(int unit, args_t *args) 1114 { 1115 int rv; 1116 char *cmd; 1117 cmd_result_t ret_code; 1118 bcm_field_group_t group; 1119 int qset_num = -1; 1120 parse_table_t pt; 1121 1122 cmd = ARG_CMD(args); 1123 1124 if (get_integer(cmd, "Group qualifier set", 1125 ARG_GET(args), &group, "group id", 1126 FALSE, 0, 0) != CMD_OK) { 1127 return CMD_FAIL; 1128 } 1129 1130 /* Parse option */ 1131 parse_table_init(0, &pt); 1132 parse_table_add(&pt, "QSET", PQ_DFL | PQ_INT, 0, &qset_num, NULL); 1133 if (!parseEndOk(args, &pt, &ret_code)) { 1134 return ret_code; 1135 } 1136 1137 if ((qset_num < 0) || (qset_num >= MAX_QSETS)) { 1138 sal_printf("%s: Group qualifier set failed: Qualifier set number " 1139 "must be 0..%d\n", cmd, (MAX_QSETS - 1)); 1140 return CMD_FAIL; 1141 } 1142 1143 if (!fp_qset_tbl[qset_num].created) { 1144 sal_printf("%s: Group qualifier set failed: qset=%d " 1145 "has not been created\n", cmd, qset_num); 1146 return CMD_FAIL; 1147 } 1148 1149 rv = bcmx_field_group_set(group, fp_qset_tbl[qset_num].qset); 1150 1151 if (BCM_FAILURE(rv)) { 1152 sal_printf("%s: Group qualifier set failed: %s\n", cmd, bcm_errmsg(rv)); 1153 return CMD_FAIL; 1154 } 1155 1156 return CMD_OK; 1157 } 1158 1159 typedef enum { 1160 ra_create, ra_show, ra_destroy 1161 } range_action_t; 1162 1163 static cmd_result_t 1164 range_cmd(int unit, args_t *args) 1165 { 1166 int rv = BCM_E_INTERNAL; 1167 char *cmd; 1168 cmd_result_t ret_code; 1169 char *param; 1170 range_action_t action; 1171 int range = -1; 1172 uint32 flags = 0; 1173 bcm_l4_port_t min = 0, max = 0; 1174 parse_table_t pt; 1175 bcm_field_range_t range_id; 1176 1177 cmd = ARG_CMD(args); 1178 1179 if ((param = ARG_GET(args)) == NULL) { 1180 sal_printf("%s: Range subcommand needed\n", cmd); 1181 return CMD_FAIL; 1182 } 1183 1184 if (sal_strcasecmp(param, "create") == 0) { 1185 action = ra_create; 1186 } else if (sal_strcasecmp(param, "show") == 0) { 1187 action = ra_show; 1188 } else if (sal_strcasecmp(param, "destroy") == 0) { 1189 action = ra_destroy; 1190 } else { 1191 sal_printf("%s: Invalid option '%s'\n", cmd, param); 1192 return CMD_FAIL; 1193 } 1194 1195 1196 /* Parse option */ 1197 parse_table_init(0, &pt); 1198 parse_table_add(&pt, "Range", PQ_DFL | PQ_INT, 0, &range, NULL); 1199 parse_table_add(&pt, "Flags", PQ_DFL | PQ_INT, 0, &flags, NULL); 1200 parse_table_add(&pt, "MIN", PQ_DFL | PQ_INT, 0, &min, NULL); 1201 parse_table_add(&pt, "MAX", PQ_DFL | PQ_INT, 0, &max, NULL); 1202 if (!parseEndOk(args, &pt, &ret_code)) { 1203 return ret_code; 1204 } 1205 1206 if (ARG_CNT(args) != 0) { 1207 sal_printf("%s: Ignoring extra arguments beginning with %s\n", 1208 cmd, ARG_GET(args)); 1209 } 1210 1211 if ((range < 0) && (action != ra_create)) { 1212 sal_printf("%s: Range=<value> argument required\n", cmd); 1213 return CMD_FAIL; 1214 } 1215 range_id = range; 1216 1217 switch (action) { 1218 case ra_create: 1219 rv = bcmx_field_range_create(&range_id, 1220 flags, min, max); 1221 if (BCM_SUCCESS(rv)) { 1222 sal_printf("%s: Created Range=0x%x, Flags=0x%x, Min=%d, Max=%d\n", 1223 cmd, range_id, flags, min, max); 1224 } 1225 break; 1226 case ra_destroy: 1227 rv = bcmx_field_range_destroy(range_id); 1228 break; 1229 case ra_show: 1230 rv = bcmx_field_range_get(range_id, 1231 &flags, &min, &max); 1232 if (BCM_SUCCESS(rv)) { 1233 sal_printf("%s: Range=0x%x, Flags=0x%x, Min=%d, Max=%d\n", 1234 cmd, range_id, flags, min, max); 1235 } 1236 break; 1237 } 1238 1239 if (BCM_FAILURE(rv)) { 1240 sal_printf("%s: Range failed: %s\n", cmd, bcm_errmsg(rv)); 1241 return CMD_FAIL; 1242 } 1243 1244 return CMD_OK; 1245 } 1246 1247 static cmd_result_t 1248 group_show_cmd(int unit, args_t *args) 1249 { 1250 int rv; 1251 char *cmd; 1252 bcm_field_group_t group; 1253 bcm_field_qset_t qset; 1254 1255 cmd = ARG_CMD(args); 1256 1257 if (get_integer(cmd, "Group qualifier show", 1258 ARG_GET(args), &group, "group id", 1259 FALSE, 0, 0) != CMD_OK) { 1260 return CMD_FAIL; 1261 } 1262 1263 rv = bcmx_field_group_get(group, &qset); 1264 1265 if (BCM_FAILURE(rv)) { 1266 sal_printf("%s: Group qualifier show failed: %s\n", 1267 cmd, bcm_errmsg(rv)); 1268 return CMD_FAIL; 1269 } 1270 1271 sal_printf(" GROUP = %d(0x%x)\n", group, group); 1272 display_qset(qset); 1273 1274 return CMD_OK; 1275 } 1276 1277 static cmd_result_t 1278 qset_cmd(int unit, args_t *args) 1279 { 1280 return subcommand_execute(unit, args, 1281 field_qset_cmd_list, 1282 COUNTOF(field_qset_cmd_list)); 1283 } 1284 1285 static cmd_result_t 1286 qset_create_cmd(int unit, args_t *args) 1287 { 1288 char *cmd; 1289 int qset_num = 0; 1290 1291 cmd = ARG_CMD(args); 1292 1293 /* Find an available qset index */ 1294 while ((fp_qset_tbl[qset_num].created)) { 1295 if (++qset_num >= MAX_QSETS) { 1296 sal_printf("%s: Qset create failed: Reached maximum number of " 1297 "qsets\n", cmd); 1298 return CMD_FAIL; 1299 } 1300 } 1301 1302 fp_qset_tbl[qset_num].created = TRUE; 1303 BCM_FIELD_QSET_INIT(fp_qset_tbl[qset_num].qset); 1304 1305 sal_printf("%s: Qset=%d created\n", cmd, qset_num); 1306 1307 return CMD_OK; 1308 } 1309 1310 static cmd_result_t 1311 qset_destroy_cmd(int unit, args_t *args) 1312 { 1313 int qset_num; 1314 1315 if (get_integer(ARG_CMD(args), "Qset destroy", 1316 ARG_GET(args), &qset_num, "qset number", 1317 TRUE, 0, (MAX_QSETS - 1)) != CMD_OK) { 1318 return CMD_FAIL; 1319 } 1320 1321 fp_qset_tbl[qset_num].created = FALSE; 1322 1323 return CMD_OK; 1324 } 1325 1326 static cmd_result_t 1327 qset_set_cmd(int unit, args_t *args) 1328 { 1329 char *cmd; 1330 cmd_result_t ret_code; 1331 int qset_num, i; 1332 fp_qset_t *qset_ptr; 1333 int qualifier[FP_QUALIFIER_CNT]; 1334 parse_table_t pt; 1335 1336 cmd = ARG_CMD(args); 1337 1338 if (get_integer(cmd, "Qset set", 1339 ARG_GET(args), &qset_num, "qset number", 1340 TRUE, 0, (MAX_QSETS - 1)) != CMD_OK) { 1341 return CMD_FAIL; 1342 } 1343 1344 if (!fp_qset_tbl[qset_num].created) { 1345 sal_printf("%s: Qset set failed: qset=%d has not been created\n", 1346 cmd, qset_num); 1347 return CMD_FAIL; 1348 } 1349 1350 qset_ptr = &fp_qset_tbl[qset_num]; 1351 1352 /* Parse option */ 1353 parse_table_init(0, &pt); 1354 for (i = 0; i < FP_QUALIFIER_CNT; i++) { 1355 qualifier[i] = -1; /* (-1) will indicate to leave unchanged */ 1356 parse_table_add(&pt, FP_QUALIFIER_NAME_GET(i), PQ_DFL | PQ_BOOL, 1357 0, &qualifier[i], NULL); 1358 } 1359 if (!parseEndOk(args, &pt, &ret_code)) { 1360 return ret_code; 1361 } 1362 1363 1364 for (i = 0; i < FP_QUALIFIER_CNT; i++) { 1365 /* If qualifier was not specified in command, leave it unchanged */ 1366 if (qualifier[i] == -1) { 1367 continue; 1368 } 1369 if (qualifier[i] == 0) { 1370 BCM_FIELD_QSET_REMOVE(qset_ptr->qset, i); 1371 } else { 1372 BCM_FIELD_QSET_ADD(qset_ptr->qset, i); 1373 } 1374 } 1375 1376 return CMD_OK; 1377 } 1378 1379 static cmd_result_t 1380 qset_show_cmd(int unit, args_t *args) 1381 { 1382 char *cmd; 1383 int qset_num; 1384 1385 cmd = ARG_CMD(args); 1386 1387 if (get_integer(cmd, "Qset show", 1388 ARG_GET(args), &qset_num, "qset number", 1389 TRUE, 0, (MAX_QSETS - 1)) != CMD_OK) { 1390 return CMD_FAIL; 1391 } 1392 1393 if (!fp_qset_tbl[qset_num].created) { 1394 sal_printf("%s: Qset show failed: qset=%d has not been created\n", 1395 cmd, qset_num); 1396 return CMD_FAIL; 1397 } 1398 1399 sal_printf(" QSET = %d\n", qset_num); 1400 display_qset(fp_qset_tbl[qset_num].qset); 1401 1402 return CMD_OK; 1403 } 1404 1405 #endif /* BCM_FIELD_SUPPORT */ 1406 #endif /* INCLUDE_BCMX */