notify.c (14769B)
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 * Misc. tests 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <sal/types.h> 13 #include <sal/core/libc.h> 14 #include <sal/appl/io.h> 15 16 #include <bcm/link.h> 17 #include <bcm/error.h> 18 19 #include <soc/drv.h> 20 #include <soc/debug.h> 21 22 #include "testlist.h" 23 24 #if defined(BCM_STRATA_SUPPORT) 25 #define LS_MAX_RETRIES 10000 26 27 #define LS_TEST_PATTERNS ((2 * SOC_MAX_NUM_PORTS) + 4) 28 29 typedef struct link_scan_s { 30 uint32 ls_irq_mask; 31 pbmp_t ls_bmp[LS_TEST_PATTERNS]; 32 int ls_linkscan; 33 } link_scan_t; 34 35 static link_scan_t *link_scan[SOC_MAX_NUM_DEVICES]; 36 37 /* 38 * Function: not_link_done 39 * Purpose: Clean up after liststatus test. 40 * Parameters: u - unit # 41 * pa - cookie from init. 42 * Returns: 0 - success, -1 - failed. 43 */ 44 int 45 not_link_done(int u, void *pa) 46 { 47 link_scan_t *ls = pa; 48 int rv; 49 50 if (ls == NULL) { 51 return 0; 52 } 53 soc_intr_enable(u, ls->ls_irq_mask & IRQ_LINK_STAT_MOD); 54 55 if ((rv = bcm_linkscan_enable_set(u, ls->ls_linkscan)) < 0) { 56 test_error(u, "ERROR: bcm_link_scan_enable_set failed: %s\n", 57 bcm_errmsg(rv));; 58 rv = -1; 59 } 60 61 sal_free(ls); 62 link_scan[u] = NULL; 63 64 return rv; 65 } 66 67 /* 68 * Function: not_link_init 69 * Purpose: Initialize link status test. 70 * Parameters: u - unit # 71 * a - args 72 * pa - cookie used in later calls. 73 * Returns: 0 - success, -1 failed. 74 */ 75 int 76 not_link_init(int u, args_t *a, void **pa) 77 { 78 link_scan_t *ls; 79 int i, rv; 80 soc_port_t port; 81 82 if (ARG_CNT(a)) { 83 test_error(u, "Arguments not supported\n"); 84 return -1; 85 } 86 87 if (link_scan[u] == NULL) { 88 link_scan[u] = sal_alloc(sizeof(link_scan_t), "not_link"); 89 if (link_scan[u] == NULL) { 90 test_error(u, "ERROR: cannot allocate memory\n"); 91 return -1; 92 } 93 sal_memset(link_scan[u], 0, sizeof(link_scan_t)); 94 } 95 ls = link_scan[u]; 96 97 SOC_PBMP_ASSIGN(ls->ls_bmp[0], PBMP_PORT_ALL(u)); 98 SOC_PBMP_CLEAR(ls->ls_bmp[1]); 99 SOC_PBMP_CLEAR(ls->ls_bmp[2]); 100 SOC_PBMP_WORD_SET(ls->ls_bmp[2], 0, 0x55555555); 101 SOC_PBMP_AND(ls->ls_bmp[2], PBMP_PORT_ALL(u)); 102 SOC_PBMP_CLEAR(ls->ls_bmp[3]); 103 SOC_PBMP_WORD_SET(ls->ls_bmp[3], 0, 0xaaaaaaaa); 104 SOC_PBMP_AND(ls->ls_bmp[3], PBMP_PORT_ALL(u)); 105 106 i = 4; 107 PBMP_PORT_ITER(u, port) { 108 SOC_PBMP_CLEAR(ls->ls_bmp[i]); 109 SOC_PBMP_PORT_ADD(ls->ls_bmp[i], port); 110 SOC_PBMP_ASSIGN(ls->ls_bmp[i + NUM_E_PORT(u)], PBMP_PORT_ALL(u)); 111 SOC_PBMP_REMOVE(ls->ls_bmp[i + NUM_E_PORT(u)], ls->ls_bmp[i]); 112 i++; 113 } 114 115 if ((rv = bcm_linkscan_enable_get(u, &ls->ls_linkscan)) < 0) { 116 test_error(u, "ERROR: bcm_linkscan_enable_get failed: %s", 117 bcm_errmsg(rv)); 118 sal_free(ls); 119 link_scan[u] = NULL; 120 return -1; 121 } 122 123 if ((rv = bcm_linkscan_enable_set(u, 0)) < 0) { 124 test_error(u, "ERROR: bcm_link_scan_enable_set failed: %s\n", 125 bcm_errmsg(rv)); 126 sal_free(ls); 127 link_scan[u] = NULL; 128 return -1; 129 } 130 131 /* Verify Auto Link Scan was disabled */ 132 133 if ((soc_pci_read(u, CMIC_SCHAN_CTRL)) & SC_MIIM_LINK_SCAN_EN_TST) { 134 test_error(u, "ERROR: Could not clear MIIM_LINK_SCAN_EN bit\n"); 135 not_link_done(u, ls); 136 return -1; 137 } 138 139 ls->ls_irq_mask = soc_intr_disable(u, IRQ_LINK_STAT_MOD); 140 141 *pa = ls; 142 return 0; 143 } 144 145 /* 146 * Function: 147 * Purpose: 148 * Parameters: 149 * Returns: 150 */ 151 int 152 not_link_test(int unit, args_t *a, void *pa) 153 { 154 link_scan_t *ls = (link_scan_t *) pa; 155 schan_msg_t schMsg; 156 int i, port, blk, rv; 157 uint32 value; 158 uint32 cnt = 0; 159 uint64 val64; 160 char pfmt[SOC_PBMP_FMT_LEN]; 161 int bitmap_ext = SOC_IS_TUCANA(unit); 162 163 COMPILER_REFERENCE(a); 164 165 /* Go through all forwarding port values */ 166 for (i = 0; i < LS_TEST_PATTERNS; i++) { 167 LOG_INFO(BSL_LS_APPL_TESTS, 168 (BSL_META_U(unit, 169 "Setting the Forwarding Port register to %s\n"), 170 SOC_PBMP_FMT(ls->ls_bmp[0], pfmt))); 171 /* Update forwarding port register for all blocks/functional us */ 172 COMPILER_64_SET(val64, 0, SOC_PBMP_WORD_GET(ls->ls_bmp[0], 0)); 173 if (SOC_IS_TUCANA(unit)) { 174 COMPILER_64_SET(val64, 1, SOC_PBMP_WORD_GET(ls->ls_bmp[0], 1)); 175 } 176 soc_reg64_write_all_blocks(unit, EPC_LINKr, val64); 177 178 (void)SOC_PBMP_FMT(ls->ls_bmp[i], pfmt); 179 LOG_INFO(BSL_LS_APPL_TESTS, 180 (BSL_META_U(unit, 181 "Sending Linkstat with value %s\n"), pfmt)); 182 /* Send a link status SChannel message */ 183 schan_msg_clear(&schMsg); 184 schMsg.header.opcode = LINKSTAT_NOTIFY_MSG; 185 186 /* Use bitmap structure */ 187 schMsg.bitmap.bitmap = SOC_PBMP_WORD_GET(ls->ls_bmp[i], 0); 188 189 if (bitmap_ext) { 190 schMsg.bitmap.bitmap_word1 = SOC_PBMP_WORD_GET(ls->ls_bmp[i], 1); 191 } 192 193 /* Write message out */ 194 if (bitmap_ext) { 195 if (soc_schan_op(unit, &schMsg, 3, 0, 0) < 0) { 196 test_error(unit, "Error in soc_schan_op.\n"); 197 return (-1); 198 } 199 } else { 200 if (soc_schan_op(unit, &schMsg, 2, 0, 0) < 0) { 201 test_error(unit, "Error in soc_schan_op.\n"); 202 return (-1); 203 } 204 } 205 206 /* Wait until a link up/down message is available for us */ 207 while (!((value = soc_pci_read(unit, CMIC_SCHAN_CTRL)) & 208 SC_LINK_STAT_MSG_TST) && (++cnt < LS_MAX_RETRIES)) { 209 LOG_INFO(BSL_LS_APPL_TESTS, 210 (BSL_META_U(unit, 211 "Waiting for message...\n"))); 212 } 213 if (cnt >= LS_MAX_RETRIES) { 214 test_error(unit, 215 "Sent S-Channel link status message, no response!!\n"); 216 return (-1); 217 } 218 /* Clear link up/down message */ 219 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_LINK_STAT_MSG_CLR); 220 221 /* Read PCI link status ... */ 222 value = soc_pci_read(unit, CMIC_LINK_STAT); 223 if (value != SOC_PBMP_WORD_GET(ls->ls_bmp[i], 0)) { 224 test_error(unit, "ERROR: unexpected link status on cmic\n" 225 "\tread 0x%x, expecting 0x%x\n", 226 value, SOC_PBMP_WORD_GET(ls->ls_bmp[i], 0)); 227 /* Just continue if we return. */ 228 } 229 230 if (bitmap_ext) { 231 /* Read PCI link status ... */ 232 value = soc_pci_read(unit, CMIC_LINK_STAT_MOD1); 233 if (value != SOC_PBMP_WORD_GET(ls->ls_bmp[i], 1)) { 234 test_error(unit, 235 "ERROR: unexpected link status (mod1) on cmic\n" 236 "\tread 0x%x, expecting 0x%x\n", 237 value, SOC_PBMP_WORD_GET(ls->ls_bmp[i], 1)); 238 /* Just continue if we return. */ 239 } 240 } 241 242 SOC_BLOCK_ITER(unit, blk, SOC_BLK_ETHER) { 243 port = SOC_BLOCK_PORT(unit, blk); 244 rv = READ_EPC_LINKr(unit, port, &val64); 245 if (rv < 0) { 246 test_error(unit, 247 "ERROR: EPC_LINK register (port %s) read failed: %s\n", 248 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 249 return -1; 250 } 251 value = COMPILER_64_LO(val64); 252 if (value != SOC_PBMP_WORD_GET(ls->ls_bmp[i], 0)) { 253 test_error(unit, "ERROR: unexpected link status on port %s\n" 254 "\tread 0x%x, expecting 0x%x\n", 255 SOC_PORT_NAME(unit, port), 256 value, SOC_PBMP_WORD_GET(ls->ls_bmp[i], 0)); 257 return -1; 258 } 259 if (bitmap_ext) { 260 value = COMPILER_64_HI(val64); 261 if (value != SOC_PBMP_WORD_GET(ls->ls_bmp[i], 1)) { 262 test_error(unit, 263 "ERROR: unexpected link status (mod1) on port %s\n" 264 "\tread 0x%x, expecting 0x%x\n", 265 SOC_PORT_NAME(unit, port), 266 value, SOC_PBMP_WORD_GET(ls->ls_bmp[i], 1)); 267 return -1; 268 } 269 } 270 } 271 } 272 273 return 0; 274 } 275 276 /* 277 * Function: 278 * Purpose: 279 * Parameters: 280 * Returns: 281 */ 282 int 283 cos_stat_test(int unit, args_t *a, void *pa) 284 { 285 int i, cos, port, npat, rv; 286 schan_msg_t schMsg; 287 uint32 value, setval; 288 pbmp_t bmp[LS_TEST_PATTERNS]; 289 290 COMPILER_REFERENCE(pa); 291 292 if (ARG_CNT(a)) { 293 test_error(unit, "Arguments not supported\n"); 294 return (-1); 295 } 296 297 SOC_PBMP_ASSIGN(bmp[0], PBMP_PORT_ALL(unit)); 298 SOC_PBMP_CLEAR(bmp[1]); 299 SOC_PBMP_CLEAR(bmp[2]); 300 SOC_PBMP_WORD_SET(bmp[2], 0, 0x55555555); 301 SOC_PBMP_AND(bmp[2], PBMP_PORT_ALL(unit)); 302 SOC_PBMP_CLEAR(bmp[3]); 303 SOC_PBMP_WORD_SET(bmp[3], 0, 0xaaaaaaaa); 304 SOC_PBMP_AND(bmp[3], PBMP_PORT_ALL(unit)); 305 306 i = 4; 307 PBMP_PORT_ITER(unit, port) { 308 SOC_PBMP_CLEAR(bmp[i]); 309 SOC_PBMP_PORT_ADD(bmp[i], port); 310 SOC_PBMP_ASSIGN(bmp[i + NUM_E_PORT(unit)], PBMP_PORT_ALL(unit)); 311 SOC_PBMP_REMOVE(bmp[i + NUM_E_PORT(unit)], bmp[i]); 312 i++; 313 } 314 npat = i + NUM_E_PORT(unit); 315 316 for (cos = 0; cos < NUM_COS(unit); cos++) { 317 /* Go through all forwarding port values */ 318 for (i = 0; i < npat; i++) { 319 setval = SOC_PBMP_WORD_GET(bmp[0], 0); 320 LOG_INFO(BSL_LS_APPL_TESTS, 321 (BSL_META_U(unit, 322 "Setting the COS%d Status register to 0x%x\n"), 323 cos, setval)); 324 325 /* Update forwarding port register all blocks/functional units */ 326 PBMP_PORT_ITER(unit, port) { 327 rv = WRITE_COS_ENABLEr(unit, port, cos, setval); 328 if (rv < 0) { 329 test_error(unit, "ERROR: COS_ENABLE.%d register (port %s) write failed: %s\n", 330 cos, SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 331 return -1; 332 } 333 } 334 335 /* Send status change SChannel message */ 336 337 setval = SOC_PBMP_WORD_GET(bmp[i], 0); 338 LOG_INFO(BSL_LS_APPL_TESTS, 339 (BSL_META_U(unit, 340 "Sending COS%d status with value 0x%x\n"), cos, setval)); 341 schan_msg_clear(&schMsg); 342 schMsg.header.opcode = COS_QSTAT_NOTIFY_MSG; 343 344 /* Use bitmap structure */ 345 schMsg.bitmap.bitmap = setval; 346 schMsg.header.cos = cos; 347 348 /* Write message out */ 349 if ((rv = soc_schan_op(unit, &schMsg, 2, 0, 0)) < 0) { 350 test_error(unit, "ERROR: soc_schan_op failed: %s\n", 351 bcm_errmsg(rv)); 352 return -1; 353 } 354 355 /* Read CMIC register ... */ 356 357 value = soc_pci_read(unit, CMIC_COS_ENABLE(cos)); 358 value = ~value; /* cmic register is inverted */ 359 360 if (value != setval) { 361 test_error(unit, "ERROR: COS_ENABLE.%d register (CMIC) unexpected value\n" 362 "\tread 0x%x, expected 0x%x\n", 363 cos, 364 value, setval); 365 return -1; 366 } 367 368 PBMP_PORT_ITER(unit, port) { 369 rv = READ_COS_ENABLEr(unit, port, cos, &value); 370 if (rv < 0) { 371 test_error(unit, "ERROR: COS_ENABLE.%d register (port %s) read failed: %s\n", 372 cos, SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 373 return -1; 374 } 375 if (value != setval) { 376 test_error(unit, "ERROR: COS_ENABLE.%d register (port %s) unexpected value\n" 377 "\tread 0x%x, expected 0x%x\n", 378 cos, SOC_PORT_NAME(unit, port), 379 value, setval); 380 return -1; 381 } 382 } 383 } 384 } 385 386 return 0; 387 } 388 389 /* 390 * Test various given register status with various patterns 391 */ 392 STATIC int 393 regStatus_test(int unit, soc_reg_t reg) 394 { 395 int i, rv, npat; 396 schan_msg_t schMsg; 397 uint32 value, setval; 398 pbmp_t bmp[LS_TEST_PATTERNS]; 399 char *regname; 400 int blk, port; 401 uint32 addr; 402 403 SOC_PBMP_ASSIGN(bmp[0], PBMP_PORT_ALL(unit)); 404 SOC_PBMP_CLEAR(bmp[1]); 405 SOC_PBMP_CLEAR(bmp[2]); 406 SOC_PBMP_WORD_SET(bmp[2], 0, 0x55555555); 407 SOC_PBMP_AND(bmp[2], PBMP_PORT_ALL(unit)); 408 SOC_PBMP_CLEAR(bmp[3]); 409 SOC_PBMP_WORD_SET(bmp[3], 0, 0xaaaaaaaa); 410 SOC_PBMP_AND(bmp[3], PBMP_PORT_ALL(unit)); 411 412 i = 4; 413 PBMP_PORT_ITER(unit, port) { 414 SOC_PBMP_CLEAR(bmp[i]); 415 SOC_PBMP_PORT_ADD(bmp[i], port); 416 SOC_PBMP_ASSIGN(bmp[i + NUM_E_PORT(unit)], PBMP_PORT_ALL(unit)); 417 SOC_PBMP_REMOVE(bmp[i + NUM_E_PORT(unit)], bmp[i]); 418 i++; 419 } 420 npat = i + NUM_E_PORT(unit); 421 422 if (!SOC_REG_IS_VALID(unit, reg)) { 423 test_error(unit, "ERROR: register %d is not valid for unit %d\n", 424 reg, unit); 425 return -1; 426 } 427 regname = SOC_REG_NAME(unit, reg); 428 429 /* Go through all forwarding port values */ 430 for (i = 0; i < npat; i++) { 431 setval = SOC_PBMP_WORD_GET(bmp[0], 0); 432 LOG_INFO(BSL_LS_APPL_TESTS, 433 (BSL_META_U(unit, 434 "Setting register %s to 0x%x\n"), 435 regname, setval)); 436 soc_reg_write_all_blocks(unit, reg, setval); 437 438 schan_msg_clear(&schMsg); 439 440 setval = SOC_PBMP_WORD_GET(bmp[i], 0); 441 /* Send status change SChannel message */ 442 switch (reg) { 443 case EPC_HOLr: 444 schMsg.header.opcode = HOL_STAT_NOTIFY_MSG; 445 break; 446 case EGR_BKP_DISr: 447 schMsg.header.opcode = BP_DISCARD_STATUS_MSG; 448 break; 449 default: 450 test_error(unit, "ERROR: unexpected register %s\n", regname); 451 return -1; 452 } 453 LOG_INFO(BSL_LS_APPL_TESTS, 454 (BSL_META_U(unit, 455 "Sending schan message value 0x%x\n"), setval)); 456 457 /* Use bitmap structure */ 458 schMsg.bitmap.bitmap = setval; 459 460 /* Write message out */ 461 if ((rv = soc_schan_op(unit, &schMsg, 2, 0, 0)) < 0) { 462 test_error(unit, "soc_schan_op failed: %s\n", bcm_errmsg(rv)); 463 return -1; 464 } 465 466 /* Read CMIC register ... */ 467 468 switch (reg) { 469 case EPC_HOLr: 470 value = soc_pci_read(unit, CMIC_HOL_STAT); 471 value = ~value; /* cmic register is inverted */ 472 break; 473 case EGR_BKP_DISr: 474 value = soc_pci_read(unit, CMIC_IGBP_DISCARD); 475 break; 476 default: 477 test_error(unit, "ERROR: unexpected register %s\n", regname); 478 return -1; 479 } 480 if (value != setval) { 481 test_error(unit, 482 "ERROR: %s register (CMIC) unexpected value\n" 483 " read=0x%x, expecting=0x%x\n", 484 regname, 485 value, setval); 486 return -1; 487 } 488 489 SOC_BLOCK_ITER(unit, blk, SOC_BLK_ETHER) { 490 port = SOC_BLOCK_PORT(unit, blk); 491 addr = soc_reg_addr(unit, reg, port, 0); 492 if ((rv = soc_reg32_read(unit, addr, &value)) < 0) { 493 test_error(unit, 494 "ERROR: %s register (port %s) read failed: %s\n", 495 regname, SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 496 return -1; 497 } 498 if (value != setval) { 499 test_error(unit, 500 "ERROR: %s register (port %s) unexpected value\n" 501 " read=0x%x, expecting=0x%x\n", 502 regname, SOC_PORT_NAME(unit, port), 503 value, setval); 504 return -1; 505 } 506 } 507 } 508 509 return 0; 510 } 511 512 /*ARGSUSED*/ 513 int 514 hol_stat_test(int u, args_t *a, void *pa) 515 { 516 COMPILER_REFERENCE(a); 517 COMPILER_REFERENCE(pa); 518 519 return regStatus_test(u, EPC_HOLr); 520 } 521 522 /*ARGSUSED*/ 523 int 524 bkp_stat_test(int u, args_t *a, void *pa) 525 { 526 COMPILER_REFERENCE(a); 527 COMPILER_REFERENCE(pa); 528 529 return regStatus_test(u, EGR_BKP_DISr); 530 } 531 #endif /* BCM_STRATA_SUPPORT */