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, ®_val); 4570 } else { 4571 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, ®_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, ®_data)); 19734 soc_reg_field_set(unit, DLB_HGT_SER_CONTROLr, ®_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 */