dispatch.c (29374B)
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: dispatch.c 8 * Purpose: Dispatch related diagnostic commands 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <appl/diag/shell.h> 14 #include <appl/diag/system.h> 15 16 #include <bcm/types.h> 17 #include <bcm/error.h> 18 #include <bcm/custom.h> 19 20 #ifdef BCM_ASYNC_SUPPORT 21 #include <bcm/async.h> 22 #include <bcm_int/async_server.h> 23 #ifdef INCLUDE_BCMX 24 #include <bcmx/async.h> 25 #endif /* INCLUDE_BCMX */ 26 #endif /* BCM_ASYNC_SUPPORT */ 27 28 #ifdef BCM_RPC_SUPPORT 29 #include <appl/cpudb/cpudb.h> 30 #include <bcm_int/rpc/rpc.h> 31 #include <bcm_int/rpc/rlink.h> 32 #if defined(BROADCOM_DEBUG) 33 extern void bcm_rpc_dump(void); 34 #endif /* BROADCOM_DEBUG */ 35 #endif /* BCM_RPC_SUPPORT */ 36 37 #include <bcm_int/control.h> 38 #ifdef INCLUDE_LIB_STKTASK 39 #include <appl/stktask/attach.h> 40 #endif /* INCLUDE_LIB_STKTASK */ 41 42 #include <appl/diag/diag.h> 43 44 #ifdef BCM_ASYNC_SUPPORT 45 char cmd_async_usage[] = 46 "async start: start the async api task\n" 47 "async stop: stop the async api task\n" 48 "async test: submit an async bcm call (vlan create)\n" 49 "async testx: submit an async bcmx call (vlan create)\n" 50 ; 51 52 void 53 cmd_async_cb(void *cookie, int ret) 54 { 55 int n; 56 57 n = PTR_TO_INT(cookie); 58 59 sal_printf("async callback cookie %d ret %d (%s)\n", 60 n, ret, bcm_errmsg(ret)); 61 } 62 63 static int cmd_async_count; 64 65 cmd_result_t 66 cmd_async(int unit, args_t *args) 67 { 68 char *cmd, *subcmd; 69 int rv; 70 71 cmd = ARG_CMD(args); 72 subcmd = ARG_GET(args); 73 74 if (subcmd == NULL) { 75 subcmd = "show"; 76 } 77 if (sal_strcasecmp(subcmd, "show") == 0) { 78 /* hmmm. Nothing to do here */ 79 return CMD_OK; 80 } 81 if (sal_strcasecmp(subcmd, "start") == 0) { 82 rv = bcm_async_start(); 83 if (rv < 0) { 84 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 85 return CMD_FAIL; 86 } 87 return CMD_OK; 88 } 89 if (sal_strcasecmp(subcmd, "stop") == 0) { 90 rv = bcm_async_stop(); 91 if (rv < 0) { 92 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 93 return CMD_FAIL; 94 } 95 return CMD_OK; 96 } 97 if (sal_strcasecmp(subcmd, "test") == 0) { 98 ++ cmd_async_count; 99 sal_printf("[bcm vlan create 0, %d]\n", cmd_async_count); 100 bcm_vlan_create_async(0, cmd_async_count, 101 cmd_async_cb, INT_TO_PTR(cmd_async_count)); 102 return CMD_OK; 103 } 104 if (sal_strcasecmp(subcmd, "testx") == 0) { 105 #ifdef INCLUDE_BCMX 106 ++ cmd_async_count; 107 sal_printf("[bcmx vlan create %d]\n", cmd_async_count); 108 bcmx_vlan_create_async(cmd_async_count, 109 cmd_async_cb, INT_TO_PTR(cmd_async_count)); 110 return CMD_OK; 111 #else 112 sal_printf("ERROR: bcmx support not included\n"); 113 return CMD_FAIL; 114 #endif /* INCLUDE_BCMX */ 115 } 116 return CMD_USAGE; 117 } 118 #endif /* BCM_ASYNC_SUPPORT */ 119 120 #ifdef BCM_RPC_SUPPORT 121 char cmd_rpc_usage[] = 122 "rpc start: start the BCM API RPC server task\n" 123 "rpc stop: stop the BCM API RPC server task\n" 124 "rpc nexthop: next rpc start will use nexthop transport\n" 125 "rpc nonexthop: next rpc start will use cpu2cpu transport\n" 126 #if defined(BROADCOM_DEBUG) 127 "rpc show: display internal rpc information\n" 128 #endif /* BROADCOM_DEBUG */ 129 ; 130 131 extern int _rpc_nexthop; 132 extern int _rlink_nexthop; 133 134 cmd_result_t 135 cmd_rpc(int unit, args_t *args) 136 { 137 char *cmd, *subcmd; 138 int rv; 139 140 cmd = ARG_CMD(args); 141 subcmd = ARG_GET(args); 142 143 if (subcmd == NULL) { 144 return CMD_USAGE; 145 } 146 147 if (sal_strcasecmp(subcmd, "nexthop") == 0) { 148 _rpc_nexthop = 1; 149 _rlink_nexthop = 1; 150 return CMD_OK; 151 } 152 if (sal_strcasecmp(subcmd, "nonexthop") == 0) { 153 _rpc_nexthop = 0; 154 _rlink_nexthop = 0; 155 return CMD_OK; 156 } 157 if (sal_strcasecmp(subcmd, "start") == 0) { 158 rv = bcm_rpc_start(); 159 if (rv < 0) { 160 sal_printf("ERROR: %s %s: rpc_start: %s\n", 161 cmd, subcmd, bcm_errmsg(rv)); 162 return CMD_FAIL; 163 } 164 rv = bcm_rlink_start(); 165 if (rv < 0) { 166 sal_printf("ERROR: %s %s: rlink_start: %s\n", 167 cmd, subcmd, bcm_errmsg(rv)); 168 return CMD_FAIL; 169 } 170 return CMD_OK; 171 } 172 if (sal_strcasecmp(subcmd, "stop") == 0) { 173 rv = bcm_rpc_stop(); 174 if (rv < 0) { 175 sal_printf("ERROR: %s %s: rpc_stop: %s\n", 176 cmd, subcmd, bcm_errmsg(rv)); 177 return CMD_FAIL; 178 } 179 rv = bcm_rlink_stop(); 180 if (rv < 0) { 181 sal_printf("ERROR: %s %s: rlink_stop: %s\n", 182 cmd, subcmd, bcm_errmsg(rv)); 183 return CMD_FAIL; 184 } 185 return CMD_OK; 186 } 187 188 #if defined(BROADCOM_DEBUG) 189 if (sal_strcasecmp(subcmd, "show") == 0) { 190 bcm_rpc_dump(); 191 return CMD_OK; 192 } 193 #endif /* BROADCOM_DEBUG */ 194 195 return CMD_USAGE; 196 } 197 #endif /* BCM_RPC_SUPPORT */ 198 199 void 200 cmd_dispatch_link_notify(int unit, bcm_port_t port, bcm_port_info_t *info) 201 { 202 if (info->linkstatus == BCM_PORT_LINK_STATUS_UP) { 203 sal_printf(" port %d.%d link up %dMb/s %s\n", 204 unit, port, info->speed, info->duplex ? "FD" : "HD"); 205 } else { 206 sal_printf(" port %d.%d link down\n", unit, port); 207 } 208 } 209 210 #ifdef INCLUDE_LIB_STKTASK 211 void 212 cmd_dispatch_attach_notify(int unit, int attached, 213 cpudb_entry_t *cpuent, int cpuinit) 214 { 215 sal_printf(" unit %d %s\n", 216 unit, attached ? "attached" : "detached"); 217 } 218 #endif /* INCLUDE_LIB_STKTASK */ 219 220 void 221 cmd_dispatch_l2_notify(int unit, bcm_l2_addr_t *l2addr, int insert, void *cookie) 222 { 223 sal_printf(" unit %d l2 %s %x:%x:%x:%x:%x:%x modport %d.%d vlan %d\n", 224 unit, insert ? "insert" : "delete", 225 l2addr->mac[0], l2addr->mac[1], l2addr->mac[2], 226 l2addr->mac[3], l2addr->mac[4], l2addr->mac[5], 227 l2addr->modid, l2addr->port, 228 l2addr->vid); 229 } 230 231 int 232 custom_unit_vlan_vector_get(int unit, int len, uint32 *args, int *actual) 233 { 234 int rv = BCM_E_NONE; 235 int i, vid, idx, maxidx, count = 0; 236 bcm_vlan_data_t *list = NULL; 237 238 rv = bcm_vlan_list(unit, &list, &count); 239 if (rv < 0) { 240 return rv; 241 } 242 243 sal_memset(args, 0, sizeof(args[0])*len); 244 args[0] = count; /* store the number of active VLANS in word0 */ 245 maxidx = 0; 246 for (i = 0; i < count; i++) { 247 vid = list[i].vlan_tag; 248 idx = vid/32 + 1; 249 if (idx < len) { 250 args[idx] |= 1 << (vid % 32); 251 if (idx > maxidx) { 252 maxidx = idx; 253 } 254 } 255 } 256 *actual = maxidx; 257 rv = bcm_vlan_list_destroy(unit, list, count); 258 return rv; 259 } 260 261 /* 262 * Generic Custom handler 263 * 264 * We now have 3 examples using this Custom handler 265 * 266 * CUSTOM_HANDLER_VLAN: Gets configured vlans across the system 267 * 268 * CUSTOM_HANDLER_STAT: Get all of a port's stats in one call. 269 * 270 * CUSTOM_HANDLER_STAT_SYNC: Sync stats counters and then get them 271 * 272 * This is the custom handler that runs on the slave devices. 273 * See companion calling routine custom_unit_vlan_vector_get/ 274 * custom_stat_get() that runs on the master. 275 */ 276 int 277 custom_handler(int unit, bcm_port_t port, int setget, int type, int len, 278 uint32 *args, int *actual, void *user_data) 279 { 280 int rv, argi, s; 281 uint64 val; 282 283 if (setget != BCM_CUSTOM_GET) { 284 return BCM_E_PARAM; 285 } 286 287 switch (type) { 288 case CUSTOM_HANDLER_VLAN_GET: /* gets vlan vector for a unit */ 289 rv = custom_unit_vlan_vector_get(unit, len, args, actual); 290 break; 291 292 case CUSTOM_HANDLER_STAT_SYNC_GET: 293 /* sync stats counters, then get them */ 294 rv = bcm_stat_sync(unit); 295 if (BCM_FAILURE(rv)) { 296 break; 297 } 298 /* FALLTHROUGH */ 299 case CUSTOM_HANDLER_STAT_GET: /* just get all stats */ 300 rv = BCM_E_NONE; 301 argi = 0; 302 for (s = 0; s < snmpValCount && argi < len; s++) { 303 COMPILER_64_ZERO(val); 304 rv = bcm_stat_get(unit, port, s, &val); 305 if (BCM_FAILURE(rv) && rv != BCM_E_PARAM) { 306 /* only break if the error is serious */ 307 break; 308 } 309 args[argi++] = COMPILER_64_HI(val); 310 args[argi++] = COMPILER_64_LO(val); 311 } 312 *actual = argi; 313 break; 314 default: 315 rv = BCM_E_PARAM; 316 break; 317 } 318 return rv; 319 } 320 321 int 322 custom_stat_get(int unit, bcm_port_t port, 323 int dosync, uint32 num_stats, uint64 stats[]) 324 { 325 int rv, argi, actual, op; 326 uint32 *args = NULL; 327 328 if(num_stats == 0 || num_stats > snmpValCount){ 329 rv = BCM_E_PARAM; 330 return rv; 331 } 332 333 args = sal_alloc(num_stats * sizeof(uint32) * 2, "custom_stat_get args Mem"); 334 if (args == NULL) { 335 return BCM_E_MEMORY; 336 } 337 338 op = dosync ? CUSTOM_HANDLER_STAT_SYNC_GET : CUSTOM_HANDLER_STAT_GET; 339 rv = bcm_custom_port_get(unit, port, op, num_stats*2, args, &actual); 340 if (rv >= 0) { 341 argi = 0; 342 for (argi = 0; argi < num_stats; argi++) { 343 COMPILER_64_SET(stats[argi], args[argi*2], args[argi*2+1]); 344 } 345 } 346 sal_free(args); 347 return rv; 348 } 349 350 #if 0 /* the bcmx version */ 351 int 352 customx_stat_get(bcmx_lport_t port, 353 int dosync, uint64 stats[snmpValCount]) 354 { 355 int rv, argi, s, op, actual; 356 uint32 args[snmpValCount*2]; 357 358 op = dosync ? 2 : 1; 359 rv = bcmx_custom_port_get(port, op, snmpValCount*2, args, &actual); 360 if (rv >= 0) { 361 argi = 0; 362 for (s = 0; s < snmpValCount; s++) { 363 COMPILER_64_SET(stats[s], args[argi], args[argi+1]); 364 argi += 2; 365 } 366 } 367 return rv; 368 } 369 #endif 370 371 char cmd_dispatch_usage[] = 372 #ifdef COMPILER_STRING_CONST_LIMIT 373 "dispatch <option>\n" 374 #else 375 "dispatch show: list attached bcm units\n" 376 "dispatch attach unit type unit: attach bcm unit\n" 377 "dispatch detach unit: detach bcm unit\n" 378 "dispatch find type unit [subtype]: find matching bcm unit\n" 379 "dispatch vcreate unit vid: bcm_vlan_create(unit, vid)\n" 380 "dispatch vdestroy unit vid: bcm_vlan_destroy(unit, vid)\n" 381 "dispatch vtime count unit vid: time count calls to vcreate\n" 382 "dispatch linkreg unit: register for link changes\n" 383 "dispatch linkunreg unit: unregister for link changes\n" 384 "dispatch l2reg unit: register for l2 changes\n" 385 "dispatch l2unreg unit: unregister for l2 changes\n" 386 "dispatch attreg: register for bcm dispatch attaches\n" 387 "dispatch attunreg unit: unregister for bcm dispatch attaches\n" 388 "dispatch cparse key: parse a cpudb key\n" 389 "dispatch init_check: check if device was initialized\n" 390 #endif 391 ; 392 393 cmd_result_t 394 cmd_dispatch(int unit, args_t *args) 395 { 396 char *cmd, *subcmd; 397 char *s, *dtype, *dsub; 398 int u, du, rv, vid; 399 #ifdef BCM_RPC_SUPPORT 400 cpudb_key_t key; 401 char keybuf[CPUDB_KEY_STRING_LEN]; 402 #endif /* BCM_RPC_SUPPORT */ 403 404 cmd = ARG_CMD(args); 405 subcmd = ARG_GET(args); 406 407 if (subcmd == NULL) { 408 subcmd = "show"; 409 } 410 if (sal_strcasecmp(subcmd, "show") == 0) { 411 for (u = 0; u < BCM_CONTROL_MAX; u++) { 412 if (!BCM_UNIT_VALID(u)) { 413 continue; 414 } 415 sal_printf("unit %d: dispatch %s, %s unit %d chip %x.%x.%x " 416 "caps %#x\n", 417 u, 418 BCM_TYPE_NAME(u), 419 BCM_CONTROL(u)->subtype ? BCM_CONTROL(u)->subtype : "-", 420 BCM_CONTROL(u)->unit, 421 BCM_CONTROL(u)->chip_vendor, 422 BCM_CONTROL(u)->chip_device, 423 BCM_CONTROL(u)->chip_revision, 424 BCM_CONTROL(u)->capability); 425 } 426 return CMD_OK; 427 } 428 429 /* dispatch attach N type N */ 430 if (sal_strcasecmp(subcmd, "attach") == 0) { 431 s = ARG_GET(args); 432 if (s == NULL) { 433 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 434 return CMD_FAIL; 435 } 436 u = parse_integer(s); 437 if (u < -1 || u >= BCM_CONTROL_MAX) { 438 sal_printf("ERROR: %s %s: unit %d out of range\n", cmd, subcmd, u); 439 return CMD_FAIL; 440 } 441 dtype = ARG_GET(args); 442 if (dtype == NULL) { 443 sal_printf("ERROR: %s %s: dispatch type missing\n", cmd, subcmd); 444 return CMD_FAIL; 445 } 446 s = ARG_GET(args); 447 if (s == NULL) { 448 sal_printf("ERROR: %s %s: dispatch unit missing\n", cmd, subcmd); 449 return CMD_FAIL; 450 } 451 du = parse_integer(s); 452 dsub = ARG_GET(args); 453 #ifdef BCM_RPC_SUPPORT 454 /* As a convenience to the user, treat client type subtype 455 strings as cpudb keys, and put into a standard format */ 456 if (sal_strcasecmp(dtype, "client") == 0) { 457 458 rv = cpudb_key_parse(dsub, &key); 459 if (BCM_SUCCESS(rv)) { 460 /* put in standard format */ 461 rv = cpudb_key_format(key, keybuf, sizeof(keybuf)); 462 if (BCM_SUCCESS(rv)) { 463 dsub = keybuf; 464 } else { 465 sal_printf("ERROR: %s %s: could not format key %s: %s\n", 466 cmd, subcmd, dsub, bcm_errmsg(rv)); 467 return CMD_FAIL; 468 } 469 } else { 470 sal_printf("ERROR: %s %s: could not parse key %s: %s\n", 471 cmd, subcmd, dsub, bcm_errmsg(rv)); 472 return CMD_FAIL; 473 } 474 } 475 #endif 476 477 rv = bcm_attach(u, dtype, dsub, du); 478 if (rv < 0) { 479 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 480 return CMD_FAIL; 481 } 482 if (u < 0) { 483 sal_printf("[unit %d attached]\n", rv); 484 } 485 return CMD_OK; 486 } 487 488 /* dispatch detach N */ 489 if (sal_strcasecmp(subcmd, "detach") == 0) { 490 s = ARG_GET(args); 491 if (s == NULL) { 492 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 493 return CMD_FAIL; 494 } 495 u = parse_integer(s); 496 rv = bcm_detach(u); 497 if (rv < 0) { 498 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 499 return CMD_FAIL; 500 } 501 return CMD_OK; 502 } 503 504 /* dispatch init_check N*/ 505 if (sal_strcasecmp(subcmd, "init_check") == 0) { 506 s = ARG_GET(args); 507 if (s == NULL) { 508 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 509 return CMD_FAIL; 510 } 511 u = parse_integer(s); 512 rv = bcm_init_check(u); 513 return CMD_OK; 514 } 515 516 /* dispatch find type remunit subtype */ 517 if (sal_strcasecmp(subcmd, "find") == 0) { 518 dtype = ARG_GET(args); 519 if (dtype == NULL) { 520 sal_printf("ERROR: %s %s: dispatch type missing\n", cmd, subcmd); 521 return CMD_FAIL; 522 } 523 s = ARG_GET(args); 524 if (s == NULL) { 525 sal_printf("ERROR: %s %s: dispatch unit missing\n", cmd, subcmd); 526 return CMD_FAIL; 527 } 528 u = parse_integer(s); 529 dsub = ARG_GET(args); 530 531 rv = bcm_find(dtype, dsub, u); 532 if (rv < 0) { 533 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 534 return CMD_FAIL; 535 } 536 sal_printf("[unit %d found]\n", rv); 537 return CMD_OK; 538 } 539 540 /* dispatch vcreate N N */ 541 if (sal_strcasecmp(subcmd, "vcreate") == 0) { 542 s = ARG_GET(args); 543 if (s == NULL) { 544 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 545 return CMD_FAIL; 546 } 547 u = parse_integer(s); 548 s = ARG_GET(args); 549 if (s == NULL) { 550 sal_printf("ERROR: %s %s: vlanid missing\n", cmd, subcmd); 551 return CMD_FAIL; 552 } 553 vid = parse_integer(s); 554 rv = bcm_vlan_create(u, vid); 555 if (rv < 0) { 556 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 557 return CMD_FAIL; 558 } 559 return CMD_OK; 560 } 561 562 /* dispatch vdestroy N N */ 563 if (sal_strcasecmp(subcmd, "vdestroy") == 0) { 564 s = ARG_GET(args); 565 if (s == NULL) { 566 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 567 return CMD_FAIL; 568 } 569 u = parse_integer(s); 570 s = ARG_GET(args); 571 if (s == NULL) { 572 sal_printf("ERROR: %s %s: vlanid missing\n", cmd, subcmd); 573 return CMD_FAIL; 574 } 575 vid = parse_integer(s); 576 rv = bcm_vlan_destroy(u, vid); 577 if (rv < 0) { 578 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 579 return CMD_FAIL; 580 } 581 return CMD_OK; 582 } 583 584 /* dispatch vtime N N N */ 585 if (sal_strcasecmp(subcmd, "vtime") == 0) { 586 int i, count; 587 uint32 btime, etime; 588 589 s = ARG_GET(args); 590 if (s == NULL) { 591 sal_printf("ERROR: %s %s: count missing\n", cmd, subcmd); 592 return CMD_FAIL; 593 } 594 count = parse_integer(s); 595 s = ARG_GET(args); 596 if (s == NULL) { 597 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 598 return CMD_FAIL; 599 } 600 u = parse_integer(s); 601 s = ARG_GET(args); 602 if (s == NULL) { 603 sal_printf("ERROR: %s %s: vlanid missing\n", cmd, subcmd); 604 return CMD_FAIL; 605 } 606 vid = parse_integer(s); 607 btime = sal_time_usecs(); 608 for (i = 0; i < count; i++) { 609 (void)bcm_vlan_create(u, vid); 610 } 611 etime = sal_time_usecs(); 612 sal_printf("%d api calls in %u usec (%d usec/call)\n", 613 count, etime-btime, (etime-btime)/count); 614 return CMD_OK; 615 } 616 617 if (sal_strcasecmp(subcmd, "linkreg") == 0) { 618 s = ARG_GET(args); 619 if (s == NULL) { 620 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 621 return CMD_FAIL; 622 } 623 u = parse_integer(s); 624 rv = bcm_linkscan_register(u, cmd_dispatch_link_notify); 625 if (rv < 0) { 626 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 627 return CMD_FAIL; 628 } 629 return CMD_OK; 630 } 631 632 if (sal_strcasecmp(subcmd, "linkunreg") == 0) { 633 s = ARG_GET(args); 634 if (s == NULL) { 635 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 636 return CMD_FAIL; 637 } 638 u = parse_integer(s); 639 rv = bcm_linkscan_unregister(u, cmd_dispatch_link_notify); 640 if (rv < 0) { 641 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 642 return CMD_FAIL; 643 } 644 return CMD_OK; 645 } 646 647 if (sal_strcasecmp(subcmd, "l2reg") == 0) { 648 s = ARG_GET(args); 649 if (s == NULL) { 650 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 651 return CMD_FAIL; 652 } 653 u = parse_integer(s); 654 rv = bcm_l2_addr_register(u, cmd_dispatch_l2_notify, NULL); 655 if (rv < 0) { 656 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 657 return CMD_FAIL; 658 } 659 return CMD_OK; 660 } 661 662 if (sal_strcasecmp(subcmd, "l2unreg") == 0) { 663 s = ARG_GET(args); 664 if (s == NULL) { 665 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 666 return CMD_FAIL; 667 } 668 u = parse_integer(s); 669 rv = bcm_l2_addr_unregister(u, cmd_dispatch_l2_notify, NULL); 670 if (rv < 0) { 671 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 672 return CMD_FAIL; 673 } 674 return CMD_OK; 675 } 676 677 #ifdef INCLUDE_LIB_STKTASK 678 if (sal_strcasecmp(subcmd, "attreg") == 0) { 679 rv = bcm_stack_attach_register(cmd_dispatch_attach_notify); 680 if (rv < 0) { 681 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 682 return CMD_FAIL; 683 } 684 return CMD_OK; 685 } 686 687 if (sal_strcasecmp(subcmd, "attunreg") == 0) { 688 rv = bcm_stack_attach_unregister(cmd_dispatch_attach_notify); 689 if (rv < 0) { 690 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 691 return CMD_FAIL; 692 } 693 return CMD_OK; 694 } 695 #endif /* INCLUDE_LIB_STKTASK */ 696 697 #ifdef INCLUDE_LIB_CPUDB 698 if (sal_strcasecmp(subcmd, "cparse") == 0) { 699 char buf[CPUDB_KEY_STRING_LEN]; 700 cpudb_key_t key; 701 702 s = ARG_GET(args); 703 if (s == NULL) { 704 sal_printf("ERROR: %s %s: key missing\n", cmd, subcmd); 705 return CMD_FAIL; 706 } 707 rv = cpudb_key_parse(s, &key); 708 if (rv < 0) { 709 sal_printf("ERROR: %s %s (cpudb_key_parse): %s\n", 710 cmd, subcmd, bcm_errmsg(rv)); 711 return CMD_FAIL; 712 } 713 rv = cpudb_key_format(key, buf, CPUDB_KEY_STRING_LEN); 714 if (rv < 0) { 715 sal_printf("ERROR: %s %s (cpudb_key_format): %s\n", 716 cmd, subcmd, bcm_errmsg(rv)); 717 return CMD_FAIL; 718 } 719 sal_printf("key %x:%x:%x:%x:%x:%x --> %s (hash %d)\n", 720 key.key[0], key.key[1], key.key[2], 721 key.key[3], key.key[4], key.key[5], 722 buf, CPUDB_KEY_HASH(key)); 723 return CMD_OK; 724 } 725 #endif /* INCLUDE_LIB_CPUDB */ 726 727 /* doesn't really belong here... */ 728 /* maxframe unit port [size] */ 729 if (sal_strcasecmp(subcmd, "maxframe") == 0) { 730 bcm_port_t p; 731 int size; 732 s = ARG_GET(args); 733 if (s == NULL) { 734 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 735 return CMD_FAIL; 736 } 737 u = parse_integer(s); 738 s = ARG_GET(args); 739 if (s == NULL) { 740 sal_printf("ERROR: %s %s: port missing\n", cmd, subcmd); 741 return CMD_FAIL; 742 } 743 p = parse_integer(s); 744 s = ARG_GET(args); 745 if (s == NULL) { 746 rv = bcm_port_frame_max_get(u, p, &size); 747 if (rv < 0) { 748 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 749 return CMD_FAIL; 750 } 751 sal_printf("%d\n", size); 752 } else { 753 size = parse_integer(s); 754 rv = bcm_port_frame_max_set(u, p, size); 755 if (rv < 0) { 756 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 757 return CMD_FAIL; 758 } 759 } 760 return CMD_OK; 761 } 762 763 /* doesn't really belong here... */ 764 /* jam unit port [enable] */ 765 if (sal_strcasecmp(subcmd, "jam") == 0) { 766 bcm_port_t p; 767 int enable; 768 s = ARG_GET(args); 769 if (s == NULL) { 770 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 771 return CMD_FAIL; 772 } 773 u = parse_integer(s); 774 s = ARG_GET(args); 775 if (s == NULL) { 776 sal_printf("ERROR: %s %s: port missing\n", cmd, subcmd); 777 return CMD_FAIL; 778 } 779 p = parse_integer(s); 780 s = ARG_GET(args); 781 if (s == NULL) { 782 rv = bcm_port_jam_get(u, p, &enable); 783 if (rv < 0) { 784 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 785 return CMD_FAIL; 786 } 787 sal_printf("jamming %s\n", enable ? "enabled" : "disabled"); 788 } else { 789 enable = parse_integer(s); 790 rv = bcm_port_jam_set(u, p, enable); 791 if (rv < 0) { 792 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 793 return CMD_FAIL; 794 } 795 } 796 return CMD_OK; 797 } 798 799 /* dispatch custom_reg <unit> */ 800 if (sal_strcasecmp(subcmd, "custom_reg") == 0) { 801 s = ARG_GET(args); 802 if (s == NULL) { 803 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 804 return CMD_FAIL; 805 } 806 u = parse_integer(s); 807 rv = bcm_custom_register(u, custom_handler, NULL); 808 if (rv < 0) { 809 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 810 return CMD_FAIL; 811 } 812 return CMD_OK; 813 } 814 815 /* dispatch custom_stat <unit> <port> */ 816 if (sal_strcasecmp(subcmd, "custom_stat") == 0) { 817 int p, si; 818 const static char *sname[] = BCM_STAT_NAME_INITIALIZER; 819 uint64 stats[snmpValCount]; 820 821 s = ARG_GET(args); 822 if (s == NULL) { 823 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 824 return CMD_FAIL; 825 } 826 u = parse_integer(s); 827 828 s = ARG_GET(args); 829 if (s == NULL) { 830 sal_printf("ERROR: %s %s: port missing\n", cmd, subcmd); 831 return CMD_FAIL; 832 } 833 p = parse_integer(s); 834 835 rv = custom_stat_get(u, p, 0, snmpValCount, stats); 836 if (rv < 0) { 837 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 838 return CMD_FAIL; 839 } 840 for (si = 0; si < snmpValCount; si++) { 841 if (COMPILER_64_IS_ZERO(stats[si])) { 842 continue; 843 } 844 if (COMPILER_64_HI(stats[si]) == 0) { 845 cli_out("\t%18u\t%s (stat %d)\n", 846 COMPILER_64_LO(stats[si]), sname[si], si); 847 } else { 848 cli_out("\t0x%08x%08x\t%s (stat %d)\n", 849 COMPILER_64_HI(stats[si]), 850 COMPILER_64_LO(stats[si]), 851 sname[si], si); 852 } 853 854 } 855 return CMD_OK; 856 } 857 858 /* dispatch custom_stattime <count> <unit> <port> */ 859 if (sal_strcasecmp(subcmd, "custom_stattime") == 0) { 860 int i, count, p; 861 uint32 btime, etime; 862 uint64 stats[snmpValCount]; 863 864 s = ARG_GET(args); 865 if (s == NULL) { 866 sal_printf("ERROR: %s %s: count missing\n", cmd, subcmd); 867 return CMD_FAIL; 868 } 869 count = parse_integer(s); 870 s = ARG_GET(args); 871 if (s == NULL) { 872 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 873 return CMD_FAIL; 874 } 875 u = parse_integer(s); 876 s = ARG_GET(args); 877 if (s == NULL) { 878 sal_printf("ERROR: %s %s: port missing\n", cmd, subcmd); 879 return CMD_FAIL; 880 } 881 p = parse_integer(s); 882 btime = sal_time_usecs(); 883 for (i = 0; i < count; i++) { 884 (void)custom_stat_get(u, p, 0, snmpValCount, stats); 885 } 886 etime = sal_time_usecs(); 887 sal_printf("%d api calls in %u usec (%d usec/call)\n", 888 count, etime-btime, (etime-btime)/count); 889 return CMD_OK; 890 } 891 892 /* dispatch stattime <count> <unit> <port> */ 893 if (sal_strcasecmp(subcmd, "stattime") == 0) { 894 int i, count, p, si; 895 uint32 btime, etime; 896 uint64 stats[snmpValCount]; 897 898 s = ARG_GET(args); 899 if (s == NULL) { 900 sal_printf("ERROR: %s %s: count missing\n", cmd, subcmd); 901 return CMD_FAIL; 902 } 903 count = parse_integer(s); 904 s = ARG_GET(args); 905 if (s == NULL) { 906 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 907 return CMD_FAIL; 908 } 909 u = parse_integer(s); 910 s = ARG_GET(args); 911 if (s == NULL) { 912 sal_printf("ERROR: %s %s: port missing\n", cmd, subcmd); 913 return CMD_FAIL; 914 } 915 p = parse_integer(s); 916 btime = sal_time_usecs(); 917 for (i = 0; i < count; i++) { 918 for (si = 0; si < snmpValCount; si++) { 919 (void)bcm_stat_get(u, p, si, &stats[si]); 920 } 921 } 922 etime = sal_time_usecs(); 923 sal_printf("%d api calls in %u usec (%d usec/call)\n", 924 count, etime-btime, (etime-btime)/count); 925 return CMD_OK; 926 } 927 928 /* dispatch pause_addr <unit> <port> [<mac>] */ 929 if (sal_strcasecmp(subcmd, "pause_addr") == 0) { 930 int p; 931 bcm_mac_t mac; 932 char macstr[SAL_MACADDR_STR_LEN]; 933 934 s = ARG_GET(args); 935 if (s == NULL) { 936 sal_printf("ERROR: %s %s: unit missing\n", cmd, subcmd); 937 return CMD_FAIL; 938 } 939 u = parse_integer(s); 940 s = ARG_GET(args); 941 if (s == NULL) { 942 sal_printf("ERROR: %s %s: port missing\n", cmd, subcmd); 943 return CMD_FAIL; 944 } 945 p = parse_integer(s); 946 947 s = ARG_GET(args); 948 if (s == NULL) { 949 rv = bcm_port_pause_addr_get(u, p, mac); 950 if (rv >= 0) { 951 format_macaddr(macstr, mac); 952 sal_printf("port %d.%d: pause mac addr %s\n", u, p, macstr); 953 } 954 } else { 955 if (parse_macaddr(s, mac) < 0) { 956 sal_printf("ERROR: %s %s: illegal mac-addr\n", cmd, subcmd); 957 return CMD_FAIL; 958 } 959 rv = bcm_port_pause_addr_set(u, p, mac); 960 } 961 if (rv < 0) { 962 sal_printf("ERROR: %s %s: %s\n", cmd, subcmd, bcm_errmsg(rv)); 963 return CMD_FAIL; 964 } 965 return CMD_OK; 966 } 967 968 return CMD_USAGE; 969 }