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

trident2.c (823646B)


      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:        trident2.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 #include <shared/bsl.h>
     12 #include <sal/core/boot.h>
     13 #include <soc/trident2.h>
     14 #include <soc/bradley.h>
     15 #include <soc/drv.h>
     16 #include <soc/error.h>
     17 #include <soc/debug.h>
     18 #include <soc/mem.h>
     19 #include <soc/mspi.h>
     20 #include <soc/l2x.h>
     21 #include <soc/soc_ser_log.h>
     22 #include <soc/tdm/core/tdm_top.h>
     23 
     24 #if defined (BCM_TRIDENT2_SUPPORT)
     25 
     26 #include <soc/td2_td2p.h>
     27 #include <soc/scache.h>
     28 
     29 #ifdef ALPM_ENABLE
     30 #include <soc/lpm.h>
     31 #include <soc/alpm.h>
     32 #include <soc/esw/alpm_int.h>
     33 #endif /* ALPM_ENABLE */
     34 
     35 #include <soc/mmu_config.h>
     36 #include <soc/trident2.h>
     37 #include <soc/post.h>
     38 
     39 #define TDM_CHIP_EXEC__IARB_TD2 11
     40 #define TDM_CHIP_EXEC__IARB_TD2P 12
     41 #include <soc/esw/portctrl.h>
     42 
     43 #ifdef PORTMOD_SUPPORT
     44 #include <soc/portmod/portmod.h>
     45 #endif /* PORTMOD_SUPPORT */
     46 
     47 #define TRIDENT2_PHY_PORT_MAX 128
     48 
     49 /* Globally stored reserved buffer values
     50  * for egress rsvd & asf rsvd */
     51 static int asf_rsvd_g = 0;
     52 static int egr_rsvd_g = 0;
     53 
     54 typedef enum {
     55     _SOC_PARITY_TYPE_NONE,
     56     _SOC_PARITY_TYPE_GENERIC,
     57     _SOC_PARITY_TYPE_PARITY,
     58     _SOC_PARITY_TYPE_ECC,
     59     _SOC_PARITY_TYPE_CPORT,
     60     _SOC_PARITY_TYPE_MMU_SER,
     61     _SOC_PARITY_TYPE_START_ERR,
     62     _SOC_PARITY_TYPE_SER,
     63     _SOC_PARITY_TYPE_BST,
     64     _SOC_PARITY_TYPE_CFAP_MEM_FAIL
     65 } _soc_td2_ser_info_type_t;
     66 
     67 typedef enum {
     68     _SOC_SER_SOURCE_TYPE_MEM,
     69     _SOC_SER_SOURCE_TYPE_REG,
     70     _SOC_SER_SOURCE_TYPE_BUS,
     71     _SOC_SER_SOURCE_TYPE_BUF,
     72     _SOC_SER_SOURCE_TYPE_OTHER
     73 } _soc_td2_ser_source_type_t;
     74 typedef struct _soc_td2_fifo_ser_info_s {
     75     soc_reg_t                   enable_reg;
     76     soc_field_t                 enable_field;
     77     _soc_td2_ser_source_type_t  type; /* 0: mem, 1: reg, 2: bus ,3 : internal buffer */
     78     soc_mem_t                   mem;
     79     soc_reg_t                   reg;
     80     char                        *name_str; /* Used when mem == INVALIDm or reg == INVALIDr or type == bus
     81                                               (either not accessible or multiple) */
     82 } _soc_td2_fifo_ser_info_t;
     83 
     84 typedef struct _soc_td2_ser_block_info_s {
     85     soc_block_t              blocktype;
     86     soc_reg_t                fifo_reset_reg;
     87     _soc_td2_fifo_ser_info_t *info;
     88 } _soc_td2_ser_block_info_t;
     89 
     90 typedef struct _soc_td2_ser_reg_s {
     91     soc_reg_t reg;
     92     char      *mem_str;
     93 } _soc_td2_ser_reg_t;
     94 
     95 typedef struct _soc_td2_ser_info_s {
     96     _soc_td2_ser_info_type_t   type;
     97     struct _soc_td2_ser_info_s *info;
     98     int                        id;
     99     soc_field_t                group_reg_enable_field;
    100     soc_field_t                group_reg_status_field;
    101     soc_mem_t                  mem;
    102     char                       *mem_str;
    103     soc_reg_t                  enable_reg;
    104     soc_field_t                enable_field;
    105     soc_reg_t                  intr_status_reg;
    106     _soc_td2_ser_reg_t         *intr_status_reg_list;
    107 } _soc_td2_ser_info_t;
    108 
    109 typedef struct _soc_td2_ser_route_block_s {
    110     uint32              cmic_bit;
    111     soc_block_t         blocktype;
    112     int                 pipe;
    113     soc_reg_t           enable_reg;
    114     soc_reg_t           status_reg;
    115     soc_field_t         enable_field;
    116     _soc_td2_ser_info_t *info;
    117     uint8               id;
    118 } _soc_td2_ser_route_block_t;
    119 
    120 typedef struct _soc_td2_mmu_traffic_ctrl_s {
    121     uint8   thdo_drop_bmp[_SOC_TD2_MAX_PORT];
    122 } _soc_td2_mmu_traffic_ctrl_t;
    123 
    124 
    125 #define   MAC_ENABLE_SET_CTRL          (1 << 0)
    126 #define   MMU_TRAFFIC_EN_CTRL          (1 << 1)
    127 #define   COSQ_SCHED_SET_CTRL          (1 << 2)
    128 static    _soc_td2_mmu_traffic_ctrl_t
    129               *_soc_td2_mmu_traffic_ctrl[SOC_MAX_NUM_DEVICES];
    130 static    sal_mutex_t _fwd_ctrl_lock[SOC_MAX_NUM_DEVICES];
    131 #define   FWD_CTRL_LOCK(unit) \
    132           sal_mutex_take(_fwd_ctrl_lock[unit], sal_mutex_FOREVER)
    133 #define   FWD_CTRL_UNLOCK(unit) \
    134           sal_mutex_give(_fwd_ctrl_lock[unit])
    135 
    136 /* Forward declarations */
    137 extern int
    138 tdm_td2_set_iarb_tdm_table(int core_bw, int is_x_ovs, int is_y_ovs, int mgm4x1,
    139 int mgm4x2p5, int mgm1x10, int *iarb_tdm_wrap_ptr_x, int *iarb_tdm_wrap_ptr_y,
    140 int *iarb_tdm_tbl_x, int *iarb_tdm_tbl_y);
    141 
    142 enum tdm_td2_port_speed {TDM_TD2_SPEED_0=0, TDM_TD2_SPEED_10M=10, TDM_TD2_SPEED_20M=20,
    143 TDM_TD2_SPEED_25M=25, TDM_TD2_SPEED_33M=33, TDM_TD2_SPEED_40M=40, TDM_TD2_SPEED_50M=50,
    144 TDM_TD2_SPEED_100M=100, TDM_TD2_SPEED_100M_FX=101, TDM_TD2_SPEED_120M=120,TDM_TD2_SPEED_400M=400,
    145 TDM_TD2_SPEED_1G=1000, TDM_TD2_SPEED_1G_FX=1001, TDM_TD2_SPEED_1p2G=1200, TDM_TD2_SPEED_2G=2000,
    146 TDM_TD2_SPEED_2p5G=2500, TDM_TD2_SPEED_4G=4000, TDM_TD2_SPEED_5G=5000, TDM_TD2_SPEED_7p5G=7500,
    147 TDM_TD2_SPEED_10G=10000, TDM_TD2_SPEED_10G_DUAL=10001, TDM_TD2_SPEED_10G_XAUI=10002,
    148 TDM_TD2_SPEED_12G=12000, TDM_TD2_SPEED_12p5G=12500, TDM_TD2_SPEED_13G=13000, TDM_TD2_SPEED_15G=15000,
    149 TDM_TD2_SPEED_16G=16000, TDM_TD2_SPEED_20G=20000, TDM_TD2_SPEED_21G=21000, TDM_TD2_SPEED_21G_DUAL=21010,
    150 TDM_TD2_SPEED_24G=24000, TDM_TD2_SPEED_25G=25000, TDM_TD2_SPEED_30G=30000, TDM_TD2_SPEED_40G=40000,
    151 TDM_TD2_SPEED_42G=40005, TDM_TD2_SPEED_50G=50000,TDM_TD2_SPEED_75G=75000, TDM_TD2_SPEED_82G=82000,
    152 TDM_TD2_SPEED_100G=100000, TDM_TD2_SPEED_120G=120000, TDM_TD2_SPEED_126G=126000};
    153 
    154 #define TDM_TD2_NUM_EXT_PORTS 130
    155 
    156 extern int
    157 _soc_td2_set_tdm_tbl(enum tdm_td2_port_speed speed[TDM_TD2_NUM_EXT_PORTS],
    158 int tdm_bw, int pgw_tdm_tbl_x0[32], int ovs_tdm_tbl_x0[32], int ovs_spacing_x0[32],
    159 int pgw_tdm_tbl_x1[32], int ovs_tdm_tbl_x1[32], int ovs_spacing_x1[32],
    160 int pgw_tdm_tbl_y0[32], int ovs_tdm_tbl_y0[32], int ovs_spacing_y0[32],
    161 int pgw_tdm_tbl_y1[32], int ovs_tdm_tbl_y1[32], int ovs_spacing_y1[32],
    162 int mmu_tdm_tbl_x[256], int mmu_tdm_ovs_x_1[16], int mmu_tdm_ovs_x_2[16],
    163 int mmu_tdm_ovs_x_3[16], int mmu_tdm_ovs_x_4[16], int mmu_tdm_tbl_y[256],
    164 int mmu_tdm_ovs_y_1[16], int mmu_tdm_ovs_y_2[16], int mmu_tdm_ovs_y_3[16],
    165 int mmu_tdm_ovs_y_4[16], int port_state_map[128], int iarb_tdm_tbl_x[512],
    166 int iarb_tdm_tbl_y[512], int ancillary_bandwidth_mode);
    167 
    168 STATIC int
    169 _soc_trident2_mdio_reg_read(int unit, uint32 phy_addr,
    170                             uint32 phy_reg, uint32 *phy_data);
    171 STATIC int
    172 _soc_trident2_mdio_reg_write(int unit, uint32 phy_addr,
    173                              uint32 phy_reg, uint32 phy_data);
    174 
    175 STATIC void
    176 _soc_trident2_ser_control_reg_get(int unit, void *fifo_ser_list,
    177                                   soc_mem_t   mem,
    178                                   soc_reg_t   *ser_control_reg,
    179                                   soc_field_t *ser_enable_field);
    180 
    181 STATIC int
    182 _soc_trident2_ser_log_update(int unit, _soc_ser_correct_info_t *si);
    183 
    184 STATIC soc_error_t
    185 _soc_trident2_mmu_ecc_mem_ser_info_get(int unit,
    186                                        soc_mem_t mem,
    187                                        void** ser_mem_info);
    188 
    189 STATIC soc_error_t
    190 _soc_trident2_ser_mem_info_get(int unit, soc_mem_t mem,
    191                                void** ser_mem_info);
    192 
    193 STATIC
    194 _soc_td2_fifo_ser_info_t _soc_td2_ep_ser_info[] = {
    195     { EFP_PARITY_CONTROLr, EFP_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "EFP BUS" },
    196     { EFP_PARITY_CONTROLr, PW_INIT_COUNTERS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_PW_INIT_COUNTERSm, INVALIDr, "" },
    197     { EFP_PARITY_CONTROLr, METER_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EFP_METER_TABLEm, INVALIDr, "" },
    198     { EFP_PARITY_CONTROLr, POLICY_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EFP_POLICY_TABLEm, INVALIDr, "" },
    199     { EGR_EDATABUF_PARITY_CONTROLr, XLP15_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP15 CELL DATABUF" },
    200     { EGR_EDATABUF_PARITY_CONTROLr, XLP14_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP14 CELL DATABUF" },
    201     { EGR_EDATABUF_PARITY_CONTROLr, XLP13_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP13 CELL DATABUF" },
    202     { EGR_EDATABUF_PARITY_CONTROLr, XLP12_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP12 CELL DATABUF" },
    203     { EGR_EDATABUF_PARITY_CONTROLr, XLP11_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP11 CELL DATABUF" },
    204     { EGR_EDATABUF_PARITY_CONTROLr, XLP10_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP10 CELL DATABUF" },
    205     { EGR_EDATABUF_PARITY_CONTROLr, XLP9_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP9 CELL DATABUF" },
    206     { EGR_EDATABUF_PARITY_CONTROLr, XLP8_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP8 CELL DATABUF" },
    207     { EGR_EDATABUF_PARITY_CONTROLr, XLP7_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP7 CELL DATABUF" },
    208     { EGR_EDATABUF_PARITY_CONTROLr, XLP6_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP6 CELL DATABUF" },
    209     { EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP5 CELL DATABUF" },
    210     { EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP4 CELL DATABUF" },
    211     { EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP3 CELL DATABUF" },
    212     { EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP2 CELL DATABUF" },
    213     { EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP1 CELL DATABUF" },
    214     { EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP0 CELL DATABUF" },
    215     { EGR_EDATABUF_PARITY_CONTROLr, CLP3_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP3 CELL DATABUF" },
    216     { EGR_EDATABUF_PARITY_CONTROLr, CLP2_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP2 CELL DATABUF" },
    217     { EGR_EDATABUF_PARITY_CONTROLr, CLP1_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP1 CELL DATABUF" },
    218     { EGR_EDATABUF_PARITY_CONTROLr, CLP0_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP0 CELL DATABUF" },
    219     /*{ EGR_EDATABUF_PARITY_CONTROLr, XLP_RESI_BUFFER_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, INVALIDm, INVALIDr, "EP RESIDUE BUF" },*/
    220     { EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "EP CM" },
    221     { EGR_EDATABUF_PARITY_CONTROLr, FCOE_DELIMITER_ERR_CNTR_PAR_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_FCOE_DELIMITER_ERROR_FRAMESr, "" },
    222     { EGR_EDATABUF_PARITY_CONTROLr, FCOE_INVALID_CNTR_PAR_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_FCOE_INVALID_CRC_FRAMESr, "" },
    223     { EGR_EDATABUF_PARITY_CONTROLr, PERQ_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_PERQ_XMT_COUNTERSm, INVALIDr, "" },
    224     { EGR_EDATABUF_PARITY_CONTROLr, EFPCTR_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, EFP_COUNTER_TABLEm, INVALIDr, "" },
    225     { EGR_EDATABUF_PARITY_CONTROLr, STATS_PAR_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "TX DEBUG COUNTER" },
    226     { EGR_EDB_CTRL_PARITY_ENr, XLP15_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP15 DATABUF CONTROL INFO" },
    227     { EGR_EDB_CTRL_PARITY_ENr, XLP14_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP14 DATABUF CONTROL INFO" },
    228     { EGR_EDB_CTRL_PARITY_ENr, XLP13_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP13 DATABUF CONTROL INFO" },
    229     { EGR_EDB_CTRL_PARITY_ENr, XLP12_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP12 DATABUF CONTROL INFO" },
    230     { EGR_EDB_CTRL_PARITY_ENr, XLP11_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP11 DATABUF CONTROL INFO" },
    231     { EGR_EDB_CTRL_PARITY_ENr, XLP10_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP10 DATABUF CONTROL INFO" },
    232     { EGR_EDB_CTRL_PARITY_ENr, XLP9_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP9 DATABUF CONTROL INFO" },
    233     { EGR_EDB_CTRL_PARITY_ENr, XLP8_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP8 DATABUF CONTROL INFO" },
    234     { EGR_EDB_CTRL_PARITY_ENr, XLP7_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP7 DATABUF CONTROL INFO" },
    235     { EGR_EDB_CTRL_PARITY_ENr, XLP6_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP6 DATABUF CONTROL INFO" },
    236     { EGR_EDB_CTRL_PARITY_ENr, XLP5_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP5 DATABUF CONTROL INFO" },
    237     { EGR_EDB_CTRL_PARITY_ENr, XLP4_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP4 DATABUF CONTROL INFO" },
    238     { EGR_EDB_CTRL_PARITY_ENr, XLP3_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP3 DATABUF CONTROL INFO" },
    239     { EGR_EDB_CTRL_PARITY_ENr, XLP2_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP2 DATABUF CONTROL INFO" },
    240     { EGR_EDB_CTRL_PARITY_ENr, XLP1_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP1 DATABUF CONTROL INFO" },
    241     { EGR_EDB_CTRL_PARITY_ENr, XLP0_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP XLP0 DATABUF CONTROL INFO" },
    242     { EGR_EDB_CTRL_PARITY_ENr, CLP3_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP3 DATABUF CONTROL INFO" },
    243     { EGR_EDB_CTRL_PARITY_ENr, CLP2_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP2 DATABUF CONTROL INFO" },
    244     { EGR_EDB_CTRL_PARITY_ENr, CLP1_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP1 DATABUF CONTROL INFO" },
    245     { EGR_EDB_CTRL_PARITY_ENr, CLP0_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EP CLP0 DATABUF CONTROL INFO" },
    246     { EGR_FLEX_CTR_OFFSET_TABLE_CONTROL_0r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_OFFSET_TABLE_0m, INVALIDr, "" },
    247     { EGR_FLEX_CTR_OFFSET_TABLE_CONTROL_1r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_OFFSET_TABLE_1m, INVALIDr, "" },
    248     { EGR_FLEX_CTR_OFFSET_TABLE_CONTROL_2r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_OFFSET_TABLE_2m, INVALIDr, "" },
    249     { EGR_FLEX_CTR_OFFSET_TABLE_CONTROL_3r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_OFFSET_TABLE_3m, INVALIDr, "" },
    250     { EGR_FLEX_CTR_COUNTER_TABLE_CONTROL_0r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_COUNTER_TABLE_0m, INVALIDr, "" },
    251     { EGR_FLEX_CTR_COUNTER_TABLE_CONTROL_1r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_COUNTER_TABLE_1m, INVALIDr, "" },
    252     { EGR_FLEX_CTR_COUNTER_TABLE_CONTROL_2r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_COUNTER_TABLE_2m, INVALIDr, "" },
    253     { EGR_FLEX_CTR_COUNTER_TABLE_CONTROL_3r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FLEX_CTR_COUNTER_TABLE_3m, INVALIDr, "" },
    254     { EGR_EFPPARS_PARITY_CONTROLr, EGR_1588_LINK_DELAY_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_1588_LINK_DELAY_64r, "" },
    255     { EGR_EFPPARS_PARITY_CONTROLr, EGR_1588_SA_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_1588_SAm, INVALIDr, "" },
    256     { EGR_EFPPARS_SER_CONTROLr, EFPPARS_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "EFPPARS BUS" },
    257     { EGR_EHCPM_ECC_PARITY_CONTROLr, SF_SRC_MODID_CHECK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_SF_SRC_MODID_CHECKr, "" },
    258     { EGR_EHCPM_ECC_PARITY_CONTROLr, MOD_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MOD_MAP_TABLEm, INVALIDr, "" },
    259     { EGR_EHCPM_SER_CONTROLr, EHCPM_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "EHCPM BUS" },
    260     { EGR_EL3_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "INIT BUFF" },
    261     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_NAT_PACKET_EDIT_INFO_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_NAT_PACKET_EDIT_INFOm, INVALIDr, "" },
    262     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_MAP_MH_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MAP_MHm, INVALIDr, "" },
    263     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "EGR MPB" },
    264     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_PORT_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_PORTm, INVALIDr, "" },
    265     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_IPMC_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_IPMCm, INVALIDr, "" },
    266     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_VFI_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VFIm, INVALIDr, "" },
    267     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_DVP_ATTRIBUTE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_DVP_ATTRIBUTEm, INVALIDr, "" },
    268     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_MAC_DA_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MAC_DA_PROFILEm, INVALIDr, "" },
    269     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, INVALIDr, "" },
    270     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_L3_INTF_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_L3_INTFm, INVALIDr, "" },
    271     { EGR_EL3_ECC_PARITY_CONTROLr, EGR_L3_NEXT_HOP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_L3_NEXT_HOPm, INVALIDr, "" },
    272     { EGR_EPMOD_SER_CONTROLr, EPMOD_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "EPMOD BUS" },
    273     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_XLATE_PARITY_EN_LPf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VLAN_XLATE_LPm, INVALIDr, "" },
    274     { EGR_VLAN_SER_CONTROLr, EVLAN_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "EVLAN BUS" },
    275     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_TAG_ACTION_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VLAN_TAG_ACTION_PROFILEm, INVALIDr, "" },
    276     { EGR_VLAN_SER_CONTROLr, EGR_ETAG_PCP_MAPPING_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_ETAG_PCP_MAPPINGm, INVALIDr, "" },
    277     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_CONTROL_3_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_VLAN_CONTROL_3r, "" },
    278     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_CONTROL_2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_VLAN_CONTROL_2r, "" },
    279     { EGR_VLAN_SER_CONTROLr, EGR_PVLAN_EPORT_CONTROL_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, EGR_PVLAN_EPORT_CONTROLr, "" },
    280     { EGR_VLAN_SER_CONTROLr, EGR_VP_VLAN_MEMBERSHIP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VP_VLAN_MEMBERSHIPm, INVALIDr, "" },
    281     { EGR_VLAN_SER_CONTROLr, EGR_VPLAG_MEMBER_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VPLAG_MEMBERm, INVALIDr, "" },
    282     { EGR_VLAN_SER_CONTROLr, EGR_VPLAG_GROUP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VPLAG_GROUPm, INVALIDr, "" },
    283     { EGR_VLAN_SER_CONTROLr, EGR_MPLS_EXP_MAPPING_1_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MPLS_EXP_MAPPING_1m, INVALIDr, "" },
    284     { EGR_VLAN_SER_CONTROLr, EGR_GPP_ATTRIBUTES_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_GPP_ATTRIBUTESm, INVALIDr, "" },
    285     { EGR_VLAN_SER_CONTROLr, EGR_GPP_ATTRIBUTES_MODBASE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_GPP_ATTRIBUTES_MODBASEm, INVALIDr, "" },
    286     { EGR_VLAN_SER_CONTROLr, EGR_FRAGMENT_ID_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_FRAGMENT_ID_TABLEm, INVALIDr, "" },
    287     { EGR_VLAN_SER_CONTROLr, EGR_DSCP_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_DSCP_TABLEm, INVALIDr, "" },
    288     { EGR_VLAN_SER_CONTROLr, EGR_PRI_CNG_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_PRI_CNG_MAPm, INVALIDr, "" },
    289     { EGR_VLAN_SER_CONTROLr, EGR_MPLS_PRI_MAPPING_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MPLS_PRI_MAPPINGm, INVALIDr, "" },
    290     { EGR_VLAN_SER_CONTROLr, EGR_MPLS_EXP_MAPPING_2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MPLS_EXP_MAPPING_2m, INVALIDr, "" },
    291     { EGR_VLAN_SER_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_IP_TUNNELm, INVALIDr, "" },
    292     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_XLATE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VLAN_XLATEm, INVALIDr, "" },
    293     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_STG_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VLAN_STGm, INVALIDr, "" },
    294     { EGR_VLAN_SER_CONTROLr, EGR_VLAN_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_VLANm, INVALIDr, "" },
    295     { INVALIDr }
    296 };
    297 
    298 STATIC
    299 _soc_td2_fifo_ser_info_t _soc_td2_ip_ser_info[] = {
    300     { CFG_SER_CONTROLr, PORT_TABLE_ECC_ENf, _SOC_SER_SOURCE_TYPE_MEM, PORT_TABm, INVALIDr, "" },
    301     { CFG_SER_CONTROLr, SYSTEM_CONFIG_TABLE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, SYSTEM_CONFIG_TABLEm, INVALIDr, "" },
    302     { CFG_SER_CONTROLr, SYSTEM_CONFIG_TABLE_MODBASE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, SYSTEM_CONFIG_TABLE_MODBASEm, INVALIDr, "" },
    303     { CFG_SER_CONTROLr, SOURCE_TRUNK_MAP_MODBASE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, SOURCE_TRUNK_MAP_MODBASEm, INVALIDr, "" },
    304     /* NOTE: Read does not get the correct value for this reg */
    305     { DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, DLB_HGT_FLOWSET_TIMESTAMP_PAGEm, INVALIDr, "" },
    306     { DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, DLB_HGT_FLOWSETm, INVALIDr, "" },
    307     { IARB_SER_CONTROLr, LEARN_FIFO_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "IARB LEARN FIFO" },
    308     { IARB_SER_CONTROLr, CMIC_BUF_ECC_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "CMIC BUFFER" },
    309     { IFP_PARITY_CONTROLr, IFP_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "IFP BUS" },
    310     /*{ IFP_PARITY_CONTROLr, COUNTER_MUX_DATA_STAGING_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INVALIDm, INVALIDr, "COUNTER MUX DATA STAGING" }, HOW TO CLEAR */
    311     /*{ IFP_PARITY_CONTROLr, METER_MUX_DATA_STAGING_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INVALIDm, INVALIDr, "METER MUX DATA STAGING" }, HOW TO CLEAR */
    312     { IFP_PARITY_CONTROLr, PORT_METER_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_PORT_METER_MAPm, INVALIDr, "" },
    313     { IFP_PARITY_CONTROLr, ING_DVP_2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_DVP_2_TABLEm, INVALIDr, "" },
    314     { IFP_PARITY_CONTROLr, STORM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_STORM_CONTROL_METERSm, INVALIDr, "" },
    315     { IFP_PARITY_CONTROLr, COUNTER_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_COUNTER_TABLEm, INVALIDr, "" },
    316     { IFP_PARITY_CONTROLr, METER_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_METER_TABLEm, INVALIDr, "" },
    317     { IFP_PARITY_CONTROLr, POLICY_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_POLICY_TABLEm, INVALIDr, "" },
    318     { IL2L3_BUS_SER_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "IL2L3 BUS" },
    319     { ILPM_SER_CONTROLr, L3_DEFIP_ALPM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_ALPM_IPV6_128m, INVALIDr, "" },
    320     { ILPM_SER_CONTROLr, L3_DEFIP_ALPM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_ALPM_IPV6_64_1m, INVALIDr, "" },
    321     { ILPM_SER_CONTROLr, L3_DEFIP_ALPM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_ALPM_IPV6_64m, INVALIDr, "" },
    322     { ILPM_SER_CONTROLr, L3_DEFIP_ALPM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_ALPM_IPV4_1m, INVALIDr, "" },
    323     { ILPM_SER_CONTROLr, L3_DEFIP_ALPM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_ALPM_IPV4m, INVALIDr, "" },
    324     /* { ILPM_SER_CONTROLr, L3_DEFIP_ALPM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INVALIDm, INVALIDr, "L3 DEFIP ALPM IPV4/_1/IPV6_64/_64_1/_128" } */
    325     { ILPM_SER_CONTROLr, L3_DEFIP_AUX_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_AUX_TABLEm, INVALIDr, "" },
    326     { ILPM_SER_CONTROLr, L3_DEFIP_DATA_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_DATA_ONLYm, INVALIDr, "" },
    327     { ILPM_SER_CONTROLr, L3_DEFIP_DATA_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_DEFIP_PAIR_128_DATA_ONLYm, INVALIDr, "" },
    328     { ILPM_SER_CONTROL_1r, RTAG7_PORT_BASED_HASH_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, RTAG7_PORT_BASED_HASHm, INVALIDr, "" },
    329     { ILPM_SER_CONTROL_1r, RTAG7_FLOW_BASED_HASH_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, RTAG7_FLOW_BASED_HASHm, INVALIDr, "" },
    330     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_0r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_0m, INVALIDr, "" },
    331     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_1r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_1m, INVALIDr, "" },
    332     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_2r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_2m, INVALIDr, "" },
    333     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_3r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_3m, INVALIDr, "" },
    334     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_4r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_4m, INVALIDr, "" },
    335     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_5r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_5m, INVALIDr, "" },
    336     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_6r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_6m, INVALIDr, "" },
    337     { ING_FLEX_CTR_OFFSET_TABLE_CONTROL_7r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_OFFSET_TABLE_7m, INVALIDr, "" },
    338     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_0r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_0m, INVALIDr, "" },
    339     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_1r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_1m, INVALIDr, "" },
    340     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_2r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_2m, INVALIDr, "" },
    341     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_3r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_3m, INVALIDr, "" },
    342     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_4r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_4m, INVALIDr, "" },
    343     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_5r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_5m, INVALIDr, "" },
    344     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_6r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_6m, INVALIDr, "" },
    345     { ING_FLEX_CTR_COUNTER_TABLE_CONTROL_7r, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_COUNTER_TABLE_7m, INVALIDr, "" },
    346     { IPARS_SER_CONTROLr, IPARS_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "IARS BUS" },
    347     { IPARS_SER_CONTROLr, SRC_VP_2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, SOURCE_VP_2m, INVALIDr, "" },
    348     { IPARS_SER_CONTROLr, SRC_TRUNK_ECC_ENf, _SOC_SER_SOURCE_TYPE_MEM, SOURCE_TRUNK_MAP_TABLEm, INVALIDr, "" },
    349     { IPARS_SER_CONTROLr, L3_TUNNEL_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_TUNNEL_DATA_ONLYm, INVALIDr, "" },
    350     { IPARS_SER_CONTROLr, FP_UDF_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_UDF_OFFSETm, INVALIDr, "" },
    351     { IPARS_SER_CONTROLr, MOD_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_MOD_MAP_TABLEm, INVALIDr, "" },
    352     { IPARS_SER_CONTROLr, LPORT_TABLE_ECC_ENf, _SOC_SER_SOURCE_TYPE_MEM, LPORT_TABm, INVALIDr, "" },
    353     { IPARS_SER_CONTROLr, CPU_TS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, CPU_TS_MAPm, INVALIDr, "" },
    354     { IPARS_SER_CONTROLr, VLAN_RANGE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_VLAN_RANGEm, INVALIDr, "" },
    355     { IRSEL1_SER_CONTROLr, INITIAL_ING_L3_NEXT_HOP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INITIAL_ING_L3_NEXT_HOPm, INVALIDr, "" },
    356     { IRSEL1_SER_CONTROLr, INITIAL_L3_ECMP_GROUP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INITIAL_L3_ECMP_GROUPm, INVALIDr, "" },
    357     { IRSEL1_SER_CONTROLr, INITIAL_L3_ECMP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INITIAL_L3_ECMPm, INVALIDr, "" },
    358     { IRSEL1_SER_CONTROLr, OAM_OPCODE_CONTROL_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, OAM_OPCODE_CONTROL_PROFILEm, INVALIDr, "" },
    359     { IRSEL1_SER_CONTROLr, INITIAL_PROT_NHI_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, INITIAL_PROT_NHI_TABLEm, INVALIDr, "" },
    360     { IRSEL1_SER_CONTROLr, PORT_CBL_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, PORT_CBL_TABLEm, INVALIDr, "" },
    361     { IRSEL1_SER_CONTROLr, TRUNK_CBL_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, TRUNK_CBL_TABLEm, INVALIDr, "" },
    362     { IRSEL1_SER_CONTROLr, PORT_CBL_TABLE_MODBASE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, PORT_CBL_TABLE_MODBASEm, INVALIDr, "" },
    363     { IRSEL1_SER_CONTROLr, L3_IPMC_1_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_IPMC_1m, INVALIDr, "" },
    364 /*    { IRSEL1_SER_CONTROLr, MAID_REDUCTION_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MAID_REDUCTIONm, INVALIDr, "" },
    365     { IRSEL1_SER_CONTROLr, MA_INDEX_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MA_INDEXm, INVALIDr, "" },
    366     { IRSEL1_SER_CONTROLr, MA_STATE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MA_STATEm, INVALIDr, "" },
    367     { IRSEL1_SER_CONTROLr, RMEP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, RMEPm, INVALIDr, "" },*/
    368     { IRSEL1_SER_CONTROLr, ING_1588_INGRESS_CTRL_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_1588_INGRESS_CTRLm, INVALIDr, "" },
    369     { IRSEL1_SER_CONTROLr, IRSEL1_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "IRSEL1 BUS" },
    370     { IRSEL2_SER_CONTROLr, ING_L3_NEXT_HOP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_L3_NEXT_HOPm, INVALIDr, "" },
    371     { IRSEL2_SER_CONTROLr, L2MC_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L2MCm, INVALIDr, "" },
    372     { IRSEL2_SER_CONTROLr, L3_IPMC_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_IPMCm, INVALIDr, "" },
    373     { IRSEL2_SER_CONTROLr, L3_IPMC_REMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_IPMC_REMAPm, INVALIDr, "" },
    374     { IRSEL2_SER_CONTROLr, L3_ECMP_GROUP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ECMP_COUNTm, INVALIDr, "" },
    375     { IRSEL2_SER_CONTROLr, L3_ECMP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ECMPm, INVALIDr, "" },
    376     { IRSEL2_SER_CONTROLr, IFP_REDIRECTION_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, IFP_REDIRECTION_PROFILEm, INVALIDr, "" },
    377     { IRSEL2_SER_CONTROLr, ICONTROL_OPCODE_BITMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ICONTROL_OPCODE_BITMAPm, INVALIDr, "" },
    378     { IRSEL2_SER_CONTROLr, EGR_MASK_MODBASE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MASK_MODBASEm, INVALIDr, "" },
    379     { IRSEL2_SER_CONTROLr, DEST_TRUNK_BITMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, DEST_TRUNK_BITMAPm, INVALIDr, "" },
    380     { IRSEL2_SER_CONTROLr, TRUNK_GROUP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, TRUNK_GROUPm, INVALIDr, "" },
    381     { IRSEL2_SER_CONTROLr, RH_ECMP_FLOWSET_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, RH_ECMP_FLOWSETm, INVALIDr, "" },
    382     { IRSEL2_SER_CONTROLr, RH_LAG_FLOWSET_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, RH_LAG_FLOWSETm, INVALIDr, "" },
    383     { IRSEL2_SER_CONTROLr, ING_SNAT_DATA_ONLY_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_SNAT_DATA_ONLYm, INVALIDr, "" },
    384     { IRSEL2_SER_CONTROLr, IRSEL2_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "IRSEL2 BUS" },
    385     { ISW1_SER_CONTROLr, FP_PORT_FIELD_SEL_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FP_PORT_FIELD_SELm, INVALIDr, "" },
    386     { ISW1_SER_CONTROLr, TTL_FN_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, TTL_FNm, INVALIDr, "" },
    387     { ISW1_SER_CONTROLr, TOS_FN_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, TOS_FNm, INVALIDr, "" },
    388     { ISW1_SER_CONTROLr, ING_PRI_CNG_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_PRI_CNG_MAPm, INVALIDr, "" },
    389     { ISW1_SER_CONTROLr, ING_UNTAGGED_PHB_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_UNTAGGED_PHBm, INVALIDr, "" },
    390     { ISW1_SER_CONTROLr, DSCP_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, DSCP_TABLEm, INVALIDr, "" },
    391     { ISW1_SER_CONTROLr, STORM_CONTROL_METER_CONFIG_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, STORM_CONTROL_METER_CONFIGr, "" },
    392     { ISW1_SER_CONTROLr, FCOE_HOP_COUNT_FN_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, FCOE_HOP_COUNT_FNm, INVALIDr, "" },
    393     { ISW1_SER_CONTROLr, ISW1_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "ISW1 BUS" },
    394     { ISW2_SER_CONTROL_0r, VOQ_PORT_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VOQ_PORT_MAPm, INVALIDr, "" },
    395     { ISW2_SER_CONTROL_0r, VOQ_MOD_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VOQ_MOD_MAPm, INVALIDr, "" },
    396     { ISW2_SER_CONTROL_0r, TRUNK_MEMBER_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, TRUNK_MEMBERm, INVALIDr, "" },
    397     /*{ ISW2_SER_CONTROL_0r, DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, DLB_HGT_FLOWSET_TIMESTAMP_PAGEm,
    398       INVALIDr, "" }, DUPLICATE */
    399     { ISW2_SER_CONTROL_0r, UNKNOWN_HGI_BITMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, UNKNOWN_HGI_BITMAPm, INVALIDr, "" },
    400     { ISW2_SER_CONTROL_0r, IMIRROR_BITMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, IMIRROR_BITMAPm, INVALIDr, "" },
    401     { ISW2_SER_CONTROL_0r, KNOWN_MCAST_BLOCK_MASK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, KNOWN_MCAST_BLOCK_MASKm, INVALIDr, "" },
    402     { ISW2_SER_CONTROL_0r, ING_EGRMSKBMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_EGRMSKBMAPm, INVALIDr, "" },
    403     { ISW2_SER_CONTROL_0r, BCAST_BLOCK_MASK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, BCAST_BLOCK_MASKm, INVALIDr, "" },
    404     { ISW2_SER_CONTROL_0r, UNKNOWN_MCAST_BLOCK_MASK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, UNKNOWN_MCAST_BLOCK_MASKm, INVALIDr, "" },
    405     { ISW2_SER_CONTROL_0r, UNKNOWN_UCAST_BLOCK_MASK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, UNKNOWN_UCAST_BLOCK_MASKm, INVALIDr, "" },
    406     { ISW2_SER_CONTROL_0r, LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, LOCAL_SW_DISABLE_DEFAULT_PBM_MIRRm,
    407       INVALIDr, "" },
    408     { ISW2_SER_CONTROL_0r, LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, LOCAL_SW_DISABLE_DEFAULT_PBMm, INVALIDr, "" },
    409     /*{ ISW2_SER_CONTROL_0r, VOQ_COS_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VOQ_COS_MAPm, INVALIDr, "" }, NA */
    410     { ISW2_SER_CONTROL_0r, NUM_QCN_CNM_RECEIVED_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, NUM_QCN_CNM_RECEIVEDm, INVALIDr, "" },
    411     { ISW2_SER_CONTROL_0r, OAM_LM_COUNTERS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, OAM_LM_COUNTERSm, INVALIDr, "" },
    412     { ISW2_SER_CONTROL_0r, SRC_MODID_EGRESS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, SRC_MODID_EGRESSm, INVALIDr, "" },
    413     { ISW2_SER_CONTROL_0r, SRC_MODID_INGRESS_BLOCK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, SRC_MODID_INGRESS_BLOCKm, INVALIDr, "" },
    414     { ISW2_SER_CONTROL_0r, E2E_HOL_STATUS_1_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, E2E_HOL_STATUS_1m, INVALIDr, "" },
    415     { ISW2_SER_CONTROL_0r, E2E_HOL_STATUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, E2E_HOL_STATUSm, INVALIDr, "" },
    416     { ISW2_SER_CONTROL_0r, VLAN_PROFILE_2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_PROFILE_2m, INVALIDr, "" },
    417     { ISW2_SER_CONTROL_0r, MAC_BLOCK_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MAC_BLOCKm, INVALIDr, "" },
    418     { ISW2_SER_CONTROL_0r, ING_PW_TERM_SEQ_NUM_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_PW_TERM_SEQ_NUMm, INVALIDr, "" },
    419     { ISW2_SER_CONTROL_0r, ALTERNATE_EMIRROR_BITMAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ALTERNATE_EMIRROR_BITMAPm, INVALIDr, "" },
    420     { ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MODPORT_MAP_MIRRORm, INVALIDr, "" },
    421     { ISW2_SER_CONTROL_0r, PORT_LAG_FAILOVER_SET_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, PORT_LAG_FAILOVER_SETm, INVALIDr, "" },
    422     { ISW2_SER_CONTROL_0r, ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_HIGIG_TRUNK_OVERRIDE_PROFILEm,
    423       INVALIDr, "" },
    424     { ISW2_SER_CONTROL_0r, MODPORT_MAP_SW_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MODPORT_MAP_SWm, INVALIDr, "" },
    425     { ISW2_SER_CONTROL_0r, NONUCAST_TRUNK_BLOCK_MASK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, NONUCAST_TRUNK_BLOCK_MASKm, INVALIDr, "" },
    426     { ISW2_SER_CONTROL_0r, TRUNK_BITMAP_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, TRUNK_BITMAPm, INVALIDr, "" },
    427     { ISW2_SER_CONTROL_0r, EGR_MASK_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EGR_MASKm, INVALIDr, "" },
    428     { ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MODPORT_MAP_M3m, INVALIDr, "" },
    429     { ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MODPORT_MAP_M2m, INVALIDr, "" },
    430     { ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MODPORT_MAP_M1m, INVALIDr, "" },
    431     { ISW2_SER_CONTROL_1r, SERVICE_PORT_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, SERVICE_PORT_MAPm, INVALIDr, "" },
    432     { ISW2_SER_CONTROL_1r, SERVICE_QUEUE_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, SERVICE_QUEUE_MAPm, INVALIDr, "" },
    433     { ISW2_SER_CONTROL_1r, ING_MISC_PORT_CONFIG_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, ING_MISC_PORT_CONFIGr, "" },
    434     { ISW2_SER_CONTROL_1r, SFLOW_EGR_THRESHOLD_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, SFLOW_EGR_THRESHOLDr, "" },
    435     /*{ ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_VLAN_TAGGED_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm,
    436       ING_NIV_RX_FRAMES_VLAN_TAGGEDr, "" },
    437     { ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_FORWARDING_DROP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm,
    438       ING_NIV_RX_FRAMES_FORWARDING_DROPr, "" },
    439     { ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_ERROR_DROP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm,
    440       ING_NIV_RX_FRAMES_ERROR_DROPr, "" },*/
    441     
    442     
    443     { ISW2_SER_CONTROL_1r, L3_MTU_VALUES_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_MTU_VALUESm, INVALIDr, "" },
    444     /*{ ISW2_SER_CONTROL_1r, ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm,
    445       ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDEDr, "" },
    446     { ISW2_SER_CONTROL_1r, ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm,
    447       ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDEDr, "" },
    448     { ISW2_SER_CONTROL_1r, ING_TRILL_RX_PKTS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, ING_TRILL_RX_PKTSr, "" },*/
    449     { ISW2_SER_CONTROL_1r, HG_COUNTERS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "HG STATS COUNTERS" },
    450     { ISW2_SER_CONTROL_1r, RDBGC_MEM_INST2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "RDBGC5/RDBGC6/RDBGC7/RDBGC8" },
    451     { ISW2_SER_CONTROL_1r, RDBGC_MEM_INST1_PARITY_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "RDBGC1/RDBGC2/RDBGC3/RDBGC4" },
    452     { ISW2_SER_CONTROL_1r, RDBGC_MEM_INST0_PARITY_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "RDISC/RUC/RPORTD/RDBGC0" },
    453     { ISW2_SER_CONTROL_1r, IP_COUNTERS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_OTHER, INVALIDm, INVALIDr, "IP STATS COUNTERS" },
    454     { ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_C_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "SW2 EOP BUFFER C" },
    455     { ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_B_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "SW2 EOP BUFFER B" },
    456     { ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_A_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUF, INVALIDm, INVALIDr, "SW2 EOP BUFFER A" },
    457     { ISW2_SER_CONTROL_1r, EMIRROR_CONTROL3_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EMIRROR_CONTROL3m, INVALIDr, "" },
    458     { ISW2_SER_CONTROL_1r, EMIRROR_CONTROL2_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EMIRROR_CONTROL2m, INVALIDr, "" },
    459     { ISW2_SER_CONTROL_1r, EMIRROR_CONTROL1_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EMIRROR_CONTROL1m, INVALIDr, "" },
    460     { ISW2_SER_CONTROL_1r, EMIRROR_CONTROL_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, EMIRROR_CONTROLm, INVALIDr, "" },
    461     { ISW2_SER_CONTROL_2r, ENDPOINT_COS_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ENDPOINT_COS_MAPm, INVALIDr, "" },
    462     { ISW2_SER_CONTROL_2r, PHB2_COS_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, PHB2_COS_MAPm, INVALIDr, "" },
    463     { ISW2_SER_CONTROL_2r, ENDPOINT_QUEUE_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ENDPOINT_QUEUE_MAPm, INVALIDr, "" },
    464     { ISW2_SER_CONTROL_2r, ING_FLEX_CTR_PKT_PRI_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_PKT_PRI_MAPm, INVALIDr, "" },
    465     { ISW2_SER_CONTROL_2r, ING_FLEX_CTR_PRI_CNG_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_PRI_CNG_MAPm, INVALIDr, "" },
    466     { ISW2_SER_CONTROL_2r, ING_FLEX_CTR_PORT_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_PORT_MAPm, INVALIDr, "" },
    467     { ISW2_SER_CONTROL_2r, ING_FLEX_CTR_TOS_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_TOS_MAPm, INVALIDr, "" },
    468     { ISW2_SER_CONTROL_2r, ING_FLEX_CTR_PKT_RES_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_FLEX_CTR_PKT_RES_MAPm, INVALIDr, "" },
    469     { ISW2_SER_CONTROL_2r, ING_SERVICE_PRI_MAP_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_SERVICE_PRI_MAPm, INVALIDr, "" },
    470     { IVXLT_SER_CONTROLr, VLAN_XLATE_PARITY_EN_LPf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_XLATE_LPm, INVALIDr, "" },
    471     { IVXLT_SER_CONTROLr, ING_ETAG_PCP_MAPPING_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_ETAG_PCP_MAPPINGm, INVALIDr, "" },
    472     { IVXLT_SER_CONTROLr, VLAN_PROT_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_PROTOCOL_DATAm, INVALIDr, "" },
    473     { IVXLT_SER_CONTROLr, ING_VLAN_TAG_ACTION_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_VLAN_TAG_ACTION_PROFILEm, INVALIDr, "" },
    474     { IVXLT_SER_CONTROLr, MPLS_ENTRY_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, MPLS_ENTRYm, INVALIDr, "" },
    475     { IVXLT_SER_CONTROLr, VLAN_SUBNET_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_SUBNET_DATA_ONLYm, INVALIDr, "" },
    476     { IVXLT_SER_CONTROLr, VLAN_PROT_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_PROTOCOLm, INVALIDr, "" },
    477     { IVXLT_SER_CONTROLr, VLAN_XLATE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_XLATEm, INVALIDr, "" },
    478     { IVXLT_SER_CONTROLr, VFP_POLICY_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, VFP_POLICY_TABLEm, INVALIDr, "" },
    479     { IVXLT_SER_CONTROLr, IVXLT_BUS_PARITY_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "IVXLT BUS" },
    480     { L2_ENTRY_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L2Xm, INVALIDr, "" },
    481     { L2_ENTRY_PARITY_CONTROLr, ING_DVP_TABLE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_DVP_TABLEm, INVALIDr, "" },
    482     { L2_ENTRY_PARITY_CONTROLr, L2_ENDPOINT_ID_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L2_ENDPOINT_IDm, INVALIDr, "" },
    483     { L2_ENTRY_PARITY_CONTROLr, PARITY_EN_LPf, _SOC_SER_SOURCE_TYPE_MEM, L2_ENTRY_LPm, INVALIDr, "" },
    484     { L2_MOD_FIFO_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L2_MOD_FIFOm, INVALIDr, "" },
    485     { L2_USER_ENTRY_DATA_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L2_USER_ENTRY_DATA_ONLYm, INVALIDr, "" },
    486     { L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ENTRY_ONLYm, INVALIDr, "" },
    487     { L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ENTRY_IPV4_UNICASTm, INVALIDr, "" },
    488     { L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ENTRY_IPV4_MULTICASTm, INVALIDr, "" },
    489     { L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ENTRY_IPV6_UNICASTm, INVALIDr, "" },
    490     { L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_ENTRY_IPV6_MULTICASTm, INVALIDr, "" },
    491     { L3_ENTRY_PARITY_CONTROLr, ING_ACTIVE_L3_IIF_PROFILE_PARITY_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_ACTIVE_L3_IIF_PROFILEm, INVALIDr, "" },
    492     { L3_ENTRY_PARITY_CONTROLr, PARITY_EN_LPf, _SOC_SER_SOURCE_TYPE_MEM, L3_ENTRY_LPm, INVALIDr, "" },
    493     { MPLS_SER_CONTROLr, ING_VP_VLAN_MEMBERSHIP_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_VP_VLAN_MEMBERSHIPm, INVALIDr, "" },
    494     { MPLS_SER_CONTROLr, L3_IIF_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_IIFm, INVALIDr, "" },
    495     { MPLS_SER_CONTROLr, ING_MPLS_EXP_MAPPING_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_MPLS_EXP_MAPPINGm, INVALIDr, "" },
    496     { MPLS_SER_CONTROLr, VRF_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, VRFm, INVALIDr, "" },
    497     { MPLS_SER_CONTROLr, VLAN_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_TABm, INVALIDr, "" },
    498     { MPLS_SER_CONTROLr, VLAN_STG_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, STG_TABm, INVALIDr, "" },
    499     { MPLS_SER_CONTROLr, VLAN_PROFILE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_PROFILE_TABm, INVALIDr, "" },
    500     { MPLS_SER_CONTROLr, ING_OUTER_DOT1P_MAPPING_TABLE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_OUTER_DOT1P_MAPPING_TABLEm, INVALIDr, "" },
    501     { MPLS_SER_CONTROLr, IP_OPTION_CONTROL_PROFILE_TABLE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, IP_OPTION_CONTROL_PROFILE_TABLEm, INVALIDr, "" },
    502     { MPLS_SER_CONTROLr, L3_IIF_PROFILE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, L3_IIF_PROFILEm, INVALIDr, "" },
    503     { MPLS_SER_CONTROLr, ING_DNAT_ADDRESS_TYPE_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_DNAT_ADDRESS_TYPEm, INVALIDr, "" },
    504     { MPLS_SER_CONTROLr, MPLS_BUS_PAR_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "MPLS BUS" },
    505     { VP_SER_CONTROLr, VLAN_MPLS_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, VLAN_MPLSm, INVALIDr, "" },
    506     { VP_SER_CONTROLr, MY_STATION_TCAM_DATA_ONLY_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, MY_STATION_TCAM_DATA_ONLYm, INVALIDr, "" },
    507     { VP_SER_CONTROLr, SOURCE_VP_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, SOURCE_VPm, INVALIDr, "" },
    508     { VP_SER_CONTROLr, VFI_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, VFIm, INVALIDr, "" },
    509     { VP_SER_CONTROLr, VFI_1_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, VFI_1m, INVALIDr, "" },
    510     { VP_SER_CONTROLr, ING_VSAN_PAR_ENf, _SOC_SER_SOURCE_TYPE_MEM, ING_VSANm, INVALIDr, "" },
    511     { VP_SER_CONTROLr, ING_TRILL_ADJACENCY_PAR_ENf, _SOC_SER_SOURCE_TYPE_REG, INVALIDm, ING_TRILL_ADJACENCYr, "" },
    512     { VP_SER_CONTROLr, VP_BUS_PAR_ENf, _SOC_SER_SOURCE_TYPE_BUS, INVALIDm, INVALIDr, "VP BUS" },
    513     { INVALIDr }
    514 };
    515 
    516 STATIC const
    517 _soc_td2_ser_block_info_t _soc_td2_ser_block_info[] = {
    518     { SOC_BLK_IPIPE, ING_SER_FIFO_CTRLr, _soc_td2_ip_ser_info },
    519     { SOC_BLK_EPIPE, EGR_SER_FIFO_CTRLr, _soc_td2_ep_ser_info },
    520     { 0 }
    521 };
    522 
    523 STATIC _soc_td2_ser_info_t _soc_td2_mmu_ser_info[] = {
    524     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    525         DEQ_NOT_IP_ERR_ENf,
    526         DEQ_NOT_IP_ERRf,
    527         INVALIDm, "MMU DEQ NOT IP",
    528         INVALIDr, INVALIDf,
    529         INVALIDr, NULL },
    530     { _SOC_PARITY_TYPE_START_ERR, NULL, 0,
    531         START_BY_START_ERR_ENf,
    532         START_BY_START_ERRf,
    533         INVALIDm, "MMU START BY START",
    534         INVALIDr, INVALIDf,
    535         INVALIDr, NULL },
    536     { _SOC_PARITY_TYPE_MMU_SER, NULL, 0,
    537         MEM_PAR_ERR_ENf,
    538         MEM_PAR_ERRf,
    539         INVALIDm, "MMU MEM PAR",
    540         INVALIDr, INVALIDf,
    541         MEM_FAIL_INT_STATr, NULL },
    542     { _SOC_PARITY_TYPE_BST, NULL, 0,
    543         INVALIDf,
    544         BST_THDI_INTf,
    545         INVALIDm, NULL,
    546         INVALIDr, INVALIDf,
    547         INVALIDr, NULL },
    548     { _SOC_PARITY_TYPE_BST, NULL, 0,
    549         INVALIDf,
    550         BST_THDO_INTf,
    551         INVALIDm, NULL,
    552         INVALIDr, INVALIDf,
    553         INVALIDr, NULL },
    554     { _SOC_PARITY_TYPE_BST, NULL, 0,
    555         INVALIDf,
    556         BST_CFAP_INTf,
    557         INVALIDm, NULL,
    558         INVALIDr, INVALIDf,
    559         INVALIDr, NULL },
    560     { _SOC_PARITY_TYPE_CFAP_MEM_FAIL, NULL, 0,
    561         CFAP_MEM_FAIL_ENf,
    562         CFAP_MEM_FAILf,
    563         INVALIDm, "CFAP MEM FAIL",
    564         INVALIDr, INVALIDf,
    565         MEM_FAIL_INT_STATr, NULL },
    566     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    567 };
    568 
    569 STATIC _soc_td2_ser_info_t _soc_td2_cport_ser_info[] = {
    570     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    571         TXFIFO0_MEM_ERRf,
    572         TXFIFO0_MEM_ERRf,
    573         INVALIDm, "CDC RX FIFO MEMORY ECC",
    574         CPORT_ECC_CONTROLr, CDC_RXFIFO_MEM_ENf,
    575         CPORT_TXFIFO0_ECC_STATUSr, NULL },
    576     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    577         CDC_TXFIFO_MEM_ERRf,
    578         CDC_TXFIFO_MEM_ERRf,
    579         INVALIDm, "CDC TX FIFO MEMORY ECC",
    580         CPORT_ECC_CONTROLr, CDC_TXFIFO_MEM_ENf,
    581         CPORT_CDC_TXFIFO_ECC_STATUSr, NULL },
    582     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    583         TXFIFO0_MEM_ERRf,
    584         TXFIFO0_MEM_ERRf,
    585         INVALIDm, "TX FIFO ECC - XPORT CORE0 OR CPORT CORE",
    586         CPORT_ECC_CONTROLr, TXFIFO_MEM_ENf,
    587         CPORT_TXFIFO0_ECC_STATUSr, NULL },
    588     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    589 };
    590 
    591 STATIC _soc_td2_ser_reg_t _soc_td2_pg_bod_status_reg[] = {
    592     { PGW_BOD_XLP0_ECC_STATUSr, "PGW BOD XLP0 ECC" },
    593     { PGW_BOD_XLP1_ECC_STATUSr, "PGW BOD XLP1 ECC" },
    594     { PGW_BOD_XLP2_ECC_STATUSr, "PGW BOD XLP2 ECC" },
    595     { PGW_BOD_XLP3_ECC_STATUSr, "PGW BOD XLP3 ECC" },
    596     { INVALIDr }
    597 };
    598 
    599 STATIC _soc_td2_ser_info_t _soc_td2_pg_ser_info[] = {
    600     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    601         PGW_OBM_PERR_INTRf,
    602         PGW_OBM_PERR_INTRf,
    603         INVALIDm, "PGW OBM",
    604         PGW_OBM0_ECC_ENABLEr, ECC_ENABLEf,
    605         PGW_OBM0_ECC_STATUSr, NULL },
    606     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    607         PGW_BOD_PERR_INTRf,
    608         PGW_BOD_PERR_INTRf,
    609         INVALIDm, "PGW BOD",
    610         PGW_BOD_ECC_ENABLEr, BOD_ECC_ENABLEf,
    611         INVALIDr, _soc_td2_pg_bod_status_reg },
    612     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    613         MIB_RSC1_MEM_ERRf,
    614         MIB_RSC1_MEM_ERRf,
    615         INVALIDm, "PGW MIB RX CTR Instance 1",
    616         INVALIDr, INVALIDf,
    617         PGW_MIB_RSC1_ECC_STATUSr, NULL },
    618     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    619         MIB_RSC0_MEM_ERRf,
    620         MIB_RSC0_MEM_ERRf,
    621         INVALIDm, "PGW MIB RX CTR Instance 0",
    622         PGW_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    623         PGW_MIB_RSC0_ECC_STATUSr, NULL },
    624     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    625         MIB_RSC1_MEM_ERRf,
    626         MIB_RSC1_MEM_ERRf,
    627         INVALIDm, "PGW MIB TX CTR Instance 1",
    628         INVALIDr, INVALIDf,
    629         PGW_MIB_TSC1_ECC_STATUSr, NULL },
    630     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    631         MIB_RSC0_MEM_ERRf,
    632         MIB_RSC0_MEM_ERRf,
    633         INVALIDm, "PGW MIB TX CTR Instance 0",
    634         PGW_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    635         PGW_MIB_TSC0_ECC_STATUSr, NULL },
    636     { _SOC_PARITY_TYPE_CPORT, _soc_td2_cport_ser_info, 0,
    637         CPORT_ERRf,
    638         CPORT_ERRf,
    639         INVALIDm, "CPORT",
    640         CPORT_INTR_ENABLEr, INVALIDf, /* group enable */
    641         INVALIDr, NULL },
    642     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    643 };
    644 
    645 STATIC const
    646 _soc_td2_ser_route_block_t  _soc_td2_ser_route_blocks[] = {
    647     { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */
    648       SOC_BLK_MMU, -1, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, INVALIDf,
    649       _soc_td2_mmu_ser_info, 0 },
    650     { 0x00000002, /* X_EP1_TO_CMIC_PERR_INTR */
    651       SOC_BLK_EPIPE, 0, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf,
    652       NULL, 0 },
    653     { 0x00000004, /* Y_EP1_TO_CMIC_PERR_INTR */
    654       SOC_BLK_EPIPE, 1, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf,
    655       NULL, 0 },
    656     { 0x00000008, /* X_EP2_TO_CMIC_PERR_INTR */
    657       SOC_BLK_EPIPE, 0, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf,
    658       NULL, 0 },
    659     { 0x00000010, /* Y_EP2_TO_CMIC_PERR_INTR */
    660       SOC_BLK_EPIPE, 1, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf,
    661       NULL, 0 },
    662     { 0x00000020, /* X_IP0_TO_CMIC_PERR_INTR */
    663       SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    664     { 0x00000040, /* Y_IP0_TO_CMIC_PERR_INTR */
    665       SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    666     { 0x00000080, /* X_IP1_TO_CMIC_PERR_INTR */
    667       SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    668     { 0x00000100, /* Y_IP1_TO_CMIC_PERR_INTR */
    669       SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    670     { 0x00000200, /* X_IP2_TO_CMIC_PERR_INTR */
    671       SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    672     { 0x00000400, /* Y_IP2_TO_CMIC_PERR_INTR */
    673       SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    674     { 0x00000800, /* X_IP3_TO_CMIC_PERR_INTR */
    675       SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    676     { 0x00001000, /* Y_IP3_TO_CMIC_PERR_INTR */
    677       SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    678     { 0x00002000, /* X_IP4_TO_CMIC_PERR_INTR */
    679       SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    680     { 0x00004000, /* Y_IP4_TO_CMIC_PERR_INTR */
    681       SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    682     { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */
    683       SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    684     { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */
    685       SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    686     { 0x00040000, /* PGW_0_TO_CMIC_PERR_INTR */
    687       SOC_BLK_PGW_CL, 0, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    688       _soc_td2_pg_ser_info, 0 },
    689     { 0x00080000, /* PGW_1_TO_CMIC_PERR_INTR */
    690       SOC_BLK_PGW_CL, 0, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    691       _soc_td2_pg_ser_info, 1 },
    692     { 0x00100000, /* PGW_2_TO_CMIC_PERR_INTR */
    693       SOC_BLK_PGW_CL, 0, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    694       _soc_td2_pg_ser_info, 2 },
    695     { 0x00200000, /* PGW_3_TO_CMIC_PERR_INTR */
    696       SOC_BLK_PGW_CL, 0, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    697       _soc_td2_pg_ser_info, 3 },
    698     { 0x00400000, /* PGW_4_TO_CMIC_PERR_INTR */
    699       SOC_BLK_PGW_CL, 1, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    700       _soc_td2_pg_ser_info, 4 },
    701     { 0x00800000, /* PGW_5_TO_CMIC_PERR_INTR */
    702       SOC_BLK_PGW_CL, 1, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    703       _soc_td2_pg_ser_info, 5 },
    704     { 0x01000000, /* PGW_6_TO_CMIC_PERR_INTR */
    705       SOC_BLK_PGW_CL, 1, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    706       _soc_td2_pg_ser_info, 6 },
    707     { 0x02000000, /* PGW_7_TO_CMIC_PERR_INTR */
    708       SOC_BLK_PGW_CL, 1, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    709       _soc_td2_pg_ser_info, 7 },
    710     { 0 } /* table terminator */
    711 };
    712 
    713 STATIC const
    714 soc_field_t _soc_td2_mmu_parity_enable_fields[] = {
    715     INVALIDf,         /* ADM */
    716     ENQ_PARITY_ENf,   /* ENQ */
    717     THDI_PARITY_ENf,  /* THDI */
    718     INVALIDf,         /* THDO */
    719     TOQ_PARITY_ENf,   /* TOQ */
    720     DEQ_PARITY_ENf,   /* DEQ */
    721     INVALIDf,
    722     CFAP_PARITY_ENf,  /* CFAP */
    723     CCP_PARITY_ENf,   /* CCP */
    724     MTRI_PARITY_ENf,  /* MTRI */
    725     MTRO_PARITY_ENf,  /* MTRO */
    726     INVALIDf,         /* INTF */
    727     INVALIDf,         /* CFG */
    728     AGING_PARITY_ENf, /* AGING */
    729     DEQ_PARITY_ENf,   /* MEM0 */
    730     INVALIDf,         /* MEM1 */
    731     INVALIDf,         /* MEM3 */
    732     INVALIDf,         /* MEM4 */
    733     INVALIDf,         /* TOQ2 */
    734     INVALIDf,         /* TOQ3 */
    735     INVALIDf,         /* TOQ4 */
    736     INTFI_PARITY_ENf, /* INTFI */
    737     INVALIDf,         /* INTFO */
    738     INTFO2_PARITY_ENf,/* INTFO2 */
    739     ES_PARITY_ENf,    /* LLS */
    740     ES_PARITY_ENf,    /* LLS_PORT */
    741     ES_PARITY_ENf,    /* LLS_L0 */
    742     ES_PARITY_ENf,    /* LLS_L1 */
    743     ES_PARITY_ENf,    /* LLS_L2 */
    744     WRED_PARITY_ENf,  /* WRED */
    745     INVALIDf,         /* MCQ */
    746     INVALIDf,         /* UCQ */
    747     PQE_PARITY_ENf,   /* PQE */
    748     QCN_PARITY_ENf,   /* QCN */
    749     CTR_PARITY_ENf,   /* CTR */
    750     INVALIDf,
    751     RQE_PARITY_ENf,   /* RQE */
    752     ES_PARITY_ENf,    /* VBS */
    753     ES_PARITY_ENf,    /* VBS_L0 */
    754     ES_PARITY_ENf,    /* VBS_L1 */
    755     ES_PARITY_ENf,    /* VBS_L2 */
    756     EPRG_PARITY_ENf,  /* EPRG */
    757     THDU_PARITY_ENf,  /* THDU */
    758     THDM_PARITY_ENf,  /* THDO_MC_DB */
    759     THDM_PARITY_ENf,  /* THDO_MC_QE */
    760     INVALIDf,         /* THDR_DB */
    761     INVALIDf,         /* THDR_QE */
    762     ES_PARITY_ENf,    /* TDM */
    763     INVALIDf,
    764     INVALIDf,
    765     INVALIDf,
    766     INVALIDf
    767 };
    768 
    769 static const soc_reg_t mmu_ovs_group_regs[2][MAX_MMU_OVS_GROUP_COUNT] = {
    770     {
    771         ES_PIPE0_OVR_SUB_GRP0_TBLr, ES_PIPE0_OVR_SUB_GRP1_TBLr,
    772         ES_PIPE0_OVR_SUB_GRP2_TBLr, ES_PIPE0_OVR_SUB_GRP3_TBLr
    773 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    774     ,
    775         ES_PIPE0_OVR_SUB_GRP4_TBLr, ES_PIPE0_OVR_SUB_GRP5_TBLr,
    776         ES_PIPE0_OVR_SUB_GRP6_TBLr, ES_PIPE0_OVR_SUB_GRP7_TBLr
    777 #endif
    778     },
    779     {
    780         ES_PIPE1_OVR_SUB_GRP0_TBLr, ES_PIPE1_OVR_SUB_GRP1_TBLr,
    781         ES_PIPE1_OVR_SUB_GRP2_TBLr, ES_PIPE1_OVR_SUB_GRP3_TBLr
    782 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    783     ,
    784         ES_PIPE1_OVR_SUB_GRP4_TBLr, ES_PIPE1_OVR_SUB_GRP5_TBLr,
    785         ES_PIPE1_OVR_SUB_GRP6_TBLr, ES_PIPE1_OVR_SUB_GRP7_TBLr
    786 #endif
    787     }
    788 };
    789 
    790 static const soc_field_t pgw_tdm_fields[] = {
    791     TDM_ENTRY0_PORT_IDf, TDM_ENTRY1_PORT_IDf,
    792     TDM_ENTRY2_PORT_IDf, TDM_ENTRY3_PORT_IDf,
    793     TDM_ENTRY4_PORT_IDf, TDM_ENTRY5_PORT_IDf,
    794     TDM_ENTRY6_PORT_IDf, TDM_ENTRY7_PORT_IDf,
    795     TDM_ENTRY8_PORT_IDf, TDM_ENTRY9_PORT_IDf,
    796     TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf,
    797     TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf,
    798     TDM_ENTRY14_PORT_IDf, TDM_ENTRY15_PORT_IDf,
    799     TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf,
    800     TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf,
    801     TDM_ENTRY20_PORT_IDf, TDM_ENTRY21_PORT_IDf,
    802     TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf,
    803     TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf,
    804     TDM_ENTRY26_PORT_IDf, TDM_ENTRY27_PORT_IDf,
    805     TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf,
    806     TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf
    807 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    808     ,
    809     TDM_ENTRY32_PORT_IDf, TDM_ENTRY33_PORT_IDf,
    810     TDM_ENTRY34_PORT_IDf, TDM_ENTRY35_PORT_IDf,
    811     TDM_ENTRY36_PORT_IDf, TDM_ENTRY37_PORT_IDf,
    812     TDM_ENTRY38_PORT_IDf, TDM_ENTRY39_PORT_IDf,
    813     TDM_ENTRY40_PORT_IDf, TDM_ENTRY41_PORT_IDf,
    814     TDM_ENTRY42_PORT_IDf, TDM_ENTRY43_PORT_IDf,
    815     TDM_ENTRY44_PORT_IDf, TDM_ENTRY45_PORT_IDf,
    816     TDM_ENTRY46_PORT_IDf, TDM_ENTRY47_PORT_IDf,
    817     TDM_ENTRY48_PORT_IDf, TDM_ENTRY49_PORT_IDf,
    818     TDM_ENTRY50_PORT_IDf, TDM_ENTRY51_PORT_IDf,
    819     TDM_ENTRY52_PORT_IDf, TDM_ENTRY53_PORT_IDf,
    820     TDM_ENTRY54_PORT_IDf, TDM_ENTRY55_PORT_IDf,
    821     TDM_ENTRY56_PORT_IDf, TDM_ENTRY57_PORT_IDf,
    822     TDM_ENTRY58_PORT_IDf, TDM_ENTRY59_PORT_IDf,
    823     TDM_ENTRY60_PORT_IDf, TDM_ENTRY61_PORT_IDf,
    824     TDM_ENTRY62_PORT_IDf, TDM_ENTRY63_PORT_IDf
    825 #endif
    826 };
    827 
    828 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    829 static soc_reg_t mmu_ovs_group_wt_select_regs[2] = {
    830     ES_PIPE0_GRP_WT_SELECTr,
    831     ES_PIPE1_GRP_WT_SELECTr
    832 };
    833 #endif
    834 
    835 static soc_reg_t pgw_tdm_regs[] = {
    836     PGW_LR_TDM_REG_0r, PGW_LR_TDM_REG_1r,
    837     PGW_LR_TDM_REG_2r, PGW_LR_TDM_REG_3r,
    838     PGW_LR_TDM_REG_4r, PGW_LR_TDM_REG_5r,
    839     PGW_LR_TDM_REG_6r, PGW_LR_TDM_REG_7r
    840 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    841     ,
    842     PGW_LR_TDM_REG_8r,  PGW_LR_TDM_REG_9r,
    843     PGW_LR_TDM_REG_10r, PGW_LR_TDM_REG_11r,
    844     PGW_LR_TDM_REG_12r, PGW_LR_TDM_REG_13r,
    845     PGW_LR_TDM_REG_14r, PGW_LR_TDM_REG_15r
    846 #endif
    847 };
    848 
    849 static soc_reg_t pgw_ovs_tdm_regs[] = {
    850     PGW_OS_TDM_REG_0r, PGW_OS_TDM_REG_1r,
    851     PGW_OS_TDM_REG_2r, PGW_OS_TDM_REG_3r,
    852     PGW_OS_TDM_REG_4r, PGW_OS_TDM_REG_5r,
    853     PGW_OS_TDM_REG_6r, PGW_OS_TDM_REG_7r
    854 };
    855 
    856 static const soc_reg_t pgw_ovs_spacing_regs[] = {
    857     PGW_OS_PORT_SPACING_REG_0r, PGW_OS_PORT_SPACING_REG_1r,
    858     PGW_OS_PORT_SPACING_REG_2r, PGW_OS_PORT_SPACING_REG_3r,
    859     PGW_OS_PORT_SPACING_REG_4r, PGW_OS_PORT_SPACING_REG_5r,
    860     PGW_OS_PORT_SPACING_REG_6r, PGW_OS_PORT_SPACING_REG_7r
    861 };
    862 
    863 static const soc_field_t pgw_spacing_fields[] = {
    864     SLOT0f, SLOT1f, SLOT2f, SLOT3f, SLOT4f, SLOT5f, SLOT6f, SLOT7f,
    865     SLOT8f, SLOT9f, SLOT10f, SLOT11f, SLOT12f, SLOT13f, SLOT14f, SLOT15f,
    866     SLOT16f, SLOT17f, SLOT18f, SLOT19f, SLOT20f, SLOT21f, SLOT22f, SLOT23f,
    867     SLOT24f, SLOT25f, SLOT26f, SLOT27f, SLOT28f, SLOT29f, SLOT30f, SLOT31f
    868 };
    869 
    870 static soc_reg_t mmu_ovs_group_wt_regs_local[2][_MMU_OVS_WT_GROUP_COUNT] = {
    871     {
    872         ES_PIPE0_OVR_SUB_GRP0_WTr, ES_PIPE0_OVR_SUB_GRP1_WTr,
    873         ES_PIPE0_OVR_SUB_GRP2_WTr, ES_PIPE0_OVR_SUB_GRP3_WTr
    874     },
    875     {
    876         ES_PIPE1_OVR_SUB_GRP0_WTr, ES_PIPE1_OVR_SUB_GRP1_WTr,
    877         ES_PIPE1_OVR_SUB_GRP2_WTr, ES_PIPE1_OVR_SUB_GRP3_WTr
    878     }
    879 };
    880 
    881 static const soc_reg_t td2_pgw_obm_ctrl_regs[] = {
    882     PGW_OBM0_CONTROLr, PGW_OBM1_CONTROLr,
    883     PGW_OBM2_CONTROLr, PGW_OBM3_CONTROLr
    884 };
    885 
    886 static const soc_field_t td2_pgw_obm_bypass_fields[] = {
    887     PORT0_BYPASS_ENABLEf, PORT1_BYPASS_ENABLEf,
    888     PORT2_BYPASS_ENABLEf, PORT3_BYPASS_ENABLEf
    889 };
    890 
    891 static const soc_field_t td2_pgw_obm_oversub_fields[] = {
    892     PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf,
    893     PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf
    894 };
    895 
    896 static const soc_reg_t td2_pgw_obm_threshold_regs[] = {
    897     PGW_OBM0_THRESHOLDr, PGW_OBM1_THRESHOLDr,
    898     PGW_OBM2_THRESHOLDr, PGW_OBM3_THRESHOLDr
    899 };
    900 
    901 static const soc_reg_t td2_pgw_obm_priority_map_regs[] = {
    902     PGW_OBM0_PRIORITY_MAPr, PGW_OBM1_PRIORITY_MAPr,
    903     PGW_OBM2_PRIORITY_MAPr, PGW_OBM3_PRIORITY_MAPr
    904 };
    905 
    906 static const soc_reg_t td2_pgw_obm_use_counter_regs[] = {
    907     PGW_OBM0_USE_COUNTERr, PGW_OBM1_USE_COUNTERr,
    908     PGW_OBM2_USE_COUNTERr, PGW_OBM3_USE_COUNTERr
    909 };
    910 
    911 static const soc_field_t td2_pgw_obm_use_count_fields[] = {
    912     PORT0_USE_COUNTf, PORT1_USE_COUNTf,
    913     PORT2_USE_COUNTf, PORT3_USE_COUNTf
    914 };
    915 
    916 static const soc_reg_t td2_pgw_obm_max_usage_regs[] = {
    917     PGW_OBM0_MAX_USAGEr, PGW_OBM1_MAX_USAGEr,
    918     PGW_OBM2_MAX_USAGEr, PGW_OBM3_MAX_USAGEr
    919 };
    920 
    921 static const soc_field_t td2_pgw_obm_max_usage_fields[] = {
    922     PORT0_MAX_USAGEf, PORT1_MAX_USAGEf,
    923     PORT2_MAX_USAGEf, PORT3_MAX_USAGEf
    924 };
    925 
    926 static const soc_reg_t td2_pgw_obm_shared_config_regs[] = {
    927     PGW_OBM0_SHARED_CONFIGr, PGW_OBM1_SHARED_CONFIGr,
    928     PGW_OBM2_SHARED_CONFIGr, PGW_OBM3_SHARED_CONFIGr
    929 };
    930 
    931 static const soc_reg_t td2_pgw_obm_fc_config_regs[] = {
    932     PGW_OBM_PORT0_FC_CONFIGr, PGW_OBM_PORT1_FC_CONFIGr,
    933     PGW_OBM_PORT2_FC_CONFIGr, PGW_OBM_PORT3_FC_CONFIGr,
    934     PGW_OBM_PORT4_FC_CONFIGr, PGW_OBM_PORT5_FC_CONFIGr,
    935     PGW_OBM_PORT6_FC_CONFIGr, PGW_OBM_PORT7_FC_CONFIGr,
    936     PGW_OBM_PORT8_FC_CONFIGr, PGW_OBM_PORT9_FC_CONFIGr,
    937     PGW_OBM_PORT10_FC_CONFIGr, PGW_OBM_PORT11_FC_CONFIGr,
    938     PGW_OBM_PORT12_FC_CONFIGr, PGW_OBM_PORT13_FC_CONFIGr,
    939     PGW_OBM_PORT14_FC_CONFIGr, PGW_OBM_PORT15_FC_CONFIGr
    940 };
    941 
    942 static soc_ser_functions_t _td2_ser_functions;
    943 
    944 uint8 _soc_alpm_mode[SOC_MAX_NUM_DEVICES];
    945 
    946 static const int a1_freq_list[]      = { 760, 660, 608, 518, 415 };
    947 static const int a2_793_freq_list[]  = { 793, 760, 635, 537, 415 };
    948 static const int a2_635_freq_list[]  = { 635, 608, 537, 518, 415 };
    949 static const int a1_td2p_freq_list[] = { 793, 760, 635, 537, 421 };
    950 
    951 
    952 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    953 mmu_ovs_group_regs_t
    954 soc_trident2_mmu_ovs_group_regs_get (int unit)
    955 {
    956     return mmu_ovs_group_regs;
    957 }
    958 
    959 mmu_ovs_group_wt_select_regs_t
    960 soc_trident2_mmu_ovs_group_wt_select_regs_get (int unit)
    961 {
    962     return mmu_ovs_group_wt_select_regs;
    963 }
    964 
    965 pgw_ovs_tdm_regs_t
    966 soc_trident2_pgw_ovs_tdm_regs_get (int unit)
    967 {
    968     return pgw_ovs_tdm_regs;
    969 }
    970 
    971 pgw_ovs_spacing_regs_t
    972 soc_trident2_pgw_ovs_spacing_regs_get (int unit)
    973 {
    974     return pgw_ovs_spacing_regs;
    975 }
    976 
    977 pgw_obm_threshold_regs_t
    978 soc_trident2_pgw_obm_threshold_regs_get (int unit)
    979 {
    980     return td2_pgw_obm_threshold_regs;
    981 }
    982 
    983 pgw_tdm_fields_t
    984 soc_trident2_pgw_tdm_fields_get (int unit)
    985 {
    986     return pgw_tdm_fields;
    987 }
    988 
    989 pgw_spacing_fields_t
    990 soc_trident2_pgw_spacing_fields_get (int unit)
    991 {
    992     return pgw_spacing_fields;
    993 }
    994 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
    995 
    996 int
    997 soc_trident2_pipe_select(int unit, int egress, int pipe)
    998 {
    999     soc_reg_t reg;
   1000 
   1001     reg = egress ? EGR_SBS_CONTROLr : SBS_CONTROLr;
   1002     return soc_reg_field32_modify(unit, reg, REG_PORT_ANY, PIPE_SELECTf, pipe);
   1003 }
   1004 
   1005 STATIC int
   1006 _soc_trident2_ser_enable_info(int unit, int block_info_idx, int inst, int port,
   1007                               soc_reg_t group_reg, uint64 *group_rval,
   1008                               const _soc_td2_ser_info_t *info_list,
   1009                               soc_mem_t mem, int enable);
   1010 STATIC int
   1011 soc_trident2_ser_enable_by_acctype(int unit, soc_reg_t reg,
   1012                                                 soc_field_t field, int enable,
   1013                                                 int egress);
   1014 
   1015 
   1016 enum _td2p_ovs_wt_speed_group {
   1017     td2p_ovs_wt_group_speed_10G,
   1018     td2p_ovs_wt_group_speed_20G,
   1019     td2p_ovs_wt_group_speed_40G,
   1020     td2p_ovs_wt_group_speed_NA
   1021 };
   1022 
   1023 /*
   1024  * MMU SER control data for Trident2 chip, this array only include the memories
   1025  * which are protected by ECC logic And whose SER_RESPONSE equal SER_NONE
   1026  */
   1027 STATIC
   1028 _soc_mem_ser_en_info_t _soc_trident2_mmu_ecc_mem_ser_info[] = {
   1029     /* MMU_CCP_EN_COR_ERR_RPTr */
   1030     { MMU_CCP0_RESEQ_MEMm, {{PARITY_ENr}, 0, CCP_PARITY_ENf, -1}, {{MMU_CCP_EN_COR_ERR_RPTr}, 0, CCP0_RESEQf, -1} },
   1031     { MMU_CCP1_RESEQ_MEMm, {{PARITY_ENr}, 0, CCP_PARITY_ENf, -1}, {{MMU_CCP_EN_COR_ERR_RPTr}, 0, CCP1_RESEQf, -1} },
   1032     { MMU_CCP_MEMm, {{PARITY_ENr}, 0, CCP_PARITY_ENf, -1}, {{MMU_CCP_EN_COR_ERR_RPTr}, 0, CCP_MEMf, -1} },
   1033 
   1034     /* MMU_CFAP_EN_COR_ERR_RPTr */
   1035     { MMU_CFAP_BANK0m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK0f, -1} },
   1036     { MMU_CFAP_BANK1m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK1f, -1} },
   1037     { MMU_CFAP_BANK2m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK2f, -1} },
   1038     { MMU_CFAP_BANK3m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK3f, -1} },
   1039     { MMU_CFAP_BANK4m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK4f, -1} },
   1040     { MMU_CFAP_BANK5m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK5f, -1} },
   1041     { MMU_CFAP_BANK6m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK6f, -1} },
   1042     { MMU_CFAP_BANK7m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK7f, -1} },
   1043     { MMU_CFAP_BANK8m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK8f, -1} },
   1044     { MMU_CFAP_BANK9m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK9f, -1} },
   1045     { MMU_CFAP_BANK10m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK10f, -1} },
   1046     { MMU_CFAP_BANK11m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK11f, -1} },
   1047     { MMU_CFAP_BANK12m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK12f, -1} },
   1048     { MMU_CFAP_BANK13m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK13f, -1} },
   1049     { MMU_CFAP_BANK14m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK14f, -1} },
   1050     { MMU_CFAP_BANK15m, {{PARITY_ENr}, 0, CFAP_PARITY_ENf, -1}, {{MMU_CFAP_EN_COR_ERR_RPTr}, 0, CFAP_BANK15f, -1} },
   1051 
   1052     /* MMU_DEQ_EN_COR_ERR_RPTr */
   1053     { MMU_PKTHDRm, {{PARITY_ENr}, 0, DEQ_PARITY_ENf, -1}, {{MMU_DEQ_EN_COR_ERR_RPTr}, 0, PKTHDRf, -1} },
   1054     { MMU_PORTCNTm, {{PARITY_ENr}, 0, DEQ_PARITY_ENf, -1}, {{MMU_DEQ_EN_COR_ERR_RPTr}, 0, PORTCNTf, -1} },
   1055     { MMU_REPL_STATE_TBL_PIPE1m, {{PARITY_ENr}, 0, DEQ_PARITY_ENf, -1}, {{MMU_DEQ_EN_COR_ERR_RPTr}, 0, REPL_STATE_TBL_PIPE1f, -1} },
   1056     { MMU_REPL_STATE_TBL_PIPE0m, {{PARITY_ENr}, 0, DEQ_PARITY_ENf, -1}, {{MMU_DEQ_EN_COR_ERR_RPTr}, 0, REPL_STATE_TBL_PIPE0f, -1} },
   1057 
   1058     /* MMU_PQE_EN_COR_ERR_RPTr */
   1059     { MMU_PQE0_MEMm, {{PARITY_ENr}, 0, PQE_PARITY_ENf, -1}, {{MMU_PQE_EN_COR_ERR_RPTr}, 0, PQE0f, -1} },
   1060     { MMU_PQE1_MEMm, {{PARITY_ENr}, 0, PQE_PARITY_ENf, -1}, {{MMU_PQE_EN_COR_ERR_RPTr}, 0, PQE1f, -1} },
   1061 
   1062     /* THDI_EN_COR_ERR_RPTr */
   1063     { THDI_PORT_PG_CNTRS_RT1_Xm, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_RT1_ERR_DET_EN_PIPEXf, -1} },
   1064     { THDI_PORT_PG_CNTRS_RT2_Xm, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_RT2_ERR_DET_EN_PIPEXf, -1} },
   1065     { THDI_PORT_PG_CNTRS_SH1_Xm, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_SH1_ERR_DET_EN_PIPEXf, -1} },
   1066     { THDI_PORT_PG_CNTRS_SH2_Xm, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_SH2_ERR_DET_EN_PIPEXf, -1} },
   1067     { THDI_PORT_SP_CNTRS_RT_Xm, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTSP_CNTR_RT_ERR_DET_EN_PIPEXf, -1} },
   1068     { THDI_PORT_SP_CNTRS_SH_Xm, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTSP_CNTR_SH_ERR_DET_EN_PIPEXf, -1} },
   1069     { THDI_PORT_PG_CNTRS_RT1_Ym, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_RT1_ERR_DET_EN_PIPEYf, -1} },
   1070     { THDI_PORT_PG_CNTRS_RT2_Ym, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_RT2_ERR_DET_EN_PIPEYf, -1} },
   1071     { THDI_PORT_PG_CNTRS_SH1_Ym, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_SH1_ERR_DET_EN_PIPEYf, -1} },
   1072     { THDI_PORT_PG_CNTRS_SH2_Ym, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTPG_CNTR_SH2_ERR_DET_EN_PIPEYf, -1} },
   1073     { THDI_PORT_SP_CNTRS_RT_Ym, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTSP_CNTR_RT_ERR_DET_EN_PIPEYf, -1} },
   1074     { THDI_PORT_SP_CNTRS_SH_Ym, {{PARITY_ENr}, 0, THDI_PARITY_ENf, -1}, {{THDI_EN_COR_ERR_RPTr}, 0, THDI_PTSP_CNTR_SH_ERR_DET_EN_PIPEYf, -1} },
   1075 
   1076     /* MMU_THDU_EN_COR_ERR_RPTr */
   1077     { MMU_THDU_XPIPE_COUNTER_QUEUEm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_COUNTER_QUEUEf, -1} },
   1078     { MMU_THDU_XPIPE_COUNTER_QGROUPm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_COUNTER_QGROUPf, -1} },
   1079     { MMU_THDU_XPIPE_COUNTER_PORTm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_COUNTER_PORTf, -1} },
   1080     { MMU_THDU_XPIPE_BST_QUEUEm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_BST_QUEUEf, -1} },
   1081     { MMU_THDU_XPIPE_BST_QGROUPm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_BST_QGROUPf, -1} },
   1082     { MMU_THDU_XPIPE_BST_PORTm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_BST_PORTf, -1} },
   1083     { MMU_THDU_XPIPE_RESUME_QUEUEm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_RESUME_QUEUEf, -1} },
   1084     { MMU_THDU_XPIPE_RESUME_QGROUPm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_RESUME_QGROUPf, -1} },
   1085     { MMU_THDU_YPIPE_COUNTER_QUEUEm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_COUNTER_QUEUEf, -1} },
   1086     { MMU_THDU_YPIPE_COUNTER_QGROUPm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_COUNTER_QGROUPf, -1} },
   1087     { MMU_THDU_YPIPE_COUNTER_PORTm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_COUNTER_PORTf, -1} },
   1088     { MMU_THDU_YPIPE_BST_QUEUEm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_BST_QUEUEf, -1} },
   1089     { MMU_THDU_YPIPE_BST_QGROUPm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_BST_QGROUPf, -1} },
   1090     { MMU_THDU_YPIPE_BST_PORTm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_BST_PORTf, -1} },
   1091     { MMU_THDU_YPIPE_RESUME_QUEUEm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_RESUME_QUEUEf, -1} },
   1092     { MMU_THDU_YPIPE_RESUME_QGROUPm, {{PARITY_ENr}, 0, THDU_PARITY_ENf, -1}, {{MMU_THDU_EN_COR_ERR_RPTr}, 0, MMU_THDU_RESUME_QGROUPf, -1} },
   1093 
   1094     /* MMU_TOQ_EN_COR_ERR_RPTr */
   1095     { MMU_CELL_LINKm, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, CELL_LINKf, -1} },
   1096     { MMU_PDB1m, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, PDB1f, -1} },
   1097     { MMU_PDB0m, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, PDB0f, -1} },
   1098     { MMU_MCQDB1m, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, MCQDB1f, -1} },
   1099     { MMU_MCQDB0m, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, MCQDB0f, -1} },
   1100     { MMU_UCQDB1m, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, UCQDB1f, -1} },
   1101     { MMU_UCQDB0m, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, UCQDB0f, -1} },
   1102     { MMU_MCFPm, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, MCFPf, -1} },
   1103     { MMU_MCQEm, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, MCQEf, -1} },
   1104     { MMU_MCQNm, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, MCQNf, -1} },
   1105     { MMU_PKT_LINKm, {{PARITY_ENr}, 0, TOQ_PARITY_ENf, -1}, {{MMU_TOQ_EN_COR_ERR_RPTr}, 0, PKT_LINKf, -1} },
   1106 
   1107     /* MMU_QCN_EN_COR_ERR_RPTr */
   1108     { MMU_QCN_CNM_QUEUE0m, {{PARITY_ENr}, 0, QCN_PARITY_ENf, -1}, {{MMU_QCN_EN_COR_ERR_RPTr}, 0, CNM_QUEUE0f, -1} },
   1109     { MMU_QCN_CNM_QUEUE1m, {{PARITY_ENr}, 0, QCN_PARITY_ENf, -1}, {{MMU_QCN_EN_COR_ERR_RPTr}, 0, CNM_QUEUE1f, -1} },
   1110 
   1111     /* ES_PIPE0_LLS_EN_COR_ERR_RPT_1r */
   1112     { ES_PIPE0_LLS_PORT_PARENT_STATEm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, PORT_PARENT_STATEf, -1} },
   1113     { ES_PIPE0_LLS_PORT_HEADS_TAILSm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, PORT_HEADS_TAILSf, -1} },
   1114     { ES_PIPE0_LLS_PORT_WERR_MAX_SCm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, PORT_WERR_MAX_SCf, -1} },
   1115     { ES_PIPE0_LLS_L0_PARENT_STATEm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_PARENT_STATEf, -1} },
   1116     { ES_PIPE0_LLS_L0_HEADS_TAILSm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_HEADS_TAILSf, -1} },
   1117     { ES_PIPE0_LLS_L0_WERR_MAX_SCm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_WERR_MAX_SCf, -1} },
   1118     { ES_PIPE0_LLS_L0_ERRORm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_ERRORf, -1} },
   1119     { ES_PIPE0_LLS_L0_CHILD_STATE1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_CHILD_STATE1f, -1} },
   1120     { ES_PIPE0_LLS_L0_CHILD_WEIGHT_WORKINGm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_CHILD_WEIGHT_WORKINGf, -1} },
   1121     { ES_PIPE0_LLS_L0_MIN_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_MIN_NEXTf, -1} },
   1122     { ES_PIPE0_LLS_L0_WERR_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_WERR_NEXTf, -1} },
   1123     { ES_PIPE0_LLS_L0_XOFFm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_1r}, 0, L0_XOFFf, -1} },
   1124 
   1125     /* ES_PIPE0_LLS_EN_COR_ERR_RPT_2r */
   1126     { ES_PIPE0_LLS_L1_PARENT_STATEm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_PARENT_STATEf, -1} },
   1127     { ES_PIPE0_LLS_L1_HEADS_TAILSm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_HEADS_TAILSf, -1} },
   1128     { ES_PIPE0_LLS_L1_WERR_MAX_SCm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_WERR_MAX_SCf, -1} },
   1129     { ES_PIPE0_LLS_L1_ERRORm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_ERRORf, -1} },
   1130     { ES_PIPE0_LLS_L1_CHILD_STATE1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_CHILD_STATE1f, -1} },
   1131     { ES_PIPE0_LLS_L1_CHILD_WEIGHT_WORKINGm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_CHILD_WEIGHT_WORKINGf, -1} },
   1132     { ES_PIPE0_LLS_L1_MIN_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_MIN_NEXTf, -1} },
   1133     { ES_PIPE0_LLS_L1_WERR_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_WERR_NEXTf, -1} },
   1134     { ES_PIPE0_LLS_L1_XOFFm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L1_XOFFf, -1} },
   1135     { ES_PIPE0_LLS_L2_ERRORm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L2_ERRORf, -1} },
   1136     { ES_PIPE0_LLS_L2_CHILD_STATE1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L2_CHILD_STATE1f, -1} },
   1137     { ES_PIPE0_LLS_L2_CHILD_WEIGHT_WORKINGm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L2_CHILD_WEIGHT_WORKINGf, -1} },
   1138     { ES_PIPE0_LLS_L2_MIN_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L2_MIN_NEXTf, -1} },
   1139     { ES_PIPE0_LLS_L2_WERR_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L2_WERR_NEXTf, -1} },
   1140     { ES_PIPE0_LLS_L2_XOFFm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE0_LLS_EN_COR_ERR_RPT_2r}, 0, L2_XOFFf, -1} },
   1141 
   1142     /* ES_PIPE1_LLS_EN_COR_ERR_RPT_1r */
   1143     { ES_PIPE1_LLS_PORT_PARENT_STATEm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, PORT_PARENT_STATEf, -1} },
   1144     { ES_PIPE1_LLS_PORT_HEADS_TAILSm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, PORT_HEADS_TAILSf, -1} },
   1145     { ES_PIPE1_LLS_PORT_WERR_MAX_SCm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, PORT_WERR_MAX_SCf, -1} },
   1146     { ES_PIPE1_LLS_L0_PARENT_STATEm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_PARENT_STATEf, -1} },
   1147     { ES_PIPE1_LLS_L0_HEADS_TAILSm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_HEADS_TAILSf, -1} },
   1148     { ES_PIPE1_LLS_L0_WERR_MAX_SCm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_WERR_MAX_SCf, -1} },
   1149     { ES_PIPE1_LLS_L0_ERRORm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_ERRORf, -1} },
   1150     { ES_PIPE1_LLS_L0_CHILD_STATE1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_CHILD_STATE1f, -1} },
   1151     { ES_PIPE1_LLS_L0_CHILD_WEIGHT_WORKINGm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_CHILD_WEIGHT_WORKINGf, -1} },
   1152     { ES_PIPE1_LLS_L0_MIN_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_MIN_NEXTf, -1} },
   1153     { ES_PIPE1_LLS_L0_WERR_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_WERR_NEXTf, -1} },
   1154     { ES_PIPE1_LLS_L0_XOFFm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_1r}, 0, L0_XOFFf, -1} },
   1155 
   1156     /* ES_PIPE1_LLS_EN_COR_ERR_RPT_2r */
   1157     { ES_PIPE1_LLS_L1_PARENT_STATEm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_PARENT_STATEf, -1} },
   1158     { ES_PIPE1_LLS_L1_HEADS_TAILSm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_HEADS_TAILSf, -1} },
   1159     { ES_PIPE1_LLS_L1_WERR_MAX_SCm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_WERR_MAX_SCf, -1} },
   1160     { ES_PIPE1_LLS_L1_ERRORm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_ERRORf, -1} },
   1161     { ES_PIPE1_LLS_L1_CHILD_STATE1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_CHILD_STATE1f, -1} },
   1162     { ES_PIPE1_LLS_L1_CHILD_WEIGHT_WORKINGm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_CHILD_WEIGHT_WORKINGf, -1} },
   1163     { ES_PIPE1_LLS_L1_MIN_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_MIN_NEXTf, -1} },
   1164     { ES_PIPE1_LLS_L1_WERR_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_WERR_NEXTf, -1} },
   1165     { ES_PIPE1_LLS_L1_XOFFm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L1_XOFFf, -1} },
   1166     { ES_PIPE1_LLS_L2_ERRORm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L2_ERRORf, -1} },
   1167     { ES_PIPE1_LLS_L2_CHILD_STATE1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L2_CHILD_STATE1f, -1} },
   1168     { ES_PIPE1_LLS_L2_CHILD_WEIGHT_WORKINGm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L2_CHILD_WEIGHT_WORKINGf, -1} },
   1169     { ES_PIPE1_LLS_L2_MIN_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L2_MIN_NEXTf, -1} },
   1170     { ES_PIPE1_LLS_L2_WERR_NEXTm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L2_WERR_NEXTf, -1} },
   1171     { ES_PIPE1_LLS_L2_XOFFm, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{ES_PIPE1_LLS_EN_COR_ERR_RPT_2r}, 0, L2_XOFFf, -1} },
   1172 
   1173     /* HSP_EN_COR_ERR_RPTr */
   1174     { HSP_SCHED_L2_ACCUM_COMP_MEM_0m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L2_ACCUM_COMP_MEM_0f, -1} },
   1175     { HSP_SCHED_L2_CREDIT_MEM_0m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L2_CREDITMEM_0f, -1} },
   1176     { HSP_SCHED_L1_ACCUM_COMP_MEM_0m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L1_ACCUM_COMP_MEM_0f, -1} },
   1177     { HSP_SCHED_L1_CREDIT_MEM_0m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L1_CREDITMEM_0f, -1} },
   1178     { HSP_SCHED_L0_ACCUM_COMP_MEM_0m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L0_ACCUM_COMP_MEM_0f, -1} },
   1179     { HSP_SCHED_L0_CREDIT_MEM_0m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L0_CREDITMEM_0f, -1} },
   1180     { HSP_SCHED_L2_ACCUM_COMP_MEM_1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L2_ACCUM_COMP_MEM_1f, -1} },
   1181     { HSP_SCHED_L2_CREDIT_MEM_1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L2_CREDITMEM_1f, -1} },
   1182     { HSP_SCHED_L1_ACCUM_COMP_MEM_1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L1_ACCUM_COMP_MEM_1f, -1} },
   1183     { HSP_SCHED_L1_CREDIT_MEM_1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L1_CREDITMEM_1f, -1} },
   1184     { HSP_SCHED_L0_ACCUM_COMP_MEM_1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L0_ACCUM_COMP_MEM_1f, -1} },
   1185     { HSP_SCHED_L0_CREDIT_MEM_1m, {{PARITY_ENr}, 0, ES_PARITY_ENf, -1}, {{HSP_EN_COR_ERR_RPTr}, 0, L0_CREDITMEM_1f, -1} },
   1186 
   1187     /* MMU_THDM_DB_EN_COR_ERR_RPTr */
   1188     { MMU_THDM_DB_QUEUE_RESUME_1m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_DB_EN_COR_ERR_RPTr}, 0, QUEUE_RESUME_1f, -1} },
   1189     { MMU_THDM_DB_QUEUE_RESUME_0m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_DB_EN_COR_ERR_RPTr}, 0, QUEUE_RESUME_0f, -1} },
   1190     { MMU_THDM_DB_QUEUE_COUNT_1m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_DB_EN_COR_ERR_RPTr}, 0, QUEUE_COUNT_1f, -1} },
   1191     { MMU_THDM_DB_QUEUE_COUNT_0m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_DB_EN_COR_ERR_RPTr}, 0, QUEUE_COUNT_0f, -1} },
   1192 
   1193     /* MMU_THDM_MCQE_EN_COR_ERR_RPTr */
   1194     { MMU_THDM_MCQE_QUEUE_RESUME_1m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_MCQE_EN_COR_ERR_RPTr}, 0, QUEUE_RESUME_1f, -1} },
   1195     { MMU_THDM_MCQE_QUEUE_RESUME_0m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_MCQE_EN_COR_ERR_RPTr}, 0, QUEUE_RESUME_0f, -1} },
   1196     { MMU_THDM_MCQE_QUEUE_COUNT_1m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_MCQE_EN_COR_ERR_RPTr}, 0, QUEUE_COUNT_1f, -1} },
   1197     { MMU_THDM_MCQE_QUEUE_COUNT_0m, {{PARITY_ENr}, 0, THDM_PARITY_ENf, -1}, {{MMU_THDM_MCQE_EN_COR_ERR_RPTr}, 0, QUEUE_COUNT_0f, -1} },
   1198 
   1199     /* MMU_EPRG_EN_COR_ERR_RPTr */
   1200     { MMU_EPRG_MEMm, {{PARITY_ENr}, 0, EPRG_PARITY_ENf, -1}, {{MMU_EPRG_EN_COR_ERR_RPTr}, 0, EPRG_MEMf, -1} },
   1201 
   1202     /* MMU_ENQ_EN_COR_ERR_RPTr */
   1203     { MMU_ENQ_PBI_DBm, {{PARITY_ENr}, 0, ENQ_PARITY_ENf, -1}, {{MMU_ENQ_EN_COR_ERR_RPTr}, 0, SOP_INFO0f, -1} },
   1204 
   1205     /* RQE_EN_COR_ERR_RPTr */
   1206     { REPLICATION_FIFO_BANK0m, {{PARITY_ENr}, 0, RQE_PARITY_ENf, -1}, {{RQE_EN_COR_ERR_RPTr}, 0, RFf, -1} },
   1207     { REPLICATION_FIFO_BANK1m, {{PARITY_ENr}, 0, RQE_PARITY_ENf, -1}, {{RQE_EN_COR_ERR_RPTr}, 0, RFf, -1} },
   1208     { RQE_FREE_LISTm, {{PARITY_ENr}, 0, RQE_PARITY_ENf, -1}, {{RQE_EN_COR_ERR_RPTr}, 0, FLf, -1} },
   1209     { RQE_LINK_LISTm, {{PARITY_ENr}, 0, RQE_PARITY_ENf, -1}, {{RQE_EN_COR_ERR_RPTr}, 0, LLf, -1} },
   1210 
   1211     { INVALIDm } /* end */
   1212 };
   1213 
   1214 
   1215 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   1216 static int _mmu_16_mode = 0;
   1217 
   1218 #ifdef BCM_56860_A0
   1219 /* These are now generated from the regsfile processing into bcm56860_a0.c */
   1220 extern _soc_mem_ser_en_info_t _soc_bcm56860_a0_ip_mem_ser_info[];
   1221 extern _soc_reg_ser_en_info_t _soc_bcm56860_a0_ip_reg_ser_info[];
   1222 extern _soc_mem_ser_en_info_t _soc_bcm56860_a0_ep_mem_ser_info[];
   1223 extern _soc_reg_ser_en_info_t _soc_bcm56860_a0_ep_reg_ser_info[];
   1224 extern _soc_mem_ser_en_info_t _soc_bcm56860_a0_mmu_mem_ser_info[];
   1225 /* Above structures are defined in chip.h */
   1226 #endif
   1227 
   1228 /* Setup dynamically in enable ser */
   1229 static uint32 _soc_td2p_ip_pipe_fifo_bmask[SOC_MAX_NUM_DEVICES][2];
   1230 
   1231 _soc_bus_buffer_ser_force_info_t _soc_bcm56860_a0_bus_buffer_ser_force_info[] = {
   1232     { "IPARS_BUS", IPARS_SER_CONTROLr, IPARS_FORCE_ERRORf },
   1233     { "IVXLT_BUS", IVXLT_SER_CONTROLr, IVXLT_BUS_PARITY_FORCE_ERRORf },
   1234     { "MPLS_BUS", MPLS_SER_CONTROLr, MPLS_BUS_CORRUPT_ENf },
   1235     { "IRSEL1_BUS", IRSEL1_SER_CONTROLr, IRSEL1_BUS_PARITY_FORCE_ERRORf },
   1236     { "ISW1_BUS", ISW1_SER_CONTROLr, ISW1_BUS_PARITY_FORCE_ERRORf },
   1237     { "IFP_BUS", IFP_PARITY_CONTROLr, IFP_BUS_PARITY_FORCE_ERRORf },
   1238     { "IRSEL2_BUS", IRSEL2_SER_CONTROLr, IRSEL2_BUS_PARITY_FORCE_ERRORf },
   1239     { "IL2L3_BUS", IL2L3_BUS_SER_CONTROLr, FORCE_ERRORf },
   1240     { "VP_BUS", VP_SER_CONTROLr, VP_BUS_CORRUPT_ENf },
   1241     { "EP_INITBUF", EGR_EL3_ECC_PARITY_CONTROLr, EP_INITBUF_ECC_CORRUPTf },
   1242     { "EFP_BUS", EFP_PARITY_CONTROLr, EFP_BUS_PARITY_FORCE_ERRORf },
   1243     { "EVLAN_BUS", EGR_VLAN_SER_CONTROLr, EVLAN_FORCE_ERRORf },
   1244     { "EHCPM_BUS", EGR_EHCPM_SER_CONTROLr, EHCPM_FORCE_ERRORf },
   1245     { "EPMOD_BUS", EGR_EPMOD_SER_CONTROLr, EPMOD_FORCE_ERRORf },
   1246     { "EFPPARS_BUS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_FORCE_ERRORf },
   1247     { "", INVALIDr } /* end */
   1248 };
   1249 
   1250 _soc_bus_buffer_ser_force_info_t ser_td2p_bus_buffer_skip_test[] = {
   1251     { "EHCPM_BUS", EGR_EHCPM_SER_CONTROLr, EHCPM_FORCE_ERRORf },
   1252     { "EPMOD_BUS", EGR_EPMOD_SER_CONTROLr, EPMOD_FORCE_ERRORf },
   1253     { "EFPPARS_BUS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_FORCE_ERRORf },
   1254     { "", INVALIDr } /* end */
   1255 };
   1256 
   1257 uint32 ser_td2p_bus_buffer_hwbase[] = {
   1258     0x90, /* IPARS_BUS */
   1259     0x91, /* IVXLT_BUS */
   1260     0x92, /* MPLS_BUS */
   1261     0x96, /* IRSEL1_BUS */
   1262     0x97, /* ISW1_BUS */
   1263     0x95, /* IFP_BUS */
   1264     0x98, /* IRSEL2_BUS */
   1265     0x93, /* IL2L3_BUS */
   1266     0x85, /* VP_BUS */
   1267     0x11, /* EP_INITBUF */
   1268     0x84, /* EFP_BUS */
   1269     0x80, /* EVLAN_BUS */
   1270     0x81, /* EHCPM_BUS */
   1271     0x82, /* EPMOD_BUS */
   1272     0x83  /* EFPPARS_BUS */
   1273 };
   1274 
   1275 _soc_bus_ser_en_info_t _soc_ep_bus_ser_info [] = {
   1276     { "EFP",     EFP_PARITY_CONTROLr,      EFP_BUS_PARITY_ENf     },
   1277     { "EFPPARS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_BUS_PARITY_ENf },
   1278     { "EHCPM",   EGR_EHCPM_SER_CONTROLr,   EHCPM_BUS_PARITY_ENf },
   1279     { "EPMOD",   EGR_EPMOD_SER_CONTROLr,   EPMOD_BUS_PARITY_ENf },
   1280     { "EVLAN",   EGR_VLAN_SER_CONTROLr,    EVLAN_BUS_PARITY_ENf },
   1281     { "", INVALIDr } /* end */
   1282 };
   1283 
   1284 _soc_buffer_ser_en_info_t _soc_ep_buffer_ser_info[] = {
   1285     { "INITBUF", EGR_EL3_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf },
   1286     { "EGR MPB",  EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf },
   1287     { "EDB_CM_MEM", EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf },
   1288     { "XLP15_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP15_ECC_ENf },
   1289     { "XLP14_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP14_ECC_ENf },
   1290     { "XLP13_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP13_ECC_ENf },
   1291     { "XLP12_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP12_ECC_ENf },
   1292     { "XLP11_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP11_ECC_ENf },
   1293     { "XLP10_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP10_ECC_ENf },
   1294     { "XLP9_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP9_ECC_ENf  },
   1295     { "XLP8_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP8_ECC_ENf  },
   1296     { "XLP7_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP7_ECC_ENf  },
   1297     { "XLP6_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP6_ECC_ENf  },
   1298     { "XLP5_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf  },
   1299     { "XLP4_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf  },
   1300     { "XLP3_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf  },
   1301     { "XLP2_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf  },
   1302     { "XLP1_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf  },
   1303     { "XLP0_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf  },
   1304     { "CLP3_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP3_ECC_ENf  },
   1305     { "CLP2_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP2_ECC_ENf  },
   1306     { "CLP1_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP1_ECC_ENf  },
   1307     { "CLP0_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP0_ECC_ENf  },
   1308     { "XLP_RESI_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP_RESI_BUFFER_PAR_ENf},
   1309     { "EP_XLP15_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP15_ECC_ENf },
   1310     { "EP_XLP14_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP14_ECC_ENf },
   1311     { "EP_XLP13_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP13_ECC_ENf },
   1312     { "EP_XLP12_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP12_ECC_ENf },
   1313     { "EP_XLP11_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP11_ECC_ENf },
   1314     { "EP_XLP10_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP10_ECC_ENf },
   1315     { "EP_XLP9__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP9_ECC_ENf  },
   1316     { "EP_XLP8__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP8_ECC_ENf  },
   1317     { "EP_XLP7__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP7_ECC_ENf  },
   1318     { "EP_XLP6__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP6_ECC_ENf  },
   1319     { "EP_XLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP5_ECC_ENf  },
   1320     { "EP_XLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP4_ECC_ENf  },
   1321     { "EP_XLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP3_ECC_ENf  },
   1322     { "EP_XLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP2_ECC_ENf  },
   1323     { "EP_XLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP1_ECC_ENf  },
   1324     { "EP_XLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP0_ECC_ENf  },
   1325     { "EP_CLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP3_ECC_ENf  },
   1326     { "EP_CLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP2_ECC_ENf  },
   1327     { "EP_CLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP1_ECC_ENf  },
   1328     { "EP_CLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP0_ECC_ENf  },
   1329     { "XLP_RESI__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP_RESI_BUFFER_PAR_ENf},
   1330 
   1331 
   1332     { "", INVALIDr }
   1333 };
   1334 
   1335 
   1336 _soc_bus_ser_en_info_t _soc_ip_bus_ser_info [] = {
   1337     { "IPARS", IPARS_SER_CONTROLr, IPARS_BUS_PARITY_ENf },
   1338     { "IRSEL1", IRSEL1_SER_CONTROLr, IRSEL1_BUS_PARITY_ENf },
   1339     { "IRSEL2", IRSEL2_SER_CONTROLr, IRSEL2_BUS_PARITY_ENf },
   1340     { "ISW1", ISW1_SER_CONTROLr, ISW1_BUS_PARITY_ENf },
   1341     { "IVXLT", IVXLT_SER_CONTROLr, IVXLT_BUS_PARITY_ENf },
   1342     { "LEARN_FIFO", IARB_SER_CONTROLr, LEARN_FIFO_ECC_ENf },
   1343     { "MPLS", MPLS_SER_CONTROLr, MPLS_BUS_PAR_ENf, },
   1344     { "SW2_EOP_BUF_C", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_C_PARITY_ENf },
   1345     { "SW2_EOP_BUF_B", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_B_PARITY_ENf },
   1346     { "SW2_EOP_BUF_A", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_A_PARITY_ENf },
   1347     { "VP", VP_SER_CONTROLr, VP_BUS_PAR_ENf },
   1348     { "IFP", IFP_PARITY_CONTROLr, IFP_BUS_PARITY_ENf },
   1349     { "IL2L3", IL2L3_BUS_SER_CONTROLr, PARITY_ENf },
   1350     { "", INVALIDr } /* end */
   1351 };
   1352 
   1353 _soc_buffer_ser_en_info_t _soc_ip_buffer_ser_info[] = {
   1354     { "COUNTER_STAGING", IFP_PARITY_CONTROLr, COUNTER_MUX_DATA_STAGING_PARITY_ENf },
   1355     { "METER_STAGING", IFP_PARITY_CONTROLr, METER_MUX_DATA_STAGING_PARITY_ENf },
   1356     { "CMIC", IARB_SER_CONTROLr, CMIC_BUF_ECC_ENf },
   1357     { "IP STATS COUNTERS", ISW2_SER_CONTROL_1r, IP_COUNTERS_PARITY_ENf },
   1358     { "RDISC/RUC/RPORTD/RDBGC0", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST0_PARITY_ENf },
   1359     { "HG STATS COUNTERS", ISW2_SER_CONTROL_1r, HG_COUNTERS_PARITY_ENf },
   1360     { "RDBGC5/RDBGC6/RDBGC7/RDBGC8", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST2_PARITY_ENf },
   1361     { "RDBGC1/RDBGC2/RDBGC3/RDBGC4", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST1_PARITY_ENf },
   1362     { "ING_NIV_RX_FRAMES_ERRe", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_ERROR_DROP_PARITY_ENf },
   1363     { "ING_NIV_RX_FRAMES_FRWD", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_FORWARDING_DROP_PARITY_ENf },
   1364     { "ING_NIV_RX_FRAMES_VLAN", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_VLAN_TAGGED_PARITY_ENf },
   1365     { "ING_TRILL_RX_ACCESS", ISW2_SER_CONTROL_1r, ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_ENf },
   1366     { "ING_TRILL_RX_NETWORK_PORT", ISW2_SER_CONTROL_1r, ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_ENf },
   1367     { "ING_TRILL_RX_PKTS table", ISW2_SER_CONTROL_1r, ING_TRILL_RX_PKTS_PARITY_ENf },
   1368     { "DLB_HGT_FLOWSET_TIME", DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_ENf },
   1369     { "DLB_HGT_FLOWSET", DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_PARITY_ENf },
   1370 
   1371     { "", INVALIDr }
   1372 };
   1373 
   1374 _soc_buffer_ser_en_info_t _soc_mmu_buffer_ser_info[] = {
   1375     { "MMU EPRG", PARITY_ENr, EPRG_PARITY_ENf },
   1376     { "MMU PQE", PARITY_ENr, PQE_PARITY_ENf },
   1377     { "MMU WRED", PARITY_ENr, WRED_PARITY_ENf },
   1378     { "MMU CTR", PARITY_ENr, CTR_PARITY_ENf },
   1379 
   1380     { "", INVALIDr }
   1381 };
   1382 
   1383 typedef struct _soc_td2p_ser_block_info_s {
   1384     int         type;
   1385     soc_block_t blocktype;
   1386     char        name[16];
   1387     soc_reg_t   fifo_reset_reg;
   1388     void        *info;
   1389 } _soc_td2p_ser_block_info_t;
   1390 
   1391 static const
   1392 _soc_td2p_ser_block_info_t _soc_td2p_ser_block_info[] = {
   1393 #ifdef BCM_56860_A0
   1394     { _SOC_SER_TYPE_REG, SOC_BLK_IPIPE, "IPIPE regs", INVALIDr, _soc_bcm56860_a0_ip_reg_ser_info },
   1395     { _SOC_SER_TYPE_MEM, SOC_BLK_IPIPE, "IPIPE mems", ING_SER_FIFO_CTRLr, _soc_bcm56860_a0_ip_mem_ser_info },
   1396     { _SOC_SER_TYPE_BUS, SOC_BLK_EPIPE, "IPIPE buses",INVALIDr, _soc_ip_bus_ser_info },
   1397     { _SOC_SER_TYPE_BUF, SOC_BLK_EPIPE, "IPIPE buff" ,INVALIDr, _soc_ip_buffer_ser_info },
   1398     { _SOC_SER_TYPE_REG, SOC_BLK_EPIPE, "EPIPE regs", INVALIDr, _soc_bcm56860_a0_ep_reg_ser_info },
   1399     { _SOC_SER_TYPE_BUS, SOC_BLK_EPIPE, "EPIPE buses",INVALIDr, _soc_ep_bus_ser_info },
   1400     { _SOC_SER_TYPE_BUF, SOC_BLK_EPIPE, "EPIPE buff" ,INVALIDr, _soc_ep_buffer_ser_info },
   1401     { _SOC_SER_TYPE_MEM, SOC_BLK_EPIPE, "EPIPE mems", EGR_SER_FIFO_CTRLr, _soc_bcm56860_a0_ep_mem_ser_info },
   1402     { _SOC_SER_TYPE_MEM, SOC_BLK_MMU,   "MMU mems", INVALIDr, _soc_bcm56860_a0_mmu_mem_ser_info },
   1403     { _SOC_SER_TYPE_BUF, SOC_BLK_MMU,   "MMU buff", INVALIDr, _soc_mmu_buffer_ser_info },
   1404 #endif
   1405     { -1, 0 }
   1406 };
   1407 
   1408 int
   1409 _soc_trident2p_ser_enable_all(int unit, const _soc_td2p_ser_block_info_t *ser_block_info, int enable)
   1410 {
   1411     uint8                           rbi, bcount, type;
   1412     uint16                          pcount;
   1413     uint32                          cmic_rval;
   1414     uint32                          rval, cmic_bit;
   1415     uint32                          fld_val = 0;
   1416     int                             port = REG_PORT_ANY;
   1417     int                             phy_port, cport, slot_port, obm_slot;
   1418     int                             rv, block_info_idx;
   1419     uint64                          rval64;
   1420     soc_reg_t                       reg, ecc1b_reg;
   1421     soc_field_t                     field, ecc1b_field;
   1422     _soc_reg_ser_en_info_t          *reg_info;
   1423     _soc_mem_ser_en_info_t          *mem_info;
   1424     _soc_bus_ser_en_info_t          *bus_info;
   1425     _soc_buffer_ser_en_info_t       *buf_info;
   1426     char                            *str_type;
   1427     char                            *str_name;
   1428     const _soc_td2_ser_route_block_t *rb;
   1429     static char *parity_module_str[4] = {"REG", "MEM", "BUS", "BUF"};
   1430     soc_info_t *si = &SOC_INFO(unit);
   1431 
   1432     /* coverity[result_independent_of_operands] */
   1433     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK2r(unit, &cmic_rval));
   1434     /* Enable new fifo mechanism based SER stuff */
   1435     for (bcount = 0; ser_block_info[bcount].blocktype; bcount++) {
   1436         int done = 0;
   1437 
   1438         LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1439                    (BSL_META_U(unit,
   1440                                "Unit %d SER enable for: %s\n"),
   1441                                     unit, ser_block_info[bcount].name));
   1442 
   1443         type = ser_block_info[bcount].type;
   1444         reg_info = (_soc_reg_ser_en_info_t*)ser_block_info[bcount].info;
   1445         mem_info = (_soc_mem_ser_en_info_t*)ser_block_info[bcount].info;
   1446         bus_info = (_soc_bus_ser_en_info_t*)ser_block_info[bcount].info;
   1447         buf_info = (_soc_buffer_ser_en_info_t*)ser_block_info[bcount].info;
   1448         for (pcount = 0; ; pcount++) {
   1449             ecc1b_reg = INVALIDr;
   1450             ecc1b_field = INVALIDf;
   1451             switch (type) {
   1452             case _SOC_SER_TYPE_REG:
   1453                 if (reg_info[pcount].reg == INVALIDr) {
   1454                     done = 1;
   1455                 } else {
   1456                     reg = reg_info[pcount].en_ctrl.ctrl_type.en_reg;
   1457                     field = reg_info[pcount].en_ctrl.en_fld;
   1458                     str_name = SOC_REG_NAME(unit, reg_info[pcount].reg);
   1459                 }
   1460                 break;
   1461             case _SOC_SER_TYPE_MEM:
   1462                 if (mem_info[pcount].mem == INVALIDm) {
   1463                     done = 1;
   1464                 } else {
   1465                     if (soc_feature(unit, soc_feature_parity_injection_l2)) {
   1466                         if ((mem_info[pcount].mem == L2_USER_ENTRYm) ||
   1467                             (mem_info[pcount].mem == L2_USER_ENTRY_DATA_ONLYm)){
   1468                             continue;
   1469                         }
   1470                     }
   1471                     if (!SOC_MEM_IS_VALID(unit, mem_info[pcount].mem) ||
   1472                         (SOC_MEM_INFO(unit, mem_info[pcount].mem).flags &
   1473                          SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) {
   1474                         continue;
   1475                     }
   1476                     reg = mem_info[pcount].en_ctrl.ctrl_type.en_reg;
   1477                     field = mem_info[pcount].en_ctrl.en_fld;
   1478                     ecc1b_reg = mem_info[pcount].ecc1b_ctrl.ctrl_type.en_reg;
   1479                     ecc1b_field = mem_info[pcount].ecc1b_ctrl.en_fld;
   1480                     str_name = SOC_MEM_NAME(unit, mem_info[pcount].mem);
   1481                 }
   1482                 break;
   1483             case _SOC_SER_TYPE_BUS:
   1484                 if (bus_info[pcount].en_reg == INVALIDr) {
   1485                     done = 1;
   1486                 } else {
   1487                     reg = bus_info[pcount].en_reg;
   1488                     field = bus_info[pcount].en_fld;
   1489                     str_name = bus_info[pcount].bus_name;
   1490                 }
   1491                 break;
   1492             case _SOC_SER_TYPE_BUF:
   1493                 if (buf_info[pcount].en_reg == INVALIDr) {
   1494                     done = 1;
   1495                 } else {
   1496                     reg = buf_info[pcount].en_reg;
   1497                     field = buf_info[pcount].en_fld;
   1498                     str_name = buf_info[pcount].buffer_name;
   1499                     /* Do not enable this parity check for TD2+ because if DLB_HGT_FLOWSET_TIMESTAMP_PAGE_X/Y
   1500                        get corrupted, we DO NOT support SER and hardware will continue to send us interrupts */
   1501                     if(reg == DLB_HGT_SER_CONTROLr && field == DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_ENf) {
   1502                         continue;
   1503                     }
   1504                 }
   1505                 break;
   1506             default:
   1507                 LOG_ERROR(BSL_LS_SOC_MEM,
   1508                           (BSL_META_U(unit,
   1509                                       "Unknown parity module [bcount: %d][pcount: %d].\n"),
   1510                                        bcount, pcount));
   1511                 return SOC_E_INTERNAL;
   1512             }
   1513             if (done) {
   1514                 break;
   1515             } else {
   1516                 str_type = parity_module_str[type];
   1517             }
   1518             /* NOTE: Do not use the field modify routine in the following as
   1519                      some regs do not return the correct value due to which the
   1520                      modify routine skips the write */
   1521             if (enable) {
   1522                 if ((reg == IFP_PARITY_CONTROLr) &&
   1523                     (field == METER_MUX_DATA_STAGING_PARITY_ENf)) {
   1524                     fld_val = 0xff;
   1525                 } else {
   1526                     fld_val = 1;
   1527                 }
   1528             } else {
   1529                 fld_val = 0;
   1530             }
   1531             if (SOC_REG_IS_64(unit, reg)) {
   1532                 SOC_IF_ERROR_RETURN
   1533                     (soc_reg_get(unit, reg, port, 0, &rval64));
   1534                 soc_reg64_field32_set(unit, reg, &rval64, field, fld_val);
   1535                 SOC_IF_ERROR_RETURN
   1536                     (soc_reg_set(unit, reg, port, 0, rval64));
   1537             } else {
   1538                 SOC_IF_ERROR_RETURN
   1539                     (soc_reg32_get(unit, reg, port, 0, &rval));
   1540                 soc_reg_field_set(unit, reg, &rval, field, fld_val);
   1541                 SOC_IF_ERROR_RETURN
   1542                     (soc_reg32_set(unit, reg, port, 0, rval));
   1543             }
   1544             if (ecc1b_reg != INVALIDr && ecc1b_field != INVALIDf) {
   1545                 if (SOC_REG_IS_64(unit, ecc1b_reg)) {
   1546                     SOC_IF_ERROR_RETURN
   1547                         (soc_reg_get(unit, ecc1b_reg, port, 0, &rval64));
   1548                     soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, enable ? 1 : 0);
   1549                     SOC_IF_ERROR_RETURN
   1550                         (soc_reg_set(unit, ecc1b_reg, port, 0, rval64));
   1551                 } else {
   1552                     SOC_IF_ERROR_RETURN
   1553                         (soc_reg32_get(unit, ecc1b_reg, port, 0, &rval));
   1554                     soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, enable ? 1 : 0);
   1555                     if (20 == SOC_REG_ACC_TYPE(unit, ecc1b_reg)) {
   1556                         int inst, pipe;
   1557                         for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
   1558                             inst = pipe | SOC_REG_ADDR_INSTANCE_MASK;
   1559                             SOC_IF_ERROR_RETURN
   1560                                 (soc_reg32_set(unit, ecc1b_reg, inst, 0, rval));
   1561                         }
   1562                     } else {
   1563                         SOC_IF_ERROR_RETURN
   1564                             (soc_reg32_set(unit, ecc1b_reg, port, 0, rval));
   1565                     }
   1566                 }
   1567             }
   1568             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1569                       (BSL_META_U(unit,
   1570                                   "SER enable for %s: %s\n"),
   1571                                    str_type, str_name));
   1572         }
   1573 
   1574         /* Loop through each place-and-route block entry */
   1575         for (rbi = 0; ; rbi++) {
   1576             rb = &_soc_td2_ser_route_blocks[rbi];
   1577             cmic_bit = rb->cmic_bit;
   1578             if (cmic_bit == 0) {
   1579                 /* End of table */
   1580                 break;
   1581             }
   1582             if (rb->blocktype == ser_block_info[bcount].blocktype) {
   1583                 /* New SER mechanism (except IP.IDB) */
   1584                 cmic_rval |= cmic_bit;
   1585                 if (rb->enable_reg != INVALIDr && rb->enable_field != INVALIDf) {
   1586                     SOC_IF_ERROR_RETURN
   1587                         (soc_reg_field32_modify(unit, rb->enable_reg,
   1588                             REG_PORT_ANY, rb->enable_field, enable ? 1 : 0));
   1589                 }
   1590                 if (rb->blocktype == SOC_BLK_IPIPE) {
   1591                     _soc_td2p_ip_pipe_fifo_bmask[unit][rb->pipe] |= cmic_bit;
   1592                 }
   1593             }
   1594         }
   1595 
   1596         /* reset (toggle) fifo if applicable */
   1597         if (ser_block_info[bcount].fifo_reset_reg != INVALIDr) {
   1598             SOC_IF_ERROR_RETURN
   1599                  (soc_reg_field32_modify(unit,
   1600                      ser_block_info[bcount].fifo_reset_reg,
   1601                                          REG_PORT_ANY, FIFO_RESETf, 1));
   1602             SOC_IF_ERROR_RETURN
   1603                  (soc_reg_field32_modify(unit,
   1604                      ser_block_info[bcount].fifo_reset_reg,
   1605                                          REG_PORT_ANY, FIFO_RESETf, 0));
   1606         }
   1607     }
   1608 
   1609     /* TBD: The following looks exactly the same like for TD2 */
   1610 
   1611     /* Enable 1B error reporting for some special items */
   1612     SOC_IF_ERROR_RETURN
   1613          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr,
   1614                                  REG_PORT_ANY, CMIC_BUFFER_1BIT_ERROR_REPORTf, enable ? 1 : 0));
   1615     SOC_IF_ERROR_RETURN
   1616          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr,
   1617                                  REG_PORT_ANY, LEARN_FIFO_1BIT_ERROR_REPORTf, enable ? 1 : 0));
   1618 
   1619     /* Loop through each place-and-route block entry to enable legacy style SER stuff */
   1620     for (rbi = 0; ; rbi++) {
   1621         rb = &_soc_td2_ser_route_blocks[rbi];
   1622         cmic_bit = rb->cmic_bit;
   1623         if (cmic_bit == 0) {
   1624             /* End of table */
   1625             break;
   1626         }
   1627         if (rb->info == NULL) {
   1628             continue;
   1629         }
   1630         if (enable) {
   1631             cmic_rval |= cmic_bit;
   1632         }
   1633 
   1634         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   1635             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   1636                 port = SOC_BLOCK_PORT(unit, block_info_idx);
   1637                 break;
   1638             }
   1639         }
   1640         if (rb->enable_reg != INVALIDr) {
   1641             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   1642                 SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   1643                     /* This port block is not configured */
   1644                     continue;
   1645             }
   1646             SOC_IF_ERROR_RETURN
   1647                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64));
   1648         }
   1649 
   1650         /*Find physical port number for the specified port */
   1651         /* coverity[negative_returns: FALSE] */
   1652         phy_port = si->port_l2p_mapping[port];
   1653 
   1654         /*Find the group and slot according to the physical port*/
   1655         cport = phy_port / _TD2_PORTS_PER_PGW;
   1656         slot_port = (phy_port % _TD2_PORTS_PER_PGW) / _TD2_XLPS_PER_PGW;
   1657 
   1658         /*If PGW number is even, the xlports are positive sequence */
   1659         if((cport % 2) == 0) {
   1660             obm_slot = slot_port;
   1661         }else{
   1662             /*If PGW number is odd, the xlports are reverse sequence */
   1663             obm_slot = 3 - slot_port;
   1664         }
   1665 
   1666         switch (obm_slot) {
   1667             case 0:
   1668                 rb->info[0].enable_reg = PGW_OBM0_ECC_ENABLEr;
   1669                 break;
   1670             case 1:
   1671                 rb->info[0].enable_reg = PGW_OBM1_ECC_ENABLEr;
   1672                 break;
   1673             case 2:
   1674                 rb->info[0].enable_reg = PGW_OBM2_ECC_ENABLEr;
   1675                 break;
   1676             case 3:
   1677                 rb->info[0].enable_reg = PGW_OBM3_ECC_ENABLEr;
   1678                 break;
   1679             default:
   1680                 break;
   1681         }
   1682 
   1683         rv = _soc_trident2_ser_enable_info(unit, block_info_idx, rb->id, port,
   1684                                            rb->enable_reg, &rval64,
   1685                                            rb->info, INVALIDm, enable);
   1686         if (rv == SOC_E_NOT_FOUND) {
   1687             continue;
   1688         } else if (SOC_FAILURE(rv)) {
   1689             return rv;
   1690         }
   1691 
   1692         if (rb->enable_reg != INVALIDr) {
   1693             /* Write per route block parity enable register */
   1694             SOC_IF_ERROR_RETURN
   1695                 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64));
   1696         }
   1697     }
   1698 
   1699     if (enable) {
   1700         /* MMU enables */
   1701         /* TD-3384 */
   1702         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   1703         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0); /* 1 */
   1704         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1705         SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0x1FFFFF));
   1706         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0);
   1707         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1708         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1);
   1709         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1710         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Allow things to stabalize */
   1711 #if defined(BCM_CMICM_SUPPORT)
   1712         /* Write CMIC enable register */
   1713         (void)soc_cmicm_intr2_enable(unit, cmic_rval);
   1714 #endif
   1715     } else {
   1716         /* MMU disables */
   1717         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   1718         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0);
   1719         /* TD-3384 */
   1720         SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0));
   1721         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1722         /* Write CMIC disable register */
   1723 #if defined(BCM_CMICM_SUPPORT)
   1724         (void)soc_cmicm_intr2_disable(unit, cmic_rval);
   1725 #endif
   1726     }
   1727     return SOC_E_NONE;
   1728 }
   1729 
   1730 #endif
   1731 
   1732 STATIC int
   1733 _soc_trident2_ser_enable_cport(int unit, int inst, const _soc_td2_ser_info_t *info,
   1734                                soc_mem_t mem, int enable)
   1735 {
   1736     soc_reg_t port_reg;
   1737     uint64 port_rval;
   1738     int block_info_idx, port;
   1739 
   1740     port = -1;
   1741     SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CPORT) {
   1742         if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst) {
   1743             port = SOC_BLOCK_PORT(unit, block_info_idx);
   1744             break;
   1745         }
   1746     }
   1747 
   1748     if (port < 0) {
   1749         return SOC_E_NONE;
   1750     }
   1751 
   1752     port_reg = info->enable_reg;
   1753     SOC_IF_ERROR_RETURN
   1754         (soc_reg_get(unit, port_reg, port, 0, &port_rval));
   1755 
   1756     SOC_IF_ERROR_RETURN
   1757         (_soc_trident2_ser_enable_info(unit, block_info_idx, inst, port,
   1758                                        port_reg, &port_rval,
   1759                                        info->info, mem, enable));
   1760 
   1761     SOC_IF_ERROR_RETURN(soc_reg_set(unit, port_reg, port, 0, port_rval));
   1762 
   1763     return SOC_E_NONE;
   1764 }
   1765 
   1766 STATIC int
   1767 _soc_trident2_ser_enable_mmu_1bit_ecc(int unit, int enable)
   1768 {
   1769     int i, f;
   1770     uint64 rval64;
   1771     uint32 rval;
   1772     soc_field_info_t *fieldp;
   1773     soc_reg_info_t   *regp;
   1774     soc_reg_t reg;
   1775 
   1776     soc_reg_t _1b_reg_list[] = {
   1777         MMU_CCP_EN_COR_ERR_RPTr,
   1778         MMU_CFAP_EN_COR_ERR_RPTr,
   1779         MMU_DEQ_EN_COR_ERR_RPTr,
   1780         MMU_ENQ_EN_COR_ERR_RPTr,
   1781         MMU_EPRG_EN_COR_ERR_RPTr,
   1782         INTFI_EN_COR_ERR_RPTr,
   1783         ES_PIPE0_LLS_EN_COR_ERR_RPT_1r,
   1784         ES_PIPE0_LLS_EN_COR_ERR_RPT_2r,
   1785         ES_PIPE1_LLS_EN_COR_ERR_RPT_1r,
   1786         ES_PIPE1_LLS_EN_COR_ERR_RPT_2r,
   1787         MMU_PQE_EN_COR_ERR_RPTr,
   1788         MMU_QCN_EN_COR_ERR_RPTr,
   1789         RQE_EN_COR_ERR_RPTr,
   1790         MMU_TDM_EN_COR_ERR_RPTr,
   1791         THDI_EN_COR_ERR_RPTr,
   1792         MMU_THDM_DB_EN_COR_ERR_RPTr,
   1793         MMU_THDM_MCQE_EN_COR_ERR_RPTr,
   1794         MMU_THDU_EN_COR_ERR_RPTr,
   1795         MMU_TOQ_EN_COR_ERR_RPTr,
   1796         HSP_EN_COR_ERR_RPTr
   1797     };
   1798     for (i = 0; i < COUNTOF(_1b_reg_list); i++) {
   1799         reg = _1b_reg_list[i];
   1800         regp = &(SOC_REG_INFO(unit, reg));
   1801         if (SOC_REG_IS_64(unit, reg)) {
   1802             SOC_IF_ERROR_RETURN
   1803                 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   1804             for (f = 0; f < regp->nFields; f++) {
   1805                 fieldp = &(regp->fields[f]);
   1806                 soc_reg64_field32_set(unit, reg, &rval64, fieldp->field,
   1807                                       enable ? 1 : 0);
   1808             }
   1809             SOC_IF_ERROR_RETURN
   1810                 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
   1811         } else {
   1812             SOC_IF_ERROR_RETURN
   1813                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1814             for (f = 0; f < regp->nFields; f++) {
   1815                 fieldp = &(regp->fields[f]);
   1816                 soc_reg_field_set(unit, reg, &rval, fieldp->field,
   1817                                   enable ? 1 : 0);
   1818             }
   1819             SOC_IF_ERROR_RETURN
   1820                 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1821         }
   1822     }
   1823     return SOC_E_NONE;
   1824 }
   1825 
   1826 STATIC int
   1827 _soc_trident2_ser_enable_info(int unit, int block_info_idx, int inst, int port,
   1828                               soc_reg_t group_reg, uint64 *group_rval,
   1829                               const _soc_td2_ser_info_t *info_list,
   1830                               soc_mem_t mem, int enable)
   1831 {
   1832     const _soc_td2_ser_info_t *info;
   1833     int info_index, rv, rv1;
   1834     soc_reg_t reg;
   1835     uint32 rval;
   1836     uint64 rval64;
   1837 
   1838     rv = SOC_E_NOT_FOUND;
   1839 
   1840     /* Loop through each info entry in the list */
   1841     for (info_index = 0; ; info_index++) {
   1842         info = &info_list[info_index];
   1843         if (info->type == _SOC_PARITY_TYPE_NONE) {
   1844             /* End of table */
   1845             break;
   1846         }
   1847 
   1848         if (mem != INVALIDm && info->mem != mem) {
   1849             continue;
   1850         }
   1851 
   1852         rv = SOC_E_NONE;
   1853 
   1854         /* Enable the info entry in the group register */
   1855         if (info->group_reg_enable_field != INVALIDf) {
   1856             soc_reg64_field32_set(unit, group_reg, group_rval,
   1857                                   info->group_reg_enable_field, enable ? 1 : 0);
   1858         }
   1859 
   1860         /* Handle different parity error reporting style */
   1861         switch (info->type) {
   1862         case _SOC_PARITY_TYPE_PARITY:
   1863         case _SOC_PARITY_TYPE_ECC:
   1864             reg = info->enable_reg;
   1865             if (!SOC_REG_IS_VALID(unit, reg)) {
   1866                 break;
   1867             }
   1868             if (SOC_REG_IS_64(unit, reg)) {
   1869                 SOC_IF_ERROR_RETURN
   1870                     (soc_reg_get(unit, reg, port, 0, &rval64));
   1871                 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field,
   1872                                       enable ? 1 : 0);
   1873                 SOC_IF_ERROR_RETURN
   1874                     (soc_reg_set(unit, reg, port, 0, rval64));
   1875             } else {
   1876                 SOC_IF_ERROR_RETURN
   1877                     (soc_reg32_get(unit, reg, port, 0, &rval));
   1878                 soc_reg_field_set(unit, reg, &rval, info->enable_field,
   1879                                   enable ? 1 : 0);
   1880                 SOC_IF_ERROR_RETURN
   1881                     (soc_reg32_set(unit, reg, port, 0, rval));
   1882             }
   1883             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1884                         (BSL_META_U(unit,
   1885                                     "SER enable for: %s\n"),
   1886                          (info->mem == INVALIDm) ? info->mem_str :
   1887                          SOC_MEM_NAME(unit, info->mem)));
   1888             break;
   1889         case _SOC_PARITY_TYPE_CPORT:
   1890             /* One more level of enable tree structure */
   1891             rv1 = _soc_trident2_ser_enable_cport(unit, inst, info, mem, enable);
   1892             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   1893                 return rv;
   1894             }
   1895             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1896                         (BSL_META_U(unit,
   1897                                     "SER enable for: %s\n"),
   1898                          (info->mem == INVALIDm) ? info->mem_str :
   1899                          SOC_MEM_NAME(unit, info->mem)));
   1900             break;
   1901         case _SOC_PARITY_TYPE_MMU_SER:
   1902             rv1 = _soc_trident2_ser_enable_mmu_1bit_ecc(unit, enable);
   1903             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   1904                 return rv;
   1905             }
   1906             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1907                         (BSL_META_U(unit,
   1908                                     "SER enable for: %s\n"),
   1909                          (info->mem == INVALIDm) ? info->mem_str :
   1910                          SOC_MEM_NAME(unit, info->mem)));
   1911             break;
   1912         case _SOC_PARITY_TYPE_GENERIC:
   1913         case _SOC_PARITY_TYPE_START_ERR:
   1914         case _SOC_PARITY_TYPE_BST:
   1915         case _SOC_PARITY_TYPE_CFAP_MEM_FAIL:
   1916             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1917                         (BSL_META_U(unit,
   1918                                     "SER enable for: %s\n"),
   1919                          (info->mem == INVALIDm) ? info->mem_str :
   1920                          SOC_MEM_NAME(unit, info->mem)));
   1921         default:
   1922             break;
   1923         } /* Handle different parity error reporting style */
   1924         if (mem != INVALIDm) {
   1925             break;
   1926         }
   1927 
   1928     } /* Loop through each info entry in the route block */
   1929 
   1930     return rv;
   1931 }
   1932 
   1933 int
   1934 soc_trident2_l3_memwr_parity_check(int unit, soc_mem_t mem, int disable)
   1935 {
   1936     uint32      rval;
   1937     soc_field_t disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   1938     soc_reg_t   disable_reg;
   1939 
   1940     switch (mem) {
   1941     case L3_ENTRY_ONLYm:
   1942     case L3_ENTRY_IPV4_UNICASTm:
   1943     case L3_ENTRY_IPV4_MULTICASTm:
   1944     case L3_ENTRY_IPV6_UNICASTm:
   1945     case L3_ENTRY_IPV6_MULTICASTm:
   1946         disable_reg = L3_ENTRY_PARITY_CONTROLr;
   1947         break;
   1948     case L3_DEFIP_ALPM_IPV4m:
   1949     case L3_DEFIP_ALPM_IPV4_1m:
   1950     case L3_DEFIP_ALPM_IPV6_64m:
   1951     case L3_DEFIP_ALPM_IPV6_64_1m:
   1952     case L3_DEFIP_ALPM_IPV6_128m:
   1953     case L3_DEFIP_ALPM_RAWm:
   1954         disable_reg = ILPM_SER_CONTROLr;
   1955         break;
   1956     default:
   1957         return SOC_E_PARAM;
   1958     }
   1959 
   1960     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, disable_reg, REG_PORT_ANY, 0, &rval));
   1961     soc_reg_field_set(unit, disable_reg, &rval, disable_field, disable ? 1 : 0);
   1962     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, disable_reg, REG_PORT_ANY, 0, rval));
   1963 
   1964     return SOC_E_NONE;
   1965 }
   1966 
   1967 /* The DISABLE_SBUS_MEMWR_PARITY_CHECK bit should be set to 0 by default */
   1968 STATIC int
   1969 _soc_trident2_sram_memwr_parity_check_init(int unit)
   1970 {
   1971     uint32      rval, raddr;
   1972     int         block, i, count;
   1973     uint8       at;
   1974     soc_field_t disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   1975     soc_reg_t   disable_regs[] =
   1976         {
   1977         VLAN_XLATE_DBGCTRL_0r,
   1978         L2_ENTRY_PARITY_CONTROLr,
   1979         L3_ENTRY_PARITY_CONTROLr,
   1980         ILPM_SER_CONTROLr,
   1981         EGR_VLAN_XLATE_CONTROLr
   1982         };
   1983 
   1984     count = COUNTOF(disable_regs);
   1985 
   1986     for (i = 0; i < count; i++) {
   1987         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, disable_regs[i], REG_PORT_ANY, 0, &rval));
   1988 
   1989         soc_reg_field_set(unit, disable_regs[i], &rval, disable_field, 0);
   1990         raddr = soc_reg_addr_get(unit, disable_regs[i], REG_PORT_ANY, 0,
   1991                                  SOC_REG_ADDR_OPTION_WRITE, &block, &at);
   1992         /* The original access type of VLAN_XLATE_CONTROL_0 is 6, but the
   1993          * register also can support access type 3 to set the value on both
   1994          * X Y pipes in same time. To simplify the initializing procedure,
   1995          * here access type 3 is always applied.
   1996          */
   1997         if (!SAL_BOOT_SIMULATION) {
   1998             at = 3;
   1999         }
   2000         SOC_IF_ERROR_RETURN(_soc_reg32_set(unit, block, at, raddr, rval));
   2001     }
   2002 
   2003     return SOC_E_NONE;
   2004 }
   2005 
   2006 
   2007 STATIC int
   2008 _soc_trident2_ser_enable_all(int unit, int enable)
   2009 {
   2010     int         rv, block_info_idx;
   2011     int         phy_port, cport, slot_port, obm_slot, port = REG_PORT_ANY;
   2012     int         egress = 0;
   2013     uint8       rbi, bcount;
   2014     uint16      pcount;
   2015     uint32      rval, cmic_bit, cmic_rval;
   2016     uint64      rb_rval64;
   2017     soc_reg_t   reg, reg_enable;
   2018     soc_field_t field;
   2019     const       _soc_td2_ser_route_block_t *rb;
   2020     soc_info_t *si = &SOC_INFO(unit);
   2021     soc_mem_t   mem;
   2022 
   2023     _soc_trident2_sram_memwr_parity_check_init (unit);
   2024 
   2025 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   2026     if (SOC_IS_TD2P_TT2P(unit)) {
   2027         _soc_td2p_ip_pipe_fifo_bmask[unit][0] = 0;
   2028         _soc_td2p_ip_pipe_fifo_bmask[unit][1] = 0;
   2029         SOC_IF_ERROR_RETURN(_soc_trident2p_ser_enable_all ( unit, _soc_td2p_ser_block_info, enable ));
   2030         return SOC_E_NONE;
   2031     }
   2032 #endif
   2033 
   2034     /* coverity[result_independent_of_operands] */
   2035     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK2r(unit, &cmic_rval));
   2036 
   2037     /* Enable new fifo mechanism based SER stuff */
   2038     for (bcount = 0; _soc_td2_ser_block_info[bcount].blocktype; bcount++) {
   2039         for (pcount = 0;
   2040              _soc_td2_ser_block_info[bcount].info[pcount].enable_reg != INVALIDr;
   2041              pcount++) {
   2042             reg_enable = _soc_td2_ser_block_info[bcount].info[pcount].enable_reg;
   2043             field = _soc_td2_ser_block_info[bcount].info[pcount].enable_field;
   2044 
   2045             if(!SOC_REG_IS_VALID(unit, reg_enable)) {
   2046                 continue;
   2047             }
   2048 
   2049             if (SOC_BLK_IPIPE == _soc_td2_ser_block_info[bcount].blocktype) {
   2050                 egress = 0;
   2051             } else {
   2052                 egress = 1;
   2053             }
   2054             if (enable) {
   2055                 if (_SOC_SER_SOURCE_TYPE_REG == _soc_td2_ser_block_info[bcount].info[pcount].type) { /* register */
   2056                     reg = _soc_td2_ser_block_info[bcount].info[pcount].reg;
   2057                     if (!SOC_REG_IS_VALID(unit, reg)) {
   2058                         continue;
   2059                     }
   2060                 }
   2061                 if (_SOC_SER_SOURCE_TYPE_MEM == _soc_td2_ser_block_info[bcount].info[pcount].type) { /* mem */
   2062                     mem = _soc_td2_ser_block_info[bcount].info[pcount].mem;
   2063                     if (!SOC_MEM_IS_VALID(unit, mem) ||
   2064                         ((mem != INVALIDm) &&
   2065                          ((SOC_MEM_INFO(unit, mem).flags &
   2066                            SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) {
   2067                         continue;
   2068                     }
   2069                 }
   2070                 /* bus or internal buffer or others without mem/reg name */
   2071                 if ((_SOC_SER_SOURCE_TYPE_BUS == _soc_td2_ser_block_info[bcount].info[pcount].type) ||
   2072                     (_SOC_SER_SOURCE_TYPE_BUF == _soc_td2_ser_block_info[bcount].info[pcount].type) ||
   2073                     (_SOC_SER_SOURCE_TYPE_OTHER == _soc_td2_ser_block_info[bcount].info[pcount].type)) {
   2074                     reg = _soc_td2_ser_block_info[bcount].info[pcount].enable_reg;
   2075                     if (!SOC_REG_IS_VALID(unit, reg)) {
   2076                         continue;
   2077                     }
   2078                 }
   2079 
   2080             }
   2081             /*set reg according to the acctype, prevent only set pipe x when acctype is 6*/
   2082             soc_trident2_ser_enable_by_acctype(unit, reg_enable, field, enable, egress);
   2083 
   2084             switch (_soc_td2_ser_block_info[bcount].info[pcount].type) {
   2085             case 0:
   2086                 LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   2087                             (BSL_META_U(unit,
   2088                                         "SER enable for mem: %s\n"),
   2089                              _soc_td2_ser_block_info[bcount].info[pcount].mem != INVALIDm ?
   2090                              SOC_MEM_NAME(unit, _soc_td2_ser_block_info[bcount].info[pcount].mem) :
   2091                              _soc_td2_ser_block_info[bcount].info[pcount].name_str));
   2092                 break;
   2093             case 1:
   2094                 LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   2095                             (BSL_META_U(unit,
   2096                                         "SER enable for reg: %s\n"),
   2097                              _soc_td2_ser_block_info[bcount].info[pcount].reg != INVALIDr ?
   2098                              SOC_REG_NAME(unit, _soc_td2_ser_block_info[bcount].info[pcount].reg) :
   2099                              _soc_td2_ser_block_info[bcount].info[pcount].name_str));
   2100                 break;
   2101             case 2:
   2102                 LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   2103                             (BSL_META_U(unit,
   2104                                         "SER enable for bus: %s\n"),
   2105                              _soc_td2_ser_block_info[bcount].info[pcount].name_str));
   2106                 break;
   2107             default: break;
   2108             }
   2109         }
   2110 
   2111         /* Loop through each place-and-route block entry */
   2112         for (rbi = 0; ; rbi++) {
   2113             rb = &_soc_td2_ser_route_blocks[rbi];
   2114             cmic_bit = rb->cmic_bit;
   2115             if (cmic_bit == 0) {
   2116                 /* End of table */
   2117                 break;
   2118             }
   2119             if (rb->blocktype == _soc_td2_ser_block_info[bcount].blocktype) {
   2120                 /* New SER mechanism */
   2121                 cmic_rval |= cmic_bit;
   2122                 if (rb->enable_reg != INVALIDr) {
   2123                     SOC_IF_ERROR_RETURN
   2124                         (soc_reg_field32_modify(unit, rb->enable_reg,
   2125                             REG_PORT_ANY, rb->enable_field, enable ? 1 : 0));
   2126                 }
   2127             }
   2128         }
   2129 
   2130         /* reset (toggle) fifo if applicable */
   2131         if (_soc_td2_ser_block_info[bcount].fifo_reset_reg != INVALIDr) {
   2132             SOC_IF_ERROR_RETURN
   2133                  (soc_reg_field32_modify(unit,
   2134                      _soc_td2_ser_block_info[bcount].fifo_reset_reg,
   2135                                          REG_PORT_ANY, FIFO_RESETf, 1));
   2136             SOC_IF_ERROR_RETURN
   2137                  (soc_reg_field32_modify(unit,
   2138                      _soc_td2_ser_block_info[bcount].fifo_reset_reg,
   2139                                          REG_PORT_ANY, FIFO_RESETf, 0));
   2140         }
   2141     }
   2142 
   2143     /* Enable 1B error reporting for some special items */
   2144     SOC_IF_ERROR_RETURN
   2145          (soc_reg_field32_modify(unit, IPARS_EN_COR_ERR_RPTr,
   2146                                  REG_PORT_ANY, LPORT_TABLEf, enable ? 1 : 0));
   2147     SOC_IF_ERROR_RETURN
   2148          (soc_reg_field32_modify(unit, IPARS_EN_COR_ERR_RPTr,
   2149                                  REG_PORT_ANY, SRC_TRUNKf, enable ? 1 : 0));
   2150     SOC_IF_ERROR_RETURN
   2151          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr,
   2152                                  REG_PORT_ANY, CMIC_BUFFER_1BIT_ERROR_REPORTf, enable ? 1 : 0));
   2153     SOC_IF_ERROR_RETURN
   2154          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr,
   2155                                  REG_PORT_ANY, LEARN_FIFO_1BIT_ERROR_REPORTf, enable ? 1 : 0));
   2156     SOC_IF_ERROR_RETURN
   2157          (soc_reg_field32_modify(unit, ICFG_EN_COR_ERR_RPTr,
   2158                                  REG_PORT_ANY, PORT_TABLEf, enable ? 1 : 0));
   2159     SOC_IF_ERROR_RETURN
   2160          (soc_reg_field32_modify(unit, EGR_EFPPARS_PARITY_CONTROLr,
   2161                                  REG_PORT_ANY, EGR_1588_LINK_DELAY_PARITY_ENf, enable ? 1 : 0));
   2162 
   2163     /* Loop through each place-and-route block entry to enable legacy style SER stuff */
   2164     for (rbi = 0; ; rbi++) {
   2165         rb = &_soc_td2_ser_route_blocks[rbi];
   2166         cmic_bit = rb->cmic_bit;
   2167         if (cmic_bit == 0) {
   2168             /* End of table */
   2169             break;
   2170         }
   2171         if (rb->info == NULL) {
   2172             continue;
   2173         }
   2174         if (enable) {
   2175             cmic_rval |= cmic_bit;
   2176         }
   2177 
   2178         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   2179             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   2180                 port = SOC_BLOCK_PORT(unit, block_info_idx);
   2181                 break;
   2182             }
   2183         }
   2184         if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   2185             SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   2186                 /* This port block is not configured */
   2187                 continue;
   2188         }
   2189         if (rb->blocktype == SOC_BLK_PGW_CL) {
   2190             /*Find physical port number for the specified port */
   2191             /* coverity[negative_returns: FALSE] */
   2192             phy_port = si->port_l2p_mapping[port];
   2193 
   2194             /*Find the group and slot according to the physical port*/
   2195             cport = phy_port / _TD2_PORTS_PER_PGW;
   2196             slot_port = (phy_port % _TD2_PORTS_PER_PGW) / _TD2_XLPS_PER_PGW;
   2197 
   2198             /*If PGW number is even, the xlports are positive sequence */
   2199             if((cport % 2) == 0) {
   2200                 obm_slot = slot_port;
   2201             }else{
   2202                 /*If PGW number is odd, the xlports are reverse sequence */
   2203                 obm_slot = 3 - slot_port;
   2204             }
   2205 
   2206             switch (obm_slot) {
   2207                 case 0:
   2208                     rb->info[0].enable_reg = PGW_OBM0_ECC_ENABLEr;
   2209                     break;
   2210                 case 1:
   2211                     rb->info[0].enable_reg = PGW_OBM1_ECC_ENABLEr;
   2212                     break;
   2213                 case 2:
   2214                     rb->info[0].enable_reg = PGW_OBM2_ECC_ENABLEr;
   2215                     break;
   2216                 case 3:
   2217                     rb->info[0].enable_reg = PGW_OBM3_ECC_ENABLEr;
   2218                     break;
   2219                 default:
   2220                     break;
   2221             }
   2222         }
   2223 
   2224         SOC_IF_ERROR_RETURN
   2225             (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_rval64));
   2226         rv = _soc_trident2_ser_enable_info(unit, block_info_idx, rb->id, port,
   2227                                            rb->enable_reg, &rb_rval64,
   2228                                            rb->info, INVALIDm, enable);
   2229         if (rv == SOC_E_NOT_FOUND) {
   2230             continue;
   2231         } else if (SOC_FAILURE(rv)) {
   2232             return rv;
   2233         }
   2234 
   2235         /* Write per route block parity enable register */
   2236         SOC_IF_ERROR_RETURN
   2237             (soc_reg_set(unit, rb->enable_reg, port, 0, rb_rval64));
   2238     }
   2239     if (enable) {
   2240         /* MMU enables */
   2241         /* TD-3384 */
   2242         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2243         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0); /* 1 */
   2244         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2245         SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0x1FFFFE));
   2246         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0);
   2247         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2248         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1);
   2249         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2250         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Allow things to stabalize */
   2251 #if defined(BCM_CMICM_SUPPORT)
   2252         /* Write CMIC enable register */
   2253         (void)soc_cmicm_intr2_enable(unit, cmic_rval);
   2254 #endif
   2255     } else {
   2256         /* MMU disables */
   2257         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2258         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0);
   2259         /* TD-3384 */
   2260         SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0));
   2261         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2262 #if defined(BCM_CMICM_SUPPORT)
   2263         /* Write CMIC disable register */
   2264         (void)soc_cmicm_intr2_disable(unit, cmic_rval);
   2265 #endif
   2266     }
   2267     return SOC_E_NONE;
   2268 }
   2269 
   2270 void
   2271 _soc_trident2_mem_rename(soc_mem_t *memory)
   2272 {
   2273     switch(*memory) {
   2274         case EGR_FRAGMENT_ID_TABLE_Xm:
   2275         case EGR_FRAGMENT_ID_TABLE_Ym:
   2276             *memory = EGR_FRAGMENT_ID_TABLEm;
   2277             break;
   2278 
   2279         case EFP_COUNTER_TABLE_Xm:
   2280         case EFP_COUNTER_TABLE_Ym:
   2281             *memory = EFP_COUNTER_TABLEm;
   2282             break;
   2283 
   2284         case EGR_PERQ_XMT_COUNTERS_Xm:
   2285         case EGR_PERQ_XMT_COUNTERS_Ym:
   2286             *memory = EGR_PERQ_XMT_COUNTERSm;
   2287             break;
   2288 
   2289         case EFP_METER_TABLE_Xm:
   2290         case EFP_METER_TABLE_Ym:
   2291             *memory = EFP_METER_TABLEm;
   2292             break;
   2293 
   2294         case EGR_PW_INIT_COUNTERS_Xm:
   2295         case EGR_PW_INIT_COUNTERS_Ym:
   2296             *memory = EGR_PW_INIT_COUNTERSm;
   2297             break;
   2298 
   2299         case FP_COUNTER_TABLE_Xm:
   2300         case FP_COUNTER_TABLE_Ym:
   2301             *memory = FP_COUNTER_TABLEm;
   2302             break;
   2303 
   2304         case FP_STORM_CONTROL_METERS_Xm:
   2305         case FP_STORM_CONTROL_METERS_Ym:
   2306             *memory = FP_STORM_CONTROL_METERSm;
   2307             break;
   2308 
   2309         case DLB_HGT_FLOWSET_Xm:
   2310         case DLB_HGT_FLOWSET_Ym:
   2311             *memory = DLB_HGT_FLOWSETm;
   2312             break;
   2313 
   2314         case DLB_HGT_FLOWSET_TIMESTAMP_PAGE_Xm:
   2315         case DLB_HGT_FLOWSET_TIMESTAMP_PAGE_Ym:
   2316             *memory = DLB_HGT_FLOWSET_TIMESTAMP_PAGEm;
   2317             break;
   2318 
   2319         case ING_PW_TERM_SEQ_NUM_Xm:
   2320         case ING_PW_TERM_SEQ_NUM_Ym:
   2321             *memory = ING_PW_TERM_SEQ_NUMm;
   2322             break;
   2323         case ING_FLEX_CTR_COUNTER_TABLE_0_Xm:
   2324         case ING_FLEX_CTR_COUNTER_TABLE_0_Ym:
   2325             *memory = ING_FLEX_CTR_COUNTER_TABLE_0m;
   2326             break;
   2327         case ING_FLEX_CTR_COUNTER_TABLE_1_Xm:
   2328         case ING_FLEX_CTR_COUNTER_TABLE_1_Ym:
   2329             *memory = ING_FLEX_CTR_COUNTER_TABLE_1m;
   2330             break;
   2331         case ING_FLEX_CTR_COUNTER_TABLE_2_Xm:
   2332         case ING_FLEX_CTR_COUNTER_TABLE_2_Ym:
   2333             *memory = ING_FLEX_CTR_COUNTER_TABLE_2m;
   2334             break;
   2335         case ING_FLEX_CTR_COUNTER_TABLE_3_Xm:
   2336         case ING_FLEX_CTR_COUNTER_TABLE_3_Ym:
   2337             *memory = ING_FLEX_CTR_COUNTER_TABLE_3m;
   2338             break;
   2339         case ING_FLEX_CTR_COUNTER_TABLE_4_Xm:
   2340         case ING_FLEX_CTR_COUNTER_TABLE_4_Ym:
   2341             *memory = ING_FLEX_CTR_COUNTER_TABLE_4m;
   2342             break;
   2343         case ING_FLEX_CTR_COUNTER_TABLE_5_Xm:
   2344         case ING_FLEX_CTR_COUNTER_TABLE_5_Ym:
   2345             *memory = ING_FLEX_CTR_COUNTER_TABLE_5m;
   2346             break;
   2347         case ING_FLEX_CTR_COUNTER_TABLE_6_Xm:
   2348         case ING_FLEX_CTR_COUNTER_TABLE_6_Ym:
   2349             *memory = ING_FLEX_CTR_COUNTER_TABLE_6m;
   2350             break;
   2351         case ING_FLEX_CTR_COUNTER_TABLE_7_Xm:
   2352         case ING_FLEX_CTR_COUNTER_TABLE_7_Ym:
   2353             *memory = ING_FLEX_CTR_COUNTER_TABLE_7m;
   2354             break;
   2355         case EGR_FLEX_CTR_COUNTER_TABLE_0_Xm:
   2356         case EGR_FLEX_CTR_COUNTER_TABLE_0_Ym:
   2357             *memory = EGR_FLEX_CTR_COUNTER_TABLE_0m;
   2358             break;
   2359         case EGR_FLEX_CTR_COUNTER_TABLE_1_Xm:
   2360         case EGR_FLEX_CTR_COUNTER_TABLE_1_Ym:
   2361             *memory = EGR_FLEX_CTR_COUNTER_TABLE_1m;
   2362             break;
   2363         case EGR_FLEX_CTR_COUNTER_TABLE_2_Xm:
   2364         case EGR_FLEX_CTR_COUNTER_TABLE_2_Ym:
   2365             *memory = EGR_FLEX_CTR_COUNTER_TABLE_2m;
   2366             break;
   2367         case EGR_FLEX_CTR_COUNTER_TABLE_3_Xm:
   2368         case EGR_FLEX_CTR_COUNTER_TABLE_3_Ym:
   2369             *memory = EGR_FLEX_CTR_COUNTER_TABLE_3m;
   2370             break;
   2371         case L3_TUNNELm:
   2372             *memory = L3_TUNNEL_DATA_ONLYm;
   2373             break;
   2374         default:
   2375             break;
   2376     }
   2377 }
   2378 
   2379 STATIC int
   2380 soc_trident2_ser_enable_by_acctype(int unit, soc_reg_t reg,
   2381                                                 soc_field_t field, int enable,
   2382                                                 int egress)
   2383 {
   2384     uint32  flags = 0;
   2385     uint32  rval = 0;
   2386     int     port = REG_PORT_ANY;
   2387     int     rv = SOC_E_NONE;
   2388 
   2389     flags = SOC_REG_ACC_TYPE(unit, reg);
   2390     if (_SOC_ACC_TYPE_PIPE_SBS == flags) {
   2391         IP_ARBITER_LOCK(unit);
   2392         /*set pipe x*/
   2393         soc_trident2_pipe_select(unit, egress, 0);
   2394         rv = soc_reg32_get(unit, reg, port, 0, &rval);
   2395         if (rv != SOC_E_NONE) {
   2396             IP_ARBITER_UNLOCK(unit);
   2397             return rv;
   2398         }
   2399         if (soc_reg_field_valid(unit, reg, field)) {
   2400             soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   2401         }
   2402         rv = soc_reg32_set(unit, reg, port, 0, rval);
   2403         if (rv != SOC_E_NONE) {
   2404             IP_ARBITER_UNLOCK(unit);
   2405             return rv;
   2406         }
   2407 
   2408         /*set pipe y*/
   2409         soc_trident2_pipe_select(unit, egress, 1);
   2410         rv = soc_reg32_get(unit, reg, port, 0, &rval);
   2411         if (rv != SOC_E_NONE) {
   2412             soc_trident2_pipe_select(unit, egress, 0);
   2413             IP_ARBITER_UNLOCK(unit);
   2414             return rv;
   2415         }
   2416         if (soc_reg_field_valid(unit, reg, field)) {
   2417             soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   2418         }
   2419         rv = soc_reg32_set(unit, reg, port, 0, rval);
   2420         if (rv != SOC_E_NONE) {
   2421             soc_trident2_pipe_select(unit, egress, 0);
   2422             IP_ARBITER_UNLOCK(unit);
   2423             return rv;
   2424         }
   2425 
   2426         soc_trident2_pipe_select(unit, egress, 0);
   2427         IP_ARBITER_UNLOCK(unit);
   2428     } else {
   2429         SOC_IF_ERROR_RETURN
   2430             (soc_reg32_get(unit, reg, port, 0, &rval));
   2431         if (soc_reg_field_valid(unit, reg, field)) {
   2432             soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   2433         }
   2434         SOC_IF_ERROR_RETURN
   2435             (soc_reg32_set(unit, reg, port, 0, rval));
   2436     }
   2437 
   2438     return rv;
   2439 }
   2440 
   2441 int
   2442 soc_trident2_mem_parity_control(int unit, soc_mem_t mem, int copyno,
   2443                                             int enable)
   2444 {
   2445     int             bcount = 0;
   2446     int             pcount = 0;
   2447     int             egress = 0;
   2448     int             rv = SOC_E_NONE;
   2449     uint8           rbi = 0;
   2450     uint32          rval = 0;
   2451     uint32          cmic_rval = 0;
   2452     soc_reg_t       reg;
   2453     soc_field_t     field;
   2454     const _soc_td2_ser_route_block_t *rb;
   2455 
   2456     _soc_trident2_mem_rename(&mem);
   2457 
   2458     /* coverity[result_independent_of_operands] */
   2459     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK2r(unit, &cmic_rval));
   2460 
   2461     for (bcount = 0; _soc_td2_ser_block_info[bcount].blocktype; bcount++) {
   2462         for (pcount = 0;
   2463             _soc_td2_ser_block_info[bcount].info[pcount].enable_reg != INVALIDr;
   2464             pcount++) {
   2465             if (_soc_td2_ser_block_info[bcount].info[pcount].mem == mem) {
   2466                 if (enable) {
   2467                     if(!SOC_MEM_IS_VALID(unit, mem) ||
   2468                        ((mem != INVALIDm) &&
   2469                         ((SOC_MEM_INFO(unit, mem).flags &
   2470                           SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) {
   2471                         rv = SOC_E_UNAVAIL;
   2472                         return rv;
   2473                     }
   2474                 }
   2475                 reg = _soc_td2_ser_block_info[bcount].info[pcount].enable_reg;
   2476                 field = _soc_td2_ser_block_info[bcount].info[pcount].enable_field;
   2477 
   2478                 if (SOC_BLK_IPIPE == _soc_td2_ser_block_info[bcount].blocktype) {
   2479                     egress = 0;
   2480                 } else {
   2481                     egress = 1;
   2482                 }
   2483 
   2484                 /*set reg according to the acctype, prevent only set pipe x when acctype is 6*/
   2485                 rv = soc_trident2_ser_enable_by_acctype(unit, reg, field, enable, egress);
   2486                 if (SOC_FAILURE(rv)) {
   2487                     return rv;
   2488                 }
   2489             }
   2490         }
   2491 
   2492         if (_soc_td2_ser_block_info[bcount].fifo_reset_reg != INVALIDr) {
   2493             SOC_IF_ERROR_RETURN
   2494                  (soc_reg_field32_modify(unit,
   2495                      _soc_td2_ser_block_info[bcount].fifo_reset_reg,
   2496                                          REG_PORT_ANY, FIFO_RESETf, 1));
   2497             SOC_IF_ERROR_RETURN
   2498                  (soc_reg_field32_modify(unit,
   2499                      _soc_td2_ser_block_info[bcount].fifo_reset_reg,
   2500                                          REG_PORT_ANY, FIFO_RESETf, 0));
   2501         }
   2502     }
   2503 
   2504     if ((rv == SOC_E_NONE) && (SOC_MEM_IS_VALID(unit, mem)) &&
   2505         (SOC_BLOCK_TYPE(unit, SOC_MEM_BLOCK_ANY(unit, mem))) == SOC_BLK_MMU) {
   2506         /* MMU controls */
   2507         for (rbi = 0; ; rbi++) {
   2508             rb = &_soc_td2_ser_route_blocks[rbi];
   2509             if (rb->cmic_bit == 0) {
   2510                 /* End of table */
   2511                 break;
   2512             }
   2513             if (rb->blocktype == SOC_BLK_MMU) {
   2514                 cmic_rval |= rb->cmic_bit;
   2515             }
   2516         }
   2517 
   2518         if (enable) {
   2519             /* MMU enables */
   2520             /* TD-3384 */
   2521             SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2522             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0); /* 1 */
   2523             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2524             SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0x1FFFFE));
   2525             soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0);
   2526             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2527             soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1);
   2528             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2529             sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Allow things to stabalize */
   2530 #if defined(BCM_CMICM_SUPPORT)
   2531             (void)soc_cmicm_intr2_enable(unit, cmic_rval);
   2532 #endif
   2533         } else {
   2534             /* MMU disables */
   2535             SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2536             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0);
   2537             /* TD-3384 */
   2538             SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0));
   2539             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2540 #if defined(BCM_CMICM_SUPPORT)
   2541             (void)soc_cmicm_intr2_disable(unit, cmic_rval);
   2542 #endif
   2543         }
   2544     }
   2545 
   2546     return rv;
   2547 }
   2548 
   2549 STATIC int
   2550 _soc_trident2_clear_mmu_memory(int unit, soc_mem_t mem)
   2551 {
   2552     int i, count;
   2553     static soc_mem_t mmu_mems[] = {
   2554         MMU_INTFI_XPIPE_FC_MAP_TBL2m,
   2555         MMU_INTFI_YPIPE_FC_MAP_TBL2m
   2556     };
   2557 
   2558     count = COUNTOF(mmu_mems);
   2559     /* MMU mem clear to avoid SER issue */
   2560     for (i = 0; i < count; i++) {
   2561         if (mem != INVALIDm) {
   2562             if (mem == mmu_mems[i]) {
   2563                 SOC_IF_ERROR_RETURN
   2564                     (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE));
   2565                 break;
   2566             }
   2567         } else {
   2568             SOC_IF_ERROR_RETURN
   2569                 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE));
   2570         }
   2571     }
   2572     return SOC_E_NONE;
   2573 }
   2574 
   2575 STATIC int
   2576 _soc_trident2_mmu_init_default_val(int unit)
   2577 {
   2578     soc_mem_t           mem0, mem1;
   2579     uint32              entry[SOC_MAX_MEM_WORDS];
   2580     int                 index, unused_idx;
   2581 
   2582     /* Set LLS_Port memory. Point to Un-used L0 node.*/
   2583     mem0 = ES_PIPE0_LLS_PORT_HEADS_TAILSm;
   2584     mem1 = ES_PIPE1_LLS_PORT_HEADS_TAILSm;
   2585     sal_memset(entry, 0, sizeof(entry));
   2586     unused_idx = 267;
   2587     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST0_HEADf, unused_idx);
   2588     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST1_HEADf, unused_idx);
   2589     soc_mem_field32_set(unit, mem0, entry, P_MIN_HEADf, unused_idx);
   2590     soc_mem_field32_set(unit, mem0, entry, P_EF_HEADf, unused_idx);
   2591     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST0_TAILf, unused_idx);
   2592     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST1_TAILf, unused_idx);
   2593     soc_mem_field32_set(unit, mem0, entry, P_MIN_TAILf, unused_idx);
   2594     soc_mem_field32_set(unit, mem0, entry, P_EF_TAILf, unused_idx);
   2595     for (index = 0; index < soc_mem_index_count(unit, mem0); index++) {
   2596         SOC_IF_ERROR_RETURN
   2597             (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, index, entry));
   2598         SOC_IF_ERROR_RETURN
   2599             (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, index, entry));
   2600     }
   2601 
   2602     /* Set LLS_L0 memory. Point to Un-used L1 node.*/
   2603     mem0 = ES_PIPE0_LLS_L0_HEADS_TAILSm;
   2604     mem1 = ES_PIPE1_LLS_L0_HEADS_TAILSm;
   2605     sal_memset(entry, 0, sizeof(entry));
   2606     unused_idx = 1023;
   2607     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST0_HEADf, unused_idx);
   2608     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST1_HEADf, unused_idx);
   2609     soc_mem_field32_set(unit, mem0, entry, P_MIN_HEADf, unused_idx);
   2610     soc_mem_field32_set(unit, mem0, entry, P_EF_HEADf, unused_idx);
   2611     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST0_TAILf, unused_idx);
   2612     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST1_TAILf, unused_idx);
   2613     soc_mem_field32_set(unit, mem0, entry, P_MIN_TAILf, unused_idx);
   2614     soc_mem_field32_set(unit, mem0, entry, P_EF_TAILf, unused_idx);
   2615     for (index = 0; index < soc_mem_index_count(unit, mem0); index++) {
   2616         SOC_IF_ERROR_RETURN
   2617             (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, index, entry));
   2618         SOC_IF_ERROR_RETURN
   2619             (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, index, entry));
   2620     }
   2621 
   2622     /* Set LLS_L1 memory. Point to Un-used L2 child.*/
   2623     mem0 = ES_PIPE0_LLS_L1_HEADS_TAILSm;
   2624     mem1 = ES_PIPE1_LLS_L1_HEADS_TAILSm;
   2625     sal_memset(entry, 0, sizeof(entry));
   2626     unused_idx = 1479;
   2627     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST0_HEADf, unused_idx);
   2628     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST1_HEADf, unused_idx);
   2629     soc_mem_field32_set(unit, mem0, entry, P_MIN_LIST_HEADf, unused_idx);
   2630     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST0_TAILf, unused_idx);
   2631     soc_mem_field32_set(unit, mem0, entry, P_WRR_LIST1_TAILf, unused_idx);
   2632     soc_mem_field32_set(unit, mem0, entry, P_MIN_LIST_TAILf, unused_idx);
   2633     for (index = 0; index < soc_mem_index_count(unit, mem0); index++) {
   2634         SOC_IF_ERROR_RETURN
   2635             (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, index, entry));
   2636         SOC_IF_ERROR_RETURN
   2637             (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, index, entry));
   2638     }
   2639     return SOC_E_NONE;
   2640 }
   2641 
   2642 int
   2643 _soc_trident2_mem_ser_control(int unit, soc_mem_t mem, int copyno,
   2644                               int enable)
   2645 {
   2646     if (enable) {
   2647         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr,
   2648                                            REG_PORT_ANY, TOP_MMU_RST_Lf, 0));
   2649         sal_usleep(1000);
   2650         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr,
   2651                                            REG_PORT_ANY, TOP_MMU_RST_Lf, 1));
   2652         sal_usleep(1000);
   2653     }
   2654     if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2655         SOC_IF_ERROR_RETURN(_soc_trident2_clear_mmu_memory(unit, INVALIDm));
   2656         SOC_IF_ERROR_RETURN(_soc_trident2_ser_enable_all(unit, enable));
   2657     }
   2658     if (enable) {
   2659         SOC_IF_ERROR_RETURN
   2660             (_soc_trident2_mmu_init_default_val(unit));
   2661     }
   2662     return SOC_E_NONE;
   2663 }
   2664 
   2665 STATIC void
   2666 _soc_td2_mem_parity_info(int unit, int block_info_idx, int pipe,
   2667                          soc_field_t field_enum, uint32 *minfo)
   2668 {
   2669     *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP)
   2670         | ((pipe & 0xff) << SOC_ERROR_PIPE_BP)
   2671         | (field_enum & SOC_ERROR_FIELD_ENUM_MASK);
   2672 }
   2673 
   2674 STATIC int
   2675 soc_td2_mem_log_content_skip(int unit, soc_mem_t mem)
   2676 {
   2677     int skip = FALSE;
   2678     switch(mem) {
   2679         case ES_PIPE0_LLS_PORT_MEMA_CONFIGm:
   2680         case ES_PIPE0_LLS_PORT_MEMB_CONFIGm:
   2681         case ES_PIPE1_LLS_PORT_MEMA_CONFIGm:
   2682         case ES_PIPE1_LLS_PORT_MEMB_CONFIGm:
   2683         case ES_PIPE0_LLS_L0_PARENTm:
   2684         case ES_PIPE0_LLS_L0_MEMA_CONFIGm:
   2685         case ES_PIPE0_LLS_L0_MEMB_CONFIGm:
   2686         case ES_PIPE0_LLS_L0_CHILD_WEIGHT_CFGm:
   2687         case ES_PIPE1_LLS_L0_PARENTm:
   2688         case ES_PIPE1_LLS_L0_MEMA_CONFIGm:
   2689         case ES_PIPE1_LLS_L0_MEMB_CONFIGm:
   2690         case ES_PIPE1_LLS_L0_CHILD_WEIGHT_CFGm:
   2691         case ES_PIPE0_LLS_L1_PARENTm:
   2692         case ES_PIPE0_LLS_L1_MEMA_CONFIGm:
   2693         case ES_PIPE0_LLS_L1_MEMB_CONFIGm:
   2694         case ES_PIPE0_LLS_L1_CHILD_WEIGHT_CFGm:
   2695         case ES_PIPE1_LLS_L1_PARENTm:
   2696         case ES_PIPE1_LLS_L1_MEMA_CONFIGm:
   2697         case ES_PIPE1_LLS_L1_MEMB_CONFIGm:
   2698         case ES_PIPE1_LLS_L1_CHILD_WEIGHT_CFGm:
   2699         case ES_PIPE0_LLS_L2_PARENTm:
   2700         case ES_PIPE0_LLS_L2_CHILD_WEIGHT_CFGm:
   2701         case ES_PIPE1_LLS_L2_PARENTm:
   2702         case ES_PIPE1_LLS_L2_CHILD_WEIGHT_CFGm:
   2703         case ES_PIPE0_TDM_TABLE_0m:
   2704         case ES_PIPE0_TDM_TABLE_1m:
   2705         case ES_PIPE1_TDM_TABLE_0m:
   2706         case ES_PIPE1_TDM_TABLE_1m:
   2707 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   2708             if (SOC_IS_TD2P_TT2P(unit)) {
   2709                 /*
   2710                 * Skip populating content for the MMU memories
   2711                 * which share same parity control bit(PARITY_ENr.ES_PARITY_ENf)
   2712                 */
   2713                 skip = TRUE;
   2714             }
   2715 #endif
   2716             break;
   2717         default:
   2718             break;
   2719     }
   2720 
   2721     return skip;
   2722 }
   2723 
   2724 STATIC int
   2725 _soc_td2_mem_is_dyn(int unit, soc_mem_t mem)
   2726 {
   2727     int rv = 0; /* mem is not dynamic */
   2728 
   2729     switch (mem) {
   2730     case FP_METER_TABLEm:
   2731     case EFP_METER_TABLEm:
   2732     case FP_STORM_CONTROL_METERSm:
   2733     case FP_STORM_CONTROL_METERS_Xm:
   2734     case FP_STORM_CONTROL_METERS_Ym:
   2735         rv = 1; break;
   2736     default:
   2737         if ((SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_ENTRY_CLEAR) ||
   2738             !(SOC_MEM_SER_CORRECTION_TYPE(unit, mem))) {
   2739             /* 1st term means mem is dynamic - eg: counter */
   2740             /* 2nd term means sw cannot restore this - so mem must be dyn */
   2741             rv = 1;
   2742         } else {
   2743             rv = 0;
   2744         }
   2745         break;
   2746     }
   2747     if (rv) {
   2748         LOG_VERBOSE(BSL_LS_SOC_SER,
   2749             (BSL_META_U(unit,
   2750                         "unit %d, mem %s is dynamic - so read of corrupted"
   2751                         " entry will be skipped !!\n"),
   2752              unit, SOC_MEM_NAME(unit, mem)));
   2753     }
   2754     return rv;
   2755 }
   2756 
   2757 STATIC int
   2758 _soc_td2_populate_ser_log(int unit, soc_reg_t parity_enable_reg,
   2759                           soc_field_t parity_enable_field,
   2760                           soc_mem_t mem,
   2761                           int mem_block,
   2762                           soc_acc_type_t acc_type,
   2763                           int index,
   2764                           sal_usecs_t detect_time,
   2765                           uint32 sblk,
   2766                           uint32 address,
   2767                           int pipe,
   2768                           int is_physical_index,
   2769                           uint32 hwbase)
   2770 {
   2771     uint32 tmp_entry[SOC_MAX_MEM_WORDS];
   2772     int log_entry_size, id, entry_dw;
   2773     int is_dynamic_mem = 0;
   2774     int at = 0;
   2775     uint32 *cache;
   2776     uint32 flags = SOC_MEM_NO_FLAGS;
   2777     uint8 *vmap;
   2778     soc_ser_log_tlv_memory_t log_mem;
   2779     soc_ser_log_tlv_generic_t log_generic;
   2780     uint8 skip = FALSE;
   2781 
   2782     sal_memset(&log_generic, 0, sizeof(log_generic));
   2783     sal_memset(&log_mem, 0, sizeof(log_mem));
   2784 
   2785     if (mem != INVALIDm) {
   2786         is_dynamic_mem = _soc_td2_mem_is_dyn(unit, mem);
   2787     }
   2788     /*
   2789     must be large enough for at least generic and terminator, as well as the
   2790     memory type since we might decode it in soc_ser_correction.
   2791     */
   2792     log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 +
   2793                      sizeof(soc_ser_log_tlv_generic_t) +
   2794                      sizeof(soc_ser_log_tlv_memory_t);
   2795 
   2796     if (mem == INVALIDm) {
   2797         mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address);
   2798         if (mem != INVALIDm) {
   2799             if (sblk) {
   2800                 SOC_MEM_BLOCK_ITER(unit, mem, mem_block) {
   2801                     if (SOC_BLOCK2OFFSET(unit, mem_block) == sblk) {
   2802                         break;
   2803                     }
   2804                 }
   2805             } else {
   2806                 mem_block = SOC_MEM_BLOCK_ANY(unit, mem);
   2807             }
   2808         }
   2809     }
   2810     /*
   2811     If we have decoded the memory we can record its contents/cache
   2812     */
   2813     if((mem != INVALIDm) &&
   2814        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != SOC_MEM_FLAG_SER_SPECIAL) &&
   2815        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) {
   2816         entry_dw = soc_mem_entry_words(unit, mem);
   2817 
   2818         /* Check to make sure this isn't a duplicate */
   2819         /* Search for a log entry with the same mem, and index with within the last 5 seconds */
   2820         if (soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()) > 0) {
   2821             return 0;
   2822         }
   2823 
   2824         log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2825 
   2826         cache = SOC_MEM_STATE(unit, mem).cache[mem_block];
   2827         vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block];
   2828         if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   2829             log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2830         }
   2831 
   2832         /* create the entry based on determined size, save id */
   2833         id = soc_ser_log_create_entry(unit, log_entry_size);
   2834 
   2835         /* Add the memory information to the log now so we can detect duplicate errors */
   2836         log_generic.time = detect_time;
   2837         log_mem.memory = mem;
   2838         log_mem.index = index;
   2839         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY,
   2840             sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   2841         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC,
   2842             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   2843 
   2844         if ((SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit))&&
   2845              L2Xm == mem) {
   2846             soc_l2x_selective_freeze(unit, SOC_L2X_FROZEN_WITHOUT_LOCK);
   2847         }
   2848 
   2849         skip = soc_td2_mem_log_content_skip(unit, mem);
   2850         if (!is_dynamic_mem && !skip) {
   2851             /* Make sure the pipe is set correctly */
   2852             IP_ARBITER_LOCK(unit);
   2853             /* Disable Parity when the mem is not dynamic */
   2854             if ((parity_enable_reg != INVALIDr) &&
   2855                 (parity_enable_field != INVALIDf)) {
   2856                 at = SOC_REG_ACC_TYPE(unit, parity_enable_reg);
   2857                 if ((1 == pipe) && (at == _SOC_ACC_TYPE_PIPE_SBS)) {
   2858                     soc_trident2_pipe_select(unit, TRUE, 1);
   2859                     soc_trident2_pipe_select(unit, FALSE, 1);
   2860                 }
   2861                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2862                     REG_PORT_ANY, parity_enable_field, 0) < 0) {
   2863                     soc_trident2_pipe_select(unit, TRUE, 0);
   2864                     soc_trident2_pipe_select(unit, FALSE, 0);
   2865                     IP_ARBITER_UNLOCK(unit);
   2866                     return 0;
   2867                 }
   2868                 if ((1 == pipe) && (at == _SOC_ACC_TYPE_PIPE_SBS)) {
   2869                     soc_trident2_pipe_select(unit, TRUE, 0);
   2870                     soc_trident2_pipe_select(unit, FALSE, 0);
   2871                 }
   2872             }
   2873 
   2874             if ((1 == pipe) &&
   2875                 ((_SOC_ACC_TYPE_PIPE_BCAST == acc_type) ||
   2876                  (_SOC_ACC_TYPE_PIPE_SBS == acc_type))) {
   2877                 soc_trident2_pipe_select(unit, TRUE, 1);
   2878                 soc_trident2_pipe_select(unit, FALSE, 1);
   2879             } else {
   2880                 soc_trident2_pipe_select(unit, TRUE, 0);
   2881                 soc_trident2_pipe_select(unit, FALSE, 0);
   2882             }
   2883 
   2884             if (is_physical_index) {
   2885                 flags = SOC_MEM_DONT_MAP_INDEX;
   2886             }
   2887             /* read the memory into a buffer */
   2888             if ((1 == pipe) &&
   2889                 ((_SOC_ACC_TYPE_PIPE_BCAST == acc_type) ||
   2890                  (_SOC_ACC_TYPE_PIPE_SBS == acc_type))) {
   2891                 soc_mem_pipe_select_read(unit, flags, mem, mem_block,
   2892                                          _SOC_ACC_TYPE_PIPE_Y, index, tmp_entry);
   2893             } else {
   2894                 /*Enable NACK on read */
   2895                 flags |= SOC_MEM_SCHAN_ERR_RETURN;
   2896                  soc_mem_read_extended(unit, flags,
   2897                                        mem, 0, mem_block,
   2898                                        index, tmp_entry);
   2899             }
   2900 
   2901             /* Enable Parity */
   2902             if ((parity_enable_reg != INVALIDr) &&
   2903                 (parity_enable_field != INVALIDf)) {
   2904                 if ((1 == pipe) && (at == _SOC_ACC_TYPE_PIPE_SBS)) {
   2905                     soc_trident2_pipe_select(unit, TRUE, 1);
   2906                     soc_trident2_pipe_select(unit, FALSE, 1);
   2907                 }
   2908                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2909                     REG_PORT_ANY, parity_enable_field, 1) < 0) {
   2910                     soc_trident2_pipe_select(unit, TRUE, 0);
   2911                     soc_trident2_pipe_select(unit, FALSE, 0);
   2912                     IP_ARBITER_UNLOCK(unit);
   2913                     return 0;
   2914                 }
   2915             }
   2916 
   2917             /* Make sure the pipe is set correctly */
   2918             soc_trident2_pipe_select(unit, TRUE, 0);
   2919             soc_trident2_pipe_select(unit, FALSE, 0);
   2920             IP_ARBITER_UNLOCK(unit);
   2921 
   2922         }
   2923 
   2924         if ((SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) &&
   2925              L2Xm == mem) {
   2926             soc_l2x_selective_thaw(unit, SOC_L2X_FROZEN_WITHOUT_LOCK);
   2927         }
   2928 
   2929         if (!is_dynamic_mem && !skip) {
   2930             /* fill in the memory contents tlv only when the mem is no dynamic */
   2931             if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS,
   2932                 entry_dw*4, tmp_entry) < 0) {
   2933                 return 0;
   2934             }
   2935 
   2936 
   2937             if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   2938                 /* fill in the memory cache tlv */
   2939                 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE,
   2940                     entry_dw*4, (cache + index*entry_dw)) < 0) {
   2941                     return 0;
   2942                 }
   2943             }
   2944         }
   2945     } else {
   2946         if ((mem != INVALIDm) &&
   2947             (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) == 0)) {
   2948             /* Check to make sure this isn't a duplicate */
   2949             /* Search for a log entry with the same mem, and index with within the last 5 seconds */
   2950             if (soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()) > 0) {
   2951                 return 0;
   2952             }
   2953 
   2954             /* create the entry based on determined size, save id */
   2955             id = soc_ser_log_create_entry(unit, log_entry_size);
   2956 
   2957             log_mem.memory = mem;
   2958             log_mem.index = index;
   2959             soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY,
   2960                 sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   2961         } else {
   2962             id = soc_ser_log_create_entry(unit, log_entry_size);
   2963             if (id == 0) {
   2964                 return id;
   2965             }
   2966             log_mem.memory = mem;
   2967             log_mem.index = index;
   2968             log_mem.hwbase = hwbase;
   2969             soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY,
   2970                                 sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   2971         }
   2972     }
   2973 
   2974     return id;
   2975 }
   2976 
   2977 STATIC int
   2978 _soc_trident2_ser_process_parity(int unit, int block_info_idx, int pipe, int port,
   2979                                  const _soc_td2_ser_info_t *info,
   2980                                  int schan, char *prefix_str, char *mem_str)
   2981 {
   2982     int rv;
   2983     _soc_td2_ser_reg_t reg_entry[2], *reg_ptr;
   2984     soc_reg_t reg;
   2985     uint32 rval, minfo;
   2986     uint32 multiple, entry_idx, idx, has_error;
   2987     char *mem_str_ptr;
   2988     _soc_ser_correct_info_t spci;
   2989     soc_stat_t *stat = SOC_STAT(unit);
   2990 
   2991     if (schan) {
   2992         /* Some table does not have NACK register */
   2993         return SOC_E_NONE;
   2994     } else {
   2995         if (info->intr_status_reg != INVALIDr) {
   2996             reg_entry[0].reg = info->intr_status_reg;
   2997             reg_entry[0].mem_str = NULL;
   2998             reg_entry[1].reg = INVALIDr;
   2999             reg_ptr = reg_entry;
   3000         } else if (info->intr_status_reg_list != NULL) {
   3001             reg_ptr = info->intr_status_reg_list;
   3002         } else {
   3003             return SOC_E_NONE;
   3004         }
   3005     }
   3006 
   3007     has_error = FALSE;
   3008     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   3009         reg = reg_ptr[idx].reg;
   3010         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   3011             reg_ptr[idx].mem_str : mem_str;
   3012         SOC_IF_ERROR_RETURN
   3013             (soc_reg32_get(unit, reg, port, 0, &rval));
   3014 
   3015         if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) {
   3016             has_error = TRUE;
   3017             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   3018             entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   3019             _soc_td2_mem_parity_info(unit, block_info_idx, pipe,
   3020                                      info->group_reg_status_field, &minfo);
   3021             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3022                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3023                                SOC_SER_ERROR_ENTRY_ID_MINFO_SET | entry_idx,
   3024                                minfo);
   3025             LOG_WARN(BSL_LS_SOC_SER,
   3026                       (BSL_META_U(unit,
   3027                                   "%s %s entry %d parity error\n"),
   3028                        prefix_str, mem_str_ptr, entry_idx));
   3029             if (multiple) {
   3030                 LOG_WARN(BSL_LS_SOC_SER,
   3031                           (BSL_META_U(unit,
   3032                                       "%s %s has multiple parity errors\n"),
   3033                            prefix_str, mem_str_ptr));
   3034             }
   3035             if (idx == 0 && info->mem != INVALIDm) {
   3036                 sal_memset(&spci, 0, sizeof(spci));
   3037                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   3038                 if (SOC_MEM_SER_CORRECTION_TYPE(unit, info->mem) != SOC_MEM_FLAG_SER_SPECIAL) {
   3039                     spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   3040                 }
   3041                 if (multiple) {
   3042                     spci.flags |= SOC_SER_ERR_MULTI;
   3043                 }
   3044                 spci.reg = INVALIDr;
   3045                 spci.mem = info->mem;
   3046                 spci.blk_type = -1;
   3047                 spci.index = entry_idx;
   3048                 spci.parity_type = info->type;
   3049                 spci.detect_time = sal_time_usecs();
   3050                 spci.log_id = _soc_td2_populate_ser_log(unit,
   3051                                           info->enable_reg,
   3052                                           info->enable_field,
   3053                                           spci.mem,
   3054                                           SOC_MEM_BLOCK_ANY(unit, spci.mem),
   3055                                           spci.acc_type,
   3056                                           spci.index,
   3057                                           spci.detect_time,
   3058                                           spci.sblk,
   3059                                           spci.addr,
   3060                                           pipe,
   3061                                           FALSE, 0);
   3062                 rv = soc_ser_correction(unit, &spci);
   3063                 if (spci.log_id != 0) {
   3064                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3065                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3066                                        spci.log_id, 0);
   3067                 }
   3068                 if (SOC_FAILURE(rv)) {
   3069                     /* Add reporting failed to correct event flag to
   3070                      * application */
   3071                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3072                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3073                             entry_idx, minfo);
   3074                     soc_ser_stat_update(unit, 0,
   3075                                         SOC_BLOCK_INFO(unit, block_info_idx).type,
   3076                                         spci.parity_type,
   3077                                         spci.double_bit,
   3078                                         SocSerCorrectTypeFailedToCorrect,
   3079                                         stat);
   3080                     return rv;
   3081                 }
   3082             }
   3083         }
   3084 
   3085         /* Clear parity status */
   3086         SOC_IF_ERROR_RETURN
   3087             (soc_reg32_set(unit, reg, port, 0, 0));
   3088     }
   3089 
   3090     if (!has_error) {
   3091         LOG_ERROR(BSL_LS_SOC_SER,
   3092                   (BSL_META_U(unit,
   3093                               "%s %s parity hardware inconsistency\n"),
   3094                    prefix_str, mem_str));
   3095     }
   3096 
   3097     return SOC_E_NONE;
   3098 }
   3099 
   3100 STATIC int
   3101 _soc_trident2_ser_process_ecc(int unit, int block_info_idx, int pipe, int port,
   3102                               const _soc_td2_ser_info_t *info,
   3103                               int schan, char *prefix_str, char *mem_str)
   3104 {
   3105     int rv;
   3106     _soc_td2_ser_reg_t reg_entry[2], *reg_ptr;
   3107     soc_reg_t reg;
   3108     uint32 minfo;
   3109     uint64 rval64;
   3110     uint32 multiple, double_bit, entry_idx, idx, has_error;
   3111     char *mem_str_ptr;
   3112     _soc_ser_correct_info_t spci;
   3113     soc_stat_t *stat = SOC_STAT(unit);
   3114 
   3115     if (schan) {
   3116         /* Some table does not have NACK register */
   3117         return SOC_E_NONE;
   3118     } else {
   3119         if (info->intr_status_reg != INVALIDr) {
   3120             reg_entry[0].reg = info->intr_status_reg;
   3121             reg_entry[0].mem_str = NULL;
   3122             reg_entry[1].reg = INVALIDr;
   3123             reg_ptr = reg_entry;
   3124         } else if (info->intr_status_reg_list != NULL) {
   3125             reg_ptr = info->intr_status_reg_list;
   3126         } else {
   3127             return SOC_E_NONE;
   3128         }
   3129     }
   3130 
   3131     has_error = FALSE;
   3132     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   3133         reg = reg_ptr[idx].reg;
   3134         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   3135             reg_ptr[idx].mem_str : mem_str;
   3136         SOC_IF_ERROR_RETURN
   3137             (soc_reg_get(unit, reg, port, 0, &rval64));
   3138 
   3139         if (soc_reg64_field32_get(unit, reg, rval64, ECC_ERRf)) {
   3140             has_error = TRUE;
   3141             multiple = soc_reg64_field32_get(unit, reg, rval64, MULTIPLE_ERRf);
   3142             double_bit = soc_reg64_field32_get(unit, reg, rval64, DOUBLE_BIT_ERRf);
   3143             entry_idx = soc_reg64_field32_get(unit, reg, rval64, ENTRY_IDXf);
   3144             _soc_td2_mem_parity_info(unit, block_info_idx, pipe,
   3145                                      info->group_reg_status_field, &minfo);
   3146             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3147                                SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   3148                                SOC_SER_ERROR_ENTRY_ID_MINFO_SET | entry_idx,
   3149                                minfo);
   3150             sal_memset(&spci, 0, sizeof(spci));
   3151             if (double_bit) {
   3152                 spci.double_bit = 1;
   3153                 LOG_WARN(BSL_LS_SOC_SER,
   3154                           (BSL_META_U(unit,
   3155                                       "%s %s entry %d double-bit ECC error\n"),
   3156                            prefix_str, mem_str_ptr, entry_idx));
   3157             } else {
   3158                 LOG_WARN(BSL_LS_SOC_SER,
   3159                           (BSL_META_U(unit,
   3160                                       "%s %s entry %d ECC error\n"),
   3161                            prefix_str, mem_str_ptr, entry_idx));
   3162             }
   3163             if (multiple) {
   3164                 LOG_WARN(BSL_LS_SOC_SER,
   3165                           (BSL_META_U(unit,
   3166                                       "%s %s has multiple ECC errors\n"),
   3167                            prefix_str, mem_str_ptr));
   3168             }
   3169             if (idx == 0 && info->mem != INVALIDm) {
   3170                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   3171                 if (SOC_MEM_SER_CORRECTION_TYPE(unit, info->mem) != SOC_MEM_FLAG_SER_SPECIAL) {
   3172                     spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   3173                 }
   3174                 if (multiple) {
   3175                     spci.flags |= SOC_SER_ERR_MULTI;
   3176                 }
   3177                 spci.reg = INVALIDr;
   3178                 spci.mem = info->mem;
   3179                 spci.blk_type = -1;
   3180                 spci.index = entry_idx;
   3181                 spci.parity_type = SOC_PARITY_TYPE_ECC;
   3182                 spci.detect_time = sal_time_usecs();
   3183                 spci.log_id = _soc_td2_populate_ser_log(unit,
   3184                                           info->enable_reg,
   3185                                           info->enable_field,
   3186                                           spci.mem,
   3187                                           SOC_MEM_BLOCK_ANY(unit, spci.mem),
   3188                                           spci.acc_type,
   3189                                           spci.index,
   3190                                           spci.detect_time,
   3191                                           spci.sblk,
   3192                                           spci.addr,
   3193                                           pipe,
   3194                                           FALSE, 0);
   3195                 rv = soc_ser_correction(unit, &spci);
   3196                 if (spci.log_id != 0) {
   3197                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3198                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3199                                        spci.log_id, 0);
   3200                 }
   3201                 if (SOC_FAILURE(rv)) {
   3202                     /* Add reporting failed to correct event flag to
   3203                      * application */
   3204                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3205                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3206                             entry_idx, minfo);
   3207                     soc_ser_stat_update(unit, 0,
   3208                                         SOC_BLOCK_INFO(unit, block_info_idx).type,
   3209                                         spci.parity_type,
   3210                                         spci.double_bit,
   3211                                         SocSerCorrectTypeFailedToCorrect,
   3212                                         stat);
   3213                     return rv;
   3214                 }
   3215             }
   3216         }
   3217 
   3218         /* Clear parity status */
   3219         COMPILER_64_ZERO(rval64);
   3220         SOC_IF_ERROR_RETURN
   3221             (soc_reg_set(unit, reg, port, 0, rval64));
   3222     }
   3223 
   3224     if (!has_error) {
   3225         LOG_ERROR(BSL_LS_SOC_SER,
   3226                   (BSL_META_U(unit,
   3227                               "%s %s ECC hardware inconsistency\n"),
   3228                    prefix_str, mem_str));
   3229     }
   3230 
   3231     return SOC_E_NONE;
   3232 }
   3233 
   3234 STATIC soc_bst_intr_check_cb td2_bst_intr_check;
   3235 
   3236 STATIC int
   3237 _soc_td2_bst_intr_check(int unit)
   3238 {
   3239     int rv = SOC_E_NONE;
   3240     if (td2_bst_intr_check) {
   3241         rv = td2_bst_intr_check(unit);
   3242     }
   3243     return rv;
   3244 }
   3245 
   3246 int
   3247 soc_td2_set_bst_intr_check_callback(int unit, soc_bst_intr_check_cb cb)
   3248 {
   3249     td2_bst_intr_check = cb;
   3250     return SOC_E_NONE;
   3251 }
   3252 
   3253 STATIC int
   3254 _soc_trident2_ser_process_bst_intr_check(int unit)
   3255 {
   3256     uint32 do_check = 0, rval;
   3257     uint32 sval[3] = {0}, tval[3] = {0};
   3258     soc_field_t snap_fld[3] = {BST_HW_SNAPSHOT_EN_THDOf,
   3259                         BST_HW_SNAPSHOT_EN_THDIf,
   3260                         BST_HW_SNAPSHOT_EN_CFAPf};
   3261     soc_field_t track_fld[3] = {BST_TRACK_EN_THDOf,
   3262                         BST_TRACK_EN_THDIf,
   3263                         BST_TRACK_EN_CFAPf};
   3264 
   3265     SOC_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval));
   3266     sval[0] = soc_reg_field_get(unit, BST_HW_SNAPSHOT_ENr, rval, snap_fld[0]);
   3267     sval[1] = soc_reg_field_get(unit, BST_HW_SNAPSHOT_ENr, rval, snap_fld[1]);
   3268     sval[2] = soc_reg_field_get(unit, BST_HW_SNAPSHOT_ENr, rval, snap_fld[2]);
   3269 
   3270     SOC_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
   3271     tval[0] = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, track_fld[0]);
   3272     tval[1] = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, track_fld[1]);
   3273     tval[2] = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, track_fld[2]);
   3274 
   3275     do_check = ((sval[0] && !tval[0]) ||
   3276         (sval[1] && !tval[1]) ||
   3277         (sval[2] && !tval[2]));
   3278 
   3279     /* If any BST snapshot is enabled and BST tracking is disabled,  do an examination for BST_TRIGGER and BST_STAT*/
   3280     if (do_check) {
   3281         _soc_td2_bst_intr_check(unit);
   3282         return SOC_E_NONE;
   3283     }
   3284 
   3285     return SOC_E_NONE;
   3286 }
   3287 
   3288 STATIC int
   3289 _soc_td_ser_mem_error_is_ecc(int unit, _soc_ser_correct_info_t *si)
   3290 {
   3291     int rv = SOC_E_NONE;
   3292     void * ser_mem_info = NULL;
   3293 
   3294     rv = _soc_trident2_ser_mem_info_get (unit, si->mem, &ser_mem_info);
   3295     if (rv == SOC_E_NONE) {
   3296 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   3297         if (SOC_IS_TD2P_TT2P(unit)) {
   3298             if (SOC_REG_IS_VALID(unit, ((_soc_mem_ser_en_info_t*)ser_mem_info)->ecc1b_ctrl.ctrl_type.en_reg) &&
   3299                 (INVALIDf != ((_soc_mem_ser_en_info_t*)ser_mem_info)->ecc1b_ctrl.en_fld)) {
   3300                 return TRUE;
   3301             }
   3302         }
   3303 #endif
   3304     }
   3305 
   3306     if(!SOC_IS_TD2P_TT2P(unit)) {
   3307         rv = _soc_trident2_mmu_ecc_mem_ser_info_get(unit, si->mem, &ser_mem_info);
   3308         if (rv == SOC_E_NONE) {
   3309             return TRUE;
   3310         }
   3311     }
   3312 
   3313     return FALSE;
   3314 }
   3315 
   3316 STATIC int
   3317 _soc_trident2_ser_log_update(int unit, _soc_ser_correct_info_t *si)
   3318 {
   3319     soc_ser_log_tlv_generic_t log_generic;
   3320 
   3321     if (NULL == si) {
   3322         return (SOC_E_PARAM);
   3323     }
   3324 
   3325     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3326 
   3327     if (si->log_id != 0) {
   3328         log_generic.flags = 0;
   3329         if (si->flags & SOC_SER_ERR_CPU) {
   3330             log_generic.flags |= SOC_SER_LOG_FLAG_ERR_SRC;
   3331         }
   3332         if (si->flags & SOC_SER_ERR_MULTI) {
   3333             log_generic.flags |= SOC_SER_LOG_FLAG_MULTIBIT;
   3334         }
   3335         if (si->double_bit != 0) {
   3336             log_generic.flags |= SOC_SER_LOG_FLAG_DOUBLEBIT;
   3337         }
   3338         log_generic.time = si->detect_time;
   3339         log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3340         log_generic.address = si->addr;
   3341         log_generic.acc_type = si->acc_type;
   3342         log_generic.block_type = si->blk_type;
   3343         log_generic.parity_type = si->parity_type;
   3344         log_generic.ser_response_flag = SOC_MEM_SER_CORRECTION_TYPE(unit, si->mem);
   3345         log_generic.corrected = SOC_SER_UNCORRECTED;
   3346         log_generic.pipe_num = si->pipe_num;
   3347         log_generic.inst = si->inst;
   3348 
   3349         soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC,
   3350                 sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3351     }
   3352 
   3353     return (SOC_E_NONE);
   3354 }
   3355 
   3356 STATIC void
   3357 _soc_trident2_ser_mmu_mem_remap(soc_mem_t *mem)
   3358 {
   3359     switch(*mem) {
   3360         case THDI_PORT_SP_CONFIG0_Ym:
   3361         case THDI_PORT_SP_CONFIG1_Ym:
   3362         case THDI_PORT_SP_CONFIG2_Ym:
   3363             *mem = THDI_PORT_SP_CONFIG_Ym;
   3364             break;
   3365         case THDI_PORT_SP_CONFIG0_Xm:
   3366         case THDI_PORT_SP_CONFIG1_Xm:
   3367         case THDI_PORT_SP_CONFIG2_Xm:
   3368             *mem = THDI_PORT_SP_CONFIG_Xm;
   3369             break;
   3370         case MMU_THDM_DB_PORTSP_CONFIG_0Am:
   3371         case MMU_THDM_DB_PORTSP_CONFIG_0Bm:
   3372         case MMU_THDM_DB_PORTSP_CONFIG_0Cm:
   3373             *mem = MMU_THDM_DB_PORTSP_CONFIG_0m;
   3374             break;
   3375         case MMU_THDM_DB_PORTSP_CONFIG_1Am:
   3376         case MMU_THDM_DB_PORTSP_CONFIG_1Bm:
   3377         case MMU_THDM_DB_PORTSP_CONFIG_1Cm:
   3378             *mem = MMU_THDM_DB_PORTSP_CONFIG_1m;
   3379             break;
   3380         case MMU_THDU_XPIPE_Q_TO_QGRP_MAP_0m:
   3381         case MMU_THDU_XPIPE_Q_TO_QGRP_MAP_1m:
   3382             *mem = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm;
   3383             break;
   3384         case MMU_THDU_XPIPE_RESUME_PORT_0m:
   3385         case MMU_THDU_XPIPE_RESUME_PORT_1m:
   3386             *mem = MMU_THDU_XPIPE_RESUME_PORTm;
   3387             break;
   3388         case MMU_THDU_YPIPE_Q_TO_QGRP_MAP_0m:
   3389         case MMU_THDU_YPIPE_Q_TO_QGRP_MAP_1m:
   3390             *mem = MMU_THDU_YPIPE_Q_TO_QGRP_MAPm;
   3391             break;
   3392         case MMU_THDU_YPIPE_RESUME_PORT_0m:
   3393         case MMU_THDU_YPIPE_RESUME_PORT_1m:
   3394             *mem = MMU_THDU_YPIPE_RESUME_PORTm;
   3395             break;
   3396         case MMU_THDM_MCQE_PORTSP_CONFIG_0Am:
   3397         case MMU_THDM_MCQE_PORTSP_CONFIG_0Bm:
   3398             *mem = MMU_THDM_MCQE_PORTSP_CONFIG_0m;
   3399             break;
   3400         case MMU_THDM_MCQE_PORTSP_CONFIG_1Am:
   3401         case MMU_THDM_MCQE_PORTSP_CONFIG_1Bm:
   3402             *mem = MMU_THDM_MCQE_PORTSP_CONFIG_1m;
   3403             break;
   3404         default:
   3405             break;
   3406     }
   3407 }
   3408 
   3409 STATIC int
   3410 _soc_trident2_ser_process_mmu_err(int unit, int block_info_idx,
   3411                                   const _soc_td2_ser_info_t *info,
   3412                                   char *prefix_str, int pipe)
   3413 {
   3414     uint32 rval, err, addr, bidx;
   3415     uint64 rval64;
   3416     soc_reg_t reg = MMU_MEM_FAIL_ADDR_64r;
   3417     uint8 blk_idx;
   3418     uint32 sblk = 0;
   3419     int rv = SOC_E_NONE;
   3420     int is_ecc = FALSE;
   3421     soc_reg_t parity_enable_reg = INVALIDr;
   3422     soc_field_t parity_enable_field = INVALIDf;
   3423     _soc_ser_correct_info_t spci;
   3424     soc_stat_t *stat = SOC_STAT(unit);
   3425 
   3426     SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval));
   3427     if (soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)) {
   3428         LOG_ERROR(BSL_LS_SOC_SER,
   3429                   (BSL_META_U(unit,
   3430                               "unit %d MMU SER interrupt with empty fifo !!\n"),
   3431                               unit));
   3432         SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   3433         LOG_WARN(BSL_LS_SOC_SER,
   3434                   (BSL_META_U(unit,
   3435                               "unit %d MMU ERR status: 0x%08x\n"), unit, rval));
   3436         SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0));
   3437         /*Check if bst interrupt occurs and process it if yes*/
   3438         _soc_trident2_ser_process_bst_intr_check(unit);
   3439         return rv;
   3440     }
   3441     SOC_BLOCK_ITER(unit, blk_idx, SOC_BLK_MMU) {
   3442         sblk = SOC_BLOCK2SCH(unit, blk_idx);
   3443         break;
   3444     }
   3445     do {
   3446         SOC_IF_ERROR_RETURN(READ_MMU_MEM_FAIL_ADDR_64r(unit, &rval64));
   3447         err = soc_reg64_field32_get(unit, reg, rval64, ERR_TYPEf);
   3448         addr = soc_reg64_field32_get(unit, reg, rval64, EADDRf);
   3449         bidx = soc_reg64_field32_get(unit, reg, rval64, BIDXf);
   3450         /* Address reported in MMU_MEM_FAIL_ADDR_64 is the entry offset within
   3451          * MMU sub block. The complete Sbus address is composed of MMU sub block
   3452          * base address and offset within MMU sub block address space.
   3453          */
   3454         addr = (bidx << 26) | addr;
   3455         sal_memset(&spci, 0, sizeof(spci));
   3456         spci.flags |= SOC_SER_SRC_MEM;
   3457         spci.reg = INVALIDr;
   3458         spci.mem = INVALIDm;
   3459         spci.blk_type = SOC_BLK_MMU;
   3460         spci.sblk = sblk;
   3461         spci.detect_time = sal_time_usecs();
   3462         spci.double_bit = (err == 2) ? 1 : 0;
   3463 
   3464         /* Try to decode memory */
   3465         spci.mem = soc_addr_to_mem_extended(unit, sblk, _SOC_ACC_TYPE_PIPE_ANY, addr);
   3466         if (spci.mem != INVALIDm) {
   3467             spci.index = addr - soc_mem_base(unit, spci.mem);
   3468             spci.flags |= SOC_SER_REG_MEM_KNOWN;
   3469             if (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != SOC_MEM_FLAG_SER_SPECIAL) {
   3470                 spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   3471             }
   3472 #ifdef BCM_56860_A0
   3473             if (SOC_IS_TD2P_TT2P(unit)) {
   3474                 _soc_trident2_ser_control_reg_get(unit, _soc_bcm56860_a0_mmu_mem_ser_info,
   3475                                                   spci.mem,
   3476                                                   &parity_enable_reg,
   3477                                                   &parity_enable_field);
   3478             } else
   3479 #endif
   3480             {
   3481                 parity_enable_reg = PARITY_ENr;
   3482                 parity_enable_field = _soc_td2_mmu_parity_enable_fields[bidx];
   3483             }
   3484         } else {
   3485             spci.flags |= SOC_SER_REG_MEM_UNKNOWN;
   3486         }
   3487         spci.mem_reported = spci.mem;
   3488         _soc_trident2_ser_mmu_mem_remap(&spci.mem);
   3489         is_ecc = _soc_td_ser_mem_error_is_ecc(unit, &spci);
   3490         LOG_WARN(BSL_LS_SOC_SER,
   3491                   (BSL_META_U(unit,
   3492                               "unit %d MMU ERR Type: %s, Addr: 0x%08x, module: %d\n"),
   3493                               unit, (is_ecc && (err == 2)) ? "2B error" : "1B error", addr, bidx));
   3494         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3495                            (is_ecc) ? SOC_SWITCH_EVENT_DATA_ERROR_ECC : SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3496                            sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3497         spci.log_id = _soc_td2_populate_ser_log(unit, parity_enable_reg, parity_enable_field,
   3498                                                 spci.mem_reported, blk_idx,
   3499                                                 _SOC_ACC_TYPE_PIPE_ANY, spci.index,
   3500                                                 spci.detect_time, spci.sblk,
   3501                                                 spci.addr, pipe, FALSE, 0);
   3502 
   3503         if ((spci.mem == INVALIDm) ||
   3504             (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != 0)) {
   3505             if (SOC_IS_TRIDENT2(unit) && ((addr & 0xFFFFF000) == 0x64001000)) {
   3506                 spci.mem = ES_PIPE0_LLS_PORT_MEMA_CONFIGm;
   3507                 spci.index = addr - 0x64001000;
   3508                 spci.flags |= SOC_SER_REG_MEM_KNOWN | SOC_SER_SKIP_HARD_FALT_CHECK;
   3509             }
   3510             rv = soc_ser_correction(unit, &spci);
   3511             if (SOC_FAILURE(rv)) {
   3512                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3513                                    SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3514                                    sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3515                 soc_ser_stat_update(unit, 0,
   3516                                     spci.blk_type,
   3517                                     SOC_PARITY_TYPE_PARITY,
   3518                                     spci.double_bit,
   3519                                     SocSerCorrectTypeFailedToCorrect,
   3520                                     stat);
   3521             }
   3522         } else if (spci.mem == INVALIDm) {
   3523             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3524                                SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3525                                sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET,
   3526                                addr);
   3527             soc_ser_stat_update(unit, 0, spci.blk_type,
   3528                                 SOC_PARITY_TYPE_PARITY,
   3529                                 spci.double_bit,
   3530                                 SocSerCorrectTypeNoAction,
   3531                                 stat);
   3532             LOG_ERROR(BSL_LS_SOC_SER,
   3533                       (BSL_META_U(unit,
   3534                                   "unit %d address 0x%08x: decoding of address to mem FAILED !!\n"),
   3535                        unit, addr));
   3536 
   3537             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3538                                SOC_SWITCH_EVENT_DATA_ERROR_FATAL,
   3539                                INVALIDm, 
   3540                                spci.index); 
   3541             /* Dont 'return' here - as it will skip clearing of
   3542              * interrupt and thus will result in processing of empty
   3543              * ser fifo */
   3544         } else {
   3545             if ((spci.mem != INVALIDm) &&
   3546                 (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) == 0) &&
   3547                 (spci.log_id != 0)) {
   3548 
   3549                 spci.addr = addr;
   3550                 if (TRUE == is_ecc) {
   3551                     spci.parity_type = SOC_PARITY_TYPE_ECC;
   3552                 } else {
   3553                     spci.parity_type = SOC_PARITY_TYPE_PARITY;
   3554                 }
   3555                 SOC_IF_ERROR_RETURN(_soc_trident2_ser_log_update(unit, &spci));
   3556             }
   3557 
   3558             soc_ser_stat_update(unit, 0,
   3559                                 spci.blk_type,
   3560                                 SOC_PARITY_TYPE_PARITY,
   3561                                 spci.double_bit,
   3562                                 SocSerCorrectTypeNoAction,
   3563                                 stat);
   3564             if (spci.double_bit) {
   3565                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3566                                    SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE,
   3567                                    sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3568             } else {
   3569                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3570                                    SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED,
   3571                                    sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3572             }
   3573         }
   3574 
   3575         if (spci.double_bit && SOC_MEM_IS_VALID(unit, spci.mem) &&
   3576             (SOC_MEM_INFO(unit, spci.mem).flags &
   3577              SOC_MEM_FLAG_SER_ECC_CORRECTABLE)) {
   3578             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3579                                SOC_SWITCH_EVENT_DATA_ERROR_FATAL,
   3580                                spci.mem, spci.index);
   3581         }
   3582         if (spci.log_id != 0) {
   3583             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3584                                SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3585                                spci.log_id, 0);
   3586         }
   3587         SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_CTRr(unit, &rval));
   3588         LOG_WARN(BSL_LS_SOC_SER,
   3589                   (BSL_META_U(unit,
   3590                               "unit %d MMU ERR ctr: %d\n"), unit, rval));
   3591         SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval));
   3592     } while (!soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf));
   3593 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   3594     if (SOC_IS_TD2P_TT2P(unit)) {
   3595         SOC_IF_ERROR_RETURN
   3596             (soc_reg_field32_modify(unit, MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3597                                     MEM_PAR_ERR_CLRf, 1));
   3598         SOC_IF_ERROR_RETURN
   3599             (soc_reg_field32_modify(unit, MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3600                                     MEM_PAR_ERR_CLRf, 0));
   3601     } else
   3602 #endif
   3603     {
   3604         SOC_IF_ERROR_RETURN
   3605             (soc_reg_field32_modify(unit, info->intr_status_reg, REG_PORT_ANY,
   3606                                     info->group_reg_status_field, 0));
   3607     }
   3608     /*Check if bst interrupt occurs and process it if yes*/
   3609     _soc_trident2_ser_process_bst_intr_check(unit);
   3610 
   3611     return rv;
   3612 }
   3613 
   3614 STATIC int
   3615 _soc_trident2_ser_process_start_err(int unit, int block_info_idx,
   3616                                     const _soc_td2_ser_info_t *info,
   3617                                     char *prefix_str)
   3618 {
   3619     soc_info_t *si;
   3620     uint64 rval64;
   3621     uint32 pbmp_31_0, pbmp_63_32, pbmp_96_64, pbmp_116_97;
   3622     soc_pbmp_t pbmp;
   3623     uint32 minfo, rval;
   3624     int port, mmu_port, phy_port;
   3625     soc_ser_log_tlv_generic_t log_generic;
   3626     int log_id;
   3627     soc_stat_t *stat = SOC_STAT(unit);
   3628 
   3629     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3630 
   3631     si = &SOC_INFO(unit);
   3632 
   3633     /* mmu port 52-0 */
   3634     SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR_0r(unit, &rval64));
   3635     pbmp_31_0 = COMPILER_64_LO(rval64);
   3636     pbmp_63_32 = COMPILER_64_HI(rval64);
   3637     /* mmu port 116-64 */
   3638     SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR_1r(unit, &rval64));
   3639     pbmp_96_64 = COMPILER_64_LO(rval64);
   3640     pbmp_116_97 = COMPILER_64_HI(rval64);
   3641     SOC_PBMP_CLEAR(pbmp);
   3642     SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0);
   3643     SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32);
   3644     SOC_PBMP_WORD_SET(pbmp, 2, pbmp_96_64);
   3645     SOC_PBMP_WORD_SET(pbmp, 3, pbmp_116_97);
   3646 
   3647     SOC_PBMP_ITER(pbmp, mmu_port) {
   3648         phy_port = si->port_m2p_mapping[mmu_port];
   3649         port = si->port_p2l_mapping[phy_port];
   3650         _soc_td2_mem_parity_info(unit, block_info_idx, 0,
   3651                                  info->group_reg_status_field, &minfo);
   3652         /* Report uncorrectable event flag to application */
   3653         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3654                            SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0,
   3655                            minfo);
   3656 
   3657         log_generic.time = sal_time_usecs();
   3658         log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3659         log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3660         log_generic.parity_type = info->type;
   3661 
   3662         log_id = soc_ser_log_create_entry(unit,
   3663             sizeof(soc_ser_log_tlv_generic_t) +
   3664             sizeof(soc_ser_log_tlv_hdr_t) *2);
   3665 
   3666         soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC,
   3667             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3668         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3669                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3670 
   3671         soc_ser_stat_update(unit, 0, SOC_BLOCK_INFO(unit, block_info_idx).type,
   3672                             SOC_PARITY_TYPE_PARITY,
   3673                             0, SocSerCorrectTypeNoAction, stat);
   3674         LOG_WARN(BSL_LS_SOC_SER,
   3675                   (BSL_META_U(unit,
   3676                               "%s port %d start error detected\n"), prefix_str,
   3677                               port));
   3678     }
   3679 
   3680     /* Clear parity status */
   3681     COMPILER_64_ZERO(rval64);
   3682     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_0r(unit, rval64));
   3683     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_1r(unit, rval64));
   3684     SOC_IF_ERROR_RETURN
   3685         (READ_MEM_FAIL_INT_STATr(unit, &rval));
   3686     soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, START_BY_START_ERRf, 0);
   3687     SOC_IF_ERROR_RETURN
   3688         (WRITE_MEM_FAIL_INT_STATr(unit, rval));
   3689     return SOC_E_NONE;
   3690 }
   3691 
   3692 STATIC int
   3693 _soc_trident2_process_ser(int unit, int block_info_idx, int inst, int pipe,
   3694                           int port, soc_reg_t group_reg, uint64 group_rval,
   3695                           const _soc_td2_ser_info_t *info_list,
   3696                           char *prefix_str);
   3697 STATIC int
   3698 _soc_trident2_ser_process_cport(int unit, int inst, int pipe,
   3699                                 const _soc_td2_ser_info_t *info)
   3700 {
   3701     soc_reg_t port_reg;
   3702     uint64 port_rval;
   3703     int block_info_idx, port;
   3704     char prefix_str[24];
   3705 
   3706     if (info->intr_status_reg == INVALIDr) {
   3707         return SOC_E_NONE;
   3708     }
   3709 
   3710     port = -1;
   3711     SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CPORT) {
   3712         if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst) {
   3713             port = SOC_BLOCK_PORT(unit, block_info_idx);
   3714             break;
   3715         }
   3716     }
   3717     if (port < 0) {
   3718         return SOC_E_NONE;
   3719     }
   3720 
   3721     port_reg = info->intr_status_reg;
   3722     SOC_IF_ERROR_RETURN
   3723         (soc_reg_get(unit, port_reg, port, 0, &port_rval));
   3724     if (COMPILER_64_IS_ZERO(port_rval)) {
   3725         return SOC_E_NONE;
   3726     }
   3727 
   3728     sal_sprintf(prefix_str, "unit %d CPORT%d", unit, inst);
   3729     SOC_IF_ERROR_RETURN
   3730         (_soc_trident2_process_ser(unit, block_info_idx, inst, pipe, port,
   3731                                    port_reg, port_rval, info->info, prefix_str));
   3732 
   3733     return SOC_E_NONE;
   3734 }
   3735 
   3736 STATIC _soc_td2_bst_hw_cb td2_bst_cb;
   3737 
   3738 STATIC int
   3739 _soc_td2_process_mmu_bst(int unit)
   3740 {
   3741     int rv = SOC_E_NONE;
   3742     if (td2_bst_cb) {
   3743         rv = td2_bst_cb(unit);
   3744     }
   3745     return rv;
   3746 }
   3747 
   3748 int soc_td2_set_bst_callback(int unit, _soc_td2_bst_hw_cb cb)
   3749 {
   3750     td2_bst_cb = cb;
   3751     return SOC_E_NONE;
   3752 }
   3753 
   3754 STATIC int
   3755 _soc_trident2_ser_process_cfap_mem_fail(int unit)
   3756 {
   3757     uint32 rval;
   3758 
   3759     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   3760     if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, rval, CFAP_MEM_FAILf)) {
   3761         LOG_WARN(BSL_LS_SOC_SER,
   3762                   (BSL_META_U(unit,
   3763                               "unit %d MMU ERR status: 0x%08x\n"), unit, rval));
   3764         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3765                            SOC_SWITCH_EVENT_DATA_ERROR_CFAP_MEM_FAIL, -1, -1);
   3766 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   3767         if (SOC_IS_TD2P_TT2P(unit)) {
   3768             SOC_IF_ERROR_RETURN
   3769                 (soc_reg_field32_modify(unit,
   3770                                         MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3771                                         CFAP_MEM_FAIL_CLRf, 1));
   3772             SOC_IF_ERROR_RETURN
   3773                 (soc_reg_field32_modify(unit,
   3774                                         MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3775                                         CFAP_MEM_FAIL_CLRf, 0));
   3776         } else
   3777 #endif
   3778         /* TD2 does not have MEM_FAIL_INT_CLEARr, so clear the
   3779            field manually. */
   3780         {
   3781             SOC_IF_ERROR_RETURN
   3782                 (soc_reg_field32_modify(unit,
   3783                                         MEM_FAIL_INT_STATr, REG_PORT_ANY,
   3784                                         CFAP_MEM_FAILf, 0));
   3785         }
   3786 
   3787     }
   3788 
   3789     return SOC_E_NONE;
   3790 }
   3791 
   3792 STATIC int
   3793 _soc_trident2_process_ser(int unit, int block_info_idx, int inst, int pipe,
   3794                           int port, soc_reg_t group_reg, uint64 group_rval,
   3795                           const _soc_td2_ser_info_t *info_list,
   3796                           char *prefix_str)
   3797 {
   3798     const _soc_td2_ser_info_t *info;
   3799     int info_index;
   3800     char *mem_str;
   3801     uint32 minfo;
   3802     soc_ser_log_tlv_generic_t log_generic;
   3803     int log_id;
   3804     uint32 block_type = 0;
   3805     soc_stat_t *stat = SOC_STAT(unit);
   3806 
   3807     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3808 
   3809     /* Loop through each info entry in the list */
   3810     for (info_index = 0; ; info_index++) {
   3811         info = &info_list[info_index];
   3812         if (info->type == _SOC_PARITY_TYPE_NONE) {
   3813             /* End of table */
   3814             break;
   3815         }
   3816 
   3817         /* Check status for the info entry in the group register */
   3818         if (!soc_reg64_field32_get(unit, group_reg, group_rval,
   3819                                    info->group_reg_status_field)) {
   3820             continue;
   3821         }
   3822 
   3823         if (info->mem_str) {
   3824             mem_str = info->mem_str;
   3825         } else if (info->mem != INVALIDm) {
   3826             mem_str = SOC_MEM_NAME(unit, info->mem);
   3827         } else {
   3828             mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field);
   3829         }
   3830 
   3831         /* Handle different parity error reporting style */
   3832         switch (info->type) {
   3833         case _SOC_PARITY_TYPE_GENERIC:
   3834             _soc_td2_mem_parity_info(unit, block_info_idx, 0,
   3835                                      info->group_reg_status_field, &minfo);
   3836             /* Report uncorrectable event flag to application */
   3837             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3838                                SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0,
   3839                                minfo);
   3840 
   3841             log_generic.time = sal_time_usecs();
   3842             log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3843             log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3844             log_generic.parity_type = info->type;
   3845 
   3846             log_id = soc_ser_log_create_entry(unit,
   3847                 sizeof(soc_ser_log_tlv_generic_t) +
   3848                 sizeof(soc_ser_log_tlv_hdr_t) *2);
   3849 
   3850             soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC,
   3851                 sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3852             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3853                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3854             block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3855             soc_ser_stat_update(unit, 0, block_type, SOC_PARITY_TYPE_PARITY,
   3856                                 0, SocSerCorrectTypeNoAction, stat);
   3857             LOG_WARN(BSL_LS_SOC_SER,
   3858                       (BSL_META_U(unit,
   3859                                   "%s %s asserted\n"), prefix_str, mem_str));
   3860 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   3861             if (SOC_IS_TD2P_TT2P(unit)) {
   3862                 SOC_IF_ERROR_RETURN
   3863                     (soc_reg_field32_modify(unit,
   3864                                             MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3865                                             DEQ_NOT_IP_ERR_CLRf, 1));
   3866                 SOC_IF_ERROR_RETURN
   3867                     (soc_reg_field32_modify(unit,
   3868                                             MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3869                                             DEQ_NOT_IP_ERR_CLRf, 0));
   3870             } else
   3871 #endif
   3872             /* TD2 does not have MEM_FAIL_INT_CLEARr, so clear the
   3873                field manually. */
   3874             {
   3875                 SOC_IF_ERROR_RETURN
   3876                     (soc_reg_field32_modify(unit,
   3877                                             MEM_FAIL_INT_STATr, REG_PORT_ANY,
   3878                                             info->group_reg_status_field, 0));
   3879             }
   3880             break;
   3881         case _SOC_PARITY_TYPE_PARITY:
   3882             /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */
   3883             SOC_IF_ERROR_RETURN
   3884                 (_soc_trident2_ser_process_parity(unit, block_info_idx,
   3885                                                   pipe, port, info, FALSE,
   3886                                                   prefix_str, mem_str));
   3887             break;
   3888         case _SOC_PARITY_TYPE_ECC:
   3889             /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   3890             SOC_IF_ERROR_RETURN
   3891                 (_soc_trident2_ser_process_ecc(unit, block_info_idx, pipe,
   3892                                                port, info, FALSE,
   3893                                                prefix_str, mem_str));
   3894             break;
   3895         case _SOC_PARITY_TYPE_CPORT:
   3896             /* One more level of report tree structure */
   3897             SOC_IF_ERROR_RETURN
   3898                 (_soc_trident2_ser_process_cport(unit, inst, pipe, info));
   3899             break;
   3900         case _SOC_PARITY_TYPE_START_ERR:
   3901             SOC_IF_ERROR_RETURN
   3902                 (_soc_trident2_ser_process_start_err(unit, block_info_idx,
   3903                                                      info, prefix_str));
   3904             break;
   3905         case _SOC_PARITY_TYPE_MMU_SER:
   3906             SOC_IF_ERROR_RETURN
   3907                 (_soc_trident2_ser_process_mmu_err(unit, block_info_idx,
   3908                                                    info, prefix_str, pipe));
   3909             break;
   3910         case _SOC_PARITY_TYPE_BST:
   3911             SOC_IF_ERROR_RETURN(_soc_td2_process_mmu_bst(unit));
   3912             break;
   3913         case _SOC_PARITY_TYPE_CFAP_MEM_FAIL:
   3914             SOC_IF_ERROR_RETURN(_soc_trident2_ser_process_cfap_mem_fail(unit));
   3915             break;
   3916         default:
   3917             break;
   3918         } /* Handle different parity error reporting style */
   3919     } /* Loop through each info entry in the list */
   3920 
   3921     return SOC_E_NONE;
   3922 }
   3923 
   3924 STATIC char *_soc_td2_ser_hwmem_base_info[] = {
   3925     "CMIC PKT BUFFER - In Iarb",
   3926     "CPU PKT BUFFER - In Iarb",
   3927     "Invalid value",
   3928     "EINITBUF_PACKET_BUFFER - In Iarb",
   3929     "INGRESS PACKET BUFFER - In Ipars",
   3930     "Invalid value",
   3931     "Invalid value",
   3932     "Invalid value",
   3933     "Invalid value",
   3934     "Invalid value",
   3935     "Invalid value",
   3936     "Invalid value",
   3937     "Invalid value",
   3938     "Invalid value",
   3939     "Invalid value",
   3940     "Invalid value",
   3941     "EP MPB DATA - In El3",
   3942     "EP INITBUF - In Ehcpm",
   3943     "CM DATA BUFFER - In Edatabuf",
   3944     "XLP0 DATA BUFFER - In Edatabuf",
   3945     "XLP1 DATA BUFFER - In Edatabuf",
   3946     "XLP2 DATA BUFFER - In Edatabuf",
   3947     "XLP3 DATA BUFFER - In Edatabuf",
   3948     "XLP4 DATA BUFFER - In Edatabuf",
   3949     "XLP5 DATA BUFFER - In Edatabuf",
   3950     "XLP6 DATA BUFFER - In Edatabuf",
   3951     "XLP7 DATA BUFFER - In Edatabuf",
   3952     "XLP8 DATA BUFFER - In Edatabuf",
   3953     "XLP9 DATA BUFFER - In Edatabuf",
   3954     "XLP10 DATA BUFFER - In Edatabuf",
   3955     "XLP11 DATA BUFFER - In Edatabuf",
   3956     "XLP12 DATA BUFFER - In Edatabuf",
   3957     "XLP13 DATA BUFFER - In Edatabuf",
   3958     "XLP14 DATA BUFFER - In Edatabuf",
   3959     "XLP15 DATA BUFFER - In Edatabuf",
   3960     "CLP0 DATA BUFFER - In Edatabuf",
   3961     "CLP1 DATA BUFFER - In Edatabuf",
   3962     "CLP2 DATA BUFFER - In Edatabuf",
   3963     "CLP3 DATA BUFFER - In Edatabuf",
   3964     "XLP RESI0 DATA BUFFER - In Edatabuf",
   3965     "XLP RESI1 DATA BUFFER - In Edatabuf",
   3966     "XLP RESI2 DATA BUFFER - In Edatabuf",
   3967     "XLP RESI3 DATA BUFFER - In Edatabuf",
   3968     "Invalid value",
   3969     "Invalid value",
   3970     "Invalid value",
   3971     "Invalid value",
   3972     "Invalid value",
   3973     "Invalid value",
   3974     "Invalid value",
   3975     "Invalid value",
   3976     "XLP0 EDB CTRL BUFFER - In Edatabuf",
   3977     "XLP1 EDB CTRL BUFFER - In Edatabuf",
   3978     "XLP2 EDB CTRL BUFFER - In Edatabuf",
   3979     "XLP3 EDB CTRL BUFFER - In Edatabuf",
   3980     "XLP4 EDB CTRL BUFFER - In Edatabuf",
   3981     "XLP5 EDB CTRL BUFFER - In Edatabuf",
   3982     "XLP6 EDB CTRL BUFFER - In Edatabuf",
   3983     "XLP7 EDB CTRL BUFFER - In Edatabuf",
   3984     "XLP8 EDB CTRL BUFFER - In Edatabuf",
   3985     "XLP9 EDB CTRL BUFFER - In Edatabuf",
   3986     "XLP10 EDB CTRL BUFFER - In Edatabuf",
   3987     "XLP11 EDB CTRL BUFFER - In Edatabuf",
   3988     "XLP12 EDB CTRL BUFFER - In Edatabuf",
   3989     "XLP13 EDB CTRL BUFFER - In Edatabuf",
   3990     "XLP14 EDB CTRL BUFFER - In Edatabuf",
   3991     "XLP15 EDB CTRL BUFFER - In Edatabuf",
   3992     "CLP0 EDB CTRL BUFFER - In Edatabuf",
   3993     "CLP1 EDB CTRL BUFFER - In Edatabuf",
   3994     "CLP2 EDB CTRL BUFFER - In Edatabuf",
   3995     "CLP3 EDB CTRL BUFFER - In Edatabuf",
   3996     "LEARN FIFO - In IARB",
   3997     "EGR VLAN BUS",
   3998     "EGR HCPM BUS",
   3999     "EGR PMOD BUS",
   4000     "EGR FPPARS BUS",
   4001     "EFP BUS",
   4002     "IVP BUS",
   4003     "ICFG BUS",
   4004     "Invalid value",
   4005     "Invalid value",
   4006     "Invalid value",
   4007     "Invalid value",
   4008     "Invalid value",
   4009     "Invalid value",
   4010     "Invalid value",
   4011     "Invalid value",
   4012     "Invalid value",
   4013     "IPARS BUS",
   4014     "IVXLT BUS",
   4015     "IMPLS BUS",
   4016     "IL2L3 BUS",
   4017     "Invalid value",
   4018     "IFP BUS",
   4019     "IRSEL1 BUS",
   4020     "ISW1 BUS",
   4021     "IRSEL2 BUS"
   4022 };
   4023 
   4024 #define _SOC_TD2_SER_REG 1
   4025 #define _SOC_TD2_SER_MEM 0
   4026 
   4027 STATIC void
   4028 _soc_trident2_print_ser_fifo_details(int unit, uint8 regmem, soc_block_t blk,
   4029                                      uint32 sblk, int pipe, uint32 address,
   4030                                      uint32 stage, uint32 base, uint32 index,
   4031                                      uint32 hwmbase, uint32 type, uint8 drop,
   4032                                      uint8 non_sbus)
   4033 {
   4034     uint32 hwmbase_max = 0;
   4035     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityError, unit)) {
   4036         switch (type) {
   4037         case 0:
   4038             LOG_WARN(BSL_LS_SOC_SER,
   4039                       (BSL_META_U(unit,
   4040                                   "Error in: SOP cell.\n")));
   4041             break;
   4042         case 1:
   4043             LOG_WARN(BSL_LS_SOC_SER,
   4044                       (BSL_META_U(unit,
   4045                                   "Error in: MOP cell.\n")));
   4046             break;
   4047         case 2:
   4048             LOG_WARN(BSL_LS_SOC_SER,
   4049                       (BSL_META_U(unit,
   4050                                   "Error in: EOP cell.\n")));
   4051             break;
   4052         case 3:
   4053             LOG_WARN(BSL_LS_SOC_SER,
   4054                       (BSL_META_U(unit,
   4055                                   "Error in: SBUS transaction.\n")));
   4056             break;
   4057         case 4:
   4058             LOG_WARN(BSL_LS_SOC_SER,
   4059                       (BSL_META_U(unit,
   4060                                   "Error in: miscellaneous transaction.\n")));
   4061             break;
   4062         default:
   4063             LOG_ERROR(BSL_LS_SOC_SER,
   4064                       (BSL_META_U(unit,
   4065                                   "Invalid error reported !!\n")));
   4066             break;
   4067         }
   4068         LOG_WARN(BSL_LS_SOC_SER,
   4069                   (BSL_META_U(unit,
   4070                               "Blk: %d, Pipe: %d, Address: 0x%08x, base: 0x%x, stage: %d, index: %d\n"),
   4071                               sblk, pipe, address, base, stage, index));
   4072         if (regmem == _SOC_TD2_SER_MEM) {
   4073             if (hwmbase >= 0x80) {
   4074                 hwmbase -= 0x38; /* handle the gap */
   4075             }
   4076             if (non_sbus) {
   4077                 hwmbase_max = sizeof(_soc_td2_ser_hwmem_base_info)/sizeof(_soc_td2_ser_hwmem_base_info[0]);
   4078                 /* coverity[overrun-local] */
   4079                 LOG_WARN(BSL_LS_SOC_SER,
   4080                           (BSL_META_U(unit,
   4081                                       "Mem hwbase: 0x%x [%s]\n"), hwmbase,
   4082                                       (hwmbase < hwmbase_max) ? _soc_td2_ser_hwmem_base_info[hwmbase] : "--"));
   4083             }
   4084         }
   4085         if (drop) {
   4086             LOG_WARN(BSL_LS_SOC_SER,
   4087                       (BSL_META_U(unit,
   4088                                   "SER caused packet drop.\n")));
   4089         }
   4090     }
   4091 }
   4092 
   4093 #define IF_IPEP_SBS_CTRL_LOCK(_unit_) \
   4094         if ((mem == EGR_SER_FIFOm) && (pipe != 0)) { \
   4095             IP_ARBITER_LOCK(_unit_);\
   4096             (void)soc_trident2_pipe_select(unit, TRUE, 1); \
   4097         }
   4098 
   4099 #define IF_IPEP_SBS_CTRL_UNLOCK(_unit_) \
   4100         if ((mem == EGR_SER_FIFOm) && (pipe != 0)) { \
   4101             (void)soc_trident2_pipe_select(unit, TRUE, 0); \
   4102             IP_ARBITER_UNLOCK(_unit_); \
   4103         } \
   4104 
   4105 STATIC uint32
   4106 _soc_trident2_flex_ctr_addr_check(int unit, uint32 address, soc_block_t blk,
   4107                                   uint32 stage, uint32 index)
   4108 {
   4109     uint32 index2 = index;
   4110 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4111     if (SOC_IS_TD2P_TT2P(unit)) {
   4112         if ((SOC_BLK_IPIPE == blk) && (21 == stage)) {
   4113             switch (address & 0xfffff000) {
   4114             /* ING_FLEX_CTR_OFFSET_TABLE_*m */
   4115             case 0x56800000:
   4116             case 0x56801000:
   4117             case 0x56802000:
   4118             case 0x56803000:
   4119             case 0x56840000:
   4120             case 0x56841000:
   4121             case 0x56842000:
   4122             case 0x56843000:
   4123                 index2 = address & 0x3ff; break; /* 1K depth */
   4124             /* ING_FLEX_CTR_COUNTER_TABLE_*m */
   4125             case 0x56804000:
   4126             case 0x56808000:
   4127             case 0x5680c000:
   4128             case 0x56810000:
   4129             case 0x56844000:
   4130             case 0x56848000:
   4131             case 0x5684c000:
   4132             case 0x56850000:
   4133                 index2 = address & 0xfff; break; /* 4K depth */
   4134             default:
   4135                 break;
   4136             }
   4137         }
   4138     } else
   4139 #endif
   4140     {
   4141         if ((blk == SOC_BLK_IPIPE) && (stage == 17)) {
   4142             switch (address & 0XFFFFF000) {
   4143             case 0x46800000:
   4144             case 0x46801000:
   4145             case 0x46802000:
   4146             case 0x46803000:
   4147             case 0x46840000:
   4148             case 0x46841000:
   4149             case 0x46842000:
   4150             case 0x46843000:
   4151                 index2 = address & 0x3ff; break; /* 1K depth */
   4152             case 0x46804000:
   4153             case 0x46808000:
   4154             case 0x4680c000:
   4155             case 0x46810000:
   4156             case 0x46844000:
   4157             case 0x46848000:
   4158             case 0x4684c000:
   4159             case 0x46850000:
   4160                 index2 = address & 0xfff; break; /* 4K depth */
   4161             default:
   4162                 break;
   4163             }
   4164         }
   4165     }
   4166     if ((SOC_BLK_EPIPE == blk) && (10 == stage)) {
   4167         switch (address & 0XFFFFF000) {
   4168         case 0x2a800000:
   4169         case 0x2a801000:
   4170         case 0x2a802000:
   4171         case 0x2a803000:
   4172             index2 = address & 0x3ff; break; /* 1K depth */
   4173         case 0x2a804000:
   4174         case 0x2a808000:
   4175         case 0x2a80c000:
   4176         case 0x2a810000:
   4177             index2 = address & 0xfff; break; /* 4K depth */
   4178         default:
   4179             break;
   4180         }
   4181     }
   4182     return index2;
   4183 }
   4184 
   4185 STATIC int
   4186 _soc_trident2_process_ser_fifo(int unit, soc_block_t blk, int pipe, char *prefix_str)
   4187 {
   4188     int i, rv;
   4189     uint8 bidx;
   4190     soc_mem_t mem;
   4191     char blk_str[10];
   4192     int *acc_type_ptr;
   4193     soc_reg_t reg = INVALIDr;
   4194     _soc_ser_correct_info_t spci;
   4195     void* ser_info_table = NULL;
   4196     soc_reg_t parity_enable_reg = INVALIDr;
   4197     soc_field_t parity_enable_field = INVALIDf;
   4198     /* There are a few tables in TD2 (like is ING_NEXT_HOP, L2MC, L3_IPMC),
   4199      * whose physical implementation is only one copy. They are written through
   4200      * the X-pipe. Type 1 in Y-pipe list covers memories of this structure.
   4201      */
   4202     static int acc_type1[] = { 3, 2, 6, 4, 1, 0, -1 };
   4203     static int acc_type0[] = { 1, 3, 6, 4, 0, -1 };
   4204     uint32 reg_val, mask, entry[SOC_MAX_MEM_WORDS];
   4205     uint32 stage = 0, addrbase = 0, index = 0, hwmbase = 0, type = 0;
   4206     uint32 sblk = 0, regmem = 0, non_sbus = 0, drop = 0, ecc_parity = 0, address = 0;
   4207     soc_stat_t *stat = SOC_STAT(unit);
   4208 
   4209 
   4210     switch (blk) {
   4211     case SOC_BLK_IPIPE:
   4212         mem = pipe ? ING_SER_FIFO_Ym : ING_SER_FIFO_Xm;
   4213 #ifdef BCM_56860_A0
   4214         if (SOC_IS_TD2P_TT2P(unit)) {
   4215             mask = _soc_td2p_ip_pipe_fifo_bmask[unit][ pipe ];
   4216             ser_info_table = _soc_bcm56860_a0_ip_mem_ser_info;
   4217         } else
   4218 #endif
   4219         {
   4220             mask = pipe ? 0x15540 : 0xAAA0; /* All IP bits based upon pipe */
   4221             ser_info_table = _soc_td2_ip_ser_info;
   4222         }
   4223         sal_sprintf(blk_str, "IPIPE");
   4224         break;
   4225     case SOC_BLK_EPIPE:
   4226 #ifdef BCM_56860_A0
   4227         if (SOC_IS_TD2P_TT2P(unit)) {
   4228             mem = EGR_SER_FIFOm;
   4229             ser_info_table = _soc_bcm56860_a0_ep_mem_ser_info;
   4230         } else
   4231 #endif
   4232         {
   4233             mem = pipe ? EGR_SER_FIFO_Ym : EGR_SER_FIFO_Xm;
   4234             ser_info_table = _soc_td2_ep_ser_info;
   4235         }
   4236         mask = 0x00000001; /* SER_FIFO_NON_EMPTYf */
   4237         reg = EGR_INTR_STATUSr;
   4238         sal_sprintf(blk_str, "EPIPE");
   4239         break;
   4240     default:
   4241         return SOC_E_PARAM;
   4242     }
   4243 
   4244     do {
   4245         
   4246         IF_IPEP_SBS_CTRL_LOCK(unit);
   4247         rv = soc_mem_pop(unit, mem, MEM_BLOCK_ANY, entry);
   4248         IF_IPEP_SBS_CTRL_UNLOCK(unit);
   4249 
   4250         SOC_IF_ERROR_RETURN(rv);
   4251         /* process entry */
   4252         if (soc_mem_field32_get(unit, mem, entry, VALIDf)) {
   4253             ecc_parity = soc_mem_field32_get(unit, mem, entry, ECC_PARITYf);
   4254             regmem = soc_mem_field32_get(unit, mem, entry, MEM_TYPEf);
   4255             address = soc_mem_field32_get(unit, mem, entry, ADDRESSf);
   4256             stage = soc_mem_field32_get(unit, mem, entry, PIPE_STAGEf);
   4257             type = soc_mem_field32_get(unit, mem, entry, INSTRUCTION_TYPEf);
   4258             drop = soc_mem_field32_get(unit, mem, entry, DROPf);
   4259             SOC_BLOCK_ITER(unit, bidx, blk) {
   4260                 sblk = SOC_BLOCK2SCH(unit, bidx);
   4261                 break;
   4262             }
   4263             LOG_WARN(BSL_LS_SOC_SER,
   4264                       (BSL_META_U(unit,
   4265                                   "%s\n"), prefix_str));
   4266             if (soc_mem_field32_get(unit, mem, entry, MULTIPLEf)) {
   4267                 LOG_WARN(BSL_LS_SOC_SER,
   4268                           (BSL_META_U(unit,
   4269                                       "Multiple: ")));
   4270             }
   4271             if (regmem == _SOC_TD2_SER_REG) {
   4272                 LOG_WARN(BSL_LS_SOC_SER,
   4273                           (BSL_META_U(unit,
   4274                                       "Reg: ")));
   4275             } else {
   4276                 LOG_WARN(BSL_LS_SOC_SER,
   4277                           (BSL_META_U(unit,
   4278                                       "Mem: ")));
   4279             }
   4280             spci.double_bit = 0;
   4281             switch (ecc_parity) {
   4282             case 0:
   4283                 LOG_WARN(BSL_LS_SOC_SER,
   4284                           (BSL_META_U(unit,
   4285                                       "Parity error..\n")));
   4286                 break;
   4287             case 1:
   4288                 LOG_WARN(BSL_LS_SOC_SER,
   4289                           (BSL_META_U(unit,
   4290                                       "Corrected single bit ECC error..\n")));
   4291                 break;
   4292             case 2:
   4293                 LOG_WARN(BSL_LS_SOC_SER,
   4294                           (BSL_META_U(unit,
   4295                                       "Double or Multiple bit ECC error..\n")));
   4296                 spci.double_bit = 1;
   4297                 break;
   4298             default:
   4299                 LOG_ERROR(BSL_LS_SOC_SER,
   4300                           (BSL_META_U(unit,
   4301                                       "Invalid SER issue !!\n")));
   4302 
   4303                 return SOC_E_INTERNAL;
   4304             }
   4305             if (regmem == _SOC_TD2_SER_MEM) {
   4306                 /* process mem */
   4307                 non_sbus = soc_mem_field32_get(unit, mem, entry, NON_SBUSf);
   4308                 addrbase = soc_mem_field32_get(unit, mem, entry, MEMBASEf);
   4309                 index = soc_mem_field32_get(unit, mem, entry, MEMINDEXf);
   4310                 hwmbase = soc_mem_field32_get(unit, mem, entry, HWMEMBASEf);
   4311 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4312                 if (SOC_IS_TD2P_TT2P(unit)){
   4313                     if ((blk == SOC_BLK_IPIPE) && (stage == 9 || stage == 13)) {
   4314                         /* Mems in these stages in IPIPE have more than
   4315                          * 256k indexes */
   4316                         index |= hwmbase << 18;
   4317                         hwmbase = addrbase = 0;
   4318                     }
   4319                 } else
   4320 #endif
   4321                 {
   4322                     if ((blk == SOC_BLK_IPIPE) &&
   4323                         (stage == 7 ||stage == 8 || stage == 11)) {
   4324                         /* Mems in these stages in IPIPE have more than
   4325                          * 256k indexes */
   4326                         index |= hwmbase << 18;
   4327                         hwmbase = addrbase = 0;
   4328                     }
   4329                 }
   4330                 index = _soc_trident2_flex_ctr_addr_check(unit, address, blk,
   4331                                                           stage, index);
   4332                 if (non_sbus == 0) {
   4333                     acc_type_ptr = pipe ? acc_type1 : acc_type0;
   4334                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4335                                        ecc_parity == 0 ?
   4336                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   4337                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   4338                                        sblk | (pipe << SOC_SER_ERROR_PIPE_BP) |
   4339                                        SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4340                     _soc_trident2_print_ser_fifo_details(unit, 0, blk, sblk, pipe, address,
   4341                                                          stage, addrbase, index, hwmbase,
   4342                                                          type, drop, non_sbus);
   4343                     sal_memset(&spci, 0, sizeof(spci));
   4344                     spci.flags = SOC_SER_SRC_MEM;
   4345                     spci.reg = INVALIDr;
   4346                     spci.mem = INVALIDm;
   4347                     spci.pipe_num = pipe;
   4348                     spci.blk_type = blk;
   4349                     spci.sblk = sblk;
   4350                     spci.addr = address - index;
   4351                     spci.index = index;
   4352                     spci.stage = stage;
   4353                     spci.detect_time = sal_time_usecs();
   4354                     spci.parity_type = ecc_parity ? SOC_PARITY_TYPE_ECC : SOC_PARITY_TYPE_PARITY;
   4355                     spci.double_bit = (ecc_parity == 2) ? 1 : 0;
   4356 
   4357                     /* Try to decode mem first */
   4358                     for (i = 0; acc_type_ptr[i] != -1; i++) {
   4359                         spci.mem = soc_addr_to_mem_extended(unit,
   4360                                     spci.sblk, acc_type_ptr[i], spci.addr);
   4361 
   4362                         if (spci.mem != INVALIDm) {
   4363                             break;
   4364                         }
   4365                     }
   4366 
   4367                     if (spci.mem != INVALIDm) {
   4368                         spci.acc_type = acc_type_ptr[i];
   4369                         spci.flags |= SOC_SER_REG_MEM_KNOWN;
   4370                     }
   4371                     else {
   4372                         /* Invalid mem, use the first acc_type_ptr*/
   4373                         spci.acc_type = acc_type_ptr[0];
   4374                         spci.flags |= SOC_SER_REG_MEM_UNKNOWN;
   4375                     }
   4376 
   4377                     if (spci.mem != INVALIDm) {
   4378                         _soc_trident2_ser_control_reg_get(unit, ser_info_table,
   4379                             spci.mem,
   4380                             &parity_enable_reg,
   4381                             &parity_enable_field);
   4382                     }
   4383 
   4384 #ifdef ALPM_ENABLE
   4385                     if ((spci.mem == L3_DEFIP_ALPM_ECCm) ||
   4386                         (spci.mem == L3_DEFIP_ALPM_IPV4m) ||
   4387                         (spci.mem == L3_DEFIP_ALPM_IPV4_1m) ||
   4388                         (spci.mem == L3_DEFIP_ALPM_IPV6_64m) ||
   4389                         (spci.mem == L3_DEFIP_ALPM_IPV6_64_1m) ||
   4390                         (spci.mem == L3_DEFIP_ALPM_IPV6_128m) ||
   4391                         (spci.mem == L3_DEFIP_AUX_TABLEm)) {
   4392                         SOC_ALPM_LPM_LOCK(unit);
   4393                     } else 
   4394 #endif
   4395                     {
   4396                         if (spci.mem != INVALIDm) {
   4397                             MEM_LOCK(unit,spci.mem);
   4398                         }
   4399                     }
   4400                     if (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != SOC_MEM_FLAG_SER_SPECIAL) {
   4401                         spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   4402                     }
   4403                     spci.log_id = _soc_td2_populate_ser_log(unit,
   4404                                               parity_enable_reg,
   4405                                               parity_enable_field,
   4406                                               spci.mem,
   4407                                               bidx,
   4408                                               spci.acc_type,
   4409                                               spci.index,
   4410                                               spci.detect_time,
   4411                                               spci.sblk,
   4412                                               spci.addr,
   4413                                               pipe,
   4414                                               TRUE, 0);
   4415 #ifdef ALPM_ENABLE
   4416                     if ((spci.mem == L3_DEFIP_ALPM_ECCm) ||
   4417                         (spci.mem == L3_DEFIP_ALPM_IPV4m) ||
   4418                         (spci.mem == L3_DEFIP_ALPM_IPV4_1m) ||
   4419                         (spci.mem == L3_DEFIP_ALPM_IPV6_64m) ||
   4420                         (spci.mem == L3_DEFIP_ALPM_IPV6_64_1m) ||
   4421                         (spci.mem == L3_DEFIP_ALPM_IPV6_128m) ||
   4422                         (spci.mem == L3_DEFIP_ALPM_RAWm) ||
   4423                         (spci.mem == L3_DEFIP_AUX_TABLEm)) {
   4424                         SOC_ALPM_LPM_UNLOCK(unit);
   4425                     } else
   4426 #endif
   4427                     {
   4428                         if (spci.mem != INVALIDm) {
   4429                             MEM_UNLOCK(unit,spci.mem);
   4430                         }
   4431                     }
   4432 
   4433                     rv = soc_ser_correction(unit, &spci);
   4434                     if (spci.log_id != 0) {
   4435                         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4436                                            SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   4437                                            spci.log_id, 0);
   4438                     }
   4439                     if (SOC_FAILURE(rv)) {
   4440                         if (rv != SOC_E_NOT_FOUND) {
   4441                             /* Add reporting failed to correct event flag to
   4442                              * application */
   4443                             soc_event_generate(unit,
   4444                                     SOC_SWITCH_EVENT_PARITY_ERROR,
   4445                                     SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   4446                                     sblk | (pipe << SOC_SER_ERROR_PIPE_BP) |
   4447                                     SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4448                             return rv;
   4449                         }
   4450                         soc_ser_stat_update(unit, 0, spci.blk_type,
   4451                                             spci.parity_type,
   4452                                             spci.double_bit,
   4453                                             SocSerCorrectTypeFailedToCorrect,
   4454                                             stat);
   4455                     }
   4456                 } else {
   4457                     LOG_WARN(BSL_LS_SOC_SER,
   4458                               (BSL_META_U(unit,
   4459                                           "%s SER mem address un-accessable !!\n"), blk_str));
   4460                     soc_ser_stat_update(unit, 0, spci.blk_type,
   4461                                         spci.parity_type,
   4462                                         spci.double_bit,
   4463                                         SocSerCorrectTypeNoAction,
   4464                                         stat);
   4465                     /* Report an event to application even though the memory cannot be accessed */
   4466                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4467                                        ecc_parity == 0 ?
   4468                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   4469                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   4470                                        sblk | (pipe << SOC_SER_ERROR_PIPE_BP) |
   4471                                        SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4472                     _soc_trident2_print_ser_fifo_details(unit, 0, blk, sblk, pipe, address,
   4473                                                          stage, addrbase, index, hwmbase,
   4474                                                          type, drop, non_sbus);
   4475                     _soc_td2_populate_ser_log(unit, INVALIDr, INVALIDf, INVALIDm, bidx, 0,
   4476                                               index, sal_time_usecs(), sblk, address, pipe,
   4477                                               FALSE, addrbase);
   4478                 }
   4479             } else {
   4480                 /* process reg */
   4481                 non_sbus = soc_mem_field32_get(unit, mem, entry, NON_SBUSf);
   4482                 addrbase = soc_mem_field32_get(unit, mem, entry, REGBASEf);
   4483                 index = soc_mem_field32_get(unit, mem, entry, REGINDEXf);
   4484                 if (non_sbus == 0) {
   4485                     acc_type_ptr = pipe ? acc_type1 : acc_type0;
   4486                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4487                                        ecc_parity == 0 ?
   4488                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   4489                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   4490                                        sblk | (pipe << SOC_SER_ERROR_PIPE_BP) |
   4491                                        SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4492                     _soc_trident2_print_ser_fifo_details(unit, 1, blk, sblk, pipe, address,
   4493                                                          stage, addrbase, index, 0, type,
   4494                                                          drop, non_sbus);
   4495                     sal_memset(&spci, 0, sizeof(spci));
   4496                     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_UNKNOWN;
   4497                     spci.reg = INVALIDr;
   4498                     spci.mem = INVALIDm;
   4499                     spci.blk_type = blk;
   4500                     spci.sblk = sblk;
   4501                     spci.addr = address;
   4502                     spci.index = index;
   4503                     spci.stage = stage;
   4504                     spci.detect_time = sal_time_usecs();
   4505                     spci.parity_type = ecc_parity ? SOC_PARITY_TYPE_ECC : SOC_PARITY_TYPE_PARITY;
   4506                     spci.double_bit = (ecc_parity == 2) ? 1 : 0;
   4507                     for (i = 0; acc_type_ptr[i] != -1; i++) {
   4508                         spci.acc_type = acc_type_ptr[i];
   4509                         spci.log_id = soc_ser_log_create_entry(unit,
   4510                             sizeof(soc_ser_log_tlv_generic_t) +
   4511                             sizeof(soc_ser_log_tlv_register_t) +
   4512                             sizeof(soc_ser_log_tlv_hdr_t) *3);
   4513                         rv = soc_ser_correction(unit, &spci);
   4514                         if (spci.log_id != 0) {
   4515                             soc_event_generate(unit,
   4516                                                SOC_SWITCH_EVENT_PARITY_ERROR,
   4517                                                SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   4518                                                spci.log_id, 0);
   4519                         }
   4520                         if (SOC_FAILURE(rv)) {
   4521                             if (rv == SOC_E_NOT_FOUND) {
   4522                                 continue;
   4523                             }
   4524                             /* Add reporting failed to correct event flag to
   4525                              * application */
   4526                             soc_event_generate(unit,
   4527                                     SOC_SWITCH_EVENT_PARITY_ERROR,
   4528                                     SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   4529                                     sblk | (pipe << SOC_SER_ERROR_PIPE_BP) |
   4530                                     SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4531                             soc_ser_stat_update(unit, 0, spci.blk_type,
   4532                                                 spci.parity_type,
   4533                                                 spci.double_bit,
   4534                                                 SocSerCorrectTypeFailedToCorrect,
   4535                                                 stat);
   4536                             return rv;
   4537                         }
   4538                         break;
   4539                     }
   4540                 } else {
   4541                     LOG_WARN(BSL_LS_SOC_SER,
   4542                               (BSL_META_U(unit,
   4543                                           "%s SER reg address un-accessable !!\n"), blk_str));
   4544                     soc_ser_stat_update(unit, 0, spci.blk_type,
   4545                                         spci.parity_type,
   4546                                         spci.double_bit,
   4547                                         SocSerCorrectTypeNoAction,
   4548                                         stat);
   4549                     /* Report an event to application even though the reg cannot be accessed */
   4550                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4551                                        ecc_parity == 0 ?
   4552                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   4553                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   4554                                        sblk | (pipe << SOC_SER_ERROR_PIPE_BP) |
   4555                                        SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4556                     _soc_trident2_print_ser_fifo_details(unit, 0, blk, sblk, pipe, address,
   4557                                                          stage, addrbase, index, hwmbase,
   4558                                                          type, drop, non_sbus);
   4559                 }
   4560             }
   4561         } else {
   4562             LOG_ERROR(BSL_LS_SOC_SER,
   4563                       (BSL_META_U(unit,
   4564                                   "unit %d Got invalid mem pop from %s !!\n"),
   4565                                   unit, SOC_MEM_NAME(unit, mem)));
   4566         }
   4567         /* check if any more pending */
   4568         if (reg == INVALIDr) {
   4569             rv = READ_CMIC_CMC0_IRQ_STAT2r(unit, &reg_val);
   4570         } else {
   4571             rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &reg_val);
   4572         }
   4573         SOC_IF_ERROR_RETURN(rv);
   4574     } while (reg_val & mask);
   4575     return SOC_E_NONE;
   4576 }
   4577 
   4578 STATIC void
   4579 _soc_trident2_ser_control_reg_get(int unit, void *fifo_ser_list,
   4580                                   soc_mem_t   mem,
   4581                                   soc_reg_t   *ser_control_reg,
   4582                                   soc_field_t *ser_enable_field)
   4583 {
   4584     int i;
   4585     _soc_td2_fifo_ser_info_t *fifo_ser_info = NULL;
   4586 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4587     _soc_mem_ser_en_info_t *ser_en_info = NULL;
   4588 #endif
   4589     if ((fifo_ser_list == NULL) || (ser_control_reg == NULL) ||
   4590         (ser_enable_field == NULL)) {
   4591         return;
   4592     }
   4593 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4594     if (SOC_IS_TD2P_TT2P(unit)) {
   4595         ser_en_info = (_soc_mem_ser_en_info_t*)fifo_ser_list;
   4596         for (i = 0; ser_en_info[i].mem != INVALIDm; i++) {
   4597             if (ser_en_info[i].mem == mem) {
   4598                 *ser_control_reg = ser_en_info[i].en_ctrl.ctrl_type.en_reg;
   4599                 *ser_enable_field = ser_en_info[i].en_ctrl.en_fld;
   4600                 break;
   4601             }
   4602         }
   4603     } else
   4604 #endif
   4605     {
   4606         fifo_ser_info = (_soc_td2_fifo_ser_info_t*)fifo_ser_list;
   4607         _soc_trident2_mem_rename(&mem);
   4608         for (i = 0; fifo_ser_info[i].enable_reg != INVALIDr; i++) {
   4609             if (fifo_ser_info[i].mem == mem) {
   4610                 *ser_control_reg = fifo_ser_info[i].enable_reg;
   4611                 *ser_enable_field = fifo_ser_info[i].enable_field;
   4612                 break;
   4613             }
   4614         }
   4615     }
   4616     return;
   4617 }
   4618 
   4619 
   4620 STATIC int
   4621 _soc_trident2_ser_process_all(int unit)
   4622 {
   4623     uint8      rbi;
   4624     int        port = REG_PORT_ANY;
   4625     uint32     cmic_rval, cmic_bit;
   4626     uint64     rb_rval64;
   4627     const      _soc_td2_ser_route_block_t *rb;
   4628     char       prefix_str[10];
   4629     int        block_info_idx;
   4630     soc_stat_t *stat = SOC_STAT(unit);
   4631 
   4632     sal_sprintf(prefix_str, "Unit: %d \n", unit);
   4633 
   4634     /* Read CMIC parity status register */
   4635     /* coverity[result_independent_of_operands] */
   4636     SOC_IF_ERROR_RETURN
   4637         (READ_CMIC_CMC0_IRQ_STAT2r(unit, &cmic_rval));
   4638     if (cmic_rval == 0) {
   4639         return SOC_E_NONE;
   4640     }
   4641     /* Loop through each place-and-route block entry */
   4642     for (rbi = 0; ; rbi++) {
   4643         rb = &_soc_td2_ser_route_blocks[rbi];
   4644         cmic_bit = rb->cmic_bit;
   4645         if (cmic_bit == 0) {
   4646             /* End of table */
   4647             break;
   4648         }
   4649         if (!(cmic_rval & cmic_bit)) {
   4650             /* No interrupt bit asserted for the route block */
   4651             continue;
   4652         }
   4653         if (rb->blocktype == SOC_BLK_IPIPE || rb->blocktype == SOC_BLK_EPIPE) {
   4654             /* New fifo style processing */
   4655             (void)_soc_trident2_process_ser_fifo(unit, rb->blocktype, rb->pipe, prefix_str);
   4656             stat->ser_err_fifo++;
   4657         } else {
   4658             /* Legacy processing */
   4659             SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   4660                 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   4661                     port = SOC_BLOCK_PORT(unit, block_info_idx);
   4662                     break;
   4663                 }
   4664             }
   4665             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   4666                 SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   4667                     /* This port block is not configured */
   4668                     LOG_ERROR(BSL_LS_SOC_SER,
   4669                               (BSL_META_U(unit,
   4670                                           "unit %d SER error on disabled port block %d !!\n"),
   4671                                           unit, block_info_idx));
   4672                     sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */
   4673                     continue;
   4674             }
   4675             /* Read per route block parity status register */
   4676             SOC_IF_ERROR_RETURN
   4677                 (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64));
   4678             if (COMPILER_64_IS_ZERO(rb_rval64)) {
   4679                 continue;
   4680             }
   4681             SOC_IF_ERROR_RETURN
   4682                 (_soc_trident2_process_ser(unit, block_info_idx, rb->id, rb->pipe,
   4683                                            port, rb->status_reg, rb_rval64,
   4684                                            rb->info, prefix_str));
   4685 
   4686             stat->ser_err_int++;
   4687         }
   4688     }
   4689     return SOC_E_NONE;
   4690 }
   4691 
   4692 
   4693 
   4694 STATIC void
   4695 soc_trident2_ser_error(void *unit_vp, void *d1, void *d2, void *d3,
   4696                        void *d4)
   4697 {
   4698     int unit = PTR_TO_INT(unit_vp);
   4699 
   4700     (void)_soc_trident2_ser_process_all(unit);
   4701     sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */
   4702 #if defined(BCM_CMICM_SUPPORT)
   4703     if (d2 != NULL) {
   4704         (void)soc_cmicm_intr2_enable(unit, PTR_TO_INT(d2));
   4705     }
   4706     /* soc_intr_enable(unit, IRQ_MEM_FAIL); */
   4707 #endif
   4708 }
   4709 
   4710 /* SER processing for TCAMs */
   4711 static _soc_generic_ser_info_t _soc_td2_tcam_ser_info_template[] = {
   4712     /* HW SER engine protection */
   4713     { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4714       _SOC_SER_INTERLEAVE_MOD2,
   4715       { {0, 95}, {1, 95}, {96, 189}, {97, 189} }, 0, 0, 0, 0,
   4716       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4717       _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_REMAP_READ  |
   4718       _SOC_SER_FLAG_SIZE_VERIFY},
   4719     { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4720       _SOC_SER_INTERLEAVE_MOD2,
   4721       { {0, 95}, {1, 95}, {96, 189}, {97, 189} }, 0, 0, 0, 0,
   4722       _SOC_SER_FLAG_MULTI_PIPE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y |
   4723       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SIZE_VERIFY |
   4724       _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_REMAP_READ},
   4725     { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4726       _SOC_SER_PARITY_8BITS,
   4727       _SOC_SER_INTERLEAVE_NONE,
   4728       { {0, 95}, {96, 189}, {190, 285}, {286, 379} }, 0, 0, 0, 0,
   4729       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4730       _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_REMAP_READ  |
   4731       _SOC_SER_FLAG_SIZE_VERIFY},
   4732     { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4733       _SOC_SER_PARITY_8BITS,
   4734       _SOC_SER_INTERLEAVE_NONE,
   4735       { {0, 95}, {96, 189}, {190, 285}, {286, 379} }, 0, 0, 0, 0,
   4736       _SOC_SER_FLAG_MULTI_PIPE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y |
   4737       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SIZE_VERIFY |
   4738       _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_REMAP_READ},
   4739     { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4740       _SOC_SER_INTERLEAVE_MOD2,
   4741       { {0, 165}, {1, 165}, {166, 329}, {167, 329} }, 0, 0, 0, 0,
   4742       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4743     { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4744       _SOC_SER_INTERLEAVE_MOD2,
   4745       { {0, 165}, {1, 165}, {166, 329}, {167, 329} }, 0, 0, 0, 0,
   4746       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4747       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4748     { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4749       _SOC_SER_INTERLEAVE_MOD2,
   4750       { {0, 237}, {1, 237}, {238, 473}, {239, 473} }, 0, 0, 0, 0,
   4751       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4752     { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4753       _SOC_SER_INTERLEAVE_MOD2,
   4754       { {0, 237}, {1, 237}, {238, 473}, {239, 473} }, 0, 0, 0, 0,
   4755       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4756       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4757     { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4758       _SOC_SER_INTERLEAVE_MOD2,
   4759       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0,
   4760       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4761     { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4762       _SOC_SER_INTERLEAVE_MOD2,
   4763       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0,
   4764       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4765       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4766     { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4767       _SOC_SER_INTERLEAVE_MOD2,
   4768       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4769       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4770     { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4771       _SOC_SER_INTERLEAVE_MOD2,
   4772       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4773       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4774       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4775     { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4776       _SOC_SER_INTERLEAVE_MOD2,
   4777       { {0, 105}, {1, 105}, {106, 210}, {107, 210} }, 0, 0, 0, 0,
   4778       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4779     { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4780       _SOC_SER_INTERLEAVE_MOD2,
   4781       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4782       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4783       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4784     { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4785       _SOC_SER_INTERLEAVE_MOD2,
   4786       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4787       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4788     { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4789       _SOC_SER_INTERLEAVE_MOD2,
   4790       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4791       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4792       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4793     { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4794       _SOC_SER_INTERLEAVE_MOD2,
   4795       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4796       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4797     { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4798       _SOC_SER_INTERLEAVE_MOD2,
   4799       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4800       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4801       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4802     { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4803       _SOC_SER_PARITY_4BITS,
   4804       _SOC_SER_INTERLEAVE_MOD2,
   4805       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4806       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4807     { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4808       _SOC_SER_PARITY_4BITS,
   4809       _SOC_SER_INTERLEAVE_MOD2,
   4810       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4811       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4812       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4813     { FP_UDF_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4814       _SOC_SER_INTERLEAVE_NONE,
   4815       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4816       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4817     { FP_UDF_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4818       _SOC_SER_INTERLEAVE_NONE,
   4819       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4820       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4821       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4822     { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4823       _SOC_SER_INTERLEAVE_MOD2,
   4824       { {0, 140}, {1, 140}, {141, 280}, {142, 280} }, 0, 0, 0, 0,
   4825       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4826     { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4827       _SOC_SER_INTERLEAVE_MOD2,
   4828       { {0, 140}, {1, 140}, {141, 280}, {142, 280} }, 0, 0, 0, 0,
   4829       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4830       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4831     { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4832       _SOC_SER_PARITY_4BITS,
   4833       _SOC_SER_INTERLEAVE_MOD2,
   4834       { {0, 140}, {1, 140}, {141, 280}, {142, 280} }, 0, 0, 0, 0,
   4835       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4836     { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4837       _SOC_SER_PARITY_4BITS,
   4838       _SOC_SER_INTERLEAVE_MOD2,
   4839       { {0, 140}, {1, 140}, {141, 280}, {142, 280} }, 0, 0, 0, 0,
   4840       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4841       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4842 
   4843     /* SW memscan SER engine protection */
   4844     { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4845       -1, -1,
   4846       { {0, 436}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0,
   4847       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4848       _SOC_SER_FLAG_SW_COMPARE | _SOC_SER_FLAG_OVERLAY},
   4849     { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4850       -1, -1,
   4851       { {0, 436}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0,
   4852       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4853       _SOC_SER_FLAG_SW_COMPARE | _SOC_SER_FLAG_OVERLAY |
   4854       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4855     { FP_GM_FIELDSm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4856       -1, -1,
   4857       { {0, 330}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0,
   4858       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4859       _SOC_SER_FLAG_SW_COMPARE |
   4860       _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE},
   4861     { FP_GM_FIELDSm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4862       -1, -1,
   4863       { {0, 330}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0,
   4864       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4865       _SOC_SER_FLAG_SW_COMPARE |
   4866       _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE |
   4867       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4868     { UDF_CONDITIONAL_CHECK_TABLE_CAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4869       _SOC_SER_PARITY_4BITS,
   4870       _SOC_SER_INTERLEAVE_MOD2,
   4871       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0,
   4872       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4873     { UDF_CONDITIONAL_CHECK_TABLE_CAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4874       _SOC_SER_PARITY_4BITS,
   4875       _SOC_SER_INTERLEAVE_MOD2,
   4876       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0,
   4877       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4878       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4879 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4880     { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4881       _SOC_SER_PARITY_4BITS,
   4882       _SOC_SER_INTERLEAVE_MOD2,
   4883       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4884       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4885     { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4886       _SOC_SER_PARITY_4BITS,
   4887       _SOC_SER_INTERLEAVE_MOD2,
   4888       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4889       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4890       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4891     { SUBPORT_TAG_SGPP_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4892       _SOC_SER_PARITY_4BITS,
   4893       _SOC_SER_INTERLEAVE_MOD2,
   4894       { {0, 32}, {1, 32}, {33, 64}, {34, 64} }, 0, 0, 0, 0,
   4895       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   4896     { SUBPORT_TAG_SGPP_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4897       _SOC_SER_PARITY_4BITS,
   4898       _SOC_SER_INTERLEAVE_MOD2,
   4899       { {0, 32}, {1, 32}, {33, 64}, {34, 64} }, 0, 0, 0, 0,
   4900       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   4901       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   4902 #endif
   4903     { INVALIDm },
   4904 };
   4905 
   4906 static _soc_generic_ser_info_t *_soc_td2_tcam_ser_info[SOC_MAX_NUM_DEVICES];
   4907 
   4908 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4909 STATIC int
   4910 _soc_trident2_tcam_idx_get(soc_mem_t mem)
   4911 {
   4912     int idx;
   4913     for (idx = 0; idx < COUNTOF(_soc_td2_tcam_ser_info_template); idx++) {
   4914         if (_soc_td2_tcam_ser_info_template[idx].mem == mem) {
   4915             break;
   4916         }
   4917     }
   4918     return idx;
   4919 }
   4920 
   4921 #define _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, table_index, section_index, start, end) \
   4922     _soc_td2_tcam_ser_info[unit][table_index].start_end_bits[section_index].start_bit = start; \
   4923     _soc_td2_tcam_ser_info[unit][table_index].start_end_bits[section_index].end_bit = end; \
   4924     _soc_td2_tcam_ser_info[unit][table_index + 1].start_end_bits[section_index].start_bit = start; \
   4925     _soc_td2_tcam_ser_info[unit][table_index + 1].start_end_bits[section_index].end_bit = end;
   4926 #endif
   4927 
   4928 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4929 STATIC void
   4930 _soc_trident2_ser_info_flag_update(_soc_generic_ser_info_t *ser_info,
   4931                               soc_mem_t mem, uint32 flag, int enable)
   4932 {
   4933     int ser_idx = 0;
   4934 
   4935     while (INVALIDm != ser_info[ser_idx].mem) {
   4936         if (ser_info[ser_idx].mem == mem) {
   4937             if (enable) {
   4938                 ser_info[ser_idx].ser_flags |= flag;
   4939             } else {
   4940                 ser_info[ser_idx].ser_flags &= ~flag;
   4941             }
   4942         }
   4943         ser_idx++;
   4944     }
   4945 }
   4946 #endif
   4947 
   4948 STATIC int
   4949 _soc_trident2_tcam_ser_init(int unit)
   4950 {
   4951     int alloc_size;
   4952 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4953     int override_idx = 0;
   4954 #endif
   4955     /* First, make per-unit copy of the master TCAM list */
   4956     alloc_size = sizeof(_soc_td2_tcam_ser_info_template);
   4957     if (NULL == _soc_td2_tcam_ser_info[unit]) {
   4958         if ((_soc_td2_tcam_ser_info[unit] =
   4959              sal_alloc(alloc_size, "td2 tcam list")) == NULL) {
   4960             return SOC_E_MEMORY;
   4961         }
   4962     }
   4963     /* Make a fresh copy of the TCAM template info */
   4964     sal_memcpy(_soc_td2_tcam_ser_info[unit],
   4965                &(_soc_td2_tcam_ser_info_template),
   4966                alloc_size);
   4967 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4968     if (!SOC_IS_TD2P_TT2P(unit)) {
   4969         /* MY_STATION_TCAM_2m exists in TD2_PLUS, not in TD2,
   4970          * set it to INVALIDm for TD2. */
   4971         override_idx = _soc_trident2_tcam_idx_get(MY_STATION_TCAM_2m);
   4972         _soc_td2_tcam_ser_info[unit][override_idx].mem = INVALIDm;
   4973     }
   4974 
   4975     if (SOC_IS_TD2P_TT2P(unit)) {
   4976         /* override start and end bit for IP_MULTICAST_TCAMm */
   4977         override_idx = _soc_trident2_tcam_idx_get(IP_MULTICAST_TCAMm);
   4978         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 0, 0, 144);
   4979         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 1, 1, 144);
   4980         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 2, 145, 288);
   4981         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 3, 146, 288);
   4982 
   4983         /* override start and end bit for L3_DEFIPm */
   4984         override_idx = _soc_trident2_tcam_idx_get(L3_DEFIPm);
   4985         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 0, 0, 97);
   4986         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 1, 1, 97);
   4987         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 2, 98, 193);
   4988         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 3, 99, 193);
   4989 
   4990         /* override start and end bit for L3_DEFIP_PAIR_128m */
   4991         override_idx = _soc_trident2_tcam_idx_get(L3_DEFIP_PAIR_128m);
   4992         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 0, 0, 99);
   4993         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 1, 100, 195);
   4994         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 2, 196, 291);
   4995         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 3, 292, 387);
   4996 
   4997         /* override start and end bit for CPU_COS_MAPm */
   4998         override_idx = _soc_trident2_tcam_idx_get(CPU_COS_MAPm);
   4999         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 0, 0, 144);
   5000         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 1, 1, 144);
   5001         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 2, 145, 288);
   5002         _TCAM_PROT_SECTIONS_START_END_BIT_OVERRIDE(unit, override_idx, 3, 146, 288);
   5003 
   5004         if (soc_feature(unit, soc_feature_field_stage_quarter_slice) &&
   5005             soc_feature(unit, soc_feature_field_quarter_slice_single_tcam) &&
   5006             soc_feature(unit, soc_feature_field_ingress_two_slice_types)) {
   5007             _soc_trident2_ser_info_flag_update(_soc_td2_tcam_ser_info[unit], FP_GLOBAL_MASK_TCAMm,
   5008                                           _SOC_SER_FLAG_NO_DMA, TRUE);
   5009             _soc_trident2_ser_info_flag_update(_soc_td2_tcam_ser_info[unit], FP_TCAMm,
   5010                                           _SOC_SER_FLAG_NO_DMA, TRUE);
   5011             _soc_trident2_ser_info_flag_update(_soc_td2_tcam_ser_info[unit], FP_GM_FIELDSm,
   5012                                           _SOC_SER_FLAG_NO_DMA, TRUE);
   5013         }
   5014 
   5015         /*
   5016         * Or _SOC_SER_FLAG_SW_COMPARE flag for EFP_TCAMm since consecutive ipipe
   5017         * and epipe sbus transcations will cause H/W SER engine use incorrect parity bit
   5018         * for checking, which result in false parity error reported.
   5019         */
   5020         _soc_trident2_ser_info_flag_update(_soc_td2_tcam_ser_info[unit], EFP_TCAMm,
   5021                                            _SOC_SER_FLAG_SW_COMPARE, TRUE);
   5022     }
   5023 #endif
   5024     return soc_generic_ser_init(unit, _soc_td2_tcam_ser_info[unit]);
   5025 }
   5026 
   5027 STATIC void
   5028 soc_trident2_ser_fail(int unit)
   5029 {
   5030     soc_generic_ser_process_error(unit, _soc_td2_tcam_ser_info[unit],
   5031                                   _SOC_PARITY_TYPE_SER);
   5032 }
   5033 
   5034 static soc_mem_t *_soc_td2_alpm_bkt_view_map[SOC_MAX_NUM_DEVICES];
   5035 
   5036 #ifdef ALPM_ENABLE
   5037 int
   5038 soc_trident2_alpm_scrub(int unit)
   5039 {
   5040     int ipv6;                   /* Iterate over ipv6 only flag. */
   5041     int idx;                    /* Iteration index.             */
   5042     int tmp_idx;                /* ipv4 entries iterator.       */
   5043     int alloc_size;             /* Allocation size.             */
   5044     int tbl_size;               /* HW table size.               */
   5045     int rv = SOC_E_FAIL;        /* Operation return status.     */
   5046     char *lpm_tbl_ptr = NULL;   /* Dma table pointer.           */
   5047     int vrf, vrf_id, step_count;
   5048     int idx_end, bkt_idx, bkt_ptr = 0, bkt_addr;
   5049     int bank_num = 0, entry_num = 0, entry_count, bank_count;
   5050     void *alpm_entry;
   5051     uint32 rval;
   5052     soc_mem_t alpm_mem;
   5053     defip_entry_t *lpm_entry;   /* Hw entry buffer.             */
   5054     defip_pair_128_entry_t *lpm_128_entry; /* Hw entry buffer.  */
   5055     defip_alpm_ipv4_1_entry_t alpm_entry_v4;
   5056     defip_alpm_ipv6_64_1_entry_t alpm_entry_v6_64;
   5057     defip_alpm_ipv6_128_entry_t alpm_entry_v6_128;
   5058     int flex;
   5059 
   5060     SOC_IF_ERROR_RETURN(READ_L3_DEFIP_RPF_CONTROLr(unit, &rval));
   5061     if (0 == soc_reg_field_get(unit, L3_DEFIP_RPF_CONTROLr, rval, LPM_MODEf)) {
   5062         return (SOC_E_NONE);
   5063     }
   5064 
   5065     /* DMA the LPM table to software copy. Calculate table size. */
   5066     tbl_size =  soc_mem_index_count(unit, L3_DEFIPm);
   5067     if (!tbl_size) {
   5068         return (SOC_E_NONE);
   5069     }
   5070     alloc_size = tbl_size * sizeof(defip_entry_t);
   5071 
   5072     /* Allocate memory buffer. */
   5073     lpm_tbl_ptr = soc_cm_salloc(unit, alloc_size, "lpm scrub");
   5074     if (lpm_tbl_ptr == NULL) {
   5075         return (SOC_E_MEMORY);
   5076     }
   5077 
   5078     /* Reset allocated buffer. */
   5079     sal_memset(lpm_tbl_ptr, 0, alloc_size);
   5080 
   5081     /* Read table to the buffer. */
   5082     if (soc_mem_read_range(unit, L3_DEFIPm, MEM_BLOCK_ANY,
   5083                            soc_mem_index_min(unit, L3_DEFIPm),
   5084                            soc_mem_index_max(unit, L3_DEFIPm), lpm_tbl_ptr) < 0) {
   5085         soc_cm_sfree(unit, lpm_tbl_ptr);
   5086         return (SOC_E_INTERNAL);
   5087     }
   5088 
   5089     if (SOC_URPF_STATUS_GET(unit)) {
   5090         tbl_size >>= 1;
   5091     }
   5092 
   5093     idx_end = tbl_size;
   5094 
   5095     if (soc_reg_field_get(unit, L3_DEFIP_RPF_CONTROLr, rval, LOOKUP_MODEf)) {
   5096         /* parallel search mode */
   5097         if (SOC_URPF_STATUS_GET(unit)) {
   5098             bank_count = 2;
   5099         } else {
   5100             bank_count = 4;
   5101         }
   5102     } else {
   5103         bank_count = 4;
   5104     }
   5105 
   5106     /* Walk all lpm entries */
   5107     for (idx = 0; idx < idx_end; idx++) {
   5108         /* Calculate entry offset */
   5109         lpm_entry =
   5110             soc_mem_table_idx_to_pointer(unit, L3_DEFIPm,
   5111                                          defip_entry_t *, lpm_tbl_ptr, idx);
   5112 
   5113         ipv6 = soc_mem_field32_get(unit, L3_DEFIPm, lpm_entry, MODE0f);
   5114 
   5115         /* Calculate LPM table traverse step count */
   5116         if (ipv6) {
   5117             if (SOC_ALPM_V6_SCALE_CHECK(unit, ipv6)) {
   5118                 step_count = 2;
   5119             } else {
   5120                 step_count = 1;
   5121             }
   5122         } else {
   5123             step_count = 2;
   5124         }
   5125 
   5126         /* Each LPM index has two IPv4 entries */
   5127         for (tmp_idx = 0; tmp_idx < step_count; tmp_idx++) {
   5128 
   5129             if (tmp_idx) {  /* If index == 1*/
   5130                 if (!ipv6) {
   5131                     /* Copy upper half of lpm entry to lower half */
   5132                     soc_alpm_lpm_ip4entry1_to_0(unit, lpm_entry, lpm_entry, TRUE);
   5133                 }
   5134             }
   5135 
   5136             /* Make sure entry is valid. */
   5137             if (!soc_L3_DEFIPm_field32_get(unit, lpm_entry, VALID0f)) {
   5138                 continue;
   5139             }
   5140 
   5141             /* Get VRF */
   5142             if (SOC_FAILURE(soc_alpm_lpm_vrf_get
   5143                             (unit, lpm_entry, &vrf_id, &vrf))) {
   5144                 goto free_lpm_table;
   5145             }
   5146 
   5147             if (ipv6 && tmp_idx) {
   5148                 bkt_ptr++;
   5149             } else {
   5150                 bkt_ptr = soc_mem_field32_get(unit, L3_DEFIPm, lpm_entry,
   5151                                               ALG_BKT_PTR0f);
   5152                 if (bkt_ptr == 0) {
   5153                     if (ipv6) {
   5154                         tmp_idx++;
   5155                     }
   5156                     continue;
   5157                 }
   5158             }
   5159 
   5160             flex = soc_mem_field32_get(unit, L3_DEFIPm, lpm_entry,
   5161                                               ENTRY_VIEW0f);
   5162             if (ipv6) {
   5163                 if (flex) {
   5164                     alpm_mem = L3_DEFIP_ALPM_IPV6_64_1m;
   5165                     entry_count = 3;
   5166                     alpm_entry = &alpm_entry_v6_64;
   5167                 } else {
   5168                     alpm_mem = L3_DEFIP_ALPM_IPV6_64m;
   5169                     entry_count = 4;
   5170                     alpm_entry = &alpm_entry_v6_64;
   5171                 }
   5172             } else {
   5173                 if (flex) {
   5174                     alpm_mem = L3_DEFIP_ALPM_IPV4_1m;
   5175                     entry_count = 4;
   5176                     alpm_entry = &alpm_entry_v4;
   5177                 } else {
   5178                     alpm_mem = L3_DEFIP_ALPM_IPV4m;
   5179                     entry_count = 6;
   5180                     alpm_entry = &alpm_entry_v4;
   5181                 }
   5182             }
   5183 
   5184             entry_num = 0;
   5185             bank_num = 0;
   5186 
   5187             /* Get the bucket pointer from lpm entry */
   5188             for (bkt_idx = 0; bkt_idx < (entry_count * bank_count); bkt_idx++) {
   5189                 /* Calculate bucket memory address */
   5190                 /* Increment so next bucket address can be calculated */
   5191                 bkt_addr = (entry_num << 16) | (bkt_ptr << 2) |
   5192                            (bank_num & 0x3);
   5193                 entry_num++;
   5194                 if (entry_num == entry_count) {
   5195                     entry_num = 0;
   5196                     bank_num++;
   5197                     if (bank_num == bank_count) {
   5198                         bank_num = 0;
   5199                     }
   5200                 }
   5201 
   5202                 /* Read entry from bucket memory */
   5203                 if (SOC_FAILURE(soc_mem_read(unit, alpm_mem, MEM_BLOCK_ANY,
   5204                                              bkt_addr, alpm_entry))) {
   5205                     goto free_lpm_table;
   5206                 }
   5207                 if (SOC_URPF_STATUS_GET(unit)) {
   5208                     /* Read the other copy */
   5209                     if (SOC_FAILURE(soc_mem_read(unit, alpm_mem, MEM_BLOCK_ANY,
   5210                                                  _soc_alpm_rpf_entry(unit, bkt_addr),
   5211                                                  alpm_entry))) {
   5212                         goto free_lpm_table;
   5213                     }
   5214                 }
   5215             } /* End of bucket walk loop*/
   5216         } /* End of lpm entry upper/lower half traversal */
   5217     } /* End of lpm table traversal */
   5218     soc_cm_sfree(unit, lpm_tbl_ptr);
   5219 
   5220     /* DMA the LPM_PAIR_128 table to software copy. Calculate table size. */
   5221     tbl_size =  soc_mem_index_count(unit, L3_DEFIP_PAIR_128m);
   5222     if (!tbl_size) {
   5223         return (SOC_E_NONE);
   5224     }
   5225     alloc_size = tbl_size * sizeof(defip_pair_128_entry_t);
   5226 
   5227     /* Allocate memory buffer. */
   5228     lpm_tbl_ptr = soc_cm_salloc(unit, alloc_size, "lpm scrub");
   5229     if (lpm_tbl_ptr == NULL) {
   5230         return (SOC_E_MEMORY);
   5231     }
   5232 
   5233     /* Reset allocated buffer. */
   5234     sal_memset(lpm_tbl_ptr, 0, alloc_size);
   5235 
   5236     /* Read table to the buffer. */
   5237     if (soc_mem_read_range(unit, L3_DEFIP_PAIR_128m, MEM_BLOCK_ANY,
   5238                            soc_mem_index_min(unit, L3_DEFIP_PAIR_128m),
   5239                            soc_mem_index_max(unit, L3_DEFIP_PAIR_128m), lpm_tbl_ptr) < 0) {
   5240         soc_cm_sfree(unit, lpm_tbl_ptr);
   5241         return (SOC_E_INTERNAL);
   5242     }
   5243 
   5244     /* bkt_count = ALPM_IPV6_128_BKT_COUNT; ?? */
   5245 
   5246     if (SOC_URPF_STATUS_GET(unit)) {
   5247         tbl_size >>= 1;
   5248         /* bucket size halves for parallel search mode */
   5249         if (soc_alpm_mode_get(unit)) {
   5250             /* bkt_count >>= 1; ?? */
   5251         }
   5252     }
   5253 
   5254     idx_end = tbl_size;
   5255     entry_count = 2;
   5256     alpm_entry = &alpm_entry_v6_128;
   5257 
   5258     if (SOC_ALPM_V6_SCALE_CHECK(unit, 1)) {
   5259         step_count = 2;
   5260     } else {
   5261         step_count = 1;
   5262     }
   5263 
   5264     /* Walk all lpm_pair_128 entries */
   5265     for (idx = 0; idx < idx_end; idx++) {
   5266         /* Calculate entry ofset. */
   5267         lpm_128_entry =
   5268             soc_mem_table_idx_to_pointer(unit, L3_DEFIP_PAIR_128m,
   5269                                          defip_pair_128_entry_t *, lpm_tbl_ptr, idx);
   5270 
   5271         /* Each lpm entry contains upto 24 IPV4 entries. Check all */
   5272         for (tmp_idx = 0; tmp_idx < step_count; tmp_idx++) {
   5273 
   5274             /* Make sure entry is valid. */
   5275             if (!soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m, lpm_128_entry,
   5276                                      VALID0_LWRf)) {
   5277                 continue;
   5278             }
   5279 
   5280             /* Get VRF */
   5281             if (SOC_FAILURE(soc_alpm_128_lpm_vrf_get
   5282                             (unit, lpm_128_entry, &vrf_id, &vrf))) {
   5283                 goto free_lpm_table;
   5284             }
   5285 
   5286             if (tmp_idx) {
   5287                 bkt_ptr++;
   5288             } else {
   5289                 bkt_ptr = soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m, lpm_128_entry,
   5290                                               ALG_BKT_PTRf);
   5291                 if (bkt_ptr == 0) {
   5292                     tmp_idx++;
   5293                     continue;
   5294                 }
   5295             }
   5296 
   5297             entry_num = 0;
   5298             bank_num = 0;
   5299 
   5300             /* Get the bucket pointer from lpm entry */
   5301             for (bkt_idx = 0; bkt_idx < (entry_count * bank_count); bkt_idx++) {
   5302                 /* Calculate bucket memory address */
   5303                 /* Increment so next bucket address can be calculated */
   5304                 bkt_addr = (entry_num << 16) | (bkt_ptr << 2) |
   5305                            (bank_num & 0x3);
   5306                 entry_num++;
   5307                 if (entry_num == entry_count) {
   5308                     entry_num = 0;
   5309                     bank_num++;
   5310                     if (bank_num == bank_count) {
   5311                         bank_num = 0;
   5312                     }
   5313                 }
   5314 
   5315                 /* Read entry from bucket memory */
   5316                 if (SOC_FAILURE(soc_mem_read(unit, L3_DEFIP_ALPM_IPV6_128m,
   5317                                 MEM_BLOCK_ANY, bkt_addr, alpm_entry))) {
   5318                     goto free_lpm_table;
   5319                 }
   5320                 if (SOC_URPF_STATUS_GET(unit)) {
   5321                     /* Read the other copy */
   5322                     if (SOC_FAILURE(soc_mem_read(unit, L3_DEFIP_ALPM_IPV6_128m,
   5323                                                  MEM_BLOCK_ANY,
   5324                                                  _soc_alpm_rpf_entry(unit, bkt_addr),
   5325                                                  alpm_entry))) {
   5326                         goto free_lpm_table;
   5327                     }
   5328                 }
   5329             } /* End of bucket walk loop*/
   5330         } /* End of lpm entry upper/lower half traversal */
   5331     } /* End of lpm table traversal */
   5332 
   5333     rv = SOC_E_NONE;
   5334 
   5335 free_lpm_table:
   5336     soc_cm_sfree(unit, lpm_tbl_ptr);
   5337 
   5338     return (rv);
   5339 }
   5340 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5341 STATIC int
   5342 soc_trident2p_alpm_mode_enable(int unit)
   5343 {
   5344     uint32 rval = 0;
   5345     uint32 mode;
   5346 
   5347     mode = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0);
   5348     if (mode && soc_feature(unit, soc_feature_alpm)) {
   5349         /* Set DEFIP mode to ALPM */
   5350         SOC_IF_ERROR_RETURN(READ_L3_DEFIP_RPF_CONTROLr(unit, &rval));
   5351         soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LPM_MODEf, 1);
   5352         /* Parallel mode */
   5353         if (mode == SOC_ALPM_MODE_PARALLEL) {
   5354             soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LOOKUP_MODEf, 1);
   5355         } else {
   5356             /* combined search mode */
   5357             soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LOOKUP_MODEf, 0);
   5358         }
   5359         SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_RPF_CONTROLr(unit, rval));
   5360     }
   5361     return SOC_E_NONE;
   5362 }
   5363 #endif
   5364 #endif /* ALPM_ENABLE */
   5365 
   5366 
   5367 STATIC int
   5368 soc_bcm56830_mem_config(int unit)
   5369 {
   5370     soc_persist_t *sop;
   5371     int         index_max;
   5372 
   5373     sop = SOC_PERSIST(unit);
   5374 
   5375     index_max = 23;
   5376     sop->memState[TRUNK_GROUPm].index_max = index_max;
   5377     sop->memState[TRUNK_BITMAPm].index_max = index_max;
   5378     sop->memState[TRUNK_CBL_TABLEm].index_max = index_max;
   5379 
   5380 
   5381     sop->memState[L2MCm].index_max = 8191;
   5382 
   5383     return SOC_E_NONE;
   5384 }
   5385 
   5386 STATIC int
   5387 soc_bcm56834_mem_config(int unit)
   5388 {
   5389     soc_persist_t *sop;
   5390     int         index_max;
   5391 
   5392     sop = SOC_PERSIST(unit);
   5393 
   5394     index_max = 47;
   5395     sop->memState[TRUNK_GROUPm].index_max = index_max;
   5396     sop->memState[TRUNK_BITMAPm].index_max = index_max;
   5397     sop->memState[TRUNK_CBL_TABLEm].index_max = index_max;
   5398 
   5399 
   5400     sop->memState[L2MCm].index_max = 8191;
   5401 
   5402     return SOC_E_NONE;
   5403 }
   5404 
   5405 int
   5406 soc_trident2_mem_config(int unit)
   5407 {
   5408     soc_persist_t *sop;
   5409     int l2_entries, cfg_l2_entries, shared_l2_banks;
   5410     int l3_entries, cfg_l3_entries, shared_l3_banks;
   5411     int alpm_enable;
   5412     int num_ecmp_rh_flowset_entries;
   5413     int shared_bank_size;
   5414     int max_l2_entries;
   5415     int max_l3_entries;
   5416     int num_ipv6_128b_entries = 0;
   5417     int config_v6_entries = 0;
   5418     int defip_config = 0;
   5419     int lpm_scaling_enable = 0, lpm_ipv6_128b_reserved = 0;
   5420     uint16              dev_id;
   5421     uint8               rev_id;
   5422     int shared_entries;
   5423     int num_defip_entries = 0;
   5424 
   5425     sop = SOC_PERSIST(unit);
   5426 
   5427     /* TRIDENT2:
   5428      * bank 0-1 are dedicated L2 banks (16k entries per bank)
   5429      * bank 6-9 are dedicated L3 banks (4k entries per bank)
   5430      * bank 2-5 are shared banks (64k entres per bank)
   5431      * These dedicated/shared banks can be configured to one of the following
   5432      * mode:
   5433      *     mode 0: 288k L2 (bank 0-5),  16k L3 (bank 6-9),   no ALPM (default)
   5434      *     mode 1: 224k L2 (bank 0-4),  80k L3 (bank 5-9),   no ALPM
   5435      *     mode 2: 160k L2 (bank 0-3), 144k L3 (bank 4-9),   no ALPM
   5436      *     mode 3:  96k L2 (bank 0-2), 208k L3 (bank 3-9),   no ALPM
   5437      *     mode 4:  32k L2 (bank 0-1),  16k L3 (bank 6-9), 128k ALPM (bank 2-5)
   5438      *
   5439      * TRIDENT2+:
   5440      * bank 0-1 are dedicated L2 banks (16k entries per bank)
   5441      * bank 6-9 are dedicated L3 banks (4k entries per bank)
   5442      * bank 2-5 are shared banks (64 or 128k entres per bank)
   5443      * These dedicated/shared banks can be configured to one of the following
   5444      * mode:
   5445      *     mode 0: 544k L2 (bank 0-5),  16k L3 (bank 6-9),   no ALPM (default)
   5446      *     mode 1: 416k L2 (bank 0-4), 144k L3 (bank 5-9),   no ALPM
   5447      *     mode 2: 288k L2 (bank 0-3), 272k L3 (bank 4-9),   no ALPM
   5448      *     mode 3: 160k L2 (bank 0-2), 400k L3 (bank 3-9),   no ALPM
   5449      *     mode 4:  32k L2 (bank 0-1),  16k L3 (bank 6-9), 128k ALPM (bank 2-5)
   5450      */
   5451 
   5452     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
   5453 
   5454 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5455     if (SOC_IS_TD2P_TT2P(unit)) {
   5456         shared_bank_size = soc_td2p_get_shared_bank_size (unit, dev_id, rev_id);
   5457     } else
   5458 #endif
   5459     {
   5460         shared_bank_size = 64;
   5461     }
   5462     max_l2_entries = 32 + shared_bank_size * 4;
   5463     max_l3_entries = 16 + shared_bank_size * 3;
   5464 
   5465     cfg_l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, -1);
   5466     l2_entries = cfg_l2_entries == -1 ? max_l2_entries * 1024 : cfg_l2_entries;
   5467 
   5468     if ((dev_id == BCM56830_DEVICE_ID) ||
   5469         ((dev_id == BCM56834_DEVICE_ID) && (l2_entries > 160 * 1024))) {
   5470         l2_entries = 160 * 1024;
   5471     }
   5472 
   5473     if (l2_entries <= 32 * 1024) { /* 32k dedicated L2 entries */
   5474         l2_entries = 32 * 1024;
   5475         shared_l2_banks = 0;
   5476     } else if (l2_entries <= max_l2_entries * 1024) {
   5477         l2_entries -= 32 * 1024;
   5478         shared_l2_banks = (l2_entries + (shared_bank_size * 1024 - 1)) / (shared_bank_size * 1024);
   5479         l2_entries = 32 * 1024 + shared_l2_banks * shared_bank_size * 1024;
   5480     } else {
   5481         LOG_CLI((BSL_META_U(unit,
   5482                             "The specified l2_mem_entries (%d) exceeds %dK\n"),
   5483                  cfg_l2_entries, max_l2_entries));
   5484         return SOC_E_PARAM;
   5485     }
   5486 
   5487 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5488     if (!soc_feature(unit, soc_feature_l3)) {
   5489         l3_entries = 0;
   5490         cfg_l3_entries = 0;
   5491         shared_l3_banks = 0;
   5492     } else
   5493 #endif
   5494     {
   5495         cfg_l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, -1);
   5496         l3_entries = cfg_l3_entries == -1 ? 16384 : cfg_l3_entries;
   5497         if (l3_entries <= 16 * 1024) { /* 16k dedicated L3 entries */
   5498             l3_entries = 16 * 1024;
   5499             shared_l3_banks = 0;
   5500         } else if (l3_entries <= max_l3_entries * 1024) {
   5501             l3_entries -= 16 * 1024;
   5502             shared_l3_banks = (l3_entries + (shared_bank_size * 1024 - 1))
   5503                                                 / (shared_bank_size * 1024);
   5504             l3_entries = 16 * 1024 + shared_l3_banks * shared_bank_size * 1024;
   5505         } else {
   5506             LOG_CLI((BSL_META_U(unit,
   5507                         "The specified l3_mem_entries (%d) exceeds %dK\n"),
   5508                         cfg_l3_entries, max_l3_entries));
   5509             return SOC_E_PARAM;
   5510         }
   5511     }
   5512 
   5513     alpm_enable = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0);
   5514 
   5515     if (alpm_enable && soc_feature(unit, soc_feature_alpm)) {
   5516         if (shared_l2_banks + shared_l3_banks != 0) {
   5517             LOG_CLI((BSL_META_U(unit,
   5518                                 "Shared banks can not be used for L2 or L3 when "
   5519                                 "ALPM is enabled\n")));
   5520             return SOC_E_PARAM;
   5521         }
   5522     } else if (shared_l2_banks + shared_l3_banks > 4) {
   5523         if (cfg_l2_entries == -1) {
   5524             LOG_CLI((BSL_META_U(unit,
   5525                                 "Default L2 size (294912) and the specified "
   5526                                 "l3_mem_entries (%d) require more than 4 shared "
   5527                                 "banks\n"),
   5528                      cfg_l3_entries));
   5529         } else {
   5530             LOG_CLI((BSL_META_U(unit,
   5531                                 "The specified l2_mem_entries (%d) and "
   5532                                 "l3_mem_entries (%d) require more than 4 shared "
   5533                                 "banks\n"),
   5534                      cfg_l2_entries, cfg_l3_entries));
   5535         }
   5536         return SOC_E_PARAM;
   5537     }
   5538 
   5539     if (soc_feature(unit, soc_feature_alpm)) {
   5540         _soc_alpm_mode[unit] = alpm_enable;
   5541     }
   5542 
   5543     /* Adjust table size to match L2_TABLE_HASH_CONTROL.MODE setting*/
   5544     sop->memState[L2Xm].index_max = l2_entries - 1;
   5545     sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1;
   5546 
   5547 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5548     if (SOC_IS_TD2P_TT2P(unit)) {
   5549         sop->memState[L2_ENTRY_ONLY_ECCm].index_max = l2_entries - 1;
   5550     }
   5551 #endif
   5552 
   5553     sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1;
   5554     sop->memState[L2_HITDA_ONLY_Xm].index_max = l2_entries / 4 - 1;
   5555     sop->memState[L2_HITDA_ONLY_Ym].index_max = l2_entries / 4 - 1;
   5556     sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1;
   5557     sop->memState[L2_HITSA_ONLY_Xm].index_max = l2_entries / 4 - 1;
   5558     sop->memState[L2_HITSA_ONLY_Ym].index_max = l2_entries / 4 - 1;
   5559     if (soc_feature(unit, soc_feature_shared_bank_lp_disabled)) {
   5560         /* Initialize to dedicated L2 entries count. */
   5561         shared_entries = shared_l2_banks * shared_bank_size * 1024;
   5562         sop->memState[L2_ENTRY_LPm].index_max =
   5563                 (l2_entries - shared_entries) / 4 - 1;
   5564     } else {
   5565         sop->memState[L2_ENTRY_LPm].index_max = l2_entries / 4 - 1;
   5566     }
   5567 
   5568     /* Adjust table size to match L3_TABLE_HASH_CONTROL.MODE setting */
   5569     sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1;
   5570     sop->memState[L3_ENTRY_ONLY_ECCm].index_max = l3_entries - 1;
   5571     sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1;
   5572     sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = l3_entries / 2 - 1;
   5573     sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = l3_entries/ 2 - 1;
   5574     sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = l3_entries / 4 - 1;
   5575     sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1;
   5576     sop->memState[L3_ENTRY_HIT_ONLY_Xm].index_max = l3_entries / 4 - 1;
   5577     sop->memState[L3_ENTRY_HIT_ONLY_Ym].index_max = l3_entries / 4 - 1;
   5578 
   5579     if (soc_feature(unit, soc_feature_shared_bank_lp_disabled)) {
   5580         /* Initialize to dedicated L3 entries count. */
   5581         shared_entries = shared_l3_banks * shared_bank_size * 1024;
   5582         sop->memState[L3_ENTRY_LPm].index_max =
   5583                 (l3_entries - shared_entries) / 4 - 1;
   5584     } else {
   5585         sop->memState[L3_ENTRY_LPm].index_max = l3_entries / 4 - 1;
   5586     }
   5587 
   5588     /* Adjust table size to match L2/L3_TABLE_HASH_CONTROL.MODE setting */
   5589     if (!(alpm_enable && soc_feature(unit, soc_feature_alpm))) {
   5590         sop->memState[L3_DEFIP_ALPM_RAWm].index_max = -1;
   5591         sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = -1;
   5592         sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = -1;
   5593         sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = -1;
   5594         sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = -1;
   5595         sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = -1;
   5596         sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = -1;
   5597         sop->memState[L3_DEFIP_ALPM_HIT_ONLY_Xm].index_max = -1;
   5598         sop->memState[L3_DEFIP_ALPM_HIT_ONLY_Ym].index_max = -1;
   5599 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5600         if (SOC_IS_TD2P_TT2P(unit)) {
   5601             sop->memState[L3_DEFIP_ALPM_ECCm].index_max = -1;
   5602         }
   5603 #endif
   5604     }
   5605 
   5606     /* LAG and ECMP resilient hashing features share the same flow set table.
   5607      * The table can be configured in one of 3 modes:
   5608      * - dedicated to LAG resilient hashing,
   5609      * - dedicated to ECMP resilient hashing,
   5610      * - split evenly between LAG and ECMP resilient hashing.
   5611      */
   5612     num_ecmp_rh_flowset_entries = soc_property_get(unit,
   5613             spn_ECMP_RESILIENT_HASH_SIZE, 32768);
   5614     switch (num_ecmp_rh_flowset_entries) {
   5615         case 0:
   5616             sop->memState[RH_ECMP_FLOWSETm].index_max = -1;
   5617             break;
   5618         case 32768:
   5619             sop->memState[RH_LAG_FLOWSETm].index_max /= 2;
   5620             sop->memState[RH_ECMP_FLOWSETm].index_max /= 2;
   5621             break;
   5622         case 65536:
   5623             sop->memState[RH_LAG_FLOWSETm].index_max = -1;
   5624             break;
   5625         default:
   5626             return SOC_E_CONFIG;
   5627     }
   5628 
   5629 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5630     if (!soc_feature(unit, soc_feature_lpm_tcam)) {
   5631         SOC_CONTROL(unit)->l3_defip_max_tcams = 0;
   5632     } else
   5633     if (soc_feature(unit, soc_feature_l3_2k_defip_table)) {
   5634         /* 56832 SKU supports only 4K IPV4 entries as compared to 16k
   5635            IPV4 entries in base chip 56860 i.e only 2 TCAMs can be
   5636            used since each TCAM can have 2k IPV4 entries.
   5637         */
   5638         SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_TD2P_DEFIP_REDUCED_TCAMS;
   5639     } else
   5640 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5641     {
   5642         SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_TD2_DEFIP_MAX_TCAMS;
   5643     }
   5644 
   5645     SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_TD2_DEFIP_TCAM_DEPTH;
   5646 
   5647     if (!soc_feature(unit, soc_feature_lpm_tcam)) {
   5648         /* LPM is disabled, disable all L3_DEFIP memories */
   5649         sop->memState[L3_DEFIPm].index_max = -1;
   5650         sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
   5651         sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
   5652         sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
   5653         sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
   5654         sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Xm].index_max = -1;
   5655         sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Ym].index_max = -1;
   5656         sop->memState[L3_DEFIP_ONLYm].index_max = -1;
   5657         sop->memState[L3_DEFIP_DATA_ONLYm].index_max = -1;
   5658         sop->memState[L3_DEFIP_HIT_ONLYm].index_max = -1;
   5659         sop->memState[L3_DEFIP_HIT_ONLY_Xm].index_max = -1;
   5660         sop->memState[L3_DEFIP_HIT_ONLY_Ym].index_max = -1;
   5661         SOC_CONTROL(unit)->l3_defip_index_remap = 0;
   5662     } else if (soc_property_get(unit, "l3_defip_sizing", TRUE)) {
   5663         if (!(soc_property_get(unit, spn_L3_ALPM_ENABLE, 0) &&
   5664               soc_feature(unit, soc_feature_alpm))) {
   5665             defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1);
   5666 
   5667 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5668             if (soc_feature(unit, soc_feature_l3_2k_defip_table)) {
   5669                 num_ipv6_128b_entries = soc_property_get(unit,
   5670                                             spn_NUM_IPV6_LPM_128B_ENTRIES,
   5671                                             (defip_config ? 512 : 0));
   5672             } else
   5673 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5674             {
   5675                 num_ipv6_128b_entries = soc_property_get(unit,
   5676                                             spn_NUM_IPV6_LPM_128B_ENTRIES,
   5677                                             (defip_config ? 2048 : 0));
   5678             }
   5679 
   5680             num_ipv6_128b_entries = num_ipv6_128b_entries +
   5681                                     (num_ipv6_128b_entries % 2);
   5682 
   5683             if (SOC_CONTROL(unit)->tcam_protect_write) {
   5684                 num_ipv6_128b_entries = (num_ipv6_128b_entries + 3) / 4 * 4;
   5685             }
   5686 
   5687             config_v6_entries = num_ipv6_128b_entries;
   5688 
   5689 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5690             if (soc_feature(unit, soc_feature_l3_2k_defip_table)) {
   5691                 lpm_scaling_enable = soc_property_get(unit,
   5692                                     spn_LPM_SCALING_ENABLE, 1);
   5693             } else
   5694 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5695             {
   5696                 lpm_scaling_enable = soc_property_get(unit,
   5697                                     spn_LPM_SCALING_ENABLE, 0);
   5698             }
   5699 
   5700 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5701             if (soc_feature(unit, soc_feature_l3_2k_defip_table)) {
   5702                 lpm_ipv6_128b_reserved = soc_property_get(unit,
   5703                                     spn_LPM_IPV6_128B_RESERVED, 0);
   5704             } else
   5705 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5706             {
   5707                 lpm_ipv6_128b_reserved = soc_property_get(unit,
   5708                                     spn_LPM_IPV6_128B_RESERVED, 1);
   5709             }
   5710 
   5711             if (lpm_scaling_enable){
   5712                 num_ipv6_128b_entries = 0;
   5713             }
   5714 
   5715             num_defip_entries = (SOC_CONTROL(unit)->l3_defip_max_tcams *
   5716                                  SOC_CONTROL(unit)->l3_defip_tcam_size) -
   5717                                  (num_ipv6_128b_entries * 2);
   5718 
   5719             /* Adjust numbers for tcam_protect_write */
   5720             if (SOC_CONTROL(unit)->tcam_protect_write) {
   5721                 /* not support in non-scaling LPM mode */
   5722                 if (!lpm_scaling_enable) {
   5723                     LOG_CLI((BSL_META_U(unit,
   5724                                         "LPM non-scaling mode does not support "
   5725                                         "tcam_protect_write. Please retry with "
   5726                                         "lpm_scaling_enable=1.\n")));
   5727                     return SOC_E_CONFIG;
   5728                 }
   5729                 if (num_defip_entries) {
   5730                     num_defip_entries -= 8;
   5731                     /* Don't use up all entries as protect entries */
   5732                     if (num_defip_entries <= 0) {
   5733                         return SOC_E_CONFIG;
   5734                     }
   5735                     SOC_CONTROL(unit)->l3_defip_tcam_size --;
   5736                 }
   5737                 /* coverity[dead_error_begin] */
   5738                 if (num_ipv6_128b_entries) {
   5739                     num_ipv6_128b_entries -= 4;
   5740                     /* Don't use up all entries as protect entries */
   5741                     if (num_ipv6_128b_entries <= 0) {
   5742                         return SOC_E_CONFIG;
   5743                     }
   5744                     SOC_CONTROL(unit)->l3_defip_tcam_size --;
   5745                 }
   5746                 if (config_v6_entries) {
   5747                     config_v6_entries -= 4;
   5748                     if (config_v6_entries < 0) {
   5749                         return SOC_E_CONFIG;
   5750                     }
   5751                 }
   5752             }
   5753 
   5754             if (lpm_scaling_enable){
   5755                 if (!lpm_ipv6_128b_reserved) {
   5756                     config_v6_entries = ((config_v6_entries /
   5757                                         SOC_CONTROL(unit)->l3_defip_tcam_size) +
   5758                                         ((config_v6_entries %
   5759                                          SOC_CONTROL(unit)->l3_defip_tcam_size)
   5760                                         ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size;
   5761                 }
   5762             }
   5763             sop->memState[L3_DEFIP_PAIR_128m].index_max =
   5764                                               num_ipv6_128b_entries - 1;
   5765             sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max =
   5766                                               num_ipv6_128b_entries - 1;
   5767             sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max =
   5768                                               num_ipv6_128b_entries - 1;
   5769             sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max =
   5770                                               num_ipv6_128b_entries - 1;
   5771             sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Xm].index_max =
   5772                                               num_ipv6_128b_entries - 1;
   5773             sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Ym].index_max =
   5774                                               num_ipv6_128b_entries - 1;
   5775 
   5776            /* For 56832 SKU, we use only 2 TCAMs to support 4k IPv4 entries.
   5777               By default, IPV6 is supported so the two TCAMs are paired
   5778               together, hence index_max for L3_DEFIP is 1023 for 56832.
   5779               Calculation: index_max = ((2 * 1024 ) - (512 *2) -1) = 1023
   5780               2-># of TCAMs, 1024-> size of TCAM,512-> ipv6_128b_entries
   5781            */
   5782             sop->memState[L3_DEFIPm].index_max = num_defip_entries - 1;
   5783 
   5784             sop->memState[L3_DEFIP_ONLYm].index_max =
   5785                                           sop->memState[L3_DEFIPm].index_max;
   5786             sop->memState[L3_DEFIP_DATA_ONLYm].index_max =
   5787                                           sop->memState[L3_DEFIPm].index_max;
   5788             sop->memState[L3_DEFIP_HIT_ONLYm].index_max =
   5789                                           sop->memState[L3_DEFIPm].index_max;
   5790             sop->memState[L3_DEFIP_HIT_ONLY_Xm].index_max =
   5791                                           sop->memState[L3_DEFIPm].index_max;
   5792             sop->memState[L3_DEFIP_HIT_ONLY_Ym].index_max =
   5793                                           sop->memState[L3_DEFIPm].index_max;
   5794             SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries;
   5795         } else {
   5796             if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) {
   5797                 /* slightly different processing for v6-128 */
   5798                 num_ipv6_128b_entries = soc_property_get(unit,
   5799                                             spn_NUM_IPV6_LPM_128B_ENTRIES,
   5800                                             2048);
   5801                 num_ipv6_128b_entries = num_ipv6_128b_entries +
   5802                                         (num_ipv6_128b_entries % 2);
   5803                 if (soc_trident2_alpm_mode_get(unit) == 1) {
   5804                     num_ipv6_128b_entries = (num_ipv6_128b_entries + 3) / 4 * 4;
   5805                 }
   5806                 if (SOC_CONTROL(unit)->tcam_protect_write) {
   5807                     num_ipv6_128b_entries = (num_ipv6_128b_entries + 3) / 4 * 4;
   5808                 }
   5809                 config_v6_entries = num_ipv6_128b_entries;
   5810                 num_defip_entries = (SOC_CONTROL(unit)->l3_defip_max_tcams *
   5811                                      SOC_CONTROL(unit)->l3_defip_tcam_size) -
   5812                                      (num_ipv6_128b_entries * 2);
   5813 
   5814                 /* Adjust numbers for tcam_protect_write */
   5815                 if (SOC_CONTROL(unit)->tcam_protect_write) {
   5816                     if (num_defip_entries) {
   5817                         num_defip_entries -= 8;
   5818                         /* Don't use up all entries as protect entries */
   5819                         if (num_defip_entries <= 0) {
   5820                             return SOC_E_CONFIG;
   5821                         }
   5822                         SOC_CONTROL(unit)->l3_defip_tcam_size --;
   5823                     }
   5824                     if (num_ipv6_128b_entries) {
   5825                         num_ipv6_128b_entries -= 4;
   5826                         /* Don't use up all entries as protect entries */
   5827                         if (num_ipv6_128b_entries <= 0) {
   5828                             return SOC_E_CONFIG;
   5829                         }
   5830                         SOC_CONTROL(unit)->l3_defip_tcam_size --;
   5831                     }
   5832                     if (config_v6_entries) {
   5833                         config_v6_entries -= 4;
   5834                         if (config_v6_entries < 0) {
   5835                             return SOC_E_CONFIG;
   5836                         }
   5837                     }
   5838                 }
   5839                 sop->memState[L3_DEFIP_PAIR_128m].index_max =
   5840                                                 num_ipv6_128b_entries - 1;
   5841                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max =
   5842                                                 num_ipv6_128b_entries - 1;
   5843                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max =
   5844                                                 num_ipv6_128b_entries - 1;
   5845                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max =
   5846                                                 num_ipv6_128b_entries - 1;
   5847                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Xm].index_max =
   5848                                                 num_ipv6_128b_entries - 1;
   5849                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Ym].index_max =
   5850                                                 num_ipv6_128b_entries - 1;
   5851                 sop->memState[L3_DEFIPm].index_max = num_defip_entries - 1;
   5852 
   5853                 sop->memState[L3_DEFIP_ONLYm].index_max =
   5854                                        sop->memState[L3_DEFIPm].index_max;
   5855                 sop->memState[L3_DEFIP_DATA_ONLYm].index_max =
   5856                                        sop->memState[L3_DEFIPm].index_max;
   5857                 sop->memState[L3_DEFIP_HIT_ONLYm].index_max =
   5858                                        sop->memState[L3_DEFIPm].index_max;
   5859                 sop->memState[L3_DEFIP_HIT_ONLY_Xm].index_max =
   5860                                        sop->memState[L3_DEFIPm].index_max;
   5861                 sop->memState[L3_DEFIP_HIT_ONLY_Ym].index_max =
   5862                                        sop->memState[L3_DEFIPm].index_max;
   5863 
   5864                 SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries;
   5865             } else {
   5866                 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
   5867                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
   5868                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
   5869                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
   5870                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Xm].index_max = -1;
   5871                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLY_Ym].index_max = -1;
   5872             }
   5873         }
   5874         soc_l3_defip_indexes_init(unit, config_v6_entries);
   5875     }
   5876     if (NULL == _soc_td2_alpm_bkt_view_map[unit]) {
   5877         if ((_soc_td2_alpm_bkt_view_map[unit] =
   5878              sal_alloc(sizeof(soc_mem_t) * SOC_TD2_ALPM_MAX_BKTS,
   5879                        "alpm_bkt_map")) == NULL) {
   5880             return SOC_E_MEMORY;
   5881         }
   5882     }
   5883     if (dev_id == BCM56830_DEVICE_ID) {
   5884          soc_bcm56830_mem_config(unit);
   5885     }
   5886     if (dev_id == BCM56834_DEVICE_ID) {
   5887          soc_bcm56834_mem_config(unit);
   5888     }
   5889 
   5890 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5891     if (SOC_IS_TD2P_TT2P(unit)) {
   5892          soc_td2p_mem_config(unit, dev_id, rev_id);
   5893     }
   5894 #endif
   5895 
   5896     memset(_soc_td2_alpm_bkt_view_map[unit], INVALIDm,
   5897            sizeof(soc_mem_t) * SOC_TD2_ALPM_MAX_BKTS);
   5898     return SOC_E_NONE;
   5899 }
   5900 
   5901 int
   5902 soc_trident2_alpm_mode_get(int unit)
   5903 {
   5904     return _soc_alpm_mode[unit];
   5905 }
   5906 
   5907 
   5908 /* Map logical (always starts from 0 and contiguous) index to physical index
   5909    which can have a starting offset and/or holes.
   5910    Input  : logical index
   5911    Returns: physical index */
   5912 int
   5913 soc_trident2_l3_defip_index_map(int unit, soc_mem_t mem, int index)
   5914 {
   5915     int wide = 0;
   5916     int alpm_mode = _soc_alpm_mode[unit];
   5917     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   5918     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   5919     int phy_index;
   5920     soc_mem_t lpm_mem  = L3_DEFIPm;
   5921     soc_mem_t pair_mem = L3_DEFIP_PAIR_128m;
   5922 
   5923     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m)) {
   5924         lpm_mem  = L3_DEFIP_LEVEL1m;
   5925         pair_mem = L3_DEFIP_PAIR_LEVEL1m;
   5926     }
   5927 
   5928     if (mem == pair_mem ||
   5929         mem == L3_DEFIP_PAIR_128_ONLYm ||
   5930         mem == L3_DEFIP_PAIR_128_DATA_ONLYm ||
   5931         mem == L3_DEFIP_PAIR_128_HIT_ONLYm ||
   5932         mem == L3_DEFIP_PAIR_128_HIT_ONLY_Xm ||
   5933         mem == L3_DEFIP_PAIR_128_HIT_ONLY_Ym) {
   5934         wide = 1;
   5935     }
   5936 
   5937     if (SOC_CONTROL(unit)->tcam_protect_write_init) {
   5938         int incr = 0, hole = 0;
   5939         incr = soc_mem_index_count(unit, mem) /
   5940                (SOC_L3_DEFIP_MAX_TCAMS_GET(unit) >> wide);
   5941         hole = index / incr;
   5942         if (defip128_tbl_sz == 0) {
   5943             phy_index = index;
   5944         } else {
   5945             phy_index = soc_l3_defip_alpm_urpf_index_map(unit, wide, index);
   5946 
   5947         }
   5948         if (SOC_CONTROL(unit)->tcam_protect_write) {
   5949             if (defip128_tbl_sz == 0) {
   5950                 phy_index += hole;
   5951             } else {
   5952                 if (wide && soc_mem_index_count(unit, lpm_mem)) {
   5953                     hole = hole * 2;
   5954                 } else if (!wide && soc_mem_index_count(unit, pair_mem)) {
   5955                     hole = hole + (hole / 2 * 2) + (hole % 2) + 1;
   5956                 }
   5957                 phy_index += hole;
   5958             }
   5959         }
   5960         return phy_index;
   5961     }
   5962 
   5963     if (defip128_tbl_sz == 0) {
   5964         phy_index = index;
   5965     } else if ((alpm_mode == 2 || alpm_mode == 0) && !is_urpf_mode) {
   5966         phy_index = soc_l3_defip_index_map(unit, wide, index);
   5967     } else if ((alpm_mode == 1 || alpm_mode == 3) && is_urpf_mode) {
   5968         phy_index = soc_l3_defip_alpm_urpf_index_map(unit, wide, index);
   5969     } else {
   5970         phy_index = soc_l3_defip_urpf_index_map(unit, wide, index);
   5971     }
   5972 
   5973     return phy_index;
   5974 }
   5975 
   5976 
   5977 /* Reverse map physical index to logical index.
   5978    Input  : physical index
   5979    Returns: logical index */
   5980 int
   5981 soc_trident2_l3_defip_index_remap(int unit, soc_mem_t mem, int index)
   5982 {
   5983     int wide = 0;
   5984     int alpm_mode = _soc_alpm_mode[unit];
   5985     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   5986     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   5987     int log_index = 0;
   5988     soc_mem_t lpm_mem  = L3_DEFIPm;
   5989     soc_mem_t pair_mem = L3_DEFIP_PAIR_128m;
   5990 
   5991     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m)) {
   5992         lpm_mem  = L3_DEFIP_LEVEL1m;
   5993         pair_mem = L3_DEFIP_PAIR_LEVEL1m;
   5994     }
   5995 
   5996     if (mem == pair_mem ||
   5997         mem == L3_DEFIP_PAIR_128_ONLYm ||
   5998         mem == L3_DEFIP_PAIR_128_DATA_ONLYm ||
   5999         mem == L3_DEFIP_PAIR_128_HIT_ONLYm ||
   6000         mem == L3_DEFIP_PAIR_128_HIT_ONLY_Xm ||
   6001         mem == L3_DEFIP_PAIR_128_HIT_ONLY_Ym) {
   6002         wide = 1;
   6003     }
   6004 
   6005     if (SOC_CONTROL(unit)->tcam_protect_write_init) {
   6006         int tcam_size = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   6007         int hole = 0;
   6008         if (soc_mem_index_count(unit, pair_mem)) {
   6009             tcam_size++;
   6010             defip128_tbl_sz += 4;
   6011         }
   6012         if (soc_mem_index_count(unit, lpm_mem)) {
   6013             tcam_size++;
   6014         }
   6015 
   6016         if (SOC_CONTROL(unit)->tcam_protect_write) {
   6017             if (defip128_tbl_sz == 0) {
   6018                 hole = index / tcam_size;
   6019                 index -= hole;
   6020             } else {
   6021                 hole = index / tcam_size;
   6022                 if (wide && soc_mem_index_count(unit, lpm_mem)) {
   6023                     hole = hole * 2;
   6024                 } else if (!wide && soc_mem_index_count(unit, pair_mem)) {
   6025                     hole = hole + (hole / 2 * 2) + (hole % 2) + 1;
   6026                 }
   6027                 index -= hole;
   6028             }
   6029         }
   6030         if (defip128_tbl_sz == 0) {
   6031             log_index = index;
   6032         } else {
   6033             log_index = soc_l3_defip_alpm_urpf_index_remap(unit, wide, index);
   6034         }
   6035         return log_index;
   6036     }
   6037 
   6038     if (defip128_tbl_sz == 0) {
   6039         log_index = index;
   6040     } else if ((alpm_mode == 2 || alpm_mode == 0) && !is_urpf_mode) {
   6041         log_index = soc_l3_defip_index_remap(unit, wide, index);
   6042     } else if ((alpm_mode == 1 || alpm_mode == 3) && is_urpf_mode) {
   6043         log_index = soc_l3_defip_alpm_urpf_index_remap(unit, wide, index);
   6044     } else {
   6045         log_index = soc_l3_defip_urpf_index_remap(unit, wide, index);
   6046     }
   6047 
   6048     return log_index;
   6049 }
   6050 
   6051 /* Given a physical index (always in terms of the narrow entry)
   6052    return the logical index and memory type */
   6053 int
   6054 soc_trident2_l3_defip_mem_index_get(int unit, int pindex, soc_mem_t *mem)
   6055 {
   6056     int logical_index =  -1;
   6057     int defip_pair_index = -1;
   6058     int cam_size = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   6059     int alpm_mode = _soc_alpm_mode[unit];
   6060     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   6061     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   6062     soc_mem_t lpm_mem  = L3_DEFIPm;
   6063     soc_mem_t pair_mem = L3_DEFIP_PAIR_128m;
   6064 
   6065     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m)) {
   6066         lpm_mem  = L3_DEFIP_LEVEL1m;
   6067         pair_mem = L3_DEFIP_PAIR_LEVEL1m;
   6068     }
   6069 
   6070     *mem = lpm_mem;
   6071 
   6072     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   6073         return pindex;
   6074     }
   6075 
   6076     if (SOC_CONTROL(unit)->tcam_protect_write_init) {
   6077         int tcam_size = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   6078         int hole = 0;
   6079         if (soc_mem_index_count(unit, pair_mem)) {
   6080             tcam_size++;
   6081             defip128_tbl_sz += 4;
   6082         }
   6083         if (soc_mem_index_count(unit, lpm_mem)) {
   6084             tcam_size++;
   6085         }
   6086 
   6087         if (SOC_CONTROL(unit)->tcam_protect_write) {
   6088             if (defip128_tbl_sz == 0) {
   6089                 hole = pindex / tcam_size;
   6090                 pindex -= hole;
   6091             } else {
   6092                 hole = pindex / tcam_size;
   6093                 if (soc_mem_index_count(unit, lpm_mem)) {
   6094                     /*First look up in the double wide. If not find then look up in the single wide*/
   6095                     *mem = pair_mem;
   6096                     hole = hole * 2;
   6097                     logical_index = soc_l3_defip_alpm_urpf_index_remap(unit, 1,
   6098                                                                        pindex - hole);
   6099                     if (logical_index == -1) {
   6100                         if (soc_mem_index_count(unit, pair_mem)) {
   6101                             *mem = lpm_mem;
   6102                             hole = hole + (hole / 2 * 2) + (hole % 2) + 1;
   6103                             logical_index =
   6104                                 soc_l3_defip_alpm_urpf_index_remap(unit, 0,
   6105                                 pindex - hole);
   6106                         }
   6107                     }
   6108                 }
   6109                 return logical_index;
   6110             }
   6111         }
   6112         if (defip128_tbl_sz == 0) {
   6113             *mem = lpm_mem;
   6114             logical_index = pindex;
   6115         } else {
   6116             *mem = lpm_mem;
   6117             logical_index = soc_l3_defip_alpm_urpf_index_remap(unit, 0, pindex);
   6118             if (logical_index == -1) {
   6119                 *mem = pair_mem;
   6120                 logical_index = soc_l3_defip_alpm_urpf_index_remap(unit, 1, pindex);
   6121             }
   6122         }
   6123         return logical_index;
   6124     }
   6125 
   6126     if ((alpm_mode == 2 || alpm_mode == 0) && !is_urpf_mode) {
   6127         logical_index = soc_l3_defip_index_remap(unit, 0, pindex);
   6128     } else if ((alpm_mode == 1 || alpm_mode == 3) && is_urpf_mode) {
   6129         logical_index = soc_l3_defip_alpm_urpf_index_remap(unit, 0, pindex);
   6130     } else {
   6131         logical_index = soc_l3_defip_urpf_index_remap(unit, 0, pindex);
   6132     }
   6133 
   6134     if (logical_index == -1) {
   6135         *mem = pair_mem;
   6136         defip_pair_index = ((pindex / (cam_size * 2)) * cam_size) +
   6137                            (pindex % cam_size);
   6138         if ((alpm_mode == 2 || alpm_mode == 0) && !is_urpf_mode) {
   6139             logical_index = soc_l3_defip_index_remap(unit, 1, defip_pair_index);
   6140         } else if ((alpm_mode == 1 || alpm_mode == 3) && is_urpf_mode) {
   6141             logical_index =
   6142                 soc_l3_defip_alpm_urpf_index_remap(unit, 1, defip_pair_index);
   6143         } else {
   6144             logical_index =
   6145                 soc_l3_defip_urpf_index_remap(unit, 1, defip_pair_index);
   6146         }
   6147     }
   6148 
   6149     return logical_index;
   6150 }
   6151 
   6152 void
   6153 _soc_trident2_alpm_bkt_view_set(int unit, int index, soc_mem_t view)
   6154 {
   6155     int bkt = (index >> 2) & SOC_TD2_ALPM_BKT_MASK;
   6156 
   6157     if (view != INVALIDm) {
   6158         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6159                     (BSL_META_U(unit,
   6160                                 "ALPM bkt set index:%d bkt:%d view:%s\n"),
   6161                      index, bkt, SOC_MEM_NAME(unit, view)));
   6162     }
   6163     _soc_td2_alpm_bkt_view_map[unit][bkt] = view;
   6164 }
   6165 
   6166 soc_mem_t
   6167 _soc_trident2_alpm_bkt_view_get(int unit, int index)
   6168 {
   6169     soc_mem_t view;
   6170     int bkt = (index >> 2) & SOC_TD2_ALPM_BKT_MASK;
   6171 
   6172     view = _soc_td2_alpm_bkt_view_map[unit][bkt];
   6173     if (view != INVALIDm) {
   6174         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6175                     (BSL_META_U(unit,
   6176                                 "ALPM bkt get index:%d bkt:%d view:%s\n"),
   6177                      index, bkt, SOC_MEM_NAME(unit, view)));
   6178     }
   6179     return view;
   6180 }
   6181 
   6182 int
   6183 _soc_trident2_mem_sram_info_get(int unit, soc_mem_t mem, int index,
   6184                                 _soc_ser_sram_info_t *sram_info)
   6185 {
   6186     soc_mem_t view;
   6187     int i, j, base, base_index, offset, base_bucket, bkt_offset;
   6188     int entries_per_ram = 0, entries_per_bank, contiguous = 0;
   6189     uint16 dev_id;
   6190     uint8 rev_id;
   6191 
   6192     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
   6193 
   6194     switch (mem) {
   6195     case L2Xm:
   6196 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6197     case L2_ENTRY_ONLY_ECCm:
   6198 #endif
   6199         if (!SOC_IS_TD2P_TT2P(unit)) {
   6200             sram_info->disable_reg = L2_ENTRY_PARITY_CONTROLr;
   6201             sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6202             sram_info->force_field = FORCE_XOR_GENERATIONf;
   6203         } else {
   6204             if (mem == L2Xm) {
   6205                 sram_info->disable_reg = L2_ENTRY_PARITY_CONTROLr;
   6206                 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6207             }
   6208         }
   6209 
   6210         if (index < SOC_TD2_NUM_ENTRIES_L2_BANK) {
   6211             if (!SOC_IS_TD2P_TT2P(unit)) {
   6212                 sram_info->force_reg = L2_ENTRY_CONTROL_6r;
   6213             }
   6214             sram_info->ram_count = SOC_TD2_NUM_EL_L2;
   6215             entries_per_ram = SOC_TD2_RAM_OFFSET_L2_BANK;
   6216             offset = index % entries_per_ram;
   6217             base = offset;
   6218             if (index >= SOC_TD2_NUM_ENTRIES_PER_L2_BANK) {
   6219                 base = offset + SOC_TD2_NUM_ENTRIES_PER_L2_BANK;
   6220             }
   6221         } else {
   6222             if (!SOC_IS_TD2P_TT2P(unit)) {
   6223                 sram_info->force_reg = ISS_MEMORY_CONTROL_84r;
   6224             }
   6225             entries_per_ram = SOC_TD2_RAM_OFFSET_L2_SHARED_BANK;
   6226             base_index = SOC_TD2_NUM_ENTRIES_L2_BANK;
   6227             offset = base_index + (index % entries_per_ram);
   6228             base = offset;
   6229 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6230             if (SOC_IS_TD2P_TT2P(unit)) {
   6231                 if (dev_id == BCM56867_DEVICE_ID) {
   6232                     sram_info->ram_count = SOC_TD2P_NUM_EL_SHARED;
   6233                 } else {
   6234                     sram_info->ram_count = SOC_TD2P_NUM_EL_SHARED/2;
   6235                 }
   6236                 entries_per_bank = entries_per_ram * sram_info->ram_count;
   6237                 for (i = 1; i < SOC_TD2_NUM_EL_L2; i++) {
   6238                     if (index >= (base_index + (entries_per_bank * i))) {
   6239                         base = offset + (entries_per_bank * i);
   6240                     }
   6241                 }
   6242             } else
   6243 #endif
   6244             {
   6245                 sram_info->ram_count = SOC_TD2_NUM_EL_SHARED;
   6246                 entries_per_bank = entries_per_ram * sram_info->ram_count;
   6247                 for (i = 1; i < SOC_TD2_NUM_EL_L2; i++) {
   6248                     if (index >= (base_index + (entries_per_bank * i))) {
   6249                         base = offset + (entries_per_bank * i);
   6250                     }
   6251                 }
   6252             }
   6253         }
   6254         break;
   6255     case L3_ENTRY_ONLYm:
   6256     case L3_ENTRY_IPV4_UNICASTm:
   6257     case L3_ENTRY_IPV4_MULTICASTm:
   6258     case L3_ENTRY_IPV6_UNICASTm:
   6259     case L3_ENTRY_IPV6_MULTICASTm:
   6260 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6261     case L3_ENTRY_ONLY_ECCm:
   6262 #endif
   6263 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6264         if (SOC_IS_TRIDENT2PLUS(unit)) {
   6265             if (index < SOC_TD2_NUM_ENTRIES_L3_BANK) {
   6266                 /* dedicated L3 entries - hash table */
   6267                 sram_info->ram_count = 1;
   6268                 entries_per_ram = SOC_TD2_NUM_ENTRIES_L3_BANK;
   6269                 base = index;
   6270             } else {
   6271                 if (dev_id == BCM56867_DEVICE_ID) {
   6272                     sram_info->ram_count = SOC_TD2P_NUM_EL_SHARED;
   6273                 } else {
   6274                     sram_info->ram_count = SOC_TD2P_NUM_EL_SHARED/2;
   6275                 }
   6276                 entries_per_ram = SOC_TD2_RAM_OFFSET_L3_NARROW;
   6277                 base_index = SOC_TD2_NUM_ENTRIES_L3_BANK;
   6278                 entries_per_bank = entries_per_ram * sram_info->ram_count;
   6279                 offset = base_index + (index % entries_per_ram);
   6280                 base = offset;
   6281                 for (i = 1; i < SOC_TD2P_NUM_EL_L3; i++) {
   6282                     if (index >= (base_index + (entries_per_bank * i))) {
   6283                         base = offset + (entries_per_bank * i);
   6284                     }
   6285                 }
   6286             }
   6287         } else
   6288 #endif
   6289         {
   6290             if ((soc_mem_index_count(unit, L3_ENTRY_ONLYm) <= SOC_TD2_NUM_ENTRIES_L3_BANK) ||
   6291                 (index < SOC_TD2_NUM_ENTRIES_L3_BANK)) {
   6292                 /* No SRAM XOR RAM in L3 banks, or the entry locates at dedicated L3 banks */
   6293                 return SOC_E_UNAVAIL;
   6294             }
   6295             sram_info->disable_reg = L3_ENTRY_PARITY_CONTROLr;
   6296             sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6297             sram_info->force_reg = ISS_MEMORY_CONTROL_84r;
   6298             sram_info->force_field = FORCE_XOR_GENERATIONf;
   6299             sram_info->ram_count = SOC_TD2_NUM_EL_SHARED;
   6300             entries_per_ram = ((mem == L3_ENTRY_ONLYm || mem == L3_ENTRY_IPV4_UNICASTm) ?
   6301                                SOC_TD2_RAM_OFFSET_L3_NARROW : (mem == L3_ENTRY_IPV6_MULTICASTm) ?
   6302                                SOC_TD2_RAM_OFFSET_L3_DOUBLE_WIDE :
   6303                                SOC_TD2_RAM_OFFSET_L3_WIDE);
   6304             base_index = ((mem == L3_ENTRY_ONLYm || mem == L3_ENTRY_IPV4_UNICASTm) ?
   6305                           SOC_TD2_NUM_ENTRIES_L3_BANK : (mem == L3_ENTRY_IPV6_MULTICASTm) ?
   6306                           SOC_TD2_NUM_ENTRIES_L3_BANK_DOUBLE_WIDE :
   6307                           SOC_TD2_NUM_ENTRIES_L3_BANK_WIDE);
   6308             entries_per_bank = entries_per_ram * sram_info->ram_count;
   6309             offset = base_index + (index % entries_per_ram);
   6310             base = offset;
   6311             for (i = 1; i < SOC_TD2_NUM_EL_ALPM; i++) {
   6312                 if (index >= (base_index + (entries_per_bank * i))) {
   6313                     base = offset + (entries_per_bank * i);
   6314                 }
   6315             }
   6316         }
   6317         break;
   6318     case L3_DEFIP_ALPM_IPV4m:
   6319     case L3_DEFIP_ALPM_IPV4_1m:
   6320     case L3_DEFIP_ALPM_IPV6_64m:
   6321     case L3_DEFIP_ALPM_IPV6_64_1m:
   6322     case L3_DEFIP_ALPM_IPV6_128m:
   6323     case L3_DEFIP_ALPM_RAWm:
   6324 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6325     case L3_DEFIP_ALPM_ECCm:
   6326 #endif
   6327         sram_info->disable_reg = ILPM_SER_CONTROLr;
   6328         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6329         sram_info->force_reg = ISS_MEMORY_CONTROL_84r;
   6330         sram_info->force_field = FORCE_XOR_GENERATIONf;
   6331 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6332         if (SOC_IS_TRIDENT2PLUS(unit)) {
   6333             sram_info->ram_count = SOC_TD2P_NUM_EL_SHARED/2;
   6334             base_bucket = ((index >> 2) & SOC_TD2_ALPM_BKT_MASK);
   6335             base = index & 0x3;
   6336             LOG_VERBOSE(BSL_LS_SOC_SER,
   6337                         (BSL_META_U(unit,
   6338                                     "reported bucket: 0x%08x, bank:%d\n"), base_bucket, base));
   6339             base_bucket = base_bucket % SOC_TD2_ALPM_BKT_OFFFSET;
   6340             LOG_VERBOSE(BSL_LS_SOC_SER,
   6341                         (BSL_META_U(unit,
   6342                                     "base bucket: 0x%08x\n"), base_bucket));
   6343             for (i = 0; i < SOC_TD2_NUM_EL_SHARED; i++) {
   6344                 sram_info->view[i] = mem;
   6345                 sram_info->index_count[i] = 1;
   6346                 bkt_offset = base_bucket + SOC_TD2_ALPM_BKT_OFFFSET * i;
   6347                 sram_info->mem_indexes[i][0] =
   6348                     (index & SOC_TD2P_ALPM_MODE0_BKT_MASK) |
   6349                     (bkt_offset << 2) | base;
   6350             }
   6351         } else
   6352 #endif
   6353         {
   6354             sram_info->ram_count = SOC_TD2_NUM_EL_SHARED;
   6355             base_bucket = ((index  >> 2) & SOC_TD2_ALPM_BKT_MASK);
   6356             base = index & 0x3;
   6357             LOG_VERBOSE(BSL_LS_SOC_SER,
   6358                         (BSL_META_U(unit,
   6359                                     "reported bucket: 0x%08x, bank:%d\n"), base_bucket, base));
   6360             base_bucket = base_bucket % SOC_TD2_ALPM_BKT_OFFFSET;
   6361             LOG_VERBOSE(BSL_LS_SOC_SER,
   6362                         (BSL_META_U(unit,
   6363                                     "base bucket: 0x%08x\n"), base_bucket));
   6364 
   6365             for (i = 0; i < SOC_TD2_NUM_EL_SHARED; i++) {
   6366                 /* Retreive views for all 8 buckets */
   6367                 bkt_offset = base_bucket + SOC_TD2_ALPM_BKT_OFFFSET * i;
   6368                 view = _soc_td2_alpm_bkt_view_map[unit][bkt_offset];
   6369                 if (INVALIDm != view) {
   6370                     LOG_VERBOSE(BSL_LS_SOC_SER,
   6371                                 (BSL_META_U(unit,
   6372                                             "\nbucket[%d]: 0x%08x view: %s\n"), i, bkt_offset,
   6373                                             SOC_MEM_NAME(unit, view)));
   6374                 }
   6375                 /* Use RAW view to recovery those unused ALPM buckets and avoid
   6376                  * false alarm */
   6377                 if (INVALIDm == view) {
   6378                     view = L3_DEFIP_ALPM_RAWm;
   6379                 }
   6380                 sram_info->view[i] = view;
   6381                 switch (view) {
   6382                 case L3_DEFIP_ALPM_RAWm:
   6383                     sram_info->index_count[i] = SOC_TD2_L3_DEFIP_ALPM_PER_BKT_COUNT;
   6384                     sram_info->mem_indexes[i][0] = (bkt_offset << 2) | base;
   6385                     break;
   6386                 case L3_DEFIP_ALPM_IPV6_128m:
   6387                     sram_info->index_count[i] = SOC_TD2_L3_DEFIP_ALPM_IPV6_128_PER_BKT_COUNT;
   6388                     sram_info->mem_indexes[i][0] = (bkt_offset << 2) | base;
   6389                     sram_info->mem_indexes[i][1] = (1 << 16) | (bkt_offset << 2) | base;
   6390                     break;
   6391                 case L3_DEFIP_ALPM_IPV6_64_1m:
   6392                     sram_info->index_count[i] = SOC_TD2_L3_DEFIP_ALPM_IPV6_64_1_PER_BKT_COUNT;
   6393                     sram_info->mem_indexes[i][0] = (bkt_offset << 2) | base;
   6394                     sram_info->mem_indexes[i][1] = (1 << 16) | (bkt_offset << 2) | base;
   6395                     sram_info->mem_indexes[i][2] = (2 << 16) | (bkt_offset << 2) | base;
   6396                     break;
   6397                 case L3_DEFIP_ALPM_IPV4m:
   6398                     sram_info->index_count[i] = SOC_TD2_L3_DEFIP_ALPM_IPV4_PER_BKT_COUNT;
   6399                     for (j = 0; j < SOC_TD2_L3_DEFIP_ALPM_IPV4_PER_BKT_COUNT; j++) {
   6400                         sram_info->mem_indexes[i][j] = (j << 16) | (bkt_offset << 2) |
   6401                                                        base;
   6402                     }
   6403                     break;
   6404                 case L3_DEFIP_ALPM_IPV4_1m:
   6405                 case L3_DEFIP_ALPM_IPV6_64m:
   6406                     sram_info->index_count[i] = SOC_TD2_L3_DEFIP_ALPM_IPV6_64_PER_BKT_COUNT;
   6407                     for (j = 0; j < SOC_TD2_L3_DEFIP_ALPM_IPV6_64_PER_BKT_COUNT; j++) {
   6408                         sram_info->mem_indexes[i][j] = (j << 16) | (bkt_offset << 2) |
   6409                                                        base;
   6410                     }
   6411                 default:
   6412                     break;
   6413                 }
   6414                 LOG_VERBOSE(BSL_LS_SOC_SER,
   6415                             (BSL_META_U(unit,
   6416                                         "Entries per bkt: %d\n"), sram_info->index_count[i]));
   6417                 for (j = 0; j < sram_info->index_count[i]; j++) {
   6418                     LOG_VERBOSE(BSL_LS_SOC_SER,
   6419                                 (BSL_META_U(unit,
   6420                                             "Index[%d]: [0x%08x]%d\n"), j, sram_info->mem_indexes[i][j],
   6421                                             sram_info->mem_indexes[i][j]));
   6422                 }
   6423             }
   6424         }
   6425         return SOC_E_NONE;
   6426     case VLAN_XLATEm:
   6427 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6428     case VLAN_XLATE_ECCm:
   6429 #endif
   6430         contiguous = 1;
   6431         sram_info->disable_reg = VLAN_XLATE_DBGCTRL_0r;
   6432         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6433         sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r;
   6434         sram_info->force_field = FORCE_XOR_GENf;
   6435         sram_info->ram_count = SOC_TD2_NUM_EL_VLAN_XLATE;
   6436         base = (index/4) * 4;
   6437         break;
   6438 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6439     case VLAN_MACm:
   6440         if (SOC_IS_TD2P_TT2P(unit)) {
   6441             contiguous = 1;
   6442             sram_info->disable_reg = VLAN_XLATE_DBGCTRL_0r;
   6443             sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6444             sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r;
   6445             sram_info->force_field = FORCE_XOR_GENf;
   6446             sram_info->ram_count = SOC_TD2_NUM_EL_VLAN_XLATE;
   6447             base = (index/4) * 4;
   6448             break;
   6449         } else {
   6450             return SOC_E_UNAVAIL;
   6451         }
   6452 #endif
   6453     case EGR_VLAN_XLATEm:
   6454 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6455     case EGR_VLAN_XLATE_ECCm:
   6456 #endif
   6457         contiguous = 1;
   6458         sram_info->disable_reg = EGR_VLAN_XLATE_CONTROLr;
   6459         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   6460         sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr;
   6461         sram_info->force_field = FORCE_XOR_GENf;
   6462         sram_info->ram_count = SOC_TD2_NUM_EL_EGR_VLAN_XLATE;
   6463         base = (index/4) * 4;
   6464         break;
   6465     case ING_L3_NEXT_HOPm:
   6466         sram_info->ram_count = SOC_TD2_NUM_EL_ING_L3_NEXT_HOP;
   6467         entries_per_ram = SOC_TD2_RAM_OFFSET_ING_L3_NEXT_HOP;
   6468         base = index % entries_per_ram;
   6469         break;
   6470     case L3_IPMCm:
   6471 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6472         if (SOC_IS_TD2P_TT2P(unit)) {
   6473             sram_info->ram_count = SOC_TD2P_NUM_EL_L3_IPMC;
   6474         } else
   6475 #endif
   6476         {
   6477             sram_info->ram_count = SOC_TD2_NUM_EL_L3_IPMC;
   6478         }
   6479         entries_per_ram = SOC_TD2_RAM_OFFSET_L3_IPMC;
   6480         if (dev_id == BCM56832_DEVICE_ID) {
   6481             entries_per_ram = 1024;
   6482         }
   6483         base = index % entries_per_ram;
   6484         break;
   6485     case L2MCm:
   6486         sram_info->ram_count = SOC_TD2_NUM_EL_L2MC(unit);
   6487         entries_per_ram = SOC_TD2_RAM_OFFSET_L2MC;
   6488         base = index % entries_per_ram;
   6489         break;
   6490 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6491     case L2_ENTRY_LPm:
   6492     case L3_ENTRY_LPm:
   6493     case VLAN_XLATE_LPm:
   6494     case EGR_VLAN_XLATE_LPm:
   6495         sram_info->view[0] = mem;
   6496         sram_info->index_count[0] = 1;
   6497         sram_info->ram_count = 1;
   6498         entries_per_ram = 0;
   6499         base = index;
   6500         break;
   6501 #endif
   6502     default: return SOC_E_PARAM;
   6503     }
   6504     sram_info->mem_indexes[0][0] = base;
   6505     if (contiguous) {
   6506         for (i = 1; i < sram_info->ram_count; i++) {
   6507             sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 1;
   6508         }
   6509     } else {
   6510         for (i = 1; i < sram_info->ram_count; i++) {
   6511             sram_info->mem_indexes[i][0] =  sram_info->mem_indexes[i-1][0] + entries_per_ram;
   6512         }
   6513     }
   6514     return SOC_E_NONE;
   6515 }
   6516 
   6517 int
   6518 _soc_trident2_mem_cpu_write_control(int unit, soc_mem_t mem, int copyno,
   6519                                     int enable, int *orig_enable)
   6520 {
   6521     soc_reg_t reg;
   6522     soc_field_t field;
   6523     int blk, port;
   6524     uint32 rval, fval, orig_fval, enable_fval, disable_fval;
   6525 
   6526     enable_fval = 1;
   6527     disable_fval = 0;
   6528 
   6529     switch (mem) {
   6530     case XLPORT_WC_UCMEM_DATAm:
   6531         reg = XLPORT_WC_UCMEM_CTRLr;
   6532         field = ACCESS_MODEf;
   6533         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   6534             port = SOC_BLOCK_PORT(unit, blk);
   6535             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   6536             /* It will use the setting from the last block */
   6537             *orig_enable = soc_reg_field_get(unit, reg, rval, field);
   6538             soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   6539             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   6540         }
   6541         return SOC_E_NONE;
   6542     case MMU_CFAP_BANK0m:
   6543     case MMU_CFAP_BANK1m:
   6544     case MMU_CFAP_BANK10m:
   6545     case MMU_CFAP_BANK11m:
   6546     case MMU_CFAP_BANK12m:
   6547     case MMU_CFAP_BANK13m:
   6548     case MMU_CFAP_BANK14m:
   6549     case MMU_CFAP_BANK15m:
   6550     case MMU_CFAP_BANK16m:
   6551     case MMU_CFAP_BANK17m:
   6552     case MMU_CFAP_BANK18m:
   6553     case MMU_CFAP_BANK19m:
   6554     case MMU_CFAP_BANK2m:
   6555     case MMU_CFAP_BANK20m:
   6556 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   6557     case MMU_CFAP_BANK21m:
   6558     case MMU_CFAP_BANK22m:
   6559     case MMU_CFAP_BANK23m:
   6560     case MMU_CFAP_BANK24m:
   6561     case MMU_CFAP_BANK25m:
   6562     case MMU_CFAP_BANK26m:
   6563     case MMU_CFAP_BANK27m:
   6564     case MMU_CFAP_BANK28m:
   6565     case MMU_CFAP_BANK29m:
   6566     case MMU_CFAP_BANK30m:
   6567     case MMU_CFAP_BANK31m:
   6568 #if 0 /* TD3TBD */
   6569     case MMU_CFAP_BANK32m:
   6570     case MMU_CFAP_BANK33m:
   6571     case MMU_CFAP_BANK34m:
   6572     case MMU_CFAP_BANK35m:
   6573     case MMU_CFAP_BANK36m:
   6574     case MMU_CFAP_BANK37m:
   6575     case MMU_CFAP_BANK38m:
   6576     case MMU_CFAP_BANK39m:
   6577 #endif
   6578 #endif
   6579     case MMU_CFAP_BANK3m:
   6580     case MMU_CFAP_BANK4m:
   6581     case MMU_CFAP_BANK5m:
   6582     case MMU_CFAP_BANK6m:
   6583     case MMU_CFAP_BANK7m:
   6584     case MMU_CFAP_BANK8m:
   6585     case MMU_CFAP_BANK9m:
   6586 #ifdef BCM_TOMAHAWK_SUPPORT
   6587         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   6588             reg = MMU_GCFG_MISCCONFIGr;
   6589         } else
   6590 #endif
   6591         {
   6592             reg = MISCCONFIGr;
   6593         }
   6594         field=INIT_MEMf;
   6595         enable_fval=1;
   6596         disable_fval=0;
   6597         break;
   6598 
   6599     case L3_DEFIP_ALPM_RAWm:
   6600     case L3_DEFIP_ALPM_IPV4m:
   6601     case L3_DEFIP_ALPM_IPV4_1m:
   6602     case L3_DEFIP_ALPM_IPV6_64m:
   6603     case L3_DEFIP_ALPM_IPV6_64_1m:
   6604     case L3_DEFIP_ALPM_IPV6_128m:
   6605         reg = ISS_MEMORY_CONTROL_84r;
   6606         field = BYPASS_ISS_MEMORY_LPf;
   6607         enable_fval = 0xf;
   6608         break;
   6609     case MMU_INTFI_PFC_ST_TBLm:
   6610         reg = INTFI_CFGr;
   6611         field = PFC_ST_TBL_DISABLEf;
   6612         break;
   6613     case LINK_STATUSm:
   6614         reg = SW2_HW_CONTROLr;
   6615         field = LINK_STATUS_UPDATE_ENABLEf;
   6616         break;
   6617     case MMU_INTFO_QCN_CNM_TIMER_TBLm:
   6618     case MMU_INTFI_XPIPE_FC_MAP_TBL2m:
   6619     case MMU_INTFI_YPIPE_FC_MAP_TBL2m:
   6620         reg = MISCCONFIGr;
   6621         field = REFRESH_ENf;
   6622         enable_fval = 0;
   6623         disable_fval = 1;
   6624         break;
   6625     default:
   6626         return SOC_E_NONE;
   6627     }
   6628 
   6629     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   6630     orig_fval = soc_reg_field_get(unit, reg, rval, field);
   6631     fval = enable ? enable_fval : disable_fval;
   6632 
   6633     *orig_enable = orig_fval == enable_fval;
   6634     if (fval != orig_fval) {
   6635         soc_reg_field_set(unit, reg, &rval, field, fval);
   6636         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   6637     }
   6638 
   6639     return SOC_E_NONE;
   6640 }
   6641 
   6642 /*
   6643  * cpu port (mmu port 0): 48 queues (2000-2047)
   6644  * loopback port (mmu port 116): 8 queues (4048-4055)
   6645  */
   6646 int
   6647 soc_trident2_num_cosq_init(int unit)
   6648 {
   6649     soc_info_t *si;
   6650     int port, phy_port, mmu_port, mmu_port_offset, pipe;
   6651     int uc_cosq_base, mc_cosq_base, uc_cosq_per_port;
   6652     uint16 dev_id;
   6653     uint8 rev_id;
   6654 
   6655     si = &SOC_INFO(unit);
   6656 
   6657     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
   6658 
   6659 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6660     if (SOC_IS_TD2P_TT2P(unit)) {
   6661         si->port_num_cosq[CMIC_PORT(unit)] = 48;
   6662     } else
   6663 #endif
   6664     {
   6665         si->port_num_cosq[CMIC_PORT(unit)] = (rev_id >= BCM56850_A1_REV_ID) ? 44 : 48;
   6666     }
   6667     si->port_cosq_base[CMIC_PORT(unit)] = 520;
   6668     si->port_num_cosq[LB_PORT(unit)] = 9;
   6669     si->port_cosq_base[LB_PORT(unit)] = 1088;
   6670 
   6671     for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
   6672         if (pipe) { /* Y-pipe */
   6673             uc_cosq_base = 1480;
   6674             mc_cosq_base = 568;
   6675         } else { /* X-pipe */
   6676             uc_cosq_base = 0;
   6677             mc_cosq_base = 0;
   6678         }
   6679         for (mmu_port_offset = 0; mmu_port_offset < _TD2_MMU_PORTS_PER_PIPE;
   6680              mmu_port_offset++) {
   6681             mmu_port = si->mmu_port_base[pipe] + mmu_port_offset;
   6682             phy_port = si->port_m2p_mapping[mmu_port];
   6683             if (phy_port == -1) {
   6684                 continue;
   6685             }
   6686             port = si->port_p2l_mapping[phy_port];
   6687 
   6688             if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   6689                 continue;
   6690             }
   6691 
   6692             if (SOC_PBMP_MEMBER(si->eq_pbm, port)) { /* VBS (HSP) port */
   6693                 si->port_num_cosq[port] = 10;
   6694                 si->port_cosq_base[port] = mc_cosq_base + (mmu_port_offset * si->port_num_cosq[port]);
   6695                 si->port_num_uc_cosq[port] = 10;
   6696 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6697                 if (SOC_IS_TD2P_TT2P(unit)) {
   6698                     /* Made port_uc_cosq_base a function of mmu_port number
   6699                      * rather than a running number (as calculated by
   6700                      * uc_cosq_base before). If it is a running number, &
   6701                      * the port numbers come & go dynamically (as in flex port)
   6702                      * uc_cosq_base overlap. With port_uc_cosq_base a function
   6703                      * of mmu_port, each port has a fixed offset
   6704  */
   6705                     si->port_uc_cosq_base[port] = uc_cosq_base + (mmu_port_offset * 10);
   6706                 } else
   6707 #endif
   6708                 {
   6709                     si->port_uc_cosq_base[port] = uc_cosq_base;
   6710                     uc_cosq_base += si->port_num_uc_cosq[port];
   6711                 }
   6712             } else {
   6713                 uc_cosq_per_port =
   6714                     soc_property_port_get(unit, port, spn_LLS_NUM_L2UC, 10);
   6715                 if (uc_cosq_per_port < 10 || uc_cosq_per_port > 16) {
   6716                     uc_cosq_per_port = 10;
   6717                 }
   6718                 uc_cosq_per_port = (uc_cosq_per_port + 3) & ~3;
   6719 
   6720                 si->port_num_cosq[port] = 10;
   6721                 si->port_cosq_base[port] = mc_cosq_base + (mmu_port_offset * si->port_num_cosq[port]);
   6722                 si->port_num_uc_cosq[port] = uc_cosq_per_port;
   6723                 /*uc_cosq_base for LLS port must be
   6724                  *divisible by 4 for PFC to work */
   6725                 uc_cosq_base = (uc_cosq_base + 3) & (~3);
   6726 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6727                 if (SOC_IS_TD2P_TT2P(unit)) {
   6728                     /* Made port_uc_cosq_base a function of mmu_port
   6729                      * number rather than a running number (as calculated by
   6730                      * uc_cosq_base before).vIf it is a running number, & the
   6731                      * port numbers come & go dynamically (as in flex port)
   6732                      * uc_cosq_base overlap. With port_uc_cosq_base a function
   6733                      * of mmu_port, each port has a fixed offset
   6734  */
   6735                     si->port_uc_cosq_base[port] =
   6736                        uc_cosq_base + (mmu_port_offset * uc_cosq_per_port);
   6737                 } else
   6738 #endif
   6739                 {
   6740                     si->port_uc_cosq_base[port] = uc_cosq_base;
   6741                     uc_cosq_base += si->port_num_uc_cosq[port];
   6742                 }
   6743             }
   6744         }
   6745     }
   6746 
   6747     return SOC_E_NONE;
   6748 }
   6749 
   6750 STATIC int
   6751 soc_trident2_max_frequency_get(int unit,  uint16 dev_id, uint8 rev_id,
   6752                                int skew_id, int *frequency)
   6753 {
   6754     switch (dev_id) {
   6755     case BCM56861_DEVICE_ID:
   6756     case BCM56864_DEVICE_ID:
   6757         *frequency = 635;
   6758         break;
   6759     case BCM56860_DEVICE_ID:
   6760     case BCM56862_DEVICE_ID:
   6761     case BCM56865_DEVICE_ID:
   6762     case BCM56866_DEVICE_ID:
   6763     case BCM56867_DEVICE_ID:
   6764     case BCM56868_DEVICE_ID:
   6765     case BCM56836_DEVICE_ID:
   6766         *frequency = 793;
   6767         break;
   6768     case BCM56832_DEVICE_ID:
   6769         *frequency = 421;
   6770         break;
   6771     case BCM56833_DEVICE_ID:
   6772         *frequency = 537;
   6773         break;
   6774     case BCM56850_DEVICE_ID:
   6775     case BCM56852_DEVICE_ID:
   6776     case BCM56853_DEVICE_ID:
   6777     case BCM56855_DEVICE_ID:
   6778     case BCM56750_DEVICE_ID:
   6779     case BCM56830_DEVICE_ID:
   6780     case BCM56834_DEVICE_ID:
   6781         *frequency = rev_id < BCM56850_A2_REV_ID ? 760 : 793;
   6782         break;
   6783     case BCM56851_DEVICE_ID: /* Cannot handle 56851P */
   6784         if (skew_id == 2) { /* 56851P */
   6785             *frequency = rev_id < BCM56851_A2_REV_ID ? 518 : 537;
   6786         } else {
   6787             *frequency = rev_id < BCM56851_A2_REV_ID ? 608 : 635;
   6788         }
   6789         break;
   6790     case BCM56854_DEVICE_ID:
   6791         *frequency = rev_id < BCM56854_A2_REV_ID ? 608 : 635;
   6792         break;
   6793     default:
   6794         return SOC_E_INTERNAL;
   6795     }
   6796 
   6797     return SOC_E_NONE;
   6798 }
   6799 
   6800 STATIC int
   6801 soc_trident2_max_io_frequency_get(int unit,  uint16 dev_id, uint8 rev_id,
   6802                                int skew_id, int *iof)
   6803 {
   6804     int frequency;
   6805 
   6806     switch (dev_id) {
   6807     case BCM56860_DEVICE_ID:
   6808     case BCM56861_DEVICE_ID:
   6809     case BCM56866_DEVICE_ID:
   6810     case BCM56867_DEVICE_ID:
   6811     case BCM56868_DEVICE_ID:
   6812     case BCM56836_DEVICE_ID:
   6813         frequency = 1280000;
   6814         break;
   6815     case BCM56862_DEVICE_ID:
   6816     case BCM56865_DEVICE_ID:
   6817         frequency = 960000;
   6818         break;
   6819     case BCM56832_DEVICE_ID:
   6820     case BCM56833_DEVICE_ID:
   6821         frequency = 1080000;
   6822         break;
   6823     /*TD2*/
   6824     case BCM56850_DEVICE_ID:
   6825     case BCM56851_DEVICE_ID:
   6826     case BCM56853_DEVICE_ID:
   6827 	case BCM56855_DEVICE_ID:
   6828     case BCM56750_DEVICE_ID:
   6829     case BCM56834_DEVICE_ID:
   6830         frequency = 1280000;
   6831         break;
   6832     case BCM56830_DEVICE_ID:
   6833     case BCM56852_DEVICE_ID:
   6834         frequency = 960000;
   6835         break;
   6836     case BCM56854_DEVICE_ID:
   6837     case BCM56864_DEVICE_ID:
   6838         frequency = 720000;
   6839         break;
   6840     default:
   6841         return SOC_E_INTERNAL;
   6842     }
   6843 
   6844     *iof = frequency;
   6845 
   6846     return SOC_E_NONE;
   6847 }
   6848 
   6849 int
   6850 soc_trident2_tsc_map_get(int unit, uint32 *tsc_map)
   6851 {
   6852     uint16 dev_id;
   6853     uint8 rev_id;
   6854 
   6855     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
   6856 
   6857     switch (dev_id) {
   6858     case BCM56861_DEVICE_ID:
   6859     case BCM56865_DEVICE_ID:
   6860     case BCM56866_DEVICE_ID:
   6861     case BCM56867_DEVICE_ID:
   6862     case BCM56868_DEVICE_ID:
   6863     case BCM56860_DEVICE_ID:
   6864     case BCM56850_DEVICE_ID:
   6865     case BCM56851_DEVICE_ID:
   6866     case BCM56853_DEVICE_ID:
   6867     case BCM56855_DEVICE_ID:
   6868     case BCM56750_DEVICE_ID:
   6869     case BCM56834_DEVICE_ID:
   6870     case BCM56833_DEVICE_ID:
   6871     case BCM56836_DEVICE_ID:
   6872         *tsc_map = 0xffffffff;
   6873         break;
   6874     case BCM56862_DEVICE_ID:
   6875     case BCM56852_DEVICE_ID:
   6876     case BCM56830_DEVICE_ID:
   6877         *tsc_map = 0xe7e7e7ef;
   6878         break;
   6879     case BCM56854_DEVICE_ID:
   6880     case BCM56864_DEVICE_ID:
   6881         *tsc_map = 0x0f1ff8e8;
   6882         break;
   6883     case BCM56832_DEVICE_ID:
   6884         *tsc_map = 0xeff7efe7;
   6885         break;
   6886     default:
   6887         return SOC_E_INTERNAL;
   6888     }
   6889 
   6890     return SOC_E_NONE;
   6891 }
   6892 
   6893 typedef struct soc_td2_valid_fallback_lanes_s {
   6894     soc_100g_lane_config_t lane_config;
   6895     int                    valid_lanes[3];
   6896 }soc_td2_valid_fallback_lanes_t;
   6897 
   6898 const soc_td2_valid_fallback_lanes_t soc_td2_valid_lanes[] = {
   6899     {SOC_LANE_CONFIG_100G_4_4_2, {TRUE, TRUE, TRUE} },
   6900     {SOC_LANE_CONFIG_100G_3_4_3, {TRUE, TRUE, TRUE} },
   6901     {SOC_LANE_CONFIG_100G_2_4_4, {TRUE, TRUE, TRUE} },
   6902     {SOC_INVALID_LANE_CONFIG}
   6903 };
   6904 
   6905 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6906 /*
   6907  * Function:
   6908  *      _soc_td2p_lane_speed_valid_check
   6909  * Purpose:
   6910  *      Validates a given port speed against allowed
   6911  *      lane configuration. Checks for valid lane values too.
   6912  * Parameters:
   6913  *      unit       - (IN) Unit number.
   6914  *      lanes      - (IN) Number of lanes used by port
   6915  *      port_speed - (IN) Port Bandwidth of port.
   6916  *
   6917  * Returns:
   6918  *      SOC_E_XXX
   6919  */
   6920 STATIC int
   6921 _soc_td2p_lane_speed_valid_check(int unit, int lanes, int port_speed)
   6922 {
   6923     int rv = SOC_E_NONE;
   6924 
   6925     switch (lanes) {
   6926         case 1:
   6927             if (port_speed != SPEED_1G   && \
   6928                 port_speed != SPEED_2p5G && \
   6929                 port_speed != SPEED_10G  && \
   6930                 port_speed != SPEED_11G) {
   6931                     LOG_ERROR(BSL_LS_SOC_COMMON,
   6932                         (BSL_META_U(unit, "Invalid #lanes=(%d) "
   6933                                           "for Speed=(%d)\n"),
   6934                                           lanes, port_speed));
   6935                 rv = SOC_E_CONFIG;
   6936             }
   6937             break;
   6938         case 2:
   6939             if (port_speed != SPEED_10G  && \
   6940                 port_speed != SPEED_20G  && \
   6941                 port_speed != SPEED_21G) {
   6942                     LOG_ERROR(BSL_LS_SOC_COMMON,
   6943                         (BSL_META_U(unit, "Invalid #lanes=(%d) "
   6944                                           "for Speed=(%d)\n"),
   6945                                           lanes, port_speed));
   6946                 rv = SOC_E_CONFIG;
   6947             }
   6948             break;
   6949         case 4:
   6950             if (SOC_IS_TITAN2PLUS(unit) && \
   6951                 (port_speed == SPEED_13G || port_speed == SPEED_16G)){
   6952                 break;
   6953             }
   6954 
   6955             if (port_speed != SPEED_10G  && \
   6956                 port_speed != SPEED_20G  && \
   6957                 port_speed != SPEED_42G  && \
   6958                 port_speed != SPEED_40G  && \
   6959                 port_speed != SPEED_11G) {
   6960                     LOG_ERROR(BSL_LS_SOC_COMMON,
   6961                         (BSL_META_U(unit, "Invalid #lanes=(%d) "
   6962                                           "for Speed=(%d)\n"),
   6963                                           lanes, port_speed));
   6964                 rv = SOC_E_CONFIG;
   6965             }
   6966             break;
   6967         case 10:
   6968             if (port_speed != SPEED_100G  && \
   6969                 port_speed != SPEED_106G) {
   6970                     LOG_ERROR(BSL_LS_SOC_COMMON,
   6971                         (BSL_META_U(unit, "Invalid #lanes=(%d) "
   6972                                           "for Speed=(%d)\n"),
   6973                                           lanes, port_speed));
   6974                 rv = SOC_E_CONFIG;
   6975             }
   6976             break;
   6977         case 12:
   6978             if (port_speed != SPEED_127G) {
   6979                     LOG_ERROR(BSL_LS_SOC_COMMON,
   6980                         (BSL_META_U(unit, "Invalid #lanes=(%d) "
   6981                                           "for Speed=(%d)\n"),
   6982                                           lanes, port_speed));
   6983                 rv = SOC_E_CONFIG;
   6984             }
   6985             break;
   6986         default:
   6987             LOG_ERROR(BSL_LS_SOC_COMMON,
   6988                 (BSL_META_U(unit, "Invalid #lanes=(%d) specified\n"),
   6989                                   lanes));
   6990             rv = SOC_E_CONFIG;
   6991     }
   6992 
   6993     return rv;
   6994 }
   6995 #endif
   6996 
   6997 STATIC int
   6998 _soc_td2_port_speed_supported(int unit, soc_port_t port, int port_bandwidth)
   6999 {
   7000     int rv;
   7001     soc_pbmp_t my_pbmp_xport_xe;
   7002 
   7003     switch (port_bandwidth) {
   7004     case 1000:
   7005     case 10000:
   7006     case 15000:
   7007     case 20000:
   7008     case 30000:
   7009     case 40000:
   7010     case 100000:
   7011     case 120000:
   7012         rv = SOC_E_NONE;
   7013         break;
   7014     case 13000:
   7015     case 16000:
   7016         if (!SOC_IS_TITAN2PLUS(unit)) {
   7017             LOG_CLI((BSL_META_U(unit,
   7018                                 "Port %d: Invalid bandwidth %d Gb\n"),
   7019                      port, port_bandwidth / 1000));
   7020             rv = SOC_E_FAIL;
   7021             break;
   7022         }
   7023     case 11000:
   7024     case 21000:
   7025     case 42000:
   7026     case 106000:
   7027     case 127000:
   7028         SOC_PBMP_CLEAR(my_pbmp_xport_xe);
   7029         my_pbmp_xport_xe = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_XE,
   7030                                                          my_pbmp_xport_xe);
   7031         if (!SOC_PBMP_MEMBER(my_pbmp_xport_xe, port)) {
   7032             rv = SOC_E_NONE;
   7033         } else {
   7034             LOG_CLI((BSL_META_U(unit,
   7035                                 "Port %d: Invalid bandwidth %d Gb\n"),
   7036                      port, port_bandwidth / 1000));
   7037             rv = SOC_E_FAIL;
   7038         }
   7039         break;
   7040     default:
   7041         LOG_CLI((BSL_META_U(unit,
   7042                             "Port %d: Invalid bandwidth %d Gb\n"),
   7043                  port, port_bandwidth / 1000));
   7044         rv = SOC_E_FAIL;
   7045         break;
   7046     }
   7047     return rv;
   7048 }
   7049 
   7050 STATIC int
   7051 soc_trident2_port_inactive_port_check(int unit, uint32 blk_inactive_map,
   7052                                       int *blk_port, int *blk_port_bandwidth)
   7053 {
   7054 #define SOC_TRIDENT2_LANE0_MASK 0x1
   7055 #define SOC_TRIDENT2_LANE1_MASK 0x2
   7056 #define SOC_TRIDENT2_LANE2_MASK 0x4
   7057 #define SOC_TRIDENT2_LANE3_MASK 0x8
   7058     int rv = SOC_E_NONE;
   7059     int port, index;
   7060     soc_info_t *si;
   7061 
   7062     si = &SOC_INFO(unit);
   7063 
   7064     /* use ieee bandwidth */
   7065     for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
   7066         blk_port_bandwidth[index]
   7067             = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(blk_port_bandwidth[index]);
   7068     }
   7069     if(SOC_IS_TD2P_TT2P(unit)) {
   7070         if (blk_inactive_map & SOC_TRIDENT2_LANE0_MASK) {
   7071             /* Lane 0 is inactive */
   7072             LOG_CLI((BSL_META_U(unit,
   7073                                 "Port %d cannot be inactive\n"),
   7074                      blk_port[0]));
   7075             return SOC_E_FAIL;
   7076         } else {
   7077             /* Lane0 is active */
   7078             if (blk_inactive_map & SOC_TRIDENT2_LANE2_MASK) {
   7079                 if ((blk_inactive_map & SOC_TRIDENT2_LANE1_MASK) &&
   7080                     (blk_inactive_map & SOC_TRIDENT2_LANE3_MASK)) {
   7081                     return SOC_E_NONE;
   7082                 } else {
   7083                     LOG_CLI((BSL_META_U(unit,
   7084                                         "Port %d can be inactive if "
   7085                                         "lane 1,2,3 are inactive\n"),
   7086                              blk_port[0]));
   7087                     return SOC_E_FAIL;
   7088                 }
   7089             } else {
   7090                 /* Both Lane0 & Lane2 are active */
   7091                 port = blk_port[0];
   7092                 if (blk_inactive_map & SOC_TRIDENT2_LANE1_MASK) {
   7093                     if (blk_port_bandwidth[0] < blk_port_bandwidth[1] * 2) {
   7094                         LOG_CLI((BSL_META_U(unit,
   7095                                             "Port %d bandwidth %d Gb is not "
   7096                                             "enough to cover flex port for "
   7097                                             "port %d\n"),
   7098                                  port, si->port_speed_max[port] / 1000,
   7099                                  blk_port[1]));
   7100                         return SOC_E_FAIL;
   7101                     }
   7102                 }
   7103 
   7104                 port = blk_port[2];
   7105                 if (blk_inactive_map & SOC_TRIDENT2_LANE3_MASK) {
   7106                     if (blk_port_bandwidth[2] < blk_port_bandwidth[3] * 2) {
   7107                         LOG_CLI((BSL_META_U(unit,
   7108                                             "Port %d bandwidth %d Gb is not "
   7109                                             "enough to cover flex port for "
   7110                                             "port %d\n"),
   7111                                  port, si->port_speed_max[port] / 1000,
   7112                                  blk_port[3]));
   7113                         return SOC_E_FAIL;
   7114                     }
   7115                 }
   7116             }
   7117         }
   7118     } else {
   7119         port = blk_port[2];
   7120         if (port != -1) {
   7121             /* Check reserved bandwidth if lane 3 is inactive flex
   7122              * port and lane 2 is active */
   7123             if ((blk_inactive_map & 0x0c) == 0x08 &&
   7124                 blk_port_bandwidth[2] <
   7125                 blk_port_bandwidth[3] * 2) {
   7126                 LOG_CLI((BSL_META_U(unit,
   7127                                     "Port %d bandwidth %d Gb is not "
   7128                                     "enough to cover flex port for "
   7129                                     "port %d\n"),
   7130                          port, si->port_speed_max[port] / 1000,
   7131                          blk_port[3]));
   7132                 rv = SOC_E_FAIL;
   7133             }
   7134         }
   7135 
   7136         port = blk_port[0];
   7137         if (port != -1) {
   7138             /* Check reserved bandwidth if lane 3 is inactive flex
   7139              * port and lane 0 is active */
   7140             if ((blk_inactive_map & 0x09) == 0x08 &&
   7141                 blk_port_bandwidth[0] <
   7142                 blk_port_bandwidth[3] * 4) {
   7143                 LOG_CLI((BSL_META_U(unit,
   7144                                     "Port %d bandwidth %d Gb is not "
   7145                                     "enough to cover flex port for "
   7146                                     "port %d\n"),
   7147                          port, si->port_speed_max[port] / 1000,
   7148                          blk_port[3]));
   7149                 rv = SOC_E_FAIL;
   7150             }
   7151 
   7152             /* Check reserved bandwidth if lane 2 is inactive flex
   7153              * port and lane 0 is active */
   7154             if ((blk_inactive_map & 0x05) == 0x04 &&
   7155                 blk_port_bandwidth[0] <
   7156                 blk_port_bandwidth[2] * 2) {
   7157                 LOG_CLI((BSL_META_U(unit,
   7158                                     "Port %d bandwidth %d Gb is not "
   7159                                     "enough to cover flex port for "
   7160                                     "port %d\n"),
   7161                          port, si->port_speed_max[port] / 1000,
   7162                          blk_port[2]));
   7163                 rv = SOC_E_FAIL;
   7164             }
   7165 
   7166             /* Check reserved bandwidth if lane 1 is inactive flex
   7167              * port and lane 0 is active */
   7168             if ((blk_inactive_map & 0x03) == 0x02 &&
   7169                 blk_port_bandwidth[0] <
   7170                 blk_port_bandwidth[1] * 4) {
   7171                 LOG_CLI((BSL_META_U(unit,
   7172                                     "Port %d bandwidth %d Gb is not "
   7173                                     "enough to cover flex port for "
   7174                                     "port %d\n"),
   7175                          port, si->port_speed_max[port] / 1000,
   7176                          blk_port[1]));
   7177                 rv = SOC_E_FAIL;
   7178             }
   7179         }
   7180     }
   7181 
   7182     return rv;
   7183 }
   7184 
   7185 /*
   7186  * Function:
   7187  *      soc_trident2_soc_info_misc_t_init
   7188  * Purpose:
   7189  *      Initialize soc_info_misc_t structure by the current SOC_INFO(unit).
   7190  * Parameters:
   7191  *      unit - StrataSwitch Unit #.
   7192  *      si_m - soc_info_misc data
   7193  * Note:
   7194  *      port_speed is initialized by si->port_speed_max
   7195  */
   7196 void
   7197 soc_trident2_soc_info_misc_t_init(int unit, soc_info_misc_t *si_m)
   7198 {
   7199     soc_info_t *si = &SOC_INFO(unit);
   7200     int i;
   7201     int logic_port;
   7202     int phy_port;
   7203 
   7204     sal_memset(si_m, 0, sizeof(*si_m));
   7205 
   7206     /* Get current information */
   7207     for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   7208         si_m->port_l2p_mapping[i] = si->port_l2p_mapping[i];
   7209         si_m->port_p2l_mapping[i] = si->port_p2l_mapping[i];
   7210         si_m->port_speed_max[i] = si->port_speed_max[i];
   7211         si_m->port_num_lanes[i] = si->port_num_lanes[i];
   7212         si_m->port_speed[i] = -1;
   7213         si_m->port_encap[i] = -1;
   7214 
   7215         logic_port = i;
   7216         phy_port = si->port_l2p_mapping[logic_port];
   7217 
   7218         /* Skip ports not defined, LB, CPU, etc. */
   7219         /* coverity[overrun-local] */
   7220         if (!SOC_PORT_ADDRESSABLE(unit, logic_port) ||
   7221             !((phy_port >= 0) && (phy_port <= TRIDENT2_PHY_PORT_MAX)) ||
   7222             IS_LB_PORT(unit, logic_port) ||
   7223             IS_CPU_PORT (unit, logic_port)) {
   7224             continue;
   7225         }
   7226 
   7227         si_m->port_speed[logic_port] = si->port_speed_max[logic_port];
   7228 
   7229         /*
   7230          * Get encapsulation mode
   7231          *
   7232          * Validate need to differentiate between HG and non-HG modes,
   7233          * so using SOC_ENCAP_HIGIG2 and SOC_ENCAP_IEEE will suffice
   7234          * to indicate HG vs non-HG.
   7235          */
   7236         /* coverity[overrun-local] */
   7237         if (IS_HG_PORT(unit, logic_port)) {
   7238             si_m->port_encap[logic_port] = SOC_ENCAP_HIGIG2;
   7239         } else {
   7240             si_m->port_encap[logic_port] = SOC_ENCAP_IEEE;
   7241         }
   7242     }
   7243     si_m->bandwidth = si->bandwidth;
   7244     SOC_PBMP_ASSIGN(si_m->oversub_pbm, si->oversub_pbm);
   7245     SOC_PBMP_ASSIGN(si_m->disabled_bitmap, si->all.disabled_bitmap);
   7246     SOC_PBMP_ASSIGN(si_m->management_pbm, si->management_pbm);
   7247 
   7248     return;
   7249 }
   7250 
   7251 /*
   7252  * Function:
   7253  *      soc_trident2_port_bandwidth_validate
   7254  * Purpose:
   7255  *      Validate the pgw port bandwidth
   7256  * --------------------------------------------
   7257  * | Frequency | Linerate bandwidth per quad  |
   7258  * | 480MHz    | 120G                         |
   7259  * | 640MHz    | 160G                         |
   7260  * | 720MHz    | Quad X-0 [port 1-32]  : 160G |
   7261  * |           | Quad X-1 [port 33-64] : 200G |
   7262  * |           | Quad Y-0 [port 65-96] : 200G |
   7263  * |           | Quad Y-1 [port 97-128]: 160G |
   7264  * | 760MHz    | 240G                         |
   7265  * --------------------------------------------
   7266  * Parameters:
   7267  *      unit - StrataSwitch Unit #.
   7268  *      si_m - soc_info_misc data
   7269  * Returns:
   7270  *      SOC_E_NONE
   7271  *      SOC_E_FAIL
   7272  */
   7273 int
   7274 soc_trident2_port_bandwidth_validate(int unit, soc_info_misc_t *si_m)
   7275 {
   7276     int rv = SOC_E_NONE;
   7277     int pipe, quad, pgw, blk;
   7278     int blk_linerate_bandwidth, blk_oversub_bandwidth;
   7279     int pgw_linerate_bandwidth, pgw_oversub_bandwidth;
   7280     int quad_linerate_bandwidth, quad_oversub_bandwidth;
   7281     int max_quad_core_bandwidth[_TD2_QUADS_PER_DEV];
   7282     int port_bandwidth;
   7283     uint32 blk_configured_map;
   7284     uint32 blk_management_map, blk_inactive_map, blk_oversub_map;
   7285     int port, phy_port;
   7286     int lane_count;
   7287     int index;
   7288     int pgw_port[_TD2_PORTS_PER_PGW], *blk_port;
   7289     int pgw_port_bandwidth[_TD2_PORTS_PER_PGW], *blk_port_bandwidth;
   7290     int i;
   7291 
   7292     /* Setup max bandwidth for each per quadrant */
   7293     if (si_m->bandwidth == 720000) {
   7294         max_quad_core_bandwidth[0] = max_quad_core_bandwidth[3] = 160000;
   7295         max_quad_core_bandwidth[1] = max_quad_core_bandwidth[2] = 200000;
   7296     } else {
   7297         for (quad = 0; quad < _TD2_QUADS_PER_DEV; quad++) {
   7298             max_quad_core_bandwidth[quad] = si_m->bandwidth / 4;
   7299         }
   7300     }
   7301 
   7302     /* Bandwidth check for ports in each XLPORT/CPORT block */
   7303     for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
   7304         for (quad = 0; quad < _TD2_QUADS_PER_PIPE; quad++) {
   7305             quad_linerate_bandwidth = 0;
   7306             quad_oversub_bandwidth = 0;
   7307             for (pgw = 0; pgw < _TD2_PGWS_PER_QUAD; pgw++) {
   7308                 pgw_linerate_bandwidth = 0;
   7309                 pgw_oversub_bandwidth = 0;
   7310 
   7311                 /* Prepare per PGW local variables for ease of processing */
   7312                 for (index = 0; index < _TD2_PORTS_PER_PGW; index++) {
   7313                     phy_port = 1 + pipe * _TD2_PORTS_PER_PIPE +
   7314                         quad * _TD2_PORTS_PER_QUAD +
   7315                         pgw * _TD2_PORTS_PER_PGW + index;
   7316                     port = si_m->port_p2l_mapping[phy_port];
   7317                     pgw_port[index] = port;
   7318                     if (port == -1) {
   7319                         pgw_port_bandwidth[index] = 0;
   7320                     } else if (si_m->port_speed_max[port] < 2500) {
   7321                         pgw_port_bandwidth[index] = 2500;
   7322                     } else {
   7323                         pgw_port_bandwidth[index] = si_m->port_speed_max[port];
   7324                     }
   7325                 }
   7326 
   7327                 for (blk = 0; blk < _TD2_XLPS_PER_PGW; blk++) {
   7328                     blk_port = &pgw_port[blk * _TD2_PORTS_PER_XLP];
   7329                     blk_port_bandwidth =
   7330                         &pgw_port_bandwidth[blk * _TD2_PORTS_PER_XLP];
   7331                     blk_configured_map = 0;
   7332                     for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
   7333                         if (blk_port[index] != -1) {
   7334                             blk_configured_map |= 1 << index;
   7335                         }
   7336                     }
   7337                     if (blk_configured_map == 0) {
   7338                         continue;
   7339                     }
   7340 
   7341                     /* Management port block (XLPORT3) handling */
   7342                     if (pipe == 0 && quad == 0 && pgw == 0 && blk == 3 &&
   7343                         SOC_PBMP_NOT_NULL(si_m->management_pbm)) {
   7344                         blk_management_map = 0;
   7345                         for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
   7346                             port = blk_port[index];
   7347                             if (port == -1) {
   7348                                 continue;
   7349                             }
   7350                             if (SOC_PBMP_MEMBER(si_m->management_pbm, port)) {
   7351                                 blk_management_map |= 1 << index;
   7352                             }
   7353                         }
   7354                         if (blk_management_map != blk_configured_map) {
   7355                             LOG_CLI((BSL_META_U(unit,
   7356                                                 "Port")));
   7357                             for (index = 0; index < _TD2_PORTS_PER_XLP;
   7358                                  index++) {
   7359                                 if (blk_port[index] != -1) {
   7360                                     LOG_CLI((BSL_META_U(unit,
   7361                                                         " %d"), blk_port[index]));
   7362                                 }
   7363                             }
   7364                             LOG_CLI((BSL_META_U(unit,
   7365                                                 ": Can not be configured to "
   7366                                                 "different management port status\n")));
   7367                             rv = SOC_E_FAIL;
   7368                             continue;
   7369                         }
   7370 
   7371                         for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
   7372                             port = blk_port[index];
   7373                             if (port == -1) {
   7374                                 continue;
   7375                             }
   7376                             phy_port = si_m->port_l2p_mapping[port];
   7377                             port_bandwidth = blk_port_bandwidth[index];
   7378                             if (port_bandwidth > 10000 ||
   7379                                 (port_bandwidth > 2500 && index != 0)) {
   7380                                 LOG_CLI((BSL_META_U(unit,
   7381                                                     "Management port %d: "
   7382                                                     "Physical port %d can not be "
   7383                                                     "configured to %d Gb\n"),
   7384                                          port, phy_port,
   7385                                          port_bandwidth / 1000));
   7386                                 rv = SOC_E_FAIL;
   7387                                 continue;
   7388                             }
   7389                         }
   7390                         port_bandwidth = blk_port_bandwidth[0];
   7391                         if (port_bandwidth > 2500) {
   7392                             for (index = 1; index < _TD2_PORTS_PER_XLP;
   7393                                  index++) {
   7394                                 port = blk_port[index];
   7395                                 if (port == -1) {
   7396                                     continue;
   7397                                 }
   7398                                 LOG_CLI((BSL_META_U(unit,
   7399                                                     "Management port %d bandwidth %d "
   7400                                                     "Gb and port %d can not be both "
   7401                                                     "configured\n"),
   7402                                          blk_port[0],
   7403                                          port_bandwidth / 1000, port));
   7404                                 rv = SOC_E_FAIL;
   7405                             }
   7406                         }
   7407                         continue;
   7408                     }
   7409 
   7410                     /* Normal port block handling */
   7411                     blk_inactive_map = 0;
   7412                     blk_oversub_map = 0;
   7413                     blk_linerate_bandwidth = 0;
   7414                     blk_oversub_bandwidth = 0;
   7415                     for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
   7416                         int real_port_bandwidth;
   7417 
   7418                         port = blk_port[index];
   7419                         if (port == -1) {
   7420                             continue;
   7421                         }
   7422                         port_bandwidth = blk_port_bandwidth[index];
   7423                         real_port_bandwidth = port_bandwidth;
   7424                         if (SOC_PBMP_MEMBER(si_m->oversub_pbm, port)) {
   7425                             blk_oversub_map |= 1 << index;
   7426                         }
   7427                         if (SOC_PBMP_MEMBER(si_m->disabled_bitmap, port)) {
   7428                             blk_inactive_map |= 1 << index;
   7429                         } else {
   7430                             /* 13G/16G uses 21G bandwidth */
   7431                             if (SOC_IS_TITAN2PLUS(unit) &&
   7432                                 ((port_bandwidth == 13000) ||
   7433                                  (port_bandwidth == 16000))) {
   7434                                 real_port_bandwidth = 21000;
   7435                             }
   7436                             if (blk_oversub_map & (1 << index)) {
   7437                                 blk_oversub_bandwidth += real_port_bandwidth;
   7438                             } else {
   7439                                 blk_linerate_bandwidth += real_port_bandwidth;
   7440                             }
   7441                         }
   7442                         if ((port_bandwidth > 42000 &&
   7443                              (index != 0 || blk != (pgw & 1))) ||
   7444                             (port_bandwidth > 21000 && index != 0) ||
   7445                             (SOC_IS_TITAN2PLUS(unit) &&
   7446                             ((port_bandwidth == 13000 && index != 0) ||
   7447                             (port_bandwidth == 16000 && index != 0))) ||
   7448                             (port_bandwidth > 11000 && (index & 1))) {
   7449                             LOG_CLI((BSL_META_U(unit,
   7450                                                 "Port %d: Physical port %d can not "
   7451                                                 "be configured to %d Gb\n"),
   7452                                      port, si_m->port_l2p_mapping[port],
   7453                                      port_bandwidth / 1000));
   7454                             rv = SOC_E_FAIL;
   7455                         }
   7456 
   7457                         /*
   7458                          * max_quad_core_bandwidth is 240G(= 960/4).
   7459                          * If port is defined HG11,HG21,HG42,HG106,HG127, then
   7460                          * max_quad_core_bandwidth needs to be adjusted to
   7461                          * accept HG speed. */
   7462                         i = pipe * _TD2_QUADS_PER_PIPE + quad;
   7463                         if (real_port_bandwidth == 127000) {
   7464                             max_quad_core_bandwidth[i] += 7000;
   7465                         } else if (real_port_bandwidth == 106000) {
   7466                             max_quad_core_bandwidth[i] += 6000;
   7467                         } else if (real_port_bandwidth == 42000) {
   7468                             max_quad_core_bandwidth[i] += 2000;
   7469                         } else if (real_port_bandwidth == 21000) {
   7470                             max_quad_core_bandwidth[i] += 1000;
   7471                         } else if (real_port_bandwidth == 11000) {
   7472                             max_quad_core_bandwidth[i] += 1000;
   7473                         }
   7474                     }
   7475 
   7476                     /* Check if any the lanes used by first port of block is
   7477                      * not used by other port */
   7478                     port_bandwidth = blk_port_bandwidth[0];
   7479                     if (port_bandwidth > 42000) {
   7480                         if (blk != (pgw & 1)) {
   7481                             continue;
   7482                         }
   7483                         lane_count = 12;
   7484                     } else if ((port_bandwidth > 21000) ||
   7485                                 (SOC_IS_TITAN2PLUS(unit) &&
   7486                                  ((port_bandwidth == 13000) ||
   7487                                   (port_bandwidth == 16000)))) {
   7488                         lane_count = 4;
   7489                     } else if (port_bandwidth > 11000) {
   7490                         lane_count = 2;
   7491                     } else {
   7492                         lane_count = 1;
   7493                     }
   7494                     for (index = 1; index < lane_count; index++) {
   7495                         port = blk_port[index];
   7496                         if (port == -1 ||
   7497                             SOC_PBMP_MEMBER(si_m->disabled_bitmap, port)) {
   7498                             continue;
   7499                         }
   7500                         LOG_CLI((BSL_META_U(unit,
   7501                                             "Port %d bandwidth %d Gb and "
   7502                                             "port %d can not be both configured\n"),
   7503                                  blk_port[0], port_bandwidth / 1000, port));
   7504                         rv = SOC_E_FAIL;
   7505                     }
   7506 
   7507                     /* Check if any the lanes used by third port of block is
   7508                      * not used by other port */
   7509                     port_bandwidth = blk_port_bandwidth[2];
   7510                     if (port_bandwidth > 11000) {
   7511                         port = blk_port[3];
   7512                         if (port != -1 &&
   7513                             !SOC_PBMP_MEMBER(si_m->disabled_bitmap, port)) {
   7514                             LOG_CLI((BSL_META_U(unit,
   7515                                                 "Port %d bandwidth %d Gb and port %d "
   7516                                                 "can not be both configured\n"),
   7517                                      blk_port[2], port_bandwidth / 1000,
   7518                                      port));
   7519                             rv = SOC_E_FAIL;
   7520                         }
   7521                         if (blk_port[0] == -1) {
   7522                             LOG_CLI((BSL_META_U(unit,
   7523                                                 "Physical port %d needs to be "
   7524                                                 "configured in order to work with "
   7525                                                 "port %d\n"),
   7526                                      1 + pipe * _TD2_PORTS_PER_PIPE +
   7527                                      pgw * _TD2_PORTS_PER_PGW +
   7528                                      blk * _TD2_PORTS_PER_XLP,
   7529                                      blk_port[2]));
   7530                             rv = SOC_E_FAIL;
   7531                         }
   7532                     }
   7533 
   7534                     if (blk_inactive_map == blk_configured_map) {
   7535                         LOG_CLI((BSL_META_U(unit,
   7536                                             "Flex port")));
   7537                         for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
   7538                             if (blk_port[index] != -1) {
   7539                                 LOG_CLI((BSL_META_U(unit,
   7540                                                     " %d"), blk_port[index]));
   7541                             }
   7542                         }
   7543                         LOG_CLI((BSL_META_U(unit,
   7544                                             ": Can not be all inactive\n")));
   7545                         rv = SOC_E_FAIL;
   7546                         continue;
   7547                     }
   7548 
   7549                     if (blk_oversub_map != 0 &&
   7550                         blk_oversub_map != blk_configured_map) {
   7551                         /*
   7552                          * Check whether user mixed line-rate and
   7553                          * oversubscription ports together within a TSC
   7554                          */
   7555                         LOG_CLI((BSL_META_U(unit,
   7556                                             "%s"),
   7557                                  blk_inactive_map ? "Flex port" : "Port"));
   7558                         for (index = 0; index < _TD2_PORTS_PER_XLP;
   7559                              index++) {
   7560                             if (blk_port[index] != -1) {
   7561                                 LOG_CLI((BSL_META_U(unit,
   7562                                                     " %d"), blk_port[index]));
   7563                             }
   7564                         }
   7565                         LOG_CLI((BSL_META_U(unit,
   7566                                             ": Can not be configured to "
   7567                                             "different oversubscription "
   7568                                             "status\n")));
   7569                         rv = SOC_E_FAIL;
   7570                         continue;
   7571                     }
   7572 
   7573                     SOC_IF_ERROR_RETURN(
   7574                         soc_trident2_port_inactive_port_check(unit,
   7575                                 blk_inactive_map, blk_port, blk_port_bandwidth));
   7576 
   7577                     pgw_linerate_bandwidth += blk_linerate_bandwidth;
   7578                     pgw_oversub_bandwidth += blk_oversub_bandwidth;
   7579                 } /* for (blk = 0; blk < _TD2_XLPS_PER_PGW; blk++) */
   7580                 quad_linerate_bandwidth += pgw_linerate_bandwidth;
   7581                 quad_oversub_bandwidth += pgw_oversub_bandwidth;
   7582             } /* for (pgw = 0; pgw < _TD2_PGWS_PER_QUAD; pgw++) */
   7583 
   7584             index = pipe * _TD2_QUADS_PER_PIPE + quad;
   7585             if (quad_linerate_bandwidth > max_quad_core_bandwidth[index]) {
   7586                 LOG_CLI((BSL_META_U(unit,
   7587                                     "PGW_CL%d and PGW_CL%d total line rate bandwidth "
   7588                                     "(%d Gb) exceeds %d Gb\n"),
   7589                          pipe * _TD2_PGWS_PER_PIPE +
   7590                          quad * _TD2_PGWS_PER_QUAD,
   7591                          pipe * _TD2_PGWS_PER_PIPE +
   7592                          quad * _TD2_PGWS_PER_QUAD + 1,
   7593                          quad_linerate_bandwidth / 1000,
   7594                          max_quad_core_bandwidth[index] / 1000));
   7595                 rv = SOC_E_FAIL;
   7596             } else if (quad_linerate_bandwidth ==
   7597                        max_quad_core_bandwidth[index] &&
   7598                        quad_oversub_bandwidth != 0) {
   7599                 LOG_CLI((BSL_META_U(unit,
   7600                                     "PGW_CL%d and PGW_CL%d total line rate bandwidth "
   7601                                     "(%d Gb) equals to max core bandwidth, no extra "
   7602                                     "bandwidth for oversubscription ports\n"),
   7603                          pipe * _TD2_PGWS_PER_PIPE +
   7604                          quad * _TD2_PGWS_PER_QUAD,
   7605                          pipe * _TD2_PGWS_PER_PIPE +
   7606                          quad * _TD2_PGWS_PER_QUAD + 1,
   7607                          quad_linerate_bandwidth / 1000));
   7608                 rv = SOC_E_FAIL;
   7609             } else if (quad_oversub_bandwidth >
   7610                        (max_quad_core_bandwidth[index] -
   7611                         quad_linerate_bandwidth) * 2) {
   7612                 LOG_CLI((BSL_META_U(unit,
   7613                                     "PGW_CL%d and PGW_CL%d total I/O "
   7614                                     "oversubscription bandwidth (%d Gb) is more than "
   7615                                     "2 times of core oversubscription bandwidth "
   7616                                     "(2 * %d Gb)\n"),
   7617                          pipe * _TD2_PGWS_PER_PIPE +
   7618                          quad * _TD2_PGWS_PER_QUAD,
   7619                          pipe * _TD2_PGWS_PER_PIPE +
   7620                          quad * _TD2_PGWS_PER_QUAD + 1,
   7621                          quad_oversub_bandwidth / 1000,
   7622                          (max_quad_core_bandwidth[index] -
   7623                          quad_linerate_bandwidth) / 1000));
   7624                 rv = SOC_E_FAIL;
   7625             }
   7626         } /* for (quad = 0; quad < _TD2_QUADS_PER_PIPE; quad++) */
   7627     } /* for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) */
   7628 
   7629     return rv;
   7630 }
   7631 
   7632 #define SOC_TD2_NUM_LPORT       (106)
   7633 #define SOC_TD2_NUM_PHY_PORT    (130)
   7634 #define SOC_TD2_NUM_MMU_PORT    (117) /* mmu port 53 to 63 are not used */
   7635 /* cpu port is logical port 0, physical port 0, mmu port 0 */
   7636 #define SOC_TD2_CPU_LPORT       (0)
   7637 #define SOC_TD2_CPU_PHY_PORT    (0)
   7638 #define SOC_TD2_CPU_MMU_PORT    (52)
   7639 /* loopback port is logical port 105, physical port 129, mmu port 116 */
   7640 #define SOC_TD2_LB_LPORT        (105)
   7641 #define SOC_TD2_LB_PHY_PORT     (129)
   7642 #define SOC_TD2_LB_MMU_PORT     (116)
   7643 
   7644 static int port_count[_TD2_PIPES_PER_DEV];
   7645 static uint32 tsc_map = 0;
   7646 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   7647 static uint32 clmac_tsc_map = 0;
   7648 soc_logical_to_ifp_port_mapping_t soc_td2p_log_to_ifp_port[SOC_MAX_NUM_DEVICES];
   7649 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   7650 
   7651 /*
   7652  * Function:
   7653  *      soc_trident2_port_portmap_parse
   7654  * Description:
   7655  *      Parse portmap soc property and fill out all output information
   7656  *      to soc_pmap_info_t pmap
   7657  * Parameters:
   7658  *      unit          - Device number
   7659  *      port          - Logical port number
   7660  *      pmap          - soc_pmap_info_t
   7661  */
   7662 int
   7663 soc_trident2_port_portmap_parse(int unit, soc_port_t port,
   7664                                 soc_pmap_info_t *pmap)
   7665 {
   7666     soc_info_t *si = &SOC_INFO(unit);
   7667     char *config_str, *sub_str, *sub_str_end;
   7668     static const char str_2p5[] = "2.5";
   7669     static const char str_osg[] = "OSG.";
   7670     int osg_cnt, osg_str_cnt; /* Oversub Speed Group count and string count */
   7671     char str_buf[8];
   7672     int phy_port, port_bandwidth;
   7673     soc_100g_lane_config_t lane_config;
   7674     int fallback_lane = SOC_LANE_CONFIG_100G_DEFAULT;
   7675     int pipe;
   7676     int tsc_id;
   7677     int num_lanes = -1;
   7678     int rv, i, index;
   7679 
   7680     config_str = soc_property_port_get_str(unit, port, spn_PORTMAP);
   7681     if (config_str == NULL) {
   7682         return SOC_E_NOT_FOUND;
   7683     }
   7684 
   7685     /*
   7686      * portmap.<port>=<physical port number>:<bandwidth in Gb>:<OSG.0xf>:
   7687      * <100G TSC lanes>:<100G Fallback XLMAC>:<i> | <m|l:lanes>
   7688      *
   7689      * If the port config ends with 'i', the port is not enabled, but can
   7690      * be enabled later as a flexport.
   7691      */
   7692     sub_str = config_str;
   7693 
   7694     /* Parse physical port number */
   7695     phy_port = sal_ctoi(sub_str, &sub_str_end);
   7696     if (sub_str == sub_str_end) {
   7697         LOG_CLI((BSL_META_U(unit,
   7698                             "Port %d: Missing physical port information \"%s\"\n"),
   7699                  port, config_str));
   7700         return SOC_E_FAIL;
   7701     }
   7702     if (phy_port < 1 || phy_port > (SOC_TD2_NUM_PHY_PORT - 2)) {
   7703         LOG_CLI((BSL_META_U(unit,
   7704                             "Port %d: Invalid physical port number %d\n"),
   7705                  port, phy_port));
   7706         return SOC_E_FAIL;
   7707     }
   7708     tsc_id = (phy_port - 1) / 4;
   7709     if (!(tsc_map & (1 << tsc_id))) {
   7710         LOG_CLI((BSL_META_U(unit,
   7711                             "Port %d: Physical port %d is in disabled TSC %d\n"),
   7712                  port, phy_port, tsc_id));
   7713         return SOC_E_FAIL;
   7714     }
   7715     pipe = phy_port < si->phy_port_base[1] ? 0 : 1;
   7716     if (port_count[pipe] >= SOC_TD2_NUM_LPORT / 2 - 1) {
   7717         LOG_CLI((BSL_META_U(unit,
   7718                             "Can not configure more than %d port in "
   7719                             "%c pipeline\n"), SOC_TD2_NUM_LPORT / 2 - 1,
   7720                  pipe ? 'Y' : 'X'));
   7721         return SOC_E_FAIL;
   7722     }
   7723 
   7724     /* Skip ':' between physical port number and bandwidth */
   7725     sub_str = sub_str_end;
   7726     if (*sub_str != '\0') {
   7727         if (*sub_str != ':') {
   7728             LOG_CLI((BSL_META_U(unit,
   7729                                 "Port %d: Bad config string \"%s\"\n"),
   7730                      port, config_str));
   7731             return SOC_E_FAIL;
   7732         }
   7733         sub_str++;
   7734     }
   7735 
   7736     /* Parse bandwidth */
   7737     for (index = 0; index < sizeof(str_2p5) - 1; index++) {
   7738         if (sub_str[index] == '\0') {
   7739             break;
   7740         }
   7741         str_buf[index] = sub_str[index];
   7742     }
   7743     str_buf[index] = '\0';
   7744     if (!sal_strcmp(str_buf, str_2p5)) {
   7745         port_bandwidth = 2500;
   7746         sub_str_end = &sub_str[sizeof(str_2p5) - 1];
   7747     } else {
   7748         port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000;
   7749         if (sub_str == sub_str_end) {
   7750             LOG_CLI((BSL_META_U(unit,
   7751                                 "Port %d: Missing bandwidth information \"%s\"\n"),
   7752                      port, config_str));
   7753             return SOC_E_FAIL;
   7754         }
   7755 
   7756         rv = _soc_td2_port_speed_supported(unit, port, port_bandwidth);
   7757         if (SOC_FAILURE(rv)) {
   7758             return SOC_E_FAIL;
   7759         }
   7760 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   7761         if (SOC_IS_TRIDENT2PLUS(unit)) {
   7762             if (soc_feature(unit, soc_feature_clmac)
   7763                 && soc_feature(unit, soc_feature_clmac_partial_support)) {
   7764                 if (port_bandwidth >= 100000
   7765                     && !(clmac_tsc_map & (1 << tsc_id))) {
   7766                         LOG_CLI((BSL_META_U(unit,
   7767                                 "Port %d: TSC %d does not support CMAC("
   7768                                 "port speed >=100G) for the given SKU.\n"),
   7769                                 port, tsc_id));
   7770                         return SOC_E_FAIL;
   7771                 }
   7772             }
   7773         }
   7774 #endif
   7775     }
   7776     /* Skip ':' between Bandwidth and OSG */
   7777     sub_str = sub_str_end;
   7778     if (*sub_str != '\0') {
   7779         if (*sub_str != ':') {
   7780             LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_U(unit,
   7781                       "Port %d: Bad config string \"%s\"\n"),
   7782                       port, config_str));
   7783             return SOC_E_FAIL;
   7784         }
   7785         sub_str_end++;
   7786     }
   7787 
   7788 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   7789     if (SOC_IS_TD2P_TT2P(unit)) {
   7790         int oversub;
   7791         if (SOC_FAILURE
   7792             (soc_td2p_port_oversub_get(unit, phy_port, port,
   7793                                        &oversub))) {
   7794             LOG_ERROR(BSL_LS_SOC_PORT,
   7795                       (BSL_META_U(unit,
   7796                                   "Port %d: Cannot get oversub mode\n"),
   7797                        port));
   7798             return SOC_E_FAIL;
   7799         }
   7800         if (oversub) {
   7801             SOC_PBMP_PORT_ADD(pmap->oversub_pbm, port);
   7802         }
   7803     }
   7804 #endif
   7805 
   7806     /* All OSGs are availiable by default */
   7807     osg_cnt = GET_MMU_OVS_GCOUNT(unit);
   7808     if (SOC_PBMP_MEMBER(pmap->oversub_pbm, port)) {
   7809         si->port_osg_bitmap[phy_port] = (1 << osg_cnt) - 1;
   7810     }
   7811 
   7812     /*Read OSG configuration.  skip if options are present*/
   7813     sub_str = sub_str_end;
   7814     if (*sub_str != '\0' && (*sub_str != 'm' &&
   7815                              *sub_str != 'i' && *sub_str != 'l')) {
   7816         /* OSG.0xf <=> OSG.  0x  f*/
   7817         osg_str_cnt = sal_strlen(str_osg) + 2 + (osg_cnt + 3) / 4;
   7818         for (index = 0; index < osg_str_cnt; index++) {
   7819             if (sub_str[index] == '\0') {
   7820                 break;
   7821             }
   7822             str_buf[index] = sub_str[index];
   7823         }
   7824         str_buf[index] = '\0';
   7825         if (!sal_strncmp(str_buf, str_osg, sal_strlen(str_osg))) {
   7826             if (!SOC_PBMP_MEMBER(pmap->oversub_pbm, port)) {
   7827                 LOG_CLI((BSL_META_U(unit,
   7828                          "Port %d: Bad config string \"%s\"\n"),
   7829                          port, config_str));
   7830                 return SOC_E_FAIL;
   7831             }
   7832             sub_str += sal_strlen(str_osg);
   7833             si->port_osg_bitmap[phy_port] =
   7834                         sal_ctoi(sub_str, &sub_str_end);
   7835             if (sub_str == sub_str_end) {
   7836                 LOG_CLI((BSL_META_U(unit,
   7837                          "Port %d: Missing OSG bitmap information \"%s\"\n"),
   7838                          port, config_str));
   7839                 return SOC_E_FAIL;
   7840             }
   7841             si->port_osg_bitmap[phy_port] &= (1 << osg_cnt) - 1;
   7842 
   7843             if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   7844                 LOG_CLI((BSL_META_U(unit,
   7845                          "Port %d OSG bitmap: 0x%x\n"),
   7846                          port, si->port_osg_bitmap[phy_port]));
   7847             }
   7848             sub_str_end = &sub_str[osg_str_cnt - sal_strlen(str_osg)]; /*Advance */
   7849 
   7850             /* Skip ':' between OSG and 100G lane config */
   7851             sub_str = sub_str_end;
   7852             if (*sub_str != '\0') {
   7853                 if (*sub_str != ':') {
   7854                     LOG_CLI((BSL_META_U(unit,
   7855                                         "Port %d: Bad config string \"%s\"\n"),
   7856                              port, config_str));
   7857                     return SOC_E_FAIL;
   7858                 }
   7859                 sub_str_end++;
   7860             }
   7861         }
   7862     }
   7863     /*Read 100G lane configuration if present.  skip if options are present*/
   7864     sub_str = sub_str_end;
   7865     lane_config = SOC_LANE_CONFIG_100G_DEFAULT;
   7866     if (*sub_str != '\0' && (*sub_str != 'm' &&
   7867                              *sub_str != 'i' && *sub_str != 'l')) {
   7868         for (index = 0; index < 3; index++) {
   7869             if (sub_str[index] == '\0') {
   7870                 break;
   7871             }
   7872             str_buf[index] = sub_str[index];
   7873         }
   7874         str_buf[index] = '\0';
   7875         if (!sal_strcmp(str_buf, "442")) {
   7876             lane_config = SOC_LANE_CONFIG_100G_4_4_2;
   7877         } else if (!sal_strcmp(str_buf, "244")) {
   7878             lane_config = SOC_LANE_CONFIG_100G_2_4_4;
   7879         } else if (!sal_strcmp(str_buf, "343")) {
   7880             lane_config = SOC_LANE_CONFIG_100G_3_4_3;
   7881         } else {
   7882             LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_U(unit,
   7883                       "Port %d: Invalid lane configuration: %s\n"),
   7884                       port, str_buf));
   7885             return SOC_E_FAIL;
   7886         }
   7887         sub_str_end = &sub_str[3]; /*Advance */
   7888 
   7889         /* Skip ':' between 100G lane config and 100G fallback port*/
   7890         sub_str = sub_str_end;
   7891         if (*sub_str != '\0') {
   7892             if (*sub_str != ':') {
   7893                 LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_U(unit,
   7894                           "Port %d: Bad config string \"%s\"\n"),
   7895                           port, config_str));
   7896                 return SOC_E_FAIL;
   7897             }
   7898             sub_str_end++;
   7899         }
   7900     }
   7901     sub_str = sub_str_end;
   7902     /*Gather the desired fallback TSC for 100G auto-negotiation*/
   7903     fallback_lane = SOC_LANE_CONFIG_100G_AN_CORE_DEFAULT;
   7904     if (*sub_str != '\0' && (*sub_str != 'm' &&
   7905                              *sub_str != 'i' && *sub_str != 'l')) {
   7906         fallback_lane = sal_ctoi(sub_str, &sub_str_end);
   7907         if (fallback_lane > 2 || fallback_lane < 0) {
   7908             LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_U(unit,
   7909                       "Port %d: invalid default lane \"%d\"\n"),
   7910                       port, fallback_lane));
   7911             return SOC_E_FAIL;
   7912         } else {
   7913             /*Validate that for a given lane configuration the selected
   7914              * fallback lane is valid.*/
   7915             for (i = 0; soc_td2_valid_lanes[i].lane_config !=
   7916                  SOC_INVALID_LANE_CONFIG; i++) {
   7917                 if (soc_td2_valid_lanes[i].lane_config == lane_config) {
   7918                     if (!soc_td2_valid_lanes[i].valid_lanes[fallback_lane]) {
   7919                         fallback_lane = -1;
   7920                         break;
   7921                     }
   7922                 }
   7923             }
   7924         }
   7925         if (fallback_lane < 0) {
   7926             LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_U(unit,
   7927                       "Port %d: invalid default lane \"%d\"\n"),
   7928                       port, fallback_lane));
   7929         }
   7930 
   7931         /* Skip ':' between 100G fallback port and options */
   7932         sub_str = sub_str_end;
   7933         if (*sub_str != '\0') {
   7934             if (*sub_str != ':') {
   7935                 LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_U(unit,
   7936                           "Port %d: Bad config string \"%s\"\n"),
   7937                           port, config_str));
   7938                 return SOC_E_FAIL;
   7939             }
   7940             sub_str_end++;
   7941         }
   7942     }
   7943 
   7944     /* Check if option presents */
   7945     *pmap->option = 0;
   7946     sub_str = sub_str_end;
   7947 
   7948     if (*sub_str != '\0') {
   7949         if (*sub_str == 'm') {
   7950             if (phy_port < 13 || phy_port > 16) {
   7951                 LOG_CLI((BSL_META_U(unit,
   7952                                     "Port %d: Physical port %d can not be "
   7953                                     "configured as management port\n"),
   7954                          port, phy_port));
   7955                 return SOC_E_FAIL;
   7956             }
   7957         } else if (*sub_str != 'i' && *sub_str != 'l') {
   7958             LOG_CLI((BSL_META_U(unit,
   7959                                 "Port %d: Bad config string \"%s\"\n"),
   7960                                 port, config_str));
   7961             return SOC_E_FAIL;
   7962         }
   7963         *pmap->option = *sub_str;
   7964         sub_str++;
   7965     }
   7966 
   7967 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   7968     if (SOC_IS_TD2P_TT2P(unit)) {
   7969         /* User has specified number of lanes for the port config*/
   7970         if (*pmap->option == 'l') {
   7971             if ((*sub_str != '\0') && (*sub_str != ':')) {
   7972                 LOG_CLI((BSL_META_U(unit,
   7973                                       "Port %d: Bad lanes config \"%s\"\n"),
   7974                            port, config_str));
   7975                 return SOC_E_FAIL;
   7976             } else if (*sub_str == '\0') {
   7977                 LOG_CLI((BSL_META_U(unit,
   7978                              "Port %d: #of lanes not specified in=(%s)\n"),
   7979                                port, config_str));
   7980                 return SOC_E_FAIL;
   7981             }
   7982             /* Skip ':' */
   7983             sub_str++;
   7984 
   7985             for (index = 0; index < 2; index++) {
   7986                 if (sub_str[index] == '\0') {
   7987                     break;
   7988                 }
   7989                 str_buf[index] = sub_str[index];
   7990             }
   7991             str_buf[index] = '\0';
   7992 
   7993             if (!sal_strcmp(str_buf, "12")) {
   7994                 num_lanes = 12;
   7995             } else if (!sal_strcmp(str_buf, "10")) {
   7996                 num_lanes = 10;
   7997             } else {
   7998                 num_lanes = sal_ctoi(sub_str, &sub_str_end);
   7999             }
   8000 
   8001             /* Validate port lanes and allowed port speed */
   8002             rv = _soc_td2p_lane_speed_valid_check(unit, num_lanes, port_bandwidth);
   8003             if (SOC_FAILURE(rv)) {
   8004                 LOG_CLI((BSL_META_U(unit,
   8005                       "Port %d: Lane config error ..\n"), port));
   8006                 return SOC_E_FAIL;
   8007             }
   8008             /* Assign lanes */
   8009             si->port_num_lanes[port] =  num_lanes;
   8010 
   8011             /* Shift ahead 2 places */
   8012             sub_str_end = &sub_str[2];
   8013             sub_str = sub_str_end;
   8014         }
   8015     }
   8016 #endif
   8017 
   8018     if (soc_feature(unit, soc_feature_management_port_lanes) &&
   8019         /* Check if number of lanes is specified for management port */
   8020         *pmap->option == 'm' && *sub_str != '\0') {
   8021         if (*sub_str != ':') {
   8022             LOG_ERROR(BSL_LS_SOC_PORT,
   8023                       (BSL_META_U(unit,
   8024                                   "Port %d: Bad config string \"%s\"\n"),
   8025                        port, config_str));
   8026             return SOC_E_FAIL;
   8027         }
   8028         /* Skip ':' */
   8029         sub_str++;
   8030         num_lanes = sal_ctoi(sub_str, &sub_str_end);
   8031         if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
   8032             LOG_ERROR(BSL_LS_SOC_PORT,
   8033                       (BSL_META_U(unit,
   8034                                   "Port %d: Invalid number of "
   8035                                   "management port lanes \"%d\"\n"),
   8036                        port, num_lanes));
   8037             return SOC_E_FAIL;
   8038         }
   8039         if (num_lanes != 1 && port_bandwidth != 10000) {
   8040             LOG_ERROR(BSL_LS_SOC_PORT,
   8041                       (BSL_META_U(unit,
   8042                                   "Port %d: Invalid number of "
   8043                                   "management port lanes \"%d\" "
   8044                                   "for this speed \"%d\"\n"),
   8045                        port, num_lanes, port_bandwidth));
   8046             return SOC_E_FAIL;
   8047         }
   8048         si->port_num_lanes[port] =  num_lanes;
   8049         sub_str = sub_str_end;
   8050     }
   8051 
   8052     /* Check trailing string */
   8053     if (*sub_str != '\0') {
   8054         LOG_CLI((BSL_META_U(unit,
   8055                             "Port %d: Bad config string \"%s\"\n"),
   8056                  port, config_str));
   8057         return SOC_E_FAIL;
   8058     }
   8059 
   8060     pmap->port = port;
   8061     pmap->phy_port = phy_port;
   8062     pmap->port_bandwidth = port_bandwidth;
   8063     pmap->lane_config = lane_config;
   8064     pmap->fallback_lane = fallback_lane;
   8065     pmap->pipe = pipe;
   8066 
   8067     return SOC_E_NONE;
   8068 }
   8069 
   8070 /*
   8071  * Trident2 port mapping
   8072  *     130 physical ports: port 0-64 in X pipe, port 65-129 in Y pipe
   8073  *     106 logical ports
   8074  *     108 mmu ports: port 0-53 in X pipe, port 64-117 in Y pipe
   8075  *     cpu port number is fixed: physical 0, logical 0, mmu 52
   8076  *     loopback port number is fixed: physical 129, logical 105, mmu 116
   8077  *     mmu port 53 and mmu port 117 are purge port
   8078  *     mmu port can only map to physical port ID in the same pipe
   8079  *     XLPORT3 (physical port 13-16) can be configured as management port(s)
   8080  *     management port can be:
   8081  *     - one 10G port
   8082  *     - one to four ports with speed up to 2.5G each
   8083  * Physical port number in eacc port group
   8084  *     PGW_CL0: CPORT0   TSC 0-2   port 1
   8085  *              XLPORT0  TSC 0     port 1-4
   8086  *              XLPORT1  TSC 1     port 5-8
   8087  *              XLPORT2  TSC 2     port 9-12
   8088  *              XLPORT3  TSC 3     port 13-16
   8089  *     PGW_CL1: CPORT1   TSC 5-7   port 21
   8090  *              XLPORT7  TSC 4     port 17-20
   8091  *              XLPORT6  TSC 5     port 21-24
   8092  *              XLPORT5  TSC 6     port 25-28
   8093  *              XLPORT4  TSC 7     port 29-32
   8094  *     PGW_CL2: CPORT2   TSC 8-10  port 33
   8095  *              XLPORT8  TSC 8     port 33-36
   8096  *              XLPORT9  TSC 9     port 37-40
   8097  *              XLPORT10 TSC 10    port 41-44
   8098  *              XLPORT11 TSC 11    port 45-48
   8099  *     PGW_CL3: CPORT3   TSC 13-15 port 53
   8100  *              XLPORT15 TSC 12    port 49-52
   8101  *              XLPORT14 TSC 13    port 53-56
   8102  *              XLPORT13 TSC 14    port 57-60
   8103  *              XLPORT12 TSC 15    port 61-64
   8104  *     PGW_CL4: CPORT4   TSC 16-18 port 65
   8105  *              XLPORT16 TSC 16    port 65-68
   8106  *              XLPORT17 TSC 17    port 69-72
   8107  *              XLPORT18 TSC 18    port 73-76
   8108  *              XLPORT19 TSC 19    port 77-80
   8109  *     PGW_CL5: CPORT5   TSC 21-23 port 85
   8110  *              XLPORT23 TSC 20    port 81-84
   8111  *              XLPORT22 TSC 21    port 85-88
   8112  *              XLPORT21 TSC 22    port 89-92
   8113  *              XLPORT20 TSC 23    port 93-96
   8114  *     PGW_CL6: CPORT6   TSC 24-26 port 97
   8115  *              XLPORT24 TSC 24    port 97-100
   8116  *              XLPORT25 TSC 25    port 101-104
   8117  *              XLPORT26 TSC 26    port 105-108
   8118  *              XLPORT27 TSC 27    port 109-112
   8119  *     PGW_CL7: CPORT7   TSC 29-31 port 117
   8120  *              XLPORT31 TSC 28    port 113-116
   8121  *              XLPORT30 TSC 29    port 117-120
   8122  *              XLPORT29 TSC 30    port 121-124
   8123  *              XLPORT28 TSC 31    port 125-128
   8124  * This routine will setup:
   8125  *     SOC_INFO(unit).port_p2l_mapping[]
   8126  *     SOC_INFO(unit).port_l2p_mapping[]
   8127  *     SOC_INFO(unit).port_p2m_mapping[]
   8128  *     SOC_INFO(unit).port_m2p_mapping[]
   8129  *     SOC_INFO(unit).port_speed_max[]
   8130  *     SOC_INFO(unit).port_group[]
   8131  *     SOC_INFO(unit).port_serdes[]
   8132  *     SOC_INFO(unit).port_num_lanes[]
   8133  *     SOC_INFO(unit).phy_port_base[]
   8134  *     SOC_INFO(unit).mmu_port_base[]
   8135  * 100+G port:
   8136  *     - can only be @ 760MHz
   8137  *     - needs to be HSP
   8138  *     - cannot be in oversubscribe mode
   8139  * 40/42G port:
   8140  *     - needs to be HSP except @ 760MHz
   8141  *     - oversubscribe mode can support both cut-through and store-and-forward
   8142  * sub-40G port:
   8143  *     - oversubscribe mode can only support store-and-forward
   8144  */
   8145 int
   8146 soc_trident2_port_config_init(int unit, uint16 dev_id, uint8 rev_id)
   8147 {
   8148 #if defined(BCM_56850_A0) || defined(BCM_56860_A0)
   8149     /*
   8150      * Compiling this function will fail due to a p2l mapping overrun, if
   8151      * a low port count device (like Apache) defines BCM_TRIDENT2_SUPPORT
   8152      * and no true TD2 devices are part of the build.
   8153      */
   8154     soc_info_t *si;
   8155     soc_info_misc_t *si_m;
   8156     soc_pmap_info_t pmap;
   8157     char option = '\0';
   8158     int rv;
   8159     int port, phy_port, mmu_port;
   8160     int pipe;
   8161     int frequency;
   8162     int index;
   8163 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8164     int i;
   8165 #endif
   8166     soc_pbmp_t pbmp, oversub_pbm, pbmp_mmu_reserved;
   8167     int freq_list_len;
   8168     int const *freq_list;
   8169 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8170     int flexport_reserve_HSP[_TD2_PIPES_PER_DEV];
   8171     int flexport_reserve_T2OQ[_TD2_PIPES_PER_DEV];
   8172     int flexport_max_speed = -1;
   8173     int flexport_max_speed_pipe[_TD2_PIPES_PER_DEV];
   8174     int num_hsp_to_reserve[_TD2_PIPES_PER_DEV]; /* index 0 is for X pipe,
   8175                                   index 1 is for Y pipe */
   8176     portmod_pbmp_t phy_pbmp;
   8177 
   8178 #ifdef BCM_WARM_BOOT_SUPPORT
   8179     uint16 upgrade_from_nosupport = 0;
   8180 #endif /* BCM_WARM_BOOT_SUPPORT */
   8181 
   8182     flexport_reserve_HSP[0] = 0;
   8183     flexport_reserve_HSP[1] = 0;
   8184     flexport_reserve_T2OQ[0] = 0;
   8185     flexport_reserve_T2OQ[1] = 0;
   8186     flexport_max_speed_pipe[0] = -1;
   8187     flexport_max_speed_pipe[1] = -1;
   8188     num_hsp_to_reserve[0] = 0;
   8189     num_hsp_to_reserve[1] = 0;
   8190 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   8191 
   8192     si = &SOC_INFO(unit);
   8193     si->flex_eligible = FALSE;
   8194 
   8195     /* Can't read skew_id from TOP register at this point */
   8196     SOC_IF_ERROR_RETURN
   8197         (soc_trident2_max_frequency_get(unit, dev_id, rev_id, -1,
   8198                                                     &si->frequency));
   8199     if (SOC_IS_TRIDENT2(unit)) {
   8200         frequency = rev_id == BCM56850_A0_REV_ID ? 415 : -1;
   8201     } else {
   8202         frequency = -1;
   8203     }
   8204     frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, frequency);
   8205 
   8206     if (frequency != -1 && frequency < si->frequency) {
   8207         if (SOC_IS_TRIDENT2(unit)) {
   8208             if (rev_id <= BCM56850_A1_REV_ID) {
   8209                 freq_list = a1_freq_list;
   8210                 freq_list_len = sizeof(a1_freq_list) / sizeof(int);
   8211             } else {
   8212                 if (si->frequency == 793) {
   8213                     freq_list = a2_793_freq_list;
   8214                     freq_list_len = sizeof(a2_793_freq_list) / sizeof(int);
   8215                 } else {
   8216                     freq_list = a2_635_freq_list;
   8217                     freq_list_len = sizeof(a2_635_freq_list) / sizeof(int);
   8218                 }
   8219             }
   8220         } else {
   8221             freq_list = a1_td2p_freq_list;
   8222             freq_list_len = sizeof(a1_td2p_freq_list) / sizeof(int);
   8223         }
   8224 
   8225         for (index = 1; index < freq_list_len; index++) { /* skip index 0 */
   8226             if (freq_list[index] < si->frequency &&
   8227                 frequency == freq_list[index]) {
   8228                 break;
   8229             }
   8230         }
   8231 
   8232         if (index < freq_list_len) {
   8233             si->frequency = frequency;
   8234         } else {
   8235             LOG_CLI((BSL_META_U(unit,
   8236                                 "*** Input core clock frequency %dMHz is not "
   8237                                 "supported!\n"), frequency));
   8238         }
   8239     } else if (frequency > si->frequency) {
   8240         LOG_CLI((BSL_META_U(unit,
   8241                             "*** Input core clock frequency %dMHz is not supported!\n"),
   8242                  frequency));
   8243     }
   8244 
   8245     /* Setup max I/O bandwidth */
   8246     SOC_IF_ERROR_RETURN
   8247         (soc_trident2_max_io_frequency_get(unit, dev_id, rev_id, -1,
   8248                                            &si->io_bandwidth));
   8249 
   8250     /* Setup max core bandwidth */
   8251     if (si->frequency >= 760) {
   8252         si->bandwidth = 960000;
   8253     } else if (si->frequency >= 608) {
   8254         si->bandwidth = 720000;
   8255     } else if (si->frequency >= 518) {
   8256         si->bandwidth = 640000;
   8257     } else {
   8258         if (SOC_IS_TRIDENT2(unit)) {
   8259             si->bandwidth = 480000;
   8260         } else {
   8261             if (si->frequency >= 517) {
   8262                 si->bandwidth = 640000;
   8263             } else {
   8264                 si->bandwidth = 480000;
   8265             }
   8266         }
   8267     }
   8268 
   8269     SOC_PBMP_CLEAR(oversub_pbm);
   8270     if (!SOC_IS_TD2P_TT2P(unit)) {
   8271         if (si->io_bandwidth > si->bandwidth) {
   8272             oversub_pbm =
   8273                 soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0);
   8274         }
   8275     }
   8276 
   8277     pbmp_mmu_reserved =
   8278         soc_property_get_pbmp(unit, "pbmp_mmu_reserved", 0);
   8279 
   8280     SOC_IF_ERROR_RETURN
   8281         (soc_trident2_tsc_map_get(unit, &tsc_map));
   8282 
   8283     for (phy_port = 0; phy_port < SOC_TD2_NUM_PHY_PORT; phy_port++) {
   8284         si->port_p2l_mapping[phy_port] = -1;
   8285         si->port_p2m_mapping[phy_port] = -1;
   8286     }
   8287     for (port = 0; port < SOC_TD2_NUM_LPORT; port++) {
   8288         si->port_l2p_mapping[port] = -1;
   8289         si->port_speed_max[port] = -1;
   8290         si->port_group[port] = -1;
   8291         si->port_serdes[port] = -1;
   8292         si->port_num_lanes[port] = -1;
   8293     }
   8294     for (mmu_port = 0; mmu_port < SOC_TD2_NUM_MMU_PORT ; mmu_port++) {
   8295         si->port_m2p_mapping[mmu_port] = -1;
   8296     }
   8297 
   8298     si->port_p2l_mapping[SOC_TD2_CPU_PHY_PORT] = SOC_TD2_CPU_LPORT;
   8299     si->port_p2m_mapping[SOC_TD2_CPU_PHY_PORT] = SOC_TD2_CPU_MMU_PORT;
   8300     si->port_p2l_mapping[SOC_TD2_LB_PHY_PORT] = SOC_TD2_LB_LPORT;
   8301     si->port_p2m_mapping[SOC_TD2_LB_PHY_PORT] = SOC_TD2_LB_MMU_PORT;
   8302     si->port_pipe[SOC_TD2_CPU_LPORT] = 0;
   8303     si->port_pipe[SOC_TD2_LB_LPORT]  = 1;
   8304     SOC_PBMP_PORT_SET(si->xpipe_pbm, SOC_TD2_CPU_LPORT);
   8305     SOC_PBMP_PORT_SET(si->ypipe_pbm, SOC_TD2_LB_LPORT);
   8306     SOC_PBMP_CLEAR(si->oversub_pbm);
   8307     SOC_PBMP_CLEAR(si->management_pbm);
   8308     SOC_PBMP_CLEAR(si->all.disabled_bitmap);
   8309 
   8310     si->phy_port_base[0] = 0;               /* First physical port in X pipe */
   8311     si->phy_port_base[1] = SOC_TD2_NUM_PHY_PORT / 2;/* First physical port in Y pipe */
   8312     si->mmu_port_base[0] = 0;               /* First mmu port in X pipe */
   8313     si->mmu_port_base[1] = 64;              /* First mmu port in Y pipe */
   8314 
   8315     port_count[0] = 0; /* X pipe */
   8316     port_count[1] = 0; /* Y pipe */
   8317 
   8318 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8319     if (SOC_IS_TRIDENT2PLUS(unit)) {
   8320         if (soc_feature(unit, soc_feature_clmac)
   8321             && soc_feature(unit, soc_feature_clmac_partial_support)) {
   8322                 /* TSCs {5,6,7}, {13,14,15}, {16,17,18}, {24,25,26}
   8323                  * support CE port. All other TSCs, if enabled, support
   8324                  * XL ports.
   8325                  */
   8326                 clmac_tsc_map = tsc_map & 0x0707e0e0;
   8327         }
   8328     }
   8329 #endif
   8330 
   8331     rv = SOC_E_NONE;
   8332     for (port = 0; port < SOC_TD2_NUM_LPORT; port++) {
   8333         int rv_p = SOC_E_NONE;
   8334         if (port == SOC_TD2_CPU_LPORT || port == SOC_TD2_LB_LPORT) {
   8335             continue;
   8336         }
   8337 
   8338         sal_memset(&pmap, 0x0, sizeof(soc_pmap_info_t));
   8339         pmap.option = &option;
   8340         sal_memcpy(&pmap.oversub_pbm, &oversub_pbm, sizeof(soc_pbmp_t));
   8341 
   8342         rv_p = soc_trident2_port_portmap_parse(unit, port, &pmap);
   8343         if (SOC_FAILURE(rv_p)) {
   8344             if (rv_p == SOC_E_FAIL) {
   8345                 rv = SOC_E_FAIL;
   8346             }
   8347             continue;
   8348         }
   8349 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8350         /*
   8351          * Use new properties for 100GE mode lane and
   8352          * fallback autoneg core if these are specified.
   8353          */
   8354         if (SOC_IS_TRIDENT2PLUS(unit)) {
   8355             int mode_lane, an_core, found = FALSE;
   8356 
   8357             if (pmap.port_bandwidth >= 100000) {
   8358                 if (SOC_SUCCESS(soc_td2p_port_lane_config_get(unit,
   8359                                     pmap.phy_port, &mode_lane, &found))) {
   8360                     if (found) {
   8361                         pmap.lane_config = mode_lane;
   8362                     }
   8363                 }
   8364                 if (SOC_SUCCESS(soc_td2p_port_autoneg_core_get(unit,
   8365                                     pmap.phy_port, &an_core, &found))) {
   8366                     if (found) {
   8367                         pmap.fallback_lane = an_core;
   8368                     }
   8369                 }
   8370             }
   8371         }
   8372 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   8373 
   8374 
   8375         /* Update soc_info */
   8376         si->port_p2l_mapping[pmap.phy_port]  = pmap.port;
   8377         si->port_l2p_mapping[port]           = pmap.phy_port;
   8378         si->port_speed_max[port]             = pmap.port_bandwidth;
   8379         si->port_100g_lane_config[port]      = pmap.lane_config;
   8380         si->port_fallback_lane[port]         = pmap.fallback_lane;
   8381         si->port_pipe[port]                  = pmap.pipe;
   8382 
   8383         if (option == 'i') {
   8384             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, pmap.port);
   8385         } else if (option == 'm') {
   8386             SOC_PBMP_PORT_ADD(si->management_pbm, pmap.port);
   8387         }
   8388 
   8389         if (SOC_PBMP_MEMBER(pmap.oversub_pbm, pmap.port)) {
   8390 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8391             if (SOC_IS_TD2P_TT2P(unit)) {
   8392                 if (pmap.port_bandwidth >= SPEED_100G) {
   8393                     LOG_CLI((BSL_META_U(unit,
   8394                              "Port %d: Physical port %d port speed %d "
   8395                              "cannot be configured as oversubscription port,"
   8396                              " When port speed is 100G or beyond\n"),
   8397                              pmap.port, pmap.phy_port, pmap.port_bandwidth));
   8398                     rv = SOC_E_FAIL;
   8399                     continue;
   8400                 } else {
   8401                     SOC_PBMP_PORT_ADD(si->oversub_pbm, pmap.port);
   8402                 }
   8403             }
   8404             else
   8405 #endif
   8406             {
   8407                 SOC_PBMP_PORT_ADD(si->oversub_pbm, pmap.port);
   8408             }
   8409         }
   8410 
   8411         port_count[pmap.pipe]++;
   8412     }
   8413 
   8414     /* Legacy Flex config ":i" case detected, disabled ports in config */
   8415     if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all))) {
   8416         si->flex_eligible = TRUE;
   8417     }
   8418 
   8419  #if defined(BCM_WARM_BOOT_SUPPORT) && defined(BCM_TRIDENT2PLUS_SUPPORT)
   8420     if (SOC_IS_TD2P_TT2P(unit)) {
   8421         if (SOC_WARM_BOOT(unit)) {
   8422             upgrade_from_nosupport = 0;
   8423             rv = soc_td2p_flexport_scache_recovery(unit);
   8424             if (SOC_FAILURE(rv)) {
   8425                 if (rv == SOC_E_NOT_FOUND) {
   8426                     upgrade_from_nosupport = 1;
   8427                     rv = SOC_E_NONE;
   8428                 } else {
   8429                     return rv;
   8430                 }
   8431             }
   8432         } else {
   8433             /* Cold boot create */
   8434             SOC_IF_ERROR_RETURN(soc_td2p_flexport_scache_allocate(unit));
   8435         }
   8436     }
   8437 #endif /* BCM_WARM_BOOT_SUPPORT && BCM_TRIDENT2PLUS_SUPPORT */
   8438 
   8439     if (port_count[0] == 0 && port_count[1] == 0) {
   8440 #ifdef __KERNEL__
   8441         /* config.bcm is not parsed yet at the time 1st call of soc_attach
   8442            in Kernel mode SDK. Shouldn't return error code. */
   8443         return SOC_E_NONE;
   8444 #else
   8445         if (SOC_CONTROL(unit)->soc_flags & SOC_F_ATTACHED) { /* not for PCID */
   8446             rv = SOC_E_FAIL;
   8447         }
   8448 #endif
   8449     }
   8450 
   8451     si_m = sal_alloc(sizeof(soc_info_misc_t), "soc_info_misc");
   8452     if (NULL == si_m) {
   8453         return rv;
   8454     }
   8455 
   8456     soc_trident2_soc_info_misc_t_init(unit, si_m);
   8457 
   8458     if (SOC_FAILURE(soc_trident2_port_bandwidth_validate(unit, si_m))) {
   8459         rv = SOC_E_FAIL;
   8460     }
   8461     sal_free(si_m);
   8462 
   8463     if (SOC_FAILURE(rv)) {
   8464         for (phy_port = 1; phy_port < 129; phy_port++) {
   8465             si->port_p2l_mapping[phy_port] = -1;
   8466         }
   8467         return rv;
   8468     }
   8469 
   8470     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   8471         LOG_CLI((BSL_META_U(unit,
   8472                             "physical to logical mapping:")));
   8473         for (index = 0; index < SOC_TD2_NUM_PHY_PORT; index++) {
   8474             if (index % 16 == 0) {
   8475                 LOG_CLI((BSL_META_U(unit,
   8476                                     "\n    ")));
   8477             }
   8478             LOG_CLI((BSL_META_U(unit,
   8479                                 " %3d"),
   8480                      si->port_p2l_mapping[index]));
   8481         }
   8482         LOG_CLI((BSL_META_U(unit,
   8483                             "\n")));
   8484         LOG_CLI((BSL_META_U(unit,
   8485                             "physical port bandwidth:")));
   8486         for (index = 0; index < SOC_TD2_NUM_PHY_PORT; index++) {
   8487             if (index % 16 == 0) {
   8488                 LOG_CLI((BSL_META_U(unit,
   8489                                     "\n    ")));
   8490             }
   8491             port = si->port_p2l_mapping[index];
   8492             if (port == -1) {
   8493                 LOG_CLI((BSL_META_U(unit,
   8494                                     "  -1")));
   8495             } else if (si->port_speed_max[port] == 2500) {
   8496                 LOG_CLI((BSL_META_U(unit,
   8497                                     " 2.5")));
   8498             } else {
   8499                 LOG_CLI((BSL_META_U(unit,
   8500                                     " %3d"),
   8501                          si->port_speed_max[port] / 1000));
   8502             }
   8503         }
   8504         LOG_CLI((BSL_META_U(unit,
   8505                             "\n")));
   8506     }
   8507 
   8508     /* Setup port_group, num_lanes, xpipe_pbm and ypipe_pbm */
   8509     for (port = 0; port < SOC_TD2_NUM_LPORT; port++) {
   8510         phy_port = si->port_l2p_mapping[port];
   8511         /* cpu, loopback, or unused port */
   8512         if ((port == SOC_TD2_CPU_LPORT) || (port == SOC_TD2_LB_LPORT)
   8513             || (phy_port == -1)) {
   8514             continue;
   8515         }
   8516         /* 16 ports per PGW_CL */
   8517         si->port_group[port] = (phy_port - 1) / _TD2_PORTS_PER_PGW;
   8518         si->port_serdes[port] = (phy_port - 1) / _TD2_PORTS_PER_XLP;
   8519         if (si->port_num_lanes[port] == -1) {
   8520             if (si->port_speed_max[port] > 106000) {
   8521                 si->port_num_lanes[port] = 12;
   8522             } else if (si->port_speed_max[port] > 42000) {
   8523                 si->port_num_lanes[port] =  10;
   8524             } else if (si->port_speed_max[port] > 21000) {
   8525                 si->port_num_lanes[port] =  4;
   8526             } else if (SOC_IS_TITAN2PLUS(unit) &&
   8527                        ((si->port_speed_max[port] == 13000) ||
   8528                         (si->port_speed_max[port] == 16000))){
   8529                 si->port_num_lanes[port] = 4;
   8530             } else if (si->port_speed_max[port] > 11000) {
   8531                 si->port_num_lanes[port] =  2;
   8532             } else {
   8533                 si->port_num_lanes[port] =  1;
   8534             }
   8535         }
   8536         if (phy_port < si->phy_port_base[1]) { /* X-pipe */
   8537             SOC_PBMP_PORT_ADD(si->xpipe_pbm, port);
   8538         } else { /* Y-pipe */
   8539             SOC_PBMP_PORT_ADD(si->ypipe_pbm, port);
   8540         }
   8541     }
   8542 
   8543     SOC_PBMP_ASSIGN(si->pipe_pbm[0], si->xpipe_pbm);
   8544     SOC_PBMP_ASSIGN(si->pipe_pbm[1], si->ypipe_pbm);
   8545 
   8546 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8547     /* Initialize device physical port information */
   8548     if (SOC_IS_TD2P_TT2P(unit)) {
   8549         SOC_IF_ERROR_RETURN(soc_td2p_phy_info_init(unit));
   8550         SOC_IF_ERROR_RETURN(soc_td2p_port_mixed_sister_speed_validate(unit));
   8551         soc_td2p_num_hsp_reserved_reset(unit);
   8552 
   8553         /* If legacy flex (:i inactive ports) is not present, check to see if new dynamic flexing is possible.
   8554            If it is, we need to reserve the appropriate number of HSP and T2OQ ports. */
   8555         if (FALSE == si->flex_eligible) {
   8556             if (soc_td2p_is_any_port_flex_enable(unit)) {
   8557 
   8558                 /*
   8559                  * This finds out if the device is booting with too many logical
   8560                  * ports given our flex situation by calling ports_max_validate
   8561                  * Determine bitmaps of used/mapped logical ports and
   8562                  * physical ports.
   8563                  *
   8564                  * A bit set indicates port is mapped.
   8565                  */
   8566                 PORTMOD_PBMP_CLEAR(phy_pbmp);
   8567                 /* Get current port assignment */
   8568                 for (phy_port = 0; phy_port < SOC_MAX_NUM_PORTS; phy_port++) {
   8569                     /* Skip not-addressable and invalid ports */
   8570                     if (!TD2P_PHY_PORT_ADDRESSABLE(unit, phy_port) ||
   8571                         (si->port_p2l_mapping[phy_port] == -1)) {
   8572                         continue;
   8573                     }
   8574 
   8575                     PORTMOD_PBMP_PORT_ADD(phy_pbmp, phy_port);
   8576                 }
   8577 
   8578                 SOC_IF_ERROR_RETURN(soc_td2p_logic_ports_max_validate(unit, phy_pbmp));
   8579 
   8580                 /* See whether we need to reserve HSP and T2OQ ports for flexport if we're
   8581                    flexing any port.  Actual reservation will come AFTER HSP/T2OQ ports have
   8582                    been assigned below. */
   8583                 SOC_IF_ERROR_RETURN(soc_td2p_port_resource_speed_max_get(unit, &flexport_max_speed));
   8584                 SOC_IF_ERROR_RETURN(soc_td2p_port_resource_speed_max_x_get(unit, &flexport_max_speed_pipe[0]));
   8585                 SOC_IF_ERROR_RETURN(soc_td2p_port_resource_speed_max_y_get(unit, &flexport_max_speed_pipe[1]));
   8586 
   8587                 /* Error check to make sure that if one pipe's max flex speed is set, the other is as well */
   8588                 if ((flexport_max_speed_pipe[0] > 0 && flexport_max_speed_pipe[1] < 0) ||
   8589                     (flexport_max_speed_pipe[0] < 0 && flexport_max_speed_pipe[1] > 0)) {
   8590 
   8591                     LOG_VERBOSE(BSL_LS_SOC_MMU,
   8592                         (BSL_META_U(unit,
   8593                          "Both port_flex_speed_max_x and port_flex_speed_max_y must be set!\n")
   8594                           ));
   8595                     return SOC_E_CONFIG;
   8596                 }
   8597 
   8598                 /* Find out how many port macros are capable of flexing per pipe */
   8599                 SOC_IF_ERROR_RETURN(
   8600                    soc_td2p_num_hsp_reserved_per_pipe(unit, 0, &num_hsp_to_reserve[0]));
   8601                 SOC_IF_ERROR_RETURN(
   8602                    soc_td2p_num_hsp_reserved_per_pipe(unit, 1, &num_hsp_to_reserve[1]));
   8603                 /* If flexing any port to 100 gig is possible, we need to preallocate
   8604                    a HSP port and T2OQ per port macro */
   8605 
   8606                 for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
   8607 
   8608                     /* If flexport_max_speed_pipe has been set for both pipes
   8609                        (check is above), use them instead of the device
   8610                        global flexport_max_speed, otherwise just use
   8611                        the global */
   8612                     if (flexport_max_speed_pipe[pipe] > 0 ) {
   8613                         flexport_max_speed = flexport_max_speed_pipe[pipe];
   8614                     }
   8615 
   8616                     if(flexport_max_speed > 42000) {
   8617                         flexport_reserve_HSP[pipe] = 1;
   8618                         flexport_reserve_T2OQ[pipe] = 1;
   8619                     }
   8620                     /* otherwise flexing only goes up to 40 gig */
   8621                     else {
   8622                         /* don't need to preallocate for frequencies at and above 960000 */
   8623                         if(si->bandwidth >= 960000) {
   8624                         }
   8625                         /* Need to preallocate 1 HSP port per port macro
   8626                            for above this freq */
   8627                         else if(si->bandwidth >= 720000) {
   8628                             flexport_reserve_HSP[pipe] = 1;
   8629                             flexport_reserve_T2OQ[pipe] = 0;
   8630                         }
   8631                         /* Otherwise, for freq 480000 and below need to
   8632                            preallocate 1 HSP and 1 T2OQ
   8633                            per port macro */
   8634                         else {
   8635                             flexport_reserve_HSP[pipe] = 1;
   8636                             flexport_reserve_T2OQ[pipe] = 1;
   8637                         }
   8638                     }
   8639                 }
   8640             }
   8641         }
   8642     }
   8643 #endif
   8644 
   8645     /* Setup vector-based scheduler (VBS)
   8646      * a.k.a high speed port scheduler (HSP) pbm */
   8647     for (port = 0; port < SOC_TD2_NUM_LPORT; port++) {
   8648         phy_port = si->port_l2p_mapping[port];
   8649         if (phy_port == -1) { /* cpu, loopback, or unused port */
   8650             continue;
   8651         }
   8652         if (si->port_speed_max[port] >= 100000 ||
   8653             (si->port_speed_max[port] >= 40000 && si->frequency < 760) ||
   8654             soc_property_port_get(unit, port, spn_PORT_SCHED_HSP, 0)) {
   8655             SOC_PBMP_PORT_ADD(si->eq_pbm, port);
   8656         }
   8657     }
   8658 
   8659 #if defined(BCM_WARM_BOOT_SUPPORT) && defined(BCM_TRIDENT2PLUS_SUPPORT)
   8660     if (SOC_IS_TD2P_TT2P(unit) && SOC_WARM_BOOT(unit) &&
   8661         (!upgrade_from_nosupport)) {
   8662         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8663                (BSL_META_U(unit,
   8664                "\nwarmboot - Function %s Line %d"),
   8665                __FUNCTION__,__LINE__));
   8666 
   8667     } else
   8668 #endif /* BCM_WARM_BOOT_SUPPORT && BCM_TRIDENT2PLUS_SUPPORT */
   8669     {
   8670         /* Assign MMU port */
   8671         for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
   8672             mmu_port = pipe * _TD2_PORTS_PER_PIPE;
   8673             /* First assign the lowest MMU port number for VBS (HSP) ports */
   8674             pbmp = pipe ? si->ypipe_pbm : si->xpipe_pbm;
   8675             SOC_PBMP_AND(pbmp, si->eq_pbm);
   8676             SOC_PBMP_ITER(pbmp, port) {
   8677                 phy_port = si->port_l2p_mapping[port];
   8678                 while (SOC_PBMP_MEMBER(pbmp_mmu_reserved, mmu_port)) {
   8679                     mmu_port++;
   8680                 }
   8681                 si->port_p2m_mapping[phy_port] = mmu_port;
   8682                 /* for HSP PBM, In TD2+/TD2, mmu_port + 36 is reserved */
   8683                 SOC_PBMP_PORT_ADD(pbmp_mmu_reserved, mmu_port+36);
   8684                 mmu_port++;
   8685             }
   8686 
   8687     #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8688             if (SOC_IS_TD2P_TT2P(unit)) {
   8689                 /* Reserve HSP and T2OQ ports if we need to. This means that
   8690                  * the "for" loops below will not allocate ports we put into
   8691                  * this reservation bitmap. Each pipe's ports 0-15 are HSP and
   8692                  * HSP + 36 is T2OQ */
   8693             if (flexport_reserve_HSP[pipe]) {
   8694 
   8695 
   8696                 /* Do not include HSP MMU ports that have already been allocated
   8697                   that are flex capable. */
   8698                 for (i = 0; i < mmu_port; i++) {
   8699                     if (soc_td2p_is_port_flex_enable(unit,
   8700                                       si->port_m2p_mapping[i]) == 1) {
   8701                      num_hsp_to_reserve[pipe] -= 1;
   8702                     }
   8703                 }
   8704 
   8705                 for (i = mmu_port%_TD2_PORTS_PER_PIPE; i < num_hsp_to_reserve[pipe]; i++) {
   8706 
   8707                     /* mmu port 0-15 on each pipe; 0-15 on X Pipe, 64-79 on Y Pipe */
   8708                     SOC_PBMP_PORT_ADD(pbmp_mmu_reserved,
   8709                                    i + (pipe * _TD2_PORTS_PER_PIPE));
   8710                         if(flexport_reserve_T2OQ[pipe] == 1) {
   8711                         /* mmu port 36-51 on each pipe; 36-51 on X Pipe, 100-115 on Y Pipe */
   8712                         SOC_PBMP_PORT_ADD(pbmp_mmu_reserved,
   8713                                     i + (pipe * _TD2_PORTS_PER_PIPE)+36);
   8714                         }
   8715                     }
   8716                 }
   8717             }
   8718     #endif
   8719 
   8720               /* Then assign the next lowest MMU port number for 40+G ports */
   8721             for (index = 0; index < _TD2_PORTS_PER_PIPE; index += 4) {
   8722                 phy_port = 1 + pipe * _TD2_PORTS_PER_PIPE + index;
   8723                 port = si->port_p2l_mapping[phy_port];
   8724                 if (port == -1) {
   8725                     continue;
   8726                 }
   8727 
   8728                 if (si->port_p2m_mapping[phy_port] == -1 &&
   8729                     si->port_speed_max[port] > 21000) {
   8730                     while (SOC_PBMP_MEMBER(pbmp_mmu_reserved, mmu_port)) {
   8731                         mmu_port++;
   8732                     }
   8733                     si->port_p2m_mapping[phy_port] = mmu_port;
   8734                     mmu_port++;
   8735                 }
   8736             }
   8737             /* Then assign the next lowest MMU port number for 20+G ports */
   8738             for (index = 0; index < _TD2_PORTS_PER_PIPE; index += 2) {
   8739                 phy_port = 1 + pipe * _TD2_PORTS_PER_PIPE + index;
   8740                 port = si->port_p2l_mapping[phy_port];
   8741                 if (port == -1) {
   8742                     continue;
   8743                 }
   8744 
   8745                 if (si->port_p2m_mapping[phy_port] == -1 &&
   8746                     si->port_speed_max[port] > 11000) {
   8747                     while (SOC_PBMP_MEMBER(pbmp_mmu_reserved, mmu_port)) {
   8748                         mmu_port++;
   8749                     }
   8750                     si->port_p2m_mapping[phy_port] = mmu_port;
   8751                     mmu_port++;
   8752                 }
   8753             }
   8754             /* Finally assign MMU port number for all other ports */
   8755             for (index = 0; index < _TD2_PORTS_PER_PIPE; index++) {
   8756                 phy_port = 1 + pipe * _TD2_PORTS_PER_PIPE + index;
   8757                 port = si->port_p2l_mapping[phy_port];
   8758                 if (port == -1) {
   8759                     continue;
   8760                 }
   8761 
   8762                 if (si->port_p2m_mapping[phy_port] == -1 &&
   8763                     si->port_speed_max[port] > 0) {
   8764                     while (SOC_PBMP_MEMBER(pbmp_mmu_reserved, mmu_port)) {
   8765                         mmu_port++;
   8766                     }
   8767                     si->port_p2m_mapping[phy_port] = mmu_port;
   8768                     mmu_port++;
   8769                 }
   8770             }
   8771             /* if we've gone out of range of the MMU ports per
   8772                pipe (0-52 in X pipe, 64-116 in Y Pipe) */
   8773             if ((mmu_port < 0) ||
   8774                 (mmu_port > 52 && mmu_port < 64) ||
   8775                 (mmu_port > 116)) {
   8776                  LOG_VERBOSE(BSL_LS_SOC_MMU,
   8777                      (BSL_META_U(unit,
   8778                       "MMU port resource allocation failure mmu_port %d\n"),
   8779                        mmu_port));
   8780                 return SOC_E_RESOURCE;
   8781             }
   8782         }
   8783     } /*  Not a TD2 &&Warmboot */
   8784 
   8785     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   8786         LOG_CLI((BSL_META_U(unit,
   8787                             "physical to mmu mapping:")));
   8788         for (index = 0; index < SOC_TD2_NUM_PHY_PORT; index++) {
   8789             if (index % 16 == 0) {
   8790                 LOG_CLI((BSL_META_U(unit,
   8791                                     "\n    ")));
   8792             }
   8793             LOG_CLI((BSL_META_U(unit,
   8794                                 " %3d"),
   8795                      si->port_p2m_mapping[index]));
   8796         }
   8797         LOG_CLI((BSL_META_U(unit,
   8798                             "\n")));
   8799     }
   8800 
   8801     return SOC_E_NONE;
   8802 #else
   8803     LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   8804               "Internal TD2 configuration error")));
   8805     return SOC_E_UNAVAIL;
   8806 #endif
   8807 }
   8808 
   8809 int
   8810 soc_trident2_lls_bmap_alloc(int unit)
   8811 {
   8812     soc_control_t *soc;
   8813     soc_info_t *si;
   8814     int port, phy_port, mmu_port, index;
   8815     int alloc_size_l0, alloc_size_l1, alloc_size_l2;
   8816 
   8817     soc = SOC_CONTROL(unit);
   8818     si = &SOC_INFO(unit);
   8819 
   8820     alloc_size_l0 =
   8821         SHR_BITALLOCSIZE(soc_mem_index_count(unit, ES_PIPE0_LLS_L0_PARENTm));
   8822     alloc_size_l1 =
   8823         SHR_BITALLOCSIZE(soc_mem_index_count(unit, ES_PIPE0_LLS_L1_PARENTm));
   8824     alloc_size_l2 =
   8825         SHR_BITALLOCSIZE(soc_mem_index_count(unit, ES_PIPE0_LLS_L2_PARENTm));
   8826 
   8827     PBMP_ALL_ITER(unit, port) {
   8828         soc->port_lls_l0_bmap[port] = sal_alloc(alloc_size_l0, "LLS_L0_BMAP");
   8829         soc->port_lls_l1_bmap[port] = sal_alloc(alloc_size_l1, "LLS_L1_BMAP");
   8830         soc->port_lls_l2_bmap[port] = sal_alloc(alloc_size_l2, "LLS_L2_BMAP");
   8831         sal_memset(soc->port_lls_l0_bmap[port], 0, alloc_size_l0);
   8832         sal_memset(soc->port_lls_l1_bmap[port], 0, alloc_size_l1);
   8833         sal_memset(soc->port_lls_l2_bmap[port], 0, alloc_size_l2);
   8834         if (SOC_PBMP_MEMBER(si->eq_pbm, port)) { /* VBS (HSP) port */
   8835             phy_port = si->port_l2p_mapping[port];
   8836             mmu_port = si->port_p2m_mapping[phy_port];
   8837             for (index = 0; index < 5; index++) {
   8838                 SHR_BITSET(SOC_CONTROL(unit)->port_lls_l0_bmap[port],
   8839                            (mmu_port & 0x3f) * 5 + index);
   8840             }
   8841             for (index = 0; index < 10; index++) {
   8842                 SHR_BITSET(SOC_CONTROL(unit)->port_lls_l1_bmap[port],
   8843                            (mmu_port & 0x3f) * 10 + index);
   8844             }
   8845             for (index = 0; index < 10; index++) {
   8846                 SHR_BITSET(SOC_CONTROL(unit)->port_lls_l2_bmap[port],
   8847                            (mmu_port & 0x3f) * 10 + index);
   8848             }
   8849         }
   8850     }
   8851 
   8852     return SOC_E_NONE;
   8853 }
   8854 
   8855 int
   8856 soc_trident2_lls_bmap_alloc_port(int unit, int port, int ets_mode)
   8857 {
   8858     soc_control_t *soc;
   8859     soc_info_t *si;
   8860     int phy_port, mmu_port, index;
   8861     int alloc_size_l0, alloc_size_l1, alloc_size_l2;
   8862 
   8863     soc = SOC_CONTROL(unit);
   8864     si = &SOC_INFO(unit);
   8865 
   8866     alloc_size_l0 =
   8867         SHR_BITALLOCSIZE(soc_mem_index_count(unit, ES_PIPE0_LLS_L0_PARENTm));
   8868     alloc_size_l1 =
   8869         SHR_BITALLOCSIZE(soc_mem_index_count(unit, ES_PIPE0_LLS_L1_PARENTm));
   8870     alloc_size_l2 =
   8871         SHR_BITALLOCSIZE(soc_mem_index_count(unit, ES_PIPE0_LLS_L2_PARENTm));
   8872 
   8873     if(soc->port_lls_l0_bmap[port] == NULL) {
   8874         soc->port_lls_l0_bmap[port] = sal_alloc(alloc_size_l0, "LLS_L0_BMAP");
   8875     }
   8876     if(soc->port_lls_l1_bmap[port] == NULL) {
   8877         soc->port_lls_l1_bmap[port] = sal_alloc(alloc_size_l1, "LLS_L1_BMAP");
   8878     }
   8879     if(soc->port_lls_l2_bmap[port] == NULL) {
   8880         soc->port_lls_l2_bmap[port] = sal_alloc(alloc_size_l2, "LLS_L2_BMAP");
   8881     }
   8882     sal_memset(soc->port_lls_l0_bmap[port], 0, alloc_size_l0);
   8883     sal_memset(soc->port_lls_l1_bmap[port], 0, alloc_size_l1);
   8884     sal_memset(soc->port_lls_l2_bmap[port], 0, alloc_size_l2);
   8885 
   8886     if (SOC_PBMP_MEMBER(si->eq_pbm, port)) { /* VBS (HSP) port */
   8887         phy_port = si->port_l2p_mapping[port];
   8888         mmu_port = si->port_p2m_mapping[phy_port];
   8889         for (index = 0; index < 5; index++) {
   8890             SHR_BITSET(SOC_CONTROL(unit)->port_lls_l0_bmap[port],
   8891                        (mmu_port & 0x3f) * 5 + index);
   8892         }
   8893         for (index = 0; index < 10; index++) {
   8894             SHR_BITSET(SOC_CONTROL(unit)->port_lls_l1_bmap[port],
   8895                        (mmu_port & 0x3f) * 10 + index);
   8896         }
   8897         for (index = 0; index < 10; index++) {
   8898             SHR_BITSET(SOC_CONTROL(unit)->port_lls_l2_bmap[port],
   8899                        (mmu_port & 0x3f) * 10 + index);
   8900         }
   8901     }
   8902 
   8903     return SOC_E_NONE;
   8904 }
   8905 
   8906 STATIC int soc_trident2_cmic_ring_map_check(int unit)
   8907 {
   8908     uint32 rval;
   8909 
   8910     /* CMIC_SBUS_RING_MAP_0_7r -> 0x33052100 */
   8911     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_0_7r(unit, &rval));
   8912     if (rval != 0x33052100) {
   8913         LOG_ERROR(BSL_LS_SOC_COMMON,
   8914                   (BSL_META_U(unit,
   8915                               "Unit %d CMIC_SBUS_RING_MAP_0_7 mismatch:%x\n"),
   8916                    unit, rval));
   8917         return SOC_E_CONFIG;
   8918     }
   8919 
   8920     /* CMIC_SBUS_RING_MAP_8_15r -> 0x33776644 */
   8921     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_8_15r(unit, &rval));
   8922     if (rval != 0x33776644) {
   8923         LOG_ERROR(BSL_LS_SOC_COMMON,
   8924                   (BSL_META_U(unit,
   8925                               "Unit %d CMIC_SBUS_RING_MAP_8_15 mismatch:%x\n"),
   8926                    unit, rval));
   8927         return SOC_E_CONFIG;
   8928     }
   8929 
   8930     /* CMIC_SBUS_RING_MAP_16_23r -> 0x33333333 */
   8931     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_16_23r(unit, &rval));
   8932     if (rval != 0x33333333) {
   8933         LOG_ERROR(BSL_LS_SOC_COMMON,
   8934                   (BSL_META_U(unit,
   8935                               "Unit %d CMIC_SBUS_RING_MAP_16_23 mismatch:%x\n"),
   8936                    unit, rval));
   8937         return SOC_E_CONFIG;
   8938     }
   8939 
   8940     /* CMIC_SBUS_RING_MAP_24_31r -> 0x44444444 */
   8941     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_24_31r(unit, &rval));
   8942     if (rval != 0x44444444) {
   8943         LOG_ERROR(BSL_LS_SOC_COMMON,
   8944                   (BSL_META_U(unit,
   8945                               "Unit %d CMIC_SBUS_RING_MAP_24_31 mismatch:%x\n"),
   8946                    unit, rval));
   8947         return SOC_E_CONFIG;
   8948     }
   8949 
   8950     /* CMIC_SBUS_RING_MAP_32_39r -> 0x66666644 */
   8951     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_32_39r(unit, &rval));
   8952     if (rval != 0x66666644) {
   8953         LOG_ERROR(BSL_LS_SOC_COMMON,
   8954                   (BSL_META_U(unit,
   8955                               "Unit %d CMIC_SBUS_RING_MAP_32_39 mismatch:%x\n"),
   8956                    unit, rval));
   8957         return SOC_E_CONFIG;
   8958     }
   8959 
   8960     /* CMIC_SBUS_RING_MAP_40_47r -> 0x77776666 */
   8961     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_40_47r(unit, &rval));
   8962     if (rval != 0x77776666) {
   8963         LOG_ERROR(BSL_LS_SOC_COMMON,
   8964                   (BSL_META_U(unit,
   8965                               "Unit %d CMIC_SBUS_RING_MAP_40_47 mismatch:%x\n"),
   8966                    unit, rval));
   8967         return SOC_E_CONFIG;
   8968     }
   8969 
   8970     /* CMIC_SBUS_RING_MAP_48_55r -> 0x00777777 */
   8971     SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_48_55r(unit, &rval));
   8972     if (rval != 0x00777777) {
   8973         LOG_ERROR(BSL_LS_SOC_COMMON,
   8974                   (BSL_META_U(unit,
   8975                               "Unit %d CMIC_SBUS_RING_MAP_48_55 mismatch:%x\n"),
   8976                    unit, rval));
   8977         return SOC_E_CONFIG;
   8978     }
   8979 
   8980     if (!SOC_IS_TD2P_TT2P(unit)) {
   8981         /* CMIC_SBUS_RING_MAP_56_63r -> 0x00000550 */
   8982         SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_56_63r(unit, &rval));
   8983         if (rval != 0x00000550) {
   8984             LOG_ERROR(BSL_LS_SOC_COMMON,
   8985                       (BSL_META_U(unit,
   8986                                   "Unit %d CMIC_SBUS_RING_MAP_56_63 mismatch:%x\n"),
   8987                        unit, rval));
   8988             return SOC_E_CONFIG;
   8989         }
   8990     } else {
   8991         /*Adding AVS to ring 5*/
   8992         /* CMIC_SBUS_RING_MAP_56_63r -> 0x00005550 */
   8993         SOC_IF_ERROR_RETURN(READ_CMIC_SBUS_RING_MAP_56_63r(unit, &rval));
   8994         if (rval != 0x00005550) {
   8995             LOG_ERROR(BSL_LS_SOC_COMMON,
   8996                       (BSL_META_U(unit,
   8997                                   "Unit %d CMIC_SBUS_RING_MAP_56_63 mismatch:%x\n"),
   8998                        unit, rval));
   8999             return SOC_E_CONFIG;
   9000         }
   9001     }
   9002 
   9003     return SOC_E_NONE;
   9004 }
   9005 
   9006 int
   9007 soc_trident2_chip_reset(int unit)
   9008 {
   9009     soc_info_t *si;
   9010     uint16 dev_id;
   9011     uint8 rev_id;
   9012     int skew_id;
   9013     int max_frequency;
   9014     uint32 rval, to_usec;
   9015     soc_reg_t reg;
   9016     int index;
   9017     int num_ecmp_rh_flowset_entries;
   9018     int rh_table_config_encoding;
   9019     soc_field_t fields[4];
   9020     uint32 values[4];
   9021     int freq_list_len, sel;
   9022     int const *freq_list;
   9023 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   9024     int num_overlay_ecmp_rh_flowset_entries;
   9025     int rh_bank_sel = 0x0;
   9026     int ecmp_levels = 1;
   9027 #endif
   9028     static const soc_reg_t lcpll_ctrl1_reg[] = {
   9029         TOP_XG_PLL0_CTRL_1r, TOP_XG_PLL1_CTRL_1r,
   9030         TOP_XG_PLL2_CTRL_1r, TOP_XG_PLL3_CTRL_1r
   9031     };
   9032     static const soc_reg_t lcpll_ctrl2_reg[] = {
   9033         TOP_XG_PLL0_CTRL_2r, TOP_XG_PLL1_CTRL_2r,
   9034         TOP_XG_PLL2_CTRL_2r, TOP_XG_PLL3_CTRL_2r
   9035     };
   9036     static const soc_reg_t lcpll_ctrl3_reg[] = {
   9037         TOP_XG_PLL0_CTRL_3r, TOP_XG_PLL1_CTRL_3r,
   9038         TOP_XG_PLL2_CTRL_3r, TOP_XG_PLL3_CTRL_3r
   9039     };
   9040     static const soc_reg_t lcpll_ctrl4_reg[] = {
   9041         TOP_XG_PLL0_CTRL_4r, TOP_XG_PLL1_CTRL_4r,
   9042         TOP_XG_PLL2_CTRL_4r, TOP_XG_PLL3_CTRL_4r
   9043     };
   9044     static const soc_reg_t lcpll_status_reg[] = {
   9045         TOP_XG_PLL0_STATUSr, TOP_XG_PLL1_STATUSr,
   9046         TOP_XG_PLL2_STATUSr, TOP_XG_PLL3_STATUSr
   9047     };
   9048     soc_field_t top_soft_rst_field = TOP_TEMP_MON_PEAK_RST_Lf;
   9049 
   9050 
   9051     si = &SOC_INFO(unit);
   9052 
   9053 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9054     if (SOC_IS_TD2P_TT2P(unit)) {
   9055         top_soft_rst_field = TOP_PVT_MON_MIN_RST_Lf;
   9056     }
   9057 #endif
   9058 
   9059     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
   9060 
   9061     to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) :
   9062                                    (10 * MILLISECOND_USEC);
   9063 
   9064     /*             Trident 2
   9065      * SBUS ring and block number:
   9066      * ring 0: IP(1)
   9067      * ring 1: EP(2)
   9068      * ring 2: MMU(3)
   9069      * ring 3: PGW_CL0(6), CPORT0(14), XLPORT0(15)-XLPORT3(18)
   9070      *         PGW_CL1(7), CPORT1(19), XLPORT4(20)-XLPORT7(23)
   9071      * ring 4: PGW_CL2(8), CPORT2(24), XLPORT8(25)-XLPORT11(28)
   9072      *         PGW_CL3(9), CPORT3(29), XLPORT12(30)-XLPORT15(33)
   9073      * ring 5: OTPC(5), TOP(57), SER(58)
   9074      * ring 6: PGW_CL4(10), CPORT4(34), XLPORT16(35)-XLPORT19(38)
   9075      *         PGW_CL5(11), CPORT5(39), XLPORT20(40)-XLPORT23(43)
   9076      * ring 7: PGW_CL6(12), CPORT6(44), XLPORT24(45)-XLPORT27(48)
   9077      *         PGW_CL7(13), CPORT7(49), XLPORT28(50)-XLPORT31(53)
   9078      */
   9079 
   9080     /*             Trident 2+
   9081      * SBUS ring and block number:
   9082      * ring 0: IP(1)
   9083      * ring 1: EP(2)
   9084      * ring 2: MMU(3)
   9085      * ring 3: PGW_CL0(6), CPORT0(14), XLPORT0(15)-XLPORT3(18)
   9086      *         PGW_CL1(7), CPORT1(19), XLPORT4(20)-XLPORT7(23)
   9087      * ring 4: PGW_CL2(8), CPORT2(24), XLPORT8(25)-XLPORT11(28)
   9088      *         PGW_CL3(9), CPORT3(29), XLPORT12(30)-XLPORT15(33)
   9089      * ring 5: OTPC(4), TOP(57), SER(58), AVS(59)
   9090      * ring 6: PGW_CL4(10), CPORT4(34), XLPORT16(35)-XLPORT19(38)
   9091      *         PGW_CL5(11), CPORT5(39), XLPORT20(40)-XLPORT23(43)
   9092      * ring 7: PGW_CL6(12), CPORT6(44), XLPORT24(45)-XLPORT27(48)
   9093      *         PGW_CL7(13), CPORT7(49), XLPORT28(50)-XLPORT31(53)
   9094      *
   9095      *      OTPC  => {
   9096      *          REGBASE    => 0,
   9097      *          MEMBASE    => 0,
   9098      *          DESC       => 'OTP',
   9099      *          BLKTYPE    => OTPC,
   9100      *          SCHANNUM   => 4,
   9101      *          BLOCKNUM   => 4, <----
   9102      *          VENDOR     => 'BROADCOM',
   9103      *      },
   9104  */
   9105 
   9106     WRITE_CMIC_SBUS_RING_MAP_0_7r(unit, 0x33052100);
   9107     WRITE_CMIC_SBUS_RING_MAP_8_15r(unit, 0x33776644);
   9108     WRITE_CMIC_SBUS_RING_MAP_16_23r(unit, 0x33333333);
   9109     WRITE_CMIC_SBUS_RING_MAP_24_31r(unit, 0x44444444);
   9110     WRITE_CMIC_SBUS_RING_MAP_32_39r(unit, 0x66666644);
   9111     WRITE_CMIC_SBUS_RING_MAP_40_47r(unit, 0x77776666);
   9112     WRITE_CMIC_SBUS_RING_MAP_48_55r(unit, 0x00777777);
   9113     if (!SOC_IS_TD2P_TT2P(unit)) {
   9114         WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x00000550);
   9115     } else {
   9116         /*Adding AVS to ring 5*/
   9117         WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x00005550);
   9118     }
   9119 
   9120     /* Read CMIC_SBUS_RING_MAP_x_x back to check if writing is successful */
   9121     SOC_IF_ERROR_RETURN(soc_trident2_cmic_ring_map_check(unit));
   9122 
   9123     WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x7d0);
   9124 
   9125 #if defined(BCM_CMICM_SUPPORT)
   9126     if (soc_feature(unit, soc_feature_mcs)) {
   9127         /* Halt all uC cores */
   9128         READ_UC_0_RST_CONTROLr(unit, &rval);
   9129         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rval,
   9130                           BYPASS_RSTFSM_CTRLf, 1);
   9131         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rval,
   9132                           CPUHALT_Nf, 0);
   9133         WRITE_UC_0_RST_CONTROLr(unit, rval);
   9134 
   9135         READ_UC_1_RST_CONTROLr(unit, &rval);
   9136         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rval,
   9137                           CPUHALT_Nf, 0);
   9138         WRITE_UC_1_RST_CONTROLr(unit, rval);
   9139     }
   9140 #endif /* BCM_CMICM_SUPPORT */
   9141 
   9142     sal_usleep(to_usec);
   9143 
   9144 
   9145     SOC_IF_ERROR_RETURN(READ_TOP_DEV_REV_IDr(unit, &rval));
   9146     skew_id = soc_reg_field_get(unit, TOP_DEV_REV_IDr, rval, DEVICE_SKEWf);
   9147     SOC_IF_ERROR_RETURN
   9148         (soc_trident2_max_frequency_get(unit, dev_id, rev_id, skew_id,
   9149                                         &max_frequency));
   9150 
   9151     if (SOC_IS_TRIDENT2(unit)) {
   9152         if (rev_id <= BCM56850_A1_REV_ID) {
   9153             freq_list = a1_freq_list;
   9154             freq_list_len = sizeof(a1_freq_list) / sizeof(int);
   9155         } else {
   9156             if (max_frequency == 793) {
   9157                 freq_list = a2_793_freq_list;
   9158                 freq_list_len = sizeof(a2_793_freq_list) / sizeof(int);
   9159             } else {
   9160                 freq_list = a2_635_freq_list;
   9161                 freq_list_len = sizeof(a2_635_freq_list) / sizeof(int);
   9162             }
   9163         }
   9164     } else {
   9165         freq_list = a1_td2p_freq_list;
   9166         freq_list_len = sizeof(a1_td2p_freq_list) / sizeof(int);
   9167     }
   9168 
   9169     if ((si->frequency != max_frequency)
   9170         || (si->frequency != freq_list[0])) {
   9171         if (si->frequency > max_frequency) {
   9172             si->frequency = max_frequency;
   9173         }
   9174         for (sel = 1; sel < freq_list_len; sel++) { /* skip index 0 */
   9175             if (si->frequency == freq_list[sel]) {
   9176                 break;
   9177             }
   9178         }
   9179         if (sel < freq_list_len) {
   9180             LOG_CLI((BSL_META_U(unit,
   9181                                 "*** change CORE_CLK_FREQ_SEL to %d\n"), sel));
   9182             LOG_CLI((BSL_META_U(unit,
   9183                                 "*** change core clock frequency to %dMHz\n"),
   9184                      si->frequency));
   9185 
   9186             SOC_IF_ERROR_RETURN(READ_TOP_CORE_CLK_FREQ_SELr(unit, &rval));
   9187             soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval,
   9188                               SW_CORE_CLK_SEL_ENf, 1);
   9189             SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   9190             soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval,
   9191                               CORE_CLK_FREQ_SELf, sel);
   9192             SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   9193 
   9194             if (SOC_IS_TRIDENT2(unit)) {
   9195                 soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval, LOAD_ENf,
   9196                                   1);
   9197                 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   9198                 soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval, LOAD_ENf,
   9199                                   0);
   9200                 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   9201             }
   9202 
   9203             sal_usleep(to_usec);
   9204         }
   9205     }
   9206 
   9207     /* Program LCPLL frequency */
   9208     for (index = 0; index < 4; index++) {
   9209         SOC_IF_ERROR_RETURN
   9210             (soc_reg_field32_modify(unit, lcpll_ctrl1_reg[index],
   9211                                     REG_PORT_ANY, PDIVf, 7));
   9212         if (SOC_IS_TD2P_TT2P(unit)) {
   9213             SOC_IF_ERROR_RETURN
   9214                 (soc_reg_field32_modify(unit, lcpll_ctrl2_reg[index],
   9215                                     REG_PORT_ANY, NDIV_INTf, 140));
   9216         } else {
   9217             SOC_IF_ERROR_RETURN
   9218                 (soc_reg_field32_modify(unit, lcpll_ctrl3_reg[index],
   9219                                     REG_PORT_ANY, CML_BYP_ENf, 1));
   9220             SOC_IF_ERROR_RETURN
   9221                 (soc_reg_field32_modify(unit, lcpll_ctrl4_reg[index],
   9222                                     REG_PORT_ANY, NDIV_INTf, 140));
   9223         }
   9224     }
   9225     fields[0] = CMIC_TO_XG_PLL0_SW_OVWRf;
   9226     values[0] = 1;
   9227     fields[1] = CMIC_TO_XG_PLL1_SW_OVWRf;
   9228     values[1] = 1;
   9229     fields[2] = CMIC_TO_XG_PLL2_SW_OVWRf;
   9230     values[2] = 1;
   9231     fields[3] = CMIC_TO_XG_PLL3_SW_OVWRf;
   9232     values[3] = 1;
   9233     SOC_IF_ERROR_RETURN
   9234         (soc_reg_fields32_modify(unit, TOP_MISC_CONTROLr, REG_PORT_ANY, 4,
   9235                                  fields, values));
   9236 
   9237     rval = 0;
   9238 
   9239     /* Configure TS PLL */
   9240     if (SOC_IS_TD2P_TT2P(unit)) {
   9241         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit,&rval));
   9242         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, PDIVf,
   9243                       soc_property_get(unit, spn_PTP_TS_PLL_PDIV, 1));
   9244         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, CH0_MDIVf,
   9245                       soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, 14));
   9246         WRITE_TOP_TS_PLL_CTRL_3r(unit, rval);
   9247     } else {
   9248         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_2r(unit,&rval));
   9249         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_2r, &rval, PDIVf,
   9250                       soc_property_get(unit, spn_PTP_TS_PLL_PDIV, 1));
   9251         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_2r, &rval, CH0_MDIVf,
   9252                       soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, 14));
   9253         WRITE_TOP_TS_PLL_CTRL_2r(unit, rval);
   9254     }
   9255 
   9256     if (SOC_IS_TD2P_TT2P(unit)) {
   9257         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval));
   9258         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_INTf,
   9259                       soc_property_get(unit, spn_PTP_TS_PLL_N, 140));
   9260         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_FRACf, 0);
   9261         WRITE_TOP_TS_PLL_CTRL_4r(unit, rval);
   9262     } else {
   9263         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit,&rval));
   9264         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, NDIV_INTf,
   9265                       soc_property_get(unit, spn_PTP_TS_PLL_N, 140));
   9266         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, NDIV_FRACf, 0);
   9267         WRITE_TOP_TS_PLL_CTRL_3r(unit, rval);
   9268     }
   9269 
   9270     if (SOC_IS_TD2P_TT2P(unit)) {
   9271         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_5r(unit,&rval));
   9272         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KAf,
   9273                       soc_property_get(unit, spn_PTP_TS_KA, 0));
   9274         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KIf,
   9275                       soc_property_get(unit, spn_PTP_TS_KI, 2));
   9276         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KPf,
   9277                       soc_property_get(unit, spn_PTP_TS_KP, 3));
   9278         WRITE_TOP_TS_PLL_CTRL_5r(unit, rval);
   9279 
   9280         if (soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0) == 0) {
   9281             SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit,&rval));
   9282             soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, FREF_SELf, 0);
   9283             WRITE_TOP_TS_PLL_CTRL_1r(unit, rval);
   9284         } else {
   9285             SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit,&rval));
   9286             soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, FREF_SELf, 1);
   9287             WRITE_TOP_TS_PLL_CTRL_1r(unit, rval);
   9288         }
   9289     } else {
   9290         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval));
   9291         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, KAf,
   9292                       soc_property_get(unit, spn_PTP_TS_KA, 2));
   9293         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, KIf,
   9294                       soc_property_get(unit, spn_PTP_TS_KI, 4));
   9295         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, KPf,
   9296                       soc_property_get(unit, spn_PTP_TS_KP, 9));
   9297         if (soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0) == 0) {
   9298             soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, REFCLK_SELf, 0);
   9299         }
   9300         else {
   9301             soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, REFCLK_SELf, 1);
   9302         }
   9303         WRITE_TOP_TS_PLL_CTRL_4r(unit, rval);
   9304     }
   9305 
   9306     /* Set 250Mhz (implies 4ns resolution) default timesync clock to
   9307        calculate assymentric delays */
   9308     SOC_TIMESYNC_PLL_CLOCK_NS(unit) = (1/250 * 1000); /* clock period in nanoseconds */
   9309 
   9310     /* Configure BS PLL */
   9311     if (SOC_IS_TD2P_TT2P(unit)) {
   9312         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_0r(unit,&rval));
   9313         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_0r, &rval, VCO_FB_DIV2f,
   9314                       1);  /* soc_property_get(unit, spn_BROAD_SYNC_VCO_DIV2, 1)); */
   9315         WRITE_TOP_BS_PLL_CTRL_0r(unit, rval);
   9316     } else {
   9317         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_0r(unit,&rval));
   9318         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_0r, &rval, VCO_DIV2f,
   9319                       1);  /* soc_property_get(unit, spn_BROAD_SYNC_VCO_DIV2, 1)); */
   9320         WRITE_TOP_BS_PLL_CTRL_0r(unit, rval);
   9321     }
   9322 
   9323     if (SOC_IS_TD2P_TT2P(unit)) {
   9324         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_3r(unit,&rval));
   9325         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_3r, &rval, PDIVf,
   9326                       soc_property_get(unit, spn_PTP_BS_PDIV, 1));
   9327         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_3r, &rval, CH0_MDIVf,
   9328                       soc_property_get(unit, spn_PTP_BS_MNDIV, 175));
   9329         WRITE_TOP_BS_PLL_CTRL_3r(unit, rval);
   9330     } else {
   9331         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_2r(unit,&rval));
   9332         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_2r, &rval, PDIVf,
   9333                       soc_property_get(unit, spn_PTP_BS_PDIV, 1));
   9334         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_2r, &rval, CH0_MDIVf,
   9335                       soc_property_get(unit, spn_PTP_BS_MNDIV, 175));
   9336         WRITE_TOP_BS_PLL_CTRL_2r(unit, rval);
   9337     }
   9338 
   9339     if (SOC_IS_TD2P_TT2P(unit)) {
   9340         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_4r(unit,&rval));
   9341         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, NDIV_INTf, 140);
   9342         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, NDIV_FRACf, 0);
   9343         WRITE_TOP_BS_PLL_CTRL_4r(unit, rval);
   9344     } else {
   9345         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_3r(unit,&rval));
   9346         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_3r, &rval, NDIV_INTf, 140);
   9347         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_3r, &rval, NDIV_FRACf, 0);
   9348         WRITE_TOP_BS_PLL_CTRL_3r(unit, rval);
   9349     }
   9350 
   9351     if (SOC_IS_TD2P_TT2P(unit)) {
   9352         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_5r(unit,&rval));
   9353         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_5r, &rval, KAf,
   9354                       soc_property_get(unit, spn_PTP_BS_KA, 0));
   9355         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_5r, &rval, KIf,
   9356                       soc_property_get(unit, spn_PTP_BS_KI, 2));
   9357         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_5r, &rval, KPf,
   9358                       soc_property_get(unit, spn_PTP_BS_KP, 3));
   9359         WRITE_TOP_BS_PLL_CTRL_5r(unit, rval);
   9360 
   9361         if (soc_property_get(unit, spn_PTP_BS_FREF, 0) == 0) {
   9362             SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_1r(unit,&rval));
   9363             soc_reg_field_set(unit, TOP_BS_PLL_CTRL_1r, &rval, FREF_SELf, 0);
   9364             WRITE_TOP_BS_PLL_CTRL_1r(unit, rval);
   9365         } else {
   9366             SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_1r(unit,&rval));
   9367             soc_reg_field_set(unit, TOP_BS_PLL_CTRL_1r, &rval, FREF_SELf, 1);
   9368             WRITE_TOP_BS_PLL_CTRL_1r(unit, rval);
   9369         }
   9370     } else {
   9371         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL_CTRL_4r(unit,&rval));
   9372         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, KAf,
   9373                       soc_property_get(unit, spn_PTP_BS_KA, 2));
   9374         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, KIf,
   9375                       soc_property_get(unit, spn_PTP_BS_KI, 4));
   9376         soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, KPf,
   9377                       soc_property_get(unit, spn_PTP_BS_KP, 9));
   9378         if (soc_property_get(unit, spn_PTP_BS_FREF, 0) == 0) {
   9379             soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, REFCLK_SELf, 0);
   9380         }
   9381         else {
   9382             soc_reg_field_set(unit, TOP_BS_PLL_CTRL_4r, &rval, REFCLK_SELf, 1);
   9383         }
   9384         WRITE_TOP_BS_PLL_CTRL_4r(unit, rval);
   9385     }
   9386 
   9387     /* Bring LCPLL, time sync PLL, BroadSync PLL out of reset */
   9388     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit,&rval));
   9389     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf,
   9390                       1);
   9391     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf,
   9392                       1);
   9393     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL2_RST_Lf,
   9394                       1);
   9395     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL3_RST_Lf,
   9396                       1);
   9397     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf,
   9398                       1);
   9399     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL_RST_Lf,
   9400                       1);
   9401 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9402     if (SOC_IS_TD2P_TT2P(unit)) {
   9403         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_ARS_PMB_CLK_ENf,
   9404                       1);
   9405         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PMB_RST_Lf,
   9406                       1);
   9407         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_ARS_RST_Lf,
   9408                       1);
   9409         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf,
   9410                       1);
   9411     }
   9412 #endif
   9413 
   9414     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   9415 
   9416     sal_usleep(to_usec);
   9417 
   9418     if (!SAL_BOOT_SIMULATION) {
   9419         /* Check LCPLL lock status */
   9420         for (index = 0; index < 4; index++) {
   9421             reg = lcpll_status_reg[index];
   9422             SOC_IF_ERROR_RETURN
   9423                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9424             if (!soc_reg_field_get(unit, reg, rval, TOP_XGPLL_LOCKf)) {
   9425                 LOG_ERROR(BSL_LS_SOC_COMMON,
   9426                           (BSL_META_U(unit,
   9427                                       "LCPLL %d not locked on unit %d "
   9428                                       "status = 0x%08x\n"), index, unit, rval));
   9429             }
   9430         }
   9431         /* Check time sync lock status */
   9432         reg = TOP_TS_PLL_STATUSr;
   9433         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9434         if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) {
   9435             LOG_ERROR(BSL_LS_SOC_COMMON,
   9436                       (BSL_META_U(unit,
   9437                                   "TS_PLL not locked on unit %d "
   9438                                   "status = 0x%08x\n"), unit, rval));
   9439         }
   9440         /* Check BroadSync lock status */
   9441         reg = TOP_BS_PLL_STATUSr;
   9442         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9443         if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) {
   9444             LOG_ERROR(BSL_LS_SOC_COMMON,
   9445                       (BSL_META_U(unit,
   9446                                   "BS_PLL not locked on unit %d "
   9447                                   "status = 0x%08x\n"), unit, rval));
   9448         }
   9449 
   9450 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9451         if (SOC_IS_TD2P_TT2P(unit)) {
   9452             /* Check Core PLL lock status */
   9453             reg = TOP_CORE_PLL_STATUSr;
   9454             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9455             if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) {
   9456                 LOG_ERROR(BSL_LS_SOC_COMMON,
   9457                         (BSL_META_U(unit,
   9458                                     "CORE_PLL not locked on unit %d "
   9459                                     "status = 0x%08x\n"), unit, rval));
   9460             }
   9461             /* Check Mcs PLL lock status */
   9462             reg = TOP_MCS_PLL_STATUSr;
   9463             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9464             if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) {
   9465                 LOG_ERROR(BSL_LS_SOC_COMMON,
   9466                         (BSL_META_U(unit,
   9467                                     "MCS_PLL not locked on unit %d "
   9468                                     "status = 0x%08x\n"), unit, rval));
   9469             }
   9470         }
   9471 #endif
   9472     }
   9473 
   9474     /* De-assert LCPLL's post reset */
   9475     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   9476     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9477                       TOP_XG_PLL0_POST_RST_Lf, 1);
   9478     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9479                       TOP_XG_PLL1_POST_RST_Lf, 1);
   9480     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9481                       TOP_XG_PLL2_POST_RST_Lf, 1);
   9482     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9483                       TOP_XG_PLL3_POST_RST_Lf, 1);
   9484     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9485                       TOP_TS_PLL_POST_RST_Lf, 1);
   9486     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9487                       TOP_BS_PLL_POST_RST_Lf, 1);
   9488     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9489                       top_soft_rst_field, 1);
   9490     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   9491 
   9492     sal_usleep(to_usec);
   9493 
   9494     /* Bring port blocks out of reset */
   9495     rval = 0;
   9496     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP0_RST_Lf, 1);
   9497     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP1_RST_Lf, 1);
   9498     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP2_RST_Lf, 1);
   9499     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP3_RST_Lf, 1);
   9500     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP4_RST_Lf, 1);
   9501     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP5_RST_Lf, 1);
   9502     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP6_RST_Lf, 1);
   9503     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_CLP7_RST_Lf, 1);
   9504     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1);
   9505     WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   9506 
   9507     sal_usleep(to_usec);
   9508 
   9509     /* Bring IP, EP, and MMU blocks out of reset */
   9510     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval));
   9511     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1);
   9512     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1);
   9513     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1);
   9514     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval));
   9515 
   9516     sal_usleep(to_usec);
   9517 
   9518     num_ecmp_rh_flowset_entries = soc_property_get(unit,
   9519             spn_ECMP_RESILIENT_HASH_SIZE, 32768);
   9520     switch (num_ecmp_rh_flowset_entries) {
   9521         case 0:
   9522             rh_table_config_encoding = 2;
   9523             break;
   9524         case 32768:
   9525             rh_table_config_encoding = 0;
   9526             break;
   9527         case 65536:
   9528             rh_table_config_encoding = 1;
   9529             break;
   9530         default:
   9531             return SOC_E_CONFIG;
   9532     }
   9533 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   9534     ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1);
   9535     if ((soc_feature(unit, soc_feature_riot) ||
   9536          soc_feature(unit, soc_feature_multi_level_ecmp)) &&
   9537         ecmp_levels > 1) {
   9538 
   9539         num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit,
   9540             spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0);
   9541 
   9542         if (SOC_FIELD_RANGE_CHECK(
   9543             num_overlay_ecmp_rh_flowset_entries, 0, 16384)) {
   9544 
   9545             num_overlay_ecmp_rh_flowset_entries = 16384;
   9546         } else if (SOC_FIELD_RANGE_CHECK(
   9547             num_overlay_ecmp_rh_flowset_entries, 16384, 32768)) {
   9548 
   9549             num_overlay_ecmp_rh_flowset_entries = 32768;
   9550         } else if (SOC_FIELD_RANGE_CHECK(
   9551             num_overlay_ecmp_rh_flowset_entries, 32768, 49152)) {
   9552 
   9553             num_overlay_ecmp_rh_flowset_entries = 49152;
   9554         } else if (SOC_FIELD_RANGE_CHECK(
   9555             num_overlay_ecmp_rh_flowset_entries, 49152, 65536)) {
   9556 
   9557             num_overlay_ecmp_rh_flowset_entries = 65536;
   9558         }
   9559 
   9560         switch (num_overlay_ecmp_rh_flowset_entries) {
   9561         case 0:
   9562             rh_bank_sel = 0x0;
   9563             break;
   9564         case 16384:
   9565             if (num_ecmp_rh_flowset_entries >= 16384) {
   9566                 rh_bank_sel = 0x1;
   9567             } else {
   9568                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   9569                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   9570                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   9571                     num_overlay_ecmp_rh_flowset_entries));
   9572                 return SOC_E_CONFIG;
   9573             }
   9574             break;
   9575         case 32768:
   9576             if (num_ecmp_rh_flowset_entries >= 32768) {
   9577                 rh_bank_sel = 0x3;
   9578             } else {
   9579                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   9580                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   9581                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   9582                     num_overlay_ecmp_rh_flowset_entries));
   9583                 return SOC_E_CONFIG;
   9584             }
   9585             break;
   9586         case 49152:
   9587             if (num_ecmp_rh_flowset_entries >= 49152) {
   9588                 rh_bank_sel = 0x7;
   9589             } else {
   9590                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   9591                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   9592                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   9593                     num_overlay_ecmp_rh_flowset_entries));
   9594                 return SOC_E_CONFIG;
   9595             }
   9596             break;
   9597         case 65536:
   9598             if (num_ecmp_rh_flowset_entries >= 65536) {
   9599                 rh_bank_sel = 0xf;
   9600             } else {
   9601                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   9602                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   9603                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   9604                     num_overlay_ecmp_rh_flowset_entries));
   9605                 return SOC_E_CONFIG;
   9606             }
   9607             break;
   9608         default:
   9609                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   9610                     "%s: Value for overlay RH entries is not correct : %d \n"),
   9611                     FUNCTION_NAME(),  num_overlay_ecmp_rh_flowset_entries));
   9612             return SOC_E_CONFIG;
   9613     }
   9614     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, RH_ECMP_FLOWSET_BANK_SELr,
   9615                 REG_PORT_ANY, BANK_SELf,
   9616                 rh_bank_sel));
   9617   }
   9618 #endif
   9619 
   9620     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr,
   9621                 REG_PORT_ANY, RH_FLOWSET_TABLE_CONFIG_ENCODINGf,
   9622                 rh_table_config_encoding));
   9623 
   9624     if (SOC_IS_TD2P_TT2P(unit)) {
   9625         READ_TOP_PVTMON_CTRL_1r(unit, &rval);
   9626         soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
   9627         WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   9628         soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0);
   9629         WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   9630         soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
   9631         WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   9632     } else {
   9633         READ_TOP_PVTMON_CTRL_1r(unit, &rval);
   9634         soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 1);
   9635         WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   9636         soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 0);
   9637         WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   9638         soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 1);
   9639         WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   9640     }
   9641 
   9642     sal_usleep(1000);
   9643 
   9644     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   9645     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9646                   top_soft_rst_field, 0);
   9647     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   9648     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   9649                   top_soft_rst_field, 1);
   9650     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   9651 
   9652     /* Do not use SBUS MDIO by default */
   9653     SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = NULL;
   9654     SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = NULL;
   9655 
   9656     /* Optionally allow SBUS MDIO for debug */
   9657     if (soc_property_get(unit, "td2_sbus_mdio", SOC_IS_TD2P_TT2P(unit))) {
   9658         SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = _soc_trident2_mdio_reg_read;
   9659         SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = _soc_trident2_mdio_reg_write;
   9660     }
   9661 
   9662     if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED) &&
   9663         soc_feature(unit, soc_feature_turbo_boot)) {
   9664         SOC_HW_RESET_START(unit);
   9665     }
   9666 
   9667     return SOC_E_NONE;
   9668 }
   9669 
   9670 int
   9671 soc_trident2_tsc_reset(int unit)
   9672 {
   9673     int blk, port;
   9674     uint32 rval;
   9675 
   9676     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   9677         port = SOC_BLOCK_PORT(unit, blk);
   9678         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   9679     }
   9680 
   9681     /* TSC reset is controlled by PortMod internally */
   9682     if (SOC_USE_PORTCTRL(unit)) {
   9683         return SOC_E_NONE;
   9684     }
   9685 
   9686     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   9687         port = SOC_BLOCK_PORT(unit, blk);
   9688 
   9689         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval));
   9690         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1);
   9691         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   9692         sal_udelay(10);
   9693         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   9694         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   9695     }
   9696 
   9697     return SOC_E_NONE;
   9698 }
   9699 
   9700 STATIC int
   9701 _soc_trident2_clear_enabled_port_data(int unit)
   9702 {
   9703     uint32 rval;
   9704     uint64 rval64;
   9705     int port, block, pgw;
   9706     uint32 evc = 0;
   9707 
   9708     /* Some registers are implemented in memory, need to clear them in order
   9709      * to have correct parity value */
   9710     COMPILER_64_ZERO(rval64);
   9711     PBMP_ALL_ITER(unit, port) {
   9712 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9713         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   9714             egr_vlan_control_1_entry_t entry;
   9715             sal_memset(&entry, 0, sizeof(entry));
   9716             SOC_IF_ERROR_RETURN(
   9717                 WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry));
   9718         } else
   9719 #endif
   9720         {
   9721             SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, 0));
   9722         }
   9723 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9724         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   9725             egr_vlan_control_2_entry_t entry;
   9726             sal_memset(&entry, 0, sizeof(entry));
   9727             SOC_IF_ERROR_RETURN(
   9728                 WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry));
   9729         } else
   9730 #endif
   9731         {
   9732             SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_2r(unit, port, 0));
   9733         }
   9734 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9735         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   9736             egr_vlan_control_3_entry_t entry;
   9737             sal_memset(&entry, 0, sizeof(entry));
   9738             SOC_IF_ERROR_RETURN(
   9739                 WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry));
   9740         } else
   9741 #endif
   9742         {
   9743             SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_3r(unit, port, 0));
   9744         }
   9745         SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, 0));
   9746         SOC_IF_ERROR_RETURN(WRITE_EGR_SF_SRC_MODID_CHECKr(unit, port, rval64));
   9747         SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64));
   9748         SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_INVALID_CRC_FRAMESr(unit, port, 0));
   9749         SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_DELIMITER_ERROR_FRAMESr(unit, port, 0));
   9750         if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   9751             SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ALL, port, &evc));
   9752         } else {
   9753             SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2r(unit, port, 0));
   9754         }
   9755         SOC_IF_ERROR_RETURN(WRITE_ING_TRILL_ADJACENCYr(unit, port, rval64));
   9756         SOC_IF_ERROR_RETURN(WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0));
   9757         SOC_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, 0));
   9758     }
   9759     rval = 0;
   9760     soc_reg_field_set(unit, PGW_MIB_RESETr, &rval, CLR_CNTf, 0xffff);
   9761     for (pgw = 0; pgw < 8; pgw++) {
   9762         block = PGW_CL_BLOCK(unit, pgw);
   9763         port = SOC_BLOCK_PORT(unit, block);
   9764         if (port < 0) { /* the PGW_CL block is not in use */
   9765             continue;
   9766         }
   9767         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, PGW_MIB_RESETr, port, 0, rval));
   9768         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, PGW_MIB_RESETr, port, 0, 0));
   9769     }
   9770     return SOC_E_NONE;
   9771 }
   9772 
   9773 STATIC int
   9774 _soc_trident2_clear_all_port_data(int unit)
   9775 {
   9776     int r, p;
   9777     uint32 addr;
   9778 
   9779     SOC_IF_ERROR_RETURN(_soc_trident2_clear_enabled_port_data(unit));
   9780 
   9781     /* Clear TDBGCn regs for all indexes */
   9782     for (r = 0; r < 12; r++) {
   9783         addr = 0x28000000 + r*0x100;
   9784         for (p = 0; p < 106; p++) {
   9785             _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   9786             _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   9787         }
   9788     }
   9789 
   9790     /* Clear EGR_TRILL_TX_PKTS */
   9791     addr = 0x28000c00;
   9792     for (p = 0; p < 106; p++) {
   9793         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   9794         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   9795     }
   9796     /* Clear EGR_TRILL_TX_ACCESS_PORT_TRILL_PKTS_DISCARDED */
   9797     addr = 0x28000d00;
   9798     for (p = 0; p < 106; p++) {
   9799         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   9800         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   9801     }
   9802     /* Clear EGR_TRILL_TX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED */
   9803     addr = 0x28000e00;
   9804     for (p = 0; p < 106; p++) {
   9805         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   9806         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   9807     }
   9808     /* Clear TPCE */
   9809     addr = 0x28000f00;
   9810     for (p = 0; p < 106; p++) {
   9811         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   9812         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   9813     }
   9814     return SOC_E_NONE;
   9815 }
   9816 
   9817 STATIC int
   9818 _soc_trident2_clear_all_memory(int unit, int mmu_init)
   9819 {
   9820     uint32              rval, in_progress;
   9821     int                 pipe_init_usec, index, count;
   9822     soc_timeout_t       to;
   9823     static const struct {
   9824         soc_mem_t mem;
   9825         uint32 skip_flags; /* always skip on QUICKTURN or XGSSIM */
   9826     } cam_list[] = {
   9827         { CPU_COS_MAPm,                     BOOT_F_PLISIM },
   9828         { EFP_TCAMm,                        BOOT_F_PLISIM },
   9829         { FP_GLOBAL_MASK_TCAMm,             BOOT_F_PLISIM },
   9830         { FP_TCAMm,                         BOOT_F_PLISIM },
   9831         { FP_UDF_TCAMm,                     BOOT_F_PLISIM },
   9832         { ING_SNATm,                        BOOT_F_PLISIM },
   9833         { IP_MULTICAST_TCAMm,               BOOT_F_PLISIM },
   9834         { L2_USER_ENTRYm,                   BOOT_F_PLISIM },
   9835         { L3_DEFIPm,                        BOOT_F_PLISIM },
   9836         { L3_DEFIP_PAIR_128m,               BOOT_F_PLISIM },
   9837         { L3_TUNNELm,                       BOOT_F_PLISIM },
   9838         { MY_STATION_TCAMm,                 BOOT_F_PLISIM },
   9839         { UDF_CONDITIONAL_CHECK_TABLE_CAMm, BOOT_F_PLISIM },
   9840         { VFP_TCAMm,                        BOOT_F_PLISIM },
   9841         { VLAN_SUBNETm,                     0 },/* VLAN API needs all 0 mask */
   9842 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9843         { MY_STATION_TCAM_2m,               BOOT_F_PLISIM },
   9844         { SUBPORT_TAG_SGPP_MAPm,            BOOT_F_PLISIM },
   9845 #endif
   9846 #ifdef PLISIM
   9847         /* In HW, these are the same as FP_GLOBAL_MASK_TCAM.
   9848          * In simulation, they are separate instances.
   9849          */
   9850         { FP_GM_FIELDSm,                    BOOT_F_PLISIM },
   9851         { FP_GLOBAL_MASK_TCAM_Xm,           BOOT_F_PLISIM },
   9852         { FP_GLOBAL_MASK_TCAM_Ym,           BOOT_F_PLISIM }
   9853 #endif
   9854     };
   9855 
   9856     if (mmu_init) {
   9857         /* Start MMU memory initialization */
   9858         SOC_IF_ERROR_RETURN
   9859             (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 0));
   9860         SOC_IF_ERROR_RETURN
   9861             (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 1));
   9862         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Allow things to stabalize */
   9863     }
   9864     SOC_IF_ERROR_RETURN
   9865         (_soc_trident2_mmu_init_default_val(unit));
   9866 
   9867     /*
   9868      * Reset the IPIPE and EPIPE block
   9869      */
   9870     rval = 0;
   9871     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   9872     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1);
   9873     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1);
   9874     /* Set count to # entries of largest IPIPE table */
   9875     count = soc_mem_index_count(unit, RH_HGT_FLOWSETm);
   9876     if (count < soc_mem_index_count(unit, L2Xm)) {
   9877         count = soc_mem_index_count(unit, L2Xm);
   9878     }
   9879     if (count < soc_mem_index_count(unit, L3_ENTRY_ONLYm)) {
   9880         count = soc_mem_index_count(unit, L3_ENTRY_ONLYm);
   9881     }
   9882     if (count < soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) {
   9883         count = soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m);
   9884     }
   9885     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, count);
   9886     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   9887 
   9888     rval = 0;
   9889     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   9890     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1);
   9891     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1);
   9892     /* Set count to # entries of largest EPIPE table (EGR_L3_NEXT_HOP) */
   9893     count = soc_mem_index_count(unit, EGR_L3_NEXT_HOPm);
   9894     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, count);
   9895     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   9896 
   9897     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   9898     if (SAL_BOOT_SIMULATION) {
   9899         pipe_init_usec = 10000000;
   9900     } else {
   9901         pipe_init_usec = 50000;
   9902     }
   9903     soc_timeout_init(&to, pipe_init_usec, 0);
   9904 
   9905     /* Wait for IPIPE memory initialization done. */
   9906     in_progress = 3;
   9907     do {
   9908         if (in_progress & 0x1) { /* X pipe not done yet */
   9909             SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2_Xr(unit, &rval));
   9910             if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2_Xr, rval,
   9911                                   DONEf)) {
   9912                 in_progress &= ~0x1;
   9913             }
   9914         }
   9915         if (in_progress & 0x2) { /* Y pipe not done yet */
   9916             SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2_Yr(unit, &rval));
   9917             if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2_Yr, rval,
   9918                                   DONEf)) {
   9919                 in_progress &= ~0x2;
   9920             }
   9921         }
   9922         if (soc_timeout_check(&to)) {
   9923             if (in_progress != 0) {
   9924                 LOG_WARN(BSL_LS_SOC_COMMON,
   9925                          (BSL_META_U(unit,
   9926                                      "unit %d : ING_HW_RESET timeout\n"),
   9927                          unit));
   9928             }
   9929             break;
   9930         }
   9931     } while (in_progress != 0);
   9932 
   9933     /* Wait for EPIPE memory initialization done. */
   9934     in_progress = 3;
   9935     do {
   9936         if (in_progress & 0x1) { /* X pipe not done yet */
   9937             SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1_Xr(unit, &rval));
   9938             if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1_Xr, rval,
   9939                                   DONEf)) {
   9940                 in_progress &= ~0x1;
   9941             }
   9942         }
   9943         if (in_progress & 0x2) { /* Y pipe not done yet */
   9944             SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1_Yr(unit, &rval));
   9945             if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1_Yr, rval,
   9946                                   DONEf)) {
   9947                 in_progress &= ~0x2;
   9948             }
   9949         }
   9950         if (soc_timeout_check(&to)) {
   9951             if (in_progress != 0) {
   9952                 LOG_WARN(BSL_LS_SOC_COMMON,
   9953                          (BSL_META_U(unit,
   9954                                      "unit %d : EGR_HW_RESET timeout\n"),
   9955                          unit));
   9956             }
   9957             break;
   9958         }
   9959     } while (in_progress != 0);
   9960 
   9961     rval = 0;
   9962     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   9963     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   9964 
   9965     /* TCAM tables are not handled by hardware reset control */
   9966     if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_XGSSIM) {
   9967         for (index = 0; index < sizeof(cam_list) / sizeof(cam_list[0]);
   9968              index++) {
   9969             if (sal_boot_flags_get() & cam_list[index].skip_flags) {
   9970                 continue;
   9971             }
   9972 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9973             if (!SOC_IS_TD2P_TT2P(unit) &&
   9974             	  ((cam_list[index].mem == MY_STATION_TCAM_2m) ||
   9975             	   (cam_list[index].mem == SUBPORT_TAG_SGPP_MAPm))) {
   9976                 continue;
   9977             }
   9978 #endif
   9979             SOC_IF_ERROR_RETURN
   9980                 (soc_mem_clear(unit, cam_list[index].mem, COPYNO_ALL, TRUE));
   9981         }
   9982     }
   9983 
   9984     return SOC_E_NONE;
   9985 }
   9986 
   9987 #if defined(BCM_WARM_BOOT_SUPPORT) && defined(BCM_TRIDENT2PLUS_SUPPORT)
   9988 /*
   9989  * IFP Logical to Physical mapping warmboot recovery.
   9990  */
   9991 STATIC int
   9992 _soc_td2p_log_to_ifp_mapping_recover(int unit)
   9993 {
   9994     int num_ports;
   9995     int ifp_port;
   9996     soc_port_t port;
   9997     uint32 y_pipe, valid, rval;
   9998 
   9999     /* Ingress logical to physical port mapping */
  10000     num_ports = soc_mem_index_count(unit, PORT_TABm) - 1;
  10001 
  10002     for (port = 0; port < num_ports; port++) {
  10003         rval = 0;
  10004         SOC_IF_ERROR_RETURN
  10005          (READ_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, &rval));
  10006         if (rval == 0) {
  10007            soc_td2p_log_to_ifp_port[unit].ifp_x_port[port] = -1;
  10008            soc_td2p_log_to_ifp_port[unit].ifp_y_port[port] = -1;
  10009            soc_td2p_log_to_ifp_port[unit].valid_x[port] = 0;
  10010            soc_td2p_log_to_ifp_port[unit].valid_y[port] = 0;
  10011            continue;
  10012         }
  10013 
  10014         y_pipe = soc_reg_field_get(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr,
  10015                                    rval, Y_PIPEf);
  10016 
  10017         ifp_port = soc_reg_field_get(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr,
  10018                                      rval, PHYSICAL_PORT_NUMf);
  10019 
  10020         valid = soc_reg_field_get(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr,
  10021                                   rval, VALIDf);
  10022         if (y_pipe) {
  10023            soc_td2p_log_to_ifp_port[unit].ifp_y_port[port] = ifp_port;
  10024            soc_td2p_log_to_ifp_port[unit].valid_y[port] = valid;
  10025            if (ifp_port > soc_td2p_log_to_ifp_port[unit].last_valid_y_port) {
  10026               soc_td2p_log_to_ifp_port[unit].last_valid_y_port = ifp_port;
  10027            }
  10028 
  10029            soc_td2p_log_to_ifp_port[unit].ifp_x_port[port] = -1;
  10030            soc_td2p_log_to_ifp_port[unit].valid_x[port] = 0;
  10031         } else {
  10032            soc_td2p_log_to_ifp_port[unit].ifp_x_port[port] = ifp_port;
  10033            soc_td2p_log_to_ifp_port[unit].valid_x[port] = valid;
  10034            if (ifp_port > soc_td2p_log_to_ifp_port[unit].last_valid_x_port) {
  10035               soc_td2p_log_to_ifp_port[unit].last_valid_x_port = ifp_port;
  10036            }
  10037 
  10038            soc_td2p_log_to_ifp_port[unit].ifp_y_port[port] = -1;
  10039            soc_td2p_log_to_ifp_port[unit].valid_y[port] = 0;
  10040         }
  10041     }
  10042 
  10043     return SOC_E_NONE;
  10044 }
  10045 #endif /* (BCM_WARM_BOOT_SUPPORT) && (BCM_TRIDENT2PLUS_SUPPORT) */
  10046 
  10047 
  10048 STATIC int
  10049 _soc_trident2_port_mapping_init(int unit)
  10050 {
  10051     soc_info_t *si;
  10052     soc_mem_t mem;
  10053     uint32 rval;
  10054     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
  10055     int port, phy_port;
  10056     int num_port, num_phy_port;
  10057     int ifp_port = -1;
  10058     si = &SOC_INFO(unit);
  10059 
  10060     /* Ingress physical to logical port mapping */
  10061     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
  10062     num_phy_port = soc_mem_index_count(unit, mem);
  10063     sal_memset(&entry, 0, sizeof(entry));
  10064     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
  10065         port = si->port_p2l_mapping[phy_port];
  10066         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
  10067                             port == -1 ? 0x7f : port);
  10068         SOC_IF_ERROR_RETURN
  10069             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry));
  10070     }
  10071 
  10072     /* Ingress logical to physical port mapping */
  10073     num_port = soc_mem_index_count(unit, PORT_TABm) - 1;
  10074 
  10075     /* Egress logical to physical port mapping */
  10076     for (port = 0; port < num_port; port++) {
  10077         phy_port = si->port_l2p_mapping[port];
  10078         rval = 0;
  10079         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
  10080                           &rval, PHYSICAL_PORT_NUMBERf,
  10081                           phy_port == -1 ? 0xff : phy_port);
  10082         SOC_IF_ERROR_RETURN
  10083             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
  10084                                                                 rval));
  10085     }
  10086 
  10087     /* MMU to physical port mapping and MMU to logical port mapping */
  10088     for (port = 0; port < num_port; port++) {
  10089         phy_port = si->port_l2p_mapping[port];
  10090         if (phy_port == -1) {
  10091             continue;
  10092         }
  10093         rval = 0;
  10094         soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval,
  10095                           PHY_PORTf, phy_port);
  10096         SOC_IF_ERROR_RETURN
  10097             (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, port, 0,
  10098                            rval));
  10099 
  10100         rval = 0;
  10101         soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval,
  10102                           LOGIC_PORTf, port);
  10103         SOC_IF_ERROR_RETURN
  10104             (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, port, 0,
  10105                            rval));
  10106     }
  10107 
  10108 #if defined BCM_TRIDENT2PLUS_SUPPORT
  10109     /*
  10110      * Maintaining a mapping database which holds unique stream IDs
  10111      * for all the valid logical ports for X and Y pipe.
  10112      * Reason to maintain a mapping database:
  10113      * Earlier, MMU port is been used as a merely unqiue stream ID.
  10114      * During flex operation, a new MMU port is been assigned to a logical port
  10115      * due to which the PHYSICAL_PORT_NUM of a IFP_GM mapping register is getting
  10116      * modified to a new stream ID, which invalids the IPBM/IPBM_MASK fields of
  10117      * FP_GLOBAL_MASK_TCAM.
  10118      */
  10119     if (SOC_IS_TRIDENT2PLUS(unit)) {
  10120         int ifp_x_port = 0;
  10121         int ifp_y_port=0;
  10122         int y_pipe=0;
  10123 
  10124         ifp_port = 0;
  10125 #ifdef BCM_WARM_BOOT_SUPPORT
  10126         if (SOC_WARM_BOOT(unit)) {
  10127            return _soc_td2p_log_to_ifp_mapping_recover(unit);
  10128         }
  10129 #endif /* BCM_WARM_BOOT_SUPPORT */
  10130         LOG_DEBUG(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
  10131                   "lport pport IFP_Port Y-Pipe\n\r")));
  10132         LOG_DEBUG(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
  10133                   "===== ===== ======== ======\n\r")));
  10134         for (port = 0; port < num_port; port++) {
  10135            /* Initialize IFP ports as per logical ports */
  10136            if (SOC_PBMP_MEMBER(si->ypipe_pbm, port)) { /* Y-pipe */
  10137               soc_td2p_log_to_ifp_port[unit].ifp_y_port[port] = ifp_y_port;
  10138               soc_td2p_log_to_ifp_port[unit].valid_y[port] = 1;
  10139               soc_td2p_log_to_ifp_port[unit].valid_x[port] = 0;
  10140               soc_td2p_log_to_ifp_port[unit].ifp_x_port[port] = -1;
  10141               ifp_port = ifp_y_port;
  10142               ifp_y_port++;
  10143               y_pipe = 1;
  10144            } else if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X-pipe */
  10145               soc_td2p_log_to_ifp_port[unit].ifp_x_port[port] = ifp_x_port;
  10146               soc_td2p_log_to_ifp_port[unit].valid_x[port] = 1;
  10147               soc_td2p_log_to_ifp_port[unit].valid_y[port] = 0;
  10148               soc_td2p_log_to_ifp_port[unit].ifp_y_port[port] = -1;
  10149               ifp_port = ifp_x_port;
  10150               ifp_x_port++;
  10151               y_pipe = 0;
  10152            } else {
  10153               soc_td2p_log_to_ifp_port[unit].valid_x[port] = 0;
  10154               soc_td2p_log_to_ifp_port[unit].valid_y[port] = 0;
  10155               ifp_port = -1;
  10156               soc_td2p_log_to_ifp_port[unit].ifp_x_port[port] = -1;
  10157               soc_td2p_log_to_ifp_port[unit].ifp_y_port[port] = -1;
  10158            }
  10159            LOG_DEBUG(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
  10160                      "%02d  %02d  %02d     %d    \n\r"), port,
  10161                       si->port_l2p_mapping[port], ifp_port, y_pipe));
  10162         }
  10163         soc_td2p_log_to_ifp_port[unit].last_valid_x_port = ifp_x_port - 1;
  10164         soc_td2p_log_to_ifp_port[unit].last_valid_y_port = ifp_y_port - 1;
  10165     }
  10166 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  10167     for (port = 0; port < num_port; port++) {
  10168         phy_port = si->port_l2p_mapping[port];
  10169         rval = 0;
  10170         if (phy_port != -1) {
  10171             soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
  10172                               VALIDf, 1);
  10173 
  10174             if (SOC_PBMP_MEMBER(si->ypipe_pbm, port)) { /* Y-pipe */
  10175                 soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr,
  10176                                   &rval, Y_PIPEf, 1);
  10177             }
  10178 
  10179             /* IFP_GM_LOGICAL_TO_PHYSICAL_MAPP?ING.PHYSICAL_PORT_NUM is
  10180              * merely a unique stream ID, it's not physical port number */
  10181 #if defined BCM_TRIDENT2PLUS_SUPPORT
  10182             if (SOC_IS_TRIDENT2PLUS(unit)) {
  10183                if (soc_td2p_log_to_ifp_port[unit].valid_y[port] == 0) {
  10184                    ifp_port = soc_td2p_log_to_ifp_port[unit].ifp_x_port[port];
  10185                } else {
  10186                    ifp_port = soc_td2p_log_to_ifp_port[unit].ifp_y_port[port];
  10187                }
  10188             } else
  10189 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  10190             {
  10191                ifp_port = si->port_p2m_mapping[phy_port];
  10192             }
  10193 
  10194             soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
  10195                               PHYSICAL_PORT_NUMf, ifp_port & 0x3f);
  10196         }
  10197         SOC_IF_ERROR_RETURN(
  10198             WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval));
  10199     }
  10200 
  10201 
  10202     return SOC_E_NONE;
  10203 }
  10204 
  10205 void
  10206 _soc_trident2_quad_bandwidth_calculate(int unit, int quad,
  10207                                        int *max_quad_core_bandwidth,
  10208                                        int *quad_linerate_bandwidth,
  10209                                        int *quad_oversub_bandwidth)
  10210 {
  10211     soc_info_t *si;
  10212     int port, phy_port, index;
  10213     int bandwidth;
  10214 
  10215     si = &SOC_INFO(unit);
  10216 
  10217     if (si->bandwidth == 720000) {
  10218         *max_quad_core_bandwidth = quad == 0 || quad == 3 ? 160000 : 200000;
  10219     } else {
  10220         *max_quad_core_bandwidth = si->bandwidth / 4;
  10221     }
  10222     *quad_linerate_bandwidth = 0;
  10223     *quad_oversub_bandwidth = 0;
  10224     for (index = 0; index < _TD2_PORTS_PER_QUAD; index++) {
  10225         phy_port = 1 + quad * _TD2_PORTS_PER_QUAD + index;
  10226         port = si->port_p2l_mapping[phy_port];
  10227         if (port == -1) {
  10228             continue;
  10229         }
  10230         if (si->port_speed_max[port] > 40000) {
  10231            bandwidth = 100000;
  10232         } else if (si->port_speed_max[port] > 20000) {
  10233             bandwidth = 40000;
  10234         } else if (si->port_speed_max[port] > 10000) {
  10235             bandwidth = 20000;
  10236         } else {
  10237             bandwidth = 10000;
  10238         }
  10239         if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) {
  10240             *quad_oversub_bandwidth += bandwidth;
  10241         } else {
  10242             *quad_linerate_bandwidth += bandwidth;
  10243         }
  10244     }
  10245 }
  10246 
  10247 #define MGM_TOKEN (NUM_EXT_PORTS+3)
  10248 
  10249 _soc_trident2_tdm_t *_soc_td2_tdm[SOC_MAX_NUM_DEVICES];
  10250 
  10251 /*
  10252  * Function:
  10253  *      soc_td2_td2p_tdm_sched_info_get
  10254  * Description:
  10255  *      Get handle of TDM data.
  10256  * Parameters:
  10257  *      unit    - Device number
  10258  *      create  - When set, alloc container if necessary.
  10259  * Return:
  10260  *      NULL    - If alloc failed or no TDM data without creation.
  10261  *      data handler.
  10262  */
  10263 _soc_trident2_tdm_t *soc_td2_td2p_tdm_sched_info_get(int unit, int create)
  10264 {
  10265     _soc_trident2_tdm_t *tdm = NULL;
  10266 
  10267     tdm = _soc_td2_tdm[unit];
  10268     if (tdm == NULL) {
  10269         if (create) {
  10270             tdm = sal_alloc(sizeof(_soc_trident2_tdm_t), "Trident2 TDM info");
  10271             if (tdm == NULL) {
  10272                 return NULL;
  10273             }
  10274             sal_memset(tdm, 0, sizeof(_soc_trident2_tdm_t));
  10275             _soc_td2_tdm[unit] = tdm;
  10276         } else {
  10277             return NULL;
  10278         }
  10279     } else {
  10280         if (create) {
  10281             sal_memset(tdm, 0, sizeof(_soc_trident2_tdm_t));
  10282         }
  10283     }
  10284 
  10285     return tdm;
  10286 }
  10287 
  10288 int
  10289 soc_trident2_get_prio_map(int unit, int port, uint16 *pri_mask)
  10290 {
  10291     char name[80];
  10292     int  pri_to_prigroup[16];
  10293     int  prio;
  10294 
  10295     if (NULL == pri_mask) {
  10296         return SOC_E_PARAM;
  10297     }
  10298 
  10299     /* internal priority to priority group mapping */
  10300     sal_sprintf(name, "%s.%s.%s.%s", spn_BUF, spn_MAP, spn_PRI, spn_PRIGROUP);
  10301 
  10302     sal_memset(pri_to_prigroup, 0, sizeof(pri_to_prigroup));
  10303 
  10304     /* OBM Priority Map configuration needs to be in sync with MMU
  10305      * configuration. If the config property is set use the prigroup map.
  10306      * else use the default lossless setting.
  10307      */
  10308     if (soc_property_port_get_csv(unit, port, name,
  10309                                   (_SOC_TD2_MAX_INTERNAL_PRIORITY + 1),
  10310                                   pri_to_prigroup)) {
  10311         *pri_mask = 0;
  10312         for (prio=0; prio <= _SOC_TD2_MAX_INTERNAL_PRIORITY; prio++) {
  10313             /*  PG7 (_SOC_TD2_MAX_PRIORITY) is mapped to Lossless priority,
  10314              *  If the config priority is lossless priority, Then Flow control
  10315              *  is enabled.
  10316              */
  10317             if (pri_to_prigroup[prio] == _SOC_TD2_MAX_PRIORITY) {
  10318                 *pri_mask |= 1 << prio;
  10319             }
  10320         }
  10321     }
  10322     return SOC_E_NONE;
  10323 }
  10324 
  10325 int
  10326 soc_td2_obm_ctrl_reg_default_set (int unit, int xlp, int port_index, int obm_inst,
  10327                                   int oversub, int default_flag)
  10328 {
  10329     soc_reg_t reg;
  10330     uint64 ctrl_rval64;
  10331     reg = td2_pgw_obm_ctrl_regs[xlp];
  10332     SOC_IF_ERROR_RETURN
  10333         (soc_reg_get(unit, reg, obm_inst, 0, &ctrl_rval64));
  10334     if ( PGW_OBM_INIT_HW_DEFAULT == default_flag ) {
  10335         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10336                               td2_pgw_obm_oversub_fields[port_index],0);
  10337         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10338                               td2_pgw_obm_bypass_fields[port_index], 1);
  10339         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10340                               OVERSUB_HEADROOM_ENABLEf, 1);
  10341     } else {
  10342         uint8 rev_id;
  10343         soc_cm_get_id_otp(unit, NULL, &rev_id);
  10344         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10345                               td2_pgw_obm_oversub_fields[port_index],
  10346                              (oversub ? 1 : 0));
  10347         /* Do not allow OBM bypass if the oversubscribed
  10348          * XLPORT block has more than 1 port configured */
  10349         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10350                               td2_pgw_obm_bypass_fields[port_index],
  10351                               (oversub ? 0 : 1));
  10352         if (SOC_IS_TD2P_TT2P(unit) || (rev_id > BCM56850_A1_REV_ID)) {
  10353             soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10354                                   OVERSUB_HEADROOM_ENABLEf, 0);
  10355         }
  10356     }
  10357     SOC_IF_ERROR_RETURN
  10358         (soc_reg_set(unit, reg, obm_inst, 0, ctrl_rval64));
  10359 
  10360     return SOC_E_NONE;
  10361 }
  10362 
  10363 int
  10364 soc_td2_obm_use_counter_reg_default_set (int unit, int xlp, int port_index,
  10365                                          int obm_inst)
  10366 {
  10367     soc_reg_t reg;
  10368     uint64 ctrl_rval64;
  10369     reg = td2_pgw_obm_use_counter_regs[xlp];
  10370     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, port_index,
  10371                                     &ctrl_rval64));
  10372     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10373                           td2_pgw_obm_use_count_fields[port_index], 0);
  10374     SOC_IF_ERROR_RETURN
  10375         (soc_reg_set(unit, reg, obm_inst, port_index, ctrl_rval64));
  10376 
  10377     return SOC_E_NONE;
  10378 }
  10379 
  10380 int
  10381 soc_td2_obm_shared_config_reg_default_set (int unit, int xlp, int port_index,
  10382                                            int obm_inst, int default_flag)
  10383 {
  10384     soc_reg_t reg;
  10385     uint64 ctrl_rval64;
  10386     reg = td2_pgw_obm_shared_config_regs[xlp];
  10387     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, port_index,
  10388                                     &ctrl_rval64));
  10389     if ( PGW_OBM_INIT_HW_DEFAULT == default_flag ) {
  10390         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10391                               SHARED_POOL_SIZEf, 0x280);
  10392     } else {
  10393         uint8 rev_id;
  10394         soc_cm_get_id_otp(unit, NULL, &rev_id);
  10395         if (!SOC_IS_TD2P_TT2P(unit) && (rev_id <= BCM56850_A1_REV_ID)) {
  10396             soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10397                                   SHARED_POOL_SIZEf, 0);
  10398         } else {
  10399             soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10400                                   SHARED_POOL_SIZEf, GET_NUM_CELLS_PER_OBM(unit));
  10401         }
  10402     }
  10403     SOC_IF_ERROR_RETURN
  10404         (soc_reg_set(unit, reg, obm_inst, port_index, ctrl_rval64));
  10405 
  10406     return SOC_E_NONE;
  10407 }
  10408 
  10409 int
  10410 soc_td2_obm_max_usage_reg_default_set (int unit, int xlp, int port_index,
  10411                                        int obm_inst)
  10412 {
  10413     soc_reg_t reg;
  10414     uint64 ctrl_rval64;
  10415     reg = td2_pgw_obm_max_usage_regs[xlp];
  10416     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, port_index,
  10417                                     &ctrl_rval64));
  10418     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10419                           td2_pgw_obm_max_usage_fields[port_index], 0);
  10420     SOC_IF_ERROR_RETURN
  10421         (soc_reg_set(unit, reg, obm_inst, port_index, ctrl_rval64));
  10422 
  10423     return SOC_E_NONE;
  10424 }
  10425 
  10426 int
  10427 soc_td2_obm_fc_config_reg_default_set (int unit, int xlp, int port_index,
  10428                                        int obm_inst, int logical_port,
  10429                                        int oversub, int default_flag)
  10430 {
  10431     soc_reg_t reg;
  10432     uint64 ctrl_rval64;
  10433     int reg_index;
  10434     uint16 pri_mask;
  10435 
  10436     if (logical_port == -1) {
  10437         return SOC_E_NONE;
  10438     }
  10439 
  10440     reg_index = xlp * _TD2_PORTS_PER_XLP + port_index;
  10441     reg = td2_pgw_obm_fc_config_regs[reg_index];
  10442 
  10443     COMPILER_64_ZERO(ctrl_rval64);
  10444     if ( PGW_OBM_INIT_HW_DEFAULT == default_flag || !oversub ) {
  10445         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10446                               PORT_FC_ENABLEf, 0);
  10447     } else {
  10448         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10449                               PORT_FC_ENABLEf, 1);
  10450     }
  10451     pri_mask = 0xffff;
  10452     if (PGW_OBM_INIT_HW_DEFAULT == default_flag){
  10453         pri_mask = 0xfffc;
  10454     } else if (soc_feature(unit, soc_feature_prigrp_to_obm_prio_map)) {
  10455         SOC_IF_ERROR_RETURN
  10456             (soc_trident2_get_prio_map(
  10457                               unit,
  10458                               logical_port,
  10459                               &pri_mask));
  10460     }
  10461     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10462                       PRIORITY_PROFILE_FCf, pri_mask);
  10463 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10464     /* This field controls the frequence of XOFF status sent to
  10465      * the xlmac is refreshed. units=250ns.
  10466      */
  10467     if (SOC_IS_TD2P_TT2P(unit)) {
  10468         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  10469                           XOFF_REFRESH_TIMERf, 0x100);
  10470     }
  10471 #endif
  10472     SOC_IF_ERROR_RETURN
  10473         (soc_reg_set(unit, reg, obm_inst, 0, ctrl_rval64));
  10474 
  10475     return SOC_E_NONE;
  10476 }
  10477 
  10478 int
  10479 soc_td2_obm_counters_reset(int unit, soc_port_t port)
  10480 {
  10481     soc_info_t *si;
  10482     soc_port_t phy_port;
  10483     int i, xlp_blk, xlp_bindex = -1, pgw_blk, pgw_bindex = -1;
  10484     int xlp_port;
  10485     soc_reg_t obm_counter_regs[4][4] = {
  10486         {SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI,
  10487          SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI,
  10488          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI,
  10489          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI},
  10490         {SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI,
  10491          SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI,
  10492          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI,
  10493          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI},
  10494         {SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI,
  10495          SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI,
  10496          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI,
  10497          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI},
  10498         {SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI,
  10499          SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI,
  10500          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI,
  10501          SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI}
  10502     };
  10503     soc_reg_t *counter_reg;
  10504     uint64 my_zero;
  10505 
  10506     si = &SOC_INFO(unit);
  10507 
  10508     phy_port = si->port_l2p_mapping[port];
  10509     for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
  10510         xlp_blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
  10511         xlp_bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
  10512         if (SOC_BLOCK_INFO(unit, xlp_blk).type == SOC_BLK_XLPORT) {
  10513             break;
  10514         }
  10515     }
  10516     for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
  10517         pgw_blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
  10518         pgw_bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
  10519         if (SOC_BLOCK_INFO(unit, pgw_blk).type == SOC_BLK_PGW_CL) {
  10520             break;
  10521         }
  10522     }
  10523     xlp_port = xlp_bindex;
  10524 
  10525     switch (pgw_bindex % 16) {
  10526     case 0:
  10527     case 1:
  10528     case 2:
  10529     case 3:
  10530         counter_reg = obm_counter_regs[0];
  10531         break;
  10532     case 4:
  10533     case 5:
  10534     case 6:
  10535     case 7:
  10536         counter_reg = obm_counter_regs[1];
  10537         break;
  10538     case 8:
  10539     case 9:
  10540     case 10:
  10541     case 11:
  10542         counter_reg = obm_counter_regs[2];
  10543         break;
  10544     case 12:
  10545     case 13:
  10546     case 14:
  10547     case 15:
  10548         counter_reg = obm_counter_regs[3];
  10549         break;
  10550     default:
  10551         return SOC_E_INTERNAL;
  10552     }
  10553 
  10554     COMPILER_64_ZERO(my_zero);
  10555     for (i = 0; i < 4; i++) {
  10556         (void)soc_counter_set(unit, port, counter_reg[i], xlp_port, my_zero);
  10557     }
  10558 
  10559     return SOC_E_NONE;
  10560 }
  10561 
  10562 STATIC int
  10563 _soc_trident2_tdm_init(int unit)
  10564 {
  10565     soc_info_t *si;
  10566     soc_pbmp_t pbmp;
  10567     int port, phy_port, mmu_port, block, obm_inst;
  10568     int pipe, pgw, xlp, tsc, group, slot, length, base, index, count, id;
  10569     int wt_group = 0;
  10570     int rv, i;
  10571     int num_of_subport;
  10572 #ifdef BCM_56850_A0
  10573     enum tdm_td2_port_speed td2_spd[TDM_TD2_NUM_EXT_PORTS];
  10574 #endif
  10575 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10576     tdm_soc_t _chip_pkg;
  10577     tdm_mod_t *_tdm_pkg;
  10578     int wt_group_select;
  10579 #endif
  10580     int pgw_master, pgw_slave;
  10581     int lossless;
  10582     int speed_max, weight;
  10583     int mtu_cells, res_cells, port_cells;
  10584     uint32 xlport_map;
  10585     soc_reg_t reg;
  10586     soc_mem_t mem;
  10587     uint64 rval64, ctrl_rval64;
  10588     uint32 rval;
  10589     uint32 entry[SOC_MAX_MEM_WORDS];
  10590     soc_field_t fields[4];
  10591     uint32 values[4];
  10592     int max_quad_core_bandwidth, quad_oversub_core_bandwidth;
  10593     int quad_linerate_bandwidth, quad_oversub_bandwidth;
  10594     uint16 dev_id;
  10595     uint8 rev_id;
  10596     int obm_setting_idx, oversub_ratio_idx;
  10597     int min_threshold, xoff_threshold, xon_threshold, xon_threshold_offset;
  10598     uint16 pri_mask;
  10599     int ancillary_bandwidth_mode = 0;
  10600     _soc_trident2_tdm_t *td2_tdm = NULL;
  10601 
  10602     static const struct _obm_setting_s {
  10603         int max_threshold;
  10604         int xoff_threshold[3]; /* for oversub ratio 1.27, 1.43, and above */
  10605     } obm_settings[] = {
  10606         { _TD2_TD2_CELLS_PER_OBM / 4, { 79, 26, 37 } },      /* 10G */
  10607         { _TD2_TD2_CELLS_PER_OBM / 2, { 315, 242, 86 } },    /* 20G */
  10608         { _TD2_TD2_CELLS_PER_OBM, { 707, 584, 339 } }        /* 40G */
  10609     };
  10610     static const struct _obm_setting_a1_s {
  10611         int xoff_threshold[3]; /* for oversub ratio 1.33, 1.5, and above */
  10612         int mtu_cells[3];      /* for oversub ratio 1.33, 1.5, and above */
  10613     } obm_settings_a1[] = {
  10614         { /* 10G */
  10615             { 56, 40, 23 },
  10616             { 5 * 1024 / _TD2_BYTES_PER_OBM_CELL,
  10617               3 * 1024 / _TD2_BYTES_PER_OBM_CELL,
  10618               2 * 1024 / _TD2_BYTES_PER_OBM_CELL }
  10619         },
  10620         { /* 20G */
  10621             { 215, 115, 60 },
  10622             { 9 * 1024 / _TD2_BYTES_PER_OBM_CELL,
  10623               9 * 1024 / _TD2_BYTES_PER_OBM_CELL,
  10624               6 * 1024 / _TD2_BYTES_PER_OBM_CELL }
  10625         },
  10626         { /* 40G */
  10627             { 661, 543, 306 },
  10628             { 9 * 1024 / _TD2_BYTES_PER_OBM_CELL,
  10629               9 * 1024 / _TD2_BYTES_PER_OBM_CELL,
  10630               9 * 1024 / _TD2_BYTES_PER_OBM_CELL }
  10631         }
  10632     };
  10633 
  10634     static const soc_mem_t mmu_tdm_regs[2] ={
  10635         ES_PIPE0_TDM_CONFIGr, ES_PIPE1_TDM_CONFIGr
  10636     };
  10637     static const soc_mem_t mmu_tdm_mems[2] ={
  10638         ES_PIPE0_TDM_TABLE_0m, ES_PIPE1_TDM_TABLE_0m
  10639     };
  10640     static const soc_reg_t mmu_ovs_group_cfg_regs[] = {
  10641         ES_PIPE0_OVR_SUB_GRP_CFGr, ES_PIPE1_OVR_SUB_GRP_CFGr
  10642     };
  10643     /* Trident2+ has different registers so pointer will be changed later */
  10644     mmu_ovs_group_wt_regs_t mmu_ovs_group_wt_regs = mmu_ovs_group_wt_regs_local;
  10645 
  10646 
  10647     static const soc_field_t xlp_cell_asf_thresh_fields[] = {
  10648         XLP0_CELL_ASM_CUT_THRU_THRESHOLDf, XLP1_CELL_ASM_CUT_THRU_THRESHOLDf,
  10649         XLP2_CELL_ASM_CUT_THRU_THRESHOLDf, XLP3_CELL_ASM_CUT_THRU_THRESHOLDf
  10650     };
  10651     static const soc_mem_t iarb_tdm_mems[2] ={
  10652         IARB_MAIN_TDM_Xm, IARB_MAIN_TDM_Ym
  10653     };
  10654 
  10655 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10656     mmu_ovs_group_wt_regs =
  10657         get_mmu_ovs_group_wt_regs ( unit, mmu_ovs_group_wt_regs );
  10658 #endif
  10659 
  10660     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  10661 
  10662     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 1);
  10663 
  10664     ancillary_bandwidth_mode = soc_property_get(unit, spn_ANCILLARY_BANDWIDTH_MODE, 0);
  10665 
  10666     td2_tdm = soc_td2_td2p_tdm_sched_info_get(unit, 1);
  10667     if (td2_tdm == NULL) {
  10668         return SOC_E_MEMORY;
  10669     }
  10670 
  10671     si = &SOC_INFO(unit);
  10672 
  10673     td2_tdm->ancillary_bandwidth_mode = ancillary_bandwidth_mode;
  10674 
  10675     PBMP_PORT_ITER(unit, port) {
  10676         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
  10677             continue;
  10678         }
  10679         phy_port = si->port_l2p_mapping[port];
  10680         td2_tdm->speed[phy_port] = si->port_speed_max[port];
  10681         td2_tdm->port_state[phy_port] =
  10682             SOC_PBMP_MEMBER(si->oversub_pbm, port) ?
  10683             PORT_STATE_OVERSUB : PORT_STATE_LINERATE;
  10684 
  10685         num_of_subport = 0;
  10686         if (SOC_IS_TD2P_TT2P(unit) &&
  10687             (td2_tdm->speed[phy_port] >= 120000)) {
  10688             num_of_subport = 11;
  10689         } else if (SOC_IS_TD2P_TT2P(unit) &&
  10690             (td2_tdm->speed[phy_port] >= 100000)) {
  10691             num_of_subport = 9;
  10692         } else if (td2_tdm->speed[phy_port] >= 40000) {
  10693             num_of_subport = 3;
  10694         } else if (SOC_IS_TITAN2PLUS(unit) &&
  10695                       ((td2_tdm->speed[phy_port] == 13000) ||
  10696                        (td2_tdm->speed[phy_port] == 16000))) {
  10697             num_of_subport = 3;
  10698         } else if (td2_tdm->speed[phy_port] >= 20000) {
  10699             num_of_subport = 1;
  10700         }
  10701         for (i = 0; i < num_of_subport; i++) {
  10702             td2_tdm->port_state[phy_port + i + 1] = PORT_STATE_SUBPORT;
  10703         }
  10704     }
  10705 
  10706     td2_tdm->speed[0] = 1000;
  10707     td2_tdm->speed[129] = 1000;
  10708     td2_tdm->tdm_bw = si->bandwidth / 1000;
  10709 
  10710     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
  10711     SOC_PBMP_AND(pbmp, si->xpipe_pbm);
  10712     if (td2_tdm->tdm_bw == 720) { /* 720g special handling */
  10713         /* tell tdm code the pipe is oversub only if all ports are oversub */
  10714         SOC_PBMP_PORT_ADD(pbmp, 0); /* cpu port */
  10715         td2_tdm->pipe_ovs_state[0] = SOC_PBMP_EQ(pbmp, si->xpipe_pbm);
  10716     } else {
  10717         /* tell tdm code the pipe is oversub if any ports is oversub */
  10718         td2_tdm->pipe_ovs_state[0] = SOC_PBMP_NOT_NULL(pbmp);
  10719     }
  10720     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
  10721     SOC_PBMP_AND(pbmp, si->ypipe_pbm);
  10722     if (td2_tdm->tdm_bw == 720) { /* 720g special handling */
  10723         /* tell tdm code the pipe is oversub only if all ports are oversub */
  10724         SOC_PBMP_PORT_ADD(pbmp, 105); /* loopback port */
  10725         td2_tdm->pipe_ovs_state[1] = SOC_PBMP_EQ(pbmp, si->ypipe_pbm);
  10726     } else {
  10727         /* tell tdm code the pipe is oversub if any ports is oversub */
  10728         td2_tdm->pipe_ovs_state[1] = SOC_PBMP_NOT_NULL(pbmp);
  10729     }
  10730     td2_tdm->manage_port_type = 0;
  10731     if (SOC_PBMP_NOT_NULL(si->management_pbm)) {
  10732         speed_max = 0;
  10733         for (phy_port = 13; phy_port <= 16; phy_port++) {
  10734             port = si->port_p2l_mapping[phy_port];
  10735             if (port == -1) {
  10736                 continue;
  10737             }
  10738             if (speed_max < si->port_speed_max[port]) {
  10739                 speed_max = si->port_speed_max[port];
  10740             }
  10741         }
  10742         if (speed_max <= 1000) {
  10743             td2_tdm->manage_port_type = 1; /* 4 x 1g */
  10744         } else if (speed_max <= 2500) {
  10745             td2_tdm->manage_port_type = 2; /* 4 * 2.5g */
  10746         } else {
  10747             td2_tdm->manage_port_type = 3; /* 1 x 10g */
  10748         }
  10749         if (td2_tdm->manage_port_type > 0) {
  10750             td2_tdm->pgw_tdm[0][0] = 1234; /* magic number used by
  10751                                                 * tdm code */
  10752         }
  10753     }
  10754 
  10755 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10756     if (SOC_IS_TD2P_TT2P(unit)) {
  10757         if (td2_tdm->manage_port_type != 0) {
  10758             _chip_pkg.soc_vars.td2p.tdm_mgmt_en = 1;
  10759         } else {
  10760             _chip_pkg.soc_vars.td2p.tdm_mgmt_en = 0;
  10761         }
  10762     }
  10763 #endif
  10764 
  10765     for (slot = 0; slot <= _MMU_TDM_LENGTH; slot++) {
  10766         td2_tdm->mmu_tdm[0][slot] = NUM_EXT_PORTS;
  10767         td2_tdm->mmu_tdm[1][slot] = NUM_EXT_PORTS;
  10768     }
  10769 
  10770     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  10771         LOG_CLI((BSL_META_U(unit,
  10772                             "tdm_bw: %dG\n"), td2_tdm->tdm_bw));
  10773         LOG_CLI((BSL_META_U(unit,
  10774                             "port speed:")));
  10775         for (index = 0; index < NUM_EXT_PORTS; index++) {
  10776             if (index % 8 == 0) {
  10777                 LOG_CLI((BSL_META_U(unit,
  10778                                     "\n    ")));
  10779             }
  10780             LOG_CLI((BSL_META_U(unit,
  10781                                 " %6d"), td2_tdm->speed[index]));
  10782         }
  10783         LOG_CLI((BSL_META_U(unit,
  10784                             "\n")));
  10785         LOG_CLI((BSL_META_U(unit,
  10786                             "port state map:")));
  10787         for (index = 0; index < NUM_EXT_PORTS; index++) {
  10788             if (index % 16 == 0) {
  10789                 LOG_CLI((BSL_META_U(unit,
  10790                                     "\n    ")));
  10791             }
  10792             if (index == 0 || index == (NUM_EXT_PORTS - 1)) {
  10793                 LOG_CLI((BSL_META_U(unit,
  10794                                     " ---")));
  10795             } else {
  10796                 LOG_CLI((BSL_META_U(unit,
  10797                                     " %3d"),
  10798                          td2_tdm->port_state[index]));
  10799             }
  10800         }
  10801         LOG_CLI((BSL_META_U(unit,
  10802                             "\n")));
  10803     }
  10804 
  10805 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10806     if (SOC_IS_TD2P_TT2P(unit)) {
  10807         _chip_pkg.unit = unit;
  10808         _chip_pkg.num_ext_ports = TD2P_NUM_EXT_PORTS;
  10809         _chip_pkg.state=sal_alloc((_chip_pkg.num_ext_ports)*sizeof(int *), "port state list");
  10810         _chip_pkg.speed=sal_alloc((_chip_pkg.num_ext_ports)*sizeof(int *), "port speed list");
  10811         for (index=1; index<(_chip_pkg.num_ext_ports); index++) {
  10812             _chip_pkg.state[index] = td2_tdm->port_state[index];
  10813         }
  10814         _chip_pkg.state[0]=1; /* enable cpu port */
  10815         _chip_pkg.state[_chip_pkg.num_ext_ports-1]=1; /* enable loopback port */
  10816         for (index=0; index<(_chip_pkg.num_ext_ports); index++) {
  10817             _chip_pkg.speed[index] = td2_tdm->speed[index];
  10818         }
  10819 
  10820         /*
  10821          * Map detected core clk frequency to TDM algorithm internal code
  10822          * value.
  10823          */
  10824         switch (si->frequency) {
  10825             case 790:
  10826             case 760:
  10827                 _chip_pkg.clk_freq = 760;
  10828                 break;
  10829             case 635:
  10830                 _chip_pkg.clk_freq = 608;
  10831                 break;
  10832             case 537:
  10833                 _chip_pkg.clk_freq = 518;
  10834                 break;
  10835             case 421:
  10836                 _chip_pkg.clk_freq = 415;
  10837                 break;
  10838             default:
  10839                 _chip_pkg.clk_freq = (si->frequency > 760) ? (760)
  10840                                         : si->frequency;
  10841         }
  10842 
  10843         _tdm_pkg = _soc_set_tdm_tbl(SOC_SEL_TDM(&_chip_pkg));
  10844         if (!_tdm_pkg) {
  10845             LOG_CLI((BSL_META_U(unit,
  10846                 "Unsupported config for TDM calendar generation\n")));
  10847             return SOC_E_FAIL;
  10848         }
  10849         sal_memcpy(td2_tdm->pgw_tdm[0], _tdm_pkg->_chip_data.cal_0.cal_main, sizeof(int)*MAX_PGW_TDM_LENGTH);
  10850         sal_memcpy(td2_tdm->pgw_ovs_tdm[0], _tdm_pkg->_chip_data.cal_0.cal_grp[0], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10851         sal_memcpy(td2_tdm->pgw_ovs_spacing[0], _tdm_pkg->_chip_data.cal_0.cal_grp[1], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10852         sal_memcpy(td2_tdm->pgw_tdm[1], _tdm_pkg->_chip_data.cal_1.cal_main, sizeof(int)*MAX_PGW_TDM_LENGTH);
  10853         sal_memcpy(td2_tdm->pgw_ovs_tdm[1], _tdm_pkg->_chip_data.cal_1.cal_grp[0], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10854         sal_memcpy(td2_tdm->pgw_ovs_spacing[1], _tdm_pkg->_chip_data.cal_1.cal_grp[1], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10855         sal_memcpy(td2_tdm->pgw_tdm[2], _tdm_pkg->_chip_data.cal_2.cal_main, sizeof(int)*MAX_PGW_TDM_LENGTH);
  10856         sal_memcpy(td2_tdm->pgw_ovs_tdm[2], _tdm_pkg->_chip_data.cal_2.cal_grp[0], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10857         sal_memcpy(td2_tdm->pgw_ovs_spacing[2], _tdm_pkg->_chip_data.cal_2.cal_grp[1], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10858         sal_memcpy(td2_tdm->pgw_tdm[3], _tdm_pkg->_chip_data.cal_3.cal_main, sizeof(int)*MAX_PGW_TDM_LENGTH);
  10859         sal_memcpy(td2_tdm->pgw_ovs_tdm[3], _tdm_pkg->_chip_data.cal_3.cal_grp[0], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10860         sal_memcpy(td2_tdm->pgw_ovs_spacing[3], _tdm_pkg->_chip_data.cal_3.cal_grp[1], sizeof(int)*_PGW_TDM_OVS_SIZE);
  10861         sal_memcpy(td2_tdm->mmu_tdm[0], _tdm_pkg->_chip_data.cal_4.cal_main, sizeof(int)*_MMU_TDM_LENGTH);
  10862         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][0], _tdm_pkg->_chip_data.cal_4.cal_grp[0], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10863         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][1], _tdm_pkg->_chip_data.cal_4.cal_grp[1], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10864         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][2], _tdm_pkg->_chip_data.cal_4.cal_grp[2], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10865         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][3], _tdm_pkg->_chip_data.cal_4.cal_grp[3], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10866         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][4], _tdm_pkg->_chip_data.cal_4.cal_grp[4], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10867         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][5], _tdm_pkg->_chip_data.cal_4.cal_grp[5], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10868         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][6], _tdm_pkg->_chip_data.cal_4.cal_grp[6], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10869         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[0][7], _tdm_pkg->_chip_data.cal_4.cal_grp[7], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10870         sal_memcpy(td2_tdm->mmu_tdm[1], _tdm_pkg->_chip_data.cal_5.cal_main, sizeof(int)*_MMU_TDM_LENGTH);
  10871         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][0], _tdm_pkg->_chip_data.cal_5.cal_grp[0], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10872         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][1], _tdm_pkg->_chip_data.cal_5.cal_grp[1], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10873         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][2], _tdm_pkg->_chip_data.cal_5.cal_grp[2], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10874         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][3], _tdm_pkg->_chip_data.cal_5.cal_grp[3], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10875         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][4], _tdm_pkg->_chip_data.cal_5.cal_grp[4], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10876         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][5], _tdm_pkg->_chip_data.cal_5.cal_grp[5], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10877         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][6], _tdm_pkg->_chip_data.cal_5.cal_grp[6], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10878         sal_memcpy(td2_tdm->mmu_ovs_group_tdm[1][7], _tdm_pkg->_chip_data.cal_5.cal_grp[7], sizeof(int)*_MMU_OVS_GROUP_TDM_LENGTH);
  10879         sal_free(_chip_pkg.state);
  10880         sal_free(_chip_pkg.speed);
  10881         _tdm_pkg->_chip_exec[TDM_CHIP_EXEC__FREE](_tdm_pkg);
  10882         sal_free(_tdm_pkg);
  10883     } else
  10884 #endif
  10885     {
  10886 #ifdef BCM_56850_A0
  10887         for (index=0; index<130; index++) {
  10888             td2_spd[index] = td2_tdm->speed[index];
  10889         }
  10890         rv = _soc_td2_set_tdm_tbl(td2_spd, td2_tdm->tdm_bw,
  10891                          td2_tdm->pgw_tdm[0],
  10892                          td2_tdm->pgw_ovs_tdm[0],
  10893                          td2_tdm->pgw_ovs_spacing[0],
  10894                          td2_tdm->pgw_tdm[1],
  10895                          td2_tdm->pgw_ovs_tdm[1],
  10896                          td2_tdm->pgw_ovs_spacing[1],
  10897                          td2_tdm->pgw_tdm[2],
  10898                          td2_tdm->pgw_ovs_tdm[2],
  10899                          td2_tdm->pgw_ovs_spacing[2],
  10900                          td2_tdm->pgw_tdm[3],
  10901                          td2_tdm->pgw_ovs_tdm[3],
  10902                          td2_tdm->pgw_ovs_spacing[3],
  10903                          td2_tdm->mmu_tdm[0],
  10904                          td2_tdm->mmu_ovs_group_tdm[0][0],
  10905                          td2_tdm->mmu_ovs_group_tdm[0][1],
  10906                          td2_tdm->mmu_ovs_group_tdm[0][2],
  10907                          td2_tdm->mmu_ovs_group_tdm[0][3],
  10908                          td2_tdm->mmu_tdm[1],
  10909                          td2_tdm->mmu_ovs_group_tdm[1][0],
  10910                          td2_tdm->mmu_ovs_group_tdm[1][1],
  10911                          td2_tdm->mmu_ovs_group_tdm[1][2],
  10912                          td2_tdm->mmu_ovs_group_tdm[1][3],
  10913                          &td2_tdm->port_state[1], /* skip cpu port */
  10914                          td2_tdm->iarb_tdm[0],
  10915                          td2_tdm->iarb_tdm[1],
  10916                          td2_tdm->ancillary_bandwidth_mode);
  10917 		if (rv == 0) {
  10918 			LOG_CLI((BSL_META_U(unit,
  10919 								"Unsupported config for TDM calendar generation\n")));
  10920 			return SOC_E_FAIL;
  10921 		}
  10922 #endif
  10923 	}
  10924 
  10925     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  10926         for (pgw = 0; pgw < _TD2_PGWS_PER_DEV; pgw += _TD2_PGWS_PER_QUAD) {
  10927             LOG_CLI((BSL_META_U(unit,
  10928                                 "PGW_CL%d pgw_tdm:"), pgw));
  10929             for (index = 0; index < GET_PGW_TDM_LENGTH(unit); index++) {
  10930                 if (index % 16 == 0) {
  10931                     LOG_CLI((BSL_META_U(unit,
  10932                                         "\n    ")));
  10933                 }
  10934                 LOG_CLI((BSL_META_U(unit,
  10935                                     " %3d"),
  10936                          td2_tdm->pgw_tdm[pgw / 2][index]));
  10937             }
  10938             LOG_CLI((BSL_META_U(unit,
  10939                                 "\n")));
  10940             LOG_CLI((BSL_META_U(unit,
  10941                                 "PGW_CL%d pgw_ovs_tdm:"), pgw));
  10942             for (index = 0; index < _PGW_TDM_OVS_SIZE; index++) {
  10943                 if (index % 16 == 0) {
  10944                     LOG_CLI((BSL_META_U(unit,
  10945                                         "\n    ")));
  10946                 }
  10947                 LOG_CLI((BSL_META_U(unit,
  10948                                     " %3d"),
  10949                                     td2_tdm->pgw_ovs_tdm[pgw / 2][index]));
  10950             }
  10951             LOG_CLI((BSL_META_U(unit,
  10952                                 "\n")));
  10953             LOG_CLI((BSL_META_U(unit,
  10954                                 "PGW_CL%d pgw_ovs_spacing:"), pgw));
  10955             for (index = 0; index < _PGW_TDM_OVS_SIZE; index++) {
  10956                 if (index % 16 == 0) {
  10957                     LOG_CLI((BSL_META_U(unit,
  10958                                         "\n    ")));
  10959                 }
  10960                 LOG_CLI((BSL_META_U(unit,
  10961                                     " %3d"),
  10962                          td2_tdm->pgw_ovs_spacing[pgw / 2][index]));
  10963             }
  10964             LOG_CLI((BSL_META_U(unit,
  10965                                 "\n")));
  10966         }
  10967         for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
  10968             LOG_CLI((BSL_META_U(unit,
  10969                                 "Pipe %c mmu_tdm:"), pipe ? 'y' : 'x'));
  10970             for (index = 0; index < _MMU_TDM_LENGTH; index++) {
  10971                 if (index % 16 == 0) {
  10972                     LOG_CLI((BSL_META_U(unit,
  10973                                         "\n    ")));
  10974                 }
  10975                 LOG_CLI((BSL_META_U(unit,
  10976                                     " %3d"),
  10977                          td2_tdm->mmu_tdm[pipe][index]));
  10978             }
  10979             LOG_CLI((BSL_META_U(unit,
  10980                                 "\n")));
  10981             for (group = 0; group < GET_MMU_OVS_GCOUNT(unit); group++) {
  10982                 LOG_CLI((BSL_META_U(unit,
  10983                                     "Pipe %c group %d ovs_group_tdm"),
  10984                          pipe ? 'y' : 'x', group));
  10985                 for (index = 0; index < _MMU_OVS_GROUP_TDM_LENGTH;
  10986                      index++) {
  10987                     if (index % 16 == 0) {
  10988                         LOG_CLI((BSL_META_U(unit,
  10989                                             "\n    ")));
  10990                     }
  10991                     LOG_CLI((BSL_META_U(unit,
  10992                                         " %3d"),
  10993                              td2_tdm->mmu_ovs_group_tdm[pipe][group][index]));
  10994                 }
  10995                 LOG_CLI((BSL_META_U(unit,
  10996                                     "\n")));
  10997             }
  10998         }
  10999     }
  11000 
  11001     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  11002         LOG_CLI((BSL_META_U(unit,
  11003                             "tdm_bw: %dG\n"), td2_tdm->tdm_bw));
  11004         LOG_CLI((BSL_META_U(unit,
  11005                             "x pipe ovs state: %d\n"),
  11006                  td2_tdm->pipe_ovs_state[0]));
  11007         LOG_CLI((BSL_META_U(unit,
  11008                             "y pipe ovs state: %d\n"),
  11009                  td2_tdm->pipe_ovs_state[1]));
  11010         LOG_CLI((BSL_META_U(unit,
  11011                             "manage port type: %d\n"),
  11012                  td2_tdm->manage_port_type));
  11013     }
  11014 
  11015 #ifdef BCM_56860_A0
  11016     if (SOC_IS_TD2P_TT2P(unit)) {
  11017         rv = tdm_td2p_set_iarb_tdm_table(td2_tdm->tdm_bw,
  11018                                 td2_tdm->pipe_ovs_state[0],
  11019                                 td2_tdm->pipe_ovs_state[1],
  11020                                 td2_tdm->manage_port_type == 1,
  11021                                 td2_tdm->manage_port_type == 2,
  11022                                 td2_tdm->manage_port_type == 3,
  11023                                 &td2_tdm->iarb_tdm_wrap_ptr[0],
  11024                                 &td2_tdm->iarb_tdm_wrap_ptr[1],
  11025                                 td2_tdm->iarb_tdm[0],
  11026                                 td2_tdm->iarb_tdm[1]);
  11027     } else
  11028 #endif
  11029     {
  11030         rv = tdm_td2_set_iarb_tdm_table(td2_tdm->tdm_bw,
  11031                                 td2_tdm->pipe_ovs_state[0],
  11032                                 td2_tdm->pipe_ovs_state[1],
  11033                                 td2_tdm->manage_port_type == 1,
  11034                                 td2_tdm->manage_port_type == 2,
  11035                                 td2_tdm->manage_port_type == 3,
  11036                                 &td2_tdm->iarb_tdm_wrap_ptr[0],
  11037                                 &td2_tdm->iarb_tdm_wrap_ptr[1],
  11038                                 td2_tdm->iarb_tdm[0],
  11039                                 td2_tdm->iarb_tdm[1]);
  11040     }
  11041     if (rv == 0) {
  11042         LOG_CLI((BSL_META_U(unit,
  11043                             "Unsupported config for TDM calendar generation\n")));
  11044         return SOC_E_FAIL;
  11045     }
  11046 
  11047     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  11048         for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
  11049             LOG_CLI((BSL_META_U(unit,
  11050                                 "Pipe %c iarb_tdm: (wrap_ptr %d)"),
  11051                      pipe ? 'y' : 'x',
  11052                      td2_tdm->iarb_tdm_wrap_ptr[pipe]));
  11053             for (index = 0; index < _IARB_TDM_LENGTH; index++) {
  11054                 if (index > td2_tdm->iarb_tdm_wrap_ptr[pipe]) {
  11055                     break;
  11056                 }
  11057                 if (index % 16 == 0) {
  11058                     LOG_CLI((BSL_META_U(unit,
  11059                                         "\n    ")));
  11060                 }
  11061                 LOG_CLI((BSL_META_U(unit,
  11062                                     " %3d"),
  11063                          td2_tdm->iarb_tdm[pipe][index]));
  11064             }
  11065             LOG_CLI((BSL_META_U(unit,
  11066                                 "\n")));
  11067         }
  11068     }
  11069 
  11070     /* Configure PGW TDM for TD2,  only need to program master PGWs (PGW_CL0/2/4/6) */
  11071     /* Configure PGW TDM for TD2+, only need to program master PGWs (PGW_CL0/3/4/7) */
  11072     for (pgw = 0; pgw < _TD2_PGWS_PER_DEV; pgw += _TD2_PGWS_PER_QUAD) {
  11073         pgw_master = pgw;
  11074         pgw_slave  = pgw + 1;
  11075 
  11076         if (SOC_IS_TD2P_TT2P(unit)) {
  11077             if (( pgw == 2 ) || ( pgw == 6 )) {
  11078                 pgw_master = pgw + 1;
  11079                 pgw_slave  = pgw;
  11080             }
  11081         }
  11082 
  11083         /* coverity[negative_returns : FALSE] */
  11084         if (!si->block_valid[PGW_CL_BLOCK(unit, pgw_master)] &&
  11085             !si->block_valid[PGW_CL_BLOCK(unit, pgw_slave)]) {
  11086             /* Both master and slave are not in use */
  11087             continue;
  11088         }
  11089 
  11090         obm_inst = pgw_master | SOC_REG_ADDR_INSTANCE_MASK;
  11091 
  11092         SOC_IF_ERROR_RETURN(soc_reg_get(unit, PGW_TDM_CONTROLr, obm_inst, 0,
  11093                                         &ctrl_rval64));
  11094 
  11095         /* Configure PGW line rate ports TDM */
  11096         count = 0;
  11097         for (base = 0; base < GET_PGW_TDM_LENGTH(unit);
  11098             base += _PGW_TDM_SLOTS_PER_REG) {
  11099             reg = pgw_tdm_regs[base / _PGW_TDM_SLOTS_PER_REG];
  11100             COMPILER_64_ZERO(rval64);
  11101             for (index = 0; index < _PGW_TDM_SLOTS_PER_REG; index++) {
  11102                 slot = base + index;
  11103                 phy_port = td2_tdm->pgw_tdm[pgw_master / 2][slot];
  11104                 if (phy_port == NUM_EXT_PORTS) {
  11105                     break;
  11106                 }
  11107                 soc_reg64_field32_set(unit, reg, &rval64, pgw_tdm_fields[slot],
  11108                                       phy_port);
  11109                 count++;
  11110             }
  11111             if (index != 0) {
  11112                 SOC_IF_ERROR_RETURN
  11113                     (soc_reg_set(unit, reg, obm_inst, 0, rval64));
  11114             }
  11115             if (index != _PGW_TDM_SLOTS_PER_REG) {
  11116             /* Due to the hardware limitation, Line-rate TDM
  11117                wrap pointer MUST be larger than 0 */
  11118                 if (count == 1) {
  11119                     count = 2;
  11120                     soc_reg64_field32_set(unit, reg, &rval64, pgw_tdm_fields[slot],
  11121                                           PGW_LR_UNUSED_SLOT);
  11122                     SOC_IF_ERROR_RETURN
  11123                         (soc_reg_set(unit, reg, obm_inst, 0, rval64));
  11124                 }
  11125                 break;
  11126             }
  11127         }
  11128 
  11129         if (count > 0) {
  11130             soc_reg64_field32_set(unit, PGW_TDM_CONTROLr, &ctrl_rval64,
  11131                                   LR_TDM_WRAP_PTRf, count - 1);
  11132         } else {
  11133 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11134             /* Switch from/to TDM table1 and to/from TDM table 2
  11135              * When switching from TDM table1 to table2, there is an
  11136              * intermediate state to wait for End-of-Table to check if tdm_ptr is equal
  11137              * to LR_TDMx_WRAP_PTR. If there's no entry in TDM table(count == 0),
  11138              * need to set LR_TDMx_WRAP_PTRf to 0 to switch new table completely */
  11139             if (SOC_IS_TD2P_TT2P(unit)) {
  11140                 soc_reg64_field32_set(unit, PGW_TDM_CONTROLr, &ctrl_rval64,
  11141                                       LR_TDM_WRAP_PTRf, 0);
  11142             }
  11143 #endif
  11144         }
  11145         soc_reg64_field32_set(unit, PGW_TDM_CONTROLr, &ctrl_rval64,
  11146                               LR_TDM_ENABLEf, count ? 1 : 0);
  11147 
  11148         /* Configure PGW oversubscription ports TDM */
  11149         count = 0;
  11150         for (base = 0; base < _PGW_TDM_OVS_SIZE;
  11151              base += _PGW_TDM_SLOTS_PER_REG) {
  11152             reg = pgw_ovs_tdm_regs[base / _PGW_TDM_SLOTS_PER_REG];
  11153             COMPILER_64_ZERO(rval64);
  11154             for (index = 0; index < _PGW_TDM_SLOTS_PER_REG; index++) {
  11155                 slot = base + index;
  11156                 phy_port = td2_tdm->pgw_ovs_tdm[pgw_master / 2][slot];
  11157                 if (phy_port == NUM_EXT_PORTS) {
  11158                     phy_port = 0xff;
  11159                 } else {
  11160                     count++;
  11161                 }
  11162                 soc_reg64_field32_set(unit, reg, &rval64, pgw_tdm_fields[slot],
  11163                                       phy_port);
  11164             }
  11165             SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, obm_inst, 0, rval64));
  11166         }
  11167         /* OS_TDM_WRAP_PTR is always 31 (reset value) */
  11168         soc_reg64_field32_set(unit, PGW_TDM_CONTROLr, &ctrl_rval64,
  11169                               OS_TDM_ENABLEf, count ? 1 : 0);
  11170 
  11171         /* Configure PGW oversubscription port spacing */
  11172         for (base = 0; base < _PGW_TDM_OVS_SIZE;
  11173              base += _PGW_TDM_SLOTS_PER_REG) {
  11174             reg = pgw_ovs_spacing_regs[base / _PGW_TDM_SLOTS_PER_REG];
  11175             COMPILER_64_ZERO(rval64);
  11176             for (index = 0; index < _PGW_TDM_SLOTS_PER_REG; index++) {
  11177                 slot = base + index;
  11178                 phy_port = td2_tdm->pgw_ovs_spacing[pgw_master / 2][slot];
  11179                 soc_reg64_field32_set(unit, reg, &rval64,
  11180                                       pgw_spacing_fields[slot], phy_port);
  11181             }
  11182             SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, obm_inst, 0, rval64));
  11183         }
  11184 
  11185         SOC_IF_ERROR_RETURN
  11186             (soc_reg_set(unit, PGW_TDM_CONTROLr, obm_inst, 0, ctrl_rval64));
  11187     }
  11188 
  11189     /* Configure PGW TDM oversubscription buffer manager (OBM) */
  11190     xlport_map = 0;
  11191     SOC_BLOCK_ITER(unit, block, SOC_BLK_XLPORT) {
  11192         xlport_map |= 1 << SOC_BLOCK_NUMBER(unit, block);
  11193     }
  11194     quad_oversub_bandwidth = 0; /* to eliminate false compiler warning */
  11195     quad_oversub_core_bandwidth = 0; /* to eliminate false compiler warning */
  11196 
  11197     for (pgw = 0; pgw < _TD2_PGWS_PER_DEV; pgw++) {
  11198         if (!(pgw & 1)) {
  11199             /* coverity[negative_returns : FALSE] */
  11200             if (!si->block_valid[PGW_CL_BLOCK(unit, pgw)] &&
  11201                 !si->block_valid[PGW_CL_BLOCK(unit, pgw + 1)]) {
  11202                 /* Both master and slave are not in use */
  11203                 pgw++;
  11204                 continue;
  11205             }
  11206             /* Calculate per quadrant line rate and oversub bandwidth */
  11207             _soc_trident2_quad_bandwidth_calculate
  11208                 (unit, pgw / _TD2_PGWS_PER_QUAD, &max_quad_core_bandwidth,
  11209                  &quad_linerate_bandwidth, &quad_oversub_bandwidth);
  11210             quad_oversub_core_bandwidth =
  11211                 max_quad_core_bandwidth - quad_linerate_bandwidth;
  11212         }
  11213 
  11214         block = PGW_CL_BLOCK(unit, pgw);
  11215         /* coverity[negative_returns : FALSE] */
  11216         if (SOC_BLOCK_PORT(unit, block) < 0) { /* PGW is not in use */
  11217             continue;
  11218         }
  11219 
  11220         obm_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK;
  11221 
  11222         COMPILER_64_ZERO(rval64);
  11223         for (xlp = 0; xlp < _TD2_XLPS_PER_PGW; xlp++){
  11224             if (!(xlport_map & (1 << (pgw * _TD2_XLPS_PER_PGW + xlp)))) {
  11225                 continue;
  11226             }
  11227             index = pgw & 1 ? _TD2_XLPS_PER_PGW - 1 - xlp : xlp;
  11228             soc_reg64_field32_set(unit, CELL_ASM_CUT_THRU_THRESHOLDr, &rval64,
  11229                                   xlp_cell_asf_thresh_fields[index], _TD2_PGW_CELL_ASM_CUT_THRU_THRESHOLD);
  11230         }
  11231         SOC_IF_ERROR_RETURN(soc_reg_set(unit, CELL_ASM_CUT_THRU_THRESHOLDr,
  11232                                         obm_inst, 0, rval64));
  11233 
  11234         for (xlp = 0; xlp < _TD2_XLPS_PER_PGW; xlp++) {
  11235             if (!(xlport_map & (1 << (pgw * _TD2_XLPS_PER_PGW + xlp)))) {
  11236                 continue;
  11237             }
  11238             /* XLP number is reversed (mirrored) in odd number PGW block */
  11239             tsc = pgw * _TD2_XLPS_PER_PGW +
  11240                 ((pgw & 1) ? (_TD2_XLPS_PER_PGW - 1 - xlp) : xlp);
  11241 
  11242             /* Count number of oversub ports in the OBM (XLPORT) */
  11243             count = 0;
  11244             for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11245                 phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11246                 if (td2_tdm->port_state[phy_port] == PORT_STATE_OVERSUB) {
  11247                     count++;
  11248                 }
  11249             }
  11250             if (count == 0) { /* the XLPORT is not in oversub mode */
  11251                 continue;
  11252             }
  11253 
  11254             for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11255                 phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11256                 if (si->port_p2l_mapping[phy_port] == -1) {
  11257                     continue;
  11258                 }
  11259                 SOC_IF_ERROR_RETURN(
  11260                     soc_td2_obm_ctrl_reg_default_set(unit, xlp, index, obm_inst,
  11261                                                      count, PGW_OBM_INIT_SW_DEFAULT));
  11262             }
  11263 
  11264             if (!SOC_IS_TD2P_TT2P(unit) && (rev_id <= BCM56850_A1_REV_ID)) {
  11265                 /* Do not map to low priority on A0/A1 */
  11266                 reg = td2_pgw_obm_priority_map_regs[xlp];
  11267                 for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11268                     phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11269                     if (si->port_p2l_mapping[phy_port] == -1) {
  11270                         continue;
  11271                     }
  11272 
  11273                     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, index,
  11274                                                     &ctrl_rval64));
  11275                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11276                                           PCP_MAPf, 0xffff);
  11277                     SOC_IF_ERROR_RETURN
  11278                         (soc_reg_set(unit, reg, obm_inst, index, ctrl_rval64));
  11279                 }
  11280 
  11281                 SOC_IF_ERROR_RETURN
  11282                     (soc_td2_obm_shared_config_reg_default_set(unit, xlp,
  11283                                         0, obm_inst, PGW_OBM_INIT_SW_DEFAULT));
  11284 
  11285                 reg = td2_pgw_obm_threshold_regs[xlp];
  11286                 for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11287                     phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11288                     port = si->port_p2l_mapping[phy_port];
  11289                     if (port == -1) {
  11290                         continue;
  11291                     }
  11292 
  11293                     if (si->port_speed_max[port] > 20000) {
  11294                         obm_setting_idx = 2; /* entry 2 in the lookup table */
  11295                         xon_threshold_offset = 24; /* xon = xoff - 24 */
  11296                     } else if (si->port_speed_max[port] > 10000) {
  11297                         obm_setting_idx = 1; /* entry 1 in the lookup table */
  11298                         xon_threshold_offset = 12; /* xon = xoff - 12 */
  11299                     } else {
  11300                         obm_setting_idx = 0; /* entry 0 in the lookup table */
  11301                         xon_threshold_offset = 6; /* xon = xoff - 6 */
  11302                     }
  11303                     if (quad_oversub_bandwidth * 2 >
  11304                         quad_oversub_core_bandwidth * 3) {
  11305                         /* oversub ratio greater than 1.5 (3/2) */
  11306                         oversub_ratio_idx = 1;
  11307                     } else if (quad_oversub_bandwidth * 3 >
  11308                         quad_oversub_core_bandwidth * 4) {
  11309                         /* oversub ratio greater than 1.33 (4/3) */
  11310                         oversub_ratio_idx = 1;
  11311                     } else {
  11312                         oversub_ratio_idx = 0;
  11313                     }
  11314 
  11315                     if (lossless) {
  11316                         xoff_threshold = obm_settings_a1[obm_setting_idx].
  11317                             xoff_threshold[oversub_ratio_idx];
  11318                         xon_threshold = xoff_threshold - xon_threshold_offset;
  11319                         mtu_cells = obm_settings_a1[obm_setting_idx].
  11320                             mtu_cells[oversub_ratio_idx];
  11321                     } else {
  11322                         xoff_threshold = 1020;
  11323                         xon_threshold = 1020;
  11324                         mtu_cells = 9 * 1024 / _TD2_BYTES_PER_OBM_CELL;
  11325                     }
  11326                     if (count > 1 &&
  11327                         quad_oversub_bandwidth > quad_oversub_core_bandwidth) {
  11328                         /*
  11329                          * packet_completion_reserved cells =
  11330                          *  (num_ports - 1) * mtu * (1 - 1 / oversub_ratio) + 4
  11331                          */
  11332                         res_cells = (count - 1) * mtu_cells *
  11333                             (quad_oversub_bandwidth -
  11334                              quad_oversub_core_bandwidth) /
  11335                             quad_oversub_bandwidth  + 4;
  11336                     } else {
  11337                         res_cells = 4;
  11338                     }
  11339                     /*
  11340                      * port_cells =
  11341                      *  (1020 - packet_completion_reserved_cells) / num_ports
  11342                      */
  11343                     port_cells = (_TD2_TD2_CELLS_PER_OBM - res_cells) / count;
  11344 
  11345                     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, index,
  11346                                                     &ctrl_rval64));
  11347                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11348                                           MIN_THRESHOLDf, port_cells);
  11349                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11350                                           LOW_PRI_THRESHOLDf, 0);
  11351                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11352                                           MAX_THRESHOLDf, port_cells);
  11353                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11354                                           FLOW_CTRL_XONf, xon_threshold);
  11355                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11356                                           FLOW_CTRL_XOFFf, xoff_threshold);
  11357                     if (!SOC_IS_TD2P_TT2P(unit)) {
  11358                         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11359                                           CUT_THROUGH_OKf, 2);
  11360                     }
  11361                     SOC_IF_ERROR_RETURN
  11362                         (soc_reg_set(unit, reg, obm_inst, index, ctrl_rval64));
  11363                 }
  11364             } else {
  11365 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11366                 if (SOC_IS_TD2P_TT2P(unit)) {
  11367                     for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11368                         phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11369                         port = si->port_p2l_mapping[phy_port];
  11370                         if (port == -1) {
  11371                             continue;
  11372                         }
  11373                         SOC_IF_ERROR_RETURN
  11374                              (soc_td2p_obm_cut_through_threshold_set(unit,
  11375                                                      xlp, index,
  11376                                                      obm_inst,
  11377                                                      PGW_OBM_INIT_SW_DEFAULT));
  11378                     }
  11379                 }
  11380 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  11381                 /* Maintaining of Priority to Priority_group mapping requires
  11382                  * sufficient Memory for OAM, Hence calling the
  11383                  * soc_property_port_get_csv function where necessary.
  11384                  */
  11385                 reg = td2_pgw_obm_priority_map_regs[xlp];
  11386                 for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11387                     phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11388                     if (si->port_p2l_mapping[phy_port] == -1) {
  11389                         continue;
  11390                     }
  11391 
  11392                     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, index,
  11393                                                     &ctrl_rval64));
  11394                     pri_mask = 0;
  11395                     if (!lossless &&
  11396                         soc_feature(unit, soc_feature_prigrp_to_obm_prio_map)) {
  11397                         SOC_IF_ERROR_RETURN
  11398                             (soc_trident2_get_prio_map(
  11399                                               unit,
  11400                                               si->port_p2l_mapping[phy_port],
  11401                                               &pri_mask));
  11402                     }
  11403                     soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11404                                       PCP_MAPf, lossless ? 0xffff : pri_mask);
  11405 
  11406                     SOC_IF_ERROR_RETURN
  11407                         (soc_reg_set(unit, reg, obm_inst, index, ctrl_rval64));
  11408                 }
  11409 
  11410                 SOC_IF_ERROR_RETURN
  11411                     (soc_td2_obm_shared_config_reg_default_set(unit, xlp,
  11412                                         index, obm_inst, PGW_OBM_INIT_SW_DEFAULT));
  11413 
  11414                 reg = td2_pgw_obm_threshold_regs[xlp];
  11415                 for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11416                     phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11417                     port = si->port_p2l_mapping[phy_port];
  11418                     if (port == -1) {
  11419                         continue;
  11420                     }
  11421 
  11422 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11423                     if (SOC_IS_TD2P_TT2P(unit)) {
  11424                          soc_td2p_set_obm_registers (unit, reg,
  11425                                        si->port_speed_max[port], index,
  11426                                        obm_inst, lossless,
  11427                                        PGW_OBM_INIT_SW_DEFAULT);
  11428 
  11429                         SOC_IF_ERROR_RETURN
  11430                             (soc_td2p_obm_prob_drop_default_set (unit, xlp,
  11431                                                          index, obm_inst,
  11432                                                          PGW_OBM_INIT_SW_DEFAULT));
  11433                     } else
  11434 #endif
  11435                     {
  11436                         if (si->port_speed_max[port] > 20000) {
  11437                             obm_setting_idx = 2; /* entry 2 in the lookup table */
  11438                             xon_threshold_offset = 24; /* xon = xoff - 24 */
  11439                         } else if (si->port_speed_max[port] > 10000) {
  11440                             obm_setting_idx = 1; /* entry 1 in the lookup table */
  11441                             xon_threshold_offset = 12; /* xon = xoff - 12 */
  11442                         } else {
  11443                             obm_setting_idx = 0; /* entry 0 in the lookup table */
  11444                             xon_threshold_offset = 6; /* xon = xoff - 6 */
  11445                         }
  11446                         if (lossless) {
  11447                             if (quad_oversub_bandwidth * 2 >
  11448                                 quad_oversub_core_bandwidth * 3) {
  11449                                 /* oversub ratio greater than 1.5 (3/2) */
  11450                                 oversub_ratio_idx = 2;
  11451                             } else if (quad_oversub_bandwidth * 3 >
  11452                                 quad_oversub_core_bandwidth * 4) {
  11453                                 /* oversub ratio greater than 1.33 (4/3) */
  11454                                 oversub_ratio_idx = 1;
  11455                             } else {
  11456                                 oversub_ratio_idx = 0;
  11457                             }
  11458 
  11459                             xoff_threshold = obm_settings[obm_setting_idx].
  11460                                 xoff_threshold[oversub_ratio_idx];
  11461                             xon_threshold = xoff_threshold - xon_threshold_offset;
  11462                             min_threshold = xon_threshold + 3;
  11463                         } else {
  11464                             xoff_threshold = 1023;
  11465                             xon_threshold = 1023;
  11466                             min_threshold = obm_settings[obm_setting_idx].
  11467                                 max_threshold;
  11468                         }
  11469 
  11470                         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, index,
  11471                                                         &ctrl_rval64));
  11472                         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11473                                               MIN_THRESHOLDf, min_threshold);
  11474                         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11475                                               LOW_PRI_THRESHOLDf, 0);
  11476                         soc_reg64_field32_set
  11477                             (unit, reg, &ctrl_rval64, MAX_THRESHOLDf,
  11478                              obm_settings[obm_setting_idx].max_threshold);
  11479                         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11480                                               FLOW_CTRL_XONf, xon_threshold);
  11481                         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11482                                               FLOW_CTRL_XOFFf, xoff_threshold);
  11483                         soc_reg64_field32_set(unit, reg, &ctrl_rval64,
  11484                                               CUT_THROUGH_OKf, 2);
  11485                         SOC_IF_ERROR_RETURN
  11486                             (soc_reg_set(unit, reg, obm_inst, index, ctrl_rval64));
  11487                     }
  11488                 }
  11489 
  11490                 if (!lossless) {
  11491                     continue;
  11492                 }
  11493                 /* The configuration of OBM is configured in sync with the MMU.
  11494                  * if spn_MMU_LOSSLESS is NOT configured, then all the priority
  11495                  * groups are Lossy (Flow Control is disabled).
  11496                  * if spn_MMU_LOSSLESS is SET (1), then the priorities which are
  11497                  * mapped to Priority Group - 7 will have flow control enabled.
  11498                  */
  11499                 for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  11500                     phy_port = 1 + tsc * _TD2_PORTS_PER_XLP + index;
  11501                     if (si->port_p2l_mapping[phy_port] == -1) {
  11502                         continue;
  11503                     }
  11504                     SOC_IF_ERROR_RETURN
  11505                         (soc_td2_obm_fc_config_reg_default_set(unit, xlp,
  11506                             index, obm_inst, si->port_p2l_mapping[phy_port],
  11507                             count, PGW_OBM_INIT_SW_DEFAULT));
  11508                 }
  11509             }
  11510         }
  11511     }
  11512 
  11513     /* Configure MMU TDM */
  11514     for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
  11515         reg = mmu_tdm_regs[pipe];
  11516         mem = mmu_tdm_mems[pipe];
  11517 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11518         wt_group_select = 0;
  11519 #endif
  11520 
  11521         length = _MMU_TDM_LENGTH;
  11522         for (slot = _MMU_TDM_LENGTH - 1; slot >= 0; slot--) {
  11523             if (td2_tdm->mmu_tdm[pipe][slot] != NUM_EXT_PORTS) {
  11524                 length = slot + 1;
  11525                 break;
  11526             }
  11527         }
  11528 
  11529         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  11530         sal_memset(entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32));
  11531         for (slot = 0; slot < length; slot += 2) {
  11532             phy_port = td2_tdm->mmu_tdm[pipe][slot];
  11533             if (phy_port == GET_OVS_TOKEN(unit)) {
  11534                 mmu_port = 57; /* oppurtunist port */
  11535             } else if (phy_port == GET_IDL_TOKEN(unit)) {
  11536                 mmu_port = 58; /* scheduler will not pick anything */
  11537             } else if (phy_port >= NUM_EXT_PORTS) {
  11538                 mmu_port = 0x3f;
  11539             } else {
  11540                 mmu_port = si->port_p2m_mapping[phy_port];
  11541             }
  11542             soc_mem_field32_set(unit, mem, entry, PORT_NUM_EVENf,
  11543                                 mmu_port & 0x3f);
  11544 
  11545             phy_port = td2_tdm->mmu_tdm[pipe][slot + 1];
  11546             if (phy_port == GET_OVS_TOKEN(unit)) {
  11547                 mmu_port = 57; /* oppurtunist port */
  11548             } else if (phy_port == GET_IDL_TOKEN(unit)) {
  11549                 mmu_port = 58; /* scheduler will not pick anything */
  11550             } else if (phy_port >= NUM_EXT_PORTS) {
  11551                 mmu_port = 0x3f;
  11552             } else {
  11553                 mmu_port = si->port_p2m_mapping[phy_port];
  11554             }
  11555             soc_mem_field32_set(unit, mem, entry, PORT_NUM_ODDf,
  11556                                 mmu_port & 0x3f);
  11557             SOC_IF_ERROR_RETURN
  11558                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot / 2, entry));
  11559         }
  11560 
  11561         soc_reg_field_set(unit, reg, &rval, CAL0_ENDf, slot / 2);
  11562         if (length & 1) {
  11563             soc_reg_field_set(unit, reg, &rval, CAL0_END_SINGLEf, 1);
  11564         }
  11565 
  11566         if (SOC_IS_TD2P_TT2P(unit)) {
  11567             /*
  11568              *  Control strict priority scheduling between CPU/Loopback port
  11569              *  and Oversub port.
  11570              *  Setting - Oversub has highest priority
  11571              */
  11572             soc_reg_field_set(unit, reg, &rval, OPP_STRICT_PRIf, 1);
  11573             soc_reg_field_set(unit, reg, &rval, OPP_PORT_ENf, 1);
  11574         }
  11575         soc_reg_field_set(unit, reg, &rval, OPP_CPULB_ENf, 1);
  11576         soc_reg_field_set(unit, reg, &rval, ENABLEf, 1);
  11577         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
  11578 
  11579         if (si->frequency < 760) {
  11580             reg = mmu_ovs_group_cfg_regs[pipe];
  11581             for (group = 0; group < GET_MMU_OVS_GCOUNT(unit); group++) {
  11582                 phy_port = td2_tdm->mmu_ovs_group_tdm[pipe][group][0];
  11583                 if (phy_port >= NUM_EXT_PORTS) {
  11584                     continue;
  11585                 }
  11586                 port = si->port_p2l_mapping[phy_port];
  11587                 if (si->port_speed_max[port] < 30000) {
  11588                     continue;
  11589                 }
  11590                 SOC_IF_ERROR_RETURN
  11591                     (soc_reg32_get(unit, reg, REG_PORT_ANY, group, &rval));
  11592                 soc_reg_field_set(unit, reg, &rval, SAME_SPACINGf,
  11593                                   si->frequency < 500 ? 6 : 8);
  11594                 SOC_IF_ERROR_RETURN
  11595                     (soc_reg32_set(unit, reg, REG_PORT_ANY, group, rval));
  11596             }
  11597         }
  11598 
  11599         /* There are 8 oversub groups in TD2+ but we support 4 speeds only
  11600          * there is ES_PIPE0_GRP_WT_SELECT register that will select
  11601          * which queue belong to which group. By default
  11602          */
  11603 
  11604         for (group = 0; group < GET_MMU_OVS_GCOUNT(unit); group++) {
  11605             reg = mmu_ovs_group_regs[pipe][group];
  11606             rval = 0;
  11607             for (slot = 0; slot < _MMU_OVS_GROUP_TDM_LENGTH; slot++) {
  11608                 phy_port = td2_tdm->mmu_ovs_group_tdm[pipe][group][slot];
  11609                 if (phy_port >= NUM_EXT_PORTS) {
  11610                     mmu_port = 0x3f;
  11611                     id = 0;
  11612                 } else {
  11613                     mmu_port = si->port_p2m_mapping[phy_port];
  11614                     id = si->port_serdes[si->port_p2l_mapping[phy_port]];
  11615                 }
  11616                 if (!SOC_IS_TD2P_TT2P(unit)) {
  11617                     soc_reg_field_set(unit, reg, &rval, PHY_PORT_IDf, id & 0xf);
  11618                 }
  11619                 soc_reg_field_set(unit, reg, &rval, MMU_PORTf,
  11620                                   mmu_port & 0x3f);
  11621                 SOC_IF_ERROR_RETURN
  11622                     (soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval));
  11623             }
  11624             rval = 0;
  11625             phy_port = td2_tdm->mmu_ovs_group_tdm[pipe][group][0];
  11626             if (phy_port >= NUM_EXT_PORTS) {
  11627                 weight = 0;
  11628                 wt_group = td2p_ovs_wt_group_speed_NA; /* "not" valid group */
  11629             } else {
  11630                 int speed;
  11631 
  11632                 port = si->port_p2l_mapping[phy_port];
  11633                 speed = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED,
  11634                                               si->port_speed_max[port]);
  11635                 if (SOC_IS_TD2P_TT2P(unit)) {
  11636                     if ( speed <= 11000 ) {
  11637                         wt_group = td2p_ovs_wt_group_speed_10G;
  11638                     } else if ( speed <= 21000 ) {
  11639                         wt_group = td2p_ovs_wt_group_speed_20G;
  11640                     } else if ( speed <= 42000 ) {
  11641                         wt_group = td2p_ovs_wt_group_speed_40G;
  11642                     } else {
  11643                         wt_group = td2p_ovs_wt_group_speed_NA; /* "not" valid group */
  11644                     }
  11645                 }
  11646                 /* use 2500M as weight unit */
  11647                 weight = (speed > 2500 ? speed : 2500) / 2500;
  11648             }
  11649 
  11650 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11651             /* TD2P supports 4 oversub speeds only 10/20 and 40*/
  11652             if (SOC_IS_TD2P_TT2P(unit)) {
  11653                 wt_group_select |= (wt_group << (group * 2));
  11654             } else
  11655 #endif
  11656             {
  11657                 wt_group = group;
  11658             }
  11659 
  11660             reg = mmu_ovs_group_wt_regs[pipe][wt_group];
  11661 
  11662             for (index = 0; index < _MMU_OVS_GROUP_TDM_LENGTH; index++) {
  11663                 soc_reg_field_set(unit, reg, &rval, WEIGHTf,
  11664                                   weight * (index + 1));
  11665                 SOC_IF_ERROR_RETURN
  11666                     (soc_reg32_set(unit, reg, REG_PORT_ANY, index, rval));
  11667             }
  11668         }
  11669 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11670         if (SOC_IS_TD2P_TT2P(unit)) {
  11671             SOC_IF_ERROR_RETURN
  11672                 (soc_reg32_set(unit, mmu_ovs_group_wt_select_regs [pipe],
  11673                                REG_PORT_ANY, 0, wt_group_select));
  11674         }
  11675 #endif
  11676     }
  11677 
  11678     /* Configure IARB TDM */
  11679     for (pipe = 0; pipe < _TD2_PIPES_PER_DEV; pipe++) {
  11680         mem = iarb_tdm_mems[pipe];
  11681         sal_memset(entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32));
  11682         for (slot = 0; slot < _IARB_TDM_LENGTH; slot++) {
  11683             if (slot > td2_tdm->iarb_tdm_wrap_ptr[pipe]) {
  11684                 break;
  11685             }
  11686             soc_mem_field32_set(unit, mem, entry, TDM_SLOTf,
  11687                                 td2_tdm->iarb_tdm[pipe][slot]);
  11688             SOC_IF_ERROR_RETURN
  11689                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, entry));
  11690         }
  11691     }
  11692     /* Both pipe are expected to have same IARB TDM table length */
  11693     fields[0] = TDM_WRAP_PTRf;
  11694     values[0] = td2_tdm->iarb_tdm_wrap_ptr[0];
  11695     fields[1] = DISABLEf;
  11696     values[1] = 0;
  11697     fields[2] = AUX_CMICM_SLOT_ENf;
  11698     values[2] = 1;
  11699     fields[3] = AUX_EP_LB_SLOT_ENf;
  11700     values[3] = 1;
  11701     SOC_IF_ERROR_RETURN
  11702         (soc_reg_fields32_modify(unit, IARB_TDM_CONTROLr, REG_PORT_ANY, 4,
  11703                                  fields, values));
  11704 
  11705 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  11706     if (SOC_IS_TD2P_TT2P(unit)) {
  11707         /* Configure oversubscription port with WAIT_FOR_2ND_MOP */
  11708         SOC_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit));
  11709         SOC_PBMP_AND(pbmp, si->oversub_pbm);
  11710         SOC_PBMP_ITER(pbmp, port) {
  11711             phy_port = si->port_l2p_mapping[port];
  11712             SOC_IF_ERROR_RETURN(soc_td2p_egr_edb_xmit_ctrl_set(
  11713                                     unit, phy_port, si->port_speed_max[port],
  11714                                     1 /*oversub*/, 0));
  11715         }
  11716 
  11717         /* Configure linerate port with WAIT_FOR_MOP */
  11718         SOC_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit));
  11719         SOC_PBMP_XOR(pbmp, si->oversub_pbm);
  11720         SOC_PBMP_ITER(pbmp, port) {
  11721             phy_port = si->port_l2p_mapping[port];
  11722             SOC_IF_ERROR_RETURN(soc_td2p_egr_edb_xmit_ctrl_set(
  11723                                     unit, phy_port, si->port_speed_max[port],
  11724                                     0 /*oversub*/, 0));
  11725         }
  11726     } else
  11727 #endif
  11728     {
  11729         /* Configure oversubscription port with WAIT_FOR_2ND_MOP */
  11730         sal_memset(entry, 0, sizeof(egr_edb_xmit_ctrl_entry_t));
  11731         soc_mem_field32_set(unit, EGR_EDB_XMIT_CTRLm, entry, WAIT_FOR_2ND_MOPf, 1);
  11732         soc_mem_field32_set(unit, EGR_EDB_XMIT_CTRLm, entry, START_CNTf,
  11733                 _TD2_MMU_XMIT_START_CNT_OVERSUB);
  11734         SOC_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit));
  11735         SOC_PBMP_AND(pbmp, si->oversub_pbm);
  11736         SOC_PBMP_ITER(pbmp, port) {
  11737             phy_port = si->port_l2p_mapping[port];
  11738             SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_EDB_XMIT_CTRLm,
  11739                                               MEM_BLOCK_ALL, phy_port, &entry));
  11740         }
  11741 
  11742         /* Configure linerate port with WAIT_FOR_MOP */
  11743         sal_memset(entry, 0, sizeof(egr_edb_xmit_ctrl_entry_t));
  11744         soc_mem_field32_set(unit, EGR_EDB_XMIT_CTRLm, entry, WAIT_FOR_MOPf, 1);
  11745         SOC_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit));
  11746         SOC_PBMP_XOR(pbmp, si->oversub_pbm);
  11747         SOC_PBMP_ITER(pbmp, port) {
  11748             phy_port = si->port_l2p_mapping[port];
  11749             soc_mem_field32_set(unit, EGR_EDB_XMIT_CTRLm, entry, START_CNTf,
  11750                     _TD2_MMU_XMIT_START_CNT_LINERATE(si->port_speed_max[port]));
  11751             SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_EDB_XMIT_CTRLm,
  11752                                               MEM_BLOCK_ALL, phy_port, &entry));
  11753         }
  11754     }
  11755 
  11756     rval = 0;
  11757 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11758     if (SOC_IS_TD2P_TT2P(unit)) {
  11759         soc_reg_field_set(unit, ENQ_CONFIGr, &rval,
  11760                       ASF_ENABLE_HS_PORT_EP_CREDIT_CHKf, 0);
  11761     }
  11762 #endif
  11763     soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_CFAP_FULL_DROP_ENf, 1);
  11764     soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_FIFO_THRESHOLDf, _TD2_MMU_ASF_FIFO_THRESHOLD);
  11765     soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_HS_FIFO_THRESHOLDf, _TD2_MMU_ASF_HS_FIFO_THRESHOLD);
  11766     SOC_IF_ERROR_RETURN(WRITE_ENQ_CONFIGr(unit, rval));
  11767 
  11768     /*
  11769      * bcmsim: C model cannot support cell based flow
  11770      */
  11771     if (SAL_BOOT_BCMSIM) {
  11772         SOC_IF_ERROR_RETURN
  11773             (soc_reg_field32_modify(unit, IARB_TDM_CONTROLr, REG_PORT_ANY,
  11774                                     DISABLEf, 1));
  11775     }
  11776 
  11777     return SOC_E_NONE;
  11778 }
  11779 
  11780 STATIC int
  11781 _soc_trident2_hash_init(int unit)
  11782 {
  11783     soc_field_t fields[4];
  11784     uint32 values[4];
  11785 
  11786     /* L2 dedicated banks */
  11787     fields[0] = BANK0_HASH_OFFSETf;
  11788     values[0] = 0;  /* CRC32_LOWER */
  11789     fields[1] = BANK1_HASH_OFFSETf;
  11790     values[1] = 16; /* CRC32_UPPER */
  11791     SOC_IF_ERROR_RETURN
  11792         (soc_reg_fields32_modify(unit, L2_TABLE_HASH_CONTROLr, REG_PORT_ANY, 2,
  11793                                  fields, values));
  11794 
  11795     /* L3 dedicated banks */
  11796     fields[0] = BANK6_HASH_OFFSETf;
  11797     values[0] = 0;  /* CRC32_LOWER */
  11798     fields[1] = BANK7_HASH_OFFSETf;
  11799     values[1] = 12; /* CRC32 >> 12 */
  11800     fields[2] = BANK8_HASH_OFFSETf;
  11801     values[2] = 24; /* CRC16_LOWER << 8 | CRC32 >> 24 */
  11802     fields[3] = BANK9_HASH_OFFSETf;
  11803     values[3] = 36; /* CRC16 >> 4 */
  11804     SOC_IF_ERROR_RETURN
  11805         (soc_reg_fields32_modify(unit, L3_TABLE_HASH_CONTROLr, REG_PORT_ANY, 4,
  11806                                  fields, values));
  11807 
  11808     /* L2/L3/ALPM shared banks */
  11809     fields[0] = BANK2_HASH_OFFSETf;
  11810     values[0] = 4;  /* CRC32 >> 4 */
  11811     fields[1] = BANK3_HASH_OFFSETf;
  11812     values[1] = 12; /* CRC32 >> 12 */
  11813     fields[2] = BANK4_HASH_OFFSETf;
  11814     values[2] = 20; /* CRC32 >> 20 */
  11815     fields[3] = BANK5_HASH_OFFSETf;
  11816     values[3] = 24; /* CRC32 >> 24 */
  11817     SOC_IF_ERROR_RETURN
  11818         (soc_reg_fields32_modify(unit, SHARED_TABLE_HASH_CONTROLr,
  11819                                  REG_PORT_ANY, 4, fields, values));
  11820 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11821     /* Robust Hash initialization */
  11822     if (SOC_IS_TD2P_TT2P(unit)) {
  11823         uint32 value, seed = 0;
  11824 
  11825         if (NULL == ROBUSTHASH(unit)) {
  11826             ROBUSTHASH(unit) = sal_alloc(sizeof(soc_robust_hash_db_t),
  11827                                          "soc_robust_hash");
  11828             if (ROBUSTHASH(unit) == NULL) {
  11829                 return SOC_E_MEMORY;
  11830             }
  11831             sal_memset(ROBUSTHASH(unit), 0, sizeof(soc_robust_hash_db_t));
  11832         }
  11833 
  11834         /* Enable Robust hashing for ING_VP_VLAN_MEMBERSHIP table and configure
  11835          * corresponding remap and action tables.
  11836          */
  11837 
  11838         if ((soc_property_get(unit, "robust_hash_disable_ing_vp_vlan", 0)) == 1)
  11839         {
  11840             /* Disable robust hashing */
  11841             SOC_IF_ERROR_RETURN
  11842                 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
  11843             soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr,
  11844                               &value, ROBUST_HASH_ENABLEf, 0x0);
  11845             SOC_IF_ERROR_RETURN
  11846                 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
  11847 
  11848             ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 0;
  11849         } else {
  11850             /* Enable robust hashing */
  11851             SOC_IF_ERROR_RETURN
  11852                 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
  11853             soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr,
  11854                               &value, ROBUST_HASH_ENABLEf, 0x1);
  11855             SOC_IF_ERROR_RETURN
  11856                 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
  11857             ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 1;
  11858 
  11859             /* Fill action and remap tables with random data */
  11860             ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[0] =
  11861                                               ING_VP_VLAN_MEMBERSHIP_REMAP_Am;
  11862             ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[1] =
  11863                                               ING_VP_VLAN_MEMBERSHIP_REMAP_Bm;
  11864             ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[0] =
  11865                                               ING_VP_VLAN_MEMBERSHIP_ACTION_Am;
  11866             ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[1] =
  11867                                               ING_VP_VLAN_MEMBERSHIP_ACTION_Bm;
  11868 
  11869             seed = soc_property_get(unit,
  11870                                     spn_ROBUST_HASH_SEED_INGRESS_VP_VLAN,
  11871                                     16777213);
  11872 
  11873             SOC_IF_ERROR_RETURN
  11874                 (soc_robust_hash_table_set(unit,
  11875                                         &(ROBUSTHASH(unit)->ing_vp_vlan_member),
  11876                                         seed));
  11877         }
  11878 
  11879         /* Enable Robust hashing for EGR_VP_VLAN_MEMBERSHIP table and configure
  11880          * corresponding remap and action tables.
  11881          */
  11882 
  11883         if ((soc_property_get(unit, "robust_hash_disable_egr_vp_vlan", 0)) == 1)
  11884         {
  11885             /* Disable robust hashing */
  11886             SOC_IF_ERROR_RETURN
  11887                 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
  11888             soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr,
  11889                               &value, ROBUST_HASH_ENABLEf, 0x0);
  11890             SOC_IF_ERROR_RETURN
  11891                 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
  11892 
  11893             ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 0;
  11894         } else {
  11895             /* Enable robust hashing */
  11896             SOC_IF_ERROR_RETURN
  11897                 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
  11898             soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr,
  11899                               &value, ROBUST_HASH_ENABLEf, 0x1);
  11900             SOC_IF_ERROR_RETURN
  11901                 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
  11902             ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 1;
  11903 
  11904             /* Fill action and remap tables with random data */
  11905             ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[0] =
  11906                                               EGR_VP_VLAN_MEMBERSHIP_REMAP_Am;
  11907             ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[1] =
  11908                                               EGR_VP_VLAN_MEMBERSHIP_REMAP_Bm;
  11909             ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[0] =
  11910                                               EGR_VP_VLAN_MEMBERSHIP_ACTION_Am;
  11911             ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[1] =
  11912                                               EGR_VP_VLAN_MEMBERSHIP_ACTION_Bm;
  11913 
  11914             seed = soc_property_get(unit,
  11915                                     spn_ROBUST_HASH_SEED_EGRESS_VP_VLAN,
  11916                                     16777213);
  11917 
  11918             SOC_IF_ERROR_RETURN
  11919                 (soc_robust_hash_table_set(unit,
  11920                                         &(ROBUSTHASH(unit)->egr_vp_vlan_member),
  11921                                         seed));
  11922         }
  11923     }
  11924 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  11925     return SOC_E_NONE;
  11926 }
  11927 
  11928 /*
  11929  * TD2+ LED Background:
  11930  *
  11931  *   The order of physical port status over LED uP0 scanchain are listed below
  11932  * 52,51,50,49,56,55,54,53,60,59,58,57,64,63,62,61,
  11933  * 48,47,46,45, ... , 36,35,34,33,
  11934  * 20,19,18,17,24,23,22,21,28,27,26,25,32,31,30,29,
  11935  * 16,15,14,13, ... ,4,3,2,1,
  11936  *
  11937  *   The order of physical port status on LED uP1 scan chain are listed below
  11938  * 116,115,114,113,120,119,118,117,124,123,122,121,128,127,126,125,
  11939  * 112,111,110,109, ... ,100,99,98,97,
  11940  * 84,83,82,81,88,87,86,85,92,91,90,89,96,95,94,93,
  11941  * 80,79,78,76, ... ,68,67,66,65
  11942  *
  11943  *   Most of time the order is fixed, except for odd-numbered PGW 100G port.
  11944  *   For odd-numbered PGWs, the port status of 100G aggregate port are shifted 8
  11945  * ports from original port number, which means the port status of port 21(PGW1),
  11946  * 53(PGW3), 85(PGW5) and 117(PGW7) are at 29, 61, 93, 125 repectively.
  11947  *
  11948  *   SDK provide a SDK default TD2+ LED remapping theme (the remap table update
  11949  * for odd-numbered 100G PGWs is disabled in default)
  11950  * After this remap, the port status layout is physical port indexed and illustrated
  11951  * as follow.
  11952  *
  11953  * Port status for physical port 1~64 are at LEDUP0 DATA RAM address 0~127.
  11954  *    ----------------------------------------------------
  11955  *   | PORT 1 | PORT 2 | PORT 3 | ... | PORT 15 | PORT 16 | <-- PGW 0
  11956  *   |----------------------------------------------------|
  11957  *   | PORT 17|  ...   |  ...   | ... | PORT 31 | PORT 32 | <-- PGW 1
  11958  *   |----------------------------------------------------|
  11959  *   | PORT 33|  ...   |  ...   | ... | PORT 47 | PORT 48 | <-- PGW 2
  11960  *   |----------------------------------------------------|
  11961  *   | PORT 49|  ...   |  ...   | ... | PORT 63 | PORT 64 | <-- PGW 3
  11962  *    ----------------------------------------------------
  11963  *
  11964  * Port status for physical port 65~128 are at LEDUP1 DATA RAM address 0~127.
  11965  *    ----------------------------------------------------
  11966  *   | PORT 65| PORT 66| PORT 67| ... | PORT 79 | PORT 80 | <-- PGW 4
  11967  *   |----------------------------------------------------|
  11968  *   | PORT 81|  ...   |  ...   | ... | PORT 95 | PORT 96 | <-- PGW 5
  11969  *   |----------------------------------------------------|
  11970  *   | PORT 97|  ...   |  ...   | ... | PORT 47 | PORT 48 | <-- PGW 6
  11971  *   |----------------------------------------------------|
  11972  *   | PORT113|  ...   |  ...   | ... | PORT127 | PORT128 | <-- PGW 7
  11973  *    ----------------------------------------------------
  11974  *
  11975  * Notes:
  11976  *   1. PORT <num> refers to physical port <num>.
  11977  *   2. if TD2P_LED_FLEXPORT_SUPPORT could be defined by compile option
  11978  *      (-DTD2P_LED_FLEXPORT_SUPPORT) or code then SDK driver will update the LED
  11979  *      remap table to retain the SDK default port status layout the same
  11980  *      after odd-numbered PGWs flex/unflex to/from 100G.
  11981  */
  11982 
  11983 STATIC int
  11984 _soc_td2p_ledup_remap_setup(int unit, int init)
  11985 {
  11986     uint8 ledup_remap[2][64];
  11987     static uint32 odd_pgw_100g = 0;
  11988 
  11989     soc_reg_t   remap_reg;
  11990     soc_field_t remap_field;
  11991     uint32 rval, odd_pgw_100g_tmp;
  11992     int led_up, led_port, pgw, phy_port, lport, update_remap = 0;
  11993     soc_info_t *si;
  11994 
  11995     soc_reg_t remap_led_regs[2][16] = {
  11996         {
  11997             CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r,   CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r,
  11998             CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r,  CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r,
  11999             CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r,
  12000             CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r,
  12001             CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r,
  12002             CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r,
  12003             CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r,
  12004             CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r,
  12005         },
  12006         {
  12007             CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r,   CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r,
  12008             CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r,  CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r,
  12009             CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r,
  12010             CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r,
  12011             CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, CMIC_LEDUP1_PORT_ORDER_REMAP_36_39r,
  12012             CMIC_LEDUP1_PORT_ORDER_REMAP_40_43r, CMIC_LEDUP1_PORT_ORDER_REMAP_44_47r,
  12013             CMIC_LEDUP1_PORT_ORDER_REMAP_48_51r, CMIC_LEDUP1_PORT_ORDER_REMAP_52_55r,
  12014             CMIC_LEDUP1_PORT_ORDER_REMAP_56_59r, CMIC_LEDUP1_PORT_ORDER_REMAP_60_63r,
  12015         }
  12016     };
  12017 
  12018     soc_field_t remap_led_fields[] = {
  12019          REMAP_PORT_0f, REMAP_PORT_1f, REMAP_PORT_2f, REMAP_PORT_3f,
  12020          REMAP_PORT_4f, REMAP_PORT_5f, REMAP_PORT_6f, REMAP_PORT_7f,
  12021          REMAP_PORT_8f, REMAP_PORT_9f, REMAP_PORT_10f, REMAP_PORT_11f,
  12022          REMAP_PORT_12f, REMAP_PORT_13f, REMAP_PORT_14f, REMAP_PORT_15f,
  12023          REMAP_PORT_16f, REMAP_PORT_17f, REMAP_PORT_18f, REMAP_PORT_19f,
  12024          REMAP_PORT_20f, REMAP_PORT_21f, REMAP_PORT_22f, REMAP_PORT_23f,
  12025          REMAP_PORT_24f, REMAP_PORT_25f, REMAP_PORT_26f, REMAP_PORT_27f,
  12026          REMAP_PORT_28f, REMAP_PORT_29f, REMAP_PORT_30f, REMAP_PORT_31f,
  12027          REMAP_PORT_32f, REMAP_PORT_33f, REMAP_PORT_34f, REMAP_PORT_35f,
  12028          REMAP_PORT_36f, REMAP_PORT_37f, REMAP_PORT_38f, REMAP_PORT_39f,
  12029          REMAP_PORT_40f, REMAP_PORT_41f, REMAP_PORT_42f, REMAP_PORT_43f,
  12030          REMAP_PORT_44f, REMAP_PORT_45f, REMAP_PORT_46f, REMAP_PORT_47f,
  12031          REMAP_PORT_48f, REMAP_PORT_49f, REMAP_PORT_50f, REMAP_PORT_51f,
  12032          REMAP_PORT_52f, REMAP_PORT_53f, REMAP_PORT_54f, REMAP_PORT_55f,
  12033          REMAP_PORT_56f, REMAP_PORT_57f, REMAP_PORT_58f, REMAP_PORT_59f,
  12034          REMAP_PORT_60f, REMAP_PORT_61f, REMAP_PORT_62f, REMAP_PORT_63f,
  12035     };
  12036 
  12037     si = &SOC_INFO(unit);
  12038 
  12039     /* Calculate remap table for 10/40G ports and 100G port of even PGW. */
  12040     for (phy_port = 1; phy_port <= TRIDENT2_PHY_PORT_MAX; phy_port++) {
  12041 
  12042         /* According to scan chain, set remap to reverse port order. */
  12043         led_up = (phy_port - 1) / 64;
  12044         led_port = (63 - (phy_port - 1) % 64);
  12045 
  12046         /* Each PGW contains 16 lanes. */
  12047         pgw = (phy_port - 1) / 16;
  12048 
  12049         /* For odd-numbered PGWs. LED port status order is reversed or fixed.  */
  12050         if (pgw % 2) {
  12051             /* Handle the mapping of reversed ports in the odd-numbered PGWs */
  12052             if ((led_port % 16) < 4) {
  12053                 led_port += 12;
  12054             } else if ((led_port % 16) < 8) {
  12055                 led_port += 4;
  12056             } else if ((led_port % 16) < 12) {
  12057                 led_port -= 4;
  12058             } else {
  12059                 led_port -= 12;
  12060             }
  12061         }
  12062         ledup_remap[led_up][led_port] = (phy_port - 1) % 64;
  12063     }
  12064 
  12065     /* Start update remap table for odd-numbered PGWs. */
  12066     /* Cleanup 100G bitmap. */
  12067     odd_pgw_100g_tmp = 0;
  12068 
  12069     for (phy_port = 1; phy_port <= TRIDENT2_PHY_PORT_MAX; phy_port++) {
  12070 
  12071          /* According to scan chain, set remap to reverse port order. */
  12072          led_up = (phy_port - 1) / 64;
  12073          led_port = (63 - (phy_port - 1) % 64);
  12074 
  12075          /* Each PGW contains 16 lanes. */
  12076          pgw = (phy_port - 1) / 16;
  12077 
  12078          lport = si->port_p2l_mapping[phy_port];
  12079 
  12080          if (lport <= 0) continue;
  12081 
  12082          /* Calculate 100G remap table. */
  12083          if ((pgw % 2) && (si->port_num_lanes[lport] >= 10)) {
  12084 
  12085             odd_pgw_100g_tmp |= (1 << pgw);
  12086 
  12087             rval = ledup_remap[led_up][led_port + 4];
  12088             ledup_remap[led_up][led_port + 4] = (phy_port - 1) % 64;
  12089 
  12090             if ((led_port % 16) < 4) {
  12091                 led_port += 12;
  12092             } else if ((led_port % 16) < 8) {
  12093                 led_port += 4;
  12094             } else if ((led_port % 16) < 12) {
  12095                 led_port -= 4;
  12096             } else {
  12097                 led_port -= 12;
  12098             }
  12099 
  12100             ledup_remap[led_up][led_port] = rval;
  12101          }
  12102     }
  12103 
  12104     /* If any PGW flex/unflex to/from 100G or remap is inited then update
  12105      * remap.
  12106      */
  12107     if ((odd_pgw_100g_tmp != odd_pgw_100g) || init) {
  12108         odd_pgw_100g = odd_pgw_100g_tmp;
  12109         update_remap = 1;
  12110     }
  12111 
  12112     /* Do the remap update/init. */
  12113     if (update_remap) {
  12114 
  12115         /* Update the remap table for each LED processor. */
  12116         for (led_up = 0; led_up < 2; led_up++) {
  12117             for (led_port = 0; led_port < 64; led_port++) {
  12118                 remap_reg = remap_led_regs[led_up][led_port / 4];
  12119                 remap_field = remap_led_fields[led_port];
  12120                 SOC_IF_ERROR_RETURN(soc_pci_getreg(unit,
  12121                                     soc_reg_addr(unit, remap_reg, REG_PORT_ANY, 0),
  12122                                     &rval));
  12123                 soc_reg_field_set(unit, remap_reg, &rval, remap_field,
  12124                                  (ledup_remap[led_up][led_port] & 0x3F));
  12125                 SOC_IF_ERROR_RETURN(soc_pci_write(unit,
  12126                                     soc_reg_addr(unit, remap_reg, REG_PORT_ANY, 0),
  12127                                     rval));
  12128             }
  12129         }
  12130     }
  12131 
  12132     return SOC_E_NONE;
  12133 }
  12134 
  12135 STATIC int
  12136 _soc_td2_ledup_init(int unit)
  12137 {
  12138     uint32 rval = 0, ix, reg_val = 0;
  12139     int port_delay, start_delay[2];
  12140     soc_info_t *si;
  12141     int port = 0, blk, lport = 0;
  12142     int x_data_ram_loc = 0;
  12143     int y_data_ram_loc = 0;
  12144     int *data_ram_loc = NULL;
  12145     int phy_port, index;
  12146     soc_reg_t   remap_reg;
  12147     soc_field_t remap_field;
  12148 
  12149     soc_reg_t remap_led0_regs[] = {
  12150         CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r,
  12151         CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r,
  12152         CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r,
  12153         CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r,
  12154         CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r,
  12155         CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r,
  12156         CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r,
  12157         CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r
  12158     };
  12159 
  12160     soc_reg_t remap_led1_regs[] = {
  12161         CMIC_LEDUP1_PORT_ORDER_REMAP_60_63r, CMIC_LEDUP1_PORT_ORDER_REMAP_56_59r,
  12162         CMIC_LEDUP1_PORT_ORDER_REMAP_52_55r, CMIC_LEDUP1_PORT_ORDER_REMAP_48_51r,
  12163         CMIC_LEDUP1_PORT_ORDER_REMAP_44_47r, CMIC_LEDUP1_PORT_ORDER_REMAP_40_43r,
  12164         CMIC_LEDUP1_PORT_ORDER_REMAP_36_39r, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r,
  12165         CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r,
  12166         CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r,
  12167         CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r,
  12168         CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r
  12169     };
  12170 
  12171     soc_field_t remap_fields[] = {
  12172         REMAP_PORT_63f, REMAP_PORT_62f, REMAP_PORT_61f, REMAP_PORT_60f,
  12173         REMAP_PORT_59f, REMAP_PORT_58f, REMAP_PORT_57f, REMAP_PORT_56f,
  12174         REMAP_PORT_55f, REMAP_PORT_54f, REMAP_PORT_53f, REMAP_PORT_52f,
  12175         REMAP_PORT_51f, REMAP_PORT_50f, REMAP_PORT_49f, REMAP_PORT_48f,
  12176         REMAP_PORT_47f, REMAP_PORT_46f, REMAP_PORT_45f, REMAP_PORT_44f,
  12177         REMAP_PORT_43f, REMAP_PORT_42f, REMAP_PORT_41f, REMAP_PORT_40f,
  12178         REMAP_PORT_39f, REMAP_PORT_38f, REMAP_PORT_37f, REMAP_PORT_36f,
  12179         REMAP_PORT_35f, REMAP_PORT_34f, REMAP_PORT_33f, REMAP_PORT_32f,
  12180         REMAP_PORT_31f, REMAP_PORT_30f, REMAP_PORT_29f, REMAP_PORT_28f,
  12181         REMAP_PORT_27f, REMAP_PORT_26f, REMAP_PORT_25f, REMAP_PORT_24f,
  12182         REMAP_PORT_23f, REMAP_PORT_22f, REMAP_PORT_21f, REMAP_PORT_20f,
  12183         REMAP_PORT_19f, REMAP_PORT_18f, REMAP_PORT_17f, REMAP_PORT_16f,
  12184         REMAP_PORT_15f, REMAP_PORT_14f, REMAP_PORT_13f, REMAP_PORT_12f,
  12185         REMAP_PORT_11f, REMAP_PORT_10f, REMAP_PORT_9f, REMAP_PORT_8f,
  12186         REMAP_PORT_7f, REMAP_PORT_6f, REMAP_PORT_5f, REMAP_PORT_4f,
  12187         REMAP_PORT_3f, REMAP_PORT_2f, REMAP_PORT_1f, REMAP_PORT_0f
  12188     };
  12189 
  12190 
  12191 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12192     uint64 led_chain_delay;
  12193     uint64 led_chain_delay1;
  12194 #endif
  12195 
  12196     si = &SOC_INFO(unit);
  12197 
  12198 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12199     if (SOC_IS_TD2P_TT2P(unit)) {
  12200         start_delay[0] = 19;
  12201         start_delay[1] = 34;
  12202         port_delay = 4;
  12203     } else
  12204 #endif
  12205     {
  12206         start_delay[0] = 14;
  12207         start_delay[1] = 24;
  12208         port_delay = 1;
  12209     }
  12210 
  12211     /* configure the LED scan delay cycles */
  12212     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval));
  12213     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval,
  12214                         LEDUP_SCAN_START_DELAYf, start_delay[0]);
  12215     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval,
  12216                         LEDUP_SCAN_INTRA_PORT_DELAYf, port_delay);
  12217     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval));
  12218 
  12219     /* coverity[result_independent_of_operands] */
  12220     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP1_CTRLr(unit, &rval));
  12221     soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval,
  12222                         LEDUP_SCAN_START_DELAYf, start_delay[1]);
  12223     soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval,
  12224                         LEDUP_SCAN_INTRA_PORT_DELAYf, port_delay);
  12225     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_CTRLr(unit, rval));
  12226 
  12227 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12228     if (SOC_IS_TD2P_TT2P(unit)) {
  12229 
  12230         /* Program the PGW_LED_CHAIN_OUT_CONFIG irrespective of the
  12231            pgw block being enabled. even pgw like pgw.cl0 are set
  12232            to delay of 4 and odd pgw i.e pgw.cl1 are set to delay value
  12233            of 1 */
  12234         COMPILER_64_SET(led_chain_delay, 0, 0x4);
  12235         COMPILER_64_SET(led_chain_delay1, 0, 0x1);
  12236         _soc_reg64_set(unit, 6, 0, (0x2006300), led_chain_delay);
  12237         _soc_reg64_set(unit, 7, 0, (0x2006300), led_chain_delay1);
  12238         _soc_reg64_set(unit, 8, 0, (0x2006300), led_chain_delay);
  12239         _soc_reg64_set(unit, 9, 0, (0x2006300), led_chain_delay1);
  12240         _soc_reg64_set(unit, 10, 0, (0x2006300), led_chain_delay);
  12241         _soc_reg64_set(unit, 11, 0, (0x2006300), led_chain_delay1);
  12242         _soc_reg64_set(unit, 12, 0, (0x2006300), led_chain_delay);
  12243         _soc_reg64_set(unit, 13, 0, (0x2006300), led_chain_delay1);
  12244 
  12245         rval = 0xffffff;
  12246         /* Initialize LED Port remap registers */
  12247         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval));
  12248         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval));
  12249         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval));
  12250         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval));
  12251         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval));
  12252         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval));
  12253         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval));
  12254         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval));
  12255         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval));
  12256         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r(unit, rval));
  12257         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r(unit, rval));
  12258         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r(unit, rval));
  12259         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r(unit, rval));
  12260         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r(unit, rval));
  12261         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r(unit, rval));
  12262         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r(unit, rval));
  12263 
  12264         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r(unit, rval));
  12265         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r(unit, rval));
  12266         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r(unit, rval));
  12267         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r(unit, rval));
  12268         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r(unit, rval));
  12269         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r(unit, rval));
  12270         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r(unit, rval));
  12271         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r(unit, rval));
  12272         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r(unit, rval));
  12273         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_36_39r(unit, rval));
  12274         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_40_43r(unit, rval));
  12275         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_44_47r(unit, rval));
  12276         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_48_51r(unit, rval));
  12277         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_52_55r(unit, rval));
  12278         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_56_59r(unit, rval));
  12279         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_60_63r(unit, rval));
  12280 
  12281         _soc_td2p_ledup_remap_setup(unit, 1);
  12282 
  12283     } else
  12284 #endif
  12285     {
  12286         x_data_ram_loc = 1;
  12287         y_data_ram_loc = 1;
  12288         for (phy_port = 1; phy_port <= TRIDENT2_PHY_PORT_MAX; phy_port++) {
  12289             lport = si->port_p2l_mapping[phy_port];
  12290             if (lport == -1) {
  12291                 continue;
  12292             }
  12293 
  12294             index = phy_port;
  12295             index--;
  12296 
  12297             if ((index % 32) / 16) {
  12298                 /* Handle the mapping in the odd-numbered PGWs */
  12299                 if (si->port_num_lanes[lport] >= 10) {
  12300                     index -= 4;
  12301                 } else if (index % 16 < 4) {
  12302                     index += 12;
  12303                 } else if (index % 16 < 8) {
  12304                     index += 4;
  12305                 } else if (index % 16 < 12) {
  12306                     index -= 4;
  12307                 } else {
  12308                     index -= 12;
  12309                 }
  12310             }
  12311 
  12312             if (index >= 64) {
  12313                 index = index - 64;
  12314                 /* coverity[overrun-local] */
  12315                 remap_reg = remap_led1_regs[index / 4];
  12316                 remap_field = remap_fields[index];
  12317                 data_ram_loc = &y_data_ram_loc;
  12318             } else {
  12319                 remap_reg = remap_led0_regs[index / 4];
  12320                 remap_field = remap_fields[index];
  12321                 data_ram_loc = &x_data_ram_loc;
  12322             }
  12323 
  12324             SOC_IF_ERROR_RETURN(soc_pci_getreg(unit, soc_reg_addr(unit, remap_reg,
  12325                                 REG_PORT_ANY, 0), &rval));
  12326             soc_reg_field_set(unit, remap_reg, &rval, remap_field, *data_ram_loc);
  12327             SOC_IF_ERROR_RETURN(soc_pci_write(unit, soc_reg_addr(unit, remap_reg,
  12328                                 REG_PORT_ANY, 0), rval));
  12329 
  12330            (*data_ram_loc)++;
  12331         }
  12332    }
  12333 
  12334 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12335     if (SOC_IS_TD2P_TT2P(unit)) {
  12336         reg_val = 0x00000005;
  12337     } else
  12338 #endif
  12339     {
  12340         reg_val = 0x00000002;
  12341     }
  12342 
  12343     if ( SAL_BOOT_QUICKTURN ) {
  12344         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  12345             port = SOC_BLOCK_PORT(unit, blk);
  12346             if (port == -1) {
  12347                 continue;
  12348             }
  12349             
  12350             #if 0
  12351             if (SOC_USE_PORTCTRL(unit)) {
  12352                 SOC_IF_ERROR_RETURN
  12353                     (soc_portctrl_led_chain_config(unit, port, 0x00000002));
  12354             } else
  12355             #endif
  12356             {
  12357                 SOC_IF_ERROR_RETURN
  12358                     (soc_reg32_set(unit, XLPORT_LED_CHAIN_CONFIGr,
  12359                                    port, 0, reg_val));
  12360             }
  12361         }
  12362     } else {
  12363 
  12364         /* Raw SCHAN ops due to missing blocks */
  12365         _soc_reg32_set(unit, 15, 0, (0x2021700), reg_val);
  12366         _soc_reg32_set(unit, 16, 0, (0x2021700), reg_val);
  12367         _soc_reg32_set(unit, 17, 0, (0x2021700), reg_val);
  12368         _soc_reg32_set(unit, 18, 0, (0x2021700), reg_val);
  12369         _soc_reg32_set(unit, 20, 0, (0x2021700), reg_val);
  12370         _soc_reg32_set(unit, 21, 0, (0x2021700), reg_val);
  12371         _soc_reg32_set(unit, 22, 0, (0x2021700), reg_val);
  12372         _soc_reg32_set(unit, 23, 0, (0x2021700), reg_val);
  12373         _soc_reg32_set(unit, 25, 0, (0x2021700), reg_val);
  12374         _soc_reg32_set(unit, 26, 0, (0x2021700), reg_val);
  12375 
  12376         _soc_reg32_set(unit, 27, 0, (0x2021700), reg_val);
  12377         _soc_reg32_set(unit, 28, 0, (0x2021700), reg_val);
  12378         _soc_reg32_set(unit, 30, 0, (0x2021700), reg_val);
  12379         _soc_reg32_set(unit, 31, 0, (0x2021700), reg_val);
  12380         _soc_reg32_set(unit, 32, 0, (0x2021700), reg_val);
  12381         _soc_reg32_set(unit, 33, 0, (0x2021700), reg_val);
  12382         _soc_reg32_set(unit, 35, 0, (0x2021700), reg_val);
  12383         _soc_reg32_set(unit, 36, 0, (0x2021700), reg_val);
  12384         _soc_reg32_set(unit, 37, 0, (0x2021700), reg_val);
  12385         _soc_reg32_set(unit, 38, 0, (0x2021700), reg_val);
  12386 
  12387         _soc_reg32_set(unit, 40, 0, (0x2021700), reg_val);
  12388         _soc_reg32_set(unit, 41, 0, (0x2021700), reg_val);
  12389         _soc_reg32_set(unit, 42, 0, (0x2021700), reg_val);
  12390         _soc_reg32_set(unit, 43, 0, (0x2021700), reg_val);
  12391         _soc_reg32_set(unit, 45, 0, (0x2021700), reg_val);
  12392         _soc_reg32_set(unit, 46, 0, (0x2021700), reg_val);
  12393         _soc_reg32_set(unit, 47, 0, (0x2021700), reg_val);
  12394         _soc_reg32_set(unit, 48, 0, (0x2021700), reg_val);
  12395         _soc_reg32_set(unit, 50, 0, (0x2021700), reg_val);
  12396         _soc_reg32_set(unit, 51, 0, (0x2021700), reg_val);
  12397 
  12398         _soc_reg32_set(unit, 52, 0, (0x2021700), reg_val);
  12399         _soc_reg32_set(unit, 53, 0, (0x2021700), reg_val);
  12400         _soc_reg32_set(unit, 55, 0, (0x2021700), reg_val);
  12401 
  12402         /* Setting the CPORT_LED_CHAIN_CONFIG register*/
  12403 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12404         if (SOC_IS_TD2P_TT2P(unit)) {
  12405             _soc_reg32_set(unit, 14, 0, (0x2021100), reg_val);
  12406             _soc_reg32_set(unit, 19, 0, (0x2021100), reg_val);
  12407             _soc_reg32_set(unit, 24, 0, (0x2021100), reg_val);
  12408             _soc_reg32_set(unit, 29, 0, (0x2021100), reg_val);
  12409             _soc_reg32_set(unit, 34, 0, (0x2021100), reg_val);
  12410             _soc_reg32_set(unit, 39, 0, (0x2021100), reg_val);
  12411             _soc_reg32_set(unit, 44, 0, (0x2021100), reg_val);
  12412             _soc_reg32_set(unit, 49, 0, (0x2021100), reg_val);
  12413         }
  12414 #endif
  12415     }
  12416     /* initialize the UP0, UP1 data ram */
  12417     rval = 0;
  12418     for (ix = 0; ix < 256; ix++) {
  12419         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval));
  12420         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_DATA_RAMr(unit,ix, rval));
  12421     }
  12422 
  12423     return SOC_E_NONE;
  12424 }
  12425 
  12426 int
  12427 soc_td2p_ledup_port_update(int unit, soc_port_t port, uint8 attach)
  12428 {
  12429 #ifdef TD2P_LED_FLEXPORT_SUPPORT
  12430     return _soc_td2p_ledup_remap_setup(unit, 0);
  12431 #else
  12432     return SOC_E_NONE;
  12433 #endif /* TD2P_LED_FLEXPORT_SUPPORT */
  12434 }
  12435 
  12436 extern int (*_phy_tscmod_firmware_set_helper[SOC_MAX_NUM_DEVICES])
  12437             (int, int, uint8 *, int);
  12438 STATIC int
  12439 _soc_trident2_tsc_firmware_set(int unit, int port, uint8 *array, int datalen)
  12440 {
  12441     /* TSC firmware set is handled by PortMod internally */
  12442     if (SOC_USE_PORTCTRL(unit)) {
  12443         return SOC_E_INTERNAL;
  12444     }
  12445 
  12446     return soc_warpcore_firmware_set(unit, port, array, datalen, 0,
  12447                                      XLPORT_WC_UCMEM_DATAm,
  12448                                      XLPORT_WC_UCMEM_CTRLr);
  12449 }
  12450 
  12451 #if defined(SER_TR_TEST_SUPPORT)
  12452 soc_ser_test_functions_t ser_trident2_test_fun;
  12453 #endif
  12454 
  12455 STATIC int
  12456 _soc_trident2_egr_buf_reset(int unit, int port, int reset)
  12457 {
  12458     uint32 entry[SOC_MAX_MEM_WORDS];
  12459 
  12460     SOC_IF_ERROR_RETURN(
  12461         READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  12462                                             port, entry));
  12463     soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
  12464                         entry, ENABLEf, reset);
  12465     SOC_IF_ERROR_RETURN(
  12466         WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  12467                                              port, entry));
  12468 
  12469     return SOC_E_NONE;
  12470 }
  12471 
  12472 STATIC int
  12473 _soc_trident2_cport_reset(int unit, int port, int reset)
  12474 {
  12475     uint32 rval = 0;
  12476 
  12477     if (reset == 1) {
  12478         SOC_IF_ERROR_RETURN(READ_CPORT_SOFT_RESETr(unit, port, &rval));
  12479         soc_reg_field_set(unit, CPORT_SOFT_RESETr, &rval,
  12480                           CPORT_COREf, 1);
  12481         SOC_IF_ERROR_RETURN(WRITE_CPORT_SOFT_RESETr(unit, port, rval));
  12482 
  12483         SOC_IF_ERROR_RETURN(_soc_trident2_egr_buf_reset(unit, port, 1));
  12484     } else {
  12485         SOC_IF_ERROR_RETURN(_soc_trident2_egr_buf_reset(unit, port, 0));
  12486 
  12487         SOC_IF_ERROR_RETURN(READ_CPORT_SOFT_RESETr(unit, port, &rval));
  12488         soc_reg_field_set(unit, CPORT_SOFT_RESETr, &rval,
  12489                           CPORT_COREf, 0);
  12490         SOC_IF_ERROR_RETURN(WRITE_CPORT_SOFT_RESETr(unit, port, rval));
  12491     }
  12492 
  12493     return SOC_E_NONE;
  12494 }
  12495 
  12496 
  12497 STATIC int
  12498 _soc_portctrl_trident2_port_init(int unit)
  12499 {
  12500     soc_info_t *si;
  12501     int port;
  12502     int blk;
  12503 
  12504     si = &SOC_INFO(unit);
  12505 
  12506     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CPORT) {
  12507         port = SOC_BLOCK_PORT(unit, blk);
  12508         if (port == -1) {
  12509             continue;
  12510         }
  12511 
  12512         /* If this is a 100G port, reset egress port buffer */
  12513         if (si->port_speed_max[port] >= 100000) {
  12514             SOC_IF_ERROR_RETURN(_soc_trident2_egr_buf_reset(unit, port, 1));
  12515 
  12516             soc_trident2_port_speed_update(unit, port, si->port_speed_max[port]);
  12517 
  12518             SOC_IF_ERROR_RETURN(_soc_trident2_egr_buf_reset(unit, port, 0));
  12519         }
  12520     }
  12521 
  12522     /* Cut through settings for all ports */
  12523     PBMP_ALL_ITER(unit, port) {
  12524         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  12525             continue;
  12526         }
  12527         SOC_IF_ERROR_RETURN(soc_td2_port_asf_set(unit, port, si->port_speed_max[port]));
  12528     }
  12529 
  12530     return SOC_E_NONE;
  12531 }
  12532 
  12533 
  12534 STATIC int
  12535 _soc_trident2_port_init(int unit)
  12536 {
  12537     static const soc_field_t port_field[] = {
  12538         PORT0f, PORT1f, PORT2f, PORT3f
  12539     };
  12540     soc_info_t *si;
  12541     uint32 rval = 0;
  12542     int port;
  12543     int subport0, subport2, phy_port_base;
  12544     int blk, bindex, mode;
  12545 
  12546     si = &SOC_INFO(unit);
  12547 
  12548     if (SOC_USE_PORTCTRL(unit)) {
  12549         return _soc_portctrl_trident2_port_init(unit);
  12550     }
  12551 
  12552     PBMP_PORT_ITER(unit, port) {
  12553         if ( IS_C_PORT(unit, port) &&
  12554              (SOC_REG_IS_VALID(unit, CPORT_CONFIGr))) {
  12555             SOC_IF_ERROR_RETURN
  12556                 (soc_reg_field32_modify(unit, CPORT_SPARE0_REGr, port, RSVDf, 0));
  12557 
  12558             if (!IS_HG_PORT(unit, port)) {
  12559                 continue;
  12560             }
  12561             SOC_IF_ERROR_RETURN(READ_CPORT_CONFIGr(unit, port, &rval));
  12562             soc_reg_field_set(unit, CPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
  12563             SOC_IF_ERROR_RETURN(WRITE_CPORT_CONFIGr(unit, port, rval));
  12564         } else {
  12565             SOC_IF_ERROR_RETURN
  12566                 (soc_reg_field32_modify(unit, XLPORT_SPARE0_REGr, port, RSVDf, 0));
  12567 
  12568             if (!IS_HG_PORT(unit, port)) {
  12569                 continue;
  12570             }
  12571             SOC_IF_ERROR_RETURN(READ_XLPORT_CONFIGr(unit, port, &rval));
  12572             soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
  12573             SOC_IF_ERROR_RETURN(WRITE_XLPORT_CONFIGr(unit, port, rval));
  12574         }
  12575     }
  12576 
  12577     /* Enable 100G /Cports */
  12578     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CPORT) {
  12579         port = SOC_BLOCK_PORT(unit, blk);
  12580         if (port == -1) {
  12581             continue;
  12582         }
  12583         /* If this is a 100G port, enable the CPORT */
  12584         if (si->port_speed_max[port] >= 100000) {
  12585             SOC_IF_ERROR_RETURN(_soc_trident2_cport_reset(unit, port, 1));
  12586 
  12587             SOC_IF_ERROR_RETURN(READ_CPORT_ENABLE_REGr(unit, port, &rval));
  12588             soc_reg_field_set(unit, CPORT_ENABLE_REGr, &rval, PORT0f, 1);
  12589             SOC_IF_ERROR_RETURN(WRITE_CPORT_ENABLE_REGr(unit, port, rval));
  12590 
  12591             soc_trident2_port_speed_update(unit, port, si->port_speed_max[port]);
  12592 
  12593             /* take cport out of reset after enable */
  12594             SOC_IF_ERROR_RETURN(_soc_trident2_cport_reset(unit, port, 0));
  12595         }
  12596 
  12597     }
  12598 
  12599     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  12600         port = SOC_BLOCK_PORT(unit, blk);
  12601         if (port == -1) {
  12602             continue;
  12603         }
  12604         phy_port_base = ((si->port_l2p_mapping[port] - 1) & ~0x3) + 1;
  12605 
  12606         /* Assert XLPORT soft reset */
  12607         rval = 0;
  12608         for (bindex = 0; bindex < _TD2_PORTS_PER_XLP; bindex++) {
  12609             if (si->port_p2l_mapping[phy_port_base + bindex] != -1) {
  12610                 soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &rval,
  12611                                   port_field[bindex], 1);
  12612             }
  12613         }
  12614         SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, rval));
  12615 
  12616         if ((si->port_speed_max[port] > 21000) ||
  12617              (SOC_IS_TITAN2PLUS(unit) &&
  12618               ((si->port_speed_max[port] == 13000) ||
  12619               (si->port_speed_max[port] == 16000)))) {
  12620             mode = SOC_TD2_PORT_MODE_SINGLE;
  12621         } else {
  12622             subport0 = si->port_p2l_mapping[phy_port_base];
  12623             subport2 = si->port_p2l_mapping[phy_port_base + 2];
  12624             if (subport0 >= 0 && si->port_speed_max[subport0] > 11000) {
  12625                 if (subport2 < 0 || si->port_speed_max[subport2] <= 11000) {
  12626                     mode = SOC_TD2_PORT_MODE_TRI_023;
  12627                 } else {
  12628                     mode = SOC_TD2_PORT_MODE_DUAL;
  12629                 }
  12630             } else if (subport2 >= 0 && si->port_speed_max[subport2] > 11000) {
  12631                 if (subport0 < 0 || si->port_speed_max[subport0] <= 11000) {
  12632                     mode = SOC_TD2_PORT_MODE_TRI_012;
  12633                 } else {
  12634                     mode = SOC_TD2_PORT_MODE_DUAL;
  12635                 }
  12636             } else {
  12637                 mode = SOC_TD2_PORT_MODE_QUAD;
  12638             }
  12639         }
  12640         rval = 0;
  12641         soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval,
  12642                           XPORT0_CORE_PORT_MODEf, mode);
  12643         soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval,
  12644                           XPORT0_PHY_PORT_MODEf, mode);
  12645         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
  12646 
  12647         /* De-assert XLPORT soft reset */
  12648         SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, 0));
  12649 
  12650         /* Enable XLPORT */
  12651         rval = 0;
  12652         for (bindex = 0; bindex < _TD2_PORTS_PER_XLP; bindex++) {
  12653             if (si->port_p2l_mapping[phy_port_base + bindex] != -1) {
  12654                 soc_reg_field_set(unit, XLPORT_ENABLE_REGr, &rval,
  12655                                   port_field[bindex], 1);
  12656             }
  12657         }
  12658         SOC_IF_ERROR_RETURN(WRITE_XLPORT_ENABLE_REGr(unit, port, rval));
  12659     }
  12660 
  12661     return SOC_E_NONE;
  12662 }
  12663 
  12664 /* Configure HSP port multicast T2OQ setting.
  12665  * Note: Caller must check if the Port is part of HSP port bitmap
  12666  * HSP Port check:  SOC_PBMP_MEMBER(si->eq_pbm, port)
  12667  */
  12668 
  12669 STATIC int
  12670 _soc_trident2_mc_toq_cfg(int unit, int port, int enable)
  12671 {
  12672     static soc_field_t t2oq_fields[] = {
  12673         IS_MC_T2OQ_PORT0f, IS_MC_T2OQ_PORT1f
  12674     };
  12675     soc_field_t field;
  12676     uint32 rval, fval;
  12677     int pipe, mmu_port, phy_port;
  12678     soc_reg_t reg = TOQ_MC_CFG1r;
  12679     soc_info_t *si = &SOC_INFO(unit);;
  12680 
  12681     pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port) ? 1 : 0;
  12682     field = t2oq_fields[pipe & 0x01];
  12683     phy_port = si->port_l2p_mapping[port];
  12684     mmu_port = si->port_p2m_mapping[phy_port];
  12685 
  12686     SOC_IF_ERROR_RETURN
  12687         (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  12688     fval = soc_reg_field_get(unit, reg, rval, field);
  12689 
  12690     if (enable) {
  12691         fval |= 1 << (mmu_port & 0x0f);
  12692     } else {
  12693         fval &= ~(1 << (mmu_port & 0x0f));
  12694     }
  12695     soc_reg_field_set(unit, reg, &rval, field, fval);
  12696     SOC_IF_ERROR_RETURN
  12697         (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
  12698 
  12699     return SOC_E_NONE;
  12700 }
  12701 
  12702 STATIC int
  12703 _soc_trident2_misc_init(int unit)
  12704 {
  12705     static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 };
  12706     soc_info_t *si;
  12707     uint32 rval = 0;
  12708     uint64 rval64;
  12709     uint32 entry[SOC_MAX_MEM_WORDS];
  12710     soc_pbmp_t pbmp;
  12711     int port;
  12712     int index, count, sub_sel, offset;
  12713     int freq, target_freq, divisor, dividend, delay;
  12714     int parity_enable, cache_fpgm;
  12715     soc_field_t fields[2];
  12716     uint32 values[2];
  12717     uint16 dev_id;
  12718     uint8 rev_id;
  12719     int l2_banks, l3_banks, l2_mode, l3_mode;
  12720     int shared_l2_banks, shared_l3_banks;
  12721     uint32 uft_bank_enable_bitmap;
  12722     int cam_enable;
  12723     int higig2;
  12724 
  12725     si = &SOC_INFO(unit);
  12726 
  12727 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12728     _mmu_16_mode = get_mmu_mode (unit);
  12729 #endif
  12730 
  12731     /* Stop the mem scan task before all of the parity init takes place */
  12732     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
  12733     SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit));
  12734 
  12735     parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
  12736     if (parity_enable) {
  12737         if ((!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) &&
  12738             !SOC_WARM_BOOT(unit)) {
  12739             /* Certain mems/regs need to be cleared before enabling SER */
  12740             SOC_IF_ERROR_RETURN(_soc_trident2_clear_mmu_memory(unit, INVALIDm));
  12741             SOC_IF_ERROR_RETURN(_soc_trident2_clear_all_port_data(unit));
  12742         }
  12743 
  12744         /* Check the whether the alpm tables use cache to recover*/
  12745         soc_ser_alpm_cache_check(unit);
  12746 
  12747         /* Enable logging of SER events */
  12748         soc_ser_log_init(unit, NULL, 0);
  12749 
  12750         SOC_IF_ERROR_RETURN(_soc_trident2_tcam_ser_init(unit));
  12751         SOC_IF_ERROR_RETURN(_soc_trident2_ser_enable_all(unit, TRUE));
  12752 #ifdef INCLUDE_MEM_SCAN
  12753         soc_mem_scan_ser_list_register(unit, TRUE,
  12754                                        _soc_td2_tcam_ser_info[unit]);
  12755 #endif
  12756         memset(&_td2_ser_functions, 0, sizeof(soc_ser_functions_t));
  12757         _td2_ser_functions._soc_ser_fail_f = &soc_trident2_ser_fail;
  12758         _td2_ser_functions._soc_ser_parity_error_cmicm_intr_f =
  12759             &soc_trident2_ser_error;
  12760         soc_ser_function_register(unit, &_td2_ser_functions);
  12761 #if defined(SER_TR_TEST_SUPPORT)
  12762         /*Initialize chip-specific functions for SER testing*/
  12763         memset(&ser_trident2_test_fun, 0, sizeof(soc_ser_test_functions_t));
  12764         ser_trident2_test_fun.inject_error_f = &soc_td2_ser_inject_error;
  12765         ser_trident2_test_fun.test_mem = &soc_td2_ser_test_mem;
  12766         ser_trident2_test_fun.test = &soc_td2_ser_test;
  12767         ser_trident2_test_fun.parity_control = &_ser_test_parity_control_reg_set;
  12768         ser_trident2_test_fun.injection_support = &soc_td2_ser_error_injection_support;
  12769         soc_ser_test_functions_register(unit, &ser_trident2_test_fun);
  12770 #endif /*defined(SER_TR_TEST_SUPPORT*/
  12771     }
  12772     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
  12773         if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN ||
  12774                             soc_property_get(unit, "sim_clear_all_mem", 0)) {
  12775             SOC_IF_ERROR_RETURN
  12776                 (_soc_trident2_clear_all_memory(unit, (parity_enable ? 0 : 1)));
  12777         }
  12778         if (!parity_enable) {
  12779             /* Clear enabled port's regs if not done above */
  12780             SOC_IF_ERROR_RETURN(_soc_trident2_clear_enabled_port_data(unit));
  12781         }
  12782     }
  12783 
  12784     SOC_IF_ERROR_RETURN(_soc_trident2_port_mapping_init(unit));
  12785     SOC_IF_ERROR_RETURN(_soc_trident2_tdm_init(unit));
  12786 
  12787     sal_memset(entry, 0, sizeof(cpu_pbm_entry_t));
  12788     soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit));
  12789     SOC_IF_ERROR_RETURN
  12790         (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry));
  12791 
  12792     sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t));
  12793     soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit));
  12794     SOC_IF_ERROR_RETURN
  12795         (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry));
  12796 
  12797     sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t));
  12798     soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf,
  12799                            &PBMP_LB(unit));
  12800     SOC_IF_ERROR_RETURN
  12801         (soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm, MEM_BLOCK_ALL, 0,
  12802                        entry));
  12803 
  12804     sal_memset(entry, 0, sizeof(isbs_port_to_pipe_mapping_entry_t));
  12805     soc_mem_pbmp_field_set(unit, ISBS_PORT_TO_PIPE_MAPPINGm, entry, BITMAPf,
  12806                            &PBMP_YPIPE(unit));
  12807     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ISBS_PORT_TO_PIPE_MAPPINGm,
  12808                                       MEM_BLOCK_ALL, 0, entry));
  12809 
  12810     sal_memset(entry, 0, sizeof(esbs_port_to_pipe_mapping_entry_t));
  12811     soc_mem_pbmp_field_set(unit, ESBS_PORT_TO_PIPE_MAPPINGm, entry, BITMAPf,
  12812                            &PBMP_YPIPE(unit));
  12813     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ESBS_PORT_TO_PIPE_MAPPINGm,
  12814                                       MEM_BLOCK_ALL, 0, entry));
  12815 
  12816 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  12817     if (SOC_IS_TRIDENT2PLUS(unit) && soc_feature(unit, soc_feature_fp_based_oam)) {
  12818         sal_memset(entry, 0, sizeof(sgpp_to_pipe_mapping_entry_t));
  12819         soc_mem_pbmp_field_set(unit, SGPP_TO_PIPE_MAPPINGm, entry,
  12820                                PIPE_Y_BITMAPf, &PBMP_YPIPE(unit));
  12821         SOC_IF_ERROR_RETURN(soc_mem_write(unit, SGPP_TO_PIPE_MAPPINGm,
  12822                                           MEM_BLOCK_ALL, 0, entry));
  12823     }
  12824 #endif
  12825 
  12826     sal_memset(entry, 0, sizeof(egr_ing_port_entry_t));
  12827     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1);
  12828     PBMP_HG_ITER(unit, port) {
  12829         higig2 = soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE,
  12830                                        soc_feature(unit,
  12831                                        soc_feature_no_higig_plus) ? 1 : 0)
  12832                                        ? 1 : 0;
  12833         soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, higig2);
  12834         SOC_IF_ERROR_RETURN
  12835             (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry));
  12836     }
  12837     higig2 = soc_property_port_get(unit, CMIC_PORT(unit), spn_HIGIG2_HDR_MODE,
  12838                                    soc_feature(unit,
  12839                                    soc_feature_no_higig_plus) ? 1 : 0)
  12840                                    ? 1 : 0;
  12841     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, higig2);
  12842     SOC_IF_ERROR_RETURN
  12843         (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index,
  12844                        entry));
  12845     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2);
  12846     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, 0);
  12847     SOC_IF_ERROR_RETURN
  12848         (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, LB_PORT(unit),
  12849                        entry));
  12850 
  12851     /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to
  12852      * initialize the cache until now.  This is the time to check for
  12853      * the cache permission of this table.
  12854      */
  12855     cache_fpgm = soc_feature(unit, soc_feature_mem_cache) &&
  12856             soc_property_get(unit, spn_MEM_CACHE_ENABLE,
  12857                              (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1);
  12858     if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) {
  12859         char mem_name[100];
  12860         char *mptr;
  12861 
  12862         sal_memset(mem_name, 0, sizeof(mem_name));
  12863         sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_"));
  12864         mptr = &mem_name[sal_strlen(mem_name)];
  12865         sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm),
  12866                     sizeof(mem_name) - sal_strlen(mem_name) - 1);
  12867         if (soc_property_get(unit, mem_name, 0)) {
  12868             cache_fpgm = 0;
  12869         }
  12870     }
  12871 
  12872     if (cache_fpgm && (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) {
  12873         SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |=
  12874             SOC_MEM_FLAG_CACHABLE;
  12875         SOC_IF_ERROR_RETURN
  12876             (soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm,
  12877                                MEM_BLOCK_ALL, TRUE));
  12878     }
  12879 
  12880     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
  12881         /* Must clear FP_GLOBAL_MASK_TCAM after port to pipe mappings
  12882          * are initialized. */
  12883         SOC_IF_ERROR_RETURN
  12884             (soc_mem_clear(unit, FP_GLOBAL_MASK_TCAMm, COPYNO_ALL, TRUE));
  12885     }
  12886 
  12887     SOC_IF_ERROR_RETURN(_soc_trident2_port_init(unit));
  12888 
  12889     /* Enable QGPORT in XLPORT3 block (if present) */
  12890     SOC_PBMP_ITER(si->management_pbm, port) {
  12891         COMPILER_64_ZERO(rval64);
  12892         soc_reg64_field32_set(unit, CELL_ASM_0_CONTROLr, &rval64,
  12893                               QGPORT_ENABLEf, 1);
  12894         SOC_IF_ERROR_RETURN
  12895             (soc_reg_set(unit, CELL_ASM_0_CONTROLr, port, 0, rval64));
  12896         break;
  12897     }
  12898 
  12899     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
  12900     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
  12901     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
  12902 
  12903     /* Enable dual hash tables */
  12904     SOC_IF_ERROR_RETURN(_soc_trident2_hash_init(unit));
  12905     if (!soc_feature(unit, soc_feature_enable_lp)) {
  12906         if (!SOC_IS_TRIDENT2PLUS(unit) && !SOC_IS_TITAN2PLUS(unit)) {
  12907             SOC_IF_ERROR_RETURN
  12908                     (soc_reg_field32_modify(unit, L2_ENTRY_CONTROL_6r, REG_PORT_ANY,
  12909                                             DISABLE_L2_ENTRY_LPf, 3));
  12910         }
  12911         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, L3_ENTRY_CONTROL_10r,
  12912                             REG_PORT_ANY, DISABLE_L3_ENTRY_LPf, 0xf));
  12913         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r,
  12914                             REG_PORT_ANY, DISABLE_ISS_MEMORY_LPf, 0xf));
  12915     }
  12916 
  12917     /*
  12918      * Disable Low Power mode for shared banks - UFT banks: 2, 3, 4 and 5.
  12919      */
  12920     if (soc_feature(unit, soc_feature_shared_bank_lp_disabled)) {
  12921         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  12922             ISS_MEMORY_CONTROL_84r, REG_PORT_ANY, DISABLE_ISS_MEMORY_LPf,
  12923             0xf));
  12924     }
  12925 
  12926     if (soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm) > 0) {
  12927         SOC_IF_ERROR_RETURN
  12928             (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, REG_PORT_ANY,
  12929                                     BYPASS_ISS_MEMORY_LPf, 0xf));
  12930     }
  12931 
  12932     if (SOC_IS_TD2P_TT2P(unit)) {
  12933         soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  12934         switch (dev_id) {
  12935             default:
  12936                 cam_enable = 0xFF;
  12937                 break;
  12938         }
  12939         soc_reg32_set(unit, L3_DEFIP_CAM_ENABLEr, REG_PORT_ANY, 0, cam_enable);
  12940     }
  12941 #ifdef ALPM_ENABLE
  12942 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12943     if (SOC_IS_TRIDENT2PLUS(unit)) {
  12944         int alpm_mode = 0;
  12945         SOC_IF_ERROR_RETURN
  12946             (soc_trident2p_alpm_mode_enable(unit));
  12947 
  12948         alpm_mode = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0);
  12949         if (alpm_mode && soc_feature(unit, soc_feature_alpm)) {
  12950             SOC_IF_ERROR_RETURN
  12951                 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r,
  12952                                         REG_PORT_ANY, FORCE_8XORf, 0x1));
  12953         }
  12954     }
  12955 #endif
  12956 #endif
  12957     SOC_IF_ERROR_RETURN
  12958         (soc_trident2_hash_bank_count_get(unit, L2Xm, &l2_banks));
  12959     SOC_IF_ERROR_RETURN
  12960         (soc_trident2_hash_bank_count_get(unit, L3_ENTRY_ONLYm, &l3_banks));
  12961     switch (l2_banks) {
  12962     case 2: l2_mode = 4;
  12963         break;
  12964     case 3: l2_mode = 3;
  12965         break;
  12966     case 4: l2_mode = 2;
  12967         break;
  12968     case 5: l2_mode = 1;
  12969         break;
  12970     case 6: l2_mode = 0;
  12971         break;
  12972     default:
  12973         return SOC_E_INTERNAL;
  12974     }
  12975     switch (l3_banks) {
  12976     case 4: l3_mode = 4;
  12977         break;
  12978     case 5: l3_mode = 1;
  12979         break;
  12980     case 6: l3_mode = 2;
  12981         break;
  12982     case 7: l3_mode = 3;
  12983         break;
  12984     default:
  12985         return SOC_E_INTERNAL;
  12986     }
  12987     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, L2_TABLE_HASH_CONTROLr,
  12988                                                REG_PORT_ANY, MODEf, l2_mode));
  12989     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, L3_TABLE_HASH_CONTROLr,
  12990                                                REG_PORT_ANY, MODEf, l3_mode));
  12991 
  12992     if (soc_property_get(unit, spn_LOW_POWER, 0) &&
  12993         soc_mem_index_max(unit, L3_DEFIP_ALPM_RAWm) == -1 ) {
  12994         /* coverity[dead_error_begin] */
  12995         shared_l2_banks = l2_banks - 2;
  12996         shared_l3_banks = l3_banks - 4;
  12997         uft_bank_enable_bitmap = ((0x70 >> shared_l3_banks)&0xf) | ((1 << shared_l2_banks) - 1);
  12998         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, SHARED_TABLE_HASH_CONTROLr,
  12999                                                    REG_PORT_ANY, UFT_BANK_ENABLEf,
  13000                                                    uft_bank_enable_bitmap));
  13001     }
  13002 
  13003     rval = 0;
  13004     soc_reg_field_set(unit, L2_AGE_DEBUGr, &rval, AGE_COUNTf,
  13005                       soc_mem_index_max(unit, L2Xm));
  13006     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_DEBUGr(unit, rval));
  13007 
  13008     rval = 0;
  13009     soc_reg32_get(unit, TOQ_MC_CFG2r, REG_PORT_ANY, 0, &rval);
  13010     soc_reg_field_set(unit, TOQ_MC_CFG2r, &rval, EPRG_KILL_TIMEOUTf, 500);
  13011     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, TOQ_MC_CFG2r,
  13012                 REG_PORT_ANY, 0, rval));
  13013 
  13014     if (SOC_IS_TRIDENT2(unit)) {
  13015         soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  13016         if (BCM56850_A2_REV_ID == rev_id) {
  13017             SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_Q_BEGINr,
  13018                 REG_PORT_ANY, QBUSf, 1));
  13019         }
  13020     }
  13021 
  13022     /*
  13023      * Egress Enable
  13024      */
  13025     if (!SOC_IS_TD2P_TT2P(unit)) {
  13026         int phy_port = 0;
  13027         sal_memset(entry, 0, sizeof(egr_enable_entry_t));
  13028         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  13029         PBMP_ALL_ITER(unit, port) {
  13030             phy_port = si->port_l2p_mapping[port];
  13031             SOC_IF_ERROR_RETURN
  13032                 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
  13033         }
  13034     } else {
  13035         /* TD2+ EGR_ENABLE should be setup during port up/down sequence
  13036          * Only CPU port EGR_ENABLE should be set here
  13037          */
  13038         const int cpu_port = 0;
  13039         const int loopback_port = si->port_l2p_mapping[LB_PORT(unit)];
  13040         sal_memset(entry, 0, sizeof(egr_enable_entry_t));
  13041         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  13042         SOC_IF_ERROR_RETURN
  13043             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, cpu_port, entry));
  13044         SOC_IF_ERROR_RETURN
  13045             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, loopback_port, entry));
  13046     }
  13047     sal_memset(entry, 0, sizeof(epc_link_bmap_entry_t));
  13048     soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf,
  13049                            &PBMP_CMIC(unit));
  13050     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry));
  13051 
  13052 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13053     if ((SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TITAN2PLUS(unit))) {
  13054 
  13055         /* Bypass control settings */
  13056         if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) {
  13057             if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) {
  13058                 rval = 0;
  13059 
  13060                 /* TD2+ does not support IRSEL1 and IVP bypass stage */
  13061                 /*soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  13062                                        IRSEL1_STAGE_BYPASS_ENABLEf, 1);
  13063                 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  13064                                        IVP_STAGE_BYPASS_ENABLEf, 1);*/
  13065 
  13066                 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  13067                                        IVXLT_STAGE_BYPASS_ENABLEf, 1);
  13068 
  13069                 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  13070                                       IFP_STAGE_BYPASS_ENABLEf, 1);
  13071 
  13072                 SOC_IF_ERROR_RETURN(WRITE_ING_BYPASS_CTRLr(unit, rval));
  13073 
  13074                 soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval,
  13075                                        EFP_STAGE_BYPASS_ENABLEf, 1);
  13076 
  13077                 SOC_IF_ERROR_RETURN(WRITE_EGR_BYPASS_CTRLr(unit, rval));
  13078             }
  13079         }
  13080     }
  13081 #endif
  13082 
  13083 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13084     if (SOC_IS_TD2P_TT2P(unit)) {
  13085         /* enable all ports */
  13086         ing_dest_port_enable_entry_t ingr_entry;
  13087         modport_map_subport_entry_t map_entry;
  13088 
  13089         sal_memset(&ingr_entry, 0, sizeof(ingr_entry));
  13090         soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, &ingr_entry, PORT_BITMAPf,
  13091                                &PBMP_ALL(unit));
  13092 
  13093         SOC_IF_ERROR_RETURN(WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0,
  13094                                                  &ingr_entry));
  13095 
  13096         sal_memset(&map_entry, 0, sizeof(map_entry));
  13097         soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, ENABLEf, 1);
  13098 
  13099         /* my_modid and other modid related initialization */
  13100         PBMP_ALL_ITER(unit, port) {
  13101             /* by default port is not trunk */
  13102             /* value already 0
  13103             soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, ISTRUNKf, 0);
  13104             */
  13105             /* configure logical port numbers */
  13106             soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, DESTf, port);
  13107             SOC_IF_ERROR_RETURN
  13108                 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL, port, &map_entry));
  13109         }
  13110         /* setting up my_modid */
  13111         SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64));
  13112 
  13113         soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
  13114                               MODID_0_VALIDf, 1);
  13115         soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
  13116                               MODID_0f, SOC_BASE_MODID(unit));
  13117 
  13118         SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64));
  13119 
  13120     }
  13121 #endif
  13122 
  13123     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64));
  13124     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13125                           L3SRC_HIT_ENABLEf, 1);
  13126     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13127                           L2DST_HIT_ENABLEf, 1);
  13128     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13129                           APPLY_EGR_MASK_ON_L2f, 1);
  13130     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13131                           APPLY_EGR_MASK_ON_L3f, 1);
  13132     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13133                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
  13134     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13135                           ARP_VALIDATION_ENf, 1);
  13136 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  13137     /*
  13138      * If riot is enabled,
  13139      *     MY_STATION1 will be used for tunnels.
  13140      *     MY_STATION2 will be used for routing.
  13141      * Else,
  13142      *     MY_STATION1 should be used for both tunnels and routing.
  13143      *     For this, USE_MY_STATION1_FOR_NON_TUNNELS should be set to TRUE.
  13144      *
  13145      * To avoid executing this code on non-td2plus devices, this code needs to
  13146      * be checked with soc_feature_my_station_2 as well.
  13147      */
  13148     if (soc_feature(unit, soc_feature_my_station_2) &&
  13149         (!soc_feature(unit, soc_feature_riot))) {
  13150         soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13151                 USE_MY_STATION1_FOR_NON_TUNNELSf, 1);
  13152     }
  13153 #endif
  13154     if (soc_feature(unit, soc_feature_port_lag_failover)) {
  13155         soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13156                 IGNORE_HG_HDR_LAG_FAILOVERf, 0);
  13157     } else {
  13158         soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  13159                 IGNORE_HG_HDR_LAG_FAILOVERf, 1);
  13160     }
  13161     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64));
  13162 
  13163     SOC_IF_ERROR_RETURN
  13164         (soc_reg_field32_modify(unit, EGR_CONFIG_1r, REG_PORT_ANY, RING_MODEf,
  13165                                 1));
  13166 
  13167     PBMP_ALL_ITER(unit, port) {
  13168         if (SOC_PBMP_MEMBER(si->eq_pbm, port)) {
  13169             SOC_IF_ERROR_RETURN(_soc_trident2_mc_toq_cfg(unit, port, TRUE));
  13170         }
  13171     }
  13172 
  13173     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
  13174      * causes the outer tag to be removed from packets that don't have
  13175      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
  13176      */
  13177 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13178     if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  13179         egr_vlan_control_1_entry_t entry;
  13180         sal_memset(&entry, 0, sizeof(entry));
  13181 
  13182         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_1m, &entry, VT_MISS_UNTAGf, 0);
  13183 
  13184         /* Enable pri/cfi remarking on egress ports. */
  13185         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_1m, &entry, REMARK_OUTER_DOT1Pf,
  13186                       1);
  13187         PBMP_ALL_ITER(unit, port) {
  13188             SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ALL, port, &entry));
  13189         }
  13190     } else
  13191 #endif
  13192     {
  13193         rval = 0;
  13194         soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
  13195 
  13196         /* Enable pri/cfi remarking on egress ports. */
  13197         soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,
  13198                       1);
  13199         PBMP_ALL_ITER(unit, port) {
  13200             SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval));
  13201         }
  13202     }
  13203 
  13204     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  13205     SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit));
  13206     SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
  13207                                      MEM_BLOCK_ANY, 0, &entry));
  13208     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf,
  13209                            &pbmp);
  13210     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
  13211                                       MEM_BLOCK_ANY, 0, &entry));
  13212 
  13213     /* Multicast range initialization */
  13214     SOC_IF_ERROR_RETURN
  13215         (soc_hbx_higig2_mcast_sizes_set(unit,
  13216              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
  13217                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
  13218              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
  13219                               soc_mem_index_count(unit, L2MCm) / 2),
  13220              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
  13221                               soc_mem_index_count(unit, L2MCm) / 2)));
  13222 
  13223 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13224     if (soc_feature(unit, soc_feature_ipmc_to_l2mc_table_size_2_to_3)) {
  13225         /*
  13226          * Trident2+ supports 8K L2MC groups and 16K IPMC groups.
  13227          * When the device is configured as a fabric,
  13228          * L2MC table support both L2MC and IPMC groups.
  13229          * Hence the L2MC table is 24K
  13230          */
  13231         int l2mc_size = (soc_mem_index_count(unit, L2MCm) / 3);
  13232         int ipmc_size = ((soc_mem_index_count(unit, L2MCm) / 3) * 2);
  13233         SOC_IF_ERROR_RETURN
  13234             (soc_hbx_mcast_size_set(unit, soc_property_get(unit,
  13235                  spn_MULTICAST_L2_RANGE, l2mc_size)));
  13236         SOC_IF_ERROR_RETURN
  13237             (soc_hbx_ipmc_size_set(unit, soc_property_get(unit,
  13238                  spn_MULTICAST_L3_RANGE, ipmc_size)));
  13239     } else
  13240 #endif
  13241     {
  13242         SOC_IF_ERROR_RETURN
  13243             (soc_hbx_mcast_size_set(unit, soc_property_get(unit,
  13244                  spn_MULTICAST_L2_RANGE, soc_mem_index_count(unit, L2MCm) / 2)));
  13245         SOC_IF_ERROR_RETURN
  13246             (soc_hbx_ipmc_size_set(unit, soc_property_get(unit,
  13247                  spn_MULTICAST_L3_RANGE, soc_mem_index_count(unit, L2MCm) / 2)));
  13248     }
  13249 
  13250     /* Setup SW2_FP_DST_ACTION_CONTROL */
  13251     fields[0] = HGTRUNK_RES_ENf;
  13252     values[0] = 1;
  13253     fields[1] = LAG_RES_ENf;
  13254     values[1] = 1;
  13255     SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit,
  13256                 SW2_FP_DST_ACTION_CONTROLr, REG_PORT_ANY, 2, fields, values));
  13257 
  13258     /* Populate and enable RTAG7 Macro flow offset table */
  13259     if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) {
  13260         count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm);
  13261         sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t));
  13262         for (index = 0; index < count; ) {
  13263             for (sub_sel = 0; sub_sel < 8 && index < count; sub_sel++) {
  13264                 for (offset = 0;
  13265                      offset < rtag7_field_width[sub_sel] && index < count;
  13266                      offset++) {
  13267                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  13268                                         SUB_SEL_ECMPf, sub_sel);
  13269                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  13270                                         OFFSET_ECMPf, offset);
  13271 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
  13272                     if(soc_feature(unit, soc_feature_riot) ||
  13273                        soc_feature(unit, soc_feature_multi_level_ecmp)) {
  13274                         soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  13275                                             SUB_SEL_ECMP_LEVEL1f, sub_sel);
  13276                         soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  13277                                             OFFSET_ECMP_LEVEL1f, offset);
  13278                     }
  13279 #endif
  13280                     SOC_IF_ERROR_RETURN
  13281                         (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm,
  13282                                        MEM_BLOCK_ANY, index, &entry));
  13283                     index++;
  13284                 }
  13285             }
  13286         }
  13287         rval = 0;
  13288         soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, USE_FLOW_SEL_ECMPf, 1);
  13289 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
  13290         if(soc_feature(unit, soc_feature_riot) ||
  13291            soc_feature(unit, soc_feature_multi_level_ecmp)) {
  13292             soc_reg_field_set(unit, RTAG7_HASH_SELr,
  13293                 &rval, USE_FLOW_SEL_ECMP1f, 1);
  13294         }
  13295 #endif
  13296         soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval,
  13297                                                 USE_FLOW_SEL_TRILL_ECMPf, 1);
  13298         SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_SELr(unit, rval));
  13299     }
  13300 
  13301     freq = si->frequency;
  13302 
  13303     /*
  13304      * Set external MDIO freq to around 6MHz
  13305      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
  13306      */
  13307     target_freq = 6;
  13308     divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2);
  13309     divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, divisor);
  13310     dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1);
  13311     rval = 0;
  13312     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor);
  13313     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend);
  13314     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval));
  13315 
  13316     /*
  13317      * Set internal MDIO freq to around 12MHz
  13318      * Valid range is from 2.5MHz to 20MHz
  13319      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
  13320      * or
  13321      * DIVISOR = core_clock_freq * DIVIDENT / (target_freq * 2)
  13322      */
  13323     target_freq = 12;
  13324     divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2);
  13325     divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, divisor);
  13326     dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1);
  13327     rval = 0;
  13328     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf,
  13329                        divisor);
  13330     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf,
  13331                        dividend);
  13332     /* coverity[result_independent_of_operands] */
  13333     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval));
  13334 
  13335     delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1);
  13336     if (delay >= 1  && delay <= 15) {
  13337         /* coverity[result_independent_of_operands] */
  13338         SOC_IF_ERROR_RETURN(READ_CMIC_MIIM_CONFIGr(unit, &rval));
  13339         soc_reg_field_set(unit, CMIC_MIIM_CONFIGr, &rval, MDIO_OUT_DELAYf,
  13340                           delay);
  13341         SOC_IF_ERROR_RETURN(WRITE_CMIC_MIIM_CONFIGr(unit, rval));
  13342     }
  13343 
  13344     if (!SOC_WARM_BOOT(unit)) {
  13345         SOC_IF_ERROR_RETURN(_soc_td2_ledup_init(unit));
  13346     }
  13347 
  13348 #if defined(BCM_CMICM_SUPPORT)
  13349     if (soc_mspi_init(unit) != SOC_E_NONE) {
  13350         LOG_WARN(BSL_LS_SOC_COMMON,
  13351                  (BSL_META_U(unit,
  13352                              "unit %d : MSPI Init Failed\n"), unit));
  13353     }
  13354 #endif
  13355 
  13356     _phy_tscmod_firmware_set_helper[unit] = _soc_trident2_tsc_firmware_set;
  13357 
  13358     if (parity_enable) {
  13359         SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
  13360         SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit));
  13361     }
  13362 
  13363     return SOC_E_NONE;
  13364 }
  13365 
  13366 
  13367 soc_mem_t
  13368 _soc_trident2_pmem(int unit, int port, soc_mem_t memx, soc_mem_t memy)
  13369 {
  13370     soc_info_t *si = &SOC_INFO(unit);
  13371     return (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) ? memx : memy;
  13372 }
  13373 
  13374 soc_reg_t
  13375 _soc_trident2_preg(int unit, int port, soc_reg_t regx, soc_reg_t regy)
  13376 {
  13377     soc_info_t *si = &SOC_INFO(unit);
  13378     return (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) ? regx : regy;
  13379 }
  13380 
  13381 uint32 _soc_trident2_mmu_port(int unit, int port)
  13382 {
  13383     soc_info_t *si = &SOC_INFO(unit);
  13384     return si->port_p2m_mapping[si->port_l2p_mapping[port]];
  13385 }
  13386 
  13387 uint32 _soc_trident2_piped_mem_index(int unit, soc_port_t port,
  13388                                      soc_mem_t mem, int arr_off)
  13389 {
  13390     int     mmu_port;
  13391 
  13392     mmu_port = SOC_TD2_MMU_PORT(unit, port);
  13393 
  13394     switch (mem) {
  13395     case MMU_THDM_DB_PORTSP_CONFIG_0m:
  13396     case MMU_THDM_DB_PORTSP_CONFIG_1m:
  13397     case MMU_THDM_MCQE_PORTSP_CONFIG_0m:
  13398     case MMU_THDM_MCQE_PORTSP_CONFIG_1m:
  13399         return (mmu_port & 0x3f) + _TD2_MMU_PORTS_PER_PIPE * arr_off;
  13400     case THDI_PORT_SP_CONFIG_Xm:
  13401     case THDI_PORT_SP_CONFIG_Ym:
  13402     case THDI_PORT_SP_CNTRS_RT_Xm:
  13403     case THDI_PORT_SP_CNTRS_RT_Ym:
  13404     case THDI_PORT_SP_CNTRS_SH_Xm:
  13405     case THDI_PORT_SP_CNTRS_SH_Ym:
  13406     case MMU_THDU_XPIPE_CONFIG_PORTm:
  13407     case MMU_THDU_YPIPE_CONFIG_PORTm:
  13408     case MMU_THDU_XPIPE_RESUME_PORTm:
  13409     case MMU_THDU_YPIPE_RESUME_PORTm:
  13410     case MMU_THDU_XPIPE_COUNTER_PORTm:
  13411     case MMU_THDU_YPIPE_COUNTER_PORTm:
  13412         return (mmu_port & 0x3f) * _TD2_MMU_NUM_POOL + arr_off;
  13413     case THDI_PORT_PG_CONFIG_Xm:
  13414     case THDI_PORT_PG_CONFIG_Ym:
  13415     case THDI_PORT_PG_CNTRS_RT1_Xm:
  13416     case THDI_PORT_PG_CNTRS_RT1_Ym:
  13417     case THDI_PORT_PG_CNTRS_RT2_Xm:
  13418     case THDI_PORT_PG_CNTRS_RT2_Ym:
  13419     case THDI_PORT_PG_CNTRS_SH1_Xm:
  13420     case THDI_PORT_PG_CNTRS_SH1_Ym:
  13421     case THDI_PORT_PG_CNTRS_SH2_Xm:
  13422     case THDI_PORT_PG_CNTRS_SH2_Ym:
  13423         return (mmu_port & 0x3f) * _TD2_MMU_NUM_PG + arr_off;
  13424    default:
  13425         return 0xffffffff;
  13426     }
  13427 }
  13428 
  13429 #define _TD2_MMU_BYTES_TO_CELLS(_byte_)  \
  13430     (((_byte_) + _TD2_MMU_BYTES_PER_CELL - 1) / _TD2_MMU_BYTES_PER_CELL)
  13431 
  13432 void
  13433 _soc_td2_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg,
  13434                              int lossless)
  13435 {
  13436     soc_info_t *si;
  13437     int fifo_entry_count;
  13438     soc_pbmp_t pbmp;
  13439     int port;
  13440     uint16 dev_id;
  13441     uint8 rev_id;
  13442     uint32* dev_mmu_params_arr = NULL;
  13443 
  13444     si = &SOC_INFO(unit);
  13445     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  13446 
  13447     sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t));
  13448 
  13449 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13450     if (SOC_IS_TD2P_TT2P(unit)) {
  13451         dev_mmu_params_arr = soc_td2p_mmu_params_arr_get(dev_id, rev_id);
  13452     } else
  13453 #endif
  13454     {
  13455         dev_mmu_params_arr = soc_td2_mmu_params_arr_get(dev_id, rev_id);
  13456     }
  13457 
  13458     if (!dev_mmu_params_arr) {
  13459         return;
  13460     }
  13461 
  13462     devcfg->max_pkt_byte = dev_mmu_params_arr[_MMU_MAX_PACKET_BYTES];
  13463     devcfg->mmu_hdr_byte = _TD2_MMU_PACKET_HEADER_BYTES;
  13464     devcfg->jumbo_pkt_size = _TD2_MMU_JUMBO_FRAME_BYTES;
  13465     devcfg->default_mtu_size = _TD2_MMU_DEFAULT_MTU_BYTES;
  13466     devcfg->mmu_cell_size = _TD2_MMU_BYTES_PER_CELL;
  13467     /*
  13468      * Reserve 1 cell for each cut-through fifo entry
  13469      * Assume each port use 1 QCN queue, reserve 1 cell for each QCN queue
  13470      * Reserve 10 cells for ingress pool overshoot for lossless setting
  13471      */
  13472     fifo_entry_count = 0;
  13473     SOC_PBMP_ASSIGN(pbmp, si->port.bitmap);
  13474     SOC_PBMP_REMOVE(pbmp, si->all.disabled_bitmap);
  13475     SOC_PBMP_ITER(pbmp, port) {
  13476         fifo_entry_count += si->port_speed_max[port] <= 11000 ? 4 : 16;
  13477     }
  13478 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13479         if (SOC_IS_TD2P_TT2P(unit)) {
  13480             if ((FALSE == si->flex_eligible) && soc_td2p_is_any_port_flex_enable(unit)) {
  13481                 fifo_entry_count = 0;
  13482             }
  13483         }
  13484 #endif
  13485     devcfg->mmu_total_cell = dev_mmu_params_arr[_MMU_TOTAL_CELLS] - fifo_entry_count -
  13486         NUM_PORT(unit) - (lossless ? 10 : 0);
  13487     devcfg->num_pg = _TD2_MMU_NUM_PG;
  13488     devcfg->num_service_pool = _TD2_MMU_NUM_POOL;
  13489     devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN |
  13490                     SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY;
  13491     devcfg->total_mcq_entry = _TD2_MMU_TOTAL_MCQ_ENTRY(unit);
  13492     devcfg->total_mcq_entry -= SOC_TD2_MMU_MCQ_RSVD_ENTRY;
  13493     devcfg->rqe_queue_num = 11;
  13494 }
  13495 
  13496 int
  13497 _soc_td2_default_lossless_pg_headroom(int unit, soc_port_t port)
  13498 {
  13499     soc_info_t *si;
  13500 
  13501     if (IS_CPU_PORT(unit, port)) {
  13502         return 50;
  13503     } else if (IS_LB_PORT(unit, port)) {
  13504         return 162;
  13505     }
  13506 
  13507     si = &SOC_INFO(unit);
  13508     if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) {
  13509         if (si->port_speed_max[port] >= 40000) {
  13510             return 461;
  13511         } else if (si->port_speed_max[port] >= 20000) {
  13512             return 262;
  13513         } else {
  13514             return 182;
  13515         }
  13516     } else {
  13517         if (si->port_speed_max[port] >= 100000) {
  13518             return 558;
  13519         } else if (si->port_speed_max[port] >= 40000) {
  13520             return 284;
  13521         } else if (si->port_speed_max[port] >= 20000) {
  13522             return 183;
  13523         } else {
  13524             return 162;
  13525         }
  13526     }
  13527 
  13528     return 0;
  13529 }
  13530 
  13531 int
  13532 _soc_td2_min_cell_rsvd_per_mcq(int unit, int port, int default_val)
  13533 {
  13534     int freq, speed, osub;
  13535     soc_info_t *si;
  13536     uint8 rev_id;
  13537 
  13538     soc_cm_get_id_otp(unit, NULL, &rev_id);
  13539 
  13540     if (rev_id == BCM56850_A1_REV_ID) {
  13541         si = &SOC_INFO(unit);
  13542         speed = si->port_speed_max[port];
  13543         osub = (SOC_PBMP_MEMBER(si->oversub_pbm, port)) ? 1 : 0;
  13544 
  13545         if (speed <= 10000) {
  13546             return (osub) ? 10 : 5;
  13547         } else if (speed <= 40000) {
  13548             freq = si->frequency;
  13549             return ((freq >= 760) && !osub) ? 9 : 16;
  13550         }
  13551     }
  13552 
  13553     return default_val;
  13554 }
  13555 
  13556 void
  13557 _soc_td2_mmu_config_buf_default_global(int unit, _soc_mmu_cfg_buf_t *buf,
  13558                                 _soc_mmu_device_info_t *devcfg, int lossless)
  13559 {
  13560     soc_info_t *si;
  13561     _soc_mmu_cfg_buf_pool_t *buf_pool;
  13562     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
  13563     int max_packet_cells, default_mtu_cells;
  13564     int port, idx, per_q_guarentee;
  13565     int total_pool_size = 0, egr_shared_total = 0;
  13566     int q_reserved = 0, in_reserved = 0;
  13567     int rqe_entry_shared_total;
  13568     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
  13569     int asf_rsvd = 0, ing_rsvd = 0, egr_rsvd = 0, mcq_entry_rsvd = 0;
  13570 
  13571     si = &SOC_INFO(unit);
  13572 
  13573     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  13574                 (BSL_META_U(unit,
  13575                             "Initializing default MMU config (u=%d)\n"), unit));
  13576     max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte +
  13577                                                    devcfg->mmu_hdr_byte,
  13578                                                    devcfg->mmu_cell_size);
  13579     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  13580                                                    devcfg->mmu_hdr_byte,
  13581                                                    devcfg->mmu_cell_size);
  13582 
  13583     total_pool_size = devcfg->mmu_total_cell;
  13584 
  13585     /* Flex port Additional buffer reserve
  13586  */
  13587     for (idx = 0; idx < NUM_PIPE(unit); idx++) {
  13588 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13589         if (SOC_IS_TD2P_TT2P(unit)) {
  13590             /* si->flex_eligible TRUE means that the old legacy ':i' flexport
  13591                is enabled. We should NOT be allocating resources according to
  13592                the new specifications. */
  13593             if (FALSE == si->flex_eligible) {
  13594                 /* This checks to see if the new flex port method has been specified
  13595                    in the config file and is being used */
  13596                 if(soc_td2p_is_any_port_flex_enable(unit)) {
  13597                     soc_td2p_mmu_additional_buffer_reserve(unit, idx, FALSE,
  13598                             &buf->rsvd_buffers[idx]);
  13599                 }
  13600             }
  13601         }
  13602 #endif
  13603             asf_rsvd += buf->rsvd_buffers[idx].asf_rsvd_cells;
  13604             egr_rsvd += buf->rsvd_buffers[idx].egr_rsvd_cells;
  13605             ing_rsvd += buf->rsvd_buffers[idx].ing_rsvd_cells;
  13606             mcq_entry_rsvd += buf->rsvd_buffers[idx].mcq_entry_rsvd;
  13607     }
  13608 
  13609     egr_rsvd_g = egr_rsvd;
  13610     asf_rsvd_g = asf_rsvd;
  13611 
  13612     if (SOC_IS_TD2P_TT2P(unit)) {
  13613         buf->headroom = _TD2_PIPES_PER_DEV * _TD2P_MMU_GLOBAL_HEADROOM;
  13614     } else {
  13615         buf->headroom = _TD2_PIPES_PER_DEV * max_packet_cells;
  13616     }
  13617 
  13618     in_reserved += buf->headroom;
  13619 
  13620     per_q_guarentee = (lossless) ? 0 : default_mtu_cells;
  13621 
  13622     PBMP_ALL_ITER(unit, port) {
  13623         q_reserved += (si->port_num_cosq[port] + si->port_num_uc_cosq[port]) *
  13624             per_q_guarentee;
  13625     }
  13626 
  13627     egr_shared_total = total_pool_size - q_reserved -
  13628                        (asf_rsvd + egr_rsvd);
  13629 
  13630     LOG_VERBOSE(BSL_LS_SOC_MMU,
  13631                 (BSL_META_U(unit,
  13632                             "MMU config: Total Shared size: %d\n"),
  13633                             egr_shared_total));
  13634 
  13635     rqe_entry_shared_total = _TD2_MMU_TOTAL_RQE_ENTRY(unit) -
  13636                              SOC_TD2_MMU_RQE_TOTAL_RSVD_ENTRY -
  13637                              SOC_TD2_MMU_RQE_USER_RSVD_ENTRY;
  13638 
  13639     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  13640         buf_pool = &buf->pools[idx];
  13641 
  13642         if (idx == 0) {  /* 100% scale up by 100 */
  13643             buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  13644             buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  13645             buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  13646             buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  13647             buf_pool->total_rqe_entry = rqe_entry_shared_total;
  13648         } else {
  13649             buf_pool->size = 0;
  13650             buf_pool->yellow_size = 0;
  13651             buf_pool->red_size = 0;
  13652             buf_pool->total_mcq_entry = 0;
  13653             buf_pool->total_rqe_entry = 0;
  13654         }
  13655     }
  13656 
  13657     for (idx = 0; idx < SOC_TD2_MMU_CFG_QGROUP_MAX; idx++) {
  13658         queue_grp = &buf->qgroups[idx];
  13659         queue_grp->guarantee = SOC_TD2_MMU_QGROUP_MIN_RSVD;
  13660         queue_grp->pool_limit = total_pool_size;
  13661         queue_grp->discard_enable = (lossless) ? 0 : 1;
  13662         queue_grp->pool_scale = -1;
  13663         queue_grp->pool_resume = default_mtu_cells * 2;
  13664         queue_grp->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  13665         queue_grp->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  13666         queue_grp->yellow_resume = default_mtu_cells * 2;
  13667         queue_grp->red_resume = default_mtu_cells * 2;
  13668 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13669         if (SOC_IS_TD2P_TT2P(unit)) {
  13670             if (!lossless) {
  13671                 queue_grp->pool_limit = 0;
  13672                 queue_grp->pool_scale = 8;
  13673                 queue_grp->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  13674                 queue_grp->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  13675             }
  13676         }
  13677 #endif
  13678     }
  13679 
  13680     /* RQE */
  13681     for (idx = 0; idx < 11; idx++) {
  13682         buf_rqe_queue = &buf->rqe_queues[idx];
  13683         buf_rqe_queue->pool_idx = 0;
  13684         if (lossless) {
  13685             buf_rqe_queue->discard_enable = 0;
  13686             buf_rqe_queue->pool_scale = -1;
  13687             buf_rqe_queue->pool_limit = egr_shared_total;
  13688             buf_rqe_queue->yellow_limit = egr_shared_total;
  13689             buf_rqe_queue->red_limit = egr_shared_total;
  13690         } else {
  13691             buf_rqe_queue->discard_enable = 1;
  13692             buf_rqe_queue->pool_scale = 8;
  13693             buf_rqe_queue->pool_limit = 0;
  13694             buf_rqe_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  13695             buf_rqe_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  13696         }
  13697         buf_rqe_queue->guarantee = default_mtu_cells;
  13698     }
  13699 }
  13700 
  13701 void
  13702 _soc_td2_mmu_config_buf_default_port(int unit, int in_port, _soc_mmu_cfg_buf_t *buf,
  13703                                 _soc_mmu_device_info_t *devcfg, int lossless)
  13704 {
  13705     soc_info_t *si;
  13706     _soc_mmu_cfg_buf_port_t *buf_port;
  13707     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
  13708     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
  13709     _soc_mmu_cfg_buf_queue_t *buf_queue;
  13710     int max_packet_cells, default_mtu_cells;
  13711     int port, idx, per_q_guarentee, mcq_guarentee;
  13712     int total_pool_size = 0, egr_shared_total = 0;
  13713     int q_reserved = 0, in_reserved = 0;
  13714     int min_cell_per_mcq;
  13715 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13716     uint32 mmu_port = 0;
  13717 #endif
  13718 
  13719     si = &SOC_INFO(unit);
  13720 
  13721     min_cell_per_mcq = soc_feature(unit, soc_feature_min_cell_per_queue) ? 1 : 0;
  13722     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  13723                 (BSL_META_U(unit,
  13724                             "Initializing default MMU config (u=%d)\n"), unit));
  13725     max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte +
  13726                                                    devcfg->mmu_hdr_byte,
  13727                                                    devcfg->mmu_cell_size);
  13728     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  13729                                                    devcfg->mmu_hdr_byte,
  13730                                                    devcfg->mmu_cell_size);
  13731 
  13732     total_pool_size = devcfg->mmu_total_cell;
  13733 
  13734     if (SOC_IS_TD2P_TT2P(unit)) {
  13735         buf->headroom = _TD2_PIPES_PER_DEV * _TD2P_MMU_GLOBAL_HEADROOM;
  13736     } else {
  13737         buf->headroom = _TD2_PIPES_PER_DEV * max_packet_cells;
  13738     }
  13739 
  13740     in_reserved += buf->headroom;
  13741 
  13742     per_q_guarentee = (lossless) ? 0 : default_mtu_cells;
  13743 
  13744     PBMP_ALL_ITER(unit, port) {
  13745         q_reserved += si->port_num_uc_cosq[port] * per_q_guarentee;
  13746 
  13747         mcq_guarentee = min_cell_per_mcq ?
  13748             _soc_td2_min_cell_rsvd_per_mcq(unit, port, per_q_guarentee) :
  13749             per_q_guarentee;
  13750         q_reserved += si->port_num_cosq[port] * mcq_guarentee;
  13751     }
  13752     q_reserved += devcfg->rqe_queue_num * 8;
  13753 
  13754 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13755     if (SOC_IS_TD2P_TT2P(unit)) {
  13756         if ((FALSE == si->flex_eligible) && soc_td2p_is_any_port_flex_enable(unit)) {
  13757             /* Legacy flex port (:i) is not enabled */
  13758             /* additional per port macro buffers reserved */
  13759             egr_shared_total = total_pool_size - q_reserved -
  13760                 ((asf_rsvd_g + egr_rsvd_g) << 1);
  13761         }
  13762         else {
  13763             egr_shared_total = total_pool_size - q_reserved;
  13764         }
  13765     } else
  13766 #endif
  13767     {
  13768         egr_shared_total = total_pool_size - q_reserved;
  13769     }
  13770     egr_shared_total += (lossless)? 10:0;
  13771 
  13772     port = in_port;
  13773     buf_port = &buf->ports[port];
  13774 
  13775     /* internal priority to priority group mapping */
  13776     for (idx = 0; idx < 16; idx++) {
  13777         buf_port->pri_to_prigroup[idx] = 7;
  13778     }
  13779 
  13780     /* priority group to pool mapping */
  13781     for (idx = 0; idx < _TD2_MMU_NUM_PG; idx++) {
  13782         buf_port->prigroups[idx].pool_idx = 0;
  13783     }
  13784 
  13785     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  13786         buf_port_pool = &buf_port->pools[idx];
  13787         buf_port_pool->guarantee = 0;
  13788         buf_port_pool->pool_limit = 0;
  13789         buf_port_pool->pool_resume = 0;
  13790         if (idx == 0) {
  13791             buf_port_pool->pool_limit = total_pool_size;
  13792             buf_port_pool->pool_resume =
  13793                 total_pool_size - (default_mtu_cells * 2);
  13794         }
  13795         in_reserved += buf_port_pool->guarantee;
  13796     }
  13797 
  13798     buf_port->pkt_size = max_packet_cells;
  13799 
  13800     /* priority group */
  13801     for (idx = 0; idx < _TD2_MMU_NUM_PG; idx++) {
  13802         buf_prigroup = &buf_port->prigroups[idx];
  13803         buf_prigroup->guarantee = 0;
  13804         buf_prigroup->user_delay = -1;
  13805         buf_prigroup->switch_delay = -1;
  13806         buf_prigroup->pkt_size = max_packet_cells;
  13807         buf_prigroup->device_headroom_enable = 0;
  13808         buf_prigroup->pool_limit = 0;
  13809         buf_prigroup->pool_floor = 0;
  13810         buf_prigroup->pool_scale = -1;
  13811         buf_prigroup->headroom = 0;
  13812         buf_prigroup->pool_resume = 0;
  13813         buf_prigroup->flow_control_enable = 0;
  13814         if (idx == 7) {
  13815             buf_prigroup->device_headroom_enable = 1;
  13816             buf_prigroup->flow_control_enable = lossless;
  13817             if (lossless) {
  13818                 buf_prigroup->guarantee = 8;
  13819                 buf_prigroup->headroom =
  13820                     _soc_td2_default_lossless_pg_headroom(unit, port);
  13821                 buf_prigroup->pool_scale = 8;
  13822                 buf_prigroup->pool_resume = default_mtu_cells * 2;
  13823             } else {
  13824 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13825                 if (SOC_IS_TD2P_TT2P(unit)) {
  13826                     if (IS_CPU_PORT(unit, port)) {
  13827                         buf_prigroup->headroom =
  13828                             _soc_td2_default_lossless_pg_headroom(unit, port);
  13829                     }
  13830                 }
  13831 #endif
  13832             }
  13833         }
  13834         in_reserved += buf_prigroup->guarantee + buf_prigroup->headroom;
  13835     }
  13836 
  13837     /* multicast queue */
  13838     for (idx = 0; idx < si->port_num_cosq[port]; idx++) {
  13839         buf_queue = &buf_port->queues[idx];
  13840         buf_queue->qgroup_id = -1;
  13841         buf_queue->color_discard_enable = 0;
  13842         if (SOC_IS_TD2P_TT2P(unit)) {
  13843             buf_queue->mcq_entry_guarantee = 4;
  13844             if (IS_LB_PORT(unit, port) &&
  13845                     (idx == (si->port_num_cosq[port]-1))) {
  13846                 buf_queue->mcq_entry_guarantee = 0;
  13847             }
  13848         } else {
  13849             buf_queue->mcq_entry_guarantee = 8;
  13850         }
  13851         if (lossless) {
  13852             buf_queue->guarantee = min_cell_per_mcq ?
  13853                 _soc_td2_min_cell_rsvd_per_mcq(unit, port, 0) : 0;
  13854             buf_queue->discard_enable = 0;
  13855             buf_queue->pool_scale = -1;
  13856             buf_queue->pool_limit = egr_shared_total;
  13857             buf_queue->yellow_limit = egr_shared_total;
  13858             buf_queue->red_limit = egr_shared_total;
  13859             buf_queue->pool_resume = 16;
  13860         } else {
  13861 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13862             if (SOC_IS_TD2P_TT2P(unit)) {
  13863                 if (IS_CPU_PORT(unit, port) ||
  13864                         (IS_LB_PORT(unit, port) && (idx != (si->port_num_cosq[port]-1)))) {
  13865                     buf_queue->guarantee = min_cell_per_mcq ?
  13866                         _soc_td2_min_cell_rsvd_per_mcq(unit, port, default_mtu_cells) :
  13867                         default_mtu_cells;
  13868                 } else {
  13869                     buf_queue->guarantee = min_cell_per_mcq ?
  13870                         _soc_td2_min_cell_rsvd_per_mcq(unit, port, 0) : 0;
  13871                 }
  13872             } else
  13873 #endif
  13874             {
  13875                 buf_queue->guarantee = min_cell_per_mcq ?
  13876                     _soc_td2_min_cell_rsvd_per_mcq(unit, port, default_mtu_cells) :
  13877                     default_mtu_cells;
  13878             }
  13879             buf_queue->discard_enable = 1;
  13880             buf_queue->pool_scale = 8;
  13881             buf_queue->pool_limit = 0;
  13882             buf_queue->yellow_limit = 8 | _MMU_CFG_BUF_DYNAMIC_FLAG
  13883                                         | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  13884             buf_queue->red_limit = 8 | _MMU_CFG_BUF_DYNAMIC_FLAG
  13885                                      | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  13886             buf_queue->pool_resume = 16;
  13887         }
  13888     }
  13889 
  13890     /* unicast queue */
  13891     for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
  13892         buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
  13893         buf_queue->qgroup_id = -1;
  13894         buf_queue->color_discard_enable = 0;
  13895         if (lossless) {
  13896             buf_queue->guarantee = 0;
  13897             buf_queue->discard_enable = 0;
  13898             buf_queue->pool_scale = -1;
  13899             buf_queue->pool_limit = egr_shared_total;
  13900             buf_queue->yellow_limit = egr_shared_total;
  13901             buf_queue->red_limit = egr_shared_total;
  13902             buf_queue->pool_resume = default_mtu_cells * 2;
  13903             buf_queue->yellow_resume = default_mtu_cells * 2;
  13904             buf_queue->red_resume = default_mtu_cells * 2;
  13905         } else {
  13906             buf_queue->guarantee = SOC_TD2_MMU_Q_MIN_RSVD;
  13907             buf_queue->discard_enable = 1;
  13908             buf_queue->pool_scale = 8;
  13909             buf_queue->pool_limit = 0;
  13910             buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  13911                                         | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  13912             buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  13913                                      | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  13914             buf_queue->pool_resume = default_mtu_cells * 2;
  13915             buf_queue->yellow_resume = default_mtu_cells * 2;
  13916             buf_queue->red_resume = default_mtu_cells * 2;
  13917 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13918             if (SOC_IS_TD2P_TT2P(unit)) {
  13919                 /* Enable QGROUP in LOSSY MODE */
  13920                 /* All Queues belong to the same egress port are assigned
  13921                  * to one queue group. Queues belong to different egress
  13922                  * ports are assigned to different queue group.
  13923                  */
  13924                 mmu_port = SOC_TD2_MMU_PORT(unit, port);
  13925                 buf_queue->qgroup_id = (mmu_port & 0x3f);
  13926                 buf_queue->qgroup_min_enable = 1;
  13927             }
  13928 #endif
  13929         }
  13930     }
  13931 
  13932     /* queue to pool mapping */
  13933     for (idx = 0;
  13934             idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) {
  13935         buf_port->queues[idx].pool_idx = 0;
  13936     }
  13937 
  13938     buf_port = &buf->ports[port];
  13939     buf_prigroup = &buf_port->prigroups[7];
  13940     if (!lossless) {
  13941         buf_prigroup->pool_limit = total_pool_size - in_reserved;
  13942     }
  13943 
  13944 }
  13945 
  13946 void
  13947 _soc_td2_mmu_config_buf_default(int unit, _soc_mmu_cfg_buf_t *buf,
  13948                                 _soc_mmu_device_info_t *devcfg, int lossless)
  13949 {
  13950     int port;
  13951 
  13952     _soc_td2_mmu_config_buf_default_global(unit,
  13953             buf, devcfg, lossless);
  13954 
  13955     PBMP_ALL_ITER(unit, port) {
  13956         _soc_td2_mmu_config_buf_default_port(unit, port,
  13957                 buf, devcfg, lossless);
  13958     }
  13959 }
  13960 
  13961 
  13962 STATIC int
  13963 _soc_td2_pool_scale_to_limit(int size, int scale)
  13964 {
  13965     int factor = 1000;
  13966 
  13967     switch (scale) {
  13968         case 7: factor = 875; break;
  13969         case 6: factor = 750; break;
  13970         case 5: factor = 625; break;
  13971         case 4: factor = 500; break;
  13972         case 3: factor = 375; break;
  13973         case 2: factor = 250; break;
  13974         case 1: factor = 125; break;
  13975         case 0:
  13976         default:
  13977             factor = 1000; break;
  13978     }
  13979     return (size * factor)/1000;
  13980 }
  13981 
  13982 STATIC int
  13983 _soc_td2_mmu_config_buf_set_hw_global(int unit, _soc_mmu_cfg_buf_t *buf,
  13984                                _soc_mmu_device_info_t *devcfg, int lossless)
  13985 {
  13986     _soc_mmu_cfg_buf_pool_t *buf_pool;
  13987     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
  13988     soc_mem_t mem, mem2;
  13989     uint32 rval, fval, rval2, rval3;
  13990     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
  13991     mmu_thdu_offset_qgroup_entry_t qgrp_offset;
  13992     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
  13993     int port, idx, limit, pval, rqlen;
  13994     int default_mtu_cells, jumbo_frame_cells;
  13995     int pool_resume = 0;
  13996     uint16      dev_id;
  13997     uint8       rev_id;
  13998     uint32* dev_mmu_params_arr = NULL;
  13999     int         ing_rsvd = 0, egr_rsvd = 0, asf_rsvd = 0, mcq_entry_rsvd = 0;
  14000     int         pool_pg_headroom = 0, queue_guarantee = 0;
  14001     int         total_rsvd = 0;
  14002     int cpu_hdrm = 0;
  14003 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14004     int lb_hdrm = 0;
  14005     int prigroup_guarantee = 0;
  14006     int rqe = 0, rqe_rsvd = 0;
  14007     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe;
  14008     soc_info_t *si;
  14009     si = &SOC_INFO(unit);
  14010 #endif
  14011 
  14012     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  14013 
  14014 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14015     if (SOC_IS_TD2P_TT2P(unit)) {
  14016         dev_mmu_params_arr = soc_td2p_mmu_params_arr_get(dev_id, rev_id);
  14017     } else
  14018 #endif
  14019     {
  14020         dev_mmu_params_arr = soc_td2_mmu_params_arr_get(dev_id, rev_id);
  14021     }
  14022 
  14023     if (!dev_mmu_params_arr) {
  14024         return SOC_E_NOT_FOUND;
  14025     }
  14026 
  14027     PBMP_ALL_ITER(unit, port) {
  14028         pool_resume += 4;
  14029     }
  14030 
  14031     jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size +
  14032                                                    devcfg->mmu_hdr_byte,
  14033                                                    devcfg->mmu_cell_size);
  14034     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  14035                                                    devcfg->mmu_hdr_byte,
  14036                                                    devcfg->mmu_cell_size);
  14037 
  14038     rval = 0;
  14039     fval = dev_mmu_params_arr[_MMU_PHYSICAL_CELLS] - dev_mmu_params_arr[_MMU_RSVD_CELLS_CFAP];
  14040     soc_reg_field_set(unit, CFAPFULLTHRESHOLDSETr, &rval, CFAPFULLSETPOINTf,
  14041                       fval);
  14042     SOC_IF_ERROR_RETURN(WRITE_CFAPFULLTHRESHOLDSETr(unit, rval));
  14043     rval = 0;
  14044     soc_reg_field_set(unit, CFAPFULLTHRESHOLDRESETr, &rval,
  14045                       CFAPFULLRESETPOINTf, fval - 2 * jumbo_frame_cells);
  14046     SOC_IF_ERROR_RETURN(WRITE_CFAPFULLTHRESHOLDRESETr(unit, rval));
  14047     rval = 0;
  14048     soc_reg_field_set(unit, CFAPBANKFULLr, &rval, LIMITf, 2046);
  14049     for (idx = 0; idx < 16; idx++) {
  14050         SOC_IF_ERROR_RETURN(WRITE_CFAPBANKFULLr(unit, idx, rval));
  14051     }
  14052 
  14053     if (SOC_IS_TRIDENT2(unit)) {
  14054         if (rev_id == BCM56850_A0_REV_ID || rev_id == BCM56850_A1_REV_ID) {
  14055             rval = 0;
  14056             soc_reg_field_set(unit, CFAP_ARBITER_MASKr, &rval, MASKf, 0xA);
  14057             SOC_IF_ERROR_RETURN(WRITE_CFAP_ARBITER_MASKr(unit, rval));
  14058         }
  14059     }
  14060 
  14061     for (idx = 0; idx < NUM_PIPE(unit); idx++) {
  14062             asf_rsvd += buf->rsvd_buffers[idx].asf_rsvd_cells;
  14063             egr_rsvd += buf->rsvd_buffers[idx].egr_rsvd_cells;
  14064             ing_rsvd += buf->rsvd_buffers[idx].ing_rsvd_cells;
  14065             mcq_entry_rsvd += buf->rsvd_buffers[idx].mcq_entry_rsvd;
  14066     }
  14067 
  14068     LOG_VERBOSE(BSL_LS_SOC_MMU,
  14069                 (BSL_META_U(unit,
  14070                             "MMU config set HW: Cells rsvd Total : %d ing %d egr %d asf %d mcq_entry %d\n"),
  14071                             (ing_rsvd + egr_rsvd + asf_rsvd), ing_rsvd, egr_rsvd, asf_rsvd, mcq_entry_rsvd));
  14072 
  14073     /* Input thresholds */
  14074     rval = 0;
  14075     soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr,
  14076                       &rval, GLOBAL_HDRM_LIMITf, buf->headroom/2);
  14077     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr,
  14078                                         REG_PORT_ANY, 0, rval));
  14079 
  14080     soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEYr,
  14081                       &rval, GLOBAL_HDRM_LIMITf, buf->headroom/2);
  14082     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEYr,
  14083                                         REG_PORT_ANY, 0, rval));
  14084 
  14085     fval = 0;
  14086     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  14087         if ((buf->pools[idx].size & ~_MMU_CFG_BUF_PERCENT_FLAG) != 0) {
  14088             fval |= 1 << idx;
  14089         }
  14090     }
  14091 
  14092     rval = 0;
  14093     fval = 0;
  14094     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  14095         buf_pool = &buf->pools[idx];
  14096         if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  14097             continue;
  14098         }
  14099 
  14100         if (buf_pool->yellow_size & _MMU_CFG_BUF_PERCENT_FLAG) {
  14101             if ((buf_pool->yellow_size & ~_MMU_CFG_BUF_PERCENT_FLAG) < 10000) {
  14102                 fval |= 1 << idx;
  14103             }
  14104         } else {
  14105             if (buf->pools[idx].size != buf->pools[idx].yellow_size) {
  14106                 fval |= 1 << idx;
  14107             }
  14108         }
  14109     }
  14110     soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, COLOR_AWAREf, fval);
  14111     soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, PUBLIC_ENABLEf, 1);
  14112     SOC_IF_ERROR_RETURN(WRITE_THDI_POOL_CONFIGr(unit, rval));
  14113 
  14114     rval = 0;
  14115     soc_reg_field_set(unit, THDI_BYPASSr, &rval, INPUT_THRESHOLD_BYPASSf, 0);
  14116     SOC_IF_ERROR_RETURN(WRITE_THDI_BYPASSr(unit, rval));
  14117 
  14118     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  14119         buf_pool = &buf->pools[idx];
  14120         if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  14121             continue;
  14122         }
  14123 
  14124         if (SOC_IS_TD2P_TT2P(unit)) {
  14125             cpu_hdrm = _TD2P_MMU_CPU_HEADROOM;
  14126         }
  14127 
  14128         if (!lossless) {
  14129             buf_pool->prigroup_headroom += cpu_hdrm;
  14130         }
  14131 
  14132 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14133         if (SOC_IS_TD2P_TT2P(unit)) {
  14134             if ((FALSE == si->flex_eligible) && soc_td2p_is_any_port_flex_enable(unit)) {
  14135                 /* Legacy flex port (:i) is not enabled */
  14136                 /* additional per port macro buffers reserved */
  14137                 /* Add cpu & lb port pg headroom */
  14138                 if (lossless) {
  14139                     lb_hdrm = _soc_td2_default_lossless_pg_headroom(
  14140                             unit,
  14141                             LB_PORT(unit));
  14142                     /* Add PG min for CPU & Loopback port */
  14143                     prigroup_guarantee = _TD2P_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS * 2;
  14144                 }
  14145                 pool_pg_headroom = ing_rsvd + cpu_hdrm + lb_hdrm + prigroup_guarantee;
  14146             } else {
  14147                 /* cpu & lb port pg headroom is already
  14148                  * included in buf_pool->prigroup_headroom */
  14149                 pool_pg_headroom = buf_pool->prigroup_headroom +
  14150                     buf_pool->prigroup_guarantee;
  14151             }
  14152         } else
  14153 #endif
  14154         {
  14155             pool_pg_headroom = buf_pool->prigroup_headroom +
  14156                 buf_pool->prigroup_guarantee;
  14157         }
  14158 
  14159         if (lossless) {
  14160             total_rsvd = (pool_pg_headroom +
  14161                     buf_pool->queue_guarantee +
  14162                     buf->headroom + asf_rsvd);
  14163         } else {
  14164             total_rsvd = (pool_pg_headroom +
  14165                     buf->headroom + asf_rsvd);
  14166         }
  14167 
  14168         limit = buf_pool->total - total_rsvd;
  14169 
  14170         LOG_VERBOSE(BSL_LS_SOC_MMU,
  14171                 (BSL_META_U(unit,
  14172                             "_soc_td2_mmu_config_buf_set_hw THDI_BUFFER_CELL_LIMIT_SP %d\n"), limit));
  14173 
  14174         rval = 0;
  14175         soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit);
  14176         SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, rval));
  14177 
  14178         rval = 0;
  14179         soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval,
  14180                             OFFSETf, pool_resume);
  14181         SOC_IF_ERROR_RETURN(WRITE_THDI_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval));
  14182     }
  14183 
  14184     rval = 0;
  14185     SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr(unit, rval));
  14186 
  14187     /* output thresholds */
  14188     SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval));
  14189     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_QUEUE_AND_GROUP_TICKETf, 1);
  14190     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_UPDATE_COLOR_RESUMEf, 1);
  14191     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
  14192     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0);
  14193     SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval));
  14194 
  14195     SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
  14196     soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, MOP_POLICYf, 1);
  14197     SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
  14198 
  14199     /* per service pool settings */
  14200     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  14201         buf_pool = &buf->pools[idx];
  14202         if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  14203             continue;
  14204         }
  14205 
  14206         queue_guarantee = buf_pool->queue_guarantee;
  14207         total_rsvd = queue_guarantee;
  14208 
  14209 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14210         if (SOC_IS_TD2P_TT2P(unit)) {
  14211             if ((FALSE == si->flex_eligible) && soc_td2p_is_any_port_flex_enable(unit)) {
  14212                 /* Legacy flex port (:i) is not enabled
  14213                 * Overwrite total_rsvd with flexport reservations made
  14214                 * Add cpu & lb port egr rsvd entries */
  14215                 if (devcfg->flags & SOC_MMU_CFG_F_RQE) {
  14216                     for (rqe = 0; rqe < 11; rqe++) {
  14217                         buf_rqe = &buf->rqe_queues[rqe];
  14218                         rqe_rsvd += buf_rqe->guarantee;
  14219                     }
  14220                 }
  14221                 if (lossless) {
  14222                     total_rsvd = egr_rsvd + asf_rsvd + rqe_rsvd;
  14223                 } else {
  14224                     total_rsvd = egr_rsvd + asf_rsvd +
  14225                         soc_td2p_egr_buf_rsvd_port(unit, CMIC_PORT(unit), default_mtu_cells) +
  14226                         soc_td2p_egr_buf_rsvd_port(unit, LB_PORT(unit), default_mtu_cells) +
  14227                         rqe_rsvd;
  14228                 }
  14229             }
  14230         }
  14231 #endif
  14232         limit = buf_pool->total - total_rsvd + (lossless ? 10 : 0);
  14233 
  14234         if (limit <= 0) {
  14235             limit = 0;
  14236         }
  14237 
  14238         LOG_VERBOSE(BSL_LS_SOC_MMU,
  14239                 (BSL_META_U(unit,
  14240                             "_soc_td2_mmu_config_buf_set_hw MMU_THDM_DB_POOL_SHARED_LIMIT %d\n"), limit));
  14241 
  14242         rval = 0;
  14243         soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval,
  14244                                                 SHARED_LIMITf, limit);
  14245         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, idx, rval));
  14246 
  14247         rval = 0;
  14248         soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr,
  14249                                     &rval, YELLOW_SHARED_LIMITf, limit/8);
  14250         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, idx, rval));
  14251 
  14252         rval = 0;
  14253         soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr,
  14254                             &rval, RED_SHARED_LIMITf, limit/8);
  14255         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, idx, rval));
  14256 
  14257         rval = 0;
  14258         soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr,
  14259                             &rval, RESUME_LIMITf, limit/8);
  14260         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, idx, rval));
  14261 
  14262         rval = 0;
  14263         soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr,
  14264                             &rval, YELLOW_RESUME_LIMITf, limit/8);
  14265         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, idx, rval));
  14266 
  14267         rval = 0;
  14268         soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr,
  14269                             &rval, RED_RESUME_LIMITf, limit/8);
  14270         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, idx, rval));
  14271 
  14272         /* mcq entries */
  14273 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14274         if (SOC_IS_TD2P_TT2P(unit)) {
  14275             if ((FALSE == si->flex_eligible) && soc_td2p_is_any_port_flex_enable(unit)) {
  14276                 /* Legacy flex port (:i) is not enabled */
  14277                 /* additional per port macro mcq entries reserved */
  14278                 /* Add cpu & lb port mcs entries */
  14279                 total_rsvd = mcq_entry_rsvd +
  14280                     soc_td2p_mcq_entries_rsvd_port(unit, CMIC_PORT(unit)) +
  14281                     soc_td2p_mcq_entries_rsvd_port(unit, LB_PORT(unit));
  14282             } else {
  14283                 /* cpu & lb port mcq reserved entries already included
  14284                  *  in buf_pool->mcq_entry_reserved
  14285                  */
  14286                 total_rsvd = buf_pool->mcq_entry_reserved;
  14287             }
  14288         } else
  14289 #endif
  14290         {
  14291             total_rsvd = buf_pool->mcq_entry_reserved;
  14292         }
  14293 
  14294         limit = buf_pool->total_mcq_entry - total_rsvd;
  14295         LOG_VERBOSE(BSL_LS_SOC_MMU,
  14296                 (BSL_META_U(unit,
  14297                             "_soc_td2_mmu_config_buf_set_hw MMU_THDM_MCQE_POOL_SHARED_LIMIT %d\n"), limit));
  14298 
  14299         rval = 0;
  14300         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr,
  14301                           &rval, SHARED_LIMITf, (limit + 3)/4);
  14302         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit,
  14303                                                                    idx, rval));
  14304 
  14305         rval = 0;
  14306         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr,
  14307                           &rval, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  14308         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit,
  14309                                                                    idx, rval));
  14310 
  14311         rval = 0;
  14312         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr,
  14313                           &rval, RED_SHARED_LIMITf, (limit + 7)/8);
  14314         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit,
  14315                                                                    idx, rval));
  14316 
  14317         rval = 0;
  14318         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr,
  14319                           &rval, RESUME_LIMITf, (limit + 7)/8);
  14320         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit,
  14321                                                                    idx, rval));
  14322 
  14323         rval = 0;
  14324         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr,
  14325                           &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8);
  14326         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit,
  14327                                                                    idx, rval));
  14328 
  14329         rval = 0;
  14330         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr,
  14331                           &rval, RED_RESUME_LIMITf, (limit + 7)/8);
  14332         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit,
  14333                                                                    idx, rval));
  14334     }
  14335 
  14336     rval = 0;
  14337     soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval,
  14338                                     CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1);
  14339     soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
  14340     soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Af, 0);
  14341     SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval));
  14342 
  14343     rval = 0;
  14344     soc_reg_field_set(unit, MMU_THDR_QE_CONFIGr, &rval,
  14345                                     CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1);
  14346     SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIGr(unit, rval));
  14347 
  14348     /* configure Q-groups */
  14349     for (idx = 0; idx < SOC_TD2_MMU_CFG_QGROUP_MAX; idx++) {
  14350         queue_grp = &buf->qgroups[idx];
  14351 
  14352         mem = MMU_THDU_XPIPE_CONFIG_QGROUPm;
  14353         mem2 = MMU_THDU_YPIPE_CONFIG_QGROUPm;
  14354         sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
  14355 
  14356         soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14357                             Q_MIN_LIMIT_CELLf, queue_grp->guarantee);
  14358 
  14359         if (queue_grp->pool_scale != -1) {
  14360             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14361                                Q_SHARED_ALPHA_CELLf, queue_grp->pool_scale);
  14362             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14363                                     Q_LIMIT_DYNAMIC_CELLf, 1);
  14364         } else {
  14365             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14366                                 Q_SHARED_LIMIT_CELLf, queue_grp->pool_limit);
  14367         }
  14368 
  14369         if ((queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  14370             (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  14371             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14372                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  14373         }
  14374 
  14375         if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
  14376             pval = _soc_td2_pool_scale_to_limit(queue_grp->pool_limit,
  14377                           queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
  14378             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14379                                     LIMIT_RED_CELLf, pval/8);
  14380 
  14381         } else {
  14382             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14383                                     LIMIT_RED_CELLf, queue_grp->red_limit);
  14384         }
  14385 
  14386         if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
  14387             pval = _soc_td2_pool_scale_to_limit(queue_grp->pool_limit,
  14388                           queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
  14389             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14390                                     LIMIT_YELLOW_CELLf, pval/8);
  14391 
  14392         } else {
  14393             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  14394                                     LIMIT_YELLOW_CELLf, queue_grp->yellow_limit);
  14395         }
  14396 
  14397         SOC_IF_ERROR_RETURN
  14398                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  14399         SOC_IF_ERROR_RETURN
  14400                 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  14401 
  14402         mem = MMU_THDU_XPIPE_OFFSET_QGROUPm;
  14403         mem2 = MMU_THDU_YPIPE_OFFSET_QGROUPm;
  14404         sal_memset(&qgrp_offset, 0, sizeof(qgrp_offset));
  14405         soc_mem_field32_set(unit, mem, &qgrp_offset,
  14406                             RESET_OFFSET_CELLf, 2);
  14407         soc_mem_field32_set(unit, mem, &qgrp_offset,
  14408                             RESET_OFFSET_YELLOW_CELLf, 2);
  14409         soc_mem_field32_set(unit, mem, &qgrp_offset,
  14410                             RESET_OFFSET_RED_CELLf, 2);
  14411         SOC_IF_ERROR_RETURN
  14412             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &qgrp_offset));
  14413         SOC_IF_ERROR_RETURN
  14414             (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, idx, &qgrp_offset));
  14415     }
  14416 
  14417     /* RQE */
  14418     for (idx = 0; idx < 11; idx++) {
  14419         buf_rqe_queue = &buf->rqe_queues[idx];
  14420 
  14421         rval = 0;
  14422         soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr,
  14423                             &rval, MIN_LIMITf, buf_rqe_queue->guarantee);
  14424         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval));
  14425 
  14426         rval = 0;
  14427         rval2 = 0;
  14428         rval3 = 0;
  14429         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
  14430                             &rval, SPIDf, buf_rqe_queue->pool_idx);
  14431 
  14432         if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  14433             (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  14434             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
  14435                                         &rval, COLOR_LIMIT_DYNAMICf, 1);
  14436             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  14437                 SHARED_RED_LIMITf, buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
  14438             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  14439                 SHARED_YELLOW_LIMITf, buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
  14440         } else {
  14441             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  14442                 SHARED_RED_LIMITf, buf_rqe_queue->red_limit / 8);
  14443 
  14444             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  14445                 SHARED_YELLOW_LIMITf, buf_rqe_queue->yellow_limit / 8);
  14446         }
  14447 
  14448         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf,
  14449                             (buf_rqe_queue->discard_enable ? 1 : 0));
  14450 
  14451         if (buf_rqe_queue->pool_scale != -1) {
  14452             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
  14453                                             &rval, DYNAMIC_ENABLEf, 1);
  14454             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2,
  14455                            SHARED_ALPHAf, buf_rqe_queue->pool_scale);
  14456         } else {
  14457             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2,
  14458                            SHARED_LIMITf, buf_rqe_queue->pool_limit);
  14459         }
  14460         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 2);
  14461 
  14462         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval));
  14463         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr_REG32(unit, idx, rval2));
  14464         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, idx, rval3));
  14465 
  14466         rval = 0;
  14467         soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr,
  14468                           &rval, RESET_OFFSET_REDf, (default_mtu_cells * 2)/8);
  14469         soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr,
  14470                        &rval, RESET_OFFSET_YELLOWf, (default_mtu_cells * 2)/8);
  14471         SOC_IF_ERROR_RETURN(
  14472                   WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
  14473 
  14474         /* queue entry */
  14475         buf_pool = &buf->pools[buf_rqe_queue->pool_idx];
  14476         if (idx == 0) {
  14477             LOG_VERBOSE(BSL_LS_SOC_MMU,
  14478                     (BSL_META_U(unit,
  14479                                 "_soc_td2_mmu_config_buf_set_hw Total shared RQE entries limit %d\n"), buf_pool->total_rqe_entry));
  14480         }
  14481         rval = 0;
  14482         soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr,
  14483                             &rval, MIN_LIMITf, buf_rqe_queue->guarantee/8);
  14484         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval));
  14485 
  14486         rval = 0;
  14487         rval2 = 0;
  14488         rval3 = 0;
  14489         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  14490                             &rval, SPIDf, buf_rqe_queue->pool_idx);
  14491 
  14492         if (SOC_IS_TD2P_TT2P(unit) && !lossless) {
  14493             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  14494                     &rval, DYNAMIC_ENABLEf, 1);
  14495             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  14496                     &rval, COLOR_LIMIT_DYNAMICf, 1);
  14497             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 1);
  14498         } else {
  14499             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  14500                     &rval, DYNAMIC_ENABLEf, 0);
  14501             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  14502                     &rval, COLOR_LIMIT_DYNAMICf, 0);
  14503             if (!lossless) {
  14504                 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 1);
  14505             } else {
  14506                 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 0);
  14507             }
  14508         }
  14509 
  14510         fval = (buf_pool->total_rqe_entry + 8 * 11 - 1) / (8 * 11);
  14511         if (SOC_IS_TD2P_TT2P(unit) && !lossless) {
  14512             fval = 0;
  14513         }
  14514         soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr,
  14515                           &rval3, SHARED_RED_LIMITf, fval);
  14516         soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr,
  14517                           &rval3, SHARED_YELLOW_LIMITf, fval);
  14518         if (SOC_IS_TD2P_TT2P(unit) && !lossless) {
  14519             fval = 8;
  14520         }
  14521         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2,
  14522                 SHARED_LIMITf, fval);
  14523         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 1);
  14524 
  14525         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval));
  14526         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2));
  14527         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3));
  14528 
  14529         rval = 0;
  14530         if (SOC_IS_TD2P_TT2P(unit) && !lossless) {
  14531             fval = 1;
  14532         } else {
  14533             fval = default_mtu_cells/8;
  14534         }
  14535         soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr,
  14536                           &rval, RESET_OFFSET_REDf, fval);
  14537         soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr,
  14538                        &rval, RESET_OFFSET_YELLOWf, fval);
  14539         SOC_IF_ERROR_RETURN(
  14540                   WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
  14541 
  14542     }
  14543 
  14544     /* per pool RQE settings */
  14545     for (idx = 0; idx < 4; idx++) {
  14546         buf_pool = &buf->pools[idx];
  14547         if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) ||
  14548             (buf_pool->total == 0)) {
  14549             continue;
  14550         }
  14551 
  14552         limit = buf_pool->total - buf_pool->queue_guarantee;
  14553 
  14554         rval = 0;
  14555         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr,
  14556                                 &rval, SHARED_LIMITf, limit);
  14557         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval, RESUME_LIMITf,
  14558                                     (limit - (default_mtu_cells * 2))/8);
  14559         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr_REG32(unit, idx, rval));
  14560 
  14561         rval = 0;
  14562         soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval,
  14563                      SHARED_RED_LIMITf, limit/8);
  14564         soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval,
  14565                   SHARED_YELLOW_LIMITf, limit/8);
  14566         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval));
  14567 
  14568         rval = 0;
  14569         soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval,
  14570                      RESUME_RED_LIMITf, (limit - (default_mtu_cells * 2))/8);
  14571         soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval,
  14572                   RESUME_YELLOW_LIMITf, (limit - (default_mtu_cells * 2))/8);
  14573         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit,
  14574                                                                      idx, rval));
  14575 
  14576         rqlen = buf_pool->total_rqe_entry/8 - 1;
  14577         if (rqlen <= 0) {
  14578             continue;
  14579         }
  14580 
  14581         rval = 0;
  14582         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, SHARED_LIMITf, rqlen);
  14583         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, RESUME_LIMITf, rqlen - 1);
  14584         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval));
  14585 
  14586         rval = 0;
  14587         soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval,
  14588                                                     SHARED_RED_LIMITf, rqlen);
  14589         soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval,
  14590                                                     SHARED_YELLOW_LIMITf, rqlen);
  14591         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, idx, rval));
  14592 
  14593         rval = 0;
  14594         soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval,
  14595                                                 RESUME_RED_LIMITf, rqlen - 1);
  14596         soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval,
  14597                                                 RESUME_YELLOW_LIMITf, rqlen - 1);
  14598         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit,
  14599                                                                      idx, rval));
  14600     }
  14601 
  14602     /* Device level config setting */
  14603     if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) {
  14604         SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
  14605         soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval,
  14606                           UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1);
  14607         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
  14608     }
  14609 
  14610     return SOC_E_NONE;
  14611 }
  14612 
  14613 int
  14614 _soc_td2_mmu_config_buf_set_hw_port(int unit, int port, _soc_mmu_cfg_buf_t *buf,
  14615                                _soc_mmu_device_info_t *devcfg, int lossless)
  14616 {
  14617     soc_info_t *si;
  14618     _soc_mmu_cfg_buf_pool_t *buf_pool;
  14619     _soc_mmu_cfg_buf_port_t *buf_port;
  14620     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
  14621     _soc_mmu_cfg_buf_queue_t *buf_queue;
  14622     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
  14623     soc_reg_t reg = INVALIDr;
  14624     soc_mem_t mem, mem1, mem2, mem3;
  14625     uint32 rval, fval;
  14626     uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS];
  14627     thdi_port_pg_config_entry_t pg_config_mem;
  14628     thdi_port_sp_config_entry_t thdi_sp_config;
  14629     int default_mtu_cells, limit, midx, pri, rlimit, min_resume_limit;
  14630     int base, numq, idx;
  14631     int qbase;
  14632 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14633     uint32 e2ecc_ds_config;
  14634 #endif
  14635     static const soc_field_t prigroup_reg[] = {
  14636         THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r
  14637     };
  14638     static const soc_field_t prigroup_field[] = {
  14639         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
  14640         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf,
  14641         PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
  14642         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
  14643     };
  14644     static const soc_field_t prigroup_spid_field[] = {
  14645         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
  14646         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
  14647     };
  14648     int index1;
  14649 
  14650     min_resume_limit = soc_feature(unit, soc_feature_min_resume_limit_1) ? 8 : 0;
  14651 
  14652     si = &SOC_INFO(unit);
  14653 
  14654     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  14655                                                    devcfg->mmu_hdr_byte,
  14656                                                    devcfg->mmu_cell_size);
  14657 
  14658     /* internal priority to priority group mapping */
  14659     buf_port = &buf->ports[port];
  14660 
  14661     for (idx = 0; idx < 16; idx++) {
  14662         if (idx % 8 == 0) { /* 8 fields per register */
  14663             reg = prigroup_reg[idx / 8];
  14664             rval = 0;
  14665         }
  14666         soc_reg_field_set(unit, reg, &rval, prigroup_field[idx],
  14667                 buf_port->pri_to_prigroup[idx]);
  14668         if (idx % 8 == 7) { /* 8 fields per register */
  14669             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  14670         }
  14671     }
  14672 
  14673     /* Input port per port settings */
  14674     buf_port = &buf->ports[port];
  14675 
  14676     rval = 0;
  14677     for (idx = 0; idx < _TD2_MMU_NUM_PG; idx++) {
  14678         soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval,
  14679                 prigroup_spid_field[idx],
  14680                 buf_port->prigroups[idx].pool_idx);
  14681     }
  14682     SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval));
  14683 
  14684     mem = SOC_TD2_PMEM(unit, port, THDI_PORT_SP_CONFIG_Xm,
  14685             THDI_PORT_SP_CONFIG_Ym);
  14686     /* Per port per pool settings */
  14687     for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  14688         buf_port_pool = &buf_port->pools[idx];
  14689         midx = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  14690         sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config));
  14691         soc_mem_field32_set(unit, mem, &thdi_sp_config,
  14692                 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee);
  14693         soc_mem_field32_set(unit, mem, &thdi_sp_config,
  14694                 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume);
  14695         soc_mem_field32_set(unit, mem, &thdi_sp_config,
  14696                 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit);
  14697         SOC_IF_ERROR_RETURN
  14698             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, &thdi_sp_config));
  14699     }
  14700 
  14701     fval = 0;
  14702     for (idx = 0; idx < _TD2_MMU_NUM_PG; idx++) {
  14703         if (buf_port->prigroups[idx].flow_control_enable != 0) {
  14704             for (pri=0; pri < 16; pri++) {
  14705                 if (buf_port->pri_to_prigroup[pri] == idx) {
  14706                     fval |= 1 << pri;
  14707                 }
  14708             }
  14709         }
  14710     }
  14711 
  14712     rval = 0;
  14713     soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  14714             INPUT_PORT_RX_ENABLEf, 1);
  14715     soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  14716             PORT_PRI_XON_ENABLEf, fval);
  14717     soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  14718             PORT_PAUSE_ENABLEf, fval ? 1 : 0);
  14719     SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, port, rval));
  14720 
  14721     rval = 0;
  14722     soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval,
  14723             PORT_MAX_PKT_SIZEf, buf_port->pkt_size);
  14724     SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval));
  14725 
  14726     /* Input port per port per priority group settings */
  14727     mem = SOC_TD2_PMEM(unit, port, THDI_PORT_PG_CONFIG_Xm,
  14728             THDI_PORT_PG_CONFIG_Ym);
  14729     for (idx = 0; idx < _TD2_MMU_NUM_PG; idx++) {
  14730         buf_prigroup = &buf->ports[port].prigroups[idx];
  14731 
  14732         midx = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  14733         sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
  14734         soc_mem_field32_set(unit, mem, &pg_config_mem,
  14735                 PG_MIN_LIMITf, buf_prigroup->guarantee);
  14736 
  14737         if (buf_prigroup->pool_scale != -1) {
  14738             soc_mem_field32_set(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf, 1);
  14739             soc_mem_field32_set(unit, mem, &pg_config_mem,
  14740                     PG_SHARED_LIMITf, buf_prigroup->pool_scale);
  14741         } else {
  14742             soc_mem_field32_set(unit, mem, &pg_config_mem,
  14743                     PG_SHARED_LIMITf, buf_prigroup->pool_limit);
  14744         }
  14745 
  14746         soc_mem_field32_set(unit, mem, &pg_config_mem,
  14747                 PG_GBL_HDRM_ENf, buf_prigroup->device_headroom_enable);
  14748         soc_mem_field32_set(unit, mem, &pg_config_mem,
  14749                 PG_HDRM_LIMITf, buf_prigroup->headroom);
  14750 
  14751         soc_mem_field32_set(unit, mem, &pg_config_mem,
  14752                 PG_RESET_OFFSETf, buf_prigroup->pool_resume);
  14753 
  14754         soc_mem_field32_set(unit, mem, &pg_config_mem,
  14755                 PG_RESET_FLOORf, buf_prigroup->pool_floor);
  14756 
  14757         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem,
  14758                     MEM_BLOCK_ALL, midx, &pg_config_mem));
  14759     }
  14760 
  14761     /***********************************
  14762      * THDO
  14763  */
  14764     /* Output port per port per queue setting for regular multicast queue */
  14765     numq = si->port_num_cosq[port];
  14766     qbase = si->port_cosq_base[port];
  14767     if (numq != 0) {
  14768 
  14769         mem = SOC_TD2_PMEM(unit, port, MMU_THDM_DB_QUEUE_CONFIG_0m,
  14770                 MMU_THDM_DB_QUEUE_CONFIG_1m);
  14771         base = soc_td2_l2_hw_index(unit, qbase, 0) - 1480;
  14772 
  14773         mem1 = SOC_TD2_PMEM(unit, port, MMU_THDM_DB_QUEUE_OFFSET_0m,
  14774                 MMU_THDM_DB_QUEUE_OFFSET_1m);
  14775         for (idx = 0; idx < numq; idx++) {
  14776             buf_queue = &buf->ports[port].queues[idx];
  14777 
  14778             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
  14779 
  14780             soc_mem_field32_set(unit, mem, entry0,
  14781                     Q_MIN_LIMITf, buf_queue->guarantee);
  14782             if (buf_queue->discard_enable) {
  14783                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1);
  14784             }
  14785             if (buf_queue->color_discard_enable) {
  14786                 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1);
  14787             }
  14788             if (buf_queue->pool_scale != -1) {
  14789                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1);
  14790                 soc_mem_field32_set(unit, mem, entry0,
  14791                         Q_SHARED_ALPHAf, buf_queue->pool_scale);
  14792             } else {
  14793                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  14794                 soc_mem_field32_set(unit, mem, entry0,
  14795                         Q_SHARED_LIMITf, buf_queue->pool_limit);
  14796             }
  14797             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  14798                     (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  14799                 soc_mem_field32_set(unit, mem, entry0,
  14800                         Q_COLOR_LIMIT_DYNAMICf, 1);
  14801                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  14802                         buf_queue->yellow_limit
  14803                                  & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  14804                                  & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  14805                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  14806                         buf_queue->red_limit
  14807                                  & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  14808                                  & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  14809             } else {
  14810                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  14811                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  14812                         buf_queue->yellow_limit / 8);
  14813                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  14814                         buf_queue->red_limit / 8);
  14815             }
  14816 
  14817             soc_mem_field32_set(unit, mem, entry0,
  14818                     Q_SPIDf, buf_queue->pool_idx);
  14819 
  14820             SOC_IF_ERROR_RETURN
  14821                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  14822                                entry0));
  14823 
  14824             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t));
  14825 
  14826             soc_mem_field32_set(unit, mem1, entry0,
  14827                     RESUME_OFFSETf, (default_mtu_cells * 2)/8);
  14828             soc_mem_field32_set(unit, mem1, entry0,
  14829                     YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
  14830             soc_mem_field32_set(unit, mem1, entry0,
  14831                     RED_RESUME_OFFSET_PROFILE_SELf, 0);
  14832             SOC_IF_ERROR_RETURN
  14833                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx,
  14834                                entry0));
  14835 
  14836             rval = 0;
  14837             SOC_IF_ERROR_RETURN(
  14838                     WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 2));
  14839 
  14840             rval = 0;
  14841             SOC_IF_ERROR_RETURN(
  14842                     WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 2));
  14843         }
  14844 
  14845         mem = SOC_TD2_PMEM(unit, port, MMU_THDM_MCQE_QUEUE_CONFIG_0m,
  14846                 MMU_THDM_MCQE_QUEUE_CONFIG_1m);
  14847         mem1 = SOC_TD2_PMEM(unit, port, MMU_THDM_MCQE_QUEUE_OFFSET_0m,
  14848                 MMU_THDM_MCQE_QUEUE_OFFSET_1m);
  14849         for (idx = 0; idx < numq; idx++) {
  14850             buf_queue = &buf->ports[port].queues[idx];
  14851             buf_pool = &buf->pools[buf_queue->pool_idx];
  14852             if (buf_pool->total == 0) {
  14853                 continue;
  14854             }
  14855             limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved;
  14856             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_0_entry_t));
  14857 
  14858             soc_mem_field32_set(unit, mem, entry0,
  14859                     Q_MIN_LIMITf, buf_queue->mcq_entry_guarantee/4);
  14860             if (buf_queue->discard_enable) {
  14861                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1);
  14862             }
  14863             if (buf_queue->color_discard_enable) {
  14864                 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1);
  14865             }
  14866             if (buf_queue->pool_scale != -1) {
  14867                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1);
  14868                 soc_mem_field32_set(unit, mem, entry0,
  14869                         Q_SHARED_ALPHAf, buf_queue->pool_scale);
  14870             } else {
  14871                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  14872                 soc_mem_field32_set(unit, mem, entry0,
  14873                         Q_SHARED_LIMITf, (limit + 3)/4);
  14874             }
  14875             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  14876                     (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  14877                 soc_mem_field32_set(unit, mem, entry0,
  14878                         Q_COLOR_LIMIT_DYNAMICf, 1);
  14879                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 0);
  14880                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 0);
  14881             } else {
  14882                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  14883                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  14884                         (limit + 7)/8);
  14885                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  14886                         (limit + 7)/8);
  14887             }
  14888 
  14889             soc_mem_field32_set(unit, mem, entry0,
  14890                     Q_SPIDf, buf_queue->pool_idx);
  14891 
  14892             SOC_IF_ERROR_RETURN
  14893                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  14894                                entry0));
  14895 
  14896             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_0_entry_t));
  14897 
  14898             soc_mem_field32_set(unit, mem1, entry0,
  14899                     RESUME_OFFSETf, 1);
  14900             soc_mem_field32_set(unit, mem1, entry0,
  14901                     YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
  14902             soc_mem_field32_set(unit, mem1, entry0,
  14903                     RED_RESUME_OFFSET_PROFILE_SELf, 0);
  14904             SOC_IF_ERROR_RETURN
  14905                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx,
  14906                                entry0));
  14907 
  14908             rval = 0;
  14909             SOC_IF_ERROR_RETURN(
  14910                     WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 1));
  14911 
  14912             rval = 0;
  14913             SOC_IF_ERROR_RETURN(
  14914                     WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 1));
  14915         }
  14916 
  14917         /* Per  port per pool */
  14918         for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  14919             buf_pool = &buf->pools[idx];
  14920             if (buf_pool->total == 0) {
  14921                 continue;
  14922             }
  14923 
  14924             limit = buf_pool->total - buf_pool->queue_guarantee;
  14925             rlimit = (limit < min_resume_limit) ? \
  14926                         min_resume_limit : (limit - 2 * default_mtu_cells);
  14927             mem2 = SOC_TD2_PMEM(unit, port, MMU_THDM_DB_PORTSP_CONFIG_0m,
  14928                     MMU_THDM_DB_PORTSP_CONFIG_1m);
  14929             index1 = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx);
  14930             sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t));
  14931 
  14932             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit);
  14933             soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, limit/8);
  14934             soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, limit/8);
  14935 
  14936             soc_mem_field32_set(unit, mem2, entry0,
  14937                     SHARED_LIMIT_ENABLEf, !lossless);
  14938 
  14939             soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, rlimit/8);
  14940             soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, rlimit/8);
  14941             soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, rlimit/8);
  14942 
  14943             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  14944                         index1, entry0));
  14945 
  14946             mem2 = SOC_TD2_PMEM(unit, port, MMU_THDM_MCQE_PORTSP_CONFIG_0m,
  14947                     MMU_THDM_MCQE_PORTSP_CONFIG_1m);
  14948             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_0_entry_t));
  14949 
  14950             limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved;
  14951 
  14952             soc_mem_field32_set(unit, mem2, entry0,
  14953                     SHARED_LIMITf, (limit + 3)/4);
  14954             soc_mem_field32_set(unit, mem2, entry0,
  14955                     SHARED_RESUME_LIMITf, limit/8 - 1);
  14956             soc_mem_field32_set(unit, mem2, entry0,
  14957                     SHARED_LIMIT_ENABLEf, !lossless);
  14958             soc_mem_field32_set(unit, mem2, entry0,
  14959                     RED_SHARED_LIMITf, (limit + 7)/8);
  14960             soc_mem_field32_set(unit, mem2, entry0,
  14961                     RED_RESUME_LIMITf, (limit + 7)/8 - 1);
  14962             soc_mem_field32_set(unit, mem2, entry0,
  14963                     YELLOW_SHARED_LIMITf, (limit + 7)/8);
  14964             soc_mem_field32_set(unit, mem2, entry0,
  14965                     YELLOW_RESUME_LIMITf, (limit + 7)/8 - 1);
  14966 
  14967 
  14968             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  14969                         index1, entry0));
  14970         }
  14971     }
  14972 
  14973     /* Output port per port per queue setting for regular unicast queue */
  14974     /* per port regular unicast queue */
  14975     numq = si->port_num_uc_cosq[port];
  14976     qbase = si->port_uc_cosq_base[port];
  14977     if (numq != 0) {
  14978         base = soc_td2_l2_hw_index(unit, qbase, 1);
  14979         mem = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_CONFIG_QUEUEm,
  14980                 MMU_THDU_YPIPE_CONFIG_QUEUEm);
  14981         mem1 = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_OFFSET_QUEUEm,
  14982                 MMU_THDU_YPIPE_OFFSET_QUEUEm);
  14983         mem2 = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_Q_TO_QGRP_MAPm,
  14984                 MMU_THDU_YPIPE_Q_TO_QGRP_MAPm);
  14985         for (idx = 0; idx < numq; idx++) {
  14986             buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx];
  14987 
  14988             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
  14989             sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_offset_queue_entry_t));
  14990 
  14991             soc_mem_field32_set(unit, mem, entry0,
  14992                     Q_MIN_LIMIT_CELLf, buf_queue->guarantee);
  14993             if (buf_queue->pool_scale != -1) {
  14994                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf, 1);
  14995                 soc_mem_field32_set(unit, mem, entry0,
  14996                         Q_SHARED_ALPHA_CELLf, buf_queue->pool_scale);
  14997             } else {
  14998                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  14999                 soc_mem_field32_set(unit, mem, entry0,
  15000                         Q_SHARED_LIMIT_CELLf, buf_queue->pool_limit);
  15001             }
  15002             soc_mem_field32_set(unit, mem1,
  15003                     entry1, RESET_OFFSET_CELLf, buf_queue->pool_resume / 8);
  15004 
  15005             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  15006                     (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  15007                 soc_mem_field32_set(unit, mem, entry0,
  15008                         Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  15009                 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf,
  15010                         buf_queue->yellow_limit
  15011                                  & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  15012                                  & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  15013                 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf,
  15014                         buf_queue->red_limit
  15015                                  & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  15016                                  & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  15017             } else {
  15018                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  15019                 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf,
  15020                         buf_queue->yellow_limit / 8);
  15021                 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf,
  15022                         buf_queue->red_limit / 8);
  15023             }
  15024             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf,
  15025                     buf_queue->yellow_resume / 8);
  15026             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf,
  15027                     buf_queue->red_resume / 8);
  15028             SOC_IF_ERROR_RETURN
  15029                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  15030 
  15031             SOC_IF_ERROR_RETURN
  15032                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1));
  15033 
  15034             sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t));
  15035             soc_mem_field32_set(unit, mem2,
  15036                     entry0, Q_SPIDf, buf_queue->pool_idx);
  15037             if (buf_queue->discard_enable) {
  15038                 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1);
  15039             }
  15040             if (buf_queue->color_discard_enable) {
  15041                 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_ENABLE_CELLf, 1);
  15042             }
  15043 
  15044 
  15045             if (buf_queue->qgroup_id >= 0) {
  15046                 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1);
  15047                 soc_mem_field32_set(unit, mem2, entry0, QGROUPf, buf_queue->qgroup_id);
  15048                 if (buf_queue->qgroup_min_enable) {
  15049                     soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1);
  15050                 }
  15051             }
  15052 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  15053             if (SOC_IS_TRIDENT2PLUS(unit)) {
  15054                 if (SOC_PBMP_MEMBER(si->eq_pbm, port)) {
  15055                     if ((idx < 8) && (buf_queue->qgroup_id < 0)) {
  15056                         /* If HSP port does not use qgroup for its lower 8 queues */
  15057                         soc_mem_field32_set(unit, mem2, entry0, QGROUPf, idx);
  15058                         e2ecc_ds_config = 2;
  15059                     } else {
  15060                         e2ecc_ds_config = 1;
  15061                     }
  15062                 } else {
  15063                     /* LLS port */
  15064                     e2ecc_ds_config = 1;
  15065                 }
  15066 
  15067                 soc_mem_field32_set(unit, mem2, entry0, Q_E2ECC_DS_CONFIGf, e2ecc_ds_config);
  15068             }
  15069 #endif
  15070 
  15071             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  15072                         base + idx, entry0));
  15073         }
  15074 
  15075         /* Per  port per pool unicast */
  15076         for (idx = 0; idx < _TD2_MMU_NUM_POOL; idx++) {
  15077             buf_pool = &buf->pools[idx];
  15078 
  15079             if (buf_pool->total == 0) {
  15080                 continue;
  15081             }
  15082 
  15083             limit = buf_pool->total - buf_pool->queue_guarantee;
  15084             mem2 = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_CONFIG_PORTm,
  15085                     MMU_THDU_YPIPE_CONFIG_PORTm);
  15086             index1 = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx);
  15087             mem3 = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_RESUME_PORTm,
  15088                     MMU_THDU_YPIPE_RESUME_PORTm);
  15089             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
  15090             sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_resume_port_entry_t));
  15091 
  15092             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit);
  15093             soc_mem_field32_set(unit, mem3, entry1,
  15094                     SHARED_RESUMEf, (limit - (default_mtu_cells * 2))/8);
  15095 
  15096             soc_mem_field32_set(unit, mem2, entry0, YELLOW_LIMITf, limit/8);
  15097             soc_mem_field32_set(unit, mem3, entry1,
  15098                     YELLOW_RESUMEf, (limit - (default_mtu_cells*2))/8);
  15099 
  15100             soc_mem_field32_set(unit, mem2, entry0, RED_LIMITf, limit/8);
  15101             soc_mem_field32_set(unit, mem3, entry1,
  15102                     RED_RESUMEf, (limit - (default_mtu_cells * 2))/8);
  15103 
  15104             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  15105                         index1, entry0));
  15106             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem3, MEM_BLOCK_ALL,
  15107                         index1, entry1));
  15108         }
  15109     }
  15110 
  15111     return SOC_E_NONE;
  15112 }
  15113 
  15114 STATIC int
  15115 _soc_td2_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf,
  15116                                _soc_mmu_device_info_t *devcfg, int lossless)
  15117 {
  15118     int port;
  15119 
  15120     SOC_IF_ERROR_RETURN(_soc_td2_mmu_config_buf_set_hw_global(unit,
  15121             buf, devcfg, lossless));
  15122 
  15123     PBMP_ALL_ITER(unit, port) {
  15124         SOC_IF_ERROR_RETURN(_soc_td2_mmu_config_buf_set_hw_port(unit, port,
  15125                 buf, devcfg, lossless));
  15126     }
  15127     return SOC_E_NONE;
  15128 }
  15129 
  15130 STATIC int
  15131 _soc_td2_mmu_config_shared_update_check(int unit, int val1, int val2, int flags)
  15132 {
  15133     int rv = 0;
  15134     if (flags == 1) {
  15135         if (val1 > val2) {
  15136             rv = 1;
  15137         }
  15138     } else {
  15139         if (val1 < val2) {
  15140             rv = 1;
  15141         }
  15142     }
  15143     return rv;
  15144 }
  15145 
  15146 int
  15147 soc_td2_mmu_config_shared_buf_recalc(int unit, uint32 spid,
  15148                                      int shared_size, int flags)
  15149 {
  15150     soc_info_t *si;
  15151     soc_mem_t mem, mem2;
  15152     soc_reg_t reg = INVALIDr;
  15153     soc_field_t field = INVALIDf;
  15154     uint32 rval, rval2;
  15155     uint32 entry0[SOC_MAX_MEM_WORDS];
  15156     thdi_port_pg_config_entry_t pg_config_mem;
  15157     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
  15158     int port, base, qbase, numq, idx;
  15159     int cur_limit, midx, index1;
  15160     int granularity;
  15161     uint16      dev_id;
  15162     uint8       rev_id;
  15163     static const soc_field_t pg_spid_field[] = {
  15164         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
  15165         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
  15166     };
  15167 
  15168     if (spid >= _TD2_MMU_NUM_POOL) {
  15169         return SOC_E_PARAM;
  15170     }
  15171 
  15172     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  15173 
  15174     si = &SOC_INFO(unit);
  15175 
  15176     /* per service pool settings */
  15177     idx = spid;
  15178     rval = 0;
  15179     reg = MMU_THDM_DB_POOL_SHARED_LIMITr;
  15180     field = SHARED_LIMITf;
  15181     granularity = 1;
  15182     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  15183     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  15184     if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15185         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity));
  15186         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  15187     }
  15188 
  15189     rval = 0;
  15190     reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr;
  15191     field = YELLOW_SHARED_LIMITf;
  15192     granularity = 8;
  15193     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  15194     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  15195     if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15196         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity));
  15197         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  15198     }
  15199 
  15200     rval = 0;
  15201     reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr;
  15202     field = RED_SHARED_LIMITf;
  15203     granularity = 8;
  15204     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  15205     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  15206     if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15207         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity));
  15208         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  15209     }
  15210 
  15211     /* configure Q-groups */
  15212     mem = MMU_THDU_XPIPE_CONFIG_QGROUPm;
  15213     for (idx = 0; idx < SOC_TD2_MMU_CFG_QGROUP_MAX; idx++) {
  15214         sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
  15215 
  15216         SOC_IF_ERROR_RETURN
  15217                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  15218 
  15219         field = Q_SHARED_LIMIT_CELLf;
  15220         granularity = 1;
  15221         if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) {
  15222             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  15223             if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15224                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  15225                                     field, shared_size/granularity);
  15226             }
  15227         }
  15228 
  15229         granularity = 8;
  15230         if (!soc_mem_field32_get(unit, mem, &cfg_qgrp,
  15231                                  Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
  15232             field = LIMIT_RED_CELLf;
  15233             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  15234             if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15235                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  15236                                     field, shared_size/granularity);
  15237             }
  15238 
  15239             field = LIMIT_YELLOW_CELLf;
  15240             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  15241             if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15242                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  15243                                     field, shared_size/granularity);
  15244             }
  15245         }
  15246 
  15247         SOC_IF_ERROR_RETURN
  15248                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  15249 
  15250         /* Y pipe */
  15251         if ((mem == MMU_THDU_XPIPE_CONFIG_QGROUPm) &&
  15252             (idx == (SOC_TD2_MMU_CFG_QGROUP_MAX -1))) {
  15253             idx = 0;
  15254             mem = MMU_THDU_YPIPE_CONFIG_QGROUPm;
  15255         }
  15256     }
  15257 
  15258     /* Input port per port settings */
  15259     PBMP_ALL_ITER(unit, port) {
  15260         rval = 0;
  15261         /* Input port per port per priority group settings */
  15262         mem = SOC_TD2_PMEM(unit, port, THDI_PORT_PG_CONFIG_Xm,
  15263                                        THDI_PORT_PG_CONFIG_Ym);
  15264         field = PG_SHARED_LIMITf;
  15265         granularity = 1;
  15266         for (idx = 0; idx < _TD2_MMU_NUM_PG; idx++) {
  15267             SOC_IF_ERROR_RETURN(READ_THDI_PORT_PG_SPIDr(unit, port, &rval));
  15268             if (spid != soc_reg_field_get(unit, THDI_PORT_PG_SPIDr, rval,
  15269                                           pg_spid_field[idx])) {
  15270                 continue;
  15271             }
  15272             midx = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  15273             sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
  15274             SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem,
  15275                                              MEM_BLOCK_ALL, midx, &pg_config_mem));
  15276             if (!soc_mem_field32_get(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf)) {
  15277                 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, field);
  15278                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15279                     soc_mem_field32_set(unit, mem, &pg_config_mem,
  15280                                         field, shared_size/granularity);
  15281                 }
  15282             }
  15283 
  15284             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem,
  15285                                            MEM_BLOCK_ALL, midx, &pg_config_mem));
  15286         }
  15287     }
  15288 
  15289     /***********************************
  15290      * THDO
  15291  */
  15292     /* Output port per port per queue setting for regular multicast queue */
  15293     PBMP_PORT_ITER(unit, port) {
  15294         numq = si->port_num_cosq[port];
  15295         qbase = si->port_cosq_base[port];
  15296         if (numq == 0) {
  15297             continue;
  15298         }
  15299 
  15300         mem = SOC_TD2_PMEM(unit, port, MMU_THDM_DB_QUEUE_CONFIG_0m,
  15301                                        MMU_THDM_DB_QUEUE_CONFIG_1m);
  15302         base = soc_td2_l2_hw_index(unit, qbase, 0) - 1480;
  15303 
  15304         for (idx = 0; idx < numq; idx++) {
  15305             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
  15306 
  15307             SOC_IF_ERROR_RETURN
  15308                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  15309             if (spid != soc_mem_field32_get(unit, mem, entry0, Q_SPIDf)) {
  15310                 continue;
  15311             }
  15312 
  15313             field = Q_SHARED_LIMITf;
  15314             granularity = 1;
  15315             if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) {
  15316                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15317                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15318                     soc_mem_field32_set(unit, mem, entry0,
  15319                                         field, shared_size/granularity);
  15320                 }
  15321             }
  15322 
  15323             granularity = 8;
  15324             if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) {
  15325                 field = YELLOW_SHARED_LIMITf;
  15326                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15327                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15328                     soc_mem_field32_set(unit, mem, entry0,
  15329                                         field, shared_size/granularity);
  15330                 }
  15331                 field = RED_SHARED_LIMITf;
  15332                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15333                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15334                     soc_mem_field32_set(unit, mem, entry0,
  15335                                         field, shared_size/granularity);
  15336                 }
  15337             }
  15338             SOC_IF_ERROR_RETURN
  15339                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  15340                                entry0));
  15341         }
  15342 
  15343         /* Per  port per pool */
  15344         idx = spid;
  15345         mem = SOC_TD2_PMEM(unit, port, MMU_THDM_DB_PORTSP_CONFIG_0m,
  15346                                         MMU_THDM_DB_PORTSP_CONFIG_1m);
  15347         index1 = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  15348         sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t));
  15349 
  15350         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
  15351                             index1, entry0));
  15352 
  15353         field = SHARED_LIMITf;
  15354         granularity = 1;
  15355         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15356         if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15357             soc_mem_field32_set(unit, mem, entry0,
  15358                                 field, shared_size/granularity);
  15359         }
  15360 
  15361         field = RED_SHARED_LIMITf;
  15362         granularity = 8;
  15363         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15364         if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15365             soc_mem_field32_set(unit, mem, entry0,
  15366                                 field, shared_size/granularity);
  15367         }
  15368 
  15369         field = YELLOW_SHARED_LIMITf;
  15370         granularity = 8;
  15371         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15372         if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15373             soc_mem_field32_set(unit, mem, entry0,
  15374                                 field, shared_size/granularity);
  15375         }
  15376 
  15377         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
  15378                             index1, entry0));
  15379     }
  15380 
  15381     /* Output port per port per queue setting for regular unicast queue */
  15382     PBMP_PORT_ITER(unit, port) {
  15383         /* per port regular unicast queue */
  15384         numq = si->port_num_uc_cosq[port];
  15385         qbase = si->port_uc_cosq_base[port];
  15386 
  15387         if (numq == 0) {
  15388             continue;
  15389         }
  15390         base = soc_td2_l2_hw_index(unit, qbase, 1);
  15391         mem = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_CONFIG_QUEUEm,
  15392                                        MMU_THDU_YPIPE_CONFIG_QUEUEm);
  15393         mem2 = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_Q_TO_QGRP_MAPm,
  15394                                        MMU_THDU_YPIPE_Q_TO_QGRP_MAPm);
  15395         for (idx = 0; idx < numq; idx++) {
  15396             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_q_to_qgrp_map_entry_t));
  15397             SOC_IF_ERROR_RETURN
  15398                 (soc_mem_read(unit, mem2, MEM_BLOCK_ALL, base + idx, entry0));
  15399             if (spid != soc_mem_field32_get(unit, mem2, entry0, Q_SPIDf)) {
  15400                 continue;
  15401             }
  15402             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
  15403             SOC_IF_ERROR_RETURN
  15404                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  15405 
  15406             field = Q_SHARED_LIMIT_CELLf;
  15407             granularity = 1;
  15408             if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) {
  15409                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15410                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15411                     soc_mem_field32_set(unit, mem, entry0,
  15412                                         field, shared_size/granularity);
  15413                 }
  15414             }
  15415 
  15416             granularity = 8;
  15417             if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
  15418                 field = LIMIT_YELLOW_CELLf;
  15419                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15420                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15421                     soc_mem_field32_set(unit, mem, entry0,
  15422                                         field, shared_size/granularity);
  15423                 }
  15424                 field = LIMIT_RED_CELLf;
  15425                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15426                 if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15427                     soc_mem_field32_set(unit, mem, entry0,
  15428                                         field, shared_size/granularity);
  15429                 }
  15430             }
  15431             SOC_IF_ERROR_RETURN
  15432                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  15433         }
  15434 
  15435         /* Per  port per pool unicast */
  15436         idx = spid;
  15437         mem = SOC_TD2_PMEM(unit, port, MMU_THDU_XPIPE_CONFIG_PORTm,
  15438                                        MMU_THDU_YPIPE_CONFIG_PORTm);
  15439         index1 = SOC_TD2_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  15440         sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
  15441 
  15442         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
  15443                             index1, entry0));
  15444 
  15445         field = SHARED_LIMITf;
  15446         granularity = 1;
  15447         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15448         if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15449             soc_mem_field32_set(unit, mem, entry0,
  15450                                 field, shared_size/granularity);
  15451         }
  15452 
  15453         granularity = 8;
  15454         field = YELLOW_LIMITf;
  15455         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15456         if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15457             soc_mem_field32_set(unit, mem, entry0,
  15458                                 field, shared_size/granularity);
  15459         }
  15460         field = RED_LIMITf;
  15461         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  15462         if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15463             soc_mem_field32_set(unit, mem, entry0,
  15464                                 field, shared_size/granularity);
  15465         }
  15466 
  15467         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
  15468                             index1, entry0));
  15469     }
  15470 
  15471     /* RQE */
  15472     for (idx = 0; idx < 11; idx++) {
  15473         rval = 0;
  15474         rval2 = 0;
  15475 
  15476         SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval));
  15477         if (spid != soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  15478                                       SPIDf)) {
  15479             continue;
  15480         }
  15481 
  15482         reg = MMU_THDR_DB_CONFIG_PRIQr;
  15483         field = SHARED_LIMITf;
  15484         granularity = 1;
  15485         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  15486         if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  15487                                DYNAMIC_ENABLEf)) {
  15488             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  15489             if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15490                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  15491                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  15492             }
  15493         }
  15494 
  15495         rval2 = 0;
  15496         reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr;
  15497         granularity = 8;
  15498         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  15499 
  15500         if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  15501                                COLOR_LIMIT_DYNAMICf)) {
  15502             field = SHARED_RED_LIMITf;
  15503             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  15504             if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15505                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  15506             }
  15507 
  15508             field = SHARED_YELLOW_LIMITf;
  15509             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  15510             if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15511                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  15512             }
  15513             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  15514         }
  15515 
  15516     }
  15517 
  15518     /* per pool RQE settings */
  15519     idx = spid;
  15520     reg = MMU_THDR_DB_CONFIG_SPr;
  15521     field = SHARED_LIMITf;
  15522     granularity = 1;
  15523 
  15524     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  15525     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  15526 
  15527     if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15528         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  15529         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  15530     }
  15531 
  15532     reg = MMU_THDR_DB_SP_SHARED_LIMITr;
  15533     granularity = 8;
  15534 
  15535     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  15536 
  15537     field = SHARED_YELLOW_LIMITf;
  15538     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  15539 
  15540     if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15541         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  15542     }
  15543 
  15544     field = SHARED_RED_LIMITf;
  15545     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  15546 
  15547     if (_soc_td2_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  15548         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  15549     }
  15550     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  15551 
  15552     return SOC_E_NONE;
  15553 }
  15554 
  15555 STATIC int
  15556 soc_td2_mmu_config_init(int unit, int test_only)
  15557 {
  15558     int rv;
  15559     int lossless;
  15560     _soc_mmu_cfg_buf_t *buf;
  15561     _soc_mmu_device_info_t devcfg;
  15562 
  15563     buf = soc_mmu_cfg_alloc(unit);
  15564     if (!buf) {
  15565         return SOC_E_MEMORY;
  15566     }
  15567 
  15568     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 1);
  15569 
  15570     _soc_td2_mmu_init_dev_config(unit, &devcfg, lossless);
  15571     _soc_td2_mmu_config_buf_default(unit, buf, &devcfg, lossless);
  15572     if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
  15573         _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
  15574     }
  15575     rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg);
  15576     if (!test_only) {
  15577         if (SOC_FAILURE(rv)) {
  15578             LOG_VERBOSE(BSL_LS_SOC_COMMON,
  15579                         (BSL_META_U(unit,
  15580                                     "MMU config: Use default setting\n")));
  15581             _soc_td2_mmu_config_buf_default(unit, buf, &devcfg, lossless);
  15582             _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg);
  15583         }
  15584         rv = _soc_td2_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless);
  15585     }
  15586 
  15587     soc_mmu_cfg_free(unit, buf);
  15588 
  15589     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  15590                 (BSL_META_U(unit,
  15591                             "MMU THDI/THDO init done\n")));
  15592     return rv;
  15593 }
  15594 
  15595 /*Clear MMU_CBPDATA for TD2 mmu_init*/
  15596 STATIC int
  15597 _soc_trident2_mmu_cbpdata_clear(int unit)
  15598 {
  15599     soc_mem_t mem;
  15600     soc_mem_t cbpdata_start_m;
  15601     soc_mem_t cbpdata_end_m;
  15602 
  15603     cbpdata_start_m = MMU_CBPDATA0m;
  15604     cbpdata_end_m = MMU_CBPDATA63m;
  15605 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  15606     if (SOC_IS_TD2P_TT2P(unit)) {
  15607         cbpdata_end_m = MMU_CBPDATA83m;
  15608     }
  15609 #endif
  15610 
  15611     for (mem = cbpdata_start_m; mem <= cbpdata_end_m; mem++) {
  15612         SOC_IF_ERROR_RETURN(
  15613                 soc_mem_clear(unit, mem, MEM_BLOCK_ALL, TRUE));
  15614     }
  15615     return SOC_E_NONE;
  15616 }
  15617 
  15618 int soc_td2_mmu_traffic_ctrl_size(int unit, int *req_scache_size)
  15619 {
  15620     *req_scache_size += sizeof(_soc_td2_mmu_traffic_ctrl_t);
  15621 
  15622     return SOC_E_NONE;
  15623 }
  15624 
  15625 int soc_td2_mmu_traffic_ctrl_wb_sync(int unit, uint8 **scache_ptr)
  15626 {
  15627     _soc_td2_mmu_traffic_ctrl_t *mmu_traffic_ctrl_scache_p;
  15628     _soc_td2_mmu_traffic_ctrl_t *mmu_traffic_ctrl;
  15629 
  15630     mmu_traffic_ctrl_scache_p =
  15631         (_soc_td2_mmu_traffic_ctrl_t *)(*scache_ptr);
  15632 
  15633 
  15634     mmu_traffic_ctrl = _soc_td2_mmu_traffic_ctrl[unit];
  15635     if (mmu_traffic_ctrl == NULL || mmu_traffic_ctrl_scache_p == NULL) {
  15636         return SOC_E_NONE;
  15637     }
  15638     sal_memcpy(mmu_traffic_ctrl_scache_p, mmu_traffic_ctrl, sizeof(_soc_td2_mmu_traffic_ctrl_t));
  15639     mmu_traffic_ctrl_scache_p++;
  15640 
  15641     *scache_ptr = (uint8 *)mmu_traffic_ctrl_scache_p;
  15642 
  15643     return SOC_E_NONE;
  15644 }
  15645 
  15646 int soc_td2_mmu_traffic_ctrl_wb_restore(int unit, uint8 **scache_ptr)
  15647 {
  15648     _soc_td2_mmu_traffic_ctrl_t *mmu_traffic_ctrl_scache_p;
  15649     _soc_td2_mmu_traffic_ctrl_t *mmu_traffic_ctrl;
  15650 
  15651     mmu_traffic_ctrl_scache_p =
  15652         (_soc_td2_mmu_traffic_ctrl_t *)(*scache_ptr);
  15653 
  15654 
  15655     mmu_traffic_ctrl = _soc_td2_mmu_traffic_ctrl[unit];
  15656     if (mmu_traffic_ctrl == NULL || mmu_traffic_ctrl_scache_p == NULL) {
  15657         return SOC_E_NONE;
  15658     }
  15659     sal_memcpy(mmu_traffic_ctrl, mmu_traffic_ctrl_scache_p, sizeof(_soc_td2_mmu_traffic_ctrl_t));
  15660     mmu_traffic_ctrl_scache_p++;
  15661 
  15662     *scache_ptr = (uint8 *)mmu_traffic_ctrl_scache_p;
  15663 
  15664     return SOC_E_NONE;
  15665 }
  15666 
  15667 /*
  15668  * LLS creation will be skipped on TD2 only when the port bitmap
  15669  * spn_PBMP_SKIP_DEFAULT_LLS is non-zero.
  15670  */
  15671 int
  15672 soc_td2_is_skip_default_lls_creation(int unit) {
  15673     int skip = 0;
  15674     soc_pbmp_t skip_default_lls_pbmp;
  15675 
  15676     skip_default_lls_pbmp = soc_property_get_pbmp(unit, spn_PBMP_SKIP_DEFAULT_LLS, 0);
  15677     if (SOC_PBMP_NOT_NULL(skip_default_lls_pbmp)) {
  15678         skip = 1;
  15679     }
  15680 
  15681     return skip;
  15682 }
  15683 
  15684 STATIC int
  15685 _soc_trident2_mmu_init(int unit)
  15686 {
  15687     uint32 rval;
  15688     uint64 rval64;
  15689     soc_info_t *si;
  15690     soc_pbmp_t pbmp;
  15691     int port, phy_port, mmu_port;
  15692     int alloc_size;
  15693     int test_only;
  15694 
  15695     if (_fwd_ctrl_lock[unit] == NULL) {
  15696         _fwd_ctrl_lock[unit] = sal_mutex_create("_fwd_ctrl_lock");
  15697     }
  15698 
  15699     if (_fwd_ctrl_lock[unit] == NULL) {
  15700         return SOC_E_MEMORY;
  15701     }
  15702 
  15703     if (_soc_td2_mmu_traffic_ctrl[unit] == NULL) {
  15704         alloc_size = sizeof(_soc_td2_mmu_traffic_ctrl_t);
  15705         _soc_td2_mmu_traffic_ctrl[unit] =
  15706             sal_alloc(alloc_size,"_soc_td2_mmu_traffic_ctrl");
  15707         if (_soc_td2_mmu_traffic_ctrl[unit] == NULL) {
  15708             return SOC_E_MEMORY;
  15709         }
  15710         sal_memset(_soc_td2_mmu_traffic_ctrl[unit], 0, alloc_size);
  15711     }
  15712 
  15713     test_only = (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM) ? TRUE : FALSE;
  15714     SOC_IF_ERROR_RETURN(soc_td2_mmu_config_init(unit, test_only));
  15715 
  15716     SOC_IF_ERROR_RETURN(soc_td2_lls_init(unit));
  15717 
  15718     rval = 0;
  15719     soc_reg_field_set(unit, ES_PIPE0_LLS_CONFIG0r, &rval, ENQUEUE_ENABLEf, 1);
  15720     soc_reg_field_set(unit, ES_PIPE0_LLS_CONFIG0r, &rval, DEQUEUE_ENABLEf, 1);
  15721     SOC_IF_ERROR_RETURN(WRITE_ES_PIPE0_LLS_CONFIG0r(unit, rval));
  15722     SOC_IF_ERROR_RETURN(WRITE_ES_PIPE1_LLS_CONFIG0r(unit, rval));
  15723 
  15724     rval = 0;
  15725     soc_reg_field_set(unit, PRIORITY_CONTROLr, &rval, USE_SC_FOR_MH_PRIf, 1);
  15726     soc_reg_field_set(unit, PRIORITY_CONTROLr, &rval, USE_QM_FOR_MH_PRIf, 1);
  15727     SOC_IF_ERROR_RETURN(WRITE_PRIORITY_CONTROLr(unit, rval));
  15728 
  15729     SOC_IF_ERROR_RETURN
  15730         (soc_reg_field32_modify(unit, OOBFC_CHANNEL_BASE_64r, REG_PORT_ANY,
  15731                                 ENG_ENf, 1));
  15732 
  15733     /* Enable IP to CMICM credit transfer */
  15734     rval = 0;
  15735     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval,
  15736                       TRANSFER_ENABLEf, 1);
  15737     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval,
  15738                       NUM_OF_CREDITSf, 32);
  15739     SOC_IF_ERROR_RETURN(WRITE_IP_TO_CMICM_CREDIT_TRANSFERr(unit, rval));
  15740 
  15741     /*Clear MMU_CBPData*/
  15742     if ( !SAL_BOOT_SIMULATION ) {
  15743         SOC_IF_ERROR_RETURN(_soc_trident2_mmu_cbpdata_clear(unit));
  15744     }
  15745 
  15746     if (!soc_td2_is_skip_default_lls_creation(unit)) {
  15747         /* Enable all ports */
  15748         COMPILER_64_ZERO(rval64);
  15749 
  15750         COMPILER_64_SET(rval64, 0x1fffff, 0xffffffff);
  15751         SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE0_64r(unit, rval64));
  15752         SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE1_64r(unit, rval64));
  15753         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE0_64r(unit, rval64));
  15754         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE1_64r(unit, rval64));
  15755         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r(unit, rval64));
  15756         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r(unit, rval64));
  15757     } else {
  15758         /* enable cpu & loopback port */
  15759         uint64 cpubit64;
  15760         COMPILER_64_ZERO(cpubit64);
  15761         COMPILER_64_SET(cpubit64, 0x100000, 0x00000000);
  15762 
  15763         COMPILER_64_ZERO(rval64);
  15764         SOC_IF_ERROR_RETURN(READ_THDU_OUTPUT_PORT_RX_ENABLE0_64r(unit, &rval64));
  15765         COMPILER_64_OR(rval64, cpubit64);
  15766         SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE0_64r(unit, rval64));
  15767 
  15768         COMPILER_64_ZERO(rval64);
  15769         SOC_IF_ERROR_RETURN(READ_THDU_OUTPUT_PORT_RX_ENABLE1_64r(unit, &rval64));
  15770         COMPILER_64_OR(rval64, cpubit64);
  15771         SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE1_64r(unit, rval64));
  15772 
  15773         COMPILER_64_ZERO(rval64);
  15774         SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_PORTSP_RX_ENABLE0_64r(unit, &rval64));
  15775         COMPILER_64_OR(rval64, cpubit64);
  15776         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE0_64r(unit, rval64));
  15777 
  15778         COMPILER_64_ZERO(rval64);
  15779         SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_PORTSP_RX_ENABLE1_64r(unit, &rval64));
  15780         COMPILER_64_OR(rval64, cpubit64);
  15781         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE1_64r(unit, rval64));
  15782 
  15783         COMPILER_64_ZERO(rval64);
  15784         SOC_IF_ERROR_RETURN(READ_MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r(unit, &rval64));
  15785         COMPILER_64_OR(rval64, cpubit64);
  15786         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r(unit, rval64));
  15787 
  15788         COMPILER_64_ZERO(rval64);
  15789         SOC_IF_ERROR_RETURN(READ_MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r(unit, &rval64));
  15790         COMPILER_64_OR(rval64, cpubit64);
  15791         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r(unit, rval64));
  15792     }
  15793 
  15794     if (soc_feature(unit, soc_feature_post)) {
  15795         SOC_IF_ERROR_RETURN(soc_mmu_post_init(unit));
  15796     }
  15797 
  15798     rval = 0;
  15799     si = &SOC_INFO(unit);
  15800     pbmp = si->oversub_pbm;
  15801     SOC_PBMP_ITER(pbmp, port) {
  15802         if (si->port_speed_max[port] >= 30000) {
  15803             phy_port = si->port_l2p_mapping[port];
  15804             mmu_port = si->port_p2m_mapping[phy_port];
  15805             if (mmu_port < si->mmu_port_base[1]) {
  15806                 rval |= 1 << mmu_port;
  15807             } else {
  15808                 rval |= 1 << (mmu_port - si->mmu_port_base[1] + 16);
  15809             }
  15810         }
  15811     }
  15812     SOC_IF_ERROR_RETURN(WRITE_ENQ_ASF_HS_OVERSUB_ENr(unit, rval));
  15813 
  15814 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  15815     if (SOC_IS_TD2P_TT2P(unit)) {
  15816         SOC_IF_ERROR_RETURN(READ_ES_PIPE0_MMU_1DBG_Cr(unit, &rval));
  15817         soc_reg_field_set(unit, ES_PIPE0_MMU_1DBG_Cr, &rval, FIELD_Af, 1);
  15818         SOC_IF_ERROR_RETURN(WRITE_ES_PIPE0_MMU_1DBG_Cr(unit, rval));
  15819 
  15820         SOC_IF_ERROR_RETURN(READ_ES_PIPE1_MMU_1DBG_Cr(unit, &rval));
  15821         soc_reg_field_set(unit, ES_PIPE1_MMU_1DBG_Cr, &rval, FIELD_Af, 1);
  15822         SOC_IF_ERROR_RETURN(WRITE_ES_PIPE1_MMU_1DBG_Cr(unit, rval));
  15823 
  15824         SOC_IF_ERROR_RETURN(READ_ES_PIPE0_MMU_2DBG_C_0r(unit, &rval));
  15825         soc_reg_field_set(unit, ES_PIPE0_MMU_2DBG_C_0r, &rval, FIELD_Af, (200 * si->frequency));
  15826         SOC_IF_ERROR_RETURN(WRITE_ES_PIPE0_MMU_2DBG_C_0r(unit, rval));
  15827 
  15828         SOC_IF_ERROR_RETURN(READ_ES_PIPE1_MMU_2DBG_C_0r(unit, &rval));
  15829         soc_reg_field_set(unit, ES_PIPE1_MMU_2DBG_C_0r, &rval, FIELD_Af, (200 * si->frequency));
  15830         SOC_IF_ERROR_RETURN(WRITE_ES_PIPE1_MMU_2DBG_C_0r(unit, rval));
  15831     }
  15832 #endif
  15833 
  15834     PBMP_ALL_ITER(unit, port) {
  15835         COMPILER_64_ZERO(rval64);
  15836         soc_reg64_field32_set(unit, INTFO_CONGST_STr, &rval64, ENf, 1);
  15837         SOC_IF_ERROR_RETURN(WRITE_INTFO_CONGST_STr(unit, port, rval64));
  15838 
  15839 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  15840         if (SOC_IS_TD2P_TT2P(unit)) {
  15841             SOC_IF_ERROR_RETURN(soc_td2p_mmu_delay_insertion_set (unit,
  15842                         port, si->port_speed_max [port]));
  15843         }
  15844 #endif
  15845 
  15846     }
  15847 
  15848     /* Enabling the Congestion state enable ,
  15849      *  so that dmvoq message is transmitted
  15850      *  when a congestion is present
  15851      */
  15852     PBMP_ALL_ITER(unit, port) {
  15853         COMPILER_64_ZERO(rval64);
  15854         soc_reg64_field32_set(unit, INTFO_CONGST_STr, &rval64, ENf, 1);
  15855         SOC_IF_ERROR_RETURN(WRITE_INTFO_CONGST_STr(unit, port, rval64));
  15856     }
  15857     return SOC_E_NONE;
  15858 }
  15859 
  15860 STATIC int
  15861 _soc_trident2_age_timer_get(int unit, int *age_seconds, int *enabled)
  15862 {
  15863     soc_control_t *soc = SOC_CONTROL(unit);
  15864     uint32 rval;
  15865 
  15866     if (!soc->l2x_sw_aging) {
  15867         SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval));
  15868         *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf);
  15869         *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf);
  15870     } else {
  15871         *enabled = soc->l2x_age_pid != SAL_THREAD_ERROR &&
  15872                    soc->l2x_age_enable ?
  15873                    1 : 0;
  15874         *age_seconds = soc->l2x_age_pid != SAL_THREAD_ERROR &&
  15875                        soc->l2x_age_enable ?
  15876                        soc->l2x_age_interval : 0;
  15877     }
  15878 
  15879     return SOC_E_NONE;
  15880 }
  15881 
  15882 STATIC int
  15883 _soc_trident2_age_timer_max_get(int unit, int *max_seconds)
  15884 {
  15885     soc_control_t *soc = SOC_CONTROL(unit);
  15886 
  15887     if (!soc->l2x_sw_aging) {
  15888         *max_seconds =
  15889             soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
  15890     } else {
  15891         *max_seconds = 0x7fffffff;
  15892     }
  15893 
  15894     return SOC_E_NONE;
  15895 }
  15896 
  15897 STATIC int
  15898 _soc_trident2_age_timer_set(int unit, int age_seconds, int enable)
  15899 {
  15900     soc_control_t *soc = SOC_CONTROL(unit);
  15901     sal_usecs_t interval = soc->l2x_age_interval;
  15902     uint32 rval = 0;
  15903 
  15904     if (!soc->l2x_sw_aging) {
  15905         soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable);
  15906         soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds);
  15907         SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval));
  15908     } else if (soc->l2x_age_interval) {
  15909         if (!enable) {
  15910             soc->l2x_age_enable = 0;
  15911         } else {
  15912             if (age_seconds) {
  15913                 SOC_CONTROL_LOCK(unit);
  15914                 soc->l2x_age_interval = age_seconds;
  15915                 SOC_CONTROL_UNLOCK(unit);
  15916             }
  15917             soc->l2x_age_enable = 1;
  15918             if (interval != age_seconds) {
  15919                 sal_sem_give(soc->l2x_age_notify);
  15920             }
  15921         }
  15922     } else {
  15923         if (enable) {
  15924             SOC_IF_ERROR_RETURN
  15925                 (soc_td2_l2_bulk_age_start(unit, age_seconds));
  15926         }
  15927     }
  15928 
  15929     return SOC_E_NONE;
  15930 }
  15931 
  15932 STATIC int
  15933 _soc_trident2_mdio_addr_to_port(uint32 phy_addr)
  15934 {
  15935     int bus, offset;
  15936 
  15937     /* Must be internal MDIO address */
  15938     if ((phy_addr & 0x80) == 0) {
  15939         return 0;
  15940     }
  15941 
  15942     /*
  15943      * Internal phy address:
  15944      * bus 0 phy 1 to 20 are mapped to Physical port 1 to 20
  15945      * bus 1 phy 1 to 24 are mapped to Physical port 21 to 44
  15946      * bus 2 phy 1 to 20 are mapped to Physical port 45 to 64
  15947      * bus 3 phy 1 to 20 are mapped to Physical port 65 to 84
  15948      * bus 4 phy 1 to 24 are mapped to Physical port 85 to 108
  15949      * bus 5 phy 1 to 20 are mapped to Physical port 109 to 128
  15950      */
  15951     bus = 0;
  15952     if (phy_addr & 0x20) {
  15953         bus |= 0x1;
  15954     }
  15955     if (phy_addr & 0x40) {
  15956         bus |= 0x2;
  15957     }
  15958     if (phy_addr & 0x100) {
  15959         bus |= 0x4;
  15960     }
  15961     offset = 0;
  15962     if (bus >= 5) {
  15963         offset = 8;
  15964     } else if (bus >= 2) {
  15965         offset = 4;
  15966     }
  15967     return (20 * bus) + (phy_addr & 0x1f) + offset;
  15968 }
  15969 
  15970 STATIC int
  15971 _soc_trident2_mdio_reg_read(int unit, uint32 phy_addr,
  15972                             uint32 phy_reg, uint32 *phy_data)
  15973 {
  15974     int port, phy_port, blk;
  15975 
  15976 #if 0
  15977     /* phy access is the same regardless if PortMod enabled */
  15978     /* TSC reg read/write is handled by PortMod internally */
  15979     if (SOC_USE_PORTCTRL(unit)) {
  15980         return SOC_E_INTERNAL;
  15981     }
  15982 #endif
  15983 
  15984     /* Physical port based on MDIO address */
  15985     phy_port = _soc_trident2_mdio_addr_to_port(phy_addr);
  15986 
  15987     /* THIS IS A TEMPORARY WORK AROUND FOR THE ACCESS */
  15988     port = SOC_INFO(unit).port_p2l_mapping[phy_port&0xFFF1];
  15989     LOG_INFO(BSL_LS_SOC_MII,
  15990              (BSL_META_U(unit,
  15991                          "soc_trident2_mdio_reg_read[%d]: %d/%d/%d\n"),
  15992               unit, phy_addr, phy_port, port));
  15993     blk = SOC_PORT_BLOCK(unit, phy_port);
  15994 
  15995     /* Call common S-bus MDIO read function */
  15996     return soc_sbus_mdio_reg_read(unit, port, blk, 0,
  15997                                   phy_addr, phy_reg, phy_data,
  15998                                   XLPORT_WC_UCMEM_DATAm,
  15999                                   XLPORT_WC_UCMEM_CTRLr);
  16000 }
  16001 
  16002 STATIC int
  16003 _soc_trident2_mdio_reg_write(int unit, uint32 phy_addr,
  16004                              uint32 phy_reg, uint32 phy_data)
  16005 {
  16006     int port, phy_port, blk;
  16007 
  16008 #if 0
  16009     /* phy access is the same regardless if PortMod enabled */
  16010     /* TSC reg read/write is handled by PortMod internally */
  16011     if (SOC_USE_PORTCTRL(unit)) {
  16012         return SOC_E_INTERNAL;
  16013     }
  16014 #endif
  16015 
  16016     /* Physical port based on MDIO address */
  16017     phy_port = _soc_trident2_mdio_addr_to_port(phy_addr);
  16018     /* THIS IS A TEMPORARY WORK AROUND FOR THE ACCESS */
  16019     port = SOC_INFO(unit).port_p2l_mapping[phy_port & 0xFFF1];
  16020     blk = SOC_PORT_BLOCK(unit, phy_port);
  16021 
  16022     /* Call common S-bus MDIO read function */
  16023     return soc_sbus_mdio_reg_write(unit, port, blk, 0,
  16024                                    phy_addr, phy_reg, phy_data,
  16025                                    XLPORT_WC_UCMEM_DATAm,
  16026                                    XLPORT_WC_UCMEM_CTRLr);
  16027 }
  16028 
  16029 /*
  16030  * Function:
  16031  *      _soc_trident2_port_lanes_update_tdm
  16032  * Description:
  16033  *      Update PGW and MMU TDM programming for flex port
  16034  * Parameters:
  16035  *      unit          - Device number
  16036  *      lanes_ctrl    - Control structure
  16037  */
  16038 STATIC int
  16039 _soc_trident2_port_lanes_update_tdm(int unit, soc_td2_port_lanes_t *lanes_ctrl)
  16040 {
  16041     soc_info_t *si = &SOC_INFO(unit);
  16042     soc_reg_t reg, *reg_list;
  16043     soc_mem_t mem;
  16044     soc_field_t field;
  16045     int port_base, phy_port_base, mmu_port_base, pgw_inst;
  16046     int block_info_idx, bindex;
  16047     int cur_ids[4], cur_ids_len;
  16048     int ids[4], ids_len;
  16049     int pipe, base, index, slot, slot_len, seq, count, i;
  16050     int base_end;
  16051     uint64 rval64;
  16052     uint32 entry[SOC_MAX_MEM_WORDS];
  16053     uint32 rval, fval;
  16054     static soc_mem_t mmu_tdm_regs[2] ={
  16055         ES_PIPE0_TDM_CONFIGr, ES_PIPE1_TDM_CONFIGr
  16056     };
  16057     static soc_mem_t mmu_tdm_mems[2] ={
  16058         ES_PIPE0_TDM_TABLE_0m, ES_PIPE1_TDM_TABLE_0m
  16059     };
  16060     /* Trident2+ has different registers so pointer will be changed later */
  16061     mmu_ovs_group_wt_regs_t mmu_ovs_group_wt_regs = mmu_ovs_group_wt_regs_local;
  16062 
  16063     static soc_mem_t mmu_tdm_fields[2] ={
  16064         PORT_NUM_EVENf, PORT_NUM_ODDf
  16065     };
  16066 
  16067 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  16068     mmu_ovs_group_wt_regs = get_mmu_ovs_group_wt_regs ( unit, mmu_ovs_group_wt_regs );
  16069 #endif
  16070 
  16071     /* Construct new and old physical port list for calendar replacement */
  16072     port_base = lanes_ctrl->port_base;
  16073     phy_port_base = si->port_l2p_mapping[port_base];
  16074     ids[0] = cur_ids[0] = phy_port_base;
  16075     ids_len = cur_ids_len = 1;
  16076     if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) {
  16077         /* port(s) to be removed */
  16078         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16079             cur_ids[1 + i] = lanes_ctrl->phy_ports[i];
  16080         }
  16081         cur_ids_len += lanes_ctrl->phy_ports_len;
  16082     } else { /* port(s) to be added */
  16083         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16084             ids[1 + i] = lanes_ctrl->phy_ports[i];
  16085         }
  16086         ids_len += lanes_ctrl->phy_ports_len;
  16087     }
  16088 
  16089     /* Update PGW line rate ports or oversubscription ports TDM */
  16090     reg_list = lanes_ctrl->oversub ? pgw_ovs_tdm_regs : pgw_tdm_regs;
  16091     pgw_inst = (si->port_group[port_base] & 0x6) | SOC_REG_ADDR_INSTANCE_MASK;
  16092     seq = 0;
  16093     /* if oversub then TDM have _TD2_PGW_TDM_LENGTH registers */
  16094     base_end = lanes_ctrl->oversub ? _TD2_PGW_TDM_LENGTH :
  16095                                      GET_PGW_TDM_LENGTH(unit);
  16096     for (base = 0; base < base_end; base += _PGW_TDM_SLOTS_PER_REG) {
  16097         reg = reg_list[base / _PGW_TDM_SLOTS_PER_REG];
  16098         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, 0, &rval64));
  16099         count = 0;
  16100         for (index = 0; index < _PGW_TDM_SLOTS_PER_REG; index++) {
  16101             slot = base + index;
  16102             fval = soc_reg64_field32_get(unit, reg, rval64,
  16103                                          pgw_tdm_fields[slot]);
  16104             for (i = 0; i < cur_ids_len; i++) {
  16105                 if (fval == cur_ids[i]) {
  16106                     break;
  16107                 }
  16108             }
  16109             if (i == cur_ids_len) { /* no match */
  16110                 continue;
  16111             }
  16112             if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  16113                 LOG_CLI((BSL_META_U(unit,
  16114                                     "set PGW_CL%d TDM slot %d from %d to %d\n"),
  16115                          pgw_inst & ~SOC_REG_ADDR_INSTANCE_MASK, slot,
  16116                          fval, ids[seq % ids_len]));
  16117             }
  16118             if (i != 0 || (seq % ids_len) != 0) {
  16119                 soc_reg64_field32_set(unit, reg, &rval64, pgw_tdm_fields[slot],
  16120                                       ids[seq % ids_len]);
  16121                 count++;
  16122             }
  16123             seq++;
  16124         }
  16125         if (count > 0) {
  16126             SOC_IF_ERROR_RETURN
  16127                 (soc_reg_set(unit, reg, pgw_inst, 0, rval64));
  16128         }
  16129     }
  16130 
  16131     /* Update oversubscription buffer manager (OBM) */
  16132     bindex = -1;
  16133     for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
  16134         block_info_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, i);
  16135         if (SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_PGW_CL) {
  16136             bindex = SOC_PORT_IDX_BINDEX(unit, phy_port_base, i);
  16137             break;
  16138         }
  16139     }
  16140     reg = td2_pgw_obm_ctrl_regs[bindex / _TD2_XLPS_PER_PGW];
  16141     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port_base, 0, &rval64));
  16142     if (soc_reg64_field32_get(unit, reg, rval64,
  16143                               td2_pgw_obm_oversub_fields[bindex & 3])) {
  16144         /* The device does not support OBM bypass while operating in OS mode
  16145          * on a 10GbE/20GbE */
  16146         fval = (lanes_ctrl->lanes == 4) ? 1 : 0;
  16147         for (index = 0; index < _TD2_PORTS_PER_XLP; index++) {
  16148             soc_reg64_field32_set(unit, reg, &rval64,
  16149                                   td2_pgw_obm_bypass_fields[index], fval);
  16150         }
  16151         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port_base, 0, rval64));
  16152     }
  16153 
  16154     /* Construct new and old MMU port list for calendar replacement */
  16155     mmu_port_base = si->port_p2m_mapping[phy_port_base];
  16156     ids[0] = cur_ids[0] = mmu_port_base & 0x3f;
  16157     ids_len = cur_ids_len = 1;
  16158     if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) {
  16159         /* port(s) to be removed */
  16160         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16161             cur_ids[1 + i] =
  16162                 si->port_p2m_mapping[lanes_ctrl->phy_ports[i]] & 0x3f;
  16163         }
  16164         cur_ids_len += lanes_ctrl->phy_ports_len;
  16165     } else { /* port(s) to be added */
  16166         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16167             ids[1 + i] = si->port_p2m_mapping[lanes_ctrl->phy_ports[i]] & 0x3f;
  16168         }
  16169         ids_len += lanes_ctrl->phy_ports_len;
  16170     }
  16171 
  16172     /* Update MMU TDM */
  16173     pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port_base) ? 1 : 0;
  16174     reg = mmu_tdm_regs[pipe];
  16175     mem = mmu_tdm_mems[pipe];
  16176     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  16177     slot_len = (soc_reg_field_get(unit, reg, rval, CAL0_ENDf) + 1) * 2;
  16178     slot_len -= soc_reg_field_get(unit, reg, rval, CAL0_END_SINGLEf);
  16179     seq = 0;
  16180     for (slot = 0; slot < slot_len; slot += 2) {
  16181         count = 0;
  16182         SOC_IF_ERROR_RETURN
  16183             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, slot / 2, entry));
  16184         for (index = 0; index < 2; index++) {
  16185             if (slot + index >= slot_len){
  16186                 break;
  16187             }
  16188             field = mmu_tdm_fields[index];
  16189             fval = soc_mem_field32_get(unit, mem, entry, field);
  16190             for (i = 0; i < cur_ids_len; i++) {
  16191                 if (fval == cur_ids[i]) {
  16192                     break;
  16193                 }
  16194             }
  16195             if (i == cur_ids_len) { /* no match found */
  16196                 continue;
  16197             }
  16198             if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  16199                 LOG_CLI((BSL_META_U(unit,
  16200                                     "set MMU pipe %d TDM slot %d from %d to %d\n"),
  16201                          pipe, slot + index, fval, ids[seq % ids_len]));
  16202             }
  16203             if (i != 0 || (seq % ids_len) != 0) {
  16204                 soc_mem_field32_set(unit, mem, entry, field,
  16205                                     ids[seq % ids_len]);
  16206                 count++;
  16207             }
  16208             seq++;
  16209         }
  16210         if (count > 0) {
  16211             SOC_IF_ERROR_RETURN
  16212                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot / 2, entry));
  16213         }
  16214     }
  16215 
  16216     if (lanes_ctrl->oversub) {
  16217         if (lanes_ctrl->slot == -1) { /* new group */
  16218             reg = mmu_ovs_group_wt_regs[pipe][lanes_ctrl->group];
  16219             rval = 0;
  16220             for (index = 0; index < _MMU_OVS_GROUP_TDM_LENGTH; index++) {
  16221                 soc_reg_field_set(unit, reg, &rval, WEIGHTf,
  16222                                   lanes_ctrl->weight * (index + 1));
  16223                 SOC_IF_ERROR_RETURN
  16224                     (soc_reg32_set(unit, reg, REG_PORT_ANY, index, rval));
  16225             }
  16226             lanes_ctrl->slot = 0;
  16227         }
  16228         if (lanes_ctrl->cur_empty) { /* last entry of the current group */
  16229             reg = mmu_ovs_group_wt_regs[pipe][lanes_ctrl->cur_group];
  16230             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0));
  16231         }
  16232         /* Add into new group */
  16233         reg = mmu_ovs_group_regs[pipe][lanes_ctrl->group];
  16234         count = _MMU_OVS_GROUP_TDM_LENGTH /
  16235             (_TD2_PORTS_PER_XLP / lanes_ctrl->lanes);
  16236         rval = 0;
  16237         if (!SOC_IS_TD2P_TT2P(unit)) {
  16238             soc_reg_field_set(unit, reg, &rval, PHY_PORT_IDf,
  16239                           si->port_serdes[port_base] & 0xf);
  16240         }
  16241         for (i = 0; i < ids_len; i++) {
  16242             soc_reg_field_set(unit, reg, &rval, MMU_PORTf, ids[i]);
  16243             SOC_IF_ERROR_RETURN
  16244                 (soc_reg32_set(unit, reg, REG_PORT_ANY,
  16245                                lanes_ctrl->slot + i * count, rval));
  16246         }
  16247         /* Remove from current group */
  16248         reg = mmu_ovs_group_regs[pipe][lanes_ctrl->cur_group];
  16249         count = _MMU_OVS_GROUP_TDM_LENGTH /
  16250             (_TD2_PORTS_PER_XLP / lanes_ctrl->cur_lanes);
  16251         rval = 0;
  16252         for (i = 0; i < cur_ids_len; i++) {
  16253             soc_reg_field_set(unit, reg, &rval, MMU_PORTf, 0x3f);
  16254             SOC_IF_ERROR_RETURN
  16255                 (soc_reg32_set(unit, reg, REG_PORT_ANY,
  16256                                lanes_ctrl->cur_slot + i * count, rval));
  16257         }
  16258     }
  16259 
  16260     return SOC_E_NONE;
  16261 }
  16262 
  16263 /*
  16264  * Function:
  16265  *      _soc_trident2_port_mode_to_portmod
  16266  * Description:
  16267  *      Convert TD2/HW port mode value to Portmod port mode
  16268  * Parameters:
  16269  *      hw_mode - TD2 port mode. SOC_TD2_PORT_MODE_XXX
  16270  *      portmod_mode - (OUT) Portmod port mode. portmodPortModeXXX
  16271  */
  16272 STATIC int
  16273 _soc_trident2_port_mode_to_portmod(int hw_mode, int *portmod_mode)
  16274 {
  16275 #ifdef PORTMOD_SUPPORT
  16276     switch (hw_mode) {
  16277         case SOC_TD2_PORT_MODE_QUAD:
  16278             *portmod_mode = portmodPortModeQuad;
  16279             break;
  16280         case SOC_TD2_PORT_MODE_TRI_012:
  16281             *portmod_mode = portmodPortModeTri012;
  16282             break;
  16283         case SOC_TD2_PORT_MODE_TRI_023:
  16284             *portmod_mode = portmodPortModeTri023;
  16285             break;
  16286         case SOC_TD2_PORT_MODE_DUAL:
  16287             *portmod_mode = portmodPortModeDual;
  16288             break;
  16289         case SOC_TD2_PORT_MODE_SINGLE:
  16290             *portmod_mode = portmodPortModeSingle;
  16291             break;
  16292         default:
  16293             return SOC_E_FAIL;
  16294     }
  16295 
  16296     return SOC_E_NONE;
  16297 
  16298 #else  /* PORTMOD_SUPPORT */
  16299     return SOC_E_UNAVAIL;
  16300 #endif /* PORTMOD_SUPPORT */
  16301 }
  16302 
  16303 /*
  16304  * Function:
  16305  *      _soc_trident2_port_mode_from_portmod
  16306  * Description:
  16307  *      Convert Portmod port mode to TD2/HW port mode value
  16308  * Parameters:
  16309  *      portmod_mode - Portmod port mode. portmodPortModeXXX
  16310  *      hw_mode - (OUT) TD2 port mode. SOC_TD2_PORT_MODE_XXX
  16311  */
  16312 STATIC int
  16313 _soc_trident2_port_mode_from_portmod(int portmod_mode, int *hw_mode)
  16314 {
  16315 #ifdef PORTMOD_SUPPORT
  16316     switch (portmod_mode) {
  16317         case portmodPortModeQuad:
  16318             *hw_mode = SOC_TD2_PORT_MODE_QUAD;
  16319             break;
  16320         case portmodPortModeTri012:
  16321             *hw_mode = SOC_TD2_PORT_MODE_TRI_012;
  16322             break;
  16323         case portmodPortModeTri023:
  16324             *hw_mode = SOC_TD2_PORT_MODE_TRI_023;
  16325             break;
  16326         case portmodPortModeDual:
  16327             *hw_mode = SOC_TD2_PORT_MODE_DUAL;
  16328             break;
  16329         case portmodPortModeSingle:
  16330             *hw_mode = SOC_TD2_PORT_MODE_SINGLE;
  16331             break;
  16332         default:
  16333             return SOC_E_FAIL;
  16334     }
  16335 
  16336     return SOC_E_NONE;
  16337 
  16338 #else  /* PORTMOD_SUPPORT */
  16339     return SOC_E_UNAVAIL;
  16340 #endif /* PORTMOD_SUPPORT */
  16341 }
  16342 
  16343 /*
  16344  * Function:
  16345  *      soc_trident2_port_lanes_validate
  16346  * Description:
  16347  *      Validate if the specified number of lanes can be configured on a port,
  16348  *      If the request can be done, fill in the control structure which will
  16349  *      be used by the routines programming the hardware.
  16350  * Parameters:
  16351  *      unit          - Device number
  16352  *      lanes_ctrl    - Control structure
  16353  *
  16354  * Each TSC can be configured into following 5 mode:
  16355  *   Lane number    0    1    2    3
  16356  *   ------------  ---  ---  ---  ---
  16357  *    single port  40G   x    x    x
  16358  *      dual port  20G   x   20G   x
  16359  *   tri_023 port  20G   x   10G  10G
  16360  *   tri_012 port  10G  10G  20G   x
  16361  *      quad port  10G  10G  10G  10G
  16362  *
  16363  *          lanes                mode         valid lane index
  16364  *       ------------      ----------------   ----------------
  16365  *       new  current        new    current
  16366  *       ---  -------      -------  -------
  16367  * #1     4      1         single    quad            0
  16368  * #2     4      1         single   tri_012          0
  16369  * #3     4      2         single   tri_023          0
  16370  * #4     4      2         single    dual            0
  16371  * #5     2      1         tri_023   quad            0
  16372  * #6     2      1         tri_012   quad            2
  16373  * #7     2      1          dual    tri_023          2
  16374  * #8     2      1          dual    tri_012          0
  16375  * #9     2      4          dual    single           0
  16376  * #10    1      2         tri_023   dual            2
  16377  * #11    1      2         tri_012   dual            0
  16378  * #12    1      2          quad    tri_023          0
  16379  * #13    1      2          quad    tri_012          2
  16380  * #14    1      4          quad    single           0
  16381  * Following mode change requires 2 transition
  16382  *   - from single to tri_023: #9 + #10
  16383  *   - from single to tri_012: #9 + #11
  16384  * Following mode change are the result of lane change on multiple ports
  16385  *   - from quad to dual: #12 + #7 or #13 + #8
  16386  *   - from dual to quad: #10 + #12 or #11 + # 13
  16387  *   - from tri_023 to tri_012: #7 + #11 or #12 + #6
  16388  *   - from tri_012 to tri_023: #8 + #10 or #13 + #5
  16389  *
  16390  * Logical port number will stay the same after conversion, for example
  16391  *     converting single port to dual port, the logical port number of lane 0
  16392  *     will be changed.
  16393  */
  16394 int
  16395 soc_trident2_port_lanes_validate(int unit, soc_td2_port_lanes_t *lanes_ctrl)
  16396 {
  16397     soc_info_t *si = &SOC_INFO(unit);
  16398     soc_reg_t reg;
  16399     int port_base, phy_port_base, mmu_port_base, id, i;
  16400     int block_info_idx;
  16401     uint32 rval, fval;
  16402     int subport0, phy_subport0;
  16403     int pipe, group, slot, count;
  16404     int speed_max, cur_speed_max;
  16405     int wt_group = 0;
  16406     int osg_bitmap;
  16407     int port_mode;
  16408 
  16409     /* Trident2+ has different registers so pointer will be changed later */
  16410     mmu_ovs_group_wt_regs_t mmu_ovs_group_wt_regs = mmu_ovs_group_wt_regs_local;
  16411 
  16412 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  16413     mmu_ovs_group_wt_regs = get_mmu_ovs_group_wt_regs ( unit, mmu_ovs_group_wt_regs );
  16414 #endif
  16415 
  16416     /* Find physical and mmu port number for the specified port */
  16417     port_base = lanes_ctrl->port_base;
  16418     phy_port_base = si->port_l2p_mapping[port_base];
  16419     if (phy_port_base == -1) {
  16420         return SOC_E_PORT;
  16421     }
  16422     lanes_ctrl->oversub = SOC_PBMP_MEMBER(si->oversub_pbm, port_base);
  16423 
  16424     if (lanes_ctrl->oversub && lanes_ctrl->lanes == 2) {
  16425         if (!soc_property_get(unit, spn_20G_OVERSUB_PORT_FLEXPORT_ENABLE, 0)) {
  16426             /* Does not allow doing flex port to 2 lanes on oversub */
  16427             return SOC_E_PARAM;
  16428         }
  16429     }
  16430 
  16431     /* Find lane index for the specified port (base port) */
  16432     for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
  16433         block_info_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, i);
  16434         if (si->port_speed_max[port_base] >= 1000000) {
  16435             if (SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_CPORT) {
  16436                 break;
  16437             }
  16438         } else {
  16439             if (SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_XLPORT) {
  16440                 break;
  16441             }
  16442         }
  16443     }
  16444     lanes_ctrl->bindex = SOC_PORT_IDX_BINDEX(unit, phy_port_base, i);
  16445 
  16446     /* Get the current mode */
  16447     if (SOC_USE_PORTCTRL(unit)) {
  16448         SOC_IF_ERROR_RETURN
  16449             (soc_portctrl_port_mode_get(unit, port_base,
  16450                                         &port_mode,
  16451                                         &lanes_ctrl->cur_lanes));
  16452         SOC_IF_ERROR_RETURN
  16453             (_soc_trident2_port_mode_from_portmod(port_mode,
  16454                                                   &lanes_ctrl->cur_mode));
  16455     } else {
  16456         SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port_base, &rval));
  16457         lanes_ctrl->cur_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  16458                                                  XPORT0_CORE_PORT_MODEf);
  16459 
  16460         /* Figure out the current number of lanes */
  16461         switch (lanes_ctrl->cur_mode) {
  16462             case SOC_TD2_PORT_MODE_QUAD:
  16463                 lanes_ctrl->cur_lanes = 1;
  16464                 break;
  16465             case SOC_TD2_PORT_MODE_TRI_012:
  16466                 lanes_ctrl->cur_lanes = lanes_ctrl->bindex == 0 ? 1 : 2;
  16467                 break;
  16468             case SOC_TD2_PORT_MODE_TRI_023:
  16469                 lanes_ctrl->cur_lanes = lanes_ctrl->bindex == 0 ? 2 : 1;
  16470                 break;
  16471             case SOC_TD2_PORT_MODE_DUAL:
  16472                 lanes_ctrl->cur_lanes = 2;
  16473                 break;
  16474             case SOC_TD2_PORT_MODE_SINGLE:
  16475                 lanes_ctrl->cur_lanes = 4;
  16476                 break;
  16477             default:
  16478                 return SOC_E_FAIL;
  16479         }
  16480     }
  16481 
  16482     /* Validate new number of lanes */
  16483     if (lanes_ctrl->lanes == 4 || lanes_ctrl->cur_lanes == 4) {
  16484         if (lanes_ctrl->bindex & 0x3) {
  16485             return SOC_E_PARAM;
  16486         }
  16487     } else if (lanes_ctrl->lanes == 2 || lanes_ctrl->cur_lanes == 2) {
  16488         if (lanes_ctrl->bindex & 0x1) {
  16489             return SOC_E_PARAM;
  16490         }
  16491     } else if (lanes_ctrl->lanes != 1) {
  16492         return SOC_E_PARAM;
  16493     }
  16494 
  16495     /* No change to number of lanes */
  16496     if (lanes_ctrl->lanes == lanes_ctrl->cur_lanes) {
  16497         return SOC_E_NONE;
  16498     }
  16499 
  16500     /* Get valid Oversub Speed Group bitmap */
  16501     osg_bitmap = si->port_osg_bitmap[phy_port_base];
  16502 
  16503     if (lanes_ctrl->oversub) {
  16504         mmu_port_base = si->port_p2m_mapping[phy_port_base];
  16505         phy_subport0 = ((phy_port_base - 1) & ~0x3) + 1;
  16506         subport0 = si->port_p2l_mapping[phy_subport0];
  16507         pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port_base) ? 1 : 0;
  16508 
  16509         /* Figure out the new speed group */
  16510         speed_max = si->port_speed_max[subport0] * lanes_ctrl->lanes /
  16511             _TD2_PORTS_PER_XLP;
  16512         lanes_ctrl->weight = (speed_max > 2500 ? speed_max : 2500) / 2500;
  16513 
  16514         /* Figure out the current speed group */
  16515         cur_speed_max = si->port_speed_max[subport0] * lanes_ctrl->cur_lanes /
  16516             _TD2_PORTS_PER_XLP;
  16517         lanes_ctrl->cur_weight =
  16518             (cur_speed_max > 2500 ? cur_speed_max : 2500) / 2500;
  16519 
  16520         lanes_ctrl->group = -1;
  16521         lanes_ctrl->slot = -1;
  16522         lanes_ctrl->cur_group = -1;
  16523         lanes_ctrl->cur_slot = -1;
  16524 
  16525         for (group = 0; group < _TD2_MMU_OVS_GROUP_COUNT ; group++) {
  16526             if (!(osg_bitmap & (0x1 << group))) {
  16527                 continue;
  16528             }
  16529             if (SOC_IS_TD2P_TT2P(unit)) {
  16530                 if ( speed_max <= 11000 ) {
  16531                     wt_group = td2p_ovs_wt_group_speed_10G;
  16532                 } else if ( speed_max <= 21000 ) {
  16533                     wt_group = td2p_ovs_wt_group_speed_20G;
  16534                 } else if ( speed_max <= 42000 ) {
  16535                     wt_group = td2p_ovs_wt_group_speed_40G;
  16536                 } else {
  16537                     wt_group = td2p_ovs_wt_group_speed_NA; /* "not" valid group */
  16538                 }
  16539             } else {
  16540                 wt_group = group;
  16541             }
  16542 
  16543             reg = mmu_ovs_group_wt_regs[pipe][wt_group];
  16544             SOC_IF_ERROR_RETURN
  16545                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  16546             fval = soc_reg_field_get(unit, reg, rval, WEIGHTf);
  16547             if (fval == 0) { /* unused group */
  16548                 if (lanes_ctrl->group == -1) {
  16549                     lanes_ctrl->group = wt_group;
  16550                 }
  16551                 continue;
  16552             } else if (fval == lanes_ctrl->weight) {
  16553                 if (lanes_ctrl->slot == -1) {
  16554                     /* Find a slot for new group */
  16555                     reg = mmu_ovs_group_regs[pipe][group];
  16556                     count = _MMU_OVS_GROUP_TDM_LENGTH /
  16557                         (_TD2_PORTS_PER_XLP / lanes_ctrl->lanes);
  16558                     for (slot = 0; slot < count; slot++) {
  16559                         SOC_IF_ERROR_RETURN
  16560                             (soc_reg32_get(unit, reg, REG_PORT_ANY, slot,
  16561                                            &rval));
  16562                         if (soc_reg_field_get(unit, reg, rval, MMU_PORTf) ==
  16563                             0x3f) {
  16564                             lanes_ctrl->group = wt_group;
  16565                             lanes_ctrl->slot = slot;
  16566                             break;
  16567                         }
  16568                     }
  16569                 }
  16570             } else if (fval == lanes_ctrl->cur_weight) {
  16571                 if (lanes_ctrl->cur_slot == -1) {
  16572                     /* Find the slot used by the currnet group */
  16573                     reg = mmu_ovs_group_regs[pipe][group];
  16574                     count = _MMU_OVS_GROUP_TDM_LENGTH /
  16575                         (_TD2_PORTS_PER_XLP / lanes_ctrl->cur_lanes);
  16576                     lanes_ctrl->cur_empty = TRUE;
  16577                     for (slot = 0; slot < count; slot++) {
  16578                         SOC_IF_ERROR_RETURN
  16579                             (soc_reg32_get(unit, reg, REG_PORT_ANY, slot,
  16580                                            &rval));
  16581                         id = soc_reg_field_get(unit, reg, rval, MMU_PORTf);
  16582                         if (id == (mmu_port_base & 0x3f)) {
  16583                             lanes_ctrl->cur_group = group;
  16584                             lanes_ctrl->cur_slot = slot;
  16585                         } else if (id != 0x3f) {
  16586                             lanes_ctrl->cur_empty = FALSE;
  16587                         }
  16588                         if (lanes_ctrl->cur_slot != -1 &&
  16589                             !lanes_ctrl->cur_empty) {
  16590                             break;
  16591                         }
  16592                     }
  16593                 }
  16594             }
  16595             if (lanes_ctrl->slot != -1 && lanes_ctrl->cur_slot != -1) {
  16596                 break;
  16597             }
  16598         }
  16599 
  16600         if (lanes_ctrl->cur_group == -1) {
  16601             return SOC_E_CONFIG;
  16602         }
  16603 
  16604         if (lanes_ctrl->group == -1) {
  16605             return SOC_E_FULL;
  16606         }
  16607     }
  16608 
  16609     /* Figure out new mode */
  16610     if (lanes_ctrl->lanes == 4) {
  16611         lanes_ctrl->mode = SOC_TD2_PORT_MODE_SINGLE;
  16612     } else if (lanes_ctrl->lanes == 2) {
  16613         if (lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_QUAD) {
  16614             lanes_ctrl->mode = lanes_ctrl->bindex == 0 ?
  16615                 SOC_TD2_PORT_MODE_TRI_023 : SOC_TD2_PORT_MODE_TRI_012;
  16616         } else {
  16617             lanes_ctrl->mode = SOC_TD2_PORT_MODE_DUAL;
  16618         }
  16619     } else{
  16620         if (lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_DUAL) {
  16621             lanes_ctrl->mode = lanes_ctrl->bindex == 0 ?
  16622                 SOC_TD2_PORT_MODE_TRI_012 : SOC_TD2_PORT_MODE_TRI_023;
  16623         } else {
  16624             lanes_ctrl->mode = SOC_TD2_PORT_MODE_QUAD;
  16625         }
  16626     }
  16627 
  16628     lanes_ctrl->phy_ports_len = 0;
  16629     if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) {
  16630         /* Figure out which port(s) to be removed */
  16631         if (lanes_ctrl->lanes == 4) {
  16632             if (lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_TRI_012 ||
  16633                 lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_QUAD) {
  16634                 if (si->port_p2l_mapping[phy_port_base + 1] != -1) {
  16635                     lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16636                         phy_port_base + 1;
  16637                 }
  16638             }
  16639             if (si->port_p2l_mapping[phy_port_base + 2] != -1) {
  16640                 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16641                                       phy_port_base + 2;
  16642             }
  16643             if (lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_TRI_023 ||
  16644                 lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_QUAD) {
  16645                 if (si->port_p2l_mapping[phy_port_base + 3] != -1) {
  16646                     lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16647                         phy_port_base + 3;
  16648                 }
  16649             }
  16650         } else {
  16651             if (si->port_p2l_mapping[phy_port_base + 1] != -1) {
  16652                 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16653                                       phy_port_base + 1;
  16654             }
  16655         }
  16656     } else { /* Figure out which port(s) to be added */
  16657         if (lanes_ctrl->lanes == 2) {
  16658             if (si->port_p2l_mapping[phy_port_base + 2] != -1) {
  16659                 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16660                                       phy_port_base + 2;
  16661             }
  16662         } else {
  16663             if (si->port_p2l_mapping[phy_port_base + 1] != -1) {
  16664                 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16665                     phy_port_base + 1;
  16666             }
  16667             if (lanes_ctrl->cur_mode == SOC_TD2_PORT_MODE_SINGLE) {
  16668                 if (si->port_p2l_mapping[phy_port_base + 2] != -1) {
  16669                     lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16670                         phy_port_base + 2;
  16671                 }
  16672                 if (si->port_p2l_mapping[phy_port_base + 3] != -1) {
  16673                     lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] =
  16674                         phy_port_base + 3;
  16675                 }
  16676             }
  16677         }
  16678     }
  16679 
  16680     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
  16681         static char *mode_name[] = {
  16682             "QUAD", "TRI_012", "TRI_023", "DUAL", "SINGLE"
  16683         };
  16684         LOG_CLI((BSL_META_U(unit,
  16685                             "port %d physical port %d bindex %d OSG 0x%x\n"),
  16686                  port_base, phy_port_base, lanes_ctrl->bindex, osg_bitmap));
  16687         LOG_CLI((BSL_META_U(unit,
  16688                             "  mode (new:%s cur:%s) lanes (new:%d cur:%d)\n"),
  16689                  mode_name[lanes_ctrl->mode],
  16690                  mode_name[lanes_ctrl->cur_mode],
  16691                  lanes_ctrl->lanes, lanes_ctrl->cur_lanes));
  16692         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16693             LOG_CLI((BSL_META_U(unit,
  16694                                 "  %s physical port %d (port %d)\n"),
  16695                      lanes_ctrl->lanes > lanes_ctrl->cur_lanes ?
  16696                      "del" : "add",
  16697                      lanes_ctrl->phy_ports[i],
  16698                      si->port_p2l_mapping[lanes_ctrl->phy_ports[i]]));
  16699         }
  16700         if (lanes_ctrl->group != -1) {
  16701             LOG_CLI((BSL_META_U(unit,
  16702                                 "new group %d slot %d\n"),
  16703                      lanes_ctrl->group, lanes_ctrl->slot));
  16704         }
  16705         LOG_CLI((BSL_META_U(unit,
  16706                             "cur group %d slot %d\n"),
  16707                  lanes_ctrl->cur_group, lanes_ctrl->cur_slot));
  16708     }
  16709 
  16710     return SOC_E_NONE;
  16711 }
  16712 
  16713 STATIC int
  16714 _soc_trident2_port_icc_width_update(int unit, soc_td2_port_lanes_t *lanes_ctrl)
  16715 {
  16716     int num_lanes;
  16717     int count_width = 0;
  16718     int port;
  16719 
  16720     if (!soc_feature(unit, soc_feature_static_repl_head_alloc)) {
  16721         if (SOC_REG_IS_VALID(unit, PORT_INITIAL_COPY_COUNT_WIDTHr)) {
  16722             port = lanes_ctrl->port_base;
  16723             if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) {
  16724                 num_lanes = lanes_ctrl->lanes;
  16725                 switch (num_lanes) {
  16726                     case 1: count_width = 1;
  16727                             break;
  16728                     case 2: count_width = 2;
  16729                             break;
  16730                     case 4: count_width = 3;
  16731                             break;
  16732                     default: count_width = 0;
  16733                              break;
  16734                 }
  16735             }
  16736             if (SOC_REG_FIELD_VALID(unit, PORT_INITIAL_COPY_COUNT_WIDTHr,
  16737                     BIT_WIDTHf)) {
  16738                 SOC_IF_ERROR_RETURN(
  16739                     soc_reg_field32_modify(unit, PORT_INITIAL_COPY_COUNT_WIDTHr,
  16740                         port, BIT_WIDTHf, count_width ? (count_width - 1) : 0));
  16741             }
  16742         }
  16743     }
  16744 
  16745     return SOC_E_NONE;
  16746 }
  16747 
  16748 /*
  16749  * Function:
  16750  *      soc_trident2_port_lanes_set
  16751  * Description:
  16752  *      Configure number of lanes used by a port
  16753  * Parameters:
  16754  *      unit          - Device number
  16755  *      lanes_ctrl    - Control structure
  16756  * Notes: Caller needs to call soc_trident2_port_lanes_validate to fill
  16757  *        in the control structure.
  16758  */
  16759 int
  16760 soc_trident2_port_lanes_set(int unit, soc_td2_port_lanes_t *lanes_ctrl)
  16761 {
  16762     int rv;
  16763     soc_info_t *si = &SOC_INFO(unit);
  16764     soc_reg_t reg;
  16765     soc_field_t fields[2];
  16766     uint32 values[2];
  16767     int pipe, port_base, phy_port_base, port, mmu_port, i;
  16768     uint32 rval;
  16769     int port_mode;
  16770     egr_enable_entry_t entry;
  16771     uint32 egress_per_port_buffer_entry[SOC_MAX_MEM_WORDS];
  16772     static soc_reg_t mmu_port_credit_regs[] = {
  16773         ES_PIPE0_MMU_PORT_CREDITr, ES_PIPE1_MMU_PORT_CREDITr
  16774     };
  16775     static soc_reg_t egr_reset_regs[] = {
  16776         EGR_XLPORT_BUFFER_SFT_RESET_0_Xr, EGR_XLPORT_BUFFER_SFT_RESET_1_Xr,
  16777         EGR_XLPORT_BUFFER_SFT_RESET_0_Yr, EGR_XLPORT_BUFFER_SFT_RESET_1_Yr
  16778     };
  16779     static soc_field_t egr_reset_fields[] = {
  16780         XLP0_RESETf, XLP1_RESETf, XLP2_RESETf, XLP3_RESETf,
  16781         XLP4_RESETf, XLP5_RESETf, XLP6_RESETf, XLP7_RESETf,
  16782         XLP8_RESETf, XLP9_RESETf, XLP10_RESETf, XLP11_RESETf,
  16783         XLP12_RESETf, XLP13_RESETf, XLP14_RESETf, XLP15_RESETf
  16784     };
  16785 
  16786     /* Find physical port number and lane index of the specified port */
  16787     port_base = lanes_ctrl->port_base;
  16788     phy_port_base = si->port_l2p_mapping[port_base];
  16789     if (phy_port_base == -1) {
  16790         return SOC_E_PORT;
  16791     }
  16792     pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port_base) ? 1 : 0;
  16793 
  16794     /* Update soc_control information */
  16795     SOC_CONTROL_LOCK(unit);
  16796     if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) {
  16797         /* port(s) to be removed */
  16798         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16799             port = si->port_p2l_mapping[lanes_ctrl->phy_ports[i]];
  16800             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port);
  16801         }
  16802     } else { /* port(s) to be added */
  16803         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16804             port = si->port_p2l_mapping[lanes_ctrl->phy_ports[i]];
  16805             SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port);
  16806         }
  16807     }
  16808 
  16809     /* Update num of lanes info which is used by SerDes driver */
  16810     SOC_PORT_NUM_LANES_SET(unit, port_base, lanes_ctrl->lanes);
  16811     for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16812         port = si->port_p2l_mapping[lanes_ctrl->phy_ports[i]];
  16813         si->port_num_lanes[port] =
  16814             lanes_ctrl->lanes > lanes_ctrl->cur_lanes ? 0 : lanes_ctrl->lanes;
  16815     }
  16816     SOC_CONTROL_UNLOCK(unit);
  16817 
  16818     /* De-assert EGR_ENABLE */
  16819     sal_memset(&entry, 0, sizeof(entry));
  16820     SOC_IF_ERROR_RETURN
  16821         (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port_base, &entry));
  16822     if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) {
  16823         /* port(s) to be removed */
  16824         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16825             SOC_IF_ERROR_RETURN
  16826                 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL,
  16827                                    lanes_ctrl->phy_ports[i], &entry));
  16828         }
  16829     }
  16830 
  16831     /* Change XLPROT mode */
  16832     if (SOC_USE_PORTCTRL(unit)) {
  16833         SOC_IF_ERROR_RETURN
  16834             (_soc_trident2_port_mode_to_portmod(lanes_ctrl->mode, &port_mode));
  16835         SOC_IF_ERROR_RETURN
  16836             (soc_portctrl_port_mode_set(unit, port_base, port_mode));
  16837     } else {
  16838         fields[0] = XPORT0_CORE_PORT_MODEf;
  16839         values[0] = lanes_ctrl->mode;
  16840         fields[1] = XPORT0_PHY_PORT_MODEf;
  16841         values[1] = lanes_ctrl->mode;
  16842         SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, XLPORT_MODE_REGr,
  16843                                                     port_base, 2, fields, values));
  16844     }
  16845 
  16846     if (lanes_ctrl->phy_ports_len > 0) {
  16847         /* Update TDM */
  16848         SOC_IF_ERROR_RETURN
  16849             (_soc_trident2_port_lanes_update_tdm(unit, lanes_ctrl));
  16850     }
  16851 
  16852     /* Clear MMU port credit before Resetting egress */
  16853     reg = mmu_port_credit_regs[pipe];
  16854     mmu_port = si->port_p2m_mapping[phy_port_base];
  16855     SOC_IF_ERROR_RETURN
  16856         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port & 0x3f, 0));
  16857     if (lanes_ctrl->lanes < lanes_ctrl->cur_lanes) { /* port(s) to be added */
  16858         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16859             mmu_port = si->port_p2m_mapping[lanes_ctrl->phy_ports[i]];
  16860             SOC_IF_ERROR_RETURN
  16861                 (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port & 0x3f, 0));
  16862         }
  16863     }
  16864 
  16865     if ((SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TITAN2PLUS(unit))) {
  16866         sal_memset(egress_per_port_buffer_entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
  16867         SOC_IF_ERROR_RETURN(
  16868                 WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  16869                     phy_port_base, egress_per_port_buffer_entry));
  16870         if (lanes_ctrl->lanes < lanes_ctrl->cur_lanes) { /* port(s) to be added */
  16871             for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16872                 SOC_IF_ERROR_RETURN(
  16873                         WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  16874                             lanes_ctrl->phy_ports[i], egress_per_port_buffer_entry));
  16875             }
  16876         }
  16877     }
  16878     else if (SOC_IS_TRIDENT2(unit)) {
  16879         /* Reset egress hardware resource */
  16880         reg = egr_reset_regs[si->port_serdes[port_base] / 8];
  16881         fields[0] = egr_reset_fields[si->port_serdes[port_base] % 16];
  16882         if (lanes_ctrl->lanes == 4 || lanes_ctrl->cur_lanes == 4) {
  16883             /* reset all 4 lanes */
  16884             values[0] = 4;
  16885         } else if (lanes_ctrl->bindex == 0) { /* reset lanes 0 and 1 */
  16886             values[0] = 1;
  16887         } else { /* reset lanes 2 and 3 */
  16888             values[0] = 2;
  16889         }
  16890         SOC_IF_ERROR_RETURN
  16891             (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  16892         soc_reg_field_set(unit, reg, &rval, fields[0], values[0]);
  16893         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
  16894         soc_reg_field_set(unit, reg, &rval, fields[0], 0);
  16895         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
  16896     }
  16897 
  16898     /* Update PORT_INITIAL_COPY_COUNT_WIDTH registers */
  16899     rv = _soc_trident2_port_icc_width_update(unit, lanes_ctrl);
  16900     if (SOC_FAILURE(rv)) {
  16901         LOG_ERROR(BSL_LS_SOC_COMMON,
  16902                   (BSL_META_U(unit,
  16903                     "Update PORT_INITIAL_COPY_COUNT_WIDTH registers fail.")));
  16904         return rv;
  16905     }
  16906 
  16907     /* Assert EGR_ENABLE */
  16908     soc_mem_field32_set(unit, EGR_ENABLEm, &entry, PRT_ENABLEf, 1);
  16909     SOC_IF_ERROR_RETURN
  16910         (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port_base, &entry));
  16911     if (lanes_ctrl->lanes < lanes_ctrl->cur_lanes) { /* port(s) to be added */
  16912         for (i = 0; i < lanes_ctrl->phy_ports_len; i++) {
  16913             SOC_IF_ERROR_RETURN
  16914                 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL,
  16915                                    lanes_ctrl->phy_ports[i], &entry));
  16916         }
  16917     }
  16918 
  16919     return SOC_E_NONE;
  16920 }
  16921 
  16922 /*
  16923  * Function:
  16924  *      soc_trident2_port_lanes_get
  16925  * Description:
  16926  *      Get number of lanes currently used by a port
  16927  * Parameters:
  16928  *      unit          - Device number
  16929  *      port_base     - Port number
  16930  *      cur_lanes     - (OUT) Number of lanes current configured on the port
  16931  */
  16932 int
  16933 soc_trident2_port_lanes_get(int unit, soc_port_t port_base, int *cur_lanes)
  16934 {
  16935     soc_info_t *si = &SOC_INFO(unit);
  16936     int cur_mode;
  16937     int phy_port_base, i;
  16938     int block_info_idx, bindex;
  16939     uint32 rval;
  16940 
  16941     /* Find physical port number and lane index of the specified port */
  16942     phy_port_base = si->port_l2p_mapping[port_base];
  16943     if (phy_port_base == -1) {
  16944         return SOC_E_PORT;
  16945     }
  16946 
  16947     bindex = -1;
  16948     for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
  16949         block_info_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, i);
  16950         if (si->port_speed_max[port_base] >= 1000000) {
  16951             if (SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_CPORT) {
  16952                 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port_base, i);
  16953                 break;
  16954             }
  16955         } else {
  16956             if (SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_XLPORT) {
  16957                 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port_base, i);
  16958                 break;
  16959             }
  16960         }
  16961     }
  16962 
  16963     /* Get the current mode */
  16964     if (SOC_USE_PORTCTRL(unit)) {
  16965         SOC_IF_ERROR_RETURN
  16966             (soc_portctrl_port_mode_get(unit, port_base,
  16967                                         &cur_mode,
  16968                                         cur_lanes));
  16969     } else {
  16970         SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port_base, &rval));
  16971         cur_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  16972                                      XPORT0_CORE_PORT_MODEf);
  16973 
  16974         /* Figure out the current number of lane from current mode */
  16975         switch (cur_mode) {
  16976             case SOC_TD2_PORT_MODE_QUAD:
  16977                 *cur_lanes = 1;
  16978                 break;
  16979             case SOC_TD2_PORT_MODE_TRI_012:
  16980                 *cur_lanes = bindex == 0 ? 1 : 2;
  16981                 break;
  16982             case SOC_TD2_PORT_MODE_TRI_023:
  16983                 *cur_lanes = bindex == 0 ? 2 : 1;
  16984                 break;
  16985             case SOC_TD2_PORT_MODE_DUAL:
  16986                 *cur_lanes = 2;
  16987                 break;
  16988             case SOC_TD2_PORT_MODE_SINGLE:
  16989                 *cur_lanes = 4;
  16990                 break;
  16991             default:
  16992                 return SOC_E_FAIL;
  16993         }
  16994     }
  16995 
  16996 #ifdef BCM_TOMAHAWK_SUPPORT
  16997     if (SOC_IS_TOMAHAWK(unit)) {
  16998         if (BCM_PBMP_MEMBER(si->management_pbm, port_base)) {
  16999             *cur_lanes = SOC_INFO(unit).port_num_lanes[port_base];
  17000         }
  17001     }
  17002 #endif
  17003 
  17004     return SOC_E_NONE;
  17005 }
  17006 
  17007 static const soc_reg_t pvtmon_result_reg[] = {
  17008     TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r,
  17009     TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r,
  17010     TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r,
  17011     TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r,
  17012     TOP_PVTMON_RESULT_8r
  17013 };
  17014 
  17015 int
  17016 soc_trident2_temperature_monitor_get(int unit,
  17017             int temperature_max,
  17018             soc_switch_temperature_monitor_t *temperature_array,
  17019             int *temperature_count)
  17020 {
  17021     soc_reg_t reg;
  17022     int index;
  17023     uint32 rval;
  17024     int fval, cur, peak;
  17025     int num_entries_out;
  17026     soc_field_t pvtmon_field_data = TEMP_DATAf;
  17027     soc_field_t pvtmon_field_peak = PEAK_TEMP_DATAf;
  17028     soc_field_t top_soft_rst_field = TOP_TEMP_MON_PEAK_RST_Lf;
  17029     int max_value = 4100000;
  17030     int mult = 5424;
  17031 
  17032 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17033     if (SOC_IS_TD2P_TT2P(unit)) {
  17034         pvtmon_field_data = PVT_DATAf;
  17035         pvtmon_field_peak = MIN_PVT_DATAf;
  17036         top_soft_rst_field = TOP_PVT_MON_MIN_RST_Lf;
  17037 
  17038         SOC_IF_ERROR_RETURN
  17039             (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_SW_CONTROLSr,
  17040                 REG_PORT_ANY, SW_TAKEOVERf, 1));
  17041 
  17042         SOC_IF_ERROR_RETURN
  17043             (soc_reg_field32_modify(unit,
  17044                 AVS_REG_PVT_MNTR_CONFIG_PVT_MNTR_TP_MODE_ENABLEr,
  17045                 REG_PORT_ANY, TP_MODE_ENf, 1));
  17046         max_value = 4100400;
  17047         mult = 4870;
  17048     }
  17049 #endif
  17050 
  17051     if (temperature_count) {
  17052         *temperature_count = 0;
  17053     }
  17054     if (COUNTOF(pvtmon_result_reg) > temperature_max) {
  17055         num_entries_out = temperature_max;
  17056     } else {
  17057         num_entries_out = COUNTOF(pvtmon_result_reg);
  17058     }
  17059     SOC_IF_ERROR_RETURN
  17060         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  17061                                 PVTMON_SELECTf, 0));
  17062 
  17063 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17064     if (SOC_IS_TD2P_TT2P(unit)) {
  17065         SOC_IF_ERROR_RETURN
  17066             (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  17067                 PVTMON_ADC_RESETBf, 1));
  17068         SOC_IF_ERROR_RETURN
  17069             (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  17070                 PVTMON_ADC_RESETBf, 0));
  17071         SOC_IF_ERROR_RETURN
  17072             (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  17073                 PVTMON_ADC_RESETBf, 1));
  17074 
  17075         SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  17076         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17077                   TOP_PVT_MON_MAX_RST_Lf, 1);
  17078         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17079                   TOP_PVT_MON_MIN_RST_Lf, 1);
  17080         SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  17081 
  17082         SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  17083         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17084                   TOP_PVT_MON_MAX_RST_Lf, 0);
  17085         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17086                   TOP_PVT_MON_MIN_RST_Lf, 0);
  17087         SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  17088 
  17089         SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  17090         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17091                   TOP_PVT_MON_MAX_RST_Lf, 1);
  17092         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17093                   TOP_PVT_MON_MIN_RST_Lf, 1);
  17094         SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  17095     }
  17096 #endif
  17097 
  17098     sal_usleep(1000);
  17099 
  17100     for (index = 0; index < num_entries_out; index++) {
  17101         peak = 0;
  17102         cur = 0;
  17103         reg = pvtmon_result_reg[index];
  17104         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  17105 
  17106         fval = soc_reg_field_get(unit, reg, rval, pvtmon_field_data);
  17107         cur = (max_value - (mult * fval)) / 1000;
  17108         fval = soc_reg_field_get(unit, reg, rval, pvtmon_field_peak);
  17109         peak = (max_value - (mult * fval)) / 1000;
  17110         if (temperature_array) {
  17111             (temperature_array + index)->curr = cur;
  17112             (temperature_array + index)->peak = peak;
  17113         }
  17114     }
  17115 
  17116     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  17117     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17118                   top_soft_rst_field, 0);
  17119     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  17120     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  17121                   top_soft_rst_field, 1);
  17122     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  17123 
  17124 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17125     if (SOC_IS_TD2P_TT2P(unit)) {
  17126         SOC_IF_ERROR_RETURN
  17127             (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_SW_CONTROLSr,
  17128                 REG_PORT_ANY, SW_TAKEOVERf, 0));
  17129 
  17130         SOC_IF_ERROR_RETURN
  17131             (soc_reg_field32_modify(unit,
  17132                 AVS_REG_PVT_MNTR_CONFIG_PVT_MNTR_TP_MODE_ENABLEr,
  17133                 REG_PORT_ANY, TP_MODE_ENf, 0));
  17134     }
  17135 #endif
  17136     if (temperature_count) {
  17137         *temperature_count=num_entries_out;
  17138     }
  17139     return SOC_E_NONE;
  17140 }
  17141 
  17142 int
  17143 soc_trident2_show_material_process(int unit)
  17144 {
  17145     soc_reg_t reg;
  17146     int index;
  17147     uint32 rval, fval, nmos[COUNTOF(pvtmon_result_reg)], n_avg, p_avg;
  17148     soc_field_t pvtmon_field_data = TEMP_DATAf;
  17149 
  17150 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17151     if (SOC_IS_TD2P_TT2P(unit)) {
  17152         pvtmon_field_data = PVT_DATAf;
  17153     }
  17154 #endif
  17155 
  17156     READ_TOP_PVTMON_CTRL_1r(unit, &rval);
  17157     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 0);
  17158     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
  17159     sal_usleep(1000);
  17160     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RESET_Nf, 1);
  17161     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
  17162     sal_usleep(1000);
  17163 
  17164     SOC_IF_ERROR_RETURN
  17165         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  17166                                 PVTMON_SELECTf, 1));
  17167     sal_usleep(1000);
  17168 
  17169     p_avg = 0;
  17170 
  17171     /* Read NMOS information */
  17172     SOC_IF_ERROR_RETURN
  17173         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
  17174                                 MEASUREMENT_CALLIBRATIONf, 5));
  17175 
  17176     sal_usleep(1000);
  17177 
  17178     n_avg = 0;
  17179     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
  17180         reg = pvtmon_result_reg[index];
  17181         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  17182         nmos[index] = soc_reg_field_get(unit, reg, rval, pvtmon_field_data);
  17183         n_avg += nmos[index];
  17184     }
  17185 
  17186     /* Read PMOS information and print both NMOS and PMOS value */
  17187     SOC_IF_ERROR_RETURN
  17188         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
  17189                                 MEASUREMENT_CALLIBRATIONf, 7));
  17190 
  17191     sal_usleep(1000);
  17192 
  17193     p_avg = 0;
  17194     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
  17195         reg = pvtmon_result_reg[index];
  17196         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  17197         fval = soc_reg_field_get(unit, reg, rval, pvtmon_field_data);
  17198         p_avg += fval;
  17199 
  17200         LOG_CLI((BSL_META_U(unit,
  17201                             "Material process location %d: NMOS = %3d PMOS = %3d\n"),
  17202                  index, nmos[index], fval));
  17203     }
  17204 
  17205     LOG_CLI((BSL_META_U(unit,
  17206                         "Average:                     NMOS = %3d PMOS = %3d\n"),
  17207              n_avg / COUNTOF(pvtmon_result_reg),
  17208              p_avg / COUNTOF(pvtmon_result_reg)));
  17209 
  17210     return SOC_E_NONE;
  17211 }
  17212 
  17213 int
  17214 soc_trident2_show_ring_osc(int unit)
  17215 {
  17216     static const struct {
  17217         int osc_sel;
  17218         soc_field_t field0;
  17219         int value0;
  17220         soc_field_t field1;
  17221         int value1;
  17222         char *name;
  17223     } osc_tbl[] = {
  17224         { 0, OSC_0_SELf, 0, INVALIDf, -1, "IO ring 0 HVT min" },
  17225         { 0, OSC_0_SELf, 1, INVALIDf, -1, "IO ring 0 HVT mid" },
  17226         { 0, OSC_0_SELf, 2, INVALIDf, -1, "IO ring 0 HVT max" },
  17227         { 0, OSC_0_SELf, 3, INVALIDf, -1, "IO ring 0 SVT min" },
  17228         { 1, OSC_1_SELf, 0, INVALIDf, -1, "IO ring 1 HVT min" },
  17229         { 1, OSC_1_SELf, 1, INVALIDf, -1, "IO ring 1 HVT mid" },
  17230         { 1, OSC_1_SELf, 2, INVALIDf, -1, "IO ring 1 HVT max" },
  17231         { 1, OSC_1_SELf, 3, INVALIDf, -1, "IO ring 1 SVT min" },
  17232         { 2, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" },
  17233         { 2, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" },
  17234         { 3, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" },
  17235         { 3, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" },
  17236         { 4, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" },
  17237         { 5, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" },
  17238         { 6, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" },
  17239         { 7, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" },
  17240         { 8, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" },
  17241         { 9, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" },
  17242         { 10, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" },
  17243         { 11, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" },
  17244         { 12, SRAM_OSC_4_PENf, 0, SRAM_OSC_4_NENf, 1, "SRAM ring 4 NMOS" },
  17245         { 13, SRAM_OSC_4_PENf, 1, SRAM_OSC_4_NENf, 0, "SRAM ring 4 PMOS" },
  17246         { 14, SRAM_OSC_5_PENf, 0, SRAM_OSC_5_NENf, 1, "SRAM ring 5 NMOS" },
  17247         { 15, SRAM_OSC_5_PENf, 1, SRAM_OSC_5_NENf, 0, "SRAM ring 5 PMOS" },
  17248     };
  17249     soc_reg_t ctrl_reg, stat_reg;
  17250     uint32 rval, fval;
  17251     int index, core_clk, quo, rem, frac, retry;
  17252 
  17253     core_clk = SOC_INFO(unit).frequency * 1024;
  17254     ctrl_reg = TOP_RING_OSC_CTRLr;
  17255     stat_reg = TOP_OSC_COUNT_STATr;
  17256 
  17257     for (index = 0; index < COUNTOF(osc_tbl); index++) {
  17258         rval = 0;
  17259 
  17260 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17261         if (SOC_IS_TD2P_TT2P(unit)) {
  17262             if (OSC_0_SELf == osc_tbl[index].field0
  17263                 || OSC_1_SELf == osc_tbl[index].field0) {
  17264                 continue;
  17265             }
  17266         }
  17267 #endif
  17268         /*
  17269          * set OSC_CNT_RSTBf to 0 to do softreset
  17270          * set OSC_CNT_START to 0 to hold the counter until it selects
  17271          * the input signal
  17272          */
  17273         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  17274         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_ENABLEf, 1);
  17275         soc_reg_field_set(unit, ctrl_reg, &rval, IROSC_ENf, 1);
  17276         soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field0,
  17277                           osc_tbl[index].value0);
  17278         if (osc_tbl[index].field1 != INVALIDf) {
  17279             soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field1,
  17280                               osc_tbl[index].value1);
  17281         }
  17282         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_SELf,
  17283                           osc_tbl[index].osc_sel);
  17284         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  17285         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_RSTBf, 1);
  17286         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  17287         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_STARTf, 1);
  17288         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  17289 
  17290         for (retry = 0; retry < 10; retry++) {
  17291             sal_usleep(1000);
  17292             SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval));
  17293             if (!soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_DONEf)) {
  17294                 continue;
  17295             }
  17296 
  17297             fval = soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_VALUEf);
  17298             quo = core_clk / fval;
  17299             rem = core_clk - quo * fval;
  17300             frac = (rem * 10000) / fval;
  17301             LOG_CLI((BSL_META_U(unit,
  17302                                 "%s: %d.%04d Mhz\n"),
  17303                      osc_tbl[index].name, quo, frac));
  17304             break;
  17305         }
  17306     }
  17307 
  17308     return SOC_E_NONE;
  17309 }
  17310 
  17311 void
  17312 soc_td2_process_func_intr(void *unit_vp, void *d1, void *d2, void *d3, void *d4)
  17313 {
  17314     int unit = PTR_TO_INT(unit_vp);
  17315     uint32 rval;
  17316 
  17317     if (soc_feature(unit, soc_feature_l2_overflow)) {
  17318         if (READ_IL2LU_INTR_STATUSr(unit, &rval)) {
  17319             LOG_ERROR(BSL_LS_SOC_COMMON,
  17320                       (BSL_META_U(unit,
  17321                                   "unit %d: Error reading %s reg !!\n"),
  17322                                   unit, SOC_REG_NAME(unit, IL2LU_INTR_STATUSr)));
  17323             return;
  17324         }
  17325         if (soc_reg_field_get(unit, IL2LU_INTR_STATUSr, rval, L2_LEARN_INSERT_FAILUREf)) {
  17326             soc_td2_l2_overflow_interrupt_handler(unit);
  17327         }
  17328     }
  17329     sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */
  17330 #if defined(BCM_CMICM_SUPPORT)
  17331     if (d1 != NULL) {
  17332         (void)soc_cmicm_intr1_enable(unit, PTR_TO_INT(d1));
  17333     }
  17334 #endif
  17335 }
  17336 
  17337 int
  17338 soc_td2_port_asf_speed_set(int unit, soc_port_t port, int speed)
  17339 {
  17340     uint32 asf_speed_mode;
  17341     uint32 rval;
  17342 
  17343     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  17344 
  17345 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  17346     if (SOC_IS_TD2P_TT2P(unit)) {
  17347         switch (speed) {
  17348         case 10:
  17349             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_10M_FULL;
  17350             break;
  17351         case 100:
  17352             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_100M_FULL;
  17353             break;
  17354         case 1000:
  17355             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_1000M_FULL;
  17356             break;
  17357         case 2500:
  17358             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_2500M_FULL;
  17359             break;
  17360         case 10000:
  17361             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_10000M_FULL;
  17362             break;
  17363         case 11000:
  17364             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_11000M_FULL;
  17365             break;
  17366         case 12000:
  17367             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_12000M_FULL;
  17368             break;
  17369         case 13000:
  17370             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_13000M_FULL;
  17371             break;
  17372         case 15000:
  17373             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_15000M_FULL;
  17374             break;
  17375         case 16000:
  17376             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_16000M_FULL;
  17377             break;
  17378         case 20000:
  17379             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_20000M_FULL;
  17380             break;
  17381         case 21000:
  17382             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_21000M_FULL;
  17383             break;
  17384         case 25000:
  17385             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_25000M_FULL;
  17386             break;
  17387         case 30000:
  17388             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_30000M_FULL;
  17389             break;
  17390         case 40000:
  17391             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_40000M_FULL;
  17392             break;
  17393         case 42000:
  17394             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_42000M_FULL;
  17395             break;
  17396         case 100000:
  17397             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_100000M_FULL;
  17398             break;
  17399         case 106000:
  17400             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_106000M_FULL;
  17401             break;
  17402         case 120000:
  17403             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_120000M_FULL;
  17404             break;
  17405         case 127000:
  17406             asf_speed_mode = SOC_TD2P_PORT_CT_SPEED_127000M_FULL;
  17407             break;
  17408         case 0:
  17409             return SOC_E_NONE;
  17410         default:
  17411             return SOC_E_PARAM;
  17412         }
  17413     } else
  17414 #endif
  17415     {
  17416         switch (speed) {
  17417         case 10:
  17418             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_10M_FULL;
  17419             break;
  17420         case 100:
  17421             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_100M_FULL;
  17422             break;
  17423         case 1000:
  17424             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_1000M_FULL;
  17425             break;
  17426         case 2500:
  17427             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_2500M_FULL;
  17428             break;
  17429         case 5000:
  17430             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_5000M_FULL;
  17431             break;
  17432         case 10000:
  17433             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_10000M_FULL;
  17434             break;
  17435         case 11000:
  17436             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_11000M_FULL;
  17437             break;
  17438         case 12000:
  17439             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_12000M_FULL;
  17440             break;
  17441         case 13000:
  17442             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_13000M_FULL;
  17443             break;
  17444         case 15000:
  17445             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_15000M_FULL;
  17446             break;
  17447         case 16000:
  17448             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_16000M_FULL;
  17449             break;
  17450         case 20000:
  17451             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_20000M_FULL;
  17452             break;
  17453         case 21000:
  17454             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_21000M_FULL;
  17455             break;
  17456         case 24000:
  17457         /* As 24G HG is not supported in TD2, so use 24G value of ASF_PORT_CFG
  17458          * (20 = 24Gbps (full duplex)) for HG 25G case */
  17459         case 25000:
  17460             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_24000M_FULL;
  17461             break;
  17462         case 30000:
  17463             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_30000M_FULL;
  17464             break;
  17465         case 32000:
  17466             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_32000M_FULL;
  17467             break;
  17468         case 40000:
  17469             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_40000M_FULL;
  17470             break;
  17471         case 42000:
  17472             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_42000M_FULL;
  17473             break;
  17474         case 100000:
  17475             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_100000M_FULL;
  17476             break;
  17477         case 120000:
  17478             asf_speed_mode = SOC_TD2_PORT_CT_SPEED_120000M_FULL;
  17479             break;
  17480         case 0:
  17481             return SOC_E_NONE;
  17482         default:
  17483             return SOC_E_PARAM;
  17484         }
  17485     }
  17486 
  17487     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval,
  17488                       ASF_PORT_SPEEDf, asf_speed_mode);
  17489 
  17490     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  17491     return SOC_E_NONE;
  17492 }
  17493 
  17494 int
  17495 soc_trident2_port_speed_update(int unit, soc_port_t port, int speed)
  17496 {
  17497     soc_info_t *si;
  17498     soc_reg_t reg;
  17499     soc_field_t field;
  17500     uint16 dev_id;
  17501     uint8 rev_id;
  17502     uint32 rval, fval;
  17503     uint64 rval64;
  17504     int block_info_idx;
  17505     int pipe, xlp, obm_inst, phy_port, mmu_port, index, i;
  17506     int asf_credit_thresh_lo, asf_credit_thresh_hi;
  17507     int max_quad_core_bandwidth, quad_oversub_core_bandwidth;
  17508     int quad_linerate_bandwidth, quad_oversub_bandwidth;
  17509     egr_edb_xmit_ctrl_entry_t entry;
  17510     int lossless;
  17511     int obm_setting_idx, oversub_ratio_idx;
  17512     int min_threshold, xoff_threshold, xon_threshold, xon_threshold_offset;
  17513     static const struct _obm_setting_s {
  17514         int max_threshold;
  17515         int xoff_threshold[3]; /* for oversub ratio 1.27, 1.43, and above */
  17516     } obm_settings[] = {
  17517         { _TD2_TD2_CELLS_PER_OBM / 4, { 79, 26, 37 } },      /* 10G */
  17518         { _TD2_TD2_CELLS_PER_OBM / 2, { 315, 242, 86 } },    /* 20G */
  17519         { _TD2_TD2_CELLS_PER_OBM, { 707, 584, 339 } },       /* 40G */
  17520         { _TD2_TD2_CELLS_PER_OBM }                           /* 42G */
  17521     };
  17522     static soc_reg_t asf_credit_thresh_lo_regs[] = {
  17523         ES_PIPE0_ASF_CREDIT_THRESH_LOr, ES_PIPE1_ASF_CREDIT_THRESH_LOr
  17524     };
  17525     static soc_reg_t asf_credit_thresh_hi_regs[] = {
  17526         ES_PIPE0_ASF_CREDIT_THRESH_HIr, ES_PIPE1_ASF_CREDIT_THRESH_HIr
  17527     };
  17528     static soc_field_t t2oq_fields[] = {
  17529         IS_MC_T2OQ_PORT0f, IS_MC_T2OQ_PORT1f
  17530     };
  17531 
  17532     soc_cm_get_id_otp(unit, &dev_id, &rev_id);
  17533     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 1);
  17534 
  17535     si = &SOC_INFO(unit);
  17536     phy_port = si->port_l2p_mapping[port];
  17537     mmu_port = si->port_p2m_mapping[phy_port];
  17538     pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port) ? 1 : 0;
  17539 
  17540     /* Update Edatabuf transmit start count */
  17541 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  17542     if (SOC_IS_TD2P_TT2P(unit)) {
  17543         int cut_thru_enable = FALSE;
  17544 
  17545         SOC_IF_ERROR_RETURN(soc_td2p_is_cut_thru_enabled(
  17546                                     unit, port, &cut_thru_enable));
  17547         if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) {
  17548             SOC_IF_ERROR_RETURN(soc_td2p_egr_edb_xmit_ctrl_set(
  17549                                     unit, phy_port, speed,
  17550                                     1 /*oversub*/, cut_thru_enable));
  17551         } else {
  17552             SOC_IF_ERROR_RETURN(soc_td2p_egr_edb_xmit_ctrl_set(
  17553                                     unit, phy_port, speed,
  17554                                     0 /*oversub*/, cut_thru_enable));
  17555         }
  17556     } else
  17557 #endif
  17558     {
  17559         if (si->frequency == 415 && !SOC_PBMP_MEMBER(si->oversub_pbm, port)) {
  17560             SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_EDB_XMIT_CTRLm,
  17561                                              MEM_BLOCK_ALL, phy_port, &entry));
  17562             soc_mem_field32_set(unit, EGR_EDB_XMIT_CTRLm, &entry, START_CNTf,
  17563                     _TD2_MMU_XMIT_START_CNT_LINERATE(speed));
  17564             SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_EDB_XMIT_CTRLm,
  17565                                               MEM_BLOCK_ALL, phy_port, &entry));
  17566         }
  17567     }
  17568 
  17569     /* Updtae VBS (HSP) port multicast T2OQ setting */
  17570     if (SOC_PBMP_MEMBER(si->eq_pbm, port) && si->frequency < 500) {
  17571         SOC_IF_ERROR_RETURN
  17572             (soc_reg32_get(unit, TOQ_MC_CFG1r, REG_PORT_ANY, 0, &rval));
  17573         field = t2oq_fields[pipe];
  17574         fval = soc_reg_field_get(unit, TOQ_MC_CFG1r, rval, field);
  17575         if (speed >= 30000) {
  17576             fval |= 1 << (mmu_port & 0x3f);
  17577         } else {
  17578             fval &= ~(1 << (mmu_port & 0x3f));
  17579         }
  17580         soc_reg_field_set(unit, TOQ_MC_CFG1r, &rval, field, fval);
  17581         SOC_IF_ERROR_RETURN
  17582             (soc_reg32_set(unit, TOQ_MC_CFG1r, REG_PORT_ANY, 0, rval));
  17583 
  17584         /* write 0 to Q_NOT_EMPTY field of sister entry locations in MMU_MCQDBx */
  17585         if (speed < 30000) {
  17586             int base;
  17587             int cosq;
  17588             int num;
  17589             mmu_mcqdb0_entry_t mcqdb0_entry;
  17590             mmu_mcqdb1_entry_t mcqdb1_entry;
  17591             base = si->port_cosq_base[port];
  17592             num = si->port_num_cosq[port];
  17593             for (index = 0; index < num; index++) {
  17594                 if (pipe == 0) {
  17595                     cosq = base + 360 + index;
  17596                     memset(&mcqdb0_entry, 0, sizeof(mcqdb0_entry));
  17597                     SOC_IF_ERROR_RETURN
  17598                         (READ_MMU_MCQDB0m(unit, MEM_BLOCK_ANY, cosq, &mcqdb0_entry));
  17599                     soc_MMU_MCQDB0m_field32_set(unit, &mcqdb0_entry, Q_NOT_EMPTYf, 0);
  17600                     SOC_IF_ERROR_RETURN
  17601                         (WRITE_MMU_MCQDB0m(unit, MEM_BLOCK_ALL, cosq, &mcqdb0_entry));
  17602                 } else {
  17603                     cosq = base - 568 + 360 + index;
  17604                     memset(&mcqdb1_entry, 0, sizeof(mcqdb1_entry));
  17605                     SOC_IF_ERROR_RETURN
  17606                         (READ_MMU_MCQDB1m(unit, MEM_BLOCK_ANY, cosq, &mcqdb1_entry));
  17607                     soc_MMU_MCQDB1m_field32_set(unit, &mcqdb1_entry, Q_NOT_EMPTYf, 0);
  17608                     SOC_IF_ERROR_RETURN
  17609                         (WRITE_MMU_MCQDB1m(unit, MEM_BLOCK_ALL, cosq, &mcqdb1_entry));
  17610                 }
  17611             }
  17612         }
  17613     }
  17614 
  17615     if (SOC_PBMP_MEMBER(si->eq_pbm, port)) {
  17616         SOC_IF_ERROR_RETURN(_soc_trident2_mc_toq_cfg(unit, port,
  17617                     (speed >= 40000) ? TRUE : FALSE));
  17618     }
  17619 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17620     if (SOC_IS_TD2P_TT2P(unit)) {
  17621        /* Update cut through credit threshold */
  17622        if (soc_td2p_use_pfc_optimized_settings(unit)) {
  17623           if (speed > 42000){
  17624               asf_credit_thresh_lo = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,100G);
  17625               asf_credit_thresh_hi = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,100G);
  17626           } else if (speed > 21000){
  17627               if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) {
  17628                   asf_credit_thresh_lo =
  17629                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED_OVERSUB(LO,40G);
  17630                   asf_credit_thresh_hi =
  17631                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED_OVERSUB(HI,40G);
  17632               } else {
  17633                   asf_credit_thresh_lo =
  17634                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,40G);
  17635                   asf_credit_thresh_hi =
  17636                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,40G);
  17637               }
  17638           } else if (speed > 11000) {
  17639               asf_credit_thresh_lo = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,20G);
  17640               asf_credit_thresh_hi = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,20G);
  17641           } else {
  17642               asf_credit_thresh_lo = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,10G);
  17643               asf_credit_thresh_hi = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,10G);
  17644           }
  17645        } else {
  17646           if (speed > 42000){
  17647               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,100G);
  17648               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,100G);
  17649           } else if (speed > 21000){
  17650               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,40G);
  17651               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,40G);
  17652           } else if (speed > 11000) {
  17653               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,20G);
  17654               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,20G);
  17655           } else {
  17656               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,10G);
  17657               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,10G);
  17658           }
  17659        }
  17660     } else
  17661 #endif
  17662     {
  17663        /* Update cut through credit threshold */
  17664        if (speed > 42000){
  17665            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,100G);
  17666            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,100G);
  17667        } else if (speed > 21000){
  17668            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,40G);
  17669            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,40G);
  17670        } else if (speed > 11000) {
  17671            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,20G);
  17672            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,20G);
  17673        } else {
  17674            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,10G);
  17675            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,10G);
  17676        }
  17677     }
  17678     reg = asf_credit_thresh_lo_regs[pipe];
  17679     rval = 0;
  17680     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_lo);
  17681     SOC_IF_ERROR_RETURN
  17682         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port & 0x3f, rval));
  17683     reg = asf_credit_thresh_hi_regs[pipe];
  17684     rval = 0;
  17685     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_hi);
  17686     SOC_IF_ERROR_RETURN
  17687         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port & 0x3f, rval));
  17688 
  17689     SOC_IF_ERROR_RETURN(soc_td2_port_asf_speed_set(unit, port, speed));
  17690 
  17691     /* Update oversubscription buffer manager (OBM) threshold */
  17692     if (!SOC_IS_TD2P_TT2P(unit) && (rev_id >= BCM56850_A2_REV_ID)) {
  17693         obm_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK;
  17694 
  17695         xlp = 0;
  17696         index = -1;
  17697         for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
  17698             block_info_idx = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
  17699             if (SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_PGW_CL) {
  17700                 xlp = SOC_PORT_IDX_BINDEX(unit, phy_port, i) /
  17701                     _TD2_PORTS_PER_XLP;
  17702                 index = SOC_PORT_IDX_BINDEX(unit, phy_port, i) %
  17703                     _TD2_PORTS_PER_XLP;
  17704                 break;
  17705             }
  17706         }
  17707 
  17708         reg = td2_pgw_obm_threshold_regs[xlp];
  17709         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, obm_inst, index, &rval64));
  17710 
  17711         {
  17712             _soc_trident2_quad_bandwidth_calculate
  17713                 (unit, si->port_group[port] / _TD2_PGWS_PER_QUAD,
  17714                  &max_quad_core_bandwidth, &quad_linerate_bandwidth,
  17715                  &quad_oversub_bandwidth);
  17716             quad_oversub_core_bandwidth =
  17717                 max_quad_core_bandwidth - quad_linerate_bandwidth;
  17718 
  17719             if (speed == 42000 && si->port_speed_max[port] > 20000) {
  17720                 obm_setting_idx = 3; /* entry 3 in the lookup table */
  17721                 xon_threshold_offset = 24; /* xon = xoff - 24 */
  17722 
  17723             } else if (speed > 20000 && si->port_speed_max[port] > 20000) {
  17724                 obm_setting_idx = 2; /* entry 2 in the lookup table */
  17725                 xon_threshold_offset = 24; /* xon = xoff - 24 */
  17726             } else if (speed > 10000 && si->port_speed_max[port] > 10000) {
  17727                 obm_setting_idx = 1; /* entry 1 in the lookup table */
  17728                 xon_threshold_offset = 12; /* xon = xoff - 12 */
  17729             } else {
  17730                 obm_setting_idx = 0; /* entry 0 in the lookup table */
  17731                 xon_threshold_offset = 6; /* xon = xoff - 6 */
  17732             }
  17733 
  17734             if (lossless) {
  17735                 if (quad_oversub_bandwidth * 2 >
  17736                     quad_oversub_core_bandwidth * 3) {
  17737                     /* oversub ratio greater than 1.5 (3/2) */
  17738                     oversub_ratio_idx = 2;
  17739                 } else if (quad_oversub_bandwidth * 3 >
  17740                     quad_oversub_core_bandwidth * 4) {
  17741                     /* oversub ratio greater than 1.33 (4/3) */
  17742                     oversub_ratio_idx = 1;
  17743                 } else {
  17744                     oversub_ratio_idx = 0;
  17745                 }
  17746 
  17747                 if (speed == 42000) {
  17748                     /* oversub ratio equal to 1.33 (4/3) */
  17749                     xoff_threshold = 632;
  17750                 } else {
  17751                     xoff_threshold = obm_settings[obm_setting_idx].
  17752                         xoff_threshold[oversub_ratio_idx];
  17753                 }
  17754 
  17755                 xon_threshold = xoff_threshold - xon_threshold_offset;
  17756                 min_threshold = xon_threshold + 3;
  17757             } else {
  17758                 xoff_threshold = 1023;
  17759                 xon_threshold = 1023;
  17760                 min_threshold = obm_settings[obm_setting_idx].
  17761                     max_threshold;
  17762             }
  17763 
  17764             soc_reg64_field32_set(unit, reg, &rval64,
  17765                                   MIN_THRESHOLDf, min_threshold);
  17766             soc_reg64_field32_set
  17767                 (unit, reg, &rval64, MAX_THRESHOLDf,
  17768                  obm_settings[obm_setting_idx].max_threshold);
  17769             soc_reg64_field32_set(unit, reg, &rval64,
  17770                                   FLOW_CTRL_XONf, xon_threshold);
  17771             soc_reg64_field32_set(unit, reg, &rval64,
  17772                                   FLOW_CTRL_XOFFf, xoff_threshold);
  17773             SOC_IF_ERROR_RETURN
  17774                 (soc_reg_set(unit, reg, obm_inst, index, rval64));
  17775         }
  17776 
  17777     }
  17778 
  17779 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17780         if (SOC_IS_TD2P_TT2P(unit)) {
  17781             SOC_IF_ERROR_RETURN(soc_td2p_mmu_delay_insertion_set (unit,
  17782                         port, speed));
  17783         }
  17784 #endif
  17785 
  17786     return SOC_E_NONE;
  17787 }
  17788 
  17789 int
  17790 soc_td2_port_asf_set(int unit, soc_port_t port, int speed)
  17791 {
  17792     soc_info_t *si;
  17793     soc_reg_t reg;
  17794     uint32 rval;
  17795     int pipe, phy_port, mmu_port;
  17796     int asf_credit_thresh_lo, asf_credit_thresh_hi;
  17797     static soc_reg_t asf_credit_thresh_lo_regs[] = {
  17798         ES_PIPE0_ASF_CREDIT_THRESH_LOr, ES_PIPE1_ASF_CREDIT_THRESH_LOr
  17799     };
  17800     static soc_reg_t asf_credit_thresh_hi_regs[] = {
  17801         ES_PIPE0_ASF_CREDIT_THRESH_HIr, ES_PIPE1_ASF_CREDIT_THRESH_HIr
  17802     };
  17803 
  17804     si = &SOC_INFO(unit);
  17805     phy_port = si->port_l2p_mapping[port];
  17806     mmu_port = si->port_p2m_mapping[phy_port];
  17807     pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port) ? 1 : 0;
  17808 
  17809 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  17810     if (SOC_IS_TD2P_TT2P(unit)) {
  17811        /* Update cut through credit threshold */
  17812        if (soc_td2p_use_pfc_optimized_settings(unit)) {
  17813           if (speed > 42000){
  17814               asf_credit_thresh_lo = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,100G);
  17815               asf_credit_thresh_hi = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,100G);
  17816           } else if (speed > 21000){
  17817               if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) {
  17818                   asf_credit_thresh_lo =
  17819                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED_OVERSUB(LO,40G);
  17820                   asf_credit_thresh_hi =
  17821                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED_OVERSUB(HI,40G);
  17822               } else {
  17823                   asf_credit_thresh_lo =
  17824                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,40G);
  17825                   asf_credit_thresh_hi =
  17826                       _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,40G);
  17827               }
  17828           } else if (speed > 11000) {
  17829               asf_credit_thresh_lo = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,20G);
  17830               asf_credit_thresh_hi = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,20G);
  17831           } else {
  17832               asf_credit_thresh_lo = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(LO,10G);
  17833               asf_credit_thresh_hi = _TD2P_MMU_ASF_CREDIT_THRESH_OPTIMIZED(HI,10G);
  17834           }
  17835        } else {
  17836           /* Update cut through credit threshold */
  17837           if (speed > 42000){
  17838               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,100G);
  17839               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,100G);
  17840           } else if (speed > 21000){
  17841               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,40G);
  17842               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,40G);
  17843           } else if (speed > 11000) {
  17844               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,20G);
  17845               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,20G);
  17846           } else {
  17847               asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,10G);
  17848               asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,10G);
  17849           }
  17850        }
  17851     } else
  17852 #endif
  17853     {
  17854        /* Update cut through credit threshold */
  17855        if (speed > 42000){
  17856            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,100G);
  17857            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,100G);
  17858        } else if (speed > 21000){
  17859            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,40G);
  17860            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,40G);
  17861        } else if (speed > 11000) {
  17862            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,20G);
  17863            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,20G);
  17864        } else {
  17865            asf_credit_thresh_lo = _TD2_MMU_ASF_CREDIT_THRESH(LO,10G);
  17866            asf_credit_thresh_hi = _TD2_MMU_ASF_CREDIT_THRESH(HI,10G);
  17867        }
  17868     }
  17869     reg = asf_credit_thresh_lo_regs[pipe];
  17870     rval = 0;
  17871     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_lo);
  17872     SOC_IF_ERROR_RETURN
  17873         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port & 0x3f, rval));
  17874     reg = asf_credit_thresh_hi_regs[pipe];
  17875     rval = 0;
  17876     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_hi);
  17877     SOC_IF_ERROR_RETURN
  17878         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port & 0x3f, rval));
  17879 
  17880     SOC_IF_ERROR_RETURN(soc_td2_port_asf_speed_set(unit, port, speed));
  17881 
  17882     return SOC_E_NONE;
  17883 }
  17884 
  17885 STATIC int
  17886 _soc_td2_thdo_hw_get(int unit, soc_port_t port, int *enable)
  17887 {
  17888     uint64 rval64;
  17889     int mmu_port, phy_port, i;
  17890     int rv = SOC_E_NONE;
  17891     soc_info_t *si;
  17892     soc_reg_t reg_tmp;
  17893     soc_reg_t reg[3][2] = {
  17894         {
  17895             THDU_OUTPUT_PORT_RX_ENABLE0_64r,
  17896             THDU_OUTPUT_PORT_RX_ENABLE1_64r
  17897         },
  17898         {
  17899             MMU_THDM_DB_PORTSP_RX_ENABLE0_64r,
  17900             MMU_THDM_DB_PORTSP_RX_ENABLE1_64r
  17901         },
  17902         {
  17903             MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r,
  17904             MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r
  17905         }
  17906     };
  17907     int max_reg = 3;
  17908 
  17909     si = &SOC_INFO(unit);
  17910 
  17911     phy_port = si->port_l2p_mapping[port];
  17912     mmu_port = si->port_p2m_mapping[phy_port];
  17913 
  17914     COMPILER_64_ZERO(rval64);
  17915 
  17916     for (i = 0; i < max_reg; i++) {
  17917         reg_tmp = SOC_TD2_PREG(unit, port, reg[i][0], reg[i][1]);
  17918 
  17919         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64));
  17920 
  17921         mmu_port &= 0x3f;
  17922         if (COMPILER_64_BITTEST(rval64 , mmu_port)) {
  17923             *enable = TRUE;
  17924         } else {
  17925             *enable = FALSE;
  17926         }
  17927     }
  17928     return rv;
  17929 }
  17930 
  17931 
  17932 STATIC int
  17933 _soc_td2_thdo_hw_set(int unit, soc_port_t port, int enable)
  17934 {
  17935     uint64 rval64, rval64_tmp;
  17936     int mmu_port, phy_port, i;
  17937     soc_info_t *si;
  17938     soc_reg_t reg_tmp;
  17939     soc_reg_t reg[3][2] = {
  17940         {
  17941             THDU_OUTPUT_PORT_RX_ENABLE0_64r,
  17942             THDU_OUTPUT_PORT_RX_ENABLE1_64r
  17943         },
  17944         {
  17945             MMU_THDM_DB_PORTSP_RX_ENABLE0_64r,
  17946             MMU_THDM_DB_PORTSP_RX_ENABLE1_64r
  17947         },
  17948         {
  17949             MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r,
  17950             MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r
  17951         }
  17952     };
  17953 
  17954     si = &SOC_INFO(unit);
  17955 
  17956     phy_port = si->port_l2p_mapping[port];
  17957     mmu_port = si->port_p2m_mapping[phy_port];
  17958 
  17959 
  17960     for (i = 0; i < 3; i++) {
  17961         COMPILER_64_ZERO(rval64);
  17962         COMPILER_64_ZERO(rval64_tmp);
  17963         reg_tmp = SOC_TD2_PREG(unit, port, reg[i][0], reg[i][1]);
  17964 
  17965         SOC_IF_ERROR_RETURN(
  17966             soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64));
  17967 
  17968         mmu_port &= 0x3f;
  17969         if (mmu_port < 32) {
  17970             COMPILER_64_SET(rval64_tmp, 0, 1 << mmu_port);
  17971         } else {
  17972             COMPILER_64_SET(rval64_tmp, 1 << (mmu_port - 32), 0);
  17973         }
  17974 
  17975         if (enable) {
  17976             COMPILER_64_OR(rval64, rval64_tmp);
  17977         } else {
  17978             COMPILER_64_NOT(rval64_tmp);
  17979             COMPILER_64_AND(rval64, rval64_tmp);
  17980         }
  17981 
  17982         SOC_IF_ERROR_RETURN(
  17983             soc_reg_set(unit, reg_tmp, REG_PORT_ANY, 0, rval64));
  17984     }
  17985 
  17986     return SOC_E_NONE;
  17987 }
  17988 
  17989 
  17990 /*
  17991  * Function:
  17992  *      _soc_td2_port_thdo_rx_enable_set
  17993  * Purpose:
  17994  *     enable/disable  the traffic to the port according to
  17995  *     different callers.
  17996  *  the traffic to the port can be enabled only if all of the callers
  17997  *  are to enable it.
  17998  * Parameters:
  17999  *     unit                - (IN) unit number
  18000  *     port                - (IN) local port
  18001  *     enable              - (IN) enable/disable the traffic to the port.
  18002  *     flag                - (IN) different callers.
  18003  * Returns:
  18004  *     BCM_E_XXX
  18005  */
  18006 STATIC int
  18007 _soc_td2_port_thdo_rx_enable_set(int unit, soc_port_t port,
  18008                                  int enable, uint8 flag)
  18009 {
  18010     int   rv = SOC_E_NONE;
  18011     uint8 *thdo_drop_bmp;
  18012     _soc_td2_mmu_traffic_ctrl_t *mmu_traffic_ctrl;
  18013     int   cur_enable = 0;
  18014 
  18015     FWD_CTRL_LOCK(unit);
  18016 
  18017     mmu_traffic_ctrl = _soc_td2_mmu_traffic_ctrl[unit];
  18018     if (mmu_traffic_ctrl ==  NULL) {
  18019         FWD_CTRL_UNLOCK(unit);
  18020         return SOC_E_INIT;
  18021     }
  18022     thdo_drop_bmp =
  18023         &(mmu_traffic_ctrl->thdo_drop_bmp[port]);
  18024 
  18025     if (!enable) {
  18026         if (*thdo_drop_bmp & flag) {
  18027             FWD_CTRL_UNLOCK(unit);
  18028             return rv;
  18029         }
  18030         if (*thdo_drop_bmp == 0) {
  18031             rv = _soc_td2_thdo_hw_set(unit, port, enable);
  18032             if (SOC_FAILURE(rv)) {
  18033                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18034                           (BSL_META_U(unit,
  18035                                       "Clear the registers fail.\n")));
  18036                 FWD_CTRL_UNLOCK(unit);
  18037                 return rv;
  18038             }
  18039         }
  18040 
  18041         *thdo_drop_bmp |= flag;
  18042 
  18043         FWD_CTRL_UNLOCK(unit);
  18044         return rv;
  18045     } else {
  18046         if (0 == *thdo_drop_bmp) {
  18047             rv = _soc_td2_thdo_hw_get(unit, port, &cur_enable);
  18048             if (SOC_FAILURE(rv)) {
  18049                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18050                           (BSL_META_U(unit,
  18051                                       "Get the registers fail.\n")));
  18052                 FWD_CTRL_UNLOCK(unit);
  18053                 return rv;
  18054             }
  18055             /* Warmboot: latest value of *thdo_drop_bmp is not sync to WB cache.
  18056             * We execute "sc controlsync=1" when one port is link up. But when we exit SDK,
  18057             * the port is link down, so the conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r
  18058             * of the port is zero.  After WarmBoot SDK,
  18059             * we can't set conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r
  18060             * for the port when it is link up, because, the value of thdo_drop_bmp is zero.
  18061             */
  18062             if(cur_enable == FALSE) {
  18063                 LOG_INFO(BSL_LS_SOC_COMMON,
  18064                           (BSL_META_U(unit,
  18065                                       "Latest thdo_drop_bmp was not updated to WB cache!!!\n")));
  18066                 *thdo_drop_bmp |= flag;
  18067             }
  18068         }
  18069         if (*thdo_drop_bmp != flag) {
  18070             /*other callers are in thdo drop*/
  18071             *thdo_drop_bmp &= ~flag;
  18072             FWD_CTRL_UNLOCK(unit);
  18073             return rv;
  18074         }
  18075 
  18076         /*Ok, only self is in thdo drop, enbable it*/
  18077         rv = _soc_td2_thdo_hw_set(unit, port, enable);
  18078         if (SOC_FAILURE(rv)) {
  18079             LOG_ERROR(BSL_LS_SOC_COMMON,
  18080                       (BSL_META_U(unit,
  18081                                   "Set the registers fail.\n")));
  18082             FWD_CTRL_UNLOCK(unit);
  18083             return rv;
  18084         }
  18085 
  18086         *thdo_drop_bmp &= ~flag;
  18087 
  18088         FWD_CTRL_UNLOCK(unit);
  18089         return rv;
  18090     }
  18091 
  18092     FWD_CTRL_UNLOCK(unit);
  18093     return rv;
  18094 }
  18095 
  18096 /*
  18097  * Function:
  18098  * soc_td2_mmu_rx_enable_set
  18099  * Purpose:
  18100  *     enable/disable mmu rx traffic from the gport.
  18101  * Parameters:
  18102  *     unit       - (IN) unit number
  18103  *     port       - (IN) PORT identifier
  18104  *     enable     - (IN) enable/disable
  18105  * Returns:
  18106  *     BCM_E_XXX
  18107  */
  18108 int
  18109 soc_td2_mmu_rx_enable_set(int unit, soc_port_t port,
  18110                           int enable)
  18111 {
  18112     uint32 rval;
  18113 
  18114     /* Disable/Enable INPUT_PORT_RX to the port */
  18115     SOC_IF_ERROR_RETURN
  18116         (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr,
  18117                        port, 0, &rval));
  18118 
  18119     if (!enable) {
  18120         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  18121                           INPUT_PORT_RX_ENABLEf,
  18122                           0);
  18123     } else {
  18124         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  18125                           INPUT_PORT_RX_ENABLEf,
  18126                           1);
  18127     }
  18128 
  18129     SOC_IF_ERROR_RETURN
  18130         (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr,
  18131                        port, 0, rval));
  18132 
  18133     return SOC_E_NONE;
  18134 }
  18135 
  18136 int
  18137 soc_td2_port_traffic_egr_enable_set(int unit, soc_port_t port,
  18138                                int enable)
  18139 {
  18140     return _soc_td2_port_thdo_rx_enable_set(unit, port, enable,
  18141                                             COSQ_SCHED_SET_CTRL);
  18142 }
  18143 
  18144 int
  18145 soc_td2_port_mmu_tx_enable_set(int unit, soc_port_t port,
  18146                                int enable)
  18147 {
  18148     return _soc_td2_port_thdo_rx_enable_set(unit, port, enable,
  18149                                            MMU_TRAFFIC_EN_CTRL);
  18150 }
  18151 
  18152 
  18153 int
  18154 soc_trident2_port_thdo_rx_enable_set(int unit, soc_port_t port,
  18155                                      int enable)
  18156 {
  18157     return _soc_td2_port_thdo_rx_enable_set(unit, port, enable,
  18158                                             MAC_ENABLE_SET_CTRL);
  18159 }
  18160 
  18161 #if defined(SER_TR_TEST_SUPPORT)
  18162 
  18163 #define MAX_HW_TCAMS 20
  18164 typedef struct ser_td2_skipped_mem_s {
  18165     soc_mem_t mem;
  18166     soc_acc_type_t acc_type;
  18167 } ser_td2_skipped_mem_t;
  18168 
  18169 const ser_td2_skipped_mem_t td2_skipped_mems[] = {
  18170     {FP_METER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  18171     {ING_L3_NEXT_HOPm, _SOC_ACC_TYPE_PIPE_Y},
  18172     {L2MCm, _SOC_ACC_TYPE_PIPE_Y},
  18173     {L3_IPMCm, _SOC_ACC_TYPE_PIPE_Y},
  18174     {OAM_LM_COUNTERSm, _SOC_ACC_TYPE_PIPE_Y},
  18175     {OAM_LM_COUNTERSm, _SOC_ACC_TYPE_PIPE_X},
  18176     {L2_ENTRY_LPm, _SOC_ACC_TYPE_PIPE_Y},
  18177     {L2_ENTRY_LPm, _SOC_ACC_TYPE_PIPE_X},
  18178     {L3_ENTRY_LPm, _SOC_ACC_TYPE_PIPE_Y},
  18179     {L3_ENTRY_LPm, _SOC_ACC_TYPE_PIPE_X},
  18180     {L2Xm, _SOC_ACC_TYPE_PIPE_Y},
  18181     {REPLICATION_FIFO_BANK0m, _SOC_ACC_TYPE_PIPE_ANY},
  18182     {REPLICATION_FIFO_BANK1m, _SOC_ACC_TYPE_PIPE_ANY},
  18183     {INVALIDm}
  18184 };
  18185 
  18186 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18187 const ser_td2_skipped_mem_t td2p_skipped_mems[] = {
  18188     {FP_METER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  18189     {L2MCm, _SOC_ACC_TYPE_PIPE_Y},
  18190     {L3_IPMCm, _SOC_ACC_TYPE_PIPE_Y},
  18191     {L2_BULK_MATCH_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  18192     {L2_BULK_MATCH_MASKm, _SOC_ACC_TYPE_PIPE_ANY},
  18193     {L2_BULK_REPLACE_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  18194     {L2_BULK_REPLACE_MASKm, _SOC_ACC_TYPE_PIPE_ANY},
  18195     {L2_MOD_FIFOm, _SOC_ACC_TYPE_PIPE_ANY},
  18196     {ING_SNAT_ONLYm, _SOC_ACC_TYPE_PIPE_ANY},
  18197     {L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY},
  18198     {OAM_LM_COUNTERSm, _SOC_ACC_TYPE_PIPE_ANY},
  18199     {LMEPm, _SOC_ACC_TYPE_PIPE_ANY},
  18200     {LMEP_DAm, _SOC_ACC_TYPE_PIPE_ANY},
  18201     {MAID_REDUCTIONm, _SOC_ACC_TYPE_PIPE_ANY},
  18202     {MA_INDEXm, _SOC_ACC_TYPE_PIPE_ANY},
  18203     {MA_STATEm, _SOC_ACC_TYPE_PIPE_ANY},
  18204     {RMEPm, _SOC_ACC_TYPE_PIPE_ANY},
  18205     {MPLS_ENTROPY_LABEL_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  18206     {L2_USER_ENTRY_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_ANY},
  18207     {REPLICATION_FIFO_BANK0m, _SOC_ACC_TYPE_PIPE_ANY},
  18208     {REPLICATION_FIFO_BANK1m, _SOC_ACC_TYPE_PIPE_ANY},
  18209     {INVALIDm}
  18210 };
  18211 #endif
  18212 
  18213 const soc_ser_overlay_test_t soc_ser_td2_overlay_mems[] = {
  18214 
  18215     {MODPORT_MAP_M0m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18216      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_X},
  18217     {MODPORT_MAP_M1m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18218      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_X},
  18219     {MODPORT_MAP_M2m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18220      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_X},
  18221     {MODPORT_MAP_M3m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18222      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_X},
  18223 
  18224     {MODPORT_MAP_M0m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18225      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_Y},
  18226     {MODPORT_MAP_M1m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18227      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_Y},
  18228     {MODPORT_MAP_M2m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18229      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_Y},
  18230     {MODPORT_MAP_M3m, ISW2_SER_CONTROL_0r, MODPORT_MAP_MIRROR_PARITY_ENf,
  18231      MODPORT_MAP_MIRRORm, _SOC_ACC_TYPE_PIPE_Y},
  18232 
  18233     {L3_ENTRY_IPV4_UNICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18234      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_X},
  18235     {L3_ENTRY_IPV4_MULTICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18236      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_X},
  18237     {L3_ENTRY_IPV6_UNICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18238      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_X},
  18239     {L3_ENTRY_IPV6_MULTICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18240      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_X},
  18241 
  18242     {L3_ENTRY_IPV4_UNICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18243      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_Y},
  18244     {L3_ENTRY_IPV4_MULTICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18245      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_Y},
  18246     {L3_ENTRY_IPV6_UNICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18247      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_Y},
  18248     {L3_ENTRY_IPV6_MULTICASTm, L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
  18249      L3_ENTRY_ONLYm,  _SOC_ACC_TYPE_PIPE_Y},
  18250 
  18251     {EGR_IP_TUNNEL_IPV6m, EGR_VLAN_SER_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf,
  18252      EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_X},
  18253     {EGR_IP_TUNNEL_MPLSm, EGR_VLAN_SER_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf,
  18254      EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_X},
  18255     {EGR_DVP_ATTRIBUTE_1m, EGR_EL3_ECC_PARITY_CONTROLr,
  18256      EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_ENf, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
  18257      _SOC_ACC_TYPE_PIPE_X},
  18258      {EGR_IP_TUNNEL_IPV6m, EGR_VLAN_SER_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf,
  18259      EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_Y},
  18260     {EGR_IP_TUNNEL_MPLSm, EGR_VLAN_SER_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf,
  18261      EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_Y},
  18262     {EGR_DVP_ATTRIBUTE_1m, EGR_EL3_ECC_PARITY_CONTROLr,
  18263      EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_ENf, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
  18264      _SOC_ACC_TYPE_PIPE_Y},
  18265     {INVALIDm}
  18266 };
  18267 
  18268 
  18269 static soc_mem_t _soc_td2_alpm_sram_list[] = {
  18270     L3_DEFIP_ALPM_IPV4m,
  18271     L3_DEFIP_ALPM_IPV4_1m,
  18272     L3_DEFIP_ALPM_IPV6_64m,
  18273     L3_DEFIP_ALPM_IPV6_64_1m,
  18274     L3_DEFIP_ALPM_IPV6_128m,
  18275     INVALIDm
  18276 };
  18277 
  18278 STATIC int
  18279 _soc_trident2_ser_mem_is_hw_cached (int unit, soc_mem_t mem)
  18280 {
  18281     switch (mem) {
  18282     case L3_DEFIP_ALPM_RAWm:
  18283     case L3_DEFIP_ALPM_IPV4m:
  18284     case L3_DEFIP_ALPM_IPV4_1m:
  18285     case L3_DEFIP_ALPM_IPV6_64m:
  18286     case L3_DEFIP_ALPM_IPV6_64_1m:
  18287     case L3_DEFIP_ALPM_IPV6_128m:
  18288 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18289     case L3_DEFIP_ALPM_ECCm:
  18290     case L2_ENTRY_LPm:
  18291     case L3_ENTRY_LPm:
  18292     case VLAN_XLATE_LPm:
  18293     case EGR_VLAN_XLATE_LPm:
  18294 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  18295     case L3_DEFIP_AUX_TABLEm:
  18296     case L3_DEFIP_PAIR_128m:
  18297     case L3_DEFIPm:
  18298     case L3_DEFIP_128_DATA_ONLYm:
  18299     case L3_DEFIP_PAIR_128_DATA_ONLYm:
  18300     case L3_DEFIP_DATA_ONLYm:
  18301         return 1;
  18302     default:
  18303         return 0;
  18304     }
  18305 }
  18306 
  18307 STATIC soc_acc_type_t
  18308 _soc_trident2_pipe_to_acc_type(int pipe)
  18309 {
  18310     soc_acc_type_t rv;
  18311     switch (pipe) {
  18312         case -1:
  18313         case 0:
  18314             rv = _SOC_ACC_TYPE_PIPE_X;
  18315             break;
  18316         case 1:
  18317             rv = _SOC_ACC_TYPE_PIPE_Y;
  18318             break;
  18319         default:
  18320             rv =_SOC_ACC_TYPE_PIPE_ALL;
  18321     };
  18322     return rv;
  18323 }
  18324 
  18325 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18326 #define _SER_TEST_MEM_TD2P_ALPM_MASK    0xFFFF
  18327 #define _SER_TEST_MEM_TD2P_ALPM_SHIFT   16
  18328 int
  18329 ser_test_trident2p_mem_index_remap(int unit, ser_test_data_t *test_data,
  18330                                   int *mem_has_ecc)
  18331 {
  18332     int uft_bkt_bank = 0;
  18333     int uft_le_fv = 0;
  18334     int uft_le_ecc = 0;
  18335     int remap_status = 0;
  18336 
  18337     *mem_has_ecc = 0;
  18338     test_data->mem = test_data->mem_fv;
  18339     test_data->index = test_data->index_fv;
  18340 
  18341     switch (test_data->mem_fv) {
  18342     case VLAN_XLATEm:
  18343     case VLAN_MACm:
  18344         test_data->mem = VLAN_XLATE_ECCm;
  18345         *mem_has_ecc = 1;
  18346         break;
  18347     case EGR_VLAN_XLATEm:
  18348         test_data->mem = EGR_VLAN_XLATE_ECCm;
  18349         *mem_has_ecc = 1;
  18350         break;
  18351     case L2Xm:
  18352     case L2_ENTRY_ONLYm:
  18353         test_data->mem = L2_ENTRY_ONLY_ECCm;
  18354         *mem_has_ecc = 1;
  18355         break;
  18356     case L3_ENTRY_ONLYm:
  18357     case L3_ENTRY_IPV4_UNICASTm:
  18358         test_data->mem = L3_ENTRY_ONLY_ECCm;
  18359         test_data->index = test_data->index_fv;
  18360         *mem_has_ecc = 1;
  18361         break;
  18362     case L3_ENTRY_IPV4_MULTICASTm:
  18363     case L3_ENTRY_IPV6_UNICASTm:
  18364         test_data->mem = L3_ENTRY_ONLY_ECCm;
  18365         test_data->index = test_data->index_fv*2;
  18366         *mem_has_ecc = 1;
  18367         break;
  18368     case L3_ENTRY_IPV6_MULTICASTm:
  18369         test_data->mem = L3_ENTRY_ONLY_ECCm;
  18370         test_data->index = test_data->index_fv*4;
  18371         *mem_has_ecc = 1;
  18372         break;
  18373     case L3_DEFIP_ALPM_IPV4m: /* 6:4 */
  18374         *mem_has_ecc = 1;
  18375         test_data->mem = L3_DEFIP_ALPM_ECCm;
  18376         uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_TD2P_ALPM_MASK;
  18377         uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_TD2P_ALPM_SHIFT;
  18378         switch (uft_le_fv) {
  18379         case 0: uft_le_ecc = 0; break;
  18380         case 1: uft_le_ecc = 0; break; /* or 1 */
  18381         case 2: uft_le_ecc = 1; break;
  18382         case 3: uft_le_ecc = 2; break;
  18383         case 4: uft_le_ecc = 2; break; /* or 3 */
  18384         case 5: uft_le_ecc = 3; break;
  18385         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  18386         }
  18387         test_data->index = (uft_le_ecc <<
  18388             _SER_TEST_MEM_TD2P_ALPM_SHIFT) + uft_bkt_bank;
  18389         break;
  18390     case L3_DEFIP_ALPM_IPV4_1m: /* 4:4 */
  18391     case L3_DEFIP_ALPM_IPV6_64m:
  18392         *mem_has_ecc = 1;
  18393         test_data->mem = L3_DEFIP_ALPM_ECCm;
  18394         test_data->index = test_data->index_fv;
  18395         break;
  18396     case L3_DEFIP_ALPM_IPV6_64_1m: /* 3:4 */
  18397         *mem_has_ecc = 1;
  18398         test_data->mem = L3_DEFIP_ALPM_ECCm;
  18399             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_TD2P_ALPM_MASK;
  18400             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_TD2P_ALPM_SHIFT;
  18401         switch (uft_le_fv) {
  18402         case 0: uft_le_ecc = 0; break; /* or 1 */
  18403         case 1: uft_le_ecc = 1; break; /* or 2 */
  18404         case 2: uft_le_ecc = 2; break; /* or 3 */
  18405         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  18406         }
  18407         test_data->index = (uft_le_ecc <<
  18408             _SER_TEST_MEM_TD2P_ALPM_SHIFT) + uft_bkt_bank;
  18409         break;
  18410     case L3_DEFIP_ALPM_IPV6_128m: /* 2:4 */
  18411         *mem_has_ecc = 1;
  18412         test_data->mem = L3_DEFIP_ALPM_ECCm;
  18413             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_TD2P_ALPM_MASK;
  18414             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_TD2P_ALPM_SHIFT;
  18415         switch (uft_le_fv) {
  18416         case 0: uft_le_ecc = 0; break; /* or 1 */
  18417         case 1: uft_le_ecc = 2; break; /* or 3 */
  18418         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  18419         }
  18420         test_data->index = (uft_le_ecc <<
  18421             _SER_TEST_MEM_TD2P_ALPM_SHIFT) + uft_bkt_bank;
  18422         break;
  18423     case L3_DEFIP_ALPM_RAWm: /* 1:4 */
  18424         *mem_has_ecc = 1;
  18425         test_data->mem = L3_DEFIP_ALPM_ECCm;
  18426             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_TD2P_ALPM_MASK;
  18427             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_TD2P_ALPM_SHIFT;
  18428         switch (uft_le_fv) {
  18429         case 0: uft_le_ecc = 0; break; /* or 1,2,3 */
  18430         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  18431         }
  18432         test_data->index = (uft_le_ecc <<
  18433             _SER_TEST_MEM_TD2P_ALPM_SHIFT) + uft_bkt_bank;
  18434         break;
  18435     default:
  18436         test_data->mem = test_data->mem_fv;
  18437         test_data->index = test_data->index_fv;
  18438         break;
  18439     }
  18440     if ((test_data->mem != test_data->mem_fv) ||
  18441         (test_data->index != test_data->index_fv)) {
  18442         LOG_VERBOSE(BSL_LS_SOC_SER,
  18443             (BSL_META_U(unit,
  18444                         "unit %d, ser_test_mem_index_remap: "
  18445                         "mem_fv %s, index_fv %0d, mem %s, index %0d, "
  18446                         "uft_bkt_bank %0d, uft_le_fv %0d, "
  18447                         "uft_le_ecc %0d, remap_status %0d \n"),
  18448              unit, SOC_MEM_NAME(unit, test_data->mem_fv), test_data->index_fv,
  18449              SOC_MEM_NAME(unit, test_data->mem), test_data->index,
  18450              uft_bkt_bank, uft_le_fv, uft_le_ecc, remap_status));
  18451     }
  18452     return remap_status;
  18453 }
  18454 
  18455 int
  18456 soc_trident2p_mem_is_eligible_for_scan(int unit, soc_mem_t mem)
  18457 {
  18458     switch (mem) {
  18459         case L3_DEFIP_ALPM_ECCm:
  18460         case L2_ENTRY_LPm:
  18461         case L3_ENTRY_LPm:
  18462         case VLAN_XLATE_LPm:
  18463         case EGR_VLAN_XLATE_LPm:
  18464         return 1;
  18465 
  18466         default:
  18467         break;
  18468     }
  18469     return 0;
  18470 }
  18471 #endif
  18472 
  18473 STATIC int
  18474 _soc_td2_refresh_modify(int unit, int enable) {
  18475     struct {
  18476         soc_reg_t ref_reg;
  18477         soc_field_t en_field;
  18478     } rf_list[] = {
  18479         {AUX_ARB_CONTROL_2r, FP_REFRESH_ENABLEf},
  18480         {EFP_METER_CONTROLr, EFP_REFRESH_ENABLEf},
  18481         {MISCCONFIGr, REFRESH_ENf},
  18482         {INVALIDr, INVALIDf}
  18483     };
  18484     uint32 rval;
  18485     int i;
  18486     for (i = 0; rf_list[i].ref_reg != INVALIDr; i++) {
  18487         if (!SOC_REG_IS_VALID(unit, rf_list[i].ref_reg)) {
  18488             continue;
  18489         }
  18490         SOC_IF_ERROR_RETURN
  18491             (soc_reg32_get(unit, rf_list[i].ref_reg, REG_PORT_ANY, 0, &rval));
  18492         soc_reg_field_set(unit, rf_list[i].ref_reg, &rval, rf_list[i].en_field,
  18493                           enable ? 1 : 0);
  18494         SOC_IF_ERROR_RETURN
  18495             (soc_reg32_set(unit, rf_list[i].ref_reg, REG_PORT_ANY, 0, rval));
  18496     }
  18497     return SOC_E_NONE;
  18498 }
  18499 
  18500 int
  18501 soc_trident2_ser_test_skip_check (int unit, soc_mem_t mem,
  18502                                    soc_acc_type_t acc_type)
  18503 {
  18504     int i;
  18505 
  18506     if (!SOC_MEM_IS_VALID(unit, mem) ||
  18507         ((mem != INVALIDm) &&
  18508          ((SOC_MEM_INFO(unit, mem).flags &
  18509            SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) {
  18510         return 1;
  18511     }
  18512 
  18513     if (soc_mem_index_count(unit, mem) <= 0) {
  18514         return 1;
  18515     }
  18516 
  18517     if (SOC_IS_TITAN2(unit)) {
  18518         /* Skip the memory if the relevant feature is disabled. */
  18519         if (!soc_feature(unit, soc_feature_l3_defip_map)) {
  18520             /* Skip L3_DEFIP memorys */
  18521             if ((L3_DEFIPm == mem) ||
  18522                 (L3_DEFIP_PAIR_128m == mem) ||
  18523                 (L3_DEFIP_DATA_ONLYm == mem) ) {
  18524                 return 1;
  18525             }
  18526         }
  18527     }
  18528 
  18529 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18530     if (SOC_IS_TD2P_TT2P(unit)) {
  18531         for (i = 0; td2p_skipped_mems[i].mem != INVALIDm; i++) {
  18532             if ((td2p_skipped_mems[i].mem == mem) &&
  18533                  ((td2p_skipped_mems[i].acc_type == acc_type) ||
  18534                   (td2p_skipped_mems[i].acc_type == _SOC_ACC_TYPE_PIPE_ANY))) {
  18535                 return 1;
  18536             }
  18537         }
  18538         if (!(SOC_MEM_INFO(unit, mem).flags & SOC_MEM_SER_FLAGS)) {
  18539             return 1;
  18540         }
  18541         /* Skip the memory if the relevant feature and memory is disabled. */
  18542         if (!soc_feature(unit, soc_feature_l3)
  18543             || !soc_feature(unit, soc_feature_lpm_tcam) ) {
  18544             /* Skip L3_DEFIP memorys */
  18545             if ((L3_DEFIPm == mem) || (L3_DEFIP_PAIR_128m == mem)) return 1;
  18546         }
  18547         if (!soc_feature(unit, soc_feature_l3) ||
  18548             !soc_feature(unit, soc_feature_ing_l3_next_hop_encoded_dest)) {
  18549             /* Skip ING L3 Next hop memory */
  18550             if ((ING_L3_NEXT_HOPm == mem)
  18551                 || (INITIAL_ING_L3_NEXT_HOPm == mem)) return 1;
  18552         }
  18553         if (!soc_feature(unit, soc_feature_l3) ||
  18554             soc_feature(unit, soc_feature_no_tunnel)) {
  18555             /* Skip ING L3 Tunnel memorys */
  18556             if ((L3_TUNNELm == mem) || (L3_TUNNEL_DATA_ONLYm == mem)) return 1;
  18557         }
  18558         if (!soc_feature(unit, soc_feature_nat)) {
  18559             /* Skip NAT  memorys */
  18560             if (ING_SNATm == mem) return 1;
  18561         }
  18562         if (!soc_feature(unit, soc_feature_mpls)) {
  18563             /* Skip MPLS memories */
  18564             if ((MPLS_ENTRYm == mem)
  18565                 || (ING_MPLS_EXP_MAPPINGm == mem)
  18566                 || (EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm == mem)) {
  18567                 return 1;
  18568             }
  18569         }
  18570     } else
  18571 #endif
  18572     {
  18573         for (i = 0; td2_skipped_mems[i].mem != INVALIDm; i++) {
  18574             if ((td2_skipped_mems[i].mem == mem) &&
  18575                 (td2_skipped_mems[i].acc_type == acc_type)) {
  18576                 return 1;
  18577             }
  18578         }
  18579     }
  18580     return 0;
  18581 }
  18582 
  18583 STATIC soc_error_t
  18584 _soc_trident2_ser_mem_info_get (int unit, soc_mem_t mem,
  18585                                      void** ser_mem_info)
  18586 {
  18587     int i, j;
  18588     _soc_td2_fifo_ser_info_t *fifo_parity = NULL;
  18589 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18590     _soc_mem_ser_en_info_t *ser_en_info = NULL;
  18591 #endif
  18592 
  18593 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18594     if (SOC_IS_TD2P_TT2P(unit)) {
  18595         /* Search for mems listed in:
  18596          * _soc_bcm56860_a0_ip_mem_ser_info,
  18597          * _soc_bcm56860_a0_ep_mem_ser_info,
  18598          * _soc_bcm56860_a0_mmu_mem_ser_info */
  18599         for (i = 0; _soc_td2p_ser_block_info[i].blocktype != 0; i++) {
  18600             if ((_soc_td2p_ser_block_info[i].type == _SOC_SER_TYPE_MEM) &&
  18601                 ((_soc_td2p_ser_block_info[i].blocktype == SOC_BLK_IPIPE) ||
  18602                  (_soc_td2p_ser_block_info[i].blocktype == SOC_BLK_EPIPE) ||
  18603                  (_soc_td2p_ser_block_info[i].blocktype == SOC_BLK_MMU))) {
  18604                 ser_en_info = _soc_td2p_ser_block_info[i].info;
  18605                 for (j = 0; ser_en_info[j].mem != INVALIDm; j++) {
  18606                     if (ser_en_info[j].mem == mem) {
  18607                         *ser_mem_info = &ser_en_info[j];
  18608                         return SOC_E_NONE;
  18609                     }
  18610                 }
  18611             }
  18612         }
  18613     } else
  18614 #endif
  18615     {
  18616         for (i = 0; _soc_td2_ser_block_info[i].blocktype != 0; i++) {
  18617             fifo_parity = _soc_td2_ser_block_info[i].info;
  18618             for (j = 0; fifo_parity[j].enable_reg != INVALIDr;j++) {
  18619                 if (fifo_parity[j].mem != INVALIDm && fifo_parity[j].mem == mem) {
  18620                     *ser_mem_info = &fifo_parity[j];
  18621                     return SOC_E_NONE;
  18622                 }
  18623             }
  18624         }
  18625     }
  18626     return SOC_E_NOT_FOUND;
  18627 }
  18628 
  18629 STATIC
  18630 soc_error_t
  18631 _soc_trident2_overlay_ser_mem_info_get (int unit, soc_mem_t mem,
  18632                                         int * index)
  18633 {
  18634     int i;
  18635     for (i = 0; soc_ser_td2_overlay_mems[i].mem != INVALIDm; i++) {
  18636         if (soc_ser_td2_overlay_mems[i].mem == mem) {
  18637             *index = i;
  18638             return SOC_E_NONE;
  18639         }
  18640     }
  18641     return SOC_E_NOT_FOUND;
  18642 }
  18643 
  18644 STATIC
  18645 soc_error_t
  18646 _soc_trident2_tcam_ser_mem_info_get (int unit, soc_mem_t mem,
  18647                                      int * index_p)
  18648 {
  18649     int i;
  18650     _soc_generic_ser_info_t *tcams = _soc_td2_tcam_ser_info[unit];
  18651 
  18652     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  18653         if (tcams[i].mem == mem) {
  18654             *index_p = i;
  18655             return SOC_E_NONE;
  18656         }
  18657     }
  18658     return SOC_E_NOT_FOUND;
  18659 }
  18660 
  18661 STATIC
  18662 soc_error_t
  18663 _soc_trident2_sram_ser_mem_info_get (int unit, soc_mem_t mem,
  18664                                      soc_mem_t ** mem_info)
  18665 {
  18666     int i;
  18667     for (i = 0; _soc_td2_alpm_sram_list[i] != INVALIDm; i++) {
  18668         if (_soc_td2_alpm_sram_list[i] == mem) {
  18669             *mem_info = &_soc_td2_alpm_sram_list[i];
  18670             return SOC_E_NONE;
  18671         }
  18672     }
  18673     return SOC_E_NOT_FOUND;
  18674 }
  18675 
  18676 STATIC
  18677 soc_error_t
  18678 _soc_trident2_mmu_ecc_mem_ser_info_get (int unit,
  18679                                         soc_mem_t mem,
  18680                                         void** ser_mem_info)
  18681 {
  18682     _soc_mem_ser_en_info_t *mem_ser_info = NULL;
  18683     uint32 i;
  18684 
  18685     mem_ser_info = _soc_trident2_mmu_ecc_mem_ser_info;
  18686 
  18687     for (i = 0; mem_ser_info[i].mem != INVALIDm; i++) {
  18688         if (!SOC_MEM_IS_VALID(unit, mem_ser_info[i].mem)) {
  18689             continue;
  18690         }
  18691 
  18692         if (mem_ser_info[i].mem != mem) {
  18693             continue;
  18694         }
  18695 
  18696         *ser_mem_info = &mem_ser_info[i];
  18697         return (SOC_E_NONE);
  18698     }
  18699 
  18700     return (SOC_E_NOT_FOUND);
  18701 }
  18702 
  18703 /*
  18704  * Function:
  18705  *      soc_td2_ser_error_injection_support
  18706  * Purpose:
  18707  *      Checks if a memory is supported by error injection interface
  18708  *
  18709  * Parameters:
  18710  *      unit        - (IN) Device Number
  18711  *      memory      - (IN) Test data required for SER test
  18712  *      pipe        - (IN) How many indices to test for each memory
  18713  *
  18714  * Returns:
  18715  *  SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported
  18716  */
  18717 soc_error_t
  18718 soc_td2_ser_error_injection_support (int unit, soc_mem_t mem,
  18719                                      int pipe)
  18720 {
  18721     int rv = SOC_E_UNAVAIL;
  18722     void * ser_mem_info = NULL;
  18723     int  tcam_idx = 0;
  18724     int  overlay_mem_idx = 0;
  18725     soc_mem_t * sram_mem_info = NULL;
  18726 
  18727     soc_acc_type_t soc_acc_type_target = _soc_trident2_pipe_to_acc_type(pipe);
  18728 
  18729     /* Check if memory is listed in skipped mems structure */
  18730     if (soc_trident2_ser_test_skip_check(unit, mem, soc_acc_type_target)) {
  18731         return rv;
  18732     }
  18733 
  18734     rv = _soc_trident2_ser_mem_info_get(unit, mem, &ser_mem_info);
  18735     if (rv == SOC_E_NONE) {
  18736         return rv;
  18737     }
  18738 
  18739     rv = _soc_trident2_tcam_ser_mem_info_get(unit, mem, &tcam_idx);
  18740     if (rv == SOC_E_NONE) {
  18741         return rv;
  18742     }
  18743 
  18744     if(!SOC_IS_TD2P_TT2P(unit)) {
  18745         rv = _soc_trident2_overlay_ser_mem_info_get(unit, mem, &overlay_mem_idx);
  18746         if (rv == SOC_E_NONE) {
  18747             return rv;
  18748         }
  18749         rv = _soc_trident2_sram_ser_mem_info_get(unit, mem, &sram_mem_info);
  18750         if (rv == SOC_E_NONE) {
  18751             return rv;
  18752         }
  18753         rv = _soc_trident2_mmu_ecc_mem_ser_info_get(unit, mem, &ser_mem_info);
  18754         if (rv == SOC_E_NONE) {
  18755             return rv;
  18756         }
  18757     }
  18758 
  18759     return rv;
  18760 }
  18761 
  18762 /*
  18763  * Function:
  18764  *      _soc_trident2_perform_ser_test
  18765  * Purpose:
  18766  *      Performs test operations common to TCAM and FIFO memory tests before
  18767  *      invoking common SER test.
  18768  * Parameters:
  18769  *      unit        - (IN) Device Number
  18770  *      test_data   - (IN) Test data required for SER test
  18771  *      test_type   - (IN) How many indices to test for each memory
  18772  *      mem_failed  - (OUT) Incremented when memories fail the test.
  18773  * Returns:
  18774  *  SOC_E_NONE if test passes, an error otherwise (multiple types of errors are
  18775  *      possible.)
  18776  */
  18777 soc_error_t
  18778 _soc_trident2_perform_ser_test(int unit, uint32 flags,
  18779                                ser_test_data_t *test_data,
  18780                                _soc_ser_test_t test_type,
  18781                                int *mem_skipped, int *mem_failed)
  18782 {
  18783     int skip_mem = FALSE;
  18784     soc_error_t rv = SOC_E_NONE;
  18785     soc_mem_t mem = INVALIDm;
  18786     mem = test_data->mem;
  18787 
  18788     if (soc_trident2_ser_test_skip_check(unit, mem, test_data->acc_type)) {
  18789         skip_mem = TRUE;
  18790     }
  18791     if (!skip_mem) {
  18792         if (mem == ING_VLAN_VFI_MEMBERSHIPm ||
  18793             mem == MMU_MTRO_EGRMETERINGCONFIG_MEM_0m ||
  18794             mem == MMU_MTRO_EGRMETERINGCONFIG_MEM_1m ||
  18795             mem == MMU_MTRI_BKPMETERINGCONFIG_MEM_0m ||
  18796             mem == MMU_MTRI_BKPMETERINGCONFIG_MEM_1m) {
  18797             flags |= SOC_INJECT_ERROR_2BIT_ECC;
  18798         }
  18799         rv = ser_test_mem(unit, flags, test_data, test_type, mem_failed);
  18800     } else {
  18801         LOG_VERBOSE(BSL_LS_SOC_SER,
  18802                     (BSL_META_U(unit,
  18803                                 "Memory %s skipped due to known issues.\n"),
  18804                      SOC_MEM_NAME(unit, mem)));
  18805         (*mem_skipped)++;
  18806     }
  18807     return rv;
  18808 }
  18809 
  18810 /*
  18811  * Function:
  18812  *      soc_td2_ser_tcam_test
  18813  * Purpose:
  18814  *      Tests that SER is working for fifo and SRAM memories
  18815  * Parameters:
  18816  *      unit        - (IN) Device Number
  18817  *      test_type   - (IN) How many indices to test for each memory
  18818  * Returns:
  18819  *  the number of tests which are failed
  18820  */
  18821 int
  18822 soc_td2_ser_tcam_test (int unit, _soc_ser_test_t test_type) {
  18823     uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS];
  18824     ser_test_data_t test_data;
  18825     int mem_failed = 0, mem_tests = 0, mem_skipped = 0;
  18826     _soc_generic_ser_info_t *tcams = _soc_td2_tcam_ser_info[unit];
  18827     int i;
  18828     soc_acc_type_t acc_type;
  18829     soc_field_t test_field = VALIDf;
  18830 
  18831     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  18832         mem_tests++;
  18833         if ( i >= MAX_HW_TCAMS) {
  18834             mem_skipped++;
  18835             LOG_VERBOSE(BSL_LS_SOC_SER,
  18836                         (BSL_META_U(unit,
  18837                                     "Memory %s skipped due to lack of test mechanism \
  18838                                     for Software-protected TCAMS.\n"),
  18839                          SOC_MEM_NAME(unit, tcams[i].mem)));
  18840             continue;
  18841         }
  18842 
  18843         /*
  18844         * Skip EFP_TCAMm for TR144 test since consecutive ipipe and epipe sbus
  18845         * transcations will cause H/W SER engine use incorrect parity bit
  18846         * for checking, which result in false parity error reported, SDK use S/W compare
  18847         * to detect EFP_TCAM parity error in memscan thread.
  18848         */
  18849         if (SOC_IS_TD2P_TT2P(unit) && (tcams[i].mem == EFP_TCAMm)) {
  18850             mem_skipped++;
  18851             LOG_VERBOSE(BSL_LS_SOC_SER,
  18852                         (BSL_META_U(unit,
  18853                                     "Memory %s skipped due to lack of test mechanism \
  18854                                     for Software-protected TCAMS.\n"),
  18855                          SOC_MEM_NAME(unit, tcams[i].mem)));
  18856             continue;
  18857         }
  18858 
  18859         if (tcams[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) {
  18860             acc_type = _SOC_ACC_TYPE_PIPE_Y;
  18861         } else {
  18862             acc_type = _SOC_ACC_TYPE_PIPE_X;
  18863         }
  18864 
  18865         if (tcams[i].mem == L3_DEFIPm) {
  18866             test_field = VALID0f;
  18867         } else if (tcams[i].mem == L3_DEFIP_PAIR_128m) {
  18868             test_field = VALID0_LWRf;
  18869         } else {
  18870             test_field = VALIDf;
  18871         }
  18872 
  18873         soc_ser_create_test_data(unit, tmp_entry, field_data, SER_RANGE_ENABLEr,
  18874                                  i, INVALIDf, tcams[i].mem, test_field,
  18875                                  MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0,
  18876                                  &test_data);
  18877         _soc_trident2_perform_ser_test(unit, 0, &test_data, test_type,
  18878                                        &mem_skipped, &mem_failed);
  18879     }
  18880     LOG_CLI((BSL_META_U(unit,
  18881                         "\nTCAM memories tested on unit %d: %d\n"), unit, mem_tests));
  18882     LOG_CLI((BSL_META_U(unit,
  18883                         "TCAM tests passed:\t%d\n"),
  18884              mem_tests - mem_failed - mem_skipped));
  18885     LOG_CLI((BSL_META_U(unit,
  18886                         "TCAM tests skipped:\t%d (use verbose option to see "
  18887                         "skipped memories)\n"),
  18888              mem_skipped));
  18889     LOG_CLI((BSL_META_U(unit,
  18890                         "TCAM tests failed:\t%d\n\n"), mem_failed));
  18891     return mem_failed;
  18892 }
  18893 
  18894 /*
  18895  * Function:
  18896  *      soc_td2_ser_hardware_test
  18897  * Purpose:
  18898  *      Tests that SER is working for fio and SRAM memories
  18899  * Parameters:
  18900  *      unit        - (IN) Device Number
  18901  *      test_type   - (IN) How many indices to test for each memory
  18902  * Returns:
  18903  *  the number of tests which are failed
  18904  */
  18905 STATIC int
  18906 soc_td2_ser_hardware_test (int unit, _soc_ser_test_t test_type) {
  18907     uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS];
  18908     ser_test_data_t test_data;
  18909     int mem_failed = 0, mem_tests = 0, mem_skipped = 0;
  18910     _soc_td2_fifo_ser_info_t *fifo_parity = _soc_td2_ip_ser_info;
  18911     int i, j;
  18912     soc_acc_type_t acc_type;
  18913 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18914     int k, rv, num_instance_to_test = 0;
  18915     _soc_mem_ser_en_info_t *ser_en_info = NULL;
  18916     soc_acc_type_t mem_acc_type, acc_type_list[SOC_MAX_NUM_PIPES];
  18917 #endif
  18918     (void) _soc_td2_refresh_modify(unit, FALSE);
  18919 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  18920     if (SOC_IS_TD2P_TT2P(unit)) {
  18921         for (i = 0; _soc_td2p_ser_block_info[i].blocktype != 0; i++) {
  18922             if ((_soc_td2p_ser_block_info[i].type == _SOC_SER_TYPE_MEM) &&
  18923                 ((_soc_td2p_ser_block_info[i].blocktype == SOC_BLK_IPIPE) ||
  18924                  (_soc_td2p_ser_block_info[i].blocktype == SOC_BLK_EPIPE) ||
  18925                  (_soc_td2p_ser_block_info[i].blocktype == SOC_BLK_MMU))) {
  18926                 ser_en_info = _soc_td2p_ser_block_info[i].info;
  18927                 for (j = 0; ser_en_info[j].mem != INVALIDm; j++) {
  18928                     mem_acc_type = SOC_MEM_ACC_TYPE(unit, ser_en_info[j].mem);
  18929                     sal_memset(acc_type_list, 0, sizeof(acc_type_list));
  18930                     switch (mem_acc_type) {
  18931                     case _SOC_ACC_TYPE_PIPE_BCAST:
  18932                     case _SOC_ACC_TYPE_PIPE_SBS:
  18933                         num_instance_to_test = NUM_PIPE(unit);
  18934                         acc_type_list[0] = _SOC_ACC_TYPE_PIPE_Y;
  18935                         acc_type_list[1] = _SOC_ACC_TYPE_PIPE_X;
  18936                         break;
  18937                     case _SOC_ACC_TYPE_PIPE_Y:
  18938                         num_instance_to_test = 1;
  18939                         acc_type_list[0] = _SOC_ACC_TYPE_PIPE_Y;
  18940                         break;
  18941                     case _SOC_ACC_TYPE_PIPE_X:
  18942                         num_instance_to_test = 1;
  18943                         acc_type_list[0] = _SOC_ACC_TYPE_PIPE_X;
  18944                         break;
  18945                     default:
  18946                         num_instance_to_test = 1;
  18947                         acc_type_list[0] = _SOC_ACC_TYPE_PIPE_X;
  18948                         break;
  18949                     }
  18950                     mem_tests += num_instance_to_test;
  18951                     for (k = 0; k < num_instance_to_test; k++) {
  18952                         test_data.test_field = EVEN_PARITYf;
  18953                         acc_type = acc_type_list[k];
  18954                         soc_ser_create_test_data(unit, tmp_entry, field_data,
  18955                                                  ser_en_info[j].en_ctrl.ctrl_type.en_reg,
  18956                                                  SOC_INVALID_TCAM_PARITY_BIT,
  18957                                                  ser_en_info[j].en_ctrl.en_fld,
  18958                                                  ser_en_info[j].mem,
  18959                                                  test_data.test_field,
  18960                                                  MEM_BLOCK_ANY,
  18961                                                  REG_PORT_ANY, acc_type, 0,
  18962                                                  &test_data);
  18963                         if ((test_data.mem_info == NULL) ||
  18964                             (!(soc_mem_index_count(unit, ser_en_info[j].mem) > 0))) {
  18965                             mem_skipped++;
  18966                             LOG_VERBOSE(BSL_LS_SOC_SER,
  18967                                     (BSL_META_U(unit,
  18968                                                 "Memory %s skipped due to lack of"
  18969                                                 " mem_info structure or being disabled.\n"),
  18970                                      SOC_MEM_NAME(unit,test_data.mem)));
  18971                             continue;
  18972                         }
  18973                         rv = _soc_trident2_perform_ser_test(unit, 0, &test_data,
  18974                                                             test_type, &mem_skipped,
  18975                                                             &mem_failed);
  18976                         if (SOC_FAILURE(rv)) {
  18977                              LOG_CLI((BSL_META_U(unit,
  18978                                       " SER test fail for mem: \t %s\n\n"),
  18979                                       SOC_MEM_NAME(unit,test_data.mem)));
  18980                         }
  18981                     }
  18982                 }
  18983             }
  18984         }
  18985     } else
  18986 #endif
  18987     {
  18988         for (i = 0; _soc_td2_ser_block_info[i].blocktype != 0; i++) {
  18989             fifo_parity = _soc_td2_ser_block_info[i].info;
  18990             for (j = 0; fifo_parity[j].enable_reg != INVALIDr; j++) {
  18991                 if (fifo_parity[j].mem != INVALIDm) {
  18992                     mem_tests += 2;
  18993                     test_data.test_field = EVEN_PARITYf;
  18994                     acc_type = _SOC_ACC_TYPE_PIPE_Y;
  18995                     soc_ser_create_test_data(unit, tmp_entry, field_data,
  18996                                              fifo_parity[j].enable_reg,
  18997                                              SOC_INVALID_TCAM_PARITY_BIT,
  18998                                              fifo_parity[j].enable_field,
  18999                                              fifo_parity[j].mem,
  19000                                              test_data.test_field, MEM_BLOCK_ANY,
  19001                                              REG_PORT_ANY, acc_type, 0, &test_data);
  19002                     if ((test_data.mem_info == NULL) ||
  19003                         (!(soc_mem_index_count(unit, fifo_parity[j].mem) > 0))) {
  19004                         mem_skipped += 2;
  19005                         LOG_VERBOSE(BSL_LS_SOC_SER,
  19006                                     (BSL_META_U(unit,
  19007                                                 "Memory %s skipped due to lack of"
  19008                                                 " mem_info structure.\n"),
  19009                                      SOC_MEM_NAME(unit,test_data.mem)));
  19010                         continue;
  19011                     }
  19012                     _soc_trident2_perform_ser_test(unit, 0, &test_data, test_type,
  19013                                                    &mem_skipped, &mem_failed);
  19014                     test_data.acc_type = _SOC_ACC_TYPE_PIPE_X;
  19015                     _soc_trident2_perform_ser_test(unit, 0, &test_data, test_type,
  19016                                                    &mem_skipped, &mem_failed);
  19017                 }
  19018             }
  19019         }
  19020         /* Perform SER test for SRAM memories */
  19021         for (i = 0; _soc_td2_alpm_sram_list[i] != INVALIDm; i++) {
  19022             soc_ser_create_test_data(unit, tmp_entry, field_data,
  19023                                      ILPM_SER_CONTROLr,
  19024                                      SOC_INVALID_TCAM_PARITY_BIT,
  19025                                      L3_DEFIP_ALPM_PARITY_ENf,
  19026                                      _soc_td2_alpm_sram_list[i],
  19027                                      EVEN_PARITYf, MEM_BLOCK_ANY,
  19028                                      REG_PORT_ANY, _SOC_ACC_TYPE_PIPE_Y, 0,
  19029                                      &test_data);
  19030             if ((test_data.mem_info == NULL) ||
  19031                 (!(soc_mem_index_count(unit, _soc_td2_alpm_sram_list[i]) > 0))) {
  19032                 mem_skipped += 2;
  19033                 LOG_VERBOSE(BSL_LS_SOC_SER,
  19034                             (BSL_META_U(unit,
  19035                                         "Memory %s skipped due to lack of"
  19036                                         " mem_info structure.\n"),
  19037                              SOC_MEM_NAME(unit,test_data.mem)));
  19038                 continue;
  19039             }
  19040             _soc_trident2_perform_ser_test(unit, 0, &test_data, test_type,
  19041                                            &mem_skipped, &mem_failed);
  19042             test_data.acc_type = _SOC_ACC_TYPE_PIPE_X;
  19043             _soc_trident2_perform_ser_test(unit, 0, &test_data, test_type,
  19044                                            &mem_skipped, &mem_failed);
  19045             mem_tests += 2;
  19046         }
  19047     }
  19048     (void) _soc_td2_refresh_modify(unit, TRUE);
  19049     LOG_CLI((BSL_META_U(unit,
  19050                         "\nH/W memories tested on unit %d: %d\n"), unit, mem_tests));
  19051     LOG_CLI((BSL_META_U(unit,
  19052                         "H/W tests passed:\t%d\n"),
  19053              mem_tests - mem_failed - mem_skipped));
  19054     LOG_CLI((BSL_META_U(unit,
  19055                         "H/W tests skipped:\t%d (use verbose option to see "
  19056                         "skipped memories)\n"),
  19057              mem_skipped));
  19058     LOG_CLI((BSL_META_U(unit,
  19059                         "H/W tests failed:\t%d\n\n"), mem_failed));
  19060     return mem_failed;
  19061 }
  19062 
  19063 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19064 void
  19065 soc_trident2p_ser_parity_control_check_all(int unit)
  19066 {
  19067 #ifdef BCM_56860_A0
  19068     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_MEM,
  19069                                             (void *)_soc_bcm56860_a0_ip_mem_ser_info);
  19070     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_MEM,
  19071                                             (void *)_soc_bcm56860_a0_ep_mem_ser_info);
  19072     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_MEM,
  19073                                             (void *)_soc_bcm56860_a0_mmu_mem_ser_info);
  19074     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_REG,
  19075                                             (void *)_soc_bcm56860_a0_ip_reg_ser_info);
  19076     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_REG,
  19077                                             (void *)_soc_bcm56860_a0_ep_reg_ser_info);
  19078     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUS,
  19079                                             (void *)_soc_ip_bus_ser_info);
  19080     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUS,
  19081                                             (void *)_soc_ep_bus_ser_info);
  19082     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUF,
  19083                                             (void *)_soc_ip_buffer_ser_info);
  19084     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUF,
  19085                                             (void *)_soc_ep_buffer_ser_info);
  19086     (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUF,
  19087                                             (void *)_soc_mmu_buffer_ser_info);
  19088 #endif
  19089 }
  19090 #endif
  19091 
  19092 soc_error_t
  19093 soc_td2x_ser_pg_parity_control_check(int unit, _soc_td2_ser_info_t *info_list)
  19094 {
  19095     _soc_td2_ser_info_t *info;
  19096     int i;
  19097     int match = 0;
  19098     uint32 rval = 0;
  19099     uint64 rval64;
  19100     soc_reg_t reg = INVALIDr;
  19101     soc_field_t field = INVALIDf;
  19102     uint32 value = 0;
  19103     uint32 total_count = 0;
  19104     uint32 pass_count = 0;
  19105 
  19106     for (i = 0; ; i++) {
  19107         info = &info_list[i];
  19108         if (info->type == _SOC_PARITY_TYPE_NONE) {
  19109             break;
  19110         }
  19111 
  19112         reg = info->enable_reg;
  19113         field = info->enable_field;
  19114         if (soc_reg_field_valid(unit, reg, field)) {
  19115             if (SOC_REG_IS_64(unit, reg)) {
  19116                 COMPILER_64_ZERO(rval64);
  19117                 SOC_IF_ERROR_RETURN
  19118                     (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  19119                 value = soc_reg64_field32_get(unit, reg, rval64, field);
  19120             } else {
  19121                 SOC_IF_ERROR_RETURN
  19122                     (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  19123                 value = soc_reg_field_get(unit, reg, rval, field);
  19124             }
  19125             if (0 == value) {
  19126                 match = 0;
  19127                 LOG_WARN(BSL_LS_SOC_SER,
  19128                          (BSL_META_U(unit,
  19129                                   "parity control %s.%s is disabled !!\n"),
  19130                                   SOC_REG_NAME(unit, reg),
  19131                                   SOC_FIELD_NAME(unit, field)));
  19132             } else {
  19133                 match = 1;
  19134             }
  19135             total_count++;
  19136             if (match) {
  19137                 pass_count++;
  19138             }
  19139         }
  19140     }
  19141     LOG_CLI((BSL_META_U(unit, "\nPort parity control checked on unit %d: %d\n"),
  19142              unit, total_count));
  19143     LOG_CLI((BSL_META_U(unit, "Passed fields:\t%d\n"), pass_count));
  19144     LOG_CLI((BSL_META_U(unit, "Failed fields::\t%d\n\n"), (total_count - pass_count)));
  19145 
  19146     return SOC_E_NONE;
  19147 }
  19148 
  19149 soc_error_t
  19150 soc_td2_ser_enable_field_check(int unit, soc_reg_t reg, soc_field_t field, int *match)
  19151 {
  19152     uint64 rval64;
  19153     uint32 rval32 = 0;
  19154     uint32 value = 0;
  19155 
  19156     if (SOC_REG_IS_VALID(unit,reg)) {
  19157         if (SOC_REG_IS_64(unit,reg)) {
  19158             COMPILER_64_ZERO(rval64);
  19159             SOC_IF_ERROR_RETURN
  19160                 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  19161             value = soc_reg64_field32_get(unit, reg, rval64, field);
  19162         } else {
  19163             SOC_IF_ERROR_RETURN
  19164                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval32));
  19165             value = soc_reg_field_get(unit, reg, rval32, field);
  19166         }
  19167         if (0 == value) {
  19168             *match = 0;
  19169             LOG_WARN(BSL_LS_SOC_SER,
  19170                      (BSL_META_U(unit,
  19171                               "parity control %s.%s is disabled !!\n"),
  19172                               SOC_REG_NAME(unit, reg),
  19173                               SOC_FIELD_NAME(unit, field)));
  19174         } else {
  19175             *match = 1;
  19176         }
  19177     }
  19178     return SOC_E_NONE;
  19179 }
  19180 
  19181 soc_error_t
  19182 soc_td2_ser_parity_control_check(int unit)
  19183 {
  19184     int i, j;
  19185     int match = 0;
  19186     _soc_mem_ser_en_info_t *mem_ser_info;
  19187     _soc_td2_fifo_ser_info_t *fifo_parity = NULL;
  19188     soc_reg_t reg = INVALIDr;
  19189     soc_field_t field = INVALIDf;
  19190     soc_reg_t ecc1b_reg = INVALIDr;
  19191     soc_field_t ecc1b_field = INVALIDf;
  19192     uint32 total_count = 0;
  19193     uint32 pass_count = 0;
  19194 
  19195     for (i = 0; _soc_td2_ser_block_info[i].blocktype != 0; i++) {
  19196         fifo_parity = _soc_td2_ser_block_info[i].info;
  19197         for (j = 0; fifo_parity[j].enable_reg != INVALIDr; j++) {
  19198             reg = fifo_parity[j].enable_reg;
  19199             field = fifo_parity[j].enable_field;
  19200             soc_td2_ser_enable_field_check(unit, reg, field, &match);
  19201             total_count++;
  19202             if (match) {
  19203                 pass_count++;
  19204             }
  19205         }
  19206     }
  19207 
  19208     mem_ser_info = _soc_trident2_mmu_ecc_mem_ser_info;
  19209     for (i = 0; mem_ser_info[i].mem != INVALIDm; i++) {
  19210         if (!SOC_MEM_IS_VALID(unit, mem_ser_info[i].mem)) {
  19211             continue;
  19212         }
  19213 
  19214         reg = mem_ser_info[i].en_ctrl.ctrl_type.en_reg;
  19215         field = mem_ser_info[i].en_ctrl.en_fld;
  19216         ecc1b_reg = mem_ser_info[i].ecc1b_ctrl.ctrl_type.en_reg;
  19217         ecc1b_field = mem_ser_info[i].ecc1b_ctrl.en_fld;
  19218 
  19219         soc_td2_ser_enable_field_check(unit, reg, field, &match);
  19220         total_count++;
  19221         if (match) {
  19222             pass_count++;
  19223         }
  19224         if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem_ser_info[i].mem)) {
  19225             soc_td2_ser_enable_field_check(unit, ecc1b_reg, ecc1b_field, &match);
  19226             total_count++;
  19227             if (match) {
  19228                 pass_count++;
  19229             }
  19230         }
  19231     }
  19232 
  19233     LOG_CLI((BSL_META_U(unit, "\nParity control checked on unit %d: %d\n"),
  19234              unit, total_count));
  19235     LOG_CLI((BSL_META_U(unit, "Passed fields:\t%d\n"), pass_count));
  19236     LOG_CLI((BSL_META_U(unit, "Failed fields::\t%d\n\n"), (total_count - pass_count)));
  19237 
  19238     return SOC_E_NONE;
  19239 }
  19240 
  19241 /*
  19242  * Function:
  19243  *      soc_td2_ser_test
  19244  * Purpose:
  19245  *      Tests that SER is working for all supported memories.
  19246  * Parameters:
  19247  *      unit        - (IN) Device Number
  19248  *      test_type   - (IN) How many indices to test for each memory
  19249  * Returns:
  19250  *  SOC_E_NONE if test passes, an error otherwise (multiple types of errors are
  19251  *      possible.)
  19252  */
  19253 soc_error_t
  19254 soc_td2_ser_test (int unit, _soc_ser_test_t test_type) {
  19255     int errors = 0;
  19256 
  19257 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19258     if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TITAN2PLUS(unit)) {
  19259         soc_trident2p_ser_parity_control_check_all(unit);
  19260     }
  19261 #endif
  19262     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) {
  19263         (void)soc_td2_ser_parity_control_check(unit);
  19264     }
  19265     (void)soc_td2x_ser_pg_parity_control_check(unit, _soc_td2_pg_ser_info);
  19266     (void)soc_td2x_ser_pg_parity_control_check(unit, _soc_td2_cport_ser_info);
  19267 
  19268     /* Test for overlay memories */
  19269     if (!SOC_IS_TD2P_TT2P(unit))
  19270     {
  19271         soc_ser_test_long_sleep = TRUE;
  19272         errors += soc_td2_ser_test_overlay(unit, test_type);
  19273         soc_ser_test_long_sleep = FALSE;
  19274     }
  19275 
  19276     /* Test TCAM memories */
  19277     errors += soc_td2_ser_tcam_test(unit, test_type);
  19278     /* Test for FIFO memories */
  19279     errors += soc_td2_ser_hardware_test(unit, test_type);
  19280 
  19281     if (errors == 0) {
  19282         return SOC_E_NONE;
  19283     } else {
  19284         LOG_CLI((BSL_META_U(unit,
  19285                     "TR 144 test failed, failed cases:%d.\n"), errors));
  19286         return SOC_E_FAIL;
  19287     }
  19288 }
  19289 
  19290 #define TR_MEM_NAME_SIZE_MAX    100
  19291 
  19292 #ifdef SOC_MEM_NAME
  19293 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) do {                    \
  19294         const char *_mem_name = SOC_MEM_NAME(_unit_, _mem);             \
  19295         if (sal_strlen(_mem_name) < TR_MEM_NAME_SIZE_MAX) {             \
  19296             sal_strcpy(_msg, _mem_name);                                \
  19297         }                                                               \
  19298     } while (0)
  19299 #else
  19300 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem)
  19301 #endif
  19302 
  19303 #define TR_TEST_MEM_PRINT(_unit, _msg, _mem) do {                       \
  19304         sal_sprintf(_msg, "Mem ID: %d", _mem);                          \
  19305         TR_TEST_MEM_NAME_GET(_unit, _msg, _mem);                        \
  19306         LOG_CLI((BSL_META_U(_unit,                                      \
  19307                             "Memory %s is valid, but not currently testable.\n"), \
  19308                  _msg));                                                \
  19309     } while (0)
  19310 
  19311 
  19312 /*
  19313  * Function:
  19314  *      soc_td2_ser_test_overlay
  19315  * Purpose:
  19316  *      performs a test of all overlay memories along with their base memories
  19317  * Parameters:
  19318  *      unit        - (IN) Device Number
  19319  *      test_type   - (IN) how to test memories
  19320  */
  19321 int
  19322 soc_td2_ser_test_overlay (int unit, _soc_ser_test_t test_type)
  19323 {
  19324     int rv = 0;
  19325     int numOverlays = COUNTOF(soc_ser_td2_overlay_mems) - 1;
  19326 
  19327     rv = soc_ser_test_overlays(unit, test_type, soc_ser_td2_overlay_mems,
  19328                               NULL);
  19329 
  19330     if (rv >= 0) {
  19331         LOG_CLI((BSL_META_U(unit,
  19332                             " Overlay memories tested: \t %d\n"),
  19333                  numOverlays));
  19334         LOG_CLI((BSL_META_U(unit,
  19335                             " Overlay memories passed: \t %d\n"),
  19336                  numOverlays - rv));
  19337         LOG_CLI((BSL_META_U(unit,
  19338                             " Overlay memories failed: \t %d\n\n"),
  19339                  rv));
  19340     } else {
  19341         LOG_INFO(BSL_LS_SOC_SER,
  19342                  (BSL_META_U(unit,
  19343                              "Internal Error during overlay test.\n")));
  19344     }
  19345     return rv;
  19346 }
  19347 
  19348 STATIC int
  19349 soc_td2_ser_pipe_check(int pipe)
  19350 {
  19351     int rv = SOC_E_NONE;
  19352 
  19353     if (pipe != SOC_PIPE_SELECT_X_COMMON &&
  19354         pipe != SOC_PIPE_SELECT_Y_COMMON &&
  19355         pipe != SOC_PIPE_SELECT_ANY &&
  19356         pipe != _SOC_ACC_TYPE_PIPE_ALL) {
  19357         rv = SOC_E_PARAM;
  19358     }
  19359 
  19360     return rv;
  19361 }
  19362 
  19363 /*
  19364  * Function:
  19365  *      soc_ser_inject_or_test_mem
  19366  * Purpose:
  19367  *      Provide a common function for injecting errors and testing single
  19368  *      single memories
  19369  * Parameters:
  19370  *      unit        - (IN) Device Number
  19371  *      mem         - (IN) The memory into which an error will be injected
  19372  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
  19373  *      index       - (IN) The index into which the error will be injected.
  19374  *      test_type   - (IN) How many indices to test in the passes memory
  19375  *      cmd         - (IN) TRUE if a command-line test is desired.
  19376  * Returns:
  19377  *      SOC_E_NONE if test passes, an error otherwise (multiple types of errors
  19378  *      are possible.)
  19379  */
  19380 soc_error_t
  19381 soc_ser_inject_or_test_mem (int unit, soc_mem_t mem, int pipe_target, int block,
  19382                             int index, _soc_ser_test_t test_type,
  19383                             int inject_only, int cmd, uint32 flags)
  19384 {
  19385     uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS];
  19386     uint32 read_flags = 0;
  19387     ser_test_data_t test_data;
  19388     int tcam_idx = 0;
  19389     void * ser_mem_info = NULL;
  19390     int overlay_mem_idx = 0;
  19391     soc_mem_t * sram_mem_info = NULL;
  19392     _soc_generic_ser_info_t *tcams = _soc_td2_tcam_ser_info[unit];
  19393     int error_count = 0, skip_count = 0, found_mem = FALSE;
  19394     char fail_message[TR_MEM_NAME_SIZE_MAX + 1];
  19395 
  19396     soc_error_t rv = SOC_E_NONE;
  19397     soc_acc_type_t soc_acc_type_target = _soc_trident2_pipe_to_acc_type(pipe_target);
  19398     soc_field_t test_field = INVALIDf;
  19399     void * ser_mmu_mem_info = NULL;
  19400 
  19401     SOC_IF_ERROR_RETURN(soc_td2_ser_pipe_check(pipe_target));
  19402 
  19403     /* Search for TCAM memories */
  19404     rv = _soc_trident2_tcam_ser_mem_info_get(unit, mem, &tcam_idx);
  19405     if (rv == SOC_E_NONE) {
  19406         if (tcams[tcam_idx].mem == L3_DEFIPm) {
  19407             test_field = VALID0f;
  19408         } else if (tcams[tcam_idx].mem == L3_DEFIP_PAIR_128m) {
  19409             test_field = VALID0_LWRf;
  19410         } else {
  19411             test_field = VALIDf;
  19412         }
  19413         soc_ser_create_test_data(unit, tmp_entry, field_data,
  19414                                      SER_RANGE_ENABLEr, tcam_idx, INVALIDf, mem,
  19415                                      test_field, block, REG_PORT_ANY,
  19416                                      soc_acc_type_target, index, &test_data);
  19417         found_mem = TRUE;
  19418     }
  19419 
  19420     if (!found_mem) {
  19421         rv = _soc_trident2_ser_mem_info_get (unit, mem, &ser_mem_info);
  19422         if (rv == SOC_E_NONE) {
  19423 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19424             if (SOC_IS_TD2P_TT2P(unit)) {
  19425                 int mem_has_ecc = 0;
  19426 
  19427                 if (mem == ING_L3_NEXT_HOPm) {
  19428                     test_field= ECC_1f;
  19429                 } else {
  19430                     test_field = EVEN_PARITYf;
  19431                 }
  19432                 soc_ser_create_test_data(unit, tmp_entry, field_data,
  19433                                          ((_soc_mem_ser_en_info_t*)ser_mem_info)->en_ctrl.ctrl_type.en_reg,
  19434                                          SOC_INVALID_TCAM_PARITY_BIT,
  19435                                          ((_soc_mem_ser_en_info_t*)ser_mem_info)->en_ctrl.en_fld,
  19436                                          mem, test_field, block,
  19437                                          REG_PORT_ANY, soc_acc_type_target,
  19438                                          index, &test_data);
  19439                 if (SOC_REG_IS_VALID(unit, ((_soc_mem_ser_en_info_t*)ser_mem_info)->ecc1b_ctrl.ctrl_type.en_reg) &&
  19440                     (INVALIDf != ((_soc_mem_ser_en_info_t*)ser_mem_info)->ecc1b_ctrl.en_fld)) {
  19441                     flags |= SOC_INJECT_ERROR_2BIT_ECC;
  19442                 }
  19443                 SOC_IF_ERROR_RETURN
  19444                     (ser_test_mem_index_remap(unit, &test_data, &mem_has_ecc));
  19445                 if (mem_has_ecc) {
  19446                     flags |= SOC_INJECT_ERROR_2BIT_ECC;
  19447                 }
  19448                 /* ING_VLAN_VFI_MEMBERSHIP is ECC protected, however
  19449                  * there is no 1bit error reporting control register for it.
  19450                  */
  19451                 if (mem == ING_VLAN_VFI_MEMBERSHIPm) {
  19452                     flags |= SOC_INJECT_ERROR_2BIT_ECC;
  19453                 }
  19454             } else
  19455 #endif
  19456             {
  19457                 soc_ser_create_test_data(unit, tmp_entry, field_data,
  19458                                          ((_soc_td2_fifo_ser_info_t*)ser_mem_info)->enable_reg,
  19459                                          SOC_INVALID_TCAM_PARITY_BIT,
  19460                                          ((_soc_td2_fifo_ser_info_t*)ser_mem_info)->enable_field,
  19461                                          mem, EVEN_PARITYf, block,
  19462                                          REG_PORT_ANY, soc_acc_type_target,
  19463                                          index, &test_data);
  19464             }
  19465             found_mem = TRUE;
  19466         }
  19467     }
  19468 
  19469     if (!SOC_IS_TD2P_TT2P(unit)) {
  19470         if (!found_mem) {
  19471             rv = _soc_trident2_overlay_ser_mem_info_get(unit, mem, &overlay_mem_idx);
  19472             if (rv == SOC_E_NONE) {
  19473                 soc_ser_create_test_data(unit, tmp_entry, field_data,
  19474                                          soc_ser_td2_overlay_mems[overlay_mem_idx].parity_enable_reg,
  19475                                          SOC_INVALID_TCAM_PARITY_BIT,
  19476                                          soc_ser_td2_overlay_mems[overlay_mem_idx].parity_enable_field,
  19477                                          soc_ser_td2_overlay_mems[overlay_mem_idx].mem, EVEN_PARITYf,
  19478                                          block, REG_PORT_ANY, soc_acc_type_target,
  19479                                          index, &test_data);
  19480                 found_mem = TRUE;
  19481             }
  19482         }
  19483         if (!found_mem) {
  19484             rv = _soc_trident2_sram_ser_mem_info_get(unit, mem, &sram_mem_info);
  19485             if (rv == SOC_E_NONE) {
  19486                 soc_ser_create_test_data(unit, tmp_entry, field_data,
  19487                                          ILPM_SER_CONTROLr,
  19488                                          SOC_INVALID_TCAM_PARITY_BIT,
  19489                                          L3_DEFIP_ALPM_PARITY_ENf,
  19490                                          mem, EVEN_PARITYf,
  19491                                          block, REG_PORT_ANY, soc_acc_type_target,
  19492                                          index, &test_data);
  19493                 found_mem = TRUE;
  19494             }
  19495         }
  19496         if (!found_mem) {
  19497             rv = _soc_trident2_mmu_ecc_mem_ser_info_get(unit, mem, &ser_mmu_mem_info);
  19498             if (rv == SOC_E_NONE) {
  19499                 soc_ser_create_test_data(unit, tmp_entry, field_data,
  19500                                          ((_soc_mem_ser_en_info_t*)ser_mmu_mem_info)->en_ctrl.ctrl_type.en_reg,
  19501                                          SOC_INVALID_TCAM_PARITY_BIT,
  19502                                          ((_soc_mem_ser_en_info_t*)ser_mmu_mem_info)->en_ctrl.en_fld,
  19503                                          mem, ECCPf,
  19504                                          block, REG_PORT_ANY, soc_acc_type_target,
  19505                                          index, &test_data);
  19506                 if (inject_only) {
  19507                     /* These memories are not suitable for TR144 */
  19508                     found_mem = TRUE;
  19509                     flags |= SOC_INJECT_ERROR_2BIT_ECC;
  19510                 }
  19511             }
  19512         }
  19513     }
  19514 
  19515     if (found_mem) {
  19516         if ((pipe_target == _SOC_ACC_TYPE_PIPE_ANY) &&
  19517             (!_soc_trident2_ser_mem_is_hw_cached(unit, test_data.mem))) {
  19518             test_data.acc_type = SOC_MEM_ACC_TYPE(unit, test_data.mem);
  19519         }
  19520         if (inject_only) {
  19521             if (soc_trident2_ser_test_skip_check(unit, mem, test_data.acc_type)) {
  19522                 TR_TEST_MEM_PRINT(unit, fail_message, mem);
  19523                 return SOC_E_UNAVAIL;
  19524             }
  19525             /* Disable parity */
  19526             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0));
  19527             /* Read the memory (required for successful injection) */
  19528             if (flags & SOC_INJECT_ERROR_DONT_MAP_INDEX) {
  19529                 read_flags = SER_TEST_MEM_F_DONT_MAP_INDEX;
  19530             }
  19531             SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, read_flags, &test_data));
  19532             /* Inject error */
  19533             SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags, &test_data));
  19534             /* Enable parity */
  19535             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1));
  19536         } else {
  19537             if (cmd) {
  19538                 ser_test_cmd_generate(unit, &test_data);
  19539             } else {
  19540                 _soc_td2_refresh_modify(unit, FALSE);
  19541                 rv = _soc_trident2_perform_ser_test(unit, flags, &test_data, test_type,
  19542                                                     &skip_count, &error_count);
  19543                 _soc_td2_refresh_modify(unit, TRUE);
  19544                 if (error_count == 0) {
  19545                     LOG_CLI((BSL_META_U(unit,
  19546                                         "SER test PASSED for memory %s\n"),
  19547                              test_data.mem_name));
  19548                 }
  19549                 if (skip_count !=0) {
  19550                     LOG_CLI((BSL_META_U(unit,
  19551                                         "Test skipped due to known issues with "
  19552                                         "this memory.\n")));
  19553                 }
  19554             }
  19555         }
  19556     } else {
  19557         TR_TEST_MEM_PRINT(unit, fail_message, mem);
  19558         rv = SOC_E_UNAVAIL;
  19559     }
  19560     return rv;
  19561 }
  19562 #undef TR_TEST_MEM_PRINT
  19563 
  19564 /*
  19565  * Function:
  19566  *      soc_td2_ser_inject_error
  19567  * Purpose:
  19568  *      Injects an error into a single td2 memory
  19569  * Parameters:
  19570  *      unit        - (IN) Device Number
  19571  *      mem         - (IN) The memory into which an error will be injected
  19572  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
  19573  *      index       - (IN) The index into which the error will be injected.
  19574  *      test_tcam   - (IN) If the memory is a TCAM, test the KEY/MASK portion,
  19575  *                         not the DATA portion
  19576  */
  19577 soc_error_t
  19578 soc_td2_ser_inject_error (int unit, uint32 flags, soc_mem_t mem,
  19579                           int pipe_target, int block, int index)
  19580 {
  19581     /* Check if memory needs to be skipped */
  19582     if (ser_trident2_test_fun.injection_support) {
  19583         SOC_IF_ERROR_RETURN(
  19584             soc_td2_ser_error_injection_support(unit, mem, pipe_target));
  19585     }
  19586 
  19587     return soc_ser_inject_or_test_mem(unit, mem, pipe_target, block, index,
  19588                                       SER_SINGLE_INDEX, TRUE, FALSE, flags);
  19589 }
  19590 
  19591 /*
  19592  * Function:
  19593  *      soc_td2_ser_test_mem
  19594  * Purpose:
  19595  *      Perform SER test on a single memory, or generate a test the user can
  19596  *      enter by the command line.
  19597  * Parameters:
  19598  *      unit        - (IN) Device Number
  19599  *      mem         - (IN) The memory into which an error will be injected
  19600  *      test_type   - (IN) How many indices to test in the passes memory
  19601  *      cmd         - (IN) TRUE if a command-line test is desired.
  19602  * Returns:
  19603  *      SOC_E_NONE if test passes, an error otherwise (multiple types of errors
  19604  *      are possible.)
  19605  */
  19606 soc_error_t
  19607 soc_td2_ser_test_mem(int unit, soc_mem_t mem, _soc_ser_test_t test_type,
  19608                      int cmd)
  19609 {
  19610     soc_acc_type_t mem_acc_type;
  19611     soc_error_t rv = SOC_E_NONE;
  19612 
  19613     if ((!SOC_MEM_IS_VALID(unit, mem)) ||
  19614         (!(soc_mem_index_count(unit, mem) > 0))) {
  19615         LOG_ERROR(BSL_LS_SOC_SER,
  19616                   (BSL_META_U(unit,
  19617                               "unit %d, mem %d is INVALID or not valid "
  19618                               "for this unit !!\n"),
  19619                    unit, mem));
  19620         return SOC_E_UNAVAIL;
  19621     }
  19622     mem_acc_type = SOC_MEM_ACC_TYPE(unit, mem);
  19623 
  19624     if (mem_acc_type == _SOC_ACC_TYPE_PIPE_BCAST ||
  19625     	  mem_acc_type == _SOC_ACC_TYPE_PIPE_SBS) {
  19626         /* Test X-pipe memory instance */
  19627         rv = soc_ser_inject_or_test_mem(unit, mem, SOC_PIPE_SELECT_ANY,
  19628                                         MEM_BLOCK_ANY, 0, test_type,
  19629                                         FALSE, cmd, FALSE);
  19630         /* Test Y-pipe memory instance */
  19631         if (SOC_SUCCESS(rv)) {
  19632             rv = soc_ser_inject_or_test_mem(unit, mem, SOC_PIPE_SELECT_Y_COMMON,
  19633                                             MEM_BLOCK_ANY, 0, test_type,
  19634                                             FALSE, cmd, FALSE);
  19635         }
  19636 
  19637     } else if (mem_acc_type == _SOC_ACC_TYPE_PIPE_X) {
  19638         /* Only X-pipe access is allowed */
  19639         rv = soc_ser_inject_or_test_mem(unit, mem, SOC_PIPE_SELECT_X_COMMON,
  19640                                         MEM_BLOCK_ANY, 0, test_type,
  19641                                         FALSE, cmd, FALSE);
  19642     } else if (mem_acc_type == _SOC_ACC_TYPE_PIPE_Y) {
  19643         /* Only Y-pipe access is allowed */
  19644         rv = soc_ser_inject_or_test_mem(unit, mem, SOC_PIPE_SELECT_Y_COMMON,
  19645                                         MEM_BLOCK_ANY, 0, test_type,
  19646                                         FALSE, cmd, FALSE);
  19647     } else {
  19648         rv = soc_ser_inject_or_test_mem(unit, mem, _SOC_ACC_TYPE_PIPE_ANY,
  19649                                         MEM_BLOCK_ANY, 0, test_type,
  19650                                         FALSE, cmd, FALSE);
  19651     }
  19652     return rv;
  19653 }
  19654 #endif /*defined(SER_TR_TEST_SUPPORT)*/
  19655 
  19656 int
  19657 soc_td2_reg_cpu_write_control(int unit, int enable)
  19658 {
  19659     uint32 intfo_dis = 0;
  19660 
  19661     if (enable) {
  19662         /* Disable HW updates */
  19663         soc_reg_field_set(unit, INTFO_HW_UPDATE_DISr, &intfo_dis,
  19664                           EG_SPf, 1);
  19665         soc_reg_field_set(unit, INTFO_HW_UPDATE_DISr, &intfo_dis,
  19666                           ING_SPf, 1);
  19667         soc_reg_field_set(unit, INTFO_HW_UPDATE_DISr, &intfo_dis,
  19668                           CONGST_STf, 1);
  19669     }
  19670     SOC_IF_ERROR_RETURN(WRITE_INTFO_HW_UPDATE_DISr(unit, intfo_dis));
  19671 
  19672     return SOC_E_NONE;
  19673 }
  19674 
  19675 /*
  19676  * Trident2 chip driver functions.
  19677  */
  19678 soc_functions_t soc_trident2_drv_funs = {
  19679     _soc_trident2_misc_init,
  19680     _soc_trident2_mmu_init,
  19681     _soc_trident2_age_timer_get,
  19682     _soc_trident2_age_timer_max_get,
  19683     _soc_trident2_age_timer_set,
  19684     _soc_trident2_tsc_firmware_set
  19685 };
  19686 
  19687 uint32* soc_td2_mmu_params_arr_get (uint16 dev_id, uint8 rev_id)
  19688 {
  19689     return soc_mmu_pkt_buf_size_arr[_MMU_PKT_BUF_SIZE_12MB];
  19690 }
  19691 
  19692 void
  19693 soc_cm_get_id_otp(int unit, uint16 *dev_id, uint8 *rev_id)
  19694 {
  19695 
  19696     soc_cm_get_id(unit, dev_id, rev_id);
  19697 
  19698 }
  19699 
  19700 int soc_td2_is_blk_valid(int unit, int blk)
  19701 {
  19702     int valid = 1;
  19703 
  19704 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19705     int blktype;
  19706     int instance;
  19707 
  19708     if (SOC_IS_TD2P_TT2P(unit)) {
  19709         blktype = SOC_BLOCK_INFO(unit, blk).type;
  19710         if ( blktype == SOC_BLK_PGW_CL ) {
  19711             if (!soc_td2p_if_full_chip(unit)) {
  19712                 instance = SOC_BLOCK_INFO(unit, blk).number;
  19713                 if ( instance >= _TD2_PGWS_PER_PIPE ) {
  19714                     valid = 0;
  19715                     LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
  19716                                (BSL_META_U(unit,
  19717                                            "Unit %d half chip config block is not valid %d\n"),
  19718                                                 unit, valid));
  19719                 }
  19720             }
  19721         }
  19722     }
  19723 #endif
  19724 
  19725     return valid;
  19726 }
  19727 
  19728 int soc_td2x_ser_dlb_parity_set(int unit, int enable)
  19729 {
  19730     uint32 reg_data;
  19731 
  19732     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, DLB_HGT_SER_CONTROLr,
  19733                 REG_PORT_ANY, 0, &reg_data));
  19734     soc_reg_field_set(unit, DLB_HGT_SER_CONTROLr, &reg_data,
  19735                 DLB_HGT_FLOWSET_PARITY_ENf, enable);
  19736     SOC_IF_ERROR_RETURN
  19737                 (soc_reg32_set(unit, DLB_HGT_SER_CONTROLr,
  19738                     REG_PORT_ANY, 0, reg_data));
  19739 
  19740     return SOC_E_NONE;
  19741 }
  19742 
  19743 STATIC int
  19744 soc_trident2_ser_single_bit_error_set(int unit, int enable)
  19745 {
  19746     int i, value;
  19747     soc_reg_t ecc_reg;
  19748     soc_field_t ecc_fld;
  19749     _soc_mem_ser_en_info_t *mem_ser_info;
  19750 
  19751     value = enable ? 1:0;
  19752     mem_ser_info = _soc_trident2_mmu_ecc_mem_ser_info;
  19753 
  19754     for (i = 0; mem_ser_info[i].mem != INVALIDm; i++) {
  19755         if (!SOC_MEM_IS_VALID(unit, mem_ser_info[i].mem)) {
  19756             continue;
  19757         }
  19758 
  19759         ecc_reg = mem_ser_info[i].ecc1b_ctrl.ctrl_type.en_reg;
  19760         ecc_fld = mem_ser_info[i].ecc1b_ctrl.en_fld;
  19761 
  19762         if (!soc_reg_field_valid(unit, ecc_reg, ecc_fld)) {
  19763             continue;
  19764         }
  19765 
  19766         LOG_VERBOSE(BSL_LS_SOC_SER,
  19767                     (BSL_META_U(unit,
  19768                                 "unit %d, MEM %50s REG %30s FIELD %40s\n"),
  19769                      unit, SOC_MEM_NAME(unit, mem_ser_info[i].mem),
  19770                      SOC_REG_NAME(unit, ecc_reg),
  19771                      SOC_FIELD_NAME(unit, ecc_fld)));
  19772 
  19773         SOC_IF_ERROR_RETURN
  19774             (soc_reg_field32_modify(unit, ecc_reg, REG_PORT_ANY,
  19775                                     ecc_fld, value));
  19776     }
  19777 
  19778     return SOC_E_NONE;
  19779 }
  19780 
  19781 STATIC int
  19782 soc_trident2_ser_single_bit_error_get(int unit, int *enable)
  19783 {
  19784     soc_reg_t ecc_reg;
  19785     soc_field_t ecc_fld;
  19786     _soc_mem_ser_en_info_t *mem_ser_info;
  19787     uint32 rval = 0, fld_value = 0, i;
  19788 
  19789     mem_ser_info = _soc_trident2_mmu_ecc_mem_ser_info;
  19790 
  19791     for (i = 0; mem_ser_info[i].mem != INVALIDm; i++) {
  19792         if (!SOC_MEM_IS_VALID(unit, mem_ser_info[i].mem)) {
  19793             continue;
  19794         }
  19795 
  19796         ecc_reg = mem_ser_info[i].ecc1b_ctrl.ctrl_type.en_reg;
  19797         ecc_fld = mem_ser_info[i].ecc1b_ctrl.en_fld;
  19798 
  19799         if (soc_reg_field_valid(unit, ecc_reg, ecc_fld)) {
  19800             SOC_IF_ERROR_RETURN
  19801                 (soc_reg32_get(unit, ecc_reg, REG_PORT_ANY, 0, &rval));
  19802             fld_value = soc_reg_field_get(unit, ecc_reg, rval, ecc_fld);
  19803             break;
  19804         }
  19805     }
  19806 
  19807     *enable = fld_value ? TRUE:FALSE;
  19808     return SOC_E_NONE;
  19809 }
  19810 
  19811 
  19812 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19813 #define MEM_SER_INFO_COUNT 3
  19814 STATIC int
  19815 soc_trident2p_ser_single_bit_error_set(int unit, int enable)
  19816 {
  19817 #ifdef BCM_56860_A0
  19818     int i, value, k;
  19819     soc_reg_t ecc_reg;
  19820     soc_field_t ecc_fld;
  19821     _soc_mem_ser_en_info_t *mem_ser_info, *mem_ser_info_all[MEM_SER_INFO_COUNT];
  19822 
  19823     value = enable ? 1:0;
  19824     mem_ser_info_all[0] = _soc_bcm56860_a0_ip_mem_ser_info;
  19825     mem_ser_info_all[1] = _soc_bcm56860_a0_ep_mem_ser_info;
  19826     mem_ser_info_all[2] = _soc_bcm56860_a0_mmu_mem_ser_info;
  19827 
  19828     for (k = 0; k < MEM_SER_INFO_COUNT; k++) {
  19829         mem_ser_info = mem_ser_info_all[k];
  19830         for (i = 0; mem_ser_info[i].mem != INVALIDm; i++) {
  19831             /* Skip the memory whose SER_RESPONSE not equal SER_NONE*/
  19832             if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem_ser_info[i].mem) != 0) {
  19833                 continue;
  19834             }
  19835 
  19836             ecc_reg = mem_ser_info[i].ecc1b_ctrl.ctrl_type.en_reg;
  19837             ecc_fld = mem_ser_info[i].ecc1b_ctrl.en_fld;
  19838 
  19839             if (!soc_reg_field_valid(unit, ecc_reg, ecc_fld)) {
  19840                 continue;
  19841             }
  19842 
  19843             LOG_VERBOSE(BSL_LS_SOC_SER,
  19844                         (BSL_META_U(unit,
  19845                                     "unit %d, MEM %50s REG %30s FIELD %40s\n"),
  19846                          unit, SOC_MEM_NAME(unit, mem_ser_info[i].mem),
  19847                          SOC_REG_NAME(unit, ecc_reg),
  19848                          SOC_FIELD_NAME(unit, ecc_fld)));
  19849 
  19850             SOC_IF_ERROR_RETURN
  19851                 (soc_reg_field32_modify(unit, ecc_reg, REG_PORT_ANY,
  19852                                         ecc_fld, value));
  19853         }
  19854     }
  19855     return SOC_E_NONE;
  19856 #else
  19857     return SOC_E_UNAVAIL;
  19858 #endif
  19859 }
  19860 
  19861 STATIC int
  19862 soc_trident2p_ser_single_bit_error_get(int unit, int *enable)
  19863 {
  19864 #ifdef BCM_56860_A0
  19865     soc_reg_t ecc_reg;
  19866     soc_field_t ecc_fld;
  19867     _soc_mem_ser_en_info_t *mem_ser_info;
  19868     uint32 rval = 0, fld_value = 0, i;
  19869 
  19870     mem_ser_info = _soc_bcm56860_a0_mmu_mem_ser_info;
  19871 
  19872     for (i = 0; mem_ser_info[i].mem != INVALIDm; i++) {
  19873         /* Skip the memory whose SER_RESPONSE not equal SER_NONE*/
  19874         if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem_ser_info[i].mem) != 0) {
  19875             continue;
  19876         }
  19877 
  19878         ecc_reg = mem_ser_info[i].ecc1b_ctrl.ctrl_type.en_reg;
  19879         ecc_fld = mem_ser_info[i].ecc1b_ctrl.en_fld;
  19880 
  19881         if (soc_reg_field_valid(unit, ecc_reg, ecc_fld)) {
  19882             SOC_IF_ERROR_RETURN
  19883                 (soc_reg32_get(unit, ecc_reg, REG_PORT_ANY, 0, &rval));
  19884             fld_value = soc_reg_field_get(unit, ecc_reg, rval, ecc_fld);
  19885             break;
  19886         }
  19887     }
  19888 
  19889     *enable = fld_value ? TRUE:FALSE;
  19890     return SOC_E_NONE;
  19891 #else
  19892     return SOC_E_UNAVAIL;
  19893 #endif
  19894 }
  19895 
  19896 
  19897 #endif
  19898 
  19899 /*
  19900  * Function:
  19901  *      soc_td2x_ser_single_bit_error_enable_set
  19902  * Purpose:
  19903  *      Enable/Disable single bit eror reporting for the memories which are
  19904  *      protected by ECC logic and whoes SER_RESPONSE is SER_NONE on TD2/TD2p chips
  19905  * Parameters:
  19906  *      unit        - (IN) Device Number
  19907  *      enable         - (IN) Enable/Disable
  19908  * Returns:
  19909  *      SOC_E_NONE if set successfully, an error otherwise
  19910  */
  19911 int soc_td2x_ser_single_bit_error_enable_set(int unit, int enable)
  19912 {
  19913     int rv = SOC_E_NONE;
  19914 
  19915 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19916     if (SOC_IS_TD2P_TT2P(unit)) {
  19917         rv = soc_trident2p_ser_single_bit_error_set(unit, enable);
  19918     } else
  19919 #endif
  19920     {
  19921         rv = soc_trident2_ser_single_bit_error_set(unit, enable);
  19922     }
  19923     return rv;
  19924 }
  19925 
  19926 /*
  19927  * Function:
  19928  *      soc_td2x_ser_single_bit_error_enable_get
  19929  * Purpose:
  19930  *      Get the status of single bit eror reporting for the memories which are
  19931  *      protected by ECC logic and whoes SER_RESPONSE is SER_NONE on TD2/TD2p chips
  19932  * Parameters:
  19933  *      unit        - (IN) Device Number
  19934  *      enable         - (OUT) Enable/Disable
  19935  * Returns:
  19936  *      SOC_E_NONE if get successfully, an error otherwise
  19937  */
  19938 int soc_td2x_ser_single_bit_error_enable_get(int unit, int *enable)
  19939 {
  19940     int rv = SOC_E_NONE;
  19941 
  19942 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  19943     if (SOC_IS_TD2P_TT2P(unit)) {
  19944         rv = soc_trident2p_ser_single_bit_error_get(unit, enable);
  19945     } else
  19946 #endif
  19947     {
  19948         rv = soc_trident2_ser_single_bit_error_get(unit, enable);
  19949     }
  19950     return rv;
  19951 }
  19952 
  19953 #endif /* BCM_TRIDENT2_SUPPORT */