failover.c (56138B)
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 * TR2 failover API 8 */ 9 10 #include <soc/defs.h> 11 #include <sal/core/libc.h> 12 #include <shared/bsl.h> 13 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 14 15 #include <soc/drv.h> 16 #include <soc/mem.h> 17 #include <soc/util.h> 18 #include <soc/debug.h> 19 #include <bcm/types.h> 20 #include <bcm/error.h> 21 #include <bcm_int/esw/mbcm.h> 22 #include <bcm_int/esw_dispatch.h> 23 #include <bcm_int/esw/field.h> 24 #include <bcm_int/esw/firebolt.h> 25 #include <bcm_int/esw/triumph2.h> 26 #include <bcm_int/esw/failover.h> 27 #include <bcm/failover.h> 28 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 29 #include <bcm_int/esw/trident2plus.h> 30 #endif 31 #if defined(BCM_SABER2_SUPPORT) 32 #include <bcm_int/esw/saber2.h> 33 #endif 34 #if defined(BCM_TOMAHAWK2_SUPPORT) 35 #include <bcm_int/esw/tomahawk2.h> 36 #endif 37 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 38 #include <soc/esw/ecmp.h> 39 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 40 #ifdef BCM_WARM_BOOT_SUPPORT 41 #include <bcm_int/esw/switch.h> 42 #include <soc/scache.h> 43 #endif /* BCM_WARM_BOOT_SUPPORT */ 44 45 /* 46 * Function: 47 * _bcm_failover_check_init 48 * Purpose: 49 * Check if Failover is initialized 50 * Parameters: 51 * unit - Device Number 52 * Returns: 53 * BCM_E_XXX 54 */ 55 56 57 STATIC int 58 _bcm_failover_check_init (int unit) 59 { 60 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { 61 return BCM_E_UNIT; 62 } 63 64 if (!_bcm_failover_bk_info[unit].initialized) { 65 return BCM_E_INIT; 66 } else { 67 return BCM_E_NONE; 68 } 69 } 70 71 72 73 /* 74 * Function: 75 * bcm_failover_lock 76 * Purpose: 77 * Take the Failover Lock Sempahore 78 * Parameters: 79 * unit - Device Number 80 * Returns: 81 * BCM_E_XXX 82 */ 83 84 85 int 86 bcm_tr2_failover_lock (int unit) 87 { 88 int rv; 89 90 rv = _bcm_failover_check_init (unit); 91 92 if ( rv == BCM_E_NONE ) { 93 sal_mutex_take(FAILOVER_INFO((unit))->failover_mutex, sal_mutex_FOREVER); 94 } 95 return rv; 96 } 97 98 99 100 /* 101 * Function: 102 * bcm_failover_unlock 103 * Purpose: 104 * Release the Failover Lock Semaphore 105 * Parameters: 106 * unit - Device Number 107 * Returns: 108 * BCM_E_XXX 109 */ 110 111 112 void 113 bcm_tr2_failover_unlock(int unit) 114 { 115 int rv; 116 117 rv = _bcm_failover_check_init (unit); 118 119 if ( rv == BCM_E_NONE ) { 120 sal_mutex_give(FAILOVER_INFO((unit))->failover_mutex); 121 } 122 } 123 124 125 126 /* 127 * Function: 128 * _bcm_tr2_failover_free_resource 129 * Purpose: 130 * Free all allocated software resources 131 * Parameters: 132 * unit - SOC unit number 133 * Returns: 134 * Nothing 135 */ 136 137 138 STATIC void 139 _bcm_tr2_failover_free_resource(int unit, _bcm_failover_bookkeeping_t *failover_info) 140 { 141 142 if (!failover_info) { 143 return; 144 } 145 146 if (failover_info->prot_group_bitmap) { 147 sal_free(failover_info->prot_group_bitmap); 148 failover_info->prot_group_bitmap = NULL; 149 } 150 151 if (failover_info->prot_nhi_bitmap) { 152 sal_free(failover_info->prot_nhi_bitmap); 153 failover_info->prot_nhi_bitmap = NULL; 154 } 155 156 if (failover_info->mmu_prot_group_bitmap) { 157 sal_free(failover_info->mmu_prot_group_bitmap); 158 failover_info->mmu_prot_group_bitmap = NULL; 159 } 160 161 } 162 163 #ifdef BCM_WARM_BOOT_SUPPORT 164 165 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 166 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_0 167 168 169 /* 170 * Function: 171 * _bcm_tr2_failover_alloc 172 * Purpose: 173 * Alloc scache for warm boot. 174 * Parameters: 175 * unit : (IN) Device Unit Number 176 * Returns: 177 * BCM_E_XXX 178 */ 179 STATIC int 180 _bcm_tr2_failover_alloc(int unit) 181 { 182 soc_scache_handle_t scache_handle; 183 uint8 *scache_ptr; 184 int rv, alloc_size, prot_grp_idx_count; 185 186 prot_grp_idx_count = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 187 alloc_size = SHR_BITALLOCSIZE(prot_grp_idx_count); 188 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_FAILOVER, 0); 189 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, alloc_size, 190 &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL); 191 if (rv == BCM_E_NOT_FOUND) { 192 rv = BCM_E_NONE; 193 } 194 195 return rv; 196 } 197 198 199 /* 200 * Function: 201 * bcm_tr2_failover_sync 202 * Purpose: 203 * Sync scache for warm boot. 204 * Parameters: 205 * unit : (IN) Device Unit Number 206 * Returns: 207 * BCM_E_XXX 208 */ 209 int 210 bcm_tr2_failover_sync(int unit) 211 { 212 soc_scache_handle_t scache_handle; 213 uint8 *scache_ptr, *ptr; 214 int prot_grp_idx_count; 215 int rv; 216 217 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_FAILOVER, 0); 218 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0, 219 &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL); 220 if (BCM_FAILURE(rv)) { 221 if (rv == BCM_E_NOT_FOUND) { 222 return BCM_E_NONE; 223 } 224 return rv; 225 } 226 227 ptr = scache_ptr; 228 prot_grp_idx_count = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 229 230 /* Sync PROT_GROUP_MAP */ 231 sal_memcpy(ptr, BCM_FAILOVER_PROT_GROUP_MAP(unit), 232 SHR_BITALLOCSIZE(prot_grp_idx_count)); 233 ptr += SHR_BITALLOCSIZE(prot_grp_idx_count); 234 235 return BCM_E_NONE; 236 } 237 238 239 /* 240 * Function: 241 * _bcm_tr2_failover_prot_nhi_recover 242 * Purpose: 243 * PROT_NHI_MAP recover for warm boot. 244 * Parameters: 245 * unit : (IN) Device Unit Number 246 * Returns: 247 * BCM_E_XXX 248 */ 249 STATIC int 250 _bcm_tr2_failover_prot_nhi_recover(int unit) 251 { 252 int idx, index_min, index_max, prot_grp_idx, grp_idx_max; 253 initial_prot_nhi_table_entry_t prot_nhi_entry; 254 soc_field_t fld; 255 soc_field_t fld_grp; 256 257 grp_idx_max = soc_mem_index_max(unit, INITIAL_PROT_GROUP_TABLEm); 258 259 index_min = soc_mem_index_min(unit, INITIAL_PROT_NHI_TABLEm); 260 index_max = soc_mem_index_max(unit, INITIAL_PROT_NHI_TABLEm); 261 if (SOC_IS_KATANA2(unit) || SOC_IS_TRIUMPH3(unit)) { 262 fld = REPLACEMENT_DATAf; 263 } else { 264 fld = PROT_NEXT_HOP_INDEXf; 265 } 266 fld_grp = PROT_GROUPf; 267 268 for (idx = index_min; idx <= index_max; idx++) { 269 SOC_IF_ERROR_RETURN(soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, MEM_BLOCK_ANY, 270 idx, &prot_nhi_entry)); 271 prot_grp_idx = soc_INITIAL_PROT_NHI_TABLEm_field32_get(unit, &prot_nhi_entry, fld_grp); 272 if ( (prot_grp_idx >= 1) && (prot_grp_idx <= grp_idx_max) && 273 (soc_INITIAL_PROT_NHI_TABLEm_field32_get(unit, &prot_nhi_entry, 274 fld) != 0) ) { 275 _BCM_FAILOVER_PROT_NHI_MAP_USED_SET(unit, idx); 276 } 277 } 278 279 return BCM_E_NONE; 280 } 281 282 283 /* 284 * Function: 285 * _bcm_tr2_failover_recovery 286 * Purpose: 287 * Scache recovery for warm boot. 288 * Parameters: 289 * unit : (IN) Device Unit Number 290 * Returns: 291 * BCM_E_XXX 292 */ 293 STATIC int 294 _bcm_tr2_failover_recovery(int unit) 295 { 296 soc_scache_handle_t scache_handle; 297 uint8 *scache_ptr, *ptr; 298 int rv, prot_grp_idx_count; 299 uint16 recovered_ver; 300 301 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_FAILOVER, 0); 302 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0, 303 &scache_ptr, BCM_WB_DEFAULT_VERSION, &recovered_ver); 304 305 if (BCM_E_NOT_FOUND == rv) { 306 /* Upgrading from SDK release that does not have warmboot state, 307 Alloc scache for now on */ 308 rv = _bcm_tr2_failover_alloc(unit); 309 if (BCM_FAILURE(rv)) { 310 return rv; 311 } 312 return BCM_E_NOT_FOUND; 313 } else if (BCM_FAILURE(rv)) { 314 return rv; 315 } 316 317 /* SCACHE Hande found, recover from SCAHE */ 318 prot_grp_idx_count = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 319 ptr = scache_ptr; 320 321 /* Recover PROT_GROUP_MAP */ 322 sal_memcpy(BCM_FAILOVER_PROT_GROUP_MAP(unit), ptr, 323 SHR_BITALLOCSIZE(prot_grp_idx_count)); 324 ptr += SHR_BITALLOCSIZE(prot_grp_idx_count); 325 326 /* Recover PROT_NHI_MAP */ 327 BCM_IF_ERROR_RETURN(_bcm_tr2_failover_prot_nhi_recover(unit)); 328 329 return BCM_E_NONE; 330 } 331 332 333 /* 334 * Function: 335 * _bcm_tr2_failover_reinit 336 * Purpose: 337 * Reinit for warm boot. 338 * Parameters: 339 * unit : (IN) Device Unit Number 340 * Returns: 341 * BCM_E_XXX 342 */ 343 STATIC int 344 _bcm_tr2_failover_reinit(int unit) 345 { 346 int idx, index_min, index_max, prot_grp_idx, grp_idx_max; 347 initial_prot_nhi_table_entry_t prot_nhi_entry; 348 soc_field_t fld; 349 soc_field_t fld_grp; 350 int rv; 351 352 if (SOC_IS_TRIUMPH3(unit)) { 353 /* Try SCACHE Recovery first */ 354 rv = _bcm_tr2_failover_recovery(unit); 355 356 if BCM_SUCCESS(rv) { 357 /* WB recovery successfull, return */ 358 return (rv); 359 } 360 361 if ( (BCM_FAILURE(rv)) && (rv != BCM_E_NOT_FOUND)) { 362 /* Something failed in WB recovery, return error code */ 363 return (rv); 364 } 365 366 /* If we are here => (rv == BCM_E_NOT_FOUND), Resort to H/w recovery */ 367 } 368 369 grp_idx_max = soc_mem_index_max(unit, INITIAL_PROT_GROUP_TABLEm); 370 371 index_min = soc_mem_index_min(unit, INITIAL_PROT_NHI_TABLEm); 372 index_max = soc_mem_index_max(unit, INITIAL_PROT_NHI_TABLEm); 373 if (SOC_IS_KATANA2(unit) || SOC_IS_TRIUMPH3(unit)) { 374 fld = REPLACEMENT_DATAf; 375 } else { 376 fld = PROT_NEXT_HOP_INDEXf; 377 } 378 fld_grp = PROT_GROUPf; 379 380 for (idx = index_min; idx <= index_max; idx++) { 381 SOC_IF_ERROR_RETURN(soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, MEM_BLOCK_ANY, 382 idx, &prot_nhi_entry)); 383 prot_grp_idx = soc_INITIAL_PROT_NHI_TABLEm_field32_get(unit, &prot_nhi_entry, fld_grp); 384 if ( (prot_grp_idx >= 1) && (prot_grp_idx <= grp_idx_max) && 385 (soc_INITIAL_PROT_NHI_TABLEm_field32_get(unit, &prot_nhi_entry, 386 fld) != 0) ) { 387 _BCM_FAILOVER_PROT_GROUP_MAP_USED_SET(unit, prot_grp_idx); 388 _BCM_FAILOVER_PROT_NHI_MAP_USED_SET(unit, idx); 389 } 390 } 391 return BCM_E_NONE; 392 } 393 #endif /* BCM_WARM_BOOT_SUPPORT */ 394 395 396 /* 397 * Function: 398 * bcm_tr2_failover_init 399 * Purpose: 400 * Initialize the Failover software module 401 * Parameters: 402 * unit - Device Number 403 * Returns: 404 * BCM_E_XXX 405 */ 406 407 408 int 409 bcm_tr2_failover_init(int unit) 410 { 411 int rv = BCM_E_NONE; 412 int num_prot_group, num_prot_nhi; 413 #if defined(BCM_SABER2_SUPPORT) 414 int mmu_num_prot_group; 415 #endif 416 _bcm_failover_bookkeeping_t *failover_info = FAILOVER_INFO(unit); 417 418 /* 419 * allocate resources 420 */ 421 if (failover_info->initialized) { 422 BCM_IF_ERROR_RETURN(bcm_tr2_failover_cleanup(unit)); 423 } 424 425 num_prot_group = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 426 num_prot_nhi = soc_mem_index_count(unit, INITIAL_PROT_NHI_TABLEm); 427 428 failover_info->prot_group_bitmap = 429 sal_alloc(SHR_BITALLOCSIZE(num_prot_group), "prot_group_bitmap"); 430 if (failover_info->prot_group_bitmap == NULL) { 431 _bcm_tr2_failover_free_resource(unit, failover_info); 432 return BCM_E_MEMORY; 433 } 434 435 failover_info->prot_nhi_bitmap = 436 sal_alloc(SHR_BITALLOCSIZE(num_prot_nhi), "prot_nhi_bitmap"); 437 if (failover_info->prot_nhi_bitmap == NULL) { 438 _bcm_tr2_failover_free_resource(unit, failover_info); 439 return BCM_E_MEMORY; 440 } 441 442 sal_memset(failover_info->prot_group_bitmap, 0, SHR_BITALLOCSIZE(num_prot_group)); 443 sal_memset(failover_info->prot_nhi_bitmap, 0, SHR_BITALLOCSIZE(num_prot_nhi)); 444 445 /* Create Failover protection mutex. */ 446 failover_info->failover_mutex = sal_mutex_create("failover_mutex"); 447 if (!failover_info->failover_mutex) { 448 _bcm_tr2_failover_free_resource(unit, failover_info); 449 return BCM_E_MEMORY; 450 } 451 452 #if defined(BCM_SABER2_SUPPORT) 453 if (SOC_IS_SABER2(unit)) { 454 /* Since each entry represent 32 group, multiplexing with 32 */ 455 mmu_num_prot_group = 2 * soc_mem_index_count(unit, MMU_INITIAL_NHOP_TBLm); 456 457 failover_info->mmu_prot_group_bitmap = 458 sal_alloc(SHR_BITALLOCSIZE(mmu_num_prot_group), "mmu_prot_group_bitmap"); 459 if (failover_info->mmu_prot_group_bitmap == NULL) { 460 _bcm_tr2_failover_free_resource(unit, failover_info); 461 return BCM_E_MEMORY; 462 } 463 464 sal_memset(failover_info->mmu_prot_group_bitmap, 0, SHR_BITALLOCSIZE(mmu_num_prot_group)); 465 } 466 #endif 467 468 #ifdef BCM_WARM_BOOT_SUPPORT 469 if(SOC_WARM_BOOT(unit)) { 470 rv = _bcm_tr2_failover_reinit(unit); 471 if (BCM_FAILURE(rv)){ 472 _bcm_tr2_failover_free_resource(unit, failover_info); 473 return rv; 474 } 475 } else { 476 /* Cold boot, Allocate scache */ 477 if (SOC_IS_TRIUMPH3(unit)) { 478 rv = _bcm_tr2_failover_alloc(unit); 479 if (BCM_FAILURE(rv)) { 480 _bcm_tr2_failover_free_resource(unit, failover_info); 481 return rv; 482 } 483 } 484 } 485 #endif /* BCM_WARM_BOOT_SUPPORT */ 486 487 /* Mark the state as initialized */ 488 failover_info->initialized = TRUE; 489 490 return rv; 491 } 492 493 /* 494 * Function: 495 * _bcm_tr2_failover_hw_clear 496 * Purpose: 497 * Perform hw tables clean up for failover module. 498 * Parameters: 499 * unit - Device Number 500 * Returns: 501 * BCM_E_XXX 502 */ 503 504 STATIC int 505 _bcm_tr2_failover_hw_clear(int unit) 506 { 507 int i, rv, rv_error = BCM_E_NONE; 508 int num_entry; 509 510 num_entry = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 511 512 /* Index-0 is reserved */ 513 for (i = 1; i < num_entry; i++) { 514 if (_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, i)) { 515 rv = bcm_tr2_failover_destroy(unit, i); 516 if (rv < 0) { 517 rv_error = rv; 518 } 519 } 520 } 521 522 #if defined(BCM_SABER2_SUPPORT) 523 if (SOC_IS_SABER2(unit)) { 524 num_entry = 2 * soc_mem_index_count(unit, MMU_INITIAL_NHOP_TBLm) ; 525 526 /* Index-0 is reserved */ 527 for (i = 1; i < num_entry; i++) { 528 if (_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, i)) { 529 rv = bcm_tr2_mmu_failover_destroy(unit, i); 530 if (rv < 0) { 531 rv_error = rv; 532 } 533 } 534 } 535 } 536 #endif 537 return rv_error; 538 } 539 540 /* 541 * Function: 542 * bcm_tr2_failover_cleanup 543 * Purpose: 544 * DeInit the Failover software module 545 * Parameters: 546 * unit - Device Number 547 * Returns: 548 * BCM_E_XXX 549 */ 550 551 int 552 bcm_tr2_failover_cleanup(int unit) 553 { 554 _bcm_failover_bookkeeping_t *failover_info = FAILOVER_INFO(unit); 555 int rv = BCM_E_UNAVAIL; 556 557 if (FALSE == failover_info->initialized) { 558 return (BCM_E_NONE); 559 } 560 561 rv = bcm_tr2_failover_lock (unit); 562 if (BCM_FAILURE(rv)) { 563 return rv; 564 } 565 566 if (0 == SOC_HW_ACCESS_DISABLE(unit)) { 567 rv = _bcm_tr2_failover_hw_clear(unit); 568 } 569 570 /* Free software resources */ 571 (void) _bcm_tr2_failover_free_resource(unit, failover_info); 572 573 bcm_tr2_failover_unlock (unit); 574 575 /* Destroy protection mutex. */ 576 sal_mutex_destroy(failover_info->failover_mutex); 577 578 /* Mark the state as uninitialized */ 579 failover_info->initialized = FALSE; 580 581 return rv; 582 } 583 584 #if defined(BCM_SABER2_SUPPORT) 585 /* 586 * Function: 587 * _bcm_tr2_failover_get_prot_group_table_index 588 * Purpose: 589 * Obtain Index into INITIAL_PROT_GROUP_TABLE 590 * Parameters: 591 * IN : Unit 592 * OUT : prot_index 593 * Returns: 594 * BCM_E_XXX 595 */ 596 597 598 STATIC int 599 _bcm_tr2_failover_get_mmu_prot_group_table_index (int unit, int *prot_index) 600 { 601 int i; 602 int num_entry; 603 604 num_entry = 2 * soc_mem_index_count(unit, MMU_INITIAL_NHOP_TBLm); 605 606 /* Index-0 is reserved */ 607 for (i = 1; i < num_entry; i++) { 608 if (!_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, i)) { 609 break; 610 } 611 } 612 613 if (i == num_entry) { 614 return BCM_E_RESOURCE; 615 } 616 _BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_SET(unit, i); 617 *prot_index = i; 618 619 return BCM_E_NONE; 620 } 621 #endif /* BCM_SABER2_SUPPORT */ 622 623 624 /* 625 * Function: 626 * _bcm_tr2_failover_clear_prot_group_table_entry 627 * Purpose: 628 * Clear INITIAL_PROT_GROUP_TABLE entry pointed by Index 629 * Parameters: 630 * IN : Unit 631 * IN : prot_index 632 * Returns: 633 * BCM_E_XXX 634 */ 635 636 637 STATIC void 638 _bcm_tr2_failover_clear_mmu_prot_group_table_entry (int unit, bcm_failover_t prot_index) 639 { 640 _BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_CLR(unit, prot_index); 641 } 642 643 644 /* 645 * Function: 646 * _bcm_tr2_failover_id_validate 647 * Purpose: 648 * Validate the failover ID 649 * Parameters: 650 * IN : failover_id 651 * Returns: 652 * BCM_E_XXX 653 */ 654 655 int 656 bcm_tr2_failover_mmu_id_validate (int unit, bcm_failover_t failover_id) 657 { 658 int num_entry; 659 660 num_entry = 2 * soc_mem_index_count(unit, MMU_INITIAL_NHOP_TBLm); 661 662 if ( ( failover_id < 1 ) || (failover_id > num_entry ) ) { 663 return BCM_E_PARAM; 664 } else if (failover_id == num_entry) { 665 return BCM_E_RESOURCE; 666 } 667 if (!_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, failover_id)) { 668 return BCM_E_NOT_FOUND; 669 } 670 671 return BCM_E_NONE; 672 } 673 /* 674 * Function: 675 * _bcm_tr2_failover_get_prot_group_table_index 676 * Purpose: 677 * Obtain Index into INITIAL_PROT_GROUP_TABLE 678 * Parameters: 679 * IN : Unit 680 * OUT : prot_index 681 * Returns: 682 * BCM_E_XXX 683 */ 684 685 686 STATIC int 687 _bcm_tr2_failover_get_prot_group_table_index (int unit, int *prot_index) 688 { 689 int i; 690 int num_entry; 691 692 num_entry = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 693 694 /* Index-0 is reserved */ 695 for (i = 1; i < num_entry; i++) { 696 if (!_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, i)) { 697 break; 698 } 699 } 700 701 if (i == num_entry) { 702 return BCM_E_RESOURCE; 703 } 704 _BCM_FAILOVER_PROT_GROUP_MAP_USED_SET(unit, i); 705 *prot_index = i; 706 707 return BCM_E_NONE; 708 } 709 710 711 712 /* 713 * Function: 714 * _bcm_tr2_failover_clear_prot_group_table_entry 715 * Purpose: 716 * Clear INITIAL_PROT_GROUP_TABLE entry pointed by Index 717 * Parameters: 718 * IN : Unit 719 * IN : prot_index 720 * Returns: 721 * BCM_E_XXX 722 */ 723 724 725 STATIC void 726 _bcm_tr2_failover_clear_prot_group_table_entry (int unit, bcm_failover_t prot_index) 727 { 728 _BCM_FAILOVER_PROT_GROUP_MAP_USED_CLR(unit, prot_index); 729 } 730 731 732 733 /* 734 * Function: 735 * _bcm_tr2_failover_set_prot_group_table_entry 736 * Purpose: 737 * Set INITIAL_PROT_GROUP_TABLE entry pointed by Index 738 * Parameters: 739 * IN : Unit 740 * IN : prot_index 741 * Returns: 742 * BCM_E_XXX 743 */ 744 745 746 STATIC void 747 _bcm_tr2_failover_set_prot_group_table_entry (int unit, bcm_failover_t prot_index) 748 { 749 _BCM_FAILOVER_PROT_GROUP_MAP_USED_SET(unit, prot_index); 750 } 751 752 /* 753 * Function: 754 * _bcm_tr2_failover_id_validate 755 * Purpose: 756 * Validate the failover ID 757 * Parameters: 758 * IN : failover_id 759 * Returns: 760 * BCM_E_XXX 761 */ 762 763 int 764 bcm_tr2_failover_id_validate (int unit, bcm_failover_t failover_id) 765 { 766 int num_entry; 767 768 num_entry = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 769 770 if ( ( failover_id < 1 ) || (failover_id > num_entry ) ) { 771 return BCM_E_PARAM; 772 } else if (failover_id == num_entry) { 773 return BCM_E_RESOURCE; 774 } 775 if (!_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, failover_id)) { 776 return BCM_E_NOT_FOUND; 777 } 778 779 return BCM_E_NONE; 780 } 781 782 /* 783 * Function: 784 * bcm_tr2_failover_create 785 * Purpose: 786 * Create a failover object 787 * Parameters: 788 * IN : unit 789 * IN : flags 790 * OUT : failover_id 791 * Returns: 792 * BCM_E_XXX 793 */ 794 795 int 796 bcm_tr2_failover_create(int unit, uint32 flags, bcm_failover_t *failover_id) 797 { 798 int rv = BCM_E_UNAVAIL; 799 initial_prot_group_table_entry_t prot_group_entry; 800 #if defined(BCM_TRIUMPH3_SUPPORT) 801 rx_prot_group_table_entry_t rx_prot_group_entry; 802 #endif /* BCM_TRIUMPH3_SUPPORT */ 803 int num_entry; 804 805 if (failover_id == NULL) { 806 return BCM_E_PARAM; 807 } 808 809 /* Check for unsupported Flag */ 810 if (flags & (~(BCM_FAILOVER_REPLACE | 811 BCM_FAILOVER_WITH_ID | 812 BCM_FAILOVER_ENCAP))) { 813 return BCM_E_PARAM; 814 } 815 816 if ((flags & BCM_FAILOVER_WITH_ID) || (flags & BCM_FAILOVER_REPLACE )) { 817 818 #if defined(BCM_SABER2_SUPPORT) 819 if ((SOC_IS_SABER2(unit)) && (flags & BCM_FAILOVER_ENCAP)) { 820 /* make sure the given id is valid */ 821 num_entry = 2 * soc_mem_index_count(unit, MMU_INITIAL_NHOP_TBLm) ; 822 if ((*failover_id < 1) || (*failover_id >= num_entry)) { 823 return BCM_E_PARAM; 824 } 825 if (flags & BCM_FAILOVER_WITH_ID) { 826 if (_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, *failover_id)) { 827 return BCM_E_EXISTS; 828 } else { 829 _BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_SET(unit, *failover_id); 830 } 831 } 832 if (flags & BCM_FAILOVER_REPLACE) { 833 if (!_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, *failover_id)) { 834 return BCM_E_NOT_FOUND; 835 } 836 } 837 _BCM_ENCAP_TYPE_IN_FAILOVER_ID(*failover_id, _BCM_FAILOVER_1_1_MC_PROTECTION_MODE); 838 return BCM_E_NONE; 839 840 } else 841 #endif 842 { 843 /* make sure the given id is valid */ 844 num_entry = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 845 if ((*failover_id < 1) || (*failover_id >= num_entry)) { 846 return BCM_E_PARAM; 847 } 848 if (flags & BCM_FAILOVER_WITH_ID) { 849 if (_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, *failover_id)) { 850 return BCM_E_EXISTS; 851 } else { 852 _BCM_FAILOVER_PROT_GROUP_MAP_USED_SET(unit, *failover_id); 853 } 854 } 855 if (flags & BCM_FAILOVER_REPLACE) { 856 if (!_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, *failover_id)) { 857 return BCM_E_NOT_FOUND; 858 } 859 } 860 } 861 rv = BCM_E_NONE; 862 _BCM_ENCAP_TYPE_IN_FAILOVER_ID(*failover_id, _BCM_FAILOVER_DEFAULT_MODE); 863 } else if (!flags) { 864 /* Get Index */ 865 rv = _bcm_tr2_failover_get_prot_group_table_index (unit, failover_id); 866 _BCM_ENCAP_TYPE_IN_FAILOVER_ID(*failover_id, _BCM_FAILOVER_DEFAULT_MODE); 867 } 868 #if defined(BCM_SABER2_SUPPORT) 869 else if ((SOC_IS_SABER2(unit)) && (flags & BCM_FAILOVER_ENCAP)) { 870 /* Get Index */ 871 rv = _bcm_tr2_failover_get_mmu_prot_group_table_index (unit, failover_id); 872 BCM_IF_ERROR_RETURN(rv); 873 _BCM_ENCAP_TYPE_IN_FAILOVER_ID(*failover_id, _BCM_FAILOVER_1_1_MC_PROTECTION_MODE); 874 return BCM_E_NONE; 875 } 876 #endif 877 878 if (BCM_SUCCESS(rv)) { 879 /* Init table entry */ 880 sal_memset(&prot_group_entry, 0, sizeof(initial_prot_group_table_entry_t)); 881 rv = soc_mem_write(unit, INITIAL_PROT_GROUP_TABLEm, 882 MEM_BLOCK_ALL, *failover_id, 883 &prot_group_entry); 884 if (rv < 0) { 885 _bcm_tr2_failover_clear_prot_group_table_entry(unit, *failover_id); 886 return BCM_E_RESOURCE; 887 } 888 } 889 890 #if defined(BCM_TRIUMPH3_SUPPORT) 891 if (SOC_IS_TRIUMPH3(unit)) { 892 /* Init table entry */ 893 sal_memset(&rx_prot_group_entry, 0, sizeof(rx_prot_group_table_entry_t)); 894 rv = soc_mem_write(unit, RX_PROT_GROUP_TABLEm, 895 MEM_BLOCK_ALL, *failover_id, 896 &rx_prot_group_entry); 897 if (rv < 0) { 898 _bcm_tr2_failover_clear_prot_group_table_entry(unit, *failover_id); 899 return BCM_E_RESOURCE; 900 } 901 } 902 #endif /* BCM_TRIUMPH3_SUPPORT */ 903 904 return rv; 905 } 906 907 /* 908 * Function: 909 * bcm_tr2_failover_destroy 910 * Purpose: 911 * Destroy a failover object 912 * Parameters: 913 * IN : unit 914 * IN : failover_id 915 * Returns: 916 * BCM_E_XXX 917 */ 918 919 int 920 bcm_tr2_failover_destroy(int unit, bcm_failover_t failover_id) 921 { 922 int rv = BCM_E_UNAVAIL; 923 initial_prot_group_table_entry_t prot_group_entry; 924 #if defined(BCM_TRIUMPH3_SUPPORT) 925 rx_prot_group_table_entry_t rx_prot_group_entry; 926 #endif /* BCM_TRIUMPH3_SUPPORT */ 927 928 rv = bcm_tr2_failover_id_validate ( unit, failover_id ); 929 BCM_IF_ERROR_RETURN(rv); 930 931 if (!_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, failover_id)) { 932 return BCM_E_NOT_FOUND; 933 } 934 935 /* Release index */ 936 _bcm_tr2_failover_clear_prot_group_table_entry (unit, failover_id); 937 938 /* Clear entry */ 939 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 940 MEM_BLOCK_ANY, failover_id, &prot_group_entry)); 941 sal_memset(&prot_group_entry, 0, 942 sizeof(initial_prot_group_table_entry_t)); 943 rv = soc_mem_write(unit, INITIAL_PROT_GROUP_TABLEm, 944 MEM_BLOCK_ALL, failover_id, 945 &prot_group_entry); 946 if (rv < 0) { 947 _bcm_tr2_failover_set_prot_group_table_entry(unit, failover_id); 948 return BCM_E_RESOURCE; 949 } 950 951 #if defined(BCM_TRIUMPH3_SUPPORT) 952 if (SOC_IS_TRIUMPH3(unit)) { 953 /* Init table entry */ 954 sal_memset(&rx_prot_group_entry, 0, sizeof(rx_prot_group_table_entry_t)); 955 956 rv = soc_mem_write(unit, RX_PROT_GROUP_TABLEm, 957 MEM_BLOCK_ALL, failover_id, 958 &rx_prot_group_entry); 959 if (rv < 0) { 960 _bcm_tr2_failover_set_prot_group_table_entry(unit, failover_id); 961 return BCM_E_RESOURCE; 962 } 963 } 964 #endif /* BCM_TRIUMPH3_SUPPORT */ 965 966 return rv; 967 } 968 969 int 970 bcm_tr2_mmu_failover_destroy(int unit, bcm_failover_t failover_id) 971 { 972 _BCM_GET_FAILOVER_ID(failover_id); 973 if (!_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, failover_id)) { 974 return BCM_E_NOT_FOUND; 975 } 976 977 /* Release index */ 978 _bcm_tr2_failover_clear_mmu_prot_group_table_entry (unit, failover_id); 979 #if defined(BCM_SABER2_SUPPORT) 980 if (SOC_IS_SABER2(unit)) { 981 bcm_sb2_failover_destroy(unit, failover_id); 982 } 983 #endif 984 return BCM_E_NONE; 985 } 986 /* 987 * Function: 988 * bcm_tr2_failover_set 989 * Purpose: 990 * Set the parameters for a failover object 991 * Parameters: 992 * IN : unit 993 * IN : failover_id 994 * IN : value 995 * Returns: 996 * BCM_E_XXX 997 */ 998 999 int 1000 bcm_tr2_failover_set(int unit, bcm_failover_t failover_id, int value) 1001 { 1002 int rv = BCM_E_UNAVAIL; 1003 initial_prot_group_table_entry_t prot_group_entry; 1004 1005 BCM_IF_ERROR_RETURN( bcm_tr2_failover_id_validate ( unit, failover_id )); 1006 if (!_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, failover_id)) { 1007 return BCM_E_NOT_FOUND; 1008 } 1009 if ((value < 0) || (value > 1)) { 1010 return BCM_E_PARAM; 1011 } 1012 1013 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 1014 MEM_BLOCK_ANY, failover_id, &prot_group_entry)); 1015 1016 soc_mem_field32_set(unit, INITIAL_PROT_GROUP_TABLEm, 1017 &prot_group_entry, STATUSf, 1018 value); 1019 1020 rv = soc_mem_write(unit, INITIAL_PROT_GROUP_TABLEm, 1021 MEM_BLOCK_ALL, failover_id, 1022 &prot_group_entry); 1023 1024 return rv; 1025 1026 } 1027 1028 1029 /* 1030 * Function: 1031 * bcm_tr2_failover_get 1032 * Purpose: 1033 * Get the parameters for a failover object 1034 * Parameters: 1035 * IN : unit 1036 * IN : failover_id 1037 * OUT : value 1038 * Returns: 1039 * BCM_E_XXX 1040 */ 1041 1042 int 1043 bcm_tr2_failover_get(int unit, bcm_failover_t failover_id, int *value) 1044 { 1045 initial_prot_group_table_entry_t prot_group_entry; 1046 1047 BCM_IF_ERROR_RETURN( bcm_tr2_failover_id_validate ( unit, failover_id )); 1048 if (!_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, failover_id)) { 1049 return BCM_E_NOT_FOUND; 1050 } 1051 1052 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 1053 MEM_BLOCK_ANY, failover_id, &prot_group_entry)); 1054 1055 *value = soc_mem_field32_get(unit, INITIAL_PROT_GROUP_TABLEm, 1056 &prot_group_entry, STATUSf); 1057 1058 return BCM_E_NONE; 1059 } 1060 1061 1062 /* 1063 * Function: 1064 * bcm_tr2_failover_prot_nhi_create 1065 * Purpose: 1066 * Create the entry for PROT_NHI 1067 * Parameters: 1068 * IN : unit 1069 * IN : Primary Next Hop Index 1070 * Returns: 1071 * BCM_E_XXX 1072 */ 1073 1074 1075 int 1076 bcm_tr2_failover_prot_nhi_create (int unit, int nh_index) 1077 { 1078 initial_prot_nhi_table_entry_t prot_nhi_entry; 1079 int rv = BCM_E_UNAVAIL; 1080 1081 sal_memset(&prot_nhi_entry, 0, sizeof(initial_prot_nhi_table_entry_t)); 1082 1083 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm, 1084 MEM_BLOCK_ALL, nh_index, &prot_nhi_entry); 1085 1086 return rv; 1087 1088 } 1089 1090 1091 /* 1092 * Function: 1093 * bcm_tr2_failover_prot_nhi_set 1094 * Purpose: 1095 * Set the parameters for PROT_NHI 1096 * Parameters: 1097 * IN : unit 1098 * IN : Primary Next Hop Index 1099 * IN : Protection Next Hop Index 1100 * IN : Failover Group Index 1101 * Returns: 1102 * BCM_E_XXX 1103 */ 1104 1105 int 1106 bcm_tr2_failover_prot_nhi_set(int unit, int nh_index, uint32 prot_nh_index, bcm_failover_t failover_id) 1107 { 1108 initial_prot_nhi_table_entry_t prot_nhi_entry; 1109 int rv = BCM_E_UNAVAIL; 1110 1111 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 1112 MEM_BLOCK_ANY, nh_index, &prot_nhi_entry)); 1113 1114 soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 1115 &prot_nhi_entry, PROT_NEXT_HOP_INDEXf, 1116 prot_nh_index); 1117 1118 soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 1119 &prot_nhi_entry, PROT_GROUPf, 1120 (uint32) failover_id); 1121 1122 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm, 1123 MEM_BLOCK_ALL, nh_index, &prot_nhi_entry); 1124 1125 return rv; 1126 1127 } 1128 1129 1130 /* 1131 * Function: 1132 * bcm_tr2_failover_prot_nhi_get 1133 * Purpose: 1134 * Get the parameters for PROT_NHI 1135 * Parameters: 1136 * IN : unit 1137 * IN : primary Next Hop Index 1138 * OUT : Failover Group Index 1139 * OUT : Protection Next Hop Index 1140 * Returns: 1141 * BCM_E_XXX 1142 */ 1143 1144 1145 int 1146 bcm_tr2_failover_prot_nhi_get(int unit, int nh_index, bcm_failover_t *failover_id, int *prot_nh_index) 1147 { 1148 initial_prot_nhi_table_entry_t prot_nhi_entry; 1149 1150 BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 1151 MEM_BLOCK_ANY, nh_index, &prot_nhi_entry)); 1152 1153 *failover_id = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm, 1154 &prot_nhi_entry, PROT_GROUPf); 1155 1156 *prot_nh_index = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm, 1157 &prot_nhi_entry, PROT_NEXT_HOP_INDEXf); 1158 1159 return BCM_E_NONE; 1160 1161 } 1162 1163 /* 1164 * Function: 1165 * bcm_tr2_failover_prot_nhi_cleanup 1166 * Purpose: 1167 * Create the entry for PROT_NHI 1168 * Parameters: 1169 * IN : unit 1170 * IN : Primary Next Hop Index 1171 * Returns: 1172 * BCM_E_XXX 1173 */ 1174 1175 1176 int 1177 bcm_tr2_failover_prot_nhi_cleanup (int unit, int nh_index) 1178 { 1179 initial_prot_nhi_table_entry_t prot_nhi_entry; 1180 int rv = BCM_E_UNAVAIL; 1181 1182 rv = soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 1183 MEM_BLOCK_ANY, nh_index, &prot_nhi_entry); 1184 1185 if (rv < 0){ 1186 return BCM_E_NOT_FOUND; 1187 } 1188 1189 sal_memset(&prot_nhi_entry, 0, sizeof(initial_prot_nhi_table_entry_t)); 1190 1191 rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm, 1192 MEM_BLOCK_ALL, nh_index, &prot_nhi_entry); 1193 1194 return rv; 1195 1196 } 1197 1198 /* 1199 * Function: 1200 * bcm_tr2_failover_prot_nhi_update 1201 * Purpose: 1202 * Update the next_hop entry for failover 1203 * Parameters: 1204 * IN : unit 1205 * IN : Old Failover next hop index 1206 * IN : New Failover next hop index 1207 * Returns: 1208 * BCM_E_XXX 1209 */ 1210 1211 1212 int 1213 bcm_tr2_failover_prot_nhi_update (int unit, int old_nh_index, int new_nh_index) 1214 { 1215 int rv=BCM_E_NONE; 1216 int num_entry, index; 1217 int prot_nh_index; 1218 uint32 *pprot_nhi = NULL; 1219 uint32 *pprot_nhi_entry = NULL; 1220 int entry_size; 1221 1222 num_entry = soc_mem_index_count(unit, INITIAL_PROT_NHI_TABLEm); 1223 entry_size = soc_mem_entry_words(unit, INITIAL_PROT_NHI_TABLEm); 1224 pprot_nhi = soc_cm_salloc(unit, num_entry * entry_size * 4, "temp_buf"); 1225 if (pprot_nhi == NULL) 1226 return BCM_E_MEMORY; 1227 rv = soc_mem_read_range(unit, INITIAL_PROT_NHI_TABLEm, MEM_BLOCK_ANY, 0, 1228 num_entry-1, pprot_nhi); 1229 if (rv == SOC_E_NONE) { 1230 for (index=0, pprot_nhi_entry = pprot_nhi; index < num_entry; index++) { 1231 prot_nh_index = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm, 1232 pprot_nhi_entry, 1233 PROT_NEXT_HOP_INDEXf); 1234 1235 if (prot_nh_index == old_nh_index) { 1236 soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 1237 pprot_nhi_entry, PROT_NEXT_HOP_INDEXf, 1238 new_nh_index); 1239 } 1240 pprot_nhi_entry += entry_size; 1241 } 1242 rv = soc_mem_write_range(unit, INITIAL_PROT_NHI_TABLEm, MEM_BLOCK_ANY, 1243 0, num_entry-1, pprot_nhi); 1244 } 1245 if (pprot_nhi) 1246 soc_cm_sfree(unit, pprot_nhi); 1247 return rv; 1248 } 1249 1250 /* 1251 * Function: 1252 * bcm_tr2_failover_ecmp_prot_nhi_set 1253 * Purpose: 1254 * Set the parameters for PROT_NHI 1255 * Parameters: 1256 * IN : unit 1257 * IN : ecmp index /dvp group pointer 1258 * IN : member offset from base ptr 1259 * IN : Primary Next Hop Index 1260 * IN : Protection Next Hop Index 1261 * IN : Failover Group Index 1262 * Returns: 1263 * BCM_E_XXX 1264 */ 1265 1266 int 1267 bcm_tr2_failover_ecmp_prot_nhi_set(int unit, int ecmp, int index, 1268 int nh_index, 1269 bcm_failover_t failover_id, 1270 int prot_nh_index) 1271 { 1272 int i, base_ptr = 0, count = 0, nhi, idx_max; 1273 uint32 hw_buf[SOC_MAX_MEM_WORDS]; /* Buffer to read hw entry. */ 1274 1275 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1276 #if defined(BCM_TRIDENT3_SUPPORT) 1277 uint8 protected_ecmp = 0; 1278 int ecmp_max_paths = 0, rv = BCM_E_NONE; 1279 uint32 alloc_sz = 0; 1280 soc_esw_ecmp_group_info_t grp_info = {0}; 1281 soc_esw_ecmp_member_info_t *mem_array = NULL; 1282 #endif /* BCM_TRIDENT3_SUPPORT */ 1283 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1284 1285 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_APACHE_SUPPORT) 1286 if (soc_feature(unit, soc_feature_hierarchical_protection)) { 1287 idx_max = (soc_mem_index_count(unit, TX_PROT_GROUP_1_1_TABLEm) * 1288 BCM_TD2P_MPLS_PS_NUM_GROUPS_PER_ENTRY); 1289 } else if (soc_feature(unit, soc_feature_td2p_mpls_linear_protection)) { 1290 idx_max = (soc_mem_index_count(unit, TX_INITIAL_PROT_GROUP_TABLEm) * 1291 BCM_TD2P_MPLS_PS_NUM_GROUPS_PER_ENTRY); 1292 } else 1293 #endif 1294 #if defined(BCM_TOMAHAWK2_SUPPORT) 1295 if (SOC_IS_TOMAHAWK2(unit)) { 1296 idx_max = (soc_mem_index_count(unit, TX_INITIAL_PROT_GROUP_TABLEm) * 1297 BCM_TH2_FAILOVER_PROT_GROUPS_PER_ENTRY); 1298 } else 1299 #endif 1300 { 1301 idx_max = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 1302 } 1303 1304 if (ecmp < 0) { 1305 base_ptr = soc_mem_index_min(unit, INITIAL_L3_ECMPm); 1306 count = soc_mem_index_count(unit, INITIAL_L3_ECMPm); 1307 } else { 1308 BCM_IF_ERROR_RETURN( 1309 _bcm_xgs3_l3_ecmp_grp_info_get(unit, ecmp, &count, &base_ptr)); 1310 } 1311 1312 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1313 #if defined(BCM_TRIDENT3_SUPPORT) 1314 if (soc_esw_ecmp_protected_enabled(unit)) { 1315 protected_ecmp = 1; 1316 rv = _bcm_xgs3_ecmp_max_grp_size_get(unit, ecmp, &ecmp_max_paths); 1317 if (rv != BCM_E_NONE) { 1318 return rv; 1319 } 1320 1321 alloc_sz = (ecmp_max_paths * sizeof(soc_esw_ecmp_member_info_t)); 1322 mem_array = sal_alloc(alloc_sz, "NH array"); 1323 if (NULL == mem_array) { 1324 return BCM_E_MEMORY; 1325 } 1326 1327 SOC_ESW_ECMP_LOCK(unit); 1328 sal_memset(mem_array, 0, alloc_sz); 1329 /* Calculate Base_ptr table index. */ 1330 grp_info.ecmp_grp = ecmp; 1331 rv = soc_esw_ecmp_protected_grp_get(unit, &grp_info, mem_array); 1332 if (rv != BCM_E_NONE) { 1333 sal_free(mem_array); 1334 SOC_ESW_ECMP_UNLOCK(unit); 1335 return rv; 1336 } 1337 } 1338 #endif /* BCM_TRIDENT3_SUPPORT */ 1339 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1340 1341 for (i = 0; i < count; i++) { 1342 if (index >= 0 && index < count && index != i) { 1343 continue; 1344 } 1345 1346 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1347 #if defined(BCM_TRIDENT3_SUPPORT) 1348 if (protected_ecmp == 1) { 1349 nhi = mem_array[i].nh; 1350 if (nhi == nh_index) { 1351 mem_array[i].prot_nh = prot_nh_index; 1352 if (failover_id > 0 && 1353 failover_id < idx_max) { 1354 mem_array[i].prot_grp = failover_id; 1355 } 1356 } else { /* Mismatch between offset and nh_index */ 1357 if (index == i) { 1358 sal_free(mem_array); 1359 SOC_ESW_ECMP_UNLOCK(unit); 1360 return BCM_E_PARAM; 1361 } 1362 } 1363 } else 1364 #endif /* BCM_TRIDENT3_SUPPORT */ 1365 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1366 { 1367 BCM_IF_ERROR_RETURN( 1368 soc_mem_read(unit, INITIAL_L3_ECMPm, 1369 MEM_BLOCK_ANY, base_ptr + i, hw_buf)); 1370 1371 nhi = soc_mem_field32_get(unit, INITIAL_L3_ECMPm, hw_buf, 1372 NEXT_HOP_INDEXf); 1373 if (nhi == nh_index) { 1374 soc_mem_field32_set(unit, INITIAL_L3_ECMPm, hw_buf, 1375 PROT_NEXT_HOP_INDEXf, (uint32)prot_nh_index); 1376 if (failover_id > 0 && 1377 failover_id < idx_max) { 1378 soc_mem_field32_set(unit, INITIAL_L3_ECMPm, hw_buf, 1379 PROT_GROUPf, (uint32)failover_id); 1380 } 1381 BCM_IF_ERROR_RETURN( 1382 soc_mem_write(unit, INITIAL_L3_ECMPm, 1383 MEM_BLOCK_ANY, base_ptr + i, hw_buf)); 1384 } else { /* Mismatch between offset and nh_index */ 1385 if (index == i) { 1386 return BCM_E_PARAM; 1387 } 1388 } 1389 } 1390 } 1391 1392 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1393 #if defined(BCM_TRIDENT3_SUPPORT) 1394 if (protected_ecmp == 1) { 1395 soc_esw_ecmp_group_info_t_init(&grp_info); 1396 grp_info.ecmp_grp = ecmp; 1397 grp_info.ecmp_member_base = base_ptr; 1398 grp_info.max_paths = ecmp_max_paths; 1399 rv = soc_esw_ecmp_protected_grp_add(unit, &grp_info, mem_array); 1400 if (rv != BCM_E_NONE) { 1401 sal_free(mem_array); 1402 SOC_ESW_ECMP_UNLOCK(unit); 1403 return rv; 1404 } 1405 sal_free(mem_array); 1406 SOC_ESW_ECMP_UNLOCK(unit); 1407 1408 if (base_ptr != grp_info.ecmp_member_base) { 1409 ecmp_count_entry_t l3_ecmp_count_entry; 1410 initial_l3_ecmp_group_entry_t initial_l3_ecmp_group_entry; 1411 1412 BCM_XGS3_L3_ENT_REF_CNT_DEC(BCM_XGS3_L3_TBL_PTR(unit, ecmp), 1413 base_ptr, ecmp_max_paths); 1414 base_ptr = grp_info.ecmp_member_base; 1415 BCM_XGS3_L3_ENT_REF_CNT_INC(BCM_XGS3_L3_TBL_PTR(unit, ecmp), 1416 base_ptr, ecmp_max_paths); 1417 1418 sal_memset(&l3_ecmp_count_entry, 0, sizeof(l3_ecmp_count_entry)); 1419 sal_memset(&initial_l3_ecmp_group_entry, 0, sizeof(initial_l3_ecmp_group_entry)); 1420 1421 SOC_IF_ERROR_RETURN( 1422 READ_INITIAL_L3_ECMP_GROUPm(unit, MEM_BLOCK_ANY, 1423 ecmp, &initial_l3_ecmp_group_entry)); 1424 soc_INITIAL_L3_ECMP_GROUPm_field32_set(unit, &initial_l3_ecmp_group_entry, 1425 BASE_PTRf, base_ptr); 1426 SOC_IF_ERROR_RETURN( 1427 WRITE_INITIAL_L3_ECMP_GROUPm(unit, MEM_BLOCK_ALL, 1428 ecmp, &initial_l3_ecmp_group_entry)); 1429 SOC_IF_ERROR_RETURN( 1430 READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, 1431 ecmp, &l3_ecmp_count_entry)); 1432 soc_L3_ECMP_COUNTm_field32_set(unit, &l3_ecmp_count_entry, 1433 BASE_PTRf, base_ptr); 1434 SOC_IF_ERROR_RETURN( 1435 WRITE_L3_ECMP_COUNTm(unit, MEM_BLOCK_ALL, 1436 ecmp, &l3_ecmp_count_entry)); 1437 1438 } 1439 1440 } 1441 #endif /* BCM_TRIDENT3_SUPPORT */ 1442 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1443 1444 return BCM_E_NONE; 1445 } 1446 1447 1448 /* 1449 * Function: 1450 * bcm_tr2_failover_ecmp_prot_nhi_get 1451 * Purpose: 1452 * Get the parameters for ecmp PROT_NHI 1453 * Parameters: 1454 * IN : unit 1455 * IN : ecmp index /dvp group pointer 1456 * IN : member offset from base ptr 1457 * IN : primary Next Hop Index 1458 * OUT : Failover Group Index 1459 * OUT : Protection Next Hop Index 1460 * Returns: 1461 * BCM_E_XXX 1462 */ 1463 1464 int 1465 bcm_tr2_failover_ecmp_prot_nhi_get(int unit, int ecmp, int index, 1466 int nh_index, 1467 bcm_failover_t *failover_id, 1468 int *prot_nh_index) 1469 { 1470 int i, base_ptr = 0, count = 0, nhi; 1471 uint32 hw_buf[SOC_MAX_MEM_WORDS]; /* Buffer to read hw entry. */ 1472 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1473 #if defined(BCM_TRIDENT3_SUPPORT) 1474 uint8 protected_ecmp = 0; 1475 int ecmp_max_paths = 0, rv = BCM_E_NONE; 1476 uint32 alloc_sz = 0; 1477 soc_esw_ecmp_group_info_t grp_info = {0}; 1478 soc_esw_ecmp_member_info_t *mem_array = NULL; 1479 #endif /* BCM_TRIDENT3_SUPPORT */ 1480 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1481 1482 1483 if (ecmp < 0) { 1484 base_ptr = soc_mem_index_min(unit, INITIAL_L3_ECMPm); 1485 count = soc_mem_index_count(unit, INITIAL_L3_ECMPm); 1486 } else { 1487 BCM_IF_ERROR_RETURN( 1488 _bcm_xgs3_l3_ecmp_grp_info_get(unit, ecmp, &count, &base_ptr)); 1489 } 1490 1491 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1492 #if defined(BCM_TRIDENT3_SUPPORT) 1493 if (soc_esw_ecmp_protected_enabled(unit)) { 1494 protected_ecmp = 1; 1495 rv = _bcm_xgs3_ecmp_max_grp_size_get(unit, ecmp, &ecmp_max_paths); 1496 if (rv != BCM_E_NONE) { 1497 return rv; 1498 } 1499 1500 alloc_sz = (ecmp_max_paths * sizeof(soc_esw_ecmp_member_info_t)); 1501 mem_array = sal_alloc(alloc_sz, "NH array"); 1502 if (NULL == mem_array) { 1503 return BCM_E_MEMORY; 1504 } 1505 1506 SOC_ESW_ECMP_LOCK(unit); 1507 sal_memset(mem_array, 0, alloc_sz); 1508 grp_info.ecmp_grp = ecmp; 1509 rv = soc_esw_ecmp_protected_grp_get(unit, &grp_info, mem_array); 1510 if (BCM_FAILURE(rv)) { 1511 sal_free(mem_array); 1512 SOC_ESW_ECMP_UNLOCK(unit); 1513 return rv; 1514 } 1515 SOC_ESW_ECMP_UNLOCK(unit); 1516 } 1517 #endif /* BCM_TRIDENT3_SUPPORT */ 1518 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1519 1520 for (i = 0; i < count; i++) { 1521 if (index >= 0 && index < count && index != i) { 1522 continue; 1523 } 1524 1525 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1526 #if defined(BCM_TRIDENT3_SUPPORT) 1527 if (protected_ecmp == 1) { 1528 nhi = mem_array[i].nh; 1529 if (nhi == nh_index) { 1530 *failover_id = mem_array[i].prot_grp; 1531 *prot_nh_index = mem_array[i].prot_nh; 1532 if (*failover_id == 0 && *prot_nh_index == 0) { 1533 sal_free(mem_array); 1534 return BCM_E_NOT_FOUND; 1535 } 1536 break; 1537 } else { /* Mismatch between offset and nh_index */ 1538 if (index == i) { 1539 sal_free(mem_array); 1540 return BCM_E_PARAM; 1541 } 1542 } 1543 } else 1544 #endif /* BCM_TRIDENT3_SUPPORT */ 1545 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1546 { 1547 1548 BCM_IF_ERROR_RETURN( 1549 soc_mem_read(unit, INITIAL_L3_ECMPm, 1550 MEM_BLOCK_ANY, base_ptr + i, hw_buf)); 1551 1552 nhi = soc_mem_field32_get(unit, INITIAL_L3_ECMPm, hw_buf, 1553 NEXT_HOP_INDEXf); 1554 if (nhi == nh_index) { 1555 *failover_id = soc_mem_field32_get(unit, INITIAL_L3_ECMPm, hw_buf, 1556 PROT_GROUPf); 1557 *prot_nh_index = soc_mem_field32_get(unit, INITIAL_L3_ECMPm, hw_buf, 1558 PROT_NEXT_HOP_INDEXf); 1559 if (*failover_id == 0 && *prot_nh_index == 0) { 1560 return BCM_E_NOT_FOUND; 1561 } 1562 break; 1563 } else { /* Mismatch between offset and nh_index */ 1564 if (index == i) { 1565 return BCM_E_PARAM; 1566 } 1567 } 1568 } 1569 } 1570 1571 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1572 #if defined(BCM_TRIDENT3_SUPPORT) 1573 sal_free(mem_array); 1574 #endif /* BCM_TRIDENT3_SUPPORT */ 1575 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1576 1577 return BCM_E_NONE; 1578 } 1579 1580 /* 1581 * Function: 1582 * bcm_tr2_failover_prot_nhi_cleanup 1583 * Purpose: 1584 * Create the entry for PROT_NHI 1585 * Parameters: 1586 * IN : unit 1587 * IN : ecmp index /dvp group pointer 1588 * IN : member offset from base ptr 1589 * IN : Primary Next Hop Index 1590 * Returns: 1591 * BCM_E_XXX 1592 */ 1593 1594 1595 int 1596 bcm_tr2_failover_ecmp_prot_nhi_cleanup(int unit, int ecmp, int index, 1597 int nh_index) 1598 { 1599 int i, base_ptr = 0, count = 0, nhi; 1600 uint32 hw_buf[SOC_MAX_MEM_WORDS]; /* Buffer to read hw entry. */ 1601 1602 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1603 #if defined(BCM_TRIDENT3_SUPPORT) 1604 uint8 protected_ecmp = 0; 1605 int ecmp_max_paths = 0, rv = BCM_E_NONE; 1606 uint32 alloc_sz = 0; 1607 soc_esw_ecmp_group_info_t grp_info = {0}; 1608 soc_esw_ecmp_member_info_t *mem_array = NULL; 1609 #endif /* BCM_TRIDENT3_SUPPORT */ 1610 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1611 1612 if (ecmp < 0) { 1613 base_ptr = soc_mem_index_min(unit, INITIAL_L3_ECMPm); 1614 count = soc_mem_index_count(unit, INITIAL_L3_ECMPm); 1615 } else { 1616 BCM_IF_ERROR_RETURN( 1617 _bcm_xgs3_l3_ecmp_grp_info_get(unit, ecmp, &count, &base_ptr)); 1618 } 1619 1620 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1621 #if defined(BCM_TRIDENT3_SUPPORT) 1622 if (soc_esw_ecmp_protected_enabled(unit)) { 1623 protected_ecmp = 1; 1624 rv = _bcm_xgs3_ecmp_max_grp_size_get(unit, ecmp, &ecmp_max_paths); 1625 if (rv != BCM_E_NONE) { 1626 return rv; 1627 } 1628 1629 alloc_sz = (ecmp_max_paths * sizeof(soc_esw_ecmp_member_info_t)); 1630 mem_array = sal_alloc(alloc_sz, "NH array"); 1631 if (NULL == mem_array) { 1632 return BCM_E_MEMORY; 1633 } 1634 1635 SOC_ESW_ECMP_LOCK(unit); 1636 sal_memset(mem_array, 0, alloc_sz); 1637 /* Calculate Base_ptr table index. */ 1638 grp_info.ecmp_grp = ecmp; 1639 rv = soc_esw_ecmp_protected_grp_get(unit, &grp_info, mem_array); 1640 if (rv != BCM_E_NONE) { 1641 sal_free(mem_array); 1642 SOC_ESW_ECMP_UNLOCK(unit); 1643 return rv; 1644 } 1645 } 1646 #endif /* BCM_TRIDENT3_SUPPORT */ 1647 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1648 1649 for (i = 0; i < count; i++) { 1650 if (index >= 0 && index < count && index != i) { 1651 continue; 1652 } 1653 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1654 #if defined(BCM_TRIDENT3_SUPPORT) 1655 if (protected_ecmp == 1) { 1656 nhi = mem_array[i].nh; 1657 if (nhi == nh_index) { 1658 mem_array[i].prot_nh = 0; 1659 mem_array[i].prot_grp = 0; 1660 } else { /* Mismatch between offset and nh_index */ 1661 if (index == i) { 1662 sal_free(mem_array); 1663 SOC_ESW_ECMP_UNLOCK(unit); 1664 return BCM_E_PARAM; 1665 } 1666 } 1667 } else 1668 #endif /* BCM_TRIDENT3_SUPPORT */ 1669 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1670 1671 { 1672 BCM_IF_ERROR_RETURN( 1673 soc_mem_read(unit, INITIAL_L3_ECMPm, 1674 MEM_BLOCK_ANY, base_ptr + i, hw_buf)); 1675 1676 nhi = soc_mem_field32_get(unit, INITIAL_L3_ECMPm, hw_buf, 1677 NEXT_HOP_INDEXf); 1678 if (nhi == nh_index) { 1679 soc_mem_field32_set(unit, INITIAL_L3_ECMPm, hw_buf, 1680 PROT_NEXT_HOP_INDEXf, 0); 1681 soc_mem_field32_set(unit, INITIAL_L3_ECMPm, hw_buf, 1682 PROT_GROUPf, 0); 1683 BCM_IF_ERROR_RETURN( 1684 soc_mem_write(unit, INITIAL_L3_ECMPm, 1685 MEM_BLOCK_ANY, base_ptr + i, hw_buf)); 1686 } else { /* Mismatch between offset and nh_index */ 1687 if (index == i) { 1688 return BCM_E_PARAM; 1689 } 1690 } 1691 } 1692 } 1693 1694 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 1695 #if defined(BCM_TRIDENT3_SUPPORT) 1696 if (protected_ecmp == 1) { 1697 soc_esw_ecmp_group_info_t_init(&grp_info); 1698 grp_info.ecmp_grp = ecmp; 1699 grp_info.ecmp_member_base = base_ptr; 1700 grp_info.max_paths = ecmp_max_paths; 1701 rv = soc_esw_ecmp_protected_grp_add(unit, &grp_info, mem_array); 1702 if (rv != BCM_E_NONE) { 1703 sal_free(mem_array); 1704 SOC_ESW_ECMP_UNLOCK(unit); 1705 return rv; 1706 } 1707 sal_free(mem_array); 1708 SOC_ESW_ECMP_UNLOCK(unit); 1709 1710 if (base_ptr != grp_info.ecmp_member_base) { 1711 ecmp_count_entry_t l3_ecmp_count_entry; 1712 initial_l3_ecmp_group_entry_t initial_l3_ecmp_group_entry; 1713 1714 BCM_XGS3_L3_ENT_REF_CNT_DEC(BCM_XGS3_L3_TBL_PTR(unit, ecmp), 1715 base_ptr, ecmp_max_paths); 1716 base_ptr = grp_info.ecmp_member_base; 1717 BCM_XGS3_L3_ENT_REF_CNT_INC(BCM_XGS3_L3_TBL_PTR(unit, ecmp), 1718 base_ptr, ecmp_max_paths); 1719 1720 sal_memset(&l3_ecmp_count_entry, 0, sizeof(l3_ecmp_count_entry)); 1721 sal_memset(&initial_l3_ecmp_group_entry, 0, sizeof(initial_l3_ecmp_group_entry)); 1722 1723 SOC_IF_ERROR_RETURN( 1724 READ_INITIAL_L3_ECMP_GROUPm(unit, MEM_BLOCK_ANY, 1725 ecmp, &initial_l3_ecmp_group_entry)); 1726 soc_INITIAL_L3_ECMP_GROUPm_field32_set(unit, &initial_l3_ecmp_group_entry, 1727 BASE_PTRf, base_ptr); 1728 SOC_IF_ERROR_RETURN( 1729 WRITE_INITIAL_L3_ECMP_GROUPm(unit, MEM_BLOCK_ALL, 1730 ecmp, &initial_l3_ecmp_group_entry)); 1731 SOC_IF_ERROR_RETURN( 1732 READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, 1733 ecmp, &l3_ecmp_count_entry)); 1734 soc_L3_ECMP_COUNTm_field32_set(unit, &l3_ecmp_count_entry, 1735 BASE_PTRf, base_ptr); 1736 SOC_IF_ERROR_RETURN( 1737 WRITE_L3_ECMP_COUNTm(unit, MEM_BLOCK_ALL, 1738 ecmp, &l3_ecmp_count_entry)); 1739 } 1740 } 1741 #endif /* BCM_TRIDENT3_SUPPORT */ 1742 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 1743 1744 return BCM_E_NONE; 1745 } 1746 1747 /* 1748 * Function: 1749 * bcm_tr2_failover_id_check 1750 * Purpose: 1751 * Check Failover identifier 1752 * Parameters: 1753 * IN : unit 1754 * IN : failover_id 1755 * Returns: 1756 * BCM_E_XXX 1757 */ 1758 int 1759 bcm_tr2_failover_id_check(int unit, bcm_failover_t failover_id) 1760 { 1761 int num_count; 1762 #if defined(BCM_SABER2_SUPPORT) 1763 int type; 1764 _BCM_GET_FAILOVER_TYPE(failover_id, type); 1765 if (type & _BCM_FAILOVER_1_1_MC_PROTECTION_MODE) { 1766 _BCM_GET_FAILOVER_ID(failover_id); 1767 num_count = 2 * soc_mem_index_count(unit, MMU_INITIAL_NHOP_TBLm); 1768 if (failover_id > 0 && failover_id < num_count) { 1769 return (BCM_E_NONE); 1770 } 1771 } else 1772 #endif 1773 { 1774 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_APACHE_SUPPORT) 1775 if (soc_feature(unit, soc_feature_hierarchical_protection)) { 1776 num_count = soc_mem_index_count(unit, TX_PROT_GROUP_1_1_TABLEm); 1777 } else if (soc_feature(unit, soc_feature_td2p_mpls_linear_protection)) { 1778 num_count = soc_mem_index_count(unit, TX_INITIAL_PROT_GROUP_TABLEm); 1779 } else 1780 #endif 1781 #if defined(BCM_TOMAHAWK2_SUPPORT) 1782 if (SOC_IS_TOMAHAWK2(unit)) { 1783 num_count = (soc_mem_index_count(unit, TX_INITIAL_PROT_GROUP_TABLEm) * 1784 BCM_TH2_FAILOVER_PROT_GROUPS_PER_ENTRY); 1785 } else 1786 #endif 1787 { 1788 num_count = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 1789 } 1790 if (failover_id > 0 && failover_id < num_count) { 1791 return (BCM_E_NONE); 1792 } 1793 } 1794 return (BCM_E_PARAM); 1795 } 1796 1797 /* 1798 * Function: 1799 * bcm_tr2_failover_egr_check 1800 * Purpose: 1801 * Check Failover for Egress Object 1802 * Parameters: 1803 * IN : unit 1804 * IN : Egress Object 1805 * Returns: 1806 * BCM_E_XXX 1807 */ 1808 1809 1810 int 1811 bcm_tr2_failover_egr_check (int unit, bcm_l3_egress_t *egr) 1812 { 1813 if (egr->failover_id > 0 && egr->failover_id < 1024) { 1814 if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, egr->failover_if_id) || 1815 BCM_XGS3_DVP_EGRESS_IDX_VALID(unit, egr->failover_if_id)) { 1816 return (BCM_E_NONE); 1817 } 1818 } 1819 return (BCM_E_PARAM); 1820 } 1821 1822 /* 1823 * Function: 1824 * bcm_tr2_failover_mpls_check 1825 * Purpose: 1826 * Check for failover enable - MPLS port 1827 * Parameters: 1828 * IN : unit 1829 * IN : Egress Object 1830 * Returns: 1831 * BCM_E_XXX 1832 */ 1833 1834 1835 int 1836 bcm_tr2_failover_mpls_check (int unit, bcm_mpls_port_t *mpls_port) 1837 { 1838 int failover_vp = -1; 1839 1840 if ( ( (mpls_port->failover_id) > 0) && ( (mpls_port->failover_id) < 1024) ) { 1841 /* Get egress next-hop index from Failover MPLS gport */ 1842 failover_vp = BCM_GPORT_MPLS_PORT_ID_GET(mpls_port->failover_port_id); 1843 if (failover_vp == -1) { 1844 return BCM_E_PARAM; 1845 } 1846 if ( (failover_vp >= 1) && (failover_vp < soc_mem_index_count(unit, SOURCE_VPm)) ) { 1847 return BCM_E_NONE; 1848 } 1849 } 1850 return BCM_E_PARAM; 1851 } 1852 1853 #ifndef BCM_SW_STATE_DUMP_DISABLE 1854 /* 1855 * Function: 1856 * _bcm_tr2_failover_sw_dump 1857 * Purpose: 1858 * Displays State information maintained by software 1859 * for 'Failover' module. 1860 * Parameters: 1861 * unit - Device unit number 1862 * Returns: 1863 * Void 1864 */ 1865 void 1866 _bcm_tr2_failover_sw_dump(int unit) 1867 { 1868 int i; 1869 int num_entry = 0; 1870 1871 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_APACHE_SUPPORT) 1872 if (soc_feature(unit, soc_feature_hierarchical_protection)) { 1873 num_entry = (soc_mem_index_count(unit, TX_PROT_GROUP_1_1_TABLEm) * 1874 BCM_TD2P_MPLS_PS_NUM_GROUPS_PER_ENTRY); 1875 } else if (soc_feature(unit, soc_feature_td2p_mpls_linear_protection)) { 1876 num_entry = (soc_mem_index_count(unit, TX_INITIAL_PROT_GROUP_TABLEm) * 1877 BCM_TD2P_MPLS_PS_NUM_GROUPS_PER_ENTRY); 1878 } else 1879 #endif 1880 #if defined (BCM_TOMAHAWK2_SUPPORT) 1881 if (SOC_IS_TOMAHAWK2(unit)) { 1882 num_entry = (soc_mem_index_count(unit, TX_INITIAL_PROT_GROUP_TABLEm) * 1883 BCM_TH2_FAILOVER_PROT_GROUPS_PER_ENTRY); 1884 } else 1885 #endif /* BCM_TOMAHAWK2_SUPPORT */ 1886 { 1887 num_entry = soc_mem_index_count(unit, INITIAL_PROT_GROUP_TABLEm); 1888 } 1889 1890 LOG_CLI((BSL_META_U(unit, 1891 "Protection Group usage bitmap:\n"))); 1892 1893 for (i = 0; i < num_entry; i++) { 1894 if (_BCM_FAILOVER_PROT_GROUP_MAP_USED_GET(unit, i)) { 1895 LOG_CLI((BSL_META_U(unit, 1896 "%d "), i)); 1897 } 1898 } 1899 LOG_CLI((BSL_META_U(unit, 1900 "\n"))); 1901 #if defined (BCM_TOMAHAWK2_SUPPORT) 1902 if (SOC_IS_TOMAHAWK2(unit)) { 1903 num_entry = (soc_mem_index_count(unit, RX_PROT_GROUP_TABLEm) * 1904 BCM_TH2_FAILOVER_PROT_GROUPS_PER_ENTRY); 1905 LOG_CLI((BSL_META_U(unit, 1906 "Ingress Protection Group usage bitmap:\n"))); 1907 1908 for (i = 0; i < num_entry; i++) { 1909 if (_BCM_FAILOVER_INGRESS_PROT_GROUP_MAP_USED_GET(unit, i)) { 1910 LOG_CLI((BSL_META_U(unit, 1911 "%d "), i)); 1912 } 1913 } 1914 LOG_CLI((BSL_META_U(unit, 1915 "\n"))); 1916 } 1917 #endif /* BCM_TOMAHAWK2_SUPPORT */ 1918 return; 1919 } 1920 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 1921 1922 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 1923