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

hurricane2.c (256043B)


      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:        hurricane2.c
      8  * Purpose:
      9  * Requires:    
     10  */
     11 
     12 
     13 #include <shared/bsl.h>
     14 
     15 #include <sal/core/boot.h>
     16 #include <shared/bsl.h>
     17 #include <soc/firebolt.h>
     18 #include <soc/bradley.h>
     19 #include <soc/hurricane2.h>
     20 #include <soc/drv.h>
     21 #include <soc/mem.h>
     22 #include <soc/hash.h>
     23 #include <soc/lpm.h>
     24 #include <soc/error.h>
     25 #include <soc/debug.h>
     26 #include <soc/er_tcam.h>
     27 #include <soc/memtune.h>
     28 #include <soc/devids.h>
     29 #include <soc/mspi.h>
     30 
     31 #include <shared/util.h>
     32 #include <shared/l3.h>
     33 #include <soc/soc_ser_log.h>
     34 
     35 
     36 #ifdef BCM_HURRICANE2_SUPPORT
     37 
     38 #define SOC_MAX_PHY_PORTS            34
     39 
     40 /*
     41  * Enduro chip driver functions.  
     42  */
     43 soc_functions_t soc_hurricane2_drv_funs = {
     44     soc_hurricane2_misc_init,
     45     soc_hurricane2_mmu_init,
     46     soc_hurricane2_age_timer_get,
     47     soc_hurricane2_age_timer_max_get,
     48     soc_hurricane2_age_timer_set,
     49 };
     50 
     51 typedef enum {
     52     _SOC_PARITY_INFO_TYPE_GENERIC,
     53     _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
     54     _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
     55     _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
     56     _SOC_PARITY_INFO_TYPE_MMU_PARITY,
     57     _SOC_PARITY_INFO_TYPE_MMU_IPMC,
     58     _SOC_PARITY_INFO_TYPE_MMU_E2EFC,
     59     _SOC_PARITY_INFO_TYPE_OAM, /* Not parity, but same interrupt */
     60     _SOC_PARITY_INFO_TYPE_NUM
     61 } _soc_parity_info_type_t;
     62 
     63 typedef struct _soc_parity_info_s {
     64     soc_field_t             enable_field;
     65     soc_field_t             error_field;
     66     char                    *msg;
     67     soc_mem_t               mem;
     68     _soc_parity_info_type_t type;
     69     soc_reg_t               control_reg;
     70     soc_reg_t               intr_status0_reg;
     71     soc_reg_t               intr_status1_reg; /* Also SBE force for ECC */
     72     soc_reg_t               nack_status0_reg;
     73     soc_reg_t               nack_status1_reg; /* Also DBE force for ECC */
     74 } _soc_parity_info_t;
     75 
     76 /*
     77  *    _SOC_PARITY_INFO_TYPE_SINGLE_PARITY
     78  *      PARITY_EN
     79  *      ENTRY_IDX, MULTIPLE_ERR, PARITY_ERR
     80  *
     81  *    _SOC_PARITY_INFO_TYPE_SINGLE_ECC
     82  *      ECC_EN
     83  *      ENTRY_IDX, DOUBLE_BIT_ERR, MULTIPLE_ERR, ECC_ERR
     84  *
     85  *    _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER
     86  *      PARITY_EN
     87  *      PORT_IDX, COUNTER_IDX, MULTIPLE_ERR, PARITY_ERR
     88  *
     89  *    _SOC_PARITY_INFO_TYPE_DUAL_PARITY
     90  *      PARITY_EN
     91  *      BUCKET_IDX, MULTIPLE_ERR, PARITY_ERR_BM
     92  */
     93 
     94 STATIC _soc_parity_info_t _soc_hu2_ip0_parity_info[] = {
     95     { PARITY_ENf, VXLT_PAR_ERRf,"VLAN_XLATE table parity error",
     96       VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
     97       VLAN_XLATE_PARITY_CONTROLr,
     98       VLAN_XLATE_PARITY_STATUS_0r, VLAN_XLATE_PARITY_STATUS_1r,
     99       INVALIDr, INVALIDr },
    100  /* { PPA_CMD_COMPLETEf }, */
    101  /* { MEM_RESET_COMPLETEf }, */
    102  /* { AGE_CMD_COMPLETEf }, */
    103     { PARITY_ENf, VLAN_SUBNET_DATA_PARITY_ERRf, "VLAN_SUBNET_DATA table parity error",
    104       VLAN_SUBNET_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    105       VLAN_SUBNET_DATA_PARITY_CONTROLr,
    106       VLAN_SUBNET_DATA_PARITY_STATUSr, INVALIDr,
    107       INVALIDr, INVALIDr },
    108     { PARITY_ENf, VLAN_PROTOCOL_DATA_PARITY_ERRf, "VLAN_PROTOCOL_DATA table parity error",
    109       VLAN_PROTOCOL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    110       VLAN_PROTOCOL_DATA_PARITY_CONTROLr,
    111       VLAN_PROTOCOL_DATA_PARITY_STATUSr, INVALIDr,
    112       INVALIDr, INVALIDr },
    113     { PARITY_ENf, VLAN_PARITY_ERRf, "VLAN table parity error",
    114       VLAN_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    115       VLAN_PARITY_CONTROLr,
    116       VLAN_PARITY_STATUSr, INVALIDr,
    117       INVALIDr, INVALIDr },
    118     { PARITY_ENf, VLAN_STG_PARITY_ERRf, "VLAN_STG table parity error",
    119       STG_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    120       VLAN_STG_PARITY_CONTROLr,
    121       VLAN_STG_PARITY_STATUSr, INVALIDr,
    122       INVALIDr, INVALIDr },
    123     /* { PARITY_ENf, L3_TUNNEL_RAM_PARITY_ERRf, "L3_TUNNEL_RAM table parity error",
    124       L3_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    125       L3_TUNNEL_DATA_ONLY_PARITY_CONTROLr,
    126       L3_TUNNEL_DATA_ONLY_PARITY_STATUSr, INVALIDr,
    127       INVALIDr, INVALIDr }, */
    128     { PARITY_ENf, SOURCE_TRUNK_MAP_PARITY_ERRf, "SOURCE_TRUNK_MAP table parity error",
    129       SOURCE_TRUNK_MAP_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    130       SOURCE_TRUNK_MAP_PARITY_CONTROLr,
    131       SOURCE_TRUNK_MAP_PARITY_STATUSr, INVALIDr,
    132       INVALIDr, INVALIDr },
    133     { PARITY_ENf, VFP_POLICY_PAR_ERRf, "VFP_POLICY table parity error",
    134       VFP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    135       VFP_POLICY_PARITY_CONTROLr,
    136       VFP_POLICY_PARITY_STATUS_INTRr, INVALIDr,
    137       INVALIDr, INVALIDr },
    138     { PARITY_ENf, LMEP_PAR_ERRf, "LMEP table parity error",
    139       LMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    140       LMEP_PARITY_CONTROLr,
    141       LMEP_PARITY_STATUSr, INVALIDr,
    142       INVALIDr, INVALIDr },
    143     { ECC_ENf, IARB_PKT_ECC_INTRf, "Iarb packet ecc error",
    144       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    145       IARB_PKT_ECC_CONTROLr,
    146       IARB_PKT_ECC_STATUS_INTRr, INVALIDr,
    147       INVALIDr, INVALIDr },
    148     /* IARB_HDR_ECC_INTR, no control/status regiters */
    149     { INVALIDf, INVALIDf }, /* table terminator */
    150 };
    151 
    152 STATIC _soc_parity_info_t _soc_wf_ip0_parity_info[] = {
    153     { PARITY_ENf, VXLT_PAR_ERRf,"VLAN_XLATE table parity error",
    154       VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    155       VLAN_XLATE_PARITY_CONTROLr,
    156       VLAN_XLATE_PARITY_STATUS_0r, VLAN_XLATE_PARITY_STATUS_1r,
    157       INVALIDr, INVALIDr },
    158  /* { PPA_CMD_COMPLETEf }, */
    159  /* { MEM_RESET_COMPLETEf }, */
    160  /* { AGE_CMD_COMPLETEf }, */
    161     { PARITY_ENf, VLAN_SUBNET_DATA_PARITY_ERRf, "VLAN_SUBNET_DATA table parity error",
    162       VLAN_SUBNET_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    163       VLAN_SUBNET_DATA_PARITY_CONTROLr,
    164       VLAN_SUBNET_DATA_PARITY_STATUSr, INVALIDr,
    165       INVALIDr, INVALIDr },
    166     { PARITY_ENf, VLAN_PROTOCOL_DATA_PARITY_ERRf, "VLAN_PROTOCOL_DATA table parity error",
    167       VLAN_PROTOCOL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    168       VLAN_PROTOCOL_DATA_PARITY_CONTROLr,
    169       VLAN_PROTOCOL_DATA_PARITY_STATUSr, INVALIDr,
    170       INVALIDr, INVALIDr },
    171     { PARITY_ENf, VLAN_PARITY_ERRf, "VLAN table parity error",
    172       VLAN_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    173       VLAN_PARITY_CONTROLr,
    174       VLAN_PARITY_STATUSr, INVALIDr,
    175       INVALIDr, INVALIDr },
    176     { PARITY_ENf, VLAN_STG_PARITY_ERRf, "VLAN_STG table parity error",
    177       STG_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    178       VLAN_STG_PARITY_CONTROLr,
    179       VLAN_STG_PARITY_STATUSr, INVALIDr,
    180       INVALIDr, INVALIDr },
    181     /* { PARITY_ENf, L3_TUNNEL_RAM_PARITY_ERRf, "L3_TUNNEL_RAM table parity error",
    182       L3_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    183       L3_TUNNEL_DATA_ONLY_PARITY_CONTROLr,
    184       L3_TUNNEL_DATA_ONLY_PARITY_STATUSr, INVALIDr,
    185       INVALIDr, INVALIDr }, */
    186     { PARITY_ENf, SOURCE_TRUNK_MAP_PARITY_ERRf, "SOURCE_TRUNK_MAP table parity error",
    187       SOURCE_TRUNK_MAP_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    188       SOURCE_TRUNK_MAP_PARITY_CONTROLr,
    189       SOURCE_TRUNK_MAP_PARITY_STATUSr, INVALIDr,
    190       INVALIDr, INVALIDr },
    191     { PARITY_ENf, LMEP_PAR_ERRf, "LMEP table parity error",
    192       LMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    193       LMEP_PARITY_CONTROLr,
    194       LMEP_PARITY_STATUSr, INVALIDr,
    195       INVALIDr, INVALIDr },
    196     { ECC_ENf, IARB_PKT_ECC_INTRf, "Iarb packet ecc error",
    197       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    198       IARB_PKT_ECC_CONTROLr,
    199       IARB_PKT_ECC_STATUS_INTRr, INVALIDr,
    200       INVALIDr, INVALIDr },
    201     /* IARB_HDR_ECC_INTR, no control/status regiters */
    202     { INVALIDf, INVALIDf }, /* table terminator */
    203 };
    204 
    205 
    206 STATIC _soc_parity_info_t _soc_hu2_ip1_parity_info[] = {
    207     /* { PARITY_ENf, VFI_PAR_ERRf, "VFI table parity error.",
    208       VFIm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    209       VFI_PARITY_CONTROLr,
    210       VFI_PARITY_STATUS_INTRr, INVALIDr,
    211       VFI_PARITY_STATUS_NACKr, INVALIDr }, */
    212     /* { PARITY_ENf, SVP_PAR_ERRf, "SOURCE_VP table parity error",
    213       SOURCE_VPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    214       SOURCE_VP_PARITY_CONTROLr,
    215       SOURCE_VP_PARITY_STATUSr, INVALIDr,
    216       SOURCE_VP_PARITY_STATUS_NACKr, INVALIDr }, */
    217     /* { PARITY_ENf, L3_IIF_PAR_ERRf, "L3_IIF table parity error",
    218       L3_IIFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    219       L3_IIF_PARITY_CONTROLr,
    220       L3_IIF_PARITY_STATUSr, INVALIDr,
    221       L3_IIF_PARITY_STATUS_NACKr, INVALIDr }, */
    222     /* { PARITY_ENf, MPLS_ENTRY_PAR_ERRf, "MPLS_ENTRY table parity error",
    223       MPLS_ENTRYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    224       MPLS_ENTRY_PARITY_CONTROLr,
    225       MPLS_ENTRY_PARITY_STATUS_INTR_0r, MPLS_ENTRY_PARITY_STATUS_INTR_1r,
    226       MPLS_ENTRY_PARITY_STATUS_NACK_0r, MPLS_ENTRY_PARITY_STATUS_NACK_1r }, */
    227     { PARITY_ENf, L2_ENTRY_PAR_ERRf, "L2_ENTRY table parity error",
    228       L2Xm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    229       L2_ENTRY_PARITY_CONTROLr,
    230       L2_ENTRY_PARITY_STATUS_0r, L2_ENTRY_PARITY_STATUS_1r,
    231       INVALIDr, INVALIDr },
    232     { PARITY_ENf, L2MC_PAR_ERRf, "L2MC table parity error",
    233       L2MCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    234       L2MC_PARITY_CONTROLr,
    235       L2MC_PARITY_STATUSr, INVALIDr,
    236       INVALIDr, INVALIDr },
    237     { PARITY_ENf, L3_ENTRY_PAR_ERRf, "L3_ENTRY table parity error",
    238       L3_ENTRY_ONLYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    239       L3_ENTRY_PARITY_CONTROLr,
    240       L3_ENTRY_PARITY_STATUS_0r, L3_ENTRY_PARITY_STATUS_1r,
    241       INVALIDr, INVALIDr },
    242     { PARITY_ENf, L3_DEFIP_DATA_PAR_ERRf, "L3_DEFIP_DATA_ONLY table parity error",
    243       L3_DEFIP_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    244       L3_DEFIP_PARITY_CONTROLr,
    245       L3_DEFIP_PARITY_STATUSr, INVALIDr
    246       INVALIDr, INVALIDr },
    247     { PARITY_ENf, L3MC_PAR_ERRf, "L3MC table parity error",
    248       L3_IPMCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    249       L3MC_PARITY_CONTROLr,
    250       L3MC_PARITY_STATUSr, INVALIDr,
    251       INVALIDr, INVALIDr },
    252     { PARITY_ENf, MA_STATE_PAR_ERRf, "MA_STATE table parity error",
    253       MA_STATEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    254       MA_STATE_PARITY_CONTROLr,
    255       MA_STATE_PARITY_STATUSr, INVALIDr,
    256       INVALIDr, INVALIDr },
    257     { PARITY_ENf, RMEP_PAR_ERRf, "RMEP table parity error",
    258       RMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    259       RMEP_PARITY_CONTROLr,
    260       RMEP_PARITY_STATUSr, INVALIDr,
    261       INVALIDr, INVALIDr },
    262     { PARITY_ENf, MAID_REDUCTION_PAR_ERRf, "MAID_REDUCTION table parity error",
    263       MAID_REDUCTIONm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    264       MAID_REDUCTION_PARITY_CONTROLr,
    265       MAID_REDUCTION_PARITY_STATUSr, INVALIDr,
    266       INVALIDr, INVALIDr },
    267     { PARITY_ENf, MA_INDEX_PAR_ERRf, "MA_INDEX table parity error",
    268       MA_INDEXm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    269       MA_INDEX_PARITY_CONTROLr,
    270       MA_INDEX_PARITY_STATUSr, INVALIDr,
    271       INVALIDr, INVALIDr },
    272     /* { PARITY_ENf, PORT_CBL_TABLE_PAR_ERRf, "PORT_CBL_TABLE table parity error",
    273       PORT_CBL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    274       PORT_CBL_TABLE_PARITY_CONTROLr,
    275       PORT_CBL_TABLE_PARITY_STATUSr, INVALIDr,
    276       INVALIDr, INVALIDr }, unsupported */
    277     { PARITY_ENf, INITIAL_NHOP_PAR_ERRf, "INITIAL_NHOP table parity error",
    278       INITIAL_ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    279       INITIAL_NHOP_PARITY_CONTROLr,
    280       INITIAL_NHOP_PARITY_STATUSr, INVALIDr,
    281       INVALIDr, INVALIDr },
    282     /* Start of parity-unrelated OAM faults */
    283 
    284     { ANY_RMEP_TLV_PORT_DOWN_INTRf, ANY_RMEP_TLV_PORT_DOWN_INTRf, NULL,
    285       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    286       INVALIDr,
    287       INVALIDr, INVALIDr,
    288       INVALIDr, INVALIDr },
    289 
    290     { ANY_RMEP_TLV_PORT_UP_INTRf, ANY_RMEP_TLV_PORT_UP_INTRf, NULL,
    291       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    292       INVALIDr,
    293       INVALIDr, INVALIDr,
    294       INVALIDr, INVALIDr },
    295 
    296     { ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, NULL,
    297       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    298       INVALIDr,
    299       INVALIDr, INVALIDr,
    300       INVALIDr, INVALIDr },
    301 
    302     { ANY_RMEP_TLV_INTERFACE_UP_INTRf, ANY_RMEP_TLV_INTERFACE_UP_INTRf, NULL,
    303       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    304       INVALIDr,
    305       INVALIDr, INVALIDr,
    306       INVALIDr, INVALIDr },
    307 
    308     { XCON_CCM_DEFECT_INTRf, XCON_CCM_DEFECT_INTRf, NULL,
    309       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    310       INVALIDr,
    311       INVALIDr, INVALIDr,
    312       INVALIDr, INVALIDr },
    313 
    314     { ERROR_CCM_DEFECT_INTRf, ERROR_CCM_DEFECT_INTRf, NULL,
    315       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    316       INVALIDr,
    317       INVALIDr, INVALIDr,
    318       INVALIDr, INVALIDr },
    319 
    320     { SOME_RDI_DEFECT_INTRf, SOME_RDI_DEFECT_INTRf, NULL,
    321       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    322       INVALIDr,
    323       INVALIDr, INVALIDr,
    324       INVALIDr, INVALIDr },
    325 
    326     { SOME_RMEP_CCM_DEFECT_INTRf, SOME_RMEP_CCM_DEFECT_INTRf, NULL,
    327       INVALIDm, _SOC_PARITY_INFO_TYPE_OAM,
    328       INVALIDr,
    329       INVALIDr, INVALIDr,
    330       INVALIDr, INVALIDr },
    331 
    332     /* End of parity-unrelated OAM faults */
    333     /* { PARITY_ENf, VFI_1_PAR_INTRf, "VFI_1 parity interrupt",
    334       VFI_1m, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    335       VFI_1_PARITY_CONTROLr,
    336       VFI_1_PARITY_STATUS_INTRr, INVALIDr,
    337       VFI_1_PARITY_STATUS_NACKr, INVALIDr }, */
    338     { INVALIDf, INVALIDf }, /* table terminator */
    339 };
    340 
    341 STATIC _soc_parity_info_t _soc_hu2_ip2_parity_info[] = {
    342     { PARITY_ENf, ING_NHOP_PAR_ERRf, "ING_L3_NEXT_HOP table parity error",
    343       ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    344       ING_L3_NEXT_HOP_PARITY_CONTROLr,
    345       ING_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr,
    346       INVALIDr, INVALIDr },
    347     { PARITY_ENf, IFP_METER_PAR_ERRf, "FP_METER_TABLE table parity error",
    348       FP_METER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    349       IFP_METER_PARITY_CONTROLr,
    350       IFP_METER_PARITY_STATUSr, INVALIDr,
    351       INVALIDr, INVALIDr },
    352     { PARITY_ENf, IFP_COUNTER_PAR_ERRf, "FP_COUNTER_TABLE table parity error",
    353       FP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    354       IFP_COUNTER_PARITY_CONTROLr,
    355       IFP_COUNTER_PARITY_STATUSr, INVALIDr,
    356       INVALIDr, INVALIDr },
    357     { PARITY_ENf, IFP_POLICY_PAR_ERRf, "FP_POLICY_TABLE table parity error",
    358       FP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    359       IFP_POLICY_PARITY_CONTROLr,
    360       IFP_POLICY_PARITY_STATUSr, INVALIDr,
    361       INVALIDr, INVALIDr },
    362     { PARITY_ENf, IFP_STORM_CONTROL_PAR_ERRf, "FP_STORM_CONTROL_METERS table parity error",
    363       FP_STORM_CONTROL_METERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    364       IFP_STORM_CONTROL_PARITY_CONTROLr,
    365       IFP_STORM_CONTROL_PARITY_STATUSr, INVALIDr,
    366       INVALIDr, INVALIDr },
    367     { PARITY_ENf, L3_MTU_VALUES_PAR_ERRf, "L3_MTU_VALUES table parity error",
    368       L3_MTU_VALUESm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    369       L3_MTU_VALUES_PARITY_CONTROLr,
    370       L3_MTU_VALUES_PARITY_STATUSr, INVALIDr,
    371       INVALIDr, INVALIDr },
    372     { PARITY_ENf, EGR_MASK_PAR_ERRf, "EGR_MASK table parity error",
    373       EGR_MASKm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    374       EGR_MASK_PARITY_CONTROLr,
    375       EGR_MASK_PARITY_STATUSr, INVALIDr,
    376       INVALIDr, INVALIDr },
    377     { PARITY_ENf, MODPORT_MAP_SW_PAR_ERRf, "MODPORT_MAP table parity error",
    378       MODPORT_MAP_SWm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    379       MODPORT_MAP_SW_PARITY_CONTROLr,
    380       MODPORT_MAP_SW_PARITY_STATUSr, INVALIDr,
    381       INVALIDr, INVALIDr },   
    382     { PARITY_ENf, MODPORT_MAP_IM_PAR_ERRf, "MODPORT_MAP_IM table parity error",
    383       MODPORT_MAP_IMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    384       MODPORT_MAP_IM_PARITY_CONTROLr,
    385       MODPORT_MAP_IM_PARITY_STATUSr, INVALIDr,
    386       INVALIDr, INVALIDr },
    387     { PARITY_ENf, MODPORT_MAP_EM_PAR_ERRf, "MODPORT_MAP_EM table parity error",
    388       MODPORT_MAP_EMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    389       MODPORT_MAP_EM_PARITY_CONTROLr,
    390       MODPORT_MAP_EM_PARITY_STATUSr, INVALIDr,
    391       INVALIDr, INVALIDr },
    392     { PARITY_ENf, OAM_LM_COUNTERS_PAR_ERRf, "OAM_LM_COUNTERS table parity error.",
    393       OAM_LM_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    394       OAM_LM_COUNTERS_PARITY_CONTROLr,
    395       OAM_LM_COUNTERS_PARITY_STATUSr, INVALIDr,
    396       INVALIDr, INVALIDr },
    397     { INVALIDf, INVALIDf }, /* table terminator */
    398 };
    399 
    400 STATIC _soc_parity_info_t _soc_hu2_ep_parity_info[] = {
    401     { PARITY_ENf, EGR_NHOP_PAR_ERRf, NULL,
    402       EGR_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    403       EGR_L3_NEXT_HOP_PARITY_CONTROLr,
    404       EGR_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr,
    405       INVALIDr, INVALIDr },
    406     { PARITY_ENf, EGR_L3_INTF_PAR_ERRf, NULL,
    407       EGR_L3_INTFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    408       EGR_L3_INTF_PARITY_CONTROLr,
    409       EGR_L3_INTF_PARITY_STATUSr, INVALIDr,
    410       INVALIDr, INVALIDr },
    411     { PARITY_ENf, EGR_VLAN_PAR_ERRf, NULL,
    412       EGR_VLANm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    413       EGR_VLAN_PARITY_CONTROLr,
    414       EGR_VLAN_PARITY_STATUSr, INVALIDr,
    415       INVALIDr, INVALIDr },
    416    { PARITY_ENf, EGR_VLAN_STG_PAR_ERRf, NULL,
    417       EGR_VLAN_STGm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    418       EGR_VLAN_STG_PARITY_CONTROLr,
    419       EGR_VLAN_STG_PARITY_STATUSr, INVALIDr,
    420       INVALIDr, INVALIDr },
    421     { PARITY_ENf, EGR_VXLT_PAR_ERRf, NULL,
    422       EGR_VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY,
    423       EGR_VLAN_XLATE_PARITY_CONTROLr,
    424       EGR_VLAN_XLATE_PARITY_STATUS_0r, EGR_VLAN_XLATE_PARITY_STATUS_1r,
    425       INVALIDr, INVALIDr },
    426     { STATS_PAR_ENf, EGR_STATS_COUNTER_TABLE_PAR_ERRf, "Parity enable for egress stats counter memory",
    427       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    428       EGR_EDATABUF_PARITY_CONTROLr,
    429       EGR_STATS_COUNTER_TABLE_PARITY_STATUSr, INVALIDr,
    430       INVALIDr, INVALIDr },
    431     { ECC_ENf, EP_INITBUF_DBEf, "EP_INITBUF double-bit ECC error",
    432       INVALIDm,_SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    433       EGR_INITBUF_ECC_CONTROLr,
    434       EGR_INITBUF_ECC_STATUS_DBEr, INVALIDr,
    435       INVALIDr, INVALIDr },
    436     { ECC_ENf, EP_INITBUF_SBEf, "EP_INITBUF single-bit ECC error (corrected)",
    437       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    438       EGR_INITBUF_ECC_CONTROLr,
    439       EGR_INITBUF_ECC_STATUS_SBEr, INVALIDr,
    440       INVALIDr, INVALIDr },
    441     { PERQ_PAR_ENf, EGR_PERQ_COUNTERf, "Parity enable for egress perq xmt counter memory",
    442       EGR_PERQ_XMT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    443       EGR_EDATABUF_PARITY_CONTROLr,
    444       EGR_PERQ_COUNTER_PARITY_STATUSr, INVALIDr,
    445       INVALIDr, INVALIDr },
    446     { EFPCTR_PAR_ENf, EGR_FP_COUNTERf, "Parity enable for efp counter memory",
    447       EFP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    448       EGR_EDATABUF_PARITY_CONTROLr,
    449       EGR_FP_COUNTER_PARITY_STATUSr, INVALIDr,
    450       INVALIDr, INVALIDr },
    451     { GP0_ECC_ENf, EGR_GP0_DBUFf, "ECC enable for gp0 interaface buffer",
    452       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    453       EGR_EDATABUF_PARITY_CONTROLr,
    454       EGR_GP0_DBITS_PARITY_STATUSr, INVALIDr,
    455       INVALIDr, INVALIDr },
    456     { GP1_ECC_ENf, EGR_GP1_DBUFf, "ECC enable for gp1 interaface buffer",
    457       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    458       EGR_EDATABUF_PARITY_CONTROLr,
    459       EGR_GP1_DBITS_PARITY_STATUSr, INVALIDr,
    460       INVALIDr, INVALIDr },
    461     { GP2_ECC_ENf, EGR_GP2_DBUFf, "ECC enable for gp2 interaface buffer",
    462       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    463       EGR_EDATABUF_PARITY_CONTROLr,
    464       EGR_GP2_DBITS_PARITY_STATUSr, INVALIDr,
    465       INVALIDr, INVALIDr },
    466     { XP0_ECC_ENf, EGR_XP0_DBUFf, "ECC enable for xp0 interaface buffer",
    467       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    468       EGR_EDATABUF_PARITY_CONTROLr,
    469       EGR_XP0_DBITS_PARITY_STATUSr, INVALIDr,
    470       INVALIDr, INVALIDr },
    471     { XP1_ECC_ENf, EGR_XP1_DBUFf, "ECC enable for xp1 interaface buffer",
    472       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    473       EGR_EDATABUF_PARITY_CONTROLr,
    474       EGR_XP1_DBITS_PARITY_STATUSr, INVALIDr,
    475       INVALIDr, INVALIDr },
    476     { XP2_ECC_ENf, EGR_XP2_DBUFf, "ECC enable for xp2 interaface buffer",
    477       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    478       EGR_EDATABUF_PARITY_CONTROLr,
    479       EGR_XP2_DBITS_PARITY_STATUSr, INVALIDr,
    480       INVALIDr, INVALIDr },
    481     { XP3_ECC_ENf, EGR_XP3_DBUFf, "ECC enable for xp3 interaface buffer",
    482       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    483       EGR_EDATABUF_PARITY_CONTROLr,
    484       EGR_XP3_DBITS_PARITY_STATUSr, INVALIDr,
    485       INVALIDr, INVALIDr },
    486     { XP4_ECC_ENf, EGR_XP4_DBUFf, "ECC enable for xp4 interaface buffer",
    487       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    488       EGR_EDATABUF_PARITY_CONTROLr,
    489       EGR_XP4_DBITS_PARITY_STATUSr, INVALIDr,
    490       INVALIDr, INVALIDr },
    491     { XP5_ECC_ENf, EGR_XP5_DBUFf, "ECC enable for xp5 interaface buffer",
    492       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    493       EGR_EDATABUF_PARITY_CONTROLr,
    494       EGR_XP5_DBITS_PARITY_STATUSr, INVALIDr,
    495       INVALIDr, INVALIDr },
    496     { XP6_ECC_ENf, EGR_XP6_DBUFf, "ECC enable for xp6 interaface buffer",
    497       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    498       EGR_EDATABUF_PARITY_CONTROLr,
    499       EGR_XP6_DBITS_PARITY_STATUSr, INVALIDr,
    500       INVALIDr, INVALIDr },
    501     { XP7_ECC_ENf, EGR_XP7_DBUFf, "ECC enable for xp7 interaface buffer",
    502       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    503       EGR_EDATABUF_PARITY_CONTROLr,
    504       EGR_XP7_DBITS_PARITY_STATUSr, INVALIDr,
    505       INVALIDr, INVALIDr },
    506     /* { GP_RESI_ECC_ENf, EGR_GP_RESI_DBUFf, "ECC enable for gp residue buffer",
    507       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    508       EGR_EDATABUF_PARITY_CONTROLr,
    509       EGR_GP_RESI_DBITS_PARITY_STATUSr, INVALIDr,
    510       INVALIDr, INVALIDr }, */
    511     { CM_ECC_ENf, EGR_CM_DBUFf, "ECC enable for cm interaface buffer",
    512       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY,
    513       EGR_EDATABUF_PARITY_CONTROLr,
    514       EGR_CM_DBITS_PARITY_STATUSr, INVALIDr,
    515       INVALIDr, INVALIDr },
    516     { INVALIDf, INVALIDf }, /* table terminator */
    517 };
    518 
    519 STATIC _soc_parity_info_t _soc_hu2_xlp_parity_info[] = {
    520     { TXFIFO_ECC_ENf, TXFIFO0_ERRf, "TXFIFO 0",
    521       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    522       XLPORT_ECC_CONTROLr,
    523       XLPORT_TXFIFO0_ECC_STATUSr, INVALIDr,
    524       INVALIDr, INVALIDr },
    525     { TXFIFO_ECC_ENf, TXFIFO1_ERRf, "TXFIFO 1",
    526       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    527       XLPORT_ECC_CONTROLr,
    528       XLPORT_TXFIFO1_ECC_STATUSr, INVALIDr,
    529       INVALIDr, INVALIDr },
    530     { TXFIFO_ECC_ENf, TXFIFO2_ERRf, "TXFIFO 2",
    531       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    532       XLPORT_ECC_CONTROLr,
    533       XLPORT_TXFIFO2_ECC_STATUSr, INVALIDr,
    534       INVALIDr, INVALIDr },
    535     { TXFIFO_ECC_ENf, TXFIFO3_ERRf, "TXFIFO 3",
    536       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    537       XLPORT_ECC_CONTROLr,
    538       XLPORT_TXFIFO3_ECC_STATUSr, INVALIDr,
    539       INVALIDr, INVALIDr },
    540     { BOD_ECC_ENABLEf, BOD_XLP0_ERRf, "Cell Assembly FIFO",
    541       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    542       XLPORT_ECC_CONTROLr,
    543       XLPORT_BOD_XLP0_ECC_STATUSr, INVALIDr,
    544       INVALIDr, INVALIDr },
    545     {  MIB_RSC_MEM_ENf, MIB_RSC1_MEM_ERRf, 
    546       "MIB RX Statistic counter memory instance 1",
    547       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    548       XLPORT_ECC_CONTROLr,
    549       XLPORT_MIB_RSC1_ECC_STATUSr, INVALIDr,
    550       INVALIDr, INVALIDr },
    551     { MIB_RSC_MEM_ENf, MIB_RSC0_MEM_ERRf, 
    552       "MIB RX Statistic counter memory instance 0",
    553       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    554       XLPORT_ECC_CONTROLr,
    555       XLPORT_MIB_RSC0_ECC_STATUSr, INVALIDr,
    556       INVALIDr, INVALIDr },
    557     { MIB_TSC_MEM_ENf, MIB_TSC1_MEM_ERRf, 
    558       "MIB TX Statistic counter memory instance 1",
    559       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    560       XLPORT_ECC_CONTROLr,
    561       XLPORT_MIB_TSC1_ECC_STATUSr, INVALIDr,
    562       INVALIDr, INVALIDr },
    563     { MIB_TSC_MEM_ENf, MIB_TSC0_MEM_ERRf, 
    564       "MIB TX Statistic counter memory instance 0",
    565       INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC,
    566       XLPORT_ECC_CONTROLr,
    567       XLPORT_MIB_TSC0_ECC_STATUSr, INVALIDr,
    568       INVALIDr, INVALIDr },
    569     { INVALIDf, INVALIDf }, /* table terminator */
    570 };
    571 
    572 STATIC _soc_parity_info_t _soc_hu2_mmu_parity_info[] = {
    573     { CELLECCERRORINTMASKf, CELLECCERRORf, "MMU CBP cell data",
    574       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    575       INVALIDr,
    576       INVALIDr, INVALIDr,
    577       INVALIDr, INVALIDr},
    578     { CBPPKTHDRPARITYERRORINTMASKf, CBPPKTHDRPARITYERRORf, 
    579       "MMU CBP packet header memory",
    580       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    581       INVALIDr,
    582       INVALIDr, INVALIDr,
    583       INVALIDr, INVALIDr}, 
    584     { CBPCELLHDRPARITYERRORINTMASKf, CBPCELLHDRPARITYERRORf, 
    585       "MMU CBP cell header memory",
    586       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    587       INVALIDr,
    588       INVALIDr, INVALIDr,
    589       INVALIDr, INVALIDr},
    590     { XQPARITYERRORINTMASKf, XQPARITYERRORf, 
    591       "MMU XQ memory",
    592       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    593       INVALIDr,
    594       INVALIDr, INVALIDr,
    595       INVALIDr, INVALIDr },
    596     { CFAPPARITYERRORINTMASKf, CFAPPARITYERRORf, 
    597       "MMU CFP memory",
    598       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    599       INVALIDr,
    600       INVALIDr, INVALIDr,
    601       INVALIDr, INVALIDr},
    602     { CCPPARITYERRORINTMASKf, CCPPARITYERRORf, 
    603       "MMU CCP memory",
    604       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    605       INVALIDr,
    606       INVALIDr, INVALIDr,
    607       INVALIDr, INVALIDr},
    608     { IPMCREPOVERLIMITERRORINTMASKf, IPMCREPOVERLIMITERRORf, 
    609       "IPMC replication over limit error",
    610       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    611       INVALIDr,
    612       INVALIDr, INVALIDr,
    613       INVALIDr, INVALIDr},
    614     { XQFLLPARITYERRORINTMASKf, XQFLLPARITYERRORf, 
    615       "MMU XQ FLL memory",
    616       INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC,
    617       INVALIDr,
    618       INVALIDr, INVALIDr,
    619       INVALIDr, INVALIDr},
    620     { E2EFCPARITYERRORINTMASKf, E2EFCPARITYERRORf, 
    621       "MMU E2EFC memory",
    622       INVALIDm, _SOC_PARITY_INFO_TYPE_MMU_E2EFC,
    623       INVALIDr,
    624       E2EFC_PARITYERRORPTRr, INVALIDr,
    625       INVALIDr, INVALIDr},
    626     { IPMCVALNXPORTPARITYERRORINTMASKf, IPMCVLANXPORTPARITYERRORf, 
    627       "MMU IPMC VLAN XPORT memory",
    628       MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_MMU_IPMC,
    629       MEMFAILINTMASKr,
    630       IPMCPARITYERRORPTRr, INVALIDr,
    631       INVALIDr, INVALIDr},
    632      /* { IPMCVALNGPORTPARITYERRORINTMASKf, IPMCVLANGPORTPARITYERRORf, 
    633       "MMU IPMC VLAN GPORT memory",
    634       MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_MMU_IPMC,
    635       MEMFAILINTMASKr,
    636       IPMCPARITYERRORPTRr, INVALIDr,
    637       INVALIDr, INVALIDr}, */
    638     { IPMCGROUP0PARITYERRORINTMASKf, IPMCGROUP0PARITYERRORf, 
    639       "MMU IPMC GORUP0 memory",
    640       MMU_IPMC_GROUP_TBL0m, _SOC_PARITY_INFO_TYPE_MMU_IPMC,
    641       INVALIDr,
    642       IPMCPARITYERRORPTRr, INVALIDr,
    643       INVALIDr, INVALIDr},
    644     { IPMCGROUP1PARITYERRORINTMASKf, IPMCGROUP1PARITYERRORf, 
    645       "MMU IPMC GORUP1 memory",
    646       MMU_IPMC_GROUP_TBL1m, _SOC_PARITY_INFO_TYPE_MMU_IPMC,
    647       INVALIDr,
    648       IPMCPARITYERRORPTRr, INVALIDr,
    649       INVALIDr, INVALIDr},
    650     { INVALIDf, INVALIDf }, /* table terminator */
    651 };
    652 
    653 
    654 typedef struct {
    655     uint32             cpi_bit;
    656     soc_block_t        blocktype;
    657     soc_reg_t          enable_reg;
    658     soc_reg_t          status_reg;
    659     _soc_parity_info_t *info;
    660 } _soc_hu2_parity_group_info_t;
    661 
    662 static _soc_hu2_parity_group_info_t _soc_hu2_parity_group_info_template[] = {
    663     { 0x00001, SOC_BLK_MMU, MEMFAILINTMASKr, MEMFAILINTSTATUSr, _soc_hu2_mmu_parity_info },
    664     { 0x00002, SOC_BLK_EPIPE, EGR_INTR_ENABLEr, EGR_INTR_STATUSr, _soc_hu2_ep_parity_info },
    665     { 0x00004, SOC_BLK_IPIPE, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, _soc_hu2_ip0_parity_info },
    666     { 0x00008, SOC_BLK_IPIPE, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, _soc_hu2_ip1_parity_info },
    667     { 0x00010, SOC_BLK_IPIPE, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, _soc_hu2_ip2_parity_info },
    668  /* { 0x00020, PCIE_REPLAY_PERR, }, */
    669     { 0x00040, SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, _soc_hu2_xlp_parity_info }, /* x4 */
    670     { 0 }, /* table terminator */
    671 };
    672 static _soc_hu2_parity_group_info_t _soc_wf_parity_group_info_template[] = {
    673     { 0x00001, SOC_BLK_MMU, MEMFAILINTMASKr, MEMFAILINTSTATUSr, _soc_hu2_mmu_parity_info },
    674     { 0x00002, SOC_BLK_EPIPE, EGR_INTR_ENABLEr, EGR_INTR_STATUSr, _soc_hu2_ep_parity_info },
    675     { 0x00004, SOC_BLK_IPIPE, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, _soc_wf_ip0_parity_info },
    676     { 0x00008, SOC_BLK_IPIPE, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, _soc_hu2_ip1_parity_info },
    677     { 0x00010, SOC_BLK_IPIPE, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, _soc_hu2_ip2_parity_info },
    678  /* { 0x00020, PCIE_REPLAY_PERR, }, */
    679     { 0x00040, SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, _soc_hu2_xlp_parity_info }, /* x4 */
    680     { 0 }, /* table terminator */
    681 };
    682 
    683 
    684 STATIC _soc_generic_ser_info_t *_soc_hu2_tcam_ser_info = NULL;
    685 STATIC _soc_hu2_parity_group_info_t *_soc_hu2_parity_group_info = NULL;
    686 STATIC soc_hurricane2_oam_handler_t hu2_oam_handler[SOC_MAX_NUM_DEVICES] = {NULL};
    687 static soc_hurricane2_oam_ser_handler_t hu2_oam_ser_handler[SOC_MAX_NUM_DEVICES] = {NULL};
    688 
    689 
    690 static soc_ser_functions_t _hu2_ser_functions;
    691 
    692 #define _SOC_HURRICANE2_SER_REG 1
    693 #define _SOC_HURRICANE2_SER_MEM 0
    694 
    695 typedef union _hurricane2_ser_nack_reg_mem_u {
    696     soc_reg_t reg;
    697     soc_mem_t mem;
    698 } _hurricane2_ser_nack_reg_mem_t;
    699 
    700 
    701 STATIC int
    702 _soc_hurricane2_parity_block_port(int unit, soc_block_t block, soc_port_t *port)
    703 {
    704     *port = SOC_BLOCK_PORT(unit, block);
    705     if ((*port != REG_PORT_ANY) && !SOC_PORT_VALID(unit, *port)) {
    706         return SOC_E_PORT;
    707     }
    708 
    709     return SOC_E_NONE;
    710 }
    711 
    712 soc_field_t _soc_hu2_oam_interrupt_fields[] = {
    713     SOME_RDI_DEFECT_INTRf,
    714     SOME_RMEP_CCM_DEFECT_INTRf,
    715     ERROR_CCM_DEFECT_INTRf,
    716     ANY_RMEP_TLV_PORT_DOWN_INTRf,
    717     ANY_RMEP_TLV_PORT_UP_INTRf,
    718     ANY_RMEP_TLV_INTERFACE_DOWN_INTRf,
    719     ANY_RMEP_TLV_INTERFACE_UP_INTRf,
    720     XCON_CCM_DEFECT_INTRf,
    721     INVALIDf
    722 };
    723 
    724 STATIC int
    725 _soc_hu2_process_oam_interrupt(int unit)
    726 {
    727     uint32 rval;
    728     int found = 0, fidx = 0;
    729     soc_hurricane2_oam_handler_t oam_handler_snapshot = hu2_oam_handler[unit];
    730 
    731 
    732     SOC_IF_ERROR_RETURN(READ_IP1_INTR_STATUSr(unit, &rval));
    733     
    734     while (_soc_hu2_oam_interrupt_fields[fidx] != INVALIDf) {
    735         if (soc_reg_field_get(unit, IP1_INTR_STATUSr, rval,
    736                           _soc_hu2_oam_interrupt_fields[fidx])) {
    737         
    738             if (oam_handler_snapshot != NULL)
    739             {
    740                 (void)(oam_handler_snapshot(unit,
    741                            _soc_hu2_oam_interrupt_fields[fidx]));
    742             }
    743             found++;
    744         }
    745         fidx++;
    746     }
    747     if (!found) {
    748       LOG_ERROR(BSL_LS_SOC_COMMON,
    749                 (BSL_META_U(unit,
    750                             "Unexpected interrupt received for OAM !!\n")));
    751     }
    752     return SOC_E_NONE;
    753 }
    754 
    755 void
    756 soc_hurricane2_oam_ser_handler_register(int unit, 
    757                                 soc_hurricane2_oam_ser_handler_t handler) 
    758 {
    759     hu2_oam_ser_handler[unit] = handler;
    760 }
    761 
    762 int
    763 soc_hurricane2_oam_ser_process(int unit, soc_mem_t mem, int index) 
    764 {
    765     if (hu2_oam_ser_handler[unit]) {
    766         return hu2_oam_ser_handler[unit](unit, mem, index);
    767     } else {
    768         return SOC_E_UNAVAIL;
    769     }
    770 }
    771 
    772 
    773 STATIC int
    774 _soc_hurricane2_parity_enable(int unit, int enable)
    775 {
    776     int group, table;
    777     uint32 group_enable, regval, cmic_enable = 0, cpi_blk_bit;
    778     _soc_parity_info_t *info;
    779     soc_reg_t group_reg, reg;
    780     soc_port_t block_port;
    781     soc_field_t enable_field;
    782     soc_block_t blk;
    783 
    784     /* loop through each group */
    785     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
    786         info = _soc_hu2_parity_group_info[group].info;
    787         group_reg = _soc_hu2_parity_group_info[group].enable_reg;
    788         group_enable = 0;
    789 
    790         cpi_blk_bit = _soc_hu2_parity_group_info[group].cpi_bit;
    791 
    792         SOC_BLOCK_ITER(unit, blk,
    793                        _soc_hu2_parity_group_info[group].blocktype) {
    794             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
    795                 cpi_blk_bit <<= 1;
    796                 continue;
    797             }
    798             /* loop through each table in the group */
    799             for (table = 0; info[table].enable_field != INVALIDf; table++) {
    800                 /* handle different parity error reporting style */
    801                 switch (info[table].type) {
    802                 case _SOC_PARITY_INFO_TYPE_GENERIC:
    803                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
    804                 case _SOC_PARITY_INFO_TYPE_MMU_IPMC:
    805                 case _SOC_PARITY_INFO_TYPE_MMU_E2EFC:
    806                 case _SOC_PARITY_INFO_TYPE_OAM:
    807                     enable_field = info[table].enable_field;
    808                     break;
    809                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
    810                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
    811                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
    812                     reg = info[table].control_reg;
    813                     if (!SOC_REG_IS_VALID(unit, reg)) {
    814                         continue;
    815                     }
    816                     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg,  block_port, 0, &regval));
    817                     soc_reg_field_set(unit, reg, &regval,
    818                                       info[table].enable_field,
    819                                       enable ? 1 : 0);
    820                     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg,  block_port, 0, regval));
    821                     enable_field = info[table].error_field;
    822                     break;
    823                 default:
    824                     enable_field = INVALIDf;
    825                     break;
    826                 } /* handle different parity error reporting style */
    827                 if (enable_field != INVALIDf) {
    828                     soc_reg_field_set(unit, group_reg, &group_enable,
    829                                       enable_field, enable ? 1 : 0);
    830                 }
    831             } /* loop through each table in the group */
    832 
    833             if (!SOC_REG_IS_VALID(unit, group_reg)) {
    834                 cpi_blk_bit <<= 1;
    835                 continue;
    836             }
    837             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, group_reg, block_port, 0, group_enable));
    838             cmic_enable |= cpi_blk_bit;
    839             cpi_blk_bit <<= 1;
    840         }
    841     } /* loop through each group */
    842 
    843     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &regval));
    844     soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_STAT_CLEARf, 1);
    845     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, regval));
    846     if (enable) {
    847         /* MMU enables */
    848         soc_reg_field_set(unit, MISCCONFIGr, &regval, PARITY_CHECK_ENf, 1);
    849         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_GEN_ENf, 1);
    850         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_STAT_CLEARf, 0);
    851         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, regval));
    852         /* Write CMIC enable register */
    853         (void)soc_cmicm_intr2_enable(unit, cmic_enable);
    854     } else {
    855         /* MMU disables */
    856         soc_reg_field_set(unit, MISCCONFIGr, &regval, PARITY_CHECK_ENf, 0);
    857         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_GEN_ENf, 0);
    858         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_STAT_CLEARf, 0);
    859         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, regval));
    860         /* Write CMIC disable register */
    861         (void)soc_cmicm_intr2_disable(unit, cmic_enable);
    862     }
    863     return SOC_E_NONE;
    864 }
    865 
    866 /* SER processing for TCAMs */
    867 STATIC _soc_generic_ser_info_t _soc_hu2_tcam_ser_info_template[] = {
    868     { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    869       _SOC_SER_INTERLEAVE_MOD2, 
    870       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0, 0 },
    871     { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    872       _SOC_SER_INTERLEAVE_MOD2,
    873       { {0, 69}, {1, 69}, {70, 138}, {71, 138} }, 0, 0, 0, 0, 0 },
    874     { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 
    875       _SOC_SER_PARITY_4BITS, _SOC_SER_INTERLEAVE_MOD2,
    876       { {0, 37}, {1, 37}, {38, 74}, {39, 74} }, 0, 0, 0, 0, 0 },
    877     { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 
    878       _SOC_SER_INTERLEAVE_MOD2,
    879       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0, 0 },
    880     { VLAN_SUBNET_ONLYm, VLAN_SUBNETm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    881       _SOC_SER_INTERLEAVE_MOD2,
    882       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0, 0 },
    883     { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 
    884       _SOC_SER_INTERLEAVE_MOD2,
    885       { {0, 69}, {1, 69}, {70, 138}, {71, 138} }, 0, 0, 0, 0, 0 },
    886     { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    887       _SOC_SER_INTERLEAVE_MOD2,
    888       { {0, 69}, {1, 69}, {70, 138}, {71, 138} }, 0, 0, 0, 0, 0 },
    889     { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    890       _SOC_SER_INTERLEAVE_MOD2,
    891       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0, 0 },
    892     { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_1BIT,
    893       _SOC_SER_INTERLEAVE_MOD2,
    894       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0, 0 },
    895     { INVALIDm },
    896 };
    897 
    898 /* Remove the VFP_TCAM and EFP_TCAM for Wolfhound */
    899 STATIC _soc_generic_ser_info_t _soc_wf_tcam_ser_info_template[] = {
    900     { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    901       _SOC_SER_INTERLEAVE_MOD2,
    902       { {0, 69}, {1, 69}, {70, 138}, {71, 138} }, 0, 0, 0, 0, 0 },
    903     { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 
    904       _SOC_SER_PARITY_4BITS, _SOC_SER_INTERLEAVE_MOD2,
    905       { {0, 37}, {1, 37}, {38, 74}, {39, 74} }, 0, 0, 0, 0, 0 },
    906     { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 
    907       _SOC_SER_INTERLEAVE_MOD2,
    908       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0, 0 },
    909     { VLAN_SUBNET_ONLYm, VLAN_SUBNETm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 
    910       _SOC_SER_INTERLEAVE_MOD2,
    911       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0, 0 },
    912     { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 
    913       _SOC_SER_INTERLEAVE_MOD2,
    914       { {0, 69}, {1, 69}, {70, 138}, {71, 138} }, 0, 0, 0, 0, 0 },
    915     { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
    916       _SOC_SER_INTERLEAVE_MOD2,
    917       { {0, 69}, {1, 69}, {70, 138}, {71, 138} }, 0, 0, 0, 0, 0 },
    918     { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_1BIT,
    919       _SOC_SER_INTERLEAVE_MOD2,
    920       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0, 0 },
    921     { INVALIDm },
    922 };
    923 
    924 
    925 
    926 STATIC int
    927 _soc_hurricane2_tcam_ser_init(int unit)
    928 {
    929     if (soc_feature(unit, soc_feature_field_multi_stage)) {
    930         _soc_hu2_tcam_ser_info = _soc_hu2_tcam_ser_info_template;
    931     } else {
    932         _soc_hu2_tcam_ser_info = _soc_wf_tcam_ser_info_template;
    933     }
    934     return soc_generic_ser_init(unit, _soc_hu2_tcam_ser_info);
    935 }
    936 
    937 void
    938 soc_hurricane2_ser_fail(int unit)
    939 
    940 {
    941     soc_generic_ser_process_error(unit, _soc_hu2_tcam_ser_info, 0);
    942 }
    943 
    944 int
    945 soc_hurricane2_ser_mem_clear(int unit, soc_mem_t mem)
    946 {
    947     uint32  range_enable;
    948     int info_ix, i;
    949     _soc_generic_ser_info_t *cur_spi;
    950     ser_memory_entry_t ser_mem;
    951     
    952     /* Check if enable */
    953     SOC_IF_ERROR_RETURN
    954         (READ_SER_RANGE_ENABLEr(unit, &range_enable));
    955 
    956     if (!range_enable) {
    957         return SOC_E_NONE;
    958     }
    959 
    960     info_ix = 0;
    961 
    962     while (_soc_hu2_tcam_ser_info[info_ix].mem != INVALIDm) {
    963         if (_soc_hu2_tcam_ser_info[info_ix].mem == mem) {
    964             break;
    965         }
    966         info_ix++;
    967     }
    968 
    969     if ((_soc_hu2_tcam_ser_info[info_ix].mem != INVALIDm) &&
    970         (range_enable & (1 << info_ix))) {
    971         cur_spi = &(_soc_hu2_tcam_ser_info[info_ix]);
    972 
    973         range_enable &= ~(1 << info_ix);
    974         /* Disable SER protection on this memory */
    975         SOC_IF_ERROR_RETURN
    976             (WRITE_SER_RANGE_ENABLEr(unit, range_enable));
    977         
    978 
    979         /* Flush SER memory segment for the table */
    980         sal_memset(&ser_mem, 0, sizeof(ser_mem));
    981         for (i = cur_spi->ser_section_start;
    982              i <= cur_spi->ser_section_end;
    983              i++) {
    984             SOC_IF_ERROR_RETURN
    985                     (WRITE_SER_MEMORYm(unit, MEM_BLOCK_ALL, i, &ser_mem));
    986         }
    987 
    988         range_enable |= (1 << info_ix);
    989         /* Enable SER protection on this memory */
    990         SOC_IF_ERROR_RETURN
    991             (WRITE_SER_RANGE_ENABLEr(unit, range_enable));
    992 
    993         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    994                     (BSL_META_U(unit,
    995                                 "\t%s: SER[%d-%d]\n"),
    996                      SOC_MEM_NAME(unit, cur_spi->mem),
    997                      cur_spi->ser_section_start, cur_spi->ser_section_end));
    998     }
    999 
   1000     return SOC_E_NONE;
   1001     
   1002 }
   1003 
   1004 
   1005 STATIC void
   1006 _soc_hu2_mem_parity_info(int unit, int block_info_idx, int pipe,
   1007                          soc_field_t field_enum, uint32 *minfo)
   1008 {
   1009     *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP)
   1010         | ((pipe & 0xff) << SOC_ERROR_PIPE_BP)
   1011         | (field_enum & SOC_ERROR_FIELD_ENUM_MASK);
   1012 }
   1013 
   1014 
   1015 
   1016 int
   1017 _soc_hurricane2_mem_parity_control(int unit, soc_mem_t mem,
   1018                                  int copyno, int enable)
   1019 {
   1020     int group, table;
   1021     uint32 cpi_blk_bit, regval;
   1022     _soc_parity_info_t *info;
   1023     soc_reg_t group_reg, reg;
   1024     soc_port_t block_port;
   1025     soc_field_t enable_field;
   1026     soc_block_t blk;
   1027 
   1028     /* Convert component/aggregate memories to the table for which
   1029      * the parity registers correspond. */
   1030     switch(mem) {
   1031     case VLAN_SUBNETm:
   1032         mem = VLAN_SUBNET_DATA_ONLYm; /* Should be VLAN_SUBNET? */
   1033         break;
   1034     case L2_ENTRY_ONLYm:
   1035         mem = L2Xm;
   1036         break;
   1037     case L2_USER_ENTRY_ONLYm:
   1038     case L2_USER_ENTRY_DATA_ONLYm:
   1039         mem = L2_USER_ENTRYm;
   1040         break;
   1041     case L3_DEFIPm:
   1042         mem = L3_DEFIP_DATA_ONLYm;
   1043         break;
   1044     case L3_DEFIP_128m:
   1045         mem = L3_DEFIP_128_DATA_ONLYm;
   1046         break;
   1047     case EGR_IP_TUNNEL_IPV6m:
   1048     case EGR_IP_TUNNEL_MPLSm:
   1049         mem = EGR_IP_TUNNELm;
   1050         break;
   1051     case L3_ENTRY_IPV4_UNICASTm:
   1052     case L3_ENTRY_IPV6_UNICASTm:
   1053     case L3_ENTRY_IPV4_MULTICASTm:
   1054     case L3_ENTRY_IPV6_MULTICASTm:
   1055         mem = L3_ENTRY_ONLYm;
   1056         break;
   1057     case VLAN_MACm:
   1058         mem = VLAN_XLATEm;
   1059         break;
   1060     default:
   1061         /* Do nothing, keep memory as provided */
   1062         break;
   1063     }
   1064 
   1065 
   1066     /* loop through each group */
   1067     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
   1068         info = _soc_hu2_parity_group_info[group].info;
   1069         group_reg = _soc_hu2_parity_group_info[group].enable_reg;
   1070         cpi_blk_bit = _soc_hu2_parity_group_info[group].cpi_bit;
   1071 
   1072         SOC_BLOCK_ITER(unit, blk,
   1073                        _soc_hu2_parity_group_info[group].blocktype) {
   1074             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   1075                 cpi_blk_bit <<= 1;
   1076                 continue;
   1077             }
   1078             if ((copyno != MEM_BLOCK_ANY) && (blk != copyno)) {
   1079                 cpi_blk_bit <<= 1;
   1080                 continue;
   1081             }
   1082 
   1083             /* loop through each table in the group */
   1084             for (table = 0; info[table].enable_field != INVALIDf; table++) {
   1085                 if (mem != info[table].mem) {
   1086                     continue;
   1087                 }
   1088 
   1089                 /* handle different parity error reporting style */
   1090                 switch (info[table].type) {
   1091                 case _SOC_PARITY_INFO_TYPE_GENERIC:
   1092                 case _SOC_PARITY_INFO_TYPE_MMU_PARITY:
   1093                 case _SOC_PARITY_INFO_TYPE_MMU_IPMC:
   1094                 case _SOC_PARITY_INFO_TYPE_MMU_E2EFC:
   1095                     enable_field = info[table].enable_field;
   1096                     SOC_IF_ERROR_RETURN
   1097                         (soc_reg_field32_modify(unit, group_reg, block_port,
   1098                                                 enable_field,
   1099                                                 enable ? 1 : 0));
   1100                     break;
   1101                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1102                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1103                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1104                     reg = info[table].control_reg;
   1105                     if (!SOC_REG_IS_VALID(unit, reg)) {
   1106                         return SOC_E_NONE;
   1107                     }
   1108                     SOC_IF_ERROR_RETURN
   1109                         (soc_reg_field32_modify(unit, reg, block_port,
   1110                                                 info[table].enable_field,
   1111                                                 enable ? 1 : 0));
   1112                     break;
   1113                 default:
   1114                     break;
   1115                 } /* handle different parity error reporting style */
   1116             } /* loop through each table in the group */
   1117             cpi_blk_bit <<= 1;
   1118         }
   1119     } /* loop through each group */
   1120 
   1121     /* MMU controls */
   1122     if (enable) {
   1123         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &regval));
   1124         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_STAT_CLEARf, 1);
   1125         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, regval));
   1126 
   1127         soc_reg_field_set(unit, MISCCONFIGr, &regval, PARITY_CHECK_ENf, 1);
   1128         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_GEN_ENf, 1);
   1129         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_STAT_CLEARf, 0);
   1130         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, regval));
   1131     } else {
   1132         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &regval));
   1133         soc_reg_field_set(unit, MISCCONFIGr, &regval, PARITY_CHECK_ENf, 0);
   1134         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_GEN_ENf, 0);
   1135         soc_reg_field_set(unit, MISCCONFIGr, &regval, E2EFC_PARITY_STAT_CLEARf, 0);
   1136         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, regval));
   1137     }
   1138 
   1139     return SOC_E_NONE;
   1140 }
   1141 
   1142 STATIC int
   1143 _soc_hurricane2_process_single_parity_error(int unit, int group,
   1144                                           soc_port_t block_port, int table,
   1145                                      int schan, char *msg, soc_block_t block)
   1146 {
   1147     _soc_parity_info_t *info;
   1148     soc_reg_t status_reg;
   1149     uint32 reg_val;
   1150     int index, multiple, error;
   1151     uint32 minfo;
   1152     _soc_ser_correct_info_t spci;
   1153 
   1154     info = _soc_hu2_parity_group_info[group].info;
   1155 
   1156     status_reg = schan ? info[table].nack_status0_reg :
   1157         info[table].intr_status0_reg;
   1158     if (status_reg == INVALIDr) {
   1159         return SOC_E_INTERNAL;
   1160     }
   1161     SOC_IF_ERROR_RETURN(soc_reg32_get(unit,status_reg,  block_port, 0, &reg_val));
   1162     index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf);
   1163     multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
   1164     error = soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERRf);
   1165  
   1166     if (error) {
   1167         _soc_hu2_mem_parity_info(unit, block, 0,
   1168                                  info[table].error_field, &minfo);
   1169         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1170                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1171                                index, minfo);
   1172         
   1173         LOG_ERROR(BSL_LS_SOC_COMMON,
   1174                   (BSL_META_U(unit,
   1175                               "unit %d %s entry %d parity error\n"),
   1176                    unit, msg, index));
   1177         if (multiple) {
   1178             LOG_ERROR(BSL_LS_SOC_COMMON,
   1179                       (BSL_META_U(unit,
   1180                                   "unit %d %s has multiple parity errors\n"),
   1181                        unit, msg));
   1182         }
   1183 
   1184         if (info[table].mem != INVALIDm) {
   1185             sal_memset(&spci, 0, sizeof(spci));
   1186             spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;         
   1187             spci.reg = INVALIDr;
   1188             spci.mem = info[table].mem;
   1189             spci.blk_type = -1;
   1190             spci.index = index;
   1191             (void)soc_ser_correction(unit, &spci);
   1192         }
   1193     } else {
   1194         LOG_ERROR(BSL_LS_SOC_COMMON,
   1195                   (BSL_META_U(unit,
   1196                               "unit %d %s: parity hardware inconsistency\n"),
   1197                    unit, msg));
   1198     }
   1199 
   1200     /* Clear parity status */
   1201     SOC_IF_ERROR_RETURN(soc_reg32_set(unit,status_reg,  block_port, 0, 0));
   1202     return SOC_E_NONE;
   1203 }
   1204 
   1205 STATIC int
   1206 _soc_hurricane2_process_single_ecc_error(int unit, int group,
   1207                                        soc_port_t block_port, int table,
   1208                                        int schan, char *msg, soc_block_t block)
   1209 {
   1210     _soc_parity_info_t *info;
   1211     soc_reg_t status_reg;
   1212     uint32 reg_val;
   1213     int index, double_bit, multiple, error;
   1214     uint32 minfo;
   1215     _soc_ser_correct_info_t spci;
   1216 
   1217     info = _soc_hu2_parity_group_info[group].info;
   1218 
   1219     status_reg = schan ? info[table].nack_status0_reg :
   1220         info[table].intr_status0_reg;
   1221     if (status_reg == INVALIDr) {
   1222         return SOC_E_INTERNAL;
   1223     }
   1224     SOC_IF_ERROR_RETURN(soc_reg32_get(unit,status_reg,  block_port, 0, &reg_val));
   1225     index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf);
   1226     double_bit = soc_reg_field_get(unit, status_reg,
   1227                                    reg_val, DOUBLE_BIT_ERRf);
   1228     multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
   1229     error = soc_reg_field_get(unit, status_reg, reg_val, ECC_ERRf);
   1230  
   1231     if (error) {
   1232         _soc_hu2_mem_parity_info(unit, block, 0,
   1233                                  info[table].error_field, &minfo);
   1234         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1235                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   1236                                index, minfo);
   1237         LOG_ERROR(BSL_LS_SOC_COMMON,
   1238                   (BSL_META_U(unit,
   1239                               "unit %d %s entry %d %s ECC error\n"),
   1240                    unit, msg, index, double_bit ? "double-bit" : ""));
   1241         if (multiple) {
   1242             LOG_ERROR(BSL_LS_SOC_COMMON,
   1243                       (BSL_META_U(unit,
   1244                                   "unit %d %s has multiple ECC errors\n"),
   1245                        unit, msg));
   1246         }
   1247         sal_memset(&spci, 0, sizeof(spci));
   1248         if (double_bit) {
   1249             spci.double_bit = 1;
   1250         }
   1251         if (info[table].mem != INVALIDm) {
   1252             spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1253             spci.reg = INVALIDr;
   1254             spci.mem = info[table].mem;
   1255             spci.blk_type = -1;
   1256             spci.index = index;
   1257             spci.parity_type = SOC_PARITY_TYPE_ECC;
   1258             (void)soc_ser_correction(unit, &spci);
   1259         }
   1260     } else {
   1261         LOG_ERROR(BSL_LS_SOC_COMMON,
   1262                   (BSL_META_U(unit,
   1263                               "unit %d %s: parity hardware inconsistency\n"),
   1264                    unit, msg));
   1265     }
   1266 
   1267     /* Clear parity status */
   1268     SOC_IF_ERROR_RETURN(soc_reg32_set(unit,status_reg,  block_port, 0, 0));
   1269     return SOC_E_NONE;
   1270 }
   1271 
   1272 STATIC int
   1273 _soc_hurricane2_process_dual_parity_error(int unit, int group,
   1274                                         soc_port_t block_port, int table,
   1275                                         int schan, char *msg, soc_block_t block)
   1276 {
   1277     _soc_parity_info_t *info;
   1278     soc_reg_t status_reg;
   1279     uint32 reg_val, bitmap = 0;
   1280     int index, bucket_index = 0, multiple = 0, ix, bits, size = 0;
   1281     _soc_ser_correct_info_t spci;
   1282     uint32 minfo;
   1283 
   1284     info = _soc_hu2_parity_group_info[group].info;
   1285 
   1286     for (ix = 0; ix < 2; ix ++) {
   1287         if (ix == 1) {
   1288             status_reg = schan ? info[table].nack_status1_reg :
   1289                 info[table].intr_status1_reg;
   1290         } else {
   1291             status_reg = schan ? info[table].nack_status0_reg :
   1292                 info[table].intr_status0_reg;
   1293         }
   1294 
   1295         if (status_reg == INVALIDr) {
   1296             continue;
   1297         }
   1298 
   1299         SOC_IF_ERROR_RETURN(soc_reg32_get(unit,status_reg, 
   1300                 block_port, 0, &reg_val));
   1301         if (soc_reg_field_valid(unit, status_reg, BUCKET_IDXf)) {
   1302             bucket_index =
   1303                 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDXf);
   1304             multiple =
   1305                 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf);
   1306             bitmap =
   1307                 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf);
   1308             size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf);
   1309         } else if (soc_reg_field_valid(unit, status_reg, BUCKET_IDX_0f)) {
   1310             bucket_index =
   1311             soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDX_0f);
   1312             multiple =
   1313                 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERR_0f);
   1314             bitmap =
   1315                 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BM_0f);
   1316             size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BM_0f);         
   1317         } else if (soc_reg_field_valid(unit, status_reg, BUCKET_IDX_1f)) {
   1318             bucket_index =
   1319                 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDX_1f);
   1320             multiple =
   1321                soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERR_1f);
   1322             bitmap =
   1323                 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BM_1f);
   1324             size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BM_1f);
   1325         }
   1326 
   1327         if (bitmap != 0) {
   1328             for (bits = 0; bits < size; bits++) {
   1329                 if (bitmap & (1 << bits)) {
   1330                     index =
   1331                         bucket_index * size * 2 + bits + (ix * size);
   1332                     _soc_hu2_mem_parity_info(unit, block, 0,
   1333                                  info[table].error_field, &minfo);
   1334                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1335                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1336                                index, minfo);
   1337                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1338                               (BSL_META_U(unit,
   1339                                           "unit %d %s entry %d parity error\n"),
   1340                                unit, msg, index));
   1341                     if (info[table].mem != INVALIDm) {
   1342                         sal_memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1343                         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1344                         spci.reg = INVALIDr;
   1345                         spci.mem = info[table].mem;
   1346                         spci.blk_type = block;
   1347                         spci.index = index;
   1348                         (void)soc_ser_correction(unit, &spci);
   1349                     }
   1350                 }
   1351             }
   1352         }
   1353 
   1354         if (multiple) {
   1355             LOG_ERROR(BSL_LS_SOC_COMMON,
   1356                       (BSL_META_U(unit,
   1357                                   "unit %d %s has multiple parity errors\n"),
   1358                        unit, msg));
   1359         }
   1360 
   1361         /* Clear parity status */
   1362         SOC_IF_ERROR_RETURN(soc_reg32_set(unit,status_reg,  block_port, 0, 0));
   1363     }
   1364 
   1365     return SOC_E_NONE;
   1366 }
   1367 
   1368 STATIC int
   1369 _soc_hurricane2_process_mmu_e2efc_error(int unit, int group,
   1370                                        soc_port_t block_port, int table,
   1371                                        char *msg, soc_block_t block)
   1372 {
   1373 #define _SOC_HU2_MMU_E2EFC_MAX     4
   1374     static soc_reg_t e2efc_regs[_SOC_HU2_MMU_E2EFC_MAX] = {
   1375           INVALIDr,  
   1376           E2EFC_CNT_SET_LIMITr,
   1377           E2EFC_CNT_RESET_LIMITr,
   1378           E2EFC_CNT_DISC_LIMITr
   1379     };
   1380 
   1381 
   1382     _soc_parity_info_t *info;
   1383     soc_reg_t err_reg;
   1384     uint32 reg_val, entry_index, mem_id;
   1385     uint32  minfo;
   1386     _soc_ser_correct_info_t spci;
   1387 
   1388     info = _soc_hu2_parity_group_info[group].info;
   1389 
   1390     err_reg = E2EFC_PARITYERRORPTRr;
   1391     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, err_reg, 
   1392                                         block_port, 0, &reg_val));
   1393     mem_id =
   1394             soc_reg_field_get(unit, err_reg, reg_val, INSTf);
   1395     /* CHECK if the error is valid */
   1396     if (mem_id == 0) {
   1397         LOG_ERROR(BSL_LS_SOC_COMMON,
   1398                   (BSL_META_U(unit,
   1399                               "unit %d %s: parity hardware inconsistency\n"),
   1400                    unit, msg));
   1401         return SOC_E_NONE;
   1402     }
   1403     entry_index =
   1404             soc_reg_field_get(unit, err_reg, reg_val, PTRf);
   1405 
   1406     _soc_hu2_mem_parity_info(unit, block, 0,
   1407                          info[table].error_field, &minfo);
   1408     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1409                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1410                        entry_index, minfo);
   1411     LOG_ERROR(BSL_LS_SOC_COMMON,
   1412               (BSL_META_U(unit,
   1413                           "unit %d MMU E2EFC entry %d parity error\n"),
   1414                unit, entry_index));
   1415     sal_memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1416     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   1417     spci.reg = e2efc_regs[mem_id];
   1418     spci.mem = INVALIDm;
   1419     spci.blk_type = SOC_BLK_MMU;
   1420     spci.index = entry_index;
   1421     (void)soc_ser_correction(unit, &spci);
   1422 
   1423     return SOC_E_NONE;
   1424 }
   1425 
   1426 STATIC int
   1427 _soc_hurricane2_process_mmu_ipmc_error(int unit, int group,
   1428                                        soc_port_t block_port, int table,
   1429                                        char *msg, soc_block_t block)
   1430 {
   1431 
   1432     _soc_parity_info_t *info;
   1433     soc_reg_t err_reg;
   1434     uint32 reg_val, entry_index;
   1435     uint32  minfo;
   1436     _soc_ser_correct_info_t spci;
   1437     soc_field_t     index_fld;
   1438     soc_mem_t       target_mem;
   1439     
   1440 
   1441     info = _soc_hu2_parity_group_info[group].info;
   1442 
   1443     err_reg = IPMCPARITYERRORPTRr;
   1444     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, err_reg, 
   1445                                         block_port, 0, &reg_val));
   1446     switch (info[table].error_field) {
   1447         case IPMCVLANXPORTPARITYERRORf:
   1448             index_fld = IPMC_VLAN_XPORT_PARITYERRORPTRf;
   1449             target_mem = MMU_IPMC_VLAN_TBLm;
   1450             break;
   1451         case IPMCVLANGPORTPARITYERRORf:
   1452             index_fld = IPMC_VLAN_GPORT_PARITYERRORPTRf;
   1453             target_mem = MMU_IPMC_VLAN_TBLm;
   1454             break;
   1455         case IPMCGROUP0PARITYERRORf:
   1456             index_fld = IPMC_GROUP0_PARITYERRORPTRf;
   1457             target_mem = MMU_IPMC_GROUP_TBL0m;
   1458             break;
   1459         case IPMCGROUP1PARITYERRORf:
   1460             index_fld = IPMC_GROUP1_PARITYERRORPTRf;
   1461             target_mem = MMU_IPMC_GROUP_TBL1m;
   1462             break;
   1463         default:
   1464             return SOC_E_INTERNAL;
   1465     }
   1466     entry_index =
   1467             soc_reg_field_get(unit, err_reg, reg_val, index_fld);
   1468 
   1469     _soc_hu2_mem_parity_info(unit, block, 0,
   1470                          info[table].error_field, &minfo);
   1471     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1472                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1473                        entry_index, minfo);
   1474     LOG_ERROR(BSL_LS_SOC_COMMON,
   1475               (BSL_META_U(unit,
   1476                           "unit %d MMU_%s entry %d parity error\n"),
   1477                unit, SOC_MEM_NAME(unit, target_mem), entry_index));
   1478     sal_memset(&spci, 0, sizeof(_soc_ser_correct_info_t));
   1479     spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   1480     spci.reg = INVALIDr;
   1481     spci.mem = target_mem;
   1482     spci.blk_type = SOC_BLK_MMU;
   1483     spci.index = entry_index;
   1484     (void)soc_ser_correction(unit, &spci);
   1485 
   1486     return SOC_E_NONE;
   1487 }
   1488 
   1489 
   1490 STATIC int
   1491 _soc_hurricane2_process_parity_error(int unit)
   1492 {
   1493     int group, table;
   1494     uint32 cmic_rval, group_status,
   1495         group_enable, cpi_blk_bit;
   1496     _soc_parity_info_t *info;
   1497     soc_reg_t group_reg, reg;
   1498     soc_port_t block_port;
   1499     soc_block_t blk;
   1500     char *msg;
   1501     uint32 minfo;
   1502 
   1503     /* Read CMIC parity status register */
   1504     /* coverity[result_independent_of_operands] */
   1505     SOC_IF_ERROR_RETURN
   1506         (READ_CMIC_CMC0_IRQ_STAT2r(unit, &cmic_rval));
   1507     if (cmic_rval == 0) {
   1508         return SOC_E_NONE;
   1509     }
   1510 
   1511     /* loop through each group */
   1512     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
   1513         info = _soc_hu2_parity_group_info[group].info;
   1514         group_reg = _soc_hu2_parity_group_info[group].status_reg;
   1515         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1516                     (BSL_META_U(unit,
   1517                                 "unit %d %s parity processing\n"),
   1518                                 unit, SOC_REG_NAME(unit, group_reg)));
   1519         cpi_blk_bit = _soc_hu2_parity_group_info[group].cpi_bit;
   1520 
   1521         SOC_BLOCK_ITER(unit, blk,
   1522                        _soc_hu2_parity_group_info[group].blocktype) {
   1523             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   1524                 cpi_blk_bit <<= 1;
   1525                 continue;
   1526             }
   1527             if (!(cmic_rval & cpi_blk_bit)) {
   1528                 cpi_blk_bit <<= 1;
   1529                 continue;
   1530             }
   1531 
   1532             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, group_reg, 
   1533                 block_port, 0, &group_status));
   1534 
   1535             /* loop through each table in the group */
   1536             for (table = 0; info[table].error_field != INVALIDf; table++) {
   1537                 if (!soc_reg_field_valid(unit, group_reg,
   1538                                          info[table].error_field)) {
   1539                     if (info[table].mem != INVALIDm) {
   1540                         LOG_ERROR(BSL_LS_SOC_COMMON,
   1541                                   (BSL_META_U(unit,
   1542                                               "unit %d %s has bad error field\n"),
   1543                                               unit, SOC_MEM_NAME(unit, info[table].mem)));
   1544                     }
   1545                     continue;
   1546                 }
   1547 
   1548                 if (!soc_reg_field_get(unit, group_reg, group_status,
   1549                                        info[table].error_field)) {
   1550                     continue;
   1551                 }
   1552                 if (info[table].msg) {
   1553                     msg = info[table].msg;
   1554                 } else if (info[table].mem != INVALIDm) {
   1555                     msg = SOC_MEM_NAME(unit, info[table].mem);
   1556                 } else {
   1557                     msg = SOC_FIELD_NAME(unit, info[table].error_field);
   1558                 }
   1559 
   1560                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1561                             (BSL_META_U(unit,
   1562                                         "unit %d %s analysis\n"),
   1563                                         unit, msg));
   1564 
   1565                 /* handle different parity error reporting style */
   1566                 switch (info[table].type) {
   1567                 case _SOC_PARITY_INFO_TYPE_GENERIC:
   1568                     _soc_hu2_mem_parity_info(unit, blk, 0,
   1569                                  info[table].error_field, &minfo);
   1570                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1571                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0,
   1572                                minfo);
   1573                     LOG_ERROR(BSL_LS_SOC_COMMON,
   1574                               (BSL_META_U(unit,
   1575                                           "unit %d %s asserted\n"),
   1576                                           unit, msg));
   1577                     break;
   1578                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1579                     SOC_IF_ERROR_RETURN
   1580                         (_soc_hurricane2_process_single_parity_error(unit,
   1581                               group, block_port, table, FALSE, msg, blk));
   1582                     break;
   1583                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1584                     SOC_IF_ERROR_RETURN
   1585                         (_soc_hurricane2_process_single_ecc_error(unit,
   1586                               group, block_port, table, FALSE, msg, blk));
   1587                     break;
   1588                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1589                     SOC_IF_ERROR_RETURN
   1590                         (_soc_hurricane2_process_dual_parity_error(unit,
   1591                               group, block_port, table, FALSE, msg, blk));
   1592                     break;                   
   1593                 case _SOC_PARITY_INFO_TYPE_MMU_E2EFC:
   1594                     SOC_IF_ERROR_RETURN
   1595                         (_soc_hurricane2_process_mmu_e2efc_error(unit,
   1596                               group, block_port, table, msg, blk));
   1597                     break;
   1598                 case _SOC_PARITY_INFO_TYPE_MMU_IPMC:
   1599                     SOC_IF_ERROR_RETURN
   1600                         (_soc_hurricane2_process_mmu_ipmc_error(unit,
   1601                               group, block_port, table, msg, blk));
   1602                     break;
   1603 
   1604                 case _SOC_PARITY_INFO_TYPE_OAM:
   1605                     SOC_IF_ERROR_RETURN
   1606                          (_soc_hu2_process_oam_interrupt(unit));                    
   1607                     break;
   1608 
   1609                 default:
   1610                     break;
   1611                 } /* handle different parity error reporting style */
   1612             } /* loop through each table in the group */
   1613 
   1614             /* clear MMU int status */
   1615             if (SOC_BLK_MMU == _soc_hu2_parity_group_info[group].blocktype) {
   1616                 SOC_IF_ERROR_RETURN(soc_reg32_set
   1617                             (unit, group_reg,  block_port, 0, 0));
   1618             }
   1619             reg = _soc_hu2_parity_group_info[group].enable_reg;
   1620             SOC_IF_ERROR_RETURN(soc_reg32_get
   1621                             (unit, reg,  block_port, 0, &group_enable));
   1622             group_enable &= ~group_status;
   1623             SOC_IF_ERROR_RETURN(soc_reg32_set
   1624                             (unit, reg,  block_port, 0, group_enable));
   1625             group_enable |= group_status;
   1626             SOC_IF_ERROR_RETURN(soc_reg32_set
   1627                             (unit, reg,  block_port, 0, group_enable));
   1628         } /* loop through each block for the group */
   1629     } /* loop through each group */
   1630 
   1631     return SOC_E_NONE;
   1632 }
   1633 
   1634 void
   1635 soc_hurricane2_parity_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4)
   1636 {
   1637     int unit = PTR_TO_INT(unit_vp);
   1638 
   1639     (void)_soc_hurricane2_process_parity_error(unit);
   1640     sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */
   1641     if (d2 != NULL) {
   1642         (void)soc_cmicm_intr2_enable(unit, PTR_TO_INT(d2));
   1643     }
   1644 }
   1645 
   1646 STATIC int
   1647 _soc_hurricane2_mem_nack_error_process(int unit, 
   1648         _hurricane2_ser_nack_reg_mem_t nack_reg_mem, 
   1649         soc_block_t block, int reg_mem)
   1650 {
   1651     int group, table;
   1652     _soc_parity_info_t *info;
   1653     soc_port_t block_port;
   1654     soc_block_t blk;
   1655     char *msg;
   1656 
   1657     if (nack_reg_mem.mem == INVALIDm) {
   1658         return SOC_E_PARAM;
   1659     }
   1660 
   1661     /* loop through each group */
   1662     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
   1663         info = _soc_hu2_parity_group_info[group].info;
   1664 
   1665         SOC_BLOCK_ITER(unit, blk,
   1666                        _soc_hu2_parity_group_info[group].blocktype) {
   1667             if (block != SOC_BLOCK_INFO(unit, blk).schan) {
   1668                 continue;
   1669             }
   1670             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   1671                 continue;
   1672             }
   1673             /* loop through each table in the group */
   1674             for (table = 0; info[table].error_field != INVALIDf; table++) {
   1675                 if (info[table].mem != nack_reg_mem.mem) {
   1676                     continue;
   1677                 }                
   1678                 if (info[table].msg) {
   1679                     msg = info[table].msg;
   1680                 } else { /* mem must be valid to get her */
   1681                     msg = SOC_MEM_NAME(unit, info[table].mem);
   1682                 }
   1683 
   1684                 /* handle different parity error reporting style */
   1685                 switch (info[table].type) {
   1686                 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY:
   1687                     SOC_IF_ERROR_RETURN
   1688                         (_soc_hurricane2_process_single_parity_error(unit,
   1689                               group, block_port, table, FALSE, msg, block));
   1690                     break;
   1691                 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC:
   1692                     SOC_IF_ERROR_RETURN
   1693                         (_soc_hurricane2_process_single_ecc_error(unit,
   1694                               group, block_port, table, FALSE, msg, blk));
   1695                     break;
   1696                 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY:
   1697                     SOC_IF_ERROR_RETURN
   1698                         (_soc_hurricane2_process_dual_parity_error(unit,
   1699                               group, block_port, table, FALSE, msg, blk));
   1700                     break;                   
   1701                 default:
   1702                     break;
   1703                 } /* handle different parity error reporting style */
   1704             } /* loop through each table in the group */
   1705         } /* loop through each block of the group */
   1706     } /* loop through each group */
   1707 
   1708     return SOC_E_NONE;
   1709 }
   1710 
   1711 void
   1712 soc_hurricane2_mem_nack(void *unit_vp, void *addr_vp, void *blk_vp, 
   1713                      void *d3, void *d4)
   1714 {
   1715     soc_mem_t mem = INVALIDm;
   1716     int reg_mem = PTR_TO_INT(d3);
   1717     int rv, unit = PTR_TO_INT(unit_vp);
   1718     uint32 address = PTR_TO_INT(addr_vp);
   1719     uint32 block = PTR_TO_INT(blk_vp);
   1720     uint32 offset = 0, min_addr = 0;
   1721     soc_regaddrinfo_t ainfo;
   1722     _hurricane2_ser_nack_reg_mem_t nack_reg_mem;
   1723     soc_field_t     error_fld = INVALIDf;
   1724     uint32 minfo;
   1725     _soc_ser_correct_info_t spci;
   1726     char *msg;
   1727 
   1728     if (reg_mem == _SOC_HURRICANE2_SER_REG) {
   1729         nack_reg_mem.reg = INVALIDr;
   1730         if (address) {
   1731             soc_regaddrinfo_get(unit, &ainfo, address);
   1732             nack_reg_mem.reg = ainfo.reg;
   1733         }
   1734     } else {
   1735         offset = address;
   1736         mem = soc_addr_to_mem_extended(unit, block, 0, address);
   1737         if (mem == INVALIDm) {
   1738             LOG_ERROR(BSL_LS_SOC_COMMON,
   1739                       (BSL_META_U(unit,
   1740                                   "unit %d mem decode failed, "
   1741                                   "SCHAN NACK analysis failure\n"), unit));
   1742             return;
   1743         }
   1744         
   1745         nack_reg_mem.mem = mem;
   1746 
   1747         min_addr = SOC_MEM_INFO(unit, mem).base;
   1748         min_addr += SOC_MEM_INFO(unit, mem).index_min;
   1749     }
   1750 
   1751     if ((mem == EGR_L3_NEXT_HOPm) || (mem == EGR_L3_INTFm) ||
   1752         (mem == EGR_VLANm) || (mem == EGR_VLAN_STGm) ||
   1753         (mem == EFP_COUNTER_TABLEm) || 
   1754         (mem == EGR_PERQ_XMT_COUNTERSm)) {
   1755         /* 
   1756          * The inetrupt of parity error for these memories will not be triggered.
   1757          * And the parity error status register will noT be updated.
   1758          * Use the offset value of S-channel msg to instead of.
   1759          */
   1760         switch (mem) {
   1761             case EGR_L3_NEXT_HOPm:
   1762                 error_fld = EGR_NHOP_PAR_ERRf;
   1763                 break;
   1764             case EGR_L3_INTFm:
   1765                 error_fld = EGR_L3_INTF_PAR_ERRf;
   1766                 break;
   1767             case EGR_VLANm:
   1768                 error_fld = EGR_VLAN_PAR_ERRf;
   1769                 break;
   1770             case EGR_VLAN_STGm:
   1771                 error_fld = EGR_VLAN_STG_PAR_ERRf;
   1772                 break;
   1773             case EFP_COUNTER_TABLEm:
   1774                 error_fld = EGR_FP_COUNTERf;
   1775                 break;
   1776             default:
   1777                 /* EGR_PERQ_XMT_COUNTERSm */
   1778                 error_fld = EGR_PERQ_COUNTERf;
   1779                 break;
   1780         }
   1781         _soc_hu2_mem_parity_info(unit, block, 0,
   1782                                  error_fld, &minfo);
   1783         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   1784                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   1785                                (offset - min_addr), minfo);
   1786         msg = SOC_MEM_NAME(unit, mem);
   1787         LOG_ERROR(BSL_LS_SOC_COMMON,
   1788                   (BSL_META_U(unit,
   1789                               "unit %d %s entry %d parity error\n"),
   1790                    unit, msg, (offset - min_addr)));
   1791         sal_memset(&spci, 0, sizeof(spci));
   1792         spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;         
   1793         spci.reg = INVALIDr;
   1794         spci.mem = mem;
   1795         spci.blk_type = -1;
   1796         spci.index = (offset - min_addr);
   1797         (void)soc_ser_correction(unit, &spci);
   1798     } else {
   1799 
   1800         if ((rv = _soc_hurricane2_mem_nack_error_process(unit, nack_reg_mem, 
   1801             (soc_block_t)block, reg_mem)) < 0) {
   1802             if (reg_mem == _SOC_HURRICANE2_SER_REG) {
   1803                 LOG_ERROR(BSL_LS_SOC_COMMON,
   1804                           (BSL_META_U(unit,
   1805                                       "unit %d REG SCHAN NACK analysis failure\n"),
   1806                            unit));
   1807             } else {
   1808                 LOG_ERROR(BSL_LS_SOC_COMMON,
   1809                           (BSL_META_U(unit,
   1810                                       "unit %d %s entry %d SCHAN NACK analysis failure\n"),
   1811                            unit, SOC_MEM_NAME(unit, mem),
   1812                            offset - min_addr));
   1813             }
   1814         }
   1815     }
   1816     if (reg_mem == _SOC_HURRICANE2_SER_REG) {
   1817         if (nack_reg_mem.reg != INVALIDr) {
   1818             LOG_ERROR(BSL_LS_SOC_COMMON,
   1819                       (BSL_META_U(unit,
   1820                                   "unit %d %s REG SCHAN NACK analysis\n"),
   1821                        unit, SOC_REG_NAME(unit, nack_reg_mem.reg)));
   1822             soc_reg32_set(unit, ainfo.reg, ainfo.port, ainfo.idx, 0);
   1823         } else {
   1824             LOG_ERROR(BSL_LS_SOC_COMMON,
   1825                       (BSL_META_U(unit,
   1826                                   "unit %d invalid register for REG SCHAN NACK analysis\n"),
   1827                        unit));
   1828         }
   1829     } else {
   1830         LOG_INFO(BSL_LS_SOC_SCHAN,
   1831                  (BSL_META_U(unit,
   1832                              "unit %d %s entry %d SCHAN NACK analysis\n"),
   1833                   unit, SOC_MEM_NAME(unit, mem),
   1834                   offset - min_addr));
   1835     }
   1836 }
   1837 
   1838 
   1839 static int
   1840 soc_hurricane2_pipe_mem_clear(int unit)
   1841 {
   1842     uint32              rval, index;
   1843     int                 blk_port;
   1844     soc_block_t         blk;
   1845     int                 pipe_init_usec;
   1846     soc_timeout_t       to;
   1847     int                 tcam_protect_write;
   1848     static const soc_mem_t cam[] = {
   1849         VLAN_SUBNETm,
   1850         VLAN_SUBNET_ONLYm,
   1851         VFP_TCAMm,
   1852         L2_USER_ENTRYm,
   1853         L2_USER_ENTRY_ONLYm,
   1854         L3_DEFIPm,
   1855         L3_DEFIP_ONLYm,
   1856         FP_TCAMm,
   1857         FP_GLOBAL_MASK_TCAMm,
   1858         CPU_COS_MAPm,
   1859         CPU_COS_MAP_ONLYm,
   1860         EFP_TCAMm
   1861     };
   1862 
   1863     /*
   1864      * Reset the IPIPE and EPIPE block
   1865      */
   1866     rval = 0;
   1867     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   1868     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1);
   1869     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1);
   1870     /* Set count to # entries in largest IPIPE table, L2_ENTRYm */
   1871     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x8000);
   1872     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   1873 
   1874     rval = 0;
   1875     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   1876     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1);
   1877     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1);
   1878     /* Set count to # entries in largest EPIPE table, EGR_L3_NEXT_HOPm */
   1879     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, 0x4000);
   1880     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   1881 
   1882     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   1883     if (SAL_BOOT_SIMULATION) {
   1884         pipe_init_usec = 10000000;
   1885     } else {
   1886         pipe_init_usec = 50000;
   1887     }
   1888     soc_timeout_init(&to, pipe_init_usec, 0);
   1889 
   1890     /* Wait for IPIPE memory initialization done. */
   1891     do {
   1892         SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval));
   1893         if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) {
   1894             break;
   1895         }
   1896         if (soc_timeout_check(&to)) {
   1897             LOG_WARN(BSL_LS_SOC_COMMON,
   1898                      (BSL_META_U(unit,
   1899                                  "unit %d : ING_HW_RESET timeout\n"), unit));
   1900             break;
   1901         }
   1902     } while (TRUE);
   1903 
   1904     /* Wait for EPIPE memory initialization done. */
   1905     do {
   1906         SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval));
   1907         if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) {
   1908             break;
   1909         }
   1910         if (soc_timeout_check(&to)) {
   1911             LOG_WARN(BSL_LS_SOC_COMMON,
   1912                      (BSL_META_U(unit,
   1913                                  "unit %d : EGR_HW_RESET timeout\n"), unit));
   1914             break;
   1915         }
   1916     } while (TRUE);
   1917 
   1918     rval = 0;
   1919     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   1920     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   1921 
   1922     if (!SAL_BOOT_SIMULATION || SAL_BOOT_BCMSIM) {
   1923         /* TCAM tables are not handled by hardware reset control */
   1924         tcam_protect_write = SOC_CONTROL(unit)->tcam_protect_write;
   1925         SOC_CONTROL(unit)->tcam_protect_write = FALSE;
   1926         for (index = 0; index < sizeof(cam) / sizeof(soc_mem_t); index++) {
   1927             if (SOC_MEM_IS_VALID(unit, cam[index])) {
   1928                 if (SAL_BOOT_BCMSIM &&
   1929                     !((cam[index] == VLAN_SUBNET_ONLYm) ||
   1930                      (cam[index] == CPU_COS_MAP_ONLYm) ||
   1931                      (cam[index] == L2_USER_ENTRY_ONLYm) ||
   1932                      (cam[index] == L3_DEFIP_ONLYm))) {
   1933                     continue;
   1934                 }
   1935                 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, cam[index],
   1936                                                   COPYNO_ALL, TRUE));
   1937             }
   1938         }
   1939         SOC_CONTROL(unit)->tcam_protect_write = tcam_protect_write;
   1940 
   1941         /* MMU_IPMC_VLAN_TBL */
   1942         SOC_IF_ERROR_RETURN
   1943             (soc_mem_clear(unit, MMU_IPMC_VLAN_TBLm, COPYNO_ALL, TRUE));
   1944         /* MMU_IPMC_GROUP_TBL0 */
   1945         SOC_IF_ERROR_RETURN
   1946             (soc_mem_clear(unit, MMU_IPMC_GROUP_TBL0m, COPYNO_ALL, TRUE));
   1947         /* MMU_IPMC_GROUP_TBL1 */
   1948         SOC_IF_ERROR_RETURN
   1949             (soc_mem_clear(unit, MMU_IPMC_GROUP_TBL1m, COPYNO_ALL, TRUE));
   1950     }
   1951 
   1952     /* Need to clear ING_PW_TERM_COUNTERS since it's not handled by reset control */
   1953     if (!(SAL_BOOT_QUICKTURN) && SOC_MEM_IS_VALID(unit, ING_PW_TERM_COUNTERSm)) {
   1954         SOC_IF_ERROR_RETURN
   1955             (soc_mem_clear(unit, ING_PW_TERM_COUNTERSm, COPYNO_ALL, TRUE));
   1956     }
   1957 
   1958     /* Reset XLPORT MIB counter (registers implemented in memory) */
   1959     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   1960         blk_port = SOC_BLOCK_PORT(unit, blk);
   1961         if (blk_port < 0) {
   1962             continue;
   1963         }
   1964         rval = 0;
   1965         /* All Ports */
   1966         soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 
   1967         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, blk_port, rval));
   1968         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, blk_port, 0));
   1969     }
   1970     
   1971     return SOC_E_NONE;
   1972 }
   1973 
   1974 
   1975 #define  HU2_NUM_COS  8
   1976 int soc_hu2_xq_mem(int unit, soc_port_t port, soc_mem_t *xq)
   1977 {
   1978     soc_mem_t   xq_mems[] = {   MMU_XQ0m,
   1979                                 MMU_XQ1m,
   1980                                 MMU_XQ2m,
   1981                                 MMU_XQ3m,
   1982                                 MMU_XQ4m,
   1983                                 MMU_XQ5m,
   1984                                 MMU_XQ6m,
   1985                                 MMU_XQ7m,
   1986                                 MMU_XQ8m,
   1987                                 MMU_XQ9m,
   1988                                 MMU_XQ10m,
   1989                                 MMU_XQ11m,
   1990                                 MMU_XQ12m,
   1991                                 MMU_XQ13m,
   1992                                 MMU_XQ14m,
   1993                                 MMU_XQ15m,
   1994                                 MMU_XQ16m,
   1995                                 MMU_XQ17m,
   1996                                 MMU_XQ18m,
   1997                                 MMU_XQ19m,
   1998                                 MMU_XQ20m,
   1999                                 MMU_XQ21m,
   2000                                 MMU_XQ22m,
   2001                                 MMU_XQ23m,
   2002                                 MMU_XQ24m,
   2003                                 MMU_XQ25m,
   2004                                 MMU_XQ26m,
   2005                                 MMU_XQ27m,
   2006                                 MMU_XQ28m,
   2007                                 MMU_XQ29m
   2008                             };
   2009     int max_port;
   2010     max_port = sizeof(xq_mems) / sizeof(xq_mems[0]);
   2011     if (port >= max_port) {
   2012         return(SOC_E_PORT);
   2013     }
   2014     *xq = xq_mems[port];
   2015     return(SOC_E_NONE);
   2016 }
   2017 
   2018 /* Hurricane uses 1.5MB of internal Buffers */
   2019 #define HU2_MMU_BUFFER_SIZE		(1.5 * 1024 * 1024) 
   2020 
   2021 /* 24GE + 4HG +1CPU ports */ 
   2022 #define HU2_MMU_TOTAL_PORTS		29 
   2023 
   2024 #define HU2_MMU_NUM_COS  		8
   2025 #define HU2_MMU_CELL_SIZE 		128
   2026 
   2027 /* total cells = 1.5MB/128 = 12288 */
   2028 #define HU2_MMU_TOTAL_CELLS 		(HU2_MMU_BUFFER_SIZE/HU2_MMU_CELL_SIZE)
   2029 
   2030 #define HU2_MMU_IN_COS_MIN_CELLS		12
   2031 #define HU2_MMU_IN_COS_MIN_XQS		8
   2032 
   2033 /* cos(8) * reserved cells(12) = 96 */
   2034 #define HU2_MMU_IN_PORT_STATIC_CELLS	(HU2_MMU_IN_COS_MIN_XQS * HU2_MMU_IN_COS_MIN_CELLS)
   2035 
   2036 /* ports(29) * per port cells(96) = 2784 */
   2037 #define HU2_MMU_TOTAL_STATIC_CELLS	(HU2_MMU_TOTAL_PORTS * HU2_MMU_IN_PORT_STATIC_CELLS)
   2038 
   2039 /* total cells(12288) - static cells(2784) = 9504 */
   2040 #define HU2_MMU_TOTAL_DYNAMIC_CELLS 	(HU2_MMU_TOTAL_CELLS - HU2_MMU_TOTAL_STATIC_CELLS)
   2041 
   2042 /* Every port has 1536 packet pointers(XQs) */
   2043 #define HU2_MMU_IN_PORT_TOTAL_XQS	1536
   2044 /* number of cos(8) * minimum xqs per cos(8) = 64 */
   2045 #define HU2_MMU_IN_PORT_STATIC_XQS	(HU2_MMU_NUM_COS * HU2_MMU_IN_COS_MIN_XQS)
   2046 /* total xqs (1536)- static xqs(64) = 1472 */
   2047 #define HU2_MMU_IN_PORT_DYNAMIC_XQS	(HU2_MMU_IN_PORT_TOTAL_XQS - HU2_MMU_IN_PORT_STATIC_XQS)
   2048 
   2049 #define HU2_MMU_MAX_PKT_SIZE		9728
   2050 /* xoff threshold = 80 */
   2051 #define HU2_MMU_XOFF_CELL_LIMIT		((HU2_MMU_MAX_PKT_SIZE/HU2_MMU_CELL_SIZE) + 4)
   2052 
   2053 /* max limit for pri-0 = (xoff threshold(80) + max packet size/128 *2 + 16)*23 */
   2054 #define HU2_MMU_MAX_CELL_LIMIT_PRI_0     5704	
   2055 /* max limit for pri-1-7 =  (total xqs/128 * 4)= 1536/128*4 */
   2056 #define HU2_MMU_MAX_CELL_LIMIT_PRI_1_7   48	
   2057 
   2058 /* cell limit0 + 7 * cell limit for pri1-7 = 6040 */ 
   2059 #define HU2_MMU_DYN_CELL_LIMIT		(HU2_MMU_MAX_CELL_LIMIT_PRI_0 +  \
   2060                                          ((HU2_MMU_NUM_COS -1) * HU2_MMU_MAX_CELL_LIMIT_PRI_1_7))
   2061 
   2062 static int port_speed_max[SOC_MAX_PHY_PORTS]; /* max phy port speed */
   2063 
   2064 int
   2065 soc_hu2_init_port_mapping(int unit)
   2066 {
   2067     soc_info_t *si;
   2068     soc_mem_t mem;
   2069     uint32 rval;
   2070     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
   2071     int port, phy_port;
   2072     int num_port, num_phy_port;
   2073 
   2074     si = &SOC_INFO(unit);
   2075 
   2076     /* Ingress physical to logical port mapping */
   2077     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
   2078     num_phy_port = soc_mem_index_count(unit, mem);
   2079     sal_memset(&entry, 0, sizeof(entry));
   2080     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
   2081         port = si->port_p2l_mapping[phy_port];
   2082         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
   2083                             port == -1 ? 0x1f : port);
   2084         SOC_IF_ERROR_RETURN
   2085             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry));
   2086     }
   2087     num_port = soc_mem_index_count(unit, PORT_TABm);
   2088     /* Egress logical to physical port mapping */
   2089     for (port = 0; port < num_port; port++) {
   2090         phy_port = si->port_l2p_mapping[port];
   2091         rval = 0;
   2092         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
   2093                           &rval, PHYSICAL_PORT_NUMBERf,
   2094                           phy_port == -1 ? 0x3f : phy_port);
   2095         SOC_IF_ERROR_RETURN
   2096             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
   2097                                                                 rval));
   2098     }
   2099     /* MMU logical to physical port mapping */
   2100     /*(Here, Same as Egress logical to physical port mapping) */
   2101     for (port = 0; port < num_port; port++) {
   2102         phy_port = si->port_m2p_mapping[port];
   2103         if (phy_port != -1) {
   2104             rval = 0;
   2105             soc_reg_field_set(unit, LOG_TO_PHY_PORT_MAPPINGr, &rval,
   2106                               PHY_PORTf, phy_port);
   2107             SOC_IF_ERROR_RETURN
   2108                 (WRITE_LOG_TO_PHY_PORT_MAPPINGr(unit, port, rval));
   2109         }
   2110     }
   2111 
   2112     return SOC_E_NONE;
   2113 }
   2114 
   2115 
   2116 #define CUSTOM_MAPPING_ARRAY_SIZE 34
   2117 #define CUSTOM_TSC_PORTMAP_COUNT 8
   2118 #define TSCPORT_OFFSET 26
   2119 typedef struct _custom_portmap_info_s {
   2120     int phy_port_default;
   2121     int phy_port_custom;
   2122 } _custom_portmap_info_t;
   2123 
   2124 static 
   2125 _custom_portmap_info_t hu2_custom_tsc_portmap[CUSTOM_TSC_PORTMAP_COUNT] = {
   2126     {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},
   2127     {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}
   2128 };
   2129 
   2130 /*
   2131  * Hu2 port mapping
   2132  * cpu port number is fixed: physical 0, logical 0, mmu 0
   2133  */
   2134 int
   2135 soc_hu2_get_port_mapping(int unit, uint16 dev_id)
   2136 {
   2137 
   2138     /* Port Mappings */
   2139     static const int p2l_mapping_24_4_0[] = { /* Non-Cascade, Powersave Plus */
   2140           0, -1,
   2141           9,  8,  7,  6,  5,  4,  3,  2,
   2142          10, 11, 12, 13, 14, 15, 16, 17,
   2143          18, 19, 20, 21, 22, 23, 24, 25,
   2144          26, 27, 28, 29,
   2145          -1, -1, -1, -1
   2146     };
   2147     static const int p2l_mapping_24_0_4[] = { /* Non-Cascade, Powersave Plus */
   2148           0, -1,
   2149           9,  8,  7,  6,  5,  4,  3,  2,
   2150          10, 11, 12, 13, 14, 15, 16, 17,
   2151          18, 19, 20, 21, 22, 23, 24, 25,
   2152          -1, -1, -1, -1,
   2153          26, 27, 28, 29
   2154     };
   2155     /* The mapping mode for QSGMII been forced at SGMII mode */
   2156     static const int p2l_mapping_18_4_0[] = { /* Non-Cascade, Powersave Plus */
   2157         0, -1,
   2158         9,  8,  7,  6,  5,  4,  3,  2,
   2159         10, 11, 12, 13, 14, 15, 16, 17,
   2160         18, -1, -1, -1, 22, -1, -1, -1, 
   2161         26, 27, 28, 29,
   2162         -1, -1, -1, -1
   2163     }; 
   2164     static const int p2l_mapping_18_0_4[] = { /* Non-Cascade, Powersave Plus */
   2165         0, -1,
   2166         9,  8,  7,  6,  5,  4,  3,  2,
   2167         10, 11, 12, 13, 14, 15, 16, 17,
   2168         18, -1, -1, -1, 22, -1, -1, -1, 
   2169         -1, -1, -1, -1,
   2170         26, 27, 28, 29
   2171     }; 
   2172     static const int p2l_mapping_24_4_0_x[] = { /* Non-Cascade (No Phy) */
   2173           0, -1,
   2174           2,  3,  4,  5,  6,  7,  8,  9,
   2175          10, 11, 12, 13, 14, 15, 16, 17,
   2176          18, 19, 20, 21, 22, 23, 24, 25,
   2177          26, 27, 28, 29,
   2178          -1, -1, -1, -1
   2179     };
   2180     static const int p2l_mapping_24_0_4_x[] = { /* Non-Cascade (No Phy) */
   2181           0, -1,
   2182           2,  3,  4,  5,  6,  7,  8,  9,
   2183          10, 11, 12, 13, 14, 15, 16, 17,
   2184          18, 19, 20, 21, 22, 23, 24, 25,
   2185          -1, -1, -1, -1,
   2186          26, 27, 28, 29
   2187     };
   2188     /* The mapping mode for QSGMII been forced at SGMII mode */
   2189     static const int p2l_mapping_18_4_0_x[] = { /* Non-Cascade (No Phy) */
   2190         0, -1,
   2191         2,  3,  4,  5,  6,  7,  8,  9,
   2192         10, 11, 12, 13, 14, 15, 16, 17,
   2193         18, -1, -1, -1, 22, -1, -1, -1, 
   2194         26, 27, 28, 29,
   2195         -1, -1, -1, -1
   2196     }; 
   2197     static const int p2l_mapping_18_0_4_x[] = { /* Non-Cascade (No Phy) */
   2198         0, -1,
   2199         2,  3,  4,  5,  6,  7,  8,  9,
   2200         10, 11, 12, 13, 14, 15, 16, 17,
   2201         18, -1, -1, -1, 22, -1, -1, -1, 
   2202         -1, -1, -1, -1,
   2203         26, 27, 28, 29
   2204     }; 
   2205     static const int p2l_mapping_24_2_2[] =  { /* Cascade */
   2206           0, -1,
   2207           9,  8,  7,  6,  5,  4,  3,  2,
   2208          10, 11, 12, 13, 14, 15, 16, 17,
   2209          18, 19, 20, 21, 22, 23, 24, 25,
   2210          26, -1, 27, -1,
   2211          28, -1, 29, -1
   2212     };
   2213     /* The mapping mode for QSGMII been forced at SGMII mode */
   2214     static const int p2l_mapping_18_2_2[] =  { /* Cascade */
   2215           0, -1,
   2216           9,  8,  7,  6,  5,  4,  3,  2,
   2217          10, 11, 12, 13, 14, 15, 16, 17,
   2218          18, -1, -1, -1, 22, -1, -1, -1,
   2219          26, -1, 27, -1,
   2220          28, -1, 29, -1
   2221     };
   2222     static const int p2l_mapping_24_2_2_x[] =  { /* Cascade (No Phy) */
   2223           0, -1,
   2224           2,  3,  4,  5,  6,  7,  8,  9,
   2225          10, 11, 12, 13, 14, 15, 16, 17,
   2226          18, 19, 20, 21, 22, 23, 24, 25,
   2227          26, -1, 27, -1,
   2228          28, -1, 29, -1
   2229     };
   2230     /* The mapping mode for QSGMII been forced at SGMII mode */
   2231     static const int p2l_mapping_18_2_2_x[] =  { /* Cascade (No Phy) */
   2232         0, -1,
   2233         2,  3,  4,  5,  6,  7,  8,  9,
   2234         10, 11, 12, 13, 14, 15, 16, 17,
   2235         18, -1, -1, -1, 22, -1, -1, -1, 
   2236         26, -1, 27, -1,
   2237         28, -1, 29, -1
   2238     }; 
   2239     static const int p2l_mapping_24_3_1[] =  { /* XAUI */
   2240           0, -1,
   2241           9,  8,  7,  6,  5,  4,  3,  2,
   2242          10, 11, 12, 13, 14, 15, 16, 17,
   2243          18, 19, 20, 21, 22, 23, 24, 25,
   2244          26, 27, 28, -1,
   2245          29, -1, -1, -1
   2246     };
   2247     /* The mapping mode for QSGMII been forced at SGMII mode */
   2248     static const int p2l_mapping_18_3_1[] =  { /* XAUI */
   2249         0, -1,
   2250         9,  8,  7,  6,  5,  4,  3,  2,
   2251         10, 11, 12, 13, 14, 15, 16, 17,
   2252         18, -1, -1, -1, 22, -1, -1, -1, 
   2253         26, 27, 28, -1,
   2254         29, -1, -1, -1
   2255     }; 
   2256     static const int p2l_mapping_24_1_1[] =  { /* 2xXAUI */
   2257           0, -1,
   2258           9,  8,  7,  6,  5,  4,  3,  2,
   2259          10, 11, 12, 13, 14, 15, 16, 17,
   2260          18, 19, 20, 21, 22, 23, 24, 25,
   2261          26, -1, -1, -1,
   2262          27, -1, -1, -1
   2263     };
   2264     /* The mapping mode for QSGMII been forced at SGMII mode */
   2265     static const int p2l_mapping_18_1_1[] =  { /* 2xXAUI */
   2266         0, -1,
   2267         9,  8,  7,  6,  5,  4,  3,  2,
   2268         10, 11, 12, 13, 14, 15, 16, 17,
   2269         18, -1, -1, -1, 22, -1, -1, -1, 
   2270         26, -1, -1, -1,
   2271         27, -1, -1, -1
   2272     }; 
   2273     static const int p2l_mapping_24_3_1_x[] =  { /* XAUI (No Phy) */
   2274           0, -1,
   2275           2,  3,  4,  5,  6,  7,  8,  9,
   2276          10, 11, 12, 13, 14, 15, 16, 17,
   2277          18, 19, 20, 21, 22, 23, 24, 25,
   2278          26, 27, 28, -1,
   2279          29, -1, -1, -1
   2280     };
   2281     /* The mapping mode for QSGMII been forced at SGMII mode */
   2282     static const int p2l_mapping_18_3_1_x[] =  { /* XAUI (No Phy) */
   2283         0, -1,
   2284         2,  3,  4,  5,  6,  7,  8,  9,
   2285         10, 11, 12, 13, 14, 15, 16, 17,
   2286         18, -1, -1, -1, 22, -1, -1, -1, 
   2287         26, 27, 28, -1,
   2288         29, -1, -1, -1
   2289     }; 
   2290     static const int p2l_mapping_24_1_1_x[] =  { /* 2xXAUI (No Phy) */
   2291           0, -1,
   2292           2,  3,  4,  5,  6,  7,  8,  9,
   2293          10, 11, 12, 13, 14, 15, 16, 17,
   2294          18, 19, 20, 21, 22, 23, 24, 25,
   2295          26, -1, -1, -1,
   2296          27, -1, -1, -1
   2297     };
   2298     /* The mapping mode for QSGMII been forced at SGMII mode */
   2299     static const int p2l_mapping_18_1_1_x[] =  { /* 2xXAUI (No Phy) */
   2300         0, -1,
   2301         2,  3,  4,  5,  6,  7,  8,  9,
   2302         10, 11, 12, 13, 14, 15, 16, 17,
   2303         18, -1, -1, -1, 22, -1, -1, -1, 
   2304         26, -1, -1, -1,
   2305         27, -1, -1, -1
   2306     }; 
   2307     static const int p2l_mapping_24_0_0[] = { /* Powersave */
   2308           0, -1,
   2309           9,  8,  7,  6,  5,  4,  3,  2,
   2310          10, 11, 12, 13, 14, 15, 16, 17,
   2311          18, 19, 20, 21, 22, 23, 24, 25,
   2312          -1, -1, -1, -1,
   2313          -1, -1, -1, -1
   2314     };
   2315     static const int p2l_mapping_16_0_0[] = { /* Powersave */
   2316           0, -1,
   2317           9,  8,  7,  6,  5,  4,  3,  2,
   2318          10, 11, 12, 13, 14, 15, 16, 17,
   2319          -1, -1, -1, -1, -1, -1, -1, -1,
   2320          -1, -1, -1, -1,
   2321          -1, -1, -1, -1
   2322     };
   2323     static const int p2l_mapping_16_4_0[] = { /* Powersave */
   2324           0, -1,
   2325           9,  8,  7,  6,  5,  4,  3,  2,
   2326          10, 11, 12, 13, 14, 15, 16, 17,
   2327          -1, -1, -1, -1, -1, -1, -1, -1,
   2328          26, 27, 28, 29,
   2329          -1, -1, -1, -1
   2330     };
   2331     static const int p2l_mapping_8_0_0[] = { /* Powersave */
   2332           0, -1,
   2333           9,  8,  7,  6,  5,  4,  3,  2,
   2334          -1, -1, -1, -1, -1, -1, -1, -1,
   2335          -1, -1, -1, -1, -1, -1, -1, -1,
   2336          -1, -1, -1, -1,
   2337          -1, -1, -1, -1
   2338     };
   2339     static const int p2l_mapping_6_4_4[] = { /* Embedded */
   2340           0, -1,
   2341           2, -1, -1, -1,  6, -1, -1, -1,
   2342          10, -1, -1, -1, 14, -1, -1, -1,
   2343          18, -1, -1, -1, 22, -1, -1, -1,
   2344          26, 27, 28, 29,
   2345          21, 23, 24, 25
   2346     };
   2347     static const int p2l_mapping_6_1_4[] = { /* Embedded - XAUI */
   2348           0, -1,
   2349           2, -1, -1, -1,  6, -1, -1, -1,
   2350          10, -1, -1, -1, 14, -1, -1, -1,
   2351          18, -1, -1, -1, 22, -1, -1, -1,
   2352          26, -1, -1, -1,
   2353          21, 23, 24, 25
   2354     };
   2355     static const int p2l_mapping_6_1_3[] = { /* Embedded Plus - XAUI */
   2356           0, -1,
   2357           2, -1, -1, -1,  6, -1, -1, -1,
   2358          10, -1, -1, -1, 14, -1, -1, -1,
   2359          18, -1, -1, -1, 22, -1, -1, -1,
   2360          26, -1, -1, -1,
   2361          27, 28, 29, -1
   2362     };
   2363     /* In Wolfhound ref platform, TSC ports are Even-Odd swapped */
   2364     /* Wolfhound Non-Cascade: only for the BCM953344R reference board */
   2365     /* static const int p2l_mapping_24_4_0_wh[] = {
   2366           0, -1,
   2367           9,  8,  7,  6,  5,  4,  3,  2,
   2368          10, 11, 12, 13, 14, 15, 16, 17,
   2369          18, 19, 20, 21, 22, 23, 24, 25,
   2370          27, 26, 29, 28,
   2371          -1, -1, -1, -1
   2372     }; */
   2373     /* The mapping mode for QSGMII been forced at SGMII mode */
   2374     /* Wolfhound Non-Cascade: only for the BCM953344R reference board */
   2375     /* static const int p2l_mapping_18_4_0_wh[] = {
   2376         0, -1,
   2377         9,  8,  7,  6,  5,  4,  3,  2,
   2378         10, 11, 12, 13, 14, 15, 16, 17,
   2379         18, -1, -1, -1, 22, -1, -1, -1, 
   2380         27, 26, 29, 28,
   2381         -1, -1, -1, -1
   2382     }; */
   2383 
   2384     /* Port Max Speeds */
   2385     static const int port_speed_max_24x1g_4x10g[] = {
   2386          -1, -1,
   2387          10, 10, 10, 10, 10, 10, 10, 10,
   2388          10, 10, 10, 10, 10, 10, 10, 10,
   2389          10, 10, 10, 10, 10, 10, 10, 10,
   2390         110,110,110,110,
   2391          -1, -1, -1, -1
   2392     };
   2393     static const int port_speed_max_24x1g_4x10g_tsc1[] = {
   2394          -1, -1,
   2395          10, 10, 10, 10, 10, 10, 10, 10,
   2396          10, 10, 10, 10, 10, 10, 10, 10,
   2397          10, 10, 10, 10, 10, 10, 10, 10,
   2398          -1, -1, -1, -1,
   2399         110,110,110,110
   2400     };
   2401     /* The mapping mode for QSGMII been forced at SGMII mode */
   2402     static const int port_speed_max_18x1g_4x10g[] = {
   2403         -1, -1,
   2404         10, 10, 10, 10, 10, 10, 10, 10,
   2405         10, 10, 10, 10, 10, 10, 10, 10,
   2406         10, -1, -1, -1, 10, -1, -1, -1,
   2407        110,110,110,110,
   2408         -1, -1, -1, -1
   2409     }; 
   2410     static const int port_speed_max_18x1g_4x10g_tsc1[] = {
   2411         -1, -1,
   2412         10, 10, 10, 10, 10, 10, 10, 10,
   2413         10, 10, 10, 10, 10, 10, 10, 10,
   2414         10, -1, -1, -1, 10, -1, -1, -1,
   2415         -1, -1, -1, -1,
   2416        110,110,110,110
   2417     }; 
   2418     static const int port_speed_max_24x1g_3x10g_1x10g[] = {
   2419         -1, -1,
   2420         10, 10, 10, 10, 10, 10, 10, 10,
   2421         10, 10, 10, 10, 10, 10, 10, 10,
   2422         10, 10, 10, 10, 10, 10, 10, 10,
   2423        110,110,110, -1,
   2424        100, -1, -1, -1
   2425     };
   2426     /* The mapping mode for QSGMII been forced at SGMII mode */
   2427     static const int port_speed_max_18x1g_3x10g_1x10g[] = {
   2428         -1, -1,
   2429         10, 10, 10, 10, 10, 10, 10, 10,
   2430         10, 10, 10, 10, 10, 10, 10, 10,
   2431         10, -1, -1, -1, 10, -1, -1, -1,
   2432        110,110,110, -1,
   2433        100, -1, -1, -1
   2434     }; 
   2435     static const int port_speed_max_24x1g_1x10g_1x10g[] = {
   2436         -1, -1,
   2437         10, 10, 10, 10, 10, 10, 10, 10,
   2438         10, 10, 10, 10, 10, 10, 10, 10,
   2439         10, 10, 10, 10, 10, 10, 10, 10,
   2440        100, -1, -1, -1,
   2441        100, -1, -1, -1
   2442     };
   2443     /* The mapping mode for QSGMII been forced at SGMII mode */
   2444     static const int port_speed_max_18x1g_1x10g_1x10g[] = {
   2445         -1, -1,
   2446         10, 10, 10, 10, 10, 10, 10, 10,
   2447         10, 10, 10, 10, 10, 10, 10, 10,
   2448         10, -1, -1, -1, 10, -1, -1, -1,
   2449        100, -1, -1, -1,
   2450        100, -1, -1, -1
   2451     }; 
   2452     static const int port_speed_max_24x1g_2x10g_2x13g[] = {
   2453         -1, -1,
   2454         10, 10, 10, 10, 10, 10, 10, 10,
   2455         10, 10, 10, 10, 10, 10, 10, 10,
   2456         10, 10, 10, 10, 10, 10, 10, 10,
   2457        110, -1,110, -1,
   2458        130, -1,130, -1
   2459     };
   2460     /* The mapping mode for QSGMII been forced at SGMII mode */
   2461     static const int port_speed_max_18x1g_2x10g_2x13g[] = {
   2462         -1, -1,
   2463         10, 10, 10, 10, 10, 10, 10, 10,
   2464         10, 10, 10, 10, 10, 10, 10, 10,
   2465         10, -1, -1, -1, 10, -1, -1, -1,
   2466        110, -1,110, -1,
   2467        130, -1,130, -1
   2468     }; 
   2469     static const int port_speed_max_24x1g_2x10g_2x10g[] = {
   2470         -1, -1,
   2471         10, 10, 10, 10, 10, 10, 10, 10,
   2472         10, 10, 10, 10, 10, 10, 10, 10,
   2473         10, 10, 10, 10, 10, 10, 10, 10,
   2474        110, -1,110, -1,
   2475        110, -1,110, -1
   2476     };
   2477     /* The mapping mode for QSGMII been forced at SGMII mode */
   2478     static const int port_speed_max_18x1g_2x10g_2x10g[] = {
   2479         -1, -1,
   2480         10, 10, 10, 10, 10, 10, 10, 10,
   2481         10, 10, 10, 10, 10, 10, 10, 10,
   2482         10, -1, -1, -1, 10, -1, -1, -1,
   2483        110, -1,110, -1,
   2484        110, -1,110, -1
   2485     };
   2486     static const int port_speed_max_24x1g_2x13g_2x10g[] = {
   2487         -1, -1,
   2488         10, 10, 10, 10, 10, 10, 10, 10,
   2489         10, 10, 10, 10, 10, 10, 10, 10,
   2490         10, 10, 10, 10, 10, 10, 10, 10,
   2491        130, -1,130, -1,
   2492        110, -1,110, -1
   2493     };
   2494     /* The mapping mode for QSGMII been forced at SGMII mode */
   2495     static const int port_speed_max_18x1g_2x13g_2x10g[] = {
   2496         -1, -1,
   2497         10, 10, 10, 10, 10, 10, 10, 10,
   2498         10, 10, 10, 10, 10, 10, 10, 10,
   2499         10, -1, -1, -1, 10, -1, -1, -1,
   2500        130, -1,130, -1,
   2501        110, -1,110, -1
   2502     }; 
   2503     static const int port_speed_max_24x1g_2x1g_2x13g[] = {
   2504         -1, -1,
   2505         10, 10, 10, 10, 10, 10, 10, 10,
   2506         10, 10, 10, 10, 10, 10, 10, 10,
   2507         10, 10, 10, 10, 10, 10, 10, 10,
   2508         10, -1, 10, -1,
   2509        130, -1,130, -1
   2510     };
   2511     static const int port_speed_max_24x1g_2x2500k_2x13g[] = {
   2512         -1, -1,
   2513         10, 10, 10, 10, 10, 10, 10, 10,
   2514         10, 10, 10, 10, 10, 10, 10, 10,
   2515         10, 10, 10, 10, 10, 10, 10, 10,
   2516         25, -1, 25, -1,
   2517        130, -1,130, -1
   2518     };
   2519     /* The mapping mode for QSGMII been forced at SGMII mode */
   2520     static const int port_speed_max_18x1g_2x1g_2x13g[] = {
   2521         -1, -1,
   2522         10, 10, 10, 10, 10, 10, 10, 10,
   2523         10, 10, 10, 10, 10, 10, 10, 10,
   2524         10, -1, -1, -1, 10, -1, -1, -1,
   2525         10, -1, 10, -1,
   2526        130, -1,130, -1
   2527     }; 
   2528     static const int port_speed_max_18x1g_2x2500k_2x13g[] = {
   2529         -1, -1,
   2530         10, 10, 10, 10, 10, 10, 10, 10,
   2531         10, 10, 10, 10, 10, 10, 10, 10,
   2532         10, -1, -1, -1, 10, -1, -1, -1,
   2533         25, -1, 25, -1,
   2534        130, -1,130, -1
   2535     }; 
   2536     static const int port_speed_max_24x1g_2x13g_2x1g[] = {
   2537         -1, -1,
   2538         10, 10, 10, 10, 10, 10, 10, 10,
   2539         10, 10, 10, 10, 10, 10, 10, 10,
   2540         10, 10, 10, 10, 10, 10, 10, 10,
   2541        130, -1,130, -1,
   2542         10, -1, 10, -1
   2543     };
   2544     static const int port_speed_max_24x1g_2x13g_2x2500k[] = {
   2545         -1, -1,
   2546         10, 10, 10, 10, 10, 10, 10, 10,
   2547         10, 10, 10, 10, 10, 10, 10, 10,
   2548         10, 10, 10, 10, 10, 10, 10, 10,
   2549        130, -1,130, -1,
   2550         25, -1, 25, -1
   2551     };
   2552     /* The mapping mode for QSGMII been forced at SGMII mode */
   2553     static const int port_speed_max_18x1g_2x13g_2x1g[] = {
   2554         -1, -1,
   2555         10, 10, 10, 10, 10, 10, 10, 10,
   2556         10, 10, 10, 10, 10, 10, 10, 10,
   2557         10, -1, -1, -1, 10, -1, -1, -1,
   2558        130, -1,130, -1,
   2559         10, -1, 10, -1
   2560     }; 
   2561     static const int port_speed_max_18x1g_2x13g_2x2500k[] = {
   2562         -1, -1,
   2563         10, 10, 10, 10, 10, 10, 10, 10,
   2564         10, 10, 10, 10, 10, 10, 10, 10,
   2565         10, -1, -1, -1, 10, -1, -1, -1,
   2566        130, -1,130, -1,
   2567         25, -1, 25, -1
   2568     }; 
   2569     static const int port_speed_max_24x1g_4x1g[] = {
   2570         -1, -1,
   2571         10, 10, 10, 10, 10, 10, 10, 10,
   2572         10, 10, 10, 10, 10, 10, 10, 10,
   2573         10, 10, 10, 10, 10, 10, 10, 10,
   2574         10, 10, 10, 10,
   2575         -1, -1, -1, -1
   2576     };
   2577     static const int port_speed_max_24x1g_4x2500k[] = {
   2578         -1, -1,
   2579         10, 10, 10, 10, 10, 10, 10, 10,
   2580         10, 10, 10, 10, 10, 10, 10, 10,
   2581         10, 10, 10, 10, 10, 10, 10, 10,
   2582         25, 25, 25, 25,
   2583         -1, -1, -1, -1
   2584     };
   2585     static const int port_speed_max_24x1g_4x2500k_tsc1[] = {
   2586         -1, -1,
   2587         10, 10, 10, 10, 10, 10, 10, 10,
   2588         10, 10, 10, 10, 10, 10, 10, 10,
   2589         10, 10, 10, 10, 10, 10, 10, 10,
   2590         -1, -1, -1, -1,
   2591         25, 25, 25, 25
   2592     };
   2593     /* The mapping mode for QSGMII been forced at SGMII mode */
   2594     static const int port_speed_max_18x1g_4x1g[] = {
   2595         -1, -1,
   2596         10, 10, 10, 10, 10, 10, 10, 10,
   2597         10, 10, 10, 10, 10, 10, 10, 10,
   2598         10, -1, -1, -1, 10, -1, -1, -1,
   2599         10, 10, 10, 10,
   2600         -1, -1, -1, -1
   2601     }; 
   2602     static const int port_speed_max_18x1g_4x2500k[] = {
   2603         -1, -1,
   2604         10, 10, 10, 10, 10, 10, 10, 10,
   2605         10, 10, 10, 10, 10, 10, 10, 10,
   2606         10, -1, -1, -1, 10, -1, -1, -1,
   2607         25, 25, 25, 25,
   2608         -1, -1, -1, -1
   2609     }; 
   2610     static const int port_speed_max_18x1g_4x2500k_tsc1[] = {
   2611         -1, -1,
   2612         10, 10, 10, 10, 10, 10, 10, 10,
   2613         10, 10, 10, 10, 10, 10, 10, 10,
   2614         10, -1, -1, -1, 10, -1, -1, -1,
   2615         -1, -1, -1, -1,
   2616         25, 25, 25, 25
   2617     }; 
   2618     static const int port_speed_max_24x1g[] = {
   2619         -1, -1,
   2620         10, 10, 10, 10, 10, 10, 10, 10,
   2621         10, 10, 10, 10, 10, 10, 10, 10,
   2622         10, 10, 10, 10, 10, 10, 10, 10,
   2623         -1, -1, -1, -1,
   2624         -1, -1, -1, -1
   2625     };
   2626     static const int port_speed_max_16x1g[] = {
   2627         -1, -1,
   2628         10, 10, 10, 10, 10, 10, 10, 10,
   2629         10, 10, 10, 10, 10, 10, 10, 10,
   2630         -1, -1, -1, -1, -1, -1, -1, -1,
   2631         -1, -1, -1, -1,
   2632         -1, -1, -1, -1
   2633     };
   2634     static const int port_speed_max_16x1g_4x1g[] = {
   2635         -1, -1,
   2636         10, 10, 10, 10, 10, 10, 10, 10,
   2637         10, 10, 10, 10, 10, 10, 10, 10,
   2638         -1, -1, -1, -1, -1, -1, -1, -1,
   2639         10, 10, 10, 10,
   2640         -1, -1, -1, -1
   2641     };
   2642     static const int port_speed_max_8x1g[] = {
   2643         -1, -1,
   2644         10, 10, 10, 10, 10, 10, 10, 10,
   2645         -1, -1, -1, -1, -1, -1, -1, -1,
   2646         -1, -1, -1, -1, -1, -1, -1, -1,
   2647         -1, -1, -1, -1,
   2648         -1, -1, -1, -1
   2649     };
   2650     static const int port_speed_max_6x1g_4x10g_4x1g[] = {
   2651          -1, -1,
   2652          10, -1, -1, -1, 10, -1, -1, -1,
   2653          10, -1, -1, -1, 10, -1, -1, -1,
   2654          10, -1, -1, -1, 10, -1, -1, -1,
   2655         110,110,110,110,
   2656          10, 10, 10, 10
   2657     };
   2658     static const int port_speed_max_6x1g_4x1g_4x1g[] = {
   2659          -1, -1,
   2660          10, -1, -1, -1, 10, -1, -1, -1,
   2661          10, -1, -1, -1, 10, -1, -1, -1,
   2662          10, -1, -1, -1, 10, -1, -1, -1,
   2663          10, 10, 10, 10,
   2664          10, 10, 10, 10
   2665     };
   2666     static const int port_speed_max_6x1g_1x10g_4x1g[] = {
   2667          -1, -1,
   2668          10, -1, -1, -1, 10, -1, -1, -1,
   2669          10, -1, -1, -1, 10, -1, -1, -1,
   2670          10, -1, -1, -1, 10, -1, -1, -1,
   2671         100, -1, -1, -1,
   2672          10, 10, 10, 10
   2673     };
   2674     static const int port_speed_max_6x1g_1x10g_3x10g[] = {
   2675          -1, -1,
   2676          10, -1, -1, -1, 10, -1, -1, -1,
   2677          10, -1, -1, -1, 10, -1, -1, -1,
   2678          10, -1, -1, -1, 10, -1, -1, -1,
   2679         100, -1, -1, -1,
   2680         110,110,110, -1
   2681     };
   2682 
   2683     soc_info_t *si;
   2684     int rv = SOC_E_NONE;
   2685     int phy_port;
   2686     const int *p2l_mapping=NULL, *speed_max=NULL;
   2687     int hu2_config_id;
   2688     uint32 qsgmii_override = 0;
   2689     int i;
   2690     int j;
   2691     int index;
   2692     int logical_port;
   2693     int port_bandwidth;
   2694     char *config_str, *sub_str, *sub_str_end;
   2695     int custom_port_mapping = 0;
   2696     int tmp_p2l_mapping[CUSTOM_MAPPING_ARRAY_SIZE];
   2697     int default_p2l_mapping[CUSTOM_MAPPING_ARRAY_SIZE];
   2698     int p2l_mapping_custom[CUSTOM_MAPPING_ARRAY_SIZE] = { /* customized p2l mapping */
   2699         0, -1,
   2700        -1, -1, -1, -1, -1, -1, -1, -1,
   2701        -1, -1, -1, -1, -1, -1, -1, -1,
   2702        -1, -1, -1, -1, -1, -1, -1, -1,
   2703        -1, -1, -1, -1,
   2704        -1, -1, -1, -1
   2705     };
   2706     int port_speed_max_custom[CUSTOM_MAPPING_ARRAY_SIZE] = {
   2707        -1, -1,
   2708        -1, -1, -1, -1, -1, -1, -1, -1,
   2709        -1, -1, -1, -1, -1, -1, -1, -1,
   2710        -1, -1, -1, -1, -1, -1, -1, -1,
   2711        -1, -1, -1, -1,
   2712        -1, -1, -1, -1
   2713     };
   2714 
   2715     hu2_config_id = soc_property_get(unit, spn_BCM5615X_CONFIG, 0);
   2716 
   2717     qsgmii_override = soc_property_get(unit,
   2718             spn_SERDES_QSGMII_SGMII_OVERRIDE, 0); 
   2719 
   2720     switch (dev_id) {
   2721         case BCM56150_DEVICE_ID:
   2722         case BCM53346_DEVICE_ID:
   2723             if (hu2_config_id == 0) {
   2724                 /* Option 1: 24P 1G +4P 1G/10G  (PHY) */
   2725                 if (qsgmii_override == 2) {
   2726                     /* (to-2SGMII): 18P 1G +4P 1G/10G  (PHY) */
   2727                     p2l_mapping = p2l_mapping_18_4_0;
   2728                     speed_max = port_speed_max_18x1g_4x10g; 
   2729                 } else {
   2730                     p2l_mapping = p2l_mapping_24_4_0;
   2731                     speed_max = port_speed_max_24x1g_4x10g;
   2732                 }
   2733             } else if ((hu2_config_id == 1) ||
   2734                        (hu2_config_id == 10)) {
   2735                 /* Option 2: 24P 1G + 2P 1G/10G + 2P 13G (PHY) */
   2736                 if (qsgmii_override == 2) {
   2737                     /* (to-2SGMII): 18P 1G + 2P 1G/10G + 2P 13G (PHY) */
   2738                     p2l_mapping = p2l_mapping_18_2_2;
   2739                     speed_max = port_speed_max_18x1g_2x10g_2x13g; 
   2740                 } else {
   2741                     p2l_mapping = p2l_mapping_24_2_2;
   2742                     speed_max = port_speed_max_24x1g_2x10g_2x13g;
   2743                 }
   2744             } else if (hu2_config_id == 11) {
   2745                 /* Option 2A: 24P 1G + 2P 13G + 2P 1G/10G (PHY) */
   2746                 if (qsgmii_override == 2) {
   2747                     /* (to-2SGMII): 18P 1G + 2P 13G + 2P 1G/10G (PHY) */
   2748                     p2l_mapping = p2l_mapping_18_2_2;
   2749                     speed_max = port_speed_max_18x1g_2x13g_2x10g; 
   2750                 } else {
   2751                     p2l_mapping = p2l_mapping_24_2_2;
   2752                     speed_max = port_speed_max_24x1g_2x13g_2x10g;
   2753                 }
   2754             } else if (hu2_config_id == 12) {
   2755                 /* Option 1A: 24P 1G + 2P 1G/10G + 2P 1G/10G (PHY)  */
   2756                 if (qsgmii_override == 2) {
   2757                     /* (to-2SGMII): 18P 1G + 2P 1G/10G + 2P 1G/10G (PHY)  */
   2758                     p2l_mapping = p2l_mapping_18_2_2;
   2759                     speed_max = port_speed_max_18x1g_2x10g_2x10g;
   2760                 } else {
   2761                     p2l_mapping = p2l_mapping_24_2_2;
   2762                     speed_max = port_speed_max_24x1g_2x10g_2x10g;
   2763                 }               
   2764             } else if (hu2_config_id == 13) {
   2765                 /* Option 1B: 24P 1G + 4P 1G/10G  (PHY, TSC1) */
   2766                 if (qsgmii_override == 2) {
   2767                     /* (to-2SGMII): 18P 1G + 4P 1G/10G  (PHY) */
   2768                     p2l_mapping = p2l_mapping_18_0_4;
   2769                     speed_max = port_speed_max_18x1g_4x10g_tsc1; 
   2770                 } else {
   2771                     p2l_mapping = p2l_mapping_24_0_4;
   2772                     speed_max = port_speed_max_24x1g_4x10g_tsc1;
   2773                 }				
   2774             } else if (hu2_config_id == 2) {
   2775                 /* Option 3: 24P 1G + 3P 1G/10G + 1P XAUI (PHY) */
   2776                 if (qsgmii_override == 2) {
   2777                     /* (to-2SGMII): 18P 1G + 3P 1G/10G + 1P XAUI (PHY) */
   2778                     p2l_mapping = p2l_mapping_18_3_1;
   2779                     speed_max = port_speed_max_18x1g_3x10g_1x10g; 
   2780                 } else {
   2781                     p2l_mapping = p2l_mapping_24_3_1;
   2782                     speed_max = port_speed_max_24x1g_3x10g_1x10g;
   2783                 }
   2784             } else if (hu2_config_id == 3) {
   2785                 /* Option 4: 24P 1G + 1P XAUI + 1P XAUI (PHY) */
   2786                 if (qsgmii_override == 2) {
   2787                     /* (to-2SGMII): 18P 1G + 1P XAUI + 1P XAUI (PHY) */
   2788                     p2l_mapping = p2l_mapping_18_1_1;
   2789                     speed_max = port_speed_max_18x1g_1x10g_1x10g; 
   2790                 } else {
   2791                     p2l_mapping = p2l_mapping_24_1_1;
   2792                     speed_max = port_speed_max_24x1g_1x10g_1x10g;
   2793                 }
   2794             }
   2795             break;
   2796         case BCM56151_DEVICE_ID:
   2797         case BCM53347_DEVICE_ID:
   2798             if (hu2_config_id == 0) {
   2799                 /* Option 1: 24P 1G + 4P 1G/10G (no Phy) */
   2800                 if (qsgmii_override == 2) {
   2801                     /* (to-2SGMII): 18P 1G + 4P 1G/10G (no Phy) */
   2802                     p2l_mapping = p2l_mapping_18_4_0_x;
   2803                     speed_max = port_speed_max_18x1g_4x10g; 
   2804                 } else {
   2805                     p2l_mapping = p2l_mapping_24_4_0_x; 
   2806                     speed_max = port_speed_max_24x1g_4x10g; 
   2807                 }
   2808             } else if ((hu2_config_id == 1) ||
   2809                        (hu2_config_id == 10)) {
   2810                 /* Option 2: 24P 1G + 2P 1G/10G + 2P 13G (no Phy) */
   2811                 if (qsgmii_override == 2) {
   2812                     /* (to-2SGMII): 18P 1G + 2P 1G/10G + 2P 13G (no Phy) */
   2813                     p2l_mapping = p2l_mapping_18_2_2_x;
   2814                     speed_max = port_speed_max_18x1g_2x10g_2x13g; 
   2815                 } else {
   2816                     p2l_mapping = p2l_mapping_24_2_2_x;
   2817                     speed_max = port_speed_max_24x1g_2x10g_2x13g;
   2818                 }
   2819             } else if (hu2_config_id == 11) {
   2820                 /* Option 2A: 24P 1G + 2P 13G + 2P 1G/10G (no Phy) */
   2821                 if (qsgmii_override == 2) {
   2822                     /* (to-2SGMII): 18P 1G + 2P 13G + 2P 1G/10G (no Phy) */
   2823                     p2l_mapping = p2l_mapping_18_2_2_x;
   2824                     speed_max = port_speed_max_18x1g_2x13g_2x10g; 
   2825                 } else {
   2826                     p2l_mapping = p2l_mapping_24_2_2_x;
   2827                     speed_max = port_speed_max_24x1g_2x13g_2x10g;
   2828                 }
   2829             } else if (hu2_config_id == 12) {
   2830                 /* Option 1A: 24P 1G + 2P 1G/10G + 2P 1G/10G (no PHY) */
   2831                 if (qsgmii_override == 2) {
   2832                     /* (to-2SGMII): 18P 1G + 2P 1G/10G + 2P 1G/10G (no PHY) */
   2833                     p2l_mapping = p2l_mapping_18_2_2_x;
   2834                     speed_max = port_speed_max_18x1g_2x10g_2x10g; 
   2835                 } else {
   2836                     p2l_mapping = p2l_mapping_24_2_2_x;
   2837                     speed_max = port_speed_max_24x1g_2x10g_2x10g;
   2838                 }
   2839             } else if (hu2_config_id == 13) {
   2840                 /* Option 1B: 24P 1G + 4P 1G/10G  (no PHY, TSC1) */
   2841                 if (qsgmii_override == 2) {
   2842                     /* (to-2SGMII): 18P 1G + 4P 1G/10G (no Phy) */
   2843                     p2l_mapping = p2l_mapping_18_0_4_x;
   2844                     speed_max = port_speed_max_18x1g_4x10g_tsc1; 
   2845                 } else {
   2846                     p2l_mapping = p2l_mapping_24_0_4_x; 
   2847                     speed_max = port_speed_max_24x1g_4x10g_tsc1; 
   2848                 }
   2849             } else if (hu2_config_id == 2) {
   2850                 /* Option 2A: 24P 1G + 3P 1G/10G + 1P XAUI (no Phy) */
   2851                 if (qsgmii_override == 2) {
   2852                     /* (to-2SGMII): 18P 1G + 3P 1G/10G + 1P XAUI (no Phy) */
   2853                     p2l_mapping = p2l_mapping_18_3_1_x;
   2854                     speed_max = port_speed_max_18x1g_3x10g_1x10g; 
   2855                 } else {
   2856                     p2l_mapping = p2l_mapping_24_3_1_x;
   2857                     speed_max = port_speed_max_24x1g_3x10g_1x10g;
   2858                 }
   2859             } else if (hu2_config_id == 3) {
   2860                 /* Option 2A: 24P 1G + 1P XAUI + 1P XAUI (no Phy) */
   2861                 if (qsgmii_override == 2) {
   2862                     /* (to-2SGMII): 18P 1G + 1P XAUI + 1P XAUI (no Phy) */
   2863                     p2l_mapping = p2l_mapping_18_1_1_x;
   2864                     speed_max = port_speed_max_18x1g_1x10g_1x10g; 
   2865                 } else {
   2866                     p2l_mapping = p2l_mapping_24_1_1_x;
   2867                     speed_max = port_speed_max_24x1g_1x10g_1x10g;
   2868                 }
   2869             }
   2870             break;
   2871         case BCM53344_DEVICE_ID:
   2872             if (hu2_config_id == 0) {
   2873                 /* Option 1: 24P 1G +4P 1G  (PHY) */
   2874                 if (qsgmii_override == 2) {
   2875                     /* (to-2SGMII): 18P 1G +4P 1G  (PHY) */
   2876                     p2l_mapping = p2l_mapping_18_4_0;
   2877                     speed_max = port_speed_max_18x1g_4x1g; 
   2878                 } else {
   2879                     p2l_mapping = p2l_mapping_24_4_0;
   2880                     speed_max = port_speed_max_24x1g_4x1g;
   2881                 }
   2882             } else if ((hu2_config_id == 1) || 
   2883                        (hu2_config_id == 10)) {
   2884                 /* Option 2: 24P 1G + 2P 1G + 2P 13G (PHY) */
   2885                 if (qsgmii_override == 2) {
   2886                     /* (to-2SGMII): 18P 1G + 2P 1G + 2P 13G (PHY) */
   2887                     p2l_mapping = p2l_mapping_18_2_2;
   2888                     speed_max = port_speed_max_18x1g_2x1g_2x13g; 
   2889                 } else {
   2890                     p2l_mapping = p2l_mapping_24_2_2;
   2891                     speed_max = port_speed_max_24x1g_2x1g_2x13g; 
   2892                 }
   2893             } else if (hu2_config_id == 11) {
   2894                 /* Option 2A: 24P 1G + 2P 13G + 2P 1G (PHY) */
   2895                 if (qsgmii_override == 2) {
   2896                     /* (to-2SGMII): 18P 1G + 2P 13G + 2P 1G (PHY) */
   2897                     p2l_mapping = p2l_mapping_18_2_2;
   2898                     speed_max = port_speed_max_18x1g_2x13g_2x1g; 
   2899                 } else {
   2900                     p2l_mapping = p2l_mapping_24_2_2;
   2901                     speed_max = port_speed_max_24x1g_2x13g_2x1g; 
   2902                 }
   2903             }
   2904             break;
   2905         case BCM56152_DEVICE_ID:
   2906             if (hu2_config_id == 0) {
   2907                 /* Option 1: 24P 1G +4P 1G/2.5G  (PHY) */
   2908                 if (qsgmii_override == 2) {
   2909                     /* (to-2SGMII): 18P 1G +4P 1G/2.5G  (PHY) */
   2910                     p2l_mapping = p2l_mapping_18_4_0;
   2911                     speed_max = port_speed_max_18x1g_4x2500k; 
   2912                 } else {
   2913                     p2l_mapping = p2l_mapping_24_4_0;
   2914                     speed_max = port_speed_max_24x1g_4x2500k; 
   2915                 }
   2916             } else if ((hu2_config_id == 1) || 
   2917                        (hu2_config_id == 10)) {
   2918                 /* Option 2: 24P 1G + 2P 1G/2.5G + 2P 13G (PHY) */
   2919                 if (qsgmii_override == 2) {
   2920                     /* (to-2SGMII): 18P 1G + 2P 1G/2.5G + 2P 13G (PHY) */
   2921                     p2l_mapping = p2l_mapping_18_2_2;
   2922                     speed_max = port_speed_max_18x1g_2x2500k_2x13g; 
   2923                 } else {
   2924                     p2l_mapping = p2l_mapping_24_2_2;
   2925                     speed_max = port_speed_max_24x1g_2x2500k_2x13g; 
   2926                 }
   2927             } else if (hu2_config_id == 11) {
   2928                 /* Option 2A: 24P 1G + 2P 13G + 2P 1G/2.5G (PHY) */
   2929                 if (qsgmii_override == 2) {
   2930                     /* (to-2SGMII): 18P 1G + 2P 13G + 2P 1G/2.5G (PHY) */
   2931                     p2l_mapping = p2l_mapping_18_2_2;
   2932                     speed_max = port_speed_max_18x1g_2x13g_2x2500k; 
   2933                 } else {
   2934                     p2l_mapping = p2l_mapping_24_2_2;
   2935                     speed_max = port_speed_max_24x1g_2x13g_2x2500k; 
   2936                 }
   2937             } else if (hu2_config_id == 13) {
   2938                 /* Option 1B: 24P 1G +4P 1G  (PHY, TSC1) */
   2939                 if (qsgmii_override == 2) {
   2940                     /* (to-2SGMII): 18P 1G +4P 1G  (PHY) */
   2941                     p2l_mapping = p2l_mapping_18_0_4;
   2942                     speed_max = port_speed_max_18x1g_4x2500k_tsc1; 
   2943                 } else {
   2944                     p2l_mapping = p2l_mapping_24_0_4;
   2945                     speed_max = port_speed_max_24x1g_4x2500k_tsc1; 
   2946                 }
   2947             }
   2948             break;
   2949         case BCM53334_DEVICE_ID:
   2950             /* 24P  1G  (PHY) */
   2951             p2l_mapping = p2l_mapping_24_0_0;
   2952             speed_max = port_speed_max_24x1g;
   2953             break;
   2954         case BCM53333_DEVICE_ID:
   2955             /* 16P  1G (PHY) */
   2956             p2l_mapping = p2l_mapping_16_0_0;
   2957             speed_max = port_speed_max_16x1g;
   2958             break;
   2959         case BCM53343_DEVICE_ID:
   2960             /* 16P  1G (PHY) + 4P 1G */
   2961             p2l_mapping = p2l_mapping_16_4_0;
   2962             speed_max = port_speed_max_16x1g_4x1g;
   2963             break;
   2964         case BCM53342_DEVICE_ID:
   2965             /* 8P  1G (PHY) */
   2966             p2l_mapping = p2l_mapping_8_0_0;
   2967             speed_max = port_speed_max_8x1g;
   2968             break;
   2969         case BCM53393_DEVICE_ID:
   2970             /* 14P 1G,  (no PHY) */
   2971             p2l_mapping = p2l_mapping_6_4_4;
   2972             speed_max = port_speed_max_6x1g_4x1g_4x1g;
   2973             break;
   2974         case BCM53394_DEVICE_ID:
   2975             if (hu2_config_id == 0) {
   2976                 /* 10P 1G + 4x1/2.5/5/10G  (no PHY) */
   2977                 p2l_mapping = p2l_mapping_6_4_4;
   2978                 speed_max = port_speed_max_6x1g_4x10g_4x1g;
   2979             } else if (hu2_config_id == 1) {
   2980                 /* 10P 1G + 1P XAUI (no Phy) */
   2981                 p2l_mapping = p2l_mapping_6_1_4;
   2982                 speed_max = port_speed_max_6x1g_1x10g_4x1g;
   2983             } else if (hu2_config_id == 2) { 
   2984                 /* 6P 1G + 3x1/10G + 1P XAUI (no Phy) */
   2985                 p2l_mapping = p2l_mapping_6_1_3;
   2986                 speed_max = port_speed_max_6x1g_1x10g_3x10g;
   2987             }
   2988             break;
   2989         default :
   2990             break;
   2991     }
   2992 
   2993     if ((p2l_mapping == NULL) || (speed_max == NULL)) {
   2994         return SOC_E_CONFIG;
   2995     }
   2996 
   2997     /* save the default p2l mapping */
   2998     sal_memcpy(default_p2l_mapping, p2l_mapping, sizeof(default_p2l_mapping));
   2999     sal_memcpy(tmp_p2l_mapping, p2l_mapping, sizeof(tmp_p2l_mapping));
   3000     sal_memcpy(port_speed_max_custom, speed_max, sizeof(port_speed_max_custom));
   3001 
   3002     for (logical_port = 2; logical_port < CUSTOM_MAPPING_ARRAY_SIZE; logical_port++) {
   3003         config_str = soc_property_port_get_str(unit, logical_port, spn_PORTMAP);
   3004         if (config_str == NULL) {
   3005             continue;
   3006         }
   3007         custom_port_mapping = 1;
   3008 
   3009         /*
   3010          * portmap.<port>=<physical port number>:<bandwidth in Gb>
   3011          *				  [:<queue config>]
   3012          */
   3013         sub_str = config_str;
   3014 
   3015         /* Parsing physical port number */
   3016         phy_port = sal_ctoi(sub_str, &sub_str_end);
   3017         if (sub_str == sub_str_end) {
   3018             LOG_ERROR(BSL_LS_SOC_COMMON,
   3019                   (BSL_META_U(unit,
   3020                               "Port %d: Missing physical port information \"%s\"\n"),
   3021                    logical_port, config_str));
   3022             rv = SOC_E_FAIL;
   3023             continue;
   3024         }
   3025         if (phy_port < 2 || phy_port > 33) {
   3026             LOG_ERROR(BSL_LS_SOC_COMMON,
   3027                   (BSL_META_U(unit,
   3028                               "Port %d: Invalid physical port number %d\n"),
   3029                    logical_port, phy_port));
   3030             rv = SOC_E_FAIL;
   3031             continue;
   3032         }
   3033 
   3034         if (p2l_mapping_custom[phy_port] != -1) {
   3035             LOG_ERROR(BSL_LS_SOC_COMMON,
   3036                   (BSL_META_U(unit,
   3037                               "Port %d: Physical port %d is used by port %d\n"),
   3038                    logical_port, phy_port, p2l_mapping_custom[phy_port]));
   3039             rv = SOC_E_FAIL;
   3040             continue;
   3041         }
   3042 
   3043         /* Skip ':' */
   3044         sub_str = sub_str_end;
   3045         if (*sub_str != '\0') {
   3046             if (*sub_str != ':') {
   3047                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3048                       (BSL_META_U(unit,
   3049                               "Port %d: Bad config string \"%s\"\n"),
   3050                        logical_port, config_str));
   3051                 rv = SOC_E_FAIL;
   3052                 continue;
   3053             }
   3054             sub_str++;
   3055         }
   3056 
   3057         /* Parsing bandwidth */
   3058         port_bandwidth = sal_ctoi(sub_str, &sub_str_end);
   3059         if (sub_str == sub_str_end) {
   3060             LOG_ERROR(BSL_LS_SOC_COMMON,
   3061                   (BSL_META_U(unit,
   3062                               "Port %d: Missing bandwidth information \"%s\"\n"),
   3063                    logical_port, config_str));
   3064             rv = SOC_E_FAIL;
   3065             continue;
   3066         }
   3067         if (port_bandwidth != 1 && port_bandwidth != 10 &&
   3068             port_bandwidth != 13 && port_bandwidth != 11) {
   3069             LOG_ERROR(BSL_LS_SOC_COMMON,
   3070                   (BSL_META_U(unit,
   3071                               "Port %d: Invalid bandwidth %d Gb\n"),
   3072                    logical_port, port_bandwidth));
   3073             rv = SOC_E_FAIL;
   3074             continue;
   3075         }
   3076 
   3077         p2l_mapping_custom[phy_port] = logical_port;
   3078         port_speed_max_custom[phy_port] = port_bandwidth * 10;
   3079         tmp_p2l_mapping[phy_port] = logical_port;
   3080     }
   3081 
   3082     if (custom_port_mapping) {
   3083         p2l_mapping = tmp_p2l_mapping;
   3084         speed_max = port_speed_max_custom;
   3085 
   3086         for (i = 0; i < CUSTOM_TSC_PORTMAP_COUNT; i++) {
   3087             for (j = 0; j < CUSTOM_MAPPING_ARRAY_SIZE; j++) {
   3088                 if (default_p2l_mapping[j] == i + TSCPORT_OFFSET) {
   3089                     hu2_custom_tsc_portmap[i].phy_port_default = j;
   3090                     /* init customer port mapping at default */
   3091                     hu2_custom_tsc_portmap[i].phy_port_custom = j;
   3092                     break;
   3093                 }
   3094     	    }
   3095         for (j = 0; j < CUSTOM_MAPPING_ARRAY_SIZE; j++) {
   3096                 if (p2l_mapping_custom[j] == i + TSCPORT_OFFSET) {
   3097                     /* apply real customer port mapping */
   3098                     hu2_custom_tsc_portmap[i].phy_port_custom = j;
   3099                     break;
   3100                 }
   3101     	    }
   3102             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3103                     (BSL_META_U(unit,
   3104                         "Customized TSC port mapping[%d] = %d, %d\n"),
   3105                         i, hu2_custom_tsc_portmap[i].phy_port_default,
   3106                         hu2_custom_tsc_portmap[i].phy_port_custom));
   3107         }
   3108     }
   3109 
   3110     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3111                 (BSL_META_U(unit,
   3112                     "P2L mapping: \n")));
   3113     for (index = 0;index < CUSTOM_MAPPING_ARRAY_SIZE;index++) {
   3114         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3115                 (BSL_META_U(unit,
   3116                     "%d "),
   3117                     p2l_mapping[index]));
   3118     }
   3119     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3120                 (BSL_META_U(unit,
   3121                     "\n")));
   3122     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3123                 (BSL_META_U(unit,
   3124                     "MAX SPEED: \n")));
   3125     for (index = 0;index < CUSTOM_MAPPING_ARRAY_SIZE;index++) {
   3126         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3127                 (BSL_META_U(unit,
   3128                     "%d "),
   3129                     speed_max[index]));
   3130     }
   3131     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3132                 (BSL_META_U(unit,
   3133                     "\n")));
   3134 
   3135     si = &SOC_INFO(unit);
   3136     si->bandwidth = 64000;
   3137     for (phy_port = 0; phy_port < SOC_MAX_PHY_PORTS; phy_port++) {
   3138         si->port_p2l_mapping[phy_port] = p2l_mapping[phy_port];
   3139         si->port_p2m_mapping[phy_port] = p2l_mapping[phy_port]; /* Same as Egr P2L */
   3140         si->max_port_p2m_mapping[phy_port] = p2l_mapping[phy_port]; /* For COSQ programming */
   3141         port_speed_max[phy_port] = 0;
   3142         if (speed_max[phy_port] != -1) {
   3143             si->port_speed_max[si->port_p2l_mapping[phy_port]] = 
   3144                 speed_max[phy_port] * 100;
   3145             port_speed_max[phy_port] = speed_max[phy_port] * 100;
   3146         }
   3147     }
   3148     return rv;
   3149 }
   3150 
   3151 /*
   3152  * HU2 port mapping
   3153  */
   3154 int
   3155 soc_hu2_port_config_init(int unit, uint16 dev_id)
   3156 {
   3157     int b, p;
   3158     /* Map of block to first physical port in the block */
   3159     int _hu2_b2pp[SOC_MAX_NUM_BLKS];
   3160 
   3161     for (b=0; SOC_BLOCK_TYPE(unit, b) != -1; b++) {
   3162         _hu2_b2pp[b] = -1;
   3163         for (p=0; SOC_PORT_BLOCK(unit, p)!= -1; p++) {
   3164             if (b == SOC_PORT_BLOCK(unit, p)) {
   3165                 _hu2_b2pp[b] = p;
   3166                 break;
   3167             }
   3168         }
   3169     }
   3170     SOC_INFO(unit).blk_fpp = _hu2_b2pp;
   3171     return soc_hu2_get_port_mapping(unit, dev_id);
   3172 }
   3173 
   3174 int
   3175 soc_hurricane2_tsc_reset(int unit)
   3176 {
   3177     int blk, port;
   3178     uint32 rval;
   3179 
   3180     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   3181         port = SOC_BLOCK_PORT(unit, blk);
   3182         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   3183     }
   3184 
   3185     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   3186         port = SOC_BLOCK_PORT(unit, blk);
   3187 
   3188         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval));
   3189         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1);
   3190         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   3191         sal_udelay(10);
   3192         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   3193         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   3194     }
   3195 
   3196     return SOC_E_NONE;
   3197 }
   3198 
   3199 int
   3200 _soc_hu2_tdm_init(int unit, uint16 dev_id)
   3201 {
   3202 
   3203     /* Embedded Mode TDM */
   3204     uint32 hu2_tdm_embedded[60] = {26,27,28,29,30,31,
   3205                       26,27,28,29,63,63,
   3206                       26,27,28,29,2,63,
   3207                       26,27,28,29,10,63,
   3208                       26,27,28,29,18,0,
   3209                       26,27,28,29,32,33,
   3210                       26,27,28,29,63,63,
   3211                       26,27,28,29,6,63,
   3212                       26,27,28,29,14,63,
   3213                       26,27,28,29,22,63};
   3214 
   3215     /* Embedded Plus Mode TDM */
   3216     uint32 hu2_tdm_embedded_plus[60] = {26,30,31,32,63,63,
   3217                       26,30,31,32,63,63,
   3218                       26,30,31,32,2,63,
   3219                       26,30,31,32,10,63,
   3220                       26,30,31,32,18,0,
   3221                       26,30,31,32,63,63,
   3222                       26,30,31,32,63,63,
   3223                       26,30,31,32,6,63,
   3224                       26,30,31,32,14,63,
   3225                       26,30,31,32,22,63};
   3226 
   3227     /* Powersave Mode TDM */
   3228     uint32 hu2_tdm_powersave[48] = {2,10,18,63,63,0,
   3229                       3,11,19,63,63,63,
   3230                       4,12,20,63,63,63,
   3231                       5,13,21,63,63,63,
   3232                       6,14,22,63,63,63,
   3233                       7,15,23,63,63,63,
   3234                       8,16,24,63,63,63,
   3235                       9,17,25,63,63,63};
   3236 
   3237     /* Cascade Mode TDM */
   3238     uint32 hu2_tdm_cascade[75] = {2,14,26,28,30,32,
   3239                       3,15,26,28,30,32,
   3240                       4,16,26,28,30,32,
   3241                       5,17,26,28,30,32,
   3242                       0,  
   3243                       6,18,26,28,30,32,
   3244                       7,19,26,28,30,32,
   3245                       8,20,26,28,30,32,
   3246                       9,21,26,28,30,32,
   3247                       63,
   3248                       10,22,26,28,30,32,
   3249                       11,23,26,28,30,32,
   3250                       12,24,26,28,30,32,
   3251                       13,25,26,28,30,32,
   3252                       63};
   3253 
   3254     /* XAUI Mode TDM */
   3255     uint32 hu2_tdm_xaui[75] = {2,14,26,27,28,30,
   3256                       3,15,26,27,28,30,
   3257                       4,16,26,27,28,30,
   3258                       5,17,26,27,28,30,
   3259                       0,  
   3260                       6,18,26,27,28,30,
   3261                       7,19,26,27,28,30,
   3262                       8,20,26,27,28,30,
   3263                       9,21,26,27,28,30,
   3264                       63,
   3265                       10,22,26,27,28,30,
   3266                       11,23,26,27,28,30,
   3267                       12,24,26,27,28,30,
   3268                       13,25,26,27,28,30,
   3269                       63};
   3270 
   3271     /* Non-Cascade Mode TDM */
   3272     uint32 hu2_tdm_non_cascade[75] = {2,14,26,27,28,29,
   3273                       3,15,26,27,28,29,
   3274                       4,16,26,27,28,29,
   3275                       5,17,26,27,28,29,
   3276                       0,
   3277                       6,18,26,27,28,29,
   3278                       7,19,26,27,28,29,
   3279                       8,20,26,27,28,29,
   3280                       9,21,26,27,28,29,
   3281                       63,
   3282                       10,22,26,27,28,29,
   3283                       11,23,26,27,28,29,
   3284                       12,24,26,27,28,29,
   3285                       13,25,26,27,28,29,
   3286                       63};
   3287 
   3288     /* Non-Cascade Mode TDM (option 1b)*/
   3289     uint32 hu2_tdm_non_cascade_1b[75] = {2,14,30,31,32,33,
   3290                       3,15,30,31,32,33,
   3291                       4,16,30,31,32,33,
   3292                       5,17,30,31,32,33,
   3293                       0,
   3294                       6,18,30,31,32,33,
   3295                       7,19,30,31,32,33,
   3296                       8,20,30,31,32,33,
   3297                       9,21,30,31,32,33,
   3298                       63,
   3299                       10,22,30,31,32,33,
   3300                       11,23,30,31,32,33,
   3301                       12,24,30,31,32,33,
   3302                       13,25,30,31,32,33,
   3303                       63};
   3304 
   3305     /* Powersave Plus Mode TDM */
   3306     uint32 hu2_tdm_powersave_plus[48] = {2,10,18,26,63,0,
   3307                       3,11,19,63,63,63,
   3308                       4,12,20,27,63,63,
   3309                       5,13,21,63,63,63,
   3310                       6,14,22,28,63,63,
   3311                       7,15,23,63,63,63,
   3312                       8,16,24,29,63,63,
   3313                       9,17,25,63,63,63};
   3314     uint32              *arr = NULL;
   3315     int                 tdm_size = 0;
   3316     uint32              rval; 
   3317     iarb_tdm_table_entry_t iarb_tdm;
   3318     mmu_arb_tdm_table_entry_t mmu_arb_tdm;
   3319     int i, port, phy_port;
   3320     int hu2_config_id;
   3321     int j;
   3322 
   3323     hu2_config_id = soc_property_get(unit, spn_BCM5615X_CONFIG, 0);
   3324 
   3325     SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval));
   3326     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 1);
   3327     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, 83);
   3328     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   3329 
   3330     switch (dev_id) {
   3331         case BCM56150_DEVICE_ID:
   3332         case BCM56151_DEVICE_ID:
   3333         case BCM53346_DEVICE_ID:
   3334         case BCM53347_DEVICE_ID:
   3335             if (hu2_config_id == 0) {
   3336                 tdm_size = 75;
   3337                 arr = hu2_tdm_non_cascade;
   3338             } else if (hu2_config_id == 13) {
   3339                 tdm_size = 75;
   3340                 arr = hu2_tdm_non_cascade_1b;
   3341             } else if ((hu2_config_id == 1) ||
   3342                        (hu2_config_id == 10) ||
   3343                        (hu2_config_id == 11) ||
   3344                        (hu2_config_id == 12)) {
   3345                 tdm_size = 75;
   3346                 arr = hu2_tdm_cascade;
   3347             } else if ((hu2_config_id == 2) ||
   3348                        (hu2_config_id == 3)) {
   3349                 tdm_size = 75;
   3350                 arr = hu2_tdm_xaui;
   3351             }
   3352             break;
   3353         case BCM53344_DEVICE_ID:
   3354             if (hu2_config_id == 0) {
   3355                 tdm_size = 48;
   3356                 arr = hu2_tdm_powersave_plus;
   3357             } else if ((hu2_config_id == 1) ||
   3358                        (hu2_config_id == 10) ||
   3359                        (hu2_config_id == 11)) {
   3360                 tdm_size = 75;
   3361                 arr = hu2_tdm_cascade;
   3362             }
   3363             break;
   3364         case BCM56152_DEVICE_ID:
   3365             if (hu2_config_id == 0) {
   3366                 tdm_size = 75;
   3367                 arr = hu2_tdm_non_cascade;
   3368             } else if (hu2_config_id == 13) {
   3369                 tdm_size = 75;
   3370                 arr = hu2_tdm_non_cascade_1b;
   3371             } else if ((hu2_config_id == 1) ||
   3372                        (hu2_config_id == 10) ||
   3373                        (hu2_config_id == 11)) {
   3374                 tdm_size = 75;
   3375                 arr = hu2_tdm_cascade;
   3376             }
   3377             break;
   3378         case BCM53333_DEVICE_ID:
   3379         case BCM53334_DEVICE_ID:
   3380         case BCM53342_DEVICE_ID:
   3381             tdm_size = 48;
   3382             arr = hu2_tdm_powersave;
   3383             break;
   3384         case BCM53343_DEVICE_ID:
   3385             tdm_size = 48;
   3386             arr = hu2_tdm_powersave_plus;
   3387             break;
   3388         case BCM53393_DEVICE_ID: 
   3389             tdm_size = 60;
   3390             arr = hu2_tdm_embedded;
   3391             break;
   3392         case BCM53394_DEVICE_ID:
   3393             tdm_size = 60;
   3394             if (hu2_config_id == 2) {
   3395                 arr = hu2_tdm_embedded_plus;
   3396             } else {
   3397                 arr = hu2_tdm_embedded;
   3398             }
   3399             break;
   3400         default :
   3401             break;
   3402     }
   3403 
   3404     if ((arr == NULL) || (tdm_size == 0)) {
   3405         return SOC_E_CONFIG;
   3406     }
   3407 
   3408     for (i = 0; i < tdm_size; i++) {
   3409         for (j = 0; j < CUSTOM_TSC_PORTMAP_COUNT; j++) {
   3410 			if (arr[i] == hu2_custom_tsc_portmap[j].phy_port_default) {
   3411                 if (hu2_custom_tsc_portmap[j].phy_port_default != hu2_custom_tsc_portmap[j].phy_port_custom) {
   3412                     arr[i] = hu2_custom_tsc_portmap[j].phy_port_custom;
   3413                 }
   3414                 break;
   3415             }
   3416         }
   3417     }
   3418     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3419                 (BSL_META_U(unit,
   3420                             "TDM table (size %d):\n"),
   3421                             tdm_size));
   3422     for (i = 0; i < tdm_size; i++) {
   3423         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3424                 (BSL_META_U(unit,
   3425                             "%d "),
   3426                             arr[i]));
   3427     }
   3428     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3429                 (BSL_META_U(unit,
   3430                             "\n")));
   3431 
   3432     for (i = 0; i < tdm_size; i++) {
   3433         phy_port = arr[i];
   3434         port = (phy_port != 63) ? SOC_INFO(unit).port_p2l_mapping[phy_port] : 63;
   3435         
   3436         sal_memset(&iarb_tdm, 0, sizeof(iarb_tdm_table_entry_t));
   3437         sal_memset(&mmu_arb_tdm, 0, sizeof(mmu_arb_tdm_table_entry_t));
   3438 
   3439         soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 
   3440                                         phy_port);
   3441 
   3442         soc_MMU_ARB_TDM_TABLEm_field32_set(unit, &mmu_arb_tdm, PORT_NUMf, 
   3443                                        (port != -1) ? port : 63);
   3444         if (i == tdm_size - 1) {
   3445             soc_MMU_ARB_TDM_TABLEm_field32_set(unit, &mmu_arb_tdm, WRAP_ENf, 1);
   3446         }
   3447         SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 
   3448                                                   &iarb_tdm));
   3449         SOC_IF_ERROR_RETURN(WRITE_MMU_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 
   3450                                                  &mmu_arb_tdm));
   3451     }
   3452     rval = 0;
   3453     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0);
   3454     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, 
   3455                       tdm_size -1);
   3456     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   3457     return SOC_E_NONE;
   3458 }
   3459 
   3460 int
   3461 soc_hurricane2_mmu_init(int unit)
   3462 {
   3463     int         cos;
   3464     soc_port_t  port;
   3465     uint32      val, oval, cfap_max_idx, tm;
   3466     int         age[HU2_NUM_COS], max_age, min_age;
   3467     int         age_enable, disabled_age;
   3468     int         skid_mark;
   3469     uint32 	dyn_xq_per_port;
   3470     uint32      limit;
   3471     uint32 	xq_limit, pkt_limit, cell_limit;
   3472     uint32      cos_min_xqs, cos_min_cells;
   3473     uint16      dev_id;
   3474     uint8       rev_id;
   3475 
   3476     soc_cm_get_id(unit, &dev_id, &rev_id);
   3477 
   3478     SOC_IF_ERROR_RETURN(_soc_hu2_tdm_init(unit, dev_id));
   3479 
   3480     cfap_max_idx = soc_mem_index_max(unit, MMU_CFAPm); 
   3481     SOC_IF_ERROR_RETURN(READ_CFAPCONFIGr(unit, &val));
   3482     oval = val;
   3483     soc_reg_field_set(unit, CFAPCONFIGr, &val, CFAPPOOLSIZEf, cfap_max_idx);
   3484     if (oval != val) {
   3485         SOC_IF_ERROR_RETURN(WRITE_CFAPCONFIGr(unit, val));
   3486     }
   3487 
   3488     /* set skidmarker to 3 */
   3489     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   3490     soc_reg_field_set(unit, MISCCONFIGr, &val, SKIDMARKERf, 3);
   3491     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val));
   3492 
   3493     /* Every inactive COSQ consumes skid mark + 4 XQs; remove them from pool */
   3494     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val));
   3495     skid_mark = soc_reg_field_get(unit, MISCCONFIGr, val, SKIDMARKERf) + 4;
   3496     
   3497     /* Enable IP to CMICM credit transfer */
   3498     val = 0;
   3499     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &val, TRANSFER_ENABLEf, 1);
   3500     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &val, NUM_OF_CREDITSf, 32);
   3501     SOC_IF_ERROR_RETURN(WRITE_IP_TO_CMICM_CREDIT_TRANSFERr(unit, val));
   3502 
   3503     if (dev_id != BCM56147_DEVICE_ID) {
   3504         /* total dynamic xqs - skid mark - 9(reserved xqs) */	
   3505         dyn_xq_per_port = HU2_MMU_IN_PORT_DYNAMIC_XQS -  skid_mark - 9;
   3506         /* limit includes the static minimum cells as well */
   3507         xq_limit = dyn_xq_per_port + 8;
   3508         cos_min_xqs = HU2_MMU_IN_COS_MIN_XQS;
   3509         cos_min_cells = HU2_MMU_IN_COS_MIN_CELLS;
   3510     }
   3511     else {
   3512         /* dynamic xqs = total xqs - static xqs(num of cos * per cos reserve(4)) */
   3513         dyn_xq_per_port = HU2_MMU_IN_PORT_TOTAL_XQS - (HU2_MMU_NUM_COS * 4); 
   3514         /* total dynamic xqs = dynamic xqs - skid mark - 9(reserved xqs) */	
   3515         dyn_xq_per_port = dyn_xq_per_port -  skid_mark - 9;
   3516         /* limit includes the static minimum cells as well */
   3517         xq_limit = dyn_xq_per_port + 4;
   3518         cos_min_xqs = HU2_MMU_IN_COS_MIN_XQS/2;
   3519         cos_min_cells = HU2_MMU_IN_COS_MIN_CELLS + 4;
   3520     }
   3521 
   3522     PBMP_ALL_ITER(unit, port) {
   3523 
   3524         for (cos = 0; cos < NUM_COS(unit); cos++) {
   3525             /* 
   3526              * The HOLCOSPKTSETLIMITr register controls BOTH the XQ 
   3527              * size per cosq AND the HOL set limit for that cosq.
   3528              */
   3529             SOC_IF_ERROR_RETURN
   3530                 (READ_HOLCOSPKTSETLIMITr(unit, port, cos, &val));
   3531             soc_reg_field_set(unit, HOLCOSPKTSETLIMITr, &val,
   3532                               PKTSETLIMITf, 
   3533                               xq_limit);
   3534             SOC_IF_ERROR_RETURN
   3535                 (WRITE_HOLCOSPKTSETLIMITr(unit, port, cos, val));
   3536 
   3537             /* reset limit is set limit - 4 */
   3538             SOC_IF_ERROR_RETURN
   3539                 (READ_HOLCOSPKTRESETLIMITr(unit, port, cos, &val));
   3540             soc_reg_field_set(unit, HOLCOSPKTRESETLIMITr, &val,
   3541                               PKTRESETLIMITf, 
   3542                               xq_limit-4);
   3543             SOC_IF_ERROR_RETURN
   3544                 (WRITE_HOLCOSPKTRESETLIMITr(unit, port, cos, val));
   3545 
   3546             val = 0;
   3547             soc_reg_field_set(unit, HOLCOSMINXQCNTr, &val,
   3548                               HOLCOSMINXQCNTf, cos_min_xqs);
   3549             SOC_IF_ERROR_RETURN
   3550                 (WRITE_HOLCOSMINXQCNTr(unit, port, cos, val)); 
   3551 
   3552             val = 0;
   3553             soc_reg_field_set(unit, LWMCOSCELLSETLIMITr, &val,
   3554                               CELLSETLIMITf, cos_min_cells);
   3555             soc_reg_field_set(unit, LWMCOSCELLSETLIMITr, &val,
   3556                               CELLRESETLIMITf, cos_min_cells);
   3557             SOC_IF_ERROR_RETURN
   3558                 (WRITE_LWMCOSCELLSETLIMITr(unit, port, cos, val)); 
   3559               
   3560             cell_limit = 0;
   3561             if (dev_id != BCM56147_DEVICE_ID) {
   3562                 if(!cos) {
   3563                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3564                                       CELLMAXLIMITf, HU2_MMU_MAX_CELL_LIMIT_PRI_0);
   3565                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3566                                       CELLMAXRESUMELIMITf, HU2_MMU_MAX_CELL_LIMIT_PRI_0 - 12);
   3567                 } else {
   3568                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3569                                       CELLMAXLIMITf, HU2_MMU_MAX_CELL_LIMIT_PRI_1_7);
   3570                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3571                                       CELLMAXRESUMELIMITf, HU2_MMU_MAX_CELL_LIMIT_PRI_1_7 - 12);
   3572                 }
   3573             } 
   3574             else {
   3575                 /* use the settings given by design team for 56147 */
   3576                 if(!cos) {
   3577                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3578                                       CELLMAXLIMITf, 8000);
   3579                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3580                                       CELLMAXRESUMELIMITf, 7238);
   3581                 } else {
   3582                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3583                                       CELLMAXLIMITf, 7250);
   3584                     soc_reg_field_set(unit, HOLCOSCELLMAXLIMITr, &cell_limit,
   3585                                       CELLMAXRESUMELIMITf, 7238);
   3586                 }
   3587            }
   3588             SOC_IF_ERROR_RETURN
   3589                 (WRITE_HOLCOSCELLMAXLIMITr(unit, port, cos, cell_limit)); 
   3590         }
   3591 
   3592         val = 0;
   3593         soc_reg_field_set(unit, DYNXQCNTPORTr, &val,
   3594                           DYNXQCNTPORTf, dyn_xq_per_port);
   3595         SOC_IF_ERROR_RETURN(WRITE_DYNXQCNTPORTr(unit, port, val)); 
   3596 
   3597         val = 0;
   3598         soc_reg_field_set(unit, DYNRESETLIMPORTr, &val,
   3599                           DYNRESETLIMPORTf, dyn_xq_per_port - 4);
   3600         SOC_IF_ERROR_RETURN(WRITE_DYNRESETLIMPORTr(unit, port, val)); 
   3601 
   3602         cell_limit = 0;
   3603         soc_reg_field_set(unit, IBPDISCARDSETLIMITr, &cell_limit,
   3604                           DISCARDSETLIMITf, HU2_MMU_TOTAL_CELLS-1);
   3605         SOC_IF_ERROR_RETURN(WRITE_IBPDISCARDSETLIMITr(unit, port, cell_limit));
   3606 
   3607         if (dev_id != BCM56147_DEVICE_ID) {
   3608             val = 0;
   3609             soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   3610                               DYNCELLSETLIMITf, HU2_MMU_DYN_CELL_LIMIT);
   3611             soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   3612                               DYNCELLRESETLIMITf, HU2_MMU_DYN_CELL_LIMIT - 24);
   3613             SOC_IF_ERROR_RETURN(WRITE_DYNCELLLIMITr(unit, port, val)); 
   3614 
   3615             pkt_limit = 0;
   3616             soc_reg_field_set(unit, IBPPKTSETLIMITr, &pkt_limit,
   3617                               PKTSETLIMITf, HU2_MMU_IN_COS_MIN_CELLS);
   3618             SOC_IF_ERROR_RETURN(WRITE_IBPPKTSETLIMITr(unit, port, pkt_limit));    
   3619 
   3620             cell_limit = 0;
   3621             soc_reg_field_set(unit, IBPCELLSETLIMITr, &cell_limit, 
   3622                               CELLSETLIMITf, HU2_MMU_XOFF_CELL_LIMIT);   
   3623             SOC_IF_ERROR_RETURN(WRITE_IBPCELLSETLIMITr(unit, port, cell_limit));
   3624         }
   3625         else {
   3626             /* use the settings given by design team for 56147 */
   3627             val = 0;
   3628             /* dyn cell limit = 8000 + (total cos -1)*4*2048/128 */
   3629             soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   3630                               DYNCELLSETLIMITf, 8448);
   3631             soc_reg_field_set(unit, DYNCELLLIMITr, &val,
   3632                               DYNCELLRESETLIMITf, 8424);
   3633             SOC_IF_ERROR_RETURN(WRITE_DYNCELLLIMITr(unit, port, val)); 
   3634 
   3635             pkt_limit = 0;
   3636             soc_reg_field_set(unit, IBPPKTSETLIMITr, &pkt_limit,
   3637                               PKTSETLIMITf, 33);
   3638             SOC_IF_ERROR_RETURN(WRITE_IBPPKTSETLIMITr(unit, port, pkt_limit));    
   3639 
   3640             cell_limit = 0;
   3641             soc_reg_field_set(unit, IBPCELLSETLIMITr, &cell_limit, 
   3642                               CELLSETLIMITf, 36);   
   3643             SOC_IF_ERROR_RETURN(WRITE_IBPCELLSETLIMITr(unit, port, cell_limit));
   3644        
   3645             /* E2EFC configuration */
   3646             if (IS_HG_PORT(unit, port)){
   3647                 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &val));
   3648                 soc_reg_field_set(unit, XPORT_CONFIGr, &val, E2E_IBP_ENf, 1);
   3649                 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, val));
   3650 
   3651                 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
   3652                 soc_reg_field_set(unit, IE2E_CONTROLr, &val, IBP_ENABLEf, 1);
   3653                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, val));
   3654 
   3655                 val = 0;
   3656                 soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val, 
   3657                                   LGf, 0);
   3658                 soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val, 
   3659                                   TIMERf, 1);                
   3660                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_HG_MIN_TX_TIMERr(unit, port-26, val));
   3661 
   3662                 val = 0;
   3663                 soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val, 
   3664                                   LGf, 1);
   3665                 soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val, 
   3666                                   TIMERf, 640);                
   3667                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_HG_MAX_TX_TIMERr(unit, port-26, val));
   3668 
   3669                 limit = 0;
   3670                 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   3671                                   PKT_SET_LIMITf, 1456);
   3672                 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   3673                                   CELL_SET_LIMITf, 9504);
   3674                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_SET_LIMITr(unit, port, limit));
   3675 
   3676                 limit = 0;
   3677                 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   3678                                   PKT_RESET_LIMITf, 1456);
   3679                 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   3680                                   CELL_RESET_LIMITf, 9504);
   3681                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_RESET_LIMITr(unit, port, limit));
   3682 
   3683                 limit = 0;
   3684                 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   3685                                   PKT_DISC_LIMITf, 1456);
   3686                 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   3687                                   CELL_DISC_LIMITf, 9504);
   3688                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_DISC_LIMITr(unit, port, limit));
   3689             }
   3690             else {
   3691                 limit = 0;
   3692                 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   3693                                   PKT_SET_LIMITf, 33);
   3694                 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &limit, 
   3695                                   CELL_SET_LIMITf, 36);
   3696                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_SET_LIMITr(unit, port, limit));
   3697 
   3698                 limit = 0;
   3699                 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   3700                                   PKT_RESET_LIMITf, 24);
   3701                 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &limit, 
   3702                                   CELL_RESET_LIMITf, 26);
   3703                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_RESET_LIMITr(unit, port, limit));
   3704 
   3705                 limit = 0;
   3706                 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   3707                                   PKT_DISC_LIMITf, 1456);
   3708                 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &limit, 
   3709                                   CELL_DISC_LIMITf, 9504);
   3710                 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CNT_DISC_LIMITr(unit, port, limit));
   3711 
   3712             }
   3713 
   3714         }
   3715 
   3716     }
   3717 
   3718     /* device specific dynamic cell limit */
   3719     if (dev_id != BCM56147_DEVICE_ID) {
   3720         cell_limit = 0;
   3721         soc_reg_field_set(unit, TOTALDYNCELLSETLIMITr,
   3722                           &cell_limit, TOTALDYNCELLSETLIMITf, HU2_MMU_TOTAL_DYNAMIC_CELLS);
   3723         SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLSETLIMITr(unit, cell_limit));
   3724         cell_limit = 0;
   3725         soc_reg_field_set(unit, TOTALDYNCELLRESETLIMITr,
   3726                           &cell_limit, TOTALDYNCELLRESETLIMITf, HU2_MMU_TOTAL_DYNAMIC_CELLS - 24);
   3727         SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLRESETLIMITr(unit, cell_limit));
   3728     }
   3729     else {
   3730         cell_limit = 0;
   3731         soc_reg_field_set(unit, TOTALDYNCELLSETLIMITr,
   3732                           &cell_limit, TOTALDYNCELLSETLIMITf, 8576);
   3733         SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLSETLIMITr(unit, cell_limit));
   3734         cell_limit = 0;
   3735         soc_reg_field_set(unit, TOTALDYNCELLRESETLIMITr,
   3736                       &cell_limit, TOTALDYNCELLRESETLIMITf, 8552);
   3737         SOC_IF_ERROR_RETURN(WRITE_TOTALDYNCELLRESETLIMITr(unit, cell_limit));
   3738 
   3739         /* E2EFC configuration */
   3740         SOC_IF_ERROR_RETURN(READ_E2EFC_IBP_ENr(unit, &val));
   3741         soc_reg_field_set(unit, E2EFC_IBP_ENr, &val, ENf, 1);
   3742         SOC_IF_ERROR_RETURN(WRITE_E2EFC_IBP_ENr(unit, val));
   3743    }
   3744 
   3745     /* 
   3746      * Configure per-XQ packet aging for the various COSQs. 
   3747      *
   3748      * The shortest age allowed by H/W is 250 microseconds.
   3749      * The longest age allowed is 7.162 seconds (7162 msec).
   3750      * The maximum ratio between the longest age and the shortest 
   3751      * (nonzero) age is 7:2.
   3752      */
   3753     age_enable = disabled_age = max_age = 0;
   3754     min_age = 7162;
   3755     for (cos = 0; cos < NUM_COS(unit); cos++) {
   3756         if ((age[cos] = 
   3757              soc_property_suffix_num_get(unit, cos, spn_MMU_XQ_AGING,
   3758                                          "cos",  0)) > 0) {
   3759             age_enable = 1;
   3760             if (age[cos] > 7162) {
   3761                 age[cos] = 7162;
   3762             }
   3763             if (age[cos] < min_age) {
   3764                 min_age = age[cos];
   3765             }
   3766         } else {
   3767             disabled_age = 1;
   3768             age[cos] = 0;
   3769         }
   3770         if (age[cos] > max_age) {
   3771             max_age = age[cos];
   3772         }
   3773     }
   3774     if (!age_enable) {
   3775         /* Disable packet aging on all COSQs */
   3776         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGTIMERr(unit, 0));
   3777         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGLIMITr(unit, 0)); /* Aesthetic */
   3778     } else {
   3779         uint32 regval = 0;
   3780         uint32 timerval;
   3781 
   3782         /* Enforce the 7:2 ratio between min and max values */
   3783         if ((((max_age * 2)+6) / 7) > min_age) {
   3784             /* Keep requested max age; make min_age comply */ 
   3785             min_age = ((max_age * 2) + 6) / 7; 
   3786         }
   3787 
   3788         /* 
   3789          * Give up granularity for range, if we need to
   3790          * "disable" (max out) aging for any COSQ(s).
   3791          */
   3792         if (disabled_age) {
   3793             /* Max range */
   3794             max_age = min_age * 7 / 2;
   3795         } 
   3796 
   3797         /* 
   3798          * Compute shortest duration of one PKTAGINGTIMERr cycle. 
   3799          * This duration is 1/7th of the longest packet age. 
   3800          * This duration is in units of 125 usec (msec * 8).
   3801          */
   3802         timerval = ((8 * max_age) + 6) / 7; 
   3803         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGTIMERr(unit, timerval));
   3804 
   3805         for (cos = 0; cos < NUM_COS(unit); cos++) {
   3806             if (!age[cos]) {
   3807                 /* 
   3808                  * Requested to be disabled, but cannot disable individual
   3809                  * COSQs once packet aging is enabled. Therefore, mark
   3810                  * this COSQ's aging duration as maxed out.
   3811                  */
   3812                 age[cos] = -1;
   3813             } else if (age[cos] < min_age) {
   3814                 age[cos] = min_age;
   3815             }
   3816 
   3817             /* Normalize each "age" into # of PKTAGINGTIMERr cycles. */
   3818             if (age[cos] > 0) {
   3819                 /* coverity[divide_by_zero : FALSE] */
   3820                 age[cos] = ((8 * age[cos]) + timerval - 1) / timerval;
   3821             }
   3822             else {
   3823                 age[cos] = 7;
   3824             }
   3825             /* Format each "age" for its appropriate field */
   3826             regval |= ((7 - age[cos]) << (cos * 3));
   3827         }
   3828         SOC_IF_ERROR_RETURN(WRITE_PKTAGINGLIMITr(unit, regval));
   3829     }
   3830 
   3831     /* Apply TM=0x10 setting for all CAMs */
   3832     tm=0x10;
   3833     val = 0;
   3834     soc_reg_field_set(unit, SW2_RAM_CONTROL_4r, &val,
   3835                       CPU_COS_MAP_TCAM_TMf, tm);
   3836     SOC_IF_ERROR_RETURN(WRITE_SW2_RAM_CONTROL_4r_REG32(unit, val));
   3837 
   3838     val = 0;
   3839     soc_reg_field_set(unit, L2_USER_ENTRY_CAM_DBGCTRLr, &val,
   3840                       TMf, tm);
   3841     SOC_IF_ERROR_RETURN(WRITE_L2_USER_ENTRY_CAM_DBGCTRLr(unit, val));
   3842 
   3843     
   3844     SOC_IF_ERROR_RETURN(READ_VLAN_SUBNET_CAM_DBGCTRLr(unit, &val));
   3845     soc_reg_field_set(unit, VLAN_SUBNET_CAM_DBGCTRLr, &val,
   3846                       TMf, tm);
   3847     SOC_IF_ERROR_RETURN(WRITE_VLAN_SUBNET_CAM_DBGCTRLr(unit, val));
   3848    
   3849     /*
   3850      * Port enable
   3851      */
   3852     val = 0;
   3853     soc_reg_field_set(unit, MMUPORTENABLEr, &val, MMUPORTENABLEf,
   3854                       SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0));
   3855     SOC_IF_ERROR_RETURN(WRITE_MMUPORTENABLEr(unit, val));
   3856 
   3857     return SOC_E_NONE;
   3858 }
   3859 
   3860 STATIC int
   3861 _hurricane2_ledup_init(int unit)
   3862 {
   3863     int ix, pval1, pval2, pval3, pval4;
   3864     uint32 rval = 0;
   3865     struct led_remap {
   3866        uint32 reg_addr;
   3867        uint32 port0;
   3868        uint32 port1;
   3869        uint32 port2;
   3870        uint32 port3;
   3871     } led0_remap[] = {
   3872         {CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r,
   3873          REMAP_PORT_0f,REMAP_PORT_1f,REMAP_PORT_2f,REMAP_PORT_3f},
   3874         {CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r,
   3875          REMAP_PORT_4f,REMAP_PORT_5f,REMAP_PORT_6f,REMAP_PORT_7f},
   3876         {CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r,
   3877          REMAP_PORT_8f,REMAP_PORT_9f,REMAP_PORT_10f,REMAP_PORT_11f},
   3878         {CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r,
   3879          REMAP_PORT_12f,REMAP_PORT_13f,REMAP_PORT_14f,REMAP_PORT_15f},
   3880         {CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r,
   3881          REMAP_PORT_16f,REMAP_PORT_17f,REMAP_PORT_18f,REMAP_PORT_19f},
   3882         {CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r,
   3883          REMAP_PORT_20f,REMAP_PORT_21f,REMAP_PORT_22f,REMAP_PORT_23f},
   3884         {CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r,
   3885          REMAP_PORT_24f,REMAP_PORT_25f,REMAP_PORT_26f,REMAP_PORT_27f},
   3886         {CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r,
   3887          REMAP_PORT_28f,REMAP_PORT_29f,REMAP_PORT_30f,REMAP_PORT_31f}
   3888     };
   3889 
   3890     /* initialize the led remap register settings. 
   3891      * port 0 entry will not be used for easy index of the physical port starting 1
   3892      */   
   3893     for (ix = 0; ix < sizeof(led0_remap)/sizeof(led0_remap[0]); ix++) {
   3894         pval1 = (ix * 4) + 2;
   3895         pval2 = pval1 + 1;
   3896         pval3 = pval1 + 2;
   3897         pval4 = pval1 + 3;
   3898         if ((pval1 == 26) || (pval1 == 30)) {
   3899             /* Transpose MXQ Block ports */
   3900             pval4 = pval1;
   3901             pval3 = pval4 + 1;
   3902             pval2 = pval4 + 2;
   3903             pval1 = pval1 + 3;
   3904         }
   3905 
   3906         rval = 0;
   3907         soc_reg_field_set(unit, led0_remap[ix].reg_addr, &rval, 
   3908                          led0_remap[ix].port0, pval1);
   3909         soc_reg_field_set(unit, led0_remap[ix].reg_addr, &rval, 
   3910                          led0_remap[ix].port1, pval2);
   3911         soc_reg_field_set(unit, led0_remap[ix].reg_addr, &rval, 
   3912                          led0_remap[ix].port2, pval3);
   3913         soc_reg_field_set(unit, led0_remap[ix].reg_addr, &rval, 
   3914                          led0_remap[ix].port3, pval4);
   3915         /* coverity[result_independent_of_operands] */
   3916         SOC_IF_ERROR_RETURN
   3917             (soc_pci_write(unit, 
   3918                 soc_reg_addr(unit, led0_remap[ix].reg_addr, REG_PORT_ANY, 0), 
   3919                 rval));
   3920     }
   3921 
   3922     /* Do Raw schan ops because Not all ports may be enabled */
   3923     {
   3924         /* XLPORT_LED_CHAIN_CONFIGr */
   3925         _soc_reg32_set(unit, 5, 0, (0x2022b00), (0x00000006));
   3926         _soc_reg32_set(unit, 6, 0, (0x2022b00), (0x00000006));
   3927     }
   3928 
   3929     /* initialize the UP0 data ram */
   3930     rval = 0;
   3931     for (ix = 0; ix < 256; ix++) {
   3932         /* coverity[result_independent_of_operands] */
   3933         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval));
   3934     }
   3935 
   3936     /* Apply LEDUP delays. */
   3937     /* coverity[result_independent_of_operands] */
   3938     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval));
   3939     soc_reg_field_set(unit,CMIC_LEDUP0_CTRLr,
   3940                       &rval, LEDUP_SCAN_START_DELAYf, 0x6);
   3941     soc_reg_field_set(unit,CMIC_LEDUP0_CTRLr,
   3942                       &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 0x5);
   3943     /* coverity[result_independent_of_operands] */
   3944     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval));
   3945 
   3946     return SOC_E_NONE;  
   3947 }
   3948 
   3949 STATIC int
   3950 _soc_hu2_power_Optimize(int unit) {
   3951     int blk;
   3952     uint32 rval;
   3953 
   3954     /* Turn on Per Stage Clock Gating */
   3955     SOC_IF_ERROR_RETURN(READ_TOP_CLOCKING_ENFORCE_PSGr(unit,&rval));
   3956     soc_reg_field_set(unit, TOP_CLOCKING_ENFORCE_PSGr, &rval,
   3957                       CLK_ENFORCE_XLPORTf, 0);
   3958     SOC_IF_ERROR_RETURN(WRITE_TOP_CLOCKING_ENFORCE_PSGr(unit,rval));
   3959 
   3960     /* Power Down Unused XLPORT Blocks */
   3961     /* Since these regis are not accessible normally, use direct schan access */
   3962     for (blk=5; blk<=6; blk++) {
   3963         _soc_reg32_get(unit, blk,0, (0x02020b00), &rval); /*XLPORT_ENABLE_REG */
   3964         if (rval == 0) { /* No Ports Enabled */
   3965             rval = 0;
   3966             soc_reg_field_set(unit, XLPORT_POWER_SAVEr, &rval,
   3967                                    XPORT_CORE0f, 1);
   3968             _soc_reg32_set(unit, blk,0, (0x02020d00), rval);
   3969 
   3970             _soc_reg32_get(unit, blk,0, (0x02021400), &rval);
   3971             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval,
   3972                                        PWRDWNf, 1);
   3973             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval,
   3974                                          IDDQf, 1);
   3975             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval,
   3976                                        TSCCLK_ENf, 0);
   3977             _soc_reg32_set(unit, blk,0, (0x02021400), rval);
   3978         }
   3979     }
   3980     
   3981     return SOC_E_NONE;
   3982 }
   3983 
   3984 #if defined(SER_TR_TEST_SUPPORT)
   3985 soc_ser_test_functions_t ser_hu2_test_fun;
   3986 #endif
   3987 
   3988 
   3989 int
   3990 soc_hurricane2_misc_init(int unit)
   3991 {
   3992 #define NUM_XLPORT 4
   3993     static const soc_field_t port_field[] = {
   3994         PORT0f, PORT1f, PORT2f, PORT3f
   3995     };
   3996     uint32              rval; 
   3997     uint32              prev_reg_addr;
   3998     uint64              reg64;
   3999     int                 port;
   4000     uint32 entry[SOC_MAX_MEM_WORDS];
   4001     soc_field_t         fields[3];
   4002     uint32              values[3];
   4003     int blk, bindex, mode;
   4004     int phy_port_base;
   4005     soc_info_t *si = &SOC_INFO(unit);
   4006     uint16      dev_id;
   4007     uint8       rev_id;
   4008     int divisor, dividend;
   4009     int hu2_config_id;
   4010     uint32 qsgmii_override = 0;
   4011     int core_clock_freq = 0, parity_enable;
   4012     uint32 eee_duration_time_pulse = 0;
   4013     pbmp_t blk_bitmap;
   4014     int led_intensity = -1;
   4015     uint32 fval;
   4016 
   4017     /* Stop the mem scan task before all of the parity init takes place */
   4018     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
   4019     
   4020     soc_cm_get_id(unit, &dev_id, &rev_id);
   4021     hu2_config_id = soc_property_get(unit, spn_BCM5615X_CONFIG, 0);
   4022 
   4023     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   4024         /* Clear IPIPE/EIPIE Memories */
   4025         SOC_IF_ERROR_RETURN(soc_hurricane2_pipe_mem_clear(unit));
   4026     }
   4027 
   4028     SOC_IF_ERROR_RETURN(soc_hu2_init_port_mapping(unit));
   4029 
   4030     
   4031     /* Turn on ingress/egress/mmu parity */
   4032     parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
   4033     if (soc_feature(unit, soc_feature_field_multi_stage)) {
   4034         _soc_hu2_parity_group_info = _soc_hu2_parity_group_info_template;
   4035     } else {
   4036         _soc_hu2_parity_group_info = _soc_wf_parity_group_info_template;
   4037     }
   4038     if (parity_enable) {
   4039         _soc_hurricane2_parity_enable(unit, TRUE);
   4040 #if defined(SER_TR_TEST_SUPPORT)
   4041         soc_hu2_ser_test_register(unit);
   4042 #endif /*defined(SER_TR_TEST_SUPPORT*/
   4043 
   4044         (void)_soc_hurricane2_tcam_ser_init(unit);
   4045         memset(&_hu2_ser_functions, 0, sizeof(soc_ser_functions_t));
   4046 #ifdef INCLUDE_MEM_SCAN        
   4047         soc_mem_scan_ser_list_register(unit, TRUE, _soc_hu2_tcam_ser_info); 
   4048 #endif /* INCLUDE_MEM_SCAN */
   4049         memset(&_hu2_ser_functions, 0, sizeof(soc_ser_functions_t));
   4050         _hu2_ser_functions._soc_ser_fail_f = &soc_hurricane2_ser_fail;
   4051         _hu2_ser_functions._soc_ser_parity_error_cmicm_intr_f = 
   4052             &soc_hurricane2_parity_error;
   4053         _hu2_ser_functions._soc_ser_mem_nack_f = 
   4054             &soc_hurricane2_mem_nack;
   4055         soc_ser_function_register(unit, &_hu2_ser_functions);
   4056     } else {
   4057         _soc_hurricane2_parity_enable(unit, FALSE);
   4058     }
   4059 
   4060     core_clock_freq = 0; /* 0 means run in native frequency */
   4061     switch (dev_id) {
   4062         case BCM56151_DEVICE_ID:
   4063         case BCM53347_DEVICE_ID:
   4064         case BCM53346_DEVICE_ID:
   4065             if ((hu2_config_id == 0) ||	(hu2_config_id == 12) || \
   4066                 (hu2_config_id == 13)) {
   4067                 core_clock_freq = soc_property_get(unit, spn_CORE_CLOCK_SPEED, 0);
   4068             }
   4069             break;
   4070         case BCM56152_DEVICE_ID:
   4071             if ((hu2_config_id == 0) || (hu2_config_id == 13)) {
   4072                 core_clock_freq = soc_property_get(unit, spn_CORE_CLOCK_SPEED, 0);
   4073             }
   4074             break;
   4075         case BCM53344_DEVICE_ID:
   4076             if (hu2_config_id == 0) {
   4077                 core_clock_freq = soc_property_get(unit, spn_CORE_CLOCK_SPEED, 0);
   4078             }
   4079             break;
   4080         case BCM53343_DEVICE_ID:
   4081         case BCM53342_DEVICE_ID:
   4082             core_clock_freq = soc_property_get(unit, spn_CORE_CLOCK_SPEED, 0);
   4083             break;
   4084         default :
   4085             break;
   4086     }
   4087 
   4088     eee_duration_time_pulse = 0x53; /* time pulse value for 1 us at 84.375MHz */
   4089     if (core_clock_freq == 25) { /* core clock at 25MHz */
   4090         SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r(unit, &rval));
   4091         soc_reg_field_set(unit, TOP_MISC_CONTROL_1r, &rval, CMIC_TO_CORE_PLL_LOADf, 1);
   4092         SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_1r(unit, rval));
   4093 
   4094         SOC_IF_ERROR_RETURN(READ_TOP_CORE_PLL_CTRL4r(unit, &rval));
   4095         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL4r, &rval, MSTR_CH0_MDIVf, 135);
   4096         SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_PLL_CTRL4r(unit, rval));
   4097 
   4098         SOC_IF_ERROR_RETURN(READ_TOP_CORE_PLL_CTRL2r(unit, &rval));
   4099         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL2r, &rval, LOAD_EN_CH0f, 1);
   4100         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL2r, &rval, LOAD_EN_CH1f, 1);
   4101         SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_PLL_CTRL2r(unit, rval));
   4102 
   4103         eee_duration_time_pulse = 0x18; /* time pulse value for 1 us at 25MHz */
   4104     } else { /* native 84.375 or 135 MHz */
   4105         core_clock_freq = 84;
   4106         /* Bump up core clock to 135 MHz if any TSC port is > 1G */
   4107         for (port = 26; port <= 33; port++) { /* All TSC ports */
   4108             if (port_speed_max[port] > 1000) {
   4109                 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r(unit, &rval));
   4110                 soc_reg_field_set(unit, TOP_MISC_CONTROL_1r, &rval, CMIC_TO_CORE_PLL_LOADf, 1);
   4111                 SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_1r(unit, rval));
   4112     
   4113                 SOC_IF_ERROR_RETURN(READ_TOP_CORE_PLL_CTRL4r(unit, &rval));
   4114                 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL4r, &rval, MSTR_CH0_MDIVf, 25);
   4115                 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_PLL_CTRL4r(unit, rval));
   4116                 
   4117                 SOC_IF_ERROR_RETURN(READ_TOP_CORE_PLL_CTRL2r(unit, &rval));
   4118                 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL2r, &rval, LOAD_EN_CH0f, 1);
   4119                 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL2r, &rval, LOAD_EN_CH1f, 1);
   4120                 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_PLL_CTRL2r(unit, rval));
   4121 
   4122                 eee_duration_time_pulse = 0x86; /* time pulse value for 1 us at 135MHz */
   4123                 core_clock_freq = 135;
   4124                 break;
   4125             }
   4126         }
   4127     }
   4128 
   4129     si->frequency = core_clock_freq;
   4130 
   4131     SOC_BLOCK_ITER(unit, blk, SOC_BLK_GPORT) {
   4132         blk_bitmap = SOC_BLOCK_BITMAP(unit, blk);
   4133         PBMP_ITER(blk_bitmap, port) {
   4134             SOC_IF_ERROR_RETURN(READ_GE0_EEE_CONFIGr(unit, port, &rval));
   4135             soc_reg_field_set(unit, GE0_EEE_CONFIGr, &rval, 
   4136                         EEE_DURATION_TIMER_PULSEf, eee_duration_time_pulse);
   4137             SOC_IF_ERROR_RETURN(WRITE_GE0_EEE_CONFIGr(unit, port, rval));
   4138             SOC_IF_ERROR_RETURN(WRITE_GE1_EEE_CONFIGr(unit, port, rval));
   4139             SOC_IF_ERROR_RETURN(WRITE_GE2_EEE_CONFIGr(unit, port, rval));
   4140             SOC_IF_ERROR_RETURN(WRITE_GE3_EEE_CONFIGr(unit, port, rval));
   4141             SOC_IF_ERROR_RETURN(WRITE_GE4_EEE_CONFIGr(unit, port, rval));
   4142             SOC_IF_ERROR_RETURN(WRITE_GE5_EEE_CONFIGr(unit, port, rval));
   4143             SOC_IF_ERROR_RETURN(WRITE_GE6_EEE_CONFIGr(unit, port, rval));
   4144             SOC_IF_ERROR_RETURN(WRITE_GE7_EEE_CONFIGr(unit, port, rval));
   4145         }
   4146     }
   4147 
   4148     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   4149     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   4150     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   4151 
   4152     /* HR2 WAR for SDK-60041 : for GE port with UNIMAC only
   4153     *  - Wrong UMAC_EEE_REF_COUNT configuration causes packet loss
   4154     * 
   4155     *  1. UMAC_EEE_REF_COUNT set to 0x1f4 for core_clk=500Mhz.
   4156     *      for HR2, core_clk=tsc_pll_clk.
   4157     *  2. Wake/Delay timer for GMII and MII register's reset value 
   4158     *      need be revised.
   4159     *      - WAKE_TIMER set to 0x1e for MII and 0x11 for GMII
   4160     *      - DELAY_ENTRY_TIMER set to 0x3c for MII and 0x22 for GMII
   4161     */
   4162     PBMP_E_ITER(unit, port) {
   4163         if (!IS_GE_PORT(unit, port) || IS_XL_PORT(unit, port)) {
   4164             continue;
   4165         }
   4166         SOC_IF_ERROR_RETURN(READ_UMAC_EEE_REF_COUNTr(unit, port, &rval));
   4167         soc_reg_field_set(unit, 
   4168                 UMAC_EEE_REF_COUNTr, &rval, EEE_REF_COUNTf, 0x1f4);
   4169         SOC_IF_ERROR_RETURN(WRITE_UMAC_EEE_REF_COUNTr(unit, port, rval));
   4170 
   4171         SOC_IF_ERROR_RETURN(WRITE_MII_EEE_WAKE_TIMERr(unit, port, 0x1e));
   4172         SOC_IF_ERROR_RETURN(WRITE_GMII_EEE_WAKE_TIMERr(unit, port, 0x11));
   4173         SOC_IF_ERROR_RETURN(WRITE_MII_EEE_DELAY_ENTRY_TIMERr(unit, port, 0x3c));
   4174         SOC_IF_ERROR_RETURN(WRITE_GMII_EEE_DELAY_ENTRY_TIMERr(unit, port, 0x22));
   4175     }
   4176 
   4177     /* Enable dual hash on L2 and L3 tables */
   4178     fields[0] = ENABLEf;
   4179     values[0] = 1;
   4180     fields[1] = HASH_SELECTf;
   4181     values[1] = FB_HASH_CRC32_LOWER;
   4182     fields[2] = INSERT_LEAST_FULL_HALFf;
   4183     values[2] = 1;
   4184     SOC_IF_ERROR_RETURN
   4185         (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   4186                                  fields, values));
   4187     SOC_IF_ERROR_RETURN
   4188         (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   4189                                  fields, values));
   4190 
   4191     /*
   4192      * Egress Enable
   4193      */
   4194     sal_memset(entry, 0, sizeof(egr_enable_entry_t));
   4195     soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
   4196     PBMP_ALL_ITER(unit, port) {
   4197         SOC_IF_ERROR_RETURN
   4198             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, SOC_INFO(unit).port_l2p_mapping[port], entry));
   4199     }
   4200 
   4201     COMPILER_64_ZERO(reg64);
   4202     soc_reg64_field32_set(unit, EPC_LINK_BMAP_64r, &reg64, PORT_BITMAP_LOf,
   4203                           SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 0));
   4204     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAP_64r(unit, reg64));
   4205 
   4206     /* GMAC init should be moved to mac */
   4207     rval = 0;
   4208     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1);
   4209     prev_reg_addr = 0xffffffff;
   4210     PBMP_E_ITER(unit, port) {
   4211         uint32  reg_addr;
   4212         si->port_num_lanes[port] = 1;
   4213         if (!IS_GE_PORT(unit, port) || IS_XL_PORT(unit, port)) {
   4214             continue;
   4215         }
   4216         reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0);
   4217         if (reg_addr != prev_reg_addr) {
   4218             SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   4219             prev_reg_addr = reg_addr;
   4220         }
   4221         switch (dev_id) {
   4222             case BCM53393_DEVICE_ID:
   4223             case BCM53394_DEVICE_ID:
   4224                 si->port_num_lanes[port] = 4;
   4225                 break;
   4226             case BCM56150_DEVICE_ID:
   4227             case BCM56151_DEVICE_ID:
   4228             case BCM56152_DEVICE_ID:
   4229             case BCM53347_DEVICE_ID:
   4230             case BCM53346_DEVICE_ID:
   4231             case BCM53344_DEVICE_ID:
   4232                 qsgmii_override = soc_property_get(unit,
   4233                         spn_SERDES_QSGMII_SGMII_OVERRIDE, 0);
   4234                 if (qsgmii_override == 2) {
   4235                     if (port == 18 || port == 22) {
   4236                         si->port_num_lanes[port] = 4; 
   4237                     }
   4238                 }
   4239                 break;
   4240             default:
   4241                 break;
   4242         }
   4243     }
   4244     prev_reg_addr = 0xffffffff;
   4245     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0);
   4246     PBMP_E_ITER(unit, port) {
   4247         uint32  reg_addr;
   4248         if (!IS_GE_PORT(unit, port) || IS_XL_PORT(unit, port)) {
   4249             continue;
   4250         }
   4251         reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0);
   4252         if (reg_addr != prev_reg_addr) {
   4253             SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   4254             prev_reg_addr = reg_addr;
   4255         }
   4256     }
   4257 
   4258     PBMP_PORT_ITER(unit, port) {
   4259         if (!IS_HG_PORT(unit, port)) {
   4260             continue;
   4261         }
   4262         si->port_num_lanes[port] = 1;
   4263         SOC_IF_ERROR_RETURN(READ_XLPORT_CONFIGr(unit, port, &rval));
   4264         soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
   4265         SOC_IF_ERROR_RETURN(WRITE_XLPORT_CONFIGr(unit, port, rval));
   4266     }
   4267 
   4268     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   4269         port = SOC_BLOCK_PORT(unit, blk);
   4270         if (port == -1) {
   4271             continue;
   4272         }
   4273         phy_port_base = si->port_l2p_mapping[port];
   4274 
   4275         /* Assert XLPORT soft reset */
   4276         rval = 0;
   4277         for (bindex = 0; bindex < NUM_XLPORT; bindex++) {
   4278             if (si->port_p2l_mapping[phy_port_base + bindex] != -1) {
   4279                 soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &rval,
   4280                                   port_field[bindex], 1);
   4281             }
   4282         }
   4283         SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, rval));
   4284 
   4285         mode = SOC_HU2_PORT_MODE_QUAD;
   4286 
   4287         switch (dev_id) {
   4288             case BCM56150_DEVICE_ID:
   4289             case BCM56151_DEVICE_ID:
   4290             case BCM53346_DEVICE_ID:
   4291             case BCM53347_DEVICE_ID:
   4292                 if ((hu2_config_id == 3) ||
   4293                     ((hu2_config_id == 2) && (port !=26))) {
   4294                     mode = SOC_HU2_PORT_MODE_SINGLE;
   4295                     si->port_num_lanes[port] = 4;
   4296                     si->port_num_lanes[port+1] = 4;
   4297                     si->port_num_lanes[port+2] = 4;
   4298                     si->port_num_lanes[port+3] = 4;
   4299                 }
   4300                 /* Fall Thru */
   4301             case BCM56152_DEVICE_ID:
   4302             case BCM53344_DEVICE_ID:
   4303                 if ((hu2_config_id == 1) || (hu2_config_id == 10)) {
   4304                     if (port != 26) {
   4305                         mode = SOC_HU2_PORT_MODE_DUAL;
   4306                         si->port_num_lanes[port] = 2;
   4307                         si->port_num_lanes[port+1] = 2;
   4308                     }
   4309                 } else if (hu2_config_id == 11) {
   4310                     if (port == 26) {
   4311                         mode = SOC_HU2_PORT_MODE_DUAL;
   4312                         si->port_num_lanes[port] = 2;
   4313                         si->port_num_lanes[port+1] = 2;
   4314                     }
   4315                 }
   4316                 break;
   4317             case BCM53394_DEVICE_ID:
   4318                 if (hu2_config_id == 1) {
   4319                     if (port == 26) {
   4320                         mode = SOC_HU2_PORT_MODE_SINGLE;
   4321                         si->port_num_lanes[port] = 4;
   4322                         si->port_num_lanes[port+1] = 4;
   4323                         si->port_num_lanes[port+2] = 4;
   4324                         si->port_num_lanes[port+3] = 4;
   4325                     }
   4326                 } else if (hu2_config_id == 2) {
   4327                     if (port == 26) {
   4328                         mode = SOC_HU2_PORT_MODE_SINGLE;
   4329                         si->port_num_lanes[port] = 4;
   4330                     }
   4331                 }
   4332                 break;
   4333             default :
   4334                 break;
   4335         }
   4336 
   4337         rval = 0;
   4338         soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval,
   4339                           XPORT0_CORE_PORT_MODEf, mode);
   4340         soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval,
   4341                           XPORT0_PHY_PORT_MODEf, mode);
   4342         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
   4343 
   4344         /* De-assert XLPORT soft reset */
   4345         SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, 0));
   4346 
   4347         /* Enable XLPORT */
   4348         rval = 0;
   4349         for (bindex = 0; bindex < NUM_XLPORT; bindex++) {
   4350             if (si->port_p2l_mapping[phy_port_base + bindex] != -1) {
   4351                 soc_reg_field_set(unit, XLPORT_ENABLE_REGr, &rval,
   4352                                   port_field[bindex], 1);
   4353             }
   4354         }
   4355         SOC_IF_ERROR_RETURN(WRITE_XLPORT_ENABLE_REGr(unit, port, rval));
   4356     }
   4357 
   4358     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &reg64));
   4359     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4360                           L3SRC_HIT_ENABLEf, 1);
   4361     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4362                           L2DST_HIT_ENABLEf, 1);
   4363     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4364                           APPLY_EGR_MASK_ON_L2f, 1);
   4365     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4366                           APPLY_EGR_MASK_ON_L3f, 1);
   4367     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4368                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
   4369     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4370                           ARP_VALIDATION_ENf, 1);
   4371     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   4372                           IGNORE_HG_HDR_LAG_FAILOVERf, 1);
   4373     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64));
   4374 
   4375     SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval));
   4376     soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, RING_MODEf, 1);
   4377     SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval));
   4378 
   4379     /*
   4380      * Set reference clock (based on 200MHz core clock)
   4381      * to be 200MHz * (1/40) = 5MHz
   4382      */
   4383     divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, 40);
   4384     dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1);
   4385     rval = 0;
   4386     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor);
   4387     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend);
   4388     /* coverity[result_independent_of_operands] */
   4389     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval));
   4390 
   4391     /* Match the Internal MDC freq with above for External MDC */
   4392     divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, 40);
   4393     dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1);
   4394     rval = 0;
   4395     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, divisor);
   4396     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, dividend);
   4397     /* coverity[result_independent_of_operands] */
   4398     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval));
   4399 
   4400     rval = 0;
   4401     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1);
   4402     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, GPORT_ENf, 1);
   4403     PBMP_E_ITER(unit, port) {
   4404         if (!IS_GE_PORT(unit, port) || IS_XL_PORT(unit, port)) {
   4405             continue;
   4406         }
   4407         SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   4408     }
   4409     soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0);
   4410     PBMP_E_ITER(unit, port) {
   4411         if (!IS_GE_PORT(unit, port) || IS_XL_PORT(unit, port)) {
   4412             continue;
   4413         }
   4414         SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval));
   4415     }
   4416 
   4417     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
   4418      * causes the outer tag to be removed from packets that don't have
   4419      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
   4420      */
   4421     rval = 0;
   4422     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
   4423 
   4424     /* Enable pri/cfi remarking on egress ports. */
   4425     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,
   4426                       1);
   4427     PBMP_ALL_ITER(unit, port) {
   4428         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval));
   4429     }
   4430 
   4431     /* Multicast range initialization */
   4432     SOC_IF_ERROR_RETURN
   4433         (soc_hbx_higig2_mcast_sizes_set(unit,
   4434              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
   4435                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   4436              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
   4437                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   4438              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
   4439                               SOC_HBX_MULTICAST_RANGE_DEFAULT)));
   4440 
   4441     /* Setup SW2_FP_DST_ACTION_CONTROL */
   4442     fields[0] = HGTRUNK_RES_ENf;
   4443     fields[1] = LAG_RES_ENf;
   4444     values[0] = values[1] = 1;
   4445     SOC_IF_ERROR_RETURN
   4446         (soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr,
   4447                                  REG_PORT_ANY, 2, fields, values));    
   4448 
   4449     /* Directed Mirroring ON by default except for CPU port */
   4450     /* The src_port info will be changed as egress port if EM_SRCMOD_CHANGEf = 1 */
   4451     PBMP_PORT_ITER(unit, port) {
   4452         SOC_IF_ERROR_RETURN(READ_EGR_PORTr(unit, port, &rval));
   4453         soc_reg_field_set(unit, EGR_PORTr, &rval, EM_SRCMOD_CHANGEf, 1);
   4454         SOC_IF_ERROR_RETURN(WRITE_EGR_PORTr(unit, port, rval));
   4455         SOC_IF_ERROR_RETURN(READ_IEGR_PORTr(unit, port, &rval));
   4456         soc_reg_field_set(unit, IEGR_PORTr, &rval, EM_SRCMOD_CHANGEf, 1);
   4457         SOC_IF_ERROR_RETURN(WRITE_IEGR_PORTr(unit, port, rval));
   4458     }
   4459 
   4460 #ifdef _HURRICANE2_QT_DEBUG
   4461     if (soc_feature(unit, soc_feature_gphy)) {
   4462         rval = 0;
   4463         soc_reg_field_set(unit, GPORT_LINK_STATUS_TO_CMICr, &rval, TRANSPOSEf, 1);
   4464         WRITE_GPORT_LINK_STATUS_TO_CMICr(unit, 0, rval);
   4465     }
   4466 #endif
   4467 
   4468     /* initialize LED UP0 */
   4469     if (!SOC_WARM_BOOT(unit)) {
   4470         SOC_IF_ERROR_RETURN(_hurricane2_ledup_init(unit));
   4471     }
   4472 
   4473     /* Turn on Power Optimization */
   4474     SOC_IF_ERROR_RETURN(_soc_hu2_power_Optimize(unit));
   4475 
   4476     led_intensity = soc_property_get(unit, spn_LED_INTENSITY, -1);
   4477 
   4478     if ((led_intensity >= 1) && (led_intensity <= 12)) {
   4479         fval = 0x0;
   4480     } else if ((led_intensity >= 13) && (led_intensity <= 25)) {
   4481         fval = 0x1;
   4482     } else if ((led_intensity >= 26) && (led_intensity <= 37)) {
   4483         fval = 0x2;
   4484     } else if ((led_intensity >= 38) && (led_intensity <= 50)) {
   4485         fval = 0x3;
   4486     } else if ((led_intensity >= 51) && (led_intensity <= 62)) {
   4487         fval = 0x4;
   4488     } else if ((led_intensity >= 63) && (led_intensity <= 75)) {
   4489         fval = 0x5;
   4490     } else if ((led_intensity >= 76) && (led_intensity <= 88)) {
   4491         fval = 0x6;
   4492     } else if ((led_intensity >= 89) && (led_intensity <= 100)) {
   4493         fval = 0x7;
   4494     } else {
   4495         fval = 0xffffffff; /* use chip default */
   4496     }
   4497 
   4498 	if (fval != 0xffffffff) {
   4499         SOC_IF_ERROR_RETURN(READ_TOP_PARALLEL_LED_CTRLr(unit, &rval));
   4500         soc_reg_field_set(unit, TOP_PARALLEL_LED_CTRLr, &rval, LED_CURRENT_SELf, fval);
   4501         SOC_IF_ERROR_RETURN(WRITE_TOP_PARALLEL_LED_CTRLr(unit, rval));
   4502     }
   4503 
   4504 
   4505     if (soc_mspi_init(unit) != SOC_E_NONE) {
   4506         LOG_WARN(BSL_LS_SOC_COMMON,
   4507                  (BSL_META_U(unit,
   4508                              "unit %d : MSPI Init Failed\n"), unit)); 
   4509     }
   4510 
   4511     if (parity_enable) {
   4512         SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
   4513     }
   4514     return SOC_E_NONE;
   4515 }
   4516 
   4517 /* soc_hu2_mem_config:
   4518  * Over-ride the default table sizes (from regsfile) for any SKUs here
   4519  */
   4520 int
   4521 soc_hu2_mem_config(int unit, int dev_id)
   4522 {
   4523     int rv = SOC_E_NONE;
   4524     soc_persist_t *sop = SOC_PERSIST(unit);
   4525 
   4526     switch (dev_id) {
   4527         case BCM53342_DEVICE_ID:
   4528         case BCM53343_DEVICE_ID:
   4529         case BCM53344_DEVICE_ID:
   4530         case BCM53346_DEVICE_ID:
   4531         case BCM53347_DEVICE_ID:
   4532         case BCM53393_DEVICE_ID:
   4533         case BCM53394_DEVICE_ID:
   4534             /* -- L2 related -- */
   4535             sop->memState[L2MCm].index_max = 511;
   4536             /* -- L3 related -- */
   4537             sop->memState[L3_IPMCm].index_max = 63;
   4538             sop->memState[L3_DEFIPm].index_max = 63;
   4539             sop->memState[L3_DEFIP_ONLYm].index_max = 63;
   4540             sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 63;
   4541             sop->memState[ING_L3_NEXT_HOPm].index_max = 511;
   4542             sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 511;
   4543             SOC_CONTROL(unit)->l3_defip_max_tcams = 1;
   4544             SOC_CONTROL(unit)->l3_defip_tcam_size = 64;
   4545             break;
   4546         default:
   4547             SOC_CONTROL(unit)->l3_defip_max_tcams = 8;
   4548             SOC_CONTROL(unit)->l3_defip_tcam_size = 64;
   4549             break;
   4550     }
   4551     return rv;
   4552 }
   4553 
   4554 int
   4555 soc_hurricane2_age_timer_get(int unit, int *age_seconds, int *enabled)
   4556 {
   4557     uint32 value;
   4558 
   4559     SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &value));
   4560     *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_ENAf);
   4561     *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_VALf);
   4562 
   4563     return SOC_E_NONE;
   4564 }
   4565 
   4566 int
   4567 soc_hurricane2_age_timer_max_get(int unit, int *max_seconds)
   4568 {
   4569     *max_seconds =
   4570         soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
   4571 
   4572     return SOC_E_NONE;
   4573 }
   4574 
   4575 int
   4576 soc_hurricane2_age_timer_set(int unit, int age_seconds, int enable)
   4577 {
   4578     uint32 value;
   4579 
   4580     value = 0;
   4581     soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_ENAf, enable);
   4582     soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_VALf, age_seconds);
   4583     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, value));
   4584 
   4585     return SOC_E_NONE;
   4586 }
   4587 
   4588 void soc_hurricane2_oam_handler_register(int unit, soc_hurricane2_oam_handler_t handler)
   4589 {
   4590     uint32 rval;
   4591     int rv, fidx = 0;
   4592     hu2_oam_handler[unit] = handler;
   4593     rv = READ_IP1_INTR_ENABLEr(unit, &rval);
   4594     if (rv) {
   4595         LOG_ERROR(BSL_LS_SOC_COMMON,
   4596                   (BSL_META_U(unit,
   4597                               "unit %d: Error reading %s reg !!\n"),
   4598                               unit, SOC_REG_NAME(unit, IP1_INTR_ENABLEr)));
   4599     }
   4600     while (_soc_hu2_oam_interrupt_fields[fidx] != INVALIDf) {
   4601         soc_reg_field_set(unit, IP1_INTR_ENABLEr, &rval,
   4602                           _soc_hu2_oam_interrupt_fields[fidx], 1);
   4603         fidx++;
   4604     }
   4605     rv = WRITE_IP1_INTR_ENABLEr(unit, rval);
   4606     if (rv) {
   4607         LOG_ERROR(BSL_LS_SOC_COMMON,
   4608                   (BSL_META_U(unit,
   4609                               "unit %d: Error writing %s reg !!\n"),
   4610                               unit, SOC_REG_NAME(unit, IP1_INTR_ENABLEr)));
   4611     }                   
   4612 }
   4613 
   4614  #if defined(INCLUDE_L3)
   4615  
   4616  /* Hurricane2 HU2_LPM TCAM table insert/delete/lookup routines
   4617   * soc_hu2_lpm_init - Called from bcm_l3_init
   4618   * soc_hu2_lpm_insert - Insert/Update an IPv4/IPV6 route entry into HU2_LPM table
   4619   * soc_hu2_lpm_delete - Delete an IPv4/IPV6 route entry from HU2_LPM table
   4620   * soc_hu2_lpm_match  - (Exact match for the key. Will match both IP address
   4621   *                                    and mask)
   4622   * soc_hu2_lpm_lookup (HU2_LPM search) - Not Implemented
   4623   */
   4624  
   4625  
   4626  
   4627  /*
   4628   * TCAM based HU2_LPM implementation. Each table entry can hold one IPV4 entries or
   4629   * one IPV6 entry. 
   4630   *
   4631   *              MAX_PFX_INDEX
   4632   * lpm_prefix_index[98].begin ---> ===============================
   4633   *                                 ==                           ==
   4634   *                                 ==    0                      ==
   4635   * lpm_prefix_index[98].end   ---> ===============================
   4636   *
   4637   * lpm_prefix_index[97].begin ---> ===============================
   4638   *                                 ==                           ==
   4639   *                                 ==    IPV6  Prefix Len = 64  ==
   4640   * lpm_prefix_index[97].end   ---> ===============================
   4641   *
   4642   *
   4643   *
   4644   * lpm_prefix_index[x].begin --->  ===============================
   4645   *                                 ==                           ==
   4646   *                                 ==                           ==
   4647   * lpm_prefix_index[x].end   --->  ===============================
   4648   *
   4649   *
   4650   *              IPV6_PFX_ZERO
   4651   * lpm_prefix_index[33].begin ---> ===============================
   4652   *                                 ==                           ==
   4653   *                                 ==    IPV6  Prefix Len = 0   ==
   4654   * lpm_prefix_index[33].end   ---> ===============================
   4655   *
   4656   *
   4657   * lpm_prefix_index[32].begin ---> ===============================
   4658   *                                 ==                           ==
   4659   *                                 ==    IPV4  Prefix Len = 32  ==
   4660   * lpm_prefix_index[32].end   ---> ===============================
   4661   *
   4662   *
   4663   *
   4664   * lpm_prefix_index[0].begin --->  ===============================
   4665   *                                 ==                           ==
   4666   *                                 ==    IPV4  Prefix Len = 0   ==
   4667   * lpm_prefix_index[0].end   --->  ===============================
   4668  */
   4669  
   4670  #ifndef HU2_LPM_HASH_SUPPORT
   4671  #define HU2_LPM_HASH_SUPPORT 1
   4672  #endif
   4673  
   4674  #define SOC_MEM_COMPARE_RETURN(a, b) {          \
   4675          if ((a) < (b)) { return -1; }           \
   4676          if ((a) > (b)) { return  1; }           \
   4677  }
   4678  
   4679  /* Can move to SOC Control structures */
   4680  soc_hu2_lpm_state_p soc_hu2_lpm_state[SOC_MAX_NUM_DEVICES];
   4681  
   4682  #define SOC_HU2_LPM_LOCK(u)             soc_mem_lock(u, L3_DEFIPm)
   4683  #define SOC_HU2_LPM_UNLOCK(u)           soc_mem_unlock(u, L3_DEFIPm)
   4684  
   4685  #define SOC_HU2_LPM_CACHE_FIELD_CREATE(m, f) soc_field_info_t * m##f
   4686  #define SOC_HU2_LPM_CACHE_FIELD_ASSIGN(m_u, s, m, f) \
   4687                  (s)->m##f = soc_mem_fieldinfo_get(m_u, m, f)
   4688  typedef struct soc_hu2_lpm_field_cache_s {
   4689      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, HITf);
   4690      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, GLOBAL_ROUTE0f);
   4691      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, CLASS_ID0f);
   4692      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, DST_DISCARD0f);
   4693      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, SRC_DISCARD0f);
   4694      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, RPE0f);
   4695      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, PRI0f);
   4696      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, DEFAULTROUTE0f);
   4697      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, ECMP_UNUSED0f);
   4698      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, ECMP_PTR0f);
   4699      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, UPPER_NEXT_HOP_INDEX0f);
   4700      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, NEXT_HOP_INDEX0f);
   4701      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, ECMP0f);
   4702      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, MASKf);
   4703      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, IP_ADDR_U_MASKf);
   4704      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, IP_ADDR_L_MASKf);
   4705      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, MODE_MASKf);
   4706      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, IP_ADDR_Uf);
   4707      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, IP_ADDR_Lf);
   4708      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, MODEf);
   4709      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, VALIDf);
   4710      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, VRF_IDf);
   4711      SOC_HU2_LPM_CACHE_FIELD_CREATE(L3_DEFIPm, VRF_ID_MASKf);
   4712  } soc_hu2_lpm_field_cache_t, *soc_hu2_lpm_field_cache_p;
   4713  static 
   4714  soc_hu2_lpm_field_cache_p soc_hu2_lpm_field_cache_state[SOC_MAX_NUM_DEVICES];
   4715  
   4716  #define SOC_MEM_OPT_F32_GET(m_unit, m_mem, m_entry_data, m_field) \
   4717          soc_meminfo_fieldinfo_field32_get( \
   4718              (&SOC_MEM_INFO(m_unit, m_mem)), (m_entry_data), \
   4719              (soc_hu2_lpm_field_cache_state[(m_unit)]->m_mem##m_field))
   4720  
   4721  #define SOC_MEM_OPT_F32_SET(m_unit, m_mem, m_entry_data, m_field, m_val) \
   4722          soc_meminfo_fieldinfo_field32_set( \
   4723              (&SOC_MEM_INFO(m_unit, m_mem)), (m_entry_data), \
   4724              (soc_hu2_lpm_field_cache_state[(m_unit)]->m_mem##m_field), (m_val))
   4725  
   4726  
   4727  #define SOC_MEM_OPT_FIELD_VALID(m_unit, m_mem, m_field) \
   4728              ((soc_hu2_lpm_field_cache_state[(m_unit)]->m_mem##m_field) != NULL)
   4729  
   4730  
   4731  #ifdef HU2_LPM_HASH_SUPPORT
   4732  typedef struct soc_hu2_lpm_hash_s {
   4733      int         unit;
   4734      int         entry_count;    /* Number entries in hash table */
   4735      int         index_count;    /* Hash index max value + 1 */
   4736      uint16      *table;         /* Hash table with 16 bit index */
   4737      uint16      *link_table;    /* To handle collisions */
   4738  } soc_hu2_lpm_hash_t;
   4739  
   4740 /*
   4741  * LPM key fields extended from 4 to 6 for VRF supporting 
   4742  *  - for HR2/GH/HR3, the VRF also the LPM key for hash but static at vrf=0
   4743  */
   4744 #define NUM_KEY_FIELDS    6 
   4745 typedef uint32 soc_hu2_lpm_hash_entry_t[NUM_KEY_FIELDS];
   4746  typedef int (*soc_hu2_lpm_hash_compare_fn)(soc_hu2_lpm_hash_entry_t key1,
   4747                                             soc_hu2_lpm_hash_entry_t key2);
   4748  static soc_hu2_lpm_hash_t *soc_hu2_lpm_hash_tab[SOC_MAX_NUM_DEVICES];
   4749  #define SOC_HU2_LPM_STATE_HASH(u)           (soc_hu2_lpm_hash_tab[(u)])
   4750  
   4751  #define HU2_LPM_HASH_INDEX_NULL  (0xFFFF)
   4752  #define HU2_LPM_HASH_INDEX_MASK  (0x3FFF)
   4753  #define HU2_LPM_HASH_IPV6_MASK   (0x8000)
   4754  
   4755  #define SOC_HU2_LPM_HASH_ENTRY_IPV6_GET(u, entry_data, odata)                 \
   4756      odata[0] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, IP_ADDR_Lf);     \
   4757      odata[1] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, IP_ADDR_L_MASKf);\
   4758      odata[2] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, IP_ADDR_Uf);     \
   4759      odata[3] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, IP_ADDR_U_MASKf);\
   4760      if ((SOC_MEM_OPT_FIELD_VALID(u, L3_DEFIPm, VRF_IDf))) {                   \
   4761         odata[4] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, VRF_IDf);     \
   4762         soc_hu2_lpm_hash_vrf_get(u, entry_data, &odata[5]);                    \
   4763      } else {                                                                  \
   4764         odata[4] = 0;                                                          \
   4765         odata[5] = 0;                                                          \
   4766      }
   4767  
   4768  #define SOC_HU2_LPM_HASH_ENTRY_IPV4_GET(u, entry_data, odata)                  \
   4769      odata[0] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, IP_ADDR_Lf);      \
   4770      odata[1] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, IP_ADDR_L_MASKf); \
   4771      odata[2] = 0;                                                              \
   4772      odata[3] = 0x80000001;                                                     \
   4773      if ((SOC_MEM_OPT_FIELD_VALID(u, L3_DEFIPm, VRF_IDf))) {                    \
   4774         odata[4] = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, VRF_IDf);      \
   4775         soc_hu2_lpm_hash_vrf_get(u, entry_data, &odata[5]);                     \
   4776      } else {                                                                   \
   4777         odata[4] = 0;                                                           \
   4778         odata[5] = 0;                                                           \
   4779      }
   4780  
   4781  #define SOC_HU2_LPM_HASH_ENTRY_GET soc_hu2_lpm_hash_entry_get
   4782  
   4783  static
   4784  void soc_hu2_lpm_hash_entry_get(int u, void *e,
   4785                                  int index, soc_hu2_lpm_hash_entry_t r_entry);
   4786  static
   4787  uint16 soc_hu2_lpm_hash_compute(uint8 *data, int data_nbits);
   4788  static
   4789  int soc_hu2_lpm_hash_create(int unit,
   4790                              int entry_count,
   4791                              int index_count,
   4792                              soc_hu2_lpm_hash_t **hu2_lpm_hash_ptr);
   4793  static
   4794  int soc_hu2_lpm_hash_destroy(soc_hu2_lpm_hash_t *hu2_lpm_hash);
   4795  static
   4796  int _soc_hu2_lpm_hash_lookup(soc_hu2_lpm_hash_t          *hash,
   4797                              soc_hu2_lpm_hash_compare_fn key_cmp_fn,
   4798                              soc_hu2_lpm_hash_entry_t    entry,
   4799                              int                         pfx,
   4800                              uint16                      *key_index);
   4801  static
   4802  int _soc_hu2_lpm_hash_insert(soc_hu2_lpm_hash_t *hash,
   4803                              soc_hu2_lpm_hash_compare_fn key_cmp_fn,
   4804                              soc_hu2_lpm_hash_entry_t entry,
   4805                              int    pfx,
   4806                              uint16 old_index,
   4807                              uint16 new_index);
   4808  
   4809  static
   4810  int _soc_hu2_lpm_hash_delete(soc_hu2_lpm_hash_t *hash,
   4811                              soc_hu2_lpm_hash_compare_fn key_cmp_fn,
   4812                              soc_hu2_lpm_hash_entry_t entry,
   4813                              int    pfx,
   4814                              uint16 delete_index);
   4815 
   4816 /*
   4817  * Function:
   4818  *      soc_hu2_lpm_hash_vrf_get
   4819  * Purpose:
   4820  *      Service routine used to determine the vrf type 
   4821  * Parameters:
   4822  *      unit      - (IN)SOC unit number.
   4823  *      lpm_entry - (IN)Route info buffer from hw.
   4824  *      vrf_id    - (OUT)Virtual router id.
   4825  * Returns:
   4826  *      BCM_E_XXX
   4827  * Note :
   4828  * - soc_hu2_lpm_hash_xxx() are SW LPM hash routines for HRx/GHx devices.
   4829  * - VRF is once of the key in LPM but only be the valid field after GH2.
   4830  */
   4831 STATIC void
   4832 soc_hu2_lpm_hash_vrf_get(int unit, void *lpm_entry, uint32 *vrf)
   4833 {
   4834     int vrf_id;
   4835 
   4836     /* Get Virtual Router id if supported. */
   4837     if (SOC_MEM_OPT_FIELD_VALID(unit, L3_DEFIPm, VRF_ID_MASKf)){
   4838         vrf_id = SOC_MEM_OPT_F32_GET(unit, L3_DEFIPm, lpm_entry, VRF_IDf);
   4839 
   4840         /* Special vrf's handling. */
   4841         if (SOC_MEM_OPT_F32_GET(unit, L3_DEFIPm, lpm_entry, VRF_ID_MASKf)) {
   4842             *vrf = _SOC_HASH_L3_VRF_SPECIFIC;    
   4843         } else if (SOC_VRF_MAX(unit) == vrf_id) {
   4844             *vrf = _SOC_HASH_L3_VRF_GLOBAL;
   4845         } else {
   4846             *vrf = _SOC_HASH_L3_VRF_OVERRIDE;    
   4847             if (SOC_MEM_OPT_FIELD_VALID(unit, L3_DEFIPm, GLOBAL_ROUTE0f)) {
   4848                 if (SOC_MEM_OPT_F32_GET(unit, L3_DEFIPm, lpm_entry, GLOBAL_ROUTE0f)) {
   4849                     *vrf = _SOC_HASH_L3_VRF_GLOBAL; 
   4850                 }
   4851             }
   4852         }
   4853     } else {
   4854         /* No vrf support on this device. */
   4855         *vrf = _SOC_HASH_L3_VRF_DEFAULT;
   4856     }
   4857 }
   4858  
   4859  /*
   4860   *      Extract key data from an entry at the given index.
   4861   */
   4862  static
   4863  void soc_hu2_lpm_hash_entry_get(int u, void *e,
   4864                                  int index, soc_hu2_lpm_hash_entry_t r_entry)
   4865  {
   4866      int                         is_ipv6;
   4867 
   4868      is_ipv6 = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, e, MODEf);
   4869 
   4870      if (SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, e, VALIDf)) {
   4871          if (is_ipv6) {
   4872             SOC_HU2_LPM_HASH_ENTRY_IPV6_GET(u, e, r_entry);
   4873          } else {
   4874             SOC_HU2_LPM_HASH_ENTRY_IPV4_GET(u, e, r_entry);
   4875          }
   4876      }
   4877  }
   4878  
   4879  /*
   4880   * Function:
   4881   *      soc_hu2_lpm_hash_compare_key
   4882   * Purpose:
   4883   *      Comparison function for hash table operations.
   4884   */
   4885  static
   4886  int soc_hu2_lpm_hash_compare_key(soc_hu2_lpm_hash_entry_t key1,
   4887                                   soc_hu2_lpm_hash_entry_t key2)
   4888  {
   4889      int idx;
   4890  
   4891      for (idx = 0; idx < NUM_KEY_FIELDS; idx++) { 
   4892          SOC_MEM_COMPARE_RETURN(key1[idx], key2[idx]);
   4893      }
   4894      return (0);
   4895  }
   4896  
   4897  /* #define HU2_LPM_DEBUG*/
   4898  #ifdef HU2_LPM_DEBUG      
   4899  #define H_INDEX_MATCH(str, tab_index, match_index)      \
   4900          LOG_ERROR(BSL_LS_SOC_COMMON, \
   4901                    (BSL_META_U(unit, \
   4902                                "%s index: H %d A %d\n"),   \
   4903                                str, (int)tab_index, match_index)
   4904  #else
   4905  #define H_INDEX_MATCH(str, tab_index, match_index)
   4906  #endif
   4907  
   4908  #define HU2_LPM_NO_MATCH_INDEX 0x4000
   4909  #define HU2_LPM_HASH_INSERT(u, entry_data, tab_index)       \
   4910      soc_hu2_lpm_hash_insert(u, entry_data, tab_index, HU2_LPM_NO_MATCH_INDEX, 0)
   4911  
   4912  #define HU2_LPM_HASH_DELETE(u, key_data, tab_index)         \
   4913      soc_hu2_lpm_hash_delete(u, key_data, tab_index)
   4914  
   4915  #define HU2_LPM_HASH_LOOKUP(u, key_data, pfx, tab_index)    \
   4916      soc_hu2_lpm_hash_lookup(u, key_data, pfx, tab_index)
   4917  
   4918  void soc_hu2_lpm_hash_insert(int u, void *entry_data, uint32 tab_index,
   4919                              uint32 old_index, int pfx)
   4920  {
   4921      soc_hu2_lpm_hash_entry_t    key_hash;
   4922  
   4923      if (SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, VALIDf)) {
   4924          if (SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry_data, MODEf)) {
   4925              /* IPV6 entry */
   4926              SOC_HU2_LPM_HASH_ENTRY_IPV6_GET(u, entry_data, key_hash);
   4927          } else {
   4928              /* IPV4 entry */
   4929              SOC_HU2_LPM_HASH_ENTRY_IPV4_GET(u, entry_data, key_hash);
   4930          }
   4931          _soc_hu2_lpm_hash_insert(SOC_HU2_LPM_STATE_HASH(u),
   4932                                  soc_hu2_lpm_hash_compare_key,
   4933                                  key_hash,
   4934                                  pfx,
   4935                                  old_index,
   4936                                  (uint16)tab_index);
   4937      }
   4938  }
   4939  
   4940  void soc_hu2_lpm_hash_delete(int u, void *key_data, uint32 tab_index)
   4941  {
   4942      soc_hu2_lpm_hash_entry_t    key_hash;
   4943      int                         pfx = -1;
   4944      int                         rv;
   4945      uint16                      index;
   4946  
   4947      if (SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, key_data, MODEf)) {
   4948          SOC_HU2_LPM_HASH_ENTRY_IPV6_GET(u, key_data, key_hash);
   4949      } else {
   4950          SOC_HU2_LPM_HASH_ENTRY_IPV4_GET(u, key_data, key_hash);
   4951      }
   4952      index = tab_index;
   4953  
   4954      rv = _soc_hu2_lpm_hash_delete(SOC_HU2_LPM_STATE_HASH(u),
   4955                                   soc_hu2_lpm_hash_compare_key,
   4956                                   key_hash, pfx, index);
   4957      if (SOC_FAILURE(rv)) {
   4958          LOG_ERROR(BSL_LS_SOC_COMMON,
   4959                    (BSL_META_U(u,
   4960                                "\ndel  index: H %d error %d\n"), index, rv));
   4961      }
   4962  }
   4963  
   4964  int soc_hu2_lpm_hash_lookup(int u, void *key_data, int pfx, int *key_index)
   4965  {
   4966      soc_hu2_lpm_hash_entry_t    key_hash;
   4967      int                         is_ipv6;
   4968      int                         rv;
   4969      uint16                      index = HU2_LPM_HASH_INDEX_NULL;
   4970  
   4971      is_ipv6 = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, key_data, MODEf);
   4972      if (is_ipv6) {
   4973          SOC_HU2_LPM_HASH_ENTRY_IPV6_GET(u, key_data, key_hash);
   4974      } else {
   4975          SOC_HU2_LPM_HASH_ENTRY_IPV4_GET(u, key_data, key_hash);
   4976      }
   4977  
   4978      rv = _soc_hu2_lpm_hash_lookup(SOC_HU2_LPM_STATE_HASH(u),
   4979                                   soc_hu2_lpm_hash_compare_key,
   4980                                   key_hash, pfx, &index);
   4981      if (SOC_FAILURE(rv)) {
   4982          *key_index = 0xFFFFFFFF;
   4983          return(rv);
   4984      }
   4985  
   4986      *key_index = index;
   4987  
   4988      return(SOC_E_NONE);
   4989  }
   4990  
   4991  /* 
   4992   * Function:
   4993   *      soc_hu2_lpm_hash_compute
   4994   * Purpose:
   4995   *      Compute CRC hash for key data.
   4996   * Parameters:
   4997   *      data - Key data
   4998   *      data_nbits - Number of data bits
   4999   * Returns:
   5000   *      Computed 16 bit hash
   5001   */
   5002  static
   5003  uint16 soc_hu2_lpm_hash_compute(uint8 *data, int data_nbits)
   5004  {
   5005      return (_shr_crc16b(0, data, data_nbits));
   5006  }
   5007  
   5008  /* 
   5009   * Function:
   5010   *      soc_hu2_lpm_hash_create
   5011   * Purpose:
   5012   *      Create an empty hash table
   5013   * Parameters:
   5014   *      unit  - Device unit
   5015   *      entry_count - Limit for number of entries in table
   5016   *      index_count - Hash index max + 1. (index_count <= count)
   5017   *      hu2_lpm_hash_ptr - Return pointer (handle) to new Hash Table
   5018   * Returns:
   5019   *      SOC_E_NONE       Success
   5020   *      SOC_E_MEMORY     Out of memory (system allocator)
   5021   */
   5022  
   5023  static
   5024  int soc_hu2_lpm_hash_create(int unit,
   5025                              int entry_count,
   5026                              int index_count,
   5027                              soc_hu2_lpm_hash_t **hu2_lpm_hash_ptr)
   5028  {
   5029      soc_hu2_lpm_hash_t  *hash;
   5030      int                 index;
   5031  
   5032      if (index_count > entry_count) {
   5033          return SOC_E_MEMORY;
   5034      }
   5035      hash = sal_alloc(sizeof (soc_hu2_lpm_hash_t), "lpm_hash");
   5036      if (hash == NULL) {
   5037          return SOC_E_MEMORY;
   5038      }
   5039  
   5040      sal_memset(hash, 0, sizeof (*hash));
   5041  
   5042      hash->unit = unit;
   5043      hash->entry_count = entry_count;
   5044      hash->index_count = index_count;
   5045  
   5046      /*
   5047       * Pre-allocate the hash table storage.
   5048       */
   5049      hash->table = sal_alloc(hash->index_count * sizeof(*(hash->table)),
   5050                              "hash_table");
   5051  
   5052      if (hash->table == NULL) {
   5053          sal_free(hash);
   5054          return SOC_E_MEMORY;
   5055      }
   5056      /*
   5057       * In case where all the entries should hash into the same bucket
   5058       * this will prevent the hash table overflow
   5059       */
   5060      hash->link_table = sal_alloc(
   5061                              hash->entry_count * sizeof(*(hash->link_table)),
   5062                              "link_table");
   5063      if (hash->link_table == NULL) {
   5064          sal_free(hash->table);
   5065          sal_free(hash);
   5066          return SOC_E_MEMORY;
   5067      }
   5068  
   5069      /*
   5070       * Set the entries in the hash table to HU2_LPM_HASH_INDEX_NULL
   5071       * Link the entries beyond hash->index_max for handling collisions
   5072       */
   5073      for(index = 0; index < hash->index_count; index++) {
   5074          hash->table[index] = HU2_LPM_HASH_INDEX_NULL;
   5075      }
   5076      for(index = 0; index < hash->entry_count; index++) {
   5077          hash->link_table[index] = HU2_LPM_HASH_INDEX_NULL;
   5078      }
   5079      *hu2_lpm_hash_ptr = hash;
   5080      return SOC_E_NONE;
   5081  }
   5082  
   5083  /* 
   5084   * Function:
   5085   *      soc_hu2_lpm_hash_destroy
   5086   * Purpose:
   5087   *      Destroy the hash table
   5088   * Parameters:
   5089   *      hu2_lpm_hash - Pointer (handle) to Hash Table
   5090   * Returns:
   5091   *      SOC_E_NONE       Success
   5092   */
   5093  static
   5094  int soc_hu2_lpm_hash_destroy(soc_hu2_lpm_hash_t *hu2_lpm_hash)
   5095  {
   5096      if (hu2_lpm_hash != NULL) {
   5097          sal_free(hu2_lpm_hash->table);
   5098          sal_free(hu2_lpm_hash->link_table);
   5099          sal_free(hu2_lpm_hash);
   5100      }
   5101  
   5102      return SOC_E_NONE;
   5103  }
   5104  
   5105  /*
   5106   * Function:
   5107   *      _soc_hu2_lpm_hash_lookup
   5108   * Purpose:
   5109   *      Look up a key in the hash table
   5110   * Parameters:
   5111   *      hash - Pointer (handle) to Hash Table
   5112   *      key_cmp_fn - Compare function which should compare key
   5113   *      entry   - The key to lookup
   5114   *      pfx     - Prefix length for lookup acceleration.
   5115   *      key_index - (OUT)       Index where the key was found.
   5116   * Returns:
   5117   *      SOC_E_NONE      Key found
   5118   *      SOC_E_NOT_FOUND Key not found
   5119   */
   5120  
   5121  static
   5122  int _soc_hu2_lpm_hash_lookup(soc_hu2_lpm_hash_t  *hash,
   5123                              soc_hu2_lpm_hash_compare_fn key_cmp_fn,
   5124                              soc_hu2_lpm_hash_entry_t    entry,
   5125                              int                          pfx,
   5126                              uint16                       *key_index)
   5127  {
   5128      int u = hash->unit;
   5129  
   5130      uint16 hash_val;
   5131      uint16 index;
   5132  
   5133      hash_val = soc_hu2_lpm_hash_compute((uint8 *)entry,
   5134                                      (32 * NUM_KEY_FIELDS)) % hash->index_count;
   5135      index = hash->table[hash_val];
   5136      H_INDEX_MATCH("lhash", entry[0], hash_val);
   5137      H_INDEX_MATCH("lkup ", entry[0], index);
   5138      while(index != HU2_LPM_HASH_INDEX_NULL) {
   5139          uint32  e[SOC_MAX_MEM_FIELD_WORDS];
   5140          soc_hu2_lpm_hash_entry_t  r_entry;
   5141          /*int     rindex;
   5142  
   5143          rindex = (index & HU2_LPM_HASH_INDEX_MASK) >> 1;*/
   5144  
   5145          SOC_IF_ERROR_RETURN(READ_L3_DEFIPm(u, MEM_BLOCK_ANY, index, e));
   5146          SOC_HU2_LPM_HASH_ENTRY_GET(u, e, index, r_entry);
   5147          if ((*key_cmp_fn)(entry, r_entry) == 0) {
   5148              *key_index = (index & HU2_LPM_HASH_INDEX_MASK);
   5149              H_INDEX_MATCH("found", entry[0], index);
   5150              return(SOC_E_NONE);
   5151          }
   5152          
   5153          index = hash->link_table[index & HU2_LPM_HASH_INDEX_MASK];
   5154          H_INDEX_MATCH("lkup1", entry[0], index);
   5155      }
   5156      H_INDEX_MATCH("not_found", entry[0], index);
   5157      return(SOC_E_NOT_FOUND);
   5158  }
   5159  
   5160  /*
   5161   * Function:
   5162   *      _soc_hu2_lpm_hash_insert
   5163   * Purpose:
   5164   *      Insert/Update a key index in the hash table
   5165   * Parameters:
   5166   *      hash - Pointer (handle) to Hash Table
   5167   *      key_cmp_fn - Compare function which should compare key
   5168   *      entry   - The key to lookup
   5169   *      pfx     - Prefix length for lookup acceleration.
   5170   *      old_index - Index where the key was moved from.
   5171   *                  HU2_LPM_HASH_INDEX_NULL if new entry.
   5172   *      new_index - Index where the key was moved to.
   5173   * Returns:
   5174   *      SOC_E_NONE      Key found
   5175   */
   5176  /*
   5177   *      Should be caled before updating the HU2_LPM table so that the
   5178   *      data in the hash table is consistent with the HU2_LPM table
   5179   */
   5180  static
   5181  int _soc_hu2_lpm_hash_insert(soc_hu2_lpm_hash_t *hash,
   5182                              soc_hu2_lpm_hash_compare_fn key_cmp_fn,
   5183                              soc_hu2_lpm_hash_entry_t entry,
   5184                              int    pfx,
   5185                              uint16 old_index,
   5186                              uint16 new_index)
   5187  {
   5188  
   5189  #define INDEX_ADD(hash, hash_idx, new_idx)                      \
   5190      hash->link_table[new_idx & HU2_LPM_HASH_INDEX_MASK] =       \
   5191          hash->table[hash_idx];                                  \
   5192      hash->table[hash_idx] = new_idx
   5193  
   5194  #define INDEX_ADD_LINK(hash, t_index, new_idx)                  \
   5195      hash->link_table[new_idx & HU2_LPM_HASH_INDEX_MASK] =       \
   5196          hash->link_table[t_index & HU2_LPM_HASH_INDEX_MASK];    \
   5197      hash->link_table[t_index & HU2_LPM_HASH_INDEX_MASK] = new_idx
   5198  
   5199  #define INDEX_UPDATE(hash, hash_idx, old_idx, new_idx)          \
   5200      hash->table[hash_idx] = new_idx;                            \
   5201      hash->link_table[new_idx & HU2_LPM_HASH_INDEX_MASK] =       \
   5202          hash->link_table[old_idx & HU2_LPM_HASH_INDEX_MASK];    \
   5203      hash->link_table[old_idx & HU2_LPM_HASH_INDEX_MASK] =       \
   5204          HU2_LPM_HASH_INDEX_NULL
   5205  
   5206  #define INDEX_UPDATE_LINK(hash, prev_idx, old_idx, new_idx)         \
   5207      hash->link_table[prev_idx & HU2_LPM_HASH_INDEX_MASK] = new_idx; \
   5208      hash->link_table[new_idx & HU2_LPM_HASH_INDEX_MASK] =           \
   5209          hash->link_table[old_idx & HU2_LPM_HASH_INDEX_MASK];        \
   5210      hash->link_table[old_idx & HU2_LPM_HASH_INDEX_MASK] =           \
   5211          HU2_LPM_HASH_INDEX_NULL
   5212  
   5213  
   5214      int u = hash->unit;
   5215  
   5216      uint16 hash_val;
   5217      uint16 index;
   5218      uint16 prev_index;
   5219  
   5220      hash_val = soc_hu2_lpm_hash_compute((uint8 *)entry,
   5221                                      (32 * NUM_KEY_FIELDS)) % hash->index_count;
   5222      index = hash->table[hash_val];
   5223      H_INDEX_MATCH("ihash", entry[0], hash_val);
   5224      H_INDEX_MATCH("ins  ", entry[0], new_index);
   5225      H_INDEX_MATCH("ins1 ", index, new_index);
   5226      prev_index = HU2_LPM_HASH_INDEX_NULL;
   5227      if (old_index != HU2_LPM_HASH_INDEX_NULL) {
   5228          while(index != HU2_LPM_HASH_INDEX_NULL) {
   5229              uint32  e[SOC_MAX_MEM_FIELD_WORDS];
   5230              soc_hu2_lpm_hash_entry_t  r_entry;
   5231              /*int     rindex;
   5232              
   5233              rindex = (index & HU2_LPM_HASH_INDEX_MASK) >> 1; */
   5234  
   5235              SOC_IF_ERROR_RETURN(READ_L3_DEFIPm(u, MEM_BLOCK_ANY, index, e));
   5236              SOC_HU2_LPM_HASH_ENTRY_GET(u, e, index, r_entry);
   5237              if ((*key_cmp_fn)(entry, r_entry) == 0) {
   5238                  /* assert(old_index == index);*/
   5239                  if (new_index != index) {
   5240                      H_INDEX_MATCH("imove", prev_index, new_index);
   5241                      if (prev_index == HU2_LPM_HASH_INDEX_NULL) {
   5242                          INDEX_UPDATE(hash, hash_val, index, new_index);
   5243                      } else {
   5244                          INDEX_UPDATE_LINK(hash, prev_index, index, new_index);
   5245                      }
   5246                  }
   5247                  H_INDEX_MATCH("imtch", index, new_index);
   5248                  return(SOC_E_NONE);
   5249              }
   5250              prev_index = index;
   5251              index = hash->link_table[index & HU2_LPM_HASH_INDEX_MASK];
   5252              H_INDEX_MATCH("ins2 ", index, new_index);
   5253          }
   5254      }
   5255      INDEX_ADD(hash, hash_val, new_index);  /* new entry */
   5256      return(SOC_E_NONE);
   5257  }
   5258  
   5259  /*
   5260   * Function:
   5261   *      _soc_hu2_lpm_hash_delete
   5262   * Purpose:
   5263   *      Delete a key index in the hash table
   5264   * Parameters:
   5265   *      hash - Pointer (handle) to Hash Table
   5266   *      key_cmp_fn - Compare function which should compare key
   5267   *      entry   - The key to delete
   5268   *      pfx     - Prefix length for lookup acceleration.
   5269   *      delete_index - Index to delete.
   5270   * Returns:
   5271   *      SOC_E_NONE      Success
   5272   *      SOC_E_NOT_FOUND Key index not found.
   5273   */
   5274  static
   5275  int _soc_hu2_lpm_hash_delete(soc_hu2_lpm_hash_t *hash,
   5276                              soc_hu2_lpm_hash_compare_fn key_cmp_fn,
   5277                              soc_hu2_lpm_hash_entry_t entry,
   5278                              int    pfx,
   5279                              uint16 delete_index)
   5280  {
   5281      uint16 hash_val;
   5282      uint16 index;
   5283      uint16 prev_index;
   5284  
   5285      hash_val = soc_hu2_lpm_hash_compute((uint8 *)entry,
   5286                                      (32 * NUM_KEY_FIELDS)) % hash->index_count;
   5287      index = hash->table[hash_val];
   5288      H_INDEX_MATCH("dhash", entry[0], hash_val);
   5289      H_INDEX_MATCH("del  ", entry[0], index);
   5290      prev_index = HU2_LPM_HASH_INDEX_NULL;
   5291      while(index != HU2_LPM_HASH_INDEX_NULL) {
   5292  #define INDEX_DELETE(hash, hash_idx, del_idx)                   \
   5293      hash->table[hash_idx] =                                     \
   5294          hash->link_table[del_idx & HU2_LPM_HASH_INDEX_MASK];     \
   5295      hash->link_table[del_idx & HU2_LPM_HASH_INDEX_MASK] =        \
   5296          HU2_LPM_HASH_INDEX_NULL
   5297  
   5298  #define INDEX_DELETE_LINK(hash, prev_idx, del_idx)              \
   5299      hash->link_table[prev_idx & HU2_LPM_HASH_INDEX_MASK] =       \
   5300          hash->link_table[del_idx & HU2_LPM_HASH_INDEX_MASK];     \
   5301      hash->link_table[del_idx & HU2_LPM_HASH_INDEX_MASK] =        \
   5302          HU2_LPM_HASH_INDEX_NULL
   5303  
   5304          if (delete_index == index) {
   5305              H_INDEX_MATCH("dfoun", entry[0], index);
   5306              if (prev_index == HU2_LPM_HASH_INDEX_NULL) {
   5307                  INDEX_DELETE(hash, hash_val, delete_index);
   5308              } else {
   5309                  INDEX_DELETE_LINK(hash, prev_index, delete_index);
   5310              }
   5311              return(SOC_E_NONE);
   5312          }
   5313          prev_index = index;
   5314          index = hash->link_table[index & HU2_LPM_HASH_INDEX_MASK];
   5315          H_INDEX_MATCH("del1 ", entry[0], index);
   5316      }
   5317      return(SOC_E_NOT_FOUND);
   5318  }
   5319  #else
   5320  #define HU2_LPM_HASH_INSERT(u, entry_data, tab_index)
   5321  #define HU2_LPM_HASH_DELETE(u, key_data, tab_index)
   5322  #define HU2_LPM_HASH_LOOKUP(u, key_data, pfx, tab_index)
   5323  #endif /* HU2_LPM_HASH_SUPPORT */
   5324  
   5325  static
   5326  int
   5327  _ip_mask2pfx(uint32 ipv4m, int *mask_len)
   5328  {
   5329      *mask_len = 0;
   5330      while (ipv4m & (1 << 31)) {
   5331          *mask_len += 1;
   5332          ipv4m <<= 1;
   5333      }
   5334  
   5335      return ((ipv4m) ? SOC_E_PARAM : SOC_E_NONE);
   5336  }
   5337  
   5338  void
   5339  soc_hu2_lpm_state_dump(int u)
   5340  {
   5341      int i;
   5342      int max_pfx_len;
   5343      max_pfx_len = MAX_PFX_INDEX(u);
   5344  
   5345     if (!bsl_check(bslLayerSoc, bslSourceSocmem, bslSeverityVerbose, u)) {
   5346          return;
   5347      }
   5348      for(i = max_pfx_len; i >= 0 ; i--) {
   5349          if ((i != MAX_PFX_INDEX(u)) && (SOC_HU2_LPM_STATE_START(u, i) == -1)) {
   5350              continue;
   5351          }
   5352          LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   5353                      (BSL_META_U(u,
   5354                                  "PFX = %d P = %d N = %d START = %d END = %d VENT = %d FENT = %d\n"),
   5355                       i,
   5356                       SOC_HU2_LPM_STATE_PREV(u, i),
   5357                       SOC_HU2_LPM_STATE_NEXT(u, i),
   5358                       SOC_HU2_LPM_STATE_START(u, i),
   5359                       SOC_HU2_LPM_STATE_END(u, i),
   5360                       SOC_HU2_LPM_STATE_VENT(u, i),
   5361                       SOC_HU2_LPM_STATE_FENT(u, i)));
   5362      }
   5363  }
   5364  
   5365 #ifdef BCM_HURRICANE3_SUPPORT
   5366 /*
   5367  *      Replicate entry to the second half of the tcam if URPF check is ON. 
   5368  */
   5369 static 
   5370 int _lpm_hr3_urpf_entry_replicate(int u, int index, uint32 *e)
   5371 {
   5372     int src_tcam_offset;  /* Defip memory size/2 urpf source lookup offset */
   5373     int ipv6;             /* IPv6 entry.                                   */
   5374     uint32 mask0;         /* Mask field value.                             */
   5375     uint32 mask1;         /* Mask field value.                             */
   5376     int def_gw_flag;      /* Entry is default gateway.                     */ 
   5377 
   5378     if(!SOC_URPF_STATUS_GET(u)) {
   5379         return (SOC_E_NONE);
   5380     }
   5381 
   5382     src_tcam_offset = (soc_mem_index_count(u, L3_DEFIPm) >> 1);
   5383 
   5384     ipv6 = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, e, MODEf);
   5385 
   5386     /* Reset destination discard bit. */
   5387     SOC_MEM_OPT_F32_SET(u, L3_DEFIPm, e, DST_DISCARD0f, 0);
   5388 
   5389     /* Set/Reset default gateway flag based on ip mask value. */
   5390     mask0 = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, e, IP_ADDR_L_MASKf);
   5391     mask1 = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, e, IP_ADDR_U_MASKf);
   5392 
   5393     if (!ipv6) {
   5394         if (SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, e, VALIDf)) {
   5395             SOC_MEM_OPT_F32_SET(u, L3_DEFIPm, e, RPE0f, (!mask0) ? 1 : 0);
   5396             SOC_MEM_OPT_F32_SET(u, L3_DEFIPm, e,
   5397                 DEFAULTROUTE0f, (!mask0) ? 1 : 0);
   5398         }
   5399     } else {
   5400         def_gw_flag = ((!mask0) &&  (!mask1)) ? 1 : 0;
   5401         SOC_MEM_OPT_F32_SET(u, L3_DEFIPm, e, RPE0f, def_gw_flag);
   5402         SOC_MEM_OPT_F32_SET(u, L3_DEFIPm, e, DEFAULTROUTE0f, def_gw_flag);
   5403     }
   5404 
   5405     /* Write entry to the second half of the tcam. */
   5406     return WRITE_L3_DEFIPm(u, MEM_BLOCK_ANY, (index + src_tcam_offset), e);
   5407 }
   5408 #endif  /* BCM_HURRICANE3_SUPPORT */
   5409 
   5410  /*
   5411   *      Create a slot for the new entry rippling the entries if required
   5412   */
   5413  static
   5414  int _lpm_hu2_entry_shift(int u, int from_ent, int to_ent)
   5415  {
   5416      uint32      e[SOC_MAX_MEM_FIELD_WORDS];
   5417  
   5418  #ifdef HU2_LPM_TABLE_CACHED
   5419      SOC_IF_ERROR_RETURN(soc_mem_cache_invalidate(u, L3_DEFIPm,
   5420                                         MEM_BLOCK_ANY, from_ent));
   5421  #endif /* HU2_LPM_TABLE_CACHED */
   5422  
   5423      SOC_IF_ERROR_RETURN(READ_L3_DEFIPm(u, MEM_BLOCK_ANY, from_ent, e));
   5424      HU2_LPM_HASH_INSERT(u, e, to_ent);
   5425      SOC_IF_ERROR_RETURN(WRITE_L3_DEFIPm(u, MEM_BLOCK_ANY, to_ent, e));
   5426 #ifdef BCM_HURRICANE3_SUPPORT
   5427     if (soc_feature(u, soc_feature_urpf)) {
   5428         SOC_IF_ERROR_RETURN(_lpm_hr3_urpf_entry_replicate(u, to_ent, e));
   5429     }
   5430 #endif  /* BCM_HURRICANE3_SUPPORT */
   5431      return (SOC_E_NONE);
   5432  }
   5433  
   5434  
   5435  /*
   5436   *      Shift prefix entries 1 entry UP, while preserving  
   5437   *      last half empty IPv4 entry if any.
   5438   */
   5439  static
   5440  int _lpm_hu2_shift_pfx_up(int u, int pfx)
   5441  {
   5442      int         from_ent;
   5443      int         to_ent;
   5444  
   5445      to_ent = SOC_HU2_LPM_STATE_END(u, pfx) + 1;
   5446  
   5447      from_ent = SOC_HU2_LPM_STATE_START(u, pfx);
   5448      if(from_ent != to_ent) {
   5449          SOC_IF_ERROR_RETURN(_lpm_hu2_entry_shift(u, from_ent, to_ent));
   5450      } 
   5451      SOC_HU2_LPM_STATE_START(u, pfx) += 1;
   5452      SOC_HU2_LPM_STATE_END(u, pfx) += 1;
   5453      return (SOC_E_NONE);
   5454  }
   5455  
   5456  /*
   5457   *      Shift prefix entries 1 entry DOWN, while preserving  
   5458   *      last half empty IPv4 entry if any.
   5459   */
   5460  static
   5461  int _lpm_hu2_shift_pfx_down(int u, int pfx)
   5462  {
   5463      int         from_ent;
   5464      int         to_ent;
   5465  
   5466  
   5467      to_ent = SOC_HU2_LPM_STATE_START(u, pfx) - 1;
   5468  
   5469      /* Don't move empty prefix . */ 
   5470      if (SOC_HU2_LPM_STATE_VENT(u, pfx) == 0) {
   5471          SOC_HU2_LPM_STATE_START(u, pfx) = to_ent;
   5472          SOC_HU2_LPM_STATE_END(u, pfx) = to_ent - 1;
   5473          return (SOC_E_NONE);
   5474      }
   5475    
   5476      from_ent = SOC_HU2_LPM_STATE_END(u, pfx);
   5477      SOC_IF_ERROR_RETURN(_lpm_hu2_entry_shift(u, from_ent, to_ent));
   5478      SOC_HU2_LPM_STATE_START(u, pfx) -= 1;
   5479      SOC_HU2_LPM_STATE_END(u, pfx) -= 1;
   5480  
   5481      return (SOC_E_NONE);
   5482  }
   5483  
   5484  /*
   5485   *      Create a slot for the new entry rippling the entries if required
   5486   */
   5487  static
   5488  int _lpm_hu2_free_slot_create(int u, int pfx, void *e, int *free_slot)
   5489  {
   5490      int         prev_pfx;
   5491      int         next_pfx;
   5492      int         free_pfx;
   5493      int         curr_pfx; 
   5494  
   5495      if (SOC_HU2_LPM_STATE_VENT(u, pfx) == 0) {
   5496          /*
   5497           * Find the  prefix position. Only prefix with valid
   5498           * entries are in the list.
   5499           * next -> high to low prefix. low to high index
   5500           * prev -> low to high prefix. high to low index
   5501           * Unused prefix length MAX_PFX_INDEX is the head of the
   5502           * list and is node corresponding to this is always
   5503           * present.
   5504           */
   5505          curr_pfx = MAX_PFX_INDEX(u);
   5506          while (SOC_HU2_LPM_STATE_NEXT(u, curr_pfx) > pfx) {
   5507              curr_pfx = SOC_HU2_LPM_STATE_NEXT(u, curr_pfx);
   5508          }
   5509          /* Insert the new prefix */
   5510          next_pfx = SOC_HU2_LPM_STATE_NEXT(u, curr_pfx);
   5511          if (next_pfx != -1) {
   5512              SOC_HU2_LPM_STATE_PREV(u, next_pfx) = pfx;
   5513          }
   5514          SOC_HU2_LPM_STATE_NEXT(u, pfx) = SOC_HU2_LPM_STATE_NEXT(u, curr_pfx);
   5515          SOC_HU2_LPM_STATE_PREV(u, pfx) = curr_pfx;
   5516          SOC_HU2_LPM_STATE_NEXT(u, curr_pfx) = pfx;
   5517  
   5518          SOC_HU2_LPM_STATE_FENT(u, pfx) =  (SOC_HU2_LPM_STATE_FENT(u, curr_pfx) + 1) / 2;
   5519          SOC_HU2_LPM_STATE_FENT(u, curr_pfx) -= SOC_HU2_LPM_STATE_FENT(u, pfx);
   5520          SOC_HU2_LPM_STATE_START(u, pfx) =  SOC_HU2_LPM_STATE_END(u, curr_pfx) +
   5521                                         SOC_HU2_LPM_STATE_FENT(u, curr_pfx) + 1;
   5522          SOC_HU2_LPM_STATE_END(u, pfx) = SOC_HU2_LPM_STATE_START(u, pfx) - 1;
   5523          SOC_HU2_LPM_STATE_VENT(u, pfx) = 0;
   5524      }
   5525  
   5526      free_pfx = pfx;
   5527      while(SOC_HU2_LPM_STATE_FENT(u, free_pfx) == 0) {
   5528          free_pfx = SOC_HU2_LPM_STATE_NEXT(u, free_pfx);
   5529          if (free_pfx == -1) {
   5530              /* No free entries on this side try the other side */
   5531              free_pfx = pfx;
   5532              break;
   5533          }
   5534      }
   5535  
   5536      while(SOC_HU2_LPM_STATE_FENT(u, free_pfx) == 0) {
   5537          free_pfx = SOC_HU2_LPM_STATE_PREV(u, free_pfx);
   5538          if (free_pfx == -1) {
   5539              if (SOC_HU2_LPM_STATE_VENT(u, pfx) == 0) {
   5540                  /* We failed to allocate entries for a newly allocated prefix.*/
   5541                  prev_pfx = SOC_HU2_LPM_STATE_PREV(u, pfx);
   5542                  next_pfx = SOC_HU2_LPM_STATE_NEXT(u, pfx);
   5543                  if (-1 != prev_pfx) {
   5544                      SOC_HU2_LPM_STATE_NEXT(u, prev_pfx) = next_pfx;
   5545                  }
   5546                  if (-1 != next_pfx) {
   5547                      SOC_HU2_LPM_STATE_PREV(u, next_pfx) = prev_pfx;
   5548                  }
   5549              }
   5550              return(SOC_E_FULL);
   5551          }
   5552      }
   5553  
   5554      /*
   5555       * Ripple entries to create free space
   5556       */
   5557      while (free_pfx > pfx) {
   5558          next_pfx = SOC_HU2_LPM_STATE_NEXT(u, free_pfx); 
   5559          SOC_IF_ERROR_RETURN(_lpm_hu2_shift_pfx_down(u, next_pfx));
   5560          SOC_HU2_LPM_STATE_FENT(u, free_pfx) -= 1;
   5561          SOC_HU2_LPM_STATE_FENT(u, next_pfx) += 1;
   5562          free_pfx = next_pfx;
   5563      }
   5564  
   5565      while (free_pfx < pfx) {
   5566          SOC_IF_ERROR_RETURN(_lpm_hu2_shift_pfx_up(u, free_pfx));
   5567          SOC_HU2_LPM_STATE_FENT(u, free_pfx) -= 1;
   5568          prev_pfx = SOC_HU2_LPM_STATE_PREV(u, free_pfx); 
   5569          SOC_HU2_LPM_STATE_FENT(u, prev_pfx) += 1;
   5570          free_pfx = prev_pfx;
   5571      }
   5572  
   5573      SOC_HU2_LPM_STATE_VENT(u, pfx) += 1;
   5574      SOC_HU2_LPM_STATE_FENT(u, pfx) -= 1;
   5575      SOC_HU2_LPM_STATE_END(u, pfx) += 1;
   5576      *free_slot = SOC_HU2_LPM_STATE_END(u, pfx);
   5577      sal_memcpy(e, soc_mem_entry_null(u, L3_DEFIPm),
   5578                 soc_mem_entry_words(u,L3_DEFIPm) * 4);
   5579  
   5580      return(SOC_E_NONE);
   5581  }
   5582  
   5583  /*
   5584   *      Delete a slot and adjust entry pointers if required.
   5585   *      e - has the contents of entry at slot(useful for IPV4 only)
   5586   */
   5587  static
   5588  int _lpm_hu2_free_slot_delete(int u, int pfx, void *e, int slot)
   5589  {
   5590      int         prev_pfx;
   5591      int         next_pfx;
   5592      int         from_ent;
   5593      int         to_ent;
   5594      uint32      ef[SOC_MAX_MEM_FIELD_WORDS];
   5595      int         rv;
   5596  
   5597      from_ent = SOC_HU2_LPM_STATE_END(u, pfx);
   5598      to_ent = slot;
   5599          SOC_HU2_LPM_STATE_VENT(u, pfx) -= 1;
   5600          SOC_HU2_LPM_STATE_FENT(u, pfx) += 1;
   5601          SOC_HU2_LPM_STATE_END(u, pfx) -= 1;
   5602          if (to_ent != from_ent) {
   5603  #ifdef HU2_LPM_TABLE_CACHED
   5604              if ((rv = soc_mem_cache_invalidate(u, L3_DEFIPm,
   5605                                                 MEM_BLOCK_ANY, from_ent)) < 0) {
   5606                  return rv;
   5607              }
   5608  #endif /* HU2_LPM_TABLE_CACHED */
   5609              if ((rv = READ_L3_DEFIPm(u, MEM_BLOCK_ANY, from_ent, ef)) < 0) {
   5610                  return rv;
   5611              }
   5612              HU2_LPM_HASH_INSERT(u, ef, to_ent);
   5613              if ((rv = WRITE_L3_DEFIPm(u, MEM_BLOCK_ANY, to_ent, ef)) < 0) {
   5614                  return rv;
   5615              }
   5616 #ifdef BCM_HURRICANE3_SUPPORT
   5617             if ((rv = _lpm_hr3_urpf_entry_replicate(u, to_ent, ef)) < 0) {
   5618                 return rv;
   5619             }
   5620 #endif  /* BCM_HURRICANE3_SUPPORT */
   5621          }
   5622  
   5623          sal_memcpy(ef, soc_mem_entry_null(u, L3_DEFIPm),
   5624                     soc_mem_entry_words(u,L3_DEFIPm) * 4);
   5625          HU2_LPM_HASH_INSERT(u, ef, from_ent);
   5626          if ((rv = WRITE_L3_DEFIPm(u, MEM_BLOCK_ANY, from_ent, ef)) < 0) {
   5627              return rv;
   5628          }
   5629 #ifdef BCM_HURRICANE3_SUPPORT
   5630         if ((rv = _lpm_hr3_urpf_entry_replicate(u, from_ent, ef)) < 0) {
   5631             return rv;
   5632         }
   5633 #endif  /* BCM_HURRICANE3_SUPPORT */
   5634  
   5635      if (SOC_HU2_LPM_STATE_VENT(u, pfx) == 0) {
   5636          /* remove from the list */
   5637          prev_pfx = SOC_HU2_LPM_STATE_PREV(u, pfx); /* Always present */
   5638          assert(prev_pfx != -1);
   5639          next_pfx = SOC_HU2_LPM_STATE_NEXT(u, pfx);
   5640          SOC_HU2_LPM_STATE_NEXT(u, prev_pfx) = next_pfx;
   5641          SOC_HU2_LPM_STATE_FENT(u, prev_pfx) += SOC_HU2_LPM_STATE_FENT(u, pfx);
   5642          SOC_HU2_LPM_STATE_FENT(u, pfx) = 0;
   5643          if (next_pfx != -1) {
   5644              SOC_HU2_LPM_STATE_PREV(u, next_pfx) = prev_pfx;
   5645          }
   5646          SOC_HU2_LPM_STATE_NEXT(u, pfx) = -1;
   5647          SOC_HU2_LPM_STATE_PREV(u, pfx) = -1;
   5648          SOC_HU2_LPM_STATE_START(u, pfx) = -1;
   5649          SOC_HU2_LPM_STATE_END(u, pfx) = -1;
   5650      }
   5651  
   5652      return(rv);
   5653  }
   5654  
   5655  
   5656  
   5657  /*
   5658   * soc_hu2_lpm_prefix_length_get (Extract vrf weighted  prefix lenght from the 
   5659   * hw entry based on ip, mask & vrf)
   5660   */
   5661  static int
   5662  soc_hu2_lpm_prefix_length_get(int u, void *entry, int *pfx_len) 
   5663  {
   5664      int         pfx;
   5665      int         rv;
   5666      int         ipv6;
   5667      uint32      ipv4a;
   5668     int         vrf_id, vrf_type;
   5669 
   5670 
   5671  
   5672      ipv6 = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry, MODEf);
   5673  
   5674      if (ipv6) {
   5675          ipv4a = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry, IP_ADDR_L_MASKf);
   5676          if ((rv = _ip_mask2pfx(ipv4a, &pfx)) < 0) {
   5677              return(rv);
   5678          }
   5679          ipv4a = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry, IP_ADDR_U_MASKf);
   5680          if (pfx) {
   5681              if (ipv4a != 0xffffffff)  {
   5682                  return(SOC_E_PARAM);
   5683              }
   5684              pfx += 32;
   5685          } else {
   5686              if ((rv = _ip_mask2pfx(ipv4a, &pfx)) < 0) {
   5687                  return(rv);
   5688              }
   5689          }
   5690          pfx += IPV6_PFX_ZERO; /* First 33 are for IPV4 addresses */
   5691      } else {
   5692          ipv4a = SOC_MEM_OPT_F32_GET(u, L3_DEFIPm, entry, IP_ADDR_L_MASKf);
   5693          if ((rv = _ip_mask2pfx(ipv4a, &pfx)) < 0) {
   5694              return(rv);
   5695          }
   5696      }
   5697     
   5698     if (soc_mem_field_valid(u,L3_DEFIPm, VRF_IDf)) {
   5699         uint32 vrf_mask_val = 0;
   5700         vrf_id = soc_L3_DEFIPm_field32_get(u, (uint32 *)entry, VRF_IDf);
   5701         vrf_mask_val = soc_L3_DEFIPm_field32_get(u, (uint32 *)entry, VRF_ID_MASKf);
   5702         if (vrf_mask_val) {
   5703             vrf_type = vrf_id;
   5704         } else if (SOC_VRF_MAX(u) == vrf_id) {
   5705             vrf_type = SOC_L3_VRF_GLOBAL;
   5706         } else {
   5707             vrf_type = SOC_L3_VRF_OVERRIDE;    
   5708             if (soc_mem_field_valid(u, L3_DEFIPm, GLOBAL_ROUTE0f)) {
   5709                 if (soc_L3_DEFIPm_field32_get(u, (uint32 *)entry, GLOBAL_ROUTE0f)) {
   5710                     vrf_type = SOC_L3_VRF_GLOBAL; 
   5711                 }
   5712             }
   5713         }
   5714     } else {
   5715         /* No vrf support on this device. */
   5716         vrf_type = SOC_L3_VRF_DEFAULT;
   5717     }
   5718 
   5719     switch (vrf_type) { 
   5720     case SOC_L3_VRF_GLOBAL:
   5721         *pfx_len = pfx;
   5722         break;
   5723     case SOC_L3_VRF_OVERRIDE:
   5724         *pfx_len = pfx + 2 * (MAX_PFX_ENTRIES(u) / 6);
   5725         break;
   5726     default:   
   5727         *pfx_len = pfx +  (MAX_PFX_ENTRIES(u) / 6);
   5728         break;
   5729     }
   5730 
   5731      return (SOC_E_NONE);
   5732  }
   5733  
   5734  /*
   5735   * _soc_hu2_lpm_match (Exact match for the key. Will match both IP address
   5736   * and mask)
   5737   */
   5738   static 
   5739  int
   5740  _soc_hu2_lpm_match(int u,
   5741                 void *key_data,
   5742                 void *e,         /* return entry data if found */
   5743                 int *index_ptr,  /* return key location */
   5744                 int *pfx_len)    /* Key prefix length */
   5745  {
   5746      int         pfx = 0;
   5747  
   5748      /* Calculate vrf weighted prefix lengh. */
   5749      soc_hu2_lpm_prefix_length_get(u, key_data, &pfx); 
   5750      *pfx_len = pfx;
   5751 
   5752 #if defined(HU2_LPM_HASH_SUPPORT) 
   5753 {
   5754      int         rv;
   5755      int         key_index = 0;
   5756      if (HU2_LPM_HASH_LOOKUP(u, key_data, pfx, &key_index) == SOC_E_NONE) {
   5757          *index_ptr = key_index;
   5758          if ((rv = READ_L3_DEFIPm(u, MEM_BLOCK_ANY,*index_ptr, e)) < 0) {
   5759              return rv;
   5760          }
   5761          return(SOC_E_NONE);
   5762      } else {
   5763          return(SOC_E_NOT_FOUND);
   5764      }
   5765 }
   5766  #endif
   5767  }
   5768  
   5769  
   5770  /*
   5771   * Initialize the start/end tracking pointers for each prefix length
   5772   */
   5773  int
   5774  soc_hu2_lpm_init(int u)
   5775  {
   5776      int max_pfx_len;
   5777      int defip_table_size;
   5778      int pfx_state_size;
   5779      int i;
   5780  
   5781      if (! soc_feature(u, soc_feature_lpm_tcam)) {
   5782          return(SOC_E_UNAVAIL);
   5783      }
   5784  
   5785      max_pfx_len = MAX_PFX_ENTRIES(u);
   5786      pfx_state_size = sizeof(soc_hu2_lpm_state_t) * (max_pfx_len);
   5787  
   5788      if (!SOC_HU2_LPM_INIT_CHECK(u)) {
   5789          soc_hu2_lpm_field_cache_state[u] = 
   5790              sal_alloc(sizeof(soc_hu2_lpm_field_cache_t), "lpm_field_state");
   5791          if (NULL == soc_hu2_lpm_field_cache_state[u]) {
   5792              return (SOC_E_MEMORY);
   5793          }
   5794          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5795             L3_DEFIPm, HITf);
   5796          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5797             L3_DEFIPm, GLOBAL_ROUTE0f);
   5798          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5799             L3_DEFIPm, CLASS_ID0f);
   5800          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5801             L3_DEFIPm, DST_DISCARD0f);
   5802          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5803             L3_DEFIPm, SRC_DISCARD0f);
   5804          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5805             L3_DEFIPm, RPE0f);
   5806          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5807             L3_DEFIPm, PRI0f);
   5808          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5809             L3_DEFIPm, DEFAULTROUTE0f);
   5810          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5811             L3_DEFIPm, ECMP_UNUSED0f);
   5812          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5813             L3_DEFIPm, ECMP_PTR0f);
   5814          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5815             L3_DEFIPm, UPPER_NEXT_HOP_INDEX0f);
   5816          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5817             L3_DEFIPm, NEXT_HOP_INDEX0f);
   5818          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5819             L3_DEFIPm, ECMP0f);
   5820          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5821             L3_DEFIPm, MASKf);
   5822          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5823             L3_DEFIPm, IP_ADDR_U_MASKf);
   5824          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5825             L3_DEFIPm, IP_ADDR_L_MASKf);
   5826          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5827             L3_DEFIPm, MODE_MASKf);
   5828          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5829             L3_DEFIPm, IP_ADDR_Uf);
   5830          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5831             L3_DEFIPm, IP_ADDR_Lf);
   5832          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5833             L3_DEFIPm, MODEf);
   5834          SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u],
   5835             L3_DEFIPm, VALIDf);
   5836         SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u], 
   5837                 L3_DEFIPm, VRF_IDf);
   5838         SOC_HU2_LPM_CACHE_FIELD_ASSIGN(u, soc_hu2_lpm_field_cache_state[u], 
   5839                 L3_DEFIPm, VRF_ID_MASKf);
   5840          SOC_HU2_LPM_STATE(u) = sal_alloc(pfx_state_size, "HU2_LPM prefix info");
   5841          if (NULL == SOC_HU2_LPM_STATE(u)) {
   5842              sal_free(soc_hu2_lpm_field_cache_state[u]);
   5843              soc_hu2_lpm_field_cache_state[u] = NULL;
   5844              return (SOC_E_MEMORY);
   5845          }
   5846      }
   5847  
   5848  #ifdef HU2_LPM_TABLE_CACHED
   5849      SOC_IF_ERROR_RETURN (soc_mem_cache_set(u, L3_DEFIPm, MEM_BLOCK_ALL, TRUE));
   5850  #endif /* HU2_LPM_TABLE_CACHED */
   5851      SOC_HU2_LPM_LOCK(u);
   5852  
   5853      sal_memset(SOC_HU2_LPM_STATE(u), 0, pfx_state_size);
   5854      for(i = 0; i < max_pfx_len; i++) {
   5855          SOC_HU2_LPM_STATE_START(u, i) = -1;
   5856          SOC_HU2_LPM_STATE_END(u, i) = -1;
   5857          SOC_HU2_LPM_STATE_PREV(u, i) = -1;
   5858          SOC_HU2_LPM_STATE_NEXT(u, i) = -1;
   5859          SOC_HU2_LPM_STATE_VENT(u, i) = 0;
   5860          SOC_HU2_LPM_STATE_FENT(u, i) = 0;
   5861      }
   5862  
   5863      defip_table_size = soc_mem_index_count(u, L3_DEFIPm);
   5864 #ifdef BCM_HURRICANE3_SUPPORT
   5865     if (SOC_IS_HURRICANE3(u) || SOC_IS_GREYHOUND2(u)) {
   5866         if (SOC_URPF_STATUS_GET(u)) {
   5867             defip_table_size >>= 1;
   5868         }
   5869     }
   5870 #endif /* BCM_HURRICANE3_SUPPORT */
   5871 
   5872      SOC_HU2_LPM_STATE_FENT(u, (MAX_PFX_INDEX(u))) = defip_table_size;
   5873  
   5874  #ifdef HU2_LPM_HASH_SUPPORT
   5875      if (SOC_HU2_LPM_STATE_HASH(u) != NULL) {
   5876          if (soc_hu2_lpm_hash_destroy(SOC_HU2_LPM_STATE_HASH(u)) < 0) {
   5877              SOC_HU2_LPM_UNLOCK(u);
   5878              return SOC_E_INTERNAL;
   5879          }
   5880          SOC_HU2_LPM_STATE_HASH(u) = NULL;
   5881      }
   5882  
   5883      if (soc_hu2_lpm_hash_create(u, defip_table_size, defip_table_size,
   5884                                  &SOC_HU2_LPM_STATE_HASH(u)) < 0) {
   5885          SOC_HU2_LPM_UNLOCK(u);
   5886          return SOC_E_MEMORY;
   5887      }
   5888  #endif
   5889  
   5890      SOC_HU2_LPM_UNLOCK(u);
   5891  
   5892      return(SOC_E_NONE);
   5893  }
   5894  /*
   5895   * De-initialize the start/end tracking pointers for each prefix length
   5896   */
   5897  int
   5898  soc_hu2_lpm_deinit(int u)
   5899  {
   5900      if (!soc_feature(u, soc_feature_lpm_tcam)) {
   5901          return(SOC_E_UNAVAIL);
   5902      }
   5903  
   5904      SOC_HU2_LPM_LOCK(u);
   5905  
   5906  #ifdef HU2_LPM_HASH_SUPPORT
   5907      if (SOC_HU2_LPM_STATE_HASH(u) != NULL) {
   5908          soc_hu2_lpm_hash_destroy(SOC_HU2_LPM_STATE_HASH(u));
   5909          SOC_HU2_LPM_STATE_HASH(u) = NULL;
   5910      }
   5911  #endif
   5912  
   5913      if (SOC_HU2_LPM_INIT_CHECK(u)) {
   5914          sal_free(soc_hu2_lpm_field_cache_state[u]);
   5915          soc_hu2_lpm_field_cache_state[u] = NULL;
   5916          sal_free(SOC_HU2_LPM_STATE(u));
   5917          SOC_HU2_LPM_STATE(u) = NULL;
   5918      }
   5919  
   5920      SOC_HU2_LPM_UNLOCK(u);
   5921  
   5922      return(SOC_E_NONE);
   5923  }
   5924  
   5925  #ifdef BCM_WARM_BOOT_SUPPORT
   5926  int
   5927  soc_hu2_lpm_reinit_done(int unit)
   5928  {
   5929      int idx;
   5930      int prev_idx = MAX_PFX_INDEX(unit);
   5931  
   5932  
   5933      int defip_table_size = soc_mem_index_count(unit, L3_DEFIPm);
   5934  
   5935      SOC_HU2_LPM_STATE_PREV(unit, MAX_PFX_INDEX(unit)) = -1;
   5936  
   5937      for (idx = MAX_PFX_INDEX(unit); idx > 0 ; idx--) {
   5938          if (-1 == SOC_HU2_LPM_STATE_START(unit, idx)) {
   5939              continue;
   5940          }
   5941  
   5942          SOC_HU2_LPM_STATE_PREV(unit, idx) = prev_idx;
   5943          SOC_HU2_LPM_STATE_NEXT(unit, prev_idx) = idx;
   5944  
   5945          SOC_HU2_LPM_STATE_FENT(unit, prev_idx) =                    \
   5946                            SOC_HU2_LPM_STATE_START(unit, idx) -      \
   5947                            SOC_HU2_LPM_STATE_END(unit, prev_idx) - 1;
   5948          prev_idx = idx;
   5949          
   5950      }
   5951  
   5952      SOC_HU2_LPM_STATE_NEXT(unit, prev_idx) = -1;
   5953      SOC_HU2_LPM_STATE_FENT(unit, prev_idx) =                       \
   5954                            defip_table_size -                       \
   5955                            SOC_HU2_LPM_STATE_END(unit, prev_idx) - 1;
   5956  
   5957      return (SOC_E_NONE);
   5958  }
   5959  
   5960  int
   5961  soc_hu2_lpm_reinit(int unit, int idx, uint32 *lpm_entry)
   5962  {
   5963      int pfx_len;
   5964  
   5965  
   5966      SOC_IF_ERROR_RETURN
   5967          (soc_hu2_lpm_prefix_length_get(unit, lpm_entry, &pfx_len));
   5968  
   5969      if (SOC_HU2_LPM_STATE_VENT(unit, pfx_len) == 0) {
   5970          SOC_HU2_LPM_STATE_START(unit, pfx_len) = idx;
   5971          SOC_HU2_LPM_STATE_END(unit, pfx_len) = idx;
   5972      } else {
   5973          SOC_HU2_LPM_STATE_END(unit, pfx_len) = idx;
   5974      }
   5975  
   5976      SOC_HU2_LPM_STATE_VENT(unit, pfx_len)++;
   5977      HU2_LPM_HASH_INSERT(unit, lpm_entry, idx);
   5978  
   5979      return (SOC_E_NONE);
   5980  }
   5981  #endif /* BCM_WARM_BOOT_SUPPORT */
   5982  
   5983  
   5984  #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP
   5985  /*
   5986   * Function:
   5987   *     soc_hu2_lpm_sw_dump
   5988   * Purpose:
   5989   *     Displays FB HU2_LPM information maintained by software.
   5990   * Parameters:
   5991   *     unit - Device unit number
   5992   * Returns:
   5993   *     None
   5994   */
   5995  void
   5996  soc_hu2_lpm_sw_dump(int unit)
   5997  {
   5998      soc_hu2_lpm_state_p  lpm_state;
   5999      int              i;
   6000  
   6001      LOG_CLI((BSL_META_U(unit,
   6002                          "\n    FB HU2_LPM State -\n")));
   6003      LOG_CLI((BSL_META_U(unit,
   6004                          "        Prefix entries : %d\n"), MAX_PFX_ENTRIES(unit)));
   6005  
   6006      lpm_state = soc_hu2_lpm_state[unit];
   6007      if (lpm_state == NULL) {
   6008          return;
   6009      }
   6010  
   6011      for (i = 0; i < MAX_PFX_ENTRIES(unit); i++) {
   6012          if (lpm_state[i].vent != 0 ) {
   6013              LOG_CLI((BSL_META_U(unit,
   6014                                  "      Prefix %d\n"), i));
   6015              LOG_CLI((BSL_META_U(unit,
   6016                                  "        Start : %d\n"), lpm_state[i].start));
   6017              LOG_CLI((BSL_META_U(unit,
   6018                                  "        End   : %d\n"), lpm_state[i].end));
   6019              LOG_CLI((BSL_META_U(unit,
   6020                                  "        Prev  : %d\n"), lpm_state[i].prev));
   6021              LOG_CLI((BSL_META_U(unit,
   6022                                  "        Next  : %d\n"), lpm_state[i].next));
   6023              LOG_CLI((BSL_META_U(unit,
   6024                                  "        Valid Entries : %d\n"), lpm_state[i].vent));
   6025              LOG_CLI((BSL_META_U(unit,
   6026                                  "        Free  Entries : %d\n"), lpm_state[i].fent));
   6027          }
   6028      }
   6029  
   6030      return;
   6031  }
   6032  #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */
   6033  
   6034  /*
   6035   * Implementation using soc_mem_read/write using entry rippling technique
   6036   * Advantage: A completely sorted table is not required. Lookups can be slow
   6037   * as it will perform a linear search on the entries for a given prefix length.
   6038   * No device access necessary for the search if the table is cached. Auxiliary
   6039   * hash table can be maintained to speed up search(Not implemented) instead of
   6040   * performing a linear search.
   6041   * Small number of entries need to be moved around (97 worst case)
   6042   * for performing insert/update/delete. However CPU needs to do all
   6043   * the work to move the entries.
   6044   */
   6045  
   6046  /*
   6047   * soc_hu2_lpm_insert
   6048   * For IPV4 assume only both IP_ADDR0 is valid
   6049   * Moving multiple entries around in h/w vs  doing a linear search in s/w
   6050   */
   6051  int
   6052  soc_hu2_lpm_insert(int u, void *entry_data)
   6053  {
   6054      int         pfx;
   6055      int         index;
   6056      uint32      e[SOC_MAX_MEM_FIELD_WORDS];
   6057      int         rv = SOC_E_NONE;
   6058      int         found = 0;
   6059  
   6060      sal_memcpy(e, soc_mem_entry_null(u, L3_DEFIPm),
   6061                 soc_mem_entry_words(u,L3_DEFIPm) * 4);
   6062  
   6063      SOC_HU2_LPM_LOCK(u);
   6064      rv = _soc_hu2_lpm_match(u, entry_data, e, &index, &pfx);
   6065      if (rv == SOC_E_NOT_FOUND) {
   6066          rv = _lpm_hu2_free_slot_create(u, pfx, e, &index);
   6067          if (rv < 0) {
   6068              SOC_HU2_LPM_UNLOCK(u);
   6069              return(rv);
   6070          }
   6071      } else {
   6072          found = 1;
   6073      }
   6074  
   6075      if (rv == SOC_E_NONE) {
   6076          /* Entry already present. Update the entry */
   6077          soc_hu2_lpm_state_dump(u);
   6078          LOG_INFO(BSL_LS_SOC_SOCMEM,
   6079                   (BSL_META_U(u,
   6080                               "\nsoc_hu2_lpm_insert: %d %d\n"),
   6081                               index, pfx));
   6082          if (!found) {
   6083              HU2_LPM_HASH_INSERT(u, entry_data, index);
   6084          }
   6085          rv = WRITE_L3_DEFIPm(u, MEM_BLOCK_ANY, index, entry_data);
   6086 #ifdef BCM_HURRICANE3_SUPPORT
   6087          if (rv >= 0 && soc_feature(u, soc_feature_urpf)) {
   6088             rv = _lpm_hr3_urpf_entry_replicate(u, index, entry_data);
   6089          }
   6090 #endif  /* BCM_HURRICANE3_SUPPORT */
   6091      }
   6092  
   6093      SOC_HU2_LPM_UNLOCK(u);
   6094  
   6095      return(rv);
   6096  }
   6097  
   6098  /*
   6099   * soc_hu2_lpm_delete
   6100   */
   6101  int
   6102  soc_hu2_lpm_delete(int u, void *key_data)
   6103  {
   6104      int         pfx;
   6105      int         index;
   6106      uint32      e[SOC_MAX_MEM_FIELD_WORDS];
   6107      int         rv = SOC_E_NONE;
   6108  
   6109      SOC_HU2_LPM_LOCK(u);
   6110      rv = _soc_hu2_lpm_match(u, key_data, e, &index, &pfx);
   6111      if (rv == SOC_E_NONE) {
   6112          LOG_INFO(BSL_LS_SOC_SOCMEM,
   6113                   (BSL_META_U(u,
   6114                               "\nsoc_hu2_lpm_delete: %d %d\n"),
   6115                               index, pfx));
   6116          HU2_LPM_HASH_DELETE(u, key_data, index);
   6117          rv = _lpm_hu2_free_slot_delete(u, pfx, e, index);
   6118      }
   6119      soc_hu2_lpm_state_dump(u);
   6120      SOC_HU2_LPM_UNLOCK(u);
   6121      return(rv);
   6122  }
   6123  
   6124  /*
   6125   * soc_hu2_lpm_match (Exact match for the key. Will match both IP
   6126   *                   address and mask)
   6127   */
   6128  int
   6129  soc_hu2_lpm_match(int u,
   6130                 void *key_data,
   6131                 void *e,         /* return entry data if found */
   6132                 int *index_ptr)  /* return key location */
   6133  {
   6134      int        pfx;
   6135      int        rv;
   6136  
   6137      SOC_HU2_LPM_LOCK(u);
   6138      rv = _soc_hu2_lpm_match(u, key_data, e, index_ptr, &pfx);
   6139      SOC_HU2_LPM_UNLOCK(u);
   6140      return(rv);
   6141  }
   6142  
   6143 #endif
   6144 
   6145 static const soc_reg_t pvtmon_result_reg[] = {
   6146     TOP_PVTMON_RESULT_0r
   6147 };
   6148 
   6149 int
   6150 soc_hu2_temperature_monitor_get(int unit,
   6151           int temperature_max,
   6152           soc_switch_temperature_monitor_t *temperature_array,
   6153           int *temperature_count)
   6154 {
   6155     soc_reg_t reg;
   6156     int index;
   6157     uint32 rval;
   6158     int fval, cur, peak;
   6159     int num_entries_out;
   6160 
   6161     *temperature_count = 0;
   6162     if (COUNTOF(pvtmon_result_reg) > temperature_max) {
   6163         num_entries_out = temperature_max;
   6164     } else {
   6165         num_entries_out = COUNTOF(pvtmon_result_reg);
   6166     }
   6167         
   6168     for (index = 0; index < num_entries_out; index++) {
   6169         reg = pvtmon_result_reg[index];
   6170         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   6171 
   6172         fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
   6173         cur = (4180000 - (5556 * fval)) / 1000;
   6174         fval = soc_reg_field_get(unit, reg, rval, PEAK_TEMP_DATAf);
   6175         peak = (4180000 - (5556 * fval)) / 1000;
   6176         (temperature_array + index)->curr = cur;
   6177         (temperature_array + index)->peak	 = peak;
   6178     }
   6179     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   6180     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6181                       TOP_TEMP_MON_PEAK_RST_Lf, 0);
   6182     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   6183     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6184                       TOP_TEMP_MON_PEAK_RST_Lf, 1);
   6185     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   6186 
   6187     *temperature_count=num_entries_out;
   6188     return SOC_E_NONE;
   6189 }
   6190 
   6191 
   6192 int
   6193 soc_hu2_show_ring_osc(int unit)
   6194 {
   6195     static const struct {
   6196         int osc_sel;
   6197         soc_field_t field0;
   6198         int value0;
   6199         soc_field_t field1;
   6200         int value1;
   6201         char *name;
   6202     } osc_tbl[] = {
   6203         { 0, OSC_0_SELf, 0, INVALIDf, -1, "IO ring 0 HVT min" },
   6204         { 0, OSC_0_SELf, 1, INVALIDf, -1, "IO ring 0 HVT mid" },
   6205         { 0, OSC_0_SELf, 2, INVALIDf, -1, "IO ring 0 HVT max" },
   6206         { 0, OSC_0_SELf, 3, INVALIDf, -1, "IO ring 0 SVT min" },
   6207         { 1, OSC_1_SELf, 0, INVALIDf, -1, "IO ring 1 HVT min" },
   6208         { 1, OSC_1_SELf, 1, INVALIDf, -1, "IO ring 1 HVT mid" },
   6209         { 1, OSC_1_SELf, 2, INVALIDf, -1, "IO ring 1 HVT max" },
   6210         { 1, OSC_1_SELf, 3, INVALIDf, -1, "IO ring 1 SVT min" },
   6211         { 2, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" },
   6212         { 2, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" },
   6213         { 3, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" },
   6214         { 3, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" },
   6215         { 4, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" },
   6216         { 5, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" },
   6217         { 6, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" },
   6218         { 7, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" },
   6219         { 8, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" },
   6220         { 9, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" },
   6221         { 10, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" },
   6222         { 11, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" },
   6223         { 12, SRAM_OSC_4_PENf, 0, SRAM_OSC_4_NENf, 1, "SRAM ring 4 NMOS" },
   6224         { 13, SRAM_OSC_4_PENf, 1, SRAM_OSC_4_NENf, 0, "SRAM ring 4 PMOS" },
   6225         { 14, SRAM_OSC_5_PENf, 0, SRAM_OSC_5_NENf, 1, "SRAM ring 5 NMOS" },
   6226         { 15, SRAM_OSC_5_PENf, 1, SRAM_OSC_5_NENf, 0, "SRAM ring 5 PMOS" },
   6227     };
   6228     uint32 rval, fval;
   6229     int index, core_clk, quo, rem, frac, retry;
   6230 
   6231     core_clk = 133 * 1024;
   6232 
   6233     for (index = 0; index < COUNTOF(osc_tbl); index++) {
   6234         rval = 0;
   6235         /*
   6236          * set OSC_CNT_RSTBf to 0 to do softreset
   6237          * set OSC_CNT_START to 0 to hold the counter until it selects
   6238          * the input signal
   6239          */
   6240         SOC_IF_ERROR_RETURN(READ_TOP_RING_OSC_CTRLr(unit, &rval));
   6241         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, OSC_ENABLEf, 1);
   6242         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, IROSC_ENf, 1);
   6243         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, osc_tbl[index].field0,
   6244                           osc_tbl[index].value0);
   6245         if (osc_tbl[index].field1 != INVALIDf) {
   6246             soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, osc_tbl[index].field1,
   6247                               osc_tbl[index].value1);
   6248         }
   6249         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, OSC_SELf,
   6250                           osc_tbl[index].osc_sel);
   6251         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
   6252         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, OSC_CNT_RSTBf, 1);
   6253         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
   6254         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, OSC_CNT_STARTf, 1);
   6255         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
   6256 
   6257         for (retry = 0; retry < 10; retry++) {
   6258             sal_usleep(1000);
   6259             SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval));
   6260             if (!soc_reg_field_get(unit, TOP_OSC_COUNT_STATr, rval, OSC_CNT_DONEf)) {
   6261                 continue;
   6262             }
   6263 
   6264             fval = soc_reg_field_get(unit, TOP_OSC_COUNT_STATr, rval, OSC_CNT_VALUEf);
   6265             quo = core_clk / fval;
   6266             rem = core_clk - quo * fval;
   6267             frac = (rem * 10000) / fval;
   6268             LOG_CLI((BSL_META_U(unit,
   6269                                 "%s: %d.%04d Mhz\n"),
   6270                      osc_tbl[index].name, quo, frac));
   6271             break;
   6272         }
   6273 
   6274         SOC_IF_ERROR_RETURN(READ_TOP_RING_OSC_CTRLr(unit, &rval));
   6275         soc_reg_field_set(unit, TOP_RING_OSC_CTRLr, &rval, OSC_CNT_STARTf, 0);
   6276         /* Clearing theStart bit Clears the Counter */
   6277         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
   6278 
   6279     }
   6280 
   6281     return SOC_E_NONE;
   6282 }
   6283 
   6284 
   6285 int
   6286 soc_hu2_show_material_process(int unit)
   6287 {
   6288     soc_reg_t reg;
   6289     int index;
   6290     uint32 rval, fval, nmos[COUNTOF(pvtmon_result_reg)], n_avg, p_avg;
   6291 
   6292     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval));
   6293     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 0);
   6294     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   6295     sal_usleep(1000);
   6296     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 1);
   6297     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   6298     sal_usleep(1000);
   6299 
   6300     SOC_IF_ERROR_RETURN
   6301         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
   6302                                 PVTMON_SELECTf, 1));
   6303     sal_usleep(1000);
   6304 
   6305     p_avg = 0;
   6306 
   6307     /* Read NMOS information */
   6308     SOC_IF_ERROR_RETURN
   6309         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
   6310                                 MEASUREMENT_CALLIBRATIONf, 5));
   6311 
   6312     sal_usleep(1000);
   6313 
   6314     n_avg = 0;
   6315     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
   6316         reg = pvtmon_result_reg[index];
   6317         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   6318         nmos[index] = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
   6319         n_avg += nmos[index];
   6320     }
   6321 
   6322     /* Read PMOS information and print both NMOS and PMOS value */
   6323     SOC_IF_ERROR_RETURN
   6324         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
   6325                                 MEASUREMENT_CALLIBRATIONf, 7));
   6326 
   6327     sal_usleep(1000);
   6328 
   6329     p_avg = 0;
   6330     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
   6331         reg = pvtmon_result_reg[index];
   6332         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   6333         fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
   6334         p_avg += fval;
   6335 
   6336         LOG_CLI((BSL_META_U(unit,
   6337                             "Material process location %d: NMOS = %3d PMOS = %3d\n"),
   6338                  index, nmos[index], fval));
   6339     }
   6340 
   6341     LOG_CLI((BSL_META_U(unit,
   6342                         "Average:                     NMOS = %3d PMOS = %3d\n"),
   6343              n_avg / COUNTOF(pvtmon_result_reg),
   6344              p_avg / COUNTOF(pvtmon_result_reg)));
   6345 
   6346     return SOC_E_NONE;
   6347 }
   6348 
   6349 
   6350 #if defined(SER_TR_TEST_SUPPORT)
   6351 /*
   6352  * Function:
   6353  *      soc_hu2_ser_mem_test
   6354  * Purpose:
   6355  *      Performs a SER test on a single Hurricane2 memory
   6356  * Parameters:
   6357  *      unit               - (IN) Device Number
   6358  *      mem                - (IN) The memory to test
   6359  *      test_type        - (IN) How many indices in the memory to test
   6360  */
   6361 int soc_hu2_ser_mem_test(int unit, soc_mem_t mem, 
   6362                                 _soc_ser_test_t test_type, int cmd) {
   6363     int group, table, i, rv;
   6364     _soc_parity_info_t *info;
   6365     soc_mem_t memTable;
   6366     soc_port_t block_port;
   6367     soc_block_t blk;
   6368     int testErrors = 0;
   6369     /*Prevent compiler error for common function signature.*/
   6370     (void) cmd;
   6371     /*TCAM_test*/
   6372     for (i = 0; _soc_hu2_tcam_ser_info[i].mem != INVALIDm; i++) {
   6373         if (_soc_hu2_tcam_ser_info[i].mem == mem) {
   6374 
   6375             /* coverity[negative_returns : FALSE] */
   6376             rv = ser_test_mem_pipe(unit, SER_RANGE_ENABLEr, 
   6377                             i, -1, _soc_hu2_tcam_ser_info[i].mem, VALIDf, 
   6378                             test_type, MEM_BLOCK_ANY,
   6379                             REG_PORT_ANY, _SOC_ACC_TYPE_PIPE_ANY, &testErrors);
   6380             if (rv != SOC_E_NONE) {
   6381                 LOG_CLI((BSL_META_U(unit,
   6382                                     "Error during TCAM test.  Aborting.\n")));
   6383                 return rv;
   6384             }
   6385         }
   6386     }
   6387     /*H/W memory Test*/
   6388     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
   6389         info = _soc_hu2_parity_group_info[group].info;
   6390 
   6391         SOC_BLOCK_ITER(unit, blk,
   6392                 _soc_hu2_parity_group_info[group].blocktype) {
   6393             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   6394                 continue;
   6395             }
   6396 
   6397             for (table = 0; info[table].error_field != INVALIDf; table++) {
   6398                 memTable = info[table].mem;
   6399                 if (memTable == INVALIDm) {
   6400                     continue;
   6401                 }
   6402                 if (memTable == mem) {
   6403                     if (_soc_hu2_parity_group_info[group].blocktype 
   6404                                         == SOC_BLK_MMU) {
   6405                         if ((mem == MMU_IPMC_VLAN_TBLm) ||
   6406                            (mem == MMU_IPMC_GROUP_TBL0m) ||
   6407                            (mem == MMU_IPMC_GROUP_TBL1m)) {
   6408                            /* The parity value is generated by software */
   6409                            continue;
   6410                         }
   6411                         rv = ser_test_mem_pipe(unit, MISCCONFIGr, -1, 
   6412                                  PARITY_CHECK_ENf,
   6413                                  mem, INVALIDf, test_type, blk, block_port, 
   6414                                  _SOC_ACC_TYPE_PIPE_ANY, &testErrors);
   6415                     } else {
   6416                         rv = ser_test_mem_pipe(unit,info[table].control_reg, -1, 
   6417                                  info[table].enable_field,
   6418                                  mem, INVALIDf, test_type, blk, block_port, 
   6419                                  _SOC_ACC_TYPE_PIPE_ANY, &testErrors);
   6420                    }
   6421                     if (rv != SOC_E_NONE) {
   6422                         LOG_CLI((BSL_META_U(unit,
   6423                                             "Error during H/W test.  Aborting.\n")));
   6424                         return rv;
   6425                     }
   6426                 }
   6427             }
   6428 
   6429         }
   6430     }
   6431     if (testErrors == 0) {
   6432         LOG_CLI((BSL_META_U(unit,
   6433                             "SER Test passed on unit: %d for memory %s\n"), unit, 
   6434                  SOC_MEM_NAME(unit,mem)));
   6435     }
   6436     else {
   6437         LOG_CLI((BSL_META_U(unit,
   6438                             "SER Test failed on unit: %d for memory %s\n"), unit, 
   6439                  SOC_MEM_NAME(unit,mem)));
   6440         return SOC_E_MEMORY;
   6441     }
   6442     return SOC_E_NONE;
   6443 }
   6444 
   6445 /*
   6446  * Function:
   6447  *      soc_hu2_ser_test
   6448  * Purpose:
   6449  *      Performs a SER test on all Hurricane2 Memories
   6450  * Parameters:
   6451  *      unit               - (IN) Device Number
   6452  *      test_type        - (IN) Determines how comprehensive of a test to run
   6453  */
   6454 int soc_hu2_ser_test(int unit, _soc_ser_test_t test_type) {
   6455     int i, group, rv, table;
   6456     _soc_parity_info_t *info;
   6457     soc_port_t block_port;
   6458     soc_mem_t memTable;
   6459     soc_block_t blk;
   6460     int numTCAMErr   = 0;
   6461     int numHwMemErr   = 0;
   6462     
   6463     /*Test each TCAM memory*/
   6464     for (i = 0; _soc_hu2_tcam_ser_info[i].mem != INVALIDm; i++) {
   6465         rv = ser_test_mem_pipe(unit, SER_RANGE_ENABLEr, i, -1,
   6466                 _soc_hu2_tcam_ser_info[i].mem, VALIDf, test_type, 
   6467                 MEM_BLOCK_ANY, REG_PORT_ANY, 
   6468                 _SOC_ACC_TYPE_PIPE_ANY, &numTCAMErr);
   6469                 if (rv != SOC_E_NONE) {
   6470                     LOG_CLI((BSL_META_U(unit,
   6471                                         "Error during TCAM test.  Aborting.\n")));
   6472                     return rv;
   6473                 }
   6474     }
   6475     /*H/W memory Test*/
   6476     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
   6477         info = _soc_hu2_parity_group_info[group].info;
   6478 
   6479         SOC_BLOCK_ITER(unit, blk,
   6480                 _soc_hu2_parity_group_info[group].blocktype) {
   6481             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   6482                 continue;
   6483             }
   6484 
   6485             for (table = 0; info[table].error_field != INVALIDf; table++) {
   6486                 memTable = info[table].mem;
   6487                 if (memTable == INVALIDm) {
   6488                     continue;
   6489                 }
   6490                 if (_soc_hu2_parity_group_info[group].blocktype == 
   6491                              SOC_BLK_MMU) {
   6492                     if ((memTable == MMU_IPMC_VLAN_TBLm) || 
   6493                        (memTable == MMU_IPMC_GROUP_TBL0m) ||
   6494                        (memTable == MMU_IPMC_GROUP_TBL1m)) {
   6495                        /* The parity value is generated by software */
   6496                        continue;
   6497                     }
   6498                     rv = ser_test_mem_pipe(unit,MISCCONFIGr, -1, 
   6499                              PARITY_CHECK_ENf,
   6500                              info[table].mem, INVALIDf, test_type, 
   6501                              blk, block_port, 
   6502                              _SOC_ACC_TYPE_PIPE_ANY, &numHwMemErr);
   6503                 } else {
   6504                     rv = ser_test_mem_pipe(unit,info[table].control_reg, -1, 
   6505                              info[table].enable_field,
   6506                              info[table].mem, INVALIDf, test_type, 
   6507                              blk, block_port, 
   6508                              _SOC_ACC_TYPE_PIPE_ANY, &numHwMemErr);
   6509                 }
   6510                 if (rv != SOC_E_NONE) {
   6511                     LOG_CLI((BSL_META_U(unit,
   6512                                         "Error during H/W test.  Aborting.\n")));
   6513                     return rv;
   6514                 }
   6515             }
   6516 
   6517         }
   6518     }
   6519     
   6520     LOG_CLI((BSL_META_U(unit,
   6521                         "Total TCAM errors on unit %d: %d\n"), unit, numTCAMErr));
   6522     LOG_CLI((BSL_META_U(unit,
   6523                         "Total H/W parity errors on unit %d: %d\n"),unit, numHwMemErr));
   6524     return SOC_E_NONE;
   6525 }
   6526 
   6527 STATIC soc_error_t
   6528 _ser_hu2_ser_error_injection_support(int unit, soc_mem_t mem,
   6529                                     int pipe_target)
   6530 {
   6531 
   6532     int rv = SOC_E_UNAVAIL;
   6533     int i = 0, hw_enable_ix = 0, group = 0, table = 0;
   6534     uint32 range_enable;
   6535     _soc_generic_ser_info_t *tcam_ser_info;
   6536     _soc_hu2_parity_group_info_t * gp;
   6537     _soc_parity_info_t *info;
   6538     soc_port_t block_port;
   6539     soc_mem_t memTable;
   6540     soc_block_t blk;
   6541 
   6542     LOG_VERBOSE(BSL_LS_SOC_SER,
   6543                 (BSL_META_U(unit,
   6544                             "unit %d, mem %s, pipe_target %d\n"),
   6545                  unit, SOC_MEM_NAME(unit,mem), pipe_target));
   6546 
   6547     if (!SOC_MEM_IS_VALID(unit, mem)) {
   6548         LOG_ERROR(BSL_LS_SOC_COMMON,
   6549                   (BSL_META_U(unit,
   6550                               "unit %d, mem %d is INVALID or not valid "
   6551                               "for this unit !!\n"),
   6552                    unit, mem));
   6553         return SOC_E_UNAVAIL;
   6554     }
   6555 
   6556     tcam_ser_info = _soc_hu2_tcam_ser_info;
   6557 
   6558     /* Search TCAMs */
   6559     if (tcam_ser_info != NULL) {
   6560         /* Check if enable */
   6561         SOC_IF_ERROR_RETURN
   6562             (READ_SER_RANGE_ENABLEr(unit, &range_enable));
   6563         LOG_DEBUG(BSL_LS_SOC_SER,
   6564                   (BSL_META_U(unit,
   6565                               "Search TCAMs: SER_RANGE_ENABLE 0x%X\n"),
   6566                    range_enable));
   6567         for (i = 0; tcam_ser_info[i].mem != INVALIDm; i++) {
   6568             if (tcam_ser_info[i].mem == mem) {
   6569                 hw_enable_ix = tcam_ser_info[i].ser_hw_index;
   6570                 LOG_DEBUG(BSL_LS_SOC_SER,
   6571                           (BSL_META_U(unit,
   6572                                       "SER Range HW Enable index %d\n"),
   6573                            hw_enable_ix));
   6574                 if (((range_enable >> hw_enable_ix) & 0x1) == 0) {
   6575                     LOG_WARN(BSL_LS_SOC_SER,
   6576                              (BSL_META_U(unit,
   6577                                          "matched mem but SER detection is disabled\n"
   6578                                          "SER_RANGE_ENABLE 0x%X, SER Range HW index %d\n"),
   6579                               range_enable,hw_enable_ix));
   6580                     return rv; /* matched mem but ser_detection is disabled */
   6581                 }
   6582                 LOG_VERBOSE(BSL_LS_SOC_SER,
   6583                             (BSL_META_U(unit,
   6584                                         "TCAM found\n")));
   6585                 return SOC_E_NONE; /* found */
   6586             }
   6587         }
   6588     }
   6589 
   6590     /*H/W memory Test*/
   6591     for (group = 0; ; group++) {
   6592         gp = &_soc_hu2_parity_group_info[group];
   6593         info = gp->info;
   6594         if (gp->cpi_bit == 0) {
   6595             /* End of table */
   6596             break;
   6597         }
   6598         SOC_BLOCK_ITER(unit, blk, gp->blocktype) {
   6599             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   6600                 continue;
   6601             }
   6602             for (table = 0; info[table].error_field != INVALIDf; table++) {
   6603                 memTable = info[table].mem;
   6604                 if (memTable == INVALIDm) {
   6605                     continue;
   6606                 }
   6607                 if (gp->blocktype == SOC_BLK_MMU) {
   6608                     if ((memTable == MMU_IPMC_VLAN_TBLm) ||
   6609                        (memTable == MMU_IPMC_GROUP_TBL0m) ||
   6610                        (memTable == MMU_IPMC_GROUP_TBL1m)) {
   6611                        /* The parity value is generated by software */
   6612                        continue;
   6613                     }
   6614                 }
   6615                 if (memTable == mem) {
   6616                     LOG_VERBOSE(BSL_LS_SOC_SER,
   6617                                 (BSL_META_U(unit,
   6618                                             "H/W memory found\n")));
   6619                     return SOC_E_NONE; /* found */
   6620                 }
   6621             }
   6622 
   6623         }
   6624     }
   6625     /* The tested memory is not found in SER enabled list, can't inject error of it */
   6626     return rv;
   6627 }
   6628 
   6629 /*
   6630  * Function:
   6631  *      soc_hu2_ser_mem_test
   6632  * Purpose:
   6633  *      Performs a SER test on a single Hurricane2 memory
   6634  * Parameters:
   6635  *      unit               - (IN) Device Number
   6636  *      mem                - (IN) The memory to test
   6637  *      test_type        - (IN) How many indices in the memory to test
   6638  */
   6639 int soc_hu2_ser_inject_error(int unit, uint32 flags, soc_mem_t mem,
   6640                              int pipeTarget, int block, int index) {
   6641     int group, table, i;
   6642     _soc_parity_info_t *info;
   6643     soc_mem_t memTable;
   6644     soc_port_t block_port;
   6645     soc_block_t blk;
   6646     ser_test_data_t test_data;
   6647     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
   6648     test_data.entry_buf = tmp_entry;
   6649     test_data.field_buf = fieldData;
   6650     /*TCAM_test*/
   6651     for (i = 0; _soc_hu2_tcam_ser_info[i].mem != INVALIDm; i++) {
   6652         if (_soc_hu2_tcam_ser_info[i].mem == mem) {          
   6653             soc_ser_create_test_data(unit, tmp_entry, fieldData,
   6654                                      SER_RANGE_ENABLEr, i, INVALIDf, mem,
   6655                                      INVALIDf, MEM_BLOCK_ANY, REG_PORT_ANY,
   6656                                      _SOC_ACC_TYPE_PIPE_ANY, index, &test_data);
   6657             /*Read the memory for successful injection*/
   6658             SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, &test_data));
   6659             /*Disable parity*/
   6660             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0));
   6661             /*Inject error*/            
   6662             SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags,
   6663                                                           &test_data));
   6664             /*Enable parity*/
   6665             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1));
   6666             return SOC_E_NONE;
   6667 
   6668         }
   6669     }
   6670     /*H/W memory Test*/
   6671     for (group = 0; _soc_hu2_parity_group_info[group].cpi_bit; group++) {
   6672         info = _soc_hu2_parity_group_info[group].info;
   6673 
   6674         SOC_BLOCK_ITER(unit, blk,
   6675                 _soc_hu2_parity_group_info[group].blocktype) {
   6676             if (_soc_hurricane2_parity_block_port(unit, blk, &block_port) < 0) {
   6677                 continue;
   6678             }
   6679 
   6680             for (table = 0; info[table].error_field != INVALIDf; table++) {
   6681                 memTable = info[table].mem;
   6682                 if (memTable == INVALIDm) {
   6683                     continue;
   6684                 }
   6685                 if (memTable == mem) {
   6686                     if((blk == block) || (block == MEM_BLOCK_ANY))
   6687                     {
   6688                         /*Inject error*/
   6689                         test_data.mem = mem;
   6690                         test_data.tcam_parity_bit = -1;
   6691                         if (_soc_hu2_parity_group_info[group].blocktype 
   6692                                         == SOC_BLK_MMU) {
   6693                             if ((mem == MMU_IPMC_VLAN_TBLm) || 
   6694                                 (mem == MMU_IPMC_GROUP_TBL0m) ||
   6695                                 (mem == MMU_IPMC_GROUP_TBL1m)) {
   6696                                 /* the parity value is generated by software */
   6697                                 continue;
   6698                             }
   6699                             soc_ser_create_test_data(unit, tmp_entry, fieldData,
   6700                                          MISCCONFIGr,
   6701                                          SOC_INVALID_TCAM_PARITY_BIT,
   6702                                          PARITY_CHECK_ENf,
   6703                                          mem, EVEN_PARITYf, blk,
   6704                                          block_port, _SOC_ACC_TYPE_PIPE_ANY, 
   6705                                          index, &test_data);
   6706                         } else {
   6707                             soc_ser_create_test_data(unit, tmp_entry, fieldData,
   6708                                          info[table].control_reg,
   6709                                          SOC_INVALID_TCAM_PARITY_BIT,
   6710                                          info[table].enable_field,
   6711                                          mem, EVEN_PARITYf, blk,
   6712                                          block_port, _SOC_ACC_TYPE_PIPE_ANY,
   6713                                          index, &test_data);
   6714                         }
   6715                         SOC_IF_ERROR_RETURN(
   6716                                 ser_test_mem_read(unit, 0, &test_data));
   6717                         /*Disable parity*/
   6718                         SOC_IF_ERROR_RETURN(
   6719                                 _ser_test_parity_control(unit, &test_data, 0));
   6720                         /*Inject error*/
   6721                         SOC_IF_ERROR_RETURN(
   6722                                 soc_ser_test_inject_full(unit, flags,
   6723                                                           &test_data));
   6724                         /*Enable parity*/
   6725                         SOC_IF_ERROR_RETURN(
   6726                                 _ser_test_parity_control(unit, &test_data, 1));
   6727                     }
   6728                 }
   6729             }
   6730 
   6731         }
   6732     }
   6733     return SOC_E_NONE;
   6734 }
   6735 
   6736 void
   6737 soc_hu2_ser_test_register(int unit)
   6738 {
   6739     /*Initialize chip-specific functions for SER testing*/
   6740     memset(&ser_hu2_test_fun, 0, sizeof(soc_ser_test_functions_t));
   6741     ser_hu2_test_fun.inject_error_f = &soc_hu2_ser_inject_error;
   6742     ser_hu2_test_fun.test_mem = &soc_hu2_ser_mem_test;
   6743     ser_hu2_test_fun.test     = &soc_hu2_ser_test;
   6744     ser_hu2_test_fun.injection_support = &_ser_hu2_ser_error_injection_support;
   6745 
   6746     soc_ser_test_functions_register(unit, &ser_hu2_test_fun);
   6747 }
   6748 #endif /* SER_TR_TEST_SUPPORT */
   6749 
   6750 
   6751 
   6752 #endif /* BCM_HURRICANE2_SUPPORT */