brd_chassis_ast.c (22153B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: brd_chassis_ast.c 8 * Purpose: BCM956000 Chassis asymmetric trunk based load balancing 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <bcm/error.h> 14 #include <bcm/stack.h> 15 #include <bcm/topo.h> 16 #include <bcm/mirror.h> 17 #include <bcm/field.h> 18 #include <appl/stktask/topo_brd.h> 19 #include <appl/stktask/stktask.h> /* bcm_st_reserved_modid_enable_get */ 20 #include <appl/cputrans/nh_tx.h> /* nh_tx_src_get */ 21 22 #include "topo_int.h" 23 #include "brd_chassis_int.h" 24 25 #if defined(INCLUDE_CHASSIS) 26 27 /* CFM and LM Hash Selection 28 29 30 CFM and LM hashes are different so packets received from an LM has 31 an opportunity to be load balanced on the outgoing CFM trunk. This 32 is because the LMs use alternate links to connect to each CFM, 33 e.g. hg0 and hg2 go to one CFM and hg1 and hg3 go to the other. If 34 the same hash is used for both the LM and CFM, then the packets 35 egressing the CFM would always use the same link, leaving half the 36 available bandwidth unused: 37 38 LM hg0 -> CFM0 trunk-link0 39 LM hg1 -> CFM1 trunk-link1 40 LM hg2 -> CFM0 trunk-link0 41 LM hg3 -> CFM1 trunk-link1 42 43 where "trunk-linkN" is the Nth member of the CFM egress trunk. 44 45 If the CFM uses a different hash than the LM, then there's a 46 reasonable chance that the traffic egressing the CFM will use both 47 members of the trunk. 48 49 */ 50 51 #define XGS2_CFM_HASH (BCM_TRUNK_PSC_SRCDSTMAC | \ 52 BCM_TRUNK_PSC_IPMACSA | \ 53 BCM_TRUNK_PSC_MACSA) 54 55 #define XGS2_LM_HASH (BCM_TRUNK_PSC_SRCDSTMAC | \ 56 BCM_TRUNK_PSC_IPMACDA | \ 57 BCM_TRUNK_PSC_MACDA) 58 59 60 61 static int _chassis_ast_default_lm_psc = BCM_TRUNK_PSC_DSTMAC; 62 static int _chassis_ast_default_cfm_psc = BCM_TRUNK_PSC_SRCMAC; 63 64 /* CFM Trunk create callback handler */ 65 STATIC int 66 chassis_ast_cfm_trunk(int unit, int tid, 67 bcm_trunk_info_t *trunk, 68 int member_count, 69 bcm_trunk_member_t *member_array, 70 void *cookie) 71 { 72 COMPILER_REFERENCE(cookie); 73 trunk->psc = _chassis_ast_default_cfm_psc; 74 return bcm_trunk_set(unit, tid, trunk, member_count, member_array); 75 } 76 77 /* Single device CFM */ 78 STATIC int 79 chassis_ast_cfm(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 80 { 81 int unit; 82 bcm_module_t mod; 83 int rv = BCM_E_NONE; 84 bcm_port_t port; 85 bcm_port_config_t config; 86 87 unit = 0; /* board fabric unit */ 88 89 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config)); 90 BCM_PBMP_ITER(config.cpu, port) { 91 break; /* Get CPU port */ 92 } 93 mod = db_ref->local_entry->mod_ids[0]; 94 95 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(unit, mod)); 96 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit, mod, port)); 97 BCM_IF_ERROR_RETURN(bcm_board_fab_mod_map(unit, 98 tp_cpu, 99 db_ref->local_entry)); 100 bcm_board_unknown_src_modid_setup(db_ref->local_entry); 101 bcm_board_trunk_callback_add(chassis_ast_cfm_trunk, NULL); 102 BCM_IF_ERROR_RETURN(bcm_board_trunk_system(&tp_cpu->local_entry, 103 db_ref, BCM_BOARD_TRUNK_NORMAL)); 104 return rv; 105 } 106 107 /* LM Trunk create callback handler */ 108 STATIC int 109 chassis_ast_lm_trunk(int unit, int tid, 110 bcm_trunk_info_t *trunk, 111 int member_count, 112 bcm_trunk_member_t *member_array, 113 void *cookie) 114 { 115 int i,j; 116 int slot; 117 bcm_module_t modid; 118 bcm_board_cfm_info_t *cfm_info = (bcm_board_cfm_info_t *)cookie; 119 bcm_port_t local_port; 120 121 trunk->psc = _chassis_ast_default_lm_psc; 122 BCM_IF_ERROR_RETURN(bcm_trunk_set(unit, tid, trunk, member_count, 123 member_array)); 124 125 for (i=0; i<member_count; i++) { 126 BCM_IF_ERROR_RETURN( 127 bcm_port_local_get(unit, member_array[i].gport, &local_port)); 128 for (j=0; j<cfm_info->count; j++) { 129 slot = cfm_info->cfm[j].slot; 130 modid = cfm_info->cfm[j].modid; 131 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 132 (BSL_META("slot:%d unit:%d tid:%d modid:%d port:%d n:%d\n"), 133 slot, 134 unit, 135 tid, 136 modid, 137 local_port, 138 cfm_info->count)); 139 /* Override trunking of CFM modid if there is more than 140 one CFM */ 141 BCM_IF_ERROR_RETURN( 142 bcm_trunk_override_ucast_set(unit, local_port, tid, 143 modid, 144 (cfm_info->count > 1))); 145 } 146 } 147 148 return BCM_E_NONE; 149 } 150 151 /* LM with a single device that connects to the CFMs */ 152 153 static int cfm_fp_entries = 0; 154 static bcm_field_group_t cfm_fp_group ; 155 static bcm_field_entry_t cfm_fp_entry[NUM_CFM]; 156 157 STATIC int 158 install_cfm_fp(int unit, bcm_board_cfm_info_t *cfm_info) 159 { 160 161 if (cfm_info->count > 1) { 162 /* Install fp rule to redirect CFM destination packets. This 163 is needed because the default L2 switch forwarding will not 164 forward a packet on the link or trunk it was received 165 on. Because all the LM external stack ports are trunked, that 166 means that any packet received from one CFM that is destined 167 for another CFM will be dropped. 168 */ 169 bcm_field_qset_t qset; 170 bcm_port_t dstport; 171 bcm_pbmp_t dstpbmp; 172 int i; 173 174 BCM_FIELD_QSET_INIT(qset); 175 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyDstPort); 176 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifySrcPort); 177 178 /* Destroy previous group if needed; ignore errors for now */ 179 if (cfm_fp_entries > 0) { 180 int rv; 181 182 for ( i=0; i<cfm_fp_entries; i++) { 183 rv = bcm_field_entry_remove(unit, cfm_fp_entry[i]); 184 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 185 (BSL_META("bcm_field_entry_remove(%d, %d)=%d\n"), 186 unit, 187 cfm_fp_entry[i], 188 rv)); 189 } 190 rv = bcm_field_group_destroy(unit, cfm_fp_group); 191 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 192 (BSL_META("bcm_field_group_destroy(%d, %d)=%d\n"), 193 unit, 194 cfm_fp_group, 195 rv)); 196 } 197 198 /* Create group */ 199 BCM_IF_ERROR_RETURN(bcm_field_group_create(unit, qset, 200 BCM_FIELD_GROUP_PRIO_ANY, 201 &cfm_fp_group)); 202 /* Create entries for each CFM */ 203 204 cfm_fp_entries = 0; 205 206 for ( i=0; i<cfm_info->count; i++) { 207 208 BCM_IF_ERROR_RETURN 209 (bcm_field_entry_create(unit, cfm_fp_group, &cfm_fp_entry[i])); 210 211 { int partner = (i == 0) ? 1 : 0; 212 /* coverity[copy_paste_error] */ 213 BCM_IF_ERROR_RETURN 214 (bcm_field_qualify_SrcPort(unit, cfm_fp_entry[i], 215 cfm_info->cfm[partner].modid, 216 BCM_FIELD_EXACT_MATCH_MASK, 0, 0)); 217 } 218 219 BCM_IF_ERROR_RETURN 220 (bcm_field_qualify_DstPort(unit, cfm_fp_entry[i], 221 cfm_info->cfm[i].modid, 222 BCM_FIELD_EXACT_MATCH_MASK, 0, 0)); 223 224 BCM_PBMP_CLEAR(dstpbmp); 225 BCM_IF_ERROR_RETURN 226 (bcm_topo_port_get(unit, 227 cfm_info->cfm[i].modid, 228 &dstport)); 229 BCM_PBMP_PORT_SET(dstpbmp, dstport); 230 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 231 (BSL_META_U(unit, 232 "port:%d pbmp[0]:%x\n"), 233 dstport, 234 _SHR_PBMP_WORD_GET(dstpbmp, 0))); 235 236 BCM_IF_ERROR_RETURN 237 (bcm_field_action_ports_add(unit, cfm_fp_entry[i], 238 bcmFieldActionRedirectPbmp, 239 dstpbmp)); 240 241 BCM_IF_ERROR_RETURN 242 (bcm_field_entry_install(unit, cfm_fp_entry[i])); 243 244 cfm_fp_entries++; 245 } 246 247 } 248 249 return BCM_E_NONE; 250 } 251 252 STATIC int 253 chassis_ast_lm(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref, 254 bcm_board_port_connection_t *connection) 255 { 256 int unit; 257 bcm_module_t mod; 258 int rv = BCM_E_NONE; 259 bcm_port_t port; 260 bcm_port_config_t config; 261 bcm_board_cfm_info_t cfm_info; 262 263 unit = 0; /* board fabric unit */ 264 265 bcm_board_cfm_info(db_ref, &cfm_info); 266 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config)); 267 BCM_PBMP_ITER(config.cpu, port) { 268 break; /* Get CPU port */ 269 } 270 mod = db_ref->local_entry->mod_ids[0]; 271 272 if (connection) { 273 BCM_IF_ERROR_RETURN( 274 bcm_board_xgs_local_switch(unit, tp_cpu, &config, connection)); 275 BCM_IF_ERROR_RETURN( 276 bcm_board_xgs_local_fabric(unit, tp_cpu, &config)); 277 } else { 278 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(unit, mod)); 279 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit, mod, port)); 280 } 281 282 BCM_IF_ERROR_RETURN(bcm_board_fab_mod_map(unit, 283 tp_cpu, 284 db_ref->local_entry)); 285 286 bcm_board_unknown_src_modid_setup(db_ref->local_entry); 287 /* Trunk everything seen with hash 2, trunk create callback 288 will handle CFM trunk override if necessary */ 289 290 bcm_board_trunk_callback_add(chassis_ast_lm_trunk, (void *)&cfm_info); 291 BCM_IF_ERROR_RETURN(bcm_board_trunk_system(&tp_cpu->local_entry, 292 db_ref, 293 BCM_BOARD_TRUNK_ALL)); 294 295 BCM_IF_ERROR_RETURN(install_cfm_fp(unit, &cfm_info)); 296 297 return rv; 298 } 299 300 301 /* 302 * Function: chassis_ast_cfm_xgs2 303 * 304 * Purpose: 305 * Program the XGS2 CFM board using asymmetric trunking. 306 */ 307 int 308 chassis_ast_cfm_xgs2(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 309 { 310 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 311 (BSL_META("TOPO: XGS 5675 BCM956000 CFM (Asymmetric Trunk)\n"))); 312 _chassis_ast_default_cfm_psc = XGS2_CFM_HASH; 313 return chassis_ast_cfm(tp_cpu, db_ref); 314 } 315 316 317 /* 318 * Function: chassis_ast_xgs2_48g 319 * 320 * Purpose: 321 * Program the XGS2-48G LM board using asymmetric trunking. 322 */ 323 int 324 chassis_ast_xgs2_48g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 325 { 326 bcm_board_port_connection_t connection[5] = { 327 { -1, -1 }, /* 5675 unit 0 */ 328 { 12, 1 }, /* 5695 unit 1 is on port 1 */ 329 { 12, 2 }, /* 5695 unit 2 is on port 2 */ 330 { 12, 3 }, /* 5673 unit 3 is on port 3 */ 331 { 12, 4 }, /* 5673 unit 4 is on port 4 */ 332 }; 333 334 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 335 (BSL_META("TOPO: XGS 569x 48GE BCM956000 LM (Asymmetric Trunk)\n"))); 336 _chassis_ast_default_lm_psc = XGS2_LM_HASH; 337 return chassis_ast_lm(tp_cpu, db_ref, connection); 338 } 339 340 /* 341 * Function: chassis_ast_xgs2_6x 342 * 343 * Purpose: 344 * Program the XGS2-6X LM board using asymmetric trunking. 345 */ 346 int 347 chassis_ast_xgs2_6x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 348 { 349 bcm_board_port_connection_t connection[7] = { 350 { -1, -1 }, /* 5675 unit 0 */ 351 { 1, 6 }, /* 5673 unit 1 is on port 6 */ 352 { 1, 7 }, /* 5673 unit 2 is on port 7 */ 353 { 1, 8 }, /* 5673 unit 3 is on port 8 */ 354 { 1, 1 }, /* 5673 unit 4 is on port 1 */ 355 { 1, 2 }, /* 5673 unit 5 is on port 2 */ 356 { 1, 3 }, /* 5673 unit 6 is on port 3 */ 357 }; 358 359 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 360 (BSL_META("TOPO: XGS 5674 6XE BCM956000 LM (Asymmetric Trunk)\n"))); 361 _chassis_ast_default_lm_psc = XGS2_LM_HASH; 362 return chassis_ast_lm(tp_cpu, db_ref, connection); 363 } 364 365 /* 366 * Function: chassis_ast_xgs3_12x 367 * 368 * Purpose: 369 * Program the XGS3-12X LM board using asymmetric trunking. 370 */ 371 int 372 chassis_ast_xgs3_12x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 373 { 374 bcm_board_port_connection_t connection[5] = { 375 { -1, -1 }, /* 5675 unit 0 - no connection map entry */ 376 { 27, 7 }, /* 56501 unit 1 port 27 connects to 5675 port 7 */ 377 { 27, 8 }, /* 56501 unit 2 port 27 connects to 5675 port 8 */ 378 { 27, 1 }, /* 56501 unit 3 port 27 connects to 5675 port 1 */ 379 { 27, 2 }, /* 56501 unit 4 port 27 connects to 5675 port 2 */ 380 }; 381 382 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 383 (BSL_META("TOPO: XGS3 56501 12XE BCM956000 LM (Asymmetric Trunk)\n"))); 384 _chassis_ast_default_lm_psc = XGS2_LM_HASH; 385 return chassis_ast_lm(tp_cpu, db_ref, connection); 386 } 387 388 389 /* 390 * Function: chassis_ast_cfm_xgs3 391 * 392 * Purpose: 393 * Program the XGS3 CFM board using asymmetric trunking. 394 */ 395 int 396 chassis_ast_cfm_xgs3(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 397 { 398 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 399 (BSL_META("TOPO: XGS 56700 BCM956000 CFM (Asymmetric Trunk)\n"))); 400 return chassis_ast_cfm(tp_cpu, db_ref); 401 } 402 403 /* 404 * Function: chassis_ast_cfm_xgs3 405 * 406 * Purpose: 407 * Program the 56800 LM board using asymmetric trunking. 408 */ 409 int 410 chassis_ast_56800_12x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 411 { 412 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 413 (BSL_META("TOPO: XGS3 56800 BCM956000 LM (Asymmetric Trunk)\n"))); 414 return chassis_ast_lm(tp_cpu, db_ref, NULL); 415 } 416 417 /***************************************************************************** 418 419 LM XGS3 48G 420 421 The XGS3 48G Line module is more complex that the others because 422 423 (a) Load balancing is unit based, rather than trunk based due to 424 the board connectivity 425 426 (b) Unlike the other LMs, it introduces a loop into the system 427 topology, which must be pruned to eliminate multicast storms. 428 429 The two units on the board are labled as 'master' and 'partner'. The 430 master unit is the unit that connects directly to the master CFM; 431 the partner is the other unit. This relationship varies, depending 432 on the CFM and backplane, so make the determination is made 433 dynamically. 434 435 */ 436 437 #define FB_HG0 24 /* External */ 438 #define FB_HG1 25 /* External */ 439 #define FB_HG2 26 /* Internal */ 440 #define FB_HG3 27 /* Internal */ 441 442 /* 443 444 Determine which unit is connected to the master CFM and which is the 445 partner. 446 447 */ 448 449 STATIC int 450 _ast_xgs3_48g_unit(topo_cpu_t *tp_cpu, 451 bcm_board_cfm_info_t *cfm_info, 452 int *master, 453 int *partner) 454 { 455 int i,m; 456 topo_stk_port_t *tsp; 457 cpudb_entry_t *l_entry = &tp_cpu->local_entry; 458 int unit, master_unit = -1; 459 bcm_module_t cfm_modid; 460 461 if (cfm_info->count == 0) { 462 /* No CFM */ 463 *master = 0; 464 *partner = 1; 465 return BCM_E_NONE; 466 } 467 468 cfm_modid = cfm_info->cfm[cfm_info->master].modid; 469 for (i = 0; i < l_entry->base.num_stk_ports; i++) { 470 if (!(l_entry->sp_info[i].flags & CPUDB_SPF_TX_RESOLVED)) { 471 /* Skip unresolved ports */ 472 continue; 473 } 474 475 tsp = &tp_cpu->tp_stk_port[i]; 476 unit = l_entry->base.stk_ports[i].unit; 477 478 if (master_unit < 0) { 479 for (m = 0; m < tsp->tx_mod_num; m++) { 480 if (tsp->tx_mods[m] == cfm_modid) { 481 *master = unit; 482 *partner = (unit == 0) ? 1 : 0; 483 return BCM_E_NONE; 484 } 485 } 486 } 487 } 488 489 return BCM_E_NOT_FOUND; 490 } 491 492 /* 493 494 Program the external module mapping. If there's only one CFM, 495 then the master unit points to all the external modids, and the 496 partner points to the master unit. If there's two CFMs, then both 497 units can point to all the external modids. 498 499 */ 500 501 STATIC int 502 _ast_xgs3_48g_ext_mod_program(topo_cpu_t *tp_cpu, 503 bcm_board_cfm_info_t *cfm_info, 504 int master, int partner) 505 { 506 int i,m; 507 topo_stk_port_t *tsp; 508 cpudb_entry_t *l_entry = &tp_cpu->local_entry; 509 bcm_port_t port; 510 bcm_module_t mod; 511 int dual = (cfm_info->count > 1); 512 513 for (i = 0; i < l_entry->base.num_stk_ports; i++) { 514 if (!(l_entry->sp_info[i].flags & CPUDB_SPF_TX_RESOLVED)) { 515 /* Skip unresolved ports */ 516 continue; 517 } 518 519 tsp = &tp_cpu->tp_stk_port[i]; 520 port = l_entry->base.stk_ports[i].port; 521 522 for (m = 0; m < tsp->tx_mod_num; m++) { 523 mod = tsp->tx_mods[m]; 524 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(master, mod, port)); 525 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(partner, mod, 526 (dual) ? port : FB_HG2)); 527 } 528 } 529 530 return BCM_E_NONE; 531 } 532 533 /* 534 * Function: chassis_ast_xgs3_48g 535 * 536 * Purpose: 537 * Program the XGS3-48G LM board using asymmetric trunking. 538 */ 539 int 540 chassis_ast_xgs3_48g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 541 { 542 bcm_module_t master_modid; 543 bcm_module_t partner_modid; 544 bcm_board_cfm_info_t cfm_info; 545 bcm_port_config_t config; 546 int master, partner; 547 548 bcm_board_cfm_info(db_ref, &cfm_info); 549 550 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 551 (BSL_META("TOPO: XGS3 56504 48GE BCM956000 LM (Asymmetric Trunk)\n"))); 552 553 /* Get master and partner units and modids */ 554 BCM_IF_ERROR_RETURN(_ast_xgs3_48g_unit(tp_cpu, &cfm_info, 555 &master, &partner)); 556 557 if ((master < 0) || (master > 1) || (partner < 0) || (partner > 1)) { 558 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 559 (BSL_META("Parameter error: master=%d partner=%d\n"), 560 master, partner)); 561 return BCM_E_INTERNAL; 562 } 563 564 master_modid = tp_cpu->local_entry.mod_ids[master]; 565 partner_modid = tp_cpu->local_entry.mod_ids[partner]; 566 567 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 568 (BSL_META("Master: %d,%d\n"), 569 master, master_modid)); 570 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 571 (BSL_META("Partner: %d,%d\n"), 572 partner, partner_modid)); 573 574 /* Assign modids */ 575 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(master, master_modid)); 576 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(partner, partner_modid)); 577 578 /* Set external modid mapping */ 579 BCM_IF_ERROR_RETURN(_ast_xgs3_48g_ext_mod_program(tp_cpu, &cfm_info, 580 master, partner)); 581 582 /* Set internal modid mapping */ 583 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(master, 584 partner_modid, 585 FB_HG2)); 586 587 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(partner, 588 master_modid, 589 FB_HG2)); 590 591 /* Add internal stack ports */ 592 BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(master, 593 FB_HG2)); 594 BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(master, 595 FB_HG3)); 596 BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(partner, 597 FB_HG2)); 598 BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(partner, 599 FB_HG3)); 600 601 /* Create trunks */ 602 603 bcm_board_trunk_callback_add(chassis_ast_lm_trunk, (void *)&cfm_info); 604 BCM_IF_ERROR_RETURN(bcm_board_trunk_system(&tp_cpu->local_entry, db_ref, 605 BCM_BOARD_TRUNK_NORMAL)); 606 BCM_IF_ERROR_RETURN(_bcm_board_setup_trunk_lm_xgs3_48g()); 607 608 BCM_IF_ERROR_RETURN(bcm_port_config_get(0, &config)); 609 BCM_IF_ERROR_RETURN(bcm_board_module_filter(0, tp_cpu, db_ref, 610 &config)); 611 BCM_IF_ERROR_RETURN(bcm_port_config_get(1, &config)); 612 BCM_IF_ERROR_RETURN(bcm_board_module_filter(1, tp_cpu, db_ref, 613 &config)); 614 if (cfm_info.count > 1) { 615 /* flood block internal to external stack ports */ 616 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(master, 617 FB_HG2, FB_HG0, -1U)); 618 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(master, 619 FB_HG2, FB_HG1, -1U)); 620 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(master, 621 FB_HG3, FB_HG0, -1U)); 622 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(master, 623 FB_HG3, FB_HG1, -1U)); 624 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(partner, 625 FB_HG2, FB_HG0, -1U)); 626 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(partner, 627 FB_HG2, FB_HG1, -1U)); 628 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(partner, 629 FB_HG3, FB_HG0, -1U)); 630 BCM_IF_ERROR_RETURN(bcm_port_flood_block_set(partner, 631 FB_HG3, FB_HG1, -1U)); 632 } 633 634 #ifdef BCM_BOARD_AUTO_E2E 635 /* intra-board end to end flow control, if available */ 636 BCM_IF_ERROR_RETURN(_bcm_board_dual_xgs3_e2e_set(master, master_modid, 637 partner, partner_modid)); 638 #endif /* BCM_BOARD_AUTO_E2E */ 639 640 return BCM_E_NONE; 641 } 642 643 644 645 #else 646 int _brd_chassis_ast_not_empty; 647 #endif /* INCLUDE_CHASSIS */