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

latency.c (57110B)


      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:      latency.c
      8  * Purpose:   Switch Latency Bypass feature support for Tomahawk SKUs
      9  * Requires:  soc/tomahawk.h
     10  */
     11 
     12 #include <soc/tomahawk.h>
     13 
     14 #if defined(BCM_TOMAHAWK_SUPPORT)
     15 #include <sal/types.h>
     16 #include <soc/drv.h>
     17 #include <soc/ll.h>
     18 #include <soc/property.h>
     19 #include <shared/bsl.h>
     20 #include <appl/diag/system.h>
     21 #include <shared/bitop.h>
     22 #include <bcm_int/esw/trunk.h>
     23 #include <bcm_int/esw/mbcm.h>
     24 #ifdef BCM_WARM_BOOT_SUPPORT
     25 #include <soc/scache.h>
     26 #endif
     27 
     28 
     29 #define SBUS_ADDR_BEAT_STAGEID    26
     30 
     31 #define _SOC_TH_LATENCY_INIT_VALIDATE(unit, ret)                              \
     32         if (!_soc_th_latency_ctrl[unit] || !_soc_th_latency_ctrl[unit]->init) \
     33             return (ret);
     34 
     35 #define _SOC_TH_LATENCY_CFG_VALIDATE(cfg, ret)             \
     36         if (!(((cfg) >= SOC_SWITCH_BYPASS_MODE_NONE) &&    \
     37               ((cfg) <= SOC_SWITCH_BYPASS_MODE_EFP)))      \
     38             return (ret);
     39 
     40 #define _SOC_SWITCH_BYPASS_MODE_INVALID		0xAB
     41 
     42 /* runtime enable/disable knob */
     43 /* temporary, will last only until system testing */
     44 #define _SOC_TH_LATENCY_RT_ENABLE_CHK(unit)                       \
     45         if (!soc_property_get(unit, "switch_bypass_enable", 1))   \
     46             return SOC_E_NONE;
     47 
     48 
     49 extern soc_th_latency_table_cfg_t
     50 soc_th_tbl_cfg[SOC_MAX_NUM_DEVICES];
     51 
     52 
     53 typedef enum {
     54     _SOC_TH_IPIPE_STAGE_IDB      =  0,
     55     _SOC_TH_IPIPE_STAGE_IDB_IS   =  1,
     56     _SOC_TH_IPIPE_STAGE_IDB_OBM0 =  2,
     57     _SOC_TH_IPIPE_STAGE_IDB_OBM1 =  3,
     58     _SOC_TH_IPIPE_STAGE_IDB_OBM2 =  4,
     59     _SOC_TH_IPIPE_STAGE_IDB_OBM3 =  5,
     60     _SOC_TH_IPIPE_STAGE_IDB_OBM4 =  6,
     61     _SOC_TH_IPIPE_STAGE_IDB_OBM5 =  7,
     62     _SOC_TH_IPIPE_STAGE_IDB_OBM6 =  8,
     63     _SOC_TH_IPIPE_STAGE_IDB_OBM7 =  9,
     64     _SOC_TH_IPIPE_STAGE_ICFG     = 10,
     65     _SOC_TH_IPIPE_STAGE_IPARS    = 11,
     66     _SOC_TH_IPIPE_STAGE_IVXLT    = 12,
     67     _SOC_TH_IPIPE_STAGE_IVP      = 13,
     68     _SOC_TH_IPIPE_STAGE_IFWD     = 14,
     69     _SOC_TH_IPIPE_STAGE_ISS      = 15,
     70     _SOC_TH_IPIPE_STAGE_IRSEL1   = 16,
     71     _SOC_TH_IPIPE_STAGE_ISW1     = 17,
     72     _SOC_TH_IPIPE_STAGE_IFP      = 18,
     73     _SOC_TH_IPIPE_STAGE_IRSEL2   = 19,
     74     _SOC_TH_IPIPE_STAGE_ISW2     = 20,
     75     _SOC_TH_IPIPE_STAGE_ISW3     = 21,
     76     _SOC_TH_IPIPE_STAGE_ISBS     = 22,
     77     _SOC_TH_IPIPE_STAGE_CEV      = 23,
     78     _SOC_TH_IPIPE_STAGE_L2_MGMT  = 24,
     79     _SOC_TH_IPIPE_STAGE_FLEX_CTR = 26
     80 } _soc_th_ipipe_stage_e;
     81 
     82 typedef enum {
     83     _SOC_TH_EPIPE_STAGE_EARB     =  0,
     84     _SOC_TH_EPIPE_STAGE_EL3      =  1,
     85     _SOC_TH_EPIPE_STAGE_EVLAN    =  2,
     86     _SOC_TH_EPIPE_STAGE_ESW      =  3,
     87     _SOC_TH_EPIPE_STAGE_EIPT     =  4,
     88     _SOC_TH_EPIPE_STAGE_EHCPM    =  5,
     89     _SOC_TH_EPIPE_STAGE_EPMOD    =  6,
     90     _SOC_TH_EPIPE_STAGE_EFPPARS  =  7,
     91     _SOC_TH_EPIPE_STAGE_EFP      =  8,
     92     _SOC_TH_EPIPE_STAGE_EFPMOD   =  9,
     93     _SOC_TH_EPIPE_STAGE_EDATABUF = 10,
     94     _SOC_TH_EPIPE_STAGE_ESBS     = 11
     95 } _soc_th_epipe_stage_e;
     96 
     97 typedef enum {
     98     _SOC_TH2_IPIPE_STAGE_IDB       =  0,
     99     _SOC_TH2_IPIPE_STAGE_IDB_IS    =  1,
    100     _SOC_TH2_IPIPE_STAGE_IDB_OBM0  =  2,
    101     _SOC_TH2_IPIPE_STAGE_IDB_OBM1  =  3,
    102     _SOC_TH2_IPIPE_STAGE_IDB_OBM2  =  4,
    103     _SOC_TH2_IPIPE_STAGE_IDB_OBM3  =  5,
    104     _SOC_TH2_IPIPE_STAGE_IDB_OBM4  =  6,
    105     _SOC_TH2_IPIPE_STAGE_IDB_OBM5  =  7,
    106     _SOC_TH2_IPIPE_STAGE_IDB_OBM6  =  8,
    107     _SOC_TH2_IPIPE_STAGE_IDB_OBM7  =  9,
    108     _SOC_TH2_IPIPE_STAGE_IDB_OBM8  = 10,
    109     _SOC_TH2_IPIPE_STAGE_IDB_OBM9  = 11,
    110     _SOC_TH2_IPIPE_STAGE_IDB_OBM10 = 12,
    111     _SOC_TH2_IPIPE_STAGE_IDB_OBM11 = 13,
    112     _SOC_TH2_IPIPE_STAGE_IDB_OBM12 = 14,
    113     _SOC_TH2_IPIPE_STAGE_IDB_OBM13 = 15,
    114     _SOC_TH2_IPIPE_STAGE_IDB_OBM14 = 16,
    115     _SOC_TH2_IPIPE_STAGE_IDB_OBM15 = 17,
    116     _SOC_TH2_IPIPE_STAGE_ISBS_IDB  = 18,
    117     _SOC_TH2_IPIPE_STAGE_ICFG      = 19,
    118     _SOC_TH2_IPIPE_STAGE_IPARS     = 20,
    119     _SOC_TH2_IPIPE_STAGE_IVXLT     = 21,
    120     _SOC_TH2_IPIPE_STAGE_IVP       = 22,
    121     _SOC_TH2_IPIPE_STAGE_IFWD      = 23,
    122     _SOC_TH2_IPIPE_STAGE_IFWD_2    = 24,
    123     _SOC_TH2_IPIPE_STAGE_IFWD_3    = 25,
    124     _SOC_TH2_IPIPE_STAGE_IFWD_4    = 26,
    125     _SOC_TH2_IPIPE_STAGE_IFWD_5    = 27,
    126     _SOC_TH2_IPIPE_STAGE_IFWD_6    = 28,
    127     _SOC_TH2_IPIPE_STAGE_IFWD_7    = 29,
    128     _SOC_TH2_IPIPE_STAGE_IFWD_8    = 30,
    129     _SOC_TH2_IPIPE_STAGE_ISS       = 31,
    130     _SOC_TH2_IPIPE_STAGE_IRSEL1    = 32,
    131     _SOC_TH2_IPIPE_STAGE_ISW1      = 33,
    132     _SOC_TH2_IPIPE_STAGE_IFP       = 34,
    133     _SOC_TH2_IPIPE_STAGE_IRSEL2    = 35,
    134     _SOC_TH2_IPIPE_STAGE_ISW2      = 36,
    135     _SOC_TH2_IPIPE_STAGE_ISW3      = 37,
    136     _SOC_TH2_IPIPE_STAGE_ISBS      = 38,
    137     _SOC_TH2_IPIPE_STAGE_CEV       = 39,
    138     _SOC_TH2_IPIPE_STAGE_L2_MGMT   = 40,
    139     _SOC_TH2_IPIPE_STAGE_L2_MGMT_2 = 41,
    140     _SOC_TH2_IPIPE_STAGE_ISW4      = 42,
    141     _SOC_TH2_IPIPE_STAGE_ISBS_ISW4 = 43,
    142     _SOC_TH2_IPIPE_STAGE_FLEX_CTR  = 44
    143 } _soc_th2_ipipe_stage_e;
    144 
    145 typedef enum {
    146     _SOC_TH2_EPIPE_STAGE_EARB      =  0,
    147     _SOC_TH2_EPIPE_STAGE_EL3       =  1,
    148     _SOC_TH2_EPIPE_STAGE_EVLAN     =  2,
    149     _SOC_TH2_EPIPE_STAGE_ESW       =  3,
    150     _SOC_TH2_EPIPE_STAGE_EIPT      =  4,
    151     _SOC_TH2_EPIPE_STAGE_EHCPM     =  5,
    152     _SOC_TH2_EPIPE_STAGE_EPMOD     =  6,
    153     _SOC_TH2_EPIPE_STAGE_EFPPARS   =  7,
    154     _SOC_TH2_EPIPE_STAGE_EFP       =  8,
    155     _SOC_TH2_EPIPE_STAGE_EFPMOD    =  9,
    156     _SOC_TH2_EPIPE_STAGE_EDATABUF  = 10,
    157     _SOC_TH2_EPIPE_STAGE_ESBS      = 11
    158 } _soc_th2_epipe_stage_e;
    159 
    160 /* Ingress Latency Config */
    161 typedef struct _soc_th_igr_latency_cfg_s {
    162     uint32 ipars    : 1;    /* IPARS Latency Mode */
    163     uint32 ivxlt    : 1;    /* IVXLT Bypass */
    164     uint32 ivp      : 1;    /* IVP Bypass */
    165     uint32 ifwd     : 1;    /* IFWD Latency Mode */
    166     uint32 irsel1   : 1;    /* IRSEL1 Latency Mode */
    167     uint32 ifp      : 1;    /* IFP Bypass */
    168     uint32 irsel2   : 2;    /* IRSEL2 Latency Mode */
    169     uint32 isw2     : 1;    /* ISW2 Latency Mode */
    170     uint32 ecmp     : 2;    /* ECMP Mode */
    171     uint32 reserved : 21;   /* reserved */
    172     /* NOTE: DON'T ALTER FIELD ORDER */
    173 } _soc_th_igr_latency_cfg_t;
    174 
    175 /* Egress Latency Config */
    176 typedef struct _soc_th_egr_latency_cfg_s {
    177     uint32 el3              : 1;    /* EL3 Latency Mode */
    178     uint32 evlan            : 1;    /* EVLAN Latency Mode */
    179     uint32 efp              : 1;    /* EFP Bypass */
    180     uint32 otag_action      : 3;    /* Single Outer Tag - action */
    181     uint32 potag_action     : 3;    /* Pri Outer Tag - action */
    182     uint32 ut_otag_action   : 3;    /* Untagged - action */
    183     uint32 outer_pri        : 1;    /* Outer PRI action */
    184     uint32 outer_cfi        : 1;    /* Outer CFI action */
    185     uint32 outer_tpid       : 16;   /* Outer Tag - TPID */
    186     uint32 reserved1        : 2;    /* reserved */
    187     uint32 profile_ptr      : 4;    /* map PRI-CFI */
    188     uint32 pri              : 3;    /* PRI for Outer tag */
    189     uint32 cfi              : 1;    /* CFI for Outer tag */
    190     uint32 reserved2        : 24;   /* reserved */
    191     /* NOTE: DON'T ALTER FIELD ORDER */
    192 } _soc_th_egr_latency_cfg_t;
    193 
    194 /* Latency core config */
    195 typedef struct _soc_th_latency_core_cfg_s {
    196     _soc_th_igr_latency_cfg_t igr;
    197     _soc_th_egr_latency_cfg_t egr;
    198     /* NOTE: DON'T ALTER FIELD ORDER */
    199 } _soc_th_latency_core_cfg_t;
    200 
    201 /* Latency ctrl */
    202 typedef struct _soc_th_latency_ctrl_s {
    203     uint8   init;
    204     int     latency;
    205     soc_th_latency_table_cfg_t tbl_cfg;
    206 } _soc_th_latency_ctrl_t;
    207 
    208 #ifdef BCM_WARM_BOOT_SUPPORT
    209 /* Latency Warmboot */
    210 typedef struct _soc_th_latency_wb_s {
    211     int unit;
    212     _soc_th_latency_ctrl_t latency_ctrl;
    213 } _soc_th_latency_wb_t;
    214 #endif
    215 
    216 
    217 /* Latency Bypass - Core Config Table  */
    218 static const _soc_th_latency_core_cfg_t
    219 _soc_th_latency_cfg_tbl[] = {
    220     { {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} }, /* Full Features */
    221     { {0, 1, 0, 1, 0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} }, /* Balanced L2 + L3 */
    222     { {1, 1, 1, 1, 1, 1, 2, 1, 2, 0}, {1, 1, 1, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} },  /* Low Latency L2 */
    223     { {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} } /* EFP Latency*/
    224 };
    225 
    226 /* Latency Control */
    227 static _soc_th_latency_ctrl_t*
    228 _soc_th_latency_ctrl[SOC_MAX_NUM_DEVICES] = {NULL};
    229 
    230 /* latency subsystem billboard */
    231 static const char *
    232 lstr[] = {"normal", "balanced (L2/L3)", "low (L2)", "EFP"};
    233 
    234 
    235 /******************************************************************************
    236  * Name: _soc_th_igr_latency_config                                           *
    237  * Description:                                                               *
    238  *     Configure ingress latency settings on the switch                       *
    239  * IN params:                                                                 *
    240  *     - Unit                                                                 *
    241  *     - Latency Mode                                                         *
    242  * Returns:                                                                   *
    243  *     - SOC_E_NONE on success                                                *
    244  *     - SOC_E_* on internal errors                                           *
    245  */
    246 STATIC int
    247 _soc_th_igr_latency_config(
    248     int   unit,
    249     int   latency)
    250 {
    251     uint32 rval = 0;
    252 
    253     _SOC_TH_UNIT_VALIDATE(unit);
    254     _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_PARAM);
    255 
    256     /* ingress latency config */
    257     if (!SOC_IS_TOMAHAWK3(unit)) {
    258         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IPARS_LATENCY_MODEf,
    259                           _soc_th_latency_cfg_tbl[latency].igr.ipars);
    260         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IVXLT_BYPASSf,
    261                           _soc_th_latency_cfg_tbl[latency].igr.ivxlt);
    262         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IVP_BYPASSf,
    263                           _soc_th_latency_cfg_tbl[latency].igr.ivp);
    264         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IFWD_LATENCY_MODEf,
    265                       _soc_th_latency_cfg_tbl[latency].igr.ifwd); 
    266 
    267         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IRSEL1_LATENCY_MODEf,
    268                           _soc_th_latency_cfg_tbl[latency].igr.irsel1);
    269         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IFP_BYPASSf,
    270                           _soc_th_latency_cfg_tbl[latency].igr.ifp);
    271         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IRSEL2_LATENCY_MODEf,
    272                          _soc_th_latency_cfg_tbl[latency].igr.irsel2);
    273         soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, ISW2_LATENCY_MODEf,
    274                          _soc_th_latency_cfg_tbl[latency].igr.isw2);
    275         SOC_IF_ERROR_RETURN(WRITE_ING_LATENCY_CONTROLr(unit, rval));
    276 
    277         /* ECMP latency config */
    278         SOC_IF_ERROR_RETURN(READ_ECMP_CONFIGr(unit, &rval));
    279         soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf,
    280                           _soc_th_latency_cfg_tbl[latency].igr.ecmp);
    281         SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval));
    282     }
    283 
    284     return SOC_E_NONE;
    285 }
    286 
    287 /******************************************************************************
    288  * Name: _soc_th_efp_latency_config                                           *
    289  * Description:                                                               *
    290  *     Configure EFP latency settings on the switch                           *
    291  * IN params:                                                                 *
    292  *     - Unit                                                                 *
    293  *     - Latency Mode                                                         *
    294  * Returns:                                                                   *
    295  *     - SOC_E_NONE on success                                                *
    296  *     - SOC_E_* on internal errors                                           *
    297  */
    298 STATIC int
    299 _soc_th_efp_latency_config(
    300     int   unit,
    301     int   latency)
    302 {
    303     uint32 val = 0;
    304 
    305     _SOC_TH_UNIT_VALIDATE(unit);
    306     _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_PARAM);
    307 
    308     soc_reg_field_set(unit, EGR_LATENCY_MODEr, &val, EFP_BYPASSf,
    309                       _soc_th_latency_cfg_tbl[latency].egr.efp);
    310 
    311     SOC_IF_ERROR_RETURN(WRITE_EGR_LATENCY_MODEr(unit, val));
    312 
    313     return SOC_E_NONE;
    314    
    315 }
    316 /******************************************************************************
    317  * Name: _soc_th_egr_latency_config                                           *
    318  * Description:                                                               *
    319  *     Configure egress latency settings on the switch                        *
    320  * IN params:                                                                 *
    321  *     - Unit                                                                 *
    322  *     - Latency Mode                                                         *
    323  * Returns:                                                                   *
    324  *     - SOC_E_NONE on success                                                *
    325  *     - SOC_E_* on internal errors                                           *
    326  */
    327 STATIC int
    328 _soc_th_egr_latency_config(
    329     int   unit,
    330     int   latency)
    331 {
    332     uint32 rval = 0;
    333     soc_port_t port;
    334 
    335     _SOC_TH_UNIT_VALIDATE(unit);
    336     _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_PARAM);
    337 
    338     if (!SOC_IS_TOMAHAWK3(unit)) {
    339         soc_reg_field_set(unit, EGR_LATENCY_MODEr, &rval, EL3_LATENCY_MODEf,
    340                           _soc_th_latency_cfg_tbl[latency].egr.el3);
    341         soc_reg_field_set(unit, EGR_LATENCY_MODEr, &rval, EVLAN_LATENCY_MODEf,
    342                           _soc_th_latency_cfg_tbl[latency].egr.evlan);
    343     }
    344     soc_reg_field_set(unit, EGR_LATENCY_MODEr, &rval, EFP_BYPASSf,
    345                       _soc_th_latency_cfg_tbl[latency].egr.efp);
    346 
    347     SOC_IF_ERROR_RETURN(WRITE_EGR_LATENCY_MODEr(unit, rval));
    348 
    349     if (SOC_SWITCH_BYPASS_MODE_NONE != latency) {
    350         rval = 0;
    351 
    352         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    353                           &rval, SOT_OTAG_ACTIONf,
    354                           _soc_th_latency_cfg_tbl[latency].egr.otag_action);
    355         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    356                           &rval, SOT_POTAG_ACTIONf,
    357                           _soc_th_latency_cfg_tbl[latency].egr.potag_action);
    358         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    359                           &rval, UT_OTAG_ACTIONf,
    360                           _soc_th_latency_cfg_tbl[latency].egr.ut_otag_action);
    361         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    362                           &rval, CHANGE_OUTER_PRIf,
    363                           _soc_th_latency_cfg_tbl[latency].egr.outer_pri);
    364         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    365                           &rval, CHANGE_OUTER_CFIf,
    366                           _soc_th_latency_cfg_tbl[latency].egr.outer_cfi);
    367         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    368                           &rval, OUTER_TPIDf,
    369                           _soc_th_latency_cfg_tbl[latency].egr.outer_tpid);
    370         soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr,
    371                           &rval, OUTER_PRI_CFI_MAPPING_PTRf,
    372                           _soc_th_latency_cfg_tbl[latency].egr.profile_ptr);
    373 
    374         /* EGR VLAN config */
    375         PBMP_PORT_ITER(unit, port) {
    376             SOC_IF_ERROR_RETURN(
    377                 WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, rval));
    378         }
    379     }
    380 
    381     return SOC_E_NONE;
    382 }
    383 
    384 /******************************************************************************
    385  * Name: _soc_th_latency_resource_avail                                       *
    386  * Description:                                                               *
    387  *     Returns if the specified resource is supported/available for the       *
    388  *     current Latency mode configured on the switch                          *
    389  * IN params:                                                                 *
    390  *     - Unit                                                                 *
    391  *     - Resource Type (Register, Memory, Feature)                            *
    392  *     - Resource Name (Enumeration)                                          *
    393  *     - latency mode                                                         *
    394  * Returns:                                                                   *
    395  *     - TRUE, if the resource is available                                   *
    396  *     - FALSE, if the resource is unavailable                                *
    397  */
    398 STATIC int
    399 _soc_th_latency_resource_avail(
    400     int                unit,
    401     soc_th_resource_e  type,
    402     int                resource,
    403     int                latency)
    404 {
    405     uint32 block, pipe_stage;
    406     uint8  mode;
    407     uint32 access_latency_mode;
    408 
    409     _SOC_TH_UNIT_VALIDATE(unit);
    410     _SOC_TH_LATENCY_RT_ENABLE_CHK(unit);
    411 
    412     _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_NONE);
    413 
    414     if (_SOC_TH_MEM == type) {
    415         if ((SOC_SWITCH_BYPASS_MODE_NONE == latency) &&
    416             SOC_MEM_IS_VALID(unit, resource)) {
    417             return TRUE;
    418         }
    419 
    420         if (!SOC_MEM_IS_VALID(unit, resource)) {
    421             return FALSE;
    422         }
    423         block = SOC_BLOCK_TYPE(unit, SOC_MEM_BLOCK_ANY(unit, resource));
    424         pipe_stage =
    425             (SOC_MEM_INFO(unit, resource).base >> SBUS_ADDR_BEAT_STAGEID);
    426         access_latency_mode = SOC_MEM_INFO(unit, resource).access_latency_mode;
    427     } else if (_SOC_TH_REG == type) {
    428         if ((SOC_SWITCH_BYPASS_MODE_NONE == latency) &&
    429             SOC_REG_IS_VALID(unit, resource)) {
    430             return TRUE;
    431         }
    432 
    433         if (!SOC_REG_IS_VALID(unit, resource)) {
    434             return FALSE;
    435         }
    436         block = SOC_REG_INFO(unit, resource).block[0];
    437         pipe_stage =
    438             (SOC_REG_INFO(unit, resource).offset >> SBUS_ADDR_BEAT_STAGEID);
    439         access_latency_mode = SOC_REG_INFO(unit, resource).access_latency_mode;
    440     } else {
    441         return TRUE;
    442     }
    443 
    444 #ifdef BCM_TOMAHAWK2_SUPPORT
    445     if (SOC_IS_TOMAHAWK2(unit)) {
    446         switch(block) {
    447             case SOC_BLK_IPIPE:
    448                 switch(pipe_stage) {
    449                     case _SOC_TH2_IPIPE_STAGE_IPARS:
    450                         mode = _soc_th_latency_cfg_tbl[latency].igr.ipars;
    451                         break;
    452                     case _SOC_TH2_IPIPE_STAGE_IVXLT:
    453                         mode = _soc_th_latency_cfg_tbl[latency].igr.ivxlt;
    454                         break;
    455                     case _SOC_TH2_IPIPE_STAGE_IVP:
    456                         mode = _soc_th_latency_cfg_tbl[latency].igr.ivp;
    457                         break;
    458                     case _SOC_TH2_IPIPE_STAGE_IFWD:
    459                         mode = _soc_th_latency_cfg_tbl[latency].igr.ifwd;
    460                         break;
    461                     case _SOC_TH2_IPIPE_STAGE_IRSEL1:
    462                         mode = _soc_th_latency_cfg_tbl[latency].igr.irsel1;
    463                         break;
    464                     case _SOC_TH2_IPIPE_STAGE_IFP:
    465                         mode = _soc_th_latency_cfg_tbl[latency].igr.ifp;
    466                         break;
    467                     case _SOC_TH2_IPIPE_STAGE_IRSEL2:
    468                         mode = _soc_th_latency_cfg_tbl[latency].igr.irsel2;
    469                         break;
    470                     case _SOC_TH2_IPIPE_STAGE_ISW2:
    471                         mode = _soc_th_latency_cfg_tbl[latency].igr.isw2;
    472                         break;
    473                     default:
    474                         return TRUE;
    475                 }
    476                 break;
    477 
    478             case SOC_BLK_EPIPE:
    479                 switch(pipe_stage) {
    480                     case _SOC_TH2_EPIPE_STAGE_EL3:
    481                         mode = _soc_th_latency_cfg_tbl[latency].egr.el3;
    482                         break;
    483                     case _SOC_TH2_EPIPE_STAGE_EVLAN:
    484                         mode = _soc_th_latency_cfg_tbl[latency].egr.evlan;
    485                         break;
    486                     case _SOC_TH2_EPIPE_STAGE_EFP:
    487                         mode = _soc_th_latency_cfg_tbl[latency].egr.efp;
    488                         break;
    489                     default:
    490                         return TRUE;
    491                 }
    492                 break;
    493 
    494             default:
    495                 return TRUE;
    496         }
    497     } else
    498 #endif
    499     {
    500         switch(block) {
    501             case SOC_BLK_IPIPE:
    502                 switch(pipe_stage) {
    503                     case _SOC_TH_IPIPE_STAGE_IPARS:
    504                         mode = _soc_th_latency_cfg_tbl[latency].igr.ipars;
    505                         break;
    506                     case _SOC_TH_IPIPE_STAGE_IVXLT:
    507                         mode = _soc_th_latency_cfg_tbl[latency].igr.ivxlt;
    508                         break;
    509                     case _SOC_TH_IPIPE_STAGE_IVP:
    510                         mode = _soc_th_latency_cfg_tbl[latency].igr.ivp;
    511                         break;
    512                     case _SOC_TH_IPIPE_STAGE_IFWD:
    513                         mode = _soc_th_latency_cfg_tbl[latency].igr.ifwd;
    514                         break;
    515                     case _SOC_TH_IPIPE_STAGE_IRSEL1:
    516                         mode = _soc_th_latency_cfg_tbl[latency].igr.irsel1;
    517                         break;
    518                     case _SOC_TH_IPIPE_STAGE_IFP:
    519                         mode = _soc_th_latency_cfg_tbl[latency].igr.ifp;
    520                         break;
    521                     case _SOC_TH_IPIPE_STAGE_IRSEL2:
    522                         mode = _soc_th_latency_cfg_tbl[latency].igr.irsel2;
    523                         break;
    524                     case _SOC_TH_IPIPE_STAGE_ISW2:
    525                         mode = _soc_th_latency_cfg_tbl[latency].igr.isw2;
    526                         break;
    527                     default:
    528                         return TRUE;
    529                 }
    530                 break;
    531 
    532             case SOC_BLK_EPIPE:
    533                 switch(pipe_stage) {
    534                     case _SOC_TH_EPIPE_STAGE_EL3:
    535                         mode = _soc_th_latency_cfg_tbl[latency].egr.el3;
    536                         break;
    537                     case _SOC_TH_EPIPE_STAGE_EVLAN:
    538                         mode = _soc_th_latency_cfg_tbl[latency].egr.evlan;
    539                         break;
    540                     case _SOC_TH_EPIPE_STAGE_EFP:
    541                         mode = _soc_th_latency_cfg_tbl[latency].egr.efp;
    542                         break;
    543                     default:
    544                         return TRUE;
    545                 }
    546                 break;
    547 
    548             default:
    549                 return TRUE;
    550         }
    551     }
    552 
    553     return (mode <= access_latency_mode);
    554 }
    555 
    556 /******************************************************************************
    557  * Name: _soc_th_latency_mem_filter                                           *
    558  * Description:                                                               *
    559  *     Filters out memories/tables unsupported for the current Latency mode   *
    560  * IN params:                                                                 *
    561  *     - Unit                                                                 *
    562  * Returns:                                                                   *
    563  *     - SOC_E_NONE on success                                                *
    564  */
    565 STATIC int
    566 _soc_th_latency_mem_filter(int unit)
    567 {
    568     soc_mem_t mem;
    569     soc_persist_t *sop;
    570     SHR_BITDCL *flags;
    571     int latency;
    572 
    573     sop = SOC_PERSIST(unit);
    574     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency));
    575     for (mem = 0; mem < NUM_SOC_MEM; mem++) {
    576         if (!SOC_MEM_IS_VALID(unit, mem)) {
    577             continue;
    578         }
    579 
    580         if (!soc_th_latency_mem_avail(unit, mem, latency)) {
    581             sop->memState[mem].index_max = -1;
    582             flags = (SHR_BITDCL *) &SOC_MEM_INFO(unit, mem).flags;
    583             SHR_BITCLR(flags, (SOC_MEM_FLAG_VALID - 1));
    584         }
    585     }
    586 
    587     return SOC_E_NONE;
    588 }
    589 
    590 /******************************************************************************
    591  * Name: _soc_th_latency_reg_filter                                           *
    592  * Description:                                                               *
    593  *     Filters out registers unsupported for the current Latency mode         *
    594  * IN params:                                                                 *
    595  *     - Unit                                                                 *
    596  * Returns:                                                                   *
    597  *     - SOC_E_NONE on success                                                *
    598  */
    599 STATIC int
    600 _soc_th_latency_reg_filter(int unit)
    601 {
    602     soc_reg_t reg;
    603     int latency;
    604     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency));
    605 
    606     for (reg = 0; reg < NUM_SOC_REG; reg++) {
    607         if (!SOC_REG_IS_VALID(unit, reg)) {
    608             continue;
    609         }
    610 
    611         if (!soc_th_latency_reg_avail(unit, reg, latency)) {
    612             SOC_REG_INFO(unit, reg).regtype = soc_invalidreg;
    613         }
    614     }
    615 
    616     if (SOC_SWITCH_BYPASS_MODE(unit) && SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) {
    617         /*
    618          * SW WAR to explicitly invalidate SHARED_TABLE_HASH_CONTROL register as this
    619          * register is not accessible in low latency modes
    620          */
    621         SOC_REG_INFO(unit, SHARED_TABLE_HASH_CONTROLr).regtype = soc_invalidreg;
    622     }
    623 
    624     return SOC_E_NONE;
    625 }
    626 static int mode[SOC_MAX_NUM_DEVICES];
    627 static int is_mode_get[SOC_MAX_NUM_DEVICES] = {0};
    628 
    629 /******************************************************************************
    630  * Name: soc_th_latency_get                                                   *
    631  * Description:                                                               *
    632  *     Get the Latency Bypass mode configured on the Switch.                  *
    633  *     TH ASF is an internal client for this API.                             *
    634  * IN params:                                                                 *
    635  *     - Unit                                                                 *
    636  * OUT params:                                                                *
    637  *     - Latency Mode                                                         *
    638  * Returns:                                                                   *
    639  *     - SOC_E_NONE on success                                                *
    640  *     - SOC_E_PARAM on invalid parameter                                     *
    641  */
    642 int
    643 soc_th_latency_get(
    644     int              unit,
    645     OUT int* const   latency)
    646 {
    647     uint16 dev_id = 0;
    648     int is_td3 = 0;
    649 
    650     _SOC_TH_UNIT_VALIDATE(unit);
    651     if (!latency) {
    652         return SOC_E_PARAM;
    653     }
    654 
    655     soc_cm_get_id(unit, &dev_id, NULL);
    656     if (dev_id >= BCM56870_DEVICE_ID &&
    657         dev_id <= BCM56870_DEVICE_ID + 10) {
    658         is_td3 = 1;
    659     }
    660 
    661     if (_soc_th_latency_ctrl[unit] && _soc_th_latency_ctrl[unit]->init) {
    662         *latency = _soc_th_latency_ctrl[unit]->latency;
    663     } else if (!is_mode_get[unit]) {
    664         /* reqd. for feature & mem checks that happen prior to "init soc" */
    665         *latency = soc_property_get(unit, spn_SWITCH_BYPASS_MODE,
    666                                     SOC_SWITCH_BYPASS_MODE_NONE);
    667 
    668         if (is_td3 || !((*latency >= SOC_SWITCH_BYPASS_MODE_NONE) &&
    669             (*latency <= SOC_SWITCH_BYPASS_MODE_EFP))) {
    670             *latency = SOC_SWITCH_BYPASS_MODE_NONE;
    671         }
    672 
    673         mode[unit] = *latency;
    674         is_mode_get[unit] = 1;
    675     } else {
    676         *latency = mode[unit];
    677     }
    678 
    679     return SOC_E_NONE;
    680 }
    681 
    682 /******************************************************************************
    683  * Name: soc_th_latency_bypassed                                              *
    684  * Description:                                                               *
    685  *     Returns if the specified feature is supported/available for the        *
    686  *     current Latency mode configured on the switch                          *
    687  * IN params:                                                                 *
    688  *     - Unit                                                                 *
    689  *     - Feature (soc_feature_*)                                              *
    690  * Returns:                                                                   *
    691  *     - FALSE, if the feature is supported                                   *
    692  *     - TRUE, if the feature is unsupported                                  *
    693  */
    694 int
    695 soc_th_latency_bypassed(
    696     int             unit,
    697     soc_feature_t   feature)
    698 {
    699     int latency;
    700 
    701     _SOC_TH_UNIT_VALIDATE(unit);
    702     _SOC_TH_LATENCY_RT_ENABLE_CHK(unit);
    703 
    704     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency));
    705 
    706     switch(feature) {
    707         /*
    708          * features supported only in NORMAL latency mode and NOT supported in either
    709          * LOW (L2) or BALANCED (L2/L3) Latency modes
    710          */
    711         case soc_feature_alpm:
    712         case soc_feature_ptp:
    713         case soc_feature_visibility:
    714         case soc_feature_robust_hash:
    715         case soc_feature_tunnel_6to4_secure:
    716         case soc_feature_tunnel_any_in_6:
    717         case soc_feature_tunnel_gre:
    718         case soc_feature_tunnel_protocol_match:
    719         case soc_feature_l2gre:
    720         case soc_feature_l2gre_default_tunnel:
    721         case soc_feature_l2_tunnel_transit_payload_tpid_parser:
    722         case soc_feature_mac_based_vlan:
    723         case soc_feature_ip_subnet_based_vlan:
    724         case soc_feature_vfi_zero_invalid:
    725         case soc_feature_hierarchical_ecmp:
    726         case soc_feature_l3_ecmp_2k_groups:
    727         case soc_feature_mpls_lsr_ecmp:
    728         case soc_feature_sflow_counters:
    729         case soc_feature_sflow_flex:
    730         case soc_feature_sflow_ing_mem:
    731         case soc_feature_sflow_ing_mirror:
    732         case soc_feature_fp_nw_tcam_prio_order_war:
    733         case soc_feature_higig2:
    734         case soc_feature_hg_no_speed_change:
    735         case soc_feature_xport_convertible:
    736         /* Please check _bcm_esw_get_fp_mode_global before
    737          * changing soc_feature_field_multi_stage.
    738          */
    739         case soc_feature_field_multi_stage:
    740             return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \
    741                     (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1;
    742 
    743         case soc_feature_alpm_flex_stat:
    744         case soc_feature_alpm_flex_stat_v6_64:
    745              if (soc_property_get(unit, spn_ALPM_FLEX_STAT_SUPPORT, 0)) {
    746                  return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \
    747                          (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1;
    748              } else {
    749                   return TRUE;
    750              }
    751 
    752         case soc_feature_field_compression:
    753              if ((soc_property_get(unit, "fp_compression_enable", 1)) != 0) {
    754                  return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \
    755                          (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1;
    756              } else {
    757                   return TRUE;
    758              }
    759 
    760         case soc_feature_field_exact_match_support:
    761         case soc_feature_uc_flowtracker_learn:
    762         case soc_feature_uc_flowtracker_export:
    763              if ((soc_property_get(unit, "fpem_mem_entries", 0)) != 0) {
    764                  return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \
    765                          (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1;
    766              } else {
    767                   return TRUE;
    768              }
    769 
    770         /*
    771          * features supported in NORMAL and BALANCED Latency modes but
    772          * NOT in LOW (L2) Latency
    773          */
    774         case soc_feature_agm:
    775         case soc_feature_vlan_pri_cfi_action:
    776         case soc_feature_color_prio_map:
    777         case soc_feature_bfd:
    778         case soc_feature_big_icmpv6_ping_check:
    779         case soc_feature_class_based_learning:
    780         case soc_feature_ecmp_random:
    781         case soc_feature_exact_width_match_mode:
    782         case soc_feature_ecmp_resilient_hash_optimized:
    783         case soc_feature_ecmp_round_robin:
    784         case soc_feature_egr_vlan_check:
    785         case soc_feature_field_ingress_cosq_override:
    786         case soc_feature_igmp_mld_support:
    787         case soc_feature_ip_mcast:
    788         case soc_feature_ip_mcast_repl:
    789         case soc_feature_ipmc_remap:
    790         case soc_feature_ipmc_repl_penultimate:
    791         case soc_feature_ipmc_use_configured_dest_mac:
    792         case soc_feature_l3:
    793         case soc_feature_l3_defip_map:
    794         case soc_feature_l3_shared_defip_table:
    795         case soc_feature_l3_dynamic_ecmp_group:
    796         case soc_feature_l3_ecmp_1k_groups:
    797         case soc_feature_l3_extended_host_entry:
    798         case soc_feature_l3_host_ecmp_group:
    799         case soc_feature_l3_iif_profile:
    800         case soc_feature_l3_iif_zero_invalid:
    801         case soc_feature_l3_ingress_interface:
    802         case soc_feature_l3_ip4_options_profile:
    803         case soc_feature_l3_ip6:
    804         case soc_feature_l3_lookup_cmd:
    805         case soc_feature_l3_sgv:
    806         case soc_feature_l3mtu_fail_tocpu:
    807         case soc_feature_l3x_parity:
    808         case soc_feature_lpm_tcam:
    809         case soc_feature_lpm_prefix_length_max_128:
    810         case soc_feature_nat:
    811         case soc_feature_pim_bidir:
    812         case soc_feature_randomized_load_balance:
    813         case soc_feature_repl_l3_intf_use_next_hop:
    814         case soc_feature_round_robin_load_balance:
    815         case soc_feature_split_repl_group_table:
    816         case soc_feature_storm_control:
    817         case soc_feature_udf_hashing:
    818         case soc_feature_udf_multi_pipe_support:
    819         case soc_feature_udf_support:
    820         case soc_feature_shared_trunk_member_table:
    821         case soc_feature_field:
    822         case soc_feature_field_wide:
    823         case soc_feature_field_intraslice_double_wide:
    824         case soc_feature_field_preselector_support:
    825         case soc_feature_field_ingress_triple_wide:
    826         case soc_feature_field_multi_pipe_support:
    827         case soc_feature_memscan_ifp_slice_adjust:
    828         case soc_feature_field_action_l2_change:
    829         case soc_feature_field_action_redirect_ipmc:
    830         case soc_feature_field_virtual_slice_group:
    831         case soc_feature_overlaid_address_class:
    832         case soc_feature_field_action_redirect_ecmp:
    833         case soc_feature_src_port_consistency_check_skip:
    834         case soc_feature_vlan_protocol_pkt_ctrl:
    835         case soc_feature_th_nh_no_overlap_ecmp:
    836         case soc_feature_vlan_egress_membership_l3_only:
    837             return (SOC_SWITCH_BYPASS_MODE_LOW == latency);
    838 
    839         /*
    840          * features supported ONLY in LOW (L2) and BALANCED (L2/L3) Latency
    841          * mode but NOT in NORMAL Latency
    842          */
    843         case soc_feature_no_tunnel:
    844         case soc_feature_fast_init:
    845             return (SOC_SWITCH_BYPASS_MODE_NONE == latency) || (SOC_SWITCH_BYPASS_MODE_EFP == latency);
    846 
    847         /*
    848          * features supported ONLY in LOW (L2) Latency
    849          */
    850         case soc_feature_fastlag:
    851         case soc_feature_fast_egr_vlan_action:
    852             return (SOC_SWITCH_BYPASS_MODE_LOW != latency);
    853 
    854         /*
    855          * features supported only in BALANCED (L2/L3) Latency
    856          */
    857         case soc_feature_egr_vlan_action:
    858         case soc_feature_fast_ecmp:
    859             return (SOC_SWITCH_BYPASS_MODE_BALANCED != latency);
    860 
    861         /*
    862          * legacy features supported in ALL THREE Latency modes
    863          */
    864         case soc_feature_advanced_flex_counter:
    865         case soc_feature_arl_hashed:
    866         case soc_feature_arl_insert_ovr:
    867         case soc_feature_basic_dos_ctrl:
    868         case soc_feature_bigmac_fault_stat:
    869         case soc_feature_counter_parity:
    870         case soc_feature_cpuport_mirror:
    871         case soc_feature_cpuport_stat_dma:
    872         case soc_feature_cpuport_switched:
    873         case soc_feature_dcb_reason_hi:
    874         case soc_feature_dodeca_serdes:
    875         case soc_feature_dual_hash:
    876         case soc_feature_eee:
    877         case soc_feature_ets:
    878         case soc_feature_extended_pci_error:
    879         case soc_feature_fe_maxframe:
    880         case soc_feature_port_flow_hash:
    881         case soc_feature_fifo_dma:
    882         case soc_feature_fifo_dma_active:
    883         case soc_feature_flex_port:
    884         case soc_feature_flexible_dma_steps:
    885         case soc_feature_force_forward:
    886         case soc_feature_generic_counters:
    887         case soc_feature_generic_table_ops:
    888         case soc_feature_gmii_clkout:
    889         case soc_feature_hw_stats_calc:
    890         case soc_feature_l2_bulk_control:
    891         case soc_feature_vlan_queue_map:
    892         case soc_feature_vlan_mc_flood_ctrl:
    893         case soc_feature_aging_extended:
    894         case soc_feature_l2_hashed:
    895         case soc_feature_l2_hw_aging_bug:
    896         case soc_feature_l2_lookup_cmd:
    897         case soc_feature_l2_lookup_retry:
    898         case soc_feature_l2_modfifo:
    899         case soc_feature_l2_overflow:
    900         case soc_feature_l2_pending:
    901         case soc_feature_l2_user_table:
    902         case soc_feature_l2x_parity:
    903         case soc_feature_led_data_offset_a0:
    904         case soc_feature_led_proc:
    905         case soc_feature_logical_port_num:
    906         case soc_feature_lport_tab_profile:
    907         case soc_feature_mbist:
    908         case soc_feature_mdio_enhanced:
    909         case soc_feature_mem_cache:
    910         case soc_feature_mem_push_pop:
    911         case soc_feature_min_cell_per_queue:
    912         case soc_feature_min_resume_limit_1:
    913         case soc_feature_mirror_control_mem:
    914         case soc_feature_mirror_cos:
    915         case soc_feature_mirror_encap_profile:
    916         case soc_feature_mirror_flexible:
    917         case soc_feature_mmu_config_property:
    918         case soc_feature_modmap:
    919         case soc_feature_modport_map_dest_is_port_or_trunk:
    920         case soc_feature_module_loopback:
    921 #ifdef INCLUDE_MSTP
    922         case soc_feature_mstp:
    923 #endif
    924         case soc_feature_new_sbus_format:
    925         case soc_feature_phy_cl45:
    926         case soc_feature_post:
    927         case soc_feature_qos_profile:
    928         case soc_feature_regs_as_mem:
    929         case soc_feature_remap_ut_prio:
    930         case soc_feature_remote_learn_trust:
    931         case soc_feature_rx_timestamp:
    932         case soc_feature_rxdma_cleanup:
    933         case soc_feature_sbusdma:
    934         case soc_feature_schan_hw_timeout:
    935         case soc_feature_schmsg_alias:
    936         case soc_feature_ser_fifo:
    937         case soc_feature_ser_parity:
    938         case soc_feature_sgmii_autoneg:
    939         case soc_feature_src_modid_base_index:
    940         case soc_feature_stat_dma:
    941         case soc_feature_stat_jumbo_adj:
    942         case soc_feature_stat_xgs3:
    943         case soc_feature_stg:
    944         case soc_feature_stg_xgs:
    945         case soc_feature_table_dma:
    946         case soc_feature_table_hi:
    947         case soc_feature_time_support:
    948         case soc_feature_timesync_support:
    949         case soc_feature_trunk_group_overlay:
    950         case soc_feature_trunk_group_size:
    951         case soc_feature_two_ingress_pipes:
    952         case soc_feature_unified_port:
    953         case soc_feature_vlan_ctrl:
    954         case soc_feature_wesp:
    955         case soc_feature_xgxs_power:
    956         case soc_feature_xgxs_v7:
    957         case soc_feature_xlmac:
    958         case soc_feature_xy_tcam:
    959         case soc_feature_xy_tcam_direct:
    960         case soc_feature_shared_hash_mem:
    961         case soc_feature_src_modid_blk:
    962         case soc_feature_src_modid_blk_profile:
    963         case soc_feature_egr_ipmc_mem_field_l3_payload_valid:
    964         case soc_feature_tslam_dma:
    965             return FALSE;
    966 
    967         /*
    968          * legacy features supported ONLY in NORMAL Latency mode
    969          */
    970         default:
    971             return (((SOC_SWITCH_BYPASS_MODE_NONE == latency) || (SOC_SWITCH_BYPASS_MODE_EFP == latency))
    972             ? (!soc_features_bcm56850_a0(unit, feature)) : TRUE);
    973     }
    974 
    975 }
    976 
    977 /******************************************************************************
    978  * Name: soc_th2_latency_bypassed                                              *
    979  * Description:                                                               *
    980  *     Returns if the specified feature is supported/available for the        *
    981  *     current Latency mode configured on the switch                          *
    982  * IN params:                                                                 *
    983  *     - Unit                                                                 *
    984  *     - Feature (soc_feature_*)                                              *
    985  * Returns:                                                                   *
    986  *     - FALSE, if the feature is supported                                   *
    987  *     - TRUE, if the feature is unsupported                                  *
    988  */
    989 int
    990 soc_th2_latency_bypassed(
    991     int             unit,
    992     soc_feature_t   feature)
    993 {
    994     int latency;
    995 
    996     _SOC_TH_UNIT_VALIDATE(unit);
    997     _SOC_TH_LATENCY_RT_ENABLE_CHK(unit);
    998 
    999     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency));
   1000 
   1001     switch(feature) {
   1002         /*
   1003          * features supported only in NORMAL latency mode and NOT supported in either
   1004          * LOW (L2) or BALANCED (L2/L3) Latency modes
   1005          */
   1006         case soc_feature_ecmp_dlb:
   1007         case soc_feature_ecmp_dlb_optimized:
   1008         case soc_feature_dgm:
   1009         case soc_feature_ecn_wred:
   1010         case soc_feature_mpls_ecn:
   1011         case soc_feature_flex_hashing:
   1012         case soc_feature_mpls_frr_lookup:    
   1013             return (SOC_SWITCH_BYPASS_MODE_NONE != latency);
   1014 
   1015         /*
   1016          * features supported in NORMAL and BALANCED Latency modes but
   1017          * NOT in LOW (L2) Latency
   1018          */
   1019         case soc_feature_lag_dlb:
   1020         case soc_feature_hg_dlb:
   1021         case soc_feature_hgt_lag_dlb_optimized:
   1022             return (SOC_SWITCH_BYPASS_MODE_LOW == latency);
   1023 
   1024         /*
   1025          * features supported ONLY in LOW (L2) and BALANCED (L2/L3) Latency
   1026          * mode but NOT in NORMAL Latency
   1027          */
   1028 
   1029         /*
   1030          * features supported ONLY in LOW (L2) Latency
   1031          */
   1032 
   1033         /*
   1034          * features supported only in BALANCED (L2/L3) Latency
   1035          */
   1036 
   1037         /*
   1038          * legacy features supported in ALL THREE Latency modes
   1039          */
   1040 
   1041         /*
   1042          * legacy features untouched
   1043          */
   1044         default:
   1045             return FALSE;
   1046     }
   1047 
   1048 }
   1049 
   1050 /******************************************************************************
   1051  * Name: soc_th_latency_mem_avail                                             *
   1052  * Description:                                                               *
   1053  *     Returns if the specified memory / table is available for the           *
   1054  *     current Latency mode configured on the switch                          *
   1055  * IN params:                                                                 *
   1056  *     - Unit                                                                 *
   1057  *     - Memory/Table                                                         *
   1058  * Returns:                                                                   *
   1059  *     - TRUE, if the memory is available                                     *
   1060  *     - FALSE, if the memory is unavailable                                  *
   1061  */
   1062 int
   1063 soc_th_latency_mem_avail(
   1064     int         unit,
   1065     soc_mem_t   mem,
   1066     int         latency)
   1067 {
   1068     return _soc_th_latency_resource_avail(unit, _SOC_TH_MEM, mem, latency);
   1069 }
   1070 
   1071 /******************************************************************************
   1072  * Name: soc_th_latency_reg_avail                                             *
   1073  * Description:                                                               *
   1074  *     Returns if the specified register is available for the                 *
   1075  *     current Latency mode configured on the switch                          *
   1076  * IN params:                                                                 *
   1077  *     - Unit                                                                 *
   1078  *     - Register                                                             *
   1079  * Returns:                                                                   *
   1080  *     - TRUE, if the register is available                                   *
   1081  *     - FALSE, if the register is unavailable                                *
   1082  */
   1083 int
   1084 soc_th_latency_reg_avail(
   1085     int         unit,
   1086     soc_reg_t   reg,
   1087     int         latency)
   1088 {
   1089     return _soc_th_latency_resource_avail(unit, _SOC_TH_REG, reg, latency);
   1090 }
   1091 
   1092 /******************************************************************************
   1093  * Name: soc_th_latency_init                                                  *
   1094  * Description:                                                               *
   1095  *     Configure the Switch and the SDK for the Latency Bypass mode           *
   1096  *     specified in config.bcm                                                *
   1097  * IN params:                                                                 *
   1098  *     - Unit                                                                 *
   1099  * Returns:                                                                   *
   1100  *     - SOC_E_NONE on success                                                *
   1101  *     - SOC_E_* on internal errors                                           *
   1102  */
   1103 int
   1104 soc_th_latency_init(int unit)
   1105 {
   1106     int latency;
   1107     uint32 rval = 0;
   1108     _SOC_TH_UNIT_VALIDATE(unit);
   1109     _SOC_TH_LATENCY_RT_ENABLE_CHK(unit);
   1110 
   1111 #ifdef BCM_WARM_BOOT_SUPPORT
   1112     if (SOC_WARM_BOOT(unit)) {
   1113         /* WB recovery happens in _bcm_esw_port_wb_recover context */
   1114         return BCM_E_NONE;
   1115     }
   1116 #endif /* BCM_WARM_BOOT_SUPPORT */
   1117 
   1118     if (!(_soc_th_latency_ctrl[unit] =
   1119           sal_alloc(sizeof(_soc_th_latency_ctrl_t), "TH Latency Ctrl Area"))) {
   1120         return SOC_E_MEMORY;
   1121     }
   1122 
   1123     latency = soc_property_get(unit, spn_SWITCH_BYPASS_MODE,
   1124                                SOC_SWITCH_BYPASS_MODE_NONE);
   1125     _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_NONE);
   1126 
   1127     /* Set MMU in reset */
   1128     if ((latency == SOC_SWITCH_BYPASS_MODE_LOW) ||
   1129         (latency == SOC_SWITCH_BYPASS_MODE_BALANCED)) {
   1130         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1131                     (BSL_META_U(unit,
   1132                                 "Unit:%d Latency mode update. Mode %d. "
   1133                                 "Initiate MMU reset\n"),
   1134                                 unit, latency));
   1135         SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval));
   1136         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0);
   1137         SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval));
   1138     }
   1139     if (SOC_SWITCH_BYPASS_MODE_EFP == latency) {
   1140         /* config EFP latency settings */
   1141         SOC_IF_ERROR_RETURN(_soc_th_efp_latency_config(unit, latency));
   1142     } else { 
   1143         /* config ingress latency settings */
   1144         SOC_IF_ERROR_RETURN(_soc_th_igr_latency_config(unit, latency));
   1145         /* config egress latency settings */
   1146         SOC_IF_ERROR_RETURN(_soc_th_egr_latency_config(unit, latency));
   1147     }
   1148 
   1149     _soc_th_latency_ctrl[unit]->init = 1;
   1150     _soc_th_latency_ctrl[unit]->latency = latency;
   1151     SOC_SWITCH_BYPASS_MODE(unit) = latency;
   1152 
   1153     /* apply reg filter for the current latency config */
   1154     SOC_IF_ERROR_RETURN(_soc_th_latency_reg_filter(unit));
   1155     /* apply memory filter for the current latency config */
   1156     SOC_IF_ERROR_RETURN(_soc_th_latency_mem_filter(unit));
   1157 
   1158     /* Bring MMU out of reset */
   1159     if ((latency == SOC_SWITCH_BYPASS_MODE_LOW) ||
   1160         (latency == SOC_SWITCH_BYPASS_MODE_BALANCED)) {
   1161         SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval));
   1162         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1);
   1163         SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval));
   1164         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1165                     (BSL_META_U(unit,
   1166                                 "Unit:%d Latency update done. MMU out of reset.\n"),
   1167                                 unit));
   1168     }
   1169 
   1170     sal_memcpy(&_soc_th_latency_ctrl[unit]->tbl_cfg, &soc_th_tbl_cfg[unit],
   1171                sizeof(soc_th_latency_table_cfg_t));
   1172 
   1173     LOG_DEBUG(BSL_LS_SOC_INIT,
   1174             (BSL_META_U(unit, "*** unit %d: configured for %s latency\n"),
   1175              unit, lstr[latency]));
   1176 
   1177     return SOC_E_NONE;
   1178 }
   1179 
   1180 int
   1181 soc_th_latency_deinit(int unit)
   1182 {
   1183     if (_soc_th_latency_ctrl[unit]) {
   1184         sal_free(_soc_th_latency_ctrl[unit]);
   1185         _soc_th_latency_ctrl[unit] = NULL;
   1186     }
   1187 
   1188     return SOC_E_NONE;
   1189 }
   1190 
   1191 
   1192 /***********************************
   1193  * Latency Bypass Warmboot Support *
   1194  */
   1195 #ifdef BCM_WARM_BOOT_SUPPORT
   1196 
   1197 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
   1198 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
   1199 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
   1200 #define BCM_WB_VERSION_1_3                SOC_SCACHE_VERSION(1,3)
   1201 #define BCM_WB_VERSION_1_4                SOC_SCACHE_VERSION(1,4)
   1202 #define BCM_WB_VERSION_1_5                SOC_SCACHE_VERSION(1,5)
   1203 #define BCM_WB_VERSION_1_6                SOC_SCACHE_VERSION(1,6)
   1204 #define BCM_WB_VERSION_1_7                SOC_SCACHE_VERSION(1,7)
   1205 #define BCM_WB_VERSION_1_8                SOC_SCACHE_VERSION(1,8)
   1206 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_8
   1207 
   1208 /* reconfigure latency sw states during wb recovery      */
   1209 /* level 0 - reinitializes latency wb control structure  */
   1210 /* level 1 - reinitializes reg and memory filters only   */
   1211 int
   1212 soc_th_latency_wb_reinit(int unit, int level)
   1213 {
   1214     int latency_wb, latency_cfg;
   1215 
   1216     if (!SOC_WARM_BOOT(unit)) {
   1217         return SOC_E_INTERNAL;
   1218     }
   1219 
   1220     /* config.bcm's version of latency */
   1221     latency_cfg = soc_property_get(unit, spn_SWITCH_BYPASS_MODE,
   1222                                    SOC_SWITCH_BYPASS_MODE_NONE);
   1223 
   1224     if (0 == level) {
   1225         _SOC_TH_UNIT_VALIDATE(unit);
   1226         _SOC_TH_LATENCY_RT_ENABLE_CHK(unit);
   1227 
   1228         if (!_soc_th_latency_ctrl[unit]) {
   1229             return SOC_E_INTERNAL;
   1230         }
   1231 
   1232         /* rashomon */
   1233         if (1 == _soc_th_latency_ctrl[unit]->init) {
   1234             /* wb's version of latency */
   1235             latency_wb = _soc_th_latency_ctrl[unit]->latency;
   1236         } else {
   1237             return SOC_E_INTERNAL;
   1238         }
   1239 
   1240         /* ratify the sanity of wb recovery */
   1241         if (latency_cfg == latency_wb) {
   1242             _soc_th_latency_ctrl[unit]->latency = latency_cfg;
   1243         } else {
   1244             return SOC_E_INTERNAL;
   1245         }
   1246 
   1247         /* reconfiguration section */
   1248         SOC_SWITCH_BYPASS_MODE(unit) = _soc_th_latency_ctrl[unit]->latency;
   1249     }    else {
   1250         if (!latency_cfg) {
   1251             return SOC_E_NONE;
   1252         }
   1253         /* reapply reg filter */
   1254         SOC_IF_ERROR_RETURN(_soc_th_latency_reg_filter(unit));
   1255         /* reapply memory filter */
   1256         SOC_IF_ERROR_RETURN(_soc_th_latency_mem_filter(unit));
   1257     }
   1258 
   1259     return SOC_E_NONE; /* back to normalcy */
   1260 }
   1261 
   1262 int
   1263 soc_th_latency_wb_memsz_get(
   1264     int               unit,
   1265     OUT uint32* const mem_sz,
   1266     uint16            scache_ver)
   1267 {
   1268     _SOC_TH_UNIT_VALIDATE(unit);
   1269     if (!mem_sz) {
   1270         return SOC_E_PARAM;
   1271     }
   1272     *mem_sz = 0;
   1273 
   1274     if (!SOC_WARM_BOOT(unit)) {
   1275         if (!_soc_th_latency_ctrl[unit] || !_soc_th_latency_ctrl[unit]->init) {
   1276             return SOC_E_NONE;
   1277         }
   1278     }
   1279 
   1280     *mem_sz = sizeof(_soc_th_latency_wb_t);
   1281 
   1282     /* adjust for lower versions */
   1283     if (scache_ver < BCM_WB_VERSION_1_8) {
   1284         *mem_sz -= sizeof(soc_th_latency_table_cfg_t);
   1285     }
   1286 
   1287     return SOC_E_NONE;
   1288 }
   1289 
   1290 int
   1291 soc_th_latency_wb_sync(
   1292     int                 unit,
   1293     IN_OUT uint8* const wb_data)
   1294 {
   1295     _soc_th_latency_wb_t *wbd;
   1296 
   1297     _SOC_TH_UNIT_VALIDATE(unit);
   1298     if (!_soc_th_latency_ctrl[unit] || !_soc_th_latency_ctrl[unit]->init) {
   1299         return SOC_E_NONE;
   1300     }
   1301     if (!wb_data) {
   1302         return SOC_E_PARAM;
   1303     }
   1304 
   1305     wbd = (_soc_th_latency_wb_t *) wb_data;
   1306     wbd->unit = unit;
   1307     sal_memcpy(&wbd->latency_ctrl, _soc_th_latency_ctrl[unit],
   1308                sizeof(_soc_th_latency_ctrl_t));
   1309 
   1310     return SOC_E_NONE;
   1311 }
   1312 
   1313 int
   1314 soc_th_latency_wb_recover(
   1315     int          unit,
   1316     uint8* const wb_data,
   1317     uint16       scache_ver)
   1318 {
   1319     _soc_th_latency_wb_t *wbd;
   1320     int adj = 0; /*scache ver adjustment */
   1321 
   1322     _SOC_TH_UNIT_VALIDATE(unit);
   1323     if (!SOC_WARM_BOOT(unit)) {
   1324         return SOC_E_INTERNAL;
   1325     }
   1326     if (!wb_data) {
   1327         return SOC_E_PARAM;
   1328     }
   1329 
   1330     wbd = (_soc_th_latency_wb_t *) wb_data;
   1331     if (wbd->unit == unit) {
   1332         if (!(_soc_th_latency_ctrl[unit] =
   1333                    sal_alloc(sizeof(_soc_th_latency_ctrl_t),
   1334                              "TH Latency Bypass Ctrl Area"))) {
   1335             return SOC_E_MEMORY;
   1336         }
   1337 
   1338         /* adjust for lower versions */
   1339         if (scache_ver < BCM_WB_VERSION_1_8) {
   1340             adj = sizeof(soc_th_latency_table_cfg_t);
   1341             /* backfill tbl_cfg from TH driver's global bookkeeping */
   1342             sal_memcpy(&_soc_th_latency_ctrl[unit]->tbl_cfg, &soc_th_tbl_cfg[unit],
   1343                        sizeof(soc_th_latency_table_cfg_t));
   1344         }
   1345 
   1346         sal_memcpy(_soc_th_latency_ctrl[unit], &wbd->latency_ctrl,
   1347                    (sizeof(_soc_th_latency_ctrl_t) - adj));
   1348     }
   1349 
   1350     SOC_IF_ERROR_RETURN(soc_th_latency_wb_reinit(unit, 0));
   1351 
   1352     LOG_CLI((BSL_META_U(unit, "*** unit %d: Latency subsystem warmbooted: "
   1353                         "configured for %s latency\n"), unit,
   1354                         lstr[_soc_th_latency_ctrl[unit]->latency]));
   1355 
   1356     return SOC_E_NONE;
   1357 }
   1358 #endif /* BCM_WARM_BOOT_SUPPORT */
   1359 
   1360 /********************************
   1361  * Latency Bypass Debug Support *
   1362  */
   1363 int
   1364 soc_th_latency_show(int unit)
   1365 {
   1366     int mode;
   1367     char *mode_str[3] = {
   1368         "Normal latency (full features)",
   1369         "Balanced (L2/L3) Latency",
   1370         "Low (L2) Latency"
   1371     };
   1372 
   1373     _SOC_TH_UNIT_VALIDATE(unit);
   1374     _SOC_TH_LATENCY_INIT_VALIDATE(unit, SOC_E_INTERNAL);
   1375 
   1376     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &mode));
   1377     LOG_CLI(("switch latency mode : %s\n", mode_str[mode]));
   1378 
   1379     if (soc_feature(unit, soc_feature_fastlag)) {
   1380         LOG_CLI(("Trunking mode : Fast LAG\n"));
   1381     }
   1382     if (soc_feature(unit, soc_feature_fast_ecmp)) {
   1383         LOG_CLI(("ECMP mode     : Fast ECMP\n"));
   1384     }
   1385 
   1386     return SOC_E_NONE;
   1387 }
   1388 
   1389 int
   1390 soc_th_latency_diag(int unit)
   1391 {
   1392     int mode;
   1393     char *mode_str[3] = {
   1394         "Normal latency (full features)",
   1395         "Balanced (L2/L3) Latency",
   1396         "Low (L2) Latency"
   1397     };
   1398     uint32 rval;
   1399     uint8 ipars, ivxlt, ivp, ifwd, irsel1, ifp, irsel2, isw2;
   1400     uint8 ecmp;
   1401 
   1402     _SOC_TH_UNIT_VALIDATE(unit);
   1403     _SOC_TH_LATENCY_INIT_VALIDATE(unit, SOC_E_INTERNAL);
   1404 
   1405     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &mode));
   1406 
   1407     SOC_IF_ERROR_RETURN(READ_ING_LATENCY_CONTROLr(unit, &rval));
   1408     ipars  = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1409                                IPARS_LATENCY_MODEf);
   1410     ivxlt  = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1411                                IVXLT_BYPASSf);
   1412     ivp    = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1413                                IVP_BYPASSf);
   1414     ifwd   = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1415                                IFWD_LATENCY_MODEf);
   1416     irsel1 = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1417                                IRSEL1_LATENCY_MODEf);
   1418     ifp    = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1419                                IFP_BYPASSf);
   1420     irsel2 = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1421                                IRSEL2_LATENCY_MODEf);
   1422     isw2   = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval,
   1423                                ISW2_LATENCY_MODEf);
   1424 
   1425     SOC_IF_ERROR_RETURN(READ_ECMP_CONFIGr(unit, &rval));
   1426     ecmp  = soc_reg_field_get(unit, ECMP_CONFIGr, rval, ECMP_MODEf);
   1427 
   1428     LOG_CLI(("switch latency mode : %s\n", mode_str[mode]));
   1429 
   1430     if (soc_feature(unit, soc_feature_fastlag)) {
   1431         LOG_CLI(("Trunking mode : Fast LAG\n"));
   1432     }
   1433     if (soc_feature(unit, soc_feature_fast_ecmp)) {
   1434         LOG_CLI(("ECMP mode     : Fast ECMP\n"));
   1435     }
   1436 
   1437     LOG_CLI(("Ingress Latency Configurations:\n"));
   1438     LOG_CLI(("ipars  ivxlt  ivp  ifwd  irsel1  ifp  irsel2  isw2  ecmp\n"));
   1439     LOG_CLI(("%5d  %5d  %3d  %4d  %6d  %3d  %6d  %4d  %4d\n",
   1440              ipars, ivxlt, ivp, ifwd, irsel1, ifp, irsel2, isw2, ecmp));
   1441 
   1442     LOG_CLI(("Egress Latency Configurations:\n"));
   1443     LOG_CLI(("el3  evlan  efp\n"));
   1444     /*
   1445      * due to an RTL issue which left EGR_LATENCY_MODE as NOTEST, we don't
   1446      * have any option but to produce the sw state in lieu of the register values
   1447      */
   1448     LOG_CLI(("%3d  %5d  %3d\n", _soc_th_latency_cfg_tbl[mode].egr.el3,
   1449              _soc_th_latency_cfg_tbl[mode].egr.evlan,
   1450              _soc_th_latency_cfg_tbl[mode].egr.efp));
   1451 
   1452     /* table configurations */
   1453     LOG_CLI(("l2_entries:%d\n",
   1454              _soc_th_latency_ctrl[unit]->tbl_cfg.l2_entries));
   1455     LOG_CLI(("fixed_l2_entries:%d\n",
   1456              _soc_th_latency_ctrl[unit]->tbl_cfg.fixed_l2_entries));
   1457     LOG_CLI(("shared_l2_banks:%d\n",
   1458              _soc_th_latency_ctrl[unit]->tbl_cfg.shared_l2_banks));
   1459     LOG_CLI(("l3_entries:%d\n",
   1460              _soc_th_latency_ctrl[unit]->tbl_cfg.l3_entries));
   1461     LOG_CLI(("fixed_l3_entries:%d\n",
   1462              _soc_th_latency_ctrl[unit]->tbl_cfg.fixed_l3_entries));
   1463     LOG_CLI(("shared_l3_banks:%d\n",
   1464              _soc_th_latency_ctrl[unit]->tbl_cfg.shared_l3_banks));
   1465     LOG_CLI(("fpem_entries:%d\n",
   1466              _soc_th_latency_ctrl[unit]->tbl_cfg.fpem_entries));
   1467     LOG_CLI(("shared_fpem_banks:%d\n",
   1468              _soc_th_latency_ctrl[unit]->tbl_cfg.shared_fpem_banks));
   1469     LOG_CLI(("alpm_enable:%d\n",
   1470              _soc_th_latency_ctrl[unit]->tbl_cfg.alpm_enable));
   1471     LOG_CLI(("max_tcams:%d\n",
   1472              _soc_th_latency_ctrl[unit]->tbl_cfg.max_tcams));
   1473     LOG_CLI(("tcam_depth:%d\n",
   1474              _soc_th_latency_ctrl[unit]->tbl_cfg.tcam_depth));
   1475 
   1476     return SOC_E_NONE;
   1477 }
   1478 
   1479 #endif /* BCM_TOMAHAWK_SUPPORT */
   1480