openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

brd_chassis_nolb.c (24060B)


      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_nolb.c
      8  * Purpose:     XGS2/XGS3 Chassis Non-load-balanced board programming
      9  */
     10 
     11 #include <shared/bsl.h>
     12 #include <shared/alloc.h>
     13 
     14 #include <bcm/error.h>
     15 #include <bcm/stack.h>
     16 #include <bcm/topo.h>
     17 #include <bcm/trunk.h>
     18 #include <appl/stktask/topology.h>
     19 #include <appl/stktask/topo_brd.h>
     20 
     21 #include "topo_int.h"
     22 #include "brd_chassis_int.h"
     23 
     24 #if defined(INCLUDE_CHASSIS)
     25 
     26 
     27 STATIC int
     28 _bcm_board_xgs3_sw_modport_set(int funit, topo_cpu_t *tp_cpu,
     29                                bcm_board_port_connection_t *connection)
     30 {
     31     int i, m, mod,unit, port;
     32     cpudb_entry_t *l_entry;
     33     topo_stk_port_t *tsp;
     34 
     35     l_entry = &tp_cpu->local_entry;
     36 
     37     for (unit = 0; unit < l_entry->base.num_units; unit++) {
     38         port = connection[unit].to;
     39         if (port < 0) { /* Skip fabric */
     40             continue;
     41         }
     42         /* Set module mapping for this leaf unit for modules outside
     43            of this board. */
     44         for (i = 0; i < l_entry->base.num_stk_ports; i++) {
     45             /* For each mod-id reached by the fabric, set in leaf. */
     46             tsp = &tp_cpu->tp_stk_port[i];
     47 
     48             /* Set modport for each module reachable outside of this board */
     49             for (m = 0; m < tsp->tx_mod_num; m++) {
     50                 mod = tsp->tx_mods[m];
     51                 BCM_IF_ERROR_RETURN(
     52                     bcm_stk_modport_set(unit,
     53                                         mod,
     54                                         connection[unit].from));
     55             }
     56         }
     57         /* Set the module mapping for this unit so it knows how to get
     58            to every other local unit. */
     59         for (m = 0; m < l_entry->base.num_units; m++) {
     60             if (connection[m].to < 0 || m == unit) {
     61                 /* Skip device if it's a fabric module or the current
     62                    unit */
     63                 continue;
     64             }
     65             mod = l_entry->mod_ids[m];
     66             BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit,
     67                                                     mod,
     68                                                     connection[unit].from));
     69         }
     70     }
     71     return BCM_E_NONE;
     72 }
     73 
     74 
     75 
     76 STATIC int
     77 _bcm_board_xgs3_sw_stk_port_add(int f_unit, topo_cpu_t *tp_cpu,
     78                                 bcm_board_port_connection_t *connection)
     79 {
     80     int s_unit, f_port, s_port;
     81     cpudb_entry_t *l_entry;
     82 
     83     l_entry = &tp_cpu->local_entry;
     84 
     85     for (s_unit = 0; s_unit < l_entry->base.num_units; s_unit++) {
     86 
     87         f_port = connection[s_unit].to;
     88         if (f_port < 0) { /* Skip device (eg fabric module) */
     89             continue;
     90         }
     91 
     92         /* Set fabric stack port state */
     93         BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(f_unit, f_port));
     94 
     95         /* Set switch stack port state */
     96         s_port = connection[s_unit].from;
     97         BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(s_unit, s_port));
     98     }
     99     return BCM_E_NONE;
    100 }
    101 
    102 
    103 int
    104 bcm_board_xgs3_sw_xgs_fabric(int funit, topo_cpu_t *tp_cpu,
    105                              cpudb_ref_t db_ref,
    106                              bcm_board_port_connection_t *connection)
    107 {
    108     int                i, m, unit;
    109     bcm_pbmp_t         pbm, empty;
    110     cpudb_entry_t      *l_entry;
    111     bcm_port_t         port, hport;
    112     bcm_module_t       mod;
    113     bcm_port_config_t  config;
    114     topo_stk_port_t    *tsp;
    115 
    116     l_entry = &tp_cpu->local_entry;
    117 
    118     /* Notify BCM layer of internal stack ports */
    119     BCM_IF_ERROR_RETURN(_bcm_board_xgs3_sw_stk_port_add(funit, tp_cpu,
    120                                                     connection));
    121     BCM_IF_ERROR_RETURN(_bcm_board_xgs3_sw_modport_set(funit, tp_cpu,
    122                                                     connection));
    123 
    124     BCM_IF_ERROR_RETURN(bcm_port_config_get(funit, &config));
    125 
    126     /* program fabric for how to get to local units */
    127     BCM_PBMP_CLEAR(empty);
    128     for (unit = 0; unit < l_entry->base.num_units; unit++) {
    129         port = connection[unit].to;
    130         if (port < 0) {
    131             continue;
    132         }
    133         mod = l_entry->mod_ids[unit];
    134         if (mod < 0) {
    135             continue;
    136         }
    137         m = l_entry->base.mod_ids_req[unit];
    138         BCM_PBMP_PORT_SET(pbm, port);
    139         BCM_PBMP_ITER(config.hg, hport) {
    140             for (i = 0; i < m; i++) {
    141                 BCM_IF_ERROR_RETURN
    142                     (bcm_stk_ucbitmap_set(funit, hport, mod+i,
    143                                           hport == port ? empty : pbm));
    144                 
    145             }
    146         }
    147     }
    148     
    149     /* set up module routing for fabric ports */
    150     for (i = 0; i < l_entry->base.num_stk_ports; i++) {
    151         tsp = &tp_cpu->tp_stk_port[i];
    152         port = l_entry->base.stk_ports[i].port;
    153         
    154         for (m = 0; m < tsp->tx_mod_num; m++) {
    155             mod = tsp->tx_mods[m];
    156             BCM_PBMP_ITER(config.hg, hport) {
    157                 BCM_PBMP_CLEAR(pbm);
    158                 if (hport != port) {
    159                     BCM_PBMP_PORT_ADD(pbm, port);
    160                 }
    161                 BCM_IF_ERROR_RETURN(
    162                                     bcm_stk_ucbitmap_set(funit, hport, mod, pbm));
    163             }
    164         }
    165     }
    166     
    167     BCM_IF_ERROR_RETURN(bcm_board_module_filter(unit, tp_cpu, db_ref,
    168                                                 &config));
    169     BCM_IF_ERROR_RETURN(bcm_board_trunk_system(l_entry, db_ref,
    170                                                BCM_BOARD_TRUNK_NORMAL));
    171     
    172     /*
    173      * Transient state setup: program  dflt modid if ports
    174      * are not resolved
    175      */
    176     bcm_board_unknown_src_modid_setup(l_entry);
    177 
    178     /*
    179      * Module programming for switches
    180      */
    181     for (unit = 0; unit < l_entry->base.num_units; unit++) {
    182         if (unit == funit) {    /* skip fabric */
    183             continue;
    184         }
    185         mod = l_entry->mod_ids[unit];
    186         if (mod >= 0) {
    187             BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(unit, mod));
    188         }
    189     }
    190     
    191 #ifdef BCM_BOARD_AUTO_E2E
    192     /* intra-board end to end flow control, if available */
    193     BCM_IF_ERROR_RETURN(bcm_board_e2e_set());
    194 #endif  /* BCM_BOARD_AUTO_E2E */
    195 
    196     return BCM_E_NONE;
    197 }
    198 
    199 int
    200 chassis_cfm_xgs2(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    201 {
    202     int                  unit;
    203     int                  unitport[1];
    204     bcm_module_t         mod;
    205     int                  rv;
    206     bcm_port_t           iport, eport;
    207     bcm_board_cfm_info_t info;
    208     bcm_port_config_t    *config;
    209 
    210     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    211                 (BSL_META("TOPO: XGS 5675 BCM956000 CFM\n")));
    212 
    213     config = sal_alloc(sizeof(bcm_port_config_t), "bcm_port_config_t");
    214     if (NULL == config) {
    215         return BCM_E_MEMORY;
    216     }
    217     bcm_port_config_t_init(config);
    218 
    219     bcm_board_cfm_info(db_ref, &info);
    220 
    221     unit = 0;            /* board fabric unit */
    222 
    223     unitport[0] = -1;    /* 5675 unit 0 */
    224 
    225     mod = db_ref->local_entry->dest_mod;
    226 
    227     rv = bcm_port_config_get(unit, config);
    228     if (BCM_FAILURE(rv)) {
    229         sal_free(config);
    230         return (rv);
    231     }
    232 
    233     BCM_PBMP_ITER(config->hg, iport) {
    234         rv = bcm_stk_ucbitmap_set(unit, iport, mod, config->cpu);
    235         if (BCM_FAILURE(rv)) {
    236             sal_free(config);
    237             return (rv);
    238         }
    239     }
    240 
    241     rv = bcm_stk_my_modid_set(0, mod);
    242     if (BCM_FAILURE(rv)) {
    243         sal_free(config);
    244         return (rv);
    245     }
    246     if ((rv=bcm_board_xgs_common(unit, tp_cpu, db_ref, unitport))
    247         == BCM_E_NONE) {
    248         if (!info.is_master) {
    249             /* If this is not the master CFM, then block multicasts */
    250             BCM_PBMP_ITER(config->hg, iport) {
    251                 BCM_PBMP_ITER(config->hg, eport) {
    252                     rv = bcm_port_flood_block_set(unit, iport, eport, -1U);
    253                     if (rv < 0) {
    254                         break;
    255                     }
    256                 }
    257             }
    258         }
    259     }
    260     sal_free(config);
    261     return rv;
    262 }
    263 
    264 int
    265 chassis_cfm_xgs3(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    266 {
    267     int                  unit;
    268     bcm_module_t         mod;
    269     int                  rv = BCM_E_NONE;
    270     bcm_port_t           port;
    271     bcm_port_t           iport, eport;
    272     bcm_board_cfm_info_t info;
    273     bcm_port_config_t    config;
    274 
    275     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    276                 (BSL_META("TOPO: XGS3 56700 BCM956010 CFM\n")));
    277     bcm_board_cfm_info(db_ref, &info);
    278 
    279     unit = 0;            /* board fabric unit */
    280 
    281     BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config));
    282     BCM_PBMP_ITER(config.cpu, port) {
    283         break;   /* Get CPU port */
    284     }
    285     mod = db_ref->local_entry->mod_ids[0];
    286 
    287     BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(0, mod));
    288     BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit, mod, port));
    289     BCM_IF_ERROR_RETURN(bcm_board_fab_mod_map(unit,
    290                                               tp_cpu,
    291                                               db_ref->local_entry));
    292     BCM_IF_ERROR_RETURN(bcm_board_module_filter(unit, tp_cpu, db_ref, &config));
    293     BCM_IF_ERROR_RETURN(bcm_board_trunk_system(&tp_cpu->local_entry,
    294                                                db_ref,
    295                                                BCM_BOARD_TRUNK_NORMAL));
    296     if (!info.is_master) {
    297         /* If this is not the master CFM, then block multicasts */
    298         BCM_PBMP_ITER(config.hg, iport) {
    299             BCM_PBMP_ITER(config.hg, eport) {
    300                 rv = bcm_port_flood_block_set(unit, iport, eport, -1U);
    301                 if (rv < 0) {
    302                     break;
    303                 }
    304             }
    305         }
    306     }
    307 
    308     return rv;
    309 }
    310 
    311 /*
    312  * Chassis line module (lm2x) board
    313  *     5671 + 2x5673
    314  * External stack ports are unit 0 ports 3,6
    315  */
    316 STATIC int
    317 _bcm_board_topomap_lm2x(int src_unit, int dest_modid,
    318                         bcm_port_t *exit_port)
    319 {
    320     switch (src_unit) {
    321     case 0:  /* 5670 */
    322         /* check for local connections */
    323         BCM_BOARD_MOD_CHECK(1, 8, dest_modid, exit_port);
    324         BCM_BOARD_MOD_CHECK(2, 1, dest_modid, exit_port);
    325         return bcm_board_topomap_stk(src_unit, dest_modid, exit_port);
    326 
    327     case 1:  /* 5673s */
    328     case 2:
    329         *exit_port = 1;    /* IPIC_PORT(src_unit) */
    330         return BCM_E_NONE;
    331 
    332     default:
    333         return BCM_E_UNIT;
    334     }
    335 }
    336 
    337 int
    338 bcm_board_topo_lm2x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    339 {
    340     int    unit;
    341     int    unitport[3];
    342 
    343     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    344                 (BSL_META("TOPO: XGS 5674 2XE board topology handler\n")));
    345     bcm_topo_map_set(_bcm_board_topomap_lm2x);
    346 
    347     unit = 0;            /* board fabric unit */
    348 
    349     unitport[0] = -1;    /* 5671 unit 0 */
    350     unitport[1] = 8;     /* 5673 unit 1 */
    351     unitport[2] = 1;     /* 5673 unit 2 */
    352 
    353     return bcm_board_xgs_common(unit, tp_cpu, db_ref, unitport);
    354 }
    355 
    356 int
    357 chassis_lm6x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    358 {
    359     int    unit;
    360     int    unitport[7];
    361 
    362     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    363                 (BSL_META("TOPO: XGS 5674 6XE board topology handler\n")));
    364 
    365     unit = 0;            /* board fabric unit */
    366 
    367     unitport[0] = -1;    /* 5671 unit 0 */
    368     unitport[1] = 6;     /* 5673 unit 1 */
    369     unitport[2] = 7;     /* 5673 unit 2 */
    370     unitport[3] = 8;     /* 5673 unit 3 */
    371     unitport[4] = 1;     /* 5673 unit 4 */
    372     unitport[5] = 2;     /* 5673 unit 5 */
    373     unitport[6] = 3;     /* 5673 unit 6 */
    374 
    375     return bcm_board_xgs_common(unit, tp_cpu, db_ref, unitport);
    376 }
    377 
    378 int
    379 chassis_lm_xgs2_48g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    380 {
    381     int    unit;
    382     int    unitport[5];
    383 
    384     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    385                 (BSL_META("TOPO: XGS 569x 48GE BCM956000 Chassis Line Card\n")));
    386 
    387     unit = 0;            /* board fabric unit */
    388 
    389     unitport[0] = -1;    /* 5675 unit 0 */
    390     unitport[1] = 1;     /* 5695 unit 1 is on port 1 */
    391     unitport[2] = 2;     /* 5695 unit 2 is on port 2 */
    392     unitport[3] = 3;     /* 5673 unit 3 is on port 3 */
    393     unitport[4] = 4;     /* 5673 unit 4 is on port 4 */
    394 
    395     BCM_IF_ERROR_RETURN(bcm_board_xgs_common(unit, tp_cpu, db_ref, unitport));
    396 
    397     return BCM_E_NONE;
    398 }
    399 
    400 /*
    401  * Firebolt Line Module
    402  *
    403  *          cfm0                       cfm1
    404  *
    405  *        |     |                    |     | 
    406  *     +--+-----+--+              +--+-----+--+
    407  *     |  0     1  |              |  0     1  |
    408  *     |           |              |           |
    409  *     |         2 +--------------+ 2         |
    410  *     |           |              |           |
    411  *     |         3 +--------------+ 3         |
    412  *     |   U1700   |              |    U1600  |
    413  *     +-----------+              +-----------+
    414  *
    415  *  Assumptions:
    416  *
    417  *  1) Each device only references Higig links 0 and 2.  This works
    418  *  for both untrunked and fabric trunked links.  If untrunked, links
    419  *  1 and 3 should be disabled. If trunked, 0 must be trunked with 1,
    420  *  and 2 with 3.
    421  *
    422  *  2) Links are symmetric, i.e., rxmod == txmod
    423  *
    424  *  3) CFM0 is always assigned slot 0, CFM1 is slot 1
    425  *
    426  *  4) Traffic is routed through the master. This assumption will
    427  *  change when traffic load balancing is implemented.
    428  *
    429  *  Therefore, if CFM0 is the master
    430  *
    431  *    U1700:MODPORT_MAP[modid(U1600)] = pbm(hg2)
    432  *    U1700:MODPORT_MAP[modid( cfm1)] = pbm(hg2)
    433  *    U1700:MODPORT_MAP[modid(other)] = pbm(hg0)
    434  *    U1600:MODPORT_MAP[modid( cfm1)] = pbm(hg0)
    435  *    U1600:MODPORT_MAP[modid(other)] = pbm(hg2)
    436  *
    437  *  Else if CFM1 is the master
    438  *
    439  *    U1600:MODPORT_MAP[modid(U1700)] = pbm(hg2)
    440  *    U1600:MODPORT_MAP[modid( cfm0)] = pbm(hg2)
    441  *    U1600:MODPORT_MAP[modid(other)] = pbm(hg0)
    442  *    U1700:MODPORT_MAP[modid( cfm0)] = pbm(hg0)
    443  *    U1700:MODPORT_MAP[modid(other)] = pbm(hg2)
    444  *
    445  *  Else if self is master
    446  *
    447  *    U1600:MODPORT_MAP[ modid(U1700)] = pbm(hg2)
    448  *    U1700:MODPORT_MAP[ modid(U1600)] = pbm(hg2)
    449  */
    450 
    451 STATIC int
    452 bcm_board_xgs3_fb_lm(int master_unit,       /* Unit connected to CFM master */
    453                      int master_modid,      /* Modid of master unit */
    454                      int partner_unit,      /* Unit connected to CFM !master */
    455                      int partner_modid,     /* Modid of partner unit */
    456                      int internal_port,     /* Internal port */
    457                      topo_cpu_t *tp_cpu,    /* Topology */
    458                      cpudb_ref_t db_ref)    /* Database information */
    459 {
    460     int                 i, m;
    461     topo_stk_port_t     *tsp;
    462     int                 port;
    463     cpudb_entry_t       *l_entry;
    464     bcm_module_t        mod;
    465     bcm_port_config_t   config;
    466     int                 spunit, npunit;
    467     int                 auto_trunk;
    468 
    469     l_entry = &tp_cpu->local_entry;
    470     for (i = 0; i < l_entry->base.num_stk_ports; i++) {
    471         if (!(l_entry->sp_info[i].flags & CPUDB_SPF_TX_RESOLVED)) {
    472             /* Skip unresolved ports */
    473             continue;
    474         }
    475 
    476         /* spunit is the unit that this stack port is connected to */
    477         spunit = l_entry->base.stk_ports[i].unit;
    478         
    479         /* npunit is the unit of the other device */
    480         npunit = (spunit == master_unit) ? partner_unit : master_unit;
    481         
    482         /* For each mod-id reached by this port, set both devices
    483            (spunit and npunit). For spunit (the unit this stack port
    484            is on), set the modmap to the stack port. For npunit (the
    485            unit this stack port is *not on), set the modmap to the
    486            internal port. */
    487 
    488         tsp = &tp_cpu->tp_stk_port[i];
    489         port = l_entry->base.stk_ports[i].port;
    490 
    491         for (m = 0; m < tsp->tx_mod_num; m++) {
    492             mod = tsp->tx_mods[m];
    493             BCM_IF_ERROR_RETURN(bcm_stk_modport_set(spunit, mod, port));
    494             BCM_IF_ERROR_RETURN(bcm_stk_modport_set(npunit, mod,
    495                                                     internal_port));
    496         }
    497     }
    498 
    499     /* The internal_port must be the same on both devices. */
    500     BCM_IF_ERROR_RETURN(bcm_stk_modport_set(master_unit,
    501                                             partner_modid,
    502                                             internal_port));
    503     BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(master_unit,
    504                                                         internal_port));
    505     BCM_IF_ERROR_RETURN(bcm_board_auto_trunk_get(&auto_trunk));
    506     if (auto_trunk) {
    507         BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(master_unit,
    508                                                             internal_port+1));
    509         BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(partner_unit,
    510                                                             internal_port+1));
    511     }
    512 
    513     BCM_IF_ERROR_RETURN(bcm_port_config_get(master_unit, &config));
    514     BCM_IF_ERROR_RETURN(bcm_board_module_filter(master_unit, tp_cpu, db_ref,
    515                                                 &config));
    516 
    517     BCM_IF_ERROR_RETURN(bcm_stk_modport_set(partner_unit,
    518                                             master_modid,
    519                                             internal_port));
    520     BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(partner_unit,
    521                                                         internal_port));
    522     BCM_IF_ERROR_RETURN(bcm_port_config_get(partner_unit, &config));
    523     BCM_IF_ERROR_RETURN(bcm_board_module_filter(partner_unit, tp_cpu, db_ref,
    524                                                 &config));
    525 
    526     
    527     BCM_IF_ERROR_RETURN(bcm_board_trunk_system(l_entry, db_ref,
    528                                                BCM_BOARD_TRUNK_NORMAL));
    529 
    530     return BCM_E_NONE;
    531 }
    532 
    533 
    534 #define FB_UNIT0 0
    535 #define FB_UNIT1 1
    536 #define FB_HG0 24
    537 #define FB_HG1 25
    538 #define FB_HG2 26
    539 #define FB_HG3 27
    540 
    541 int
    542 _bcm_board_setup_trunk_lm_xgs3_48g(void)
    543 {
    544     bcm_trunk_info_t     trunk;
    545     bcm_trunk_chip_info_t    ti;
    546     bcm_trunk_member_t   member_array[2];
    547     
    548     sal_memset(&trunk, 0, sizeof(trunk));
    549     trunk.psc        = -1;
    550     trunk.dlf_index  = -1;
    551     trunk.mc_index   = -1;
    552     trunk.ipmc_index = -1;
    553 
    554     bcm_trunk_member_t_init(&member_array[0]);
    555     member_array[0].gport = BCM_GPORT_DEVPORT(FB_UNIT0, FB_HG2);
    556     bcm_trunk_member_t_init(&member_array[1]);
    557     member_array[1].gport = BCM_GPORT_DEVPORT(FB_UNIT0, FB_HG3);
    558 
    559     BCM_IF_ERROR_RETURN(bcm_trunk_chip_info_get(FB_UNIT0, &ti));
    560     bcm_trunk_destroy(FB_UNIT0, ti.trunk_fabric_id_max);
    561     BCM_IF_ERROR_RETURN(bcm_trunk_create(FB_UNIT0,
    562                                          BCM_TRUNK_FLAG_WITH_ID,
    563                                          &ti.trunk_fabric_id_max));
    564     BCM_IF_ERROR_RETURN(bcm_trunk_set(FB_UNIT0,
    565                                       ti.trunk_fabric_id_max, &trunk,
    566                                       2, member_array));
    567 
    568     bcm_trunk_member_t_init(&member_array[0]);
    569     member_array[0].gport = BCM_GPORT_DEVPORT(FB_UNIT1, FB_HG2);
    570     bcm_trunk_member_t_init(&member_array[1]);
    571     member_array[1].gport = BCM_GPORT_DEVPORT(FB_UNIT1, FB_HG3);
    572 
    573     BCM_IF_ERROR_RETURN(bcm_trunk_chip_info_get(FB_UNIT1, &ti));
    574     bcm_trunk_destroy(FB_UNIT1, ti.trunk_fabric_id_max);
    575     BCM_IF_ERROR_RETURN(bcm_trunk_create(FB_UNIT1,
    576                                          BCM_TRUNK_FLAG_WITH_ID,
    577                                          &ti.trunk_fabric_id_max));
    578     BCM_IF_ERROR_RETURN(bcm_trunk_set(FB_UNIT1,
    579                                       ti.trunk_fabric_id_max, &trunk,
    580                                       2, member_array));
    581 
    582     return BCM_E_NONE;
    583 }
    584 
    585 /* Two FBs on a BCM956000 LM */
    586 int
    587 chassis_lm_xgs3_48g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    588 {
    589     int                      unit0_modid;
    590     int                      unit1_modid;
    591     int                      master_slot;
    592 
    593     /* If there's no master yet, set self as master */
    594     master_slot = db_ref->master_entry ?
    595         db_ref->master_entry->base.slot_id : -1;
    596     unit0_modid = tp_cpu->local_entry.mod_ids[FB_UNIT0];
    597     unit1_modid = tp_cpu->local_entry.mod_ids[FB_UNIT1];
    598 
    599     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    600                 (BSL_META("TOPO: XGS3 56504 48GE BCM956000 Chassis Line Card\n")));
    601     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    602                 (BSL_META("      master on slot %d\n"),
    603                  master_slot));
    604 
    605     switch (master_slot) {
    606     case 0:
    607         /* CFM0 Master */
    608         BCM_IF_ERROR_RETURN
    609             (bcm_board_xgs3_fb_lm(FB_UNIT1, unit1_modid,
    610                                   FB_UNIT0, unit0_modid,
    611                                   FB_HG2, tp_cpu, db_ref));
    612         break;
    613     case 1:
    614         /* CFM1 Master */
    615         BCM_IF_ERROR_RETURN
    616             (bcm_board_xgs3_fb_lm(FB_UNIT0, unit0_modid,
    617                                   FB_UNIT1, unit1_modid,
    618                                   FB_HG2, tp_cpu, db_ref));
    619         break;
    620     default:
    621         /* LM (self) Master */
    622         BCM_IF_ERROR_RETURN
    623             (bcm_board_xgs3_fb_lm(FB_UNIT1,
    624                                   unit1_modid,
    625                                   FB_UNIT0,
    626                                   unit0_modid, FB_HG2, tp_cpu, db_ref));
    627         /* If master not elected, don't set up trunks yet */
    628         break;
    629     }    
    630 
    631     /* The CFM trunk was handled by bcm_board_xgs3_fb_lm() above.
    632        Set up the intraboard trunk here. */
    633     BCM_IF_ERROR_RETURN(_bcm_board_setup_trunk_lm_xgs3_48g());
    634     
    635     BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(FB_UNIT0, unit0_modid));
    636     BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(FB_UNIT1, unit1_modid));
    637 
    638 #ifdef BCM_BOARD_AUTO_E2E
    639     /* intra-board end to end flow control, if available */
    640     BCM_IF_ERROR_RETURN(_bcm_board_dual_xgs3_e2e_set(FB_UNIT0, unit0_modid,
    641                                                      FB_UNIT1, unit1_modid));
    642 #endif  /* BCM_BOARD_AUTO_E2E */
    643 
    644     return BCM_E_NONE;
    645 }
    646 
    647 #undef FB_UNIT0
    648 #undef FB_UNIT1
    649 
    650 /* Four 56501 FBs on a BCM956000 LM */
    651 int
    652 chassis_lm_xgs3_12x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    653 {
    654     int               unit;
    655     int               rv = BCM_E_NONE;
    656     bcm_board_port_connection_t connection[5];
    657     int               master_slot;
    658 
    659     master_slot = db_ref->master_entry ?
    660         db_ref->master_entry->base.slot_id : -1;
    661     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    662                 (BSL_META("TOPO: XGS3 56501 12XE BCM956000 Chassis Line Card\n")));
    663     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    664                 (BSL_META("      master on slot %d\n"),
    665                  master_slot));
    666 
    667     unit = 0;    /* board fabric unit */
    668 
    669     /* 5675 unit 0 - no connection map entry */
    670     connection[0].from = -1;
    671     connection[0].to   = -1;
    672 
    673     /* 56501 unit 1 port 27 connects to 5675 port 7 */
    674     connection[1].from = FB_HG3;
    675     connection[1].to   = 7;
    676 
    677     /* 56501 unit 2 port 27 connects to 5675 port 8 */
    678     connection[2].from = FB_HG3;
    679     connection[2].to   = 8;
    680 
    681     /* 56501 unit 3 port 27 connects to 5675 port 1 */
    682     connection[3].from = FB_HG3;
    683     connection[3].to   = 1;
    684 
    685     /* 56501 unit 4 port 27 connects to 5675 port 2 */
    686     connection[4].from = FB_HG3;
    687     connection[4].to   = 2;
    688     rv = bcm_board_xgs3_sw_xgs_fabric(unit, tp_cpu, db_ref, connection);
    689 
    690     return rv;
    691 }
    692 
    693 int
    694 chassis_lm_56800_12x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref)
    695 {
    696     int                  unit;
    697     bcm_module_t         mod;
    698     bcm_port_t           port;
    699     bcm_port_config_t    config;
    700 
    701     LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY,
    702                 (BSL_META("TOPO: XGS3 56800 LM\n")));
    703 
    704     unit = 0;            /* board fabric unit */
    705 
    706     BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config));
    707     BCM_PBMP_ITER(config.cpu, port) {
    708         break;   /* Get CPU port */
    709     }
    710     mod = db_ref->local_entry->mod_ids[0];
    711     BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit, mod, port));
    712     BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(0, mod));
    713     BCM_IF_ERROR_RETURN(bcm_board_fab_mod_map(unit,
    714                                               tp_cpu,
    715                                               db_ref->local_entry));
    716     BCM_IF_ERROR_RETURN(bcm_board_module_filter(unit, tp_cpu, db_ref, &config));
    717     BCM_IF_ERROR_RETURN(bcm_board_trunk_system(&tp_cpu->local_entry,
    718                                                db_ref,
    719                                                BCM_BOARD_TRUNK_NORMAL));
    720 
    721     return BCM_E_NONE;
    722 }
    723 
    724 #else
    725 int _brd_chassis_nolb_not_empty;
    726 #endif /* INCLUDE_CHASSIS */
    727