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

failover.c (17152B)


      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  * TR3 failover API
      8  */
      9 
     10 #include <soc/defs.h>
     11 #include <sal/core/libc.h>
     12 
     13 #if defined(BCM_TRIUMPH3_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/firebolt.h>
     24 #include <bcm_int/esw/triumph2.h>
     25 #include <bcm/failover.h>
     26 #include <bcm_int/common/multicast.h>
     27 #include <bcm_int/esw/multicast.h>
     28 #include <bcm_int/esw/failover.h>
     29 
     30 STATIC int
     31 _bcm_tr3_failover_nhi_get(int unit, bcm_gport_t port, int *nh_index)
     32 {
     33     int vp=0xFFFF;
     34     ing_dvp_table_entry_t dvp;
     35 
     36     if (!BCM_GPORT_IS_MPLS_PORT(port) &&
     37          !BCM_GPORT_IS_MIM_PORT(port) ) {
     38         return BCM_E_PARAM;
     39     }
     40     
     41     if ( BCM_GPORT_IS_MPLS_PORT(port)) {
     42          vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
     43     } else if ( BCM_GPORT_IS_MIM_PORT(port)) {
     44          vp = BCM_GPORT_MIM_PORT_ID_GET(port);
     45     }
     46 
     47     if (vp >= soc_mem_index_count(unit, SOURCE_VPm)) {
     48         return BCM_E_PARAM;
     49     }
     50     BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp));
     51 
     52     /* Next-hop index is used for multicast replication */
     53     *nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf);
     54     return BCM_E_NONE;
     55 }
     56 /*
     57  * Function:
     58  *		bcm_tr3_failover_status_set
     59  * Purpose:
     60  *		Set the parameters for  a failover object
     61  * Parameters:
     62  *		IN :  unit
     63  *           IN :  failover_id
     64  *           IN :  value
     65  * Returns:
     66  *		BCM_E_XXX
     67  */
     68 
     69 int
     70 bcm_tr3_failover_status_set(int unit, bcm_failover_element_t *failover, int value)
     71 {
     72     int rv = BCM_E_UNAVAIL;
     73     int nh_index;
     74     initial_prot_group_table_entry_t  prot_group_entry;
     75     rx_prot_group_table_entry_t  rx_prot_group_entry;
     76     initial_prot_nhi_table_entry_t   prot_nhi_entry;
     77 
     78     if ((value < 0) || (value > 1)) {
     79        return BCM_E_PARAM;
     80     }
     81 
     82     if (failover->failover_id != BCM_FAILOVER_INVALID) {
     83          /* Group protection for Port and Tunnel: Egress and Ingress */
     84          BCM_IF_ERROR_RETURN( 
     85               bcm_tr2_failover_id_validate ( unit, failover->failover_id ));
     86 
     87          BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 
     88                    MEM_BLOCK_ANY, failover->failover_id, &prot_group_entry));
     89 
     90          soc_mem_field32_set(unit, INITIAL_PROT_GROUP_TABLEm, 
     91                    &prot_group_entry, STATUSf, value);
     92 
     93          BCM_IF_ERROR_RETURN(
     94               soc_mem_write(unit, INITIAL_PROT_GROUP_TABLEm,
     95                    MEM_BLOCK_ALL, failover->failover_id, &prot_group_entry));
     96 
     97          BCM_IF_ERROR_RETURN (soc_mem_read(unit, RX_PROT_GROUP_TABLEm, 
     98                MEM_BLOCK_ANY, failover->failover_id, &rx_prot_group_entry));
     99 
    100          soc_mem_field32_set(unit, RX_PROT_GROUP_TABLEm, 
    101                &rx_prot_group_entry, DROP_DATA_ENABLEf, value);
    102 
    103          rv =   soc_mem_write(unit, RX_PROT_GROUP_TABLEm,
    104                MEM_BLOCK_ALL, failover->failover_id,  &rx_prot_group_entry);
    105 
    106     }else if (failover->intf != BCM_IF_INVALID) {
    107         /* Only Egress is applicable */
    108         if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, failover->intf)) {
    109             nh_index = failover->intf - BCM_XGS3_EGRESS_IDX_MIN(unit);
    110         } else {
    111             nh_index = failover->intf  - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit);
    112         }
    113 
    114          BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    115                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry));
    116 
    117          soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    118                                        &prot_nhi_entry, REPLACE_ENABLEf, value);
    119 
    120          rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm,
    121                        MEM_BLOCK_ALL, nh_index, &prot_nhi_entry);
    122 
    123     } else if (failover->port != BCM_GPORT_INVALID) {
    124          /* Individual protection for Pseudo-wire: Egress and Ingress */
    125          BCM_IF_ERROR_RETURN (
    126                _bcm_tr3_failover_nhi_get(unit, failover->port , &nh_index));
    127 
    128          BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    129                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry));
    130 
    131          soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    132                                        &prot_nhi_entry, REPLACE_ENABLEf, value);
    133 
    134          rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm,
    135                        MEM_BLOCK_ALL, nh_index, &prot_nhi_entry);
    136 
    137          
    138 
    139     }
    140     return rv;
    141 }
    142 
    143 
    144 /*
    145  * Function:
    146  *		bcm_tr3_failover_status_get
    147  * Purpose:
    148  *		Get the parameters for  a failover object
    149  * Parameters:
    150  *		IN :  unit
    151  *           IN :  failover_id
    152  *           OUT :  value
    153  * Returns:
    154  *		BCM_E_XXX
    155  */
    156 
    157 int
    158 bcm_tr3_failover_status_get(int unit, bcm_failover_element_t *failover, int  *value)
    159 {
    160     initial_prot_group_table_entry_t  prot_group_entry;
    161     rx_prot_group_table_entry_t  rx_prot_group_entry;
    162     initial_prot_nhi_table_entry_t   prot_nhi_entry;
    163     int nh_index;
    164 
    165 
    166     if (failover->failover_id != BCM_FAILOVER_INVALID) {
    167 
    168          BCM_IF_ERROR_RETURN( bcm_tr2_failover_id_validate ( unit, failover->failover_id ));
    169 
    170          BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_GROUP_TABLEm, 
    171                    MEM_BLOCK_ANY, failover->failover_id, &prot_group_entry));
    172 
    173          *value =   soc_mem_field32_get(unit, INITIAL_PROT_GROUP_TABLEm,
    174                    &prot_group_entry, STATUSf);
    175 
    176          BCM_IF_ERROR_RETURN (soc_mem_read(unit, RX_PROT_GROUP_TABLEm, 
    177                MEM_BLOCK_ANY, failover->failover_id, &rx_prot_group_entry));
    178 
    179          *value &=   soc_mem_field32_get(unit, RX_PROT_GROUP_TABLEm,
    180                &rx_prot_group_entry, DROP_DATA_ENABLEf);
    181     
    182     }else if (failover->intf != BCM_IF_INVALID) {
    183 
    184         if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, failover->intf)) {
    185             nh_index = failover->intf - BCM_XGS3_EGRESS_IDX_MIN(unit);
    186         } else {
    187             nh_index = failover->intf  - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit);
    188         }
    189 
    190          BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    191                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry));
    192 
    193          *value =   soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm,
    194                    &prot_nhi_entry, REPLACE_ENABLEf);
    195 
    196     } else if (failover->port != BCM_GPORT_INVALID) {
    197 
    198          BCM_IF_ERROR_RETURN (
    199                _bcm_tr3_failover_nhi_get(unit, failover->port , &nh_index));
    200 
    201          BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    202                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry));
    203 
    204          *value =   soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm,
    205                    &prot_nhi_entry, REPLACE_ENABLEf);
    206 
    207     }
    208     return BCM_E_NONE;
    209 }
    210 
    211 
    212 /*
    213  * Function:
    214  *		bcm_tr3_failover_prot_nhi_set
    215  * Purpose:
    216  *		Set the parameters for PROT_NHI
    217  * Parameters:
    218  *		IN :  unit
    219  *           IN :  Primary Next Hop Index
    220  *           IN :  Protection Next Hop Index
    221  *           IN :  Failover Group Index
    222  * Returns:
    223  *		BCM_E_XXX
    224  */
    225 
    226 int
    227 bcm_tr3_failover_prot_nhi_set(int unit, uint32 flags, int nh_index, uint32 prot_nh_index, 
    228                                            bcm_multicast_t  mc_group, bcm_failover_t failover_id)
    229 {
    230     initial_prot_nhi_table_entry_t   prot_nhi_entry;
    231     int rv;
    232     int l3mc_index;
    233 
    234     BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    235                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry));
    236 
    237     /* if mc_group is valid */
    238     if (_BCM_MULTICAST_IS_SET(mc_group)) {
    239          l3mc_index = _BCM_MULTICAST_ID_GET(mc_group);
    240          if ((l3mc_index >= 0) && (l3mc_index < soc_mem_index_count(unit, L3_IPMCm))) {
    241               soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    242                                        &prot_nhi_entry, REPLACEMENT_DATAf, 
    243                                        l3mc_index);
    244               soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    245                                        &prot_nhi_entry, REPLACEMENT_TYPEf, 
    246                                        0x1);
    247          }
    248     } else {
    249          /* if prot_nh_index is valid */
    250          soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    251                                        &prot_nhi_entry, REPLACEMENT_DATAf, 
    252                                        prot_nh_index);
    253          soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    254                                        &prot_nhi_entry, REPLACEMENT_TYPEf, 
    255                                        0x0);
    256     }
    257 
    258     /* if failover_id is valid */
    259     soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, 
    260                                        &prot_nhi_entry, PROT_GROUPf, 
    261                                        (uint32) failover_id);
    262 
    263     rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm,
    264                        MEM_BLOCK_ALL, nh_index, &prot_nhi_entry);
    265 
    266     if (rv == SOC_E_NONE && _BCM_FAILOVER_PROT_NHI_MAP_IS_VALID(unit)) {
    267         _BCM_FAILOVER_PROT_NHI_MAP_USED_SET(unit, nh_index);
    268     }
    269 
    270     return rv;
    271 
    272 }
    273 
    274 
    275 /*
    276  * Function: bcm_tr3_failover_prot_nhi_get
    277  * Purpose:
    278  *		Get the parameters for PROT_NHI
    279  * Parameters:
    280  *		IN :  unit
    281  *           IN :  primary Next Hop Index
    282  *           OUT :  Failover Group Index
    283  *           OUT : Protection Next Hop Index
    284  * Returns:
    285  *		BCM_E_XXX
    286  */
    287 
    288 
    289 int
    290 bcm_tr3_failover_prot_nhi_get(int unit, int nh_index, 
    291             bcm_failover_t  *failover_id, int  *prot_nh_index, bcm_multicast_t  *mc_group)
    292 {
    293     initial_prot_nhi_table_entry_t   prot_nhi_entry;
    294     uint32 replacement_type;
    295     int l3mc_index;
    296 
    297     BCM_IF_ERROR_RETURN (soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    298                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry));
    299 
    300     *failover_id =   soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm,
    301                               &prot_nhi_entry, PROT_GROUPf);
    302 
    303     replacement_type =   soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm,
    304                               &prot_nhi_entry, REPLACEMENT_TYPEf);
    305 
    306     if (!replacement_type) {
    307        *prot_nh_index = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm,
    308                               &prot_nhi_entry, REPLACEMENT_DATAf);
    309     } else {
    310        l3mc_index = soc_mem_field32_get(unit, INITIAL_PROT_NHI_TABLEm,
    311                               &prot_nhi_entry, REPLACEMENT_DATAf);
    312         _BCM_MULTICAST_GROUP_SET(*mc_group,
    313                                  _BCM_MULTICAST_TYPE_EGRESS_OBJECT,
    314                                  l3mc_index); 
    315     }
    316 
    317     return BCM_E_NONE;
    318 
    319 }
    320 
    321 /*
    322  * Function:
    323  *		bcm_tr3_failover_prot_nhi_cleanup
    324  * Purpose:
    325  *		Create  the  entry for  PROT_NHI
    326  * Parameters:
    327  *		IN :  unit
    328  *           IN :  Primary Next Hop Index
    329  * Returns:
    330  *		BCM_E_XXX
    331  */
    332 
    333 
    334 int
    335 bcm_tr3_failover_prot_nhi_cleanup  (int unit, int nh_index)
    336 {
    337     initial_prot_nhi_table_entry_t  prot_nhi_entry;
    338     int rv;
    339 
    340     rv = soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    341                              MEM_BLOCK_ANY, nh_index, &prot_nhi_entry);
    342 
    343    if (rv < 0){
    344          return BCM_E_NOT_FOUND;
    345     }
    346 
    347     sal_memset(&prot_nhi_entry, 0, sizeof(initial_prot_nhi_table_entry_t));
    348 
    349     rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm,
    350                        MEM_BLOCK_ALL, nh_index, &prot_nhi_entry);
    351 
    352     if (rv == SOC_E_NONE && _BCM_FAILOVER_PROT_NHI_MAP_IS_VALID(unit)) {
    353         _BCM_FAILOVER_PROT_NHI_MAP_USED_CLR(unit, nh_index);
    354     }
    355     return rv;
    356 
    357 }
    358 
    359 /*
    360  * Function:
    361  *    bcm_tr3_failover_prot_nhi_update
    362  * Purpose:
    363  *    Update the next_hop  entry for failover
    364  * Parameters:
    365  *    IN :  unit
    366  *    IN :  Old Failover next hop index
    367  *    IN :  New Failover next hop index
    368  * Returns:
    369  *    BCM_E_XXX
    370  */
    371 
    372 
    373 int
    374 bcm_tr3_failover_prot_nhi_update  (int unit, int old_nh_index, int new_nh_index)
    375 {
    376     uint32  prot_nhi_entry;
    377     int rv = BCM_E_NONE;
    378     int  num_entry, index;
    379     uint32 mask = 0;
    380     uint32 imask = 0;
    381     uint32 data_old = 0;
    382     uint32 data_new = 0;
    383     int fld_len = 0;
    384     
    385     num_entry = soc_mem_index_count(unit, INITIAL_PROT_NHI_TABLEm);
    386 
    387     fld_len = soc_mem_field_length(unit, INITIAL_PROT_NHI_TABLEm, REPLACEMENT_DATAf);
    388     soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, &mask, REPLACEMENT_DATAf, (1<<fld_len) - 1);
    389     fld_len = soc_mem_field_length(unit, INITIAL_PROT_NHI_TABLEm, REPLACEMENT_TYPEf);
    390     soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, &mask, REPLACEMENT_TYPEf,  (1<<fld_len) - 1);
    391 
    392     imask = ~mask;
    393 
    394     /* REPLACEMENT_TYPE should be 0 */
    395     soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, &data_old, REPLACEMENT_DATAf, 
    396                                     old_nh_index);
    397     
    398     /* REPLACEMENT_TYPE should be 0 */
    399     soc_mem_field32_set(unit, INITIAL_PROT_NHI_TABLEm, &data_new, REPLACEMENT_DATAf, 
    400                                     new_nh_index);
    401     
    402     for ( index=0; index < num_entry; index++ ) {
    403         if (_BCM_FAILOVER_PROT_NHI_MAP_IS_VALID(unit)) {
    404             if (_BCM_FAILOVER_PROT_NHI_MAP_USED_GET(unit, index) == 0) {
    405                 continue;
    406             }
    407         }
    408         rv = soc_mem_read(unit, INITIAL_PROT_NHI_TABLEm, 
    409                                        MEM_BLOCK_ANY, index, &prot_nhi_entry);
    410         if (rv < 0) {
    411             return BCM_E_NOT_FOUND;
    412         }
    413 
    414         if ((prot_nhi_entry & mask) == data_old)  {
    415             prot_nhi_entry &= imask;
    416             prot_nhi_entry |= data_new;
    417             rv = soc_mem_write(unit, INITIAL_PROT_NHI_TABLEm,
    418                                        MEM_BLOCK_ALL, index, &prot_nhi_entry);
    419             if (rv < 0) {
    420                 return BCM_E_NOT_FOUND;
    421             }
    422         }
    423     }
    424     return rv;
    425 }
    426 
    427 
    428 /*
    429  * Function:
    430  *    bcm_tr3_failover_egr_check
    431  * Purpose:
    432  *    Check for failover enable - Egress Object
    433  * Parameters:
    434  *    IN :  unit
    435  *    IN :  Egress Object
    436  * Returns:
    437  *    BCM_E_XXX
    438  */
    439 
    440 
    441 int
    442 bcm_tr3_failover_egr_check (int unit, bcm_l3_egress_t  *egr)
    443 {
    444     int l3mc_index = -1;
    445 
    446      if (_BCM_MULTICAST_IS_SET(egr->failover_mc_group )) {
    447          l3mc_index = _BCM_MULTICAST_ID_GET(egr->failover_mc_group);
    448          if ((l3mc_index >= 0) && (l3mc_index < soc_mem_index_count(unit, L3_IPMCm))) {
    449               return BCM_E_NONE;
    450          } else {
    451                return BCM_E_PARAM;
    452          }
    453      } else if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, egr->failover_if_id) || 
    454         BCM_XGS3_DVP_EGRESS_IDX_VALID(unit, egr->failover_if_id)) {
    455          return (BCM_E_NONE);
    456     }
    457     return BCM_E_PARAM;
    458 }
    459 
    460 /*
    461  * Function:
    462  *    bcm_tr3_failover_mpls_check
    463  * Purpose:
    464  *    Check for failover enable - MPLS port
    465  * Parameters:
    466  *    IN :  unit
    467  *    IN :  Egress Object
    468  * Returns:
    469  *    BCM_E_XXX
    470  */
    471 
    472 
    473 int
    474 bcm_tr3_failover_mpls_check (int unit, bcm_mpls_port_t  *mpls_port)
    475 {
    476     int failover_vp = -1;
    477     int l3mc_index = -1;
    478 
    479      /* Get egress next-hop index from Failover MPLS gport */
    480      if (_BCM_MULTICAST_IS_SET(mpls_port->failover_mc_group)) {
    481          l3mc_index = _BCM_MULTICAST_ID_GET(mpls_port->failover_mc_group);
    482          if ((l3mc_index >= 0) && (l3mc_index < soc_mem_index_count(unit, L3_IPMCm))) {
    483               return BCM_E_NONE;
    484          } else {
    485                return BCM_E_PARAM;
    486          }
    487      } else {
    488          failover_vp = BCM_GPORT_MPLS_PORT_ID_GET(mpls_port->failover_port_id);
    489          if (failover_vp == -1) {
    490               return BCM_E_PARAM;
    491          }
    492          if ( (failover_vp >= 1)  && (failover_vp < soc_mem_index_count(unit, SOURCE_VPm)) ) {
    493               return BCM_E_NONE;
    494          } else {
    495               return BCM_E_PARAM;
    496          }
    497      }
    498     return BCM_E_PARAM;
    499 }
    500 
    501 /*
    502  * Function:
    503  *    bcm_tr3_failover_extender_check
    504  * Purpose:
    505  *    Check for failover enable - EXTENDER port
    506  * Parameters:
    507  *    IN :  unit
    508  *    IN :  Egress Object
    509  * Returns:
    510  *    BCM_E_XXX
    511  */
    512 int
    513 bcm_tr3_failover_extender_check(int unit,
    514                                 bcm_extender_port_t *extender_port)
    515 {
    516     int failover_vp = -1;
    517     int l3mc_index = -1;
    518 
    519     if (extender_port->failover_id > 0 && extender_port->failover_id < 1024) {
    520         /* Get egress next-hop index from Failover EXTENDER gport */
    521         if (_BCM_MULTICAST_IS_SET(extender_port->failover_mc_group)
    522             && SOC_MEM_FIELD_VALID(unit, INITIAL_PROT_NHI_TABLEm, 
    523                                    REPLACEMENT_TYPEf)) {
    524             l3mc_index = 
    525                 _BCM_MULTICAST_ID_GET(extender_port->failover_mc_group);
    526             if (l3mc_index >= 0 
    527                 && l3mc_index < soc_mem_index_count(unit, L3_IPMCm)) {
    528                 return BCM_E_NONE;
    529             } else {
    530                 return BCM_E_PARAM;
    531             }
    532         } else {
    533             failover_vp = 
    534                 BCM_GPORT_EXTENDER_PORT_ID_GET(extender_port->failover_port_id);
    535             if (failover_vp == -1) {
    536                 return BCM_E_PARAM;
    537             }
    538             if (failover_vp > 0 
    539                 && failover_vp < soc_mem_index_count(unit, SOURCE_VPm)) {
    540                 return BCM_E_NONE;
    541             } else {
    542                 return BCM_E_PARAM;
    543             }
    544         }
    545     }
    546     return BCM_E_PARAM;
    547 }
    548 
    549 
    550 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */