soc.c (50604B)
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 * SOC-related CLI commands 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <appl/diag/system.h> 13 #include <appl/diag/parse.h> 14 #include <appl/diag/dport.h> 15 #include <shared/bsl.h> 16 #include <bcm/error.h> 17 #include <bcm/init.h> 18 19 #include <soc/mem.h> 20 #include <soc/drv.h> 21 22 #ifdef BCM_CMICM_SUPPORT 23 #include <soc/cmicm.h> 24 #endif 25 26 27 #ifdef BCM_XGS12_FABRIC_SUPPORT 28 #include <appl/diag/pp.h> 29 #include <soc/hercules.h> 30 #endif 31 32 #ifdef BCM_XGS_SUPPORT 33 #include <soc/hash.h> 34 #endif 35 36 /* 37 * Raw SOC reset 38 */ 39 40 char socres_usage[] = 41 "Parameters: none\n\t" 42 "Performs an SCP reset -- NOT recommended\n"; 43 44 cmd_result_t 45 cmd_socres(int unit, args_t *a) 46 { 47 if (!sh_check_attached(ARG_CMD(a), unit)) 48 return CMD_FAIL; 49 50 if (soc_reset(unit) < 0) 51 return CMD_FAIL; 52 53 return CMD_OK; 54 } 55 56 /* 57 * Set number of microseconds before timing out on the S-Channel DONE bit 58 * during S-Channel operations. 59 */ 60 61 char stimeout_usage[] = 62 "Parameters: [usec]\n\t" 63 "Sets number of microseconds before S-Channel operations time out.\n\t" 64 "If argument is not given, displays the current setting.\n"; 65 66 cmd_result_t 67 cmd_stimeout(int unit, args_t *a) 68 { 69 char *usec_str = ARG_GET(a); 70 int usec; 71 72 if (!sh_check_attached(ARG_CMD(a), unit)) { 73 return CMD_FAIL; 74 } 75 76 if (usec_str) { 77 usec = parse_integer(usec_str); 78 SOC_CONTROL(unit)->schanTimeout = usec; 79 } else { 80 cli_out("S-Channel timeout is %d usec\n", 81 SOC_CONTROL(unit)->schanTimeout); 82 } 83 84 return CMD_OK; 85 } 86 87 /* 88 * Set number of microseconds before timing out on the MIIM DONE bit 89 * during PHY register operations. 90 */ 91 92 char mtimeout_usage[] = 93 "Parameters: [usec]\n\t" 94 "Sets number of microseconds before MIIM operations time out.\n\t" 95 "If argument is not given, displays the current setting.\n"; 96 97 cmd_result_t 98 cmd_mtimeout(int unit, args_t *a) 99 { 100 char *usec_str = ARG_GET(a); 101 int usec; 102 103 if (!sh_check_attached(ARG_CMD(a), unit)) { 104 return CMD_FAIL; 105 } 106 107 if (usec_str) { 108 usec = parse_integer(usec_str); 109 SOC_CONTROL(unit)->miimTimeout = usec; 110 } else { 111 cli_out("MIIM timeout is %d usec\n", 112 SOC_CONTROL(unit)->miimTimeout); 113 } 114 115 return CMD_OK; 116 } 117 118 /* 119 * Set number of milliseconds before timing out on BIST operations. 120 */ 121 122 char btimeout_usage[] = 123 "Parameters: [msec]\n\t" 124 "Sets number of milliseconds before BIST operations time out.\n\t" 125 "If argument is not given, displays the current setting.\n"; 126 127 cmd_result_t 128 cmd_btimeout(int unit, args_t *a) 129 { 130 char *msec_str = ARG_GET(a); 131 int msec; 132 133 if (!sh_check_attached(ARG_CMD(a), unit)) { 134 return CMD_FAIL; 135 } 136 137 if (msec_str) { 138 msec = parse_integer(msec_str); 139 SOC_CONTROL(unit)->bistTimeout = msec; 140 } else { 141 cli_out("BIST timeout is %d msec\n", 142 SOC_CONTROL(unit)->bistTimeout); 143 } 144 145 return CMD_OK; 146 } 147 148 /* 149 * Perform generic S-channel operation given raw S-channel buffer words. 150 */ 151 152 char schan_usage[] = 153 "Parameters: DW0 [... DWn]\n\t" 154 "Sends the specified raw data as an S-channel message, waits for a\n\t" 155 "response, then displays the S-channel message buffer (response).\n"; 156 157 cmd_result_t 158 cmd_schan(int unit, args_t *a) 159 { 160 schan_msg_t msg; 161 int i; 162 char *datastr = ARG_GET(a); 163 int rv = CMD_FAIL; 164 165 if (!sh_check_attached(ARG_CMD(a), unit)) { 166 goto done; 167 } 168 169 if (datastr == NULL) { 170 return CMD_USAGE; 171 } 172 173 sal_memset(&msg, 0, sizeof (msg)); /* Clear all words, not just header */ 174 175 for (i = 0; datastr; i++) { 176 msg.dwords[i] = parse_integer(datastr); 177 datastr = ARG_GET(a); 178 } 179 180 if ((i = soc_schan_op(unit, &msg, 181 CMIC_SCHAN_WORDS(unit), 182 CMIC_SCHAN_WORDS(unit), 1)) < 0) { 183 cli_out("S-Channel operation failed: %s\n", soc_errmsg(i)); 184 goto done; 185 } 186 187 for (i = 0; i < CMIC_SCHAN_WORDS(unit); i++) { 188 cli_out("0x%x ", msg.dwords[i]); 189 } 190 191 cli_out("\n"); 192 193 rv = CMD_OK; 194 195 done: 196 return rv; 197 } 198 199 cmd_result_t 200 cmd_esw_soc(int u, args_t *a) 201 /* 202 * Function: sh_soc 203 * Purpose: Print soc control information. 204 * Parameters: u - unit # 205 * a - pointer to args, expects <unit> ...., if none passed, 206 * default unit # used. 207 * Returns: CMD_OK/CMD_FAIL 208 */ 209 { 210 char *c; 211 cmd_result_t rv = CMD_OK; 212 213 if (!sh_check_attached("soc", u)) { 214 return(CMD_FAIL); 215 } 216 217 if (!ARG_CNT(a)) { 218 rv = soc_dump(u, " ") ? CMD_FAIL : CMD_OK; 219 } else { 220 while ((CMD_OK == rv) && (c = ARG_GET(a))) { 221 if (!isint(c)) { 222 cli_out("%s: Invalid unit identifier: %s\n", ARG_CMD(a), c); 223 rv = CMD_FAIL; 224 } else { 225 rv = soc_dump(parse_integer(c), " ") ? 226 CMD_FAIL : CMD_OK; 227 } 228 } 229 } 230 return(rv); 231 } 232 233 /* 234 * Utility routine for BIST command as well as BIST diagnostic 235 */ 236 237 static void 238 bist_add_mem(soc_mem_t *mems, int *num_mems, soc_mem_t mem) 239 { 240 int i; 241 242 for (i = 0; i < *num_mems; i++) { 243 if (mems[i] == mem) { 244 return; /* Already there */ 245 } 246 } 247 248 mems[(*num_mems)++] = mem; 249 } 250 251 int 252 bist_args_to_mems(int unit, args_t *a, soc_mem_t *mems, int *num_mems) 253 { 254 char *parm; 255 soc_mem_t mem; 256 int rv = 0; 257 258 *num_mems = 0; 259 260 while ((parm = ARG_GET(a)) != 0) { 261 if (sal_strcasecmp(parm, "all") == 0) { 262 for (mem = 0; mem < NUM_SOC_MEM; mem++) { 263 if (soc_mem_is_valid(unit, mem) && 264 (soc_mem_is_bistepic(unit, mem) || 265 soc_mem_is_bistcbp(unit, mem) || 266 soc_mem_is_bistffp(unit, mem))) { 267 bist_add_mem(mems, num_mems, mem); 268 } 269 } 270 } else if (sal_strcasecmp(parm, "cbp") == 0) { 271 for (mem = 0; mem < NUM_SOC_MEM; mem++) { 272 if (soc_mem_is_valid(unit, mem) && 273 soc_mem_is_cbp(unit, mem)) { 274 bist_add_mem(mems, num_mems, mem); 275 } 276 } 277 } else if (parse_memory_name(unit, &mem, parm, 0, 0) < 0) { 278 cli_out("BIST ERROR: Unknown memory name: %s\n", parm); 279 rv = -1; 280 } else { 281 bist_add_mem(mems, num_mems, mem); 282 } 283 } 284 285 if (*num_mems == 0) { 286 cli_out("BIST ERROR: No memories specified\n"); 287 rv = -1; 288 } 289 290 return rv; 291 } 292 293 /* 294 * BIST (non-diagnostic version) 295 */ 296 297 char bist_usage[] = 298 "Parameters: [table] ...\n\t" 299 "Runs raw BIST (built-in self-test) on list of BISTable memories.\n\t" 300 "Use \"listmem\" to get a list of BISTable memories.\n\t" 301 "The special name CBP can be used to refer to all CBP memories.\n"; 302 303 cmd_result_t 304 cmd_bist(int unit, args_t *a) 305 { 306 soc_mem_t *mems; 307 int num_mems; 308 int rv; 309 310 /*BIST is not supported on XGSIII devices*/ 311 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56601, a); 312 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56602, a); 313 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56504, a); 314 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56102, a); 315 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56304, a); 316 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56112, a); 317 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56314, a); 318 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM56514, a); 319 UNSUPPORTED_COMMAND(unit, SOC_CHIP_BCM5650, a); 320 321 if (!sh_check_attached(ARG_CMD(a), unit)) { 322 return CMD_FAIL; 323 } 324 325 mems = sal_alloc(sizeof(soc_mem_t) * NUM_SOC_MEM, 326 "BIST mem list"); 327 if (NULL == mems) { 328 cli_out("Insufficient memory for BIST\n"); 329 return BCM_E_MEMORY; 330 } 331 332 if (bist_args_to_mems(unit, a, mems, &num_mems) < 0) { 333 sal_free(mems); 334 return CMD_FAIL; 335 } 336 337 if ((rv = soc_bist(unit, 338 mems, num_mems, 339 SOC_CONTROL(unit)->bistTimeout)) < 0) { 340 cli_out("BIST failed: %s\n", soc_errmsg(rv)); 341 sal_free(mems); 342 return CMD_FAIL; 343 } 344 345 sal_free(mems); 346 return CMD_OK; 347 } 348 349 /* 350 * PBMP 351 */ 352 cmd_result_t 353 cmd_esw_bcm_pbmp(int unit, args_t *a) 354 { 355 pbmp_t pbmp; 356 pbmp_t st; 357 char *c; 358 bcm_port_t port; 359 bcm_port_config_t *pcfg; 360 char pbmp_str[FORMAT_PBMP_MAX]; 361 char pfmt[SOC_PBMP_FMT_LEN]; 362 int res = CMD_OK; 363 364 COMPILER_REFERENCE(unit); 365 366 pcfg = sal_alloc(sizeof(bcm_port_config_t), "bcm port config"); 367 if (NULL == pcfg) { 368 cli_out("ERROR: %s\n", bcm_errmsg(BCM_E_MEMORY)); 369 return CMD_FAIL; 370 } 371 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, pcfg)); 372 373 c = ARG_GET(a); 374 375 if (!c) { 376 BCM_PBMP_ASSIGN(st, pcfg->stack_ext); 377 BCM_PBMP_OR(st, pcfg->stack_int); 378 379 cli_out("Current BCM bitmaps:\n"); 380 cli_out(" FE ==> %s\n", 381 SOC_PBMP_FMT(pcfg->fe, pfmt)); 382 cli_out(" GE ==> %s\n", 383 SOC_PBMP_FMT(pcfg->ge, pfmt)); 384 cli_out(" XE ==> %s\n", 385 SOC_PBMP_FMT(pcfg->xe, pfmt)); 386 cli_out(" E ==> %s\n", 387 SOC_PBMP_FMT(pcfg->e, pfmt)); 388 cli_out(" HG ==> %s\n", 389 SOC_PBMP_FMT(pcfg->hg, pfmt)); 390 cli_out(" HL ==> %s\n", 391 SOC_PBMP_FMT(PBMP_HL_ALL(unit), pfmt)); 392 cli_out(" ST ==> %s\n", 393 SOC_PBMP_FMT(st, pfmt)); 394 cli_out(" PORT ==> %s\n", 395 SOC_PBMP_FMT(pcfg->port, pfmt)); 396 cli_out(" CMIC ==> %s\n", 397 SOC_PBMP_FMT(pcfg->cpu, pfmt)); 398 cli_out(" ALL ==> %s\n", 399 SOC_PBMP_FMT(pcfg->all, pfmt)); 400 goto exit; 401 } 402 403 if (sal_strcasecmp(c, "port") == 0) { 404 if ((c = ARG_GET(a)) == NULL) { 405 cli_out("ERROR: missing port string\n"); 406 res = CMD_FAIL; 407 goto exit; 408 } 409 if (parse_bcm_port(unit, c, &port) < 0) { 410 cli_out("%s: Invalid port string: %s\n", ARG_CMD(a), c); 411 res = CMD_FAIL; 412 goto exit; 413 } 414 cli_out(" port %s ==> %s (%d)\n", 415 c, BCM_PORT_NAME(unit, port), port); 416 goto exit; 417 } 418 419 if (parse_bcm_pbmp(unit, c, &pbmp) < 0) { 420 cli_out("%s: Invalid pbmp string (%s); use 'pbmp ?' for more info.\n", 421 ARG_CMD(a), c); 422 res = CMD_FAIL; 423 goto exit; 424 } 425 426 format_bcm_pbmp(unit, pbmp_str, sizeof (pbmp_str), pbmp); 427 428 cli_out(" %s ==> %s\n", SOC_PBMP_FMT(pbmp, pfmt), pbmp_str); 429 430 exit: 431 if (pcfg != NULL) { 432 sal_free(pcfg); 433 } 434 return res; 435 } 436 437 /* 438 * Disabled PBMP 439 */ 440 cmd_result_t 441 cmd_esw_disabled_pbmp(int unit, args_t *a) 442 { 443 char *c; 444 char pfmt[SOC_PBMP_FMT_LEN]; 445 446 COMPILER_REFERENCE(unit); 447 448 c = ARG_GET(a); 449 450 if (!c) { 451 cli_out("Current disabled bitmaps:\n"); 452 cli_out(" FE ==> %s\n", 453 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, fe), pfmt)); 454 cli_out(" GE ==> %s\n", 455 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, ge), pfmt)); 456 cli_out(" XE ==> %s\n", 457 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, xe), pfmt)); 458 #ifdef BCM_CMAC_SUPPORT 459 cli_out(" CE ==> %s\n", 460 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, ce), pfmt)); 461 #endif 462 cli_out(" E ==> %s\n", 463 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, ether), pfmt)); 464 cli_out(" HG ==> %s\n", 465 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, hg), pfmt)); 466 cli_out(" LP ==> %s\n", 467 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, lp), pfmt)); 468 cli_out(" IL ==> %s\n", 469 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, il), pfmt)); 470 cli_out(" SCH ==> %s\n", 471 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, sch), pfmt)); 472 cli_out(" HL ==> %s\n", 473 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, hl), pfmt)); 474 cli_out(" ST ==> %s\n", 475 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, st), pfmt)); 476 cli_out(" GX ==> %s\n", 477 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, gx), pfmt)); 478 cli_out(" XL ==> %s\n", 479 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, xl), pfmt)); 480 cli_out(" MXQ ==> %s\n", 481 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, mxq), pfmt)); 482 cli_out(" XG ==> %s\n", 483 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, xg), pfmt)); 484 cli_out(" XQ ==> %s\n", 485 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, xq), pfmt)); 486 cli_out(" XT ==> %s\n", 487 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, xt), pfmt)); 488 cli_out(" XW ==> %s\n", 489 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, xw), pfmt)); 490 cli_out(" CL ==> %s\n", 491 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, cl), pfmt)); 492 cli_out(" C ==> %s\n", 493 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, c), pfmt)); 494 cli_out(" AXP ==> %s\n", 495 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, axp), pfmt)); 496 cli_out(" HPLT ==> %s\n", 497 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, hyplite), pfmt)); 498 cli_out(" PORT ==> %s\n", 499 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, port), pfmt)); 500 cli_out(" ALL ==> %s\n", 501 SOC_PBMP_FMT(SOC_PORT_DISABLED_BITMAP(unit, all), pfmt)); 502 503 return CMD_OK; 504 } 505 506 return CMD_OK; 507 } 508 509 cmd_result_t 510 cmd_esw_pbmp(int unit, args_t *a) 511 { 512 pbmp_t pbmp; 513 char *c; 514 soc_port_t port; 515 char pbmp_str[FORMAT_PBMP_MAX]; 516 char pfmt[SOC_PBMP_FMT_LEN]; 517 518 COMPILER_REFERENCE(unit); 519 520 c = ARG_GET(a); 521 522 if (!c) { 523 cli_out("Current bitmaps:\n"); 524 cli_out(" FE ==> %s\n", 525 SOC_PBMP_FMT(PBMP_FE_ALL(unit), pfmt)); 526 cli_out(" GE ==> %s\n", 527 SOC_PBMP_FMT(PBMP_GE_ALL(unit), pfmt)); 528 cli_out(" XE ==> %s\n", 529 SOC_PBMP_FMT(PBMP_XE_ALL(unit), pfmt)); 530 #ifdef BCM_CMAC_SUPPORT 531 cli_out(" CE ==> %s\n", 532 SOC_PBMP_FMT(PBMP_CE_ALL(unit), pfmt)); 533 #endif 534 cli_out(" E ==> %s\n", 535 SOC_PBMP_FMT(PBMP_E_ALL(unit), pfmt)); 536 cli_out(" HG ==> %s\n", 537 SOC_PBMP_FMT(PBMP_HG_ALL(unit), pfmt)); 538 cli_out(" LP ==> %s\n", 539 SOC_PBMP_FMT(PBMP_LP_ALL(unit), pfmt)); 540 cli_out(" IL ==> %s\n", 541 SOC_PBMP_FMT(PBMP_IL_ALL(unit), pfmt)); 542 cli_out(" SCH ==> %s\n", 543 SOC_PBMP_FMT(PBMP_SCH_ALL(unit), pfmt)); 544 cli_out(" HL ==> %s\n", 545 SOC_PBMP_FMT(PBMP_HL_ALL(unit), pfmt)); 546 cli_out(" HG2 ==> %s\n", 547 SOC_PBMP_FMT(SOC_HG2_PBM(unit), pfmt)); 548 cli_out(" ST ==> %s\n", 549 SOC_PBMP_FMT(PBMP_ST_ALL(unit), pfmt)); 550 cli_out(" S ==> %s\n", 551 SOC_PBMP_FMT(SOC_INFO(unit).s_pbm, pfmt)); 552 cli_out(" GX ==> %s\n", 553 SOC_PBMP_FMT(PBMP_GX_ALL(unit), pfmt)); 554 cli_out(" XL ==> %s\n", 555 SOC_PBMP_FMT(PBMP_XL_ALL(unit), pfmt)); 556 cli_out(" XLB0 ==> %s\n", 557 SOC_PBMP_FMT(PBMP_XLB0_ALL(unit), pfmt)); 558 cli_out(" MXQ ==> %s\n", 559 SOC_PBMP_FMT(PBMP_MXQ_ALL(unit), pfmt)); 560 cli_out(" XG ==> %s\n", 561 SOC_PBMP_FMT(PBMP_XG_ALL(unit), pfmt)); 562 cli_out(" XQ ==> %s\n", 563 SOC_PBMP_FMT(PBMP_XQ_ALL(unit), pfmt)); 564 cli_out(" XT ==> %s\n", 565 SOC_PBMP_FMT(PBMP_XT_ALL(unit), pfmt)); 566 cli_out(" XW ==> %s\n", 567 SOC_PBMP_FMT(PBMP_XW_ALL(unit), pfmt)); 568 cli_out(" CL ==> %s\n", 569 SOC_PBMP_FMT(PBMP_CL_ALL(unit), pfmt)); 570 cli_out(" CLG2 ==> %s\n", 571 SOC_PBMP_FMT(PBMP_CLG2_ALL(unit), pfmt)); 572 cli_out(" C ==> %s\n", 573 SOC_PBMP_FMT(PBMP_C_ALL(unit), pfmt)); 574 cli_out(" CXX ==> %s\n", 575 SOC_PBMP_FMT(PBMP_CXX_ALL(unit), pfmt)); 576 cli_out(" AXP ==> %s\n", 577 SOC_PBMP_FMT(PBMP_AXP_ALL(unit), pfmt)); 578 cli_out(" HPLT ==> %s\n", 579 SOC_PBMP_FMT(PBMP_HYPLITE_ALL(unit), pfmt)); 580 cli_out(" PORT ==> %s\n", 581 SOC_PBMP_FMT(PBMP_PORT_ALL(unit), pfmt)); 582 cli_out(" CMIC ==> %s\n", 583 SOC_PBMP_FMT(PBMP_CMIC(unit), pfmt)); 584 cli_out(" LB ==> %s\n", 585 SOC_PBMP_FMT(PBMP_LB(unit), pfmt)); 586 cli_out(" RDB ==> %s\n", 587 SOC_PBMP_FMT(PBMP_RDB_ALL(unit), pfmt)); 588 cli_out(" FAE ==> %s\n", 589 SOC_PBMP_FMT(PBMP_FAE_ALL(unit), pfmt)); 590 cli_out(" MMU ==> %s\n", 591 SOC_PBMP_FMT(PBMP_MMU(unit), pfmt)); 592 cli_out(" OVERSUB ==> %s\n", 593 SOC_PBMP_FMT(PBMP_OVERSUB(unit), pfmt)); 594 cli_out(" MGMT ==> %s\n", 595 SOC_PBMP_FMT(PBMP_MANAGEMENT(unit), pfmt)); 596 cli_out(" ALL ==> %s\n", 597 SOC_PBMP_FMT(PBMP_ALL(unit), pfmt)); 598 cli_out(" MACSEC ==> %s\n", 599 SOC_PBMP_FMT(PBMP_MACSEC_ALL(unit), pfmt)); 600 cli_out(" ROE ==> %s\n", 601 SOC_PBMP_FMT(PBMP_CPRI_ALL(unit), pfmt)); 602 return CMD_OK; 603 } 604 605 if (sal_strcasecmp(c, "bcm") == 0) { 606 return cmd_esw_bcm_pbmp(unit, a); 607 } 608 609 if (sal_strcasecmp(c, "disabled") == 0) { 610 return cmd_esw_disabled_pbmp(unit, a); 611 } 612 613 if (sal_strcasecmp(c, "port") == 0) { 614 if ((c = ARG_GET(a)) == NULL) { 615 cli_out("ERROR: missing port string\n"); 616 return CMD_FAIL; 617 } 618 if (parse_port(unit, c, &port) < 0) { 619 cli_out("%s: Invalid port string: %s\n", ARG_CMD(a), c); 620 return CMD_FAIL; 621 } 622 cli_out(" port %s ==> %s (%d)\n", 623 c, SOC_PORT_NAME(unit, port), port); 624 return CMD_OK; 625 } 626 627 if (parse_pbmp(unit, c, &pbmp) < 0) { 628 cli_out("%s: Invalid pbmp string (%s); use 'pbmp ?' for more info.\n", 629 ARG_CMD(a), c); 630 return CMD_FAIL; 631 } 632 633 format_pbmp(unit, pbmp_str, sizeof (pbmp_str), pbmp); 634 635 cli_out(" %s ==> %s\n", SOC_PBMP_FMT(pbmp, pfmt), pbmp_str); 636 637 return CMD_OK; 638 } 639 640 #ifdef BCM_XGS12_FABRIC_SUPPORT 641 642 char if_xqdump_usage[] = 643 "Usage :\n\t" 644 " xqdump <pbmp> [cos] [xqptr]\n\t" 645 " - Display packets pending in the XQ\n\t" 646 " - No COS selects all COS\n\t" 647 " - xqptr will try to dump packets already transmitted\n\t" 648 " - NOTE! This command will probably trash the chip state!\n"; 649 650 cmd_result_t 651 if_xqdump(int unit, args_t * args) 652 { 653 char *argpbm, *argcos, *argptr; 654 pbmp_t pbm; 655 int rv; 656 int cos_start, cos_end, xq_ptr; 657 soc_port_t port, dport; 658 659 if (!SOC_IS_XGS12_FABRIC(unit)) { 660 cli_out("Command only valid for BCM5670/75 fabric\n"); 661 return CMD_FAIL; 662 } 663 664 if ((argpbm = ARG_GET(args)) == NULL) { 665 pbm = PBMP_PORT_ALL(unit); 666 } else { 667 if (parse_pbmp(unit, argpbm, &pbm) < 0) { 668 cli_out("%s: Error: unrecognized port bitmap: %s\n", 669 ARG_CMD(args), argpbm); 670 return CMD_FAIL; 671 } 672 } 673 674 if ((argcos = ARG_GET(args)) == NULL) { 675 cos_start = 0; 676 cos_end = NUM_COS(unit) - 1; 677 } else { 678 cos_start = cos_end = sal_ctoi(argcos, 0); 679 680 if (cos_start >= NUM_COS(unit)) { 681 cli_out("%s: Error: COS out of range: %s\n", 682 ARG_CMD(args), argcos); 683 return CMD_FAIL; 684 } 685 } 686 687 if ((argptr = ARG_GET(args)) == NULL) { 688 /* coverity[overrun-local] */ 689 DPORT_SOC_PBMP_ITER(unit, pbm, dport, port) { 690 if ((rv = diag_dump_cos_packets(unit, port, 691 cos_start, cos_end)) < 0) { 692 cli_out("Error dumping packets for port %d: %s\n", 693 port, soc_errmsg(rv)); 694 return CMD_FAIL; 695 } 696 } 697 } else { 698 xq_ptr = sal_ctoi(argptr, 0); 699 DPORT_SOC_PBMP_ITER(unit, pbm, dport, port) { 700 diag_dump_xq_packet(unit, SOC_PORT_BLOCK(unit, port), xq_ptr); 701 } 702 } 703 704 cli_out("XQ state probably trashed. Recommend resetting the chip.\n"); 705 706 return CMD_OK; 707 } 708 709 char if_ibdump_usage[] = 710 "Usage :\n\t" 711 " ibdump <pbmp>\n\t" 712 " - Display packets pending in the Ingress Buffer\n"; 713 714 cmd_result_t 715 if_ibdump(int unit, args_t * args) 716 { 717 char *argpbm; 718 pbmp_t pbm; 719 int rv; 720 soc_port_t port; 721 722 if (!SOC_IS_XGS12_FABRIC(unit)) { 723 cli_out("Command only valid for BCM5670/75 fabric\n"); 724 return CMD_FAIL; 725 } 726 727 if (!soc_feature(unit, soc_feature_fabric_debug)) { 728 cli_out("Command not valid for BCM5670_A0\n"); 729 return CMD_FAIL; 730 } 731 732 if ((argpbm = ARG_GET(args)) == NULL) { 733 pbm = PBMP_PORT_ALL(unit); 734 } else { 735 if (parse_pbmp(unit, argpbm, &pbm) < 0) { 736 cli_out("%s: Error: unrecognized port bitmap: %s\n", 737 ARG_CMD(args), argpbm); 738 return CMD_FAIL; 739 } 740 } 741 742 PBMP_PORT_ITER(unit, port) { 743 if (PBMP_MEMBER((pbm), port)) { 744 if ((rv = diag_dump_ib_packets(unit, port)) < 0) { 745 cli_out("Error dumping packets for port %d: %s\n", 746 port, soc_errmsg(rv)); 747 return CMD_FAIL; 748 } 749 } 750 } 751 752 return CMD_OK; 753 } 754 755 char if_xqerr_usage[] = 756 "Parameters: [PortBitMap=<pbmp>] [COS=<cos>]\n\t" 757 "[BitsError=<num>][PacketNum=<num>][BitNum=<bit>]\n\t" 758 " - Introduce bit-errors to packets pending in the XQ\n\t" 759 " - Only one COS should be configured for this port,\n\t" 760 " else the chip state will be hopelessly scrambled.\n"; 761 762 cmd_result_t 763 if_xqerr(int unit, args_t * args) 764 { 765 parse_table_t pt; 766 soc_pbmp_t pbm; 767 int rv; 768 int cos, errors, packet, bit; 769 soc_port_t port, dport; 770 771 if (!SOC_IS_XGS12_FABRIC(unit)) { 772 cli_out("Command only valid for BCM5670/75 fabric\n"); 773 return CMD_FAIL; 774 } 775 776 SOC_PBMP_CLEAR(pbm); 777 cos = 0; 778 errors = 1; 779 packet = 0; 780 bit = 0; 781 782 parse_table_init(unit, &pt); 783 parse_table_add(&pt, "PortBitMap", PQ_PBMP | PQ_DFL, 0, &pbm, 0); 784 parse_table_add(&pt, "COS", PQ_INT | PQ_DFL, 0, &cos, 0); 785 parse_table_add(&pt, "BitsError", PQ_INT | PQ_DFL, 0, &errors, 0); 786 parse_table_add(&pt, "PacketNum", PQ_INT | PQ_DFL, 0, &packet, 0); 787 parse_table_add(&pt, "BitNum", PQ_INT | PQ_DFL, 0, &bit, 0); 788 789 if (parse_arg_eq(args, &pt) < 0) { 790 cli_out("%s: Invalid argument: %s\n", ARG_CMD(args), ARG_CUR(args)); 791 parse_arg_eq_done(&pt); 792 return(CMD_FAIL); 793 } 794 parse_arg_eq_done(&pt); 795 796 if ( cos >= NUM_COS(unit) ) { 797 cli_out("%s: Error: COS out of range: %d\n", 798 ARG_CMD(args), cos); 799 return CMD_FAIL; 800 } 801 802 if ( errors > 2 ) { 803 cli_out("%s: Error: Excessive bit errors selected: %d\n", 804 ARG_CMD(args), errors); 805 } 806 807 /* coverity[overrun-local] */ 808 DPORT_SOC_PBMP_ITER(unit, pbm, dport, port) { 809 if ((rv = diag_set_cos_errors(unit, port, cos, 810 errors, packet, bit)) < 0) { 811 cli_out("Error adjusting XQ packets for port %d: %s\n", 812 port, soc_errmsg(rv)); 813 return CMD_FAIL; 814 } 815 } 816 817 return CMD_OK; 818 } 819 820 char if_mmu_cfg_usage[] = 821 "Usage :\n\t" 822 "Parameters: [PortBitMap=<pbmp>] [COSNum=<cos>]\n\t" 823 "[LosslessMode=true|false]\n\t" 824 " - Configure MMU for the given ports and number of COS.\n\t" 825 " - Lossless mode is ingress throttle.\n\t" 826 " - not Lossless is throughput mode or egress throttle.\n"; 827 828 cmd_result_t 829 if_mmu_cfg(int unit, args_t * args) 830 { 831 parse_table_t pt; 832 pbmp_t pbm; 833 int rv; 834 int num_ports, num_cos, lossless; 835 soc_port_t port, dport; 836 837 if (!SOC_IS_XGS12_FABRIC(unit)) { 838 cli_out("Command only valid for BCM5670/75 fabric\n"); 839 return CMD_FAIL; 840 } 841 842 pbm = PBMP_ALL(unit); 843 num_cos = 4; /* Safe for both modes */ 844 lossless = FALSE; 845 846 parse_table_init(unit, &pt); 847 parse_table_add(&pt, "PortBitMap", PQ_PBMP | PQ_DFL, 0, &pbm, 0); 848 parse_table_add(&pt, "COSNum", PQ_INT | PQ_DFL, 0, &num_cos, 0); 849 parse_table_add(&pt, "LosslessMode", PQ_BOOL | PQ_DFL, 0, &lossless, 0); 850 851 if (parse_arg_eq(args, &pt) < 0) { 852 cli_out("%s: Invalid argument: %s\n", ARG_CMD(args), ARG_CUR(args)); 853 parse_arg_eq_done(&pt); 854 return(CMD_FAIL); 855 } 856 parse_arg_eq_done(&pt); 857 858 if (num_cos < 1) { 859 cli_out("No COS selected.\n"); 860 return CMD_FAIL; 861 } else if (num_cos > NUM_COS(unit)) { 862 cli_out("Too many COS selected, unit only allows %d.\n", 863 NUM_COS(unit)); 864 return CMD_FAIL; 865 } 866 867 if (lossless && (num_cos > 4)) { 868 cli_out("%s: %d COS selected, lossless mode allows only 4.\n", 869 ARG_CMD(args), num_cos); 870 return(CMD_FAIL); 871 } 872 873 /* Only "real" ports */ 874 SOC_PBMP_AND(pbm, PBMP_ALL(unit)); 875 876 /* Count the ports */ 877 num_ports = 0; 878 SOC_PBMP_ITER(pbm, port) { 879 num_ports++; 880 } 881 882 if (num_ports < 1) { 883 cli_out("No ports selected.\n"); 884 return CMD_FAIL; 885 } 886 887 /* Only want "other" port count, but don't try 0. */ 888 if (num_ports > 1) { 889 num_ports--; 890 } 891 892 if (SOC_IS_HERCULES1(unit)) { 893 DPORT_SOC_PBMP_ITER(unit, pbm, dport, port) { 894 if ((rv = soc_hercules_mmu_limits_config(unit, port, 895 num_ports, num_cos, lossless)) < 0) { 896 cli_out("Error configuring MMU for port %d: %s\n", 897 port, soc_errmsg(rv)); 898 return CMD_FAIL; 899 } 900 } 901 } else { 902 /* coverity[overrun-local] */ 903 DPORT_SOC_PBMP_ITER(unit, pbm, dport, port) { 904 if ((rv = soc_hercules15_mmu_limits_config(unit, port, 905 num_ports, num_cos, lossless)) < 0) { 906 cli_out("Error configuring MMU for port %d: %s\n", 907 port, soc_errmsg(rv)); 908 return CMD_FAIL; 909 } 910 } 911 } 912 913 return CMD_OK; 914 } 915 916 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 917 918 #ifdef BCM_XGS_SWITCH_SUPPORT 919 920 /* 921 * Hash Select 922 * 923 * Currently the only thing handled by this routine is HashSelect for 924 * Draco, however it is designed so it can be extended to support any 925 * other hash settings for any other chips. Any such things should be 926 * added to the parse table below. 927 */ 928 929 char hash_usage[] = 930 "Parameters: [HashSelect=<U16|L16|LSB|ZERO|U32|L32>]\n\t" 931 "Displays all hash parameters if no arguments given.\n\t" 932 "Note: if HashSelect is changed, L2 and L3 tables should be cleared.\n"; 933 934 cmd_result_t 935 cmd_hash(int unit, args_t *a) 936 { 937 parse_table_t pt; 938 int r; 939 int hash_sel=0; 940 char **hashSels; 941 static char *xgs2hashSels[] = { 942 "u16", "l16", "lsb", "zero", "u32", "l32", NULL 943 }; 944 static char *xgs3hashSels[] = { 945 "zero", "u32", "l32", "lsb", "l16", "u16", NULL 946 }; 947 948 if (!sh_check_attached(ARG_CMD(a), unit)) { 949 return CMD_FAIL; 950 } 951 952 if (!soc_feature(unit, soc_feature_arl_hashed)) { 953 cli_out("%s: No hash features on this chip\n", ARG_CMD(a)); 954 return CMD_FAIL; 955 } 956 957 if (SOC_IS_XGS3_SWITCH(unit)) { 958 hashSels = xgs3hashSels; 959 } else if (SOC_IS_XGS12_SWITCH(unit)) { 960 hashSels = xgs2hashSels; 961 } else { 962 cli_out("%s: No hash features on this chip\n", ARG_CMD(a)); 963 return CMD_FAIL; 964 } 965 966 r = SOC_E_UNAVAIL; 967 #ifdef BCM_XGS3_SWITCH_SUPPORT 968 if (SOC_IS_XGS3_SWITCH(unit)) { 969 uint32 hreg; 970 r = READ_HASH_CONTROLr(unit, &hreg); 971 if (soc_reg_field_valid(unit, 972 HASH_CONTROLr, 973 L2_AND_VLAN_MAC_HASH_SELECTf)) { 974 hash_sel = soc_reg_field_get(unit, 975 HASH_CONTROLr, 976 hreg, L2_AND_VLAN_MAC_HASH_SELECTf); 977 } else { 978 cli_out("%s: feature not available on this device\n", 979 ARG_CMD(a)); 980 return CMD_FAIL; 981 } 982 } 983 #endif 984 #ifdef BCM_XGS12_SWITCH_SUPPORT 985 if (SOC_IS_XGS12_SWITCH(unit)) { 986 r = soc_draco_hash_get(unit, &hash_sel); 987 } 988 #endif 989 990 if (r < 0) { 991 cli_out("%s: Error getting hash select: %s\n", 992 ARG_CMD(a), soc_errmsg(r)); 993 return CMD_FAIL; 994 } 995 996 parse_table_init(unit, &pt); 997 parse_table_add(&pt, "HashSelect", PQ_DFL|PQ_MULTI, 998 (void *)0, &hash_sel, hashSels); 999 1000 if (!ARG_CNT(a)) { /* Display settings */ 1001 cli_out("Current settings:\n"); 1002 cli_out(" HashSelect=%s\n", hashSels[hash_sel]); 1003 parse_arg_eq_done(&pt); 1004 return(CMD_OK); 1005 } 1006 1007 if (parse_arg_eq(a, &pt) < 0) { 1008 cli_out("%s: Error: Unknown option: %s\n", ARG_CMD(a), ARG_CUR(a)); 1009 parse_arg_eq_done(&pt); 1010 return(CMD_FAIL); 1011 } 1012 parse_arg_eq_done(&pt); 1013 1014 r = SOC_E_UNAVAIL; 1015 #ifdef BCM_XGS3_SWITCH_SUPPORT 1016 if (SOC_IS_XGS3_SWITCH(unit)) { 1017 uint32 hreg; 1018 r = READ_HASH_CONTROLr(unit, &hreg); 1019 soc_reg_field_set(unit, HASH_CONTROLr, &hreg, 1020 L2_AND_VLAN_MAC_HASH_SELECTf, hash_sel); 1021 if (r >= 0) { 1022 r = WRITE_HASH_CONTROLr(unit, hreg); 1023 } 1024 } 1025 #endif 1026 #ifdef BCM_XGS12_SWITCH_SUPPORT 1027 if (SOC_IS_XGS12_SWITCH(unit)) { 1028 r = soc_draco_hash_set(unit, hash_sel); 1029 } 1030 #endif 1031 if (r < 0) { 1032 cli_out("%s: Error setting hash select: %s\n", 1033 ARG_CMD(a), soc_errmsg(r)); 1034 return CMD_FAIL; 1035 } 1036 1037 return CMD_OK; 1038 } 1039 1040 #endif /* BCM_XGS_SWITCH_SUPPORT */ 1041 1042 /**************************************************************** 1043 * Interrupt enable/disable commands. 1044 */ 1045 struct _irq_cmic_stat_info { 1046 soc_field_t field; 1047 char *name; 1048 }; 1049 static struct _irq_cmic_stat_info irq_info[] = { 1050 { BSAFE_OP_DONEf, "BsafeOpDone" }, 1051 { BSE_CMDMEM_DONEf, "BseCmdDone" }, 1052 { CH0_CHAIN_DONEf, "ChainDone0" }, 1053 { CH0_DESC_DONEf, "DescDone0" }, 1054 { CH1_CHAIN_DONEf, "ChainDone1" }, 1055 { CH1_DESC_DONEf, "DescDone1" }, 1056 { CH2_CHAIN_DONEf, "ChainDone2" }, 1057 { CH2_DESC_DONEf, "DescDone2" }, 1058 { CH3_CHAIN_DONEf, "ChainDone3" }, 1059 { CH3_DESC_DONEf, "DescDone3" }, 1060 { CHIP_FUNC_INTR_0f, "ChipFuncIntr0" }, 1061 { CHIP_FUNC_INTR_1f, "ChipFuncIntr1" }, 1062 { CHIP_FUNC_INTR_2f, "ChipFuncIntr2" }, 1063 { CHIP_FUNC_INTR_3f, "ChipFuncIntr3" }, 1064 { CHIP_FUNC_INTR_4f, "ChipFuncIntr4" }, 1065 { CHIP_FUNC_INTR_5f, "ChipFuncIntr5" }, 1066 { CHIP_FUNC_INTR_6f, "ChipFuncIntr6" }, 1067 { CHIP_FUNC_INTR_7f, "ChipFuncIntr7" }, 1068 { CSE_CMDMEM_DONEf, "CseCmdDone" }, 1069 #if defined(BCM_HB_GW_SUPPORT) 1070 { EP_INTRf, "EpIntr" }, 1071 #endif 1072 { FIFO_CH0_DMA_INTRf, "FifoDmaIntr0" }, 1073 { FIFO_CH1_DMA_INTRf, "FifoDmaIntr1" }, 1074 { FIFO_CH2_DMA_INTRf, "FifoDmaIntr2" }, 1075 { FIFO_CH3_DMA_INTRf, "FifoDmaIntr3" }, 1076 { HSE_CMDMEM_DONEf, "HseCmdDone" }, 1077 { I2C_INTRf, "I2Cintr" }, 1078 #if defined(BCM_HB_GW_SUPPORT) 1079 { IP_INTRf, "IpIntr" }, 1080 #endif 1081 { L2_MOD_FIFO_NOT_EMPTYf, "L2ModFifoNotEmpty" }, 1082 { LINK_STAT_MODf, "LinkStatMod" }, 1083 { MEM_FAILf, "MemFail" }, 1084 { MIIM_OP_DONEf, "MiimOpDone" }, 1085 #ifdef BCM_HERCULES_SUPPORT 1086 { MMU_GROUP_INTRf, "MmuGroupIntr" }, 1087 #endif 1088 { PCI_FATAL_ERRf, "PciFatalErr" }, 1089 { PCI_PARITY_ERRf, "PciParityErr" }, 1090 { RX_PAUSE_STAT_MODf, "RxPauseStatMod" }, 1091 { SCHAN_ERRf, "SchanErr" }, 1092 { SCH_MSG_DONEf, "SchMsgDone" }, 1093 { SLAM_DMA_COMPLETEf, "SlamDmaComplete" }, 1094 { STATS_DMA_ITER_DONEf, "StatIterDone" }, 1095 { STAT_DMA_DONEf, "StatDmaDone" }, 1096 #ifdef BCM_HERCULES_SUPPORT 1097 { STATS_DMA_DONEf, "StatDmaDone" }, 1098 #endif 1099 { TABLE_DMA_COMPLETEf, "TableDmaComplete" }, 1100 { TX_PAUSE_STAT_MODf, "TxPauseStatMod" }, 1101 { BROADSYNC_INTERRUPTf, "Broadsync" } 1102 }; 1103 1104 #ifdef BCM_CMICM_SUPPORT 1105 static struct _irq_cmic_stat_info irq_cmic_stat0_info[] = { /* array of all possible fields of all supported devices */ 1106 { SBUSDMA_ECCERRf, "SbusDmaEccErr" }, 1107 { SW_INTRf, "SwIntr" }, 1108 { CROSS_COUPLED_MEMORYDMA_DONEf, "CrossCoupledmemDMADone" }, 1109 { SCHAN_OP_DONEf, "SchanDone0" }, 1110 { CH0_INTR_COALESCING_INTRf, "Coalescing0" }, 1111 { CH1_INTR_COALESCING_INTRf, "Coalescing1" }, 1112 { CH2_INTR_COALESCING_INTRf, "Coalescing2" }, 1113 { CH3_INTR_COALESCING_INTRf, "Coalescing3" }, 1114 { CH0_CHAIN_DONEf, "ChainDone0" }, 1115 { CH0_DESC_DONEf, "DescDone0" }, 1116 { CH1_CHAIN_DONEf, "ChainDone1" }, 1117 { CH1_DESC_DONEf, "DescDone1" }, 1118 { CH2_CHAIN_DONEf, "ChainDone2" }, 1119 { CH2_DESC_DONEf, "DescDone2" }, 1120 { CH3_CHAIN_DONEf, "ChainDone3" }, 1121 { CH3_DESC_DONEf, "DescDone3" }, 1122 { MIIM_OP_DONEf, "MiimOpDone" }, 1123 { SBUSDMA_CH2_DONEf, "SbusDmaDone2" }, 1124 { STATS_DMA_ITER_DONEf, "StatsDmaIterDone" }, 1125 { FIFO_CH0_DMA_INTRf, "FifoDma0" }, 1126 { FIFO_CH1_DMA_INTRf, "FifoDma1" }, 1127 { FIFO_CH2_DMA_INTRf, "FifoDma2" }, 1128 { FIFO_CH3_DMA_INTRf, "FifoDma3" }, 1129 { SBUSDMA_CH0_DONEf, "SbusDmaDone0" }, 1130 { SBUSDMA_CH1_DONEf, "SbusDmaDone1" }, 1131 { TABLE_DMA_DONEf, "TableDmaDone" }, 1132 { SLAM_DMA_DONEf, "SlamDmaDone" }, 1133 { CH0_DESC_CONTROLLED_INTRf, "CntldDescDone0" }, 1134 { CH1_DESC_CONTROLLED_INTRf, "CntldDescDone1" }, 1135 { CH2_DESC_CONTROLLED_INTRf, "CntldDescDone2" }, 1136 { CH3_DESC_CONTROLLED_INTRf, "CntldDescDone3" }, 1137 }; 1138 1139 1140 static struct _irq_cmic_stat_info irq_cmic_stat1_info[] = { /* array of all possible fields of all supported devices */ 1141 { SER_INTRf, "SerIntr" }, 1142 { SRAM_ECC_INTRf, "SRAMEcc" }, 1143 { PCIEINTF_NEEDS_CLEANUPf, "PCIeCleanup" }, 1144 { TIM1_INTR2f, "Tim1_2" }, 1145 { TIM1_INTR1f, "Tim1_1" }, 1146 { TIM0_INTR2f, "Tim0_2" }, 1147 { TIM0_INTR1f, "Tim0_1" }, 1148 { WDT_1_INTRf, "WDT_1" }, 1149 { WDT_0_INTRf, "WDT_0" }, 1150 { UC_1_PMUIRQf, "Uc_1" }, 1151 { UC_0_PMUIRQf, "Uc_0" }, 1152 { CHIP_FUNC_INTRf, "ChipFunc" }, 1153 { GPIO_INTRf, "Gpio" }, 1154 { MIIM_OP_DONEf, "MiimPhy" }, 1155 { COMMON_SCHAN_DONEf, "CommonSchanDone" }, 1156 { UART1_INTERRUPTf, "UART1" }, 1157 { UART0_INTERRUPTf, "UART0" }, 1158 { SPI_INTERRUPTf, "SPI" }, 1159 { PHY_PAUSESCAN_PAUSESTATUS_CHDf, "PauseChanged" }, 1160 { PHY_LINKSCAN_LINKSTATUS_CHDf, "PHYLinkChanged" }, 1161 { TIMESYNC_INTRf, "TimeSync" }, 1162 { PCIE_ECRC_ERR_INTRf, "PCIeEcrcErr" }, 1163 { BROADSYNC_INTRf, "BroadSyncIntr" }, 1164 { I2C_INTRf, "I2C" } 1165 }; 1166 1167 #ifdef BCM_XGS_SUPPORT 1168 static struct _irq_cmic_stat_info irq_cmic_stat2_info[] = { 1169 { CHIP_PARITY_INTERUPT_STATUSf, "ChipParityIntr" } 1170 }; 1171 #endif 1172 1173 #endif /* BCM_CMICM_SUPPORT */ 1174 char cmd_intr_usage[] = 1175 "Usage:\n" 1176 " intr enable [cmc <cmcId> stat <statId>] [<mask>/<irq_name> ...] - Enable interrupts\n" 1177 " intr disable [cmc <cmcId> stat <statId>] [<mask>/<irq_name> ...] - Disable interrupts\n" 1178 " intr mask [cmc <cmcId> stat <statId>] - Show current mask reg\n" 1179 " intr pending [cmc <cmcId> stat <statId>] - Show current state\n" 1180 " intr names [cmc <cmcId> stat <statId>] - List interrupt names\n" 1181 "Note:\n" 1182 " Valid cmcId range : 0-2\n" 1183 " Valid statId range : 0-2\n"; 1184 1185 1186 static int parse_irq_list(args_t *a, char **irq_names, uint32 *irq_masks, 1187 int count, uint32 *mask) 1188 { 1189 char *intr; 1190 int i; 1191 1192 if ((intr = ARG_GET(a)) == NULL) { 1193 return -1; 1194 } 1195 1196 if ((*mask = sal_ctoi(intr, 0)) == 0) { /* Assume arg list */ 1197 do { 1198 for (i = 0; i < count; i++) { 1199 if (parse_cmp(irq_names[i], intr, '\0')) { 1200 break; 1201 } 1202 } 1203 if (i == count) { 1204 return -1; 1205 } 1206 *mask |= irq_masks[i]; 1207 } while ((intr = ARG_GET(a)) != NULL); 1208 } 1209 return 0; 1210 } 1211 1212 1213 #ifdef BCM_CMICM_SUPPORT 1214 cmd_result_t 1215 cmd_cmicm_intr(int unit,args_t *a) 1216 { 1217 int cmcId = 0; 1218 int count = 0; 1219 int statId = 0; 1220 int intrCnt = 0; 1221 int intrName = 0; 1222 int regName = 0; 1223 int maskName = 0; 1224 int hwFieldCnt = 0; 1225 int swFieldCnt = 0; 1226 int statArrayCnt = 0; 1227 int start = 0; 1228 int end = 0; 1229 char *subcmd = NULL; 1230 char *irq_names[33]; 1231 char *cmd_option = NULL; 1232 uint32 mask = 0, temp_mask = 0; 1233 uint32 omask = 0; 1234 uint32 irq_masks[33]; 1235 soc_reg_info_t *reg_info = NULL; 1236 soc_field_info_t *field_info = NULL; 1237 struct _irq_cmic_stat_info *irqInfo = NULL; 1238 struct _irq_cmic_stat_info *tmpIrqInfo = NULL; 1239 uint32 (*pIntrEnaFunc)(int, int, uint32) = NULL; 1240 uint32 (*pIntrDisFunc)(int, int, uint32) = NULL; 1241 1242 1243 if (!(SOC_REG_IS_VALID (unit, CMIC_IRQ_STATr)) && (ARG_CNT(a) <= 4)) { 1244 cli_out("Options cmc,stat must be provided\n"); 1245 return CMD_USAGE; 1246 } 1247 1248 if ((subcmd = ARG_GET(a)) == NULL) { 1249 return CMD_USAGE; 1250 } 1251 1252 if (!(parse_cmp("Enable", subcmd, '\0')) && 1253 !(parse_cmp("Disable", subcmd, '\0')) && 1254 !(parse_cmp("Mask", subcmd, '\0')) && 1255 !(parse_cmp("Pending", subcmd, '\0')) && 1256 !(parse_cmp("Names", subcmd, '\0'))) { 1257 return CMD_USAGE; 1258 } 1259 1260 cmd_option = subcmd; 1261 1262 /* Expected subcmd :- cmc */ 1263 subcmd = ARG_GET(a); 1264 if (subcmd == NULL) { 1265 return CMD_USAGE; 1266 } else { 1267 if (!(parse_cmp("cmc", subcmd, '\0'))) { 1268 return CMD_USAGE; 1269 } 1270 } 1271 1272 /* Expected subcmd :- <cmcId> */ 1273 subcmd = ARG_GET(a); 1274 if (subcmd == NULL) { 1275 return CMD_USAGE; 1276 } else { 1277 cmcId = parse_integer (subcmd); 1278 } 1279 1280 /* Expected subcmd :- stat */ 1281 subcmd = ARG_GET(a); 1282 if (subcmd == NULL) { 1283 return CMD_USAGE; 1284 } else { 1285 if (!(parse_cmp("stat", subcmd, '\0'))) { 1286 return CMD_USAGE; 1287 } 1288 } 1289 1290 /* Expected subcmd :- <statId> */ 1291 subcmd = ARG_GET(a); 1292 if (subcmd == NULL) { 1293 return CMD_USAGE; 1294 } else { 1295 statId = parse_integer (subcmd); 1296 } 1297 1298 switch (statId) { 1299 case 0: 1300 switch (cmcId) { 1301 case 0: 1302 regName = CMIC_CMC0_IRQ_STAT0r; 1303 break; 1304 case 1: 1305 regName = CMIC_CMC1_IRQ_STAT0r; 1306 break; 1307 case 2: 1308 regName = CMIC_CMC2_IRQ_STAT0r; 1309 break; 1310 default: 1311 return CMD_USAGE; 1312 } 1313 1314 irqInfo = irq_cmic_stat0_info; 1315 statArrayCnt = sizeof(irq_cmic_stat0_info) 1316 / sizeof(irq_cmic_stat0_info[0]); 1317 pIntrEnaFunc = soc_cmicm_cmcx_intr0_enable; 1318 pIntrDisFunc = soc_cmicm_cmcx_intr0_disable; 1319 intrName = CMIC_CMCx_IRQ_STAT0_OFFSET(cmcId); 1320 maskName = CMIC_CMCx_PCIE_IRQ_MASK0_OFFSET(cmcId); 1321 break; 1322 1323 case 1: 1324 switch (cmcId) { 1325 case 0: 1326 regName = CMIC_CMC0_IRQ_STAT1r; 1327 break; 1328 case 1: 1329 regName = CMIC_CMC1_IRQ_STAT1r; 1330 break; 1331 case 2: 1332 regName = CMIC_CMC2_IRQ_STAT1r; 1333 break; 1334 default: 1335 return CMD_USAGE; 1336 } 1337 1338 irqInfo = irq_cmic_stat1_info; 1339 statArrayCnt = sizeof(irq_cmic_stat1_info) 1340 / sizeof(irq_cmic_stat1_info[0]); 1341 pIntrEnaFunc = soc_cmicm_cmcx_intr1_enable; 1342 pIntrDisFunc = soc_cmicm_cmcx_intr1_disable; 1343 intrName = CMIC_CMCx_IRQ_STAT1_OFFSET(cmcId); 1344 maskName = CMIC_CMCx_PCIE_IRQ_MASK1_OFFSET(cmcId); 1345 break; 1346 1347 case 2: 1348 #ifdef BCM_XGS_SUPPORT 1349 if (SOC_IS_XGS(unit)) { 1350 switch (cmcId) { 1351 case 0: 1352 regName = CMIC_CMC0_IRQ_STAT2r; 1353 break; 1354 case 1: 1355 regName = CMIC_CMC1_IRQ_STAT2r; 1356 break; 1357 case 2: 1358 regName = CMIC_CMC2_IRQ_STAT2r; 1359 break; 1360 default: 1361 return CMD_USAGE; 1362 } 1363 irqInfo = irq_cmic_stat2_info; 1364 statArrayCnt = sizeof(irq_cmic_stat2_info) 1365 / sizeof(irq_cmic_stat2_info[0]); 1366 pIntrEnaFunc = soc_cmicm_cmcx_intr2_enable; 1367 pIntrDisFunc = soc_cmicm_cmcx_intr2_disable; 1368 intrName = CMIC_CMCx_IRQ_STAT2_OFFSET(cmcId); 1369 maskName = CMIC_CMCx_PCIE_IRQ_MASK2_OFFSET(cmcId); 1370 break; 1371 } else 1372 #endif 1373 { 1374 return CMD_USAGE; 1375 } 1376 default : 1377 return CMD_USAGE; 1378 } 1379 1380 mask = 0; 1381 count = 0; 1382 1383 if (!(SOC_REG_IS_VALID (unit, regName)) ) { 1384 return CMD_FAIL; 1385 } 1386 1387 reg_info = &SOC_REG_INFO(unit, regName); 1388 1389 /* Compare H/W and S/W IRQ_STAT fields and update irq_names, irq_mask*/ 1390 for (hwFieldCnt = 0; hwFieldCnt < reg_info->nFields; hwFieldCnt++) { 1391 field_info = ®_info->fields[reg_info->nFields - 1 - hwFieldCnt]; 1392 1393 if (field_info->flags & SOCF_RES) { 1394 continue; 1395 } 1396 1397 tmpIrqInfo = irqInfo; 1398 1399 for (swFieldCnt = 0; swFieldCnt < statArrayCnt ; swFieldCnt++) { 1400 if (tmpIrqInfo->field == field_info->field) { 1401 irq_names[count] = tmpIrqInfo->name; 1402 break; 1403 } 1404 tmpIrqInfo++; 1405 } 1406 1407 if (swFieldCnt == statArrayCnt) { 1408 cli_out("Could not parse %s (0x%08x)\n" 1409 "It needs to be added to the list of interrupt names\n", 1410 SOC_FIELD_NAME(unit, field_info->field), 1411 1 << field_info->bp); 1412 irq_names[count] = SOC_FIELD_NAME(unit, field_info->field); 1413 } 1414 start = field_info->bp; 1415 end = field_info->bp + field_info->len; 1416 if (end < 32) { 1417 temp_mask = (1 << end) - 1; 1418 } else { 1419 temp_mask = -1; 1420 } 1421 temp_mask = ((uint32)-1 << start) & temp_mask; 1422 irq_masks[count] = temp_mask; 1423 mask |= irq_masks[count]; 1424 count++; 1425 } 1426 1427 irq_names[count] = "ALL"; 1428 irq_masks[count] = mask; 1429 count++; 1430 1431 /* Handler for Sub Commands 1432 * ======================== 1433 */ 1434 1435 /* INTR Enable [cmc <cmcId> stat <statId>] [<mask> | <irq_name> ...] */ 1436 if (parse_cmp("Enable", cmd_option, '\0')) { 1437 if (parse_irq_list(a, irq_names, irq_masks, count, &mask)) { 1438 cli_out("Invalid Interupt Name/Value.\n"); 1439 return CMD_USAGE; 1440 } 1441 omask = pIntrEnaFunc (unit, cmcId, mask); 1442 cli_out("Enabled with mask 0x%08x. " 1443 "Mask was 0x%08x\n", mask, omask); 1444 /* INTR Disable [cmc <cmcId> stat <statId>] [<mask> | <irq_name> ...] */ 1445 } else if (parse_cmp("Disable", cmd_option , '\0')) { 1446 if (parse_irq_list(a, irq_names, irq_masks, count, &mask)) { 1447 cli_out("Invalid Interupt Name/Value.\n"); 1448 return CMD_USAGE; 1449 } 1450 omask = pIntrDisFunc (unit, cmcId, mask); 1451 cli_out("Disabled with mask 0x%08x. " 1452 "Mask was 0x%08x\n", mask, omask); 1453 /* INTR Mask [cmc <cmcId> stat <statId>] */ 1454 } else if (parse_cmp("Mask", cmd_option, '\0')) { 1455 mask = soc_pci_read(unit, maskName); 1456 if (mask) { 1457 cli_out("Current interrupt control reg: 0x%08x\n", mask); 1458 cli_out("Interrupts enabled for the following:\n"); 1459 for (intrCnt = 0; intrCnt < count - 1; intrCnt++) { 1460 if (mask & irq_masks[intrCnt]) { 1461 cli_out("%-30s\t\n", irq_names[intrCnt]); 1462 mask &= ~irq_masks[intrCnt]; 1463 } 1464 } 1465 if (mask) { 1466 cli_out("Warning: Unknown interrupts are enabled: 0x%08x\n", 1467 mask); 1468 } 1469 } else { 1470 cli_out("No interrupts enabled\n"); 1471 } 1472 /* INTR Pending [cmc <cmcId> stat <statId>] */ 1473 } else if (parse_cmp("Pending", cmd_option, '\0')) { 1474 mask = soc_pci_read(unit, intrName); 1475 if (mask) { 1476 cli_out("Current interrupt status reg: 0x%08x\n", mask); 1477 cli_out("The following interrupts are pending:\n"); 1478 for (intrCnt = 0; intrCnt < count - 1; intrCnt++) { 1479 if (mask & irq_masks[intrCnt]) { 1480 cli_out("%-30s\t\n", irq_names[intrCnt]); 1481 mask &= ~irq_masks[intrCnt]; 1482 } 1483 } 1484 if (mask) { 1485 cli_out("Warning: Unknown interrupts are pending: 0x%08x\n", 1486 mask); 1487 } 1488 } else { 1489 cli_out("No interrupts pending\n"); 1490 } 1491 /* INTR Names [cmc <cmcId> stat <statId>] */ 1492 } else if (parse_cmp("Names", cmd_option, '\0')) { 1493 cli_out("%-30s %s\n", "Name", "Mask"); 1494 for (intrCnt = 0; intrCnt < count; intrCnt++) { 1495 cli_out("%-30s0x%08x\n", irq_names[intrCnt], irq_masks[intrCnt]); 1496 } 1497 } else { 1498 return CMD_USAGE; 1499 } 1500 return CMD_OK; 1501 } 1502 #endif /* BCM_CMICM_SUPPORT */ 1503 1504 cmd_result_t 1505 cmd_intr(int unit, args_t *a) 1506 { 1507 char *subcmd; 1508 uint32 mask = 0; 1509 uint32 omask; 1510 int i, j, count; 1511 char *irq_names[33]; 1512 uint32 irq_masks[33]; 1513 soc_reg_info_t *reg_info; 1514 soc_field_info_t *field_info; 1515 1516 if (!sh_check_attached(ARG_CMD(a), unit)) { 1517 return CMD_FAIL; 1518 } 1519 1520 #ifdef BCM_CMICM_SUPPORT 1521 /* Call cmd_cmicm_intr function if CMICm is supported*/ 1522 if (soc_feature(unit, soc_feature_cmicm)) { 1523 return cmd_cmicm_intr (unit, a); 1524 } 1525 #endif /* BCM_CMICM_SUPPORT */ 1526 1527 if (!(SOC_REG_IS_VALID (unit, CMIC_IRQ_STATr))) { 1528 return CMD_FAIL; 1529 } 1530 1531 if ((subcmd = ARG_GET(a)) == NULL) { 1532 return CMD_USAGE; 1533 } 1534 1535 reg_info = &SOC_REG_INFO(unit, CMIC_IRQ_STATr); 1536 mask = 0; 1537 count = 0; 1538 for (i = 0; i < reg_info->nFields; i++) { 1539 field_info = ®_info->fields[reg_info->nFields - 1 - i]; 1540 if (field_info->flags & SOCF_RES) { 1541 continue; 1542 } 1543 for (j = 0; j < sizeof(irq_info) / sizeof(irq_info[0]); j++) { 1544 if (irq_info[j].field == field_info->field) { 1545 irq_names[count] = irq_info[j].name; 1546 break; 1547 } 1548 } 1549 if (j == sizeof(irq_info) / sizeof(irq_info[0])) { 1550 cli_out("Could not parse %s (0x%08x)\n" 1551 "It needs to be added to the list of interrupt names\n", 1552 SOC_FIELD_NAME(unit, field_info->field), 1553 1 << field_info->bp); 1554 irq_names[count] = SOC_FIELD_NAME(unit, field_info->field); 1555 } 1556 irq_masks[count] = 1 << field_info->bp; 1557 mask |= irq_masks[count]; 1558 count++; 1559 } 1560 irq_names[count] = "ALL"; 1561 irq_masks[count] = mask; 1562 count++; 1563 1564 if (parse_cmp("Enable", subcmd, '\0')) { 1565 if (parse_irq_list(a, irq_names, irq_masks, count, &mask)) { 1566 cli_out("Invalid Interrupt Name/Value.\n"); 1567 cli_out("Note: cmc,stat options are not supported " 1568 "in this device\n"); 1569 return CMD_USAGE; 1570 } 1571 omask = soc_intr_enable(unit, mask); 1572 cli_out("Enabled with mask 0x%08x. " 1573 "Mask was 0x%08x\n", mask, omask); 1574 } else if (parse_cmp("Disable", subcmd, '\0')) { 1575 if (parse_irq_list(a, irq_names, irq_masks, count, &mask)) { 1576 cli_out("Invalid Interrupt Name/Value.\n"); 1577 cli_out("Note: cmc,stat options are not supported " 1578 "in this device\n"); 1579 return CMD_USAGE; 1580 } 1581 omask = soc_intr_disable(unit, mask); 1582 cli_out("Disabled with mask 0x%08x. " 1583 "Mask was 0x%08x\n", mask, omask); 1584 } else if (parse_cmp("Mask", subcmd, '\0')) { 1585 mask = soc_pci_read(unit, CMIC_IRQ_MASK); 1586 if (mask) { 1587 cli_out("Current interrupt control reg: 0x%08x\n", mask); 1588 cli_out("Interrupts enabled for the following:\n"); 1589 for (i = 0; i < count - 1; i++) { 1590 if (mask & irq_masks[i]) { 1591 cli_out("%-30s\t\n", irq_names[i]); 1592 mask &= ~irq_masks[i]; 1593 } 1594 } 1595 if (mask) { 1596 cli_out("Warning: Unknown interrupts are enabled: 0x%08x\n", 1597 mask); 1598 } 1599 } else { 1600 cli_out("No interrupts enabled\n"); 1601 } 1602 } else if (parse_cmp("Pending", subcmd, '\0')) { 1603 mask = soc_pci_read(unit, CMIC_IRQ_STAT); 1604 if (mask) { 1605 cli_out("Current interrupt status reg: 0x%08x\n", mask); 1606 cli_out("The following interrupts are pending:\n"); 1607 for (i = 0; i < count - 1; i++) { 1608 if (mask & irq_masks[i]) { 1609 cli_out("%-30s\t\n", irq_names[i]); 1610 mask &= ~irq_masks[i]; 1611 } 1612 } 1613 if (mask) { 1614 cli_out("Warning: Unknown interrupts are pending: 0x%08x\n", 1615 mask); 1616 } 1617 } else { 1618 cli_out("No interrupts pending\n"); 1619 } 1620 } else if (parse_cmp("Names", subcmd, '\0')) { 1621 cli_out("%-30s %s\n", "Name", "Mask"); 1622 for (i = 0; i < count; i++) { 1623 cli_out("%-30s0x%08x\n", irq_names[i], irq_masks[i]); 1624 } 1625 } else { 1626 return CMD_USAGE; 1627 } 1628 1629 return CMD_OK; 1630 }