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 (13485B)


      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  * Saber2 failover API
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <soc/defs.h>
     13 #include <sal/core/libc.h>
     14 
     15 #if defined(BCM_SABER2_SUPPORT) &&  defined(INCLUDE_L3)
     16 
     17 #include <soc/drv.h>
     18 #include <soc/mem.h>
     19 #include <soc/util.h>
     20 #include <soc/debug.h>
     21 #include <bcm/types.h>
     22 #include <bcm/error.h>
     23 #include <bcm/failover.h>
     24 #include <bcm_int/esw_dispatch.h>
     25 #include <bcm_int/esw/katana2.h>
     26 #include <bcm_int/esw/katana.h>
     27 #include <bcm_int/common/multicast.h>
     28 #include <bcm_int/esw/failover.h>
     29 #include <bcm_int/esw/triumph2.h>
     30 #ifdef BCM_WARM_BOOT_SUPPORT
     31 #include <bcm_int/esw/switch.h>
     32 #include <soc/scache.h>
     33 #endif /* BCM_WARM_BOOT_SUPPORT */
     34 
     35 
     36 typedef struct _bcm_failover_keeper_s {
     37     int primary_nhi;
     38     int secondary_nhi;
     39 } _bcm_failover_keeper_t;
     40 STATIC _bcm_failover_keeper_t *failover_keeper[SOC_MAX_NUM_DEVICES];
     41 
     42 
     43 #ifdef BCM_WARM_BOOT_SUPPORT
     44 
     45 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
     46 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_0
     47 
     48     STATIC int
     49 _bcm_sb2_failover_wb_alloc(int unit)
     50 {
     51     soc_scache_handle_t scache_handle;
     52     uint8 *scache_ptr;
     53     int rv, alloc_size;
     54 
     55 
     56     alloc_size = 3 * sizeof(uint32) * 2 * soc_mem_index_count(unit,MMU_INITIAL_NHOP_TBLm);
     57 
     58     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_FAILOVER, 0);
     59     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, alloc_size,
     60             &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL);
     61     if (rv == BCM_E_NOT_FOUND) {
     62         rv = BCM_E_NONE;
     63     }
     64 
     65     return rv;
     66 }
     67 
     68     int
     69 bcm_sb2_failover_sync(int unit)
     70 {
     71     soc_scache_handle_t scache_handle;
     72     uint8 *scache_ptr, *ptr;
     73     uint32 index;
     74 
     75     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_FAILOVER, 0);
     76     BCM_IF_ERROR_RETURN
     77         (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0,
     78                                  &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL));
     79 
     80     ptr = scache_ptr;
     81     for (index = 0; index < (2 * soc_mem_index_count (unit, MMU_INITIAL_NHOP_TBLm));
     82             index++)
     83     {
     84         *(((uint32 *)ptr)) = failover_keeper[unit][index].primary_nhi;
     85         ptr += sizeof(uint32);
     86         *(((uint32 *)ptr)) = failover_keeper[unit][index].secondary_nhi;
     87         ptr += sizeof(uint32);
     88         if (_BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_GET(unit, index)) {
     89             *(((uint32 *)ptr)) = 0x1;
     90         } else {
     91             *(((uint32 *)ptr)) = 0x0;
     92         }
     93         ptr += sizeof(uint32);
     94     }
     95     return BCM_E_NONE; 
     96 }
     97 
     98     int
     99 bcm_sb2_failover_reinit(int unit)
    100 {
    101     soc_scache_handle_t scache_handle;
    102     uint8 *scache_ptr, *ptr;
    103     int stable_size, rv;
    104     uint16 recovered_ver;
    105     int index;
    106 
    107     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    108     if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
    109         /* COSQ warmboot requires extended scache support i.e. level2 warmboot*/
    110         return BCM_E_NONE;
    111     }
    112 
    113     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_FAILOVER, 0);
    114     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0, &scache_ptr,
    115             BCM_WB_DEFAULT_VERSION,  &recovered_ver);
    116     if (BCM_E_NOT_FOUND == rv) {
    117         /* Upgrading from SDK release that does not have warmboot state */
    118         BCM_IF_ERROR_RETURN(_bcm_sb2_failover_wb_alloc(unit));
    119         return BCM_E_NONE;
    120     } else if (BCM_FAILURE(rv)) {
    121         return rv;
    122     }
    123 
    124     ptr = scache_ptr;
    125 
    126     for (index = 0; index < (2 * soc_mem_index_count (unit, MMU_INITIAL_NHOP_TBLm));
    127             index++) {
    128         failover_keeper[unit][index].primary_nhi = *(((uint32 *)ptr));
    129         ptr += sizeof(uint32);
    130         failover_keeper[unit][index].secondary_nhi = *(((uint32 *)ptr));
    131         ptr += sizeof(uint32);
    132         if (*(((uint32 *)ptr)) == 1) {
    133             _BCM_FAILOVER_MMU_PROT_GROUP_MAP_USED_SET(unit, index);
    134         }
    135         ptr += sizeof(uint32);
    136     }
    137     return BCM_E_NONE; 
    138 }
    139 #endif 
    140 
    141 int
    142 bcm_sb2_failover_init(int unit)
    143 {
    144     int index;
    145     if (failover_keeper[unit] == NULL) {
    146         failover_keeper[unit] =
    147             sal_alloc((sizeof(_bcm_failover_keeper_t) * 
    148                         2 * soc_mem_index_count(unit,MMU_INITIAL_NHOP_TBLm )), 
    149                     "failover_keeper");
    150     }
    151     for (index = 0; index < (2 * soc_mem_index_count(unit,MMU_INITIAL_NHOP_TBLm ));
    152             index++) { 
    153         failover_keeper[unit][index].primary_nhi = -1;
    154         failover_keeper[unit][index].secondary_nhi = -1;
    155     }
    156 #ifdef BCM_WARM_BOOT_SUPPORT
    157     if (SOC_WARM_BOOT(unit)) {
    158         return bcm_sb2_failover_reinit(unit);
    159     } else {
    160         BCM_IF_ERROR_RETURN(_bcm_sb2_failover_wb_alloc(unit));
    161     }
    162 #endif /* BCM_WARM_BOOT_SUPPORT */
    163 
    164 
    165     return BCM_E_NONE;
    166 }
    167 
    168 int
    169 bcm_sb2_failover_cleanup(int unit)
    170 {
    171     if (failover_keeper[unit]) {
    172         sal_free(failover_keeper[unit]);
    173         failover_keeper[unit] = NULL;
    174      }
    175  
    176     return BCM_E_NONE;
    177 
    178 }
    179 
    180 int
    181 bcm_sb2_failover_destroy(int unit, int failover_id) 
    182 {
    183     mmu_initial_nhop_tbl_entry_t  mmu_prot_nhi_entry;
    184     soc_field_t field[4] =
    185     {
    186         PROT_DROP_STATUS0f,
    187         PROT_DROP_STATUS1f,
    188         PROT_DROP_STATUS2f,
    189         PROT_DROP_STATUS3f
    190     };
    191     if (failover_keeper[unit][failover_id].primary_nhi != -1) {
    192 
    193         BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    194                     MEM_BLOCK_ANY, 
    195                     failover_keeper[unit][failover_id].primary_nhi / 4,
    196                     &mmu_prot_nhi_entry));
    197 
    198         soc_mem_field32_set(unit, MMU_INITIAL_NHOP_TBLm,
    199                 &mmu_prot_nhi_entry,
    200                 field[failover_keeper[unit][failover_id].primary_nhi % 4] , 0);
    201 
    202         BCM_IF_ERROR_RETURN (soc_mem_write(unit, MMU_INITIAL_NHOP_TBLm,
    203                     MEM_BLOCK_ALL, failover_keeper[unit][failover_id].primary_nhi / 4 ,
    204                     &mmu_prot_nhi_entry));
    205 
    206         BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    207                     MEM_BLOCK_ANY, 
    208                     failover_keeper[unit][failover_id].secondary_nhi / 4,
    209                     &mmu_prot_nhi_entry));
    210 
    211         soc_mem_field32_set(unit, MMU_INITIAL_NHOP_TBLm,
    212                 &mmu_prot_nhi_entry,
    213                 field[failover_keeper[unit][failover_id].secondary_nhi % 4] , 0);
    214 
    215         BCM_IF_ERROR_RETURN (soc_mem_write(unit, MMU_INITIAL_NHOP_TBLm,
    216                     MEM_BLOCK_ALL, failover_keeper[unit][failover_id].secondary_nhi / 4 ,
    217                     &mmu_prot_nhi_entry));
    218 
    219         failover_keeper[unit][failover_id].primary_nhi = -1;
    220         failover_keeper[unit][failover_id].secondary_nhi = -1;
    221     }
    222     return BCM_E_NONE;
    223 }
    224 /*
    225  * Function:
    226  *		bcm_sb2_failover_prot_nhi_set
    227  * Purpose:
    228  *		Set the parameters for PROT_NHI
    229  * Parameters:
    230  *		IN :  unit
    231  *           IN :  Primary Next Hop Index
    232  *           IN :  Protection Next Hop Index
    233  *           IN :  Failover Group Index
    234  * Returns:
    235  *		BCM_E_XXX
    236  */
    237 
    238 int
    239 bcm_sb2_failover_prot_nhi_set(int unit, uint32 flags, int nh_index, uint32 prot_nh_index, 
    240                                            bcm_multicast_t  mc_group, bcm_failover_t failover_id)
    241 {
    242     _BCM_GET_FAILOVER_ID(failover_id);
    243     if (failover_keeper[unit][failover_id].primary_nhi != -1) {
    244         return BCM_E_PARAM;
    245     }
    246     failover_keeper[unit][failover_id].primary_nhi = nh_index;
    247     failover_keeper[unit][failover_id].secondary_nhi = prot_nh_index;
    248 
    249     return BCM_E_NONE;
    250 
    251 }
    252 
    253 
    254 /*
    255  * Function: bcm_sb2_failover_prot_nhi_get
    256  * Purpose:
    257  *		Get the parameters for PROT_NHI
    258  * Parameters:
    259  *		IN :  unit
    260  *           IN :  primary Next Hop Index
    261  *           OUT :  Failover Group Index
    262  *           OUT : Protection Next Hop Index
    263  * Returns:
    264  *		BCM_E_XXX
    265  */
    266 
    267 
    268 int
    269 bcm_sb2_failover_prot_nhi_get(int unit, int nh_index, 
    270             bcm_failover_t  *failover_id, int  *prot_nh_index, bcm_multicast_t  *mc_group)
    271 {
    272 
    273     _BCM_GET_FAILOVER_ID(*failover_id);
    274 
    275     *prot_nh_index = failover_keeper[unit][*failover_id].secondary_nhi;
    276 
    277     return BCM_E_NONE;
    278 
    279 }
    280 
    281 
    282 /*
    283  * Function:
    284  *        bcm_sb2_failover_status_set
    285  * Purpose:
    286  *        Set the parameters for a failover object
    287  * Parameters:
    288  *        IN :  unit
    289  *           IN :  failover_id
    290  *           IN :  value
    291  * Returns:
    292  *        BCM_E_XXX
    293  */
    294 
    295 int
    296 bcm_sb2_failover_status_set(int unit,
    297                                      bcm_failover_element_t *failover,
    298                                      int value)
    299 {
    300     int rv = BCM_E_UNAVAIL;
    301     mmu_initial_nhop_tbl_entry_t  mmu_prot_nhi_entry;
    302     soc_field_t field[4] =
    303     {
    304         PROT_DROP_STATUS0f,
    305         PROT_DROP_STATUS1f,
    306         PROT_DROP_STATUS2f,
    307         PROT_DROP_STATUS3f
    308     };
    309 
    310     if ((value < 0) || (value > 1)) {
    311        return BCM_E_PARAM;
    312     }
    313     _BCM_GET_FAILOVER_ID(failover->failover_id);
    314     if ((failover_keeper[unit][failover->failover_id].secondary_nhi == -1) ||
    315         (failover_keeper[unit][failover->failover_id].primary_nhi == -1)) {
    316        return BCM_E_INTERNAL;
    317     }
    318     if (failover->failover_id != BCM_FAILOVER_INVALID) {
    319          /* Group protection for Port and Tunnel: Egress and Ingress */
    320          BCM_IF_ERROR_RETURN(
    321               bcm_tr2_failover_mmu_id_validate ( unit, failover->failover_id ));
    322 
    323          if (value) {
    324              BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    325                          MEM_BLOCK_ANY, 
    326                          failover_keeper[unit][failover->failover_id].secondary_nhi / 4,
    327                          &mmu_prot_nhi_entry));
    328 
    329              soc_mem_field32_set(unit, MMU_INITIAL_NHOP_TBLm,
    330                      &mmu_prot_nhi_entry,
    331                      field[failover_keeper[unit][failover->failover_id].secondary_nhi % 4] , 0);
    332 
    333              rv = soc_mem_write(unit, MMU_INITIAL_NHOP_TBLm,
    334                      MEM_BLOCK_ALL, failover_keeper[unit][failover->failover_id].secondary_nhi / 4 ,
    335                      &mmu_prot_nhi_entry);
    336 
    337              BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    338                          MEM_BLOCK_ANY, 
    339                          failover_keeper[unit][failover->failover_id].primary_nhi / 4,
    340                          &mmu_prot_nhi_entry));
    341 
    342              soc_mem_field32_set(unit, MMU_INITIAL_NHOP_TBLm,
    343                      &mmu_prot_nhi_entry,
    344                      field[failover_keeper[unit][failover->failover_id].primary_nhi % 4] , 1);
    345 
    346              rv = soc_mem_write(unit, MMU_INITIAL_NHOP_TBLm,
    347                      MEM_BLOCK_ALL, failover_keeper[unit][failover->failover_id].primary_nhi / 4 ,
    348                      &mmu_prot_nhi_entry);
    349          } else {
    350              BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    351                          MEM_BLOCK_ANY, 
    352                          failover_keeper[unit][failover->failover_id].primary_nhi / 4,
    353                          &mmu_prot_nhi_entry));
    354 
    355              soc_mem_field32_set(unit, MMU_INITIAL_NHOP_TBLm,
    356                      &mmu_prot_nhi_entry,
    357                      field[failover_keeper[unit][failover->failover_id].primary_nhi % 4] , 0);
    358 
    359              rv = soc_mem_write(unit, MMU_INITIAL_NHOP_TBLm,
    360                      MEM_BLOCK_ALL, failover_keeper[unit][failover->failover_id].primary_nhi / 4 ,
    361                      &mmu_prot_nhi_entry);
    362 
    363              BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    364                          MEM_BLOCK_ANY, 
    365                          failover_keeper[unit][failover->failover_id].secondary_nhi / 4,
    366                          &mmu_prot_nhi_entry));
    367 
    368              soc_mem_field32_set(unit, MMU_INITIAL_NHOP_TBLm,
    369                      &mmu_prot_nhi_entry,
    370                      field[failover_keeper[unit][failover->failover_id].secondary_nhi % 4] , 1);
    371 
    372              rv = soc_mem_write(unit, MMU_INITIAL_NHOP_TBLm,
    373                      MEM_BLOCK_ALL, failover_keeper[unit][failover->failover_id].secondary_nhi / 4 ,
    374                      &mmu_prot_nhi_entry);
    375 
    376          }
    377     } else {
    378        return BCM_E_PARAM;
    379     } 
    380     return rv;
    381 }
    382 
    383 
    384 /*
    385  * Function:
    386  *        bcm_sb2_failover_status_get
    387  * Purpose:
    388  *        Get the parameters for a failover object
    389  * Parameters:
    390  *        IN :  unit
    391  *           IN :  failover_id
    392  *           OUT :  value
    393  * Returns:
    394  *        BCM_E_XXX
    395  */
    396 
    397 int
    398 bcm_sb2_failover_status_get(int unit,
    399                                      bcm_failover_element_t *failover,
    400                                      int  *value)
    401 {
    402     mmu_initial_nhop_tbl_entry_t   prot_nhi_entry;
    403     soc_field_t field[4] =
    404     {
    405         PROT_DROP_STATUS0f,
    406         PROT_DROP_STATUS1f,
    407         PROT_DROP_STATUS2f,
    408         PROT_DROP_STATUS3f
    409     };
    410 
    411     _BCM_GET_FAILOVER_ID(failover->failover_id);
    412     if (failover->failover_id != BCM_FAILOVER_INVALID) {
    413 
    414          BCM_IF_ERROR_RETURN(
    415             bcm_tr2_failover_mmu_id_validate ( unit, failover->failover_id ));
    416 
    417          BCM_IF_ERROR_RETURN (soc_mem_read(unit, MMU_INITIAL_NHOP_TBLm,
    418                      MEM_BLOCK_ANY, 
    419                      failover_keeper[unit][failover->failover_id].secondary_nhi / 4,
    420                      &prot_nhi_entry));
    421 
    422          *value =   soc_mem_field32_get(unit, MMU_INITIAL_NHOP_TBLm,
    423                  &prot_nhi_entry, 
    424                  field[failover_keeper[unit][failover->failover_id].secondary_nhi % 4]);
    425          *value = *value ? 0 : 1 ;
    426     } else {
    427         return BCM_E_PARAM;
    428     }
    429     return BCM_E_NONE;
    430 }
    431 
    432 #endif /* defined(BCM_SABER2_SUPPORT) &&  defined(INCLUDE_L3) */