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

ser.c (307610B)


      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  * SER common code.
      8  *
      9  * Common code for memory SER protection.
     10  */
     11 
     12 #include <shared/bsl.h>
     13 
     14 #include <sal/core/libc.h>
     15 #include <sal/core/dpc.h>
     16 #include <soc/drv.h>
     17 #include <soc/debug.h>
     18 #include <soc/util.h>
     19 #include <soc/mem.h>
     20 #include <soc/l2x.h>
     21 #include <soc/l2u.h>
     22 #include <soc/l3x.h>
     23 #include <soc/dma.h>
     24 #include <soc/soc_ser_log.h>
     25 #include <soc/iproc.h>
     26 #ifdef BCM_CMICM_SUPPORT
     27 #include <soc/cmicm.h>
     28 #endif
     29 #ifdef BCM_CMICX_SUPPORT
     30 #include <soc/intr_cmicx.h>
     31 #endif
     32 #ifdef BCM_TSN_SUPPORT
     33 #include <bcm_int/esw/tsn_stat.h>
     34 #endif /* BCM_TSN_SUPPORT */
     35 
     36 #if defined(BCM_TRIUMPH2_SUPPORT)
     37 #include <soc/triumph2.h>
     38 #include <soc/triumph.h>
     39 #endif /* BCM_TRIUMPH2_SUPPORT */
     40 #if defined(BCM_TRIDENT_SUPPORT)
     41 #include <soc/trident.h>
     42 #endif /* BCM_TRIDENT_SUPPORT */
     43 #if defined(BCM_TRIDENT2_SUPPORT)
     44 #include <soc/trident2.h>
     45 #endif /* BCM_TRIDENT2_SUPPORT */
     46 #if defined(BCM_TRIUMPH3_SUPPORT)
     47 #include <soc/triumph3.h>
     48 #endif /* BCM_TRIUMPH3_SUPPORT */
     49 #if defined(BCM_HELIX4_SUPPORT)
     50 #include <soc/helix4.h>
     51 #endif /* BCM_HELIX4_SUPPORT */
     52 #if defined(BCM_KATANA_SUPPORT)
     53 #include <soc/katana.h>
     54 #endif /* BCM_KATANA_SUPPORT */
     55 #if defined(BCM_KATANA2_SUPPORT)
     56 #include <soc/katana2.h>
     57 #endif /* BCM_KATANA2_SUPPORT */
     58 #if defined(BCM_ENDURO_SUPPORT)
     59 #include <soc/enduro.h>
     60 #endif /* BCM_ENDURO_SUPPORT */
     61 #if defined(BCM_HURRICANE2_SUPPORT)
     62 #include <soc/hurricane2.h>
     63 #endif /* BCM_HURRICANE2_SUPPORT */
     64 #if defined(BCM_GREYHOUND_SUPPORT)
     65 #include <soc/greyhound.h>
     66 #endif /* BCM_GREYHOUND_SUPPORT */
     67 #if defined(BCM_TOMAHAWK_SUPPORT)
     68 #include <soc/tomahawk.h>
     69 #endif /* BCM_TOMAHAWK_SUPPORT */
     70 #if defined(BCM_TOMAHAWK2_SUPPORT)
     71 #include <soc/tomahawk2.h>
     72 #endif /* BCM_TOMAHAWK2_SUPPORT */
     73 #if defined(BCM_TOMAHAWK3_SUPPORT)
     74 #include <soc/tomahawk3.h>
     75 #endif
     76 #if defined(BCM_HURRICANE3_SUPPORT)
     77 #include <soc/hurricane3.h>
     78 #endif /* BCM_HURRICANE3_SUPPORT */
     79 #if defined(BCM_GREYHOUND2_SUPPORT)
     80 #include <soc/greyhound2.h>
     81 #endif /* BCM_GREYHOUND2_SUPPORT */
     82 #if defined(BCM_APACHE_SUPPORT)
     83 #include <soc/apache.h>
     84 #endif /* BCM_APACHE_SUPPORT */
     85 #if defined(BCM_MONTEREY_SUPPORT)
     86 #include <soc/monterey.h>
     87 #endif /* BCM_MONTEREY_SUPPORT */
     88 #if defined(BCM_TRIDENT3_SUPPORT)
     89 #include <soc/trident3.h>
     90 #endif
     91 #if defined(BCM_HELIX5_SUPPORT)
     92 #include <soc/helix5.h>
     93 #endif
     94 #if defined(BCM_MAVERICK2_SUPPORT)
     95 #include <soc/maverick2.h>
     96 #endif
     97 
     98 #if defined(BCM_XGS_SUPPORT)
     99 
    100 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT
    101 #include <soc/esw/ecmp.h>
    102 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */
    103 
    104 #define _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, field) \
    105     if (SOC_MEM_FIELD_VALID(unit, mem, field)) {          \
    106         soc_mem_field32_set(unit, mem, entry, field, 0);  \
    107     }
    108 
    109 #define _SOC_DRV_MEM_CHK_L2_MEM(mem) \
    110         (mem == L2Xm || mem == L2_ENTRY_1m || mem == L2_ENTRY_2m)
    111 
    112 /* Keep this size in sync with the items in the 2 lists below */
    113 #define SOC_SER_REG_CACHE_MAX 30
    114 
    115 #define _SOC_SER_CACHE_REG_CASES        \
    116     case DMVOQ_WRED_CONFIGr:            \
    117     case GLOBAL_SP_WRED_CONFIGr:        \
    118     case MAXBUCKETCONFIG_64r:           \
    119     case MINBUCKETCONFIG_64r:           \
    120     case PG_RESET_FLOOR_CELLr:          \
    121     case PG_RESET_OFFSET_CELLr:         \
    122     case PORT_SHARED_LIMIT_CELLr:       \
    123     case PORT_SP_WRED_CONFIGr:          \
    124     case S2_MAXBUCKETCONFIG_64r:        \
    125     case S2_MINBUCKETCONFIG_64r:        \
    126     case S3_MAXBUCKETCONFIG_64r:        \
    127     case S3_MINBUCKETCONFIG_64r:        \
    128     case S2_COSWEIGHTSr:                \
    129     case S3_COSWEIGHTSr:                \
    130     case WRED_CONFIGr:                  \
    131     case ING_TRILL_ADJACENCYr:          \
    132     case EGR_VLAN_CONTROL_2r:           \
    133     case EGR_PVLAN_EPORT_CONTROLr:      \
    134     case E2EFC_CNT_SET_LIMITr:          \
    135     case E2EFC_CNT_RESET_LIMITr:        \
    136     case E2EFC_CNT_DISC_LIMITr:         \
    137     case CPUMAXBUCKETCONFIG_64r:        \
    138     case EGR_1588_LINK_DELAY_64r:       \
    139     case STORM_CONTROL_METER_CONFIGr:   \
    140     case EGR_SF_SRC_MODID_CHECKr:       \
    141     case EGR_VLAN_CONTROL_3r:           \
    142     case SFLOW_ING_THRESHOLDr:          \
    143     case PG_SHARED_LIMIT_CELLr:         \
    144     case EGR_VLAN_CONTROL_1r:           \
    145     case EGR_IPMC_CFG2r:                \
    146 
    147 
    148 #define _SOC_TH_ACC_TYPE_FOR_PIPE(pipe) \
    149     (((pipe) == 0)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 : \
    150      ((pipe) == 1)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 : \
    151      ((pipe) == 2)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_2 : \
    152      ((pipe) == 3)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_3 : \
    153      ((pipe) == 4)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_4 : \
    154      ((pipe) == 5)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_5 : \
    155      ((pipe) == 6)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_6 : \
    156                     _SOC_MEM_ADDR_ACC_TYPE_PIPE_7)
    157 #if defined(BCM_TOMAHAWK_SUPPORT)
    158 #define _SOC_TH_ACC_TYPE_DUPLICATE 9
    159 #define _SOC_TH_ACC_TYPE_DUPLICATE_2 15
    160 #define _SOC_TH_ACC_TYPE_DUPLICATE_4 16
    161 #endif /* BCM_TOMAHAWK_SUPPORT */
    162 
    163 #if defined(ALPM_ENABLE)
    164 #define _ALPM_LOCK(unit) \
    165     L3_LOCK(unit); \
    166     _alpm_lock = 1
    167 #define _ALPM_UNLOCK(unit) \
    168     if (_alpm_lock) { \
    169         L3_UNLOCK(unit); \
    170     }
    171 #else
    172 #define _ALPM_LOCK(unit)
    173 #define _ALPM_UNLOCK(unit)
    174 #endif /* ALPM_ENABLE */
    175 
    176 
    177 #define _L2_LOCK(unit) \
    178     MEM_LOCK(unit, L2Xm);
    179 
    180 #define _L2_UNLOCK(unit, lock) \
    181     if ((lock)) { \
    182         MEM_UNLOCK(unit, L2Xm); \
    183     }
    184 
    185 #define _SOC_SER_NUM_EM_ENTRIES_PER_LP_ENTRY 4
    186 
    187 #define _SOC_FPEM_EM2(pipe, mem_mode) \
    188     ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_2m \
    189                   : ((pipe == 1)? EXACT_MATCH_2_PIPE1m : \
    190                      (pipe == 2)? EXACT_MATCH_2_PIPE2m : \
    191                      (pipe == 3)? EXACT_MATCH_2_PIPE3m : \
    192                                   EXACT_MATCH_2_PIPE0m))
    193 
    194 #define _SOC_FPEM_EM4(pipe, mem_mode) \
    195     ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_4m \
    196                   : ((pipe == 1)? EXACT_MATCH_4_PIPE1m : \
    197                      (pipe == 2)? EXACT_MATCH_4_PIPE2m : \
    198                      (pipe == 3)? EXACT_MATCH_4_PIPE3m : \
    199                                   EXACT_MATCH_4_PIPE0m))
    200 
    201 #define _SOC_FPEM_EM2_ENTRY_ONLY(pipe, mem_mode) \
    202     ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_2_ENTRY_ONLYm \
    203                   : ((pipe == 1)? EXACT_MATCH_2_ENTRY_ONLY_PIPE1m : \
    204                      (pipe == 2)? EXACT_MATCH_2_ENTRY_ONLY_PIPE2m : \
    205                      (pipe == 3)? EXACT_MATCH_2_ENTRY_ONLY_PIPE3m : \
    206                                   EXACT_MATCH_2_ENTRY_ONLY_PIPE0m))
    207 
    208 #define _SOC_FPEM_EM4_ENTRY_ONLY(pipe, mem_mode) \
    209     ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_4_ENTRY_ONLYm \
    210                   : ((pipe == 1)? EXACT_MATCH_4_ENTRY_ONLY_PIPE1m : \
    211                      (pipe == 2)? EXACT_MATCH_4_ENTRY_ONLY_PIPE2m : \
    212                      (pipe == 3)? EXACT_MATCH_4_ENTRY_ONLY_PIPE3m : \
    213                                   EXACT_MATCH_4_ENTRY_ONLY_PIPE0m))
    214 
    215 #define _SOC_FPEM_ECC(pipe, mem_mode) \
    216     ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? FPEM_ECCm \
    217                   : ((pipe == 1)? FPEM_ECC_PIPE1m : \
    218                      (pipe == 2)? FPEM_ECC_PIPE2m : \
    219                      (pipe == 3)? FPEM_ECC_PIPE3m : \
    220                                   FPEM_ECC_PIPE0m))
    221 
    222 #define _SOC_EXACT_MATCH_ECC(pipe, mem_mode) \
    223     ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_ECCm \
    224                   : ((pipe == 1)? EXACT_MATCH_ECC_PIPE1m : \
    225                                   EXACT_MATCH_ECC_PIPE0m))
    226 
    227 #define _SOC_MEM_CHK_FPEM_MEM(mem) \
    228         (mem == EXACT_MATCH_2m || \
    229          mem == EXACT_MATCH_2_PIPE0m || mem == EXACT_MATCH_2_PIPE1m || \
    230          mem == EXACT_MATCH_2_PIPE2m || mem == EXACT_MATCH_2_PIPE3m || \
    231          mem == EXACT_MATCH_4m || \
    232          mem == EXACT_MATCH_4_PIPE0m || mem == EXACT_MATCH_4_PIPE1m || \
    233          mem == EXACT_MATCH_4_PIPE2m || mem == EXACT_MATCH_4_PIPE3m)
    234 
    235 static int _soc_ser_reg_cache_list[SOC_SER_REG_CACHE_MAX] = {
    236     DMVOQ_WRED_CONFIGr,             /* 1 */
    237     GLOBAL_SP_WRED_CONFIGr,         /* 2 */
    238     MAXBUCKETCONFIG_64r,            /* 3 */
    239     MINBUCKETCONFIG_64r,            /* 4 */
    240     PG_RESET_FLOOR_CELLr,           /* 5 */
    241     PG_RESET_OFFSET_CELLr,          /* 6 */
    242     PORT_SHARED_LIMIT_CELLr,        /* 7 */
    243     PORT_SP_WRED_CONFIGr,           /* 8 */
    244     S2_MAXBUCKETCONFIG_64r,         /* 9 */
    245     S2_MINBUCKETCONFIG_64r,         /* 10 */
    246     S3_MAXBUCKETCONFIG_64r,         /* 11 */
    247     S3_MINBUCKETCONFIG_64r,         /* 12 */
    248     S2_COSWEIGHTSr,                 /* 13 */
    249     S3_COSWEIGHTSr,                 /* 14 */
    250     WRED_CONFIGr,                   /* 15 */
    251     ING_TRILL_ADJACENCYr,           /* 16 */
    252     EGR_VLAN_CONTROL_2r,            /* 17 */
    253     EGR_PVLAN_EPORT_CONTROLr,       /* 18 */
    254     E2EFC_CNT_SET_LIMITr,           /* 19 */
    255     E2EFC_CNT_RESET_LIMITr,         /* 20 */
    256     E2EFC_CNT_DISC_LIMITr,          /* 21 */
    257     CPUMAXBUCKETCONFIG_64r,         /* 22 */
    258     EGR_1588_LINK_DELAY_64r,        /* 23 */
    259     STORM_CONTROL_METER_CONFIGr,    /* 24 */
    260     EGR_SF_SRC_MODID_CHECKr,        /* 25 */
    261     EGR_VLAN_CONTROL_3r,            /* 26 */
    262     SFLOW_ING_THRESHOLDr,           /* 27 */
    263     PG_SHARED_LIMIT_CELLr,          /* 28 */
    264     EGR_VLAN_CONTROL_1r,            /* 29 */
    265     EGR_IPMC_CFG2r                  /* 30 */
    266 };
    267 
    268 #define _SOC_SER_CLEAR_REG_CASES    \
    269     case GLOBAL_SP_WRED_AVG_QSIZEr: \
    270     case PORT_SP_WRED_AVG_QSIZEr:   \
    271     case WRED_AVG_QSIZEr:           \
    272     case VOQ_WRED_AVG_QSIZEr:       \
    273     case EGR_FCOE_DELIMITER_ERROR_FRAMESr:          \
    274     case EGR_FCOE_INVALID_CRC_FRAMESr:              \
    275     case EGR_FCOE_DELIMITER_ERROR_FRAMES_64r:       \
    276     case EGR_FCOE_DELIMITER_ERROR_FRAMES_64_PIPE0r: \
    277     case EGR_FCOE_DELIMITER_ERROR_FRAMES_64_PIPE1r: \
    278     case EGR_FCOE_INVALID_CRC_FRAMES_64r:           \
    279     case EGR_FCOE_INVALID_CRC_FRAMES_64_PIPE0r:     \
    280     case EGR_FCOE_INVALID_CRC_FRAMES_64_PIPE1r:     \
    281     case MINBUCKETr:                \
    282     case MAXBUCKETr:                \
    283     case S3_MINBUCKETr:             \
    284     case S3_MAXBUCKETr:             \
    285     case S2_MINBUCKETr:             \
    286     case S2_MAXBUCKETr:             \
    287     case S3_WERRCOUNTr:             \
    288     case S2_WERRCOUNTr:             \
    289     case CPUMAXBUCKETr:             \
    290     case HG_PKT_SIGNATURE_1r:       \
    291     case HG_PKT_SIGNATURE_2r:       \
    292     case HG_PKT_SIGNATURE_3r:
    293 
    294 #define _SOC_MAX_PORTS_NUMS    170 
    295 #define _SOC_SER_REG_INDEX_MAX  79 
    296 
    297 typedef struct _soc_ser_reg_cache_s {
    298     uint64 data[_SOC_MAX_PORTS_NUMS][_SOC_SER_REG_INDEX_MAX];
    299 } _soc_ser_reg_cache_t;
    300 typedef struct _soc_ser_reg_cache_array_s {
    301      _soc_ser_reg_cache_t reg_cache[SOC_SER_REG_CACHE_MAX];
    302 } _soc_ser_reg_cache_array_t;
    303 _soc_ser_reg_cache_array_t *_soc_ser_reg_cache[SOC_MAX_NUM_DEVICES] = {NULL};
    304 
    305 typedef struct mem_ser_info {
    306     uint32    next_idx;
    307     soc_mem_t ser_mem;
    308     uint32    hw_idx;
    309     uint32    entry_data[SOC_MAX_MEM_WORDS];
    310 } mem_ser_info_t;
    311 
    312 typedef struct _mem_ser_info_head_t {
    313     mem_ser_info_t   *base_addr;
    314     uint32            head_idx;
    315     uint32            tail_idx;
    316     int               counter;
    317 } mem_ser_info_head_t;
    318 
    319 typedef struct soc_ser_alpm_cache_flag_s {
    320     uint32      flag_defip;
    321     uint32      flag_defip_128;
    322     uint32      flag_defip_alpm_v4;
    323     uint32      flag_defip_alpm_v4_1;
    324     uint32      flag_defip_alpm_v6;
    325     uint32      flag_defip_alpm_v6_1;
    326     uint32      flag_defip_alpm_v6_128;
    327     uint32      flag_defip_aux;
    328 } soc_ser_alpm_cache_flag_t;
    329 
    330 static mem_ser_info_head_t mem_ser_info_head[SOC_MAX_NUM_DEVICES];
    331 
    332 #define SER_MEM_INFO_MAX_NUM     32
    333 #define SER_MEM_INFO_BASE_ADDR(unit)     mem_ser_info_head[unit].base_addr
    334 #define SER_MEM_INFO_HEAD_IDX(unit)      mem_ser_info_head[unit].head_idx
    335 #define SER_MEM_INFO_TAIL_IDX(unit)      mem_ser_info_head[unit].tail_idx
    336 #define SER_MEM_INFO_COUNTER(unit)       mem_ser_info_head[unit].counter
    337 #define SER_MEM_INFO_NEXT_IDX(unit, cur_idx)      mem_ser_info_head[unit].base_addr[cur_idx].next_idx
    338 
    339 static soc_ser_functions_t *_soc_ser_functions[SOC_MAX_NUM_DEVICES];
    340 static soc_oam_event_functions_t *_soc_oam_event_functions[SOC_MAX_NUM_DEVICES];
    341 static soc_ser_alpm_cache_flag_t alpm_no_cache_flag[SOC_MAX_NUM_DEVICES];
    342 #ifdef BCM_TSN_SUPPORT
    343 static soc_ser_tsn_stat_functions_t *soc_ser_tsn_stat_functions[SOC_MAX_NUM_DEVICES];
    344 #endif /* BCM_TSN_SUPPORT */
    345 #if defined(INCLUDE_FLOWTRACKER)
    346 STATIC int  _soc_ft_em_ser_correction(int unit, int pipe, soc_mem_t mem, int index);
    347 #endif /* BCM_TOMAHAWK_SUPPORT */
    348 
    349 /* scrub_load: 0=scrub, 1=load cache */
    350 int soc_ser_reg_load_scrub(int unit, int scrub_load)
    351 {
    352     uint64 rval64;
    353     soc_reg_t reg;
    354     int r, i, blk, port, mindex;
    355     soc_block_types_t regblktype;
    356 
    357     /* Access all cacheable regs (store in cache if requested) */
    358     for (r = 0; r < SOC_SER_REG_CACHE_MAX; r++) {
    359         reg = _soc_ser_reg_cache_list[r];
    360         if (!SOC_REG_IS_VALID(unit, reg)) {
    361             continue;
    362         }
    363         if (SOC_REG_INFO(unit, reg).regtype == soc_genreg) {
    364             SOC_IF_ERROR_RETURN
    365                 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
    366             if (scrub_load) {
    367                 soc_ser_reg_cache_set(unit, reg, 0, 0, rval64);
    368             }
    369             LOG_VERBOSE(BSL_LS_SOC_SER,
    370                         (BSL_META_U(unit,
    371                                     "Reg: %s port:%d index:%d\n"), SOC_REG_NAME(unit, reg), 0, 0));
    372         } else if (SOC_REG_INFO(unit, reg).regtype == soc_cosreg) {
    373             regblktype = SOC_REG_INFO(unit, reg).block;
    374             for (i = 0; i < NUM_COS(unit); i++) {
    375                 SOC_BLOCKS_ITER(unit, blk, regblktype) {
    376                     port = SOC_BLOCK_PORT(unit, blk);
    377                     SOC_IF_ERROR_RETURN
    378                         (soc_reg_get(unit, reg, port, i, &rval64));
    379                     if (scrub_load) {
    380                         soc_ser_reg_cache_set(unit, reg, port, i, rval64);
    381                     }
    382                     LOG_VERBOSE(BSL_LS_SOC_SER,
    383                                 (BSL_META_U(unit,
    384                                             "Reg: %s port:%d index:%d\n"), SOC_REG_NAME(unit, reg), port, i));
    385                 }
    386             }
    387         } else if ((SOC_REG_INFO(unit, reg).regtype == soc_portreg) ||
    388                    (SOC_REG_INFO(unit, reg).regtype == soc_ppportreg)) {
    389             mindex = 1;
    390             switch (reg) {
    391             case DMVOQ_WRED_CONFIGr:
    392             case S3_COSWEIGHTSr: mindex = 72; break;
    393             case PG_RESET_OFFSET_CELLr:
    394             case PORT_SHARED_LIMIT_CELLr:
    395             case WRED_CONFIGr: mindex = 8; break;
    396             case PORT_SP_WRED_CONFIGr:
    397             case S2_MINBUCKETCONFIG_64r:
    398             case S2_MAXBUCKETCONFIG_64r:
    399             case S3_MINBUCKETCONFIG_64r:
    400             case S3_MAXBUCKETCONFIG_64r: mindex = 4; break;
    401             case S2_COSWEIGHTSr: mindex = 12; break;
    402             default: break;
    403             }
    404             PBMP_ALL_ITER(unit, port) {
    405                 switch (reg) {
    406                 case DMVOQ_WRED_CONFIGr:
    407                     if (!SOC_INFO(unit).port_num_ext_cosq[port]) {
    408                         continue;
    409                     }
    410                     break;
    411                 case MINBUCKETCONFIG_64r:
    412                 case MINBUCKETr:
    413                 case MAXBUCKETCONFIG_64r:
    414                 case MAXBUCKETr:
    415 #ifdef BCM_ENDURO_SUPPORT
    416                     if (SOC_IS_ENDURO(unit)) {
    417                         if (IS_CPU_PORT(unit, port)) {
    418                             continue;
    419                         } else if (IS_XQ_PORT(unit, port)) {
    420                             mindex = 26;
    421                         } else {
    422                             mindex = 8;
    423                         }
    424                     } else {
    425 #endif
    426                     if (IS_CPU_PORT(unit, port)) {
    427                         mindex = 48;
    428                     } else if (IS_LB_PORT(unit, port)) {
    429                         mindex = 5;
    430                     } else if (!SOC_INFO(unit).port_num_ext_cosq[port]) {
    431                         mindex = 15;
    432                     } else {
    433                         mindex = 79;
    434                     }
    435 #ifdef BCM_TRIUMPH_SUPPORT
    436                     if (SOC_IS_TRIUMPH(unit)) {
    437                         if (IS_CPU_PORT(unit, port)) {
    438                             continue;
    439                         }
    440                     }
    441 #endif
    442 #ifdef BCM_ENDURO_SUPPORT
    443                     }
    444 #endif
    445                     break;
    446                 case PORT_SP_WRED_CONFIGr:
    447                     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
    448                         continue;
    449                     }
    450                     break;
    451                 case S2_MINBUCKETCONFIG_64r:
    452                 case S2_MAXBUCKETCONFIG_64r:
    453                 case S3_MINBUCKETCONFIG_64r:
    454                 case S3_MAXBUCKETCONFIG_64r:
    455                 case S2_COSWEIGHTSr:
    456                     if (IS_CPU_PORT(unit, port)) {
    457                         continue;
    458                     }
    459                     break;
    460                 case S3_COSWEIGHTSr:
    461                     if (!SOC_INFO(unit).port_num_ext_cosq[port]) {
    462                         mindex = 8;
    463                     }
    464                     break;
    465                 case WRED_CONFIGr:
    466                     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
    467                         continue;
    468                     }
    469                     break;
    470                 default: break;
    471                 }
    472                 for (i = 0; i < mindex; i++) {
    473                     SOC_IF_ERROR_RETURN
    474                         (soc_reg_get(unit, reg, port, i, &rval64));
    475                     if (scrub_load) {
    476                         soc_ser_reg_cache_set(unit, reg, port, i, rval64);
    477                     }
    478                     LOG_VERBOSE(BSL_LS_SOC_SER,
    479                                 (BSL_META_U(unit,
    480                                             "Reg: %s port:%d index:%d\n"), SOC_REG_NAME(unit, reg), port, i));
    481                 }
    482             }
    483         }
    484     }
    485     return SOC_E_NONE;
    486 }
    487 
    488 int
    489 soc_ser_reg_cache_clear(int unit, soc_reg_t reg, int port)
    490 {
    491     int i;
    492 
    493     if (reg == INVALIDr) {
    494         sal_memset(&_soc_ser_reg_cache[unit]->reg_cache, 0, sizeof(_soc_ser_reg_cache_t));
    495     } else {
    496         for (i = 0; i < SOC_SER_REG_CACHE_MAX; i++) {
    497             if (reg == _soc_ser_reg_cache_list[i]) {
    498                 if (port == REG_PORT_ANY) {
    499                     sal_memset(&_soc_ser_reg_cache[unit]->reg_cache[i].data[0][0],
    500                                0, sizeof(_soc_ser_reg_cache_t));
    501                 } else {
    502                     sal_memset(&_soc_ser_reg_cache[unit]->reg_cache[i].data[port][0],
    503                                0, sizeof(_soc_ser_reg_cache_t) / _SOC_MAX_PORTS_NUMS);
    504                 }
    505                 break;
    506             }
    507         }
    508     }
    509     return SOC_E_NONE;
    510 }
    511 
    512 int
    513 soc_ser_reg_cache_init(int unit)
    514 {
    515     if (_soc_ser_reg_cache[unit] == NULL) {
    516         _soc_ser_reg_cache[unit] = sal_alloc(sizeof(_soc_ser_reg_cache_array_t), "reg-cache");
    517     }
    518     if (SOC_WARM_BOOT(unit) && (SOC_CONTROL(unit)->mem_scache_ptr == NULL)) {
    519         return soc_ser_reg_load_scrub(unit, 1);
    520     } else {
    521         return soc_ser_reg_cache_clear(unit, INVALIDr, REG_PORT_ANY);
    522     }
    523 }
    524 
    525 void
    526 soc_ser_reg_cache_info(int unit, int *count, int *size)
    527 {
    528     *count = SOC_SER_REG_CACHE_MAX;
    529     *size = sizeof(_soc_ser_reg_cache_array_t);
    530 }
    531 
    532 int
    533 soc_ser_reg_cache_set(int unit, soc_reg_t reg, int port, int index, uint64 data)
    534 {
    535     int i;
    536 
    537     if (_soc_ser_reg_cache[unit] == NULL || SOC_MEM_TEST_SKIP_CACHE(unit)) {
    538         return SOC_E_NONE;
    539     }
    540     switch (reg) {
    541     _SOC_SER_CACHE_REG_CASES
    542         break;
    543     default:
    544         return SOC_E_NONE;
    545     }
    546     assert(port < _SOC_MAX_PORTS_NUMS);
    547     assert(index < _SOC_SER_REG_INDEX_MAX);
    548     if (port >= _SOC_MAX_PORTS_NUMS) {
    549         return SOC_E_PARAM;
    550     }
    551     if (index >= _SOC_SER_REG_INDEX_MAX) {
    552         return SOC_E_PARAM;
    553     }
    554     for (i = 0; i < SOC_SER_REG_CACHE_MAX; i++) {
    555         if (reg == _soc_ser_reg_cache_list[i]) {
    556             if (port == REG_PORT_ANY) {
    557                 port = 0;
    558             }
    559             if (index < 0) {
    560                 index = 0;
    561             }
    562             LOG_VERBOSE(BSL_LS_SOC_SER,
    563                         (BSL_META_U(unit,
    564                                     "Set cache: reg:%d port:%d index:%d "
    565                                     "data:0x%x%x\n"), reg, port, index,
    566                          COMPILER_64_HI(data), COMPILER_64_LO(data)));
    567             _soc_ser_reg_cache[unit]->reg_cache[i].data[port][index] = data;
    568             break;
    569         }
    570     }
    571     return SOC_E_NONE;
    572 }
    573 
    574 int
    575 soc_ser_reg32_cache_set(int unit, soc_reg_t reg, int port, int index, uint32 data)
    576 {
    577     uint64 val;
    578 
    579     if (_soc_ser_reg_cache[unit] == NULL || SOC_MEM_TEST_SKIP_CACHE(unit)) {
    580         return SOC_E_NONE;
    581     }
    582     COMPILER_64_SET(val, 0, data);
    583     return soc_ser_reg_cache_set(unit, reg, port, index, val);
    584 }
    585 
    586 int
    587 soc_ser_reg_cache_get(int unit, soc_reg_t reg, int port, int index, uint64 *data)
    588 {
    589     int i;
    590 
    591     if (_soc_ser_reg_cache[unit] == NULL) {
    592         return SOC_E_UNAVAIL;
    593     }
    594     switch (reg) {
    595     _SOC_SER_CACHE_REG_CASES
    596         break;
    597     default:
    598         return SOC_E_UNAVAIL;
    599     }
    600     assert(port < _SOC_MAX_PORTS_NUMS);
    601     assert(index < _SOC_SER_REG_INDEX_MAX);
    602     if (port >= _SOC_MAX_PORTS_NUMS) {
    603         return SOC_E_PARAM;
    604     }
    605     if (index >= _SOC_SER_REG_INDEX_MAX) {
    606         return SOC_E_PARAM;
    607     }
    608     for (i = 0; i < SOC_SER_REG_CACHE_MAX; i++) {
    609         if (reg == _soc_ser_reg_cache_list[i]) {
    610             if (port == REG_PORT_ANY) {
    611                 port = 0;
    612             }
    613             if (index < 0) {
    614                 index = 0;
    615             }
    616             *data = _soc_ser_reg_cache[unit]->reg_cache[i].data[port][index];
    617             LOG_VERBOSE(BSL_LS_SOC_SER,
    618                         (BSL_META_U(unit,
    619                                     "Get cache: reg:%d port:%d index:%d "
    620                                     "data:0x%x%x\n"), reg, port, index,
    621                          COMPILER_64_HI(*data), COMPILER_64_LO(*data)));
    622             break;
    623         }
    624     }
    625     return SOC_E_NONE;
    626 }
    627 
    628 int
    629 soc_ser_reg32_cache_get(int unit, soc_reg_t reg, int port, int index, uint32 *data)
    630 {
    631     uint64 val;
    632 
    633     if (_soc_ser_reg_cache[unit] == NULL) {
    634         return SOC_E_UNAVAIL;
    635     }
    636     COMPILER_64_ZERO(val);
    637     SOC_IF_ERROR_RETURN(soc_ser_reg_cache_get(unit, reg, port, index, &val));
    638     *data = COMPILER_64_LO(val);
    639     return SOC_E_NONE;
    640 }
    641 
    642 int SOC_REG_IS_DYNAMIC(int unit, soc_reg_t reg)
    643 {
    644     switch (reg) {
    645     _SOC_SER_CLEAR_REG_CASES
    646         return TRUE;
    647     default: return FALSE;
    648     }
    649 }
    650 
    651 int
    652 soc_ser_reg_clear(int unit, soc_reg_t reg, int port, int index, uint64 data)
    653 {
    654     if (SOC_REG_IS_DYNAMIC(unit, reg)) {
    655         SOC_IF_ERROR_RETURN(soc_reg_set_nocache(unit, reg, port, index, data));
    656     }
    657     return SOC_E_NONE;
    658 }
    659 
    660 void
    661 soc_ser_function_register(int unit, soc_ser_functions_t *functions)
    662 {
    663     _soc_ser_functions[unit] = functions;
    664 }
    665 
    666 void
    667 soc_oam_event_function_register(int unit, soc_oam_event_functions_t *functions)
    668 {
    669     _soc_oam_event_functions[unit] = functions;
    670 }
    671 
    672 #ifdef BCM_TSN_SUPPORT
    673 int
    674 soc_ser_tsn_stat_function_register(
    675     int unit,
    676     soc_ser_tsn_stat_functions_t *functions)
    677 {
    678     soc_ser_tsn_stat_functions[unit] = functions;
    679     return SOC_E_NONE;
    680 }
    681 #endif /* BCM_TSN_SUPPORT */
    682 
    683 int
    684 soc_ser_populate_tcam_log(int unit, soc_mem_t mem, soc_acc_type_t target_pipe, int index)
    685 {
    686     if ((_soc_ser_functions[unit] != NULL) &&
    687         (_soc_ser_functions[unit]->_soc_ser_populate_tcam_log_f != NULL)) {
    688         return (*(_soc_ser_functions[unit]->_soc_ser_populate_tcam_log_f))
    689             (unit, mem, target_pipe, index);
    690     }
    691     /*Should return 0 as the invalid log id*/
    692     return 0;
    693 }
    694 
    695 int
    696 soc_ser_stat_error(int unit, int port)
    697 {
    698     int fixed = 0;
    699     soc_stat_t *stat = SOC_STAT(unit);
    700 
    701     if ((_soc_ser_functions[unit] != NULL) &&
    702         (_soc_ser_functions[unit]->_soc_ser_stat_nack_f != NULL)) {
    703         (*(_soc_ser_functions[unit]->_soc_ser_stat_nack_f))(unit, &fixed);
    704     } else {
    705         return SOC_E_UNAVAIL;
    706     }
    707 
    708     if (!fixed) {
    709         return SOC_E_INTERNAL;
    710     }
    711     stat->ser_err_stat++;
    712     return SOC_E_NONE;
    713 }
    714 
    715 int
    716 soc_process_ser_parity_error(int unit,
    717                              _soc_ser_parity_info_t *_ser_parity_info,
    718                              int parity_err_type)
    719 {
    720     int info_ix, index_min, index_max, ser_mem_count, copyno, mem_index, rv;
    721     uint32 start_addr, end_addr;
    722     uint32 fail_count, addr;
    723     uint32 pipe_acc;
    724     _soc_ser_parity_info_t *cur_spi;
    725     _soc_ser_correct_info_t spci = {0};
    726     soc_stat_t *stat = SOC_STAT(unit);
    727 
    728     /* coverity[result_independent_of_operands] */
    729     SOC_IF_ERROR_RETURN(READ_CMIC_SER_FAIL_CNTr(unit, &fail_count));
    730 
    731     if (!fail_count) {
    732         LOG_ERROR(BSL_LS_SOC_SER,
    733                   (BSL_META_U(unit,
    734                               "SER parity failure without valid count\n")));
    735     } else {
    736         /*coverity[result_independent_of_operands]*/
    737         SOC_IF_ERROR_RETURN(READ_CMIC_SER_FAIL_ENTRYr(unit, &addr));
    738 
    739         info_ix = 0;
    740         while (_ser_parity_info[info_ix].mem != INVALIDm) {
    741             cur_spi = &(_ser_parity_info[info_ix]);
    742             index_min = soc_mem_index_min(unit, cur_spi->mem);
    743             index_max = soc_mem_index_max(unit, cur_spi->mem);
    744             pipe_acc = cur_spi->ser_flags & _SOC_SER_FLAG_ACC_TYPE_MASK;
    745             ser_mem_count = index_max - index_min + 1;
    746             if (!ser_mem_count) {
    747                 info_ix++;
    748                 continue;
    749             }
    750             SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) {
    751                 break;
    752             }
    753             start_addr =
    754                 soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_min);
    755             end_addr =
    756                 soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_max);
    757 
    758             if (0 != pipe_acc) {
    759                 /* Override ACC_TYPE in addresses */
    760                 start_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK <<
    761                                 _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
    762                 start_addr |= (pipe_acc & _SOC_MEM_ADDR_ACC_TYPE_MASK) <<
    763                     _SOC_MEM_ADDR_ACC_TYPE_SHIFT;
    764 
    765                 end_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK <<
    766                                 _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
    767                 end_addr |= (pipe_acc & _SOC_MEM_ADDR_ACC_TYPE_MASK) <<
    768                     _SOC_MEM_ADDR_ACC_TYPE_SHIFT;
    769             }
    770 
    771             if ((addr >= start_addr) && (addr <= end_addr)) {
    772                 /* Addr in memory range */
    773                 mem_index = (addr - start_addr) + index_min;
    774 #ifdef BCM_KATANA_SUPPORT
    775                 if (0 != (cur_spi->ser_flags & _SOC_SER_FLAG_REMAP_READ)) {
    776                     if (SOC_IS_KATANA(unit)) {
    777                         mem_index =
    778                             soc_kt_l3_defip_index_remap(unit, cur_spi->mem,
    779                                                          mem_index);
    780                     }
    781                 }
    782 #endif /* BCM_KATANA_SUPPORT */
    783                 LOG_WARN(BSL_LS_SOC_SER,
    784                           (BSL_META_U(unit,
    785                                       "%s entry %d TCAM parity error\n"),
    786                            SOC_MEM_NAME(unit, cur_spi->mem),
    787                            mem_index));
    788                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
    789                                    parity_err_type, addr,
    790                                    0);
    791                 stat->ser_err_tcam++;
    792                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
    793                 spci.reg = INVALIDr;
    794                 spci.mem = cur_spi->mem;
    795                 spci.blk_type = copyno;
    796                 spci.index = mem_index;
    797                 spci.detect_time = sal_time_usecs();
    798                 spci.log_id = soc_ser_populate_tcam_log(unit,
    799                     spci.mem, pipe_acc, spci.index);
    800                 rv = soc_ser_correction(unit, &spci);
    801                 if (spci.log_id != 0) {
    802                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
    803                             SOC_SWITCH_EVENT_DATA_ERROR_LOG,
    804                             spci.log_id, 0);
    805                 }
    806                 if (SOC_FAILURE(rv)) {
    807                     /* Report failed to correct event flag to
    808                      * application */
    809                     soc_event_generate(unit,
    810                                 SOC_SWITCH_EVENT_PARITY_ERROR,
    811                                 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
    812                                 addr,
    813                                 0);
    814                     return rv;
    815                 }
    816                 break;
    817             }
    818             info_ix++;
    819         }
    820     }
    821     /* coverity[result_independent_of_operands] */
    822     SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_ENTRYr(unit, 0));
    823     SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_CNTr(unit, 0));
    824     return SOC_E_NONE;
    825 }
    826 
    827 int
    828 soc_process_cmicm_ser_parity_error(int unit,
    829                                    _soc_ser_parity_info_t *_ser_parity_info,
    830                                    int parity_err_type)
    831 {
    832     uint8 at, fail = 0;
    833     int info_ix, index_min, index_max, phys_index_min, phys_index_max;
    834     int ser_mem_count, copyno, mem_index, rv;
    835     uint32 start_addr, end_addr;
    836     uint32 fail_count, addr;
    837     _soc_ser_parity_info_t *cur_spi;
    838     _soc_ser_correct_info_t spci = {0};
    839     soc_stat_t *stat = SOC_STAT(unit);
    840 
    841     /* First work on ser0 */
    842     /*coverity[result_independent_of_operands]*/
    843     SOC_IF_ERROR_RETURN(READ_CMIC_SER0_FAIL_CNTr(unit, &fail_count));
    844     if (fail_count) {
    845         fail++;
    846         /*coverity[result_independent_of_operands]*/
    847         SOC_IF_ERROR_RETURN(READ_CMIC_SER0_FAIL_ENTRYr(unit, &addr));
    848         info_ix = 0;
    849         while (_ser_parity_info[info_ix].mem != INVALIDm) {
    850             cur_spi = &(_ser_parity_info[info_ix]);
    851             if (cur_spi->cmic_ser_id == 1) {
    852                 info_ix++;
    853                 continue;
    854             }
    855             phys_index_min = index_min =
    856                 soc_mem_index_min(unit, cur_spi->mem);
    857             phys_index_max = index_max =
    858                 soc_mem_index_max(unit, cur_spi->mem);
    859             if (0 != (cur_spi->ser_flags & _SOC_SER_FLAG_REMAP_READ)) {
    860 
    861                 /* Skip index map lkup if table is 0 size */
    862                 if (soc_feature(unit, soc_feature_skip_null_table_lkup)) {
    863                     if (0 == soc_mem_index_count(unit, cur_spi->mem)) {
    864                         info_ix++;
    865                         continue;
    866                     }
    867                 }
    868 #ifdef BCM_TRIUMPH3_SUPPORT
    869                 if (SOC_IS_TRIUMPH3(unit)) {
    870                     phys_index_min =
    871                         soc_tr3_l3_defip_index_map(unit,
    872                                                    cur_spi->mem,
    873                                                    index_min);
    874                     phys_index_max =
    875                         soc_tr3_l3_defip_index_map(unit,
    876                                                    cur_spi->mem,
    877                                                    index_max);
    878                 }
    879 #endif /* BCM_TRIUMPH3_SUPPORT */
    880 #ifdef BCM_KATANA2_SUPPORT
    881                 if (SOC_IS_KATANA2(unit)) {
    882                     phys_index_min =
    883                         soc_kt2_l3_defip_index_map(unit,
    884                                                    cur_spi->mem,
    885                                                    index_min);
    886                     phys_index_max =
    887                         soc_kt2_l3_defip_index_map(unit,
    888                                                    cur_spi->mem,
    889                                                    index_max);
    890                 }
    891 #endif /* BCM_KATANA2_SUPPORT */
    892             }
    893             ser_mem_count = phys_index_max - phys_index_min + 1;
    894             if (!ser_mem_count) {
    895                 info_ix++;
    896                 continue;
    897             }
    898             SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) {
    899                 break;
    900             }
    901             start_addr =
    902                 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno,
    903                                  phys_index_min, &at);
    904             end_addr =
    905                 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno,
    906                                  phys_index_max, &at);
    907             LOG_VERBOSE(BSL_LS_SOC_SER,
    908                         (BSL_META_U(unit,
    909                                     "Mem: %s addr: %x start: %x end: %x\n"),
    910                          SOC_MEM_NAME(unit, cur_spi->mem), addr,
    911                          start_addr, end_addr));
    912 
    913             if ((addr >= start_addr) && (addr <= end_addr)) {
    914                 /* Addr in memory range */
    915                 mem_index = (addr - start_addr) + phys_index_min;
    916                 if (0 != (cur_spi->ser_flags & _SOC_SER_FLAG_REMAP_READ)) {
    917                     /* Now, mem_index is the physical index.
    918                      * The correction routines expect the logical index.
    919                      * Reverse the mapping.
    920                      */
    921 #ifdef BCM_TRIUMPH3_SUPPORT
    922                     if (SOC_IS_TRIUMPH3(unit)) {
    923                         mem_index =
    924                             soc_tr3_l3_defip_index_remap(unit, cur_spi->mem,
    925                                                          mem_index);
    926                     }
    927 #endif /* BCM_TRIUMPH3_SUPPORT */
    928 #ifdef BCM_KATANA2_SUPPORT
    929                     if (SOC_IS_KATANA2(unit)) {
    930                         mem_index =
    931                             soc_kt2_l3_defip_index_remap(unit, cur_spi->mem,
    932                                                          mem_index);
    933                     }
    934 #endif /* BCM_KATANA2_SUPPORT */
    935                 }
    936                 LOG_WARN(BSL_LS_SOC_SER,
    937                           (BSL_META_U(unit,
    938                                       "ser0 %s entry %d TCAM parity error\n"),
    939                            SOC_MEM_NAME(unit, cur_spi->mem),
    940                            mem_index));
    941                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
    942                                    SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
    943                                    cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET,
    944                                    mem_index);
    945                 stat->ser_err_tcam++;
    946                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
    947                 spci.reg = INVALIDr;
    948                 spci.mem = cur_spi->mem;
    949                 spci.blk_type = copyno;
    950                 spci.index = mem_index;
    951                 spci.detect_time = sal_time_usecs();
    952                 spci.log_id = soc_ser_log_create_entry(unit,
    953                     sizeof(soc_ser_log_tlv_generic_t) +
    954                     sizeof(soc_ser_log_tlv_memory_t) +
    955                     sizeof(soc_ser_log_tlv_hdr_t) *3);
    956                 rv = soc_ser_correction(unit, &spci);
    957                 if (spci.log_id != 0) {
    958                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
    959                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
    960                                        spci.log_id, 0);
    961                 }
    962                 if (SOC_FAILURE(rv)) {
    963                     /* Report failed to correct event flag to
    964                      * application */
    965                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
    966                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
    967                             cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET,
    968                             mem_index);
    969                     return rv;
    970                 }
    971                 break;
    972             }
    973             info_ix++;
    974         }
    975         /*coverity[result_independent_of_operands]*/
    976         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_ENTRYr(unit, 0));
    977         /*coverity[result_independent_of_operands]*/
    978         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_CNTr(unit, 0));
    979     }
    980 
    981     /* Then work on ser1 */
    982     /*coverity[result_independent_of_operands]*/
    983     SOC_IF_ERROR_RETURN(READ_CMIC_SER1_FAIL_CNTr(unit, &fail_count));
    984     if (fail_count) {
    985         fail++;
    986         /*coverity[result_independent_of_operands]*/
    987         SOC_IF_ERROR_RETURN(READ_CMIC_SER1_FAIL_ENTRYr(unit, &addr));
    988         info_ix = 0;
    989         while (_ser_parity_info[info_ix].mem != INVALIDm) {
    990             cur_spi = &(_ser_parity_info[info_ix]);
    991             if (cur_spi->cmic_ser_id == 0) {
    992                 info_ix++;
    993                 continue;
    994             }
    995             index_min = soc_mem_index_min(unit, cur_spi->mem);
    996             index_max = soc_mem_index_max(unit, cur_spi->mem);
    997             SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) {
    998                 break;
    999             }
   1000             start_addr =
   1001                 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, index_min, &at);
   1002             end_addr =
   1003                 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, index_max, &at);
   1004 
   1005             if ((addr >= start_addr) && (addr <= end_addr)) {
   1006                 /* Addr in memory range */
   1007                 mem_index = (addr - start_addr) + index_min;
   1008                 LOG_WARN(BSL_LS_SOC_SER,
   1009                           (BSL_META_U(unit,
   1010                                       "ser1 %s entry %d TCAM parity error\n"),
   1011                            SOC_MEM_NAME(unit, cur_spi->mem),
   1012                            mem_index));
   1013                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1014                                    SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   1015                                    cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET,
   1016                                    mem_index);
   1017                 stat->ser_err_tcam++;
   1018                 sal_memset(&spci, 0, sizeof(spci));
   1019                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1020                 spci.mem = cur_spi->mem;
   1021                 spci.blk_type = copyno;
   1022                 spci.index = mem_index;
   1023                 spci.detect_time = sal_time_usecs();
   1024                 spci.log_id = soc_ser_log_create_entry(unit,
   1025                     sizeof(soc_ser_log_tlv_generic_t) +
   1026                     sizeof(soc_ser_log_tlv_memory_t) +
   1027                     sizeof(soc_ser_log_tlv_hdr_t) *3);
   1028                 rv = soc_ser_correction(unit, &spci);
   1029                 if (spci.log_id != 0) {
   1030                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1031                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   1032                                        spci.log_id, 0);
   1033                 }
   1034                 if (SOC_FAILURE(rv)) {
   1035                     /* Report failed to correct event flag to
   1036                      * application */
   1037                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1038                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1039                             cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET,
   1040                             mem_index);
   1041                     return rv;
   1042                 }
   1043                 break;
   1044             }
   1045             info_ix++;
   1046         }
   1047         /*coverity[result_independent_of_operands]*/
   1048         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_ENTRYr(unit, 0));
   1049         /*coverity[result_independent_of_operands]*/
   1050         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_CNTr(unit, 0));
   1051     }
   1052     if (!fail) {
   1053         LOG_ERROR(BSL_LS_SOC_SER,
   1054                   (BSL_META_U(unit,
   1055                               "SER parity failure without valid count\n")));
   1056     }
   1057     return SOC_E_NONE;
   1058 }
   1059 
   1060 int
   1061 soc_ser_mem_nack(void *unit_vp, void *addr_vp, void *d2,
   1062                  void *d3, void *d4)
   1063 {
   1064     int unit = PTR_TO_INT(unit_vp);
   1065 
   1066     if ((_soc_ser_functions[unit] != NULL) &&
   1067         (_soc_ser_functions[unit]->_soc_ser_mem_nack_f != NULL)) {
   1068         sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_mem_nack_f), unit_vp,
   1069                 addr_vp, d2, d3, d4);
   1070         return TRUE;
   1071     }
   1072 
   1073     return FALSE;
   1074 }
   1075 
   1076 int
   1077 soc_ser_parity_error_intr(int unit)
   1078 {
   1079     if ((_soc_ser_functions[unit] != NULL) &&
   1080         (_soc_ser_functions[unit]->_soc_ser_parity_error_intr_f != NULL)) {
   1081         soc_intr_disable(unit, IRQ_MEM_FAIL);
   1082         sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_parity_error_intr_f),
   1083                 INT_TO_PTR(unit), 0, 0, 0, 0);
   1084         return TRUE;
   1085     } else if ((_soc_oam_event_functions[unit] != NULL) &&
   1086                (_soc_oam_event_functions[unit]->_soc_oam_event_intr_f != NULL)) {
   1087         soc_intr_disable(unit, IRQ_MEM_FAIL);
   1088         sal_dpc(*(_soc_oam_event_functions[unit]->_soc_oam_event_intr_f),
   1089                 INT_TO_PTR(unit), 0, 0, 0, 0);
   1090         return TRUE;
   1091     }
   1092     return FALSE;
   1093 }
   1094 
   1095 soc_error_t
   1096 soc_ser_tcam_scan_engine_enable(int unit, int enable)
   1097 {
   1098     /*
   1099     uint64 config;
   1100     COMPILER_64_ZERO(config);
   1101     */
   1102 
   1103 #ifdef BCM_TOMAHAWK2_SUPPORT
   1104     if (SOC_IS_TOMAHAWK2(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) {
   1105         return soc_th2_tcam_engine_enable(unit, enable);
   1106     }
   1107 #endif
   1108 
   1109 #ifdef BCM_TRIDENT3_SUPPORT
   1110     if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) {
   1111         return soc_td3_tcam_engine_enable(unit, enable);
   1112     }
   1113 #endif
   1114 
   1115 #ifdef BCM_TOMAHAWK3_SUPPORT
   1116     if (SOC_IS_TOMAHAWK3(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) {
   1117         return soc_th3_tcam_engine_enable(unit, enable);
   1118     }
   1119 #endif
   1120     return SOC_E_NONE;
   1121 }
   1122 
   1123 int
   1124 soc_ser_parity_error_cmicm_intr(void *unit_vp, void *d1, void *d2,
   1125                                 void *d3, void *d4)
   1126 {
   1127     int unit = PTR_TO_INT(unit_vp);
   1128 
   1129     if ((_soc_ser_functions[unit] != NULL) &&
   1130         (_soc_ser_functions[unit]->_soc_ser_parity_error_cmicm_intr_f != NULL)) {
   1131         sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_parity_error_cmicm_intr_f),
   1132                 unit_vp, d1, d2, d3, d4);
   1133         return TRUE;
   1134     } else if ((_soc_oam_event_functions[unit] != NULL) &&
   1135                (_soc_oam_event_functions[unit]->_soc_oam_event_intr_f != NULL)) {
   1136         sal_dpc(*(_soc_oam_event_functions[unit]->_soc_oam_event_intr_f),
   1137                 unit_vp, d1, d2, d3, d4);
   1138         return TRUE;
   1139     }
   1140 
   1141     return FALSE;
   1142 }
   1143 
   1144 #ifdef BCM_CMICX_SUPPORT
   1145 int
   1146 soc_ser_parity_error_cmicx_intr(void *unit_vp, void *d1, void *d2,
   1147                                 void *d3, void *d4)
   1148 {
   1149     int unit = PTR_TO_INT(unit_vp);
   1150 
   1151     if ((_soc_ser_functions[unit] != NULL) &&
   1152         (_soc_ser_functions[unit]->_soc_ser_parity_error_cmicx_intr_f != NULL)) {
   1153         sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_parity_error_cmicx_intr_f),
   1154                 unit_vp, d1, d2, d3, d4);
   1155         return TRUE;
   1156     }
   1157 
   1158     return FALSE;
   1159 }
   1160 #endif
   1161 
   1162 void
   1163 soc_ser_fail(void *unit_vp, void *addr_vp, void *d2,
   1164              void *d3, void *d4)
   1165 
   1166 {
   1167     int unit = PTR_TO_INT(unit_vp);
   1168 
   1169     if ((_soc_ser_functions[unit] != NULL) &&
   1170         (_soc_ser_functions[unit]->_soc_ser_fail_f != NULL)) {
   1171         (*(_soc_ser_functions[unit]->_soc_ser_fail_f))(unit);
   1172     }
   1173 
   1174     return;
   1175 }
   1176 
   1177 STATIC int
   1178 _soc_ser_granularity(_soc_ser_parity_mode_t parity_mode)
   1179 {
   1180     int ser_mem_granularity;
   1181 
   1182     switch (parity_mode) {
   1183     case _SOC_SER_PARITY_MODE_2BITS:
   1184         ser_mem_granularity = 2;
   1185         break;
   1186     case _SOC_SER_PARITY_MODE_4BITS:
   1187         ser_mem_granularity = 4;
   1188         break;
   1189     case _SOC_SER_PARITY_MODE_8BITS:
   1190         ser_mem_granularity = 8;
   1191         break;
   1192     case _SOC_SER_PARITY_MODE_1BIT:
   1193     default:
   1194         ser_mem_granularity = 1;
   1195         break;
   1196     }
   1197     return ser_mem_granularity;
   1198 }
   1199 
   1200 int
   1201 soc_ser_mem_clear(int unit, _soc_ser_parity_info_t *_ser_parity_info,
   1202                   soc_mem_t mem)
   1203 {
   1204     int info_ix, ser_mem_count, ser_mem_granularity;
   1205     uint32 addr_valid = 0;
   1206     _soc_ser_parity_info_t *cur_spi;
   1207 
   1208     /* coverity[result_independent_of_operands] */
   1209     SOC_IF_ERROR_RETURN
   1210         (READ_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, &addr_valid));
   1211 
   1212     if (!addr_valid) {
   1213         /* No SER protection, do nothing */
   1214         return SOC_E_NONE;
   1215     }
   1216 
   1217     info_ix = 0;
   1218     while (_ser_parity_info[info_ix].mem != INVALIDm) {
   1219         if (_ser_parity_info[info_ix].mem == mem) {
   1220             break;
   1221         }
   1222         info_ix++;
   1223     }
   1224 
   1225     if ((_ser_parity_info[info_ix].mem != INVALIDm) &&
   1226         (addr_valid & (1 << info_ix))) {
   1227         cur_spi = &(_ser_parity_info[info_ix]);
   1228 
   1229         addr_valid &= ~(1 << info_ix);
   1230         /* Disable SER protection on this memory */
   1231         /*coverity[result_independent_of_operands]*/
   1232         SOC_IF_ERROR_RETURN
   1233             (WRITE_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid));
   1234 
   1235         ser_mem_granularity =
   1236             _soc_ser_granularity(cur_spi->parity_mode);
   1237 
   1238         /* Flush SER memory segment for the table */
   1239         for (ser_mem_count = cur_spi->ser_section_start;
   1240              ser_mem_count < cur_spi->ser_section_end;
   1241              ser_mem_count += ser_mem_granularity) {
   1242             /* coverity[result_independent_of_operands] */
   1243             SOC_IF_ERROR_RETURN
   1244                 (WRITE_CMIC_SER_MEM_ADDRr(unit, ser_mem_count));
   1245             /* coverity[result_independent_of_operands] */
   1246             SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_MEM_DATAr(unit, 0));
   1247         }
   1248 
   1249         addr_valid |= (1 << info_ix);
   1250         /* Enable SER protection on this memory */
   1251         /*coverity[result_independent_of_operands]*/
   1252         SOC_IF_ERROR_RETURN
   1253             (WRITE_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid));
   1254 
   1255         LOG_VERBOSE(BSL_LS_SOC_SER,
   1256                     (BSL_META_U(unit,
   1257                                 "\t%s: SER[%d-%d]\n"),
   1258                      SOC_MEM_NAME(unit, cur_spi->mem),
   1259                      cur_spi->ser_section_start, cur_spi->ser_section_end));
   1260     }
   1261 
   1262     return SOC_E_NONE;
   1263 }
   1264 
   1265 int
   1266 soc_cmicm_ser_mem_clear(int unit, _soc_ser_parity_info_t *_ser_parity_info,
   1267                         soc_mem_t mem)
   1268 {
   1269     int info_ix, ser_mem_count, ser_mem_granularity;
   1270     uint32 addr_valid = 0;
   1271     _soc_ser_parity_info_t *cur_spi;
   1272 
   1273     /* First work on ser0 */
   1274     SOC_IF_ERROR_RETURN
   1275         (READ_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, &addr_valid));
   1276 
   1277     if (!addr_valid) {
   1278         /* No SER protection, do nothing */
   1279         goto check_ser1;
   1280     }
   1281 
   1282     info_ix = 0;
   1283     while (_ser_parity_info[info_ix].mem != INVALIDm) {
   1284         if ((_ser_parity_info[info_ix].mem == mem) &&
   1285             (_ser_parity_info[info_ix].cmic_ser_id == 0)) {
   1286             break;
   1287         }
   1288         info_ix++;
   1289     }
   1290 
   1291     if ((_ser_parity_info[info_ix].mem != INVALIDm) &&
   1292         (addr_valid & (1 << info_ix))) {
   1293         cur_spi = &(_ser_parity_info[info_ix]);
   1294 
   1295         addr_valid &= ~(1 << info_ix);
   1296         /* Disable SER protection on this memory */
   1297         /*coverity[result_independent_of_operands]*/
   1298         SOC_IF_ERROR_RETURN
   1299             (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid));
   1300 
   1301         ser_mem_granularity =
   1302             _soc_ser_granularity(cur_spi->parity_mode);
   1303 
   1304         /* Flush SER memory segment for the table */
   1305         for (ser_mem_count = cur_spi->ser_section_start;
   1306              ser_mem_count < cur_spi->ser_section_end;
   1307              ser_mem_count += ser_mem_granularity) {
   1308             SOC_IF_ERROR_RETURN
   1309                 (WRITE_CMIC_SER0_MEM_ADDRr(unit, ser_mem_count));
   1310             SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_MEM_DATAr(unit, 0));
   1311         }
   1312 
   1313         addr_valid |= (1 << info_ix);
   1314         /* Enable SER protection on this memory */
   1315         /*coverity[result_independent_of_operands]*/
   1316         SOC_IF_ERROR_RETURN
   1317             (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid));
   1318 
   1319         LOG_VERBOSE(BSL_LS_SOC_SER,
   1320                     (BSL_META_U(unit,
   1321                                 "\t%s: SER0[%d-%d]\n"),
   1322                      SOC_MEM_NAME(unit, cur_spi->mem),
   1323                      cur_spi->ser_section_start, cur_spi->ser_section_end));
   1324     }
   1325 
   1326 check_ser1:
   1327     /* Then work on ser1 */
   1328     /* coverity[result_independent_of_operands] */
   1329     SOC_IF_ERROR_RETURN
   1330         (READ_CMIC_SER1_PROTECT_ADDR_RANGE_VALIDr(unit, &addr_valid));
   1331 
   1332     if (!addr_valid) {
   1333         /* No SER protection, do nothing */
   1334         return SOC_E_NONE;
   1335     }
   1336 
   1337     info_ix = 0;
   1338     while (_ser_parity_info[info_ix].mem != INVALIDm) {
   1339         if ((_ser_parity_info[info_ix].mem == mem) &&
   1340             (_ser_parity_info[info_ix].cmic_ser_id == 1)) {
   1341             break;
   1342         }
   1343         info_ix++;
   1344     }
   1345 
   1346     if ((_ser_parity_info[info_ix].mem != INVALIDm) &&
   1347         (addr_valid & (1 << info_ix))) {
   1348         cur_spi = &(_ser_parity_info[info_ix]);
   1349 
   1350         addr_valid &= ~(1 << info_ix);
   1351         /* Disable SER protection on this memory */
   1352         /*coverity[result_independent_of_operands]*/
   1353         SOC_IF_ERROR_RETURN
   1354             (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid));
   1355 
   1356         ser_mem_granularity =
   1357             _soc_ser_granularity(cur_spi->parity_mode);
   1358 
   1359         /* Flush SER memory segment for the table */
   1360         for (ser_mem_count = cur_spi->ser_section_start;
   1361              ser_mem_count < cur_spi->ser_section_end;
   1362              ser_mem_count += ser_mem_granularity) {
   1363             /* coverity[result_independent_of_operands] */
   1364             SOC_IF_ERROR_RETURN
   1365                 (WRITE_CMIC_SER1_MEM_ADDRr(unit, ser_mem_count));
   1366             /* coverity[result_independent_of_operands] */
   1367             SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_MEM_DATAr(unit, 0));
   1368         }
   1369 
   1370         addr_valid |= (1 << info_ix);
   1371         /* Enable SER protection on this memory */
   1372         /*coverity[result_independent_of_operands]*/
   1373         SOC_IF_ERROR_RETURN
   1374             (WRITE_CMIC_SER1_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid));
   1375 
   1376         LOG_VERBOSE(BSL_LS_SOC_SER,
   1377                     (BSL_META_U(unit,
   1378                                 "\t%s: SER0[%d-%d]\n"),
   1379                      SOC_MEM_NAME(unit, cur_spi->mem),
   1380                      cur_spi->ser_section_start, cur_spi->ser_section_end));
   1381     }
   1382     return SOC_E_NONE;
   1383 }
   1384 
   1385 int
   1386 soc_ser_init(int unit, _soc_ser_parity_info_t *_ser_parity_info, int max_mem)
   1387 {
   1388     int info_ix, o_info_ix;
   1389     int index_min, index_max, copyno, ser_mem_granularity;
   1390     int i, ser_mem_count, ser_mem_total = 0;
   1391     uint32 start_addr, end_addr, ser_mem_addr = 0, reg_addr;
   1392     uint32 addr_valid0 = 0;
   1393     uint32 acc_type;
   1394     uint8 wb_flag = 0;
   1395 #ifdef BCM_CMICM_SUPPORT
   1396     uint8 at;
   1397     uint32 addr_valid1 = 0, ser_mem_addr0 = 0, ser_mem_addr1 = 0;
   1398     uint32 ser_mem_total0 = 0, ser_mem_total1 = 0;
   1399 #endif /* BCM_CMICM_SUPPORT */
   1400     _soc_ser_parity_info_t *cur_spi, *multi_pipe_spi;
   1401 
   1402     LOG_VERBOSE(BSL_LS_SOC_SER,
   1403                 (BSL_META_U(unit,
   1404                             "Unit %d: SER parity initialization:\n"), unit));
   1405 
   1406     soc_ser_function_register(unit, NULL);
   1407 
   1408     info_ix = 0;
   1409     while (_ser_parity_info[info_ix].mem != INVALIDm) {
   1410         cur_spi = &(_ser_parity_info[info_ix]);
   1411 
   1412         if (cur_spi->ser_flags & _SOC_SER_FLAG_SW_COMPARE) {
   1413             if (SOC_MEM_INFO(unit, cur_spi->mem).flags & SOC_MEM_FLAG_BE) {
   1414                 LOG_ERROR(BSL_LS_SOC_SER,
   1415                           (BSL_META_U(unit,
   1416                                       "\tSW SER init of Big Endian TCAMs is not supported: %s\n"),
   1417                            SOC_MEM_NAME(unit, cur_spi->mem)));
   1418                 return SOC_E_INTERNAL;
   1419             }
   1420 
   1421             LOG_VERBOSE(BSL_LS_SOC_SER,
   1422                         (BSL_META_U(unit,
   1423                                     "\tSkipping HW SER init of manual scan mem: %s\n"),
   1424                          SOC_MEM_NAME(unit, cur_spi->mem)));
   1425             SOC_MEM_INFO(unit, cur_spi->mem).flags |= SOC_MEM_FLAG_SER_ENGINE;
   1426             info_ix++;
   1427             continue;
   1428         }
   1429 
   1430         index_min = soc_mem_index_min(unit, cur_spi->mem);
   1431         index_max = soc_mem_index_max(unit, cur_spi->mem);
   1432 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \
   1433     defined(BCM_KATANA_SUPPORT)
   1434         if (soc_feature(unit, soc_feature_l3_defip_map) &&
   1435             ((cur_spi->mem == L3_DEFIP_PAIR_128m) ||
   1436              (cur_spi->mem == L3_DEFIPm))) {
   1437             /* Override SOC memory impression for overlay
   1438              * LPM tables. */
   1439             index_min = 0;
   1440             index_max = (SOC_CONTROL(unit)->l3_defip_max_tcams *
   1441                          SOC_CONTROL(unit)->l3_defip_tcam_size) - 1;
   1442             if (cur_spi->mem == L3_DEFIP_PAIR_128m) {
   1443                 index_max /= 2;
   1444             }
   1445         }
   1446 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT */
   1447         ser_mem_count = index_max - index_min + 1;
   1448         if (!ser_mem_count) {
   1449             LOG_VERBOSE(BSL_LS_SOC_SER,
   1450                         (BSL_META_U(unit,
   1451                                     "\tSkipping empty mem: %s\n"),
   1452                          SOC_MEM_NAME(unit, cur_spi->mem)));
   1453             info_ix++;
   1454             continue;
   1455         }
   1456 
   1457         ser_mem_granularity = _soc_ser_granularity(cur_spi->parity_mode);
   1458         ser_mem_count *= ser_mem_granularity;
   1459 
   1460         /* Round up to words for simplicity */
   1461         ser_mem_count = 32 * ((ser_mem_count + 31) / 32);
   1462         if ((ser_mem_count + ser_mem_total) > max_mem) {
   1463             /* Can't fit requested parity bits in SER memory */
   1464             LOG_VERBOSE(BSL_LS_SOC_SER,
   1465                         (BSL_META_U(unit,
   1466                                     "SER mem full: Skipping further config.\n")));
   1467             break;
   1468         }
   1469 
   1470         /* Parity bits fit, so on with the config */
   1471         SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) {
   1472             break;
   1473         }
   1474 #ifdef BCM_CMICM_SUPPORT
   1475         if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) {
   1476             start_addr = soc_mem_addr_get(unit, cur_spi->mem, 0, copyno,
   1477                                           index_min, &at);
   1478             end_addr = soc_mem_addr_get(unit, cur_spi->mem, 0, copyno,
   1479                                         index_max, &at);
   1480         } else
   1481 #endif /* BCM_CMICM_SUPPORT */
   1482         {
   1483             start_addr = soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_min);
   1484             end_addr = soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_max);
   1485         }
   1486 
   1487         /* Flush SER memory */
   1488 #ifdef BCM_CMICM_SUPPORT
   1489         if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) {
   1490             if (cur_spi->cmic_ser_id) {
   1491                 ser_mem_addr1 = ser_mem_total1; /* Previous total */
   1492                 ser_mem_total1 += ser_mem_count; /* New total */
   1493                 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   1494                     for (i=ser_mem_addr1; i<ser_mem_total1; i++) {
   1495                         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_MEM_ADDRr(unit, i));
   1496                         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_MEM_DATAr(unit, 0));
   1497                     }
   1498                 }
   1499                 /* Record section for mem_clear use */
   1500                 cur_spi->ser_section_start = ser_mem_addr1;
   1501                 cur_spi->ser_section_end = ser_mem_total1 - ser_mem_granularity;
   1502             } else {
   1503                 ser_mem_addr0 = ser_mem_total0; /* Previous total */
   1504                 ser_mem_total0 += ser_mem_count; /* New total */
   1505                 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   1506                     for (i=ser_mem_addr0; i<ser_mem_total0; i++) {
   1507                         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_MEM_ADDRr(unit, i));
   1508                         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_MEM_DATAr(unit, 0));
   1509                     }
   1510                 }
   1511                 /* Record section for mem_clear use */
   1512                 cur_spi->ser_section_start = ser_mem_addr0;
   1513                 cur_spi->ser_section_end = ser_mem_total0 - ser_mem_granularity;
   1514             }
   1515             ser_mem_total += ser_mem_count; /* New total */
   1516         } else
   1517 #endif /* BCM_CMICM_SUPPORT */
   1518         {
   1519             ser_mem_addr = ser_mem_total; /* Previous total */
   1520             ser_mem_total += ser_mem_count; /* New total */
   1521             if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   1522                 for (i=ser_mem_addr; i<ser_mem_total; i++) {
   1523                     /* coverity[result_independent_of_operands] */
   1524                     SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_MEM_ADDRr(unit, i));
   1525                     /* coverity[result_independent_of_operands] */
   1526                     SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_MEM_DATAr(unit, 0));
   1527                 }
   1528             }
   1529             /* Record section for mem_clear use */
   1530             cur_spi->ser_section_start = ser_mem_addr;
   1531             cur_spi->ser_section_end = ser_mem_total - ser_mem_granularity;
   1532         }
   1533 
   1534         /* For multiple pipeline units, different pipeline's hardware
   1535          * instances are duplicates.  The SER parity bits are thus
   1536          * shared, but the configuration registers in the CMIC must be
   1537          * different to capture the different SBUS ranges of the
   1538          * read accesses.
   1539          */
   1540         multi_pipe_spi = cur_spi;
   1541         o_info_ix = info_ix;
   1542         if (SOC_WARM_BOOT(unit) && SOC_IS_KATANA(unit)) {
   1543             wb_flag = 1;
   1544         }
   1545         while (cur_spi->mem == multi_pipe_spi->mem) {
   1546             if (cur_spi != multi_pipe_spi) {
   1547                 info_ix++; /* Advance the index */
   1548                 if (0 != (multi_pipe_spi->ser_flags &
   1549                           _SOC_SER_FLAG_MULTI_PIPE)) {
   1550                     /* Get the non-default pipeline access type */
   1551                     acc_type = multi_pipe_spi->ser_flags &
   1552                         _SOC_SER_FLAG_ACC_TYPE_MASK;
   1553 
   1554                     /* Override ACC_TYPE in address */
   1555                     /* Note, this function does not support the
   1556                      * extended sbus addressing for multiple pipeline
   1557                      * devices.
   1558                      * soc_generic_ser_init _must_ be used
   1559                      * for such devices.
   1560                      */
   1561                     start_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK <<
   1562                                     _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   1563                     start_addr |=
   1564                         (acc_type & _SOC_MEM_ADDR_ACC_TYPE_MASK) <<
   1565                         _SOC_MEM_ADDR_ACC_TYPE_SHIFT;
   1566                     end_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK <<
   1567                                     _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   1568                     end_addr |=
   1569                         (acc_type & _SOC_MEM_ADDR_ACC_TYPE_MASK) <<
   1570                         _SOC_MEM_ADDR_ACC_TYPE_SHIFT;
   1571                 } else {
   1572                     LOG_VERBOSE(BSL_LS_SOC_SER,
   1573                                 (BSL_META_U(unit,
   1574                                             "SER mem muliple pipeline mismatch %s vs. %s.\n"),
   1575                                  SOC_MEM_NAME(unit, cur_spi->mem),
   1576                                  SOC_MEM_NAME(unit, multi_pipe_spi->mem)));
   1577                     return SOC_E_INTERNAL;
   1578                 }
   1579             }
   1580 
   1581             reg_addr =
   1582                 soc_reg_addr(unit, multi_pipe_spi->start_addr_reg,
   1583                              REG_PORT_ANY, 0);
   1584             if (!wb_flag) {
   1585                 /* coverity[result_independent_of_operands] */
   1586                 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, start_addr));
   1587             }
   1588             reg_addr =
   1589                 soc_reg_addr(unit, multi_pipe_spi->end_addr_reg,
   1590                              REG_PORT_ANY, 0);
   1591             if (!wb_flag) {
   1592                 /* coverity[result_independent_of_operands] */
   1593                 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, end_addr));
   1594             }
   1595             reg_addr =
   1596                 soc_reg_addr(unit, multi_pipe_spi->cmic_mem_addr_reg,
   1597                              REG_PORT_ANY, 0);
   1598 
   1599 
   1600 #ifdef BCM_CMICM_SUPPORT
   1601             if (soc_feature(unit, soc_feature_cmicm) &&
   1602                 !SOC_IS_KATANA(unit)) {
   1603                 if (multi_pipe_spi->cmic_ser_id) {
   1604                     /* coverity[result_independent_of_operands] */
   1605                     SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr,
   1606                                                       ser_mem_addr1));
   1607                     addr_valid1 |= (1 << info_ix);
   1608                 } else {
   1609                     /* coverity[result_independent_of_operands] */
   1610                     SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr,
   1611                                                       ser_mem_addr0));
   1612                     addr_valid0 |= (1 << info_ix);
   1613                 }
   1614             } else
   1615 #endif /* BCM_CMICM_SUPPORT */
   1616             {
   1617                 if (!wb_flag) {
   1618                     /* coverity[result_independent_of_operands] */
   1619                     SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr,
   1620                                                   ser_mem_addr));
   1621                 }
   1622                 addr_valid0 |= (1 << info_ix);
   1623             }
   1624 
   1625             if (multi_pipe_spi->bit_offset != -1) {
   1626                 if (!wb_flag) {
   1627                     /* coverity[result_independent_of_operands] */
   1628                     SOC_IF_ERROR_RETURN
   1629                     (soc_pci_write(unit, soc_reg_addr(unit,
   1630                                          multi_pipe_spi->entry_len_reg,
   1631                                          REG_PORT_ANY, 0),
   1632                                    multi_pipe_spi->bit_offset));
   1633                 }
   1634             }
   1635             SOC_IF_ERROR_RETURN
   1636                 (soc_reg_field32_modify(unit, multi_pipe_spi->parity_mode_reg,
   1637                                         REG_PORT_ANY, multi_pipe_spi->parity_mode_field,
   1638                                         multi_pipe_spi->parity_mode));
   1639 
   1640             multi_pipe_spi = &(_ser_parity_info[info_ix + 1]);
   1641         }
   1642 
   1643 #ifdef BCM_CMICM_SUPPORT
   1644         if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) {
   1645             LOG_VERBOSE(BSL_LS_SOC_SER,
   1646                         (BSL_META_U(unit,
   1647                                     "\t%s(%d-%d): Sbus range (0x%08x-0x%08x) SER[%d][%d](0x%03x)\n"),
   1648                          SOC_MEM_NAME(unit, cur_spi->mem),
   1649                          index_min, index_max, start_addr, end_addr,
   1650                          cur_spi->cmic_ser_id, o_info_ix,
   1651                          cur_spi->cmic_ser_id ?
   1652                          ser_mem_addr1 : ser_mem_addr0));
   1653         } else
   1654 #endif /* BCM_CMICM_SUPPORT */
   1655         {
   1656             LOG_VERBOSE(BSL_LS_SOC_SER,
   1657                         (BSL_META_U(unit,
   1658                                     "\t%s(%d-%d): Sbus range (0x%08x-0x%08x) SER[%d](0x%03x)\n"),
   1659                          SOC_MEM_NAME(unit, cur_spi->mem),
   1660                          index_min, index_max, start_addr, end_addr,
   1661                          o_info_ix, ser_mem_addr));
   1662         }
   1663         if (cur_spi->bit_offset != -1) {
   1664             LOG_VERBOSE(BSL_LS_SOC_SER,
   1665                         (BSL_META_U(unit,
   1666                                     "\tBits protected per entry: %d\n"),
   1667                          cur_spi->bit_offset));
   1668         }
   1669         SOC_MEM_INFO(unit, cur_spi->mem).flags |= SOC_MEM_FLAG_SER_ENGINE;
   1670         info_ix++;
   1671     }
   1672 
   1673 #ifdef BCM_CMICM_SUPPORT
   1674     if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) {
   1675         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_ENTRYr(unit, 0));
   1676         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_CNTr(unit, 0));
   1677         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_ENTRYr(unit, 0));
   1678         SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_CNTr(unit, 0));
   1679     } else
   1680 #endif /* BCM_CMICM_SUPPORT */
   1681     {
   1682         if (!wb_flag) {
   1683             SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_ENTRYr(unit, 0));
   1684             SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_CNTr(unit, 0));
   1685         }
   1686     }
   1687 
   1688     /* Enable SER protection last */
   1689 #ifdef BCM_CMICM_SUPPORT
   1690     if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) {
   1691         SOC_IF_ERROR_RETURN
   1692             (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid0));
   1693         /* coverity[result_independent_of_operands] */
   1694         SOC_IF_ERROR_RETURN
   1695             (WRITE_CMIC_SER1_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid1));
   1696     } else
   1697 #endif /* BCM_CMICM_SUPPORT */
   1698     {
   1699         if (!wb_flag) {
   1700             /* coverity[result_independent_of_operands] */
   1701             SOC_IF_ERROR_RETURN
   1702                 (WRITE_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid0));
   1703         }
   1704     }
   1705     return SOC_E_NONE;
   1706 }
   1707 
   1708 STATIC int
   1709 _soc_generic_ser_granularity(_soc_ser_protection_type_t prot_type,
   1710                              _soc_ser_protection_mode_t prot_mode,
   1711                              __soc_ser_start_end_bits_t *bits)
   1712 {
   1713     int i, words = 0, ser_mem_gran;
   1714 
   1715     for (i = 0; i < SOC_NUM_GENERIC_PROT_SECTIONS; i++) {
   1716         if (bits[i].start_bit >= 0) {
   1717             words++;
   1718         }
   1719     }
   1720     if (prot_type == _SOC_SER_TYPE_PARITY) {
   1721         switch (prot_mode) {
   1722         case _SOC_SER_PARITY_2BITS:
   1723             ser_mem_gran = 2;
   1724             break;
   1725         case _SOC_SER_PARITY_4BITS:
   1726             ser_mem_gran = 4;
   1727             break;
   1728         case _SOC_SER_PARITY_8BITS:
   1729             ser_mem_gran = 8;
   1730             break;
   1731         case _SOC_SER_PARITY_1BIT:
   1732         default:
   1733             ser_mem_gran = 1;
   1734             break;
   1735         }
   1736         return ser_mem_gran;
   1737     } else {
   1738         switch (prot_mode) {
   1739         case _SOC_SER_ECC_2FLD:
   1740             ser_mem_gran = 2;
   1741             break;
   1742         case _SOC_SER_ECC_4FLD:
   1743             ser_mem_gran = 4;
   1744             break;
   1745         case _SOC_SER_ECC_1FLD:
   1746         default:
   1747             ser_mem_gran = 1;
   1748             break;
   1749         }
   1750         return ser_mem_gran * words * 9;
   1751     }
   1752 }
   1753 
   1754 int
   1755 soc_generic_ser_process_error(int unit, _soc_generic_ser_info_t *ser_info,
   1756                               int err_type)
   1757 {
   1758     uint8 at;
   1759     int info_ix, hw_ix, acc_type, rv;
   1760     int index_min, index_max, phys_index_min, phys_index_max;
   1761     int ser_mem_count, copyno, mem_index;
   1762     uint32 start_addr, end_addr, count;
   1763     uint32 ser_err[2], addr;
   1764     _soc_generic_ser_info_t *cur_ser_info;
   1765     _soc_ser_correct_info_t spci = {0};
   1766     soc_stat_t *stat = SOC_STAT(unit);
   1767     ser_result_0_entry_t err_result;
   1768     soc_mem_t cur_mem;
   1769 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \
   1770     defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   1771     defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   1772     uint8 *corrupt = NULL;
   1773     int is_l3_defip = FALSE;
   1774 #endif
   1775 #if defined(ALPM_ENABLE)
   1776     uint8 _alpm_lock = 0;
   1777 #endif /* ALPM_ENABLE */
   1778     int block_type = 0;
   1779 
   1780     sal_memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1781 
   1782     SOC_IF_ERROR_RETURN(READ_SER_ERROR_0r(unit, &ser_err[0]));
   1783     SOC_IF_ERROR_RETURN(READ_SER_ERROR_1r(unit, &ser_err[1]));
   1784 
   1785     if (!soc_reg_field_get(unit, SER_ERROR_0r, ser_err[0], ERROR_0_VALf) &&
   1786         !soc_reg_field_get(unit, SER_ERROR_1r, ser_err[1], ERROR_1_VALf)) {
   1787         LOG_ERROR(BSL_LS_SOC_SER,
   1788                   (BSL_META_U(unit,
   1789                               "SER parity failure without valid error !!\n")));
   1790         return SOC_E_NONE;
   1791     }
   1792     do {
   1793         if (soc_reg_field_get(unit, SER_ERROR_0r, ser_err[0],
   1794                               ERROR_0_VALf)) {
   1795             SOC_IF_ERROR_RETURN
   1796                 (soc_mem_read(unit, SER_RESULT_0m, MEM_BLOCK_ANY,
   1797                               0, &err_result));
   1798             hw_ix = soc_mem_field32_get(unit, SER_RESULT_0m,
   1799                                         &err_result, RANGEf);
   1800             addr = soc_mem_field32_get(unit, SER_RESULT_0m,
   1801                                        &err_result, SBUS_ADDRf);
   1802             acc_type = soc_mem_field32_get(unit, SER_RESULT_0m,
   1803                                        &err_result, ACC_TYPEf);
   1804             SOC_IF_ERROR_RETURN(WRITE_SER_ERROR_0r(unit, 0));
   1805         } else {
   1806             SOC_IF_ERROR_RETURN
   1807                 (soc_mem_read(unit, SER_RESULT_1m, MEM_BLOCK_ANY,
   1808                               0, &err_result));
   1809             hw_ix = soc_mem_field32_get(unit, SER_RESULT_1m,
   1810                                         &err_result, RANGEf);
   1811             addr = soc_mem_field32_get(unit, SER_RESULT_1m,
   1812                                        &err_result, SBUS_ADDRf);
   1813             acc_type = soc_mem_field32_get(unit, SER_RESULT_1m,
   1814                                        &err_result, ACC_TYPEf);
   1815             SOC_IF_ERROR_RETURN(WRITE_SER_ERROR_1r(unit, 0));
   1816         }
   1817 
   1818         info_ix = 0;
   1819         while (ser_info[info_ix].mem != INVALIDm) {
   1820             if (0 == (ser_info[info_ix].ser_flags & _SOC_SER_FLAG_SW_COMPARE)) {
   1821                 if ((ser_info[info_ix].ser_hw_index != -1) &&
   1822                     (ser_info[info_ix].ser_hw_index == hw_ix)) {
   1823                     break;
   1824                 }
   1825             }
   1826             info_ix++;
   1827         }
   1828         if (ser_info[info_ix].mem == INVALIDm) {
   1829             LOG_ERROR(BSL_LS_SOC_SER,
   1830                       (BSL_META_U(unit,
   1831                                   "SER parity failure with invalid mem range !!\n")));
   1832             return SOC_E_NONE;
   1833         }
   1834         cur_ser_info = &(ser_info[info_ix]);
   1835         phys_index_min = index_min =
   1836             soc_mem_index_min(unit, cur_ser_info->mem);
   1837         phys_index_max = index_max =
   1838             soc_mem_index_max(unit, cur_ser_info->mem);
   1839         if (0 != (cur_ser_info->ser_flags & _SOC_SER_FLAG_REMAP_READ)) {
   1840 #ifdef BCM_TRIDENT2_SUPPORT
   1841             if (SOC_IS_TD2_TT2(unit)) {
   1842                 if (soc_feature(unit, soc_feature_l3_defip_map)) {
   1843                     /* coverity[Improper use of negative value]*/
   1844                     phys_index_min =
   1845                         soc_trident2_l3_defip_index_map(unit,
   1846                                                         cur_ser_info->mem,
   1847                                                         index_min);
   1848                     /* coverity[Improper use of negative value]*/
   1849                     phys_index_max =
   1850                         soc_trident2_l3_defip_index_map(unit,
   1851                                                         cur_ser_info->mem,
   1852                                                         index_max);
   1853                 }
   1854             }
   1855 #endif /* BCM_TRIDENT2_SUPPORT */
   1856 #ifdef BCM_APACHE_SUPPORT
   1857             if (SOC_IS_APACHE(unit) &&  !SOC_IS_MONTEREY(unit)){
   1858                 phys_index_min =
   1859                     soc_apache_l3_defip_index_map(unit,
   1860                                                   cur_ser_info->mem,
   1861                                                   index_min);
   1862                 phys_index_max =
   1863                     soc_apache_l3_defip_index_map(unit,
   1864                                                   cur_ser_info->mem,
   1865                                                   index_max);
   1866             }
   1867 #endif /* BCM_APACHE_SUPPORT */
   1868 #ifdef BCM_MONTEREY_SUPPORT
   1869             if (SOC_IS_MONTEREY(unit)) {
   1870                 phys_index_min =
   1871                     soc_monterey_l3_defip_index_map(unit,
   1872                                                   cur_ser_info->mem,
   1873                                                   index_min);
   1874                 phys_index_max =
   1875                     soc_monterey_l3_defip_index_map(unit,
   1876                                                   cur_ser_info->mem,
   1877                                                   index_max);
   1878             }
   1879 #endif /* BCM_MONTEREY_SUPPORT */
   1880 #ifdef BCM_HELIX4_SUPPORT
   1881             if (SOC_IS_HELIX4(unit)) {
   1882                 /* Helix4 uses the Triumph3 mapping logic */
   1883                 phys_index_min =
   1884                     soc_tr3_l3_defip_index_map(unit,
   1885                                                cur_ser_info->mem,
   1886                                                index_min);
   1887                 phys_index_max =
   1888                     soc_tr3_l3_defip_index_map(unit,
   1889                                                cur_ser_info->mem,
   1890                                                index_max);
   1891             }
   1892 #endif /* BCM_HELIX4_SUPPORT */
   1893 #ifdef BCM_KATANA2_SUPPORT
   1894             if (SOC_IS_KATANA2(unit)) {
   1895                 phys_index_min =
   1896                     soc_kt2_l3_defip_index_map(unit,
   1897                                                cur_ser_info->mem,
   1898                                                index_min);
   1899                 phys_index_max =
   1900                     soc_kt2_l3_defip_index_map(unit,
   1901                                                cur_ser_info->mem,
   1902                                                index_max);
   1903             }
   1904 #endif /* BCM_KATANA2_SUPPORT */
   1905         }
   1906         ser_mem_count = phys_index_max - phys_index_min + 1;
   1907         if (!ser_mem_count) {
   1908             LOG_ERROR(BSL_LS_SOC_SER,
   1909                       (BSL_META_U(unit,
   1910                                   "SER parity failure with unavailable mem range !!\n")));
   1911             return SOC_E_NONE;
   1912         }
   1913         SOC_MEM_BLOCK_ITER(unit, cur_ser_info->mem, copyno) {
   1914             break;
   1915         }
   1916         start_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno,
   1917                                        phys_index_min, &at);
   1918         end_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno,
   1919                                      phys_index_max, &at);
   1920         if ((addr >= start_addr) && (addr <= end_addr)) {
   1921             /* Addr in memory range */
   1922             mem_index = (addr - start_addr) + phys_index_min;
   1923             if (0 != (cur_ser_info->ser_flags & _SOC_SER_FLAG_REMAP_READ)) {
   1924                 /* Now, mem_index is the physical index.
   1925                  * The correction routines expect the logical index.
   1926                  * Reverse the mapping.
   1927                  */
   1928 #ifdef BCM_APACHE_SUPPORT
   1929                 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
   1930                     mem_index =
   1931                         soc_apache_l3_defip_index_remap(unit,
   1932                                                         cur_ser_info->mem,
   1933                                                         mem_index);
   1934                 }
   1935 #endif /* BCM_APACHE_SUPPORT */
   1936 #ifdef BCM_MONTEREY_SUPPORT
   1937                 if (SOC_IS_MONTEREY(unit)) {
   1938                     mem_index =
   1939                         soc_monterey_l3_defip_index_remap(unit,
   1940                                                         cur_ser_info->mem,
   1941                                                         mem_index);
   1942                 }
   1943 #endif
   1944 #ifdef BCM_HELIX4_SUPPORT
   1945                 if (SOC_IS_HELIX4(unit)) {
   1946                     /* Helix4 uses the Triumph3 remapping logic */
   1947                     /* Coverity
   1948                      * return value of mem_index from TRIDENT2
   1949                      * case will not affect HELIX4_SUPPORT case
   1950                      */
   1951                     /* coverity[negative_returns] */
   1952                     mem_index =
   1953                         soc_tr3_l3_defip_index_remap(unit,
   1954                                                      cur_ser_info->mem,
   1955                                                      mem_index);
   1956                 }
   1957 #endif /* BCM_HELIX4_SUPPORT */
   1958 #ifdef BCM_KATANA2_SUPPORT
   1959                 if (SOC_IS_KATANA2(unit)) {
   1960                     /* coverity[negative_returns] */
   1961                     mem_index =
   1962                         soc_kt2_l3_defip_index_remap(unit,
   1963                                                      cur_ser_info->mem,
   1964                                                      mem_index);
   1965                 }
   1966 #endif /* BCM_KATANA2_SUPPORT */
   1967             }
   1968 
   1969             cur_mem = cur_ser_info->mem;
   1970 #if defined(SOC_UNIQUE_ACC_TYPE_ACCESS)
   1971             if ((cur_ser_info->ser_flags & _SOC_SER_FLAG_ACC_TYPE_CHK) &&
   1972                 soc_feature(unit, soc_feature_unique_acc_type_access) &&
   1973                 (SOC_MEM_UNIQUE_ACC(unit, cur_ser_info->mem) != NULL)) {
   1974                     cur_mem = SOC_MEM_UNIQUE_ACC(unit,
   1975                                                  cur_ser_info->mem)[acc_type];
   1976                     if (!SOC_MEM_IS_VALID(unit, cur_mem)) {
   1977                         LOG_WARN(BSL_LS_SOC_SER,
   1978                                   (BSL_META_U(unit, "Assume _PIPE0 view for ser_correction - could not find unique view for mem %s, acc_type %d \n"),
   1979                                    SOC_MEM_NAME(unit, cur_ser_info->mem), acc_type));
   1980                         cur_mem = SOC_MEM_UNIQUE_ACC(
   1981                                       unit, cur_ser_info->mem)[0];
   1982                     }
   1983             }
   1984 #endif /* SOC_UNIQUE_ACC_TYPE_ACCESS */
   1985 
   1986 #if defined(BCM_TRIDENT2_SUPPORT)
   1987         if (SOC_IS_TD2_TT2(unit)) {
   1988             if (cur_mem == L3_DEFIP_PAIR_128m || cur_mem == L3_DEFIPm) {
   1989                 /* We cannot be here for any L3_DEFIP_ALPM views or
   1990                  * for L3_DEFIP_AUX_TABLE views */
   1991                 is_l3_defip = TRUE;
   1992                 _ALPM_LOCK(unit);
   1993             }
   1994         }
   1995 #endif
   1996 
   1997 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \
   1998     defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   1999     defined(BCM_GREYHOUND_SUPPORT)
   2000             MEM_LOCK(unit, cur_mem);
   2001             corrupt = SOC_MEM_STATE(unit, cur_mem).corrupt[copyno];
   2002             /* For L3_DEFIP* tables, we cannot use cache for SER correction on
   2003              * multi-pipe devices. Because the data may be updated by H/W.
   2004              */
   2005             if (is_l3_defip && NUM_PIPE(unit) > 1) {
   2006                 corrupt = NULL;
   2007             }
   2008             /* coverity[negative_shift] */
   2009             if ((corrupt == NULL) || (TCAM_CORRUPT_MAP_TST(corrupt, mem_index))) {
   2010 #endif
   2011                 LOG_WARN(BSL_LS_SOC_SER,
   2012                           (BSL_META_U(unit,
   2013                                       "Unit %d: %s entry %d TCAM parity error\n"),
   2014                            unit, SOC_MEM_NAME(unit, cur_mem),
   2015                            mem_index));
   2016                 /* The value of err_type vary depending different chip since the
   2017                  * err_type is defined in the chip related code specially. The
   2018                  * original code just used the err_type as the event type directly,
   2019                  * as a result, the events reported in different chip are different.
   2020                  * In fact the only thing needed here is a
   2021                  * SOC_SWITCH_EVENT_DATA_ERROR_PARITY raised.
   2022                  * So err_type is never known.
   2023                  */
   2024                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2025                                    SOC_SWITCH_EVENT_DATA_ERROR_PARITY, addr, 0);
   2026                 stat->ser_err_tcam++;
   2027                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   2028                 spci.reg = INVALIDr;
   2029                 spci.mem = cur_mem;
   2030                 spci.blk_type = copyno;
   2031                 spci.index = mem_index;
   2032                 spci.acc_type = acc_type;
   2033                 spci.addr = addr;
   2034 
   2035 #if defined(BCM_TOMAHAWK_SUPPORT)
   2036                 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   2037                     if (acc_type <= _SOC_MEM_ADDR_ACC_TYPE_PIPE_3) {
   2038                         spci.pipe_num = acc_type;
   2039                     } else {
   2040                         spci.pipe_num = 0;
   2041                     }
   2042                 } else
   2043 #endif /* BCM_TOMAHAWK_SUPPORT */
   2044                 {
   2045                     spci.pipe_num =
   2046                         (_SOC_MEM_ADDR_ACC_TYPE_PIPE_Y == acc_type) ? 1 : 0;
   2047                 }
   2048                 spci.detect_time = sal_time_usecs();
   2049                 spci.log_id = soc_ser_log_create_entry(unit,
   2050                     sizeof(soc_ser_log_tlv_generic_t) +
   2051                     sizeof(soc_ser_log_tlv_memory_t) +
   2052                     sizeof(soc_ser_log_tlv_hdr_t) *3);
   2053                 rv = soc_ser_correction(unit, &spci);
   2054                 if (spci.log_id != 0) {
   2055                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2056                             SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   2057                             spci.log_id, 0);
   2058                 }
   2059                 if (SOC_FAILURE(rv)) {
   2060 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \
   2061     defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   2062     defined(BCM_GREYHOUND_SUPPORT)
   2063 
   2064                     MEM_UNLOCK(unit, cur_mem);
   2065 #endif
   2066                     /* Report failed to correct event flag to
   2067                      * application */
   2068                     soc_event_generate(unit,
   2069                                 SOC_SWITCH_EVENT_PARITY_ERROR,
   2070                                 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   2071                                 addr,
   2072                                 0);
   2073                     block_type = SOC_BLOCK_INFO(unit, copyno).type;
   2074                     soc_ser_stat_update(unit, SOC_SER_STAT_TCAM, block_type,
   2075                                         SOC_PARITY_TYPE_PARITY,
   2076                                         spci.double_bit,
   2077                                         SocSerCorrectTypeFailedToCorrect,
   2078                                         stat);
   2079                     _ALPM_UNLOCK(unit);
   2080                     return rv;
   2081                 }
   2082 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \
   2083     defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   2084     defined(BCM_GREYHOUND_SUPPORT)
   2085                 /* Clear corrupt bit after correction, no matter how many times
   2086                  * the parity error at this index in this table has been detected.
   2087                  */
   2088                 if (corrupt != NULL) {
   2089                     TCAM_CORRUPT_MAP_CLR(corrupt, mem_index);
   2090                 }
   2091                 LOG_VERBOSE(BSL_LS_SOC_SER,
   2092                             (BSL_META_U(unit,
   2093                                         "Unit %d: %s entry %d TCAM parity error indicating bit is cleared.\n"),
   2094                              unit, SOC_MEM_NAME(unit, cur_mem),
   2095                              mem_index));
   2096             }
   2097         MEM_UNLOCK(unit, cur_mem);
   2098 #endif
   2099         _ALPM_UNLOCK(unit);
   2100         }
   2101         SOC_IF_ERROR_RETURN(READ_SER_ERROR_0r(unit, &ser_err[0]));
   2102         SOC_IF_ERROR_RETURN(READ_SER_ERROR_1r(unit, &ser_err[1]));
   2103     } while (soc_reg_field_get(unit, SER_ERROR_0r, ser_err[0], ERROR_0_VALf) ||
   2104              soc_reg_field_get(unit, SER_ERROR_1r, ser_err[1], ERROR_1_VALf));
   2105     SOC_IF_ERROR_RETURN(READ_SER_MISSED_EVENTr(unit, &count));
   2106     if (count) {
   2107         LOG_VERBOSE(BSL_LS_SOC_SER,
   2108                     (BSL_META_U(unit,
   2109                                 "Overflow events: %d.\n"), count));
   2110     }
   2111     return SOC_E_NONE;
   2112 }
   2113 
   2114 int
   2115 soc_generic_ser_init(int unit, _soc_generic_ser_info_t *ser_info)
   2116 {
   2117     int info_ix, hw_ser_ix;
   2118     int index_min=0, index_max=0, copyno, ser_mem_gran;
   2119     int i = 0, ser_mem_count;
   2120     uint32 rval = 0, start_addr, end_addr;
   2121     uint32 addr_valid = 0, ser_mem_addr = 0, ser_mem_total = 0;
   2122     uint32 acc_type, at_bmp;
   2123     _soc_generic_ser_info_t *cur_ser_info;
   2124     ser_memory_entry_t ser_mem;
   2125     uint8 at, alias;
   2126 
   2127     static soc_reg_t range_cfg[] = {
   2128         SER_RANGE_0_CONFIGr, SER_RANGE_1_CONFIGr, SER_RANGE_2_CONFIGr,
   2129         SER_RANGE_3_CONFIGr,
   2130         SER_RANGE_4_CONFIGr, SER_RANGE_5_CONFIGr, SER_RANGE_6_CONFIGr,
   2131         SER_RANGE_7_CONFIGr,
   2132         SER_RANGE_8_CONFIGr, SER_RANGE_9_CONFIGr, SER_RANGE_10_CONFIGr,
   2133         SER_RANGE_11_CONFIGr,
   2134         SER_RANGE_12_CONFIGr, SER_RANGE_13_CONFIGr, SER_RANGE_14_CONFIGr,
   2135         SER_RANGE_15_CONFIGr,
   2136         SER_RANGE_16_CONFIGr, SER_RANGE_17_CONFIGr, SER_RANGE_18_CONFIGr,
   2137         SER_RANGE_19_CONFIGr,
   2138         SER_RANGE_20_CONFIGr, SER_RANGE_21_CONFIGr, SER_RANGE_22_CONFIGr,
   2139         SER_RANGE_23_CONFIGr,
   2140         SER_RANGE_24_CONFIGr, SER_RANGE_25_CONFIGr, SER_RANGE_26_CONFIGr,
   2141         SER_RANGE_27_CONFIGr,
   2142         SER_RANGE_28_CONFIGr, SER_RANGE_29_CONFIGr, SER_RANGE_30_CONFIGr,
   2143         SER_RANGE_31_CONFIGr
   2144     };
   2145     static soc_reg_t addr_mask[] = {
   2146         SER_RANGE_0_ADDR_MASKr, SER_RANGE_1_ADDR_MASKr, SER_RANGE_2_ADDR_MASKr,
   2147         SER_RANGE_3_ADDR_MASKr,
   2148         SER_RANGE_4_ADDR_MASKr, SER_RANGE_5_ADDR_MASKr, SER_RANGE_6_ADDR_MASKr,
   2149         SER_RANGE_7_ADDR_MASKr,
   2150         SER_RANGE_8_ADDR_MASKr, SER_RANGE_9_ADDR_MASKr, SER_RANGE_10_ADDR_MASKr,
   2151         SER_RANGE_11_ADDR_MASKr,
   2152         SER_RANGE_12_ADDR_MASKr, SER_RANGE_13_ADDR_MASKr, SER_RANGE_14_ADDR_MASKr,
   2153         SER_RANGE_15_ADDR_MASKr,
   2154         SER_RANGE_16_ADDR_MASKr, SER_RANGE_17_ADDR_MASKr, SER_RANGE_18_ADDR_MASKr,
   2155         SER_RANGE_19_ADDR_MASKr,
   2156         SER_RANGE_20_ADDR_MASKr, SER_RANGE_21_ADDR_MASKr, SER_RANGE_22_ADDR_MASKr,
   2157         SER_RANGE_23_ADDR_MASKr,
   2158         SER_RANGE_24_ADDR_MASKr, SER_RANGE_25_ADDR_MASKr, SER_RANGE_26_ADDR_MASKr,
   2159         SER_RANGE_27_ADDR_MASKr,
   2160         SER_RANGE_28_ADDR_MASKr, SER_RANGE_29_ADDR_MASKr, SER_RANGE_30_ADDR_MASKr,
   2161         SER_RANGE_31_ADDR_MASKr
   2162     };
   2163     static soc_reg_t range_start[] = {
   2164         SER_RANGE_0_STARTr, SER_RANGE_1_STARTr, SER_RANGE_2_STARTr,
   2165         SER_RANGE_3_STARTr,
   2166         SER_RANGE_4_STARTr, SER_RANGE_5_STARTr, SER_RANGE_6_STARTr,
   2167         SER_RANGE_7_STARTr,
   2168         SER_RANGE_8_STARTr, SER_RANGE_9_STARTr, SER_RANGE_10_STARTr,
   2169         SER_RANGE_11_STARTr,
   2170         SER_RANGE_12_STARTr, SER_RANGE_13_STARTr, SER_RANGE_14_STARTr,
   2171         SER_RANGE_15_STARTr,
   2172         SER_RANGE_16_STARTr, SER_RANGE_17_STARTr, SER_RANGE_18_STARTr,
   2173         SER_RANGE_19_STARTr,
   2174         SER_RANGE_20_STARTr, SER_RANGE_21_STARTr, SER_RANGE_22_STARTr,
   2175         SER_RANGE_23_STARTr,
   2176         SER_RANGE_24_STARTr, SER_RANGE_25_STARTr, SER_RANGE_26_STARTr,
   2177         SER_RANGE_27_STARTr,
   2178         SER_RANGE_28_STARTr, SER_RANGE_29_STARTr, SER_RANGE_30_STARTr,
   2179         SER_RANGE_31_STARTr
   2180     };
   2181     static soc_reg_t range_end[] = {
   2182         SER_RANGE_0_ENDr, SER_RANGE_1_ENDr, SER_RANGE_2_ENDr, SER_RANGE_3_ENDr,
   2183         SER_RANGE_4_ENDr, SER_RANGE_5_ENDr, SER_RANGE_6_ENDr, SER_RANGE_7_ENDr,
   2184         SER_RANGE_8_ENDr, SER_RANGE_9_ENDr, SER_RANGE_10_ENDr, SER_RANGE_11_ENDr,
   2185         SER_RANGE_12_ENDr, SER_RANGE_13_ENDr, SER_RANGE_14_ENDr, SER_RANGE_15_ENDr,
   2186         SER_RANGE_16_ENDr, SER_RANGE_17_ENDr, SER_RANGE_18_ENDr, SER_RANGE_19_ENDr,
   2187         SER_RANGE_20_ENDr, SER_RANGE_21_ENDr, SER_RANGE_22_ENDr, SER_RANGE_23_ENDr,
   2188         SER_RANGE_24_ENDr, SER_RANGE_25_ENDr, SER_RANGE_26_ENDr, SER_RANGE_27_ENDr,
   2189         SER_RANGE_28_ENDr, SER_RANGE_29_ENDr, SER_RANGE_30_ENDr, SER_RANGE_31_ENDr
   2190     };
   2191     static soc_reg_t range_result[] = {
   2192         SER_RANGE_0_RESULTr, SER_RANGE_1_RESULTr, SER_RANGE_2_RESULTr,
   2193         SER_RANGE_3_RESULTr,
   2194         SER_RANGE_4_RESULTr, SER_RANGE_5_RESULTr, SER_RANGE_6_RESULTr,
   2195         SER_RANGE_7_RESULTr,
   2196         SER_RANGE_8_RESULTr, SER_RANGE_9_RESULTr, SER_RANGE_10_RESULTr,
   2197         SER_RANGE_11_RESULTr,
   2198         SER_RANGE_12_RESULTr, SER_RANGE_13_RESULTr, SER_RANGE_14_RESULTr,
   2199         SER_RANGE_15_RESULTr,
   2200         SER_RANGE_16_RESULTr, SER_RANGE_17_RESULTr, SER_RANGE_18_RESULTr,
   2201         SER_RANGE_19_RESULTr,
   2202         SER_RANGE_20_RESULTr, SER_RANGE_21_RESULTr, SER_RANGE_22_RESULTr,
   2203         SER_RANGE_23_RESULTr,
   2204         SER_RANGE_24_RESULTr, SER_RANGE_25_RESULTr, SER_RANGE_26_RESULTr,
   2205         SER_RANGE_27_RESULTr,
   2206         SER_RANGE_28_RESULTr, SER_RANGE_29_RESULTr, SER_RANGE_30_RESULTr,
   2207         SER_RANGE_31_RESULTr
   2208     };
   2209     static soc_reg_t prot_word[][SOC_NUM_GENERIC_PROT_SECTIONS] = {
   2210         { SER_RANGE_0_PROT_WORD_0r, SER_RANGE_0_PROT_WORD_1r,
   2211           SER_RANGE_0_PROT_WORD_2r, SER_RANGE_0_PROT_WORD_3r },
   2212         { SER_RANGE_1_PROT_WORD_0r, SER_RANGE_1_PROT_WORD_1r,
   2213           SER_RANGE_1_PROT_WORD_2r, SER_RANGE_1_PROT_WORD_3r },
   2214         { SER_RANGE_2_PROT_WORD_0r, SER_RANGE_2_PROT_WORD_1r,
   2215           SER_RANGE_2_PROT_WORD_2r, SER_RANGE_2_PROT_WORD_3r },
   2216         { SER_RANGE_3_PROT_WORD_0r, SER_RANGE_3_PROT_WORD_1r,
   2217           SER_RANGE_3_PROT_WORD_2r, SER_RANGE_3_PROT_WORD_3r },
   2218         { SER_RANGE_4_PROT_WORD_0r, SER_RANGE_4_PROT_WORD_1r,
   2219           SER_RANGE_4_PROT_WORD_2r, SER_RANGE_4_PROT_WORD_3r },
   2220         { SER_RANGE_5_PROT_WORD_0r, SER_RANGE_5_PROT_WORD_1r,
   2221           SER_RANGE_5_PROT_WORD_2r, SER_RANGE_5_PROT_WORD_3r },
   2222         { SER_RANGE_6_PROT_WORD_0r, SER_RANGE_6_PROT_WORD_1r,
   2223           SER_RANGE_6_PROT_WORD_2r, SER_RANGE_6_PROT_WORD_3r },
   2224         { SER_RANGE_7_PROT_WORD_0r, SER_RANGE_7_PROT_WORD_1r,
   2225           SER_RANGE_7_PROT_WORD_2r, SER_RANGE_7_PROT_WORD_3r },
   2226         { SER_RANGE_8_PROT_WORD_0r, SER_RANGE_8_PROT_WORD_1r,
   2227           SER_RANGE_8_PROT_WORD_2r, SER_RANGE_8_PROT_WORD_3r },
   2228         { SER_RANGE_9_PROT_WORD_0r, SER_RANGE_9_PROT_WORD_1r,
   2229           SER_RANGE_9_PROT_WORD_2r, SER_RANGE_9_PROT_WORD_3r },
   2230         { SER_RANGE_10_PROT_WORD_0r, SER_RANGE_10_PROT_WORD_1r,
   2231           SER_RANGE_10_PROT_WORD_2r, SER_RANGE_10_PROT_WORD_3r },
   2232         { SER_RANGE_11_PROT_WORD_0r, SER_RANGE_11_PROT_WORD_1r,
   2233           SER_RANGE_11_PROT_WORD_2r, SER_RANGE_11_PROT_WORD_3r },
   2234         { SER_RANGE_12_PROT_WORD_0r, SER_RANGE_12_PROT_WORD_1r,
   2235           SER_RANGE_12_PROT_WORD_2r, SER_RANGE_12_PROT_WORD_3r },
   2236         { SER_RANGE_13_PROT_WORD_0r, SER_RANGE_13_PROT_WORD_1r,
   2237           SER_RANGE_13_PROT_WORD_2r, SER_RANGE_13_PROT_WORD_3r },
   2238         { SER_RANGE_14_PROT_WORD_0r, SER_RANGE_14_PROT_WORD_1r,
   2239           SER_RANGE_14_PROT_WORD_2r, SER_RANGE_14_PROT_WORD_3r },
   2240         { SER_RANGE_15_PROT_WORD_0r, SER_RANGE_15_PROT_WORD_1r,
   2241           SER_RANGE_15_PROT_WORD_2r, SER_RANGE_15_PROT_WORD_3r },
   2242         { SER_RANGE_16_PROT_WORD_0r, SER_RANGE_16_PROT_WORD_1r,
   2243           SER_RANGE_16_PROT_WORD_2r, SER_RANGE_16_PROT_WORD_3r },
   2244         { SER_RANGE_17_PROT_WORD_0r, SER_RANGE_17_PROT_WORD_1r,
   2245           SER_RANGE_17_PROT_WORD_2r, SER_RANGE_17_PROT_WORD_3r },
   2246         { SER_RANGE_18_PROT_WORD_0r, SER_RANGE_18_PROT_WORD_1r,
   2247           SER_RANGE_18_PROT_WORD_2r, SER_RANGE_18_PROT_WORD_3r },
   2248         { SER_RANGE_19_PROT_WORD_0r, SER_RANGE_19_PROT_WORD_1r,
   2249           SER_RANGE_19_PROT_WORD_2r, SER_RANGE_19_PROT_WORD_3r },
   2250         { SER_RANGE_20_PROT_WORD_0r, SER_RANGE_20_PROT_WORD_1r,
   2251           SER_RANGE_20_PROT_WORD_2r, SER_RANGE_20_PROT_WORD_3r },
   2252         { SER_RANGE_21_PROT_WORD_0r, SER_RANGE_21_PROT_WORD_1r,
   2253           SER_RANGE_21_PROT_WORD_2r, SER_RANGE_21_PROT_WORD_3r },
   2254         { SER_RANGE_22_PROT_WORD_0r, SER_RANGE_22_PROT_WORD_1r,
   2255           SER_RANGE_22_PROT_WORD_2r, SER_RANGE_22_PROT_WORD_3r },
   2256         { SER_RANGE_23_PROT_WORD_0r, SER_RANGE_23_PROT_WORD_1r,
   2257           SER_RANGE_23_PROT_WORD_2r, SER_RANGE_23_PROT_WORD_3r },
   2258         { SER_RANGE_24_PROT_WORD_0r, SER_RANGE_24_PROT_WORD_1r,
   2259           SER_RANGE_24_PROT_WORD_2r, SER_RANGE_24_PROT_WORD_3r },
   2260         { SER_RANGE_25_PROT_WORD_0r, SER_RANGE_25_PROT_WORD_1r,
   2261           SER_RANGE_25_PROT_WORD_2r, SER_RANGE_25_PROT_WORD_3r },
   2262         { SER_RANGE_26_PROT_WORD_0r, SER_RANGE_26_PROT_WORD_1r,
   2263           SER_RANGE_26_PROT_WORD_2r, SER_RANGE_26_PROT_WORD_3r },
   2264         { SER_RANGE_27_PROT_WORD_0r, SER_RANGE_27_PROT_WORD_1r,
   2265           SER_RANGE_27_PROT_WORD_2r, SER_RANGE_27_PROT_WORD_3r },
   2266         { SER_RANGE_28_PROT_WORD_0r, SER_RANGE_28_PROT_WORD_1r,
   2267           SER_RANGE_28_PROT_WORD_2r, SER_RANGE_28_PROT_WORD_3r },
   2268         { SER_RANGE_29_PROT_WORD_0r, SER_RANGE_29_PROT_WORD_1r,
   2269           SER_RANGE_29_PROT_WORD_2r, SER_RANGE_29_PROT_WORD_3r },
   2270         { SER_RANGE_30_PROT_WORD_0r, SER_RANGE_30_PROT_WORD_1r,
   2271           SER_RANGE_30_PROT_WORD_2r, SER_RANGE_30_PROT_WORD_3r },
   2272         { SER_RANGE_31_PROT_WORD_0r, SER_RANGE_31_PROT_WORD_1r,
   2273           SER_RANGE_31_PROT_WORD_2r, SER_RANGE_31_PROT_WORD_3r }
   2274     };
   2275 
   2276     static soc_reg_t range_addr_bits[] = {
   2277         SER_RANGE_0_ADDR_BITSr, SER_RANGE_1_ADDR_BITSr,
   2278         SER_RANGE_2_ADDR_BITSr, SER_RANGE_3_ADDR_BITSr,
   2279         SER_RANGE_4_ADDR_BITSr, SER_RANGE_5_ADDR_BITSr,
   2280         SER_RANGE_6_ADDR_BITSr, SER_RANGE_7_ADDR_BITSr,
   2281         SER_RANGE_8_ADDR_BITSr, SER_RANGE_9_ADDR_BITSr,
   2282         SER_RANGE_10_ADDR_BITSr, SER_RANGE_11_ADDR_BITSr,
   2283         SER_RANGE_12_ADDR_BITSr, SER_RANGE_13_ADDR_BITSr,
   2284         SER_RANGE_14_ADDR_BITSr, SER_RANGE_15_ADDR_BITSr,
   2285         SER_RANGE_16_ADDR_BITSr, SER_RANGE_17_ADDR_BITSr,
   2286         SER_RANGE_18_ADDR_BITSr, SER_RANGE_19_ADDR_BITSr,
   2287         SER_RANGE_20_ADDR_BITSr, SER_RANGE_21_ADDR_BITSr,
   2288         SER_RANGE_22_ADDR_BITSr, SER_RANGE_23_ADDR_BITSr,
   2289         SER_RANGE_24_ADDR_BITSr, SER_RANGE_25_ADDR_BITSr,
   2290         SER_RANGE_26_ADDR_BITSr, SER_RANGE_27_ADDR_BITSr,
   2291         SER_RANGE_28_ADDR_BITSr, SER_RANGE_29_ADDR_BITSr,
   2292         SER_RANGE_30_ADDR_BITSr, SER_RANGE_31_ADDR_BITSr
   2293     };
   2294 
   2295     static soc_reg_t range_disable[] = {
   2296         SER_RANGE_0_DISABLEr, SER_RANGE_1_DISABLEr,
   2297         SER_RANGE_2_DISABLEr, SER_RANGE_3_DISABLEr,
   2298         SER_RANGE_4_DISABLEr, SER_RANGE_5_DISABLEr,
   2299         SER_RANGE_6_DISABLEr, SER_RANGE_7_DISABLEr,
   2300         SER_RANGE_8_DISABLEr, SER_RANGE_9_DISABLEr,
   2301         SER_RANGE_10_DISABLEr, SER_RANGE_11_DISABLEr,
   2302         SER_RANGE_12_DISABLEr, SER_RANGE_13_DISABLEr,
   2303         SER_RANGE_14_DISABLEr, SER_RANGE_15_DISABLEr,
   2304         SER_RANGE_16_DISABLEr, SER_RANGE_17_DISABLEr,
   2305         SER_RANGE_18_DISABLEr, SER_RANGE_19_DISABLEr,
   2306         SER_RANGE_20_DISABLEr, SER_RANGE_21_DISABLEr,
   2307         SER_RANGE_22_DISABLEr, SER_RANGE_23_DISABLEr,
   2308         SER_RANGE_24_DISABLEr, SER_RANGE_25_DISABLEr,
   2309         SER_RANGE_26_DISABLEr, SER_RANGE_27_DISABLEr,
   2310         SER_RANGE_28_DISABLEr, SER_RANGE_29_DISABLEr,
   2311         SER_RANGE_30_DISABLEr, SER_RANGE_31_DISABLEr
   2312     };
   2313 
   2314     LOG_VERBOSE(BSL_LS_SOC_SER,
   2315                 (BSL_META_U(unit,
   2316                             "SER engine init:\n")));
   2317 
   2318     info_ix = 0;
   2319     hw_ser_ix = 0;
   2320     sal_memset(&ser_mem, 0, sizeof(ser_mem));
   2321     /* Clear parity/ecc memory */
   2322     if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) {
   2323         SOC_IF_ERROR_RETURN
   2324             (soc_mem_clear(unit, SER_MEMORYm, COPYNO_ALL, TRUE));
   2325     }
   2326     while (ser_info[info_ix].mem != INVALIDm) {
   2327         alias = FALSE;
   2328         cur_ser_info = &(ser_info[info_ix]);
   2329         cur_ser_info->ser_hw_index = -1;
   2330         if ((info_ix > 0) &&
   2331             (cur_ser_info->ser_flags & _SOC_SER_FLAG_CONFIG_SKIP)) {
   2332             /* This entry does not require separate range in ser_engine.
   2333              * But, this entry is used by memscan and therefore must have all
   2334              * the info needed by memscan.
   2335              * This entry should inherit property of previous entry as they map
   2336              * to same range in ser_engine */
   2337             cur_ser_info->ser_section_start =
   2338                 ser_info[info_ix - 1].ser_section_start;
   2339             cur_ser_info->ser_section_end =
   2340                 ser_info[info_ix - 1].ser_section_end;
   2341             cur_ser_info->ser_hw_index =
   2342                 ser_info[info_ix - 1].ser_hw_index;
   2343             info_ix++;
   2344             continue;
   2345         }
   2346 
   2347         if (cur_ser_info->ser_flags & _SOC_SER_FLAG_SW_COMPARE) {
   2348             if (SOC_MEM_INFO(unit, cur_ser_info->mem).flags &
   2349                 SOC_MEM_FLAG_BE) {
   2350                 LOG_ERROR(BSL_LS_SOC_SER,
   2351                           (BSL_META_U(unit,
   2352                                       "\tSW SER init of Big Endian TCAMs is not supported: %s\n"),
   2353                            SOC_MEM_NAME(unit, cur_ser_info->mem)));
   2354                 return SOC_E_INTERNAL;
   2355             }
   2356 
   2357             LOG_VERBOSE(BSL_LS_SOC_SER,
   2358                         (BSL_META_U(unit,
   2359                                     "\tSkipping HW SER init of manual scan mem: %s\n"),
   2360                          SOC_MEM_NAME(unit, cur_ser_info->mem)));
   2361             SOC_MEM_INFO(unit, ser_info[info_ix].mem).flags |= SOC_MEM_FLAG_SER_ENGINE;
   2362             info_ix++;
   2363             continue;
   2364         }
   2365         index_min = soc_mem_index_min(unit, cur_ser_info->mem);
   2366         index_max = soc_mem_index_max(unit, cur_ser_info->mem);
   2367 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   2368         if (soc_feature(unit, soc_feature_l3_defip_map) &&
   2369             ((cur_ser_info->mem == L3_DEFIP_PAIR_128m) ||
   2370              (cur_ser_info->mem == L3_DEFIPm))) {
   2371             /* Override SOC memory impression for overlay
   2372              * LPM tables. */
   2373             index_min = 0;
   2374             index_max = (SOC_CONTROL(unit)->l3_defip_max_tcams *
   2375                          SOC_CONTROL(unit)->l3_defip_tcam_size) - 1;
   2376             if (cur_ser_info->mem == L3_DEFIP_PAIR_128m) {
   2377                 index_max /= 2;
   2378             }
   2379         }
   2380 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT*/
   2381 
   2382         ser_mem_count = index_max - index_min + 1;
   2383         if (!ser_mem_count || !SOC_MEM_IS_VALID(unit, cur_ser_info->mem)) {
   2384             LOG_VERBOSE(BSL_LS_SOC_SER,
   2385                         (BSL_META_U(unit,
   2386                                     "\tSkipping empty mem: %s\n"),
   2387                          SOC_MEM_NAME(unit, cur_ser_info->mem)));
   2388 #if defined(BCM_TOMAHAWK_SUPPORT)
   2389             if (SOC_IS_TOMAHAWKX(unit)) {
   2390                 /* For different latency modes, we want to keep constant map
   2391                  * between info_ix and hw_ser_ix. In other words, if some mem
   2392                  * is not enabled in lower latency mode, we want to keep the
   2393                  * bit position for that mem in SER_RANGE_ENABLE constant
   2394                  * - because in tomahawk/ser.c, this bit position is hard-coded
   2395                  * based on max_latency_mode. Otherwise, we will have to keep
   2396                  * track of this position for mem based on latency modes.
   2397                  */
   2398                 LOG_VERBOSE(BSL_LS_SOC_SER,
   2399                             (BSL_META_U(unit,
   2400                                         "\tRange[%2d](0x%04x, %08d): %s(%d-%d): "
   2401                                         "Sbus range (0x%08x-0x%08x), info_ix=%d, <======= skipped\n"),
   2402                              hw_ser_ix, 0, 0,
   2403                              SOC_MEM_NAME(unit, cur_ser_info->mem),
   2404                              index_min, index_max, 0, 0, info_ix));
   2405                 hw_ser_ix++;
   2406             }
   2407 #endif
   2408             info_ix++;
   2409             continue;
   2410         }
   2411 
   2412         ser_mem_gran = _soc_generic_ser_granularity(cur_ser_info->prot_type,
   2413                                                     cur_ser_info->prot_mode,
   2414                                                     cur_ser_info->start_end_bits);
   2415         ser_mem_count *= ser_mem_gran;
   2416 
   2417         /* Round up to entry size for simplicity */
   2418         ser_mem_count = ((ser_mem_count + 31) / 32); /* Changed from 36 per DE input */
   2419 
   2420         if (cur_ser_info->alias_mem != INVALIDm) {
   2421             /* See if the aliased memory has already been configured */
   2422             for (i = 0; i < info_ix; i++) {
   2423                 if (ser_info[i].mem == cur_ser_info->alias_mem) {
   2424                     LOG_VERBOSE(BSL_LS_SOC_SER,
   2425                                 (BSL_META_U(unit,
   2426                                             "\tSER alias mem.\n")));
   2427                     alias = TRUE;
   2428                     break;
   2429                 }
   2430             }
   2431         }
   2432 
   2433         if (!alias && (cur_ser_info->ser_flags & _SOC_SER_FLAG_ACC_TYPE_CHK)) {
   2434            ser_mem_count *= cur_ser_info->num_instances;
   2435         }
   2436 
   2437         if (!alias &&
   2438             (cur_ser_info->ser_flags & _SOC_SER_FLAG_MULTI_PIPE)) {
   2439             i = info_ix - 1;
   2440             if ((i >= 0) && (ser_info[i].mem == cur_ser_info->mem) &&
   2441                 !(ser_info[i].ser_flags & _SOC_SER_FLAG_CONFIG_SKIP)) {
   2442                 /* For multiple pipeline units, different pipeline's hardware
   2443                  * instances are duplicates.  The SER parity bits are thus
   2444                  * shared, but the configuration registers in the CMIC
   2445                  * must be different to capture the different SBUS ranges
   2446                  * of the read accesses.
   2447                  */
   2448                 LOG_VERBOSE(BSL_LS_SOC_SER,
   2449                             (BSL_META_U(unit,
   2450                                         "\tSER multiple pipeline mem.\n")));
   2451                 /* Get the non-default pipeline access type */
   2452                 acc_type = cur_ser_info->ser_flags &
   2453                     _SOC_SER_FLAG_ACC_TYPE_MASK;
   2454 
   2455                 /* Copy info for mem clear */
   2456                 cur_ser_info->ser_section_start =
   2457                     ser_info[i].ser_section_start;
   2458                 cur_ser_info->ser_section_end =
   2459                     ser_info[i].ser_section_end;
   2460                 cur_ser_info->ser_hw_index =
   2461                     ser_info[i].ser_hw_index;
   2462 
   2463                 /* For multi-pipe, we can use the access type bitmap
   2464                  * point multiple SBUS accesses to the same HW
   2465                  * range checker.
   2466                  * The HW index advanced when the first entry was set,
   2467                  * so we need to use the previous valid HW index. */
   2468                 if (0 == hw_ser_ix) {
   2469                     return SOC_E_INTERNAL;
   2470                 }
   2471                 SOC_IF_ERROR_RETURN
   2472                     (soc_reg32_set(unit, range_cfg[hw_ser_ix - 1],
   2473                                    REG_PORT_ANY, 0, rval));
   2474                 at_bmp =
   2475                     soc_reg_field_get(unit, SER_RANGE_0_CONFIGr, rval,
   2476                                       ACC_TYPEf);
   2477                 at_bmp |= (1 << acc_type);
   2478                 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval,
   2479                                   ACC_TYPEf, at_bmp);
   2480                 SOC_IF_ERROR_RETURN
   2481                     (soc_reg32_set(unit, range_cfg[hw_ser_ix - 1],
   2482                                    REG_PORT_ANY, 0, rval));
   2483                 info_ix++;
   2484                 /* Don't advance hw_ser_ix again in case of designs with
   2485                  * more than two pipes */
   2486                 continue;
   2487             }
   2488         }
   2489 
   2490         if (!alias && ((ser_mem_count + ser_mem_total) >
   2491                        soc_mem_index_count(unit, SER_MEMORYm))) {
   2492             /* Can't fit requested parity bits in SER memory */
   2493             LOG_VERBOSE(BSL_LS_SOC_SER,
   2494                         (BSL_META_U(unit,
   2495                                     "SER mem full: Skipping further config.\n")));
   2496             break;
   2497         }
   2498 
   2499         /* Parity bits fit, so on with the config */
   2500         SOC_MEM_BLOCK_ITER(unit, cur_ser_info->mem, copyno) {
   2501             break;
   2502         }
   2503         start_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno,
   2504                                       index_min, &at);
   2505         end_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno,
   2506                                     index_max, &at);
   2507 
   2508         /* Flush SER memory if not aliased */
   2509         ser_mem_addr = alias ? ser_info[i].ser_section_start :
   2510                                ser_mem_total; /* Previous total */
   2511         if (alias) {
   2512             LOG_VERBOSE(BSL_LS_SOC_SER,
   2513                         (BSL_META_U(unit,
   2514                                     "\tReuse SER_MEM (%d) from index: %d - %d\n"),
   2515                          ser_mem_count, ser_info[i].ser_section_start,
   2516                          ser_info[i].ser_section_end));
   2517         } else {
   2518             ser_mem_total += ser_mem_count; /* New total */
   2519             LOG_VERBOSE(BSL_LS_SOC_SER,
   2520                         (BSL_META_U(unit,
   2521                                     "\tClear SER_MEM (%d) from index: %d - %d\n"),
   2522                          ser_mem_count, ser_mem_addr, ser_mem_total-1));
   2523             for (i = ser_mem_addr; i < ser_mem_total; i++) {
   2524                 /* mem clear */
   2525                 SOC_IF_ERROR_RETURN
   2526                     (WRITE_SER_MEMORYm(unit, MEM_BLOCK_ALL, i, &ser_mem));
   2527             }
   2528         }
   2529 
   2530         /* Record section for mem_clear use */
   2531         cur_ser_info->ser_section_start = ser_mem_addr;
   2532         cur_ser_info->ser_section_end = alias ? ser_info[i].ser_section_end :
   2533                                                 (ser_mem_total-1);
   2534         cur_ser_info->ser_hw_index = hw_ser_ix;
   2535 
   2536         SOC_IF_ERROR_RETURN
   2537             (soc_reg32_set(unit, range_start[hw_ser_ix], REG_PORT_ANY, 0,
   2538                            start_addr));
   2539         SOC_IF_ERROR_RETURN
   2540             (soc_reg32_set(unit, range_end[hw_ser_ix], REG_PORT_ANY, 0,
   2541                            end_addr));
   2542         if (SOC_REG_IS_VALID(unit, range_disable[0])) {
   2543             if (cur_ser_info->ser_flags & _SOC_SER_FLAG_RANGE_DISABLE) {
   2544                 SOC_IF_ERROR_RETURN
   2545                     (soc_reg32_set(unit, range_addr_bits[hw_ser_ix], REG_PORT_ANY, 0,
   2546                                cur_ser_info->addr_start_bit));
   2547                 SOC_IF_ERROR_RETURN
   2548                     (soc_reg32_set(unit, range_disable[hw_ser_ix], REG_PORT_ANY, 0,
   2549                                cur_ser_info->addr_mask));
   2550             }
   2551         } else {
   2552             SOC_IF_ERROR_RETURN
   2553                 (soc_reg32_set(unit, addr_mask[hw_ser_ix], REG_PORT_ANY, 0,
   2554                            cur_ser_info->addr_mask ?
   2555                            cur_ser_info->addr_mask : 0xffffffff));
   2556         }
   2557         SOC_IF_ERROR_RETURN
   2558             (soc_reg32_set(unit, range_result[hw_ser_ix], REG_PORT_ANY, 0,
   2559                            ser_mem_addr));
   2560         if ((!(cur_ser_info->ser_flags & _SOC_SER_FLAG_VIEW_DISABLE)) &&
   2561             (!(SOC_MEM_INFO(unit, cur_ser_info->mem).flags &
   2562                SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP))) {
   2563             addr_valid |= (1 << hw_ser_ix);
   2564         }
   2565 
   2566         for (i = 0; i < SOC_NUM_GENERIC_PROT_SECTIONS; i++) {
   2567             if (cur_ser_info->start_end_bits[i].start_bit != -1) {
   2568                 rval = 0;
   2569                 soc_reg_field_set(unit, SER_RANGE_0_PROT_WORD_0r, &rval,
   2570                                   DATA_STARTf,
   2571                                   cur_ser_info->start_end_bits[i].start_bit);
   2572                 soc_reg_field_set(unit, SER_RANGE_0_PROT_WORD_0r, &rval,
   2573                                   DATA_ENDf,
   2574                                   cur_ser_info->start_end_bits[i].end_bit);
   2575                 SOC_IF_ERROR_RETURN
   2576                     (soc_reg32_set(unit, prot_word[hw_ser_ix][i],
   2577                                    REG_PORT_ANY, 0, rval));
   2578             }
   2579         }
   2580         rval = 0;
   2581         soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, BLOCKf,
   2582                           SOC_BLOCK2SCH(unit, copyno));
   2583         if (soc_reg_field_valid(unit, SER_RANGE_0_CONFIGr, ACC_TYPEf)) {
   2584             soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, ACC_TYPEf,
   2585                               1 << at);
   2586         }
   2587 #if defined(BCM_TOMAHAWK_SUPPORT)
   2588         if (soc_reg_field_valid(unit, SER_RANGE_0_CONFIGr, ACC_TYPE_MODEf)) {
   2589             soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, ACC_TYPE_MODEf,
   2590                               (cur_ser_info->ser_flags & _SOC_SER_FLAG_ACC_TYPE_CHK)? 1 : 0);
   2591         }
   2592 #endif /* BCM_TOMAHAWK_SUPPORT */
   2593         soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, PROT_TYPEf,
   2594                           cur_ser_info->prot_type);
   2595         soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, PROT_MODEf,
   2596                           cur_ser_info->prot_mode);
   2597         soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, INTERLEAVE_MODEf,
   2598                           cur_ser_info->intrlv_mode);
   2599         SOC_IF_ERROR_RETURN
   2600             (soc_reg32_set(unit, range_cfg[hw_ser_ix], REG_PORT_ANY, 0, rval));
   2601 
   2602         LOG_VERBOSE(BSL_LS_SOC_SER,
   2603                     (BSL_META_U(unit,
   2604                                 "\tRange[%2d](0x%04x, %08d): %s(%d-%d): "
   2605                                 "Sbus range (0x%08x-0x%08x), info_ix=%d\n"),
   2606                      hw_ser_ix, ser_mem_addr, ser_mem_addr,
   2607                      SOC_MEM_NAME(unit, cur_ser_info->mem),
   2608                      index_min, index_max, start_addr, end_addr, info_ix));
   2609         SOC_MEM_INFO(unit, ser_info[info_ix].mem).flags |= SOC_MEM_FLAG_SER_ENGINE;
   2610 #if defined(SOC_UNIQUE_ACC_TYPE_ACCESS)
   2611         if (soc_feature(unit, soc_feature_unique_acc_type_access) &&
   2612             (SOC_MEM_UNIQUE_ACC(unit, ser_info[info_ix].mem) != NULL)) {
   2613             int pipe;
   2614             soc_mem_t mem1 = ser_info[info_ix].mem;
   2615             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2616                 SOC_MEM_INFO(unit,
   2617                              SOC_MEM_UNIQUE_ACC(unit, mem1)[pipe]
   2618                              ).flags |= SOC_MEM_FLAG_SER_ENGINE;
   2619             }
   2620             /* Non-tcam-iterations loop should also skip the _PIPE0,1,2,3,etc
   2621              * views */
   2622         }
   2623 #endif /* SOC_UNIQUE_ACC_TYPE_ACCESS */
   2624         info_ix++;
   2625         hw_ser_ix++;
   2626     }
   2627 
   2628     SOC_IF_ERROR_RETURN
   2629         (WRITE_SER_RING_ERR_CTRLr(unit, 0xf));
   2630     /* Enable SER protection last */
   2631     SOC_IF_ERROR_RETURN
   2632         (WRITE_SER_RANGE_ENABLEr(unit, addr_valid));
   2633     if (soc_feature(unit, soc_feature_ser_hw_bg_read)) {
   2634         SOC_IF_ERROR_RETURN
   2635             (WRITE_SER_CONFIG_REGr(unit, 0x3));
   2636     } else {
   2637         SOC_IF_ERROR_RETURN
   2638             (WRITE_SER_CONFIG_REGr(unit, 0x1));
   2639     }
   2640     /* Kick off s/w background scan if applicable */
   2641     if (!soc_feature(unit, soc_feature_ser_hw_bg_read)) {
   2642 
   2643     }
   2644     return SOC_E_NONE;
   2645 }
   2646 
   2647 int
   2648 soc_generic_ser_at_map_init(int unit, uint32 map[], int items)
   2649 {
   2650     int i = 0;
   2651     uint32 fld_val;
   2652     ser_acc_type_map_entry_t ser_acc_type;
   2653 
   2654     if (items > soc_mem_index_count(unit, SER_ACC_TYPE_MAPm)) {
   2655         return SOC_E_PARAM;
   2656     }
   2657     while (items--) {
   2658         sal_memset(&ser_acc_type, 0, sizeof(ser_acc_type));
   2659         fld_val = map[i];
   2660         soc_mem_field_set(unit, SER_ACC_TYPE_MAPm,
   2661                           (uint32 *)&ser_acc_type, COMPRESSED_ACC_TYPEf, &fld_val);
   2662         SOC_IF_ERROR_RETURN
   2663             (soc_mem_write(unit, SER_ACC_TYPE_MAPm, MEM_BLOCK_ALL, i++,
   2664                            &ser_acc_type));
   2665     }
   2666     return SOC_E_NONE;
   2667 }
   2668 
   2669 int
   2670 soc_generic_ser_mem_scan_start(int unit)
   2671 {
   2672 #ifdef INCLUDE_MEM_SCAN
   2673     /* Kick off s/w background scan */
   2674     if (soc_property_get(unit, spn_MEM_SCAN_ENABLE,
   2675                         (SAL_BOOT_SIMULATION || SOC_IS_TOMAHAWK3(unit)) ? 0 : 1)) {
   2676         sal_usecs_t interval = 0;
   2677         int rate = 0;
   2678 
   2679         if (soc_mem_scan_running(unit, &rate, &interval)) {
   2680             if (soc_mem_scan_stop(unit)) {
   2681                 return SOC_E_INTERNAL;
   2682             }
   2683         }
   2684         rate = rate ? rate : soc_property_get(unit, spn_MEM_SCAN_RATE,
   2685                                               SOC_MEMSCAN_RATE_DEFAULT);
   2686         interval = interval ? interval :
   2687                               soc_property_get(unit, spn_MEM_SCAN_INTERVAL,
   2688                               SAL_BOOT_SIMULATION ? SOC_MEMSCAN_INTERVAL_SIM_DEFAULT :
   2689                               SOC_MEMSCAN_INTERVAL_DEFAULT);
   2690         if (soc_mem_scan_start(unit, rate, interval)) {
   2691             return SOC_E_INTERNAL;
   2692         }
   2693     }
   2694 #endif /* INCLUDE_MEM_SCAN */
   2695     return SOC_E_NONE;
   2696 }
   2697 
   2698 int
   2699 soc_generic_sram_mem_scan_start(int unit)
   2700 {
   2701 #ifdef BCM_SRAM_SCAN_SUPPORT
   2702     if (soc_property_get(unit, spn_SRAM_SCAN_ENABLE, SAL_BOOT_SIMULATION ? 0 :
   2703                           (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit)
   2704                            || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)))) {
   2705         sal_usecs_t interval = 0;
   2706         int rate = 0;
   2707 
   2708         if (soc_sram_scan_running(unit, &rate, &interval)) {
   2709             if (soc_sram_scan_stop(unit)) {
   2710                 return SOC_E_INTERNAL;
   2711             }
   2712         }
   2713         rate = rate ? rate : soc_property_get(unit, spn_SRAM_SCAN_RATE,
   2714                                               SOC_SRAMSCAN_RATE_DEFAULT);
   2715         interval = interval ? interval :
   2716                               soc_property_get(unit, spn_SRAM_SCAN_INTERVAL,
   2717                               SAL_BOOT_SIMULATION ? SOC_SRAMSCAN_INTERVAL_SIM_DEFAULT :
   2718                               SOC_SRAMSCAN_INTERVAL_DEFAULT);
   2719         if (soc_sram_scan_start(unit, rate, interval)) {
   2720             return SOC_E_INTERNAL;
   2721         }
   2722     }
   2723 #endif
   2724     return SOC_E_NONE;
   2725 }
   2726 
   2727 int
   2728 soc_generic_ser_mem_scan_stop(int unit)
   2729 {
   2730 #ifdef INCLUDE_MEM_SCAN
   2731     sal_usecs_t interval = 0;
   2732     int rate = 0;
   2733 
   2734     if (soc_mem_scan_running(unit, &rate, &interval)) {
   2735         if (soc_mem_scan_stop(unit)) {
   2736             return SOC_E_INTERNAL;
   2737         }
   2738     }
   2739 #endif /* INCLUDE_MEM_SCAN */
   2740     return SOC_E_NONE;
   2741 }
   2742 
   2743 int
   2744 soc_generic_sram_mem_scan_stop(int unit)
   2745 {
   2746 #ifdef BCM_SRAM_SCAN_SUPPORT
   2747     sal_usecs_t interval = 0;
   2748     int rate = 0;
   2749 
   2750     if (soc_sram_scan_running(unit, &rate, &interval)) {
   2751         if (soc_sram_scan_stop(unit)) {
   2752             return SOC_E_INTERNAL;
   2753         }
   2754     }
   2755 #endif /* INCLUDE_SRAM_SCAN */
   2756     return SOC_E_NONE;
   2757 }
   2758 
   2759 int
   2760 soc_generic_ser_mem_update(int unit, soc_mem_t mem, int stage, int mode)
   2761 {
   2762     int rv = SOC_E_NONE;
   2763 #ifdef INCLUDE_MEM_SCAN
   2764     int i, info_ix = 0, hw_ser_ix = 0;
   2765     _soc_generic_ser_info_t *ser_info;
   2766     uint32 range_enable;
   2767 
   2768     /* 1. It is possible that mem is marked invalid due to latency mode (eg: TH)
   2769      * 2. It is possible that parity is disabled for this mem by property */
   2770     if (!SOC_MEM_IS_VALID(unit, mem) ||
   2771         (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) {
   2772         LOG_VERBOSE(BSL_LS_SOC_SER,
   2773                   (BSL_META_U(unit, "mem_update DISABLED for mem = %s as "
   2774                    "mem is INVALID or parity is disabled by config property \n"),
   2775                    SOC_MEM_NAME(unit,mem)));
   2776        return rv;
   2777     }
   2778 
   2779     if (soc_property_get(unit, spn_MEM_SCAN_ENABLE, SAL_BOOT_SIMULATION ? 0 : 1)) {
   2780         /* search the memory and update the engine config */
   2781         ser_info = soc_mem_scan_ser_info_get(unit);
   2782         if (ser_info == NULL) {
   2783             if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2784                 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   2785                     rv = SOC_E_NONE;
   2786                 } else {
   2787                     rv = SOC_E_INIT;
   2788                     LOG_ERROR(BSL_LS_SOC_SER,
   2789                               (BSL_META_U(unit, "mem_update FAILED for mem = %s as "
   2790                                "ser_info is NULL\n"), SOC_MEM_NAME(unit,mem)));
   2791                 }
   2792             }
   2793             goto _error;
   2794         }
   2795         while (ser_info[info_ix].mem != INVALIDm) {
   2796             /* Note: This will be the global view index */
   2797 #ifdef BCM_TRIDENT3_SUPPORT
   2798             if (SOC_IS_TRIDENT3X(unit)) {
   2799                 if (ser_info[info_ix].mem != mem) {
   2800                     info_ix++;
   2801                     continue;
   2802                 }
   2803                 (void)soc_trident3_tcam_mode_set(unit, stage, mode);
   2804                 if (mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) {
   2805                     ser_info[info_ix].ser_dynamic_state |=
   2806                             _SOC_SER_STATE_PIPE_MODE_UNIQUE;
   2807                     ser_info[info_ix + 1].ser_dynamic_state |=
   2808                             _SOC_SER_STATE_PIPE_MODE_UNIQUE;
   2809                 } else {
   2810                     ser_info[info_ix].ser_dynamic_state &=
   2811                             ~_SOC_SER_STATE_PIPE_MODE_UNIQUE;
   2812                     ser_info[info_ix + 1].ser_dynamic_state &=
   2813                             ~_SOC_SER_STATE_PIPE_MODE_UNIQUE;
   2814                 }
   2815                 break;
   2816             }
   2817 #endif
   2818             if (ser_info[info_ix].mem == mem) {
   2819                 rv = READ_SER_RANGE_ENABLEr(unit, &range_enable);
   2820                 if (SOC_FAILURE(rv)) {
   2821                     goto _error;
   2822                 }
   2823                 /* ASSUMPTION: _soc_th_tcam_ser_info_template[] table
   2824                  * lists entries for global, unique view consecutively at
   2825                  * {info_ix +0, +1, +2, +3}, info_ix +4 respectively and
   2826                  * because no ranges are configured for info_ix +1, +2, +3
   2827                  * so enable bits for global, unique views
   2828                  * will be at consecutive hw_ser_ix, hw_ser_ix+1 positions
   2829                  * in SER_RANGE_ENABLE REGISTER
   2830                  *
   2831                  * Summary:
   2832                  *
   2833                  * Global view:
   2834                  * info_ix +0, +1, +2, +3 point to 4 entries in _template[]
   2835                  * hw_ser_ix will point to enable bit in SER_RANGE_CONTROL
   2836                  *
   2837                  * Unique view:
   2838                  * info_ix+NUM_PIPE will point to entry in _template[]
   2839                  * hw_ser_ix+1 will point to enable bit for unique view because
   2840                  * entries at info_ix +1, +2, +3 do not need separate ranges in
   2841                  * ser_engine
   2842                  *
   2843                  * memscan:
   2844                  * Irrespective of global/unique mode, memscan always scans
   2845                  * entries at info_ix +0, +1, +2, +3
   2846  */
   2847                 hw_ser_ix = ser_info[info_ix].ser_hw_index;
   2848                 LOG_VERBOSE(BSL_LS_SOC_SER,
   2849                             (BSL_META_U(unit, "mem_update for mem = %s, "
   2850                              "range_enable = 0x%x,  hw_ser_ix = %0d, "
   2851                              "request to change mode to %s \n"),
   2852                              SOC_MEM_NAME(unit,mem), range_enable, hw_ser_ix,
   2853                              mode? "PIPE_UNIQUE" : "GLOBAL"));
   2854                 if (mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) {
   2855                     /* Break before make to avoid any spurious schan
   2856                      * transaction errors
   2857                      */
   2858                     range_enable &= ~(1 << hw_ser_ix); /* disable global */
   2859                     range_enable |= (1 << (hw_ser_ix + 1)); /* enable unique */
   2860 
   2861                     for (i = 0; i < NUM_PIPE(unit); i++) {
   2862                         ser_info[info_ix + i].ser_dynamic_state |=
   2863                             _SOC_SER_STATE_PIPE_MODE_UNIQUE;
   2864                     }
   2865                 } else {
   2866                     range_enable &= ~(1 << (hw_ser_ix + 1)); /* disable unique */
   2867                     range_enable |= (1 << hw_ser_ix); /* enable global */
   2868 
   2869                     for (i = 0; i < NUM_PIPE(unit); i++) {
   2870                         ser_info[info_ix + i].ser_dynamic_state &=
   2871                             ~_SOC_SER_STATE_PIPE_MODE_UNIQUE;
   2872                     }
   2873                 }
   2874                 rv = WRITE_SER_RANGE_ENABLEr(unit, range_enable);
   2875                 LOG_VERBOSE(BSL_LS_SOC_SER,
   2876                             (BSL_META_U(unit, "mem_update for mem = %s, "
   2877                              "range_enable = 0x%x,  hw_ser_ix = %0d\n"),
   2878                              SOC_MEM_NAME(unit,mem), range_enable, hw_ser_ix));
   2879                 if (SOC_FAILURE(rv)) {
   2880                     goto _error;
   2881                 }
   2882                 break;
   2883             }
   2884             info_ix++;
   2885         }
   2886 _error:
   2887         return rv;
   2888     }
   2889 #endif /* INCLUDE_MEM_SCAN */
   2890     return rv;
   2891 }
   2892 
   2893 STATIC int
   2894 _soc_ser_sync_mac_limits(int unit, soc_mem_t mem)
   2895 {
   2896     LOG_VERBOSE(BSL_LS_SOC_SER,
   2897         (BSL_META_U(unit,
   2898                     "th_dbg: entered _soc_ser_sync_mac_limits "
   2899                     "routine\n")));
   2900 #ifdef BCM_XGS_SWITCH_SUPPORT
   2901     
   2902     SOC_IF_ERROR_RETURN(soc_l2x_freeze(unit));
   2903     if (_SOC_DRV_MEM_CHK_L2_MEM(mem)) {
   2904         /* Read L2 table from hardware and update the */
   2905         /* Decrement port/trunk and vlan/vfi counts */
   2906 #if defined(BCM_TRIUMPH3_SUPPORT)
   2907         if (SOC_IS_TRIUMPH3(unit)) {
   2908             soc_tr3_l2_entry_limit_count_update(unit);
   2909         }
   2910 #endif
   2911 #if defined(BCM_GREYHOUND_SUPPORT)
   2912         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
   2913             soc_gh_l2_entry_limit_count_update(unit);
   2914         }
   2915 #endif
   2916 #if defined(BCM_TRIUMPH2_SUPPORT)
   2917         if (SOC_IS_TRIUMPH2(unit) ||
   2918            SOC_IS_KATANA(unit) ||
   2919            SOC_IS_APOLLO(unit)) {
   2920             soc_triumph_l2_entry_limit_count_update(unit);
   2921         }
   2922 #endif
   2923     } else {
   2924         /* Calculate and restore port/trunk and vlan/vfi counts */
   2925         if (mem == VLAN_OR_VFI_MAC_COUNTm) {
   2926 #if defined(BCM_TRIUMPH3_SUPPORT)
   2927             if (SOC_IS_TRIUMPH3(unit)) {
   2928                 soc_tr3_l2_entry_limit_count_update(unit);
   2929             }
   2930 #endif
   2931 #if defined(BCM_TRIUMPH2_SUPPORT)
   2932         if (SOC_IS_TRIUMPH2(unit) ||
   2933             SOC_IS_KATANA(unit) ||
   2934             SOC_IS_APOLLO(unit)) {
   2935             soc_triumph_l2_entry_limit_count_update(unit);
   2936         }
   2937 #endif
   2938         }
   2939     }
   2940     SOC_IF_ERROR_RETURN(soc_l2x_thaw(unit));
   2941 #endif /* BCM_XGS_SWITCH_SUPPORT */
   2942     return SOC_E_NONE;
   2943 }
   2944 
   2945 STATIC int
   2946 _soc_ser_check_hard_fault(int unit, soc_mem_t mem, int at,
   2947                           int copyno, int index, uint32 *cptr,
   2948                           int at_other, int pipe, int is_physical_index)
   2949 {
   2950     int rv;
   2951     uint8 hf = FALSE;
   2952     uint32 *entry = NULL;
   2953     uint32 flags = SOC_MEM_NO_FLAGS;
   2954     uint32 bytes = soc_mem_entry_bytes(unit, mem);
   2955 
   2956     entry = sal_alloc((4 * SOC_MAX_MEM_WORDS), "hw_fault entry");
   2957     if (entry == NULL) {
   2958         return SOC_E_MEMORY;
   2959     }
   2960     sal_memset(entry, 0, (4 * SOC_MAX_MEM_WORDS));
   2961     LOG_VERBOSE(BSL_LS_SOC_SER,
   2962         (BSL_META_U(unit,
   2963                     "th_dbg: entered _soc_ser_check_hard_fault "
   2964                     "routine\n")));
   2965 
   2966     if (soc_feature(unit, soc_feature_efp_meter_table_write_ignore_nack) ||
   2967         SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
   2968         if ((mem == EFP_METER_TABLEm ||
   2969              mem == EFP_METER_TABLE_PIPE0m ||
   2970              mem == EFP_METER_TABLE_PIPE1m ||
   2971              mem == EFP_METER_TABLE_PIPE2m ||
   2972              mem == EFP_METER_TABLE_PIPE3m ||
   2973              mem == EFP_METER_TABLE_Xm ||
   2974              mem == EFP_METER_TABLE_Ym) && ((index % 2) == 1)) {
   2975             /*
   2976              * When parity error happened in odd entry
   2977              * Skip checking
   2978              */
   2979             rv = SOC_E_NONE;
   2980             goto free_exit;
   2981         }
   2982     }
   2983 
   2984     if (is_physical_index) {
   2985         flags = SOC_MEM_DONT_MAP_INDEX;
   2986     }
   2987     /* Read back to ensure correction happened properly OR if there
   2988      * is a hard fault.
   2989      */
   2990     if (((1 == pipe) &&
   2991          ((_SOC_ACC_TYPE_PIPE_BCAST == at) ||
   2992           (_SOC_ACC_TYPE_PIPE_SBS == at))) ||
   2993          (_SOC_ACC_TYPE_PIPE_Y == at)) { /* Use h/w (other pipe) cache */
   2994         IP_ARBITER_LOCK(unit);
   2995 #if defined(BCM_TRIDENT_SUPPORT)
   2996         if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
   2997             soc_trident_pipe_select(unit, TRUE, 1);
   2998             soc_trident_pipe_select(unit, FALSE, 1);
   2999         }
   3000 #endif
   3001 #if defined(BCM_TRIDENT2_SUPPORT)
   3002         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2X(unit)) {
   3003             soc_trident2_pipe_select(unit, TRUE, 1);
   3004             soc_trident2_pipe_select(unit, FALSE, 1);
   3005         }
   3006 #endif
   3007         rv = soc_mem_pipe_select_read(unit, flags, mem,
   3008                                       copyno, at, index, entry);
   3009 #if defined(BCM_TRIDENT_SUPPORT)
   3010         if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
   3011             soc_trident_pipe_select(unit, TRUE, 0);
   3012             soc_trident_pipe_select(unit, FALSE, 0);
   3013         }
   3014 #endif
   3015 #if defined(BCM_TRIDENT2_SUPPORT)
   3016         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2X(unit)) {
   3017             soc_trident2_pipe_select(unit, TRUE, 0);
   3018             soc_trident2_pipe_select(unit, FALSE, 0);
   3019         }
   3020 #endif
   3021         IP_ARBITER_UNLOCK(unit);
   3022     } else {
   3023         rv = soc_mem_read_extended(unit, flags | SOC_MEM_SCHAN_ERR_RETURN,
   3024                                    mem, 0, copyno, index, entry);
   3025     }
   3026     if (SOC_FAILURE(rv)) {
   3027         /* Obvious hard fault */
   3028         hf = TRUE;
   3029         LOG_ERROR(BSL_LS_SOC_SER,
   3030                   (BSL_META_U(unit,
   3031                               "Hard fault detected (read) at: %s.%s[%d] !!\n"),
   3032                    SOC_MEM_NAME(unit, mem),
   3033                    SOC_BLOCK_NAME(unit, copyno),
   3034                    index));
   3035     } else {
   3036         /* Check for multi bit or other forms of un-detectable errors
   3037            by comparing read back data from h/w with cache(s/w or h/w) */
   3038         if (cptr != NULL) {
   3039             if (at != -1) {
   3040                 soc_mem_parity_field_clear(unit, mem, entry, cptr);
   3041                 if (sal_memcmp(entry, cptr, bytes) != 0) {
   3042 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_MEM_SCAN)
   3043                     uint32 *mask = NULL;
   3044                     uint32 dw = 0;
   3045                     uint32 entry_dw = soc_mem_entry_words(unit, mem);
   3046                     uint32 mask_length = SOC_MAX_MEM_WORDS * sizeof(uint32);
   3047 
   3048                     mask = sal_alloc((4 * SOC_MAX_MEM_WORDS), "mask entry");
   3049                     if (mask == NULL) {
   3050                         rv = SOC_E_MEMORY;
   3051                         goto free_exit;
   3052                     }
   3053                     sal_memset((void *)mask, 0xff, mask_length);
   3054                     soc_mem_scan_mask_get(unit, mem, copyno, at, mask, mask_length);
   3055                     for (dw = 0; dw < entry_dw; dw++) {
   3056                         if (((entry[dw] ^ cptr[dw]) &
   3057                              mask[dw]) != 0) {
   3058                             break;
   3059                         }
   3060                     }
   3061 
   3062                     if (mask != NULL) {
   3063                         sal_free(mask);
   3064                     }
   3065                     if (dw < entry_dw)
   3066 #endif
   3067                     {
   3068                         hf = TRUE;
   3069                         LOG_ERROR(BSL_LS_SOC_SER,
   3070                                   (BSL_META_U(unit,
   3071                                               "Hard fault detected (pipe compare) "
   3072                                               "at: %s.%s[%d] !!\n"),
   3073                                    SOC_MEM_NAME(unit, mem),
   3074                                    SOC_BLOCK_NAME(unit, copyno),
   3075                                    index));
   3076                     }
   3077                 }
   3078             } else {
   3079                 
   3080                 
   3081             }
   3082         }
   3083     }
   3084     if (hf == TRUE) {
   3085         /* Raise a hard fault event and disable parity if applicable */
   3086         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3087                            SOC_SWITCH_EVENT_DATA_ERROR_FATAL, mem,
   3088                            index);
   3089 #if defined(BCM_TRIDENT2_SUPPORT)
   3090         if (SOC_IS_TD2_TT2(unit)) {
   3091 #if defined(BCM_TOMAHAWK_SUPPORT)
   3092             if (SOC_IS_TOMAHAWKX(unit)) {
   3093                 soc_th_mem_parity_control(unit, mem, copyno, FALSE, FALSE);
   3094             } else
   3095 #endif
   3096 #if defined(BCM_TRIDENT3_SUPPORT)
   3097             if (SOC_IS_TRIDENT3X(unit)) {
   3098                 soc_td3_mem_parity_control(unit, mem, copyno, FALSE, FALSE);
   3099             } else
   3100 #endif
   3101             {
   3102                 soc_trident2_mem_parity_control(unit, mem, copyno, FALSE);
   3103             }
   3104         }
   3105 #endif
   3106 #if defined(BCM_TRIDENT_SUPPORT)
   3107         if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
   3108             _soc_trident_mem_parity_control(unit, mem, copyno, FALSE);
   3109         }
   3110 #endif
   3111     }
   3112 free_exit:
   3113     if (entry != NULL) {
   3114         sal_free(entry);
   3115     }
   3116     return rv;
   3117 }
   3118 
   3119 STATIC int
   3120 _soc_ser_correction_event_generate(int unit, soc_switch_event_t event, _soc_ser_correct_info_t *si,
   3121                    uint32 arg1, uint32 arg2)
   3122 {
   3123     if (soc_property_get(unit, spn_ENHANCED_SER_CORRECTION_EVENT_REPORT, 0)) {
   3124         if (si != NULL) {
   3125             if (si->parity_type == SOC_PARITY_TYPE_ECC) {
   3126                 if (si->double_bit) {
   3127                     soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_ECC_2BIT_CORRECTED, arg1, arg2);
   3128                 } else {
   3129                     soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_ECC_1BIT_CORRECTED, arg1, arg2);
   3130                 }
   3131             } else {
   3132                 soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_PARITY_CORRECTED, arg1, arg2);
   3133             }
   3134         }
   3135     } else {
   3136         soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_CORRECTED, arg1, arg2);
   3137     }
   3138     return SOC_E_NONE;
   3139 }
   3140 
   3141 STATIC int
   3142 _soc_ser_recovery_hw_cache(int unit, int pipe, soc_mem_t mem, int copyno,
   3143                            int index, _soc_ser_correct_info_t *si, int is_physical_index)
   3144 {
   3145     int acc_type=0, cache_acc_type=0;
   3146     uint32 *entry = NULL;
   3147     uint32 flags = SOC_MEM_NO_FLAGS;
   3148     soc_stat_t *stat = SOC_STAT(unit);
   3149     int rv;
   3150     void *null_entry;
   3151     int entry_dw;
   3152 #if defined(BCM_TOMAHAWK_SUPPORT)
   3153     int restore_pipe = 0;
   3154 #endif /* BCM_TOMAHAWK_SUPPORT */
   3155     soc_mem_t report_mem = mem;
   3156     int report_index = index;
   3157 
   3158     LOG_VERBOSE(BSL_LS_SOC_SER,
   3159         (BSL_META_U(unit,
   3160                     "th_dbg: entered _soc_ser_recovery_hw_cache "
   3161                     "routine\n")));
   3162 
   3163     entry = sal_alloc((4 * SOC_MAX_MEM_WORDS), "hw_cache entry");
   3164     if (entry == NULL) {
   3165         return SOC_E_MEMORY;
   3166     }
   3167     sal_memset(entry, 0, (4 * SOC_MAX_MEM_WORDS));
   3168     if ((SOC_IS_TD2P_TT2P(unit) ||
   3169          SOC_IS_TD2_TT2(unit) || SOC_IS_TD_TT(unit)) && \
   3170         (!SOC_IS_APACHE(unit))) {
   3171         if (pipe == SOC_PIPE_ANY) {
   3172             pipe = 0;
   3173         }
   3174         switch (mem) {
   3175         case L3_DEFIP_ALPM_RAWm:
   3176         case L3_DEFIP_ALPM_IPV4m:
   3177         case L3_DEFIP_ALPM_IPV4_1m:
   3178         case L3_DEFIP_ALPM_IPV6_64m:
   3179         case L3_DEFIP_ALPM_IPV6_64_1m:
   3180         case L3_DEFIP_ALPM_IPV6_128m:
   3181 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   3182         case L3_DEFIP_ALPM_ECCm:
   3183         case L2_ENTRY_LPm:
   3184         case L2_ENTRY_ISS_LPm:
   3185         case L3_ENTRY_LPm:
   3186         case L3_ENTRY_ISS_LPm:
   3187         case VLAN_XLATE_LPm:
   3188         case EGR_VLAN_XLATE_LPm:
   3189 #endif /* BCM_TOMAHAWK_SUPPORT */
   3190 #if defined(BCM_TRIDENT3_SUPPORT)
   3191         case ING_DNAT_ADDRESS_TYPE_ECCm:
   3192         case ING_VP_VLAN_MEMBERSHIP_ECCm:
   3193         case EGR_VP_VLAN_MEMBERSHIP_ECCm:
   3194         case SUBPORT_ID_TO_SGPP_MAP_ECCm:
   3195         case EXACT_MATCH_LPm:
   3196         case VLAN_XLATE_1_LPm:
   3197         case VLAN_XLATE_2_LPm:
   3198         case EGR_VLAN_XLATE_1_LPm:
   3199         case EGR_VLAN_XLATE_2_LPm:
   3200         case MPLS_ENTRY_LPm:
   3201 #endif
   3202 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3203         case L3_DEFIP_ALPM_LEVEL2_ECCm:
   3204         case L3_DEFIP_ALPM_LEVEL3_ECCm:
   3205         case L3_DEFIP_LEVEL1m:
   3206         case L3_DEFIP_PAIR_LEVEL1m:
   3207         case L3_DEFIP_TCAM_LEVEL1m:
   3208         case L3_DEFIP_DATA_LEVEL1m:
   3209 #endif
   3210         case L3_DEFIP_AUX_TABLEm:
   3211         case L3_DEFIP_PAIR_128m:
   3212         case L3_DEFIPm:
   3213         case L3_DEFIP_128_DATA_ONLYm:
   3214         case L3_DEFIP_PAIR_128_DATA_ONLYm:
   3215         case L3_DEFIP_DATA_ONLYm:
   3216 #if defined(BCM_TOMAHAWK_SUPPORT)
   3217             if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   3218                 if (NUM_PIPE(unit) == 1) {
   3219                     rv = SOC_E_UNAVAIL;
   3220                     goto free_exit;
   3221                 }
   3222                 if (pipe >= NUM_PIPE(unit)) {
   3223                     rv = SOC_E_PARAM;
   3224                     goto free_exit;
   3225                 }
   3226 #ifdef BCM_TOMAHAWK3_SUPPORT
   3227                 if (SOC_IS_TOMAHAWK3(unit)) {
   3228                     if (mem == L3_DEFIP_ALPM_LEVEL3_ECCm) {
   3229                         pipe = (pipe == 1 || pipe == 6 || pipe == 7) ? 0 :
   3230                                (pipe == 2 || pipe == 3 || pipe == 5) ? 4 :
   3231                                 pipe;
   3232                         restore_pipe = pipe ? 0 : 4;
   3233                     } else if (mem == L3_DEFIP_ALPM_LEVEL2_ECCm) {
   3234                         pipe = (pipe == 1) ? 0 :
   3235                                (pipe == 2) ? 3 :
   3236                                (pipe == 5) ? 4 :
   3237                                (pipe == 6) ? 7 :
   3238                                 pipe;
   3239                         restore_pipe = pipe ? 0 : 3;
   3240                     } else {
   3241                         restore_pipe = pipe ? 0 : 1;
   3242                     }
   3243                 } else
   3244 #endif
   3245                 {
   3246                     restore_pipe = pipe ? 0 : 1;
   3247                 }
   3248                 acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe);
   3249                 cache_acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(restore_pipe);
   3250                 /* LOG_VERBOSE(BSL_LS_SOC_SER,
   3251                  *             (BSL_META_U(unit,
   3252                  *                         "th_dbg: pipe=%0d, restore_pipe=%0d, acc_type=%0d, cache_acc_type=%0d\n"),
   3253                  *              unit, pipe, restore_pipe, acc_type,
   3254                  *              cache_acc_type));
   3255                  */
   3256             } else
   3257 #endif /* BCM_TOMAHAWK_SUPPORT */
   3258             {
   3259                 if (pipe == 0) {
   3260                     acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_X;
   3261                     cache_acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y;
   3262                 } else if (pipe == 1) {
   3263                     acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y;
   3264                     cache_acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_X;
   3265                 } else {
   3266                     rv = SOC_E_PARAM;
   3267                     goto free_exit;
   3268                 }
   3269             }
   3270             if (is_physical_index) {
   3271                 flags = SOC_MEM_DONT_MAP_INDEX;
   3272             }
   3273             if ((SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) &&
   3274                 (mem == L3_DEFIP_ALPM_RAWm)) {
   3275                 null_entry = soc_mem_entry_null(unit, mem);
   3276                 sal_memcpy(entry, null_entry, soc_mem_entry_words(unit, mem) *
   3277                            sizeof(uint32));
   3278             } else {
   3279             rv = soc_mem_pipe_select_read(unit, flags, mem,
   3280                                           copyno, cache_acc_type,
   3281                                           index, entry);
   3282             if (SOC_FAILURE(rv)) {
   3283                 null_entry = soc_mem_entry_null(unit, mem);
   3284                 sal_memcpy(entry, null_entry, soc_mem_entry_words(unit, mem) *
   3285                            sizeof(uint32));
   3286                     LOG_ERROR(BSL_LS_SOC_SER,
   3287                               (BSL_META_U(unit,
   3288                                           "Un-expected error in %s[%d] blk: %s at same "
   3289                                           "index[%d] in multiple pipes.\n"),
   3290                                SOC_MEM_NAME(unit, mem), mem,
   3291                                SOC_BLOCK_NAME(unit, copyno), index));
   3292             }
   3293             }
   3294             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HITf);
   3295             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT0f);
   3296             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT1f);
   3297             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_0f);
   3298             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_1f);
   3299             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_2f);
   3300             _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_3f);
   3301             rv = soc_mem_pipe_select_write(unit, flags, mem,
   3302                                            copyno, acc_type, index, entry);
   3303             if (rv != SOC_E_NONE) {
   3304                 goto free_exit;
   3305             }
   3306             /* If mem == L3_DEFIP_ALPM_RAWm, it means we are recovering
   3307              * the ALPM bucket which is unused, the memory view of this
   3308              * bucket is not determined, so we used raw view for recovering,
   3309              * and since it's not used, event generation is not necessary.
   3310              */
   3311             if (mem != L3_DEFIP_ALPM_RAWm) {
   3312 #if defined(BCM_TRIDENT2_SUPPORT)
   3313                 /* For L3_DEFIP/L3_DEFIP_DATA_ONLY view the input index is physical
   3314                  * index, so need to remap to logical index. For L3_DEFIP_PAIR_128_DATA_ONLY view
   3315                  * when correcting the view will be changed to L3_DEFIP_DATA_ONLY.
   3316                  * For L3_DEFIP_PAIR_128 view, When L3_ALPM_ENABLE=2,  the physical index
   3317                  * is equal to logical index, but When L3_ALPM_ENABLE=1, the physical index
   3318                  * is not equal to logical index, so need to remap physical index to logical one.
   3319                  */
   3320                 if (is_physical_index && SOC_IS_TD2_TT2(unit) && !SOC_IS_APACHE(unit)) {
   3321                     if (mem == L3_DEFIPm || mem == L3_DEFIP_DATA_ONLYm) {
   3322                         report_index =
   3323                             soc_trident2_l3_defip_mem_index_get(unit,
   3324                                                                 index,
   3325                                                                 &report_mem);
   3326                         if (report_mem == L3_DEFIP_PAIR_128m) {
   3327                             report_mem = L3_DEFIP_PAIR_128_DATA_ONLYm;
   3328                         } else if (report_mem != mem) {
   3329                             report_mem = mem;
   3330                         }
   3331                     } else if (mem == L3_DEFIP_PAIR_128m) {
   3332                         report_index=
   3333                             soc_trident2_l3_defip_index_remap(unit,
   3334                                                               mem,
   3335                                                               index);
   3336                     }
   3337                 }
   3338 #endif
   3339                 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3340                                                    si, report_mem, report_index);
   3341             }
   3342 #if defined(BCM_TOMAHAWK_SUPPORT)
   3343             if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   3344                 LOG_WARN(BSL_LS_SOC_SER,
   3345                           (BSL_META_U(unit,
   3346                                       "RESTORE pipe %0d [from pipe %0d]: %s[%d] "
   3347                                       "blk: %s index: %d\n"),
   3348                            pipe, restore_pipe, SOC_MEM_NAME(unit, report_mem),
   3349                            report_mem, SOC_BLOCK_NAME(unit, copyno), report_index));
   3350             } else
   3351 #endif /* BCM_TOMAHAWK_SUPPORT */
   3352             {
   3353                 LOG_WARN(BSL_LS_SOC_SER,
   3354                           (BSL_META_U(unit,
   3355                                       "RESTORE[from %c pipe]: %s[%d] "
   3356                                       "blk: %s index: %d\n"),
   3357                            pipe ? 'X':'Y', SOC_MEM_NAME(unit, report_mem),
   3358                            report_mem, SOC_BLOCK_NAME(unit, copyno), report_index));
   3359             }
   3360             stat->ser_err_restor++;
   3361             if (NULL != si) {
   3362                 entry_dw = soc_mem_entry_words(unit, mem);
   3363                 if ((si->log_id != 0) &&
   3364                     (si->flags & SOC_SER_LOG_WRITE_CACHE)) {
   3365                     if (si->index == index) {
   3366                         (void)soc_ser_log_add_tlv(unit, si->log_id,
   3367                                                   SOC_SER_LOG_TLV_CACHE,
   3368                                                   entry_dw*4, entry);
   3369                     } else {
   3370                         LOG_VERBOSE(BSL_LS_SOC_SER,
   3371                             (BSL_META_U(unit,
   3372                                         "skipped updating tlv_cache index: %d\n"),
   3373                              index));
   3374                     }
   3375                 }
   3376                 si->ctype = socSerCorrectTypeHwCacheRestore;
   3377             }
   3378             if (NULL != si) {
   3379                 if (si->flags & SOC_SER_SKIP_HARD_FALT_CHECK) {
   3380                     return SOC_E_NONE;
   3381                 }
   3382             }
   3383             rv = _soc_ser_check_hard_fault(unit, mem, acc_type, copyno,
   3384                                              index, entry, cache_acc_type,
   3385                                              pipe, is_physical_index);
   3386             goto free_exit;
   3387         default:
   3388             rv = SOC_E_UNAVAIL;
   3389             goto free_exit;
   3390         }
   3391     }
   3392     rv = SOC_E_UNAVAIL;
   3393 free_exit:
   3394     if(entry != NULL) {
   3395         sal_free(entry);
   3396     }
   3397     return rv;
   3398 }
   3399 
   3400 #if defined(BCM_TOMAHAWK_SUPPORT)
   3401 STATIC int
   3402 _soc_ser_mem_mode_get(int unit, soc_mem_t mem) {
   3403     int rv;
   3404     int tmp_mem_mode = _SOC_SER_MEM_MODE_GLOBAL;
   3405     rv = soc_th_ser_mem_mode_get(unit, mem, &tmp_mem_mode);
   3406     if ((rv == SOC_E_NONE) && (tmp_mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE)) {
   3407         return _SOC_SER_MEM_MODE_PIPE_UNIQUE;
   3408     } else {
   3409         if (rv != SOC_E_NONE) {
   3410             LOG_ERROR(BSL_LS_SOC_SER,
   3411                 (BSL_META_U(unit,
   3412                             "Could not determine unique-global mode for"
   3413                             "mem %s - will assume global mode !!\n"),
   3414                  SOC_MEM_NAME(unit, mem)));
   3415         }
   3416         return _SOC_SER_MEM_MODE_GLOBAL;
   3417     }
   3418 }
   3419 #endif /* BCM_TOMAHAWK_SUPPORT */
   3420 
   3421 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   3422 /* Following maps ecc_entry_index to lp_entry_index */
   3423 STATIC int
   3424 _soc_fv_lp_index_remap(int fpem_ecc_index, int em2)
   3425 {
   3426     int uft_bank, fpem_ecc_index_in_uft_bank, lp_bkt_adr;
   3427 
   3428     /* Each uft bank has 32K _ecc entries */
   3429     uft_bank = fpem_ecc_index / 32768;
   3430 
   3431     /* address within uft_bank */
   3432     fpem_ecc_index_in_uft_bank = fpem_ecc_index % 32768;
   3433 
   3434     if (em2) {
   3435         /* Each em2 entry has 2 fpem_ecc entries and every
   3436          * lp_bkt has 4 em2 entries and thus 8 _ecc entries.
   3437          * Each uft_bank has 8K lp entries */
   3438         lp_bkt_adr = fpem_ecc_index_in_uft_bank / 8;
   3439         return (uft_bank * 8192) + lp_bkt_adr;
   3440     } else {
   3441         /* Each em4 entry has 4 fpem_ecc entries and every
   3442          * lp_bkt has 4 em4 entries and thus 16 _ecc entries.
   3443          * Each uft_bank has 8K lp entries */
   3444         lp_bkt_adr = fpem_ecc_index_in_uft_bank / 16;
   3445         return (uft_bank * 8192) + lp_bkt_adr + 4096;
   3446     }
   3447 }
   3448 #endif
   3449 
   3450 /* hw_cpu: Need special handling for hw vs cpu error on some devices/mems.
   3451            hw=0, cpu=1.
   3452 */
   3453 #define _SOC_SER_MEM_OVERLAY_SET 6
   3454 STATIC int
   3455 _soc_ser_overlay_mem_correction(int unit, int hw_cpu, int pipe, int sblk, int addr,
   3456                                 soc_mem_t reported_mem, int copyno, int index,
   3457                                 _soc_ser_correct_info_t *si)
   3458 {
   3459     soc_mem_t mem = INVALIDm;
   3460     soc_mem_t mem_for_write = INVALIDm;
   3461     void *null_entry;
   3462     int rv, entry_dw;
   3463     uint8 fix = 0, *vmap;
   3464     int i, m, vindex = 0, index_for_write = 0;
   3465     int num_mems = 1;
   3466     int clear_mems = 1;
   3467     soc_stat_t *stat = SOC_STAT(unit);
   3468     uint32 entry[SOC_MAX_MEM_WORDS], *cache;
   3469     int num_indexes[_SOC_SER_MEM_OVERLAY_SET] = {1, 1, 1, 1, 1, 1};
   3470     int iratio[_SOC_SER_MEM_OVERLAY_SET] = {1, 1, 1, 1, 1, 1};
   3471     soc_mem_t mem_list[_SOC_SER_MEM_OVERLAY_SET] =
   3472                        {INVALIDm, INVALIDm, INVALIDm, INVALIDm};
   3473 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   3474     soc_field_t ecc_data_field = INVALIDf;
   3475 #endif /* BCM_TOMAHAWK_SUPPORT */
   3476 #if defined(BCM_TOMAHAWK_SUPPORT)
   3477     int fpem_mem_mode = _SOC_SER_MEM_MODE_GLOBAL;
   3478 #endif
   3479 #if defined(BCM_TRIDENT2_SUPPORT)
   3480         int defip_cam_size = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   3481         int phy_index = 0;
   3482 #endif
   3483 
   3484     int reported_mem_is_fpem_lp = 0; /* reported_mem in ser_fifo */
   3485     int use_pipe_select_write = 0, acc_type = 0;
   3486 
   3487     LOG_VERBOSE(BSL_LS_SOC_SER,
   3488         (BSL_META_U(unit,
   3489                     "th_dbg: entered "
   3490                     "_soc_ser_overlay_mem_correction routine\n")));
   3491 
   3492     if (copyno == MEM_BLOCK_ANY) {
   3493         copyno = SOC_MEM_BLOCK_ANY(unit, reported_mem);
   3494     }
   3495 
   3496     mem_list[0] = reported_mem;
   3497     switch (reported_mem) {
   3498     case MODPORT_MAP_SWm:
   3499         if (SOC_IS_TRX(unit) &&
   3500             !(SOC_IS_TRIUMPH3(unit) || SOC_IS_TD_TT(unit) || SOC_IS_TD2_TT2(unit) ||
   3501               SOC_IS_KATANA2(unit) || SOC_IS_GREYHOUND(unit) ||
   3502               SOC_IS_HURRICANEX(unit))) {
   3503             num_mems = 1;
   3504             mem_list[0] = MODPORT_MAPm;
   3505             break;
   3506         } else {
   3507             LOG_VERBOSE(BSL_LS_SOC_SER,
   3508                 (BSL_META_U(unit,
   3509                             "th_dbg: returning SOC_E_UNAVAIL "
   3510                             "for MODPORT_MAP_SW\n")));
   3511             return SOC_E_UNAVAIL;
   3512         }
   3513     case MODPORT_MAP_M0m:
   3514     case MODPORT_MAP_M1m:
   3515     case MODPORT_MAP_M2m:
   3516     case MODPORT_MAP_M3m:
   3517         num_mems = 1;
   3518         mem_list[0] = MODPORT_MAP_MIRRORm;
   3519         break;
   3520     case ESM_PKT_TYPE_ID_DATA_ONLYm:
   3521         num_mems = 1;
   3522         mem_list[0] = ESM_PKT_TYPE_IDm;
   3523         break;
   3524     case ING_SNAT_DATA_ONLYm:
   3525         num_mems = 1;
   3526         mem_list[0] = ING_SNATm;
   3527         break;
   3528     case VLAN_SUBNET_DATA_ONLYm:
   3529         num_mems = 1;
   3530         mem_list[0] = VLAN_SUBNETm;
   3531         break;
   3532     case MY_STATION_TCAM_DATA_ONLYm:
   3533         num_mems = 1;
   3534         mem_list[0] = MY_STATION_TCAMm;
   3535         break;
   3536     case L2_USER_ENTRY_DATA_ONLYm:
   3537         num_mems = 1;
   3538         mem_list[0] = L2_USER_ENTRYm;
   3539         break;
   3540     case L3_TUNNEL_DATA_ONLYm:
   3541         num_mems = 1;
   3542         mem_list[0] = L3_TUNNELm;
   3543         break;
   3544 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   3545 /* swname for following is L2_USER_ENTRY_DATA_ONLYm which is
   3546  * already covered above
   3547     case L2_USER_ENTRY_DATAm:
   3548         num_mems = 1;
   3549         mem_list[0] = L2_USER_ENTRYm;
   3550         break;
   3551 */
   3552     case SRC_COMPRESSION_DATA_ONLYm:
   3553         num_mems = 1;
   3554         mem_list[0] = SRC_COMPRESSIONm;
   3555         if (_SOC_SER_MEM_MODE_PIPE_UNIQUE ==
   3556                 _soc_ser_mem_mode_get(unit, mem_list[0]) &&
   3557             (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL)  &&
   3558             (pipe <  NUM_PIPE(unit))) {
   3559             mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe];
   3560         }
   3561         break;
   3562     case DST_COMPRESSION_DATA_ONLYm:
   3563         num_mems = 1;
   3564         mem_list[0] = DST_COMPRESSIONm;
   3565         if (_SOC_SER_MEM_MODE_PIPE_UNIQUE ==
   3566                 _soc_ser_mem_mode_get(unit, mem_list[0]) &&
   3567             (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL)  &&
   3568             (pipe <  NUM_PIPE(unit))) {
   3569             mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe];
   3570         }
   3571         break;
   3572     case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm:
   3573         num_mems = 1;
   3574         mem_list[0] = EXACT_MATCH_LOGICAL_TABLE_SELECTm;
   3575         if (_SOC_SER_MEM_MODE_PIPE_UNIQUE ==
   3576                 _soc_ser_mem_mode_get(unit, mem_list[0]) &&
   3577             (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL)  &&
   3578             (pipe <  NUM_PIPE(unit))) {
   3579             mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe];
   3580         }
   3581         break;
   3582     case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm:
   3583         num_mems = 1;
   3584         mem_list[0] = IFP_LOGICAL_TABLE_SELECTm;
   3585         if (_SOC_SER_MEM_MODE_PIPE_UNIQUE ==
   3586                 _soc_ser_mem_mode_get(unit, mem_list[0]) &&
   3587             (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL)  &&
   3588             (pipe <  NUM_PIPE(unit))) {
   3589             mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe];
   3590         }
   3591         break;
   3592 #endif /* BCM_TOMAHAWK_SUPPORT */
   3593 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   3594     case ING_VP_VLAN_MEMBERSHIP_ECCm:
   3595         num_mems = 1;
   3596         if (SOC_IS_TOMAHAWK2(unit)) {
   3597             mem_list[0] = ING_VP_VLAN_MEMBERSHIPm;
   3598         } else if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) {
   3599             /* In TD3 based devices one entry in ECC view corresponds to
   3600              * two entries in the functional view
   3601              */
   3602             index *= 2;
   3603             mem_list[0] = ING_VP_VLAN_MEMBERSHIPm;
   3604             num_indexes[0] = 2;
   3605         }
   3606         break;
   3607     case EGR_VP_VLAN_MEMBERSHIP_ECCm:
   3608         num_mems = 1;
   3609         if (SOC_IS_TOMAHAWK2(unit)) {
   3610             mem_list[0] = EGR_VP_VLAN_MEMBERSHIPm;
   3611         } else if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) {
   3612             index *= 2;
   3613             mem_list[0] = EGR_VP_VLAN_MEMBERSHIPm;
   3614             num_indexes[0] = 2;
   3615         }
   3616         break;
   3617     case ING_DNAT_ADDRESS_TYPE_ECCm:
   3618         num_mems = 1;
   3619         if (SOC_IS_TOMAHAWK2(unit)) {
   3620             mem_list[0] = ING_DNAT_ADDRESS_TYPEm;
   3621         } else if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) {
   3622             index *= 2;
   3623             mem_list[0] = ING_DNAT_ADDRESS_TYPEm;
   3624             num_indexes[0] = 2;
   3625         }
   3626         break;
   3627     case SUBPORT_ID_TO_SGPP_MAP_ECCm:
   3628         num_mems = 1;
   3629         if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) {
   3630             index *= 2;
   3631             mem_list[0] = SUBPORT_ID_TO_SGPP_MAPm;
   3632             num_indexes[0] = 2;
   3633         }
   3634         break;
   3635 #endif
   3636 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   3637     case MY_STATION_TCAM_2_DATA_ONLYm:
   3638         num_mems = 1;
   3639         mem_list[0] = MY_STATION_TCAM_2m;
   3640         break;
   3641     case SUBPORT_TAG_SGPP_MAP_DATA_ONLYm:
   3642         num_mems = 1;
   3643         mem_list[0] = SUBPORT_TAG_SGPP_MAPm;
   3644         break;
   3645 #endif
   3646 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3647     case CPU_COS_MAP_DATA_ONLYm:
   3648         num_mems = 1;
   3649         mem_list[0] = CPU_COS_MAPm;
   3650         break;
   3651 #endif
   3652 #if defined(BCM_TRIDENT3_SUPPORT)
   3653     case PHB_SELECT_TCAM_DATA_ONLYm:
   3654         num_mems = 1;
   3655         mem_list[0] = PHB_SELECT_TCAMm;
   3656         break;
   3657     case FLEX_RTAG7_HASH_TCAM_DATA_ONLYm:
   3658         num_mems = 1;
   3659         mem_list[0] = FLEX_RTAG7_HASH_TCAMm;
   3660         break;
   3661     case PKT_FLOW_SELECT_TCAM_1_DATA_ONLYm:
   3662         num_mems = 1;
   3663         mem_list[0] = PKT_FLOW_SELECT_TCAM_1m;
   3664         break;
   3665     case PKT_FLOW_SELECT_TCAM_2_DATA_ONLYm:
   3666         num_mems = 1;
   3667         mem_list[0] = PKT_FLOW_SELECT_TCAM_2m;
   3668         break;
   3669     case IP_PARSER1_MICE_TCAM_DATA_ONLY_0m:
   3670         num_mems = 1;
   3671         mem_list[0] = IP_PARSER1_MICE_TCAM_0m;
   3672         break;
   3673     case IP_PARSER1_MICE_TCAM_DATA_ONLY_1m:
   3674         num_mems = 1;
   3675         mem_list[0] = IP_PARSER1_MICE_TCAM_1m;
   3676         break;
   3677     case IP_PARSER2_MICE_TCAM_DATA_ONLY_0m:
   3678         num_mems = 1;
   3679         mem_list[0] = IP_PARSER2_MICE_TCAM_0m;
   3680         break;
   3681     case IP_PARSER2_MICE_TCAM_DATA_ONLY_1m:
   3682         num_mems = 1;
   3683         mem_list[0] = IP_PARSER2_MICE_TCAM_1m;
   3684         break;
   3685     case EGR_ZONE_0_EDITOR_CONTROL_TCAM_DATA_ONLYm:
   3686         num_mems = 1;
   3687         mem_list[0] = EGR_ZONE_0_EDITOR_CONTROL_TCAMm;
   3688         break;
   3689     case EGR_ZONE_1_EDITOR_CONTROL_TCAM_DATA_ONLYm:
   3690         num_mems = 1;
   3691         mem_list[0] = EGR_ZONE_1_EDITOR_CONTROL_TCAMm;
   3692         break;
   3693     case EGR_ZONE_2_EDITOR_CONTROL_TCAM_DATA_ONLYm:
   3694         num_mems = 1;
   3695         mem_list[0] = EGR_ZONE_2_EDITOR_CONTROL_TCAMm;
   3696         break;
   3697     case EGR_ZONE_3_EDITOR_CONTROL_TCAM_DATA_ONLYm:
   3698         num_mems = 1;
   3699         mem_list[0] = EGR_ZONE_3_EDITOR_CONTROL_TCAMm;
   3700         break;
   3701     case EGR_ZONE_4_EDITOR_CONTROL_TCAM_DATA_ONLYm:
   3702         num_mems = 1;
   3703         mem_list[0] = EGR_ZONE_4_EDITOR_CONTROL_TCAMm;
   3704         break;
   3705     case EGR_PKT_FLOW_SELECT_TCAM_DATA_ONLYm:
   3706         num_mems = 1;
   3707         mem_list[0] = EGR_PKT_FLOW_SELECT_TCAMm;
   3708         break;
   3709     case EGR_FIELD_EXTRACTION_PROFILE_1_TCAM_DATA_ONLYm:
   3710         num_mems = 1;
   3711         mem_list[0] = EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm;
   3712         break;
   3713     case EGR_FIELD_EXTRACTION_PROFILE_2_TCAM_DATA_ONLYm:
   3714         num_mems = 1;
   3715         mem_list[0] = EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm;
   3716         break;
   3717     case EGR_QOS_CTRL_TCAM_DATA_ONLYm:
   3718         num_mems = 1;
   3719         mem_list[0] = EGR_QOS_CTRL_TCAMm;
   3720         break;
   3721 #endif
   3722     case L2_ENTRY_1m:
   3723         num_mems = 2;
   3724         mem_list[1] = L2_ENTRY_2m; iratio[1] = 2;
   3725         break;
   3726     case MPLS_ENTRYm:
   3727     case MPLS_ENTRY_1m:
   3728         if (soc_feature(unit, soc_feature_ism_memory)) {
   3729             num_mems = 2;
   3730             mem_list[1] = MPLS_ENTRY_EXTDm; iratio[1] = 2;
   3731             break;
   3732         } else {
   3733             return SOC_E_UNAVAIL;
   3734         }
   3735 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   3736     case MPLS_ENTRY_ECCm:
   3737         if (SOC_IS_TRIDENT3X(unit)) {
   3738             num_mems = 2;
   3739             mem_list[0] = MPLS_ENTRY_SINGLEm; iratio[0] = 1;
   3740             mem_list[1] = MPLS_ENTRYm; iratio[1] = 2;
   3741         } else if (SOC_IS_TOMAHAWK3(unit)) {
   3742             num_mems = 1;
   3743             mem_list[0] = MPLS_ENTRY_SINGLEm;
   3744         } else {
   3745         num_mems = 1;
   3746         mem_list[0] = MPLS_ENTRYm;
   3747         }
   3748         break;
   3749 #endif /* BCM_TOMAHAWK_SUPPORT */
   3750 #if defined(BCM_TRIDENT3_SUPPORT)
   3751     case VLAN_XLATE_1_ECCm:
   3752         num_mems = 2;
   3753         mem_list[0] = VLAN_XLATE_1_SINGLEm; iratio[0] = 1;
   3754         mem_list[1] = VLAN_XLATE_1_DOUBLEm; iratio[1] = 2;
   3755         break;
   3756     case VLAN_XLATE_2_ECCm:
   3757         num_mems = 2;
   3758         mem_list[0] = VLAN_XLATE_2_SINGLEm; iratio[0] = 1;
   3759         mem_list[1] = VLAN_XLATE_2_DOUBLEm; iratio[1] = 2;
   3760         break;
   3761     case EGR_VLAN_XLATE_1_ECCm:
   3762         num_mems = 2;
   3763         mem_list[0] = EGR_VLAN_XLATE_1_SINGLEm; iratio[0] = 1;
   3764         mem_list[1] = EGR_VLAN_XLATE_1_DOUBLEm; iratio[1] = 2;
   3765         break;
   3766     case EGR_VLAN_XLATE_2_ECCm:
   3767         num_mems = 2;
   3768         mem_list[0] = EGR_VLAN_XLATE_2_SINGLEm; iratio[0] = 1;
   3769         mem_list[1] = EGR_VLAN_XLATE_2_DOUBLEm; iratio[1] = 2;
   3770         break;
   3771 #endif /* BCM_TRIDENT3_SUPPORT */
   3772 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3773     case IFP_POLICY_TABLEm:
   3774         if (SOC_IS_TRIDENT3X(unit)) {
   3775             num_mems = 2;
   3776             mem_list[0] = IFP_POLICY_TABLEm; iratio[0] = 1;
   3777             mem_list[1] = IFP_POLICY_TABLE_WIDEm; iratio[1] = 1;
   3778         } else {
   3779             return SOC_E_UNAVAIL;
   3780         }
   3781         break;
   3782     case IFP_POLICY_TABLE_WIDEm:
   3783         if (SOC_IS_TRIDENT3X(unit)) {
   3784             num_mems = 3;
   3785             mem_list[0] = IFP_POLICY_TABLEm; iratio[0] = 1;
   3786             mem_list[1] = IFP_POLICY_TABLEm; iratio[1] = 1;
   3787             mem_list[2] = IFP_POLICY_TABLE_WIDEm; iratio[2] = 1;
   3788         } else {
   3789             return SOC_E_UNAVAIL;
   3790         }
   3791         break;
   3792 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK3_SUPPORT */
   3793 #ifdef BCM_TOMAHAWK3_SUPPORT
   3794     case L3_TUNNEL_ECCm:
   3795         if (SOC_IS_TOMAHAWK3(unit)) {
   3796             num_mems = 3;
   3797             mem_list[0] = L3_TUNNEL_SINGLEm; iratio[0] = 1;
   3798             mem_list[1] = L3_TUNNEL_DOUBLEm; iratio[1] = 2;
   3799             mem_list[2] = L3_TUNNEL_QUADm; iratio[2] = 4;
   3800         }
   3801         break;
   3802 #endif
   3803 
   3804     case VLAN_XLATE_1m:
   3805         num_mems = 2;
   3806         mem_list[1] = VLAN_XLATE_EXTDm; iratio[1] = 2;
   3807         break;
   3808     case L3_ENTRY_1m:
   3809         num_mems = 3;
   3810         mem_list[1] = L3_ENTRY_2m; iratio[1] = 2;
   3811         mem_list[2] = L3_ENTRY_4m; iratio[2] = 4;
   3812         break;
   3813     case EGR_IP_TUNNELm:
   3814         if (soc_feature(unit, soc_feature_common_egr_ip_tunnel_ser)) {
   3815             num_mems = 0;
   3816             if (SOC_MEM_IS_VALID(unit, EGR_IP_TUNNELm)) {
   3817                 mem_list[num_mems] = EGR_IP_TUNNELm;
   3818                 num_mems++;
   3819             } else if (SOC_MEM_IS_VALID(unit, EGR_IP_TUNNEL_MPLSm)) {
   3820                 mem_list[num_mems] = EGR_IP_TUNNEL_MPLSm;
   3821                 num_mems++;
   3822             } else if (SOC_MEM_IS_VALID(unit, EGR_IP_TUNNEL_IPV6m)) {
   3823                 mem_list[num_mems] = EGR_IP_TUNNEL_IPV6m; iratio[num_mems] = 2;
   3824                 num_mems++;
   3825             }
   3826         } else if (SOC_IS_TRIDENT(unit) &&
   3827             !(soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser))) {
   3828             num_mems = 3;
   3829             if (hw_cpu) {
   3830                 /* Sbus read */
   3831                 mem_list[0] = EGR_IP_TUNNELm;
   3832                 mem_list[1] = EGR_IP_TUNNEL_MPLSm;
   3833                 mem_list[2] = EGR_IP_TUNNEL_IPV6m;
   3834             } else {
   3835             index *= 4; /* To keep the index ratio based logic below, consistent */
   3836             num_indexes[0] = 4; num_indexes[1] = 4;
   3837                 num_indexes[2] = 2;
   3838             mem_list[0] = EGR_IP_TUNNELm;
   3839             mem_list[1] = EGR_IP_TUNNEL_MPLSm;
   3840             mem_list[2] = EGR_IP_TUNNEL_IPV6m; iratio[2] = 2;
   3841             }
   3842         } else if (soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser)) {
   3843             /* Note: This is an exception case where the wider memories index is
   3844              *       used for reporting the error on a hw lookup while view name
   3845              *       received is always EGR_IP_TUNNEL in the correction routine.
   3846              *       On a cpu access error the actual view used for access is
   3847              *       used for reporting the error index but again the view name
   3848              *       is always EGR_IP_TUNNEL.
   3849              *       So for a reported index 'n' we will need to check/fix
   3850              *       index n/2 and n*2 as well.
   3851              */
   3852             num_mems = 3;
   3853             if (hw_cpu) {
   3854                 /* Sbus read */
   3855                 mem_list[0] = EGR_IP_TUNNELm;
   3856                 mem_list[1] = EGR_IP_TUNNEL_MPLSm;
   3857                 if (soc_mem_index_valid(unit, EGR_IP_TUNNEL_IPV6m, index)) {
   3858                     mem_list[2] = EGR_IP_TUNNEL_IPV6m;
   3859                 } else {
   3860                     num_mems--;
   3861                 }
   3862             } else {
   3863             index *= 2; /* To keep the index ratio based logic below, consistent */
   3864             num_indexes[0] = 2; num_indexes[1] = 2;
   3865             mem_list[0] = EGR_IP_TUNNELm;
   3866             mem_list[1] = EGR_IP_TUNNEL_MPLSm;
   3867             mem_list[2] = EGR_IP_TUNNEL_IPV6m; iratio[2] = 2;
   3868             }
   3869         }
   3870 #if defined(BCM_TRIDENT3_SUPPORT)
   3871         else if (soc_feature(unit, soc_feature_td3_style_mpls)) {
   3872             num_mems = 4;
   3873             mem_list[1] = EGR_IP_TUNNEL_MPLSm;
   3874             mem_list[2] = EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm; iratio[2] = 2;
   3875             mem_list[3] = EGR_IP_TUNNEL_IPV6m; iratio[3] = 2;
   3876         }
   3877 #endif /* BCM_TRIDENT3_SUPPORT */
   3878         else {
   3879             num_mems = 3;
   3880             mem_list[1] = EGR_IP_TUNNEL_MPLSm;
   3881             mem_list[2] = EGR_IP_TUNNEL_IPV6m; iratio[2] = 2;
   3882 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3883             if (SOC_IS_APACHE(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TOMAHAWK3(unit)) {
   3884                 /* Index reported for EGR_IP_TUNNEL_MPLSm is different for apache.
   3885                  * Index reported is changed by factor of two.
   3886                  * Adjust index ratio accordingly
   3887                  */
   3888                 iratio[1] = 2;
   3889             }
   3890 #endif /* BCM_APACHE_SUPPORT */
   3891         }
   3892         break;
   3893     case L3_ENTRY_ONLYm:
   3894         if (SOC_MEM_IS_VALID(unit, L3_ENTRY_IPV4_UNICASTm)) {
   3895             mem_list[0] = L3_ENTRY_IPV4_UNICASTm;
   3896         }
   3897         /* passthru */
   3898         /* coverity[fallthrough: FALSE] */
   3899     case L3_ENTRY_IPV4_UNICASTm:
   3900         num_mems = 4;
   3901         mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1;
   3902 #ifdef BCM_SCORPION_SUPPORT
   3903         if (SOC_IS_SCORPION(unit)) {
   3904             mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 1;
   3905         } else
   3906 #endif
   3907         {
   3908             mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2;
   3909         }
   3910         mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2;
   3911         mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4;
   3912         break;
   3913     case L3_ENTRY_IPV4_MULTICASTm:
   3914         /* The iratio array is for IPv4_UC view, so need to convert the index to right one */
   3915         index *= 2;
   3916         num_mems = 4;
   3917         mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1;
   3918         mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2;
   3919         mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2;
   3920         mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4;
   3921         break;
   3922     case L3_ENTRY_IPV6_UNICASTm:
   3923         /* The iratio array is for IPv4_UC view, so need to convert the index to right one */
   3924         index *= 2;
   3925         num_mems = 4;
   3926         mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1;
   3927         mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2;
   3928         mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2;
   3929         mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4;
   3930         break;
   3931     case L3_ENTRY_IPV6_MULTICASTm:
   3932         /* The iratio array is for IPv4_UC view, so need to convert the index to right one */
   3933         index *= 4;
   3934         num_mems = 4;
   3935         mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1;
   3936         mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2;
   3937         mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2;
   3938         mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4;
   3939         break;
   3940 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   3941     case L3_ENTRY_ONLY_ECCm:
   3942         num_mems = 4;
   3943         mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1;
   3944         mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2;
   3945         mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2;
   3946         mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4;
   3947         break;
   3948 #endif
   3949 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3950     case L3_ENTRY_ECCm:
   3951         if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   3952         num_mems = 3;
   3953         mem_list[0] = L3_ENTRY_SINGLEm; iratio[0] = 1;
   3954         mem_list[1] = L3_ENTRY_DOUBLEm; iratio[1] = 2;
   3955         mem_list[2] = L3_ENTRY_QUADm; iratio[2] = 4;
   3956         }
   3957         break;
   3958 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT
   3959     case INITIAL_L3_ECMPm:
   3960         if (soc_esw_ecmp_protected_enabled(unit)) {
   3961             rv = soc_esw_ecmp_protected_ser_update(unit, reported_mem, index);
   3962         }
   3963         break;
   3964 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */
   3965     case IFP_TCAMm:
   3966         if (SOC_IS_TRIDENT3X(unit)) {
   3967             num_mems = 2;
   3968             mem_list[0] = IFP_TCAMm; iratio[0] = 1; num_indexes[0] = 1;
   3969            /* In order to support the bcmFieldQualifyInPorts qualifier in
   3970             * Global Mode, reads/writes on IFP_TCAM_WIDE should always be
   3971             * in per pipe mode.
   3972             */
   3973             mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe];
   3974             iratio[1] = 2; num_indexes[1] = 1;
   3975             break;
   3976         } else {
   3977             return SOC_E_UNAVAIL;
   3978         }
   3979     case IFP_TCAM_PIPE0m:
   3980     case IFP_TCAM_PIPE1m:
   3981         if (SOC_IS_TRIDENT3X(unit)) {
   3982             num_mems = 2;
   3983             mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAMm)[pipe];
   3984             iratio[0] = 1; num_indexes[0] = 1;
   3985             mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe];
   3986             iratio[1] = 2; num_indexes[1] = 1;
   3987             break;
   3988         } else {
   3989             return SOC_E_UNAVAIL;
   3990         }
   3991     case IFP_TCAM_WIDEm:
   3992         if (SOC_IS_TRIDENT3X(unit)) {
   3993             index *= 2;
   3994             num_mems = 2;
   3995             mem_list[0] = IFP_TCAMm; iratio[0] = 1; num_indexes[0] = 2;
   3996            /* In order to support the bcmFieldQualifyInPorts qualifier in
   3997             * Global Mode, reads/writes on IFP_TCAM_WIDE should always be
   3998             * in per pipe mode.
   3999             */
   4000             mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe];
   4001             iratio[1] = 2; num_indexes[1] = 1;
   4002             break;
   4003         } else {
   4004             return SOC_E_UNAVAIL;
   4005         }
   4006     case IFP_TCAM_WIDE_PIPE0m:
   4007     case IFP_TCAM_WIDE_PIPE1m:
   4008         if (SOC_IS_TRIDENT3X(unit)) {
   4009             index *= 2;
   4010             num_mems = 2;
   4011             mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAMm)[pipe];
   4012             iratio[0] = 1; num_indexes[0] = 2;
   4013             mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe];
   4014             iratio[1] = 2; num_indexes[1] = 1;
   4015             break;
   4016         } else {
   4017             return SOC_E_UNAVAIL;
   4018         }
   4019 #endif
   4020 #if defined(BCM_TOMAHAWK_SUPPORT)
   4021     case FPEM_ECCm:
   4022     case EXACT_MATCH_ECCm:
   4023         /* Note: Assume both EM2, EM4 are always in same mode */
   4024         fpem_mem_mode = _soc_ser_mem_mode_get(unit, EXACT_MATCH_2m);
   4025         num_mems = 2;
   4026         mem_list[0] = _SOC_FPEM_EM2(pipe, fpem_mem_mode); iratio[0] = 2;
   4027         mem_list[1] = _SOC_FPEM_EM4(pipe, fpem_mem_mode); iratio[1] = 4;
   4028         break;
   4029     case EXACT_MATCH_2m:
   4030         reported_mem_is_fpem_lp = 1;
   4031         /* means mem reported in ser_fifo is FPEM_LPm */
   4032         fpem_mem_mode = _soc_ser_mem_mode_get(unit, reported_mem);
   4033         num_mems = 1;
   4034         mem_list[0] = _SOC_FPEM_EM2(pipe, fpem_mem_mode); iratio[0] = 2;
   4035         num_indexes[0] = _SOC_SER_NUM_EM_ENTRIES_PER_LP_ENTRY;
   4036         /* each FPEM_LP entry covers 4 EM2 entries */
   4037         break;
   4038     case EXACT_MATCH_4m:
   4039         reported_mem_is_fpem_lp = 1;
   4040         /* means mem reported in ser_fifo is FPEM_LPm */
   4041         fpem_mem_mode = _soc_ser_mem_mode_get(unit, reported_mem);
   4042         num_mems = 1;
   4043         mem_list[0] = _SOC_FPEM_EM4(pipe, fpem_mem_mode); iratio[0] = 4;
   4044         num_indexes[0] = _SOC_SER_NUM_EM_ENTRIES_PER_LP_ENTRY;
   4045         /* each FPEM_LP entry covers 4 EM4 entries */
   4046         break;
   4047 #endif /* BCM_TOMAHAWK_SUPPORT */
   4048     case L3_DEFIP_128_DATA_ONLYm:
   4049         num_mems = 1;
   4050         mem_list[0] = L3_DEFIP_128m;
   4051         break;
   4052 #if defined(BCM_TRIDENT2_SUPPORT)
   4053     case L3_DEFIP_PAIR_128_DATA_ONLYm:
   4054         num_mems = 1;
   4055         mem_list[0] = L3_DEFIP_PAIR_128_DATA_ONLYm;
   4056         if (NUM_PIPE(unit) == 1) {
   4057             /* Using cache restore from  aggregated memory */
   4058             mem_list[0] = L3_DEFIP_PAIR_128m;
   4059         } else if (SOC_IS_TD2_TT2(unit)) {
   4060             num_indexes[0] = 2;
   4061             index = (index / defip_cam_size) * defip_cam_size * 2 +
   4062                     (index % defip_cam_size);
   4063         }
   4064         break;
   4065 #endif /* BCM_TRIDENT2_SUPPORT */
   4066     case L3_DEFIP_DATA_ONLYm:
   4067         if (soc_feature(unit, soc_feature_l3_defip_map)) {
   4068             num_mems = 1;
   4069 #ifdef BCM_TRIUMPH3_SUPPORT
   4070             if ((SOC_IS_TRIUMPH3(unit)) || ((SOC_IS_HELIX4(unit)) &&
   4071                 (!soc_feature(unit, soc_feature_l3_256_defip_table))) ) {
   4072                 index = soc_tr3_l3_defip_mem_index_get(unit, index,
   4073                                                        &mem_list[0]);
   4074             } else
   4075 #endif /* BCM_TRIUMPH3_SUPPORT */
   4076 #ifdef BCM_KATANA_SUPPORT
   4077             if (SOC_IS_KATANA(unit)) {
   4078                 index = soc_kt_l3_defip_mem_index_get(unit, index,
   4079                                                       &mem_list[0]);
   4080             } else
   4081 #endif /* BCM_TRIUMPH3_SUPPORT */
   4082 #ifdef BCM_KATANA2_SUPPORT
   4083             if (SOC_IS_KATANA2(unit)) {
   4084                 index = soc_kt2_l3_defip_index_map(unit, mem_list[0], index);
   4085                 index = soc_kt2_l3_defip_mem_index_get(unit, index,
   4086                                                        &mem_list[0]);
   4087                 if (mem_list[0] == L3_DEFIP_DATA_ONLYm) {
   4088                     mem_list[0] = L3_DEFIPm;
   4089                 } else if (mem_list[0] == L3_DEFIP_PAIR_128_DATA_ONLYm) {
   4090                     mem_list[0] = L3_DEFIP_PAIR_128m;
   4091                 }
   4092             } else
   4093 #endif /* BCM_KATANA2_SUPPORT */
   4094 #if defined(BCM_MONTEREY_SUPPORT)
   4095             if (SOC_IS_MONTEREY(unit)) {
   4096                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4097                     (BSL_META_U(unit,
   4098                                 "ap_dbg: "
   4099                                 "phys_index = %0d for mem = %0d\n"),
   4100                      index, mem_list[0]));
   4101                 /* The index is logical index, we need convert to physical index first*/
   4102                 index = soc_monterey_l3_defip_index_map(unit, mem_list[0], index);
   4103 
   4104                 index = soc_monterey_l3_defip_mem_index_get(unit, index,
   4105                                                           &mem_list[0]);
   4106                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4107                     (BSL_META_U(unit,
   4108                                 "ap_dbg: "
   4109                                 "logical_index = %0d  for mem = %0d\n"),
   4110                      index, mem_list[0]));
   4111             } else
   4112 #endif /* BCM_MONTEREY_SUPPORT */
   4113 #if defined(BCM_APACHE_SUPPORT)
   4114             if (SOC_IS_APACHE(unit)) {
   4115                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4116                     (BSL_META_U(unit,
   4117                                 "ap_dbg: "
   4118                                 "phys_index = %0d for mem = %0d\n"),
   4119                      index, mem_list[0]));
   4120                 /* The index is logical index, we need convert to physical index first*/
   4121                 index = soc_apache_l3_defip_index_map(unit, mem_list[0], index);
   4122 
   4123                 index = soc_apache_l3_defip_mem_index_get(unit, index,
   4124                                                           &mem_list[0]);
   4125                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4126                     (BSL_META_U(unit,
   4127                                 "ap_dbg: "
   4128                                 "logical_index = %0d  for mem = %0d\n"),
   4129                      index, mem_list[0]));
   4130             } else
   4131 #endif /* BCM_APACHE_SUPPORT */
   4132 #if defined(BCM_TRIDENT3_SUPPORT)
   4133             if (SOC_IS_TRIDENT3X(unit) && NUM_PIPE(unit) == 1) {
   4134                 /* Using cache restore from  aggregated memory
   4135                  * Index remaping already done
   4136                  */
   4137                 mem_list[0] = L3_DEFIPm;
   4138             } else
   4139 #endif
   4140 #if defined(BCM_TRIDENT2_SUPPORT)
   4141             if (SOC_IS_TD2_TT2(unit)) {
   4142                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4143                     (BSL_META_U(unit,
   4144                                 "th_dbg: "
   4145                                 "phys_index = %0d for mem = %0d\n"),
   4146                      index, mem_list[0]));
   4147 
   4148                 (void)soc_trident2_l3_defip_mem_index_get(unit, index,
   4149                                                             &mem_list[0]);
   4150                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4151                     (BSL_META_U(unit,
   4152                                 "th_dbg: "
   4153                                 "logical_index = %0d  for mem = %0d\n"),
   4154                      index, mem_list[0]));
   4155                 /* Lets only correct the data portion of the TCAM to avoid
   4156                    getting into deadlock situation in bulk op retry for TD2.
   4157                    Note that mem cache is not used for this memory anyways. */
   4158                 if (mem_list[0] == L3_DEFIPm) {
   4159                     mem_list[0] = L3_DEFIP_DATA_ONLYm;
   4160                     LOG_VERBOSE(BSL_LS_SOC_SER,
   4161                         (BSL_META_U(unit,
   4162                                     "th_dbg: mem_for_restore=%0d:"
   4163                                     "L3_DEFIP_DATA_ONLYm\n"), mem_list[0]));
   4164                 } else if (mem_list[0] == L3_DEFIP_PAIR_128m) {
   4165                     mem_list[0] = L3_DEFIP_PAIR_128_DATA_ONLYm;
   4166                     num_indexes[0] = 2;
   4167                     LOG_VERBOSE(BSL_LS_SOC_SER,
   4168                         (BSL_META_U(unit,
   4169                                     "th_dbg: mem_for_restore=%0d:"
   4170                                     "L3_DEFIP_PAIR_128_DATA_ONLYm\n"),
   4171                          mem_list[0]));
   4172                 }
   4173                 if (SOC_CONTROL(unit)->alpm_bulk_retry) {
   4174                     sal_sem_give(SOC_CONTROL(unit)->alpm_bulk_retry);
   4175                 }
   4176             } else
   4177 #endif /* BCM_TRIDENT2_SUPPORT */
   4178 #if defined(BCM_TRIUMPH_SUPPORT)
   4179             if (SOC_IS_TRIUMPH(unit)) {
   4180                 num_mems = 1;
   4181                 mem_list[0] = L3_DEFIPm;
   4182                 break;
   4183             } else
   4184 #endif      /* BCM_TRIUMPH_SUPPORT */
   4185             {
   4186                 
   4187                 return SOC_E_UNAVAIL;
   4188             }
   4189             break;
   4190         } else
   4191 #if defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_ENDURO_SUPPORT)
   4192         if (SOC_IS_TRIUMPH(unit) || SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) ||
   4193             SOC_IS_HURRICANE3(unit)) {
   4194 #ifdef BCM_ENDURO_SUPPORT
   4195             if (SOC_IS_ENDURO(unit)) {
   4196                 index = soc_enduro_l3_defip_index_map(unit, mem_list[0], index);
   4197             }
   4198 #endif /* BCM_ENDURO_SUPPORT */
   4199             num_mems = 1;
   4200             mem_list[0] = L3_DEFIPm;
   4201             break;
   4202         }  else
   4203 #endif
   4204         {
   4205             return SOC_E_UNAVAIL;
   4206         }
   4207     default:
   4208         return SOC_E_UNAVAIL;
   4209     }
   4210     for (m = 0; m < num_mems; m++) {
   4211         mem = mem_list[m];
   4212         entry_dw = soc_mem_entry_words(unit, mem);
   4213 
   4214         MEM_LOCK(unit, mem_list[m]);
   4215 
   4216 #ifdef BCM_TRIDENT3_SUPPORT
   4217         if (SOC_IS_TRIDENT3X(unit) && NUM_PIPE(unit) == 1) {
   4218             if (reported_mem == ING_VP_VLAN_MEMBERSHIP_ECCm ||
   4219                 reported_mem == EGR_VP_VLAN_MEMBERSHIP_ECCm ||
   4220                 reported_mem == ING_DNAT_ADDRESS_TYPE_ECCm ||
   4221                 reported_mem == SUBPORT_ID_TO_SGPP_MAP_ECCm) {
   4222                 /* There is no DISABLE_SBUS_MEMWR_ECC_CHECK field in following mems
   4223                  * ING_VP_VLAN_MEMBERSHIP_HASH_CONTROL
   4224                  * EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROL
   4225                  * ING_DNAT_ADDRESS_TYPE_HASH_CONTROL
   4226                  * SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROL
   4227                  * So we need to clear the error entry first to be able to
   4228                  * CACHE_RESTORE entries in functional view
   4229                  */
   4230                 null_entry = soc_mem_entry_null(unit, reported_mem);
   4231                 (void)soc_mem_write(unit, reported_mem, copyno, index/2, null_entry);
   4232             }
   4233         }
   4234 #endif
   4235         /* coverity[negative_returns] */
   4236         cache = SOC_MEM_STATE(unit, mem).cache[copyno];
   4237         vmap = SOC_MEM_STATE(unit, mem).vmap[copyno];
   4238         vindex = index/iratio[m];
   4239 #ifdef BCM_TRIDENT3_SUPPORT
   4240         if (SOC_IS_TRIDENT3X(unit)) {
   4241             if ((mem == IFP_POLICY_TABLE_WIDEm) && (reported_mem == IFP_POLICY_TABLEm)) {
   4242                 vindex = vindex / SOC_TD3_FP_SLICE_ENTRY_NARROW_VIEW *
   4243                          SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW +
   4244                          vindex % SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW;
   4245             } else if ((mem == IFP_POLICY_TABLEm) && (reported_mem == IFP_POLICY_TABLE_WIDEm)) {
   4246                 /* One IFP_POLICY_TABLE_WIDE entry has two IFP_POLICY_TABLE entries.
   4247                  * Need to calculate the index twice.
   4248                  */
   4249                 if (m == 0) {
   4250                     vindex = vindex / SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW *
   4251                              SOC_TD3_FP_SLICE_ENTRY_NARROW_VIEW +
   4252                              vindex % SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW;
   4253                 } else if (m == 1) {
   4254                     vindex = vindex / SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW *
   4255                              SOC_TD3_FP_SLICE_ENTRY_NARROW_VIEW +
   4256                              vindex % SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW;
   4257                     /* calculate second single entry's index */
   4258                     vindex += SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW;
   4259                 }
   4260             }
   4261         }
   4262 #endif
   4263         for (i = 0; i < num_indexes[m]; i++) {
   4264             if (cache != NULL && CACHE_VMAP_TST(vmap, vindex+i)) {
   4265                 sal_memcpy(entry, cache + ((vindex+i) * entry_dw),
   4266                            entry_dw * 4);
   4267                 mem_for_write = mem;
   4268                 index_for_write = vindex + i;
   4269 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   4270                 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) ||
   4271                     SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
   4272                     switch (mem) {
   4273                     case L3_ENTRY_IPV4_UNICASTm:
   4274                         ecc_data_field = ECC_DATAf;
   4275                         soc_mem_field_get(unit, mem,
   4276                                           cache + ((vindex+i) * entry_dw),
   4277                                           ecc_data_field, entry);
   4278                         mem_for_write = L3_ENTRY_ONLY_ECCm;
   4279                         index_for_write = index + i;
   4280                         break;
   4281                     case L3_ENTRY_IPV4_MULTICASTm:
   4282                     case L3_ENTRY_IPV6_UNICASTm:
   4283                     case L3_ENTRY_IPV6_MULTICASTm:
   4284                         switch(index % iratio[m]) {
   4285                         case 1:  ecc_data_field = ECC_DATA1f; break;
   4286                         case 2:  ecc_data_field = ECC_DATA2f; break;
   4287                         case 3:  ecc_data_field = ECC_DATA3f; break;
   4288                         default: ecc_data_field = ECC_DATA0f; break;
   4289                         }
   4290                         soc_mem_field_get(unit, mem,
   4291                                           cache + ((vindex+i) * entry_dw),
   4292                                           ecc_data_field, entry);
   4293                         mem_for_write = L3_ENTRY_ONLY_ECCm;
   4294                         index_for_write = index + i;
   4295                         break;
   4296 #if defined(BCM_TOMAHAWK_SUPPORT)
   4297                     case EXACT_MATCH_2m:
   4298                     case EXACT_MATCH_2_PIPE0m:
   4299                     case EXACT_MATCH_2_PIPE1m:
   4300                     case EXACT_MATCH_2_PIPE2m:
   4301                     case EXACT_MATCH_2_PIPE3m:
   4302                     case EXACT_MATCH_4m:
   4303                     case EXACT_MATCH_4_PIPE0m:
   4304                     case EXACT_MATCH_4_PIPE1m:
   4305                     case EXACT_MATCH_4_PIPE2m:
   4306                     case EXACT_MATCH_4_PIPE3m:
   4307                         if (!reported_mem_is_fpem_lp) {
   4308                             /* reported_mem is FPEM_ECC or EXACT_MATCH_ECCm */
   4309                             switch (index % iratio[m]) {
   4310                                 case 1:  ecc_data_field = ECC_DATA1f; break;
   4311                                 case 2:  ecc_data_field = ECC_DATA2f; break;
   4312                                 case 3:  ecc_data_field = ECC_DATA3f; break;
   4313                                 default: ecc_data_field = ECC_DATA0f; break;
   4314                             }
   4315                             soc_mem_field_get(unit, mem,
   4316                                               cache + ((vindex+i)*entry_dw),
   4317                                               ecc_data_field, entry);
   4318 #ifdef BCM_TOMAHAWK3_SUPPORT
   4319                             if (SOC_IS_TOMAHAWK3(unit)) {
   4320                                 mem_for_write = EXACT_MATCH_ECCm;
   4321                             } else
   4322 #endif
   4323                             if (SOC_IS_TRIDENT3X(unit)) {
   4324                                 mem_for_write = _SOC_EXACT_MATCH_ECC(pipe,
   4325                                                             fpem_mem_mode);
   4326                             } else {
   4327                                 mem_for_write = _SOC_FPEM_ECC(pipe,
   4328                                                             fpem_mem_mode);
   4329                             }
   4330                             index_for_write = index + i;
   4331                         }
   4332                         break;
   4333 #endif /* BCM_TOMAHAWK_SUPPORT */
   4334                     case MPLS_ENTRYm:
   4335                         if (SOC_IS_TOMAHAWKX(unit)) {
   4336                             mem_for_write = MPLS_ENTRY_ECCm;
   4337                         }
   4338                         break;
   4339                     default:
   4340                         break;
   4341                     }
   4342                 }
   4343 #endif /* (BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) */
   4344                 rv = soc_mem_write(unit, mem_for_write, copyno,
   4345                                    index_for_write, entry);
   4346                 if (NULL != si) {
   4347                     if ((si->log_id != 0) &&
   4348                         (si->flags & SOC_SER_LOG_WRITE_CACHE)) {
   4349                         if (si->index == index_for_write) {
   4350                             (void)soc_ser_log_add_tlv(unit, si->log_id,
   4351                                                       SOC_SER_LOG_TLV_CACHE,
   4352                                                       soc_mem_entry_words(unit, mem_for_write)*4,
   4353                                                       entry);
   4354                         } else {
   4355                             LOG_VERBOSE(BSL_LS_SOC_SER,
   4356                                 (BSL_META_U(unit,
   4357                                             "skipped updating tlv_cache index: %d\n"),
   4358                                  index_for_write));
   4359                         }
   4360                     }
   4361                     si->ctype = SocSerCorrectTypeCacheRestore;
   4362                 }
   4363                 if (rv < 0) {
   4364                     LOG_ERROR(BSL_LS_SOC_SER,
   4365                               (BSL_META_U(unit,
   4366                                           "CACHE_RESTORE %s.%s[%d] failed: %s\n"),
   4367                                SOC_MEM_NAME(unit, mem_for_write),
   4368                                SOC_BLOCK_NAME(unit, copyno), index_for_write,
   4369                                soc_errmsg(rv)));
   4370                     MEM_UNLOCK(unit, mem_list[m]);
   4371 
   4372                     return rv;
   4373                 }
   4374                 fix++;
   4375                 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4376                                                    si, mem, vindex);
   4377                 LOG_WARN(BSL_LS_SOC_SER,
   4378                           (BSL_META_U(unit,
   4379                                       "CACHE_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"),
   4380                            SOC_MEM_NAME(unit, mem_for_write),
   4381                            mem_for_write, SOC_BLOCK_NAME(unit, copyno),
   4382                            index_for_write, sblk, addr));
   4383                 stat->ser_err_restor++;
   4384                 LOG_VERBOSE(BSL_LS_SOC_SER,
   4385                     (BSL_META_U(unit,
   4386                                 "th_dbg: this CACHE_RESTORE was "
   4387                                 "from overlay_mem_correction\n")));
   4388             }
   4389             if (cache == NULL) {
   4390                 /* Do hw cache (from the other pipe) based correction if s/w mem
   4391                    cache is not available */
   4392 #if defined(BCM_TRIDENT2_SUPPORT)
   4393                 if (((mem_list[m] == L3_DEFIP_PAIR_128_DATA_ONLYm) ||
   4394                       mem_list[m] == L3_DEFIP_DATA_ONLYm)
   4395                      && SOC_IS_TD2_TT2(unit) && !SOC_IS_APACHE(unit)) {
   4396                     mem = L3_DEFIP_DATA_ONLYm;
   4397                     if (mem_list[m] == L3_DEFIP_PAIR_128_DATA_ONLYm) {
   4398                         phy_index= ((vindex / (defip_cam_size * 2)) * defip_cam_size * 2)
   4399                                     + (vindex % defip_cam_size) + (i * defip_cam_size);
   4400                     } else {
   4401                         phy_index = vindex;
   4402                     }
   4403                     rv = _soc_ser_recovery_hw_cache(unit, pipe, mem, copyno,
   4404                                                     phy_index, si, TRUE);
   4405                 } else
   4406 #endif
   4407                 {
   4408                     rv = _soc_ser_recovery_hw_cache(unit, pipe, mem, copyno,
   4409                                                     vindex+i, si, FALSE);
   4410                 }
   4411                 if (!(rv == SOC_E_NONE || rv == SOC_E_UNAVAIL)) {
   4412                     return rv;
   4413                 } else if (rv == SOC_E_NONE) {
   4414                     fix++;
   4415                 }
   4416             }
   4417             if (reported_mem_is_fpem_lp && (fix > 0)) {
   4418                 /* reported_mem_is_fpem_lp implies that we are doing indirect
   4419                  * restore of LP control word by writing to one of the
   4420                  * functional views (EXACT_MATCH_2,4)
   4421                  * We need to restore only one of the 4 entries for
   4422                  * corresponding LP control word to be recomputed.
   4423                  * Thus, after we do the 1st restore - exit.
   4424                  *
   4425                  * reported_mem_is_fpem_lp also implies that 'mem' is either
   4426                  * EXACT_MATCH_2m or
   4427                  * EXACT_MATCH_2_PIPE0m or
   4428                  * EXACT_MATCH_2_PIPE1m or
   4429                  * EXACT_MATCH_2_PIPE2m or
   4430                  * EXACT_MATCH_2_PIPE3m or
   4431                  * EXACT_MATCH_4m or
   4432                  * EXACT_MATCH_4_PIPE0m or
   4433                  * EXACT_MATCH_4_PIPE1m or
   4434                  * EXACT_MATCH_4_PIPE2m or
   4435                  * EXACT_MATCH_4_PIPE3m
   4436                  */
   4437                 break;
   4438             }
   4439         } /* each index */
   4440         MEM_UNLOCK(unit, mem_list[m]);
   4441         
   4442         if ((mem == L3_ENTRY_ONLYm) || (mem == L3_ENTRY_IPV4_UNICASTm) ||
   4443             (mem == L3_ENTRY_IPV4_MULTICASTm) || (mem == L3_ENTRY_IPV6_UNICASTm) ||
   4444             (mem == L3_ENTRY_IPV6_MULTICASTm) ||
   4445             _SOC_MEM_CHK_FPEM_MEM(mem)) {
   4446             if (fix != 0) {
   4447                 break;
   4448             }
   4449         }
   4450     } /* each mem */
   4451     if (fix == 0) {
   4452         LOG_VERBOSE(BSL_LS_SOC_SER,
   4453             (BSL_META_U(unit,
   4454                         "th_dbg: overlay_mem_correction falling "
   4455                         "back to CLEAR_RESTORE\n")));
   4456         /* Fall back to clear - this is always the widest view */
   4457 #if defined(BCM_TRX_SUPPORT)
   4458         /* For L3_ENTRY_*, clear the entry in L3_ENTRY_IPV4_UNICAST view */
   4459         if (SOC_IS_TRX(unit)) {
   4460 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   4461             if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) ||
   4462                 SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
   4463                 vindex = index;
   4464                 switch (mem) {
   4465                 case MPLS_ENTRYm:
   4466 #ifdef BCM_TOMAHAWK3_SUPPORT
   4467                 case MPLS_ENTRY_SINGLEm:
   4468 #endif
   4469                     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   4470                         mem = MPLS_ENTRY_ECCm;
   4471                     }
   4472                     break;
   4473                 case L3_ENTRY_IPV6_MULTICASTm:
   4474                     mem = L3_ENTRY_ONLY_ECCm;
   4475                     break;
   4476 #if defined(BCM_TOMAHAWK3_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   4477                 case L3_ENTRY_QUADm:
   4478                     mem = L3_ENTRY_ECCm;
   4479                     break;
   4480 #endif
   4481 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4482                 case L3_TUNNEL_QUADm:
   4483                     mem = L3_TUNNEL_ECCm;
   4484                     break;
   4485 #endif
   4486 #if defined(BCM_TRIDENT3_SUPPORT)
   4487                 case EGR_VLAN_XLATE_1_DOUBLEm:
   4488                     mem = EGR_VLAN_XLATE_1_ECCm;
   4489                     break;
   4490                 case EGR_VLAN_XLATE_2_DOUBLEm:
   4491                     mem = EGR_VLAN_XLATE_2_ECCm;
   4492                     break;
   4493                 case VLAN_XLATE_1_DOUBLEm:
   4494                     mem = VLAN_XLATE_1_ECCm;
   4495                     break;
   4496                 case VLAN_XLATE_2_DOUBLEm:
   4497                     mem = VLAN_XLATE_2_ECCm;
   4498                     break;
   4499                 case IFP_TCAM_WIDEm:
   4500                 case IFP_TCAM_WIDE_PIPE0m:
   4501                 case IFP_TCAM_WIDE_PIPE1m:
   4502                     mem = reported_mem;
   4503                     if ((mem == IFP_TCAM_WIDEm) ||
   4504                         (mem == IFP_TCAM_WIDE_PIPE0m) ||
   4505                         (mem == IFP_TCAM_WIDE_PIPE1m)) {
   4506                         vindex = index / 2;
   4507                     }
   4508                     break;
   4509                 case IFP_POLICY_TABLE_WIDEm:
   4510                     mem = reported_mem;
   4511                     vindex = index;
   4512                     break;
   4513 #endif
   4514                 case EXACT_MATCH_2m:
   4515                     /* we can be here only when (reported_mem ==  FPEM_LPm) */
   4516                     /* Write to ENTRY_ONLY view to prevent cache from
   4517                      * recording that there is EXACT_MATCH_2 type entry at this
   4518                      * location.
   4519                      * Clear this FPEM_LPm location
   4520                      * Because at corresponding locatons in fv, we may have EM4
   4521                      * entries, so this LP entry is NULL */
   4522 #ifdef BCM_TOMAHAWK3_SUPPORT
   4523                     if (SOC_IS_TOMAHAWK3(unit)) {
   4524                         mem = EXACT_MATCH_ECCm;
   4525                     } else
   4526 #endif
   4527 #ifdef BCM_TRIDENT3_SUPPORT
   4528                     if (SOC_IS_TRIDENT3X(unit)) {
   4529                         mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode);;
   4530                     } else
   4531 #endif
   4532                     {
   4533                         mem = FPEM_LPm;
   4534                         vindex = _soc_fv_lp_index_remap(index, 1);
   4535                     }
   4536                     break;
   4537                 case EXACT_MATCH_2_PIPE0m:
   4538                 case EXACT_MATCH_2_PIPE1m:
   4539                 case EXACT_MATCH_2_PIPE2m:
   4540                 case EXACT_MATCH_2_PIPE3m:
   4541                     /* Can be here only when (reported_mem ==  FPEM_LPm) */
   4542                     /* Write to ENTRY_ONLY view to prevent cache from
   4543                      * recording that there is EXACT_MATCH_2 type entry at this
   4544                      * location.
   4545                      * Clear this FPEM_LPm location
   4546                      * Because at corresponding locatons in fv, we may have EM4
   4547                      * entries, so this LP entry is NULL */
   4548 #ifdef BCM_TRIDENT3_SUPPORT
   4549                     if (SOC_IS_TRIDENT3X(unit)) {
   4550                         mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode);
   4551                     } else
   4552 #endif
   4553                     {
   4554                         mem = FPEM_LPm;
   4555                         vindex = _soc_fv_lp_index_remap(index, 1);
   4556                         use_pipe_select_write = 1;
   4557                         acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe);
   4558                     }
   4559                     break;
   4560                 case EXACT_MATCH_4m:
   4561 #ifdef BCM_TOMAHAWK3_SUPPORT
   4562                     if (SOC_IS_TOMAHAWK3(unit)) {
   4563                         mem = EXACT_MATCH_ECCm;
   4564                     } else
   4565 #endif
   4566 #ifdef BCM_TRIDENT3_SUPPORT
   4567                     if (SOC_IS_TRIDENT3X(unit)) {
   4568                         mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode);
   4569                     } else
   4570 #endif
   4571                     {
   4572                         if (!reported_mem_is_fpem_lp) {
   4573                             /* reported_mem is FPEM_ECCm */
   4574                             mem = FPEM_ECCm;
   4575                         } else { /* (reported_mem == FPEM_LPm) */
   4576                             /* Write to ENTRY_ONLY view to prevent cache from
   4577                              * recording that there is EXACT_MATCH_4 type entry at
   4578                              * this location.
   4579                              * Clear this FPEM_LPm location
   4580                              * Because at corresponding locatons in fv, we may have EM2
   4581                              * entries, so this LP entry is NULL */
   4582                             mem = FPEM_LPm;
   4583                             vindex = _soc_fv_lp_index_remap(index, 0);
   4584                         }
   4585                     }
   4586                     break;
   4587                 case EXACT_MATCH_4_PIPE0m:
   4588                 case EXACT_MATCH_4_PIPE1m:
   4589                 case EXACT_MATCH_4_PIPE2m:
   4590                 case EXACT_MATCH_4_PIPE3m:
   4591 #ifdef BCM_TRIDENT3_SUPPORT
   4592                     if (SOC_IS_TRIDENT3X(unit)) {
   4593                         mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode);
   4594                     } else
   4595 #endif
   4596                     {
   4597                         if (!reported_mem_is_fpem_lp) {
   4598                             /* reported_mem is FPEM_ECCm */
   4599                             mem = _SOC_FPEM_ECC(pipe,
   4600                                                 _SOC_SER_MEM_MODE_PIPE_UNIQUE);
   4601                         } else { /* (reported_mem == FPEM_LPm) */
   4602                             /* Write to ENTRY_ONLY view to prevent cache from
   4603                              * recording that there is EXACT_MATCH_4 type entry at
   4604                              * this location.
   4605                              * Clear this FPEM_LPm location
   4606                              * Because at corresponding locatons in fv, we may have EM2
   4607                              * entries, so this LP entry is NULL */
   4608                             mem = FPEM_LPm;
   4609                             vindex = _soc_fv_lp_index_remap(index, 0);
   4610                             use_pipe_select_write = 1;
   4611                             acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe);
   4612                     }
   4613                     }
   4614                     break;
   4615                 case EGR_IP_TUNNEL_IPV6m:
   4616                     mem = reported_mem;
   4617                     vindex = index;
   4618                     break;
   4619                 default:
   4620                     break;
   4621                 }
   4622             } else
   4623 #endif /* BCM_TOMAHAWK_SUPPORT */
   4624             {
   4625                 if (mem == L3_ENTRY_IPV6_MULTICASTm) {
   4626                     mem = L3_ENTRY_ONLYm;
   4627                     vindex = index;
   4628                 }
   4629             }
   4630         }
   4631         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) {
   4632             if (mem == L3_ENTRY_4m) {
   4633                 mem = L3_ENTRY_1m;
   4634                 vindex = index;
   4635             }
   4636         }
   4637         if (SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT(unit)) {
   4638             mem = mem_list[0];
   4639             vindex = index;
   4640         }
   4641 
   4642         if (EGR_IP_TUNNELm == reported_mem) {
   4643             clear_mems = 2;
   4644             if ((SOC_IS_TRIDENT(unit) &&
   4645                  !soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser)) ||
   4646                  soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser)) {
   4647                 /* SBUS read triggers */
   4648                 mem_list[0] = EGR_IP_TUNNELm;
   4649                 mem_list[1] = EGR_IP_TUNNEL_IPV6m;
   4650                 iratio[0] = 1;
   4651                 iratio[1] = 1;
   4652 
   4653                 /* Error exists in EGR_IP_TUNNEL if index is bigger than max of ipv6 */
   4654                 if (index > soc_mem_index_max(unit, EGR_IP_TUNNEL_IPV6m)) {
   4655                     clear_mems = 1;
   4656                 }
   4657             } else {
   4658                 mem_list[0] = EGR_IP_TUNNELm;
   4659                 mem_list[1] = EGR_IP_TUNNEL_IPV6m;
   4660                 iratio[0] = 1;
   4661                 iratio[1] = 2;
   4662             }
   4663 
   4664             if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) ||
   4665                 SOC_IS_TRIDENT3X(unit)) {
   4666                 int neighbour_index;
   4667                 soc_mem_t check_mem_list[2] =
   4668                               {EGR_IP_TUNNELm, EGR_IP_TUNNEL_MPLSm};
   4669 
   4670                 neighbour_index = index % 2? index -1 : index + 1;
   4671 
   4672                 /* Check if the neighbour is valid or not for
   4673                 * EGR_IP_TUNNEL or EGR_IP_TUNNEL_MPLS view.
   4674                 * If yes, do not clear EGR_IP_TUNNEL_IPV6 view.
   4675                 * If no, clear EGR_IP_TUNNEL_IPV6 view.
   4676                 */
   4677                 for (i = 0; i < 2; i++) {
   4678                     cache = SOC_MEM_STATE(unit, check_mem_list[i]).cache[copyno];
   4679                     vmap = SOC_MEM_STATE(unit, check_mem_list[i]).vmap[copyno];
   4680 
   4681                     if (cache != NULL && CACHE_VMAP_TST(vmap, neighbour_index)) {
   4682                         clear_mems = 1;
   4683                         break;
   4684                     }
   4685                 }
   4686             }
   4687         }
   4688 #endif
   4689         for (i = 0; i < clear_mems; i++) {
   4690             if (EGR_IP_TUNNELm == reported_mem) {
   4691                 mem = mem_list[i];
   4692                 vindex = index / iratio[i];
   4693             }
   4694             null_entry = soc_mem_entry_null(unit, mem);
   4695             if (use_pipe_select_write) {
   4696                 rv = soc_mem_pipe_select_write(unit, SOC_MEM_NO_FLAGS, mem,
   4697                                                copyno, acc_type, vindex,
   4698                                                null_entry);
   4699             } else {
   4700                 rv = soc_mem_write(unit, mem, copyno, vindex, null_entry);
   4701             }
   4702             if (NULL != si) {
   4703                 si->ctype = SocSerCorrectTypeEntryClear;
   4704             }
   4705             if (rv < 0) {
   4706                 LOG_ERROR(BSL_LS_SOC_SER,
   4707                           (BSL_META_U(unit,
   4708                                       "CLEAR_RESTORE %s.%s[%d] failed: %s\n"),
   4709                            SOC_MEM_NAME(unit, mem),
   4710                            SOC_BLOCK_NAME(unit, copyno),
   4711                            vindex, soc_errmsg(rv)));
   4712                 return rv;
   4713             }
   4714             _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4715                                                si, mem, vindex);
   4716             LOG_WARN(BSL_LS_SOC_SER,
   4717                       (BSL_META_U(unit,
   4718                                   "CLEAR_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"),
   4719                        SOC_MEM_NAME(unit, mem), mem,
   4720                        SOC_BLOCK_NAME(unit, copyno),
   4721                        vindex, sblk, addr));
   4722             LOG_VERBOSE(BSL_LS_SOC_SER,
   4723                 (BSL_META_U(unit,
   4724                             "th_dbg: overlay_mem_correction did "
   4725                             "CLEAR_RESTORE !!\n")));
   4726             if (_SOC_DRV_MEM_CHK_L2_MEM(mem) &&
   4727                 soc_feature(unit, soc_feature_mac_learn_limit)) {
   4728                 /* coverity[stack_use_overflow] */
   4729                 if ((rv =_soc_ser_sync_mac_limits(unit, mem)) != SOC_E_NONE) {
   4730                     LOG_ERROR(BSL_LS_SOC_SER,
   4731                               (BSL_META_U(unit,
   4732                                           "L2 mac limit sync failed !!\n")));
   4733                     return rv;
   4734                 }
   4735             }
   4736         }
   4737         stat->ser_err_clear++;
   4738     }
   4739     return SOC_E_NONE;
   4740 }
   4741 
   4742 void
   4743 _soc_sram_info_init(int unit, _soc_ser_sram_info_t *sram_info)
   4744 {
   4745     sal_memset(sram_info, 0x00, sizeof(_soc_ser_sram_info_t));
   4746     sram_info->disable_reg = INVALIDr;
   4747     sram_info->disable_field = INVALIDf;
   4748     sram_info->disable_mem = INVALIDm;
   4749     sram_info->disable_mem_field = INVALIDf;
   4750     sram_info->disable_mem_index = -1;
   4751     sram_info->force_reg = INVALIDr;
   4752     sram_info->force_mem = INVALIDm;
   4753     sram_info->force_field = INVALIDf;
   4754     sram_info->disable_xor_write_field = INVALIDf;
   4755     return;
   4756 }
   4757 
   4758 STATIC int
   4759 _soc_ser_sram_correction(int unit, int pipe, int sblk, int addr, soc_mem_t mem,
   4760                          int copyno, int index, uint8 mode,
   4761                          _soc_ser_correct_info_t *si)
   4762 {
   4763 #define _SOC_SER_SRAM_CHK_RETURN(str) \
   4764         if (rv != SOC_E_NONE) {\
   4765             LOG_ERROR(BSL_LS_SOC_SER, \
   4766                       (BSL_META_U(unit, \
   4767                                   "SER SRAM correction encoutered error(%d) in %s\n"), \
   4768                        rv, str));\
   4769             if (mem_to_lock != INVALIDm) { \
   4770                 MEM_UNLOCK(unit, mem_to_lock); \
   4771             } \
   4772             goto free_exit;\
   4773         }
   4774 
   4775 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4776 /*
   4777  * For TD2+, L2X thread is frozen for L2X memory corrections done
   4778  *           via L2_ENTRY_ONLY_ECC memory.
   4779  * For Apache, L2X thread is also frozen for correcting LP memory
   4780  */
   4781 #define _SOC_IF_ERR_L2X_THAW(rv, mem)                                          \
   4782         if (((mem == L2_ENTRY_ONLY_ECCm) &&                                    \
   4783               (soc_feature(unit, soc_feature_td2p_a0_sw_war) ||                \
   4784                soc_feature(unit, soc_feature_l2_activity_freeze_ser))) ||      \
   4785             (((mem == L2_ENTRY_LPm) || (mem == L2_ENTRY_ISS_LPm)) &&           \
   4786              soc_feature(unit, soc_feature_l2_activity_freeze_ser))) {         \
   4787             if (rv != SOC_E_NONE) { \
   4788                 rv1 = soc_l2x_thaw(unit);                                      \
   4789                 if (SOC_FAILURE(rv1)) {                                        \
   4790                     LOG_WARN(BSL_LS_SOC_SER, \
   4791                              (BSL_META_U(unit, \
   4792                                          "L2 thaw failed in %s correction\n"), \
   4793                              SOC_MEM_NAME(unit, mem)));                        \
   4794                     rv = rv1;                                                  \
   4795                 } \
   4796                 if (mem_to_lock != INVALIDm) {                                 \
   4797                     MEM_UNLOCK(unit, mem_to_lock);                             \
   4798                 }                                                              \
   4799                 goto free_exit;                                                     \
   4800             } \
   4801         }
   4802 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4803 
   4804     void *null_entry;
   4805     int is_l3_defip = FALSE;
   4806     uint8 *vmap, at = 0, _l2_lock = 0;
   4807 #if defined(ALPM_ENABLE)
   4808     uint8 _alpm_lock = 0;
   4809 #endif /* ALPM_ENABLE */
   4810     int rv = SOC_E_NONE, i, j, start_index, entry_dw, block;
   4811     soc_stat_t *stat = SOC_STAT(unit);
   4812     _soc_ser_sram_info_t *sram_info = NULL;
   4813     uint32 *entry = NULL, rval, *cache, raddr = 0;
   4814     soc_mem_t mem_to_restore = mem, mem_to_lock = mem, mem_for_cache_read = mem;
   4815     soc_mem_t mem_to_report = mem;
   4816 #if defined(BCM_TOMAHAWK_SUPPORT)
   4817     int fpem_mem_mode = _SOC_SER_MEM_MODE_GLOBAL;
   4818 #endif /* BCM_TOMAHAWK_SUPPORT */
   4819     int use_overlay_mem_correction = 0;
   4820     int use_recovery_hw_cache = 0;
   4821 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4822     int rv1;
   4823 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4824     uint32 hash_control_entry[4];
   4825     soc_ser_correction_type_t ctype = SocSerCorrectTypeEntryClear;
   4826 
   4827     LOG_VERBOSE(BSL_LS_SOC_SER,
   4828         (BSL_META_U(unit,
   4829                     "th_dbg: entered _soc_ser_sram_correction "
   4830                     "routine\n")));
   4831 
   4832     if (!SOC_MEM_IS_VALID(unit, mem) || index < 0 ||
   4833         !(mode == _SOC_SER_SRAM_CORRECTION_MODE_0 ||
   4834           mode == _SOC_SER_SRAM_CORRECTION_MODE_1)) {
   4835         return SOC_E_PARAM;
   4836     }
   4837     sram_info = sal_alloc(sizeof(_soc_ser_sram_info_t), "sram info");
   4838     if (sram_info == NULL) {
   4839         return SOC_E_MEMORY;
   4840     }
   4841     entry = sal_alloc((4 * SOC_MAX_MEM_WORDS), "sram_entry");
   4842     if (entry == NULL) {
   4843         rv = SOC_E_MEMORY;
   4844         goto free_exit;
   4845     }
   4846     _soc_sram_info_init(unit, sram_info);
   4847     /* Determine RAM count and indexes for all RAMs */
   4848 #if defined(BCM_HELIX5_SUPPORT)
   4849         if (SOC_IS_HELIX5(unit)) {
   4850             rv = soc_helix5_mem_sram_info_get(unit, mem, index, sram_info);
   4851         } else
   4852 #endif
   4853 #if defined(BCM_TRIDENT3_SUPPORT)
   4854         if (SOC_IS_TRIDENT3X(unit)) {
   4855         rv = soc_trident3_mem_sram_info_get(unit, mem, index, sram_info);
   4856         } else
   4857 #endif
   4858 #if defined(BCM_TOMAHAWK_SUPPORT)
   4859         if (SOC_IS_TOMAHAWKX(unit)) {
   4860         rv = soc_tomahawk_mem_sram_info_get(unit, mem, index, sram_info);
   4861         } else
   4862 #endif /* BCM_TOMAHAWK_SUPPORT */
   4863 #if defined(BCM_MONTEREY_SUPPORT)
   4864         if (SOC_IS_MONTEREY(unit)) {
   4865         rv = _soc_monterey_mem_sram_info_get(unit, mem, index, sram_info);
   4866         } else 
   4867 #endif /* BCM_MONTEREY_SUPPORT */
   4868 #if defined(BCM_APACHE_SUPPORT)
   4869         if (SOC_IS_APACHE(unit)) {
   4870         rv = _soc_apache_mem_sram_info_get(unit, mem, index, sram_info);
   4871         } else 
   4872 #endif /* BCM_APACHE_SUPPORT */
   4873 #if defined(BCM_TRIDENT2_SUPPORT)
   4874         if (SOC_IS_TD2_TT2(unit)) { /* Tomahawk check is made earlier */
   4875         rv = _soc_trident2_mem_sram_info_get(unit, mem, index, sram_info);
   4876         } else
   4877 #endif /* BCM_TRIDENT2_SUPPORT */
   4878     {
   4879         rv = SOC_E_UNAVAIL;
   4880     }
   4881     if (rv != SOC_E_NONE) {
   4882         goto free_exit;
   4883     }
   4884     
   4885 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \
   4886     defined(BCM_TRIDENT3_SUPPORT)
   4887     /* coverity[Structurally dead code]*/
   4888     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || SOC_IS_TD2P_TT2P(unit)) {
   4889         if ((mem == L2_ENTRY_LPm) || (mem == L2_ENTRY_ISS_LPm)) {
   4890             _L2_LOCK(unit);
   4891             _l2_lock = 1;
   4892         }
   4893     }
   4894 #endif /* BCM_TOMAHAWK_SUPPORT */
   4895 
   4896     /* Update all RAM indexes with data from cache or null entry */
   4897 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \
   4898     defined(BCM_TRIDENT3_SUPPORT)
   4899     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) {
   4900         switch (mem) {
   4901         case L2_ENTRY_ONLY_ECCm:
   4902             mem_to_restore = L2_ENTRY_ONLY_ECCm;
   4903             mem_to_lock = L2Xm;
   4904             mem_for_cache_read = L2Xm;
   4905             mem_to_report = L2Xm;
   4906             break;
   4907 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   4908         case L2_ENTRY_ECCm:
   4909             if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   4910                 mem_to_restore = L2_ENTRY_ECCm;
   4911                 mem_to_lock = L2Xm;
   4912                 mem_for_cache_read = L2Xm;
   4913                 mem_to_report = L2Xm;
   4914             }
   4915             break;
   4916 #endif
   4917         case FPEM_ECCm:
   4918         case FPEM_LPm:
   4919         case L3_ENTRY_ECCm:
   4920         case L3_ENTRY_ONLY_ECCm:
   4921         case MPLS_ENTRY_ECCm:
   4922         case VLAN_XLATE_1_ECCm:
   4923         case VLAN_XLATE_2_ECCm:
   4924         case EGR_VLAN_XLATE_1_ECCm:
   4925         case EGR_VLAN_XLATE_2_ECCm:
   4926         case EXACT_MATCH_ECCm:
   4927             mem_to_lock = INVALIDm;
   4928             use_overlay_mem_correction = 1;
   4929             break;
   4930 #ifdef BCM_TRIDENT3_SUPPORT
   4931         case ING_DNAT_ADDRESS_TYPE_ECCm:
   4932         case ING_VP_VLAN_MEMBERSHIP_ECCm:
   4933         case EGR_VP_VLAN_MEMBERSHIP_ECCm:
   4934         case SUBPORT_ID_TO_SGPP_MAP_ECCm:
   4935             if (NUM_PIPE(unit) == 1) {
   4936                 mem_to_lock = INVALIDm;
   4937                 use_overlay_mem_correction = 1;
   4938             }
   4939             break;
   4940 #endif
   4941 #ifdef BCM_TOMAHAWK3_SUPPORT
   4942         case L3_DEFIP_ALPM_LEVEL3_ECCm:
   4943             if (SOC_IS_TOMAHAWK3(unit)) {
   4944                 mem_to_lock = INVALIDm;
   4945                 use_recovery_hw_cache = 1;
   4946                 is_l3_defip = TRUE;
   4947             }
   4948             break;
   4949 #endif
   4950         case L2_ENTRY_LPm:
   4951         case L2_ENTRY_ISS_LPm:
   4952         case L3_ENTRY_LPm:
   4953         case L3_ENTRY_ISS_LPm:
   4954         case VLAN_XLATE_LPm:
   4955         case EGR_VLAN_XLATE_LPm:
   4956             mem_to_lock = INVALIDm;
   4957             use_recovery_hw_cache = 1;
   4958             break;
   4959         case EXACT_MATCH_LPm:
   4960         case VLAN_XLATE_1_LPm:
   4961         case VLAN_XLATE_2_LPm:
   4962         case EGR_VLAN_XLATE_1_LPm:
   4963         case EGR_VLAN_XLATE_2_LPm:
   4964         case MPLS_ENTRY_LPm:
   4965             if (SOC_IS_TRIDENT3X(unit)) {
   4966                 mem_to_lock = INVALIDm;
   4967                 use_recovery_hw_cache = 1;
   4968             }
   4969             break;
   4970         case L3_DEFIP_ALPM_ECCm:
   4971             mem_to_lock = INVALIDm;
   4972             use_recovery_hw_cache = 1;
   4973             is_l3_defip = TRUE;
   4974 #ifdef BCM_TRIDENT3_SUPPORT
   4975             /* There is no HASH_CONTROL memory to set
   4976              * DISABLE_SBUS_MEMWR_ECC_CHECK field
   4977              * So we need to clear the error entry first to be able to
   4978              * CACHE_RESTORE entries in functional view
   4979              */
   4980             if (SOC_IS_TRIDENT3X(unit) && NUM_PIPE(unit) == 1) {
   4981                 null_entry = soc_mem_entry_null(unit, mem);
   4982                 (void)soc_mem_write(unit, mem, copyno, index, null_entry);
   4983             }
   4984 #endif
   4985             break;
   4986         case VLAN_XLATE_ECCm:
   4987 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4988         case VLAN_MACm:
   4989 #endif
   4990             mem_to_restore = VLAN_XLATE_ECCm;
   4991             mem_to_lock = VLAN_XLATEm;
   4992             mem_for_cache_read = VLAN_XLATEm;
   4993             mem_to_report = VLAN_XLATEm;
   4994             break;
   4995         case EGR_VLAN_XLATE_ECCm:
   4996             mem_to_restore = EGR_VLAN_XLATE_ECCm;
   4997             mem_to_lock = EGR_VLAN_XLATEm;
   4998             mem_for_cache_read = EGR_VLAN_XLATEm;
   4999             mem_to_report = EGR_VLAN_XLATEm;
   5000             break;
   5001         default:
   5002             break;
   5003         }
   5004         sal_memset(entry, 0, 4*soc_mem_entry_words(unit, mem_to_restore));
   5005 
   5006         if (NUM_PIPE(unit) == 1) {
   5007             /* use_recovery_hw_cache is to be enabled only for multi-pipe devices */
   5008             use_recovery_hw_cache = 0;
   5009         }
   5010     }
   5011 #endif /* BCM_TOMAHAWK_SUPPORT */
   5012 
   5013 #if defined(BCM_TRIDENT2_SUPPORT)
   5014         if (SOC_IS_TD2_TT2(unit)) {
   5015             if (mem == L3_DEFIP_ALPM_IPV4m || mem == L3_DEFIP_ALPM_IPV4_1m ||
   5016                 mem == L3_DEFIP_ALPM_IPV6_64m || mem == L3_DEFIP_ALPM_IPV6_64_1m ||
   5017                 mem == L3_DEFIP_ALPM_IPV6_128m || mem == L3_DEFIP_PAIR_128m ||
   5018                 mem == L3_DEFIPm || mem == L3_DEFIP_AUX_TABLEm) {
   5019                 /* Take ALPM_LOCK during correction for ALPM related tables */
   5020                 mem_to_lock = INVALIDm;
   5021                 is_l3_defip = TRUE;
   5022             }
   5023         }
   5024 #endif
   5025 
   5026     if (mem_to_lock != INVALIDm) {
   5027         MEM_LOCK(unit, mem_to_lock);
   5028     } else if (is_l3_defip) {
   5029         _ALPM_LOCK(unit);
   5030     }
   5031 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5032     /*
   5033      * On Trident2+ A0, disable learning and aging before Reading/Writing
   5034      * L2_ENTRY_ONLY_ECCm. Will be re-enabled after SER correction.
   5035      */
   5036     if ((mem == L2_ENTRY_ONLY_ECCm) &&
   5037         (soc_feature(unit, soc_feature_td2p_a0_sw_war) ||
   5038         soc_feature(unit, soc_feature_l2_activity_freeze_ser))) {
   5039         rv = soc_l2x_freeze(unit);
   5040         if (SOC_FAILURE(rv)) {
   5041             LOG_WARN(BSL_LS_SOC_SER,
   5042                      (BSL_META_U(unit,
   5043                                  "L2 freeze failed in L2_ENTRY_ONLY_ECCm correction\n")));
   5044             if (mem_to_lock != INVALIDm) {
   5045                 MEM_UNLOCK(unit, mem_to_lock);
   5046             }
   5047             goto free_exit;
   5048         }
   5049     }
   5050 #endif
   5051     cache = SOC_MEM_STATE(unit, mem_for_cache_read).cache[copyno];
   5052     vmap = SOC_MEM_STATE(unit, mem_for_cache_read).vmap[copyno];
   5053     entry_dw = soc_mem_entry_words(unit, mem_for_cache_read);
   5054     if ((mode == _SOC_SER_SRAM_CORRECTION_MODE_0) &&
   5055         (sram_info->disable_reg != INVALIDr)) {
   5056         rv = soc_reg32_get(unit, sram_info->disable_reg, REG_PORT_ANY, 0, &rval);
   5057 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5058         _SOC_IF_ERR_L2X_THAW(rv, mem);
   5059 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5060         _SOC_SER_SRAM_CHK_RETURN("reg get");
   5061         soc_reg_field_set(unit, sram_info->disable_reg, &rval,
   5062                           sram_info->disable_field, 1);
   5063         raddr = soc_reg_addr_get(unit, sram_info->disable_reg, REG_PORT_ANY, 0,
   5064                                  SOC_REG_ADDR_OPTION_WRITE, &block, &at);
   5065         at = 3;
   5066 #if defined(BCM_TOMAHAWK_SUPPORT)
   5067         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   5068             at = _SOC_TH_ACC_TYPE_DUPLICATE;
   5069             if ((mem == FPEM_ECCm) || (mem == FPEM_LPm)) {
   5070                 fpem_mem_mode = _soc_ser_mem_mode_get(unit, EXACT_MATCH_2m);
   5071                     /* Note: Assume both EM2, EM4 are always in same mode */
   5072                 if (fpem_mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) {
   5073                    at = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe);
   5074                 }
   5075             }
   5076         }
   5077 #endif /* BCM_TOMAHAWK_SUPPORT */
   5078         rv = _soc_reg32_set(unit, block, at, raddr, rval);
   5079 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5080         _SOC_IF_ERR_L2X_THAW(rv, mem);
   5081 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5082         _SOC_SER_SRAM_CHK_RETURN("reg set");
   5083     } else if (sram_info->disable_mem != INVALIDm) {
   5084         sal_memset(hash_control_entry, 0, sizeof(hash_control_entry));
   5085         rv = soc_mem_read(unit, sram_info->disable_mem, MEM_BLOCK_ANY,
   5086                           sram_info->disable_mem_index, hash_control_entry);
   5087 
   5088         _SOC_SER_SRAM_CHK_RETURN("mem read");
   5089         soc_mem_field32_set(unit, sram_info->disable_mem , hash_control_entry,
   5090                             sram_info->disable_mem_field, 1);
   5091         rv = soc_mem_write(unit, sram_info->disable_mem, MEM_BLOCK_ALL,
   5092                            sram_info->disable_mem_index, hash_control_entry);
   5093         _SOC_SER_SRAM_CHK_RETURN("mem write");
   5094     }
   5095 
   5096     for (i = 0; i < sram_info->ram_count; i++) {
   5097         /* coverity[uninit_use] */
   5098         start_index = sram_info->mem_indexes[i][0];
   5099         if ((mem == L3_ENTRY_IPV4_UNICASTm) || use_overlay_mem_correction) {
   5100             /* To avoid the unnecessary event of correction for Trident2 */
   5101             use_overlay_mem_correction = 1;
   5102             if (mem == FPEM_LPm) {
   5103                 if (sram_info->view[i] == FPEM_LPm) {
   5104                     null_entry = soc_mem_entry_null(unit, FPEM_LPm);
   5105                     rv = soc_mem_write(unit, FPEM_LPm, copyno, start_index,
   5106                                        null_entry);
   5107                             /* Note: we are clearing unused index - so ok to
   5108                              * clear in all pipes - no need to restrict access
   5109                              * to per pipe when,
   5110                              * (fpem_mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE)
   5111                              */
   5112 
   5113                     _SOC_SER_SRAM_CHK_RETURN("mem write");
   5114                     LOG_WARN(BSL_LS_SOC_SER,
   5115                               (BSL_META_U(unit,
   5116                                           "CLEAR_RESTORE: %s[%d] start_index: %d\n"),
   5117                                SOC_MEM_NAME(unit, FPEM_LPm), FPEM_LPm,
   5118                                start_index));
   5119                 } else {
   5120                     rv = _soc_ser_overlay_mem_correction(unit, 0, pipe, sblk,
   5121                                                          addr,
   5122                                                          sram_info->view[i],
   5123                                                          copyno, start_index,
   5124                                                          si);
   5125                 }
   5126             } else {
   5127                 rv = _soc_ser_overlay_mem_correction(unit, 0, pipe, sblk, addr,
   5128                                                      mem, copyno, start_index,
   5129                                                      si);
   5130             }
   5131             if (!(rv == SOC_E_NONE || rv == SOC_E_UNAVAIL)) {
   5132                     
   5133                 LOG_ERROR(BSL_LS_SOC_SER,
   5134                           (BSL_META_U(unit,
   5135                                       "SER SRAM correction encoutered error(%d) "
   5136                                       "in overlay mem correction\n"),
   5137                            rv));
   5138                 if (mem_to_lock != INVALIDm) {
   5139                     MEM_UNLOCK(unit, mem_to_lock);
   5140                 }
   5141                 goto free_exit;
   5142             }
   5143             if (si != NULL) {
   5144                 if (SocSerCorrectTypeCacheRestore == si->ctype ||
   5145                     socSerCorrectTypeHwCacheRestore == si->ctype) {
   5146                     ctype = si->ctype;
   5147                 }
   5148             }
   5149         } else if (((mem == L3_DEFIP_ALPM_IPV4m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4 == 1)) ||
   5150                    ((mem == L3_DEFIP_ALPM_IPV4_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 == 1)) ||
   5151                    ((mem == L3_DEFIP_ALPM_IPV6_64m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6 == 1)) ||
   5152                    ((mem == L3_DEFIP_ALPM_IPV6_64_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 == 1)) ||
   5153                    ((mem == L3_DEFIP_ALPM_IPV6_128m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 == 1)) ||
   5154                    ((mem == L3_DEFIP_PAIR_128m) && (alpm_no_cache_flag[unit].flag_defip_128 == 1)) ||
   5155                    ((mem == L3_DEFIPm) && (alpm_no_cache_flag[unit].flag_defip == 1)) ||
   5156                    ((mem == L3_DEFIP_AUX_TABLEm) && (alpm_no_cache_flag[unit].flag_defip_aux == 1)) ||
   5157                    use_recovery_hw_cache) {
   5158             /* To avoid the unnecessary event of correction for Trident2 */
   5159             use_recovery_hw_cache = 1;
   5160             for (j = 0; j < sram_info->index_count[i]; j++) {
   5161                 rv = _soc_ser_recovery_hw_cache(unit, pipe, sram_info->view[i],
   5162                                                 copyno, sram_info->mem_indexes[i][j],
   5163                                                 si, FALSE);
   5164                 if (!(rv == SOC_E_NONE || rv == SOC_E_UNAVAIL)) {
   5165                     
   5166                     LOG_ERROR(BSL_LS_SOC_SER,
   5167                               (BSL_META_U(unit,
   5168                                           "SER SRAM correction encoutered error(%d) "
   5169                                           "in recovery from hw cache\n"),
   5170                                rv));
   5171                     if (mem_to_lock != INVALIDm) {
   5172                         MEM_UNLOCK(unit, mem_to_lock);
   5173                     }
   5174                     _ALPM_UNLOCK(unit)
   5175                     _L2_UNLOCK(unit, _l2_lock)
   5176 
   5177                     goto free_exit;
   5178                 }
   5179             }
   5180         } else if ((sram_info->view[i] == L3_DEFIP_ALPM_IPV4m ||
   5181                     sram_info->view[i] == L3_DEFIP_ALPM_IPV4_1m ||
   5182                     sram_info->view[i] == L3_DEFIP_ALPM_IPV6_64m ||
   5183                     sram_info->view[i] == L3_DEFIP_ALPM_IPV6_64_1m ||
   5184                     sram_info->view[i] == L3_DEFIP_ALPM_IPV6_128m ||
   5185                     sram_info->view[i] == L3_DEFIP_ALPM_RAWm)) {
   5186             cache = SOC_MEM_STATE(unit, sram_info->view[i]).cache[copyno];
   5187             vmap = SOC_MEM_STATE(unit, sram_info->view[i]).vmap[copyno];
   5188             entry_dw = soc_mem_entry_words(unit, sram_info->view[i]);
   5189             for (j = 0; j < sram_info->index_count[i]; j++) {
   5190                 if (cache != NULL && CACHE_VMAP_TST(vmap, sram_info->mem_indexes[i][j])) {
   5191                     sal_memcpy(entry, cache + sram_info->mem_indexes[i][j] * entry_dw, entry_dw * 4);
   5192                     rv = soc_mem_write(unit, sram_info->view[i], copyno, sram_info->mem_indexes[i][j], entry);
   5193                     _SOC_SER_SRAM_CHK_RETURN("mem write");
   5194                     LOG_WARN(BSL_LS_SOC_SER,
   5195                               (BSL_META_U(unit,
   5196                                           "CACHE_RESTORE: %s[%d] start_index: %d\n"),
   5197                                SOC_MEM_NAME(unit, sram_info->view[i]),
   5198                                sram_info->view[i], sram_info->mem_indexes[i][j]));
   5199                     stat->ser_err_restor++;
   5200                     if (NULL != si) {
   5201                         if ((si->log_id != 0) &&
   5202                             (si->flags & SOC_SER_LOG_WRITE_CACHE)) {
   5203                             if (si->index == sram_info->mem_indexes[i][j]) {
   5204                                 (void)soc_ser_log_add_tlv(unit, si->log_id,
   5205                                                           SOC_SER_LOG_TLV_CACHE,
   5206                                                           entry_dw*4, entry);
   5207                             } else {
   5208                                 LOG_VERBOSE(BSL_LS_SOC_SER,
   5209                                     (BSL_META_U(unit,
   5210                                                 "skipped updating tlv_cache index: %d\n"),
   5211                                      sram_info->mem_indexes[i][j]));
   5212                             }
   5213                         }
   5214                     }
   5215                     ctype = SocSerCorrectTypeCacheRestore;
   5216                 } else { /* Fall back to clear */
   5217                     if (NUM_PIPE(unit) == 1) {
   5218                     null_entry = soc_mem_entry_null(unit, sram_info->view[i]);
   5219                     rv = soc_mem_write(unit, sram_info->view[i], copyno, sram_info->mem_indexes[i][j], null_entry);
   5220                     } else {
   5221                         rv = _soc_ser_recovery_hw_cache(unit, pipe, sram_info->view[i],
   5222                                                         copyno, sram_info->mem_indexes[i][j],
   5223                                                         si, FALSE);
   5224                     }
   5225                     _SOC_SER_SRAM_CHK_RETURN("mem write");
   5226                     LOG_WARN(BSL_LS_SOC_SER,
   5227                               (BSL_META_U(unit,
   5228                                           "CLEAR_RESTORE: %s[%d] start_index: %d\n"),
   5229                                SOC_MEM_NAME(unit, sram_info->view[i]),
   5230                                sram_info->view[i], sram_info->mem_indexes[i][j]));
   5231                     stat->ser_err_clear++;
   5232                 }
   5233             }
   5234         } else {   /* Correct from Cache */
   5235             if (cache != NULL && CACHE_VMAP_TST(vmap, start_index)) {
   5236                 sal_memcpy(entry, cache + start_index * entry_dw, entry_dw * 4);
   5237                 rv = soc_mem_write(unit, mem_to_restore, copyno, start_index, entry);
   5238 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5239                 _SOC_IF_ERR_L2X_THAW(rv, mem);
   5240 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5241                 _SOC_SER_SRAM_CHK_RETURN("mem write");
   5242                 LOG_WARN(BSL_LS_SOC_SER,
   5243                           (BSL_META_U(unit,
   5244                                       "CACHE_RESTORE: %s[%d] start_index: %d\n"),
   5245                            SOC_MEM_NAME(unit, mem_to_restore),
   5246                            mem_to_restore, start_index));
   5247                 stat->ser_err_restor++;
   5248                 if (NULL != si) {
   5249                     if ((si->log_id != 0) &&
   5250                         (si->flags & SOC_SER_LOG_WRITE_CACHE)) {
   5251                         if (si->index == start_index) {
   5252                             (void)soc_ser_log_add_tlv(unit, si->log_id,
   5253                                                       SOC_SER_LOG_TLV_CACHE,
   5254                                                       entry_dw*4, entry);
   5255                         } else {
   5256                             LOG_VERBOSE(BSL_LS_SOC_SER,
   5257                                 (BSL_META_U(unit,
   5258                                             "skipped updating tlv_cache index: %d\n"),
   5259                                  start_index));
   5260                         }
   5261                     }
   5262                 }
   5263                 ctype = SocSerCorrectTypeCacheRestore;
   5264             } else { /* Fall back to clear (write null-entry) */
   5265 
   5266                 null_entry = soc_mem_entry_null(unit, mem_to_restore);
   5267                 rv = soc_mem_write(unit, mem_to_restore, copyno, start_index, null_entry);
   5268 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5269                 _SOC_IF_ERR_L2X_THAW(rv, mem);
   5270 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5271 
   5272                 _SOC_SER_SRAM_CHK_RETURN("mem write");
   5273                 LOG_WARN(BSL_LS_SOC_SER,
   5274                           (BSL_META_U(unit,
   5275                                       "CLEAR_RESTORE: %s[%d] start_index: %d\n"),
   5276                            SOC_MEM_NAME(unit, mem_to_restore),
   5277                            mem_to_restore, start_index));
   5278                 stat->ser_err_clear++;
   5279             }
   5280         }
   5281     }
   5282 
   5283     if ((mode == _SOC_SER_SRAM_CORRECTION_MODE_0) &&
   5284         (sram_info->disable_reg != INVALIDr)) {
   5285         soc_reg_field_set(unit, sram_info->disable_reg, &rval,
   5286                           sram_info->disable_field, 0);
   5287         rv = _soc_reg32_set(unit, block, at, raddr, rval);
   5288 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5289         _SOC_IF_ERR_L2X_THAW(rv, mem);
   5290 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5291         _SOC_SER_SRAM_CHK_RETURN("reg set");
   5292     } else if (sram_info->disable_mem != INVALIDm) {
   5293         soc_mem_field32_set(unit, sram_info->disable_mem , hash_control_entry,
   5294                             sram_info->disable_mem_field, 0);
   5295         rv = soc_mem_write(unit, sram_info->disable_mem, MEM_BLOCK_ALL,
   5296                            sram_info->disable_mem_index, hash_control_entry);
   5297         _SOC_SER_SRAM_CHK_RETURN("mem write");
   5298     }
   5299 
   5300 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5301     /*TD2+ SW WAR. Enabled learning and aging */
   5302     if ((mem == L2_ENTRY_ONLY_ECCm) &&
   5303         (soc_feature(unit, soc_feature_td2p_a0_sw_war) ||
   5304         soc_feature(unit, soc_feature_l2_activity_freeze_ser))) {
   5305         rv = soc_l2x_thaw(unit);
   5306         if (SOC_FAILURE(rv)) {
   5307             LOG_WARN(BSL_LS_SOC_SER,
   5308                      (BSL_META_U(unit,
   5309                                  "L2 thaw failed in L2_ENTRY_ONLY_ECCm correction\n")));
   5310             if (mem_to_lock != INVALIDm) {
   5311                 MEM_UNLOCK(unit, mem_to_lock);
   5312             }
   5313             goto free_exit;
   5314         }
   5315     }
   5316 #endif
   5317 
   5318     if (mem_to_lock != INVALIDm) {
   5319         MEM_UNLOCK(unit, mem_to_lock);
   5320     }
   5321     _ALPM_UNLOCK(unit)
   5322     _L2_UNLOCK(unit, _l2_lock)
   5323 
   5324     /* resume alpm operations that could have been terminated because of ser
   5325      * problem
   5326      */
   5327     switch (mem) {
   5328     case L3_DEFIP_ALPM_IPV4m:
   5329     case L3_DEFIP_ALPM_IPV4_1m:
   5330     case L3_DEFIP_ALPM_IPV6_64m:
   5331     case L3_DEFIP_ALPM_IPV6_64_1m:
   5332     case L3_DEFIP_ALPM_IPV6_128m:
   5333     case L3_DEFIP_ALPM_ECCm:
   5334 #ifdef BCM_TOMAHAWK3_SUPPORT
   5335     case L3_DEFIP_ALPM_LEVEL3_ECCm:
   5336 #endif
   5337         if (SOC_CONTROL(unit)->alpm_lookup_retry &&
   5338             SHR_BITGET(&(SOC_CONTROL(unit)->alpm_mem_ops), _SOC_ALPM_LOOKUP)) {
   5339             sal_sem_give(SOC_CONTROL(unit)->alpm_lookup_retry);
   5340         }
   5341         if (SOC_CONTROL(unit)->alpm_insert_retry &&
   5342             SHR_BITGET(&(SOC_CONTROL(unit)->alpm_mem_ops), _SOC_ALPM_INSERT)) {
   5343             sal_sem_give(SOC_CONTROL(unit)->alpm_insert_retry);
   5344         }
   5345         if (SOC_CONTROL(unit)->alpm_delete_retry &&
   5346             SHR_BITGET(&(SOC_CONTROL(unit)->alpm_mem_ops), _SOC_ALPM_DELETE)) {
   5347             sal_sem_give(SOC_CONTROL(unit)->alpm_delete_retry);
   5348         }
   5349         break;
   5350     default: break;
   5351     }
   5352     if (NULL != si) {
   5353         if (use_recovery_hw_cache) {
   5354             ctype = socSerCorrectTypeHwCacheRestore;
   5355         }
   5356         si->ctype = ctype;
   5357         soc_ser_stat_update(unit, 0, si->blk_type,
   5358                             si->parity_type, si->double_bit,
   5359                             ctype, stat);
   5360     }
   5361     if (!(use_overlay_mem_correction || use_recovery_hw_cache)) {
   5362         _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   5363                                            si, mem_to_report, index);
   5364         stat->ser_err_corr++;
   5365     }
   5366     rv = SOC_E_NONE;
   5367 free_exit:
   5368     if (sram_info != NULL) {
   5369         sal_free(sram_info);
   5370     }
   5371     if (entry != NULL) {
   5372         sal_free(entry);
   5373     }
   5374 
   5375     return rv;
   5376 }
   5377 
   5378 int
   5379 soc_ser_sram_correction(int unit, int pipe, int sblk, int addr, soc_mem_t mem,
   5380                         int copyno, int index, _soc_ser_correct_info_t *si)
   5381 {
   5382     int rv;
   5383     LOG_VERBOSE(BSL_LS_SOC_SER,
   5384         (BSL_META_U(unit,
   5385                     "th_dbg: entered soc_ser_sram_correction "
   5386                     "routine\n")));
   5387 
   5388     
   5389     switch (mem) {
   5390     case L3_ENTRY_ONLYm:
   5391     case L3_ENTRY_IPV4_UNICASTm:
   5392     case L3_ENTRY_IPV4_MULTICASTm:
   5393     case L3_ENTRY_IPV6_UNICASTm:
   5394     case L3_ENTRY_IPV6_MULTICASTm:
   5395         rv = _soc_ser_sram_correction(unit, pipe, sblk, addr,
   5396                                       L3_ENTRY_IPV4_UNICASTm, copyno, index,
   5397                                       _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5398         if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) {
   5399             return rv;
   5400         }
   5401         break;
   5402     case L2Xm:
   5403     case L3_DEFIP_ALPM_IPV4m:
   5404     case L3_DEFIP_ALPM_IPV4_1m:
   5405     case L3_DEFIP_ALPM_IPV6_64m:
   5406     case L3_DEFIP_ALPM_IPV6_64_1m:
   5407     case L3_DEFIP_ALPM_IPV6_128m:
   5408     case L3_DEFIP_ALPM_RAWm:
   5409     case VLAN_XLATEm:
   5410     case EGR_VLAN_XLATEm:
   5411         return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5412                                         index, _SOC_SER_SRAM_CORRECTION_MODE_0,
   5413                                         si);
   5414 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \
   5415     defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   5416     case L2_ENTRY_ONLY_ECCm:
   5417     case L2_ENTRY_LPm:
   5418     case L2_ENTRY_ISS_LPm:
   5419     case L3_ENTRY_ONLY_ECCm:
   5420     case L3_ENTRY_LPm:
   5421     case L3_ENTRY_ISS_LPm:
   5422     case FPEM_LPm:
   5423     case L3_DEFIP_ALPM_ECCm:
   5424     case VLAN_XLATE_ECCm:
   5425     case VLAN_MACm:
   5426     case VLAN_XLATE_LPm:
   5427     case EGR_VLAN_XLATE_ECCm:
   5428     case EGR_VLAN_XLATE_LPm:
   5429     case EXACT_MATCH_LPm:
   5430     case VLAN_XLATE_1_LPm:
   5431     case VLAN_XLATE_2_LPm:
   5432     case EGR_VLAN_XLATE_1_LPm:
   5433     case EGR_VLAN_XLATE_2_LPm:
   5434     case MPLS_ENTRY_LPm:
   5435         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || 
   5436             SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) {
   5437             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5438                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5439         }
   5440         else {
   5441             break;
   5442         }
   5443     case FPEM_ECCm:
   5444 #if defined(INCLUDE_FLOWTRACKER)
   5445         if (SOC_CONTROL(unit)->uc_flowtracker_enable) {
   5446             return _soc_ft_em_ser_correction(unit, pipe, mem, index);
   5447         }
   5448 #endif /* INCLUDE_FLOWTRACKER */
   5449         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) ||
   5450             SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) {
   5451             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5452                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5453         }
   5454         else {
   5455             break;
   5456         }
   5457 #endif /* BCM_TOMAHAWK_SUPPORT */
   5458 #if defined(BCM_TRIDENT3_SUPPORT)
   5459     case MPLS_ENTRY_ECCm:
   5460     case VLAN_XLATE_1_ECCm:
   5461     case VLAN_XLATE_2_ECCm:
   5462     case EGR_VLAN_XLATE_1_ECCm:
   5463     case EGR_VLAN_XLATE_2_ECCm:
   5464     case ING_DNAT_ADDRESS_TYPE_ECCm:
   5465     case ING_VP_VLAN_MEMBERSHIP_ECCm:
   5466     case EGR_VP_VLAN_MEMBERSHIP_ECCm:
   5467     case SUBPORT_ID_TO_SGPP_MAP_ECCm:
   5468         if (SOC_IS_TRIDENT3X(unit)) {
   5469             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5470                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5471         } else {
   5472             break;
   5473         }
   5474     case VLAN_XLATE_1_SINGLEm:
   5475     case VLAN_XLATE_1_DOUBLEm:
   5476     case EGR_VLAN_XLATE_1_SINGLEm:
   5477     case EGR_VLAN_XLATE_1_DOUBLEm:
   5478     case VLAN_XLATE_2_SINGLEm:
   5479     case VLAN_XLATE_2_DOUBLEm:
   5480     case EGR_VLAN_XLATE_2_SINGLEm:
   5481     case EGR_VLAN_XLATE_2_DOUBLEm:
   5482         if (SOC_IS_TRIDENT3X(unit)) {
   5483             soc_trident3_vlan_xlate_mem_remap(&mem, &index);
   5484             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5485                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5486         } else {
   5487             break;
   5488         }
   5489 #endif
   5490 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   5491     case L2_ENTRY_ECCm:
   5492     case L3_ENTRY_ECCm:
   5493         if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   5494             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5495                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5496         } else {
   5497             break;
   5498         }
   5499     case EXACT_MATCH_ECCm:
   5500 #if defined(INCLUDE_FLOWTRACKER)
   5501         if (SOC_CONTROL(unit)->uc_flowtracker_enable) {
   5502             return _soc_ft_em_ser_correction(unit, pipe, mem, index);
   5503         }
   5504 #endif /* INCLUDE_FLOWTRACKER */
   5505         if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   5506             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5507                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5508         } else {
   5509             break;
   5510         }
   5511 #endif
   5512 #ifdef BCM_TOMAHAWK3_SUPPORT
   5513     case L3_DEFIP_ALPM_LEVEL3_ECCm:
   5514     case L3_DEFIP_ALPM_LEVEL3m:
   5515         if (SOC_IS_TOMAHAWK3(unit)) {
   5516             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5517                                             index, _SOC_SER_SRAM_CORRECTION_MODE_0, si);
   5518         }
   5519         break;
   5520 #endif
   5521     case ING_L3_NEXT_HOPm:
   5522         if (SOC_IS_TRIDENT3X(unit)) {
   5523             break;
   5524         } else {
   5525             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5526                                             index, _SOC_SER_SRAM_CORRECTION_MODE_1,
   5527                                             si);
   5528         }
   5529     case L3_IPMCm:
   5530     case L2MCm:
   5531         if (!SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TRIDENT3X(unit)) {
   5532             return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno,
   5533                                             index,
   5534                                             _SOC_SER_SRAM_CORRECTION_MODE_1,
   5535                                             si);
   5536         }
   5537         break;
   5538     default: break;
   5539     }
   5540     return SOC_E_UNAVAIL;
   5541 }
   5542 
   5543 int
   5544 soc_mem_alpm_aux_table_correction(int unit, int pipe, int index, soc_mem_t mem)
   5545 {
   5546     int rv = SOC_E_UNAVAIL;
   5547 #if defined(BCM_TRIDENT2_SUPPORT)
   5548     int bidx, sblk = 0, blk;
   5549     _soc_ser_correct_info_t spci;
   5550 #endif
   5551 
   5552 #if defined(BCM_TRIDENT2_SUPPORT)
   5553     blk = SOC_BLK_IPIPE;
   5554     SOC_BLOCK_ITER(unit, bidx, blk) {
   5555         sblk = SOC_BLOCK2SCH(unit, bidx);
   5556         break;
   5557     }
   5558 
   5559     if (SOC_IS_TD2_TT2(unit)) {
   5560         sal_memset(&spci, 0, sizeof(spci));
   5561         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   5562         spci.reg = INVALIDr;
   5563         spci.mem = mem;
   5564         spci.pipe_num = pipe;
   5565         spci.blk_type = blk;
   5566         spci.sblk = sblk;
   5567         spci.index = index;
   5568         spci.parity_type = SOC_PARITY_TYPE_PARITY;
   5569 
   5570         LOG_WARN(BSL_LS_SOC_SER,
   5571               (BSL_META_U(unit,
   5572                           "Inline correction: mem:%s pipe:%d index:%d\n"),
   5573                           SOC_MEM_NAME(unit, mem), pipe, index));
   5574 
   5575         return soc_ser_correction(unit, &spci);
   5576     } else
   5577 #endif
   5578     {
   5579         return rv;
   5580     }
   5581 }
   5582 
   5583 /* Writing back to logical table will trigger update to LP mem */
   5584 int
   5585 _soc_ser_lp_mem_correction(int unit, soc_mem_t mem, int index, int copyno)
   5586 {
   5587 #ifdef BCM_XGS_SWITCH_SUPPORT
   5588     int rv = SOC_E_NONE, i, entry_dw;
   5589     uint32 entry[SOC_MAX_MEM_WORDS];
   5590     soc_mem_t hash_mem[_SOC_SER_MEM_OVERLAY_SET] =
   5591         {INVALIDm, INVALIDm, INVALIDm, INVALIDm, INVALIDm, INVALIDm};
   5592     int hash_index[_SOC_SER_MEM_OVERLAY_SET] = {0};
   5593     uint32 *cache = NULL;
   5594     uint8 *vmap = NULL;
   5595 
   5596     LOG_VERBOSE(BSL_LS_SOC_SER,
   5597         (BSL_META_U(unit,
   5598                     "th_dbg: entered soc_ser_lp_mem_correction "
   5599                     "routine\n")));
   5600 
   5601 #ifdef BCM_HELIX5_SUPPORT
   5602     if (SOC_IS_HELIX5(unit)) {
   5603         /* Ignore error since index reported can be for a view which is never used
   5604          * This happens when LP table is directly written to instead of inserting
   5605          * proper entries in functional view
   5606          *
   5607          * Therefore, we clear erroneous LP entry first and then try to restore it
   5608          * from functional view if possible
   5609          */
   5610         (void)soc_hx5_ser_lp_mem_info_get(unit, mem, index,
   5611                                           hash_mem, hash_index);
   5612     } else
   5613 #endif
   5614 #ifdef BCM_MAVERICK2_SUPPORT
   5615     if (SOC_IS_MAVERICK2(unit)) {
   5616         (void)soc_mv2_ser_lp_mem_info_get(unit, mem, index,
   5617                                           hash_mem, hash_index);
   5618     } else
   5619 #endif
   5620     {
   5621     switch (mem) {
   5622     case L2_ENTRY_ISS_LPm:
   5623         hash_mem[0] = L2Xm;
   5624         hash_index[0] = (soc_mem_index_count(unit, L2_ENTRY_LPm) + index) * 4;
   5625         break;
   5626     case L2_ENTRY_LPm:
   5627         hash_mem[0] = L2Xm;
   5628         hash_index[0] = index * 4;
   5629         break;
   5630     case L3_ENTRY_ISS_LPm:
   5631         /* Restore all views for L3 LP mems */
   5632         hash_mem[0] = L3_ENTRY_IPV4_UNICASTm;
   5633         hash_index[0] = (soc_mem_index_count(unit, L3_ENTRY_LPm) + index) * 4;
   5634 
   5635         hash_mem[1] = L3_ENTRY_IPV4_MULTICASTm;
   5636         hash_index[1] = hash_index[0] / 2;
   5637 
   5638         hash_mem[2] = L3_ENTRY_IPV6_UNICASTm;
   5639         hash_index[2] = hash_index[0] / 2;
   5640 
   5641         hash_mem[3] = L3_ENTRY_IPV6_MULTICASTm;
   5642         hash_index[3] = soc_mem_index_count(unit, L3_ENTRY_LPm) + index;
   5643         break;
   5644     case L3_ENTRY_LPm:
   5645         hash_mem[0] = L3_ENTRY_IPV4_UNICASTm;
   5646         hash_index[0] = index * 4;
   5647 
   5648         hash_mem[1] = L3_ENTRY_IPV4_MULTICASTm;
   5649         hash_index[1] = hash_index[0] / 2;
   5650 
   5651         hash_mem[2] = L3_ENTRY_IPV6_UNICASTm;
   5652         hash_index[2] = hash_index[0] / 2;
   5653 
   5654         hash_mem[3] = L3_ENTRY_IPV6_MULTICASTm;
   5655         hash_index[3] = index;
   5656         break;
   5657     case VLAN_XLATE_LPm:
   5658         hash_mem[0] = VLAN_XLATEm;
   5659         hash_index[0] = index * 4;
   5660         break;
   5661     case EGR_VLAN_XLATE_LPm:
   5662         hash_mem[0] = EGR_VLAN_XLATEm;
   5663         hash_index[0] = index * 4;
   5664         break;
   5665     default:
   5666         return SOC_E_PARAM;
   5667     }
   5668     }
   5669 
   5670     /* Clear erroneous LP entry first, restoration done later */
   5671     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, copyno,
   5672                         index, soc_mem_entry_null(unit, mem)));
   5673 
   5674 for (i = 0; hash_mem[i] != INVALIDm; i++) {
   5675     if (hash_mem[i] != L2Xm) {
   5676         MEM_LOCK(unit, hash_mem[i]);
   5677     } else if (SOC_FAILURE(soc_l2x_freeze(unit))) {
   5678         LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 freeze failed\n")));
   5679     }
   5680 
   5681     if (copyno != -1) {
   5682         cache = SOC_MEM_STATE(unit, hash_mem[i]).cache[copyno];
   5683         vmap = SOC_MEM_STATE(unit, hash_mem[i]).vmap[copyno];
   5684     }
   5685 
   5686     rv = SOC_E_FAIL;
   5687 
   5688     /* If cache is valid, read from cache */
   5689     if (cache != NULL && vmap != NULL && CACHE_VMAP_TST(vmap, hash_index[i])) {
   5690         entry_dw = soc_mem_entry_words(unit, hash_mem[i]);
   5691         sal_memcpy(entry, cache + ((hash_index[i]) * entry_dw), entry_dw * 4);
   5692         rv = soc_mem_write(unit, hash_mem[i], copyno, hash_index[i], entry);
   5693     }
   5694 
   5695     if (hash_mem[i] != L2Xm) {
   5696         MEM_UNLOCK(unit, hash_mem[i]);
   5697     } else if (SOC_FAILURE(soc_l2x_thaw(unit))) {
   5698         LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 thaw failed\n")));
   5699     }
   5700 
   5701     if (SOC_SUCCESS(rv)) {
   5702         return rv;
   5703     }
   5704 }
   5705 
   5706 for (i = 0; hash_mem[i] != INVALIDm; i++) {
   5707     if (hash_mem[i] != L2Xm) {
   5708         MEM_LOCK(unit, hash_mem[i]);
   5709     } else if (SOC_FAILURE(soc_l2x_freeze(unit))) {
   5710         LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 freeze failed\n")));
   5711     }
   5712 
   5713     /* If cache is not valid, read from H/W */
   5714     rv = soc_mem_read(unit, hash_mem[i], copyno, hash_index[i], entry);
   5715     if (SOC_FAILURE(rv)) {
   5716         /* If read fails, write NULL entry */
   5717         rv = soc_mem_write(unit, hash_mem[i], copyno,
   5718                            hash_index[i], soc_mem_entry_null(unit, hash_mem[i]));
   5719     } else {
   5720         rv = soc_mem_write(unit, hash_mem[i], copyno, hash_index[i], entry);
   5721     }
   5722 
   5723     if (hash_mem[i] != L2Xm) {
   5724         MEM_UNLOCK(unit, hash_mem[i]);
   5725     } else if (SOC_FAILURE(soc_l2x_thaw(unit))) {
   5726         LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 thaw failed\n")));
   5727     }
   5728 
   5729     if (SOC_FAILURE(rv)) {
   5730         return rv;
   5731     }
   5732 
   5733 }
   5734     return rv;
   5735 #endif /* BCM_XGS_SWITCH_SUPPORT */
   5736     return SOC_E_NONE;
   5737 }
   5738 
   5739 STATIC void
   5740 _soc_ser_ism_correction(int unit)
   5741 {
   5742 #define _SOC_SER_ISM_DMA_CHUNK_SIZE 1024
   5743     uint32 *tbl_chnk;
   5744     int rv, m, buf_size, chunksize;
   5745     int chnk_idx, chnk_idx_max, mem_idx_max;
   5746     static soc_mem_t ism_mems[] = {
   5747         VLAN_XLATEm,
   5748         L2_ENTRY_1m,
   5749         L3_ENTRY_1m,
   5750         MPLS_ENTRYm,
   5751         EGR_VLAN_XLATEm
   5752     };
   5753     LOG_VERBOSE(BSL_LS_SOC_SER,
   5754         (BSL_META_U(unit,
   5755                     "th_dbg: entered soc_ser_ism_mem_correction "
   5756                     "routine\n")));
   5757 
   5758     chunksize = _SOC_SER_ISM_DMA_CHUNK_SIZE;
   5759     buf_size = 4 * SOC_MAX_MEM_WORDS * chunksize;
   5760     tbl_chnk = soc_cm_salloc(unit, buf_size, "ism ser correction");
   5761     if (NULL == tbl_chnk) {
   5762         LOG_ERROR(BSL_LS_SOC_SER,
   5763                   (BSL_META_U(unit,
   5764                               "Memory allocation failure in ser ism "
   5765                               "correction !!\n")));
   5766         return;
   5767     }
   5768 
   5769     for (m=0; m<COUNTOF(ism_mems); m++) {
   5770         if (!soc_mem_index_count(unit, ism_mems[m])) {
   5771             continue;
   5772         }
   5773         mem_idx_max = soc_mem_index_max(unit, ism_mems[m]);
   5774         MEM_LOCK(unit, ism_mems[m]);
   5775         for (chnk_idx = soc_mem_index_min(unit, ism_mems[m]);
   5776              chnk_idx <= mem_idx_max; chnk_idx += chunksize) {
   5777             sal_memset((void *)tbl_chnk, 0, buf_size);
   5778             chnk_idx_max = ((chnk_idx + chunksize) <= mem_idx_max) ?
   5779                 (chnk_idx + chunksize - 1) : mem_idx_max;
   5780             rv = soc_mem_read_range(unit, ism_mems[m], MEM_BLOCK_ANY, chnk_idx,
   5781                                     chnk_idx_max, tbl_chnk);
   5782             if (SOC_FAILURE(rv)) {
   5783                 LOG_ERROR(BSL_LS_SOC_SER,
   5784                           (BSL_META_U(unit,
   5785                                       "DMA failure in ser ism "
   5786                                       "correction for %s mem !!\n"),
   5787                            SOC_MEM_NAME(unit, ism_mems[m])));
   5788                 MEM_UNLOCK(unit, ism_mems[m]);
   5789                 soc_cm_sfree(unit, tbl_chnk);
   5790                 return;
   5791             }
   5792         }
   5793         MEM_UNLOCK(unit, ism_mems[m]);
   5794     }
   5795     soc_cm_sfree(unit, tbl_chnk);
   5796 }
   5797 
   5798 STATIC int check_parity(uint32 *p32, int n32)
   5799 {
   5800     uint32 parity = 0;
   5801     uint32 tmpI   = 0;
   5802 
   5803     for (n32--; n32>=0; n32--) {
   5804 
   5805         tmpI=p32[n32];
   5806         tmpI=tmpI^(tmpI>>1);
   5807         tmpI=tmpI^(tmpI>>2);
   5808         tmpI=tmpI^(tmpI>>4);
   5809         tmpI=tmpI^(tmpI>>8);
   5810         tmpI=tmpI^(tmpI>>16);
   5811 
   5812         parity = parity ^ (tmpI&1);
   5813     }
   5814 
   5815     return parity&1;
   5816 }
   5817 #ifdef _SER_TIME_STAMP
   5818 extern sal_usecs_t ser_time_1;
   5819 sal_usecs_t ser_time_5;
   5820 #endif
   5821 
   5822 int
   5823 _soc_oam_ser_correction(int unit, soc_mem_t mem, int index)
   5824 {
   5825     LOG_VERBOSE(BSL_LS_SOC_SER,
   5826         (BSL_META_U(unit,
   5827                     "th_dbg: entered _soc_oam_ser_correction "
   5828                     "routine\n")));
   5829 #ifdef BCM_TRIUMPH3_SUPPORT
   5830     if (SOC_IS_TRIUMPH3(unit)) {
   5831         return soc_tr3_oam_ser_process(unit, mem, index);
   5832     }
   5833 #endif /* BCM_TRIUMPH3_SUPPORT */
   5834 #ifdef BCM_HURRICANE2_SUPPORT
   5835     if (SOC_IS_HURRICANE2(unit)) {
   5836         return soc_hurricane2_oam_ser_process(unit, mem, index);
   5837     }
   5838 #endif /* BCM_HURRICANE2_SUPPORT */
   5839 #ifdef BCM_GREYHOUND_SUPPORT
   5840         if (SOC_IS_GREYHOUND(unit)) {
   5841             return soc_greyhound_oam_ser_process(unit, mem, index);
   5842         }
   5843 #endif /* BCM_GREYHOUND_SUPPORT */
   5844 #ifdef BCM_HURRICANE3_SUPPORT
   5845         if (SOC_IS_HURRICANE3(unit)) {
   5846             return soc_hr3_oam_ser_process(unit, mem, index);
   5847         }
   5848 #endif /* BCM_HURRICANE3_SUPPORT */
   5849 #ifdef BCM_GREYHOUND2_SUPPORT
   5850     if (SOC_IS_GREYHOUND2(unit)) {
   5851         return soc_gh2_oam_ser_process(unit, mem, index);
   5852     }
   5853 #endif /* BCM_GREYHOUND2_SUPPORT */
   5854 #ifdef BCM_KATANA2_SUPPORT
   5855     if (SOC_IS_KATANA2(unit)) {
   5856         return soc_kt2_oam_ser_process(unit, mem, index);
   5857     }
   5858 #endif /* BCM_KATANA2_SUPPORT */
   5859 
   5860 #ifdef BCM_TRIUMPH2_SUPPORT
   5861     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit)) {
   5862         return soc_triumph2_oam_ser_process(unit, mem, index);
   5863     }
   5864 #endif /* BCM_TRIUMPH2_SUPPORT */
   5865 
   5866     LOG_ERROR(BSL_LS_SOC_SER,
   5867               (BSL_META_U(unit,
   5868                           "SER Handling routine not avaialable\n")));
   5869     return SOC_E_UNAVAIL;
   5870 }
   5871 
   5872 #if defined(INCLUDE_FLOWTRACKER)
   5873 STATIC int
   5874 _soc_ft_em_ser_correction(int unit, int pipe, soc_mem_t mem, int index)
   5875 {
   5876    LOG_VERBOSE(BSL_LS_SOC_SER,
   5877         (BSL_META_U(unit,
   5878                     "th_dbg: entered _soc_ft_em_ser_correction routine\n")));
   5879    if (soc_feature(unit, soc_feature_uc_flowtracker_learn)) {
   5880        return soc_th_ft_em_ser_process(unit, pipe, mem, index);
   5881    }
   5882 
   5883     LOG_ERROR(BSL_LS_SOC_SER,
   5884               (BSL_META_U(unit,
   5885                           "SER Handling routine not avaialable\n")));
   5886    return SOC_E_UNAVAIL;
   5887  }
   5888 #endif /* INCLUDE_FLOWTRACKER */
   5889 
   5890 STATIC int
   5891 _soc_ser_ipfix_correction(int unit, soc_mem_t mem)
   5892 {
   5893     int port;
   5894     int ingress_stage = 0;
   5895     int rv;
   5896 
   5897     LOG_VERBOSE(BSL_LS_SOC_SER,
   5898         (BSL_META_U(unit,
   5899                     "th_dbg: entered _soc_ser_ipfix_correction "
   5900                     "routine\n")));
   5901     /*
   5902      * Also need to clear the
   5903      * 1. ingress/egress fifo counter
   5904      * 2. ingress/egress port record count
   5905      * 3. ingress/egress port sampling count
   5906      */
   5907     ingress_stage = (mem == ING_IPFIX_SESSION_TABLEm) ? 1 : 0;
   5908 
   5909     if (ingress_stage) {
   5910         rv = WRITE_ING_IPFIX_EXPORT_FIFO_COUNTERr(unit, 0);
   5911         if (rv < 0) {
   5912             LOG_ERROR(BSL_LS_SOC_SER,
   5913                       (BSL_META_U(unit,
   5914                                   "ING_IPFIX_EXPORT_FIFO_COUNTERr clear failed: %s\n"),
   5915                        soc_errmsg(rv)));
   5916             return rv;
   5917         }
   5918     } else {
   5919         rv = WRITE_EGR_IPFIX_EXPORT_FIFO_COUNTERr(unit, 0);
   5920         if (rv < 0) {
   5921             LOG_ERROR(BSL_LS_SOC_SER,
   5922                       (BSL_META_U(unit,
   5923                                   "EGR_IPFIX_EXPORT_FIFO_COUNTERr clear failed: %s\n"),
   5924                        soc_errmsg(rv)));
   5925             return rv;
   5926         }
   5927     }
   5928 
   5929     PBMP_PORT_ITER(unit, port) {
   5930         if (ingress_stage) {
   5931 
   5932             rv = WRITE_ING_IPFIX_PORT_RECORD_COUNTr(unit, port, 0);
   5933             if (rv < 0) {
   5934                 LOG_ERROR(BSL_LS_SOC_SER,
   5935                           (BSL_META_U(unit,
   5936                                       "ING_IPFIX_PORT_RECORD_COUNTr clear for "
   5937                                       "port(%d) failed: %s\n"),
   5938                            port, soc_errmsg(rv)));
   5939                 return rv;
   5940             }
   5941 
   5942             rv = WRITE_ING_IPFIX_PORT_SAMPLING_COUNTERr(unit, port, 0);
   5943             if (rv < 0) {
   5944                 LOG_ERROR(BSL_LS_SOC_SER,
   5945                           (BSL_META_U(unit,
   5946                                       "ING_IPFIX_PORT_SAMPLING_COUNTERr clear for "
   5947                                       "port(%d) failed: %s\n"),
   5948                            port, soc_errmsg(rv)));
   5949                 return rv;
   5950             }
   5951         } else {
   5952 
   5953             rv = WRITE_EGR_IPFIX_PORT_RECORD_COUNTr(unit, port, 0);
   5954             if (rv < 0) {
   5955                 LOG_ERROR(BSL_LS_SOC_SER,
   5956                           (BSL_META_U(unit,
   5957                                       "EGR_IPFIX_PORT_RECORD_COUNTr clear for "
   5958                                       "port(%d) failed: %s\n"),
   5959                            port, soc_errmsg(rv)));
   5960                 return rv;
   5961             }
   5962 
   5963             rv = WRITE_EGR_IPFIX_PORT_SAMPLING_COUNTERr(unit, port, 0);
   5964             if (rv < 0) {
   5965                 LOG_ERROR(BSL_LS_SOC_SER,
   5966                           (BSL_META_U(unit,
   5967                                       "EGR_IPFIX_PORT_SAMPLING_COUNTERr clear for "
   5968                                       "port(%d) failed: %s\n"),
   5969                            port, soc_errmsg(rv)));
   5970                 return rv;
   5971             }
   5972         }
   5973     }
   5974     return SOC_E_NONE;
   5975 }
   5976 
   5977 #ifdef BCM_CMICX_SUPPORT
   5978 int
   5979 soc_ser_top_intr_reg_enable(int unit, int num, int bit, int enable)
   5980 {
   5981     int rv = SOC_E_NONE;
   5982     uint32 reg_val = 0;
   5983     soc_reg_t ser_intr_reg[4] = {ICFG_CHIP_LP_INTR_ENABLE_REG0r,
   5984                                  ICFG_CHIP_LP_INTR_ENABLE_REG1r,
   5985                                  ICFG_CHIP_LP_INTR_ENABLE_REG2r,
   5986                                  ICFG_CHIP_LP_INTR_ENABLE_REG3r};
   5987 
   5988     rv = soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[num],
   5989                           REG_PORT_ANY, 0), &reg_val);
   5990     if (rv == SOC_E_NONE) {
   5991         if (enable == 1) {
   5992             reg_val |= 1 << bit;
   5993         } else {
   5994             reg_val &= ~(1 << bit);
   5995         }
   5996 
   5997         rv = soc_iproc_setreg(unit, soc_reg_addr(unit, ser_intr_reg[num],
   5998                               REG_PORT_ANY, 0), reg_val);
   5999     }
   6000 
   6001     return rv;
   6002 }
   6003 
   6004 void soc_ser_cmicx_intr_handler(int unit, void *data)
   6005 {
   6006     uint32 reg0_val = 0;
   6007     uint32 reg1_val = 0;
   6008     uint32 reg2_val = 0;
   6009     uint32 reg3_val = 0;
   6010     int i = 0, j = 0, k = 0;
   6011     soc_reg_t ser_intr_reg[4] = {ICFG_CHIP_LP_INTR_RAW_STATUS_REG0r,
   6012                                  ICFG_CHIP_LP_INTR_RAW_STATUS_REG1r,
   6013                                  ICFG_CHIP_LP_INTR_RAW_STATUS_REG2r,
   6014                                  ICFG_CHIP_LP_INTR_RAW_STATUS_REG3r};
   6015 
   6016     (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[0], REG_PORT_ANY, 0),
   6017                      &reg0_val);
   6018     (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[1], REG_PORT_ANY, 0),
   6019                      &reg1_val);
   6020     (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[2], REG_PORT_ANY, 0),
   6021                      &reg2_val);
   6022     (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[3], REG_PORT_ANY, 0),
   6023                      &reg3_val);
   6024 
   6025     for(i = 0, j = 0, k = 0; i < 32; i++, j++, k++) {
   6026         if(reg0_val & 1 << i) {
   6027 #ifdef BCM_TRIDENT3_SUPPORT
   6028             if (SOC_IS_TRIDENT3X(unit)) {
   6029             if((i == 0) || (i >= 4 && i <= 12)) {
   6030                 (void)soc_ser_top_intr_reg_enable(unit, 0, i, 0);
   6031             LOG_INFO(BSL_LS_SOC_INTR,
   6032                      (BSL_META_U(unit,
   6033                                      "soc_ser_cmicx_intr_handler type 0 unit %d: dispatch\n"), unit));
   6034                 if (soc_ser_parity_error_cmicx_intr(INT_TO_PTR(unit), 0, 0,
   6035                                                     INT_TO_PTR(0),
   6036                                                     INT_TO_PTR(i))) {
   6037             } else {
   6038                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6039                           (BSL_META_U(unit,
   6040                                           "soc_ser_cmicx_intr_handler unit %d: "
   6041                                       "Disabling unhandled interrupt(s): %d\n"),
   6042                                unit, PTR_TO_INT(i)));
   6043                     (void)soc_ser_top_intr_reg_enable(unit, 0, i, 0);
   6044             }
   6045             } else if (i == 1) {
   6046             LOG_INFO(BSL_LS_SOC_INTR,
   6047                      (BSL_META_U(unit,
   6048                                  "soc_cmicm_intr type 3 unit %d: dispatch\n"),
   6049                       unit));
   6050 
   6051                 sal_dpc(soc_trident3_process_func_intr, INT_TO_PTR(unit),
   6052                             0, 0, 0, INT_TO_PTR(i));
   6053             }
   6054         }
   6055 #endif
   6056     }
   6057 
   6058         if (reg1_val & 1 << i) {
   6059 #ifdef BCM_TRIDENT3_SUPPORT
   6060             if (SOC_IS_TRIDENT3X(unit)) {
   6061             (void)soc_ser_top_intr_reg_enable(unit, 1, i, 0);
   6062             if (soc_ser_parity_error_cmicx_intr(INT_TO_PTR(unit), 0, 0,
   6063                                                 INT_TO_PTR(1),
   6064                                                 INT_TO_PTR(i))) {
   6065             } else {
   6066                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6067                           (BSL_META_U(unit,
   6068                                       "soc_ser_cmicx_intr_handler unit %d: "
   6069                                       "Disabling unhandled interrupt(s): %d\n"),
   6070                            unit, PTR_TO_INT(i)));
   6071                 (void)soc_ser_top_intr_reg_enable(unit, 1, i, 0);
   6072             }
   6073         }
   6074 #endif
   6075         }
   6076 
   6077         if (reg2_val & 1 << i) {
   6078             (void)soc_ser_top_intr_reg_enable(unit, 2, i, 0);
   6079             if (soc_ser_parity_error_cmicx_intr(INT_TO_PTR(unit), 0, 0,
   6080                                                 INT_TO_PTR(2),
   6081                                                 INT_TO_PTR(i))) {
   6082             } else {
   6083                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6084                           (BSL_META_U(unit,
   6085                                       "soc_ser_cmicx_intr_handler unit %d: "
   6086                                       "Disabling unhandled interrupt(s): %d\n"),
   6087                            unit, PTR_TO_INT(i)));
   6088                 (void)soc_ser_top_intr_reg_enable(unit, 2, i, 0);
   6089             }
   6090         }
   6091     }
   6092 }
   6093 #endif
   6094 
   6095 #ifdef BCM_TSN_SUPPORT
   6096 STATIC int
   6097 _soc_ser_mem_is_tsn_cnt_mem(int unit, soc_mem_t mem)
   6098 {
   6099 #ifdef BCM_GREYHOUND2_SUPPORT
   6100     if (SOC_IS_GREYHOUND2(unit) &&
   6101         /* Port cnt */
   6102         (mem == SR_PORT_COUNT_RXm ||
   6103          mem == SR_PORT_COUNT_RX_TAGGEDm ||
   6104          mem == SR_PORT_COUNT_RX_WRONG_LANm ||
   6105          mem == SR_PORT_COUNT_RX_ERRORm ||
   6106          mem == SR_PORT_COUNT_RX_TAG_ERRORm ||
   6107          mem == SR_PORT_COUNT_RX_DUPLICATESm ||
   6108          mem == SR_PORT_COUNT_RX_OUTOFORDERm ||
   6109          mem == SR_PORT_COUNT_OWN_RXm ||
   6110          mem == SR_PORT_COUNT_UNEXPECTED_FRAMEm ||
   6111          mem == SR_PORT_MTU_ERRORm || mem == SR_PORT_STU_ERRORm ||
   6112          mem == SR_PORT_PROXY_MAC_ERRORm ||
   6113          mem == SR_PORT_COUNT_RX_PASSEDm ||
   6114          mem == SR_PORT_COUNT_TXm ||
   6115          mem == SR_PORT_COUNT_TX_TAGGEDm ||
   6116          mem == SR_PORT_TX_MTU_ERRORm || mem == SR_PORT_TX_STU_ERRORm ||
   6117         /* Flow cnt */
   6118          mem == SR_FLOW_COUNT_POOL0m || mem == SR_FLOW_COUNT_POOL1m ||
   6119          mem == SR_FLOW_COUNT_POOL2m || mem == SR_FLOW_COUNT_POOL3m ||
   6120          mem == SR_FLOW_COUNT_POOL4m || mem == SR_FLOW_COUNT_POOL5m ||
   6121          mem == SR_FLOW_COUNT_POOL6m || mem == SR_FLOW_COUNT_POOL7m ||
   6122          mem == EGR_SR_FLOW_COUNT_POOL0m || mem == EGR_SR_FLOW_COUNT_POOL1m)) {
   6123         return TRUE;
   6124     }
   6125 #endif /* BCM_GREYHOUND2_SUPPORT */
   6126     return FALSE;
   6127 }
   6128 #endif /* BCM_TSN_SUPPORT */
   6129 
   6130 STATIC int
   6131 _soc_ser_mem_entry_clear(int unit, soc_mem_t mem, int copyno,
   6132                          int index, _soc_ser_correct_info_t *si,
   6133                          soc_ser_log_tlv_generic_t *log_generic,
   6134                          soc_stat_t *stat)
   6135 {
   6136     int rv = SOC_E_NONE;
   6137     void *null_entry = NULL;
   6138 #ifdef BCM_TRIUMPH3_SUPPORT
   6139     uint32 rval;
   6140 #endif
   6141     uint32 stat_flags = 0;
   6142     int block_type = 0;
   6143     int parity_type = 0;
   6144 
   6145     LOG_VERBOSE(BSL_LS_SOC_SER,
   6146         (BSL_META_U(unit,
   6147                     "th_dbg: SER_CORRECTION_TYPE = "
   6148                     "ENTRY_CLEAR for mem = %0d\n"), mem));
   6149 #ifdef BCM_TRIUMPH3_SUPPORT
   6150     if (SOC_IS_TRIUMPH3(unit)) {
   6151         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   6152         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1);
   6153         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   6154     }
   6155 #endif
   6156 
   6157     if (si->flags & SOC_SER_ALSO_UPDATE_SW_COUNTER) {
   6158         rv = SOC_E_FAIL;
   6159         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   6160             rv = soc_ser_update_counter(
   6161                     unit,
   6162                     0,               /* is_reg */
   6163                     INVALIDr,        /* restore_reg */
   6164                     si->mem,         /* restore_mem */
   6165                     si->index,
   6166                     copyno,
   6167                     INVALIDr,        /* base_reg */
   6168                     si->counter_base_mem, /* base_mem */
   6169                     si->inst, /* inst_num */
   6170                     si->pipe_num,
   6171                     SOC_SER_COUNTER_CORRECTION(unit)); /* restore_last */
   6172         }
   6173     } else {
   6174         null_entry = soc_mem_entry_null(unit, mem);
   6175         rv = soc_mem_write(unit, mem, copyno, index, null_entry);
   6176     }
   6177 
   6178     if (rv < 0) {
   6179         LOG_ERROR(BSL_LS_SOC_SER,
   6180                   (BSL_META_U(unit,
   6181                               "ENTRY_CLEAR %s.%s[%d] failed: %s\n"),
   6182                    SOC_MEM_NAME(unit, mem),
   6183                    SOC_BLOCK_NAME(unit, copyno), index, soc_errmsg(rv)));
   6184         if (si->log_id != 0) {
   6185             log_generic->corrected = SOC_SER_UNCORRECTED;
   6186             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6187                 sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6188         }
   6189         return rv;
   6190     }
   6191 #if defined(BCM_TRIDENT_SUPPORT)
   6192     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT(unit)) {
   6193         soc_ser_counter_info_set(unit, mem, index, null_entry);
   6194     }
   6195 #endif
   6196 #ifdef BCM_TRIUMPH3_SUPPORT
   6197     if (SOC_IS_TRIUMPH3(unit)) {
   6198         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0);
   6199         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   6200 
   6201     }
   6202 #endif
   6203     _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   6204                                        si, mem, index);
   6205     LOG_WARN(BSL_LS_SOC_SER,
   6206               (BSL_META_U(unit,
   6207                           "ENTRY_CLEAR: %s[%d] blk: %s index: %d : [%d][%x]\n"),
   6208                SOC_MEM_NAME(unit, mem), mem,
   6209                SOC_BLOCK_NAME(unit, copyno), index, si->sblk, si->addr));
   6210 
   6211     /* Handle IPFIX ser */
   6212     if (mem == ING_IPFIX_SESSION_TABLEm ||
   6213         mem == EGR_IPFIX_SESSION_TABLEm) {
   6214         if ((rv = _soc_ser_ipfix_correction(unit, mem)) < 0) {
   6215             if (si->log_id != 0) {
   6216                 log_generic->corrected = SOC_SER_UNCORRECTED;
   6217                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6218                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6219             }
   6220             return rv;
   6221         }
   6222     }
   6223 
   6224     stat->ser_err_clear++;
   6225     if (si->log_id != 0) {
   6226         log_generic->corrected = SOC_SER_CORRECTED;
   6227         soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6228             sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6229     }
   6230     if ((si->mem != INVALIDm) &&
   6231         (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) {
   6232         stat_flags = SOC_SER_STAT_TCAM;
   6233         block_type = SOC_BLOCK_INFO(unit, copyno).type;
   6234         parity_type = SOC_PARITY_TYPE_PARITY;
   6235     } else {
   6236         stat_flags = 0;
   6237         block_type = si->blk_type;
   6238         parity_type = si->parity_type;
   6239     }
   6240     soc_ser_stat_update(unit, stat_flags, block_type,
   6241                         parity_type, si->double_bit,
   6242                         SocSerCorrectTypeEntryClear,
   6243                         stat);
   6244 #ifdef BCM_TSN_SUPPORT
   6245     if (soc_feature(unit, soc_feature_tsn) &&
   6246         (soc_ser_tsn_stat_functions[unit] != NULL) &&
   6247         (soc_ser_tsn_stat_functions[unit]->_soc_tsn_stat_counter_update_f != NULL)) {
   6248         uint64 new_packet_count;
   6249         COMPILER_64_ZERO(new_packet_count);
   6250 
   6251         if (_soc_ser_mem_is_tsn_cnt_mem(unit, mem)) {
   6252             rv = (*(soc_ser_tsn_stat_functions[unit]->_soc_tsn_stat_counter_update_f))(
   6253                     unit, mem, index, new_packet_count);
   6254             if (SOC_FAILURE(rv)) {
   6255                 LOG_ERROR(BSL_LS_SOC_SER,
   6256                           (BSL_META_U(unit,
   6257                                       "ENTRY_CLEAR %s.%s[%d] "
   6258                                       "tsn cnt clear failed: %s\n"),
   6259                            SOC_MEM_NAME(unit, mem),
   6260                            SOC_BLOCK_NAME(unit, copyno), index, soc_errmsg(rv)));
   6261             }
   6262         }
   6263     }
   6264 #endif /* BCM_TSN_SUPPORT */
   6265     return SOC_E_NONE;
   6266 }
   6267 
   6268 STATIC int
   6269 _soc_ser_mem_entry_restore(int unit, soc_mem_t mem, int copyno,
   6270                            int index, _soc_ser_correct_info_t *si,
   6271                            soc_ser_log_tlv_generic_t *log_generic,
   6272                            soc_stat_t *stat, uint32 flags,
   6273                            uint32 *entry)
   6274 {
   6275     int rv = SOC_E_NONE;
   6276     int is_l3_defip = FALSE;
   6277     int entry_dw;
   6278     void *null_entry = NULL;
   6279     uint32 *cache = NULL;
   6280     uint8 *vmap;
   6281 #if defined(ALPM_ENABLE)
   6282     uint8 _alpm_lock = 0;
   6283 #endif /* ALPM_ENABLE */
   6284     uint32 stat_flags = 0;
   6285     int block_type = 0;
   6286     int parity_type = 0;
   6287     soc_ser_correction_type_t ctype;
   6288 #ifdef BCM_TOMAHAWK_SUPPORT
   6289     uint16 dev_id;
   6290     uint8 rev_id;
   6291     uint8 at = 0;
   6292     int recover_pipe = si->pipe_num;
   6293 #endif
   6294 
   6295     LOG_VERBOSE(BSL_LS_SOC_SER,
   6296         (BSL_META_U(unit,
   6297         "th_dbg: SER_CORRECTION_TYPE = %s for mem = %0d\n"),
   6298         ((flags == SOC_MEM_FLAG_SER_ECC_CORRECTABLE) ? "ECC_CORRECTABLE" :
   6299         (flags == SOC_MEM_FLAG_SER_CACHE_RESTORE) ? "CACHE_RESTORE" :
   6300         (flags == SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE) ? "WRITE_CACHE_RESTORE" : "UNKNOW"),
   6301         mem));
   6302 
   6303     if (SOC_IS_TD2_TT2(unit)) {
   6304         if (mem == L3_DEFIP_ALPM_IPV4m || mem == L3_DEFIP_ALPM_IPV4_1m ||
   6305             mem == L3_DEFIP_ALPM_IPV6_64m || mem == L3_DEFIP_ALPM_IPV6_64_1m ||
   6306             mem == L3_DEFIP_ALPM_IPV6_128m || mem == L3_DEFIP_AUX_TABLEm ||
   6307             mem == L3_DEFIPm || mem == L3_DEFIP_PAIR_128m ||
   6308             mem == L3_DEFIP_ALPM_LEVEL2_ECCm || mem == L3_DEFIP_TCAM_LEVEL1m ||
   6309             mem == L3_DEFIP_PAIR_LEVEL1m || mem == L3_DEFIP_DATA_LEVEL1m) {
   6310             /* Take advantage of SER write cache flow */
   6311             is_l3_defip = TRUE;
   6312         }
   6313     }
   6314 
   6315     /* In TD2, the HW does SBUS MEMWR error checking
   6316      * on the L3_ENTRY table in general. Include both
   6317      * XOR and non-XOR mems.
   6318      */
   6319 #if defined(BCM_TRIDENT2_SUPPORT)
   6320     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) {
   6321         soc_trident2_l3_memwr_parity_check(unit, mem, TRUE);
   6322     }
   6323 #endif /* BCM_TRIDENT2_SUPPORT */
   6324 #if defined(BCM_TRIDENT3_SUPPORT)
   6325     if (SOC_IS_TRIDENT3X(unit)) {
   6326         soc_trident3_l3_memwr_parity_check(unit, mem, TRUE);
   6327     }
   6328 #endif
   6329     rv = _soc_ser_overlay_mem_correction(unit, si->flags & SOC_SER_ERR_CPU ? 1 : 0,
   6330                                          si->pipe_num, si->sblk, si->addr, mem,
   6331                                          copyno, index, si);
   6332 
   6333 #if defined(BCM_TRIDENT3_SUPPORT)
   6334     if (SOC_IS_TRIDENT3X(unit)) {
   6335         soc_trident3_l3_memwr_parity_check(unit, mem, FALSE);
   6336     }
   6337 #endif
   6338 #if defined(BCM_TRIDENT_SUPPORT)
   6339     if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
   6340         if (rv == SOC_E_UNAVAIL)  {
   6341             rv = soc_trident_ser_dual_pipe_correction(unit, mem, copyno, index, si);
   6342         }
   6343     }
   6344 #endif
   6345 
   6346 #if defined(BCM_TRIDENT2_SUPPORT)
   6347     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) {
   6348         soc_trident2_l3_memwr_parity_check(unit, mem, FALSE);
   6349     }
   6350 #endif /* BCM_TRIDENT2_SUPPORT */
   6351     if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) {
   6352         if (si->log_id != 0) {
   6353             log_generic->corrected = (rv == SOC_E_NONE);
   6354             if (rv == SOC_E_NONE) {
   6355                 log_generic->hw_cache =
   6356                     (si->ctype == socSerCorrectTypeHwCacheRestore) ? TRUE : FALSE;
   6357                 if (si->ctype == SocSerCorrectTypeEntryClear) {
   6358                     log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR;
   6359                 } else if (si->ctype == SocSerCorrectTypeCacheRestore) {
   6360                     log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE;
   6361                 }
   6362             }
   6363             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6364                 sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6365         }
   6366         if (rv == SOC_E_NONE) {
   6367             if ((si->mem != INVALIDm) &&
   6368                 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) {
   6369                 stat_flags = SOC_SER_STAT_TCAM;
   6370                 block_type = SOC_BLOCK_INFO(unit, copyno).type;
   6371                 parity_type = SOC_PARITY_TYPE_PARITY;
   6372             } else {
   6373                 stat_flags = 0;
   6374                 block_type = si->blk_type;
   6375                 parity_type = si->parity_type;
   6376             }
   6377             ctype = si->ctype ? si->ctype : SocSerCorrectTypeCacheRestore;
   6378             soc_ser_stat_update(unit, stat_flags, block_type,
   6379                                 parity_type, si->double_bit,
   6380                                 ctype,
   6381                                 stat);
   6382         }
   6383         return rv;
   6384     }
   6385             /* Take lock to ensure that cache won't be changed during correction */
   6386     if (is_l3_defip) {
   6387         _ALPM_LOCK(unit);
   6388     } else {
   6389         MEM_LOCK(unit, mem);
   6390     }
   6391     cache = SOC_MEM_STATE(unit, mem).cache[copyno];
   6392     vmap = SOC_MEM_STATE(unit, mem).vmap[copyno];
   6393     if (is_l3_defip && (NUM_PIPE(unit) > 1)) {
   6394         /* For L3_DEFIP* tables, we can't use cache for SER correction
   6395          * on multi-pipe devices
   6396          */
   6397         if (((mem == L3_DEFIPm) && (alpm_no_cache_flag[unit].flag_defip == 1)) ||
   6398             ((mem == L3_DEFIP_PAIR_128m) && (alpm_no_cache_flag[unit].flag_defip_128 == 1)) ||
   6399             ((mem == L3_DEFIP_ALPM_IPV4m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4 == 1)) ||
   6400             ((mem == L3_DEFIP_ALPM_IPV4_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 == 1)) ||
   6401             ((mem == L3_DEFIP_ALPM_IPV6_64m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6 == 1)) ||
   6402             ((mem == L3_DEFIP_ALPM_IPV6_64_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 == 1)) ||
   6403             ((mem == L3_DEFIP_ALPM_IPV6_128m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 == 1)) ||
   6404             ((mem == L3_DEFIP_AUX_TABLEm) && (alpm_no_cache_flag[unit].flag_defip_aux == 1)) ||
   6405             (mem == L3_DEFIP_ALPM_LEVEL2_ECCm) || (mem == L3_DEFIP_TCAM_LEVEL1m) ||
   6406             (mem == L3_DEFIP_PAIR_LEVEL1m) || (mem == L3_DEFIP_DATA_LEVEL1m) ||
   6407             ((cache != NULL) && (!CACHE_VMAP_TST(vmap, index)))) {
   6408             cache = NULL;
   6409         }
   6410     }
   6411     if ((cache == NULL) && (NUM_PIPE(unit) > 1)) {
   6412 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   6413         if ((SOC_IS_TD2_TT2(unit) &&
   6414             (mem == L3_DEFIPm ||
   6415              mem == L3_DEFIP_PAIR_128m) )||
   6416              (SOC_IS_TOMAHAWK3(unit) &&
   6417              (mem == L3_DEFIP_TCAM_LEVEL1m || mem == L3_DEFIP_DATA_LEVEL1m ||
   6418               mem == L3_DEFIP_PAIR_LEVEL1m))) {
   6419             rv = _soc_ser_recovery_hw_cache(unit, si->pipe_num, mem,
   6420                                             copyno, index, si, TRUE);
   6421         } else
   6422 #endif
   6423         {
   6424             rv = _soc_ser_recovery_hw_cache(unit, si->pipe_num, mem,
   6425                                             copyno, index, si, FALSE);
   6426         }
   6427         if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) {
   6428             if (rv == SOC_E_NONE && mem == L3_DEFIP_AUX_TABLEm &&
   6429                 SOC_IS_TD2_TT2(unit)) {
   6430                 if (SOC_CONTROL(unit)->alpm_bulk_retry) {
   6431                     sal_sem_give(SOC_CONTROL(unit)->alpm_bulk_retry);
   6432                 }
   6433             }
   6434             if (si->log_id != 0) {
   6435                 log_generic->corrected = (rv == SOC_E_NONE);
   6436                 log_generic->hw_cache = (rv == SOC_E_NONE) ? TRUE : FALSE;
   6437                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6438                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6439             }
   6440             if (rv == SOC_E_NONE) {
   6441                 if ((si->mem != INVALIDm) &&
   6442                     (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) {
   6443                     stat_flags = SOC_SER_STAT_TCAM;
   6444                     block_type = SOC_BLOCK_INFO(unit, copyno).type;
   6445                     parity_type = SOC_PARITY_TYPE_PARITY;
   6446                 } else {
   6447                     stat_flags = 0;
   6448                     block_type = si->blk_type;
   6449                     parity_type = si->parity_type;
   6450                 }
   6451                 soc_ser_stat_update(unit, stat_flags, block_type,
   6452                                     parity_type, si->double_bit,
   6453                                     socSerCorrectTypeHwCacheRestore,
   6454                                     stat);
   6455             }
   6456             if (is_l3_defip) {
   6457                 _ALPM_UNLOCK(unit)
   6458             } else {
   6459                 MEM_UNLOCK(unit,mem);
   6460             }
   6461             return rv;
   6462         }
   6463     }
   6464     if (cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   6465         entry_dw = soc_mem_entry_words(unit, mem);
   6466         sal_memcpy(entry, cache + index * entry_dw, entry_dw * 4);
   6467         if ((si->log_id != 0) &&
   6468             (si->flags & SOC_SER_LOG_WRITE_CACHE)) {
   6469             (void)soc_ser_log_add_tlv(unit, si->log_id,
   6470                                       SOC_SER_LOG_TLV_CACHE,
   6471                                       entry_dw*4, entry);
   6472         }
   6473 
   6474 #ifdef BCM_TOMAHAWK_SUPPORT
   6475         soc_cm_get_id(unit, &dev_id, &rev_id);
   6476         at = SOC_MEM_ACC_TYPE(unit, mem);
   6477 
   6478         if ((dev_id == BCM56983_DEVICE_ID ) &&
   6479             ((at == _SOC_TH_ACC_TYPE_DUPLICATE_2) ||
   6480              (at == _SOC_TH_ACC_TYPE_DUPLICATE_4))) {
   6481             if (at == _SOC_TH_ACC_TYPE_DUPLICATE_2) {
   6482                 if (si->pipe_num == 1) {
   6483                     recover_pipe = 0;
   6484                 } else if (si->pipe_num == 6) {
   6485                     recover_pipe = 7;
   6486                 }
   6487             }
   6488             if (at == _SOC_TH_ACC_TYPE_DUPLICATE_4) {
   6489                 if (si->pipe_num == 1 || si->pipe_num == 6 || si->pipe_num == 7) {
   6490                     recover_pipe = 0;
   6491                 }
   6492             }
   6493             rv = soc_mem_pipe_select_write(unit, SOC_MEM_NO_FLAGS, mem,
   6494                                            copyno, recover_pipe, index, entry);
   6495         } else
   6496 #endif
   6497         {
   6498             rv = soc_mem_write(unit, mem, copyno, index, entry);
   6499         }
   6500         if (rv < 0) {
   6501             LOG_ERROR(BSL_LS_SOC_SER,
   6502                       (BSL_META_U(unit,
   6503                                   "CACHE_RESTORE %s.%s[%d] failed: %s\n"),
   6504                        SOC_MEM_NAME(unit, mem),
   6505                        SOC_BLOCK_NAME(unit, copyno),
   6506                        index, soc_errmsg(rv)));
   6507 
   6508             if (is_l3_defip) {
   6509                 _ALPM_UNLOCK(unit)
   6510             } else {
   6511                 MEM_UNLOCK(unit,mem);
   6512             }
   6513 
   6514             if (si->log_id != 0) {
   6515                 log_generic->corrected = (rv == SOC_E_NONE);
   6516                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6517                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6518             }
   6519             return rv;
   6520         }
   6521         if (si->log_id != 0) {
   6522             log_generic->corrected = SOC_SER_CORRECTED;
   6523             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6524                 sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6525         }
   6526         if ((si->mem != INVALIDm) &&
   6527             (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) {
   6528             stat_flags = SOC_SER_STAT_TCAM;
   6529             block_type = SOC_BLOCK_INFO(unit, copyno).type;
   6530             parity_type = SOC_PARITY_TYPE_PARITY;
   6531         } else {
   6532             stat_flags = 0;
   6533             block_type = si->blk_type;
   6534             parity_type = si->parity_type;
   6535         }
   6536         soc_ser_stat_update(unit, stat_flags, block_type,
   6537                             parity_type, si->double_bit,
   6538                             SocSerCorrectTypeCacheRestore,
   6539                             stat);
   6540         _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   6541                                            si, mem, index);
   6542         LOG_WARN(BSL_LS_SOC_SER,
   6543                   (BSL_META_U(unit,
   6544                               "CACHE_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"),
   6545                    SOC_MEM_NAME(unit, mem), mem,
   6546                    SOC_BLOCK_NAME(unit, copyno),
   6547                    index, si->sblk, si->addr));
   6548         stat->ser_err_restor++;
   6549 #ifdef _SER_TIME_STAMP
   6550         ser_time_5 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1);
   6551         LOG_CLI((BSL_META_U(unit,
   6552                             "Total: %d\n"), ser_time_5));
   6553 #endif
   6554     } else { /* Fall back to clear */
   6555         LOG_VERBOSE(BSL_LS_SOC_SER,
   6556             (BSL_META_U(unit,
   6557                         "th_dbg: "
   6558                         "main routine falling back to clear\n")));
   6559         null_entry = soc_mem_entry_null(unit, mem);
   6560 #ifdef BCM_TRIDENT2_SUPPORT
   6561         if (SOC_IS_TRIDENT2(unit) &&
   6562             (mem == ES_PIPE0_LLS_PORT_MEMA_CONFIGm) &&
   6563             (si->index > 52 && si->index < 64)) {
   6564             rv = soc_mem_write_extended(unit,
   6565                                         SOC_MEM_DONT_USE_CACHE | SOC_MEM_DONT_CHECK_INDEX,
   6566                                         mem, copyno, index, null_entry);
   6567         } else
   6568 #endif
   6569         {
   6570             rv = soc_mem_write(unit, mem, copyno, index, null_entry);
   6571         }
   6572         if (rv < 0) {
   6573             LOG_ERROR(BSL_LS_SOC_SER,
   6574                       (BSL_META_U(unit,
   6575                                   "CLEAR_RESTORE %s.%s[%d] failed: %s\n"),
   6576                        SOC_MEM_NAME(unit, mem),
   6577                        SOC_BLOCK_NAME(unit, copyno),
   6578                        index, soc_errmsg(rv)));
   6579 
   6580             if (is_l3_defip) {
   6581                 _ALPM_UNLOCK(unit)
   6582             } else {
   6583                 MEM_UNLOCK(unit, mem);
   6584             }
   6585 
   6586             if (si->log_id != 0) {
   6587                 log_generic->corrected = SOC_SER_UNCORRECTED;
   6588                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6589                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6590             }
   6591             return rv;
   6592         }
   6593 
   6594         if (si->log_id != 0) {
   6595             log_generic->corrected = SOC_SER_CORRECTED;
   6596             log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR;
   6597             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6598                 sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6599         }
   6600         if ((si->mem != INVALIDm) &&
   6601             (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) {
   6602             stat_flags = SOC_SER_STAT_TCAM;
   6603             block_type = SOC_BLOCK_INFO(unit, copyno).type;
   6604             parity_type = SOC_PARITY_TYPE_PARITY;
   6605         } else {
   6606             stat_flags = 0;
   6607             block_type = si->blk_type;
   6608             parity_type = si->parity_type;
   6609         }
   6610         soc_ser_stat_update(unit, stat_flags, block_type,
   6611                             parity_type, si->double_bit,
   6612                             SocSerCorrectTypeEntryClear,
   6613                             stat);
   6614         _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   6615                                            si, mem, index);
   6616         LOG_WARN(BSL_LS_SOC_SER,
   6617                   (BSL_META_U(unit,
   6618                               "CLEAR_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"),
   6619                    SOC_MEM_NAME(unit, mem), mem,
   6620                    SOC_BLOCK_NAME(unit, copyno),
   6621                    index, si->sblk, si->addr));
   6622         if (_SOC_DRV_MEM_CHK_L2_MEM(mem) &&
   6623             soc_feature(unit, soc_feature_mac_learn_limit)) {
   6624             if ((rv =_soc_ser_sync_mac_limits(unit, mem)) != SOC_E_NONE) {
   6625                 LOG_ERROR(BSL_LS_SOC_SER,
   6626                           (BSL_META_U(unit,
   6627                                       "L2 mac limit sync failed !!\n")));
   6628                 if (is_l3_defip) {
   6629                     _ALPM_UNLOCK(unit)
   6630                 } else {
   6631                     MEM_UNLOCK(unit, mem);
   6632                 }
   6633                 return rv;
   6634             }
   6635         }
   6636         stat->ser_err_clear++;
   6637 #ifdef _SER_TIME_STAMP
   6638         ser_time_5 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1);
   6639         LOG_CLI((BSL_META_U(unit,
   6640                             "Total: %d\n"), ser_time_5));
   6641 #endif
   6642     }
   6643     if ((cache != NULL) && !(si->flags & SOC_SER_SKIP_HARD_FALT_CHECK)) {
   6644         rv = _soc_ser_check_hard_fault(unit, mem, si->acc_type, copyno,
   6645                                          index,
   6646                                          null_entry == NULL ?
   6647                                          entry : null_entry, 0,
   6648                                          si->pipe_num, FALSE);
   6649         if (is_l3_defip) {
   6650             _ALPM_UNLOCK(unit)
   6651         } else {
   6652             MEM_UNLOCK(unit, mem);
   6653         }
   6654 
   6655         return rv;
   6656     }
   6657 
   6658     if (is_l3_defip) {
   6659         _ALPM_UNLOCK(unit)
   6660     } else {
   6661         MEM_UNLOCK(unit, mem);
   6662     }
   6663     return SOC_E_NONE;
   6664 }
   6665 
   6666 STATIC int
   6667 _soc_vfp_ser_correction(int unit, soc_mem_t mem, int index, int copyno)
   6668 {
   6669     int rv = SOC_E_NONE;
   6670 
   6671 #ifdef BCM_TOMAHAWK2_SUPPORT
   6672     if (SOC_IS_TOMAHAWK2(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) {
   6673         int entry_dw;
   6674         entry_dw = soc_mem_entry_words(unit, mem);
   6675         rv = soc_th2_vfp_ser_correction(unit, mem, index, copyno, entry_dw);
   6676     }
   6677 #endif
   6678 
   6679     return rv;
   6680 }
   6681 
   6682 STATIC int
   6683 _soc_ser_mem_entry_special(int unit, soc_mem_t mem, int copyno,
   6684                               int index, _soc_ser_correct_info_t *si,
   6685                               soc_ser_log_tlv_generic_t *log_generic,
   6686                               soc_stat_t *stat)
   6687 {
   6688     int rv = SOC_E_NONE;
   6689 
   6690     if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) ==
   6691         SOC_MEM_FLAG_SER_SPECIAL) {
   6692         LOG_VERBOSE(BSL_LS_SOC_SER,
   6693             (BSL_META_U(unit,
   6694                         "th_dbg: SER_CORRECTION_TYPE = "
   6695                         "SPECIAL for mem = %0d\n"), mem));
   6696     }
   6697     stat->ser_err_spe++;
   6698     
   6699     switch (mem) {
   6700         case L2_ENTRY_LPm:
   6701         case L2_ENTRY_ISS_LPm:
   6702         case L3_ENTRY_LPm:
   6703         case L3_ENTRY_ISS_LPm:
   6704         case VLAN_XLATE_LPm:
   6705         case EGR_VLAN_XLATE_LPm:
   6706         case EXACT_MATCH_LPm:
   6707         case VLAN_XLATE_1_LPm:
   6708         case VLAN_XLATE_2_LPm:
   6709         case EGR_VLAN_XLATE_1_LPm:
   6710         case EGR_VLAN_XLATE_2_LPm:
   6711         case MPLS_ENTRY_LPm:
   6712             LOG_WARN(BSL_LS_SOC_SER,
   6713                       (BSL_META_U(unit,
   6714                                   "SER_SPECIAL: %s[%d] blk: %s index: %d : [%d][%x]\n"),
   6715                        SOC_MEM_NAME(unit, mem), mem,
   6716                        SOC_BLOCK_NAME(unit, copyno),
   6717                        index, si->sblk, si->addr));
   6718             rv = _soc_ser_lp_mem_correction(unit, mem, index, copyno);
   6719             if (SOC_SUCCESS(rv)) {
   6720                 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   6721                                                    si, mem, index);
   6722                 stat->ser_err_corr++;
   6723             } else {
   6724                 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit,
   6725                           "SER correction failed for LP memory \n")));
   6726 
   6727             }
   6728             break;
   6729         case PORT_OR_TRUNK_MAC_COUNTm:
   6730         case VLAN_OR_VFI_MAC_COUNTm:
   6731             rv = _soc_ser_sync_mac_limits(unit, mem);
   6732             break;
   6733         case MA_STATEm:
   6734         case RMEPm:
   6735             rv = _soc_oam_ser_correction(unit, mem, index);
   6736             if (rv != SOC_E_NONE) {
   6737                 LOG_ERROR(BSL_LS_SOC_SER,
   6738                           (BSL_META_U(unit,
   6739                                       "Error in SER Handling rv=%d\n"),
   6740                            rv));
   6741             }
   6742             break;
   6743         case VFP_TCAMm:
   6744             rv = _soc_vfp_ser_correction(unit, mem, index, copyno);
   6745             if (rv != SOC_E_NONE) {
   6746                 LOG_ERROR(BSL_LS_SOC_SER,
   6747                           (BSL_META_U(unit,
   6748                                       "Error in SER Handling rv=%d\n"),
   6749                            rv));
   6750             }
   6751             break;
   6752         default:
   6753             LOG_ERROR(BSL_LS_SOC_SER,
   6754                       (BSL_META_U(unit,
   6755                                   "Unknown ser correction !!\n")));
   6756             rv = SOC_E_INTERNAL;
   6757             stat->ser_err_sw++;
   6758             break;
   6759     }
   6760     if (si->log_id != 0) {
   6761         log_generic->corrected = (rv == SOC_E_NONE);
   6762         soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6763             sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6764     }
   6765     if (rv == SOC_E_NONE) {
   6766         soc_ser_stat_update(unit, 0, si->blk_type,
   6767                             si->parity_type, si->double_bit,
   6768                             SocSerCorrectTypeSpecial,
   6769                             stat);
   6770     }
   6771     return rv;
   6772 }
   6773 
   6774 void
   6775 soc_ser_stat_update(int unit, uint32 flags, int blk_type,
   6776                            int parity_type, uint8 db,
   6777                            soc_ser_correction_type_t ctype,
   6778                            soc_stat_t *stat)
   6779 {
   6780     soc_ser_block_type_t btype = 0;
   6781     soc_ser_error_type_t etype = 0;
   6782 
   6783     if (!soc_feature(unit, soc_feature_ser_error_stat)) {
   6784         return;
   6785     }
   6786 
   6787     switch (blk_type) {
   6788         case SOC_BLK_MMU:
   6789             btype = SocSerBlockTypeMMU;
   6790             break;
   6791         case SOC_BLK_MMU_GLB:
   6792             btype = SocSerBlockTypeMMU_GLB;
   6793             break;
   6794         case SOC_BLK_MMU_SC:
   6795             btype = SocSerBlockTypeMMU_SC;
   6796             break;
   6797         case SOC_BLK_MMU_SED:
   6798             btype = SocSerBlockTypeMMU_SED;
   6799             break;
   6800         case SOC_BLK_MMU_XPE:
   6801             btype = SocSerBlockTypeMMU_XPE;
   6802             break;
   6803         case SOC_BLK_IPIPE:
   6804             btype = SocSerBlockTypeIPIPE;
   6805             break;
   6806         case SOC_BLK_EPIPE:
   6807             btype = SocSerBlockTypeEPIPE;
   6808             break;
   6809         case SOC_BLK_PGW_CL:
   6810             btype = SocSerBlockTypePGW;
   6811             break;
   6812         case SOC_BLK_CLPORT:
   6813             btype = SocSerBlockTypeCLPORT;
   6814             break;
   6815         case SOC_BLK_XTPORT:
   6816             btype = SocSerBlockTypeXLPORT;
   6817             break;
   6818         case SOC_BLK_MACSEC:
   6819             btype = SocSerBlockTypeMACSEC;
   6820             break;
   6821         default:
   6822             break;
   6823     }
   6824 
   6825     if (parity_type == SOC_PARITY_TYPE_PARITY) {
   6826         etype = SocSerErrorTypeParity;
   6827     } else if (parity_type == SOC_PARITY_TYPE_ECC &&
   6828                db == 0) {
   6829         etype = SocSerErrorTypeEccSingleBit;
   6830     } else if (parity_type == SOC_PARITY_TYPE_ECC &&
   6831                db == 1) {
   6832         etype = SocSerErrorTypeEccDoubleBit;
   6833     } else {
   6834         etype = SocSerErrorTypeUnknown;
   6835     }
   6836 
   6837     SOC_SER_ERR_STAT_LOCK(unit);
   6838     if (flags & SOC_SER_STAT_TCAM) {
   6839         stat->ser_tcam_err[btype][etype][ctype]++;
   6840     }
   6841     stat->ser_err[btype][etype][ctype]++;
   6842 
   6843     SOC_SER_ERR_STAT_UNLOCK(unit);
   6844     return;
   6845 }
   6846 
   6847 STATIC int
   6848 _soc_ser_mem_correction(int unit, _soc_ser_correct_info_t *si,
   6849                            soc_ser_log_tlv_generic_t *log_generic,
   6850                            soc_stat_t *stat)
   6851 {
   6852     soc_mem_t mem = si->mem;
   6853     int rv, index = si->index, entry_dw;
   6854     int copyno = 0;
   6855     uint32 entry[SOC_MAX_MEM_WORDS];
   6856     uint32 flags = 0;
   6857     soc_ser_log_tlv_memory_t log_mem;
   6858     log_mem.index = index;
   6859 
   6860     if (!(si->flags & SOC_SER_REG_MEM_KNOWN)) {
   6861         /* Decode memory from address details */
   6862         mem = soc_addr_to_mem_extended(unit, si->sblk, si->acc_type, si->addr);
   6863         if (mem == INVALIDm) {
   6864                 if (si->log_id != 0) {
   6865                 log_mem.memory = mem;
   6866                 log_generic->corrected = SOC_SER_UNCORRECTED;
   6867                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_MEMORY,
   6868                     sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   6869                     soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6870                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6871             }
   6872             if (soc_feature(unit, soc_feature_two_ingress_pipes) &&
   6873                 soc_feature(unit, soc_feature_sbusdma)) {
   6874                 LOG_VERBOSE(BSL_LS_SOC_SER,
   6875                             (BSL_META_U(unit,
   6876                                         "memory not decoded [%d %d 0x%8x].\n"),
   6877                              si->sblk, si->acc_type, si->addr));
   6878                 return SOC_E_NOT_FOUND;
   6879             } else {
   6880                 LOG_ERROR(BSL_LS_SOC_SER,
   6881                           (BSL_META_U(unit,
   6882                                       "memory not decoded [%d %d 0x%8x].\n"),
   6883                            si->sblk, si->acc_type, si->addr));
   6884                 stat->ser_err_sw++;
   6885                 return SOC_E_INTERNAL;
   6886             }
   6887                 }
   6888     }
   6889     /* In TR3 and HX4, there are several memory names VLAN_XLATEm, 
   6890      * VLAN_XLATE_1m, VLAN_XLATE_EXTDm for the physical VLAN_XLATE 
   6891      * table, refering to single or double base entry views. 
   6892      * When parity errors are detected in the physical table, 
   6893      * _soc_ser_overlay_mem_correction should be invoked with the parameter 
   6894      * "reported_mem" as VLAN_XLATE_1m to correct errors in appropiate table
   6895      * views. The routine soc_addr_to_mem_extended always returns VLAN_XLATEm, 
   6896      * not VLAN_XLATE_1m. So overriding memory name is added here.
   6897      * The long term way to handle these things which are per device is 
   6898      * to register a per device memory check and over-ride function and 
   6899      * call it from soc_ser_correction() */
   6900     if (soc_feature(unit, soc_feature_ism_memory) && mem == VLAN_XLATEm) {
   6901         mem = VLAN_XLATE_1m;
   6902     }
   6903     if (!SOC_MEM_IS_VALID(unit, mem)) {
   6904                 return SOC_E_INTERNAL;
   6905             }
   6906     if (si->log_id != 0) {
   6907         if (si->flags & SOC_SER_LOG_MEM_REPORTED) {
   6908             log_mem.memory = si->mem_reported;
   6909         } else {
   6910             log_mem.memory = mem;
   6911         }
   6912         log_generic->ser_response_flag = SOC_MEM_SER_CORRECTION_TYPE(unit, mem);
   6913         soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_MEMORY,
   6914             sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   6915     }
   6916 
   6917     if (si->sblk) {
   6918         SOC_MEM_BLOCK_ITER(unit, mem, copyno) {
   6919             if (SOC_BLOCK2OFFSET(unit, copyno) == si->sblk) {
   6920                 break;
   6921             }
   6922         }
   6923     } else {
   6924         copyno = SOC_MEM_BLOCK_ANY(unit, mem);
   6925     }
   6926     stat->ser_err_mem++;
   6927     LOG_WARN(BSL_LS_SOC_SER,
   6928               (BSL_META_U(unit,
   6929                           "mem: %d=%s blkoffset:%d\n"), mem,
   6930                SOC_MEM_NAME(unit, mem), copyno));
   6931     entry_dw = soc_mem_entry_words(unit, mem);
   6932     if (soc_feature(unit, soc_feature_shared_hash_mem)) {
   6933         rv = soc_ser_sram_correction(unit, si->pipe_num, si->sblk, si->addr,
   6934                                      mem, copyno, index, si);
   6935         if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) {
   6936             if (si->log_id != 0) {
   6937                 log_generic->corrected = (rv == SOC_E_NONE);
   6938                 if (si->ctype == SocSerCorrectTypeEntryClear) {
   6939                     log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR;
   6940                 } else if (si->ctype == SocSerCorrectTypeCacheRestore) {
   6941                     log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE;
   6942                 }
   6943                 log_generic->hw_cache =
   6944                     (si->ctype == socSerCorrectTypeHwCacheRestore) ? TRUE : FALSE;
   6945                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6946                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6947             }
   6948             return rv;
   6949         }
   6950     }
   6951     if (soc_feature(unit, soc_feature_fp_meter_ser_verify) &&
   6952         (FP_METER_TABLEm == mem)) {
   6953         int i=0;
   6954 
   6955         /* Get data even on parity error */
   6956         if (SOC_E_NONE == soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN,
   6957                                                 mem, 0, copyno, index, entry)) {
   6958             if (!check_parity(entry, entry_dw)) {
   6959                 if (si->log_id != 0) {
   6960                     log_generic->corrected = SOC_SER_UNKNOWN;
   6961                     soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6962                         sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6963                 }
   6964                 /* No error case. Print and return */
   6965                 LOG_WARN(BSL_LS_SOC_SER,
   6966                          (BSL_META_U(unit,
   6967                                      "NO PARITY ERROR: reg/mem:%d btype:%d sblk:%d at:%d "
   6968                                      "stage:%d addr:0x%08x index: %d\n"),
   6969                           (si->flags & SOC_SER_SRC_MEM) ? si->mem : si->reg,
   6970                           si->blk_type, si->sblk, si->acc_type,
   6971                           si->stage, si->addr, si->index));
   6972 
   6973                 for (i=0;i<entry_dw;i++) {
   6974                     LOG_WARN(BSL_LS_SOC_SER,
   6975                              (BSL_META_U(unit,
   6976                                          "NO PARITY ERROR: Entry[%d]:%08X\n"), i, entry[i]));
   6977                 }
   6978                 return SOC_E_NONE;
   6979             }
   6980         }
   6981     } else if (soc_feature(unit, soc_feature_ism_memory) &&
   6982                (mem == RAW_ENTRY_TABLEm)) {
   6983         /* Packet lookup encountered an error - dump mems from cpu and do
   6984            normal correction */
   6985         _soc_ser_ism_correction(unit);
   6986         if (si->log_id != 0) {
   6987             log_generic->corrected = SOC_SER_UNKNOWN;
   6988             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   6989                 sizeof(soc_ser_log_tlv_generic_t), log_generic);
   6990         }
   6991         return SOC_E_NONE;
   6992     }
   6993 
   6994     switch (SOC_MEM_SER_CORRECTION_TYPE(unit, mem)) {
   6995         case SOC_MEM_FLAG_SER_ENTRY_CLEAR:
   6996             return _soc_ser_mem_entry_clear(unit, mem, copyno,index, si,
   6997                                             log_generic, stat);
   6998         case SOC_MEM_FLAG_SER_ECC_CORRECTABLE:
   6999             if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) ==
   7000                 SOC_MEM_FLAG_SER_ECC_CORRECTABLE) {
   7001                 flags = SOC_MEM_FLAG_SER_ECC_CORRECTABLE;
   7002             }
   7003             stat->ser_err_ecc++;
   7004             /* passthru */
   7005             /* coverity[fallthrough: FALSE] */
   7006         case SOC_MEM_FLAG_SER_CACHE_RESTORE:
   7007             if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) ==
   7008                 SOC_MEM_FLAG_SER_CACHE_RESTORE) {
   7009                 flags = SOC_MEM_FLAG_SER_CACHE_RESTORE;
   7010             }
   7011             /* passthru */
   7012             /* coverity[fallthrough: FALSE] */
   7013         case SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE:
   7014             if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) ==
   7015                 SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE) {
   7016                 flags = SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE;
   7017             }
   7018             return _soc_ser_mem_entry_restore(unit, mem, copyno, index, si,
   7019                                               log_generic, stat, flags, entry);
   7020         case SOC_MEM_FLAG_SER_SPECIAL:
   7021             return _soc_ser_mem_entry_special(unit, mem, copyno, index, si,
   7022                                               log_generic, stat);
   7023         default:
   7024             if (si->log_id != 0) {
   7025                 log_generic->corrected = SOC_SER_UNCORRECTED;
   7026                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7027                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7028             }
   7029             stat->ser_err_sw++;
   7030             return SOC_E_INTERNAL;
   7031     }
   7032 }
   7033 
   7034 STATIC int
   7035 _soc_ser_reg_correction(int unit, _soc_ser_correct_info_t *si,
   7036                            soc_ser_log_tlv_generic_t *log_generic,
   7037                            soc_stat_t *stat)
   7038 {
   7039     uint64 rval64;
   7040     int rv, index = si->index;
   7041     int copyno = 0;
   7042     soc_reg_t reg = si->reg;
   7043     soc_port_t port = si->port;
   7044     soc_ser_log_tlv_register_t log_reg;
   7045 
   7046     if (si->log_id != 0) {
   7047         log_reg.index = index;
   7048     }
   7049 
   7050     stat->ser_err_reg++;
   7051     if (!(si->flags & SOC_SER_REG_MEM_KNOWN)) {
   7052          soc_regaddrinfo_t ainfo;
   7053 
   7054          /* Decode register from address details */
   7055          soc_regaddrinfo_extended_get(unit, &ainfo, si->sblk,
   7056                                       si->acc_type, si->addr);
   7057          reg = ainfo.reg;
   7058          port = ainfo.port;
   7059          if (si->log_id != 0) {
   7060             log_reg.port = port;
   7061             log_reg.reg = reg;
   7062          }
   7063          if (reg == INVALIDr || port == -1) {
   7064             if (si->log_id != 0) {
   7065            log_generic->corrected = SOC_SER_UNCORRECTED;
   7066                soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7067                sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7068                soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER,
   7069                    sizeof(soc_ser_log_tlv_register_t), &log_reg);
   7070             }
   7071             if (soc_feature(unit, soc_feature_two_ingress_pipes) &&
   7072                 soc_feature(unit, soc_feature_sbusdma)) {
   7073                 LOG_VERBOSE(BSL_LS_SOC_SER,
   7074                             (BSL_META_U(unit,
   7075                                         "register not decoded [%d %d 0x%8x].\n"),
   7076                              si->sblk, si->acc_type, si->addr));
   7077                 return SOC_E_NOT_FOUND;
   7078             } else {
   7079                 LOG_ERROR(BSL_LS_SOC_SER,
   7080                           (BSL_META_U(unit,
   7081                                       "register not decoded [%d %d 0x%8x].\n"),
   7082                            si->sblk, si->acc_type, si->addr));
   7083                 stat->ser_err_sw++;
   7084                 return SOC_E_INTERNAL;
   7085             }
   7086          }
   7087          index = ainfo.idx >= 0 ? ainfo.idx : 0;
   7088          LOG_WARN(BSL_LS_SOC_SER,
   7089                    (BSL_META_U(unit,
   7090                                "reg: %d=%s port: %d index: %d\n"),
   7091                     reg, SOC_REG_NAME(unit, reg), ainfo.port, index));
   7092     }
   7093     if (reg == INVALIDr || port == -1) {
   7094         if (si->log_id != 0) {
   7095             log_generic->corrected = SOC_SER_UNCORRECTED;
   7096             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7097                                 sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7098             soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER,
   7099                                 sizeof(soc_ser_log_tlv_register_t), &log_reg);
   7100         }
   7101         return SOC_E_PARAM;
   7102     }
   7103     if (si->blk_type >= 0) {
   7104         SOC_BLOCK_ITER(unit, copyno, si->blk_type) {
   7105             if (SOC_BLOCK_TYPE(unit, copyno) == si->blk_type) {
   7106                 break;
   7107             }
   7108         }
   7109     }
   7110     if (!SOC_REG_IS_VALID(unit, reg)) {
   7111         return SOC_E_INTERNAL;
   7112     }
   7113     if (SOC_REG_IS_COUNTER(unit, reg)) {
   7114         if (si->flags & SOC_SER_REG_READ_AGAIN) {
   7115             if (SOC_REG_IS_VALID(unit, ICTRL_64r)) {
   7116                 (void)soc_reg_get(unit, ICTRL_64r, port, index, &rval64);
   7117             }
   7118         }
   7119         if (SOC_SER_COUNTER_CORRECTION(unit) == 0) {
   7120             COMPILER_64_ZERO(rval64);
   7121             /* Clear counter in h/w and s/w */
   7122             rv = soc_counter_set(unit, port, reg, index, rval64);
   7123 
   7124             if (si->log_id != 0) {
   7125                 log_generic->corrected = (rv == SOC_E_NONE);
   7126                 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR;
   7127                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7128                                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7129                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER,
   7130                                     sizeof(soc_ser_log_tlv_register_t), &log_reg);
   7131             }
   7132 
   7133             SOC_IF_ERROR_RETURN(rv);
   7134             LOG_WARN(BSL_LS_SOC_SER,
   7135                       (BSL_META_U(unit,
   7136                                   "COUNTER_CLEAR: %s[%d] blk: %s index: %d : port[%d]\n"),
   7137                        SOC_REG_NAME(unit, reg), reg,
   7138                        SOC_BLOCK_NAME(unit, copyno),
   7139                        index, port));
   7140             stat->ser_err_clear++;
   7141             soc_ser_stat_update(unit, 0, si->blk_type,
   7142                                 si->parity_type, si->double_bit,
   7143                                 SocSerCorrectTypeEntryClear,
   7144                                 stat);
   7145         } else {
   7146             /* Restore last s/w counter value in h/w */
   7147             rv = soc_counter_get(unit, port, reg, index, &rval64);
   7148 
   7149             if (si->log_id != 0) {
   7150                 log_generic->corrected = (rv == SOC_E_NONE);
   7151                 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE;
   7152                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7153                                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7154                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER,
   7155                                     sizeof(soc_ser_log_tlv_register_t), &log_reg);
   7156             }
   7157 
   7158             SOC_IF_ERROR_RETURN(rv);
   7159             SOC_IF_ERROR_RETURN(soc_counter_set(unit, port, reg, index, rval64));
   7160             LOG_WARN(BSL_LS_SOC_SER,
   7161                       (BSL_META_U(unit,
   7162                                   "COUNTER_RESTORE: %s[%d] blk: %s index: %d : port[%d]\n"),
   7163                        SOC_REG_NAME(unit, reg), reg,
   7164                        SOC_BLOCK_NAME(unit, copyno),
   7165                        index, port));
   7166             stat->ser_err_restor++;
   7167             soc_ser_stat_update(unit, 0, si->blk_type,
   7168                                 si->parity_type, si->double_bit,
   7169                                 SocSerCorrectTypeCacheRestore,
   7170                                 stat);
   7171         }
   7172         _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, si,
   7173                                            reg | SOC_SER_ERROR_DATA_REG_ID_OFFSET_SET,
   7174                                            port << SOC_SER_ERROR_PIPE_BP | index);
   7175     } else {
   7176         COMPILER_64_ZERO(rval64);
   7177         rv = soc_ser_reg_cache_get(unit, reg, port, index, &rval64);
   7178         if (rv == SOC_E_UNAVAIL) {
   7179             rv = soc_ser_reg_clear(unit, reg, port, index, rval64);
   7180             if (si->log_id != 0) {
   7181                 log_generic->corrected = (rv == SOC_E_NONE);
   7182                 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR;
   7183                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7184                                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7185                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER,
   7186                                     sizeof(soc_ser_log_tlv_register_t), &log_reg);
   7187             }
   7188 
   7189             SOC_IF_ERROR_RETURN(rv);
   7190             _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, si,
   7191                                                reg | SOC_SER_ERROR_DATA_REG_ID_OFFSET_SET,
   7192                                                port << SOC_SER_ERROR_PIPE_BP | index);
   7193             LOG_WARN(BSL_LS_SOC_SER,
   7194                       (BSL_META_U(unit,
   7195                                   "REG_CLEAR: %s[%d] blk: %s index: %d : port[%d]\n"),
   7196                        SOC_REG_NAME(unit, reg), reg,
   7197                        SOC_BLOCK_NAME(unit, copyno),
   7198                        index, port));
   7199             stat->ser_err_clear++;
   7200             soc_ser_stat_update(unit, 0, si->blk_type,
   7201                                 si->parity_type, si->double_bit,
   7202                                 SocSerCorrectTypeEntryClear,
   7203                                 stat);
   7204         } else {
   7205             rv = soc_reg_set_nocache(unit, reg, port, index, rval64);
   7206             if (si->log_id != 0) {
   7207                 log_generic->corrected = (rv == SOC_E_NONE);
   7208                 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE;
   7209                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   7210                                     sizeof(soc_ser_log_tlv_generic_t), log_generic);
   7211                 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER,
   7212                                     sizeof(soc_ser_log_tlv_register_t), &log_reg);
   7213             }
   7214 
   7215             SOC_IF_ERROR_RETURN(rv);
   7216             _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, si,
   7217                                                reg | SOC_SER_ERROR_DATA_REG_ID_OFFSET_SET,
   7218                                                port << SOC_SER_ERROR_PIPE_BP | index);
   7219             LOG_WARN(BSL_LS_SOC_SER,
   7220                       (BSL_META_U(unit,
   7221                                   "REG_RESTORE: %s[%d] blk: %s index: %d : port[%d]\n"),
   7222                        SOC_REG_NAME(unit, reg), reg,
   7223                        SOC_BLOCK_NAME(unit, copyno),
   7224                        index, port));
   7225             stat->ser_err_restor++;
   7226             soc_ser_stat_update(unit, 0, si->blk_type,
   7227                                 si->parity_type, si->double_bit,
   7228                                 SocSerCorrectTypeCacheRestore,
   7229                                 stat);
   7230         }
   7231     }
   7232 
   7233     return SOC_E_NONE;
   7234 }
   7235 
   7236 /* Top level SER correction routine */
   7237 int
   7238 soc_ser_correction(int unit, _soc_ser_correct_info_t *si)
   7239 {
   7240     soc_stat_t *stat = SOC_STAT(unit);
   7241     soc_ser_log_tlv_generic_t log_generic;
   7242 
   7243     if (!SOC_SER_CORRECTION_SUPPORT(unit)) {
   7244         return SOC_E_NONE;
   7245     }
   7246     if (SOC_HW_ACCESS_DISABLE(unit)) {
   7247         LOG_WARN(BSL_LS_SOC_SER,
   7248                   (BSL_META_U(unit,
   7249                               "SER_CORRECTION: reg/mem:%d hardware access disable\n"),
   7250                    (si->flags & SOC_SER_SRC_MEM) ? si->mem : si->reg));
   7251         return SOC_E_NONE;
   7252     }
   7253 
   7254     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   7255 
   7256     if (si->log_id != 0) {
   7257         log_generic.flags = 0;
   7258         if (si->flags & SOC_SER_ERR_CPU) {
   7259             log_generic.flags |= SOC_SER_LOG_FLAG_ERR_SRC;
   7260         }
   7261         if (si->flags & SOC_SER_ERR_MULTI) {
   7262             log_generic.flags |= SOC_SER_LOG_FLAG_MULTIBIT;
   7263         }
   7264         if (si->double_bit != 0) {
   7265             log_generic.flags |= SOC_SER_LOG_FLAG_DOUBLEBIT;
   7266         }
   7267         log_generic.time = si->detect_time;
   7268         log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   7269         log_generic.address = si->addr;
   7270         log_generic.acc_type = si->acc_type;
   7271         log_generic.block_type = si->blk_type;
   7272         log_generic.parity_type = si->parity_type;
   7273         log_generic.ser_response_flag = 0;
   7274         log_generic.corrected = SOC_SER_UNCORRECTED;
   7275         log_generic.pipe_num = si->pipe_num;
   7276         log_generic.inst = si->inst;
   7277     }
   7278 
   7279     LOG_WARN(BSL_LS_SOC_SER,
   7280               (BSL_META_U(unit,
   7281                           "SER_CORRECTION: reg/mem:%d btype:%d sblk:%d at:%d "
   7282                           "stage:%d addr:0x%08x port: %d index: %d\n"),
   7283                (si->flags & SOC_SER_SRC_MEM) ? si->mem : si->reg, si->blk_type,
   7284                si->sblk, si->acc_type, si->stage, si->addr, si->port, si->index));
   7285 
   7286     if (si->flags & SOC_SER_SRC_MEM) {
   7287         /* Handle mems */
   7288         return _soc_ser_mem_correction(unit, si, &log_generic, stat);
   7289     } else {
   7290         /* Handle regs */
   7291         return _soc_ser_reg_correction(unit, si, &log_generic, stat);
   7292     }
   7293 }
   7294 
   7295 static int
   7296 _soc_ser_mem_info_init(int unit)
   7297 {
   7298     uint32    size_ser_info = sizeof(mem_ser_info_t), i = 0;
   7299 
   7300     SER_MEM_INFO_BASE_ADDR(unit) =
   7301             (mem_ser_info_t *)sal_alloc(size_ser_info * SER_MEM_INFO_MAX_NUM,
   7302                                         "mem_ser_info");
   7303     if (SER_MEM_INFO_BASE_ADDR(unit) == NULL) {
   7304         LOG_WARN(BSL_LS_SOC_SER,
   7305             (BSL_META_U(unit,
   7306                         "ERR: allocate memory space fail\n")));
   7307         return SOC_E_MEMORY;
   7308     }
   7309     sal_memset(SER_MEM_INFO_BASE_ADDR(unit), 0, size_ser_info * SER_MEM_INFO_MAX_NUM);
   7310 
   7311     for (i = 0; i < SER_MEM_INFO_MAX_NUM - 1; i++) {
   7312         SER_MEM_INFO_NEXT_IDX(unit, i) = i + 1;
   7313     }
   7314     SER_MEM_INFO_NEXT_IDX(unit, i) = 0;
   7315     SER_MEM_INFO_HEAD_IDX(unit) = 0;
   7316     SER_MEM_INFO_TAIL_IDX(unit) = 0;
   7317     return SOC_E_NONE;
   7318 }
   7319 
   7320 void
   7321 soc_ser_mem_info_dump(int unit)
   7322 {
   7323     int        counter;
   7324     uint32     tail_idx, cur_idx;
   7325     mem_ser_info_t *ser_info_p = NULL;
   7326 
   7327     if(!bsl_check(bslLayerSoc, bslSourceSer, bslSeverityNormal, unit)) {
   7328         return;
   7329     }
   7330     counter = SER_MEM_INFO_COUNTER(unit);
   7331     cur_idx = SER_MEM_INFO_HEAD_IDX(unit);
   7332     tail_idx = SER_MEM_INFO_TAIL_IDX(unit);
   7333 
   7334     LOG_DEBUG(BSL_LS_SOC_SER,
   7335         (BSL_META_U(unit,
   7336                     "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"),
   7337          tail_idx, cur_idx,
   7338          SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit)));
   7339 
   7340     while (cur_idx != tail_idx || counter) {
   7341         ser_info_p = SER_MEM_INFO_BASE_ADDR(unit) + cur_idx;
   7342         LOG_DEBUG(BSL_LS_SOC_SER,
   7343             (BSL_META_U(unit,
   7344                         "[mem=%s][idx=%d] at ser_mem_info[%d]\n"),
   7345              SOC_MEM_NAME(unit, ser_info_p->ser_mem), ser_info_p->hw_idx, cur_idx));
   7346         cur_idx = SER_MEM_INFO_NEXT_IDX(unit, cur_idx);
   7347         counter--;
   7348     }
   7349     assert(counter == 0);
   7350 }
   7351 
   7352 STATIC void
   7353 _soc_ser_mem_info_insert(int unit, soc_mem_t rst_mem, uint32 hw_idx,
   7354                                 uint32 *entry_data)
   7355 {
   7356     mem_ser_info_t *mem_ser_info_addr = NULL;
   7357     uint32         entry_bsize = soc_mem_entry_bytes(unit, rst_mem);
   7358     uint32         tail_idx = SER_MEM_INFO_TAIL_IDX(unit);
   7359     uint32         old_hw_idx = 0;
   7360     soc_mem_t      old_rst_mem;
   7361 
   7362     mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit) + tail_idx;
   7363 
   7364     soc_ser_mem_info_dump(unit);
   7365 
   7366     old_hw_idx = mem_ser_info_addr->hw_idx;
   7367     old_rst_mem = mem_ser_info_addr->ser_mem;
   7368     mem_ser_info_addr->ser_mem = rst_mem;
   7369     mem_ser_info_addr->hw_idx = hw_idx;
   7370     sal_memset(mem_ser_info_addr->entry_data, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));
   7371     sal_memcpy(mem_ser_info_addr->entry_data, entry_data, entry_bsize);
   7372 
   7373     if (SER_MEM_INFO_COUNTER(unit) < SER_MEM_INFO_MAX_NUM) {
   7374         SER_MEM_INFO_COUNTER(unit)++;
   7375         LOG_INFO(BSL_LS_SOC_SER,
   7376             (BSL_META_U(unit,
   7377                         "store [mem=%s] [idx=%d] at ser_mem_info[%d]\n"),
   7378              SOC_MEM_NAME(unit, rst_mem), hw_idx, tail_idx));
   7379     } else {
   7380         /* overlay */
   7381         assert(SER_MEM_INFO_TAIL_IDX(unit) == SER_MEM_INFO_HEAD_IDX(unit));
   7382         LOG_INFO(BSL_LS_SOC_SER,
   7383             (BSL_META_U(unit,
   7384                         "overlay [mem=%s][idx=%d] to [mem=%s][idx=%d] at ser_mem_info[%d]\n"),
   7385              SOC_MEM_NAME(unit, rst_mem), hw_idx,
   7386              SOC_MEM_NAME(unit, old_rst_mem), old_hw_idx, tail_idx));
   7387         SER_MEM_INFO_HEAD_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, SER_MEM_INFO_HEAD_IDX(unit));
   7388     }
   7389     SER_MEM_INFO_TAIL_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, tail_idx);
   7390 
   7391     LOG_VERBOSE(BSL_LS_SOC_SER,
   7392         (BSL_META_U(unit,
   7393                     "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"),
   7394          SER_MEM_INFO_TAIL_IDX(unit), SER_MEM_INFO_HEAD_IDX(unit),
   7395          SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit)));
   7396 }
   7397 STATIC void
   7398 _soc_ser_mem_info_delete(int unit, uint32 cur_idx, uint32 pre_idx)
   7399 {
   7400     mem_ser_info_t *mem_ser_info_addr = NULL;
   7401     uint32         tail_idx, pre_head_idx;
   7402     soc_mem_t      rst_mem;
   7403     uint32         hw_idx;
   7404     int            counter;
   7405     if (SER_MEM_INFO_COUNTER(unit) <= 0) {
   7406         LOG_WARN(BSL_LS_SOC_SER,
   7407             (BSL_META_U(unit,
   7408                         "There is fatal error!!!\n")));
   7409         LOG_WARN(BSL_LS_SOC_SER,
   7410             (BSL_META_U(unit,
   7411                         "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"),
   7412              SER_MEM_INFO_TAIL_IDX(unit), SER_MEM_INFO_HEAD_IDX(unit),
   7413              SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit)));
   7414         return;
   7415     }
   7416 
   7417     soc_ser_mem_info_dump(unit);
   7418 
   7419     mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit) + cur_idx;
   7420     rst_mem = mem_ser_info_addr->ser_mem;
   7421     hw_idx = mem_ser_info_addr->hw_idx;
   7422     mem_ser_info_addr->ser_mem = 0;
   7423     mem_ser_info_addr->hw_idx = 0;
   7424     sal_memset(mem_ser_info_addr->entry_data, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));
   7425 
   7426     tail_idx = SER_MEM_INFO_TAIL_IDX(unit);
   7427     /* full */
   7428     if (SER_MEM_INFO_COUNTER(unit) == SER_MEM_INFO_MAX_NUM) {
   7429         assert(SER_MEM_INFO_TAIL_IDX(unit) == SER_MEM_INFO_HEAD_IDX(unit));
   7430 
   7431         if (cur_idx == tail_idx) {
   7432             SER_MEM_INFO_HEAD_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx);
   7433         } else if (SER_MEM_INFO_NEXT_IDX(unit, cur_idx) == tail_idx) {
   7434             SER_MEM_INFO_TAIL_IDX(unit) = cur_idx;
   7435         }  else {
   7436             /* find previous index of head index */
   7437             pre_head_idx = tail_idx; /* tail index is equal to head index */
   7438             counter = SER_MEM_INFO_COUNTER(unit);
   7439             while (SER_MEM_INFO_NEXT_IDX(unit, pre_head_idx) != tail_idx) {
   7440                 counter--;
   7441                 pre_head_idx = SER_MEM_INFO_NEXT_IDX(unit, pre_head_idx);
   7442             }
   7443             assert(counter == 1);
   7444 
   7445             SER_MEM_INFO_TAIL_IDX(unit) = cur_idx;
   7446             SER_MEM_INFO_NEXT_IDX(unit, pre_idx) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx);
   7447             SER_MEM_INFO_NEXT_IDX(unit, pre_head_idx) = cur_idx;
   7448             SER_MEM_INFO_NEXT_IDX(unit, cur_idx) = tail_idx;
   7449         }
   7450     } else {
   7451         if (SER_MEM_INFO_NEXT_IDX(unit, cur_idx) == SER_MEM_INFO_TAIL_IDX(unit)) {
   7452             SER_MEM_INFO_TAIL_IDX(unit) = cur_idx;
   7453         } else if (cur_idx == SER_MEM_INFO_HEAD_IDX(unit)) {
   7454             SER_MEM_INFO_HEAD_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx);
   7455         } else {
   7456             /* pre_idx is equal to cur_idx only when cur_idx == SER_MEM_INFO_HEAD_IDX(unit) */
   7457             assert(pre_idx != cur_idx);
   7458             SER_MEM_INFO_NEXT_IDX(unit, pre_idx) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx);
   7459             SER_MEM_INFO_NEXT_IDX(unit, cur_idx) = SER_MEM_INFO_NEXT_IDX(unit, tail_idx);
   7460             SER_MEM_INFO_NEXT_IDX(unit, tail_idx) = cur_idx;
   7461         }
   7462     }
   7463     SER_MEM_INFO_COUNTER(unit)--;
   7464     LOG_INFO(BSL_LS_SOC_SER,
   7465         (BSL_META_U(unit,
   7466                     "delete [mem=%s][idx=%d] at ser_mem_info[%d]\n"),
   7467          SOC_MEM_NAME(unit, rst_mem), hw_idx, cur_idx));
   7468     LOG_VERBOSE(BSL_LS_SOC_SER,
   7469         (BSL_META_U(unit,
   7470                     "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"),
   7471          SER_MEM_INFO_TAIL_IDX(unit), SER_MEM_INFO_HEAD_IDX(unit),
   7472          SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit)));
   7473 }
   7474 
   7475 int
   7476 soc_ser_counter_info_set(int unit, soc_mem_t rst_mem,
   7477                          uint32 hw_idx, uint32 *entry_data)
   7478 {
   7479     mem_ser_info_t *mem_ser_info_addr = NULL;
   7480     soc_mem_t mem_ser_list[] = {EFP_COUNTER_TABLE_Xm,
   7481                                 EFP_COUNTER_TABLE_Ym,
   7482                                 EFP_COUNTER_TABLEm,
   7483                                 FP_COUNTER_TABLE_Xm,
   7484                                 FP_COUNTER_TABLE_Ym,
   7485                                 FP_COUNTER_TABLEm};
   7486     uint32    i, mem_num = sizeof(mem_ser_list)/sizeof(mem_ser_list[0]);
   7487     int       rv = SOC_E_NONE;
   7488     uint32    idx, pre_idx;
   7489 
   7490     for (i = 0; i < mem_num; i++) {
   7491         if (mem_ser_list[i] == rst_mem) {
   7492             break;
   7493         }
   7494     }
   7495     if (i >= mem_num) {
   7496         return SOC_E_UNAVAIL;
   7497     }
   7498 
   7499     if (entry_data == NULL) {
   7500         LOG_WARN(BSL_LS_SOC_SER,
   7501             (BSL_META_U(unit,
   7502                         "pointer entry_data is NULL\n")));
   7503         return SOC_E_PARAM;
   7504     }
   7505 
   7506     if (soc_mem_index_count(unit, rst_mem) <= hw_idx) {
   7507         LOG_WARN(BSL_LS_SOC_SER,
   7508             (BSL_META_U(unit,
   7509                         "store mem %s, max index=%d, wrong index=%d\n"),
   7510              SOC_MEM_NAME(unit, rst_mem), soc_mem_index_count(unit, rst_mem), hw_idx));
   7511         return SOC_E_INTERNAL;
   7512     }
   7513 
   7514     SOC_MEM_SER_INFO_LOCK(unit);
   7515 
   7516     if (SER_MEM_INFO_BASE_ADDR(unit) == NULL) {
   7517         rv = _soc_ser_mem_info_init(unit);
   7518         if (rv != SOC_E_NONE) {
   7519             SOC_MEM_SER_INFO_UNLOCK(unit);
   7520             return rv;
   7521         }
   7522     }
   7523     idx = SER_MEM_INFO_HEAD_IDX(unit);
   7524     pre_idx = idx;
   7525 
   7526     for (i = 0; i < SER_MEM_INFO_COUNTER(unit); i++) {
   7527         mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit);
   7528         mem_ser_info_addr += idx;
   7529         if (mem_ser_info_addr->ser_mem == rst_mem &&
   7530             mem_ser_info_addr->hw_idx ==  hw_idx) {
   7531              break;
   7532         }
   7533         pre_idx = idx;
   7534         idx = SER_MEM_INFO_NEXT_IDX(unit, idx);
   7535     }
   7536     if (i < SER_MEM_INFO_COUNTER(unit)) { /* found */
   7537         /* delete old info */
   7538         _soc_ser_mem_info_delete(unit, idx, pre_idx);
   7539         /* insert new info at tail */
   7540         _soc_ser_mem_info_insert(unit, rst_mem, hw_idx, entry_data);
   7541     } else {
   7542         /* not found */
   7543         assert(idx == SER_MEM_INFO_TAIL_IDX(unit));
   7544         /* insert new info at tail */
   7545         _soc_ser_mem_info_insert(unit, rst_mem, hw_idx, entry_data);
   7546     }
   7547     SOC_MEM_SER_INFO_UNLOCK(unit);
   7548     return SOC_E_NONE;
   7549 }
   7550 
   7551 int
   7552 soc_ser_counter_info_get(int unit, soc_mem_t rst_mem,
   7553                          int hw_idx, uint32 *entry_data)
   7554 {
   7555     mem_ser_info_t *mem_ser_info_addr = NULL;
   7556     uint32 entry_bsize = soc_mem_entry_bytes(unit, rst_mem);
   7557     soc_mem_t mem_ser_list[] = {EFP_COUNTER_TABLE_Xm,
   7558                                 EFP_COUNTER_TABLE_Ym,
   7559                                 EFP_COUNTER_TABLEm,
   7560                                 FP_COUNTER_TABLE_Xm,
   7561                                 FP_COUNTER_TABLE_Ym,
   7562                                 FP_COUNTER_TABLEm};
   7563     int    i = 0, mem_num = sizeof(mem_ser_list)/sizeof(mem_ser_list[0]);
   7564     uint32 idx, pre_idx;
   7565 
   7566     for (i = 0; i < mem_num; i++) {
   7567         if (mem_ser_list[i] == rst_mem) {
   7568             break;
   7569         }
   7570     }
   7571     if (i >= mem_num) {
   7572         return SOC_E_NONE;
   7573     }
   7574     if (entry_data == NULL) {
   7575         LOG_WARN(BSL_LS_SOC_SER,
   7576             (BSL_META_U(unit,
   7577                         "pointer entry_data is NULL\n")));
   7578         return SOC_E_PARAM;
   7579     }
   7580     if (soc_mem_index_count(unit, rst_mem) <= hw_idx) {
   7581         LOG_WARN(BSL_LS_SOC_SER,
   7582             (BSL_META_U(unit,
   7583                         "restore mem %s, max index=%d, wrong index=%d\n"),
   7584              SOC_MEM_NAME(unit, rst_mem), soc_mem_index_count(unit, rst_mem), hw_idx));
   7585         return SOC_E_INTERNAL;
   7586     }
   7587 
   7588     SOC_MEM_SER_INFO_LOCK(unit);
   7589 
   7590     if (SER_MEM_INFO_BASE_ADDR(unit) == NULL) {
   7591         LOG_VERBOSE(BSL_LS_SOC_SER,
   7592             (BSL_META_U(unit,
   7593                         "ser mem info is not initialized\n")));
   7594         SOC_MEM_SER_INFO_UNLOCK(unit);
   7595         return SOC_E_NOT_FOUND;
   7596     }
   7597 
   7598     idx = SER_MEM_INFO_HEAD_IDX(unit);
   7599     pre_idx = idx;
   7600 
   7601     for (i = 0; i < SER_MEM_INFO_COUNTER(unit); i++) {
   7602         mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit);
   7603         mem_ser_info_addr += idx;
   7604         if (mem_ser_info_addr->ser_mem == rst_mem &&
   7605             mem_ser_info_addr->hw_idx ==  hw_idx) {
   7606              break;
   7607         }
   7608         pre_idx = idx;
   7609         idx = SER_MEM_INFO_NEXT_IDX(unit, idx);
   7610     }
   7611 
   7612     /* found */
   7613     if (i < SER_MEM_INFO_COUNTER(unit)) {
   7614         sal_memcpy(entry_data, mem_ser_info_addr->entry_data, entry_bsize);
   7615         _soc_ser_mem_info_delete(unit, idx, pre_idx);
   7616         SOC_MEM_SER_INFO_UNLOCK(unit);
   7617         return SOC_E_NONE;
   7618     } else {
   7619         assert(idx == SER_MEM_INFO_TAIL_IDX(unit));
   7620         LOG_WARN(BSL_LS_SOC_SER,
   7621             (BSL_META_U(unit,
   7622                         "not found mem %s, hw idx=%d\n"),
   7623              SOC_MEM_NAME(unit, rst_mem), hw_idx));
   7624 
   7625         SOC_MEM_SER_INFO_UNLOCK(unit);
   7626         return SOC_E_NOT_FOUND;
   7627     }
   7628 }
   7629 
   7630 void soc_ser_alpm_cache_check(int unit)
   7631 {
   7632     if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) {
   7633         alpm_no_cache_flag[unit].flag_defip = soc_property_get(unit, "mem_nocache_L3_DEFIP", 1);
   7634         alpm_no_cache_flag[unit].flag_defip_128 = soc_property_get(unit, "mem_nocache_L3_DEFIP_PAIR_128", 1);
   7635         alpm_no_cache_flag[unit].flag_defip_alpm_v4 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV4", 1);
   7636         alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV4_1", 1);
   7637         alpm_no_cache_flag[unit].flag_defip_alpm_v6 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV6_64", 1);
   7638         alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV6_64_1", 1);
   7639         alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV6_128", 1);
   7640         alpm_no_cache_flag[unit].flag_defip_aux = soc_property_get(unit, "mem_nocache_L3_DEFIP_AUX_TABLE", 1);
   7641     } else {
   7642         alpm_no_cache_flag[unit].flag_defip = 1;
   7643         alpm_no_cache_flag[unit].flag_defip_128 = 1;
   7644         alpm_no_cache_flag[unit].flag_defip_alpm_v4 = 1;
   7645         alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 = 1;
   7646         alpm_no_cache_flag[unit].flag_defip_alpm_v6 = 1;
   7647         alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 = 1;
   7648         alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 = 1;
   7649         alpm_no_cache_flag[unit].flag_defip_aux = 1;
   7650     }
   7651 }
   7652 
   7653 #endif /* BCM_XGS_SUPPORT */