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

hurricane.c (104783B)


      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:        hurricane.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/hurricane.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 
     28 #ifdef BCM_HURRICANE_SUPPORT
     29 
     30 /*
     31  * Enduro chip driver functions.  
     32  */
     33 soc_functions_t soc_hurricane_drv_funs = {
     34     soc_hurricane_misc_init,
     35     soc_hurricane_mmu_init,
     36     soc_hurricane_age_timer_get,
     37     soc_hurricane_age_timer_max_get,
     38     soc_hurricane_age_timer_set,
     39 };
     40 
     41 typedef enum {
     42     _SOC_PARITY_INFO_TYPE_GENERIC,
     43     _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
     44     _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
     45     _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER,
     46     _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
     47     _SOC_PARITY_INFO_TYPE_MMU_PARITY,
     48     _SOC_PARITY_INFO_TYPE_MMUIPMC,
     49     _SOC_PARITY_INFO_TYPE_MMUWRED,
     50     _SOC_PARITY_INFO_TYPE_OAM, /* Not parity, but same interrupt */
     51     _SOC_PARITY_INFO_TYPE_NUM
     52 } _soc_parity_info_type_t;
     53 
     54 typedef struct _soc_parity_info_s {
     55     soc_field_t             enable_field;
     56     soc_field_t             error_field;
     57     char                    *msg;
     58     soc_mem_t               mem;
     59     _soc_parity_info_type_t type;
     60     soc_reg_t               control_reg;
     61     soc_reg_t               intr_status0_reg;
     62     soc_reg_t               intr_status1_reg; /* Also SBE force for ECC */
     63     soc_reg_t               nack_status0_reg;
     64     soc_reg_t               nack_status1_reg; /* Also DBE force for ECC */
     65 } _soc_parity_info_t;
     66 
     67 /*
     68  *    _SOC_PARITY_INFO_TYPE_SINGLE_PARITY
     69  *      PARITY_EN
     70  *      ENTRY_IDX, MULTIPLE_ERR, PARITY_ERR
     71  *
     72  *    _SOC_PARITY_INFO_TYPE_SINGLE_ECC
     73  *      ECC_EN
     74  *      ENTRY_IDX, DOUBLE_BIT_ERR, MULTIPLE_ERR, ECC_ERR
     75  *
     76  *    _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER
     77  *      PARITY_EN
     78  *      PORT_IDX, COUNTER_IDX, MULTIPLE_ERR, PARITY_ERR
     79  *
     80  *    _SOC_PARITY_INFO_TYPE_DUAL_PARITY
     81  *      PARITY_EN
     82  *      BUCKET_IDX, MULTIPLE_ERR, PARITY_ERR_BM
     83  */
     84 
     85 STATIC _soc_parity_info_t _soc_hu_ip0_parity_info[] = {
     86     { PARITY_ENf, VXLT_PAR_ERRf, NULL,
     87       VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
     88       VLAN_XLATE_PARITY_CONTROLr,
     89       VLAN_XLATE_PARITY_STATUS_0r, VLAN_XLATE_PARITY_STATUS_1r,
     90       INVALIDr, INVALIDr },
     91  /* { PPA_CMD_COMPLETEf }, */
     92  /* { MEM_RESET_COMPLETEf }, */
     93  /* { AGE_CMD_COMPLETEf }, */
     94     { PARITY_ENf, VLAN_SUBNET_DATA_PARITY_ERRf, NULL,
     95       VLAN_SUBNET_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
     96       VLAN_SUBNET_DATA_PARITY_CONTROLr,
     97       VLAN_SUBNET_DATA_PARITY_STATUSr, INVALIDr,
     98       INVALIDr, INVALIDr },
     99     { PARITY_ENf, VLAN_PROTOCOL_DATA_PARITY_ERRf, NULL,
    100       VLAN_PROTOCOL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    101       VLAN_PROTOCOL_DATA_PARITY_CONTROLr,
    102       VLAN_PROTOCOL_DATA_PARITY_STATUSr, INVALIDr,
    103       INVALIDr, INVALIDr },
    104     { PARITY_ENf, VLAN_PARITY_ERRf, NULL,
    105       VLAN_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    106       VLAN_PARITY_CONTROLr,
    107       VLAN_PARITY_STATUSr, INVALIDr,
    108       INVALIDr, INVALIDr },
    109     { PARITY_ENf, VLAN_STG_PARITY_ERRf, NULL,
    110       STG_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    111       VLAN_STG_PARITY_CONTROLr,
    112       VLAN_STG_PARITY_STATUSr, INVALIDr,
    113       INVALIDr, INVALIDr },
    114     { PARITY_ENf, L3_TUNNEL_RAM_PARITY_ERRf, NULL,
    115       L3_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    116       L3_TUNNEL_DATA_ONLY_PARITY_CONTROLr,
    117       L3_TUNNEL_DATA_ONLY_PARITY_STATUSr, INVALIDr,
    118       INVALIDr, INVALIDr },
    119     { PARITY_ENf, SOURCE_TRUNK_MAP_PARITY_ERRf, NULL,
    120       SOURCE_TRUNK_MAP_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    121       SOURCE_TRUNK_MAP_PARITY_CONTROLr,
    122       SOURCE_TRUNK_MAP_PARITY_STATUSr, INVALIDr,
    123       INVALIDr, INVALIDr },
    124     { PARITY_ENf, VFP_POLICY_PAR_ERRf, NULL,
    125       VFP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    126       VFP_POLICY_PARITY_CONTROLr,
    127       VFP_POLICY_PARITY_STATUS_INTRr, INVALIDr,
    128       INVALIDr, INVALIDr },
    129     { PARITY_ENf, LMEP_PAR_ERRf, NULL,
    130       LMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    131       LMEP_PARITY_CONTROLr,
    132       LMEP_PARITY_STATUSr, INVALIDr,
    133       INVALIDr, INVALIDr },
    134     { ECC_ENf, IARB_PKT_ECC_INTRf, "Iarb packet ecc error",
    135       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    136       IARB_PKT_ECC_CONTROLr,
    137       IARB_PKT_ECC_STATUS_INTRr, INVALIDr,
    138       INVALIDr, INVALIDr },
    139     { ECC_ENf, IARB_HDR_ECC_INTRf, "Iarb header ecc error",
    140       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    141       IARB_HDR_ECC_CONTROLr,
    142       IARB_HDR_ECC_STATUS_INTRr, INVALIDr,
    143       INVALIDr, INVALIDr },
    144     { INVALIDf, INVALIDf }, /* table terminator */
    145 };
    146 
    147 STATIC _soc_parity_info_t _soc_hu_ip1_parity_info[] = {
    148     { PARITY_ENf, VFI_PAR_ERRf, NULL,
    149       VFIm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    150       VFI_PARITY_CONTROLr,
    151       VFI_PARITY_STATUS_INTRr, INVALIDr,
    152       VFI_PARITY_STATUS_NACKr, INVALIDr },
    153     { PARITY_ENf, SVP_PAR_ERRf, NULL,
    154       SOURCE_VPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    155       SOURCE_VP_PARITY_CONTROLr,
    156       SOURCE_VP_PARITY_STATUSr, INVALIDr,
    157       SOURCE_VP_PARITY_STATUS_NACKr, INVALIDr },
    158     { PARITY_ENf, L3_IIF_PAR_ERRf, NULL,
    159       L3_IIFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    160       L3_IIF_PARITY_CONTROLr,
    161       L3_IIF_PARITY_STATUSr, INVALIDr,
    162       L3_IIF_PARITY_STATUS_NACKr, INVALIDr },
    163     { PARITY_ENf, MPLS_ENTRY_PAR_ERRf, NULL,
    164       MPLS_ENTRYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    165       MPLS_ENTRY_PARITY_CONTROLr,
    166       MPLS_ENTRY_PARITY_STATUS_INTR_0r, MPLS_ENTRY_PARITY_STATUS_INTR_1r,
    167       MPLS_ENTRY_PARITY_STATUS_NACK_0r, MPLS_ENTRY_PARITY_STATUS_NACK_1r },
    168     { PARITY_ENf, L2_ENTRY_PAR_ERRf, NULL,
    169       L2Xm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    170       L2_ENTRY_PARITY_CONTROLr,
    171       L2_ENTRY_PARITY_STATUS_0r, L2_ENTRY_PARITY_STATUS_1r,
    172       INVALIDr, INVALIDr },
    173     { PARITY_ENf, L2MC_PAR_ERRf, NULL,
    174       L2MCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    175       L2MC_PARITY_CONTROLr,
    176       L2MC_PARITY_STATUSr, INVALIDr,
    177       INVALIDr, INVALIDr },
    178     { PARITY_ENf, L3_ENTRY_PAR_ERRf, NULL,
    179       L3_ENTRY_ONLYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    180       L3_ENTRY_PARITY_CONTROLr,
    181       L3_ENTRY_PARITY_STATUS_0r, L3_ENTRY_PARITY_STATUS_1r,
    182       INVALIDr, INVALIDr },
    183     { PARITY_ENf, L3_DEFIP_DATA_PAR_ERRf, NULL,
    184       L3_DEFIP_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    185       L3_DEFIP_PARITY_CONTROLr,
    186       L3_DEFIP_PARITY_STATUSr, INVALIDr
    187       INVALIDr, INVALIDr },
    188 	{ PARITY_ENf, L3MC_PAR_ERRf, NULL,
    189 	  L3_IPMCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    190 	  L3MC_PARITY_CONTROLr,
    191 	  L3MC_PARITY_STATUSr, INVALIDr,
    192 	  INVALIDr, INVALIDr },
    193     { PARITY_ENf, MA_STATE_PAR_ERRf, NULL,
    194       MA_STATEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    195       MA_STATE_PARITY_CONTROLr,
    196       MA_STATE_PARITY_STATUSr, INVALIDr,
    197       INVALIDr, INVALIDr },
    198     { PARITY_ENf, RMEP_PAR_ERRf, NULL,
    199       RMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    200       RMEP_PARITY_CONTROLr,
    201       RMEP_PARITY_STATUSr, INVALIDr,
    202       INVALIDr, INVALIDr },
    203     { PARITY_ENf, MAID_REDUCTION_PAR_ERRf, NULL,
    204       MAID_REDUCTIONm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    205       MAID_REDUCTION_PARITY_CONTROLr,
    206       MAID_REDUCTION_PARITY_STATUSr, INVALIDr,
    207       INVALIDr, INVALIDr },
    208     { PARITY_ENf, MA_INDEX_PAR_ERRf, NULL,
    209       MA_INDEXm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    210       MA_INDEX_PARITY_CONTROLr,
    211       MA_INDEX_PARITY_STATUSr, INVALIDr,
    212       INVALIDr, INVALIDr },
    213     { PARITY_ENf, PORT_CBL_TABLE_PAR_ERRf, NULL,
    214       PORT_CBL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    215       PORT_CBL_TABLE_PARITY_CONTROLr,
    216       PORT_CBL_TABLE_PARITY_STATUSr, INVALIDr,
    217       INVALIDr, INVALIDr },
    218     { PARITY_ENf, INITIAL_NHOP_PAR_ERRf, NULL,
    219       INITIAL_ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    220       INITIAL_NHOP_PARITY_CONTROLr,
    221       INITIAL_NHOP_PARITY_STATUSr, INVALIDr,
    222       INVALIDr, INVALIDr },
    223     /* Start of parity-unrelated OAM faults */
    224 
    225     { ANY_RMEP_TLV_PORT_DOWN_INTRf, ANY_RMEP_TLV_PORT_DOWN_INTRf, NULL,
    226       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    227       INVALIDr,
    228       INVALIDr, INVALIDr,
    229       INVALIDr, INVALIDr },
    230 
    231     { ANY_RMEP_TLV_PORT_UP_INTRf, ANY_RMEP_TLV_PORT_UP_INTRf, NULL,
    232       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    233       INVALIDr,
    234       INVALIDr, INVALIDr,
    235       INVALIDr, INVALIDr },
    236 
    237     { ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, NULL,
    238       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    239       INVALIDr,
    240       INVALIDr, INVALIDr,
    241       INVALIDr, INVALIDr },
    242 
    243     { ANY_RMEP_TLV_INTERFACE_UP_INTRf, ANY_RMEP_TLV_INTERFACE_UP_INTRf, NULL,
    244       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    245       INVALIDr,
    246       INVALIDr, INVALIDr,
    247       INVALIDr, INVALIDr },
    248 
    249     { XCON_CCM_DEFECT_INTRf, XCON_CCM_DEFECT_INTRf, NULL,
    250       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    251       INVALIDr,
    252       INVALIDr, INVALIDr,
    253       INVALIDr, INVALIDr },
    254 
    255     { ERROR_CCM_DEFECT_INTRf, ERROR_CCM_DEFECT_INTRf, NULL,
    256       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    257       INVALIDr,
    258       INVALIDr, INVALIDr,
    259       INVALIDr, INVALIDr },
    260 
    261     { SOME_RDI_DEFECT_INTRf, SOME_RDI_DEFECT_INTRf, NULL,
    262       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    263       INVALIDr,
    264       INVALIDr, INVALIDr,
    265       INVALIDr, INVALIDr },
    266 
    267     { SOME_RMEP_CCM_DEFECT_INTRf, SOME_RMEP_CCM_DEFECT_INTRf, NULL,
    268       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    269       INVALIDr,
    270       INVALIDr, INVALIDr,
    271       INVALIDr, INVALIDr },
    272 
    273     /* End of parity-unrelated OAM faults */
    274     { PARITY_ENf, VFI_1_PAR_INTRf, NULL,
    275       VFI_1m, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    276       VFI_1_PARITY_CONTROLr,
    277       VFI_1_PARITY_STATUS_INTRr, INVALIDr,
    278       VFI_1_PARITY_STATUS_NACKr, INVALIDr },
    279     { INVALIDf, INVALIDf }, /* table terminator */
    280 };
    281 
    282 STATIC _soc_parity_info_t _soc_hu_ip2_parity_info[] = {
    283     { PARITY_ENf, ING_NHOP_PAR_ERRf, NULL,
    284       ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    285       ING_L3_NEXT_HOP_PARITY_CONTROLr,
    286       ING_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr,
    287       INVALIDr, INVALIDr },
    288     { PARITY_ENf, IFP_METER_PAR_ERRf, NULL,
    289       FP_METER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    290       IFP_METER_PARITY_CONTROLr,
    291       IFP_METER_PARITY_STATUSr, INVALIDr,
    292       INVALIDr, INVALIDr },
    293     { PARITY_ENf, IFP_COUNTER_PAR_ERRf, NULL,
    294       FP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    295       IFP_COUNTER_PARITY_CONTROLr,
    296       IFP_COUNTER_PARITY_STATUSr, INVALIDr,
    297       INVALIDr, INVALIDr },
    298     { PARITY_ENf, IFP_POLICY_PAR_ERRf, NULL,
    299       FP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    300       IFP_POLICY_PARITY_CONTROLr,
    301       IFP_POLICY_PARITY_STATUSr, INVALIDr,
    302       INVALIDr, INVALIDr },
    303     { PARITY_ENf, IFP_STORM_CONTROL_PAR_ERRf, NULL,
    304       FP_STORM_CONTROL_METERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    305       IFP_STORM_CONTROL_PARITY_CONTROLr,
    306       IFP_STORM_CONTROL_PARITY_STATUSr, INVALIDr,
    307       INVALIDr, INVALIDr },
    308     { PARITY_ENf, L3_MTU_VALUES_PAR_ERRf, NULL,
    309       L3_MTU_VALUESm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    310       L3_MTU_VALUES_PARITY_CONTROLr,
    311       L3_MTU_VALUES_PARITY_STATUSr, INVALIDr,
    312       INVALIDr, INVALIDr },
    313     { PARITY_ENf, EGR_MASK_PAR_ERRf, NULL,
    314       EGR_MASKm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    315       EGR_MASK_PARITY_CONTROLr,
    316       EGR_MASK_PARITY_STATUSr, INVALIDr,
    317       INVALIDr, INVALIDr },
    318     { PARITY_ENf, MODPORT_MAP_SW_PAR_ERRf, NULL,
    319       MODPORT_MAP_SWm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    320       MODPORT_MAP_SW_PARITY_CONTROLr,
    321       MODPORT_MAP_SW_PARITY_STATUSr, INVALIDr,
    322       INVALIDr, INVALIDr },
    323 	{ PARITY_ENf, MODPORT_MAP_SW_PAR_ERRf, NULL,
    324 	  MODPORT_MAPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    325 	  MODPORT_MAP_SW_PARITY_CONTROLr,
    326 	  MODPORT_MAP_SW_PARITY_STATUSr, INVALIDr,
    327 	  INVALIDr, INVALIDr },   
    328     { PARITY_ENf, MODPORT_MAP_IM_PAR_ERRf, NULL,
    329       MODPORT_MAP_IMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    330       MODPORT_MAP_IM_PARITY_CONTROLr,
    331       MODPORT_MAP_IM_PARITY_STATUSr, INVALIDr,
    332       INVALIDr, INVALIDr },
    333     { PARITY_ENf, MODPORT_MAP_EM_PAR_ERRf, NULL,
    334       MODPORT_MAP_EMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    335       MODPORT_MAP_EM_PARITY_CONTROLr,
    336       MODPORT_MAP_EM_PARITY_STATUSr, INVALIDr,
    337       INVALIDr, INVALIDr },
    338     { INVALIDf, INVALIDf }, /* table terminator */
    339 };
    340 
    341 STATIC _soc_parity_info_t _soc_hu_ep_parity_info[] = {
    342     { PARITY_ENf, EGR_NHOP_PAR_ERRf, NULL,
    343       EGR_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    344       EGR_L3_NEXT_HOP_PARITY_CONTROLr,
    345       EGR_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr,
    346       INVALIDr, INVALIDr },
    347     { PARITY_ENf, EGR_L3_INTF_PAR_ERRf, NULL,
    348       EGR_L3_INTFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    349       EGR_L3_INTF_PARITY_CONTROLr,
    350       EGR_L3_INTF_PARITY_STATUSr, INVALIDr,
    351       INVALIDr, INVALIDr },
    352 /*    { PARITY_ENf, EGR_MPLS_LABEL_PAR_ERRf, NULL,
    353       EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    354       EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_CONTROLr,
    355       EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_STATUSr, INVALIDr,
    356       INVALIDr, INVALIDr }, */
    357     { PARITY_ENf, EGR_VLAN_PAR_ERRf, NULL,
    358       EGR_VLANm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    359       EGR_VLAN_PARITY_CONTROLr,
    360       EGR_VLAN_PARITY_STATUSr, INVALIDr,
    361       INVALIDr, INVALIDr },
    362    { PARITY_ENf, EGR_VLAN_STG_PAR_ERRf, NULL,
    363       EGR_VLAN_STGm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    364       EGR_VLAN_STG_PARITY_CONTROLr,
    365       EGR_VLAN_STG_PARITY_STATUSr, INVALIDr,
    366       INVALIDr, INVALIDr },
    367     { PARITY_ENf, EGR_VXLT_PAR_ERRf, NULL,
    368       EGR_VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    369       EGR_VLAN_XLATE_PARITY_CONTROLr,
    370       EGR_VLAN_XLATE_PARITY_STATUS_0r, EGR_VLAN_XLATE_PARITY_STATUS_1r,
    371       INVALIDr, INVALIDr },
    372 /*    { PARITY_ENf, EGR_IP_TUNNEL_PAR_ERRf, NULL,
    373       EGR_IP_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    374       EGR_IP_TUNNEL_PARITY_CONTROLr,
    375       EGR_IP_TUNNEL_PARITY_STATUSr, INVALIDr,
    376       INVALIDr, INVALIDr }, 
    377     { PARITY_ENf, EGR_PW_COUNT_PAR_ERRf, NULL,
    378       EGR_PW_INIT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    379       EGR_PW_INIT_COUNTERS_PARITY_CONTROLr,
    380       EGR_PW_INIT_COUNTERS_PARITY_STATUSr, INVALIDr,
    381       INVALIDr, INVALIDr },
    382     { PARITY_ENf, EGR_IPFIX_SESS_PAR_ERRf, NULL,
    383       EGR_IPFIX_SESSION_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    384       EGR_IPFIX_SESSION_PARITY_CONTROLr,
    385       EGR_IPFIX_SESSION_PARITY_STATUSr, INVALIDr,
    386       INVALIDr, INVALIDr },
    387     { PARITY_ENf, EGR_IPFIX_EXPORT_PAR_ERRf, NULL,
    388       EGR_IPFIX_EXPORT_FIFOm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    389       EGR_IPFIX_EXPORT_FIFO_PARITY_CONTROLr,
    390       EGR_IPFIX_EXPORT_FIFO_PARITY_STATUSr, INVALIDr,
    391       INVALIDr, INVALIDr }, */
    392     { ECC_ENf, EP_INITBUF_DBEf, "EP_INITBUF double-bit ECC error",
    393       INVALIDm,_SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    394       EGR_INITBUF_ECC_CONTROLr,
    395       EGR_INITBUF_ECC_STATUS_DBEr, INVALIDr,
    396       INVALIDr, INVALIDr },
    397     { ECC_ENf, EP_INITBUF_SBEf, "EP_INITBUF single-bit ECC error (corrected)",
    398       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    399       EGR_INITBUF_ECC_CONTROLr,
    400       EGR_INITBUF_ECC_STATUS_SBEr, INVALIDr,
    401       INVALIDr, INVALIDr },
    402     { PARITY_ENf, EGR_PERQ_COUNTERf, "EP_PERQ_COUNTER table parity error",
    403       EGR_PERQ_XMT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    404       EGR_PERQ_COUNTER_PARITY_CONTROLr,
    405       EGR_PERQ_COUNTER_PARITY_STATUSr, INVALIDr,
    406       INVALIDr, INVALIDr },
    407 /*    { PARITY_ENf, EGR_FP_COUNTERf, NULL,
    408       EFP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    409       EGR_FP_COUNTER_PARITY_CONTROLr,
    410       EGR_FP_COUNTER_PARITY_STATUSr, INVALIDr,
    411       INVALIDr, INVALIDr }, */
    412     { PARITY_ENf, EGR_GP0_DBUFf, "EP_GP0_DATABUF memory parity error",
    413       EFP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    414       EGR_GP0_DBUF_PARITY_CONTROLr,
    415       EGR_GP0_DBUF_PARITY_STATUSr, INVALIDr,
    416       INVALIDr, INVALIDr },
    417     { PARITY_ENf, EGR_GP1_DBUFf, "EP_GP1_DATABUF memory parity error",
    418       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    419       EGR_GP1_DBUF_PARITY_CONTROLr,
    420       EGR_GP1_DBUF_PARITY_STATUSr, INVALIDr,
    421       INVALIDr, INVALIDr },
    422     { PARITY_ENf, EGR_GP2_DBUFf, "EP_GP2_DATABUF memory parity error",
    423       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    424       EGR_GP2_DBUF_PARITY_CONTROLr,
    425       EGR_GP2_DBUF_PARITY_STATUSr, INVALIDr,
    426       INVALIDr, INVALIDr },
    427     { PARITY_ENf, EGR_XQ0_DBUFf, "EP_XQ0_DATABUF memory parity error",
    428       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    429       EGR_XQ0_DBUF_PARITY_CONTROLr,
    430       EGR_XQ0_DBUF_PARITY_STATUSr, INVALIDr,
    431       INVALIDr, INVALIDr },
    432     { PARITY_ENf, EGR_XQ1_DBUFf, "EP_XQ1_DATABUF memory parity error",
    433       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    434       EGR_XQ1_DBUF_PARITY_CONTROLr,
    435       EGR_XQ1_DBUF_PARITY_STATUSr, INVALIDr,
    436       INVALIDr, INVALIDr },
    437     { PARITY_ENf, EGR_XQ2_DBUFf, "EP_XQ2_DATABUF memory parity error",
    438       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    439       EGR_XQ2_DBUF_PARITY_CONTROLr,
    440       EGR_XQ2_DBUF_PARITY_STATUSr, INVALIDr,
    441       INVALIDr, INVALIDr },
    442     { PARITY_ENf, EGR_XQ3_DBUFf, "EP_XQ3_DATABUF memory parity error",
    443       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    444       EGR_XQ3_DBUF_PARITY_CONTROLr,
    445       EGR_XQ3_DBUF_PARITY_STATUSr, INVALIDr,
    446       INVALIDr, INVALIDr },
    447 /*    { PARITY_ENf, EGR_LP_DBUFf, "EP_LP_DATABUF memory parity error",
    448       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    449       EGR_LP_DBUF_PARITY_CONTROLr,
    450       EGR_LP_DBUF_PARITY_STATUSr, INVALIDr,
    451       INVALIDr, INVALIDr }, */
    452     { PARITY_ENf, EGR_CM_DBUFf, "EGR_CM_DBUF memory parity error",
    453       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    454       EGR_CM_DBUF_PARITY_CONTROLr,
    455       EGR_CM_DBUF_PARITY_STATUSr, INVALIDr,
    456       INVALIDr, INVALIDr },
    457     { INVALIDf, INVALIDf }, /* table terminator */
    458 };
    459 
    460 STATIC _soc_parity_info_t _soc_hu_xqp_parity_info[] = {
    461     { XQBOD_RXFIFOf, XQBOD_RXFIFOf, "XQBOD_RXFIFO",
    462       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    463       XQPORT_PARITY_CONTROLr,
    464       XQPORT_XQBOD_RXFIFO_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr,
    465       INVALIDr, XQPORT_FORCE_DOUBLE_BIT_ERRORr },
    466     { XQBODE_TXFIFOf, XQBODE_TXFIFOf, "XQBODE_TXFIFO",
    467       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    468       XQPORT_PARITY_CONTROLr,
    469       XQPORT_XQBODE_TXFIFO_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr,
    470       INVALIDr, XQPORT_FORCE_DOUBLE_BIT_ERRORr },
    471     { INVALIDf, INVALIDf }, /* table terminator */
    472 };
    473 
    474 static struct {
    475     uint32             cpi_bit;
    476     soc_block_t        blocktype;
    477     soc_reg_t          enable_reg;
    478     soc_reg_t          status_reg;
    479     _soc_parity_info_t *info;
    480 } _soc_hu_parity_group_info[] = {
    481     { 0x00002, SOC_BLK_EPIPE, EP_INTR_ENABLEr, EP_INTR_STATUSr, _soc_hu_ep_parity_info },
    482     { 0x00004, SOC_BLK_IPIPE, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, _soc_hu_ip0_parity_info },
    483     { 0x00008, SOC_BLK_IPIPE, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, _soc_hu_ip1_parity_info },
    484     { 0x00010, SOC_BLK_IPIPE, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, _soc_hu_ip2_parity_info },
    485  /* { 0x00020, PCIE_REPLAY_PERR, }, */
    486     { 0x00040, SOC_BLK_XQPORT, XQPORT_INTR_ENABLEr, XQPORT_INTR_STATUSr, _soc_hu_xqp_parity_info }, /* x4 */
    487     { 0 }, /* table terminator */
    488 };
    489 
    490 STATIC soc_hurricane_oam_handler_t hu_oam_handler = NULL;
    491 
    492 static soc_ser_functions_t _hurricane_ser_functions;
    493 
    494 STATIC int
    495 _soc_hurricane_parity_block_port(int unit, soc_block_t block, soc_port_t *port)
    496 {
    497     *port = SOC_BLOCK_PORT(unit, block);
    498     if ((*port != REG_PORT_ANY) && !SOC_PORT_VALID(unit, *port)) {
    499         return SOC_E_PORT;
    500     }
    501 
    502     return SOC_E_NONE;
    503 }
    504 
    505 STATIC int
    506 _soc_hurricane_parity_enable(int unit, int enable)
    507 {
    508     int group, table;
    509     uint32 addr, group_enable, regval, cmic_enable = 0, cpi_blk_bit;
    510     _soc_parity_info_t *info;
    511     soc_reg_t group_reg, reg;
    512     soc_port_t block_port;
    513     soc_field_t enable_field;
    514     soc_block_t blk;
    515 
    516     /* loop through each group */
    517     for (group = 0; _soc_hu_parity_group_info[group].cpi_bit; group++) {
    518         info = _soc_hu_parity_group_info[group].info;
    519         group_reg = _soc_hu_parity_group_info[group].enable_reg;
    520         group_enable = 0;
    521 
    522         cpi_blk_bit = _soc_hu_parity_group_info[group].cpi_bit;
    523 
    524         SOC_BLOCK_ITER(unit, blk,
    525                        _soc_hu_parity_group_info[group].blocktype) {
    526             if (_soc_hurricane_parity_block_port(unit, blk, &block_port) < 0) {
    527                 cpi_blk_bit <<= 1;
    528                 continue;
    529             }
    530             /* loop through each table in the group */
    531             for (table = 0; info[table].enable_field != INVALIDf; table++) {
    532                 /* handle different parity error reporting style */
    533                 switch (info[table].type) {
    534                 case _SOC_PARITY_INFO_TYPE_GENERIC:
    535                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
    536                 case _SOC_PARITY_INFO_TYPE_MMUIPMC:
    537                 case _SOC_PARITY_INFO_TYPE_MMUWRED:
    538                 case _SOC_PARITY_INFO_TYPE_OAM:
    539                     enable_field = info[table].enable_field;
    540                     break;
    541                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
    542                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
    543                 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER:
    544                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
    545                     reg = info[table].control_reg;
    546                     if (!SOC_REG_IS_VALID(unit, reg)) {
    547                         continue;
    548                     }
    549                     addr = soc_reg_addr(unit, reg, block_port, 0);
    550                     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &regval));
    551                     soc_reg_field_set(unit, reg, &regval,
    552                                       info[table].enable_field,
    553                                       enable ? 1 : 0);
    554                     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, regval));
    555                     enable_field = info[table].error_field;
    556                     break;
    557                 default:
    558                     enable_field = INVALIDf;
    559                     break;
    560                 } /* handle different parity error reporting style */
    561                 if (enable_field != INVALIDf) {
    562                     soc_reg_field_set(unit, group_reg, &group_enable,
    563                                       enable_field, enable ? 1 : 0);
    564                 }
    565             } /* loop through each table in the group */
    566 
    567             if (!SOC_REG_IS_VALID(unit, group_reg)) {
    568                 cpi_blk_bit <<= 1;
    569                 continue;
    570             }
    571             addr = soc_reg_addr(unit, group_reg, block_port, 0);
    572             SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable));
    573             cmic_enable |= cpi_blk_bit;
    574             cpi_blk_bit <<= 1;
    575         }
    576     } /* loop through each group */
    577     /* coverity[result_independent_of_operands] */
    578     SOC_IF_ERROR_RETURN(WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit,
    579                                                             cmic_enable));
    580     return SOC_E_NONE;
    581 }
    582 
    583 int
    584 _soc_hurricane_mem_parity_control(int unit, soc_mem_t mem,
    585                                  int copyno, int enable)
    586 {
    587     int group, table;
    588     uint32 cpi_blk_bit, misc_cfg;
    589     _soc_parity_info_t *info;
    590     soc_reg_t group_reg, reg;
    591     soc_port_t block_port;
    592     soc_field_t enable_field;
    593     soc_block_t blk;
    594 
    595     if (!soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
    596         /* Parity checking is not enabled, nothing to do */
    597         return SOC_E_NONE;
    598     }
    599 
    600     /* Convert component/aggregate memories to the table for which
    601      * the parity registers correspond. */
    602     switch(mem) {
    603     case VLAN_SUBNETm:
    604         mem = VLAN_SUBNET_DATA_ONLYm; /* Should be VLAN_SUBNET? */
    605         break;
    606     case L2_ENTRY_ONLYm:
    607         mem = L2Xm;
    608         break;
    609     case L2_USER_ENTRY_ONLYm:
    610     case L2_USER_ENTRY_DATA_ONLYm:
    611         mem = L2_USER_ENTRYm;
    612         break;
    613     case L3_DEFIPm:
    614         mem = L3_DEFIP_DATA_ONLYm;
    615         break;
    616     case L3_DEFIP_128m:
    617         mem = L3_DEFIP_128_DATA_ONLYm;
    618         break;
    619     case EGR_IP_TUNNEL_IPV6m:
    620     case EGR_IP_TUNNEL_MPLSm:
    621         mem = EGR_IP_TUNNELm;
    622         break;
    623 	case L3_ENTRY_IPV4_UNICASTm:
    624 	case L3_ENTRY_IPV6_UNICASTm:
    625 	case L3_ENTRY_IPV4_MULTICASTm:
    626 	case L3_ENTRY_IPV6_MULTICASTm:
    627         mem = L3_ENTRY_ONLYm;
    628         break;
    629 	case VLAN_MACm:
    630 	    mem = VLAN_XLATEm;
    631 		break;
    632     default:
    633         /* Do nothing, keep memory as provided */
    634         break;
    635     }
    636 
    637 
    638     /* loop through each group */
    639     for (group = 0; _soc_hu_parity_group_info[group].cpi_bit; group++) {
    640         info = _soc_hu_parity_group_info[group].info;
    641         group_reg = _soc_hu_parity_group_info[group].enable_reg;
    642         cpi_blk_bit = _soc_hu_parity_group_info[group].cpi_bit;
    643 
    644         SOC_BLOCK_ITER(unit, blk,
    645                        _soc_hu_parity_group_info[group].blocktype) {
    646             if (_soc_hurricane_parity_block_port(unit, blk, &block_port) < 0) {
    647                 cpi_blk_bit <<= 1;
    648                 continue;
    649             }
    650             if ((copyno != MEM_BLOCK_ANY) && (blk != copyno)) {
    651                 cpi_blk_bit <<= 1;
    652                 continue;
    653             }
    654 
    655             /* loop through each table in the group */
    656             for (table = 0; info[table].enable_field != INVALIDf; table++) {
    657                 if (mem != info[table].mem) {
    658                     continue;
    659                 }
    660 
    661                 /* handle different parity error reporting style */
    662                 switch (info[table].type) {
    663                 case _SOC_PARITY_INFO_TYPE_GENERIC:
    664                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
    665                 case _SOC_PARITY_INFO_TYPE_MMUIPMC:
    666                 case _SOC_PARITY_INFO_TYPE_MMUWRED:
    667                     enable_field = info[table].enable_field;
    668                     SOC_IF_ERROR_RETURN
    669                         (soc_reg_field32_modify(unit, group_reg, block_port,
    670                                                 enable_field,
    671                                                 enable ? 1 : 0));
    672                     break;
    673                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
    674                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
    675                 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER:
    676                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
    677                     reg = info[table].control_reg;
    678                     if (!SOC_REG_IS_VALID(unit, reg)) {
    679                         return SOC_E_NONE;
    680                     }
    681                     SOC_IF_ERROR_RETURN
    682                         (soc_reg_field32_modify(unit, reg, block_port,
    683                                                 info[table].enable_field,
    684                                                 enable ? 1 : 0));
    685                     break;
    686                 default:
    687                     break;
    688                 } /* handle different parity error reporting style */
    689             } /* loop through each table in the group */
    690             cpi_blk_bit <<= 1;
    691         }
    692     } /* loop through each group */
    693 
    694     /* MMU controls */
    695     if (enable) {
    696         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg));
    697         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg,
    698                           E2EFC_PARITY_STAT_CLEARf, 1);
    699         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    700 
    701         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHECK_ENf, 1);
    702         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, E2EFC_PARITY_GEN_ENf, 1);
    703         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, E2EFC_PARITY_STAT_CLEARf, 0);
    704         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, METERING_CLK_ENf, 1);
    705         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    706     } else {
    707         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg));
    708         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHECK_ENf, 0);
    709         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, E2EFC_PARITY_GEN_ENf, 0);
    710         soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, METERING_CLK_ENf, 0);
    711         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg));
    712     }
    713 
    714     return SOC_E_NONE;
    715 }
    716 
    717 STATIC int
    718 _soc_hurricane_process_single_parity_error(int unit, int group,
    719                                           soc_port_t block_port, int table,
    720                                           int schan, char *msg)
    721 {
    722     _soc_parity_info_t *info;
    723     soc_reg_t status_reg;
    724     uint32 addr, reg_val;
    725     int index, multiple, error;
    726 
    727     info = _soc_hu_parity_group_info[group].info;
    728 
    729     status_reg = schan ? info[table].nack_status0_reg :
    730         info[table].intr_status0_reg;
    731     if (status_reg == INVALIDr) {
    732         return SOC_E_INTERNAL;
    733     }
    734     addr = soc_reg_addr(unit, status_reg, block_port, 0);
    735     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    736     index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf);
    737     multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
    738     error = soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERRf);
    739  
    740     if (error) {
    741         LOG_ERROR(BSL_LS_SOC_COMMON,
    742                   (BSL_META_U(unit,
    743                               "unit %d %s entry %d parity error\n"),
    744                    unit, msg, index));
    745         if (multiple) {
    746             LOG_ERROR(BSL_LS_SOC_COMMON,
    747                       (BSL_META_U(unit,
    748                                   "unit %d %s has multiple parity errors\n"),
    749                        unit, msg));
    750         }
    751     } else {
    752         LOG_ERROR(BSL_LS_SOC_COMMON,
    753                   (BSL_META_U(unit,
    754                               "unit %d %s: parity hardware inconsistency\n"),
    755                    unit, msg));
    756     }
    757 
    758     /* Clear parity status */
    759     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0));
    760     return SOC_E_NONE;
    761 }
    762 
    763 STATIC int
    764 _soc_hurricane_process_single_ecc_error(int unit, int group,
    765                                        soc_port_t block_port, int table,
    766                                        int schan, char *msg)
    767 {
    768     _soc_parity_info_t *info;
    769     soc_reg_t status_reg;
    770     uint32 addr, reg_val;
    771     int index, double_bit, multiple, error;
    772 
    773     info = _soc_hu_parity_group_info[group].info;
    774 
    775     status_reg = schan ? info[table].nack_status0_reg :
    776         info[table].intr_status0_reg;
    777     if (status_reg == INVALIDr) {
    778         return SOC_E_INTERNAL;
    779     }
    780     addr = soc_reg_addr(unit, status_reg, block_port, 0);
    781     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    782     index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf);
    783     double_bit = soc_reg_field_get(unit, status_reg,
    784                                    reg_val, DOUBLE_BIT_ERRf);
    785     multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
    786     error = soc_reg_field_get(unit, status_reg, reg_val, ECC_ERRf);
    787  
    788     if (error) {
    789         LOG_ERROR(BSL_LS_SOC_COMMON,
    790                   (BSL_META_U(unit,
    791                               "unit %d %s entry %d %s ECC error\n"),
    792                    unit, msg, index, double_bit ? "double-bit" : ""));
    793         if (multiple) {
    794             LOG_ERROR(BSL_LS_SOC_COMMON,
    795                       (BSL_META_U(unit,
    796                                   "unit %d %s has multiple ECC errors\n"),
    797                        unit, msg));
    798         }
    799     } else {
    800         LOG_ERROR(BSL_LS_SOC_COMMON,
    801                   (BSL_META_U(unit,
    802                               "unit %d %s: parity hardware inconsistency\n"),
    803                    unit, msg));
    804     }
    805 
    806     /* Clear parity status */
    807     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0));
    808     return SOC_E_NONE;
    809 }
    810 
    811 STATIC int
    812 _soc_hurricane_process_dual_parity_error(int unit, int group,
    813                                         soc_port_t block_port, int table,
    814                                         int schan, char *msg)
    815 {
    816     _soc_parity_info_t *info;
    817     soc_reg_t status_reg;
    818     uint32 addr, reg_val, bitmap;
    819     int index, bucket_index, multiple, ix, bits, size;
    820 
    821     info = _soc_hu_parity_group_info[group].info;
    822 
    823     for (ix = 0; ix < 2; ix ++) {
    824         if (ix == 1) {
    825             status_reg = schan ? info[table].nack_status1_reg :
    826                 info[table].intr_status1_reg;
    827         } else {
    828             status_reg = schan ? info[table].nack_status0_reg :
    829                 info[table].intr_status0_reg;
    830         }
    831 
    832         if (status_reg == INVALIDr) {
    833             continue;
    834         }
    835 
    836         addr = soc_reg_addr(unit, status_reg, block_port, 0);
    837         SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    838         bucket_index =
    839             soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDXf);
    840         multiple =
    841             soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
    842         bitmap =
    843             soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf);
    844         size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf);
    845 
    846         if (bitmap != 0) {
    847             for (bits = 0; bits < size; bits++) {
    848                 if (bitmap & (1 << bits)) {
    849                     index =
    850                         bucket_index * size * 2 + bits + (ix * size);
    851                     LOG_ERROR(BSL_LS_SOC_COMMON,
    852                               (BSL_META_U(unit,
    853                                           "unit %d %s entry %d parity error\n"),
    854                                unit, msg, index));
    855                 }
    856             }
    857         }
    858 
    859         if (multiple) {
    860             LOG_ERROR(BSL_LS_SOC_COMMON,
    861                       (BSL_META_U(unit,
    862                                   "unit %d %s has multiple parity errors\n"),
    863                        unit, msg));
    864         }
    865 
    866         /* Clear parity status */
    867         SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0));
    868     }
    869 
    870     return SOC_E_NONE;
    871 }
    872 
    873 STATIC int
    874 _soc_hurricane_process_mmu_parity_error(int unit, int group,
    875                                        soc_port_t block_port, int table,
    876                                        char *msg)
    877 {
    878     _soc_parity_info_t *info;
    879     soc_reg_t status_reg, index_reg;
    880     uint32 addr, reg_val;
    881     int index;
    882 
    883     info = _soc_hu_parity_group_info[group].info;
    884 
    885     status_reg = info[table].intr_status1_reg;
    886     index_reg = info[table].intr_status0_reg;
    887     if (index_reg == INVALIDr) {
    888         LOG_ERROR(BSL_LS_SOC_COMMON,
    889                   (BSL_META_U(unit,
    890                               "unit %d %s parity error\n"),
    891                               unit, msg));
    892         return SOC_E_NONE;
    893     }
    894     if (status_reg != INVALIDr) {
    895         addr = soc_reg_addr(unit, status_reg, block_port, 0);
    896         SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    897         if (reg_val == 0) {
    898             LOG_ERROR(BSL_LS_SOC_COMMON,
    899                       (BSL_META_U(unit,
    900                                   "unit %d %s: parity hardware inconsistency\n"),
    901                        unit, msg));
    902             return SOC_E_NONE;
    903         }
    904     }
    905     addr = soc_reg_addr(unit, index_reg, block_port, 0);
    906     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &reg_val));
    907     index = reg_val;
    908  
    909     LOG_ERROR(BSL_LS_SOC_COMMON,
    910               (BSL_META_U(unit,
    911                           "unit %d %s entry %d parity error\n"),
    912                unit, msg, index));
    913     /* update soc stats for some cases */
    914     if (info[table].error_field == CCP_PAR_ERRf) {
    915         SOC_CONTROL(unit)->stat.err_cpcrc++;
    916     } else if (info[table].error_field == CFAP_PAR_ERRf) {
    917         SOC_CONTROL(unit)->stat.err_cfap++;
    918     } 
    919 
    920     return SOC_E_NONE;
    921 }
    922 
    923 
    924 STATIC int
    925 _soc_hurricane_process_parity_error(int unit)
    926 {
    927     int group, table, index, size;
    928     uint32 addr, cmic_status, group_status, status,
    929         group_enable, cpi_blk_bit;
    930     uint32 entry_idx;
    931     _soc_parity_info_t *info;
    932     soc_reg_t group_reg, reg;
    933     soc_port_t block_port;
    934     soc_block_t blk;
    935     char *msg;
    936     soc_hurricane_oam_handler_t oam_handler_snapshot;
    937 
    938     /* coverity[result_independent_of_operands] */
    939     SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit,
    940                                                            &cmic_status));
    941 
    942     /* loop through each group */
    943     for (group = 0; _soc_hu_parity_group_info[group].cpi_bit; group++) {
    944         info = _soc_hu_parity_group_info[group].info;
    945         group_reg = _soc_hu_parity_group_info[group].status_reg;
    946         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    947                     (BSL_META_U(unit,
    948                                 "unit %d %s parity processing\n"),
    949                                 unit, SOC_REG_NAME(unit, group_reg)));
    950         cpi_blk_bit = _soc_hu_parity_group_info[group].cpi_bit;
    951 
    952         SOC_BLOCK_ITER(unit, blk,
    953                        _soc_hu_parity_group_info[group].blocktype) {
    954             if (_soc_hurricane_parity_block_port(unit, blk, &block_port) < 0) {
    955                 cpi_blk_bit <<= 1;
    956                 continue;
    957             }
    958             if (!(cmic_status & cpi_blk_bit)) {
    959                 cpi_blk_bit <<= 1;
    960                 continue;
    961             }
    962 
    963             addr = soc_reg_addr(unit, group_reg, block_port, 0);
    964             SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_status));
    965 
    966             /* loop through each table in the group */
    967             for (table = 0; info[table].error_field != INVALIDf; table++) {
    968                 if (!soc_reg_field_valid(unit, group_reg,
    969                                          info[table].error_field)) {
    970                     if (info[table].mem != INVALIDm) {
    971                         LOG_ERROR(BSL_LS_SOC_COMMON,
    972                                   (BSL_META_U(unit,
    973                                               "unit %d %s has bad error field\n"),
    974                                               unit, SOC_MEM_NAME(unit, info[table].mem)));
    975                     }
    976                     continue;
    977                 }
    978 
    979                 if (!soc_reg_field_get(unit, group_reg, group_status,
    980                                        info[table].error_field)) {
    981                     continue;
    982                 }
    983                 if (info[table].msg) {
    984                     msg = info[table].msg;
    985                 } else if (info[table].mem != INVALIDm) {
    986                     msg = SOC_MEM_NAME(unit, info[table].mem);
    987                 } else {
    988                     msg = SOC_FIELD_NAME(unit, info[table].error_field);
    989                 }
    990 
    991                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
    992                             (BSL_META_U(unit,
    993                                         "unit %d %s analysis\n"),
    994                                         unit, msg));
    995 
    996                 /* handle different parity error reporting style */
    997                 switch (info[table].type) {
    998                 case _SOC_PARITY_INFO_TYPE_GENERIC:
    999                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1000                               (BSL_META_U(unit,
   1001                                           "unit %d %s asserted\n"),
   1002                                           unit, msg));
   1003                     break;
   1004                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1005                     SOC_IF_ERROR_RETURN
   1006                         (_soc_hurricane_process_single_parity_error(unit,
   1007                               group, block_port, table, FALSE, msg));
   1008                     break;
   1009                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1010                     SOC_IF_ERROR_RETURN
   1011                         (_soc_hurricane_process_single_ecc_error(unit,
   1012                               group, block_port, table, FALSE, msg));
   1013                     break;
   1014                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1015                     SOC_IF_ERROR_RETURN
   1016                         (_soc_hurricane_process_dual_parity_error(unit,
   1017                                        group, block_port, table, FALSE, msg));
   1018                     break;
   1019                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
   1020                     SOC_IF_ERROR_RETURN
   1021                         (_soc_hurricane_process_mmu_parity_error(unit,
   1022                               group, block_port, table, msg));
   1023                     break;
   1024                 case _SOC_PARITY_INFO_TYPE_MMUIPMC:
   1025                     /*
   1026                      * status0 (MEM1_IPMCGRP_TBL_PARITYERRORPTRr) is index
   1027                      * status1 (MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr) is table id
   1028                      *         MMU_IPMC_GROUP_TBL0m - MMU_IPMC_GROUP_TBL8m
   1029                      */
   1030                     reg = info[table].intr_status1_reg;
   1031                     addr = soc_reg_addr(unit, reg, block_port, 0);
   1032                     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status));
   1033                     size = soc_reg_field_length(unit, reg, STATUSf);
   1034                     reg = info[table].intr_status0_reg;
   1035                     for (index = 0; index < size; index++, status >>= 1) {
   1036                         if (!(status & 1)) {
   1037                             continue;
   1038                         }
   1039                         addr = soc_reg_addr(unit, reg, block_port, index);
   1040                         SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr,
   1041                                                            &entry_idx));
   1042                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1043                                   (BSL_META_U(unit,
   1044                                               "unit %d %s%d entry %d parity error\n"),
   1045                                    unit, msg, index, entry_idx));
   1046                     }
   1047                     break;
   1048                 case _SOC_PARITY_INFO_TYPE_MMUWRED:
   1049                     /*
   1050                      * status0 (WRED_PARITY_ERROR_INFOr) is index
   1051                      * status1 (WRED_PARITY_ERROR_BITMAPr) is table id
   1052                      */
   1053                     reg = info[table].intr_status0_reg;
   1054                     addr = soc_reg_addr(unit, reg, block_port, 0);
   1055                     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr,
   1056                                                        &entry_idx));
   1057                     reg = info[table].intr_status1_reg;
   1058                     addr = soc_reg_addr(unit, reg, block_port, 0);
   1059                     SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status));
   1060                     if (status & 0x000003) {
   1061                         msg = "WRED_CFG_CELL";
   1062                     } else if (status & 0x00000c) {
   1063                         msg = "WRED_THD_0_CELL";
   1064                     } else if (status & 0x000030) {
   1065                         msg = "WRED_THD_1_CELL";
   1066                     } else if (status & 0x0000c0) {
   1067                         msg = "WRED_CFG_PACKET";
   1068                     } else if (status & 0x000300) {
   1069                         msg = "WRED_THD_0_PACKET";
   1070                     } else if (status & 0x000c00) {
   1071                         msg = "WRED_THD_1_PACKET";
   1072                     } else if (status & 0x003000) {
   1073                         msg = "WRED_PORT_CFG_CELL";
   1074                     } else if (status & 0x00c000) {
   1075                         msg = "WRED_PORT_THD_0_CELL";
   1076                     } else if (status & 0x030000) {
   1077                         msg = "WRED_PORT_THD_1_CELL";
   1078                     } else if (status & 0x0c0000) {
   1079                         msg = "WRED_PORT_CFG_PACKET";
   1080                     } else if (status & 0x300000) {
   1081                         msg = "WRED_PORT_THD_0_PACKET";
   1082                     } else if (status & 0xc00000) {
   1083                         msg = "WRED_PORT_THD_1_PACKET";
   1084                     } else {
   1085                         break;
   1086                     }
   1087                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1088                               (BSL_META_U(unit,
   1089                                           "unit %d %s entry %d parity error\n"),
   1090                                unit, msg, entry_idx));
   1091                     break;
   1092                 case _SOC_PARITY_INFO_TYPE_OAM:
   1093                     /* OAM isn't parity-related but shares an interrupt */
   1094 
   1095                     oam_handler_snapshot = hu_oam_handler;
   1096 
   1097                     if (oam_handler_snapshot != NULL)
   1098                     {
   1099                         SOC_IF_ERROR_RETURN(oam_handler_snapshot(unit,
   1100                                             info[table].error_field));
   1101                     }
   1102 
   1103                     break;
   1104                 default:
   1105                     break;
   1106                 } /* handle different parity error reporting style */
   1107             } /* loop through each table in the group */
   1108 
   1109             reg = _soc_hu_parity_group_info[group].enable_reg;
   1110             addr = soc_reg_addr(unit, reg, block_port, 0);
   1111             SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_enable));
   1112             group_enable &= ~group_status;
   1113             SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable));
   1114             group_enable |= group_status;
   1115             SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable));
   1116         } /* loop through each block for the group */
   1117     } /* loop through each group */
   1118 
   1119     return SOC_E_NONE;
   1120 }
   1121 
   1122 void
   1123 soc_hurricane_parity_error(void *unit_vp, void *d1, void *d2,
   1124                          void *d3, void *d4)
   1125 {
   1126     int unit = PTR_TO_INT(unit_vp);
   1127 
   1128     _soc_hurricane_process_parity_error(unit);
   1129     soc_intr_enable(unit, IRQ_MEM_FAIL);
   1130 }
   1131 
   1132 STATIC int
   1133 _soc_hurricane_mem_nack_error_process(int unit, soc_mem_t mem, int copyno)
   1134 {
   1135     int group, table;
   1136     _soc_parity_info_t *info;
   1137     soc_port_t block_port;
   1138     soc_block_t blk;
   1139     char *msg;
   1140 
   1141     if (mem == INVALIDm) {
   1142         return SOC_E_PARAM;
   1143     }
   1144 
   1145     /* loop through each group */
   1146     for (group = 0; _soc_hu_parity_group_info[group].cpi_bit; group++) {
   1147         info = _soc_hu_parity_group_info[group].info;
   1148 
   1149         SOC_BLOCK_ITER(unit, blk,
   1150                        _soc_hu_parity_group_info[group].blocktype) {
   1151             if (copyno != blk) {
   1152                 continue;
   1153             }
   1154             if (_soc_hurricane_parity_block_port(unit, blk, &block_port) < 0) {
   1155                 continue;
   1156             }
   1157             /* loop through each table in the group */
   1158             for (table = 0; info[table].error_field != INVALIDf; table++) {
   1159                 if (info[table].mem != mem) {
   1160                     continue;
   1161                 }
   1162                 if (info[table].nack_status0_reg == INVALIDr) {
   1163                     return SOC_E_NOT_FOUND;
   1164                 }
   1165                 if (info[table].msg) {
   1166                     msg = info[table].msg;
   1167                 } else { /* mem must be valid to get her */
   1168                     msg = SOC_MEM_NAME(unit, info[table].mem);
   1169                 }
   1170 
   1171                 /* handle different parity error reporting style */
   1172                 switch (info[table].type) {
   1173                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1174                     SOC_IF_ERROR_RETURN
   1175                         (_soc_hurricane_process_single_parity_error(unit,
   1176                               group, block_port, table, TRUE, msg));
   1177                     break;
   1178                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1179                     SOC_IF_ERROR_RETURN
   1180                         (_soc_hurricane_process_single_ecc_error(unit,
   1181                               group, block_port, table, TRUE, msg));
   1182                     break;
   1183                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1184                     SOC_IF_ERROR_RETURN
   1185                         (_soc_hurricane_process_dual_parity_error(unit,
   1186                               group, block_port, table, TRUE, msg));
   1187                     break;
   1188                 default:
   1189                     break;
   1190                 } /* handle different parity error reporting style */
   1191             } /* loop through each table in the group */
   1192         } /* loop through each block of the group */
   1193     } /* loop through each group */
   1194 
   1195     return SOC_E_NONE;
   1196 }
   1197 
   1198 STATIC int
   1199 _soc_hurricane_mem_ecc_force(int unit, soc_port_t block_port,
   1200                             _soc_parity_info_t *info)
   1201 {
   1202     soc_reg_t force_sbe_reg, force_dbe_reg;
   1203     soc_field_t force_field;
   1204 
   1205     force_field = info->error_field;
   1206     if (force_field == RX_FIFO_MEM_ERRf) {
   1207         force_field = RX_FIFO_MEMf;
   1208     } else if (force_field == TX_FIFO_MEM_ERRf) {
   1209         force_field = TX_FIFO_MEMf;
   1210     }
   1211 
   1212     force_sbe_reg = info->intr_status1_reg;
   1213     force_dbe_reg = info->nack_status1_reg;
   1214 
   1215     /* Single-bit error force */
   1216     if (SOC_REG_IS_VALID(unit, force_sbe_reg) &&
   1217         soc_reg_field_valid(unit, force_sbe_reg, force_field)) {
   1218         SOC_IF_ERROR_RETURN
   1219             (soc_reg_field32_modify(unit, force_sbe_reg,
   1220                                     block_port, force_field, 1));        
   1221     } else {
   1222         LOG_ERROR(BSL_LS_SOC_COMMON,
   1223                   (BSL_META_U(unit,
   1224                               "unit %d %s.%s not valid\n"),
   1225                    unit, SOC_REG_NAME(unit, force_sbe_reg),
   1226                    SOC_FIELD_NAME(unit, force_field)));
   1227     }
   1228 
   1229     sal_usleep(1000); /* Wait for interrupt-mode logic to kick in */
   1230 
   1231     /* Double-bit error force */
   1232     if (SOC_REG_IS_VALID(unit, force_dbe_reg) &&
   1233         soc_reg_field_valid(unit, force_dbe_reg, force_field)) {
   1234         SOC_IF_ERROR_RETURN
   1235             (soc_reg_field32_modify(unit, force_dbe_reg,
   1236                                     block_port, force_field, 1));        
   1237     } else {
   1238         LOG_ERROR(BSL_LS_SOC_COMMON,
   1239                   (BSL_META_U(unit,
   1240                               "unit %d %s.%s not valid\n"),
   1241                    unit, SOC_REG_NAME(unit, force_dbe_reg),
   1242                    SOC_FIELD_NAME(unit, force_field)));
   1243     }
   1244 
   1245     return SOC_E_NONE;
   1246 }
   1247 
   1248 int
   1249 _soc_hurricane_mem_nack_error_test(int unit)
   1250 {
   1251     int group, table, index, rv;
   1252     uint32 tmp_entry[SOC_MAX_MEM_WORDS];
   1253     uint32 parity, rval;
   1254     _soc_parity_info_t *info;
   1255     soc_mem_t mem;
   1256     int	 index_min, index_max, index_range;
   1257     soc_port_t block_port;
   1258     soc_block_t blk;
   1259     soc_field_t par_ecc_field;
   1260 
   1261     /* loop through each group */
   1262     for (group = 0; _soc_hu_parity_group_info[group].cpi_bit; group++) {
   1263         info = _soc_hu_parity_group_info[group].info;
   1264 
   1265         SOC_BLOCK_ITER(unit, blk,
   1266                        _soc_hu_parity_group_info[group].blocktype) {
   1267             if (_soc_hurricane_parity_block_port(unit, blk, &block_port) < 0) {
   1268                 continue;
   1269             }
   1270 
   1271             for (table = 0; info[table].error_field != INVALIDf; table++) {
   1272                 mem = info[table].mem;
   1273                 if (mem == INVALIDm) {
   1274                     continue;
   1275                 }
   1276                 if ((info[table].control_reg == INVALIDr) ||
   1277                     !soc_reg_field_valid(unit, info[table].control_reg,
   1278                                          info[table].enable_field)) {
   1279                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1280                               (BSL_META_U(unit,
   1281                                           "unit %d %s has no parity toggle\n"),
   1282                                unit, SOC_MEM_NAME(unit, mem)));
   1283                     continue;
   1284                 }
   1285 
   1286                 index_min = soc_mem_index_min(unit, mem);
   1287                 index_max = soc_mem_index_max(unit, mem);
   1288                 index_range = index_max - index_min + 1;
   1289                 index = index_min + (index_range / 2);
   1290 
   1291                 if ((rv = soc_mem_write(unit, mem, blk, index,
   1292                                         soc_mem_entry_null(unit, mem))) < 0) {
   1293                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1294                               (BSL_META_U(unit,
   1295                                           "unit %d %s entry %d mem write error\n"),
   1296                                unit, SOC_MEM_NAME(unit, mem), index));
   1297                     continue;
   1298                 }
   1299             
   1300                 /* Disable parity */
   1301                 SOC_IF_ERROR_RETURN
   1302                     (soc_reg_field32_modify(unit, info[table].control_reg,
   1303                                             block_port, info[table].enable_field, 0));
   1304 
   1305                 if ((rv = soc_mem_read(unit, mem, blk, index, tmp_entry)) < 0) {
   1306                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1307                               (BSL_META_U(unit,
   1308                                           "unit %d %s entry %d mem read error\n"),
   1309                                unit, SOC_MEM_NAME(unit, mem), index));
   1310                     continue;
   1311                 }
   1312 
   1313                 switch (info[table].type) {
   1314                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1315                 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER:
   1316                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1317                     par_ecc_field = EVEN_PARITYf;
   1318                     if (mem == L3_ECMP_COUNTm) {
   1319                         par_ecc_field = EVEN_PARITY_0f;
   1320                     }
   1321                     break;
   1322                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1323                     if (block_port != REG_PORT_ANY) {
   1324                         /* Force registers exist */
   1325                         SOC_IF_ERROR_RETURN
   1326                             (_soc_hurricane_mem_ecc_force(unit, block_port,
   1327                                                          &(info[table])));
   1328                     }
   1329                     par_ecc_field = ECCf;
   1330                     break;
   1331                 default:
   1332                     par_ecc_field = INVALIDf;
   1333                 }
   1334 
   1335                 if (!soc_mem_field_valid(unit, mem, par_ecc_field)) {
   1336 #if !defined(SOC_NO_NAMES)
   1337                     if (par_ecc_field == INVALIDf) {
   1338                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1339                                   (BSL_META_U(unit,
   1340                                               "unit %d %s doesn't contain INVALIDf\n"),
   1341                                    unit, SOC_MEM_NAME(unit, mem)));
   1342                     } else {
   1343                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1344                                   (BSL_META_U(unit,
   1345                                               "unit %d %s doesn't contain %s\n"),
   1346                                    unit, SOC_MEM_NAME(unit, mem),
   1347                                    soc_fieldnames[par_ecc_field]));
   1348                     }
   1349 #endif
   1350                     continue;
   1351                 }
   1352 
   1353                 parity =
   1354                     soc_mem_field32_get(unit, mem, tmp_entry, par_ecc_field);
   1355                 parity ^= 0x1; /* Bad parity */
   1356                 soc_mem_field32_set(unit, mem, tmp_entry, par_ecc_field, parity);
   1357             
   1358 
   1359                 if ((rv = soc_mem_write(unit, mem, blk, index, tmp_entry)) < 0) {
   1360                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1361                               (BSL_META_U(unit,
   1362                                           "unit %d %s entry %d mem write error\n"),
   1363                                unit, SOC_MEM_NAME(unit, mem), index));
   1364                     continue;
   1365                 }
   1366             
   1367                 /* Enable parity */
   1368                 SOC_IF_ERROR_RETURN
   1369                     (soc_reg_field32_modify(unit, info[table].control_reg,
   1370                                             block_port, info[table].enable_field, 1));
   1371 
   1372                 if ((rv = soc_mem_read(unit, mem, blk, index, tmp_entry)) < 0) {
   1373                     if (rv == SOC_E_FAIL) {
   1374                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1375                                   (BSL_META_U(unit,
   1376                                               "unit %d NACK received for %s entry %d:\n\t"),
   1377                                    unit, SOC_MEM_NAME(unit, mem), index));
   1378                         if ((rv = _soc_hurricane_mem_nack_error_process(unit,
   1379                                                                        mem, blk)) < 0) {
   1380                             LOG_ERROR(BSL_LS_SOC_COMMON,
   1381                                       (BSL_META_U(unit,
   1382                                                   "unit %d %s entry %d SCHAN NACK analysis failure\n"),
   1383                                        unit, SOC_MEM_NAME(unit, mem), index));
   1384                         }
   1385                     } else {
   1386                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1387                                   (BSL_META_U(unit,
   1388                                               "unit %d %s entry %d mem read error\n"),
   1389                                    unit, SOC_MEM_NAME(unit, mem), index));
   1390                     }
   1391                 } else {
   1392                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1393                               (BSL_META_U(unit,
   1394                                           "unit %d %s entry %d mem parity induction failed\n"),
   1395                                unit, SOC_MEM_NAME(unit, mem), index));
   1396                 }
   1397                 sal_usleep(1000);
   1398             }
   1399         }
   1400     }
   1401 
   1402     /* Apply delay so LEDUP can capture correct status. */
   1403     /* coverity[result_independent_of_operands] */
   1404     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP_CTRLr(unit, &rval));
   1405     soc_reg_field_set(unit,CMIC_LEDUP_CTRLr,
   1406                       &rval, LEDUP_SCAN_START_DELAYf, 0x5);
   1407     /* coverity[result_independent_of_operands] */
   1408     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP_CTRLr(unit, rval));
   1409 
   1410     return SOC_E_NONE;
   1411 }
   1412 
   1413 static int
   1414 soc_hurricane_pipe_mem_clear(int unit)
   1415 {
   1416     uint32              rval;
   1417     int                 pipe_init_usec;
   1418     soc_timeout_t       to;
   1419 
   1420     /*
   1421      * Reset the IPIPE and EPIPE block
   1422      */
   1423     rval = 0;
   1424     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   1425     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1);
   1426     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1);
   1427     /* Set count to # entries in largest IPIPE table, L2_ENTRYm */
   1428     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x8000);
   1429     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   1430 
   1431     rval = 0;
   1432     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   1433     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1);
   1434     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1);
   1435     /* Set count to # entries in largest EPIPE table, EGR_L3_NEXT_HOPm */
   1436     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, 0x4000);
   1437     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   1438 
   1439     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   1440     if (SAL_BOOT_SIMULATION) {
   1441         pipe_init_usec = 10000000;
   1442     } else {
   1443         pipe_init_usec = 50000;
   1444     }
   1445     soc_timeout_init(&to, pipe_init_usec, 0);
   1446 
   1447     /* Wait for IPIPE memory initialization done. */
   1448     do {
   1449         SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval));
   1450         if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) {
   1451             break;
   1452         }
   1453         if (soc_timeout_check(&to)) {
   1454             LOG_WARN(BSL_LS_SOC_COMMON,
   1455                      (BSL_META_U(unit,
   1456                                  "unit %d : ING_HW_RESET timeout\n"), unit));
   1457             break;
   1458         }
   1459     } while (TRUE);
   1460 
   1461     /* Wait for EPIPE memory initialization done. */
   1462     do {
   1463         SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval));
   1464         if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) {
   1465             break;
   1466         }
   1467         if (soc_timeout_check(&to)) {
   1468             LOG_WARN(BSL_LS_SOC_COMMON,
   1469                      (BSL_META_U(unit,
   1470                                  "unit %d : EGR_HW_RESET timeout\n"), unit));
   1471             break;
   1472         }
   1473     } while (TRUE);
   1474 
   1475     rval = 0;
   1476     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   1477     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   1478 
   1479     /* Need to clear ING_PW_TERM_COUNTERS since it's not handled by reset control */
   1480     if (!(SAL_BOOT_QUICKTURN) && SOC_MEM_IS_VALID(unit, ING_PW_TERM_COUNTERSm)) {
   1481         SOC_IF_ERROR_RETURN
   1482             (soc_mem_clear(unit, ING_PW_TERM_COUNTERSm, COPYNO_ALL, TRUE));
   1483     }
   1484     return SOC_E_NONE;
   1485 }
   1486 
   1487 
   1488 #define  HU_NUM_COS  8
   1489 int soc_hu_xq_mem(int unit, soc_port_t port, soc_mem_t *xq)
   1490 {
   1491     soc_mem_t   xq_mems[] = {   MMU_XQ0m,
   1492                                 MMU_XQ1m,
   1493                                 MMU_XQ2m,
   1494                                 MMU_XQ3m,
   1495                                 MMU_XQ4m,
   1496                                 MMU_XQ5m,
   1497                                 MMU_XQ6m,
   1498                                 MMU_XQ7m,
   1499                                 MMU_XQ8m,
   1500                                 MMU_XQ9m,
   1501                                 MMU_XQ10m,
   1502                                 MMU_XQ11m,
   1503                                 MMU_XQ12m,
   1504                                 MMU_XQ13m,
   1505                                 MMU_XQ14m,
   1506                                 MMU_XQ15m,
   1507                                 MMU_XQ16m,
   1508                                 MMU_XQ17m,
   1509                                 MMU_XQ18m,
   1510                                 MMU_XQ19m,
   1511                                 MMU_XQ20m,
   1512                                 MMU_XQ21m,
   1513                                 MMU_XQ22m,
   1514                                 MMU_XQ23m,
   1515                                 MMU_XQ24m,
   1516                                 MMU_XQ25m,
   1517                                 MMU_XQ26m,
   1518                                 MMU_XQ27m,
   1519 								MMU_XQ28m,
   1520 								MMU_XQ29m
   1521                             };
   1522     int max_port;
   1523     max_port = sizeof(xq_mems) / sizeof(xq_mems[0]);
   1524     if (port >= max_port) {
   1525         return(SOC_E_PORT);
   1526     }
   1527     *xq = xq_mems[port];
   1528     return(SOC_E_NONE);
   1529 }
   1530 
   1531 /* Hurricane uses 1.5MB of internal Buffers */
   1532 #define HU_MMU_BUFFER_SIZE		(1.5 * 1024 * 1024) 
   1533 
   1534 /* 24GE + 4HG +1CPU ports */ 
   1535 #define HU_MMU_TOTAL_PORTS		29 
   1536 
   1537 #define HU_MMU_NUM_COS  		8
   1538 #define HU_MMU_CELL_SIZE 		128
   1539 
   1540 /* total cells = 1.5MB/128 = 12288 */
   1541 #define HU_MMU_TOTAL_CELLS 		(HU_MMU_BUFFER_SIZE/HU_MMU_CELL_SIZE)
   1542 
   1543 #define HU_MMU_IN_COS_MIN_CELLS		12
   1544 #define HU_MMU_IN_COS_MIN_XQS		8
   1545 
   1546 /* cos(8) * reserved cells(12) = 96 */
   1547 #define HU_MMU_IN_PORT_STATIC_CELLS	(HU_MMU_IN_COS_MIN_XQS * HU_MMU_IN_COS_MIN_CELLS)
   1548 
   1549 /* ports(29) * per port cells(96) = 2784 */
   1550 #define HU_MMU_TOTAL_STATIC_CELLS	(HU_MMU_TOTAL_PORTS * HU_MMU_IN_PORT_STATIC_CELLS)
   1551 
   1552 /* total cells(12288) - static cells(2784) = 9504 */
   1553 #define HU_MMU_TOTAL_DYNAMIC_CELLS 	(HU_MMU_TOTAL_CELLS - HU_MMU_TOTAL_STATIC_CELLS)
   1554 
   1555 /* Every port has 1536 packet pointers(XQs) */
   1556 #define HU_MMU_IN_PORT_TOTAL_XQS	1536
   1557 /* number of cos(8) * minimum xqs per cos(8) = 64 */
   1558 #define HU_MMU_IN_PORT_STATIC_XQS	(HU_MMU_NUM_COS * HU_MMU_IN_COS_MIN_XQS)
   1559 /* total xqs (1536)- static xqs(64) = 1472 */
   1560 #define HU_MMU_IN_PORT_DYNAMIC_XQS	(HU_MMU_IN_PORT_TOTAL_XQS - HU_MMU_IN_PORT_STATIC_XQS)
   1561 
   1562 #define HU_MMU_MAX_PKT_SIZE		9728
   1563 /* xoff threshold = 80 */
   1564 #define HU_MMU_XOFF_CELL_LIMIT		((HU_MMU_MAX_PKT_SIZE/HU_MMU_CELL_SIZE) + 4)
   1565 
   1566 /* max limit for pri-0 = (xoff threshold(80) + max packet size/128 *2 + 16)*23 */
   1567 #define HU_MMU_MAX_CELL_LIMIT_PRI_0     5704	
   1568 /* max limit for pri-1-7 =  (total xqs/128 * 4)= 1536/128*4 */
   1569 #define HU_MMU_MAX_CELL_LIMIT_PRI_1_7   48	
   1570 
   1571 /* cell limit0 + 7 * cell limit for pri1-7 = 6040 */ 
   1572 #define HU_MMU_DYN_CELL_LIMIT		(HU_MMU_MAX_CELL_LIMIT_PRI_0 +  \
   1573                                          ((HU_MMU_NUM_COS -1) * HU_MMU_MAX_CELL_LIMIT_PRI_1_7))
   1574 
   1575 int
   1576 soc_hurricane_mmu_init(int unit)
   1577 {
   1578     int         cos;
   1579     soc_port_t  port;
   1580     uint32      val, oval, cfap_max_idx, tm;
   1581     int         age[HU_NUM_COS], max_age, min_age;
   1582     int         age_enable, disabled_age;
   1583     int         skid_mark;
   1584     uint32 	dyn_xq_per_port;
   1585     uint32      limit;
   1586     uint32 	xq_limit, pkt_limit, cell_limit;
   1587     uint32      cos_min_xqs, cos_min_cells;
   1588     uint16      dev_id;
   1589     uint8       rev_id;
   1590 
   1591     cfap_max_idx = soc_mem_index_max(unit, MMU_CFAPm); 
   1592     SOC_IF_ERROR_RETURN(READ_CFAPCONFIGr(unit, &val));
   1593     oval = val;
   1594     soc_reg_field_set(unit, CFAPCONFIGr, &val, CFAPPOOLSIZEf, cfap_max_idx);
   1595     if (oval != val) {
   1596         SOC_IF_ERROR_RETURN(WRITE_CFAPCONFIGr(unit, val));
   1597     }
   1598 
   1599     /* set skidmarker to 3 */
   1600     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   1601     soc_reg_field_set(unit, MISCCONFIGr, &val, SKIDMARKERf, 3);
   1602     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val));
   1603 
   1604     /* Every inactive COSQ consumes skid mark + 4 XQs; remove them from pool */
   1605     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   1606     skid_mark = soc_reg_field_get(unit, MISCCONFIGr, val, SKIDMARKERf) + 4;
   1607     
   1608     soc_cm_get_id(unit, &dev_id, &rev_id);
   1609 
   1610     if (dev_id != BCM56147_DEVICE_ID) {
   1611         /* total dynamic xqs - skid mark - 9(reserved xqs) */	
   1612         dyn_xq_per_port = HU_MMU_IN_PORT_DYNAMIC_XQS -  skid_mark - 9;
   1613         /* limit includes the static minimum cells as well */
   1614         xq_limit = dyn_xq_per_port + 8;
   1615         cos_min_xqs = HU_MMU_IN_COS_MIN_XQS;
   1616         cos_min_cells = HU_MMU_IN_COS_MIN_CELLS;
   1617     }
   1618     else {
   1619         /* dynamic xqs = total xqs - static xqs(num of cos * per cos reserve(4)) */
   1620         dyn_xq_per_port = HU_MMU_IN_PORT_TOTAL_XQS - (HU_MMU_NUM_COS * 4); 
   1621         /* total dynamic xqs = dynamic xqs - skid mark - 9(reserved xqs) */	
   1622         dyn_xq_per_port = dyn_xq_per_port -  skid_mark - 9;
   1623         /* limit includes the static minimum cells as well */
   1624         xq_limit = dyn_xq_per_port + 4;
   1625         cos_min_xqs = HU_MMU_IN_COS_MIN_XQS/2;
   1626         cos_min_cells = HU_MMU_IN_COS_MIN_CELLS + 4;
   1627     }
   1628 
   1629     PBMP_ALL_ITER(unit, port) {
   1630 
   1631         for (cos = 0; cos < NUM_COS(unit); cos++) {
   1632             /* 
   1633              * The HOLCOSPKTSETLIMITr register controls BOTH the XQ 
   1634              * size per cosq AND the HOL set limit for that cosq.
   1635              */
   1636             SOC_IF_ERROR_RETURN
   1637                 (READ_HOLCOSPKTSETLIMITr(unit, port, cos, &val));
   1638             soc_reg_field_set(unit, HOLCOSPKTSETLIMITr, &val,
   1639                               PKTSETLIMITf, 
   1640                               xq_limit);
   1641             SOC_IF_ERROR_RETURN
   1642                 (WRITE_HOLCOSPKTSETLIMITr(unit, port, cos, val));
   1643 
   1644             /* reset limit is set limit - 4 */
   1645             SOC_IF_ERROR_RETURN
   1646                 (READ_HOLCOSPKTRESETLIMITr(unit, port, cos, &val));
   1647             soc_reg_field_set(unit, HOLCOSPKTRESETLIMITr, &val,
   1648                               PKTRESETLIMITf, 
   1649                               xq_limit-4);
   1650             SOC_IF_ERROR_RETURN
   1651                 (WRITE_HOLCOSPKTRESETLIMITr(unit, port, cos, val));
   1652 
   1653             val = 0;
   1654             soc_reg_field_set(unit, HOLCOSMINXQCNTr, &val,
   1655                               HOLCOSMINXQCNTf, cos_min_xqs);
   1656             SOC_IF_ERROR_RETURN
   1657                 (WRITE_HOLCOSMINXQCNTr(unit, port, cos, val)); 
   1658 
   1659             val = 0;
   1660             soc_reg_field_set(unit, LWMCOSCELLSETLIMITr, &val,
   1661                               CELLSETLIMITf, cos_min_cells);
   1662             soc_reg_field_set(unit, LWMCOSCELLSETLIMITr, &val,
   1663                               CELLRESETLIMITf, cos_min_cells);
   1664             SOC_IF_ERROR_RETURN
   1665                 (WRITE_LWMCOSCELLSETLIMITr(unit, port, cos, val)); 
   1666               
   1667             cell_limit = 0;
   1668             if (dev_id != BCM56147_DEVICE_ID) {
   1669                 if(!cos) {
   1670                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1671                                       CELLMAXLIMITf, HU_MMU_MAX_CELL_LIMIT_PRI_0);
   1672                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1673                                       CELLMAXRESUMELIMITf, HU_MMU_MAX_CELL_LIMIT_PRI_0 - 12);
   1674                 } else {
   1675                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1676                                       CELLMAXLIMITf, HU_MMU_MAX_CELL_LIMIT_PRI_1_7);
   1677                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1678                                       CELLMAXRESUMELIMITf, HU_MMU_MAX_CELL_LIMIT_PRI_1_7 - 12);
   1679                 }
   1680             } 
   1681             else {
   1682                 /* use the settings given by design team for 56147 */
   1683                 if(!cos) {
   1684                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1685                                       CELLMAXLIMITf, 8000);
   1686                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1687                                       CELLMAXRESUMELIMITf, 7238);
   1688                 } else {
   1689                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1690                                       CELLMAXLIMITf, 7250);
   1691                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   1692                     	              CELLMAXRESUMELIMITf, 7238);
   1693                 }
   1694            }
   1695             SOC_IF_ERROR_RETURN
   1696                 (WRITE_HOLCOSCELLMAXLIMITr(unit, port, cos, cell_limit)); 
   1697         }
   1698 
   1699     val = 0;
   1700     soc_reg_field_set(unit, DYNXQCNTPORTr, &val,
   1701                       DYNXQCNTPORTf, dyn_xq_per_port);
   1702     SOC_IF_ERROR_RETURN(WRITE_DYNXQCNTPORTr(unit, port, val)); 
   1703 
   1704     val = 0;
   1705     soc_reg_field_set(unit, DYNRESETLIMPORTr, &val,
   1706                       DYNRESETLIMPORTf, dyn_xq_per_port - 4);
   1707     SOC_IF_ERROR_RETURN(WRITE_DYNRESETLIMPORTr(unit, port, val)); 
   1708 
   1709     cell_limit = 0;
   1710     soc_reg_field_set(unit, IBPDISCARDSETLIMITr, &cell_limit,
   1711                       DISCARDSETLIMITf, HU_MMU_TOTAL_CELLS-1);
   1712     SOC_IF_ERROR_RETURN(WRITE_IBPDISCARDSETLIMITr(unit, port, cell_limit));
   1713 
   1714     if (dev_id != BCM56147_DEVICE_ID) {
   1715     	val = 0;
   1716     	soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   1717         	              DYNCELLSETLIMITf, HU_MMU_DYN_CELL_LIMIT);
   1718     	soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   1719         	              DYNCELLRESETLIMITf, HU_MMU_DYN_CELL_LIMIT - 24);
   1720     	SOC_IF_ERROR_RETURN(WRITE_DYNCELLLIMITr(unit, port, val)); 
   1721 
   1722     	pkt_limit = 0;
   1723     	soc_reg_field_set(unit, IBPPKTSETLIMITr, &pkt_limit,
   1724         	              PKTSETLIMITf, HU_MMU_IN_COS_MIN_CELLS);
   1725     	SOC_IF_ERROR_RETURN(WRITE_IBPPKTSETLIMITr(unit, port, pkt_limit));    
   1726 
   1727     	cell_limit = 0;
   1728     	soc_reg_field_set(unit, IBPCELLSETLIMITr, &cell_limit, 
   1729         	              CELLSETLIMITf, HU_MMU_XOFF_CELL_LIMIT);   
   1730     	SOC_IF_ERROR_RETURN(WRITE_IBPCELLSETLIMITr(unit, port, cell_limit));
   1731 	}
   1732     else {
   1733         /* use the settings given by design team for 56147 */
   1734     	val = 0;
   1735         /* dyn cell limit = 8000 + (total cos -1)*4*2048/128 */
   1736     	soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   1737         	              DYNCELLSETLIMITf, 8448);
   1738     	soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   1739         	              DYNCELLRESETLIMITf, 8424);
   1740     	SOC_IF_ERROR_RETURN(WRITE_DYNCELLLIMITr(unit, port, val)); 
   1741 
   1742     	pkt_limit = 0;
   1743     	soc_reg_field_set(unit, IBPPKTSETLIMITr, &pkt_limit,
   1744         	              PKTSETLIMITf, 33);
   1745     	SOC_IF_ERROR_RETURN(WRITE_IBPPKTSETLIMITr(unit, port, pkt_limit));    
   1746 
   1747     	cell_limit = 0;
   1748     	soc_reg_field_set(unit, IBPCELLSETLIMITr, &cell_limit, 
   1749         	              CELLSETLIMITf, 36);   
   1750     	SOC_IF_ERROR_RETURN(WRITE_IBPCELLSETLIMITr(unit, port, cell_limit));
   1751    
   1752         /* E2EFC configuration */
   1753         if (IS_HG_PORT(unit, port)){
   1754             SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &val));
   1755             soc_reg_field_set(unit, XPORT_CONFIGr, &val, E2E_IBP_ENf, 1);
   1756             SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, val));
   1757 
   1758             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
   1759             soc_reg_field_set(unit, IE2E_CONTROLr, &val, IBP_ENABLEf, 1);
   1760             SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, val));
   1761 
   1762             val = 0;
   1763             soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val, 
   1764                               LGf, 0);
   1765             soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val, 
   1766                               TIMERf, 1);                
   1767             SOC_IF_ERROR_RETURN(WRITE_E2EFC_HG_MIN_TX_TIMERr(unit, port-26, val));
   1768 
   1769             val = 0;
   1770             soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val, 
   1771                               LGf, 1);
   1772             soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val, 
   1773                               TIMERf, 640);                
   1774             SOC_IF_ERROR_RETURN(WRITE_E2EFC_HG_MAX_TX_TIMERr(unit, port-26, val));
   1775 
   1776             limit = 0;
   1777             soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   1778                               PKT_SET_LIMITf, 1456);
   1779             soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   1780                               CELL_SET_LIMITf, 9504);
   1781             SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_SET_LIMITr(unit, port, limit));
   1782 
   1783             limit = 0;
   1784             soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   1785                               PKT_RESET_LIMITf, 1456);
   1786             soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   1787                               CELL_RESET_LIMITf, 9504);
   1788             SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_RESET_LIMITr(unit, port, limit));
   1789 
   1790             limit = 0;
   1791             soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   1792                               PKT_DISC_LIMITf, 1456);
   1793             soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   1794                               CELL_DISC_LIMITf, 9504);
   1795             SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_DISC_LIMITr(unit, port, limit));
   1796         }
   1797         else {
   1798             limit = 0;
   1799             soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   1800                               PKT_SET_LIMITf, 33);
   1801             soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   1802                               CELL_SET_LIMITf, 36);
   1803             SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_SET_LIMITr(unit, port, limit));
   1804 
   1805             limit = 0;
   1806             soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   1807                               PKT_RESET_LIMITf, 24);
   1808             soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   1809                               CELL_RESET_LIMITf, 26);
   1810             SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_RESET_LIMITr(unit, port, limit));
   1811 
   1812             limit = 0;
   1813             soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   1814                               PKT_DISC_LIMITf, 1456);
   1815             soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   1816                               CELL_DISC_LIMITf, 9504);
   1817             SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_DISC_LIMITr(unit, port, limit));
   1818 
   1819         }
   1820 
   1821 	}
   1822 
   1823     }
   1824 
   1825     /* device specific dynamic cell limit */
   1826     if (dev_id != BCM56147_DEVICE_ID) {
   1827    	cell_limit = 0;
   1828     	soc_reg_field_set(unit, TOTALDYNCELLSETLIMITr,
   1829                           &cell_limit, TOTALDYNCELLSETLIMITf, HU_MMU_TOTAL_DYNAMIC_CELLS);
   1830     	SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLSETLIMITr(unit, cell_limit));
   1831     	cell_limit = 0;
   1832     	soc_reg_field_set(unit, TOTALDYNCELLRESETLIMITr,
   1833                           &cell_limit, TOTALDYNCELLRESETLIMITf, HU_MMU_TOTAL_DYNAMIC_CELLS - 24);
   1834     	SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLRESETLIMITr(unit, cell_limit));
   1835     }
   1836     else {
   1837         cell_limit = 0;
   1838     	soc_reg_field_set(unit, TOTALDYNCELLSETLIMITr,
   1839                           &cell_limit, TOTALDYNCELLSETLIMITf, 8576);
   1840     	SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLSETLIMITr(unit, cell_limit));
   1841     	cell_limit = 0;
   1842     	soc_reg_field_set(unit, TOTALDYNCELLRESETLIMITr,
   1843         	          &cell_limit, TOTALDYNCELLRESETLIMITf, 8552);
   1844     	SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLRESETLIMITr(unit, cell_limit));
   1845 
   1846         /* E2EFC configuration */
   1847         SOC_IF_ERROR_RETURN(READ_E2EFC_IBP_ENr(unit, &val));
   1848         soc_reg_field_set(unit, E2EFC_IBP_ENr, &val, ENf, 1);
   1849         SOC_IF_ERROR_RETURN(WRITE_E2EFC_IBP_ENr(unit, val));
   1850    }
   1851 
   1852     /* 
   1853      * Configure per-XQ packet aging for the various COSQs. 
   1854      *
   1855      * The shortest age allowed by H/W is 250 microseconds.
   1856      * The longest age allowed is 7.162 seconds (7162 msec).
   1857      * The maximum ratio between the longest age and the shortest 
   1858      * (nonzero) age is 7:2.
   1859      */
   1860     age_enable = disabled_age = max_age = 0;
   1861     min_age = 7162;
   1862     for (cos = 0; cos < NUM_COS(unit); cos++) {
   1863         if ((age[cos] = 
   1864              soc_property_suffix_num_get(unit, cos, spn_MMU_XQ_AGING,
   1865                                          "cos",  0)) > 0) {
   1866             age_enable = 1;
   1867             if (age[cos] > 7162) {
   1868                 age[cos] = 7162;
   1869             }
   1870             if (age[cos] < min_age) {
   1871                 min_age = age[cos];
   1872             }
   1873         } else {
   1874             disabled_age = 1;
   1875             age[cos] = 0;
   1876         }
   1877         if (age[cos] > max_age) {
   1878             max_age = age[cos];
   1879         }
   1880     }
   1881     if (!age_enable) {
   1882         /* Disable packet aging on all COSQs */
   1883         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGTIMERr(unit, 0));
   1884         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGLIMITr(unit, 0)); /* Aesthetic */
   1885     } else {
   1886         uint32 regval = 0;
   1887         uint32 timerval;
   1888 
   1889         /* Enforce the 7:2 ratio between min and max values */
   1890         if ((((max_age * 2)+6) / 7) > min_age) {
   1891             /* Keep requested max age; make min_age comply */ 
   1892             min_age = ((max_age * 2) + 6) / 7; 
   1893         }
   1894 
   1895         /* 
   1896          * Give up granularity for range, if we need to
   1897          * "disable" (max out) aging for any COSQ(s).
   1898          */
   1899         if (disabled_age) {
   1900             /* Max range */
   1901             max_age = min_age * 7 / 2;
   1902         } 
   1903 
   1904         /* 
   1905          * Compute shortest duration of one PKTAGINGTIMERr cycle. 
   1906          * This duration is 1/7th of the longest packet age. 
   1907          * This duration is in units of 125 usec (msec * 8).
   1908          */
   1909         timerval = ((8 * max_age) + 6) / 7; 
   1910         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGTIMERr(unit, timerval));
   1911 
   1912         for (cos = 0; cos < NUM_COS(unit); cos++) {
   1913             if (!age[cos]) {
   1914                 /* 
   1915                  * Requested to be disabled, but cannot disable individual
   1916                  * COSQs once packet aging is enabled. Therefore, mark
   1917                  * this COSQ's aging duration as maxed out.
   1918                  */
   1919                 age[cos] = -1;
   1920             } else if (age[cos] < min_age) {
   1921                 age[cos] = min_age;
   1922             }
   1923 
   1924             /* Normalize each "age" into # of PKTAGINGTIMERr cycles. */
   1925 	    if (age[cos] > 0) {
   1926                 /* coverity[divide_by_zero : FALSE] */
   1927 	        age[cos] = ((8 * age[cos]) + timerval - 1) / timerval;
   1928 	    }
   1929 	    else {
   1930 	        age[cos] = 7;
   1931 	    }
   1932             /* Format each "age" for its appropriate field */
   1933             regval |= ((7 - age[cos]) << (cos * 3));
   1934         }
   1935         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGLIMITr(unit, regval));
   1936     }
   1937 
   1938     /* Apply TM=0x10 setting for all CAMs */
   1939     tm=0x10;
   1940     val = 0;
   1941     soc_reg_field_set(unit, SW2_RAM_CONTROL_4r, &val,
   1942                       CPU_COS_MAP_TCAM_TMf, tm);
   1943     SOC_IF_ERROR_RETURN(WRITE_SW2_RAM_CONTROL_4r_REG32(unit, val));
   1944 
   1945     val = 0;
   1946     soc_reg_field_set(unit, L2_USER_ENTRY_CAM_DBGCTRLr, &val,
   1947                       TMf, tm);
   1948     SOC_IF_ERROR_RETURN(WRITE_L2_USER_ENTRY_CAM_DBGCTRLr(unit, val));
   1949 
   1950     
   1951     SOC_IF_ERROR_RETURN(READ_VLAN_SUBNET_CAM_DBGCTRLr(unit, &val));
   1952     soc_reg_field_set(unit, VLAN_SUBNET_CAM_DBGCTRLr, &val,
   1953                       TMf, tm);
   1954     SOC_IF_ERROR_RETURN(WRITE_VLAN_SUBNET_CAM_DBGCTRLr(unit, val));
   1955     
   1956     val = 0;
   1957     soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &val,
   1958                       ALL_TCAMS_TM_7_0f, tm);
   1959     soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &val,
   1960                       ALL_GLOBAL_MASK_TCAMS_TM_7_0f, tm);
   1961     SOC_IF_ERROR_RETURN(WRITE_FP_CAM_CONTROL_TM_7_THRU_0r(unit, val));
   1962 
   1963     /*
   1964      * Port enable
   1965      */
   1966     val = 0;
   1967     soc_reg_field_set(unit, MMUPORTENABLEr, &val, MMUPORTENABLEf,
   1968                       SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0));
   1969     SOC_IF_ERROR_RETURN(WRITE_MMUPORTENABLEr(unit, val));
   1970 
   1971     return SOC_E_NONE;
   1972 }
   1973 
   1974 
   1975 
   1976 uint32 hu_tdm[75] = {2,14,26,27,28,29,
   1977                   3,15,26,27,28,29,
   1978                   4,16,26,27,28,29,
   1979                   5,17,26,27,28,29,
   1980                   0,                  
   1981                   6,18,26,27,28,29,
   1982                   7,19,26,27,28,29,
   1983                   8,20,26,27,28,29,
   1984                   9,21,26,27,28,29,
   1985                   0,
   1986                   10,22,26,27,28,29,
   1987                   11,23,26,27,28,29,
   1988                   12,24,26,27,28,29,
   1989                   13,25,26,27,28,29,
   1990                   30};
   1991 
   1992 int
   1993 soc_hurricane_misc_init(int unit)
   1994 {
   1995 #define NUM_XQPORT 4
   1996     uint32              rval; 
   1997     uint32              prev_reg_addr;
   1998     uint64              reg64;
   1999     int                 port, i;
   2000     uint32              mode;
   2001     uint32              *arr;
   2002     int                 tdm_size;
   2003     iarb_tdm_table_entry_t iarb_tdm;
   2004     mmu_arb_tdm_table_entry_t mmu_arb_tdm;
   2005     uint32              imask;
   2006     soc_field_t         fields[3];
   2007     uint32              values[3];
   2008 
   2009     for (port = 26; port <= 29; port++) {
   2010         if (SOC_PORT_VALID(unit, port)) {
   2011             mode = 1; /* gport mode */
   2012             if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) {
   2013                 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE);
   2014                 mode = 2; /* xport mode */
   2015             } 
   2016             SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
   2017             soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, XQPORT_MODE_BITSf, mode);
   2018             SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval));
   2019         } /* if SOC_PORT_VALID */
   2020     } /* for port= */
   2021 
   2022     SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval));
   2023     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 1);
   2024     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, 83);
   2025     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   2026 
   2027     /* Program for Different TDM mode */
   2028     tdm_size = 75;
   2029     arr = hu_tdm;
   2030     for (i = 0; i < tdm_size; i++) {
   2031         sal_memset(&iarb_tdm, 0, sizeof(iarb_tdm_table_entry_t));
   2032         sal_memset(&mmu_arb_tdm, 0, sizeof(mmu_arb_tdm_table_entry_t));
   2033         soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 
   2034                                         arr[i]);
   2035         soc_MMU_ARB_TDM_TABLEm_field32_set(unit, &mmu_arb_tdm, PORT_NUMf, 
   2036                                        arr[i]); 
   2037         if (i == tdm_size - 1) {
   2038             soc_MMU_ARB_TDM_TABLEm_field32_set(unit, &mmu_arb_tdm, WRAP_ENf, 1);
   2039         }
   2040         SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 
   2041                                                   &iarb_tdm));
   2042         SOC_IF_ERROR_RETURN(WRITE_MMU_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 
   2043                                                  &mmu_arb_tdm));
   2044     }
   2045     rval = 0;
   2046     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0);
   2047     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, 
   2048                       tdm_size -1);
   2049     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   2050 
   2051     if (!SOC_IS_RELOADING(unit)) {
   2052         /* Clear IPIPE/EIPIE Memories */
   2053         SOC_IF_ERROR_RETURN(soc_hurricane_pipe_mem_clear(unit));
   2054     }
   2055 
   2056     /* Turn on ingress/egress/mmu parity */
   2057     if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2058         _soc_hurricane_parity_enable(unit, TRUE);
   2059         if (soc_property_get(unit, "parity_test", FALSE)) {
   2060             _soc_hurricane_mem_nack_error_test(unit);
   2061         }
   2062         memset(&_hurricane_ser_functions, 0, sizeof(soc_ser_functions_t));
   2063         _hurricane_ser_functions._soc_ser_parity_error_intr_f = 
   2064             &soc_hurricane_parity_error;
   2065         soc_ser_function_register(unit, &_hurricane_ser_functions);
   2066     }
   2067     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2068     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   2069     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2070 
   2071     /* Enable dual hash on L2 and L3 tables */
   2072     fields[0] = ENABLEf;
   2073     values[0] = 1;
   2074     fields[1] = HASH_SELECTf;
   2075     values[1] = FB_HASH_CRC32_LOWER;
   2076     fields[2] = INSERT_LEAST_FULL_HALFf;
   2077     values[2] = 1;
   2078     SOC_IF_ERROR_RETURN
   2079         (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   2080                                  fields, values));
   2081     SOC_IF_ERROR_RETURN
   2082         (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   2083                                  fields, values));
   2084 
   2085     /*
   2086      * Egress Enable
   2087      */
   2088     rval = 0;
   2089     soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1);
   2090     PBMP_ALL_ITER(unit, port) {
   2091         SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval));
   2092     }
   2093 
   2094     COMPILER_64_ZERO(reg64);
   2095     soc_reg64_field32_set(unit, EPC_LINK_BMAP_64r, &reg64, PORT_BITMAP_LOf,
   2096                           SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 0));
   2097     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAP_64r(unit, reg64));
   2098 
   2099     /* GMAC init should be moved to mac */
   2100     rval = 0;
   2101     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1);
   2102     prev_reg_addr = 0xffffffff;
   2103     PBMP_E_ITER(unit, port) {
   2104         uint32  reg_addr;
   2105         if (IS_XQ_PORT(unit, port)) {
   2106             continue;
   2107         }
   2108         reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0);
   2109         if (reg_addr != prev_reg_addr) {
   2110             SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2111             prev_reg_addr = reg_addr;
   2112         }
   2113     }
   2114     prev_reg_addr = 0xffffffff;
   2115     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0);
   2116     PBMP_E_ITER(unit, port) {
   2117         uint32  reg_addr;
   2118         if (IS_XQ_PORT(unit, port)) {
   2119             continue;
   2120         }
   2121         reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0);
   2122         if (reg_addr != prev_reg_addr) {
   2123             SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2124             prev_reg_addr = reg_addr;
   2125         }
   2126     }
   2127 
   2128     /* XMAC init should be moved to mac */
   2129     if (SOC_PBMP_NOT_NULL(PBMP_XE_ALL(unit)) ||
   2130         SOC_PBMP_NOT_NULL(PBMP_HG_ALL(unit))) {
   2131         rval = 0;
   2132         soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1);
   2133         soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
   2134         PBMP_HG_ITER(unit, port) {
   2135             SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval));
   2136         }
   2137         soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0);
   2138         PBMP_XE_ITER(unit, port) {
   2139             SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval));
   2140         }
   2141     }
   2142 
   2143     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &reg64));
   2144     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2145                           L3SRC_HIT_ENABLEf, 1);
   2146     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2147                           L2DST_HIT_ENABLEf, 1);
   2148     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2149                           APPLY_EGR_MASK_ON_L2f, 1);
   2150     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2151                           APPLY_EGR_MASK_ON_L3f, 1);
   2152     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2153                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
   2154     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2155                           ARP_VALIDATION_ENf, 1);
   2156     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   2157                           IGNORE_HG_HDR_LAG_FAILOVERf, 1);
   2158     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64));
   2159 
   2160     SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval));
   2161     soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, RING_MODEf, 1);
   2162     SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval));
   2163 
   2164     /*
   2165      * Set reference clock (based on 200MHz core clock)
   2166      * to be 200MHz * (1/40) = 5MHz
   2167      */
   2168     rval = 0;
   2169     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, 40);
   2170     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, 1);
   2171     /* coverity[result_independent_of_operands] */
   2172     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval));
   2173 
   2174     /* Match the Internal MDC freq with above for External MDC */
   2175     rval = 0;
   2176     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 40);
   2177     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 1);
   2178     /* coverity[result_independent_of_operands] */
   2179     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval));
   2180 
   2181     /*
   2182      * Set reference clock (based on 200MHz core clock)
   2183      * to be 200MHz * (1/8) = 25MHz
   2184      */
   2185     rval = 0;
   2186     soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVISORf,  8);
   2187     soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVIDENDf, 1);
   2188     /* coverity[result_independent_of_operands] */
   2189     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval));
   2190 
   2191     rval = 0;
   2192     soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVISORf,  8);
   2193     soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVIDENDf, 1);
   2194     /* coverity[result_independent_of_operands] */
   2195     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval));
   2196 
   2197     rval = 0x01; /* 125KHz I2C sampling rate based on 5Mhz reference clock */
   2198     /* coverity[result_independent_of_operands] */
   2199     SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval));
   2200 
   2201     /* GMAC init should be moved to mac */
   2202     rval = 0;
   2203     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1);
   2204     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, GPORT_ENf, 1);
   2205     PBMP_E_ITER(unit, port) {
   2206         if (IS_XQ_PORT(unit, port)) {
   2207             continue;
   2208         }
   2209         SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2210     }
   2211     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0);
   2212     PBMP_E_ITER(unit, port) {
   2213         if (IS_XQ_PORT(unit, port)) {
   2214             continue;
   2215         }
   2216         SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   2217     }
   2218 
   2219     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
   2220      * causes the outer tag to be removed from packets that don't have
   2221      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
   2222      */
   2223     rval = 0;
   2224     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
   2225 
   2226     /* Enable pri/cfi remarking on egress ports. */
   2227     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,
   2228                       1);
   2229     PBMP_ALL_ITER(unit, port) {
   2230         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval));
   2231     }
   2232 
   2233     /* Multicast range initialization */
   2234     SOC_IF_ERROR_RETURN
   2235         (soc_hbx_higig2_mcast_sizes_set(unit,
   2236              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
   2237                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   2238              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
   2239                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   2240              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
   2241                               SOC_HBX_MULTICAST_RANGE_DEFAULT)));
   2242 
   2243     /* Setup SW2_FP_DST_ACTION_CONTROL */
   2244     fields[0] = HGTRUNK_RES_ENf;
   2245     fields[1] = LAG_RES_ENf;
   2246     values[0] = values[1] = 1;
   2247     SOC_IF_ERROR_RETURN
   2248         (soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr,
   2249                                  REG_PORT_ANY, 2, fields, values));
   2250 
   2251     /* Enable MMU parity error interrupt */
   2252     SOC_IF_ERROR_RETURN(WRITE_MEMFAILINTSTATUSr(unit, 0));
   2253     SOC_IF_ERROR_RETURN(READ_MEMFAILINTMASKr(unit, &imask));
   2254     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2255                       CFAPPARITYERRORINTMASKf, 1);
   2256     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2257                       CCPPARITYERRORINTMASKf, 1);
   2258     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2259                       CBPPKTHDRPARITYERRORINTMASKf, 1);
   2260     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2261                       CBPCELLHDRPARITYERRORINTMASKf, 1);
   2262     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2263                       XQPARITYERRORINTMASKf, 1);
   2264     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2265                       CELLECCERRORINTMASKf, 1);
   2266     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2267                       CFAPFAILINTMASKf, 1);
   2268     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2269                       SOFTRESETINTMASKf, 1);
   2270     soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2271                       CELLNOTIPINTMASKf, 1);
   2272     if (soc_feature(unit, soc_feature_ip_mcast_repl)) {
   2273         soc_reg_field_set(unit, MEMFAILINTMASKr, &imask,
   2274                           IPMCREPOVERLIMITERRORINTMASKf, 1);
   2275     }
   2276     SOC_IF_ERROR_RETURN(WRITE_MEMFAILINTMASKr(unit, imask));
   2277 
   2278     /* Directed Mirroring ON by default except for CPU port */
   2279     /* The src_port info will be changed as egress port if EM_SRCMOD_CHANGEf = 1 */
   2280     PBMP_PORT_ITER(unit, port) {
   2281         SOC_IF_ERROR_RETURN(READ_EGR_PORTr(unit, port, &rval));
   2282         soc_reg_field_set(unit, EGR_PORTr, &rval, EM_SRCMOD_CHANGEf, 1);
   2283         SOC_IF_ERROR_RETURN(WRITE_EGR_PORTr(unit, port, rval));
   2284         SOC_IF_ERROR_RETURN(READ_IEGR_PORTr(unit, port, &rval));
   2285         soc_reg_field_set(unit, IEGR_PORTr, &rval, EM_SRCMOD_CHANGEf, 1);
   2286         SOC_IF_ERROR_RETURN(WRITE_IEGR_PORTr(unit, port, rval));
   2287     }
   2288     /* Apply delay so LEDUP can capture correct status. */
   2289     /* coverity[result_independent_of_operands] */
   2290     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP_CTRLr(unit, &rval));
   2291     soc_reg_field_set(unit,CMIC_LEDUP_CTRLr,
   2292                      &rval, LEDUP_SCAN_START_DELAYf, 0x5);
   2293     /* coverity[result_independent_of_operands] */
   2294     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP_CTRLr(unit, rval));
   2295 
   2296     return SOC_E_NONE;
   2297 }
   2298 
   2299 int
   2300 soc_hurricane_age_timer_get(int unit, int *age_seconds, int *enabled)
   2301 {
   2302     uint32 value;
   2303 
   2304     SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &value));
   2305     *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_ENAf);
   2306     *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_VALf);
   2307 
   2308     return SOC_E_NONE;
   2309 }
   2310 
   2311 int
   2312 soc_hurricane_age_timer_max_get(int unit, int *max_seconds)
   2313 {
   2314     *max_seconds =
   2315         soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
   2316 
   2317     return SOC_E_NONE;
   2318 }
   2319 
   2320 int
   2321 soc_hurricane_age_timer_set(int unit, int age_seconds, int enable)
   2322 {
   2323     uint32 value;
   2324 
   2325     value = 0;
   2326     soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_ENAf, enable);
   2327     soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_VALf, age_seconds);
   2328     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, value));
   2329 
   2330     return SOC_E_NONE;
   2331 }
   2332 
   2333 void soc_hurricane_oam_handler_register(soc_hurricane_oam_handler_t handler)
   2334 {
   2335     hu_oam_handler = handler;
   2336 }
   2337 
   2338 int
   2339 soc_hu_xqport_mode_change(int unit, soc_port_t port, soc_mac_mode_t mode)
   2340 {
   2341     int rv = SOC_E_NONE;
   2342     uint32 old_bits, bits, rval, to_usec, max_sz;
   2343     uint64 rval64, max_sz64;
   2344     soc_field_t xq_rst2 = INVALIDf;
   2345     soc_field_t ep_port_rst = INVALIDf;
   2346     soc_field_t ep_mmu_rst = INVALIDf;
   2347     mac_driver_t *macd;
   2348     int autoneg, autoneg_done, speed, duplex, enable, master;
   2349     int pause_rx, pause_tx, dual_modid;
   2350     soc_port_ability_t ability;
   2351     soc_reg_t           reg;
   2352     int reset_sleep_usec;
   2353     int hypercore_mixed_mode = 0;
   2354 
   2355     if (!SOC_PORT_VALID(unit, port)) {
   2356         return SOC_E_PORT;
   2357     }
   2358 
   2359     hypercore_mixed_mode =
   2360         soc_property_get(unit, spn_BCM5614X_HYPERCORE_MIXED_MODE, 0);
   2361 
   2362     sal_memset(&ability, 0, sizeof(soc_port_ability_t));
   2363 
   2364     SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
   2365     old_bits = soc_reg_field_get(unit, XQPORT_MODE_REGr, rval,
   2366                                  XQPORT_MODE_BITSf);
   2367     bits = mode == SOC_MAC_MODE_10000 ? 2 : 1;
   2368     if (bits == old_bits) {
   2369         return SOC_E_NONE;
   2370     }
   2371 
   2372     to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) :
   2373                                    (10 * MILLISECOND_USEC);
   2374 
   2375     /* get current MAC and PHY settings */
   2376     SOC_IF_ERROR_RETURN(soc_phyctrl_auto_negotiate_get(unit, port, &autoneg,
   2377                                                        &autoneg_done));
   2378     SOC_IF_ERROR_RETURN(soc_phyctrl_ability_advert_get(unit, port, &ability));
   2379     SOC_IF_ERROR_RETURN(soc_phyctrl_speed_get(unit, port, &speed));
   2380     SOC_IF_ERROR_RETURN(soc_phyctrl_duplex_get(unit, port, &duplex));
   2381     SOC_IF_ERROR_RETURN(soc_phyctrl_enable_get(unit, port, &enable));
   2382     SOC_IF_ERROR_RETURN(soc_phyctrl_master_get(unit, port, &master));
   2383 
   2384     SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd));
   2385     SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &pause_tx, &pause_rx));
   2386     SOC_IF_ERROR_RETURN(READ_MAC_CNTMAXSZr(unit, port, &max_sz64));
   2387     SOC_IF_ERROR_RETURN(READ_QPORT_CNTMAXSIZEr(unit, port, &max_sz));
   2388 
   2389     SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd));
   2390 
   2391     /* Disable MAC TX and RX */
   2392     SOC_IF_ERROR_RETURN(MAC_ENABLE_SET(macd, unit, port, FALSE));
   2393 
   2394     /* Change the XQPORT block mode */
   2395     SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
   2396     soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, 
   2397                       XQPORT_MODE_BITSf, bits);
   2398     SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval));
   2399     
   2400     /* Disable MAC TX and RX */
   2401     SOC_IF_ERROR_RETURN(MAC_ENABLE_SET(macd, unit, port, FALSE));
   2402 
   2403     /* Block linkscan and sbus access */
   2404     soc_linkscan_pause(unit);
   2405     COUNTER_LOCK(unit);
   2406     /* Egress disable */
   2407     rval = 0;
   2408     soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 0);
   2409     SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval));
   2410     sal_usleep(to_usec);
   2411 
   2412     if (hypercore_mixed_mode == 0) {
   2413         /* Disable mixed mode speed for XQPorts belongig to same hypercore.
   2414         * In this mode changing speed on XQPort connected to lane0 impacts the setting on
   2415         * XQPort connected to lane2.*/
   2416         switch (port) {
   2417             case 26:
   2418                 ep_port_rst = EGR_XQP0_PORT_INT_RESETf;
   2419                 ep_mmu_rst = EGR_XQP0_MMU_INT_RESETf;
   2420                 xq_rst2 = XQ0_HOTSWAP_RST_Lf;
   2421                 break;
   2422             case 27:
   2423                 ep_port_rst = EGR_XQP1_PORT_INT_RESETf;
   2424                 ep_mmu_rst = EGR_XQP1_MMU_INT_RESETf;
   2425                 xq_rst2 = XQ1_HOTSWAP_RST_Lf;
   2426                 break;
   2427             case 28:
   2428                 ep_port_rst = EGR_XQP2_PORT_INT_RESETf;
   2429                 ep_mmu_rst = EGR_XQP2_MMU_INT_RESETf;
   2430                 xq_rst2 = XQ2_HOTSWAP_RST_Lf;
   2431                 break;
   2432             case 29:
   2433                 ep_port_rst = EGR_XQP3_PORT_INT_RESETf;
   2434                 ep_mmu_rst = EGR_XQP3_MMU_INT_RESETf;
   2435                 xq_rst2 = XQ3_HOTSWAP_RST_Lf;
   2436                 break;
   2437             default:
   2438                 return SOC_E_PORT;
   2439         }
   2440 
   2441         /* Hold the XQPORT hotswap reset */
   2442         rval = 0;
   2443         /* coverity[result_independent_of_operands] */
   2444         SOC_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REGr(unit, &rval));
   2445         soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, xq_rst2, 0);
   2446         /* coverity[result_independent_of_operands] */
   2447         SOC_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REGr(unit, rval));
   2448         sal_usleep(to_usec);
   2449 
   2450         /* Clear the ECRC register */
   2451         SOC_IF_ERROR_RETURN(WRITE_EGRESSCELLREQUESTCOUNTr(unit, port, 0));
   2452 
   2453         /* Reset the EP */
   2454         SOC_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval));
   2455         soc_reg_field_set(unit, EDATABUF_XQP_FLEXPORT_CONFIGr, &rval,
   2456                 ep_port_rst, 1);
   2457         soc_reg_field_set(unit, EDATABUF_XQP_FLEXPORT_CONFIGr, &rval,
   2458                 ep_mmu_rst, 1);
   2459         SOC_IF_ERROR_RETURN(WRITE_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, rval));
   2460         sal_usleep(to_usec);
   2461 
   2462         SOC_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval));
   2463         soc_reg_field_set(unit, EDATABUF_XQP_FLEXPORT_CONFIGr, &rval,
   2464                 ep_port_rst, 0);
   2465         soc_reg_field_set(unit, EDATABUF_XQP_FLEXPORT_CONFIGr, &rval,
   2466                 ep_mmu_rst, 0);
   2467         SOC_IF_ERROR_RETURN(WRITE_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, rval));
   2468         sal_usleep(to_usec);
   2469 
   2470         /* Bring the XQPORT block out of reset */
   2471         /* coverity[result_independent_of_operands] */
   2472         SOC_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REGr(unit, &rval));
   2473         soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, xq_rst2, 1);
   2474         /* coverity[result_independent_of_operands] */
   2475         SOC_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REGr(unit, rval));
   2476         sal_usleep(to_usec);
   2477 
   2478         /* Bring the hyperlite out of reset */
   2479         soc_xgxs_reset(unit, port);
   2480         SOC_IF_ERROR_RETURN(
   2481             soc_reg_field32_modify(unit, XQPORT_XGXS_NEWCTL_REGr,
   2482             port, TXD1G_FIFO_RSTBf, 0xf));
   2483 
   2484         /* Port probe and initialization */
   2485         PHY_FLAGS_CLR(unit,port,~PHY_FLAGS_INIT_DONE);
   2486         SOC_COUNTER_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
   2487         SOC_COUNTER_IF_ERROR_RETURN(soc_phyctrl_probe(unit, port));
   2488         SOC_COUNTER_IF_ERROR_RETURN(soc_phyctrl_init(unit, port));
   2489         /* end of disable mixed mode in hypercore */
   2490     } else {
   2491         /* Enable mixed mode speed for XQPorts belongig to same hypercore.
   2492         * In this mode, the XQPorts support mixed mode speed
   2493         * without switch reset. Changing speed on a XQPort does not impact the
   2494         * settings on the other XQPort in the same hypercore */
   2495 
   2496         /* Bring the hyperlite out of reset */
   2497         reset_sleep_usec = 1100;
   2498         reg = MAC_XGXS_CTRLr;
   2499 
   2500         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2501         soc_reg64_field32_set(unit, reg, &rval64, LCREFENf, 1);
   2502         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2503 
   2504         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2505         soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   2506         soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   2507         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 1);
   2508         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2509         sal_usleep(reset_sleep_usec);
   2510 
   2511         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2512         soc_reg64_field32_set(unit, reg, &rval64, AFIFO_RSTf, 1);
   2513         soc_reg64_field32_set(unit, reg, &rval64, TXFIFO_RSTLf, 0);
   2514         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2515         sal_usleep(reset_sleep_usec);
   2516 
   2517         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2518         soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   2519         soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   2520         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2521         sal_usleep(reset_sleep_usec);
   2522 
   2523         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2524         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 1);
   2525         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2526         sal_usleep(reset_sleep_usec);
   2527 
   2528         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2529         soc_reg64_field32_set(unit, reg, &rval64, RSTB_MDIOREGSf, 1);
   2530         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2531         sal_usleep(reset_sleep_usec);
   2532 
   2533         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2534         soc_reg64_field32_set(unit, reg, &rval64, RSTB_PLLf, 1);
   2535         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2536         sal_usleep(reset_sleep_usec);
   2537 
   2538         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2539         soc_reg64_field32_set(unit, reg, &rval64, BIGMACRSTLf, 1);
   2540         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2541 
   2542         /* Bring Tx FIFO out of reset */
   2543         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   2544         soc_reg64_field32_set(unit, reg, &rval64, TXFIFO_RSTLf, 1);
   2545         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   2546 
   2547         SOC_IF_ERROR_RETURN(
   2548             soc_reg_field32_modify(unit, XQPORT_XGXS_NEWCTL_REGr,
   2549             port, TXD1G_FIFO_RSTBf, 0xf));
   2550         /* end of enable mixed mode in hypercore */
   2551     }
   2552 
   2553     /* Change the XQPORT block mode */
   2554     SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
   2555     soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, 
   2556                       XQPORT_MODE_BITSf, bits);
   2557     SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval));
   2558 
   2559     /* Need to reset the Bigmac to make registers accessible */
   2560     SOC_IF_ERROR_RETURN(READ_MAC_CTRLr(unit, port, &rval64));
   2561     soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, TXRESETf, 0);
   2562     soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, RXRESETf, 0);
   2563     SOC_IF_ERROR_RETURN(WRITE_MAC_CTRLr(unit, port, rval64));
   2564 
   2565     /* restore PHY setting */
   2566     SOC_IF_ERROR_RETURN(soc_phyctrl_auto_negotiate_set(unit, port, autoneg));
   2567     SOC_IF_ERROR_RETURN(soc_phyctrl_ability_advert_set(unit, port, &ability));
   2568     if (!autoneg) {
   2569         SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, speed));
   2570         SOC_IF_ERROR_RETURN(soc_phyctrl_duplex_set(unit, port, duplex));
   2571     }
   2572     SOC_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, enable));
   2573     SOC_IF_ERROR_RETURN(soc_phyctrl_master_set(unit, port, master));
   2574 
   2575     if (mode == SOC_MAC_MODE_10000) {
   2576         soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE);
   2577     } else {
   2578         soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE);
   2579     }
   2580 
   2581     /* Port probe and initialization */
   2582     SOC_IF_ERROR_RETURN(MAC_INIT(macd, unit, port));
   2583 
   2584     /* Restore previous MAC settings */
   2585     SOC_IF_ERROR_RETURN(MAC_ENABLE_SET(macd, unit, port, enable));
   2586     SOC_IF_ERROR_RETURN(MAC_PAUSE_SET(macd, unit, port, pause_tx, pause_rx));
   2587 
   2588     /* Restore XQPORT registers that may have been reset */
   2589     dual_modid = (NUM_MODID(unit) == 2) ? 1 : 0;
   2590     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMODID_ENr, port,
   2591                                                DUAL_MODID_ENf, dual_modid));
   2592     SOC_IF_ERROR_RETURN(WRITE_MAC_CNTMAXSZr(unit, port, max_sz64));
   2593     SOC_IF_ERROR_RETURN(WRITE_QPORT_CNTMAXSIZEr(unit, port, max_sz));
   2594 
   2595     /* Enable MAC TX and RX */
   2596     SOC_IF_ERROR_RETURN(MAC_ENABLE_SET(macd, unit, port, TRUE));
   2597 
   2598     /* Egress Enable */
   2599     rval = 0;
   2600     soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1);
   2601     SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval));
   2602 
   2603     /* Resume sbus access and linkscan */
   2604     COUNTER_UNLOCK(unit);
   2605     soc_linkscan_continue(unit);
   2606     return rv;
   2607 }
   2608 #endif /* BCM_HURRICANE_SUPPORT */