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

enduro.c (141880B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        enduro.c
      8  * Purpose:
      9  * Requires:    
     10  */
     11 
     12 
     13 #include <sal/core/boot.h>
     14 #include <shared/bsl.h>
     15 #include <soc/firebolt.h>
     16 #include <soc/bradley.h>
     17 #include <soc/enduro.h>
     18 #include <soc/drv.h>
     19 #include <soc/mem.h>
     20 #include <soc/hash.h>
     21 #include <soc/lpm.h>
     22 #include <soc/error.h>
     23 #include <soc/debug.h>
     24 #include <soc/er_tcam.h>
     25 #include <soc/memtune.h>
     26 #include <soc/devids.h>
     27 #include <soc/soc_ser_log.h>
     28 
     29 #ifdef BCM_ENDURO_SUPPORT
     30 
     31 /*
     32  * Enduro chip driver functions.  
     33  */
     34 soc_functions_t soc_enduro_drv_funs = {
     35     soc_enduro_misc_init,
     36     soc_enduro_mmu_init,
     37     soc_enduro_age_timer_get,
     38     soc_enduro_age_timer_max_get,
     39     soc_enduro_age_timer_set,
     40 };
     41 
     42 typedef enum {
     43     _SOC_PARITY_INFO_TYPE_GENERIC,
     44     _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
     45     _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
     46     _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER,
     47     _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
     48     _SOC_PARITY_INFO_TYPE_MMU_PARITY,
     49     _SOC_PARITY_INFO_TYPE_MMUIPMC,
     50     _SOC_PARITY_INFO_TYPE_MMUWRED,
     51     _SOC_PARITY_INFO_TYPE_MMUMTRO,
     52     _SOC_PARITY_INFO_TYPE_MMUE2EFC,
     53     _SOC_PARITY_INFO_TYPE_OAM, /* Not parity, but same interrupt */
     54     _SOC_PARITY_INFO_TYPE_SER, /* Parity error from CMIC SER module */
     55     _SOC_PARITY_INFO_TYPE_NUM
     56 } _soc_parity_info_type_t;
     57 
     58 typedef struct _soc_parity_info_s {
     59     soc_field_t             enable_field;
     60     soc_field_t             error_field;
     61     char                    *msg;
     62     soc_mem_t               mem;
     63     _soc_parity_info_type_t type;
     64     soc_reg_t               control_reg;
     65     soc_reg_t               intr_status0_reg;
     66     soc_reg_t               intr_status1_reg; /* Also SBE force for ECC */
     67     soc_reg_t               nack_status0_reg;
     68     soc_reg_t               nack_status1_reg; /* Also DBE force for ECC */
     69 } _soc_parity_info_t;
     70 
     71 #if defined(SER_TR_TEST_SUPPORT)
     72 soc_ser_test_functions_t ser_enduro_test_fun;
     73 #endif
     74 
     75 /*
     76  *    _SOC_PARITY_INFO_TYPE_SINGLE_PARITY
     77  *      PARITY_EN
     78  *      ENTRY_IDX, MULTIPLE_ERR, PARITY_ERR
     79  *
     80  *    _SOC_PARITY_INFO_TYPE_SINGLE_ECC
     81  *      ECC_EN
     82  *      ENTRY_IDX, DOUBLE_BIT_ERR, MULTIPLE_ERR, ECC_ERR
     83  *
     84  *    _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER
     85  *      PARITY_EN
     86  *      PORT_IDX, COUNTER_IDX, MULTIPLE_ERR, PARITY_ERR
     87  *
     88  *    _SOC_PARITY_INFO_TYPE_DUAL_PARITY
     89  *      PARITY_EN
     90  *      BUCKET_IDX, MULTIPLE_ERR, PARITY_ERR_BM
     91  */
     92 
     93 static _soc_parity_info_t _soc_en_ip0_parity_info[] = {
     94     { PARITY_ENf, VXLT_PAR_ERRf, NULL,
     95       VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
     96       VLAN_XLATE_PARITY_CONTROLr,
     97       VLAN_XLATE_PARITY_STATUS_0r, VLAN_XLATE_PARITY_STATUS_1r,
     98       INVALIDr, INVALIDr },
     99  /* { PPA_CMD_COMPLETEf }, */
    100  /* { MEM_RESET_COMPLETEf }, */
    101  /* { AGE_CMD_COMPLETEf }, */
    102     { PARITY_ENf, VLAN_SUBNET_DATA_PARITY_ERRf, NULL,
    103       VLAN_SUBNET_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    104       VLAN_SUBNET_DATA_PARITY_CONTROLr,
    105       VLAN_SUBNET_DATA_PARITY_STATUSr, INVALIDr,
    106       INVALIDr, INVALIDr },
    107     { PARITY_ENf, VLAN_PROTOCOL_DATA_PARITY_ERRf, NULL,
    108       VLAN_PROTOCOL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    109       VLAN_PROTOCOL_DATA_PARITY_CONTROLr,
    110       VLAN_PROTOCOL_DATA_PARITY_STATUSr, INVALIDr,
    111       INVALIDr, INVALIDr },
    112     { PARITY_ENf, VLAN_PARITY_ERRf, NULL,
    113       VLAN_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    114       VLAN_PARITY_CONTROLr,
    115       VLAN_PARITY_STATUSr, INVALIDr,
    116       INVALIDr, INVALIDr },
    117     { PARITY_ENf, VLAN_STG_PARITY_ERRf, NULL,
    118       STG_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    119       VLAN_STG_PARITY_CONTROLr,
    120       VLAN_STG_PARITY_STATUSr, INVALIDr,
    121       INVALIDr, INVALIDr },
    122     { PARITY_ENf, L3_TUNNEL_RAM_PARITY_ERRf, NULL,
    123       L3_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    124       L3_TUNNEL_DATA_ONLY_PARITY_CONTROLr,
    125       L3_TUNNEL_DATA_ONLY_PARITY_STATUSr, INVALIDr,
    126       INVALIDr, INVALIDr },
    127     { PARITY_ENf, SOURCE_TRUNK_MAP_PARITY_ERRf, NULL,
    128       SOURCE_TRUNK_MAP_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    129       SOURCE_TRUNK_MAP_PARITY_CONTROLr,
    130       SOURCE_TRUNK_MAP_PARITY_STATUSr, INVALIDr,
    131       INVALIDr, INVALIDr },
    132     { PARITY_ENf, VFP_POLICY_PAR_ERRf, NULL,
    133       VFP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    134       VFP_POLICY_PARITY_CONTROLr,
    135       VFP_POLICY_PARITY_STATUS_INTRr, INVALIDr,
    136       INVALIDr, INVALIDr },
    137     { PARITY_ENf, LMEP_PAR_ERRf, NULL,
    138       LMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    139       LMEP_PARITY_CONTROLr,
    140       LMEP_PARITY_STATUSr, INVALIDr,
    141       INVALIDr, INVALIDr },
    142     { ECC_ENf, IARB_PKT_ECC_INTRf, "Iarb packet ecc error",
    143       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    144       IARB_PKT_ECC_CONTROLr,
    145       IARB_PKT_ECC_STATUS_INTRr, INVALIDr,
    146       INVALIDr, INVALIDr },
    147     { ECC_ENf, IARB_HDR_ECC_INTRf, "Iarb header ecc error",
    148       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    149       IARB_HDR_ECC_CONTROLr,
    150       IARB_HDR_ECC_STATUS_INTRr, INVALIDr,
    151       INVALIDr, INVALIDr },
    152     { INVALIDf, INVALIDf }, /* table terminator */
    153 };
    154 
    155 static _soc_parity_info_t _soc_en_ip1_parity_info[] = {
    156     { PARITY_ENf, VFI_PAR_ERRf, NULL,
    157       VFIm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    158       VFI_PARITY_CONTROLr,
    159       VFI_PARITY_STATUS_INTRr, INVALIDr,
    160       VFI_PARITY_STATUS_NACKr, INVALIDr },
    161     { PARITY_ENf, SVP_PAR_ERRf, NULL,
    162       SOURCE_VPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    163       SOURCE_VP_PARITY_CONTROLr,
    164       SOURCE_VP_PARITY_STATUS_INTRr, INVALIDr,
    165       SOURCE_VP_PARITY_STATUS_NACKr, INVALIDr },
    166     { PARITY_ENf, L3_IIF_PAR_ERRf, NULL,
    167       L3_IIFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    168       L3_IIF_PARITY_CONTROLr,
    169       L3_IIF_PARITY_STATUS_INTRr, INVALIDr,
    170       L3_IIF_PARITY_STATUS_NACKr, INVALIDr },
    171     { PARITY_ENf, MPLS_ENTRY_PAR_ERRf, NULL,
    172       MPLS_ENTRYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    173       MPLS_ENTRY_PARITY_CONTROLr,
    174       MPLS_ENTRY_PARITY_STATUS_INTR_0r, MPLS_ENTRY_PARITY_STATUS_INTR_1r,
    175       MPLS_ENTRY_PARITY_STATUS_NACK_0r, MPLS_ENTRY_PARITY_STATUS_NACK_1r },
    176     { PARITY_ENf, L2_ENTRY_PAR_ERRf, NULL,
    177       L2Xm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    178       L2_ENTRY_PARITY_CONTROLr,
    179       L2_ENTRY_PARITY_STATUS_0r, L2_ENTRY_PARITY_STATUS_1r,
    180       INVALIDr, INVALIDr },
    181     { PARITY_ENf, L2MC_PAR_ERRf, NULL,
    182       L2MCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    183       L2MC_PARITY_CONTROLr,
    184       L2MC_PARITY_STATUSr, INVALIDr,
    185       INVALIDr, INVALIDr },
    186     { PARITY_ENf, L3_ENTRY_PAR_ERRf, NULL,
    187       L3_ENTRY_ONLYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    188       L3_ENTRY_PARITY_CONTROLr,
    189       L3_ENTRY_PARITY_STATUS_0r, L3_ENTRY_PARITY_STATUS_1r,
    190       INVALIDr, INVALIDr },
    191     { PARITY_ENf, L3_DEFIP_DATA_PAR_ERRf, NULL,
    192       L3_DEFIP_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    193       L3_DEFIP_PARITY_CONTROLr,
    194       L3_DEFIP_PARITY_STATUSr, INVALIDr,
    195       INVALIDr, INVALIDr },
    196     { PARITY_ENf, L3MC_PAR_ERRf, NULL,
    197       L3_IPMCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    198       L3MC_PARITY_CONTROLr,
    199       L3MC_PARITY_STATUSr, INVALIDr,
    200       INVALIDr, INVALIDr },
    201     { PARITY_ENf, MA_STATE_PAR_ERRf, NULL,
    202       MA_STATEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    203       MA_STATE_PARITY_CONTROLr,
    204       MA_STATE_PARITY_STATUSr, INVALIDr,
    205       INVALIDr, INVALIDr },
    206     { PARITY_ENf, RMEP_PAR_ERRf, NULL,
    207       RMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    208       RMEP_PARITY_CONTROLr,
    209       RMEP_PARITY_STATUSr, INVALIDr,
    210       INVALIDr, INVALIDr },
    211     { PARITY_ENf, MAID_REDUCTION_PAR_ERRf, NULL,
    212       MAID_REDUCTIONm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    213       MAID_REDUCTION_PARITY_CONTROLr,
    214       MAID_REDUCTION_PARITY_STATUSr, INVALIDr,
    215       INVALIDr, INVALIDr },
    216     { PARITY_ENf, MA_INDEX_PAR_ERRf, NULL,
    217       MA_INDEXm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    218       MA_INDEX_PARITY_CONTROLr,
    219       MA_INDEX_PARITY_STATUSr, INVALIDr,
    220       INVALIDr, INVALIDr },
    221     { PARITY_ENf, PORT_CBL_TABLE_PAR_ERRf, NULL,
    222       PORT_CBL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    223       PORT_CBL_TABLE_PARITY_CONTROLr,
    224       PORT_CBL_TABLE_PARITY_STATUSr, INVALIDr,
    225       INVALIDr, INVALIDr },
    226     { PARITY_ENf, INITIAL_NHOP_PAR_ERRf, NULL,
    227       INITIAL_ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    228       INITIAL_NHOP_PARITY_CONTROLr,
    229       INITIAL_NHOP_PARITY_STATUSr, INVALIDr,
    230       INVALIDr, INVALIDr },
    231     /* Start of parity-unrelated OAM faults */
    232 
    233     { ANY_RMEP_TLV_PORT_DOWN_INTRf, ANY_RMEP_TLV_PORT_DOWN_INTRf, NULL,
    234       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    235       INVALIDr,
    236       INVALIDr, INVALIDr,
    237       INVALIDr, INVALIDr },
    238 
    239     { ANY_RMEP_TLV_PORT_UP_INTRf, ANY_RMEP_TLV_PORT_UP_INTRf, NULL,
    240       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    241       INVALIDr,
    242       INVALIDr, INVALIDr,
    243       INVALIDr, INVALIDr },
    244 
    245     { ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, NULL,
    246       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    247       INVALIDr,
    248       INVALIDr, INVALIDr,
    249       INVALIDr, INVALIDr },
    250 
    251     { ANY_RMEP_TLV_INTERFACE_UP_INTRf, ANY_RMEP_TLV_INTERFACE_UP_INTRf, NULL,
    252       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    253       INVALIDr,
    254       INVALIDr, INVALIDr,
    255       INVALIDr, INVALIDr },
    256 
    257     { XCON_CCM_DEFECT_INTRf, XCON_CCM_DEFECT_INTRf, NULL,
    258       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    259       INVALIDr,
    260       INVALIDr, INVALIDr,
    261       INVALIDr, INVALIDr },
    262 
    263     { ERROR_CCM_DEFECT_INTRf, ERROR_CCM_DEFECT_INTRf, NULL,
    264       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    265       INVALIDr,
    266       INVALIDr, INVALIDr,
    267       INVALIDr, INVALIDr },
    268 
    269     { SOME_RDI_DEFECT_INTRf, SOME_RDI_DEFECT_INTRf, NULL,
    270       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    271       INVALIDr,
    272       INVALIDr, INVALIDr,
    273       INVALIDr, INVALIDr },
    274 
    275     { SOME_RMEP_CCM_DEFECT_INTRf, SOME_RMEP_CCM_DEFECT_INTRf, NULL,
    276       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    277       INVALIDr,
    278       INVALIDr, INVALIDr,
    279       INVALIDr, INVALIDr },
    280 
    281     /* End of parity-unrelated OAM faults */
    282     { PARITY_ENf, VFI_1_PAR_INTRf, NULL,
    283       VFI_1m, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    284       VFI_1_PARITY_CONTROLr,
    285       VFI_1_PARITY_STATUS_INTRr, INVALIDr,
    286       VFI_1_PARITY_STATUS_NACKr, INVALIDr },
    287     { INVALIDf, INVALIDf }, /* table terminator */
    288 };
    289 
    290 static _soc_parity_info_t _soc_en_ip2_parity_info[] = {
    291     { PARITY_ENf, ING_NHOP_PAR_ERRf, NULL,
    292       ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    293       ING_L3_NEXT_HOP_PARITY_CONTROLr,
    294       ING_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr,
    295       INVALIDr, INVALIDr },
    296     { PARITY_ENf, IFP_METER_PAR_ERRf, NULL,
    297       FP_METER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    298       IFP_METER_PARITY_CONTROLr,
    299       IFP_METER_PARITY_STATUSr, INVALIDr,
    300       INVALIDr, INVALIDr },
    301     { PARITY_ENf, IFP_COUNTER_PAR_ERRf, NULL,
    302       FP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    303       IFP_COUNTER_PARITY_CONTROLr,
    304       IFP_COUNTER_PARITY_STATUSr, INVALIDr,
    305       INVALIDr, INVALIDr },
    306     { PARITY_ENf, IFP_POLICY_PAR_ERRf, NULL,
    307       FP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    308       IFP_POLICY_PARITY_CONTROLr,
    309       IFP_POLICY_PARITY_STATUSr, INVALIDr,
    310       INVALIDr, INVALIDr },
    311     { PARITY_ENf, IFP_STORM_CONTROL_PAR_ERRf, NULL,
    312       FP_STORM_CONTROL_METERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    313       IFP_STORM_CONTROL_PARITY_CONTROLr,
    314       IFP_STORM_CONTROL_PARITY_STATUSr, INVALIDr,
    315       INVALIDr, INVALIDr },
    316     { PARITY_ENf, L3_MTU_VALUES_PAR_ERRf, NULL,
    317       L3_MTU_VALUESm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    318       L3_MTU_VALUES_PARITY_CONTROLr,
    319       L3_MTU_VALUES_PARITY_STATUSr, INVALIDr,
    320       INVALIDr, INVALIDr },
    321     { PARITY_ENf, EGR_MASK_PAR_ERRf, NULL,
    322       EGR_MASKm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    323       EGR_MASK_PARITY_CONTROLr,
    324       EGR_MASK_PARITY_STATUSr, INVALIDr,
    325       INVALIDr, INVALIDr },
    326     { PARITY_ENf, MODPORT_MAP_SW_PAR_ERRf, NULL,
    327       MODPORT_MAP_SWm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    328       MODPORT_MAP_SW_PARITY_CONTROLr,
    329       MODPORT_MAP_SW_PARITY_STATUSr, INVALIDr,
    330       INVALIDr, INVALIDr },
    331     { PARITY_ENf, MODPORT_MAP_IM_PAR_ERRf, NULL,
    332       MODPORT_MAP_IMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    333       MODPORT_MAP_IM_PARITY_CONTROLr,
    334       MODPORT_MAP_IM_PARITY_STATUSr, INVALIDr,
    335       INVALIDr, INVALIDr },
    336     { PARITY_ENf, MODPORT_MAP_EM_PAR_ERRf, NULL,
    337       MODPORT_MAP_EMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    338       MODPORT_MAP_EM_PARITY_CONTROLr,
    339       MODPORT_MAP_EM_PARITY_STATUSr, INVALIDr,
    340       INVALIDr, INVALIDr },
    341     { INVALIDf, INVALIDf }, /* table terminator */
    342 };
    343 
    344 static _soc_parity_info_t _soc_en_ep_parity_info[] = {
    345     { PARITY_ENf, EGR_NHOP_PAR_ERRf, NULL,
    346       EGR_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    347       EGR_L3_NEXT_HOP_PARITY_CONTROLr,
    348       EGR_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr,
    349       INVALIDr, INVALIDr },
    350     { PARITY_ENf, EGR_L3_INTF_PAR_ERRf, NULL,
    351       EGR_L3_INTFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    352       EGR_L3_INTF_PARITY_CONTROLr,
    353       EGR_L3_INTF_PARITY_STATUSr, INVALIDr,
    354       INVALIDr, INVALIDr },
    355     { PARITY_ENf, EGR_MPLS_LABEL_PAR_ERRf, NULL,
    356       EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    357       EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_CONTROLr,
    358       EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_STATUSr, INVALIDr,
    359       INVALIDr, INVALIDr },
    360     { PARITY_ENf, EGR_VLAN_PAR_ERRf, NULL,
    361       EGR_VLANm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    362       EGR_VLAN_PARITY_CONTROLr,
    363       EGR_VLAN_PARITY_STATUSr, INVALIDr,
    364       INVALIDr, INVALIDr },
    365    { PARITY_ENf, EGR_VLAN_STG_PAR_ERRf, NULL,
    366       EGR_VLAN_STGm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    367       EGR_VLAN_STG_PARITY_CONTROLr,
    368       EGR_VLAN_STG_PARITY_STATUSr, INVALIDr,
    369       INVALIDr, INVALIDr },
    370     { PARITY_ENf, EGR_VXLT_PAR_ERRf, NULL,
    371       EGR_VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    372       EGR_VLAN_XLATE_PARITY_CONTROLr,
    373       EGR_VLAN_XLATE_PARITY_STATUS_0r, EGR_VLAN_XLATE_PARITY_STATUS_1r,
    374       INVALIDr, INVALIDr },
    375     { PARITY_ENf, EGR_IP_TUNNEL_PAR_ERRf, NULL,
    376       EGR_IP_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    377       EGR_IP_TUNNEL_PARITY_CONTROLr,
    378       EGR_IP_TUNNEL_PARITY_STATUSr, INVALIDr,
    379       INVALIDr, INVALIDr },
    380     { PARITY_ENf, EGR_PW_COUNT_PAR_ERRf, NULL,
    381       EGR_PW_INIT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    382       EGR_PW_INIT_COUNTERS_PARITY_CONTROLr,
    383       EGR_PW_INIT_COUNTERS_PARITY_STATUSr, INVALIDr,
    384       INVALIDr, INVALIDr },
    385 /*    { PARITY_ENf, EGR_IPFIX_SESS_PAR_ERRf, NULL,
    386       EGR_IPFIX_SESSION_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    387       EGR_IPFIX_SESSION_PARITY_CONTROLr,
    388       EGR_IPFIX_SESSION_PARITY_STATUSr, INVALIDr,
    389       INVALIDr, INVALIDr },
    390     { PARITY_ENf, EGR_IPFIX_EXPORT_PAR_ERRf, NULL,
    391       EGR_IPFIX_EXPORT_FIFOm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    392       EGR_IPFIX_EXPORT_FIFO_PARITY_CONTROLr,
    393       EGR_IPFIX_EXPORT_FIFO_PARITY_STATUSr, INVALIDr,
    394       INVALIDr, INVALIDr }, */
    395     { ECC_ENf, EP_INITBUF_DBEf, "EP_INITBUF double-bit ECC error",
    396       INVALIDm,_SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    397       EGR_INITBUF_ECC_CONTROLr,
    398       EGR_INITBUF_ECC_STATUS_DBEr, INVALIDr,
    399       INVALIDr, INVALIDr },
    400     { ECC_ENf, EP_INITBUF_SBEf, "EP_INITBUF single-bit ECC error (corrected)",
    401       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    402       EGR_INITBUF_ECC_CONTROLr,
    403       EGR_INITBUF_ECC_STATUS_SBEr, INVALIDr,
    404       INVALIDr, INVALIDr },
    405     { PARITY_ENf, EGR_PERQ_COUNTERf, "EP_PERQ_COUNTER table parity error",
    406       EGR_PERQ_XMT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    407       EGR_PERQ_COUNTER_PARITY_CONTROLr,
    408       EGR_PERQ_COUNTER_PARITY_STATUSr, INVALIDr,
    409       INVALIDr, INVALIDr },
    410     { PARITY_ENf, EGR_FP_COUNTERf, NULL,
    411       EFP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    412       EGR_FP_COUNTER_PARITY_CONTROLr,
    413       EGR_FP_COUNTER_PARITY_STATUSr, INVALIDr,
    414       INVALIDr, INVALIDr },
    415     { PARITY_ENf, EGR_GP0_DBUFf, "EP_GP0_DATABUF memory parity error",
    416       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    417       EGR_GP0_DBUF_PARITY_CONTROLr,
    418       EGR_GP0_DBUF_PARITY_STATUSr, INVALIDr,
    419       INVALIDr, INVALIDr },
    420     { PARITY_ENf, EGR_GP1_DBUFf, "EP_GP1_DATABUF memory parity error",
    421       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    422       EGR_GP1_DBUF_PARITY_CONTROLr,
    423       EGR_GP1_DBUF_PARITY_STATUSr, INVALIDr,
    424       INVALIDr, INVALIDr },
    425     { PARITY_ENf, EGR_GP2_DBUFf, "EP_GP2_DATABUF memory parity error",
    426       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    427       EGR_GP2_DBUF_PARITY_CONTROLr,
    428       EGR_GP2_DBUF_PARITY_STATUSr, INVALIDr,
    429       INVALIDr, INVALIDr },
    430     { PARITY_ENf, EGR_XQ0_DBUFf, "EP_XQ0_DATABUF memory parity error",
    431       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    432       EGR_XQ0_DBUF_PARITY_CONTROLr,
    433       EGR_XQ0_DBUF_PARITY_STATUSr, INVALIDr,
    434       INVALIDr, INVALIDr },
    435     { PARITY_ENf, EGR_XQ1_DBUFf, "EP_XQ1_DATABUF memory parity error",
    436       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    437       EGR_XQ1_DBUF_PARITY_CONTROLr,
    438       EGR_XQ1_DBUF_PARITY_STATUSr, INVALIDr,
    439       INVALIDr, INVALIDr },
    440     { PARITY_ENf, EGR_XQ2_DBUFf, "EP_XQ2_DATABUF memory parity error",
    441       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    442       EGR_XQ2_DBUF_PARITY_CONTROLr,
    443       EGR_XQ2_DBUF_PARITY_STATUSr, INVALIDr,
    444       INVALIDr, INVALIDr },
    445     { PARITY_ENf, EGR_XQ3_DBUFf, "EP_XQ3_DATABUF memory parity error",
    446       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    447       EGR_XQ3_DBUF_PARITY_CONTROLr,
    448       EGR_XQ3_DBUF_PARITY_STATUSr, INVALIDr,
    449       INVALIDr, INVALIDr },
    450     { PARITY_ENf, EGR_LP_DBUFf, "EP_LP_DATABUF memory parity error",
    451       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    452       EGR_LP_DBUF_PARITY_CONTROLr,
    453       EGR_LP_DBUF_PARITY_STATUSr, INVALIDr,
    454       INVALIDr, INVALIDr },
    455     { PARITY_ENf, EGR_CM_DBUFf, "EGR_CM_DBUF memory parity error",
    456       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    457       EGR_CM_DBUF_PARITY_CONTROLr,
    458       EGR_CM_DBUF_PARITY_STATUSr, INVALIDr,
    459       INVALIDr, INVALIDr },
    460     { INVALIDf, INVALIDf }, /* table terminator */
    461 };
    462 
    463 /*
    464  * Is DEQ_CBPERRPTRr for MMU_CBPDATA0 - MMU_CBPDATA31 (15-bit address)?
    465  * How does MMU_CELLCHKm (15-bit address) report parity error?
    466  */
    467 static _soc_parity_info_t _soc_en_mmu_parity_info[] = {
    468     { AGING_CTR_PAR_ERR_ENf, AGING_CTR_PAR_ERRf, NULL,
    469       MMU_AGING_CTRm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    470       INVALIDr,
    471       INVALIDr, INVALIDr,
    472       INVALIDr, INVALIDr },
    473     { AGING_EXP_PAR_ERR_ENf, AGING_EXP_PAR_ERRf, NULL,
    474       MMU_AGING_EXPm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    475       INVALIDr,
    476       INVALIDr, INVALIDr,
    477       INVALIDr, INVALIDr },
    478     { CCP_PAR_ERR_ENf, CCP_PAR_ERRf, NULL,
    479       MMU_CCP_MEMm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    480       INVALIDr,
    481       CCPPARITYERRORPTRr, INVALIDr,
    482       INVALIDr, INVALIDr },
    483     { CFAP_PAR_ERR_ENf, CFAP_PAR_ERRf, NULL,
    484       MMU_CFAP_MEMm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    485       INVALIDr,
    486       CFAPPARITYERRORPTRr, INVALIDr,
    487       INVALIDr, INVALIDr },
    488     { CFAP_MEM_FAIL_ENf, CFAP_MEM_FAILf, NULL,
    489       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    490       INVALIDr,
    491       INVALIDr, INVALIDr,
    492       INVALIDr, INVALIDr },
    493     { DEQ_PKTHDR_CPU_ERR_ENf, DEQ_PKTHDR_CPU_ERRf, NULL,
    494       MMU_CBPPKTHEADERCPUm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    495       INVALIDr,
    496       DEQ_PKTHDRCPUERRPTRr, INVALIDr,
    497       INVALIDr, INVALIDr },
    498     { DEQ_PKTHDR0_ERR_ENf, DEQ_PKTHDR0_ERRf, NULL,
    499       MMU_CBPPKTHEADER0_MEM0m, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    500       INVALIDr,
    501       DEQ_PKTHDR0ERRPTRr, INVALIDr,
    502       INVALIDr, INVALIDr },
    503     { DEQ0_NOT_IP_ERR_ENf, DEQ0_NOT_IP_ERRf, NULL,
    504       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    505       INVALIDr,
    506       INVALIDr, INVALIDr,
    507       INVALIDr, INVALIDr },
    508     { DEQ0_CELLCRC_ERR_ENf, DEQ0_CELLCRC_ERRf, NULL,
    509       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    510       INVALIDr,
    511       INVALIDr, INVALIDr,
    512       INVALIDr, INVALIDr },
    513     { START_BY_START_ERR_ENf, START_BY_START_ERRf, NULL,
    514       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    515       INVALIDr,
    516       INVALIDr, INVALIDr,
    517       INVALIDr, INVALIDr },
    518     { MEM1_IPMC_TBL_PAR_ERR_ENf, MEM1_IPMC_TBL_PAR_ERRf, "MMU_IPMC_GROUP_TBL",
    519       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    520       INVALIDr,
    521       MEM1_IPMCGRP_TBL_PARITYERRORPTRr, MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr,
    522       INVALIDr, INVALIDr },
    523     { MEM1_VLAN_TBL_PAR_ERR_ENf, MEM1_VLAN_TBL_PAR_ERRf, NULL,
    524       MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    525       INVALIDr,
    526       MEM1_IPMCVLAN_TBL_PARITYERRORPTRr, INVALIDr,
    527       INVALIDr, INVALIDr },
    528     { TOQ0_CELLHDR_PAR_ERR_ENf, TOQ0_CELLHDR_PAR_ERRf, NULL,
    529       MMU_CBPCELLHEADERm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    530       INVALIDr,
    531       TOQ_CELLHDRERRPTRr, INVALIDr,
    532       INVALIDr, INVALIDr },
    533     { TOQ0_PKTHDR1_PAR_ERR_ENf, TOQ0_PKTHDR1_PAR_ERRf, NULL,
    534       MMU_CBPPKTHEADER1_MEM0m, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    535       INVALIDr,
    536       TOQ_PKTHDR1ERRPTRr, INVALIDr,
    537       INVALIDr, INVALIDr },
    538     { TOQ0_PKTLINK_PAR_ERR_ENf, TOQ0_PKTLINK_PAR_ERRf, NULL,
    539       MMU_PKTLINK0m, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    540       INVALIDr,
    541       TOQ_PKTLINKERRPTRr, INVALIDr,
    542       INVALIDr, INVALIDr },
    543     { TOQ0_CELLLINK_PAR_ERR_ENf, TOQ0_CELLLINK_PAR_ERRf, NULL,
    544       MMU_CELLLINKm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    545       INVALIDr,
    546       TOQ_CELLLINKERRPTRr, INVALIDr,
    547       INVALIDr, INVALIDr },
    548     { TOQ0_IPMC_TBL_PAR_ERR_ENf, TOQ0_IPMC_TBL_PAR_ERRf, NULL,
    549       INVALIDm, _SOC_PARITY_INFO_TYPE_MMUIPMC,
    550       INVALIDr,
    551       TOQ_IPMCGRPERRPTR0r, TOQ_ERRINTR1r,
    552       INVALIDr, INVALIDr },
    553     { TOQ0_VLAN_TBL_PAR_ERR_ENf, TOQ0_VLAN_TBL_PAR_ERRf, NULL,
    554       MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    555       INVALIDr,
    556       TOQ_IPMCVLANERRPTRr, INVALIDr,
    557       INVALIDr, INVALIDr },
    558     { MTRO_PAR_ERR_ENf, MTRO_PAR_ERRf, NULL,
    559       INVALIDm, _SOC_PARITY_INFO_TYPE_MMUMTRO,
    560       INVALIDr,
    561       INVALIDr, INVALIDr,
    562       INVALIDr, INVALIDr },
    563     { PFAP_PAR_ERR_ENf, PFAP_PAR_ERRf, NULL,
    564       MMU_PFAP_MEMm, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    565       INVALIDr,
    566       PFAPPARITYERRORPTRr, INVALIDr,
    567       INVALIDr, INVALIDr },
    568     { PFAP_MEM_FAIL_ENf, PFAP_MEM_FAILf, NULL,
    569       MMU_PFAP_MEMm, _SOC_PARITY_INFO_TYPE_GENERIC,
    570       INVALIDr,
    571       INVALIDr, INVALIDr,
    572       INVALIDr, INVALIDr },
    573     { WRED_PAR_ERR_ENf, WRED_PAR_ERRf, NULL,
    574       INVALIDm, _SOC_PARITY_INFO_TYPE_MMUWRED,
    575       INVALIDr,
    576       WRED_PARITY_ERROR_INFOr, WRED_PARITY_ERROR_BITMAPr,
    577       INVALIDr, INVALIDr },
    578     { DEQ_PKTHDR2_ERR_ENf, DEQ_PKTHDR2_PAR_ERRf, NULL,
    579       MMU_CBPPKTHEADER2m, _SOC_PARITY_INFO_TYPE_MMU_PARITY,
    580       INVALIDr,
    581       DEQ_PKTHDR2ERRPTRr, INVALIDr,
    582       INVALIDr, INVALIDr },
    583     { E2EFC_ERR_ENf, E2EFC_PAR_ERRf, NULL,
    584       INVALIDm, _SOC_PARITY_INFO_TYPE_MMUE2EFC,
    585       INVALIDr,
    586       INVALIDr, INVALIDr,
    587       INVALIDr, INVALIDr },
    588     { INVALIDf, INVALIDf }, /* table terminator */
    589 };
    590 
    591 static _soc_parity_info_t _soc_en_xqp_parity_info[] = {
    592     { EHG_TX_DATAf, EHG_TX_DATAf, NULL,
    593       XQPORT_EHG_TX_TUNNEL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    594       XQPORT_PARITY_CONTROLr,
    595       XQPORT_EHG_TX_DATA_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr,
    596       XQPORT_EHG_TX_DATA_PARITY_STATUS_NACKr, XQPORT_FORCE_DOUBLE_BIT_ERRORr },
    597     
    598     { XQBOD_RXFIFOf, XQBOD_RXFIFOf, "XQBOD_RXFIFO",
    599       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    600       XQPORT_PARITY_CONTROLr,
    601       XQPORT_XQBOD_RXFIFO_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr,
    602       INVALIDr, XQPORT_FORCE_DOUBLE_BIT_ERRORr },
    603     { XQBODE_TXFIFOf, XQBODE_TXFIFOf, "XQBODE_TXFIFO",
    604       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    605       XQPORT_PARITY_CONTROLr,
    606       XQPORT_XQBODE_TXFIFO_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr,
    607       INVALIDr, XQPORT_FORCE_DOUBLE_BIT_ERRORr },
    608     { INVALIDf, INVALIDf }, /* table terminator */
    609 };
    610 
    611 static struct {
    612     uint32             cpi_bit;
    613     soc_block_t        blocktype;
    614     soc_reg_t          enable_reg;
    615     soc_reg_t          status_reg;
    616     _soc_parity_info_t *info;
    617 } _soc_en_parity_group_info[] = {
    618     { 0x00001, SOC_BLK_MMU, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, _soc_en_mmu_parity_info },
    619     { 0x00002, SOC_BLK_EPIPE, EP_INTR_ENABLEr, EP_INTR_STATUSr, _soc_en_ep_parity_info },
    620     { 0x00004, SOC_BLK_IPIPE, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, _soc_en_ip0_parity_info },
    621     { 0x00008, SOC_BLK_IPIPE, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, _soc_en_ip1_parity_info },
    622     { 0x00010, SOC_BLK_IPIPE, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, _soc_en_ip2_parity_info },
    623  /* { 0x00020, PCIE_REPLAY_PERR, }, */
    624     { 0x00040, SOC_BLK_XQPORT, XQPORT_INTR_ENABLEr, XQPORT_INTR_STATUSr, _soc_en_xqp_parity_info }, /* x4 */
    625     { 0 }, /* table terminator */
    626 };
    627 
    628 soc_enduro_oam_handler_t en_oam_handler[SOC_MAX_NUM_DEVICES] = {NULL};
    629 
    630 static soc_ser_functions_t _enduro_ser_functions;
    631 
    632 #define _SOC_ENDURO_SER_REG 1
    633 #define _SOC_ENDURO_SER_MEM 0
    634 
    635 typedef union _enduro_ser_nack_reg_mem_u {
    636     soc_reg_t reg;
    637     soc_mem_t mem;
    638 } _enduro_ser_nack_reg_mem_t;
    639 
    640 STATIC int
    641 _soc_enduro_parity_block_port(int unit, soc_block_t block, soc_port_t *port)
    642 {
    643     *port = SOC_BLOCK_PORT(unit, block);
    644     if ((*port != REG_PORT_ANY) && !SOC_PORT_VALID(unit, *port)) {
    645         return SOC_E_PORT;
    646     }
    647 
    648     return SOC_E_NONE;
    649 }
    650 
    651 STATIC int
    652 _soc_enduro_parity_enable(int unit, int enable)
    653 {
    654     int group, table;
    655     uint32 addr, group_enable, regval, misc_cfg, cmic_enable = 0, cpi_blk_bit;
    656     _soc_parity_info_t *info;
    657     soc_reg_t group_reg, reg;
    658     soc_port_t block_port;
    659     soc_field_t enable_field;
    660     soc_block_t blk;
    661 
    662     /* loop through each group */
    663     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
    664         info = _soc_en_parity_group_info[group].info;
    665         group_reg = _soc_en_parity_group_info[group].enable_reg;
    666         group_enable = 0;
    667 
    668         cpi_blk_bit = _soc_en_parity_group_info[group].cpi_bit;
    669 
    670         SOC_BLOCK_ITER(unit, blk,
    671                        _soc_en_parity_group_info[group].blocktype) {
    672             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
    673                 cpi_blk_bit <<= 1;
    674                 continue;
    675             }
    676             /* loop through each table in the group */
    677             for (table = 0; info[table].enable_field != INVALIDf; table++) {
    678                 /* handle different parity error reporting style */
    679                 switch (info[table].type) {
    680                 case _SOC_PARITY_INFO_TYPE_GENERIC:
    681                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
    682                 case _SOC_PARITY_INFO_TYPE_MMUIPMC:
    683                 case _SOC_PARITY_INFO_TYPE_MMUWRED:
    684                 case _SOC_PARITY_INFO_TYPE_MMUMTRO:
    685                 case _SOC_PARITY_INFO_TYPE_MMUE2EFC:
    686                 case _SOC_PARITY_INFO_TYPE_OAM:
    687                     enable_field = info[table].enable_field;
    688                     break;
    689                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
    690                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
    691                 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER:
    692                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
    693                     reg = info[table].control_reg;
    694                     if (!SOC_REG_IS_VALID(unit, reg)) {
    695                         continue;
    696                     }
    697                     addr = soc_reg_addr(unit, reg, block_port, 0);
    698                     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &regval));
    699                     soc_reg_field_set(unit, reg, &regval,
    700                                       info[table].enable_field,
    701                                       enable ? 1 : 0);
    702                     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, regval));
    703                     enable_field = info[table].error_field;
    704                     break;
    705                 default:
    706                     enable_field = INVALIDf;
    707                     break;
    708                 } /* handle different parity error reporting style */
    709                 if (enable_field != INVALIDf) {
    710                     soc_reg_field_set(unit, group_reg, &group_enable,
    711                                       enable_field, enable ? 1 : 0);
    712                 }
    713             } /* loop through each table in the group */
    714 
    715             if (!SOC_REG_IS_VALID(unit, group_reg)) {
    716                 cpi_blk_bit <<= 1;
    717                 continue;
    718             }
    719             addr = soc_reg_addr(unit, group_reg, block_port, 0);
    720             SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable));
    721             cmic_enable |= cpi_blk_bit;
    722             cpi_blk_bit <<= 1;
    723         }
    724     } /* loop through each group */
    725 
    726     /* coverity[result_independent_of_operands] */
    727     SOC_IF_ERROR_RETURN(WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit,
    728                                                             cmic_enable));
    729 
    730     /* MMU enables */
    731     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg));
    732     soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_STAT_CLEARf, 1);
    733     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    734 
    735     soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 1);
    736     soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 1);
    737     soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_STAT_CLEARf, 0);
    738     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    739 
    740     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &regval));
    741     soc_intr_enable(unit, IRQ_MEM_FAIL);
    742 
    743     return SOC_E_NONE;
    744 }
    745 
    746 STATIC void
    747 _soc_enduro_mem_parity_info(int unit, int block_info_idx,
    748                             soc_field_t field_enum, uint32 *minfo)
    749 {
    750     *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP)
    751         | (field_enum & SOC_ERROR_FIELD_ENUM_MASK);
    752 }
    753 
    754 int
    755 _soc_enduro_mem_parity_control(int unit, soc_mem_t mem,
    756                                  int copyno, int enable)
    757 {
    758     int group, table;
    759     uint32 cpi_blk_bit, misc_cfg;
    760     _soc_parity_info_t *info;
    761     soc_reg_t group_reg, reg;
    762     soc_port_t block_port;
    763     soc_field_t enable_field;
    764     soc_block_t blk;
    765 
    766     if (!soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
    767         /* Parity checking is not enabled, nothing to do */
    768         return SOC_E_NONE;
    769     }
    770 
    771     /* Convert component/aggregate memories to the table for which
    772      * the parity registers correspond. */
    773     switch(mem) {
    774     case VLAN_SUBNETm:
    775         mem = VLAN_SUBNET_DATA_ONLYm; /* Should be VLAN_SUBNET? */
    776         break;
    777     case VLAN_MACm:
    778         mem = VLAN_XLATEm;
    779         break;
    780     case L2_ENTRY_ONLYm:
    781         mem = L2Xm;
    782         break;
    783     case L2_USER_ENTRY_ONLYm:
    784     case L2_USER_ENTRY_DATA_ONLYm:
    785         mem = L2_USER_ENTRYm;
    786         break;
    787     case L3_ENTRY_IPV4_UNICASTm:
    788     case L3_ENTRY_IPV6_UNICASTm:
    789     case L3_ENTRY_IPV4_MULTICASTm:
    790     case L3_ENTRY_IPV6_MULTICASTm:
    791         mem = L3_ENTRY_ONLYm;
    792         break;
    793     case L3_DEFIPm:
    794         mem = L3_DEFIP_DATA_ONLYm;
    795         break;
    796     case L3_DEFIP_128m:
    797         mem = L3_DEFIP_128_DATA_ONLYm;
    798         break;
    799     case EGR_IP_TUNNEL_IPV6m:
    800     case EGR_IP_TUNNEL_MPLSm:
    801         mem = EGR_IP_TUNNELm;
    802         break;
    803     default:
    804         /* Do nothing, keep memory as provided */
    805         break;
    806     }
    807 
    808 
    809     /* loop through each group */
    810     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
    811         info = _soc_en_parity_group_info[group].info;
    812         group_reg = _soc_en_parity_group_info[group].enable_reg;
    813         cpi_blk_bit = _soc_en_parity_group_info[group].cpi_bit;
    814 
    815         SOC_BLOCK_ITER(unit, blk,
    816                        _soc_en_parity_group_info[group].blocktype) {
    817             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
    818                 cpi_blk_bit <<= 1;
    819                 continue;
    820             }
    821             if ((copyno != MEM_BLOCK_ANY) && (blk != copyno)) {
    822                 cpi_blk_bit <<= 1;
    823                 continue;
    824             }
    825 
    826             /* loop through each table in the group */
    827             for (table = 0; info[table].enable_field != INVALIDf; table++) {
    828                 if (mem != info[table].mem) {
    829                     continue;
    830                 }
    831 
    832                 /* handle different parity error reporting style */
    833                 switch (info[table].type) {
    834                 case _SOC_PARITY_INFO_TYPE_GENERIC:
    835                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
    836                 case _SOC_PARITY_INFO_TYPE_MMUIPMC:
    837                 case _SOC_PARITY_INFO_TYPE_MMUWRED:
    838                 case _SOC_PARITY_INFO_TYPE_MMUMTRO:
    839                 case _SOC_PARITY_INFO_TYPE_MMUE2EFC:
    840                     enable_field = info[table].enable_field;
    841                     SOC_IF_ERROR_RETURN
    842                         (soc_reg_field32_modify(unit, group_reg, block_port,
    843                                                 enable_field,
    844                                                 enable ? 1 : 0));
    845                     break;
    846                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
    847                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
    848                 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER:
    849                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
    850                     reg = info[table].control_reg;
    851                     if (!SOC_REG_IS_VALID(unit, reg)) {
    852                         return SOC_E_NONE;
    853                     }
    854                     SOC_IF_ERROR_RETURN
    855                         (soc_reg_field32_modify(unit, reg, block_port,
    856                                                 info[table].enable_field,
    857                                                 enable ? 1 : 0));
    858                     break;
    859                 default:
    860                     /* coverity[assigned_value] */
    861                     enable_field = INVALIDf;
    862                     break;
    863                 } /* handle different parity error reporting style */
    864             } /* loop through each table in the group */
    865             cpi_blk_bit <<= 1;
    866         }
    867     } /* loop through each group */
    868 
    869     /* MMU controls */
    870     if (enable) {
    871         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg));
    872         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg,
    873                           PARITY_STAT_CLEARf, 1);
    874         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    875 
    876         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 1);
    877         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 1);
    878         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg,
    879                           PARITY_STAT_CLEARf, 0);
    880         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, METERING_CLK_ENf, 1);
    881         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    882     } else {
    883         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg));
    884         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 0);
    885         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 0);
    886         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, METERING_CLK_ENf, 0);
    887         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    888     }
    889 
    890     return SOC_E_NONE;
    891 }
    892 
    893 STATIC int
    894 _soc_enduro_process_single_parity_error(int unit, int group,
    895                                           soc_port_t block_port, int table,
    896                                           int schan, char *msg, soc_block_t block)
    897 {
    898     _soc_parity_info_t *info;
    899     soc_reg_t status_reg;
    900     uint32 addr, reg_val, minfo;
    901     int index, multiple, error, rv;
    902     _soc_ser_correct_info_t spci;
    903 
    904     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
    905 
    906     info = _soc_en_parity_group_info[group].info;
    907 
    908     status_reg = schan ? info[table].nack_status0_reg :
    909         info[table].intr_status0_reg;
    910     if (status_reg == INVALIDr) {
    911         return SOC_E_INTERNAL;
    912     }
    913     addr = soc_reg_addr(unit, status_reg, block_port, 0);
    914     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    915     index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf);
    916     multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
    917     error = soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERRf);
    918  
    919     if (error) {
    920         _soc_enduro_mem_parity_info(unit, block, info[table].error_field, 
    921                                     &minfo);
    922         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
    923                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
    924                            index, minfo);
    925 
    926         LOG_ERROR(BSL_LS_SOC_COMMON,
    927                   (BSL_META_U(unit,
    928                               "unit %d %s entry %d parity error\n"),
    929                    unit, msg, index));
    930         if (multiple) {
    931             LOG_ERROR(BSL_LS_SOC_COMMON,
    932                       (BSL_META_U(unit,
    933                                   "unit %d %s has multiple parity errors\n"),
    934                        unit, msg));
    935         }
    936         if (info[table].mem != INVALIDm) {
    937             spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
    938             spci.reg = INVALIDr;
    939             spci.mem = info[table].mem;
    940             spci.blk_type = block;
    941             spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index);
    942             rv = soc_ser_correction(unit, &spci);
    943             if (SOC_FAILURE(rv)) {
    944                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
    945                                    SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
    946                                    index, minfo);
    947             }
    948         }
    949     } else {
    950         LOG_ERROR(BSL_LS_SOC_COMMON,
    951                   (BSL_META_U(unit,
    952                               "unit %d %s: parity hardware inconsistency\n"),
    953                    unit, msg));
    954     }
    955 
    956     /* Clear parity status */
    957     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0));
    958     return SOC_E_NONE;
    959 }
    960 
    961 STATIC int
    962 _soc_enduro_process_single_ecc_error(int unit, int group,
    963                                        soc_port_t block_port, int table,
    964                                        int schan, char *msg, soc_block_t block)
    965 {
    966     _soc_parity_info_t *info;
    967     soc_reg_t status_reg;
    968     uint32 addr, reg_val, minfo;
    969     int rv, index, single_bit = 0, double_bit = 0, multiple = 0, error = 0;
    970     _soc_ser_correct_info_t spci;
    971 
    972     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
    973 
    974     info = _soc_en_parity_group_info[group].info;
    975 
    976     status_reg = schan ? info[table].nack_status0_reg :
    977         info[table].intr_status0_reg;
    978     if (status_reg == INVALIDr) {
    979         return SOC_E_INTERNAL;
    980     }
    981     addr = soc_reg_addr(unit, status_reg, block_port, 0);
    982     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    983     index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf);
    984 
    985     if (soc_reg_field_valid(unit, status_reg, SINGLE_BIT_ERRf)) {
    986         single_bit = soc_reg_field_get(unit, status_reg,
    987                                        reg_val, SINGLE_BIT_ERRf);
    988     }
    989     if (soc_reg_field_valid(unit, status_reg, DOUBLE_BIT_ERRf)) {
    990         double_bit = soc_reg_field_get(unit, status_reg,
    991                                        reg_val, DOUBLE_BIT_ERRf);
    992     }
    993 
    994     if (soc_reg_field_valid(unit, status_reg, ECC_ERRf)) {
    995         error = soc_reg_field_get(unit, status_reg, reg_val, ECC_ERRf);
    996     }
    997 
    998     multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
    999 
   1000     if (single_bit || double_bit || error) {
   1001         LOG_ERROR(BSL_LS_SOC_COMMON,
   1002                   (BSL_META_U(unit,
   1003                               "unit %d %s entry %d %s ECC error\n"),
   1004                    unit, msg, index, double_bit ? "double-bit" : "single-bit"));
   1005         _soc_enduro_mem_parity_info(unit, block,
   1006                                     info[table].error_field, &minfo);
   1007         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1008                            SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   1009                            index, minfo);
   1010 
   1011         if (multiple) {
   1012             LOG_ERROR(BSL_LS_SOC_COMMON,
   1013                       (BSL_META_U(unit,
   1014                                   "unit %d %s has multiple ECC errors\n"),
   1015                        unit, msg));
   1016         }
   1017         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1018         spci.reg = INVALIDr;
   1019         spci.mem = info[table].mem;
   1020         spci.blk_type = block;
   1021         spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index);
   1022         spci.double_bit = (double_bit == 0) ? 0 : 1;
   1023         spci.parity_type = SOC_PARITY_TYPE_ECC;
   1024         rv = soc_ser_correction(unit, &spci);
   1025         if (SOC_FAILURE(rv)) {
   1026             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1027                                SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1028                                index, minfo);
   1029         }
   1030     } else {
   1031         LOG_ERROR(BSL_LS_SOC_COMMON,
   1032                   (BSL_META_U(unit,
   1033                               "unit %d %s: parity hardware inconsistency\n"),
   1034                    unit, msg));
   1035     }
   1036 
   1037     /* Clear parity status */
   1038     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0));
   1039     return SOC_E_NONE;
   1040 }
   1041 
   1042 STATIC int
   1043 _soc_enduro_process_dual_parity_error(int unit, int group,
   1044                                         soc_port_t block_port, int table,
   1045                                         int schan, char *msg, soc_block_t block)
   1046 {
   1047     _soc_parity_info_t *info;
   1048     soc_reg_t status_reg;
   1049     uint32 addr, reg_val, minfo, bitmap = 0;
   1050     int rv, index, bucket_index = 0, multiple = 0, ix, bits, size = 0;
   1051     _soc_ser_correct_info_t spci;
   1052 
   1053     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1054 
   1055     info = _soc_en_parity_group_info[group].info;
   1056 
   1057     for (ix = 0; ix < 2; ix ++) {
   1058         if (ix == 1) {
   1059             status_reg = schan ? info[table].nack_status1_reg :
   1060                 info[table].intr_status1_reg;
   1061         } else {
   1062             status_reg = schan ? info[table].nack_status0_reg :
   1063                 info[table].intr_status0_reg;
   1064         }
   1065 
   1066         if (status_reg == INVALIDr) {
   1067             continue;
   1068         }
   1069 
   1070         addr = soc_reg_addr(unit, status_reg, block_port, 0);
   1071         SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
   1072         if (soc_reg_field_valid(unit, status_reg, BUCKET_IDXf)) {
   1073             bucket_index =
   1074                 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDXf);
   1075             multiple =
   1076                 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
   1077             bitmap =
   1078                 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf);
   1079             size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf);
   1080         } else if (soc_reg_field_valid(unit, status_reg, BUCKET_IDX_0f)) {
   1081             bucket_index =
   1082                 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDX_0f);
   1083             if (MPLS_ENTRYm == info[table].mem) {
   1084                 multiple =
   1085                     soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
   1086                 bitmap =
   1087                     soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf);
   1088                 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf);
   1089             } else {
   1090                 multiple =
   1091                     soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERR_0f);
   1092                 bitmap =
   1093                     soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BM_0f);
   1094                 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BM_0f);
   1095             }
   1096         } else if (soc_reg_field_valid(unit, status_reg, BUCKET_IDX_1f)) {
   1097             bucket_index =
   1098                     soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDX_1f);
   1099             if (MPLS_ENTRYm == info[table].mem) {
   1100                 multiple =
   1101                     soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
   1102                 bitmap =
   1103                     soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf);
   1104                 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf);
   1105             } else {
   1106                 multiple =
   1107                    soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERR_1f);
   1108                 bitmap =
   1109                     soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BM_1f);
   1110                 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BM_1f);
   1111             }
   1112         }
   1113 
   1114         if (multiple) {
   1115             LOG_ERROR(BSL_LS_SOC_COMMON,
   1116                       (BSL_META_U(unit,
   1117                                   "unit %d %s has multiple parity errors\n"),
   1118                        unit, msg));
   1119         }
   1120 
   1121         if (bitmap != 0) {
   1122             for (bits = 0; bits < size; bits++) {
   1123                 if (bitmap & (1 << bits)) {
   1124                     index =
   1125                         bucket_index * size * 2 + bits + (ix * size);
   1126                     if (info[table].mem == L2Xm) {
   1127                         /* Check the valid index range before reporting the error.*/
   1128                         if (index > soc_mem_index_max(unit, L2Xm)){
   1129                             LOG_ERROR(BSL_LS_SOC_COMMON,
   1130                                       (BSL_META_U(unit,
   1131                                                   "L2X entry parity error index"
   1132                                                   " %d out of valid range !\n"),
   1133                                       index));                                                                                                       
   1134                             continue;
   1135                         }
   1136                     }
   1137                     _soc_enduro_mem_parity_info(unit, block,
   1138                                                 info[table].error_field, &minfo);
   1139                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1140                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1141                                        index, minfo);
   1142 
   1143                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1144                               (BSL_META_U(unit,
   1145                                           "unit %d %s entry %d parity error\n"),
   1146                                unit, msg, index));
   1147                     
   1148                     if (info[table].mem != INVALIDm) {
   1149                         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1150                         spci.reg = INVALIDr;
   1151                         spci.mem = info[table].mem;
   1152                         spci.blk_type = block;
   1153                         spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index);
   1154                         rv = soc_ser_correction(unit, &spci);
   1155                         if (SOC_FAILURE(rv)) {
   1156                             soc_event_generate(unit, 
   1157                                 SOC_SWITCH_EVENT_PARITY_ERROR,
   1158                                 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1159                                 index, minfo);
   1160                         }
   1161                     }
   1162                 }
   1163             }
   1164         }
   1165 
   1166         /* Clear parity status */
   1167         SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0));
   1168     }
   1169 
   1170     return SOC_E_NONE;
   1171 }
   1172 
   1173 STATIC int
   1174 _soc_enduro_parity_mmu_clear(int unit, soc_field_t status_field)
   1175 {
   1176     uint32 rval;
   1177     SOC_IF_ERROR_RETURN
   1178         (READ_MEM_FAIL_INT_STATr(unit, &rval));
   1179     soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, status_field, 0);
   1180     SOC_IF_ERROR_RETURN
   1181         (WRITE_MEM_FAIL_INT_STATr(unit, rval));
   1182     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   1183     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1);
   1184     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1185     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   1186     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0);
   1187     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1188     return SOC_E_NONE;
   1189 }
   1190 
   1191 STATIC int
   1192 _soc_enduro_process_mmu_parity_error(int unit, int group,
   1193                                        soc_port_t block_port, int table,
   1194                                        char *msg, soc_block_t block)
   1195 {
   1196     _soc_parity_info_t *info;
   1197     soc_reg_t status_reg, index_reg, group_reg;
   1198     uint32 addr, reg_val, group_status, minfo;
   1199     int index, rv;
   1200     _soc_ser_correct_info_t spci;
   1201 
   1202     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1203 
   1204     info = _soc_en_parity_group_info[group].info;
   1205     group_reg = _soc_en_parity_group_info[group].status_reg;
   1206     addr = soc_reg_addr(unit, group_reg, block_port, 0);
   1207     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_status));
   1208     
   1209     status_reg = info[table].intr_status1_reg;
   1210     index_reg = info[table].intr_status0_reg;
   1211     if (index_reg == INVALIDr) {
   1212         LOG_ERROR(BSL_LS_SOC_COMMON,
   1213                   (BSL_META_U(unit,
   1214                               "unit %d %s parity error\n"),
   1215                               unit, msg));
   1216         return SOC_E_NONE;
   1217     }
   1218     if (status_reg != INVALIDr) {
   1219         addr = soc_reg_addr(unit, status_reg, block_port, 0);
   1220         SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
   1221         if (reg_val == 0) {
   1222             LOG_ERROR(BSL_LS_SOC_COMMON,
   1223                       (BSL_META_U(unit,
   1224                                   "unit %d %s: parity hardware inconsistency\n"),
   1225                        unit, msg));
   1226             return SOC_E_NONE;
   1227         }
   1228     }
   1229     addr = soc_reg_addr(unit, index_reg, block_port, 0);
   1230     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
   1231     index = reg_val;
   1232     _soc_enduro_mem_parity_info(unit, block,
   1233                                  info[table].error_field, &minfo);
   1234     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1235                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1236                        index, minfo); 
   1237 
   1238     LOG_ERROR(BSL_LS_SOC_COMMON,
   1239               (BSL_META_U(unit,
   1240                           "unit %d %s entry %d parity error\n"),
   1241                unit, msg, index));
   1242 
   1243     if (info[table].mem != INVALIDm) {
   1244         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1245         spci.reg = INVALIDr;
   1246         spci.mem = info[table].mem;
   1247         spci.blk_type = block;
   1248         spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index);
   1249         rv = soc_ser_correction(unit, &spci);
   1250         if (SOC_FAILURE(rv)) {
   1251             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1252                                SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1253                                index, minfo);
   1254         }
   1255     }
   1256 
   1257     /* update soc stats for some cases */
   1258     if (info[table].error_field == CCP_PAR_ERRf) {
   1259         SOC_CONTROL(unit)->stat.err_cpcrc++;
   1260     } else if (info[table].error_field == CFAP_PAR_ERRf) {
   1261         SOC_CONTROL(unit)->stat.err_cfap++;
   1262     } 
   1263     SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, info[table].error_field));
   1264     return SOC_E_NONE;
   1265 }
   1266 
   1267 STATIC int
   1268 _soc_enduro_process_mmu_ipmc_parity_error(int unit, _soc_parity_info_t *info,
   1269                                           soc_port_t block_port, soc_block_t block)
   1270 {
   1271     static soc_mem_t ipmc_mems[] =
   1272     {
   1273         MMU_IPMC_GROUP_TBL0m,
   1274         MMU_IPMC_GROUP_TBL1m,
   1275         MMU_IPMC_GROUP_TBL2m,
   1276         MMU_IPMC_GROUP_TBL3m
   1277     };
   1278     static soc_field_t ipmc_mem_fields[] =
   1279     {
   1280         IGPERR0f,
   1281         IGPERR1f,
   1282         IGPERR2f,
   1283         IGPERR3f
   1284     };
   1285     int index, rv;
   1286     soc_reg_t mem_id_reg, index_reg;
   1287     uint32 addr, mem_bitmap, entry_index, status, minfo;
   1288     _soc_ser_correct_info_t spci;
   1289     
   1290     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1291     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status));
   1292     if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status,
   1293                            TOQ0_IPMC_TBL_PAR_ERRf)) {
   1294         LOG_ERROR(BSL_LS_SOC_COMMON,
   1295                   (BSL_META_U(unit,
   1296                               "unit %d IPMC: parity hardware inconsistency\n"),
   1297                               unit));
   1298         return SOC_E_NONE;
   1299     }
   1300     /*
   1301      * status0 (TOQ_IPMCGRPERRPTR0r) is index
   1302      * status1 (TOQ_ERRINTR1r) is table id
   1303      * MMU_IPMC_GROUP_TBL0m - MMU_IPMC_GROUP_TBL3m
   1304      */
   1305     index_reg = info->intr_status0_reg;
   1306     addr = soc_reg_addr(unit, index_reg, block_port, 0);
   1307     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &entry_index));
   1308     mem_id_reg = info->intr_status1_reg;
   1309     addr = soc_reg_addr(unit, mem_id_reg, block_port, 0);
   1310     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &mem_bitmap));
   1311     for (index = 0; index < COUNTOF(ipmc_mem_fields); index++) {
   1312         if (!soc_reg_field_get(unit, mem_id_reg, mem_bitmap,
   1313                                ipmc_mem_fields[index])) {
   1314             continue;
   1315         }
   1316         _soc_enduro_mem_parity_info(unit, block,
   1317                                     info->error_field, &minfo);
   1318         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1319                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   1320                            entry_index, minfo);
   1321         LOG_ERROR(BSL_LS_SOC_COMMON,
   1322                   (BSL_META_U(unit,
   1323                               "unit %d IPMC%d entry %d parity error\n"),
   1324                               unit, index, entry_index));
   1325         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1326         spci.reg = INVALIDr;
   1327         spci.mem = ipmc_mems[index];
   1328         spci.blk_type = SOC_BLK_MMU;
   1329         spci.index = soc_enduro_mem_index_remap(unit, spci.mem, entry_index);
   1330         rv = soc_ser_correction(unit, &spci);
   1331         if (SOC_FAILURE(rv)) {
   1332             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1333                                SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1334                                entry_index, minfo);
   1335         }
   1336         /* Clear memory id register explicitly */
   1337         soc_reg_field_set(unit, mem_id_reg, &mem_bitmap, ipmc_mem_fields[index], 0);
   1338         addr = soc_reg_addr(unit, mem_id_reg, block_port, 0);
   1339         SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, mem_bitmap));
   1340         break;
   1341     }
   1342     SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, TOQ0_IPMC_TBL_PAR_ERRf));
   1343     return SOC_E_NONE;
   1344 }
   1345 
   1346 STATIC int
   1347 _soc_enduro_process_mmu_e2efc_parity_error(int unit, _soc_parity_info_t *info,
   1348                                           soc_port_t block_port, soc_block_t block)
   1349 {
   1350     static soc_reg_t e2efc_regs[] = {
   1351           INVALIDr,  
   1352           E2EFC_CNT_SET_LIMITr,
   1353           E2EFC_CNT_RESET_LIMITr,
   1354           E2EFC_CNT_DISC_LIMITr
   1355     };
   1356     int rv;
   1357     soc_reg_t err_reg;
   1358     uint32 reg_val, val, status, entry_index, mem_id, minfo;
   1359     _soc_ser_correct_info_t spci;
   1360 
   1361     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1362     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status));
   1363     if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, E2EFC_PAR_ERRf)) {
   1364         LOG_ERROR(BSL_LS_SOC_COMMON,
   1365                   (BSL_META_U(unit,
   1366                               "unit %d E2EFC: parity hardware inconsistency\n"),
   1367                               unit));
   1368         return SOC_E_NONE;
   1369     }
   1370 
   1371     err_reg = E2EFC_PARITYERRORPTRr;
   1372     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, err_reg, 
   1373                                         block_port, 0, &reg_val));
   1374 
   1375     /* Disable parity */
   1376     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   1377     soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0);
   1378     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val));
   1379         
   1380     mem_id = soc_reg_field_get(unit, err_reg, reg_val, INSTf);
   1381     /* CHECK if the error is valid */
   1382     if (mem_id == 0) {
   1383         LOG_ERROR(BSL_LS_SOC_COMMON,
   1384                   (BSL_META_U(unit,
   1385                               "unit %d E2EFC: parity hardware inconsistency\n"),
   1386                               unit));
   1387         return SOC_E_NONE;
   1388     }
   1389     entry_index = soc_reg_field_get(unit, err_reg, reg_val, PTRf);
   1390 
   1391     _soc_enduro_mem_parity_info(unit, block,
   1392                                 info->error_field, &minfo);
   1393     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1394                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1395                        entry_index, minfo);
   1396     LOG_ERROR(BSL_LS_SOC_COMMON,
   1397               (BSL_META_U(unit,
   1398                           "unit %d E2EFC entry %d parity error\n"),
   1399                           unit, entry_index));
   1400     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   1401     spci.reg = e2efc_regs[mem_id];
   1402     spci.mem = INVALIDm;
   1403     spci.blk_type = SOC_BLK_MMU;
   1404     spci.index = entry_index;
   1405     rv = soc_ser_correction(unit, &spci);
   1406     if (SOC_FAILURE(rv)) {
   1407             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1408                                SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1409                                entry_index, minfo);
   1410         }
   1411     SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, E2EFC_PAR_ERRf));
   1412     /* Enable parity */
   1413     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   1414     soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1);
   1415     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val));
   1416     return SOC_E_NONE;
   1417 }
   1418 
   1419 STATIC int
   1420 _soc_enduro_process_mmu_mtro_parity_error(int unit, _soc_parity_info_t *info,
   1421                                           soc_port_t block_port, soc_block_t block)
   1422 {
   1423     static soc_reg_t mtro_regs[] = {
   1424         MINBUCKETCONFIG_64r,
   1425         MINBUCKETr,
   1426         MAXBUCKETCONFIG_64r,
   1427         MAXBUCKETr
   1428     };
   1429     static soc_reg_t cpu_mtro_regs[] = {
   1430         CPUMAXBUCKETCONFIG_64r,
   1431         CPUMAXBUCKETr
   1432     };
   1433     uint32 i, addr, status, val, minfo, index = 0;
   1434     _soc_ser_correct_info_t spci;
   1435     int rv, port = 0;
   1436     
   1437     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1438     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   1439     spci.mem = INVALIDm;
   1440     spci.blk_type = SOC_BLK_MMU;
   1441     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status));
   1442     if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, MTRO_PAR_ERRf)) {
   1443         LOG_ERROR(BSL_LS_SOC_COMMON,
   1444                   (BSL_META_U(unit,
   1445                               "unit %d MTRO: parity hardware inconsistency\n"),
   1446                               unit));
   1447         return SOC_E_NONE;
   1448     }
   1449     SOC_IF_ERROR_RETURN(READ_EGRSHAPEPARITYERRORPTRr(unit, &addr));
   1450     
   1451     /* Disable parity */
   1452     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   1453     soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0);
   1454     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val));
   1455         
   1456     if (addr < 8) {
   1457         /* port lb0 */
   1458         port = 1;
   1459         index = addr;
   1460     } else if (addr >= 0x40 && addr <= 0x6f) {
   1461         /* port ge0 ~ ge5 */
   1462         port = ((addr - 0x40) / 0x8) + 0x2;
   1463         index = (addr - 0x40) % 0x8;
   1464     } else if (addr >= 0x80 && addr <= 0xaf) {
   1465         /* port ge6 ~ ge11 */
   1466         port = ((addr - 0x80) / 0x8) + 0x8;
   1467         index = (addr - 0x80) % 0x8;
   1468     } else if (addr >= 0xc0 && addr <= 0xef) {
   1469         /* port ge12 ~ ge17 */
   1470         port = ((addr - 0xc0) / 0x8) + 0xe;
   1471         index = (addr - 0xc0) % 0x8;
   1472     } else if (addr >= 0x100 && addr <= 0x12f) {
   1473         /* port ge18 ~ ge23 */
   1474         port = ((addr - 0x100) / 0x8) + 0x14;
   1475         index = (addr - 0x100) % 0x8;
   1476     } else if (addr >= 0x140 && addr <= 0x16f) {
   1477         /* port hg0 ~ hg1 */
   1478         port = ((addr - 0x140) / 0x18) + 0x1a;
   1479         index = (addr - 0x140) % 0x18;
   1480     } else if (addr >= 0x180 && addr <= 0x1af) {
   1481         /* port hg2 ~ hg3 */
   1482         port = ((addr - 0x180) / 0x18) + 0x1c;
   1483         index = (addr - 0x180) % 0x18;
   1484     } else if (addr >= 0x1c0 && addr <= 0x1c7) {
   1485         /* port hg0 ~ hg3 */
   1486         port = ((addr - 0x1c0) / 0x2) + 0x1a;
   1487         index = (addr - 0x1c0) % 0x2 + 0x18;
   1488     } else if (addr >= 0x200 && addr <= 0x22f) {
   1489         port = REG_PORT_ANY;
   1490         index = (addr - 0x200) % 0x30;
   1491     }
   1492     if (port == REG_PORT_ANY) {
   1493         for (i = 0; i < COUNTOF(cpu_mtro_regs); i++) {
   1494             spci.port = port;
   1495             spci.index = index;
   1496             spci.reg = cpu_mtro_regs[i];
   1497             _soc_enduro_mem_parity_info(unit, block,
   1498                                         info->error_field, &minfo);
   1499             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1500                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1501                                index, minfo);
   1502             rv = soc_ser_correction(unit, &spci);
   1503             if (SOC_FAILURE(rv)) {
   1504                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1505                                    SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1506                                    index, minfo);
   1507             }
   1508         }
   1509     } else if (port >=1 && port <= 29) {
   1510         for (i = 0; i < COUNTOF(mtro_regs); i++) {
   1511             spci.port = port;
   1512             spci.index = index;
   1513             spci.reg = mtro_regs[i];
   1514             _soc_enduro_mem_parity_info(unit, block,
   1515                                 info->error_field, &minfo);
   1516             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1517                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1518                                index, minfo);
   1519             rv = soc_ser_correction(unit, &spci);
   1520             if (SOC_FAILURE(rv)) {
   1521                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1522                                    SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1523                                    index, minfo);
   1524             }
   1525         }
   1526     } else {
   1527         LOG_ERROR(BSL_LS_SOC_COMMON,
   1528                   (BSL_META_U(unit,
   1529                               "unit %d MTRO: parity hardware inconsistency\n"),
   1530                               unit));
   1531     }
   1532     SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, MTRO_PAR_ERRf));
   1533     /* Enable parity */
   1534     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   1535     soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1);
   1536     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val));
   1537     return SOC_E_NONE;
   1538 }
   1539 
   1540 STATIC int
   1541 _soc_enduro_process_mmu_wred_parity_error(int unit, _soc_parity_info_t *info,
   1542                                           soc_port_t block_port, soc_block_t block)
   1543 {
   1544     int rv;
   1545     soc_mem_t mem;
   1546     soc_reg_t mem_id_reg, index_reg;
   1547     uint32 addr, mem_bitmap, entry_index, status, minfo;
   1548     _soc_ser_correct_info_t spci;
   1549     
   1550     memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1551     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status));
   1552     if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, WRED_PAR_ERRf)) {
   1553         LOG_ERROR(BSL_LS_SOC_COMMON,
   1554               (BSL_META_U(unit,
   1555                           "unit %d WRED: parity hardware inconsistency\n"),
   1556                           unit));
   1557         return SOC_E_NONE;
   1558     }
   1559     /*
   1560      * status0 (WRED_PARITY_ERROR_INFOr) is index
   1561      * status1 (WRED_PARITY_ERROR_BITMAPr) is table id
   1562      */
   1563     index_reg = info->intr_status0_reg;
   1564     addr = soc_reg_addr(unit, index_reg, block_port, 0);
   1565     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &entry_index));
   1566     
   1567     mem_id_reg = info->intr_status1_reg;
   1568     addr = soc_reg_addr(unit, mem_id_reg, block_port, 0);
   1569     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &mem_bitmap));
   1570     
   1571     if (mem_bitmap & 0x000003) {
   1572         mem = MMU_WRED_CFG_CELLm;
   1573     } else if (mem_bitmap & 0x00000c) {
   1574         mem = MMU_WRED_THD_0_CELLm;
   1575     } else if (mem_bitmap & 0x000030) {
   1576         mem = MMU_WRED_THD_1_CELLm;
   1577     } else if (mem_bitmap & 0x0000c0) {
   1578         mem = MMU_WRED_CFG_PACKETm;
   1579     } else if (mem_bitmap & 0x000300) {
   1580         mem = MMU_WRED_THD_0_PACKETm;
   1581     } else if (mem_bitmap & 0x000c00) {
   1582         mem = MMU_WRED_THD_1_PACKETm;
   1583     } else if (mem_bitmap & 0x003000) {
   1584         mem = MMU_WRED_PORT_CFG_CELLm;
   1585     } else if (mem_bitmap & 0x00c000) {
   1586         mem = MMU_WRED_PORT_THD_0_CELLm;
   1587     } else if (mem_bitmap & 0x030000) {
   1588         mem = MMU_WRED_PORT_THD_1_CELLm;
   1589     } else if (mem_bitmap & 0x0c0000) {
   1590         mem = MMU_WRED_PORT_CFG_PACKETm;
   1591     } else if (mem_bitmap & 0x300000) {
   1592         mem = MMU_WRED_PORT_THD_0_PACKETm;
   1593     } else if (mem_bitmap & 0xc00000) {
   1594         mem = MMU_WRED_PORT_THD_1_PACKETm;
   1595     } else {
   1596         mem = INVALIDm;
   1597     }
   1598     if (mem != INVALIDm) {
   1599         _soc_enduro_mem_parity_info(unit, block, info->error_field, &minfo);
   1600         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1601                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1602                            entry_index, minfo);
   1603         LOG_ERROR(BSL_LS_SOC_COMMON,
   1604                   (BSL_META_U(unit,
   1605                               "unit %d %s entry %d parity error\n"),
   1606                               unit, SOC_MEM_NAME(unit, mem), entry_index));
   1607         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1608         spci.reg = INVALIDr;
   1609         spci.mem = mem;
   1610         spci.blk_type = block;
   1611         spci.index = soc_enduro_mem_index_remap(unit, spci.mem, entry_index);
   1612         rv = soc_ser_correction(unit, &spci);
   1613         if (SOC_FAILURE(rv)) {
   1614             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1615                                SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   1616                                entry_index, minfo);
   1617         }
   1618     } else {
   1619         LOG_ERROR(BSL_LS_SOC_COMMON,
   1620                   (BSL_META_U(unit,
   1621                               "unit %d WRED: parity hardware inconsistency\n"),
   1622                               unit));
   1623     }
   1624     SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, WRED_PAR_ERRf));
   1625     return SOC_E_NONE;
   1626 }
   1627 
   1628 STATIC int
   1629 _soc_enduro_process_parity_error(int unit)
   1630 {
   1631     int group, table;
   1632     uint32 addr, cmic_status, group_status;
   1633     uint32 group_enable, cpi_blk_bit, minfo;
   1634 
   1635     _soc_parity_info_t *info;
   1636     soc_reg_t group_reg, reg;
   1637     soc_port_t block_port;
   1638     soc_block_t blk;
   1639     char *msg;
   1640     soc_enduro_oam_handler_t oam_handler_snapshot;
   1641 
   1642     /* coverity[result_independent_of_operands] */
   1643     SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit,
   1644                                                            &cmic_status));
   1645 
   1646     /* loop through each group */
   1647     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
   1648         info = _soc_en_parity_group_info[group].info;
   1649         group_reg = _soc_en_parity_group_info[group].status_reg;
   1650         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1651                     (BSL_META_U(unit,
   1652                                 "unit %d %s parity processing\n"),
   1653                                 unit, SOC_REG_NAME(unit, group_reg)));
   1654         cpi_blk_bit = _soc_en_parity_group_info[group].cpi_bit;
   1655 
   1656         SOC_BLOCK_ITER(unit, blk,
   1657                        _soc_en_parity_group_info[group].blocktype) {
   1658             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
   1659                 cpi_blk_bit <<= 1;
   1660                 continue;
   1661             }
   1662             if (!(cmic_status & cpi_blk_bit)) {
   1663                 cpi_blk_bit <<= 1;
   1664                 continue;
   1665             }
   1666 
   1667             addr = soc_reg_addr(unit, group_reg, block_port, 0);
   1668             SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_status));
   1669 
   1670             /* loop through each table in the group */
   1671             for (table = 0; info[table].error_field != INVALIDf; table++) {
   1672                 if (!soc_reg_field_valid(unit, group_reg,
   1673                                          info[table].error_field) &&
   1674                     (info[table].mem != INVALIDm)) {
   1675                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1676                               (BSL_META_U(unit,
   1677                                           "unit %d %s has bad error field\n"),
   1678                                           unit, SOC_MEM_NAME(unit, info[table].mem)));
   1679                     continue;
   1680                 }
   1681 
   1682                 if (!soc_reg_field_get(unit, group_reg, group_status,
   1683                                        info[table].error_field)) {
   1684                     continue;
   1685                 }
   1686                 if (info[table].msg) {
   1687                     msg = info[table].msg;
   1688                 } else if (info[table].mem != INVALIDm) {
   1689                     msg = SOC_MEM_NAME(unit, info[table].mem);
   1690                 } else {
   1691                     msg = SOC_FIELD_NAME(unit, info[table].error_field);
   1692                 }
   1693 
   1694                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1695                             (BSL_META_U(unit,
   1696                                         "unit %d %s analysis\n"),
   1697                                         unit, msg));
   1698 
   1699                 /* Handle different parity error reporting style */
   1700                 switch (info[table].type) {
   1701                 case _SOC_PARITY_INFO_TYPE_GENERIC:
   1702                     _soc_enduro_mem_parity_info(unit, blk,
   1703                                                 info[table].error_field,
   1704                                                 &minfo);
   1705                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   1706                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   1707                                        0, minfo);
   1708 
   1709                     if (info[table].enable_field == START_BY_START_ERR_ENf) {
   1710                         uint64 rr64;
   1711                         uint32 msw;
   1712                         uint32 lsw;
   1713                         uint32 regval;
   1714 
   1715                         /* Clear the START_BY_START port bitmap */
   1716                         SOC_IF_ERROR_RETURN
   1717                             (READ_START_BY_START_ERRORr(unit, &rr64));
   1718                         COMPILER_64_TO_32_HI(msw, rr64);
   1719                         COMPILER_64_TO_32_LO(lsw, rr64);
   1720                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1721                                   (BSL_META_U(unit,
   1722                                               "unit %d START_BY_START_ERRROR"
   1723                                               " = 0x%x%08x\n"),
   1724                                    unit, msw, lsw));
   1725                         COMPILER_64_ZERO(rr64);
   1726                         SOC_IF_ERROR_RETURN
   1727                             (WRITE_START_BY_START_ERRORr(unit, rr64));
   1728 
   1729                         /* Clear the START_BY_START error indication */
   1730                         SOC_IF_ERROR_RETURN
   1731                             (READ_MEM_FAIL_INT_STATr(unit, &regval));
   1732                         soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &regval,
   1733                                           START_BY_START_ERRf, 0);
   1734                         SOC_IF_ERROR_RETURN
   1735                             (WRITE_MEM_FAIL_INT_STATr(unit, regval));
   1736                     } else if (info[table].enable_field
   1737                                == DEQ0_CELLCRC_ERR_ENf) {
   1738                         uint32 regval;
   1739 
   1740                         /* Clear the DEQ0_CELLCRC error indication */
   1741                         SOC_IF_ERROR_RETURN
   1742                             (READ_MEM_FAIL_INT_STATr(unit, &regval));
   1743                         soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &regval,
   1744                                           DEQ0_CELLCRC_ERRf, 0);
   1745                         SOC_IF_ERROR_RETURN
   1746                             (WRITE_MEM_FAIL_INT_STATr(unit, regval));
   1747                     }
   1748 
   1749                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1750                               (BSL_META_U(unit,
   1751                                           "unit %d %s asserted\n"),
   1752                                           unit, msg));
   1753                     break;
   1754                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1755                     SOC_IF_ERROR_RETURN
   1756                         (_soc_enduro_process_single_parity_error(unit,
   1757                               group, block_port, table, FALSE, msg, blk));
   1758                     break;
   1759                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1760                     SOC_IF_ERROR_RETURN
   1761                         (_soc_enduro_process_single_ecc_error(unit,
   1762                               group, block_port, table, FALSE, msg, blk));
   1763                     break;
   1764                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1765                     SOC_IF_ERROR_RETURN
   1766                         (_soc_enduro_process_dual_parity_error(unit,
   1767                                        group, block_port, table, FALSE, msg, blk));
   1768                     break;
   1769                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
   1770                     SOC_IF_ERROR_RETURN
   1771                         (_soc_enduro_process_mmu_parity_error(unit,
   1772                               group, block_port, table, msg, blk));
   1773                     break;
   1774                 case _SOC_PARITY_INFO_TYPE_MMUMTRO:
   1775                     SOC_IF_ERROR_RETURN
   1776                         (_soc_enduro_process_mmu_mtro_parity_error(unit, 
   1777                             &info[table], block_port, blk));
   1778                     break;
   1779                 case _SOC_PARITY_INFO_TYPE_MMUE2EFC:
   1780                     SOC_IF_ERROR_RETURN
   1781                         (_soc_enduro_process_mmu_e2efc_parity_error(unit, 
   1782                             &info[table], block_port, blk));
   1783                     break;
   1784                 case _SOC_PARITY_INFO_TYPE_MMUIPMC:
   1785                 	 SOC_IF_ERROR_RETURN
   1786                         (_soc_enduro_process_mmu_ipmc_parity_error(unit, 
   1787                             &info[table], block_port, blk));
   1788                     break;
   1789                 case _SOC_PARITY_INFO_TYPE_MMUWRED:
   1790                     SOC_IF_ERROR_RETURN
   1791                         (_soc_enduro_process_mmu_wred_parity_error(unit, 
   1792                             &info[table], block_port, blk));
   1793                     break;
   1794                 case _SOC_PARITY_INFO_TYPE_OAM:
   1795                     /* OAM isn't parity-related but shares an interrupt */
   1796 
   1797                     oam_handler_snapshot = en_oam_handler[unit];
   1798 
   1799                     if (oam_handler_snapshot != NULL)
   1800                     {
   1801                         SOC_IF_ERROR_RETURN(oam_handler_snapshot(unit,
   1802                                             info[table].error_field));
   1803                     }
   1804 
   1805                     break;
   1806                 default:
   1807                     break;
   1808                 } /* handle different parity error reporting style */
   1809             } /* loop through each table in the group */
   1810 
   1811             reg = _soc_en_parity_group_info[group].enable_reg;
   1812             addr = soc_reg_addr(unit, reg, block_port, 0);
   1813             SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_enable));
   1814             /* Exclude non-parity status bits */
   1815             group_status &= group_enable;
   1816             group_enable &= ~group_status;
   1817             SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable));
   1818             group_enable |= group_status;
   1819             SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable));
   1820         } /* loop through each block for the group */
   1821     } /* loop through each group */
   1822 
   1823     return SOC_E_NONE;
   1824 }
   1825 
   1826 
   1827 void
   1828 soc_enduro_parity_error(void *unit_vp, void *d1, void *d2,
   1829                          void *d3, void *d4)
   1830 {
   1831     int unit = PTR_TO_INT(unit_vp);
   1832 
   1833     _soc_enduro_process_parity_error(unit);
   1834     soc_intr_enable(unit, IRQ_MEM_FAIL);
   1835 }
   1836 
   1837 STATIC int
   1838 _soc_enduro_mem_nack_error_process(int unit, _enduro_ser_nack_reg_mem_t nack_reg_mem, 
   1839     soc_block_t block, int reg_mem)
   1840 {
   1841     int group, table;
   1842     _soc_parity_info_t *info;
   1843     soc_port_t block_port;
   1844     soc_block_t blk;
   1845     char *msg;
   1846 
   1847     if (nack_reg_mem.mem == INVALIDm) {
   1848         return SOC_E_PARAM;
   1849     }
   1850 
   1851     /* loop through each group */
   1852     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
   1853         info = _soc_en_parity_group_info[group].info;
   1854 
   1855         SOC_BLOCK_ITER(unit, blk,
   1856                        _soc_en_parity_group_info[group].blocktype) {
   1857             if (block != SOC_BLOCK_INFO(unit, blk).schan) {
   1858                 continue;
   1859             }
   1860             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
   1861                 continue;
   1862             }
   1863             /* loop through each table in the group */
   1864             for (table = 0; info[table].error_field != INVALIDf; table++) {
   1865                 if (info[table].mem != nack_reg_mem.mem) {
   1866                     continue;
   1867                 }
   1868                 if (info[table].nack_status0_reg == INVALIDr) {
   1869                     return SOC_E_NONE;
   1870                 }
   1871                 if (info[table].msg) {
   1872                     msg = info[table].msg;
   1873                 } else { /* mem must be valid to get her */
   1874                     msg = SOC_MEM_NAME(unit, info[table].mem);
   1875                 }
   1876 
   1877                 /* handle different parity error reporting style */
   1878                 switch (info[table].type) {
   1879                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1880                     SOC_IF_ERROR_RETURN
   1881                         (_soc_enduro_process_single_parity_error(unit,
   1882                               group, block_port, table, TRUE, msg, block));
   1883                     break;
   1884                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1885                     SOC_IF_ERROR_RETURN
   1886                         (_soc_enduro_process_single_ecc_error(unit,
   1887                               group, block_port, table, TRUE, msg, block));
   1888                     break;
   1889                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1890                     SOC_IF_ERROR_RETURN
   1891                         (_soc_enduro_process_dual_parity_error(unit,
   1892                               group, block_port, table, TRUE, msg, block));
   1893                     break;
   1894                 default:
   1895                     break;
   1896                 } /* handle different parity error reporting style */
   1897             } /* loop through each table in the group */
   1898         } /* loop through each block of the group */
   1899     } /* loop through each group */
   1900 
   1901     return SOC_E_NONE;
   1902 }
   1903 
   1904 void
   1905 soc_enduro_mem_nack(void *unit_vp, void *addr_vp, void *blk_vp, 
   1906                      void *d3, void *d4)
   1907 {
   1908     soc_mem_t mem = INVALIDm;
   1909     int reg_mem = PTR_TO_INT(d3);
   1910     int rv, unit = PTR_TO_INT(unit_vp);
   1911     uint32 address = PTR_TO_INT(addr_vp);
   1912     uint32 block = PTR_TO_INT(blk_vp);
   1913     uint32 offset = 0, min_addr = 0, max_addr = 0;
   1914     soc_regaddrinfo_t ainfo;
   1915     _enduro_ser_nack_reg_mem_t nack_reg_mem;
   1916     nack_reg_mem.mem = INVALIDm;
   1917     nack_reg_mem.reg = INVALIDr;
   1918 
   1919     if (reg_mem == _SOC_ENDURO_SER_REG) {
   1920         if (address) {
   1921             soc_regaddrinfo_get(unit, &ainfo, address);
   1922             nack_reg_mem.reg = ainfo.reg;
   1923         }
   1924     } else {
   1925         offset = address & ~0xC0f00000; /* Strip block ID */
   1926         mem = soc_addr_to_mem(unit, address, &block);
   1927         if (mem == INVALIDm) {
   1928             LOG_ERROR(BSL_LS_SOC_COMMON,
   1929                       (BSL_META_U(unit,
   1930                                   "unit %d mem decode failed, "
   1931                                   "SCHAN NACK analysis failure\n"), unit));
   1932             return;
   1933         }
   1934         
   1935         nack_reg_mem.mem = mem;
   1936 
   1937         min_addr = max_addr = SOC_MEM_INFO(unit, mem).base;
   1938         min_addr += SOC_MEM_INFO(unit, mem).index_min;
   1939         max_addr += SOC_MEM_INFO(unit, mem).index_max;
   1940     }
   1941 
   1942     if ((rv = _soc_enduro_mem_nack_error_process(unit, nack_reg_mem, (soc_block_t)block,
   1943         reg_mem)) < 0) {
   1944         if (reg_mem == _SOC_ENDURO_SER_REG) {
   1945             LOG_ERROR(BSL_LS_SOC_COMMON,
   1946                       (BSL_META_U(unit,
   1947                                   "unit %d REG SCHAN NACK analysis failure\n"),
   1948                        unit));
   1949         } else {
   1950             LOG_ERROR(BSL_LS_SOC_COMMON,
   1951                       (BSL_META_U(unit,
   1952                                   "unit %d %s entry %d SCHAN NACK analysis failure\n"),
   1953                        unit, SOC_MEM_NAME(unit, mem),
   1954                        min_addr - offset));
   1955         }
   1956     }
   1957     if (reg_mem == _SOC_ENDURO_SER_REG) {
   1958             LOG_ERROR(BSL_LS_SOC_COMMON,
   1959                       (BSL_META_U(unit,
   1960                                   "unit %d REG SCHAN NACK analysis\n"),
   1961                        unit));
   1962     } else {
   1963         LOG_INFO(BSL_LS_SOC_SCHAN,
   1964                  (BSL_META_U(unit,
   1965                              "unit %d %s entry %d SCHAN NACK analysis\n"),
   1966                   unit, SOC_MEM_NAME(unit, mem),
   1967                   min_addr - offset));
   1968     }
   1969 }
   1970 
   1971 STATIC int
   1972 _soc_enduro_mem_ecc_force(int unit, soc_port_t block_port,
   1973                             _soc_parity_info_t *info)
   1974 {
   1975     soc_reg_t force_sbe_reg, force_dbe_reg;
   1976     soc_field_t force_field;
   1977 
   1978     force_field = info->error_field;
   1979     if (force_field == RX_FIFO_MEM_ERRf) {
   1980         force_field = RX_FIFO_MEMf;
   1981     } else if (force_field == TX_FIFO_MEM_ERRf) {
   1982         force_field = TX_FIFO_MEMf;
   1983     }
   1984 
   1985     force_sbe_reg = info->intr_status1_reg;
   1986     force_dbe_reg = info->nack_status1_reg;
   1987 
   1988     /* Single-bit error force */
   1989     if (SOC_REG_IS_VALID(unit, force_sbe_reg) &&
   1990         soc_reg_field_valid(unit, force_sbe_reg, force_field)) {
   1991         SOC_IF_ERROR_RETURN
   1992             (soc_reg_field32_modify(unit, force_sbe_reg,
   1993                                     block_port, force_field, 1));        
   1994     } else {
   1995         LOG_ERROR(BSL_LS_SOC_COMMON,
   1996                   (BSL_META_U(unit,
   1997                               "unit %d %s.%s not valid\n"),
   1998                    unit, SOC_REG_NAME(unit, force_sbe_reg),
   1999                    SOC_FIELD_NAME(unit, force_field)));
   2000     }
   2001 
   2002     sal_usleep(1000); /* Wait for interrupt-mode logic to kick in */
   2003 
   2004     /* Double-bit error force */
   2005     if (SOC_REG_IS_VALID(unit, force_dbe_reg) &&
   2006         soc_reg_field_valid(unit, force_dbe_reg, force_field)) {
   2007         SOC_IF_ERROR_RETURN
   2008             (soc_reg_field32_modify(unit, force_dbe_reg,
   2009                                     block_port, force_field, 1));        
   2010     } else {
   2011         LOG_ERROR(BSL_LS_SOC_COMMON,
   2012                   (BSL_META_U(unit,
   2013                               "unit %d %s.%s not valid\n"),
   2014                    unit, SOC_REG_NAME(unit, force_dbe_reg),
   2015                    SOC_FIELD_NAME(unit, force_field)));
   2016     }
   2017 
   2018     return SOC_E_NONE;
   2019 }
   2020 
   2021 int
   2022 _soc_enduro_mem_nack_error_test(int unit)
   2023 {
   2024     int group, table, index, rv;
   2025     uint32 tmp_entry[SOC_MAX_MEM_WORDS];
   2026     uint32 parity;
   2027     _soc_parity_info_t *info;
   2028     soc_mem_t mem;
   2029     int	 index_min, index_max, index_range;
   2030     soc_port_t block_port;
   2031     soc_block_t blk;
   2032     soc_field_t par_ecc_field;
   2033     _enduro_ser_nack_reg_mem_t nack_reg_mem;
   2034 
   2035     /* loop through each group */
   2036     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
   2037         info = _soc_en_parity_group_info[group].info;
   2038 
   2039         SOC_BLOCK_ITER(unit, blk,
   2040                        _soc_en_parity_group_info[group].blocktype) {
   2041             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
   2042                 continue;
   2043             }
   2044 
   2045             for (table = 0; info[table].error_field != INVALIDf; table++) {
   2046                 mem = info[table].mem;
   2047                 if (mem == INVALIDm) {
   2048                     continue;
   2049                 }
   2050                 if ((info[table].control_reg == INVALIDr) ||
   2051                     !soc_reg_field_valid(unit, info[table].control_reg,
   2052                                          info[table].enable_field)) {
   2053                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2054                               (BSL_META_U(unit,
   2055                                           "unit %d %s has no parity toggle\n"),
   2056                                unit, SOC_MEM_NAME(unit, mem)));
   2057                     continue;
   2058                 }
   2059 
   2060                 index_min = soc_mem_index_min(unit, mem);
   2061                 index_max = soc_mem_index_max(unit, mem);
   2062                 index_range = index_max - index_min + 1;
   2063                 index = index_min + (index_range / 2);
   2064 
   2065                 if ((rv = soc_mem_write(unit, mem, blk, index,
   2066                                         soc_mem_entry_null(unit, mem))) < 0) {
   2067                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2068                               (BSL_META_U(unit,
   2069                                           "unit %d %s entry %d mem write error\n"),
   2070                                unit, SOC_MEM_NAME(unit, mem), index));
   2071                     continue;
   2072                 }
   2073             
   2074                 /* Disable parity */
   2075                 SOC_IF_ERROR_RETURN
   2076                     (soc_reg_field32_modify(unit, info[table].control_reg,
   2077                                             block_port, info[table].enable_field, 0));
   2078 
   2079                 if ((rv = soc_mem_read(unit, mem, blk, index, tmp_entry)) < 0) {
   2080                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2081                               (BSL_META_U(unit,
   2082                                           "unit %d %s entry %d mem read error\n"),
   2083                                unit, SOC_MEM_NAME(unit, mem), index));
   2084                     continue;
   2085                 }
   2086 
   2087                 switch (info[table].type) {
   2088                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   2089                 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER:
   2090                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   2091                     par_ecc_field = EVEN_PARITYf;
   2092                     if (mem == L3_ECMP_COUNTm) {
   2093                         par_ecc_field = EVEN_PARITY_0f;
   2094                     }
   2095                     break;
   2096                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   2097                     if (block_port != REG_PORT_ANY) {
   2098                         /* Force registers exist */
   2099                         SOC_IF_ERROR_RETURN
   2100                             (_soc_enduro_mem_ecc_force(unit, block_port,
   2101                                                          &(info[table])));
   2102                     }
   2103                     par_ecc_field = ECCf;
   2104                     break;
   2105                 default:
   2106                     /* coverity[assigned_value] */
   2107                     par_ecc_field = INVALIDf;
   2108                     continue;
   2109                 }
   2110 
   2111                 if (!soc_mem_field_valid(unit, mem, par_ecc_field)) {
   2112 #if !defined(SOC_NO_NAMES)
   2113                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2114                               (BSL_META_U(unit,
   2115                                           "unit %d %s doesn't contain %s\n"),
   2116                                unit, SOC_MEM_NAME(unit, mem),
   2117                                soc_fieldnames[par_ecc_field]));
   2118 #endif
   2119                     continue;
   2120                 }
   2121 
   2122                 parity =
   2123                     soc_mem_field32_get(unit, mem, tmp_entry, par_ecc_field);
   2124                 parity ^= 0x1; /* Bad parity */
   2125                 soc_mem_field32_set(unit, mem, tmp_entry, par_ecc_field, parity);
   2126             
   2127 
   2128                 if ((rv = soc_mem_write(unit, mem, blk, index, tmp_entry)) < 0) {
   2129                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2130                               (BSL_META_U(unit,
   2131                                           "unit %d %s entry %d mem write error\n"),
   2132                                unit, SOC_MEM_NAME(unit, mem), index));
   2133                     continue;
   2134                 }
   2135             
   2136                 /* Enable parity */
   2137                 SOC_IF_ERROR_RETURN
   2138                     (soc_reg_field32_modify(unit, info[table].control_reg,
   2139                                             block_port, info[table].enable_field, 1));
   2140 
   2141                 if ((rv = soc_mem_read(unit, mem, blk, index, tmp_entry)) < 0) {
   2142                     if (rv == SOC_E_FAIL) {
   2143                         LOG_ERROR(BSL_LS_SOC_COMMON,
   2144                                   (BSL_META_U(unit,
   2145                                               "unit %d NACK received for %s entry %d:\n\t"),
   2146                                    unit, SOC_MEM_NAME(unit, mem), index));
   2147                         nack_reg_mem.mem = mem;
   2148                         if ((rv = _soc_enduro_mem_nack_error_process(unit,
   2149                                                                        nack_reg_mem, blk, _SOC_ENDURO_SER_MEM)) < 0) {
   2150                             LOG_ERROR(BSL_LS_SOC_COMMON,
   2151                                       (BSL_META_U(unit,
   2152                                                   "unit %d %s entry %d SCHAN NACK analysis failure\n"),
   2153                                        unit, SOC_MEM_NAME(unit, mem), index));
   2154                         }
   2155                     } else {
   2156                         LOG_ERROR(BSL_LS_SOC_COMMON,
   2157                                   (BSL_META_U(unit,
   2158                                               "unit %d %s entry %d mem read error\n"),
   2159                                    unit, SOC_MEM_NAME(unit, mem), index));
   2160                     }
   2161                 } else {
   2162                     LOG_ERROR(BSL_LS_SOC_COMMON,
   2163                               (BSL_META_U(unit,
   2164                                           "unit %d %s entry %d mem parity induction failed\n"),
   2165                                unit, SOC_MEM_NAME(unit, mem), index));
   2166                 }
   2167                 sal_usleep(1000);
   2168             }
   2169         }
   2170     }
   2171 
   2172     return SOC_E_NONE;
   2173 }
   2174 
   2175 STATIC int
   2176 soc_enduro_pipe_mem_clear(int unit)
   2177 {
   2178     uint32              rval;
   2179     int                 pipe_init_usec;
   2180     soc_timeout_t       to;
   2181 
   2182     /*
   2183      * Reset the IPIPE and EPIPE block
   2184      */
   2185     rval = 0;
   2186     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   2187     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1);
   2188     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1);
   2189     /* Set count to # entries in largest IPIPE table, L2_ENTRYm */
   2190     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x8000);
   2191     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   2192 
   2193     rval = 0;
   2194     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   2195     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1);
   2196     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1);
   2197     /* Set count to # entries in largest EPIPE table, EGR_L3_NEXT_HOPm */
   2198     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, 0x4000);
   2199     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   2200 
   2201     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   2202     if (SAL_BOOT_SIMULATION) {
   2203         pipe_init_usec = 10000000;
   2204     } else {
   2205         pipe_init_usec = 50000;
   2206     }
   2207     soc_timeout_init(&to, pipe_init_usec, 0);
   2208 
   2209     /* Wait for IPIPE memory initialization done. */
   2210     do {
   2211         SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval));
   2212         if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) {
   2213             break;
   2214         }
   2215         if (soc_timeout_check(&to)) {
   2216             LOG_WARN(BSL_LS_SOC_COMMON,
   2217                      (BSL_META_U(unit,
   2218                                  "unit %d : ING_HW_RESET timeout\n"), unit));
   2219             break;
   2220         }
   2221     } while (TRUE);
   2222 
   2223     /* Wait for EPIPE memory initialization done. */
   2224     do {
   2225         SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval));
   2226         if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) {
   2227             break;
   2228         }
   2229         if (soc_timeout_check(&to)) {
   2230             LOG_WARN(BSL_LS_SOC_COMMON,
   2231                      (BSL_META_U(unit,
   2232                                  "unit %d : EGR_HW_RESET timeout\n"), unit));
   2233             break;
   2234         }
   2235     } while (TRUE);
   2236 
   2237     rval = 0;
   2238     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   2239     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   2240 
   2241     SOC_IF_ERROR_RETURN
   2242     (soc_mem_clear(unit, XQPORT_EHG_RX_TUNNEL_DATAm, COPYNO_ALL, TRUE));
   2243     SOC_IF_ERROR_RETURN
   2244     (soc_mem_clear(unit, XQPORT_EHG_RX_TUNNEL_MASKm, COPYNO_ALL, TRUE));
   2245     SOC_IF_ERROR_RETURN
   2246     (soc_mem_clear(unit, XQPORT_EHG_TX_TUNNEL_DATAm, COPYNO_ALL, TRUE));
   2247 
   2248     /* LMEP and LMEP_1 table is not properly handled by reset control */
   2249     SOC_IF_ERROR_RETURN(soc_mem_clear(unit, LMEPm, COPYNO_ALL, TRUE));
   2250     SOC_IF_ERROR_RETURN(soc_mem_clear(unit, LMEP_1m, COPYNO_ALL, TRUE));
   2251 
   2252     return SOC_E_NONE;
   2253 }
   2254 
   2255 /* SER processing for TCAMs */
   2256 STATIC _soc_ser_parity_info_t _soc_enduro_ser_parity_info[] = {
   2257     { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   2258       CMIC_SER_START_ADDR_0r, CMIC_SER_END_ADDR_0r,
   2259       CMIC_SER_MEM_ADDR_0r, CMIC_SER_PARITY_MODE_SELr,
   2260       RANGE_0_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ},
   2261     { EGR_ERSPANm, _SOC_SER_PARITY_MODE_2BITS,
   2262       CMIC_SER_START_ADDR_1r, CMIC_SER_END_ADDR_1r,
   2263       CMIC_SER_MEM_ADDR_1r, CMIC_SER_PARITY_MODE_SELr,
   2264       RANGE_1_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ},
   2265     { FP_SLICE_MAPm, _SOC_SER_PARITY_MODE_2BITS,
   2266       CMIC_SER_START_ADDR_2r, CMIC_SER_END_ADDR_2r,
   2267       CMIC_SER_MEM_ADDR_2r, CMIC_SER_PARITY_MODE_SELr,
   2268       RANGE_2_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ},
   2269     { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   2270       CMIC_SER_START_ADDR_3r, CMIC_SER_END_ADDR_3r,
   2271       CMIC_SER_MEM_ADDR_3r, CMIC_SER_PARITY_MODE_SELr,
   2272       RANGE_3_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ},
   2273     { MPLS_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   2274       CMIC_SER_START_ADDR_4r, CMIC_SER_END_ADDR_4r,
   2275       CMIC_SER_MEM_ADDR_4r, CMIC_SER_PARITY_MODE_SELr,
   2276       RANGE_4_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ},
   2277     { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   2278       CMIC_SER_START_ADDR_5r, CMIC_SER_END_ADDR_5r,
   2279       CMIC_SER_MEM_ADDR_5r, CMIC_SER_PARITY_MODE_SELr,
   2280       RANGE_5_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ},
   2281     { INVALIDm, _SOC_SER_PARITY_MODE_NUM},
   2282 };
   2283 
   2284 #define SOC_ENDURO_SER_MEM_AVAILABLE       (2048 * 32)  /* bits */
   2285 
   2286 STATIC int
   2287 _soc_enduro_ser_init(int unit)
   2288 {
   2289     return soc_ser_init(unit, _soc_enduro_ser_parity_info,
   2290             SOC_ENDURO_SER_MEM_AVAILABLE);
   2291 }
   2292 
   2293 void
   2294 soc_enduro_ser_fail(int unit)
   2295 
   2296 {
   2297     soc_process_ser_parity_error(unit, _soc_enduro_ser_parity_info,
   2298             SOC_SWITCH_EVENT_DATA_ERROR_PARITY);
   2299     return;
   2300 }
   2301 
   2302 uint32 tdm[84] = {2,10,18,26,27,28,29,
   2303                   3,11,19,26,27,28,29,
   2304                   4,12,20,26,27,28,29,
   2305                   5,13,21,26,27,28,29,
   2306                   6,14,22,26,27,28,29,
   2307                   7,15,23,26,27,28,29,
   2308                   8,16,24,26,27,28,29,
   2309                   9,17,25,26,27,28,29,
   2310                   1,30,30,26,27,28,29,
   2311                   1,30,30,26,27,28,29,
   2312                   1,30,30,26,27,28,29,
   2313                   0,30,30,26,27,28,29};
   2314 
   2315 uint32 tdm_56333_lp[56] = {2,10,1,30,30,30,30,
   2316                   3,11,1,30,30,30,30,
   2317                   4,12,30,30,30,30,30,
   2318                   5,13,30,30,30,30,30,
   2319                   6,14,0,30,30,30,30,
   2320                   7,15,30,30,30,30,30,
   2321                   8,16,30,30,30,30,30,
   2322                   9,17,30,30,30,30,30};
   2323 
   2324 uint32 tdm_56333_ge_linerate[84] = {2,10,18,26,27,28,29,
   2325                   3,11,19,26,27,28,29,
   2326                   4,12,20,26,27,28,29,
   2327                   5,13,21,26,27,28,29,
   2328                   6,14,22,26,27,28,29,
   2329                   7,15,23,30,30,0,30,
   2330                   8,16,24,30,30,0,1,
   2331                   9,17,25,30,30,30,1,
   2332                   30,30,30,30,30,30,30,
   2333                   30,30,30,30,30,30,30,
   2334                   30,30,30,30,30,30,30,
   2335                   30,30,30,30,30,0,30};
   2336 
   2337 int
   2338 soc_enduro_misc_init(int unit)
   2339 {
   2340 #define NUM_XQPORT 4
   2341     uint32              rval; 
   2342     uint32              prev_reg_addr;
   2343     uint64              reg64;
   2344     int                 port, i;
   2345     uint32              mode;
   2346     uint32              *arr;
   2347     int                 tdm_size;
   2348     iarb_tdm_table_entry_t iarb_tdm;
   2349     arb_tdm_table_entry_t arb_tdm;
   2350     uint64              multipass;
   2351     uint16              dev_id;
   2352     uint8               rev_id;
   2353     uint32              bm;
   2354     soc_field_t         fields[3];
   2355     uint32              values[3];
   2356     soc_pbmp_t          pbmp_ge_linerate;
   2357 
   2358     /* set the mode for XQPORT blocks */
   2359     PBMP_XQ_ITER(unit, port) {
   2360         mode = 1; /* gport-mode */
   2361         if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) {
   2362             soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE);
   2363             mode = 2;  /* xport-mode */
   2364         }
   2365         SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
   2366         soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, 
   2367                                    XQPORT_MODE_BITSf, mode);
   2368         SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval));
   2369     }
   2370 
   2371     SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval));
   2372     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 1);
   2373     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   2374 
   2375     /* Program for Different TDM mode */
   2376     soc_cm_get_id(unit, &dev_id, &rev_id);
   2377     if((dev_id == BCM56333_DEVICE_ID) || (dev_id == BCM56331_DEVICE_ID)){
   2378         SOC_PBMP_CLEAR(pbmp_ge_linerate);
   2379         pbmp_ge_linerate = soc_property_get_pbmp_default(unit, 
   2380                             spn_BCM56333_PBMP_GE_LINERATE, pbmp_ge_linerate);
   2381         if (SOC_PBMP_NOT_NULL(pbmp_ge_linerate)) {
   2382             /* Use config variable to decide which 12 ports out of 24 
   2383                get guarantee line rate  bandwidth on 56333 */
   2384             i = 0;
   2385             SOC_PBMP_ITER(pbmp_ge_linerate, port) {
   2386                 if ((i % 4) == 0) {
   2387                     tdm_56333_ge_linerate[56 + (i / 4)] = port;
   2388                 } else if ((i % 4) == 1) {
   2389                     tdm_56333_ge_linerate[63 + (i / 4)] = port;
   2390                 } else if ((i % 4) == 2) {
   2391                     tdm_56333_ge_linerate[70 + (i / 4)] = port;
   2392                 } else if ((i % 4) == 3) {
   2393                     tdm_56333_ge_linerate[77 + (i / 4)] = port;
   2394                 } 
   2395                 i++;
   2396                 if (i == 12) {
   2397                     break;
   2398                 }
   2399             }
   2400             tdm_size = 84;
   2401             arr = tdm_56333_ge_linerate;
   2402         } else {
   2403             if (dev_id == BCM56333_DEVICE_ID) {
   2404                 tdm_size = 56;
   2405                 arr = tdm_56333_lp;        	
   2406             } else {
   2407                 tdm_size = 84;
   2408                 arr = tdm;
   2409             }
   2410         }
   2411     } else if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) { 
   2412         tdm_size = 56;
   2413         arr = tdm_56333_lp;
   2414     } else {
   2415         tdm_size = 84;
   2416         arr = tdm;
   2417     }
   2418     for (i = 0; i < tdm_size; i++) {
   2419         sal_memset(&iarb_tdm, 0, sizeof(iarb_tdm_table_entry_t));
   2420         sal_memset(&arb_tdm, 0, sizeof(arb_tdm_table_entry_t));
   2421         soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 
   2422                                         arr[i]);
   2423         soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, 
   2424                                        arr[i]); 
   2425         /* Cache the CPU slot entry */
   2426         if (IS_CPU_PORT(unit, arr[i])) {
   2427             sal_memcpy(&(SOC_CONTROL(unit)->iarb_tdm), &iarb_tdm, 
   2428                        sizeof(iarb_tdm));
   2429             SOC_CONTROL(unit)->iarb_tdm_idx = i;
   2430         }
   2431         if (i == tdm_size - 1) {
   2432             soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, WRAP_ENf, 1);
   2433         }
   2434         SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 
   2435                                                   &iarb_tdm));
   2436         SOC_IF_ERROR_RETURN(WRITE_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 
   2437                                                  &arb_tdm));
   2438     }
   2439     rval = 0;
   2440     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0);
   2441     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, 
   2442                       tdm_size -1);
   2443     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   2444 
   2445     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   2446         /* Clear IPIPE/EIPIE Memories */
   2447         SOC_IF_ERROR_RETURN(soc_enduro_pipe_mem_clear(unit));
   2448     }
   2449 
   2450     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
   2451 
   2452     /* Turn on ingress/egress/mmu parity */
   2453     if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2454 #if defined(SER_TR_TEST_SUPPORT)
   2455         /*Initialize chip-specific functions for SER testing*/
   2456         memset(&ser_enduro_test_fun, 0, sizeof(soc_ser_test_functions_t));
   2457         ser_enduro_test_fun.inject_error_f = &soc_enduro_ser_inject_error;
   2458         ser_enduro_test_fun.injection_support = &soc_enduro_ser_error_injection_support;
   2459         soc_ser_test_functions_register(unit, &ser_enduro_test_fun);
   2460 #endif /*defined(SER_TR_TEST_SUPPORT*/
   2461         _soc_enduro_parity_enable(unit, TRUE);
   2462         if (soc_feature(unit, soc_feature_ser_parity)) {
   2463             SOC_IF_ERROR_RETURN(_soc_enduro_ser_init(unit));
   2464 #ifdef INCLUDE_MEM_SCAN
   2465             soc_mem_scan_ser_list_register(unit, FALSE,
   2466                                            _soc_enduro_ser_parity_info);
   2467 #endif /* INCLUDE_MEM_SCAN */
   2468         }
   2469 
   2470         sal_memset(&_enduro_ser_functions, 0, sizeof(soc_ser_functions_t));
   2471         _enduro_ser_functions._soc_ser_fail_f = &soc_enduro_ser_fail;
   2472         _enduro_ser_functions._soc_ser_parity_error_intr_f = &soc_enduro_parity_error;
   2473         _enduro_ser_functions._soc_ser_mem_nack_f = &soc_enduro_mem_nack;
   2474         soc_ser_function_register(unit, &_enduro_ser_functions);
   2475     }
   2476 
   2477     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2478     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   2479     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2480 
   2481     /* Enable dual hash on L2, L3 and MPLS_ENTRY tables */
   2482     fields[0] = ENABLEf;
   2483     values[0] = 1;
   2484     fields[1] = HASH_SELECTf;
   2485     values[1] = FB_HASH_CRC32_LOWER;
   2486     fields[2] = INSERT_LEAST_FULL_HALFf;
   2487     values[2] = 1;
   2488     SOC_IF_ERROR_RETURN
   2489         (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   2490                                  fields, values));
   2491     SOC_IF_ERROR_RETURN
   2492         (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   2493                                  fields, values));
   2494     SOC_IF_ERROR_RETURN
   2495         (soc_reg_field32_modify(unit, MPLS_ENTRY_HASH_CONTROLr, REG_PORT_ANY,
   2496                                 INSERT_LEAST_FULL_HALFf, 1));
   2497 
   2498     /*
   2499      * Egress Enable
   2500      */
   2501     rval= 0;
   2502     soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1);
   2503     PBMP_ALL_ITER(unit, port) {
   2504         SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval));
   2505     }
   2506 
   2507     COMPILER_64_ZERO(reg64);
   2508     soc_reg64_field32_set(unit, EPC_LINK_BMAP_64r, &reg64, PORT_BITMAP_LOf,
   2509                           SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 0));
   2510     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAP_64r(unit, reg64));
   2511 
   2512     /* GMAC init should be moved to mac */
   2513     rval = 0;
   2514     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1);
   2515     prev_reg_addr = 0xffffffff;
   2516     PBMP_E_ITER(unit, port) {
   2517         uint32  reg_addr;
   2518         if (IS_XQ_PORT(unit, port)) {
   2519             continue;
   2520         }
   2521         reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0);
   2522         if (reg_addr != prev_reg_addr) {
   2523             SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2524             prev_reg_addr = reg_addr;
   2525         }
   2526     }
   2527     prev_reg_addr = 0xffffffff;
   2528     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0);
   2529     PBMP_E_ITER(unit, port) {
   2530         uint32  reg_addr;
   2531         if (IS_XQ_PORT(unit, port)) {
   2532             continue;
   2533         }
   2534         reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0);
   2535         if (reg_addr != prev_reg_addr) {
   2536             SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2537             prev_reg_addr = reg_addr;
   2538         }
   2539     }
   2540 
   2541     /* XMAC init should be moved to mac */
   2542     if (SOC_PBMP_NOT_NULL(PBMP_XE_ALL(unit)) ||
   2543         SOC_PBMP_NOT_NULL(PBMP_HG_ALL(unit))) {
   2544         rval = 0;
   2545         soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1);
   2546         soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
   2547         PBMP_HG_ITER(unit, port) {
   2548             SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval));
   2549         }
   2550         soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0);
   2551         PBMP_XE_ITER(unit, port) {
   2552             SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval));
   2553         }
   2554     }
   2555 
   2556     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &reg64));
   2557     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2558                           L3SRC_HIT_ENABLEf, 1);
   2559     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2560                           L2DST_HIT_ENABLEf, 1);
   2561     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2562                           APPLY_EGR_MASK_ON_L2f, 1);
   2563     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2564                           APPLY_EGR_MASK_ON_L3f, 1);
   2565     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2566                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
   2567     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2568                           ARP_VALIDATION_ENf, 1);
   2569     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2570                           IGNORE_HG_HDR_LAG_FAILOVERf, 1);
   2571     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64));
   2572 
   2573     /* Backwards compatible mirroring by default */
   2574     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2575     soc_reg_field_set(unit, MISCCONFIGr, &rval, 
   2576                       DRACO_1_5_MIRRORING_MODE_ENf, 1);
   2577     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2578 
   2579     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &reg64));
   2580     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2581                           DRACO1_5_MIRRORf, 1);
   2582     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64));
   2583 
   2584     SOC_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, &rval));
   2585     soc_reg_field_set(unit, EGR_CONFIGr, &rval, DRACO1_5_MIRRORf, 1);
   2586     SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIGr(unit, rval));
   2587 
   2588 
   2589     SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval));
   2590     soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, RING_MODEf, 1);
   2591     SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval));
   2592 
   2593     /*
   2594      * Set reference clock (based on 200MHz core clock)
   2595      * to be 200MHz * (1/40) = 5MHz
   2596      */
   2597     rval = 0;
   2598     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, 40);
   2599     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, 1);
   2600     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval));
   2601 
   2602     /* Match the Internal MDC freq with above for External MDC */
   2603     rval = 0;
   2604     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 40);
   2605     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 1);
   2606     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval));
   2607 
   2608     /*
   2609      * Set reference clock (based on 200MHz core clock)
   2610      * to be 200MHz * (1/8) = 25MHz
   2611      */
   2612     rval = 0;
   2613     soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVISORf,  8);
   2614     soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVIDENDf, 1);
   2615     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval));
   2616 
   2617     rval = 0;
   2618     soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVISORf,  8);
   2619     soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVIDENDf, 1);
   2620     /* coverity[result_independent_of_operands] */
   2621     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval));
   2622 
   2623     rval = 0x01; /* 125KHz I2C sampling rate based on 5Mhz reference clock */
   2624     SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval));
   2625 
   2626     /* GMAC init should be moved to mac */
   2627     rval = 0;
   2628     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1);
   2629     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, GPORT_ENf, 1);
   2630     PBMP_E_ITER(unit, port) {
   2631         if (IS_XQ_PORT(unit, port)) {
   2632             continue;
   2633         }
   2634         SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2635     }
   2636     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0);
   2637     PBMP_E_ITER(unit, port) {
   2638         if (IS_XQ_PORT(unit, port)) {
   2639             continue;
   2640         }
   2641         SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2642     }
   2643 
   2644     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
   2645      * causes the outer tag to be removed from packets that don't have
   2646      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
   2647      */
   2648     rval = 0;
   2649     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
   2650 
   2651     /* Enable pri/cfi remarking on egress ports. */
   2652     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,
   2653                       1);
   2654     PBMP_ALL_ITER(unit, port) {
   2655         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval));
   2656     }
   2657 
   2658     /* Multicast range initialization */
   2659     SOC_IF_ERROR_RETURN
   2660         (soc_hbx_higig2_mcast_sizes_set(unit,
   2661              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
   2662                               SOC_EN_BROADCAST_RANGE_DEFAULT),
   2663              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
   2664                               SOC_EN_L2_MULTICAST_RANGE_DEFAULT),
   2665              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
   2666                               SOC_EN_IP_MULTICAST_RANGE_DEFAULT)));
   2667 
   2668     /* Enable vrf based l3 lookup by default. */
   2669     SOC_IF_ERROR_RETURN
   2670         (soc_reg_field32_modify(unit, VRF_MASKr, REG_PORT_ANY, MASKf, 0));
   2671 
   2672     /* Setup SW2_FP_DST_ACTION_CONTROL */
   2673     fields[0] = HGTRUNK_RES_ENf;
   2674     fields[1] = LAG_RES_ENf;
   2675     values[0] = values[1] = 1;
   2676     SOC_IF_ERROR_RETURN
   2677         (soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr,
   2678                                  REG_PORT_ANY, 2, fields, values));
   2679 
   2680     /* Initialize the multipass loopback bitmap to the loopback port */
   2681     COMPILER_64_ZERO(multipass);
   2682     bm=0x0;
   2683     PBMP_ALL_ITER(unit, port) {
   2684         if (IS_LB_PORT(unit, port)) {
   2685                 bm = bm | (1 << port); 
   2686         }
   2687     }
   2688     soc_reg64_field32_set(unit, MULTIPASS_LOOPBACK_BITMAP_64r, &multipass, 
   2689                         BITMAPf, bm);
   2690     SOC_IF_ERROR_RETURN(WRITE_MULTIPASS_LOOPBACK_BITMAP_64r(unit, multipass));
   2691 
   2692     /* Apply delay so LEDUP can capture correct status. */
   2693     /* coverity[result_independent_of_operands] */
   2694     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP_CTRLr(unit, &rval));
   2695     soc_reg_field_set(unit,CMIC_LEDUP_CTRLr,
   2696                      &rval, LEDUP_SCAN_START_DELAYf, 0x5);
   2697     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP_CTRLr(unit, rval));
   2698 
   2699     /* Enable shaping mode. */
   2700     if (soc_reg_field_valid(unit, EGR_Q_BEGINr, DWRR_OR_SHAPINGf)) {
   2701         SOC_IF_ERROR_RETURN(READ_EGR_Q_BEGINr(unit, &rval));
   2702         soc_reg_field_set(unit,EGR_Q_BEGINr, &rval, DWRR_OR_SHAPINGf, 0x1);
   2703         SOC_IF_ERROR_RETURN(WRITE_EGR_Q_BEGINr(unit, rval));
   2704     }
   2705 
   2706     /* Cache LMEP/LMEP_1 table */
   2707     SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, LMEPm, MEM_BLOCK_ALL, TRUE));
   2708     SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, LMEP_1m, MEM_BLOCK_ALL, TRUE));
   2709 
   2710     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
   2711     return SOC_E_NONE;
   2712 }
   2713 
   2714 #define TR_MMU_NUM_PG   8
   2715 #define TR_MMU_NUM_COS  8
   2716 
   2717 /* Standard Ethernet MTU, 1536 bytes (1 cell = 128 bytes) */
   2718 #define TR_MMU_ETH_FRAME_CELLS  12
   2719 
   2720 /* Jumbo Frame MTU, 9216 (1 cell = 128 bytes) */
   2721 #define TR_MMU_JUMBO_FRAME_CELLS  72
   2722 
   2723 /* MAX Frame MTU, 16384 (1 cell = 128 bytes) */
   2724 #define TR_MMU_MAX_FRAME_CELLS  128
   2725 
   2726 #define EN_MMU_IN_PG_MIN_CELLS      12
   2727 #define EN_MMU_IN_PG_MIN_PACKETS      12
   2728 
   2729 #define TR_MMU_IN_PORT_MIN_CELLS       72
   2730 #define TR_MMU_IN_PORT_MIN_PKTS        1
   2731 #define DAGGER_MMU_IN_PORT_MIN_PKTS    72
   2732 #define TR_MMU_PG_HDRM_LIMIT_CELLS     36
   2733 #define TR_MMU_PG_HDRM_LIMIT_PKTS      36
   2734 #define TR_MMU_PG_RESET_OFFSET_CELLS   24
   2735 #define TR_MMU_PG_RESET_OFFSET_PKTS    1
   2736 
   2737 #define TR_MMU_OUT_PORT_MIN_CELLS      12
   2738 #define TR_MMU_OUT_PORT_MIN_PKTS       1
   2739 #define DAGGER_MMU_OUT_PORT_MIN_PKTS   4
   2740 #define TR_MMU_OUT_RESET_OFFSET_CELLS  24
   2741 #define TR_MMU_OUT_RESET_OFFSET_PKTS   2
   2742 #define TR_MMU_SOP_POLICY              0
   2743 #define TR_MMU_MOP_POLICY              7
   2744 int
   2745 soc_enduro_mmu_init(int unit)
   2746 {
   2747     uint16              dev_id;
   2748     uint8               rev_id;
   2749     uint32              rval, tm;    
   2750     uint32              rval0, rval1, cell_rval, pkt_rval;
   2751     int                 port;
   2752     int                 total_cells, total_pkts;
   2753     int                 in_reserved_cells, in_reserved_pkts;
   2754     int                 out_reserved_cells, out_reserved_pkts;
   2755     int                 out_shared_cells, out_shared_pkts;
   2756     int                 idx, count;
   2757     soc_pbmp_t          pbmp_8pg;
   2758 
   2759     soc_cm_get_id(unit, &dev_id, &rev_id);
   2760 
   2761     /* Total number of cells */
   2762     if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) {
   2763         total_cells = 8 * 1024; /* 8K cells */
   2764     } else {
   2765         total_cells = 16 * 1024; /* 16K cells */
   2766     }
   2767 
   2768     /* Total number of packet pointers */
   2769     total_pkts = 6 * 1024; /* 6K packet pointers */
   2770 
   2771     /* Ports with 8PG (1PG for other ports) */
   2772     SOC_PBMP_CLEAR(pbmp_8pg);
   2773     SOC_PBMP_WORD_SET(pbmp_8pg, 0, 0x3c000000); /* 26-29 */
   2774     SOC_PBMP_AND(pbmp_8pg, PBMP_ALL(unit));
   2775 
   2776     /*
   2777      * Reserved space calculation:
   2778      *   Input port:
   2779      *     per-port minimum
   2780      *     per-PG minimum (config to 0)
   2781      *     per-PG headroom
   2782      *     per-device headroom
   2783      *     per-port minimum for SC and QM traffic (config to 0)
   2784      *   Output port:
   2785      *     per-port per-COS minimum space
   2786      * Shared space calculation:
   2787      *   Input port: total - input port reserved - output port reserved
   2788      *   Output port: total - output port reserved
   2789      */
   2790     in_reserved_cells = (NUM_PORT(unit) + 1) * TR_MMU_IN_PORT_MIN_CELLS +
   2791         NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_CELLS +
   2792         (NUM_PORT(unit) + 1) * TR_MMU_ETH_FRAME_CELLS;
   2793     out_reserved_cells =
   2794         (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) *
   2795         TR_MMU_OUT_PORT_MIN_CELLS;
   2796     if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) {
   2797         in_reserved_pkts = (NUM_PORT(unit) + 1) * DAGGER_MMU_IN_PORT_MIN_PKTS +
   2798             NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_PKTS;
   2799         out_reserved_pkts =
   2800             (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) *
   2801             DAGGER_MMU_OUT_PORT_MIN_PKTS;
   2802     } else {
   2803         in_reserved_pkts = (NUM_PORT(unit) + 1) * TR_MMU_IN_PORT_MIN_PKTS +
   2804             NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_PKTS;
   2805         out_reserved_pkts =
   2806             (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) *
   2807             TR_MMU_OUT_PORT_MIN_PKTS;
   2808     }
   2809 
   2810     /*
   2811      * Input PGs threshold
   2812      */
   2813     cell_rval = 0;
   2814     soc_reg_field_set(unit, PG_MIN_CELLr, &cell_rval, PG_MINf,
   2815                       EN_MMU_IN_PG_MIN_CELLS);
   2816     pkt_rval = 0;
   2817     soc_reg_field_set(unit, PG_MIN_PACKETr, &pkt_rval, PG_MINf,
   2818                       EN_MMU_IN_PG_MIN_PACKETS);
   2819     PBMP_PORT_ITER(unit, port) {
   2820         idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0;
   2821         SOC_IF_ERROR_RETURN(WRITE_PG_MIN_CELLr(unit, port, idx,
   2822                                                       cell_rval));
   2823         SOC_IF_ERROR_RETURN(WRITE_PG_MIN_PACKETr(unit, port, idx,
   2824                                                         pkt_rval));
   2825     }
   2826 
   2827     /*
   2828      * Input ports threshold
   2829      */
   2830     /* Reserved space: Input port per-port minimum */
   2831     cell_rval = 0;
   2832     soc_reg_field_set(unit, PORT_MIN_CELLr, &cell_rval, PORT_MINf,
   2833                       TR_MMU_IN_PORT_MIN_CELLS);
   2834     pkt_rval = 0;
   2835     if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) {
   2836         soc_reg_field_set(unit, PORT_MIN_PACKETr, &pkt_rval, PORT_MINf,
   2837                           DAGGER_MMU_IN_PORT_MIN_PKTS);
   2838     } else {
   2839         soc_reg_field_set(unit, PORT_MIN_PACKETr, &pkt_rval, PORT_MINf,
   2840                           TR_MMU_IN_PORT_MIN_PKTS);
   2841     }
   2842     PBMP_ALL_ITER(unit, port) {
   2843         SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_CELLr(unit, port, cell_rval));
   2844         SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_PACKETr(unit, port, pkt_rval));
   2845     }
   2846 
   2847     /* Reserved space: Input port per-PG minimum
   2848      * Use defalt value 0
   2849      * With only one PG in use PORT_MIN should be sufficient */
   2850 
   2851     /* Reserved space: Input port per-PG headroom
   2852      * Use only 1PG (highest priority PG for the port) */
   2853     cell_rval = 0;
   2854     soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &cell_rval, PG_HDRM_LIMITf,
   2855                       TR_MMU_PG_HDRM_LIMIT_CELLS);
   2856     soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &cell_rval, PG_GEf, 1);
   2857     pkt_rval = 0;
   2858     soc_reg_field_set(unit, PG_HDRM_LIMIT_PACKETr, &pkt_rval, PG_HDRM_LIMITf,
   2859                       TR_MMU_PG_HDRM_LIMIT_PKTS);
   2860     PBMP_PORT_ITER(unit, port) {
   2861         idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0;
   2862         SOC_IF_ERROR_RETURN(WRITE_PG_HDRM_LIMIT_CELLr(unit, port, idx,
   2863                                                       cell_rval));
   2864         SOC_IF_ERROR_RETURN(WRITE_PG_HDRM_LIMIT_PACKETr(unit, port, idx,
   2865                                                         pkt_rval));
   2866     }
   2867 
   2868     /* Reserved space: Input port per-device headroom */
   2869     cell_rval = 0;
   2870     soc_reg_field_set(unit, GLOBAL_HDRM_LIMITr, &cell_rval, 
   2871                   GLOBAL_HDRM_LIMITf, 
   2872                   (NUM_PORT(unit) + 1) * TR_MMU_ETH_FRAME_CELLS);
   2873     SOC_IF_ERROR_RETURN(WRITE_GLOBAL_HDRM_LIMITr(unit, cell_rval));
   2874 
   2875     /* Input port shared space */
   2876     cell_rval = 0;
   2877     soc_reg_field_set(unit, TOTAL_SHARED_LIMIT_CELLr, &cell_rval,
   2878                       TOTAL_SHARED_LIMITf,
   2879                       total_cells - in_reserved_cells - out_reserved_cells);
   2880     SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMIT_CELLr(unit, cell_rval));
   2881     pkt_rval = 0;
   2882     soc_reg_field_set(unit, TOTAL_SHARED_LIMIT_PACKETr, &pkt_rval,
   2883                       TOTAL_SHARED_LIMITf,
   2884                       total_pkts - in_reserved_pkts - out_reserved_pkts);
   2885     SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMIT_PACKETr(unit, pkt_rval));
   2886 
   2887     /* Input port per-port shared space limit - no limit */
   2888     cell_rval = 0;
   2889     soc_reg_field_set(unit, PORT_SHARED_LIMIT_CELLr, &cell_rval,
   2890                       PORT_SHARED_LIMITf, total_cells - 1);
   2891     pkt_rval = 0;
   2892     soc_reg_field_set(unit, PORT_SHARED_LIMIT_PACKETr, &pkt_rval,
   2893                       PORT_SHARED_LIMITf, total_pkts - 1);
   2894     PBMP_ALL_ITER(unit, port) {
   2895         SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMIT_CELLr(unit, port,
   2896                                                           cell_rval));
   2897         SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMIT_PACKETr(unit, port,
   2898                                                             pkt_rval));
   2899     }
   2900 
   2901     /* Input port per-PG reset offset
   2902      * Use only 1PG (highest priority PG for the port)
   2903      * Use default value 0 for CPU */
   2904     cell_rval = 0;
   2905     soc_reg_field_set(unit, PG_RESET_OFFSET_CELLr, &cell_rval,
   2906                       PG_RESET_OFFSETf, TR_MMU_PG_RESET_OFFSET_CELLS);
   2907     pkt_rval = 0;
   2908     soc_reg_field_set(unit, PG_RESET_OFFSET_PACKETr, &pkt_rval,
   2909                       PG_RESET_OFFSETf, TR_MMU_PG_RESET_OFFSET_PKTS);
   2910     PBMP_PORT_ITER(unit, port) {
   2911         idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0;
   2912         SOC_IF_ERROR_RETURN(WRITE_PG_RESET_OFFSET_CELLr(unit, port, idx,
   2913                                                         cell_rval));
   2914         SOC_IF_ERROR_RETURN(WRITE_PG_RESET_OFFSET_PACKETr(unit, port, idx,
   2915                                                           pkt_rval));
   2916     }
   2917 
   2918     /* Input port per-PG reset floor (cell). Use default value 0 */
   2919 
   2920     /* Reserved space: Input port per-port minimum for SC and QM traffic
   2921      * Use default value 0 */
   2922 
   2923     /* Input port priority XON disable */
   2924 
   2925     /* Input port max packet size in cells */
   2926     rval0 = 0;
   2927     soc_reg_field_set(unit, PORT_MAX_PKT_SIZEr, &rval0, PORT_MAX_PKT_SIZEf,
   2928                       TR_MMU_JUMBO_FRAME_CELLS);
   2929     PBMP_ALL_ITER(unit, port) {
   2930         SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_PKT_SIZEr(unit, port, rval0));
   2931     }
   2932 
   2933     /* Input port per-PG threshold */
   2934     rval0 = 0;
   2935     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG0_THRESH_SELf, 0x8);
   2936     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG1_THRESH_SELf, 0x8);
   2937     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG2_THRESH_SELf, 0x8);
   2938     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG3_THRESH_SELf, 0x8);
   2939     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG4_THRESH_SELf, 0x8);
   2940     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG5_THRESH_SELf, 0x8);
   2941     soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG6_THRESH_SELf, 0x8);
   2942     PBMP_ITER(pbmp_8pg, port) {
   2943         SOC_IF_ERROR_RETURN(WRITE_PG_THRESH_SELr(unit, port, rval0));
   2944     }
   2945 
   2946     idx = TR_MMU_NUM_PG - 1;
   2947     rval0 = 0;
   2948     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI0_GRPf, idx);
   2949     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI1_GRPf, idx);
   2950     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI2_GRPf, idx);
   2951     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI3_GRPf, idx);
   2952     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI4_GRPf, idx);
   2953     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI5_GRPf, idx);
   2954     soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI6_GRPf, idx);
   2955     rval1 = 0;
   2956     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI7_GRPf, idx);
   2957     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI8_GRPf, idx);
   2958     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI9_GRPf, idx);
   2959     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI10_GRPf, idx);
   2960     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI11_GRPf, idx);
   2961     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI12_GRPf, idx);
   2962     soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI13_GRPf, idx);
   2963     PBMP_ITER(pbmp_8pg, port) {
   2964         SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP0r(unit, port, rval0));
   2965         SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP1r(unit, port, rval1));
   2966     }
   2967     
   2968     /*
   2969      * Output ports threshold
   2970      */
   2971     /* Reserved space: Output port per-port per-COS minimum space */
   2972     cell_rval = 0;
   2973     soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, Q_MIN_CELLf,
   2974                       TR_MMU_OUT_PORT_MIN_CELLS);
   2975     soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval,
   2976                       Q_LIMIT_ENABLE_CELLf, 0x1);
   2977     soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval,
   2978                       Q_LIMIT_DYNAMIC_CELLf, 0x1);
   2979     soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval,
   2980                       Q_SHARED_LIMIT_CELLf, 2); /* alpha index 2 */
   2981     pkt_rval = 0;
   2982     if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) {
   2983         soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 
   2984                           Q_MIN_PACKETf, DAGGER_MMU_OUT_PORT_MIN_PKTS);
   2985     } else {
   2986         soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 
   2987                           Q_MIN_PACKETf, TR_MMU_OUT_PORT_MIN_PKTS);
   2988     }
   2989     soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval,
   2990                       Q_LIMIT_ENABLE_PACKETf, 0x1);
   2991     soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval,
   2992                       Q_LIMIT_DYNAMIC_PACKETf, 0x1);
   2993     soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval,
   2994                       Q_SHARED_LIMIT_PACKETf, 2); /* alpha index 2 */
   2995     PBMP_ALL_ITER(unit, port) {
   2996         count = IS_CPU_PORT(unit, port) ?
   2997             SOC_INFO(unit).num_cpu_cosq : TR_MMU_NUM_COS;
   2998         for (idx = 0; idx < count; idx++) {
   2999             SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIG_CELLr(unit, port, idx,
   3000                                                             cell_rval));
   3001             SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIG_PACKETr(unit, port, idx,
   3002                                                               pkt_rval));
   3003         }
   3004     }
   3005 
   3006     /* Output port per-port per-COS reset offset */
   3007     cell_rval = 0;
   3008     soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_CELLr, &cell_rval,
   3009                       Q_RESET_OFFSET_CELLf, TR_MMU_OUT_RESET_OFFSET_CELLS);
   3010     pkt_rval = 0;
   3011     soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_PACKETr, &pkt_rval,
   3012                       Q_RESET_OFFSET_PACKETf, TR_MMU_OUT_RESET_OFFSET_PKTS);
   3013     PBMP_ALL_ITER(unit, port) {
   3014         count = IS_CPU_PORT(unit, port) ?
   3015             SOC_INFO(unit).num_cpu_cosq : TR_MMU_NUM_COS;
   3016         for (idx = 0; idx < count; idx++) {
   3017             SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_RESET_OFFSET_CELLr(unit, port,
   3018                                                                   idx,
   3019                                                                   cell_rval));
   3020             SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_RESET_OFFSET_PACKETr(unit, port,
   3021                                                                     idx,
   3022                                                                     pkt_rval));
   3023         }
   3024     }
   3025 
   3026     out_shared_cells = total_cells - out_reserved_cells;
   3027     out_shared_pkts = total_pkts - out_reserved_pkts;
   3028 
   3029     /* Output port per-device shared */
   3030     cell_rval = 0;
   3031     soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, &cell_rval,
   3032                       OP_BUFFER_SHARED_LIMIT_CELLf, out_shared_cells);
   3033     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_CELLr(unit, cell_rval));
   3034     pkt_rval = 0;
   3035     soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_PACKETr, &pkt_rval,
   3036                       OP_BUFFER_SHARED_LIMIT_PACKETf, out_shared_pkts);
   3037     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_PACKETr(unit, pkt_rval));
   3038 
   3039     /* Output port per-device shared for YELLOW traffic */
   3040     cell_rval = 0;
   3041     soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, &cell_rval,
   3042                       OP_BUFFER_LIMIT_YELLOW_CELLf, out_shared_cells >> 3);
   3043     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_YELLOW_CELLr(unit, cell_rval));
   3044     pkt_rval = 0;
   3045     soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_PACKETr, &pkt_rval,
   3046                       OP_BUFFER_LIMIT_YELLOW_PACKETf, out_shared_pkts >> 2);
   3047     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_YELLOW_PACKETr(unit, pkt_rval));
   3048 
   3049     /* Output port per-device shared for RED traffic */
   3050     cell_rval = 0;
   3051     soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_CELLr, &cell_rval,
   3052                       OP_BUFFER_LIMIT_RED_CELLf, out_shared_cells >> 3);
   3053     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_RED_CELLr(unit, cell_rval));
   3054     pkt_rval = 0;
   3055     soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_PACKETr, &pkt_rval,
   3056                       OP_BUFFER_LIMIT_RED_PACKETf, out_shared_pkts >> 2);
   3057     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_RED_PACKETr(unit, pkt_rval));
   3058 
   3059     /* Output port per-device shared  */
   3060     cell_rval = 0;
   3061     soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_CELLr, &cell_rval,
   3062                       OP_BUFFER_SHARED_LIMIT_RESUME_CELLf, out_shared_cells * 85 / 100);
   3063     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_RESUME_CELLr(unit, cell_rval));
   3064     pkt_rval = 0;
   3065     soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_PACKETr, &pkt_rval,
   3066                       OP_BUFFER_SHARED_LIMIT_RESUME_PACKETf, out_shared_pkts * 85 / 100);
   3067     SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_RESUME_PACKETr(unit, pkt_rval));
   3068 
   3069     /*
   3070      * Output port per-port shared
   3071      * Limit check disabled, however still keep code as reference
   3072      * OP_SHARED_LIMIT set to 3/4 of total shared space
   3073      * OP_SHARED_RESET_VALUE set to 1/2 of total shared space
   3074      */
   3075     cell_rval = 0;
   3076     soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval,
   3077                       OP_SHARED_LIMIT_CELLf, out_shared_cells * 3 / 4);
   3078     soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval,
   3079                       OP_SHARED_RESET_VALUE_CELLf, out_shared_cells / 2);
   3080     soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval,
   3081                       PORT_LIMIT_ENABLE_CELLf, 0);
   3082     pkt_rval = 0;
   3083     soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval,
   3084                       OP_SHARED_LIMIT_PACKETf, out_shared_pkts * 3 / 4);
   3085     soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval,
   3086                       OP_SHARED_RESET_VALUE_PACKETf, out_shared_pkts / 2);
   3087     soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval,
   3088                       PORT_LIMIT_ENABLE_PACKETf, 0);
   3089     PBMP_ALL_ITER(unit, port) {
   3090         SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIG_CELLr(unit, port, cell_rval));
   3091         SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIG_PACKETr(unit, port,
   3092                                                          pkt_rval));
   3093     }
   3094 
   3095     /* Output port per-port shared for YELLOW traffic */
   3096     cell_rval = 0;
   3097     soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOW_CELLr, &cell_rval,
   3098                       OP_PORT_LIMIT_YELLOW_CELLf,
   3099                       (out_shared_cells * 3 / 4) >> 3);
   3100     pkt_rval = 0;
   3101     soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOW_PACKETr, &pkt_rval,
   3102                       OP_PORT_LIMIT_YELLOW_PACKETf,
   3103                       (out_shared_pkts * 3 / 4) >> 2);
   3104     PBMP_ALL_ITER(unit, port) {
   3105         SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_YELLOW_CELLr(unit, port,
   3106                                                              cell_rval));
   3107         SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_YELLOW_PACKETr(unit, port,
   3108                                                                pkt_rval));
   3109     }
   3110 
   3111     /* Output port per-port shared for RED traffic */
   3112     cell_rval = 0;
   3113     soc_reg_field_set(unit, OP_PORT_LIMIT_RED_CELLr, &cell_rval,
   3114                       OP_PORT_LIMIT_RED_CELLf,
   3115                       (out_shared_cells * 3 / 4) >> 3);
   3116     pkt_rval = 0;
   3117     soc_reg_field_set(unit, OP_PORT_LIMIT_RED_PACKETr, &pkt_rval,
   3118                       OP_PORT_LIMIT_RED_PACKETf,
   3119                       (out_shared_pkts * 3 / 4) >> 2);
   3120     PBMP_ALL_ITER(unit, port) {
   3121         SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_RED_CELLr(unit, port,
   3122                                                           cell_rval));
   3123         SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_RED_PACKETr(unit, port,
   3124                                                             pkt_rval));
   3125     }
   3126 
   3127     /* Output port configuration */
   3128     rval0 = 0;
   3129     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0,
   3130                       MOP_POLICYf, TR_MMU_MOP_POLICY);
   3131     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0,
   3132                       SOP_POLICYf, TR_MMU_SOP_POLICY);
   3133     SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval0));
   3134 
   3135     /* Apply TM setting on MMU_CELLLINK */
   3136     rval = 0x20;
   3137     SOC_IF_ERROR_RETURN(WRITE_CELLLINKMEMDEBUGr(unit, rval));
   3138 
   3139     /* Apply TM=0x10 setting for all CAMs */
   3140     rval = 0;
   3141     tm=0x10;
   3142     soc_reg_field_set(unit, SW2_RAM_CONTROL_4r, &rval,
   3143                       CPU_COS_MAP_TCAM_TMf, tm);
   3144     SOC_IF_ERROR_RETURN(WRITE_SW2_RAM_CONTROL_4r_REG32(unit, rval));
   3145 
   3146     rval = 0;
   3147     soc_reg_field_set(unit, EFP_RAM_CONTROLr, &rval,
   3148                       EFP_CAM_TM_7_THRU_0f, tm);
   3149     SOC_IF_ERROR_RETURN(WRITE_EFP_RAM_CONTROLr(unit, rval));
   3150 
   3151     rval = 0;
   3152     soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &rval,
   3153                       ALL_TCAMS_TM_7_0f, tm);
   3154     soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &rval,
   3155                       ALL_GLOBAL_MASK_TCAMS_TM_7_0f, tm);
   3156     SOC_IF_ERROR_RETURN(WRITE_FP_CAM_CONTROL_TM_7_THRU_0r(unit, rval));
   3157 
   3158     rval = 0;
   3159     soc_reg_field_set(unit, VLAN_SUBNET_CAM_DBGCTRLr, &rval,
   3160                       TMf, tm);
   3161     SOC_IF_ERROR_RETURN(WRITE_VLAN_SUBNET_CAM_DBGCTRLr(unit, rval));
   3162 
   3163     rval = 0;
   3164     soc_reg_field_set(unit, L2_USER_ENTRY_CAM_DBGCTRLr, &rval,
   3165                       TMf, tm);
   3166     SOC_IF_ERROR_RETURN(WRITE_L2_USER_ENTRY_CAM_DBGCTRLr(unit, rval));
   3167 
   3168     rval = 0;
   3169     soc_reg_field_set(unit, L3_DEFIP_128_CAM_DBGCTRLr, &rval,
   3170                       CAM0_TMf, tm);
   3171     soc_reg_field_set(unit, L3_DEFIP_128_CAM_DBGCTRLr, &rval,
   3172                       CAM1_TMf, tm);
   3173     SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_128_CAM_DBGCTRLr(unit, rval));
   3174 
   3175     rval = 0;
   3176     soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval,
   3177                       CAM0_TMf, tm);
   3178     soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval,
   3179                       CAM1_TMf, tm);
   3180     SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL0r(unit, rval));
   3181 
   3182     rval = 0;
   3183     soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL1r, &rval,
   3184                       CAM2_TMf, tm);
   3185     soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL1r, &rval,
   3186                       CAM3_TMf, tm);
   3187     SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL1r(unit, rval));
   3188 
   3189     rval = 0;
   3190     soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL2r, &rval,
   3191                       CAM4_TMf, tm);
   3192     soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL2r, &rval,
   3193                       CAM5_TMf, tm);    
   3194     SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL2r(unit, rval));
   3195 
   3196     rval = 0;
   3197     soc_reg_field_set(unit, L3_TUNNEL_CAM_DBGCTRLr, &rval,
   3198                       TMf, tm);
   3199     SOC_IF_ERROR_RETURN(WRITE_L3_TUNNEL_CAM_DBGCTRLr(unit, rval));
   3200 
   3201     rval = 0;
   3202     soc_reg_field_set(unit, MPLS_STATION_CAM_DBGCTRLr, &rval,
   3203                       CAM0_TMf, tm);
   3204     SOC_IF_ERROR_RETURN(WRITE_MPLS_STATION_CAM_DBGCTRLr(unit, rval));
   3205 
   3206     rval = 0;
   3207     soc_reg_field_set(unit, VFP_CAM_CONTROL_TM_7_THRU_0r, &rval,
   3208                       TMf, tm);
   3209     SOC_IF_ERROR_RETURN(WRITE_VFP_CAM_CONTROL_TM_7_THRU_0r(unit, rval));
   3210 
   3211     /* Input port enable */
   3212     rval=0;
   3213     soc_reg_field_set(unit, INPUT_PORT_RX_ENABLEr, &rval, 
   3214                           INPUT_PORT_RX_ENABLEf,
   3215                           SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0));
   3216     SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLEr(unit, rval));
   3217     SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLEr(unit, rval));
   3218     return SOC_E_NONE;
   3219 }
   3220 
   3221 int
   3222 soc_enduro_age_timer_get(int unit, int *age_seconds, int *enabled)
   3223 {
   3224     uint32 value;
   3225 
   3226     SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &value));
   3227     *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_ENAf);
   3228     *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_VALf);
   3229 
   3230     return SOC_E_NONE;
   3231 }
   3232 
   3233 int
   3234 soc_enduro_age_timer_max_get(int unit, int *max_seconds)
   3235 {
   3236     *max_seconds =
   3237         soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
   3238 
   3239     return SOC_E_NONE;
   3240 }
   3241 
   3242 int
   3243 soc_enduro_age_timer_set(int unit, int age_seconds, int enable)
   3244 {
   3245     uint32 value;
   3246 
   3247     value = 0;
   3248     soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_ENAf, enable);
   3249     soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_VALf, age_seconds);
   3250     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, value));
   3251 
   3252     return SOC_E_NONE;
   3253 }
   3254 
   3255 void soc_enduro_oam_handler_register(int unit, soc_enduro_oam_handler_t handler)
   3256 {
   3257     en_oam_handler[unit] = handler;
   3258     soc_intr_enable(unit, IRQ_MEM_FAIL);
   3259 }
   3260 
   3261 void
   3262 soc_enduro_mem_config(int unit)
   3263 {
   3264     uint16              dev_id;
   3265     uint8               rev_id;
   3266     soc_persist_t       *sop;
   3267 
   3268     sop = SOC_PERSIST(unit);
   3269     soc_cm_get_id(unit, &dev_id, &rev_id);
   3270 
   3271     switch (dev_id) {
   3272     case BCM56320_DEVICE_ID:
   3273         sop->memState[MPLS_ENTRYm].index_max = 0;
   3274         sop->memState[OAM_LM_COUNTERSm].index_max = 0;
   3275         sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 0;
   3276         break;
   3277     case BCM56321_DEVICE_ID:
   3278         sop->memState[MPLS_ENTRYm].index_max = 0;
   3279         sop->memState[OAM_LM_COUNTERSm].index_max = 0;
   3280         sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 0;
   3281         sop->memState[L2Xm].index_max = 16383;
   3282         sop->memState[L2_ENTRY_ONLYm].index_max = 16383;
   3283         sop->memState[L2_HITDA_ONLYm].index_max = 2047;
   3284         sop->memState[L2_HITSA_ONLYm].index_max = 2047;
   3285         sop->memState[L3_DEFIPm].index_max = 511;
   3286         sop->memState[L3_DEFIP_ONLYm].index_max = 511;
   3287         sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 511;
   3288         sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 511;
   3289         sop->memState[L3_TUNNELm].index_max = 127;
   3290         break;
   3291     case BCM56230_DEVICE_ID:
   3292     case BCM56231_DEVICE_ID:
   3293         /* L2 MAC Address : 16K */
   3294         sop->memState[L2Xm].index_max = 16383;
   3295         sop->memState[L2_ENTRY_ONLYm].index_max = 16383;
   3296         sop->memState[L2_HITDA_ONLYm].index_max = 2047;
   3297         sop->memState[L2_HITSA_ONLYm].index_max = 2047;
   3298 
   3299         /* MPLS Labels : 1K */
   3300         sop->memState[EGR_IP_TUNNELm].index_max = 255;
   3301         sop->memState[EGR_IP_TUNNEL_IPV6m].index_max = 127;
   3302         sop->memState[EGR_IP_TUNNEL_MPLSm].index_max = 255;
   3303         sop->memState[MPLS_ENTRYm].index_max = 1023;
   3304         sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 1023;
   3305 
   3306         /* VPLS VFI : 1K */
   3307         sop->memState[VFIm].index_max = 1023;
   3308         sop->memState[VFI_1m].index_max = 1023;
   3309         sop->memState[VLAN_OR_VFI_MAC_COUNTm].index_max = 5119;
   3310         sop->memState[VLAN_OR_VFI_MAC_LIMITm].index_max = 5119;
   3311 
   3312         /* Virtual Ports : 4K */
   3313         sop->memState[SOURCE_VPm].index_max = 4095;
   3314         sop->memState[SVP_DISABLE_VLAN_CHECKS_TABm].index_max = 4095;
   3315         sop->memState[ING_DVP_TABLEm].index_max = 4095;
   3316 
   3317         /* IPMc Groups : 512 */
   3318         sop->memState[EGR_IPMCm].index_max = 511;
   3319         sop->memState[L3_IPMCm].index_max = 511;
   3320         sop->memState[MMU_IPMC_GROUP_TBL0m].index_max = 511;
   3321         sop->memState[MMU_IPMC_GROUP_TBL1m].index_max = 511;
   3322         sop->memState[MMU_IPMC_GROUP_TBL2m].index_max = 511;
   3323         sop->memState[MMU_IPMC_GROUP_TBL3m].index_max = 511;
   3324         sop->memState[L3_MTU_VALUESm].index_max = 8703;
   3325 
   3326         /* IPv4 LPM : 4K */
   3327         sop->memState[L3_DEFIPm].index_max = 2047;
   3328         sop->memState[L3_DEFIP_ONLYm].index_max = 2047;
   3329         sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 2047;
   3330         sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 2047;
   3331         SOC_CONTROL(unit)->l3_defip_index_remap = 2048;
   3332 
   3333         /* L3 Next Hop : 2K */
   3334         sop->memState[EGR_L3_NEXT_HOPm].index_max = 2047;
   3335         sop->memState[ING_L3_NEXT_HOPm].index_max = 2047;
   3336         sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 2047;        
   3337         break;
   3338     default:
   3339         break;
   3340     }
   3341     return;
   3342 }
   3343 
   3344 #define _ENDURO_INDEX_1K_ENTRIES  1023
   3345 /* Map logical (always starts from 0 and contiguous) index to physical index
   3346    which can have a starting offset and/or holes.
   3347    Input  : logical index
   3348    Returns: physical index */
   3349 int
   3350 soc_enduro_l3_defip_index_map(int unit, soc_mem_t mem, int index)
   3351 {
   3352     if (SOC_CONTROL(unit)->l3_defip_index_remap == 0) {
   3353         return index;
   3354     }
   3355 
   3356     if (index > _ENDURO_INDEX_1K_ENTRIES) {
   3357         return index + SOC_CONTROL(unit)->l3_defip_index_remap;
   3358     }
   3359  
   3360     return index;
   3361 }
   3362 
   3363 /* Map physical (always starts from 0 and contiguous) index to logic index
   3364    which can have a starting offset and/or holes.
   3365    Input  : physical index
   3366    Returns: logical index */
   3367 int
   3368 soc_enduro_l3_defip_index_remap(int unit, soc_mem_t mem, int index)
   3369 {
   3370     if (SOC_CONTROL(unit)->l3_defip_index_remap == 0) {
   3371         return index;
   3372     }
   3373 
   3374     if (SOC_CONTROL(unit)->l3_defip_urpf) { /* URPF mode */
   3375         int tmp_index;
   3376 
   3377         tmp_index = index - SOC_CONTROL(unit)->l3_defip_index_remap;
   3378         if (tmp_index > _ENDURO_INDEX_1K_ENTRIES) {
   3379             return tmp_index;
   3380         } 
   3381     }
   3382  
   3383     return index;
   3384 }
   3385 
   3386 int
   3387 soc_enduro_mem_index_remap(int unit, soc_mem_t mem, int index)
   3388 {
   3389 	switch (mem) {
   3390 	    case L3_DEFIPm:
   3391 	    case L3_DEFIP_ONLYm:
   3392 	    case L3_DEFIP_DATA_ONLYm:
   3393 	    case L3_DEFIP_HIT_ONLYm:
   3394 		return soc_enduro_l3_defip_index_remap(unit, mem, index);
   3395 	default:
   3396 		return index;
   3397 	}
   3398 }
   3399 
   3400 #if defined(SER_TR_TEST_SUPPORT)
   3401 /*
   3402  * Function:
   3403  *      soc_enduro_ser_inject_error
   3404  * Purpose:
   3405  *       Injects an error into a single enduro memory
   3406  * Parameters:
   3407  *      unit               - (IN) Device Number
   3408  *      mem                - (IN) The memory to test
   3409  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
   3410  *      block - (IN) The index into which block will be injected.
   3411  *      index  - (IN) The index into which the error will be injected.
   3412  */
   3413 int soc_enduro_ser_inject_error(int unit, uint32 flags, soc_mem_t mem,
   3414                                 int pipeTarget, int block, int index)
   3415 {
   3416     int group, table;
   3417     _soc_parity_info_t *info;
   3418     soc_mem_t memTable;
   3419     soc_port_t block_port;
   3420     soc_block_t blk;
   3421     ser_test_data_t test_data;
   3422     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
   3423 
   3424     /*H/W memory Test*/
   3425     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
   3426         info = _soc_en_parity_group_info[group].info;
   3427 
   3428         SOC_BLOCK_ITER(unit, blk,
   3429             _soc_en_parity_group_info[group].blocktype) {
   3430             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
   3431                 continue;
   3432             }
   3433 
   3434             for (table = 0; info[table].error_field != INVALIDf; table++) {
   3435                 memTable = info[table].mem;
   3436                 if (memTable == INVALIDm) {
   3437                     continue;
   3438                 }
   3439          
   3440                 if (memTable == mem) {
   3441                     if((blk == block) || (block == MEM_BLOCK_ANY)) {
   3442                         /*Inject error*/
   3443                         test_data.mem = mem;
   3444                         test_data.tcam_parity_bit = -1;
   3445                         if (_soc_en_parity_group_info[group].blocktype 
   3446                                     == SOC_BLK_MMU) {
   3447                             soc_ser_create_test_data(unit, tmp_entry, fieldData,
   3448                                      MISCCONFIGr,
   3449                                      SOC_INVALID_TCAM_PARITY_BIT,
   3450                                      PARITY_CHECK_ENf,
   3451                                      mem, EVEN_PARITYf, blk,
   3452                                      block_port, _SOC_ACC_TYPE_PIPE_ANY,
   3453                                      index, &test_data);
   3454                         } else {
   3455                             soc_ser_create_test_data(unit, tmp_entry, fieldData,
   3456                                      info[table].control_reg,
   3457                                      SOC_INVALID_TCAM_PARITY_BIT,
   3458                                      info[table].enable_field,
   3459                                      mem, EVEN_PARITYf, blk,
   3460                                      block_port, _SOC_ACC_TYPE_PIPE_ANY,
   3461                                      index, &test_data);
   3462                         }
   3463                         /*Disable parity*/
   3464                         SOC_IF_ERROR_RETURN(_ser_test_parity_control(
   3465                                 unit, &test_data, 0));
   3466                         /*Read the memory for successful injection*/
   3467                         SOC_IF_ERROR_RETURN(ser_test_mem_read(
   3468                                     unit, 0, &test_data));
   3469                         /*Inject error*/
   3470                         SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(
   3471                                 unit, flags, &test_data));
   3472                         /*Enable parity*/
   3473                         SOC_IF_ERROR_RETURN(_ser_test_parity_control(
   3474                                 unit, &test_data, 1));
   3475                     }
   3476                 }
   3477             }
   3478         }
   3479     }
   3480     return SOC_E_NONE;
   3481 }
   3482 
   3483 /*
   3484  * Function:
   3485  *      soc_enduro_ser_error_injection_support
   3486  * Purpose:
   3487  *      Checks if a memory is supported by error injection interface
   3488  *
   3489  * Parameters:
   3490  *      unit        - (IN) Device Number
   3491  *      memory      - (IN) Test data required for SER test
   3492  *      pipe        - (IN) How many indices to test for each memory
   3493  *
   3494  * Returns:
   3495  *  SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported
   3496  */
   3497 soc_error_t
   3498 soc_enduro_ser_error_injection_support (int unit, soc_mem_t mem, int pipe)
   3499 {
   3500     int rv = SOC_E_UNAVAIL;
   3501     _soc_parity_info_t *info = NULL;
   3502     int group, table;
   3503     soc_port_t block_port;
   3504     soc_block_t blk;
   3505 
   3506     for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) {
   3507         info = _soc_en_parity_group_info[group].info;
   3508         SOC_BLOCK_ITER(unit, blk,
   3509             _soc_en_parity_group_info[group].blocktype) {
   3510             if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) {
   3511                 continue;
   3512             }
   3513             for (table = 0; info[table].error_field != INVALIDf; table++) {
   3514                 if (info[table].mem != mem) {
   3515                     continue;
   3516                 }
   3517                 return SOC_E_NONE;
   3518             }
   3519         }
   3520     }
   3521     return rv;
   3522 }
   3523 
   3524 #endif /* SER_TR_TEST_SUPPORT */
   3525 #endif /* BCM_ENDURO_SUPPORT */