ser.c (381938B)
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: ser.c 8 * Purpose: SER enable/detect and test functionality. 9 * Requires: sal/soc/shared layer 10 */ 11 12 13 #include <shared/bsl.h> 14 #include <soc/drv.h> 15 #include <soc/error.h> 16 #include <soc/debug.h> 17 #include <soc/mem.h> 18 #include <soc/iproc.h> 19 #include <soc/intr.h> 20 #ifdef BCM_CMICX_SUPPORT 21 #include <soc/intr_cmicx.h> 22 #endif 23 #ifdef ALPM_ENABLE 24 #include <soc/esw/alpm_int.h> 25 #endif 26 27 #ifdef BCM_TRIDENT3_SUPPORT 28 29 #include <soc/soc_ser_log.h> 30 #include <soc/trident3.h> 31 #include <bcm_int/common/field.h> 32 33 #define _SOC_TD3_IFP_SLICE_MODE_NARROW 0 34 #define _SOC_TD3_IFP_SLICE_MODE_WIDE 1 35 36 #define _SOC_MMU_BASE_INDEX_GLB 0 37 #define _SOC_MMU_BASE_INDEX_XPE 0 38 #define _SOC_MMU_BASE_INDEX_SC 0 39 #define _SOC_MMU_BASE_INDEX_SED 0 40 41 #define _SOC_MMU_ADDR_ZERO_OUT_SEG_FIELD 0xfffc7fff /* [17:15] = 3'b000 */ 42 43 #define _SOC_TD3_ACC_TYPE_UNIQUE_PIPE0 0 44 #define _SOC_TD3_ACC_TYPE_UNIQUE_PIPE1 1 45 #define _SOC_TD3_ACC_TYPE_SINGLE 20 46 #define _SOC_TD3_ACC_TYPE_DUPLICATE 9 47 #define _SOC_TD3_ACC_TYPE_ADDR_SPLIT_DIST 10 48 #define _SOC_TD3_ACC_TYPE_ADDR_SPLIT_SPLIT 12 49 #define _SOC_TD3_ACC_TYPE_DATA_SPLIT 14 50 #define _SOC_TD3_ACC_TYPE_NAME(at) \ 51 (at == _SOC_TD3_ACC_TYPE_UNIQUE_PIPE0) ? "AT_UNIQUE_PIPE0" : \ 52 (at == _SOC_TD3_ACC_TYPE_UNIQUE_PIPE1) ? "AT_UNIQUE_PIPE1" : \ 53 (at == _SOC_TD3_ACC_TYPE_SINGLE) ? "AT_SINGLE" : \ 54 (at == _SOC_TD3_ACC_TYPE_DUPLICATE) ? "AT_DUPLICATE" : \ 55 (at == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_DIST) ? "AT_ADDR_SPLIT_DIST" : \ 56 (at == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_SPLIT) ? "AT_ADDR_SPLIT_SPLIT" : \ 57 (at == _SOC_TD3_ACC_TYPE_DATA_SPLIT) ? "AT_DATA_SPLIT" : \ 58 "AT_UNKNOWN" 59 60 #define _SOC_TD3_CEV_INTR 0x00000001 61 #define _SOC_TD3_IPIPE0_IDB_INTR 0x00000080 62 #define _SOC_TD3_IPIPE1_IDB_INTR 0x00000100 63 #define _SOC_TD3_IPIPE0_ISW4_INTR 0x00000800 64 #define _SOC_TD3_IPIPE1_ISW4_INTR 0x00001000 65 66 typedef struct _soc_td3_ser_mmu_intr_info_s { 67 soc_reg_t int_statf; 68 int mmu_base_index; 69 int ser_info_index; 70 } _soc_td3_ser_mmu_intr_info_t; 71 72 73 typedef struct _soc_td3_ser_route_block_s { 74 uint8 cmic_reg; /* 3: intr3, 4: intr4, 5: intr5 */ 75 uint32 cmic_bit; 76 soc_block_t blocktype; 77 int pipe; 78 soc_reg_t enable_reg; 79 soc_reg_t status_reg; 80 soc_field_t enable_field; 81 void *info; 82 uint8 id; 83 } _soc_td3_ser_route_block_t; 84 85 typedef struct _soc_td3_tcam_wrapper_info_s { 86 soc_mem_t mem; 87 soc_reg_t enable_reg; 88 soc_field_t enable_field; 89 soc_field_t parity_field; /* used to sw inject test */ 90 } _soc_td3_tcam_wrapper_info_t; 91 92 #if defined(BCM_56870_A0) 93 extern _soc_bus_ser_en_info_t _soc_bcm56870_a0_ip_bus_ser_info[]; 94 extern _soc_buffer_ser_en_info_t _soc_bcm56870_a0_ip_buffer_ser_info[]; 95 extern _soc_bus_ser_en_info_t _soc_bcm56870_a0_ep_bus_ser_info[]; 96 extern _soc_buffer_ser_en_info_t _soc_bcm56870_a0_ep_buffer_ser_info[]; 97 #endif 98 99 typedef struct _soc_td3_tmp_ser_info_s { 100 soc_reg_t enable_reg; 101 soc_field_t enable_field; 102 uint32 value; 103 } _soc_td3_tmp_ser_info_t; 104 105 typedef struct _soc_td3_hash_table_ser_info_s { 106 soc_mem_t mem; 107 soc_field_t enable_field; 108 } _soc_td3_hash_table_ser_info_t; 109 110 static soc_ser_functions_t _td3_ser_functions; 111 112 _soc_bus_buffer_ser_force_info_t ser_td3_bus_buffer_skip_test[] = { 113 { "DPP_OUTPUT_EVENT_FIFO", SW4_SER_CONTROLr, EVENT_FIFO_ECC_FORCE_ERRf }, 114 { "SLOT_PIPELINE", SW4_SER_CONTROLr, SLOT_PIPELINE_ECC_FORCE_ERRf }, 115 { "SOP_EVENT_BUFFER", IDB_SER_CONTROLr, SOP_EVENT_ECC_CORRUPTf }, 116 { "EOP_EVENT_BUFFER", IDB_SER_CONTROLr, EOP_EVENT_ECC_CORRUPTf }, 117 { "MGMT_CELL_ASSEM_BUFFER", IDB_SER_CONTROLr, CA_MGMT_ECC_CORRUPTf }, 118 { "", INVALIDr } /* end */ 119 }; 120 121 uint32 ser_td3_bus_buffer_hwbase[] = { 122 0x1b, /* IRSEL2_BUS */ 123 0x14, /* IPARS2_BUS */ 124 0x2b, /* ICFG_ISW3_PT_BUS */ 125 0x5e, /* EVLAN_BUS */ 126 0, /* DPP_OUTPUT_EVENT_FIFO */ 127 0x2c, /* IRSEL1_FPEM_DELAY_BUFFER */ 128 0x75, /* EFP_DATA_PT_BUF */ 129 0x9, /* ISW3_EOP_BUFFER_B */ 130 0, /* MGMT_CELL_ASSEM_BUFFER */ 131 0x26, /* IFWD2_PT_BUF */ 132 0, /* SLOT_PIPELINE */ 133 0x77, /* EGR_VLAN_HWY2 */ 134 0x41, /* EP_INITBUF_RAM_WRAPPER */ 135 0x11, /* IPARS1_BUS */ 136 0x40, /* INGRESS_PACKET_BUFFER */ 137 0x5a, /* EVLAN_BUS */ 138 0x23, /* IPARS2_PT_BUF */ 139 0x19, /* ISW1_BUS */ 140 0x21, /* IVXLT1_PT_BUF */ 141 0x18, /* IRSEL1_PT_BUS */ 142 0x1a, /* IFP_BUS */ 143 0x79, /* EGR_EL3_HWY2 */ 144 0x15, /* IVXLT2_BUS */ 145 0, /* EOP_EVENT_BUFFER */ 146 0x78, /* EGR_EL3_HWY1 */ 147 0x12, /* IVXLT1_BUS */ 148 0x29, /* IRSEL2_PT_BUS */ 149 0x5c, /* EFP_BUS */ 150 0x3a, /* RSEL1_FLEX_CTR_BUS_FIFO */ 151 0x18, /* IRSEL1_BUS */ 152 0x1c, /* ISW2_BUS */ 153 0x13, /* IVP_BUS */ 154 0x22, /* IVP_PT_BUF */ 155 0x39, /* IPARS2_PT_BUF1 */ 156 0x5b, /* EPMOD_BUS */ 157 0x28, /* IFP_PT_BUF */ 158 0, /* SOP_EVENT_BUFFER */ 159 0x40, /* IP_PACKET_BUFFER */ 160 0x17, /* IFWD2_BUS */ 161 0x25, /* IFWD1_PT_BUS */ 162 0x24, /* IVXLT2_PT_BUF */ 163 0x76, /* EGR_VLAN_HWY1 */ 164 0, /* CELL_QUEUE */ 165 0x16, /* IFWD1_BUS */ 166 0x2a /* ISW2_PT_BUS */ 167 }; 168 169 static soc_field_t _soc_td3_mmu_xpe_enable_fields[] = { 170 AGING_PARITY_ENf, 171 TCB_PARITY_ENf, 172 THDM_PARITY_ENf, 173 ENQX_PARITY_ENf, 174 EPRG_PARITY_ENf, 175 RQE_PARITY_ENf, 176 THDI_PARITY_ENf, 177 THDU_PARITY_ENf, 178 PQE_PARITY_ENf, 179 WRED_PARITY_ENf, 180 DQX_PARITY_ENf, 181 CCP_PARITY_ENf, 182 CTR_PARITY_ENf, 183 INVALIDf 184 }; 185 186 static soc_field_t _soc_td3_mmu_sc_enable_fields[] = { 187 TDM_PARITY_ENf, 188 VBS_PARITY_ENf, 189 TOQ_PARITY_ENf, 190 INVALIDf 191 }; 192 193 static soc_field_t _soc_td3_mmu_sed_enable_fields[] = { 194 MB0_PARITY_ENf, 195 MB1_PARITY_ENf, 196 ENQS_PARITY_ENf, 197 MTRO_PARITY_ENf, 198 DQS_PARITY_ENf, 199 CFAP_PARITY_ENf, 200 INVALIDf 201 }; 202 203 static soc_field_t _soc_td3_mmu_sed_int_enable_fields[] = { 204 CFAP_MEM_FAIL_ENf, 205 MEM_PAR_ERR_ENf, 206 INVALIDf 207 }; 208 static soc_field_t _soc_td3_mmu_sed_int_status_fields[] = { 209 CFAP_MEM_FAIL_STATf, 210 MEM_PAR_ERR_STATf, 211 INVALIDf 212 }; 213 static soc_field_t _soc_td3_mmu_sed_int_clr_fields[] = { 214 CFAP_MEM_FAIL_CLRf, 215 MEM_PAR_ERR_CLRf, 216 INVALIDf 217 }; 218 219 static _soc_td3_ser_info_t _soc_td3_mmu_ser_info[] = { 220 { _SOC_TD3_PARITY_TYPE_MMU_GLB, NULL, 0, 221 INVALIDf, INVALIDf, 222 INVALIDm, "MMU GLB MEM PAR", 223 MMU_GCFG_PARITY_ENr, INTFO_PARITY_ENf, NULL, 224 MMU_GCFG_GLB_CPU_INT_ENr, MEM_PAR_ERR_ENf, NULL, 225 MMU_GCFG_GLB_CPU_INT_STATr, NULL, MEM_PAR_ERR_STATf, NULL, 226 MMU_GCFG_GLB_CPU_INT_CLEARr, MEM_PAR_ERR_CLRf, NULL 227 }, 228 { _SOC_TD3_PARITY_TYPE_MMU_XPE, NULL, 0, 229 INVALIDf, INVALIDf, 230 INVALIDm, "MMU XPE MEM PAR", 231 MMU_XCFG_PARITY_ENr, INVALIDf, _soc_td3_mmu_xpe_enable_fields, 232 MMU_XCFG_XPE_CPU_INT_ENr, MEM_PAR_ERR_ENf, NULL, 233 MMU_XCFG_XPE_CPU_INT_STATr, NULL, MEM_PAR_ERR_STATf, NULL, 234 MMU_XCFG_XPE_CPU_INT_CLEARr, MEM_PAR_ERR_CLRf, NULL 235 }, 236 { _SOC_TD3_PARITY_TYPE_MMU_SC, NULL, 0, 237 INVALIDf, INVALIDf, 238 INVALIDm, "MMU SC MEM PAR", 239 MMU_SCFG_PARITY_ENr, INVALIDf, _soc_td3_mmu_sc_enable_fields, 240 MMU_SCFG_SC_CPU_INT_ENr, MEM_PAR_ERR_ENf, NULL, 241 MMU_SCFG_SC_CPU_INT_STATr, NULL, MEM_PAR_ERR_STATf/*INVALIDf*/, 242 NULL/*_soc_td3_mmu_sc_status_fields*/, 243 MMU_SCFG_SC_CPU_INT_CLEARr, MEM_PAR_ERR_CLRf/*INVALIDf*/, 244 NULL/*_soc_td3_mmu_sc_clr_fields*/ 245 }, 246 { _SOC_TD3_PARITY_TYPE_MMU_SED, NULL, 0, 247 INVALIDf, INVALIDf, 248 INVALIDm, "MMU SED MEM PAR", 249 MMU_SEDCFG_PARITY_ENr, INVALIDf, _soc_td3_mmu_sed_enable_fields, 250 MMU_SEDCFG_SED_CPU_INT_ENr, INVALIDf, 251 _soc_td3_mmu_sed_int_enable_fields, 252 MMU_SEDCFG_SED_CPU_INT_STATr, NULL, INVALIDf, 253 _soc_td3_mmu_sed_int_status_fields, 254 MMU_SEDCFG_SED_CPU_INT_CLEARr, INVALIDf, 255 _soc_td3_mmu_sed_int_clr_fields 256 }, 257 { _SOC_TD3_PARITY_TYPE_NONE } /* table terminator */ 258 }; 259 260 static soc_field_t _soc_td3_mmu_top_int_enable_fields[] = { 261 SED_CPU_INT_ENf, 262 SC_CPU_INT_ENf, 263 XPE_CPU_INT_ENf, 264 GLB_CPU_INT_ENf, 265 INVALIDf 266 }; 267 268 static soc_field_t _soc_td3_mmu_top_int_status_fields[] = { 269 SED_CPU_INT_STATf, 270 SC_CPU_INT_STATf, 271 XPE_CPU_INT_STATf, 272 GLB_CPU_INT_STATf, 273 INVALIDf 274 }; 275 276 static _soc_td3_ser_info_t _soc_td3_mmu_top_ser_info[] = { 277 { _SOC_TD3_PARITY_TYPE_MMU_SER, _soc_td3_mmu_ser_info, 0, 278 INVALIDf, INVALIDf, 279 INVALIDm, "MMU MEM PAR", 280 INVALIDr, INVALIDf, NULL, 281 MMU_GCFG_ALL_CPU_INT_ENr, INVALIDf, 282 _soc_td3_mmu_top_int_enable_fields, 283 MMU_GCFG_ALL_CPU_INT_STATr, 284 NULL, INVALIDf, _soc_td3_mmu_top_int_status_fields, 285 INVALIDr, INVALIDf, NULL 286 }, 287 { _SOC_TD3_PARITY_TYPE_NONE } /* table terminator */ 288 }; 289 290 static const 291 _soc_td3_ser_mmu_intr_info_t mmu_intr_info[] = { 292 { GLB_CPU_INT_STATf, _SOC_MMU_BASE_INDEX_GLB, 0 }, 293 { XPE_CPU_INT_STATf, _SOC_MMU_BASE_INDEX_XPE, 1 }, 294 { SC_CPU_INT_STATf, _SOC_MMU_BASE_INDEX_SC, 2 }, 295 { SED_CPU_INT_STATf, _SOC_MMU_BASE_INDEX_SED, 3}, 296 { INVALIDf, -1, -1 } 297 }; 298 299 static _soc_td3_ser_reg_t _soc_td3_pm_clp_rx_status_reg[] = { 300 { CLPORT_MIB_RSC0_ECC_STATUSr, "CLP MIB RSC0 ECC" }, 301 { CLPORT_MIB_RSC1_ECC_STATUSr, "CLP MIB RSC1 ECC" }, 302 { INVALIDr, "INVALIDr"} 303 }; 304 305 static _soc_td3_ser_reg_t _soc_td3_pm_clp_tx_status_reg[] = { 306 { CLPORT_MIB_TSC0_ECC_STATUSr, "CLP MIB TSC0 ECC" }, 307 { CLPORT_MIB_TSC1_ECC_STATUSr, "CLP MIB TSC1 ECC" }, 308 { INVALIDr, "INVALIDr"} 309 }; 310 311 static _soc_td3_ser_reg_t _soc_td3_pm_xlp_rx_status_reg[] = { 312 { XLPORT_MIB_RSC0_ECC_STATUSr, "XLP MIB RSC0 ECC" }, 313 { XLPORT_MIB_RSC1_ECC_STATUSr, "XLP MIB RSC1 ECC" }, 314 { INVALIDr, "INVALIDr"} 315 }; 316 317 static _soc_td3_ser_reg_t _soc_td3_pm_xlp_tx_status_reg[] = { 318 { XLPORT_MIB_TSC0_ECC_STATUSr, "XLP MIB TSC0 ECC" }, 319 { XLPORT_MIB_TSC1_ECC_STATUSr, "XLP MIB TSC1 ECC" }, 320 { INVALIDr, "INVALIDr"} 321 }; 322 323 static _soc_td3_ser_info_t _soc_td3_pm_clp_ser_info[] = { 324 { _SOC_TD3_PARITY_TYPE_CLMAC, NULL, 0, 325 MAC_ERRf, MAC_ERRf, 326 INVALIDm, "MAC RX TimeStamp CDC memory", 327 CLMAC_ECC_CTRLr, RX_TS_MEM_ECC_CTRL_ENf, NULL, 328 CLMAC_INTR_ENABLEr, EN_RX_TS_MEM_SINGLE_BIT_ERRf, NULL, 329 CLMAC_INTR_STATUSr, NULL, SUM_RX_TS_MEM_SINGLE_BIT_ERRf, NULL, 330 CLMAC_CLEAR_ECC_STATUSr, CLEAR_RX_TS_MEM_SINGLE_BIT_ERRf, NULL 331 }, 332 { _SOC_TD3_PARITY_TYPE_CLMAC, NULL, 0, 333 MAC_ERRf, MAC_ERRf, 334 INVALIDm, "MAC RX TimeStamp CDC memory", 335 CLMAC_ECC_CTRLr, RX_TS_MEM_ECC_CTRL_ENf, NULL, 336 CLMAC_INTR_ENABLEr, EN_RX_TS_MEM_DOUBLE_BIT_ERRf, NULL, 337 CLMAC_INTR_STATUSr, NULL, SUM_RX_TS_MEM_DOUBLE_BIT_ERRf, NULL, 338 CLMAC_CLEAR_ECC_STATUSr, CLEAR_RX_TS_MEM_DOUBLE_BIT_ERRf, NULL 339 }, 340 { _SOC_TD3_PARITY_TYPE_CLMAC, NULL, 0, 341 MAC_ERRf, MAC_ERRf, 342 INVALIDm, "CLMAC RX CDC single bit", 343 CLMAC_ECC_CTRLr, RX_CDC_ECC_CTRL_ENf, NULL, 344 CLMAC_INTR_ENABLEr, EN_RX_CDC_SINGLE_BIT_ERRf, NULL, 345 CLMAC_INTR_STATUSr, NULL, SUM_RX_CDC_SINGLE_BIT_ERRf, NULL, 346 CLMAC_CLEAR_ECC_STATUSr, CLEAR_RX_CDC_SINGLE_BIT_ERRf, NULL 347 }, 348 { _SOC_TD3_PARITY_TYPE_CLMAC, NULL, 0, 349 MAC_ERRf, MAC_ERRf, 350 INVALIDm, "CLMAC RX CDC double bits", 351 CLMAC_ECC_CTRLr, RX_CDC_ECC_CTRL_ENf, NULL, 352 CLMAC_INTR_ENABLEr, EN_RX_CDC_DOUBLE_BIT_ERRf, NULL, 353 CLMAC_INTR_STATUSr, NULL, SUM_RX_CDC_DOUBLE_BIT_ERRf, NULL, 354 CLMAC_CLEAR_ECC_STATUSr, CLEAR_RX_CDC_DOUBLE_BIT_ERRf, NULL 355 }, 356 { _SOC_TD3_PARITY_TYPE_CLMAC, NULL, 0, 357 MAC_ERRf, MAC_ERRf, 358 INVALIDm, "CLMAC TX CDC single bit", 359 CLMAC_ECC_CTRLr, TX_CDC_ECC_CTRL_ENf, NULL, 360 CLMAC_INTR_ENABLEr, EN_TX_CDC_SINGLE_BIT_ERRf, NULL, 361 CLMAC_INTR_STATUSr, NULL, SUM_TX_CDC_SINGLE_BIT_ERRf, NULL, 362 CLMAC_CLEAR_ECC_STATUSr, CLEAR_TX_CDC_SINGLE_BIT_ERRf, NULL 363 }, 364 { _SOC_TD3_PARITY_TYPE_CLMAC, NULL, 0, 365 MAC_ERRf, MAC_ERRf, 366 INVALIDm, "CLMAC TX CDC double bits", 367 CLMAC_ECC_CTRLr, TX_CDC_ECC_CTRL_ENf, NULL, 368 CLMAC_INTR_ENABLEr, EN_TX_CDC_DOUBLE_BIT_ERRf, NULL, 369 CLMAC_INTR_STATUSr, NULL, SUM_TX_CDC_DOUBLE_BIT_ERRf, NULL, 370 CLMAC_CLEAR_ECC_STATUSr, CLEAR_TX_CDC_DOUBLE_BIT_ERRf, NULL 371 }, 372 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 373 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 374 INVALIDm, "MIB RX Statistic Counter memory", 375 CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, NULL, 376 INVALIDr, INVALIDf, NULL, 377 INVALIDr, _soc_td3_pm_clp_rx_status_reg, INVALIDf, NULL, 378 CLPORT_INTR_STATUSr, MIB_RX_MEM_ERRf, NULL 379 }, 380 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 381 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 382 INVALIDm, "MIB TX Statistic Counter memory", 383 CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, NULL, 384 INVALIDr, INVALIDf, NULL, 385 INVALIDr, _soc_td3_pm_clp_tx_status_reg, INVALIDf, NULL, 386 CLPORT_INTR_STATUSr, MIB_TX_MEM_ERRf, NULL 387 }, 388 { _SOC_TD3_PARITY_TYPE_NONE } /* table terminator */ 389 }; 390 391 static _soc_td3_ser_info_t _soc_td3_pm_xlp_ser_info[] = { 392 { _SOC_TD3_PARITY_TYPE_XLMAC, NULL, 0, 393 MAC_ERRf, MAC_ERRf, 394 INVALIDm, "MAC RX CDC memory", 395 XLMAC_ECC_CTRLr, RX_CDC_ECC_CTRL_ENf, NULL, 396 XLMAC_INTR_ENABLEr, EN_RX_CDC_SINGLE_BIT_ERRf, NULL, 397 XLMAC_INTR_STATUSr, NULL, SUM_RX_CDC_SINGLE_BIT_ERRf, NULL, 398 XLMAC_CLEAR_ECC_STATUSr, CLEAR_RX_CDC_SINGLE_BIT_ERRf, NULL 399 }, 400 { _SOC_TD3_PARITY_TYPE_XLMAC, NULL, 0, 401 MAC_ERRf, MAC_ERRf, 402 INVALIDm, "MAC RX CDC memory", 403 XLMAC_ECC_CTRLr, RX_CDC_ECC_CTRL_ENf, NULL, 404 XLMAC_INTR_ENABLEr, EN_RX_CDC_DOUBLE_BIT_ERRf, NULL, 405 XLMAC_INTR_STATUSr, NULL, SUM_RX_CDC_DOUBLE_BIT_ERRf, NULL, 406 XLMAC_CLEAR_ECC_STATUSr, CLEAR_RX_CDC_DOUBLE_BIT_ERRf, NULL 407 }, 408 { _SOC_TD3_PARITY_TYPE_XLMAC, NULL, 0, 409 MAC_ERRf, MAC_ERRf, 410 INVALIDm, "MAC RX CDC memory", 411 XLMAC_ECC_CTRLr, TX_CDC_ECC_CTRL_ENf, NULL, 412 XLMAC_INTR_ENABLEr, EN_TX_CDC_SINGLE_BIT_ERRf, NULL, 413 XLMAC_INTR_STATUSr, NULL, SUM_TX_CDC_SINGLE_BIT_ERRf, NULL, 414 XLMAC_CLEAR_ECC_STATUSr, CLEAR_TX_CDC_SINGLE_BIT_ERRf, NULL 415 }, 416 { _SOC_TD3_PARITY_TYPE_XLMAC, NULL, 0, 417 MAC_ERRf, MAC_ERRf, 418 INVALIDm, "MAC TX CDC memory", 419 XLMAC_ECC_CTRLr, TX_CDC_ECC_CTRL_ENf, NULL, 420 XLMAC_INTR_ENABLEr, EN_TX_CDC_DOUBLE_BIT_ERRf, NULL, 421 XLMAC_INTR_STATUSr, NULL, SUM_TX_CDC_DOUBLE_BIT_ERRf, NULL, 422 XLMAC_CLEAR_ECC_STATUSr, CLEAR_TX_CDC_DOUBLE_BIT_ERRf, NULL 423 }, 424 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 425 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 426 INVALIDm, "MIB RX Statistic Counter memory", 427 XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, NULL, 428 INVALIDr, INVALIDf, NULL, 429 INVALIDr, _soc_td3_pm_xlp_rx_status_reg, INVALIDf, NULL, 430 XLPORT_INTR_STATUSr, MIB_RX_MEM_ERRf, NULL 431 }, 432 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 433 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 434 INVALIDm, "MIB TX Statistic Counter memory", 435 XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, NULL, 436 INVALIDr, INVALIDf, NULL, 437 INVALIDr, _soc_td3_pm_xlp_tx_status_reg, INVALIDf, NULL, 438 XLPORT_INTR_STATUSr, MIB_TX_MEM_ERRf, NULL 439 }, 440 { _SOC_TD3_PARITY_TYPE_NONE } /* table terminator */ 441 }; 442 443 static _soc_td3_ser_reg_t _soc_td3_idb_status_reg[] = { 444 { IDB_OBM0_OVERSUB_MON_ECC_STATUSr, "IDB OBM0 oversub Monitoring memory" }, 445 { IDB_OBM1_OVERSUB_MON_ECC_STATUSr, "IDB OBM1 oversub Monitoring memory" }, 446 { IDB_OBM2_OVERSUB_MON_ECC_STATUSr, "IDB OBM2 oversub Monitoring memory" }, 447 { IDB_OBM3_OVERSUB_MON_ECC_STATUSr, "IDB OBM3 oversub Monitoring memory" }, 448 { IDB_OBM4_OVERSUB_MON_ECC_STATUSr, "IDB OBM4 oversub Monitoring memory" }, 449 { IDB_OBM5_OVERSUB_MON_ECC_STATUSr, "IDB OBM5 oversub Monitoring memory" }, 450 { IDB_OBM6_OVERSUB_MON_ECC_STATUSr, "IDB OBM6 oversub Monitoring memory" }, 451 { IDB_OBM7_OVERSUB_MON_ECC_STATUSr, "IDB OBM7 oversub Monitoring memory" }, 452 { IDB_OBM8_OVERSUB_MON_ECC_STATUSr, "IDB OBM8 oversub Monitoring memory" }, 453 { IDB_OBM9_OVERSUB_MON_ECC_STATUSr, "IDB OBM9 oversub Monitoring memory" }, 454 { IDB_OBM10_OVERSUB_MON_ECC_STATUSr, "IDB OBM10 oversub Monitoring memory" }, 455 { IDB_OBM11_OVERSUB_MON_ECC_STATUSr, "IDB OBM11 oversub Monitoring memory" }, 456 { IDB_OBM12_OVERSUB_MON_ECC_STATUSr, "IDB OBM12 oversub Monitoring memory" }, 457 { IDB_OBM13_OVERSUB_MON_ECC_STATUSr, "IDB OBM13 oversub Monitoring memory" }, 458 { IDB_OBM14_OVERSUB_MON_ECC_STATUSr, "IDB OBM14 oversub Monitoring memory" }, 459 { IDB_OBM15_OVERSUB_MON_ECC_STATUSr, "IDB OBM15 oversub Monitoring memory" }, 460 { IDB_CA_CPU_ECC_STATUSr, "CA-CPU packet buffer memory" }, 461 { IDB_CA_LPBK_ECC_STATUSr, "CA-LPBK packet buffer memory" }, 462 { IDB_IS_TDM_CAL_ECC_STATUSr, "IDB IS_TDM0,1 calendar" }, 463 { IDB_SOP_EVENT_ECC_STATUSr, "IDB SOP Event Fifo ECC Status" }, 464 { IDB_EOP_EVENT_ECC_STATUSr, "IDB EOP Event Fifo ECC Status" }, 465 { INVALIDr } 466 }; 467 468 static _soc_td3_ser_info_t _soc_td3_idb_ser_info[] = { 469 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 470 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 471 INVALIDm, "OBM0 DATA FIFO", 472 IDB_OBM0_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 473 INVALIDr, INVALIDf, NULL, 474 IDB_OBM0_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 475 INVALIDr, INVALIDf, NULL 476 }, 477 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 478 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 479 INVALIDm, "OBM1 DATA FIFO", 480 IDB_OBM1_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 481 INVALIDr, INVALIDf, NULL, 482 IDB_OBM1_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 483 INVALIDr, INVALIDf, NULL 484 }, 485 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 486 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 487 INVALIDm, "OBM2 DATA FIFO", 488 IDB_OBM2_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 489 INVALIDr, INVALIDf, NULL, 490 IDB_OBM2_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 491 INVALIDr, INVALIDf, NULL 492 }, 493 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 494 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 495 INVALIDm, "OBM3 DATA FIFO", 496 IDB_OBM3_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 497 INVALIDr, INVALIDf, NULL, 498 IDB_OBM3_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 499 INVALIDr, INVALIDf, NULL 500 }, 501 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 502 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 503 INVALIDm, "OBM4 DATA FIFO", 504 IDB_OBM4_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 505 INVALIDr, INVALIDf, NULL, 506 IDB_OBM4_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 507 INVALIDr, INVALIDf, NULL 508 }, 509 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 510 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 511 INVALIDm, "OBM5 DATA FIFO", 512 IDB_OBM5_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 513 INVALIDr, INVALIDf, NULL, 514 IDB_OBM5_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 515 INVALIDr, INVALIDf, NULL 516 }, 517 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 518 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 519 INVALIDm, "OBM6 DATA FIFO", 520 IDB_OBM6_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 521 INVALIDr, INVALIDf, NULL, 522 IDB_OBM6_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 523 INVALIDr, INVALIDf, NULL 524 }, 525 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 526 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 527 INVALIDm, "OBM7 DATA FIFO", 528 IDB_OBM7_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 529 INVALIDr, INVALIDf, NULL, 530 IDB_OBM7_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 531 INVALIDr, INVALIDf, NULL 532 }, 533 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 534 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 535 INVALIDm, "OBM8 DATA FIFO", 536 IDB_OBM8_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 537 INVALIDr, INVALIDf, NULL, 538 IDB_OBM8_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 539 INVALIDr, INVALIDf, NULL 540 }, 541 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 542 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 543 INVALIDm, "OBM9 DATA FIFO", 544 IDB_OBM9_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 545 INVALIDr, INVALIDf, NULL, 546 IDB_OBM9_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 547 INVALIDr, INVALIDf, NULL 548 }, 549 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 550 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 551 INVALIDm, "OBM10 DATA FIFO", 552 IDB_OBM10_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 553 INVALIDr, INVALIDf, NULL, 554 IDB_OBM10_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 555 INVALIDr, INVALIDf, NULL 556 }, 557 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 558 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 559 INVALIDm, "OBM11 DATA FIFO", 560 IDB_OBM11_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 561 INVALIDr, INVALIDf, NULL, 562 IDB_OBM11_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 563 INVALIDr, INVALIDf, NULL 564 }, 565 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 566 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 567 INVALIDm, "OBM12 DATA FIFO", 568 IDB_OBM12_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 569 INVALIDr, INVALIDf, NULL, 570 IDB_OBM12_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 571 INVALIDr, INVALIDf, NULL 572 }, 573 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 574 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 575 INVALIDm, "OBM13 DATA FIFO", 576 IDB_OBM13_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 577 INVALIDr, INVALIDf, NULL, 578 IDB_OBM13_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 579 INVALIDr, INVALIDf, NULL 580 }, 581 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 582 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 583 INVALIDm, "OBM14 DATA FIFO", 584 IDB_OBM14_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 585 INVALIDr, INVALIDf, NULL, 586 IDB_OBM14_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 587 INVALIDr, INVALIDf, NULL 588 }, 589 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 590 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 591 INVALIDm, "OBM15 DATA FIFO", 592 IDB_OBM15_SER_CONTROLr, DATA_ECC_ENABLEf, NULL, 593 INVALIDr, INVALIDf, NULL, 594 IDB_OBM15_DATA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 595 INVALIDr, INVALIDf, NULL 596 }, 597 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 598 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 599 INVALIDm, "OBM0 CELL ASSEM BUFFER", 600 IDB_OBM0_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 601 INVALIDr, INVALIDf, NULL, 602 IDB_OBM0_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 603 INVALIDr, INVALIDf, NULL 604 }, 605 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 606 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 607 INVALIDm, "OBM1 CELL ASSEM BUFFER", 608 IDB_OBM1_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 609 INVALIDr, INVALIDf, NULL, 610 IDB_OBM1_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 611 INVALIDr, INVALIDf, NULL 612 }, 613 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 614 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 615 INVALIDm, "OBM2 CELL ASSEM BUFFER", 616 IDB_OBM2_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 617 INVALIDr, INVALIDf, NULL, 618 IDB_OBM2_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 619 INVALIDr, INVALIDf, NULL 620 }, 621 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 622 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 623 INVALIDm, "OBM3 CELL ASSEM BUFFER", 624 IDB_OBM3_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 625 INVALIDr, INVALIDf, NULL, 626 IDB_OBM3_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 627 INVALIDr, INVALIDf, NULL 628 }, 629 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 630 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 631 INVALIDm, "OBM4 CELL ASSEM BUFFER", 632 IDB_OBM4_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 633 INVALIDr, INVALIDf, NULL, 634 IDB_OBM4_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 635 INVALIDr, INVALIDf, NULL 636 }, 637 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 638 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 639 INVALIDm, "OBM5 CELL ASSEM BUFFER", 640 IDB_OBM5_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 641 INVALIDr, INVALIDf, NULL, 642 IDB_OBM5_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 643 INVALIDr, INVALIDf, NULL 644 }, 645 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 646 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 647 INVALIDm, "OBM6 CELL ASSEM BUFFER", 648 IDB_OBM6_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 649 INVALIDr, INVALIDf, NULL, 650 IDB_OBM6_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 651 INVALIDr, INVALIDf, NULL 652 }, 653 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 654 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 655 INVALIDm, "OBM7 CELL ASSEM BUFFER", 656 IDB_OBM7_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 657 INVALIDr, INVALIDf, NULL, 658 IDB_OBM7_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 659 INVALIDr, INVALIDf, NULL 660 }, 661 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 662 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 663 INVALIDm, "OBM8 CELL ASSEM BUFFER", 664 IDB_OBM8_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 665 INVALIDr, INVALIDf, NULL, 666 IDB_OBM8_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 667 INVALIDr, INVALIDf, NULL 668 }, 669 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 670 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 671 INVALIDm, "OBM9 CELL ASSEM BUFFER", 672 IDB_OBM9_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 673 INVALIDr, INVALIDf, NULL, 674 IDB_OBM9_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 675 INVALIDr, INVALIDf, NULL 676 }, 677 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 678 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 679 INVALIDm, "OBM10 CELL ASSEM BUFFER", 680 IDB_OBM10_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 681 INVALIDr, INVALIDf, NULL, 682 IDB_OBM10_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 683 INVALIDr, INVALIDf, NULL 684 }, 685 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 686 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 687 INVALIDm, "OBM11 CELL ASSEM BUFFER", 688 IDB_OBM11_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 689 INVALIDr, INVALIDf, NULL, 690 IDB_OBM11_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 691 INVALIDr, INVALIDf, NULL 692 }, 693 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 694 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 695 INVALIDm, "OBM12 CELL ASSEM BUFFER", 696 IDB_OBM12_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 697 INVALIDr, INVALIDf, NULL, 698 IDB_OBM12_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 699 INVALIDr, INVALIDf, NULL 700 }, 701 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 702 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 703 INVALIDm, "OBM13 CELL ASSEM BUFFER", 704 IDB_OBM13_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 705 INVALIDr, INVALIDf, NULL, 706 IDB_OBM13_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 707 INVALIDr, INVALIDf, NULL 708 }, 709 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 710 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 711 INVALIDm, "OBM14 CELL ASSEM BUFFER", 712 IDB_OBM14_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 713 INVALIDr, INVALIDf, NULL, 714 IDB_OBM14_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 715 INVALIDr, INVALIDf, NULL 716 }, 717 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 718 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 719 INVALIDm, "OBM15 CELL ASSEM BUFFER", 720 IDB_OBM15_SER_CONTROLr, CA_FIFO_ECC_ENABLEf, NULL, 721 INVALIDr, INVALIDf, NULL, 722 IDB_OBM15_CA_ECC_STATUSr, NULL, ECC_ERRf, NULL, 723 INVALIDr, INVALIDf, NULL 724 }, 725 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 726 MEM_ERROR_OCCURREDf, MEM_ERROR_OCCURREDf, 727 INVALIDm, "IP IDB memory", 728 INVALIDr, INVALIDf, NULL, 729 INVALIDr, INVALIDf, NULL, 730 INVALIDr, _soc_td3_idb_status_reg, ECC_ERRf, NULL, 731 INVALIDr, INVALIDf, NULL 732 }, 733 734 { _SOC_TD3_PARITY_TYPE_NONE } /* table terminator */ 735 }; 736 737 static _soc_td3_ser_info_t _soc_td3_isw4_ser_info[] = { 738 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 739 SLOT_PIPELINE_ECC_ERRf, SLOT_PIPELINE_ECC_ERRf, 740 INVALIDm, "Slot pipeline", 741 INVALIDr, INVALIDf, NULL, 742 INVALIDr, INVALIDf, NULL, 743 SLOT_PIPELINE_ECC_STATUS_INTRr, NULL, ECC_ERRf, NULL, 744 INVALIDr, INVALIDf, NULL 745 }, 746 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 747 CELL_QUEUE_ECC_ERRf, CELL_QUEUE_ECC_ERRf, 748 INVALIDm, "Cell queue", 749 INVALIDr, INVALIDf, NULL, 750 INVALIDr, INVALIDf, NULL, 751 CELL_QUEUE_ECC_STATUS_INTRr, NULL, ECC_ERRf, NULL, 752 INVALIDr, INVALIDf, NULL 753 }, 754 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 755 EVENT_FIFO_ECC_ERRf, EVENT_FIFO_ECC_ERRf, 756 INVALIDm, "Event FIFO", 757 INVALIDr, INVALIDf, NULL, 758 INVALIDr, INVALIDf, NULL, 759 EVENT_FIFO_ECC_STATUS_INTRr, NULL, ECC_ERRf, NULL, 760 INVALIDr, INVALIDf, NULL 761 }, 762 763 { _SOC_TD3_PARITY_TYPE_NONE} /* table terminator */ 764 }; 765 766 static _soc_td3_ser_info_t _soc_td3_cev_ser_info[] = { 767 { _SOC_TD3_PARITY_TYPE_ECC, NULL, 0, 768 FIFO_PARITY_ERRORf, FIFO_PARITY_ERRORf, 769 INVALIDm, "Central fifo", 770 INVALIDr, INVALIDf, NULL, 771 INVALIDr, INVALIDf, NULL, 772 CENTRAL_CTR_EVICTION_INTR_STATUSr, NULL, FIFO_PARITY_ERRORf, NULL, 773 INVALIDr, INVALIDf, NULL 774 }, 775 776 { _SOC_TD3_PARITY_TYPE_NONE} /* table terminator */ 777 }; 778 779 /* Setup dynamically in enable ser */ 780 uint32 soc_td3_ip_pipe_fifo_bmask[SOC_MAX_NUM_DEVICES][2]={{0}}; 781 782 static const 783 _soc_td3_ser_route_block_t _soc_td3_ser_route_blocks[] = { 784 { 0, 0x00000001, /* CEV_TO_CMIC_INTR */ 785 SOC_BLK_IPIPE, -1, CENTRAL_CTR_EVICTION_INTR_ENABLEr, CENTRAL_CTR_EVICTION_INTR_STATUSr, INVALIDf, 786 _soc_td3_cev_ser_info, 0 }, 787 { 0, 0x00000010, /* MMU_TO_CMIC_MEMFAIL_INTR */ 788 SOC_BLK_MMU, -1, INVALIDr, INVALIDr, INVALIDf, 789 _soc_td3_mmu_top_ser_info, 0 }, 790 /* xsm: not using MMU_GLB or MMU_XPE or MMU_SC is on purpose */ 791 { 0, 0x00000020, /* PIPE0_EP_TO_CMIC_PERR_INTR */ 792 SOC_BLK_EPIPE, 0, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf, 793 NULL, 0 }, 794 { 0, 0x00000040, /* PIPE1_EP_TO_CMIC_PERR_INTR */ 795 SOC_BLK_EPIPE, 1, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf, 796 NULL, 0 }, 797 { 0, 0x00000080, /* PIPE0_IP0_TO_CMIC_PERR_INTR */ 798 /* Note: This is an exception for being legacy style in IP */ 799 SOC_BLK_IPIPE, 0, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, INVALIDf, 800 _soc_td3_idb_ser_info, 0 }, 801 { 0, 0x00000100, /* PIPE1_IP0_TO_CMIC_PERR_INTR */ 802 /* Note: This is an exception for being legacy style in IP */ 803 SOC_BLK_IPIPE, 1, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, INVALIDf, 804 _soc_td3_idb_ser_info, 0 }, 805 { 0, 0x00000200, /* PIPE0_IP_TO_CMIC_PERR_INTR */ 806 SOC_BLK_IPIPE, 0, INVALIDr, INVALIDr, INVALIDf, 807 NULL, 0 }, 808 { 0, 0x00000400, /* PIPE1_IP_TO_CMIC_PERR_INTR */ 809 SOC_BLK_IPIPE, 1, INVALIDr, INVALIDr, INVALIDf, 810 NULL, 0 }, 811 { 0, 0x00000800, /* PIPE0_ISW4_TO_CMIC_PERR_INTR */ 812 SOC_BLK_IPIPE, 0, ISW4_INTR_ENABLEr, ISW4_INTR_STATUSr, INVALIDf, 813 _soc_td3_isw4_ser_info, 0 }, 814 { 0, 0x00001000, /* PIPE1_ISW4_TO_CMIC_PERR_INTR */ 815 SOC_BLK_IPIPE, 1, ISW4_INTR_ENABLEr, ISW4_INTR_STATUSr, INVALIDf, 816 _soc_td3_isw4_ser_info, 0 }, 817 { 1, 0x00000001, /* PM0_INTR */ 818 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 819 _soc_td3_pm_clp_ser_info, 0 }, 820 { 1, 0x00000002, /* PM1_INTR */ 821 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 822 _soc_td3_pm_clp_ser_info, 1 }, 823 { 1, 0x00000004, /* PM2_INTR */ 824 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 825 _soc_td3_pm_clp_ser_info, 2 }, 826 { 1, 0x00000008, /* PM3_INTR */ 827 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 828 _soc_td3_pm_clp_ser_info, 3 }, 829 { 1, 0x00000010, /* PM4_INTR */ 830 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 831 _soc_td3_pm_clp_ser_info, 4 }, 832 { 1, 0x00000020, /* PM5_INTR */ 833 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 834 _soc_td3_pm_clp_ser_info, 5 }, 835 { 1, 0x00000040, /* PM6_INTR */ 836 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 837 _soc_td3_pm_clp_ser_info, 6 }, 838 { 1, 0x00000080, /* PM7_INTR */ 839 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 840 _soc_td3_pm_clp_ser_info, 7 }, 841 { 1, 0x00000100, /* PM8_INTR */ 842 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 843 _soc_td3_pm_clp_ser_info, 8 }, 844 { 1, 0x00000200, /* PM9_INTR */ 845 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 846 _soc_td3_pm_clp_ser_info, 9 }, 847 { 1, 0x00000400, /* PM10_INTR */ 848 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 849 _soc_td3_pm_clp_ser_info, 10 }, 850 { 1, 0x00000800, /* PM11_INTR */ 851 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 852 _soc_td3_pm_clp_ser_info, 11 }, 853 { 1, 0x00001000, /* PM12_INTR */ 854 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 855 _soc_td3_pm_clp_ser_info, 12 }, 856 { 1, 0x00002000, /* PM13_INTR */ 857 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 858 _soc_td3_pm_clp_ser_info, 13 }, 859 { 1, 0x00004000, /* PM14_INTR */ 860 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 861 _soc_td3_pm_clp_ser_info, 14 }, 862 { 1, 0x00008000, /* PM15_INTR */ 863 SOC_BLK_CLPORT, 0, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 864 _soc_td3_pm_clp_ser_info, 15 }, 865 { 1, 0x00010000, /* PM16_INTR */ 866 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 867 _soc_td3_pm_clp_ser_info, 16 }, 868 { 1, 0x00020000, /* PM17_INTR */ 869 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 870 _soc_td3_pm_clp_ser_info, 17 }, 871 { 1, 0x00040000, /* PM18_INTR */ 872 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 873 _soc_td3_pm_clp_ser_info, 18 }, 874 { 1, 0x00080000, /* PM19_INTR */ 875 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 876 _soc_td3_pm_clp_ser_info, 19 }, 877 { 1, 0x00100000, /* PM20_INTR */ 878 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 879 _soc_td3_pm_clp_ser_info, 20 }, 880 { 1, 0x00200000, /* PM21_INTR */ 881 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 882 _soc_td3_pm_clp_ser_info, 21 }, 883 { 1, 0x00400000, /* PM22_INTR */ 884 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 885 _soc_td3_pm_clp_ser_info, 22 }, 886 { 1, 0x00800000, /* PM23_INTR */ 887 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 888 _soc_td3_pm_clp_ser_info, 23 }, 889 { 1, 0x01000000, /* PM24_INTR */ 890 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 891 _soc_td3_pm_clp_ser_info, 24 }, 892 { 1, 0x02000000, /* PM25_INTR */ 893 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 894 _soc_td3_pm_clp_ser_info, 25 }, 895 { 1, 0x04000000, /* PM26_INTR */ 896 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 897 _soc_td3_pm_clp_ser_info, 26 }, 898 { 1, 0x08000000, /* PM27_INTR */ 899 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 900 _soc_td3_pm_clp_ser_info, 27 }, 901 { 1, 0x10000000, /* PM28_INTR */ 902 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 903 _soc_td3_pm_clp_ser_info, 28 }, 904 { 1, 0x20000000, /* PM29_INTR */ 905 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 906 _soc_td3_pm_clp_ser_info, 29 }, 907 { 1, 0x40000000, /* PM30_INTR */ 908 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 909 _soc_td3_pm_clp_ser_info, 30 }, 910 { 1, 0x80000000, /* PM31_INTR */ 911 SOC_BLK_CLPORT, 1, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 912 _soc_td3_pm_clp_ser_info, 31 }, 913 { 2, 0x00000001, /* PM32_INTR */ 914 SOC_BLK_XLPORT, 1, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 915 _soc_td3_pm_xlp_ser_info, 0 }, 916 { 0 } /* table terminator */ 917 }; 918 919 static _soc_generic_ser_info_t _soc_td3_tcam_ser_info_template[] = { 920 { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 921 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 922 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 923 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 924 { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 925 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 926 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 927 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 928 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 929 930 /* default_acc_type = DATA_SPLIT, but still need to scan each pipe separately */ 931 { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 932 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 933 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 934 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 935 { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 936 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 937 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 938 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 939 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 940 941 /* default_acc_type = DUPLICATE, so need to scan each pipe separately */ 942 { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 943 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 944 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 945 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 946 { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 947 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 948 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 949 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 950 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 951 952 /* default_acc_type = DUPLICATE, so need to scan each pipe separately */ 953 { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 954 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 955 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 956 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 957 { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 958 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 959 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 960 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 961 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 962 963 { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 964 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 965 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 966 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 967 { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 968 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 969 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 970 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 971 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 972 973 /* default_acc_type = DUPLICATE, so need to scan each pipe separately */ 974 { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 975 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 976 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 977 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 978 { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 979 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 980 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 981 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 982 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 983 984 /* default_acc_type = DUPLICATE, so need to scan each pipe separately */ 985 { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 986 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 987 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 988 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 989 { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 990 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 991 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 992 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 993 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 994 995 /* default_acc_type = DUPLICATE, so need to scan each pipe separately */ 996 { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 997 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 998 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 999 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1000 { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1001 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1002 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1003 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1004 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1005 1006 /* default_acc_type = DATA_SPLIT, but still need to scan each pipe separately */ 1007 { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1008 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1009 _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_MULTI_PIPE | 1010 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY | 1011 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1012 { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1013 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1014 _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_MULTI_PIPE | 1015 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY | 1016 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1017 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1018 1019 /* default_acc_type = DATA_SPLIT, but still need to scan each pipe separately */ 1020 { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1021 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1022 _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_MULTI_PIPE | 1023 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY | 1024 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1025 { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1026 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1027 _SOC_SER_FLAG_NO_DMA | _SOC_SER_FLAG_MULTI_PIPE | 1028 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY | 1029 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1030 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1031 1032 /* Global view */ 1033 { SRC_COMPRESSIONm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1034 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1035 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1036 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1037 { SRC_COMPRESSIONm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1038 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1039 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1040 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1041 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1042 1043 /* Global view */ 1044 { DST_COMPRESSIONm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1045 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1046 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1047 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1048 { DST_COMPRESSIONm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1049 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1050 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1051 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1052 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1053 1054 { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1055 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1056 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1057 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1058 { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1059 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1060 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1061 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1062 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1063 1064 { IFP_LOGICAL_TABLE_SELECTm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1065 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1066 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1067 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1068 { IFP_LOGICAL_TABLE_SELECTm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1069 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1070 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1071 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1072 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1073 1074 { EXACT_MATCH_LOGICAL_TABLE_SELECTm, INVALIDm, _SOC_SER_TYPE_PARITY, 1075 0, 0, 1076 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1077 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1078 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1079 { EXACT_MATCH_LOGICAL_TABLE_SELECTm, INVALIDm, _SOC_SER_TYPE_PARITY, 1080 0, 0, 1081 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1082 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1083 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1084 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1085 1086 { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1087 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1088 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1089 _SOC_SER_FLAG_XY_READ | _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 }, 1090 { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1091 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1092 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1093 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1094 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1095 1096 { IFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1097 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1098 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1099 _SOC_SER_FLAG_XY_READ | 1100 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1101 { IFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1102 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1103 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1104 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1105 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1106 1107 { IFP_TCAM_WIDEm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1108 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1109 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1110 _SOC_SER_FLAG_XY_READ | 1111 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1112 { IFP_TCAM_WIDEm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1113 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1114 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1115 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1116 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1117 1118 { PHB_SELECT_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1119 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1120 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1121 _SOC_SER_FLAG_XY_READ | 1122 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1123 { PHB_SELECT_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1124 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1125 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1126 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1127 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1128 1129 { FLEX_RTAG7_HASH_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1130 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1131 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1132 _SOC_SER_FLAG_XY_READ | 1133 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1134 { FLEX_RTAG7_HASH_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1135 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1136 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1137 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1138 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1139 1140 { PKT_FLOW_SELECT_TCAM_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1141 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1142 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1143 _SOC_SER_FLAG_XY_READ | 1144 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1145 { PKT_FLOW_SELECT_TCAM_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1146 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1147 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1148 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1149 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1150 1151 { PKT_FLOW_SELECT_TCAM_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1152 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1153 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1154 _SOC_SER_FLAG_XY_READ | 1155 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1156 { PKT_FLOW_SELECT_TCAM_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1157 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1158 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1159 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1160 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1161 1162 { PKT_FLOW_SELECT_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1163 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1164 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1165 _SOC_SER_FLAG_XY_READ | 1166 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1167 { PKT_FLOW_SELECT_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1168 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1169 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1170 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1171 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1172 1173 { FORWARDING_1_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1174 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1175 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1176 _SOC_SER_FLAG_XY_READ | 1177 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1178 { FORWARDING_1_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1179 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1180 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1181 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1182 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1183 1184 { FORWARDING_2_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1185 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1186 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1187 _SOC_SER_FLAG_XY_READ | 1188 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1189 { FORWARDING_2_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1190 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1191 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1192 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1193 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1194 1195 { FORWARDING_3_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1196 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1197 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1198 _SOC_SER_FLAG_XY_READ | 1199 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1200 { FORWARDING_3_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1201 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1202 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1203 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1204 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1205 1206 { TUNNEL_ADAPT_1_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1207 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1208 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1209 _SOC_SER_FLAG_XY_READ | 1210 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1211 { TUNNEL_ADAPT_1_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1212 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1213 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1214 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1215 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1216 1217 { TUNNEL_ADAPT_2_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1218 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1219 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1220 _SOC_SER_FLAG_XY_READ | 1221 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1222 { TUNNEL_ADAPT_2_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1223 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1224 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1225 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1226 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1227 1228 { TUNNEL_ADAPT_3_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1229 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1230 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1231 _SOC_SER_FLAG_XY_READ | 1232 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1233 { TUNNEL_ADAPT_3_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1234 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1235 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1236 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1237 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1238 1239 { TUNNEL_ADAPT_4_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1240 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1241 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1242 _SOC_SER_FLAG_XY_READ | 1243 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1244 { TUNNEL_ADAPT_4_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1245 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1246 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1247 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1248 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1249 1250 { EGR_ZONE_0_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1251 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1252 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1253 _SOC_SER_FLAG_XY_READ | 1254 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1255 { EGR_ZONE_0_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1256 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1257 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1258 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1259 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1260 1261 { EGR_ZONE_1_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1262 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1263 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1264 _SOC_SER_FLAG_XY_READ | 1265 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1266 { EGR_ZONE_1_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1267 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1268 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1269 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1270 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1271 1272 { EGR_ZONE_2_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1273 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1274 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1275 _SOC_SER_FLAG_XY_READ | 1276 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1277 { EGR_ZONE_2_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1278 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1279 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1280 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1281 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1282 1283 { EGR_ZONE_3_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1284 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1285 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1286 _SOC_SER_FLAG_XY_READ | 1287 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1288 { EGR_ZONE_3_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1289 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1290 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1291 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1292 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1293 1294 { EGR_ZONE_4_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1295 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1296 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1297 _SOC_SER_FLAG_XY_READ | 1298 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1299 { EGR_ZONE_4_EDITOR_CONTROL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1300 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1301 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1302 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1303 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1304 1305 { EGR_PKT_FLOW_SELECT_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1306 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1307 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1308 _SOC_SER_FLAG_XY_READ | 1309 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1310 { EGR_PKT_FLOW_SELECT_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1311 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1312 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1313 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1314 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1315 1316 { EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1317 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1318 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1319 _SOC_SER_FLAG_XY_READ | 1320 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1321 { EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1322 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1323 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1324 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1325 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1326 1327 { EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1328 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1329 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1330 _SOC_SER_FLAG_XY_READ | 1331 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1332 { EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1333 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1334 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1335 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1336 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1337 1338 { EGR_QOS_CTRL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1339 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1340 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1341 _SOC_SER_FLAG_XY_READ | 1342 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1343 { EGR_QOS_CTRL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1344 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1345 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1346 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1347 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1348 1349 { EGR_ADAPT_1_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1350 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1351 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1352 _SOC_SER_FLAG_XY_READ | 1353 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1354 { EGR_ADAPT_1_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1355 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1356 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1357 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1358 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1359 1360 { EGR_ADAPT_2_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1361 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1362 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1363 _SOC_SER_FLAG_XY_READ | 1364 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1365 { EGR_ADAPT_2_LOGICAL_TBL_SEL_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1366 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1367 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1368 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1369 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1370 1371 { IP_PARSER0_HME_STAGE_TCAM_ONLY_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1372 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1373 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1374 _SOC_SER_FLAG_XY_READ | 1375 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1376 { IP_PARSER0_HME_STAGE_TCAM_ONLY_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1377 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1378 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1379 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1380 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1381 1382 { IP_PARSER1_HME_STAGE_TCAM_ONLY_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1383 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1384 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1385 _SOC_SER_FLAG_XY_READ | 1386 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1387 { IP_PARSER1_HME_STAGE_TCAM_ONLY_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1388 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1389 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1390 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1391 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1392 1393 { IP_PARSER1_HME_STAGE_TCAM_ONLY_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1394 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1395 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1396 _SOC_SER_FLAG_XY_READ | 1397 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1398 { IP_PARSER1_HME_STAGE_TCAM_ONLY_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1399 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1400 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1401 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1402 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1403 1404 { IP_PARSER1_HME_STAGE_TCAM_NARROW_ONLY_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1405 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1406 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1407 _SOC_SER_FLAG_XY_READ | 1408 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1409 { IP_PARSER1_HME_STAGE_TCAM_NARROW_ONLY_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1410 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1411 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1412 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1413 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1414 1415 { IP_PARSER1_HME_STAGE_TCAM_ONLY_3m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1416 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1417 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1418 _SOC_SER_FLAG_XY_READ | 1419 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1420 { IP_PARSER1_HME_STAGE_TCAM_ONLY_3m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1421 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1422 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1423 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1424 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1425 1426 { IP_PARSER1_HME_STAGE_TCAM_ONLY_4m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1427 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1428 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1429 _SOC_SER_FLAG_XY_READ | 1430 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1431 { IP_PARSER1_HME_STAGE_TCAM_ONLY_4m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1432 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1433 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1434 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1435 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1436 1437 { IP_PARSER1_MICE_TCAM_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1438 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1439 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1440 _SOC_SER_FLAG_XY_READ | 1441 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1442 { IP_PARSER1_MICE_TCAM_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1443 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1444 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1445 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1446 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1447 1448 { IP_PARSER1_MICE_TCAM_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1449 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1450 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1451 _SOC_SER_FLAG_XY_READ | 1452 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1453 { IP_PARSER1_MICE_TCAM_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1454 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1455 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1456 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1457 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1458 1459 { IP_PARSER2_HME_STAGE_TCAM_ONLY_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1460 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1461 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1462 _SOC_SER_FLAG_XY_READ | 1463 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1464 { IP_PARSER2_HME_STAGE_TCAM_ONLY_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1465 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1466 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1467 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1468 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1469 1470 { IP_PARSER2_HME_STAGE_TCAM_ONLY_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1471 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1472 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1473 _SOC_SER_FLAG_XY_READ | 1474 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1475 { IP_PARSER2_HME_STAGE_TCAM_ONLY_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1476 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1477 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1478 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1479 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1480 1481 { IP_PARSER2_HME_STAGE_TCAM_NARROW_ONLY_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1482 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1483 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1484 _SOC_SER_FLAG_XY_READ | 1485 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1486 { IP_PARSER2_HME_STAGE_TCAM_NARROW_ONLY_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1487 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1488 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1489 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1490 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1491 1492 { IP_PARSER2_HME_STAGE_TCAM_NARROW_ONLY_3m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1493 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1494 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1495 _SOC_SER_FLAG_XY_READ | 1496 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1497 { IP_PARSER2_HME_STAGE_TCAM_NARROW_ONLY_3m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1498 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1499 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1500 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1501 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1502 1503 { IP_PARSER2_HME_STAGE_TCAM_ONLY_4m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1504 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1505 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1506 _SOC_SER_FLAG_XY_READ | 1507 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1508 { IP_PARSER2_HME_STAGE_TCAM_ONLY_4m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1509 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1510 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1511 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1512 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1513 1514 { IP_PARSER2_MICE_TCAM_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1515 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1516 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1517 _SOC_SER_FLAG_XY_READ | 1518 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1519 { IP_PARSER2_MICE_TCAM_0m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1520 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1521 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1522 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1523 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1524 1525 { IP_PARSER2_MICE_TCAM_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1526 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1527 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1528 _SOC_SER_FLAG_XY_READ | 1529 _SOC_MEM_ADDR_ACC_TYPE_PIPE_0}, 1530 { IP_PARSER2_MICE_TCAM_1m, INVALIDm, _SOC_SER_TYPE_PARITY, 0, 0, 1531 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 1532 _SOC_SER_FLAG_DISCARD_READ | _SOC_SER_FLAG_MULTI_PIPE | 1533 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_CONFIG_SKIP | 1534 _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 }, 1535 1536 /* End of list */ 1537 { INVALIDm }, 1538 }; 1539 1540 static soc_mem_t _soc_td3_skip_populating[] = { 1541 /* Shared MMU_WRED_ENABLE_ECCP_MEM.PROFILE_ECCP_EN */ 1542 MMU_WRED_DROP_CURVE_PROFILE_0m, 1543 MMU_WRED_DROP_CURVE_PROFILE_0_Am, 1544 MMU_WRED_DROP_CURVE_PROFILE_0_Bm, 1545 MMU_WRED_DROP_CURVE_PROFILE_1m, 1546 MMU_WRED_DROP_CURVE_PROFILE_1_Am, 1547 MMU_WRED_DROP_CURVE_PROFILE_1_Bm, 1548 MMU_WRED_DROP_CURVE_PROFILE_2m, 1549 MMU_WRED_DROP_CURVE_PROFILE_2_Am, 1550 MMU_WRED_DROP_CURVE_PROFILE_2_Bm, 1551 MMU_WRED_DROP_CURVE_PROFILE_3m, 1552 MMU_WRED_DROP_CURVE_PROFILE_3_Am, 1553 MMU_WRED_DROP_CURVE_PROFILE_3_Bm, 1554 MMU_WRED_DROP_CURVE_PROFILE_4m, 1555 MMU_WRED_DROP_CURVE_PROFILE_4_Am, 1556 MMU_WRED_DROP_CURVE_PROFILE_4_Bm, 1557 MMU_WRED_DROP_CURVE_PROFILE_5m, 1558 MMU_WRED_DROP_CURVE_PROFILE_5_Am, 1559 MMU_WRED_DROP_CURVE_PROFILE_5_Bm, 1560 MMU_WRED_DROP_CURVE_PROFILE_6m, 1561 MMU_WRED_DROP_CURVE_PROFILE_6_Am, 1562 MMU_WRED_DROP_CURVE_PROFILE_6_Bm, 1563 MMU_WRED_DROP_CURVE_PROFILE_7m, 1564 MMU_WRED_DROP_CURVE_PROFILE_7_Am, 1565 MMU_WRED_DROP_CURVE_PROFILE_7_Bm, 1566 MMU_WRED_DROP_CURVE_PROFILE_8m, 1567 MMU_WRED_DROP_CURVE_PROFILE_8_Am, 1568 MMU_WRED_DROP_CURVE_PROFILE_8_Bm, 1569 1570 /* Shared MMU_SCFG_PARITY_EN.TDM_PARITY_EN*/ 1571 TDM_CALENDAR0m, 1572 TDM_CALENDAR1m, 1573 INVALIDm 1574 }; 1575 1576 static int _soc_td3_tcam_mode_info[SOC_MAX_NUM_DEVICES][7]; 1577 static _soc_generic_ser_info_t *_soc_td3_tcam_ser_info[SOC_MAX_NUM_DEVICES]; 1578 1579 STATIC soc_error_t _soc_td3_ser_tcam_control_reg_get(int unit, soc_mem_t mem, 1580 soc_reg_t *ser_control_reg, soc_field_t *ser_enable_field); 1581 1582 int 1583 soc_trident3_tcam_mode_set(int unit, int stage, int mode) 1584 { 1585 if (stage < 0 || stage >=7) { 1586 if (stage == -1) { 1587 return SOC_E_NONE; 1588 } 1589 return SOC_E_PARAM; 1590 } 1591 1592 _soc_td3_tcam_mode_info[unit][stage] = mode; 1593 1594 return SOC_E_NONE; 1595 } 1596 1597 int 1598 soc_trident3_tcam_mode_get(int unit, soc_mem_t mem, int *mode) 1599 { 1600 int stage = 0; 1601 1602 switch(mem) { 1603 /* Field lookup TCAMs and SRAMs */ 1604 case VFP_TCAMm: 1605 case VFP_POLICY_TABLEm: 1606 stage = _BCM_FIELD_STAGE_LOOKUP; 1607 break; 1608 1609 /* Field Egress TCAMs and SRAMs */ 1610 case EFP_TCAMm: 1611 case EFP_POLICY_TABLEm: 1612 case EFP_COUNTER_TABLEm: 1613 case EFP_METER_TABLEm: 1614 stage = _BCM_FIELD_STAGE_EGRESS; 1615 break; 1616 1617 /* Field Ingress TCAMs */ 1618 case IFP_LOGICAL_TABLE_SELECTm: 1619 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 1620 case IFP_TCAMm: 1621 /* Field Ingress SRAMs */ 1622 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm: 1623 case IFP_LOGICAL_TABLE_ACTION_PRIORITYm: 1624 case IFP_KEY_GEN_PROGRAM_PROFILEm: 1625 case IFP_KEY_GEN_PROGRAM_PROFILE2m: 1626 case IFP_POLICY_TABLEm: 1627 case IFP_METER_TABLEm: 1628 stage = _BCM_FIELD_STAGE_INGRESS; 1629 break; 1630 1631 /* Exact Match TCAMs */ 1632 case EXACT_MATCH_LOGICAL_TABLE_SELECTm: 1633 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 1634 /* Exact Match SRAMs */ 1635 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm: 1636 case EXACT_MATCH_KEY_GEN_PROGRAM_PROFILEm: 1637 case EXACT_MATCH_ACTION_PROFILEm: 1638 case EXACT_MATCH_QOS_ACTIONS_PROFILEm: 1639 case EXACT_MATCH_DEFAULT_POLICYm: 1640 case EXACT_MATCH_KEY_GEN_MASKm: 1641 case EXACT_MATCH_2m: 1642 case EXACT_MATCH_4m: 1643 case EXACT_MATCH_2_ENTRY_ONLYm: 1644 case EXACT_MATCH_4_ENTRY_ONLYm: 1645 stage = _BCM_FIELD_STAGE_EXACTMATCH; 1646 break; 1647 1648 /* Field Ingress Compression TCAMs and SRAMs */ 1649 case SRC_COMPRESSIONm: 1650 case SRC_COMPRESSION_TCAM_ONLYm: 1651 case SRC_COMPRESSION_DATA_ONLYm: 1652 case DST_COMPRESSIONm: 1653 case DST_COMPRESSION_TCAM_ONLYm: 1654 case DST_COMPRESSION_DATA_ONLYm: 1655 stage = _BCM_FIELD_STAGE_CLASS; 1656 break; 1657 case TTL_FNm: 1658 case TOS_FNm: 1659 case TCP_FNm: 1660 case IP_PROTO_MAPm: 1661 stage = _BCM_FIELD_STAGE_CLASS; 1662 break; 1663 case IFP_TCAM_WIDEm: 1664 if (soc_property_get(unit, spn_FIELD_ATOMIC_UPDATE, FALSE) == TRUE) { 1665 stage = _BCM_FIELD_STAGE_INGRESS; 1666 } else { 1667 /* 1668 * Inorder to support bcmFieldQualifyInPorts in Global mode, 1669 * IP_TCAM_WIDE should always be in pipe local mode. 1670 */ 1671 *mode = _SOC_SER_MEM_MODE_PIPE_UNIQUE; 1672 return SOC_E_NONE; 1673 } 1674 break; 1675 1676 default: 1677 return SOC_E_NOT_FOUND; 1678 } 1679 1680 *mode = _soc_td3_tcam_mode_info[unit][stage]; 1681 return SOC_E_NONE; 1682 } 1683 1684 int 1685 soc_trident3_tcam_ser_init(int unit) 1686 { 1687 int alloc_size = 0; 1688 1689 /* First, make per-unit copy of the master TCAM list */ 1690 if (!soc_feature(unit, soc_feature_tcam_scan_engine)) { 1691 alloc_size = sizeof(_soc_td3_tcam_ser_info_template); 1692 1693 if (NULL == _soc_td3_tcam_ser_info[unit]) { 1694 if ((_soc_td3_tcam_ser_info[unit] = 1695 sal_alloc(alloc_size, "th tcam list")) == NULL) { 1696 return SOC_E_MEMORY; 1697 } 1698 } 1699 1700 /* Make a fresh copy of the TCAM template info */ 1701 sal_memcpy(_soc_td3_tcam_ser_info[unit], 1702 &(_soc_td3_tcam_ser_info_template), 1703 alloc_size); 1704 } 1705 1706 return SOC_E_NONE; 1707 } 1708 1709 STATIC int 1710 _soc_trident3_mmu_ser_config(int unit, _soc_td3_ser_info_t *info_list, 1711 int enable) 1712 { 1713 int info_index, f, rv; 1714 soc_field_t *fields; 1715 uint32 rval; 1716 _soc_td3_ser_info_t *info; 1717 1718 switch(info_list->type) { 1719 case _SOC_TD3_PARITY_TYPE_MMU_SER: 1720 /* Interrupt enable */ 1721 fields = info_list->intr_enable_field_list; 1722 SOC_IF_ERROR_RETURN 1723 (soc_reg32_get(unit, info_list->intr_enable_reg, REG_PORT_ANY, 0, 1724 &rval)); 1725 for (f=0 ;; f++) { 1726 if (fields[f] == INVALIDf) { 1727 break; 1728 } 1729 soc_reg_field_set(unit, info_list->intr_enable_reg, &rval, 1730 fields[f], enable ? 1 : 0); 1731 } 1732 SOC_IF_ERROR_RETURN 1733 (soc_reg32_set(unit, info_list->intr_enable_reg, REG_PORT_ANY, 0, 1734 rval)); 1735 /* Loop through each info entry in the list */ 1736 for (info_index = 0; ; info_index++) { 1737 info = &(info_list->info[info_index]); 1738 if (info->type == _SOC_TD3_PARITY_TYPE_NONE) { 1739 /* End of table */ 1740 break; 1741 } 1742 rv = _soc_trident3_mmu_ser_config(unit, info, enable); 1743 if (SOC_FAILURE(rv)) { 1744 LOG_CLI((BSL_META_U(unit, 1745 "Error configuring %s !!\n"), 1746 info->mem_str)); 1747 return rv; 1748 } 1749 } 1750 break; 1751 case _SOC_TD3_PARITY_TYPE_MMU_GLB: 1752 case _SOC_TD3_PARITY_TYPE_MMU_XPE: 1753 case _SOC_TD3_PARITY_TYPE_MMU_SC: 1754 case _SOC_TD3_PARITY_TYPE_MMU_SED: 1755 /* Parity enable */ 1756 SOC_IF_ERROR_RETURN 1757 (soc_reg32_get(unit, info_list->enable_reg, REG_PORT_ANY, 0, 1758 &rval)); 1759 if (info_list->enable_field_list) { 1760 fields = info_list->enable_field_list; 1761 for (f=0 ;; f++) { 1762 if (fields[f] == INVALIDf) { 1763 break; 1764 } 1765 soc_reg_field_set(unit, info_list->enable_reg, &rval, fields[f], 1766 enable ? 1 : 0); 1767 } 1768 } else if (info_list->enable_reg != INVALIDr) { 1769 soc_reg_field_set(unit, info_list->enable_reg, &rval, 1770 info_list->enable_field, enable ? 1 : 0); 1771 } 1772 SOC_IF_ERROR_RETURN 1773 (soc_reg32_set(unit, info_list->enable_reg, REG_PORT_ANY, 0, rval)); 1774 /* Interrupt enable */ 1775 SOC_IF_ERROR_RETURN 1776 (soc_reg32_get(unit, info_list->intr_enable_reg, REG_PORT_ANY, 0, 1777 &rval)); 1778 if (info_list->intr_enable_field_list) { 1779 fields = info_list->intr_enable_field_list; 1780 for (f=0 ;; f++) { 1781 if (fields[f] == INVALIDf) { 1782 break; 1783 } 1784 soc_reg_field_set(unit, info_list->intr_enable_reg, &rval, 1785 fields[f], enable ? 1 : 0); 1786 } 1787 } else if (info_list->intr_enable_reg != INVALIDr) { 1788 soc_reg_field_set(unit, info_list->intr_enable_reg, &rval, 1789 info_list->intr_enable_field, enable ? 1 : 0); 1790 } 1791 SOC_IF_ERROR_RETURN 1792 (soc_reg32_set(unit, info_list->intr_enable_reg, REG_PORT_ANY, 0, 1793 rval)); 1794 break; 1795 default: break; 1796 } 1797 return SOC_E_NONE; 1798 } 1799 1800 int 1801 soc_td3_ser_enable_info(int unit, int block_info_idx, int inst, int port, 1802 soc_reg_t group_reg, uint64 *group_rval, 1803 _soc_td3_ser_info_t *info_list, 1804 soc_mem_t mem, int enable) 1805 { 1806 _soc_td3_ser_info_t *info; 1807 int info_index, rv, rv1; 1808 uint32 rval; 1809 soc_reg_t reg; 1810 uint64 rval64; 1811 int log_port; 1812 rv = SOC_E_NOT_FOUND; 1813 1814 /* Loop through each info entry in the list */ 1815 for (info_index = 0; ; info_index++) { 1816 info = &info_list[info_index]; 1817 if (info->type == _SOC_TD3_PARITY_TYPE_NONE) { 1818 /* End of table */ 1819 break; 1820 } 1821 rv = SOC_E_NONE; 1822 1823 if (group_reg != INVALIDr && info->group_reg_enable_field != INVALIDf) { 1824 /* Enable the info entry in the group register */ 1825 soc_reg64_field32_set(unit, group_reg, group_rval, 1826 info->group_reg_enable_field, enable ? 1 : 0); 1827 } 1828 /* Handle different parity error reporting style */ 1829 switch (info->type) { 1830 case _SOC_TD3_PARITY_TYPE_MMU_SER: 1831 rv1 = _soc_trident3_mmu_ser_config(unit, info, enable); 1832 if (SOC_FAILURE(rv1)) { 1833 LOG_CLI((BSL_META_U(unit, 1834 "Error configuring MMU SER !!\n"))); 1835 return rv1; 1836 } 1837 break; 1838 case _SOC_TD3_PARITY_TYPE_ECC: 1839 case _SOC_TD3_PARITY_TYPE_PARITY: 1840 reg = info->enable_reg; 1841 if (!SOC_REG_IS_VALID(unit, reg)) { 1842 break; 1843 } 1844 if (SOC_REG_IS_64(unit, reg)) { 1845 SOC_IF_ERROR_RETURN 1846 (soc_reg_get(unit, reg, port, 0, &rval64)); 1847 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field, 1848 enable ? 1 : 0); 1849 SOC_IF_ERROR_RETURN 1850 (soc_reg_set(unit, reg, port, 0, rval64)); 1851 } else { 1852 SOC_IF_ERROR_RETURN 1853 (soc_reg32_get(unit, reg, port, 0, &rval)); 1854 soc_reg_field_set(unit, reg, &rval, info->enable_field, 1855 enable ? 1 : 0); 1856 SOC_IF_ERROR_RETURN 1857 (soc_reg32_set(unit, reg, port, 0, rval)); 1858 } 1859 LOG_VERBOSE(BSL_LS_SOC_SER, 1860 (BSL_META_U(unit, 1861 "SER enable for: %s\n"), 1862 (info->mem == INVALIDm) ? info->mem_str : 1863 SOC_MEM_NAME(unit, info->mem))); 1864 break; 1865 case _SOC_TD3_PARITY_TYPE_CLMAC: 1866 case _SOC_TD3_PARITY_TYPE_XLMAC: 1867 reg = info->enable_reg; 1868 /* At this moment, port mapping info is not ready on PCID server */ 1869 if (SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM) { 1870 break; 1871 } 1872 if (!SOC_REG_IS_VALID(unit, reg)) { 1873 break; 1874 } 1875 PBMP_ITER(SOC_BLOCK_BITMAP(unit, block_info_idx), log_port) { 1876 if (SOC_REG_IS_64(unit, reg)) { 1877 SOC_IF_ERROR_RETURN 1878 (soc_reg_get(unit, reg, log_port, 0, &rval64)); 1879 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field, 1880 enable ? 1 : 0); 1881 SOC_IF_ERROR_RETURN 1882 (soc_reg_set(unit, reg, log_port, 0, rval64)); 1883 } else { 1884 SOC_IF_ERROR_RETURN 1885 (soc_reg32_get(unit, reg, log_port, 0, &rval)); 1886 soc_reg_field_set(unit, reg, &rval, info->enable_field, 1887 enable ? 1 : 0); 1888 SOC_IF_ERROR_RETURN 1889 (soc_reg32_set(unit, reg, log_port, 0, rval)); 1890 } 1891 } 1892 LOG_VERBOSE(BSL_LS_SOC_SER, 1893 (BSL_META_U(unit, 1894 "SER enable for: %s\n"), 1895 (info->mem == INVALIDm) ? info->mem_str : 1896 SOC_MEM_NAME(unit, info->mem))); 1897 break; 1898 default: break; 1899 } 1900 } 1901 return rv; 1902 } 1903 1904 STATIC int 1905 _soc_trident3_ser_block_enable(int unit, int enable, uint32 *p_cmic_bit, 1906 int type, soc_block_t blocktype, 1907 soc_reg_t fifo_reset_reg, void *info) 1908 { 1909 uint8 rbi; 1910 uint16 pcount; 1911 uint32 cmic_bit, rval; 1912 int port = REG_PORT_ANY; 1913 uint64 rval64; 1914 soc_reg_t reg, ecc1b_reg; 1915 soc_field_t field, ecc1b_field; 1916 int field_position = -1; 1917 int ecc1b_field_position = -1; 1918 uint8 flag = 0; 1919 uint8 ecc1b_flag = 0; 1920 uint8 skip = 0; 1921 uint32 value; 1922 _soc_reg_ser_en_info_t *reg_info; 1923 _soc_mem_ser_en_info_t *mem_info; 1924 _soc_bus_ser_en_info_t *bus_info; 1925 _soc_buffer_ser_en_info_t *buf_info; 1926 char *str_type; 1927 char *str_name; 1928 static char *mmu_base_type[8] = { 1929 "IPORT", "EPORT", "IPIPE", "EPIPE", "CHIP", "XPE", "SLICE", "LAYER"}; 1930 static char *parity_module_str[4] = {"REG", "MEM", "BUS", "BUF"}; 1931 const _soc_td3_ser_route_block_t *rb; 1932 1933 int done = 0; 1934 1935 reg_info = (_soc_reg_ser_en_info_t*)info; 1936 mem_info = (_soc_mem_ser_en_info_t*)info; 1937 bus_info = (_soc_bus_ser_en_info_t*)info; 1938 buf_info = (_soc_buffer_ser_en_info_t*)info; 1939 for (pcount = 0;;pcount++) { /* walk thro each entry of block_info */ 1940 ecc1b_reg = INVALIDr; 1941 ecc1b_field = INVALIDf; 1942 switch (type) { 1943 case _SOC_SER_TYPE_REG: 1944 if (reg_info[pcount].reg == INVALIDr) { 1945 done = 1; 1946 } else { 1947 reg = reg_info[pcount].en_ctrl.ctrl_type.en_reg; 1948 flag = reg_info[pcount].en_ctrl.flag_reg_mem; 1949 field = reg_info[pcount].en_ctrl.en_fld; 1950 field_position = reg_info[pcount].en_ctrl.en_fld_position; 1951 ecc1b_reg = reg_info[pcount].ecc1b_ctrl.ctrl_type.en_reg; 1952 ecc1b_flag = reg_info[pcount].ecc1b_ctrl.flag_reg_mem; 1953 ecc1b_field = reg_info[pcount].ecc1b_ctrl.en_fld; 1954 ecc1b_field_position = reg_info[pcount].ecc1b_ctrl.en_fld_position; 1955 str_name = SOC_REG_NAME(unit, reg_info[pcount].reg); 1956 } 1957 break; 1958 case _SOC_SER_TYPE_MEM: 1959 if (mem_info[pcount].mem == INVALIDm) { 1960 done = 1; 1961 } else if (!SOC_MEM_IS_VALID(unit, mem_info[pcount].mem) || 1962 (SOC_MEM_INFO(unit, mem_info[pcount].mem).flags & 1963 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) { 1964 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, 1965 "skip SER enable for mem %s\n"), 1966 SOC_MEM_NAME(unit, mem_info[pcount].mem))); 1967 continue; 1968 } else { 1969 reg = mem_info[pcount].en_ctrl.ctrl_type.en_reg; 1970 flag = mem_info[pcount].en_ctrl.flag_reg_mem; 1971 field = mem_info[pcount].en_ctrl.en_fld; 1972 field_position = mem_info[pcount].en_ctrl.en_fld_position; 1973 ecc1b_reg = mem_info[pcount].ecc1b_ctrl.ctrl_type.en_reg; 1974 ecc1b_flag = mem_info[pcount].ecc1b_ctrl.flag_reg_mem; 1975 ecc1b_field = mem_info[pcount].ecc1b_ctrl.en_fld; 1976 ecc1b_field_position = mem_info[pcount].ecc1b_ctrl.en_fld_position; 1977 str_name = SOC_MEM_NAME(unit, mem_info[pcount].mem); 1978 1979 1980 } 1981 break; 1982 case _SOC_SER_TYPE_BUS: 1983 if (bus_info[pcount].en_reg == INVALIDr) { 1984 done = 1; 1985 } else { 1986 reg = bus_info[pcount].en_reg; 1987 field = bus_info[pcount].en_fld; 1988 str_name = bus_info[pcount].bus_name; 1989 } 1990 break; 1991 case _SOC_SER_TYPE_BUF: 1992 if (buf_info[pcount].en_reg == INVALIDr) { 1993 done = 1; 1994 } else { 1995 reg = buf_info[pcount].en_reg; 1996 field = buf_info[pcount].en_fld; 1997 str_name = buf_info[pcount].buffer_name; 1998 1999 if (reg == IDB_SER_CONTROLr && field == IS_TDM_ECC_ENf) { 2000 skip = 1; 2001 } else { 2002 skip = 0; 2003 } 2004 } 2005 break; 2006 default: 2007 LOG_CLI((BSL_META_U(unit, 2008 "Unknown parity module " 2009 "[pcount: %d].\n"), pcount)); 2010 return SOC_E_INTERNAL; 2011 } 2012 if (done) { 2013 break; 2014 } else { 2015 str_type = parity_module_str[type]; 2016 } 2017 2018 if (SOC_REG_IS_VALID(unit, reg) && (flag == 0) && !skip) { 2019 /* NOTE: Do not use the field modify routine in the following as 2020 some regs do not return the correct value due to which the 2021 modify routine skips the write */ 2022 if (SOC_REG_IS_64(unit, reg)) { 2023 SOC_IF_ERROR_RETURN 2024 (soc_reg_get(unit, reg, port, 0, &rval64)); 2025 if (field_position == -1) { 2026 soc_reg64_field32_set(unit, reg, &rval64, field, 2027 enable ? 1 : 0); 2028 } else { 2029 value = soc_reg64_field32_get(unit, reg, rval64, field); 2030 if (enable) { 2031 value |= (1 << field_position); 2032 } else { 2033 value &= ~(1 << field_position); 2034 } 2035 soc_reg64_field32_set(unit, reg, &rval64, field, value); 2036 } 2037 SOC_IF_ERROR_RETURN 2038 (soc_reg_set(unit, reg, port, 0, rval64)); 2039 } else { 2040 /* int at, bt; */ 2041 SOC_IF_ERROR_RETURN 2042 (soc_reg32_get(unit, reg, port, 0, &rval)); 2043 if (field_position == -1) { 2044 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 2045 } else { 2046 value = soc_reg_field_get(unit, reg, rval, field); 2047 if (enable) { 2048 value |= (1 << field_position); 2049 } else { 2050 value &= ~(1 << field_position); 2051 } 2052 soc_reg_field_set(unit, reg, &rval, field, value); 2053 } 2054 SOC_IF_ERROR_RETURN 2055 (soc_reg32_set(unit, reg, port, 0, rval)); 2056 } 2057 } 2058 if (ecc1b_reg != INVALIDr && ecc1b_field != INVALIDf && 2059 SOC_REG_IS_VALID(unit, ecc1b_reg) && (ecc1b_flag == 0)) { 2060 if (ecc1b_reg == ISW3_SER_CONTROL_1r && 2061 ecc1b_field == HG_COUNTERS_EN_COR_ERR_RPTf) { 2062 continue; 2063 } 2064 if (SOC_REG_IS_64(unit, ecc1b_reg)) { 2065 SOC_IF_ERROR_RETURN 2066 (soc_reg_get(unit, ecc1b_reg, port, 0, &rval64)); 2067 soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, 2068 enable ? 1 : 0); 2069 if (ecc1b_field_position == -1) { 2070 soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, 2071 enable ? 1 : 0); 2072 } else { 2073 value = soc_reg64_field32_get(unit, ecc1b_reg, rval64, 2074 ecc1b_field); 2075 if (enable) { 2076 value |= (1 << ecc1b_field_position); 2077 } else { 2078 value &= ~(1 << ecc1b_field_position); 2079 } 2080 soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, 2081 value); 2082 } 2083 SOC_IF_ERROR_RETURN 2084 (soc_reg_set(unit, ecc1b_reg, port, 0, rval64)); 2085 } else { 2086 int at, bt; 2087 SOC_IF_ERROR_RETURN 2088 (soc_reg32_get(unit, ecc1b_reg, port, 0, &rval)); 2089 if (ecc1b_field_position == -1) { 2090 soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, 2091 enable ? 1 : 0); 2092 } else { 2093 value = soc_reg_field_get(unit, ecc1b_reg, rval, ecc1b_field); 2094 if (enable) { 2095 value |= (1 << ecc1b_field_position); 2096 } else { 2097 value &= ~(1 << ecc1b_field_position); 2098 } 2099 soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, value); 2100 } at = SOC_REG_ACC_TYPE(unit, ecc1b_reg); 2101 bt = SOC_REG_BASE_TYPE(unit, ecc1b_reg); 2102 if (20 == at) { /* ACC_TYPE_SINGLE */ 2103 int inst, pipe, max_pipe; 2104 switch (bt) { 2105 case 2: /* IPIPE */ 2106 case 3: /* EPIPE */ 2107 max_pipe = NUM_PIPE(unit); break; 2108 case 4: /* CHIP */ 2109 max_pipe = 1; break; 2110 case 5: /* XPE */ 2111 max_pipe = NUM_XPE(unit); break; 2112 case 6: /* SLICE */ 2113 max_pipe = NUM_SLICE(unit); break; 2114 case 7: /* LAYER */ 2115 max_pipe = NUM_LAYER(unit); break; 2116 default: 2117 /* 0: IPORT */ 2118 /* 1: EPORT */ 2119 max_pipe = -1; 2120 LOG_ERROR(BSL_LS_SOC_SER, 2121 (BSL_META_U(unit, 2122 "unit %d, reg %s has unexpected " 2123 "base_type %s, will skip enable of " 2124 "1b err reporting\n"), 2125 unit, SOC_REG_NAME(unit, ecc1b_reg), 2126 mmu_base_type[bt])); 2127 break; 2128 } 2129 for (pipe = 0; pipe < max_pipe; pipe++) { 2130 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 2131 SOC_IF_ERROR_RETURN 2132 (soc_reg32_set(unit, ecc1b_reg, inst, 0, rval)); 2133 } 2134 } else { 2135 SOC_IF_ERROR_RETURN 2136 (soc_reg32_set(unit, ecc1b_reg, port, 0, rval)); 2137 } 2138 } 2139 } 2140 LOG_VERBOSE(BSL_LS_SOC_SER, 2141 (BSL_META_U(unit, 2142 "SER enable for %s: %s\n"), 2143 str_type, str_name)); 2144 } /* walk thro each entry of block_info */ 2145 2146 /* Loop through each place-and-route block entry */ 2147 for (rbi = 0; ; rbi++) { 2148 rb = &_soc_td3_ser_route_blocks[rbi]; 2149 cmic_bit = rb->cmic_bit; 2150 if (cmic_bit == 0) { 2151 /* End of table */ 2152 break; 2153 } 2154 if (rb->blocktype == blocktype) { 2155 /* LHS has only SOC_BLK_MMU and * RHS has only 2156 * SOC_BLK_MMU_GLB. Thus for MMU, following will not be 2157 * executed. 2158 */ 2159 /* New SER mechanism (except IP.IDB) */ 2160 *p_cmic_bit |= cmic_bit; 2161 /* block_info has entries only for BLK_IPIPE, BLK_EPIPE, 2162 * BLK_MMU_GLB. 2163 * route_block_info on other hand has BLK_MMU, BLK_IPIPE, 2164 * BLK_EPIPE, BLK_CLPORT. 2165 * So, we can he here only for BLK_IPIPE, BLK_EPIPE and for 2166 * these cmic reg is always cmic_rval - see block_info[] array 2167 */ 2168 if (rb->enable_reg != INVALIDr && 2169 rb->enable_field != INVALIDf) { 2170 SOC_IF_ERROR_RETURN 2171 (soc_reg_field32_modify(unit, rb->enable_reg, 2172 REG_PORT_ANY, rb->enable_field, enable ? 1 : 0)); 2173 } 2174 if ((rb->blocktype == SOC_BLK_IPIPE) 2175 && (rb->cmic_bit != _SOC_TD3_IPIPE0_IDB_INTR) 2176 && (rb->cmic_bit != _SOC_TD3_IPIPE1_IDB_INTR) 2177 && (rb->cmic_bit != _SOC_TD3_CEV_INTR)) { 2178 soc_td3_ip_pipe_fifo_bmask[unit][rb->pipe] |= cmic_bit; 2179 } 2180 } 2181 } 2182 2183 /* reset (toggle) fifo if applicable */ 2184 if (fifo_reset_reg != INVALIDr) { 2185 SOC_IF_ERROR_RETURN 2186 (soc_reg_field32_modify(unit, fifo_reset_reg, 2187 REG_PORT_ANY, FIFO_RESETf, 1)); 2188 SOC_IF_ERROR_RETURN 2189 (soc_reg_field32_modify(unit, fifo_reset_reg, 2190 REG_PORT_ANY, FIFO_RESETf, 0)); 2191 } 2192 2193 return SOC_E_NONE; 2194 } 2195 2196 int 2197 soc_trident3_ser_enable_parity_table(int unit, int type, void *info, int enable) 2198 { 2199 uint32 i = 0; 2200 uint32 entry[SOC_MAX_MEM_WORDS]; 2201 uint32 copyno; 2202 uint32 value = 0; 2203 uint32 done = 0; 2204 uint8 flag = 0; 2205 soc_mem_t en_mem = INVALIDm; 2206 soc_mem_t ecc1b_en_mem = INVALIDm; 2207 soc_field_t en_fld = INVALIDf; 2208 soc_field_t ecc1b_en_fld = INVALIDf; 2209 int en_fld_position = -1; 2210 int ecc1b_en_fld_position = -1; 2211 const _soc_mem_ser_en_info_t *mem_info; 2212 const _soc_reg_ser_en_info_t *reg_info; 2213 2214 mem_info = (_soc_mem_ser_en_info_t*)info; 2215 reg_info = (_soc_reg_ser_en_info_t*)info; 2216 2217 for (i = 0; ; i++) { 2218 switch(type) { 2219 case _SOC_SER_TYPE_REG: 2220 if (reg_info[i].reg == INVALIDr) { 2221 done = 1; 2222 } 2223 en_mem = reg_info[i].en_ctrl.ctrl_type.en_mem; 2224 flag = reg_info[i].en_ctrl.flag_reg_mem; 2225 en_fld = reg_info[i].en_ctrl.en_fld; 2226 en_fld_position = reg_info[i].en_ctrl.en_fld_position; 2227 ecc1b_en_mem = reg_info[i].ecc1b_ctrl.ctrl_type.en_mem; 2228 ecc1b_en_fld = reg_info[i].ecc1b_ctrl.en_fld; 2229 ecc1b_en_fld_position = reg_info[i].ecc1b_ctrl.en_fld_position; 2230 break; 2231 case _SOC_SER_TYPE_MEM: 2232 if (mem_info[i].mem == INVALIDm) { 2233 done = 1; 2234 } 2235 en_mem = mem_info[i].en_ctrl.ctrl_type.en_mem; 2236 flag = mem_info[i].en_ctrl.flag_reg_mem; 2237 en_fld = mem_info[i].en_ctrl.en_fld; 2238 en_fld_position = mem_info[i].en_ctrl.en_fld_position; 2239 ecc1b_en_mem = mem_info[i].ecc1b_ctrl.ctrl_type.en_mem; 2240 ecc1b_en_fld = mem_info[i].ecc1b_ctrl.en_fld; 2241 ecc1b_en_fld_position = mem_info[i].ecc1b_ctrl.en_fld_position; 2242 break; 2243 default: 2244 LOG_CLI((BSL_META_U(unit, 2245 "Unknown parity module " 2246 "[type: %d].\n"), type)); 2247 break; 2248 } 2249 2250 if (done == 1) { 2251 break; 2252 } 2253 2254 if (flag == 0) { 2255 continue; 2256 } 2257 2258 SOC_MEM_BLOCK_ITER(unit, en_mem, copyno) { 2259 SOC_IF_ERROR_RETURN(soc_mem_read(unit, en_mem, copyno, 0, entry)); 2260 if (en_fld_position == -1) { 2261 soc_mem_field32_set(unit, en_mem, entry, en_fld, enable ? 1 : 0); 2262 } else { 2263 value = soc_mem_field32_get(unit, en_mem, entry, en_fld); 2264 if (enable) { 2265 value |= (1 << en_fld_position); 2266 } else { 2267 value &= ~(1 << en_fld_position); 2268 } 2269 soc_mem_field32_set(unit, en_mem, entry, en_fld, value); 2270 } 2271 SOC_IF_ERROR_RETURN(soc_mem_write(unit, en_mem, copyno, 0, entry)); 2272 } 2273 2274 if (ecc1b_en_mem != INVALIDm) { 2275 SOC_MEM_BLOCK_ITER(unit, ecc1b_en_mem, copyno) { 2276 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ecc1b_en_mem, copyno, 2277 0, entry)); 2278 if (ecc1b_en_fld_position == -1) { 2279 soc_mem_field32_set(unit, ecc1b_en_mem, entry, 2280 ecc1b_en_fld, enable ? 1 : 0); 2281 } else { 2282 value = soc_mem_field32_get(unit, ecc1b_en_mem, 2283 entry, ecc1b_en_fld); 2284 if (enable) { 2285 value |= (1 << ecc1b_en_fld_position); 2286 } else { 2287 value &= ~(1 << ecc1b_en_fld_position); 2288 } 2289 soc_mem_field32_set(unit, ecc1b_en_mem, entry, 2290 ecc1b_en_fld, value); 2291 } 2292 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ecc1b_en_mem, copyno, 2293 0, entry)); 2294 } 2295 } 2296 } 2297 2298 return SOC_E_NONE; 2299 } 2300 2301 int 2302 soc_trident3_ser_enable_parity_table_all(int unit, int enable) 2303 { 2304 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table(unit, 2305 _SOC_SER_TYPE_MEM, (void*) SOC_IP_MEM_SER_INFO(unit), enable)); 2306 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table(unit, 2307 _SOC_SER_TYPE_REG, (void*) SOC_IP_REG_SER_INFO(unit), enable)); 2308 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table(unit, 2309 _SOC_SER_TYPE_MEM, (void*) SOC_EP_MEM_SER_INFO(unit), enable)); 2310 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table(unit, 2311 _SOC_SER_TYPE_REG, (void*) SOC_EP_REG_SER_INFO(unit), enable)); 2312 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table(unit, 2313 _SOC_SER_TYPE_MEM, (void*) SOC_MMU_MEM_SER_INFO(unit), enable)); 2314 2315 return SOC_E_NONE; 2316 } 2317 2318 2319 int 2320 soc_trident3_ser_enable_all(int unit, int enable) 2321 { 2322 uint8 rbi; 2323 uint32 cmic_bit; 2324 uint32 cmic_rval0; 2325 uint32 cmic_rval1; 2326 uint32 cmic_rval2; 2327 int port = REG_PORT_ANY; 2328 int rv, block_info_idx; 2329 uint64 rval64; 2330 const _soc_td3_ser_route_block_t *rb; 2331 2332 soc_iproc_getreg(unit,soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG0r, REG_PORT_ANY, 0), 2333 &cmic_rval0); 2334 soc_iproc_getreg(unit,soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG1r, REG_PORT_ANY, 0), 2335 &cmic_rval1); 2336 soc_iproc_getreg(unit,soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG2r, REG_PORT_ANY, 0), 2337 &cmic_rval2); 2338 2339 soc_td3_ip_pipe_fifo_bmask[unit][0] = 0; 2340 soc_td3_ip_pipe_fifo_bmask[unit][1] = 0; 2341 2342 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2343 _SOC_SER_TYPE_REG, SOC_BLK_IPIPE, INVALIDr, 2344 (void*) SOC_IP_REG_SER_INFO(unit))); 2345 2346 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2347 _SOC_SER_TYPE_MEM, SOC_BLK_IPIPE, ING_SER_FIFO_CTRLr, 2348 (void*) SOC_IP_MEM_SER_INFO(unit))); 2349 2350 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2351 _SOC_SER_TYPE_REG, SOC_BLK_EPIPE, INVALIDr, 2352 (void*) SOC_EP_REG_SER_INFO(unit))); 2353 2354 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2355 _SOC_SER_TYPE_MEM, SOC_BLK_EPIPE, EGR_SER_FIFO_CTRLr, 2356 (void*) SOC_EP_MEM_SER_INFO(unit))); 2357 2358 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2359 _SOC_SER_TYPE_MEM, SOC_BLK_MMU_GLB, INVALIDr, 2360 (void*) SOC_MMU_MEM_SER_INFO(unit))); 2361 2362 #if defined(BCM_56870_A0) 2363 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2364 _SOC_SER_TYPE_BUS, SOC_BLK_IPIPE, INVALIDr, 2365 (void*) &_soc_bcm56870_a0_ip_bus_ser_info)); 2366 2367 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2368 _SOC_SER_TYPE_BUF, SOC_BLK_IPIPE, INVALIDr, 2369 (void*) &_soc_bcm56870_a0_ip_buffer_ser_info)); 2370 2371 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2372 _SOC_SER_TYPE_BUS, SOC_BLK_EPIPE, INVALIDr, 2373 (void*) &_soc_bcm56870_a0_ep_bus_ser_info)); 2374 2375 SOC_IF_ERROR_RETURN(_soc_trident3_ser_block_enable(unit, enable, &cmic_rval0, 2376 _SOC_SER_TYPE_BUF, SOC_BLK_EPIPE, INVALIDr, 2377 (void*) &_soc_bcm56870_a0_ep_buffer_ser_info)); 2378 #endif 2379 2380 /* Enable 1B error reporting for some special items */ 2381 2382 /* Loop through each place-and-route block entry to enable legacy 2383 style SER stuff */ 2384 /* BLK_MMU, BLK_CLPORT will be handled here */ 2385 for (rbi = 0; ; rbi++) { 2386 rb = &_soc_td3_ser_route_blocks[rbi]; 2387 2388 port = REG_PORT_ANY; 2389 cmic_bit = rb->cmic_bit; 2390 if (cmic_bit == 0) { 2391 /* End of table */ 2392 break; 2393 } 2394 2395 if (rb->info == NULL) { 2396 continue; 2397 } 2398 2399 if (enable) { 2400 switch (rb->cmic_reg) { 2401 case 0: cmic_rval0 |= cmic_bit; break; 2402 case 1: cmic_rval1 |= cmic_bit; break; 2403 case 2: cmic_rval2 |= cmic_bit; break; 2404 default: break; 2405 } 2406 } else { 2407 switch (rb->cmic_reg) { 2408 case 0: cmic_rval0 &= ~cmic_bit; break; 2409 case 1: cmic_rval1 &= ~cmic_bit; break; 2410 case 2: cmic_rval2 &= ~cmic_bit; break; 2411 default: break; 2412 } 2413 } 2414 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 2415 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 2416 port = SOC_BLOCK_PORT(unit, block_info_idx); 2417 break; 2418 } 2419 } 2420 if (rb->enable_reg != INVALIDr) { 2421 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 2422 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 2423 /* This port block is not configured */ 2424 continue; 2425 } 2426 SOC_IF_ERROR_RETURN 2427 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64)); 2428 } 2429 2430 rv = soc_td3_ser_enable_info(unit, block_info_idx, rb->id, port, 2431 rb->enable_reg, &rval64, 2432 rb->info, INVALIDm, enable); 2433 if (rv == SOC_E_NOT_FOUND) { 2434 continue; 2435 } else if (SOC_FAILURE(rv)) { 2436 return rv; 2437 } 2438 2439 if (rb->enable_reg != INVALIDr) { 2440 /* Write per route block parity enable register */ 2441 SOC_IF_ERROR_RETURN 2442 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64)); 2443 } 2444 } 2445 2446 soc_iproc_setreg(unit, 2447 soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG0r, REG_PORT_ANY, 0), 2448 cmic_rval0); 2449 soc_iproc_setreg(unit, 2450 soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG1r, REG_PORT_ANY, 0), 2451 cmic_rval1); 2452 soc_iproc_setreg(unit, 2453 soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG2r, REG_PORT_ANY, 0), 2454 cmic_rval2); 2455 if (enable) { 2456 /* MMU enables */ 2457 /* check trident2.c - may have to add some similar code here */ 2458 2459 /* Write CMIC enable register */ 2460 soc_cmic_intr_enable(unit, CHIP_INTR_LOW_PRIORITY); 2461 /* Waiting for HW feedback, so disable tcam scan engine first */ 2462 (void)soc_ser_tcam_scan_engine_enable(unit, FALSE); 2463 (void)soc_td3_ser_tcam_wrapper_enable(unit, TRUE); 2464 } else { 2465 /* MMU disables */ 2466 /* check trident2.c - may have to add some similar code here */ 2467 2468 /* Write CMIC disable register */ 2469 soc_cmic_intr_disable(unit, CHIP_INTR_LOW_PRIORITY); 2470 (void)soc_ser_tcam_scan_engine_enable(unit, FALSE); 2471 (void)soc_td3_ser_tcam_wrapper_enable(unit, FALSE); 2472 } 2473 return SOC_E_NONE; 2474 } 2475 2476 int soc_trident3_pipe_select(int unit, int egress, int pipe); 2477 2478 STATIC void 2479 _soc_td3_ser_control_reg_get(int unit, 2480 const _soc_mem_ser_en_info_t *ser_en_info_list, 2481 soc_mem_t mem, 2482 soc_reg_t *ser_control_reg, 2483 soc_mem_t *ser_control_mem, 2484 soc_field_t *ser_enable_field, 2485 int *ser_enable_field_position) 2486 { 2487 int i; 2488 if ((ser_en_info_list == NULL) || (ser_control_reg == NULL) || 2489 (ser_enable_field == NULL)) { 2490 return; 2491 } 2492 for (i = 0; ser_en_info_list[i].mem != INVALIDm; i++) { 2493 if (ser_en_info_list[i].mem == mem) { 2494 *ser_control_reg = ser_en_info_list[i].en_ctrl.flag_reg_mem ? INVALIDr : 2495 ser_en_info_list[i].en_ctrl.ctrl_type.en_reg; 2496 *ser_control_mem = ser_en_info_list[i].en_ctrl.flag_reg_mem ? 2497 ser_en_info_list[i].en_ctrl.ctrl_type.en_mem : 2498 INVALIDm; 2499 *ser_enable_field = ser_en_info_list[i].en_ctrl.en_fld; 2500 *ser_enable_field_position = ser_en_info_list[i].en_ctrl.en_fld_position; 2501 return; 2502 } 2503 } 2504 LOG_ERROR(BSL_LS_SOC_SER, 2505 (BSL_META_U(unit, 2506 "unit %d, mem %s reported in ser_fifo but not " 2507 "listed in ip, ep_mem_ser_info list !!\n"), 2508 unit, SOC_MEM_NAME(unit,mem) )); 2509 return; 2510 } 2511 2512 STATIC void 2513 _soc_td3_mem_parity_info(int unit, int block_info_idx, int pipe, 2514 soc_field_t field_enum, uint32 *minfo) 2515 { 2516 *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) 2517 | ((pipe & 0xff) << SOC_ERROR_PIPE_BP) 2518 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK); 2519 } 2520 2521 STATIC int 2522 _soc_td3_mem_has_ecc(int unit, soc_mem_t mem) 2523 { 2524 if (SOC_MEM_FIELD_VALID(unit, mem, ECCf) || 2525 SOC_MEM_FIELD_VALID(unit, mem, ECC0f) || 2526 SOC_MEM_FIELD_VALID(unit, mem, ECC_0f) || 2527 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_ECC_CORRECTABLE)) { 2528 return 1; 2529 } 2530 return 0; 2531 } 2532 2533 STATIC int 2534 _soc_td3_mem_is_dyn(int unit, soc_mem_t mem) 2535 { 2536 int rv = 0; /* mem is not dynamic */ 2537 /* 2538 * 2539 if (SOC_MEM_FIELD_VALID(unit, mem, HITf) || 2540 SOC_MEM_FIELD_VALID(unit, mem, HIT0f) || 2541 SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) || 2542 SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) || 2543 SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) || 2544 SOC_MEM_FIELD_VALID(unit, mem, HITSAf) || 2545 SOC_MEM_FIELD_VALID(unit, mem, HITDAf) || 2546 SOC_MEM_FIELD_VALID(unit, mem, MY_STATION_HITf)) { 2547 return 1; 2548 } 2549 */ 2550 switch (mem) { 2551 case IFP_METER_TABLEm: 2552 case EFP_METER_TABLEm: 2553 case FP_STORM_CONTROL_METERSm: 2554 rv = 1; break; 2555 default: 2556 /* 2557 * Cannot use following, because FLAG_DYNAMIC will be set by esw/drv.c 2558 * for any mem which contains PARITY, ECC, HIT bits 2559 * if (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_DYNAMIC) { 2560 * rv = 1; break; 2561 * } 2562 */ 2563 if ((SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_ENTRY_CLEAR) || 2564 !(SOC_MEM_SER_CORRECTION_TYPE(unit, mem))) { 2565 /* 1st term means mem is dynamic - eg: counter */ 2566 /* 2nd term means sw cannot restore this - so mem must be dyn */ 2567 rv = 1; 2568 } else { 2569 rv = 0; 2570 } 2571 break; 2572 } 2573 if (rv) { 2574 LOG_VERBOSE(BSL_LS_SOC_SER, 2575 (BSL_META_U(unit, 2576 "unit %d, mem %s is dynamic - so read of corrupted" 2577 " entry will be skipped !!\n"), 2578 unit, SOC_MEM_NAME(unit, mem))); 2579 } 2580 return rv; 2581 } 2582 2583 int 2584 soc_td3_parity_bit_enable(int unit, soc_reg_t enreg, soc_mem_t enmem, 2585 soc_field_t enfld, int enfld_position, int enable) 2586 { 2587 uint32 rval = 0; 2588 uint32 value = 0; 2589 uint32 entry[SOC_MAX_MEM_WORDS]; 2590 uint32 copyno; 2591 uint64 rval64; 2592 2593 if (SOC_REG_IS_VALID(unit, enreg)) { 2594 if (SOC_REG_IS_64(unit, enreg)) { 2595 SOC_IF_ERROR_RETURN 2596 (soc_reg_get(unit, enreg, REG_PORT_ANY, 0, &rval64)); 2597 if (enfld_position == -1) { 2598 soc_reg64_field32_set(unit, enreg, &rval64, enfld, enable ? 1 : 0); 2599 } else { 2600 value = soc_reg64_field32_get(unit, enreg, rval64, enfld); 2601 if (enable) { 2602 value |= (1 << enfld_position); 2603 } else { 2604 value &= ~(1 << enfld_position); 2605 } 2606 soc_reg64_field32_set(unit, enreg, &rval64, enfld, value); 2607 } 2608 SOC_IF_ERROR_RETURN 2609 (soc_reg_set(unit, enreg, REG_PORT_ANY, 0, rval64)); 2610 } else { 2611 SOC_IF_ERROR_RETURN 2612 (soc_reg32_get(unit, enreg, REG_PORT_ANY, 0, &rval)); 2613 if (enfld_position == -1) { 2614 soc_reg_field_set(unit, enreg, &rval, enfld, enable ? 1 : 0); 2615 } else { 2616 value = soc_reg_field_get(unit, enreg, rval, enfld); 2617 if (enable) { 2618 value |= (1 << enfld_position); 2619 } else { 2620 value &= ~(1 << enfld_position); 2621 } 2622 soc_reg_field_set(unit, enreg, &rval, enfld, value); 2623 } 2624 SOC_IF_ERROR_RETURN 2625 (soc_reg32_set(unit, enreg, REG_PORT_ANY, 0, rval)); 2626 } 2627 } else if (SOC_MEM_IS_VALID(unit, enmem)){ 2628 SOC_MEM_BLOCK_ITER(unit, enmem, copyno) { 2629 SOC_IF_ERROR_RETURN(soc_mem_read(unit, enmem, copyno, 0, entry)); 2630 if (enfld_position == -1) { 2631 soc_mem_field32_set(unit, enmem, entry, enfld, enable ? 1 : 0); 2632 } else { 2633 value = soc_mem_field32_get(unit, enmem, entry, enfld); 2634 if (enable) { 2635 value |= (1 << enfld_position); 2636 } else { 2637 value &= ~(1 << enfld_position); 2638 } 2639 soc_mem_field32_set(unit, enmem, entry, enfld, value); 2640 } 2641 SOC_IF_ERROR_RETURN(soc_mem_write(unit, enmem, copyno, 0, entry)); 2642 } 2643 } 2644 2645 return SOC_E_NONE; 2646 } 2647 2648 STATIC int 2649 _soc_td3_mem_log_content_skip(int unit, soc_mem_t mem){ 2650 soc_mem_t *mem_list = NULL; 2651 int i = 0; 2652 2653 mem_list = _soc_td3_skip_populating; 2654 2655 i = 0; 2656 while(mem_list[i] != INVALIDm) { 2657 if (mem == mem_list[i]) { 2658 return TRUE; 2659 } 2660 i++; 2661 } 2662 2663 return FALSE; 2664 } 2665 2666 int 2667 _soc_td3_populate_ser_log(int unit, soc_reg_t parity_enable_reg, 2668 soc_mem_t parity_enable_mem, 2669 soc_field_t parity_enable_field, 2670 int parity_enable_field_position, 2671 soc_mem_t mem, 2672 int mem_block, 2673 int pipe_num, 2674 int index, 2675 sal_usecs_t detect_time, 2676 uint32 sblk, 2677 uint32 address, 2678 int disable_parity, 2679 int disable_mem_read, 2680 int disable_fill_cache_log, 2681 int force_cache_log, 2682 int is_physical_index, 2683 uint32 hwbase) 2684 { 2685 uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 2686 int log_entry_size, id, entry_dw; 2687 uint32 *cache; 2688 uint32 flags = SOC_MEM_NO_FLAGS; 2689 uint8 *vmap; 2690 soc_ser_log_tlv_memory_t log_mem; 2691 soc_ser_log_tlv_generic_t log_generic; 2692 int final_disable_parity = 0; 2693 int final_disable_mem_read = 0; 2694 int rv; 2695 2696 sal_memset(&log_generic, 0, sizeof(log_generic)); 2697 sal_memset(&log_mem, 0, sizeof(log_mem)); 2698 sal_memset(tmp_entry, 0, sizeof(tmp_entry)); 2699 2700 /* 2701 must be large enough for at least generic and terminator, as well as the 2702 memory type since we might decode it in soc_ser_correction. 2703 */ 2704 log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 + 2705 sizeof(soc_ser_log_tlv_generic_t) + 2706 sizeof(soc_ser_log_tlv_memory_t); 2707 2708 if (mem != INVALIDm) { 2709 final_disable_mem_read = disable_mem_read || 2710 _soc_td3_mem_is_dyn(unit, mem) || 2711 _soc_td3_mem_log_content_skip(unit, mem) || 2712 ((parity_enable_reg == INVALIDr) && 2713 (parity_enable_mem == INVALIDm)) || 2714 (parity_enable_field == INVALIDf); 2715 2716 final_disable_parity = (!final_disable_mem_read) && 2717 disable_parity; /* over-ride if necessary */ 2718 2719 /* Check to make sure this isn't a duplicate */ 2720 /* Search for a log entry with the same mem, and index with within 2721 * the last 5 seconds */ 2722 rv = soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()); 2723 if (rv > 0) { 2724 LOG_VERBOSE(BSL_LS_SOC_SER, 2725 (BSL_META_U(unit, 2726 "unit %d, ser_logging was skipped for mem %s " 2727 "- too close to similar event !!\n"), 2728 unit, SOC_MEM_NAME(unit, mem))); 2729 return rv; 2730 } 2731 2732 entry_dw = soc_mem_entry_words(unit, mem); 2733 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2734 2735 if (sblk) { 2736 SOC_MEM_BLOCK_ITER(unit, mem, mem_block) { 2737 if (SOC_BLOCK2OFFSET(unit, mem_block) == sblk) { 2738 break; 2739 } 2740 } 2741 } else { 2742 mem_block = SOC_MEM_BLOCK_ANY(unit, mem); 2743 } 2744 2745 cache = SOC_MEM_STATE(unit, mem).cache[mem_block]; 2746 vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block]; 2747 if ((cache != NULL && CACHE_VMAP_TST(vmap, index)) || 2748 force_cache_log) { 2749 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2750 } 2751 2752 /* create the entry based on determined size, save id */ 2753 id = soc_ser_log_create_entry(unit, log_entry_size); 2754 if (id == 0) { 2755 return id; 2756 } 2757 2758 /* Add the memory information to the log now so we can detect duplicate errors */ 2759 log_generic.time = detect_time; 2760 log_mem.memory = mem; 2761 log_mem.index = index; 2762 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY, 2763 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 2764 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC, 2765 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 2766 2767 /* If we have decoded the memory we can record its contents 2768 * (which can help with analysis with nature of the error 2769 */ 2770 if (final_disable_parity) { 2771 SOC_IF_ERROR_RETURN(soc_td3_parity_bit_enable(unit, parity_enable_reg, 2772 parity_enable_mem, 2773 parity_enable_field, 2774 parity_enable_field_position, 0)); 2775 } 2776 2777 /* read the memory into a buffer */ 2778 if (!final_disable_mem_read) { 2779 if (is_physical_index) { 2780 flags = SOC_MEM_DONT_MAP_INDEX; 2781 } 2782 if ((pipe_num >= 0) && (pipe_num < NUM_PIPE(unit))) { 2783 soc_mem_pipe_select_read(unit, flags, mem, mem_block, 2784 pipe_num, index, tmp_entry); 2785 } else { 2786 flags |= SOC_MEM_DONT_USE_CACHE | SOC_MEM_SCHAN_ERR_RETURN; 2787 /*Enable NACK on read */ 2788 soc_mem_read_extended(unit, 2789 flags, 2790 mem, 0, mem_block, 2791 index, tmp_entry); 2792 } 2793 } 2794 2795 /* Re_enable Parity */ 2796 if (final_disable_parity) { 2797 SOC_IF_ERROR_RETURN(soc_td3_parity_bit_enable(unit, parity_enable_reg, 2798 parity_enable_mem, 2799 parity_enable_field, 2800 parity_enable_field_position, 1)); 2801 2802 } 2803 2804 /* fill in the memory contents tlv */ 2805 if (!final_disable_mem_read) { 2806 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS, 2807 entry_dw*4, tmp_entry) < 0) { 2808 return 0; 2809 } 2810 } 2811 2812 if (cache != NULL && CACHE_VMAP_TST(vmap, index) && 2813 !disable_fill_cache_log) { 2814 /* fill in the memory cache tlv */ 2815 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE, 2816 entry_dw*4, (cache + index*entry_dw)) < 0) { 2817 return 0; 2818 } 2819 } 2820 } else { 2821 /* create the entry based on determined size, save id */ 2822 id = soc_ser_log_create_entry(unit, log_entry_size); 2823 if (id == 0) { 2824 return id; 2825 } 2826 log_mem.memory = mem; 2827 log_mem.index = index; 2828 log_mem.hwbase = hwbase; 2829 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY, 2830 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 2831 } 2832 return id; 2833 } 2834 2835 STATIC int 2836 _soc_td3_add_log_generic(int unit, _soc_ser_correct_info_t *spci) 2837 { 2838 2839 if (spci->log_id != 0) { 2840 soc_ser_log_tlv_generic_t log_generic; 2841 2842 /* Add the memory information to the log now so we can detect duplicate errors */ 2843 log_generic.flags = 0; 2844 if (spci->flags & SOC_SER_ERR_CPU) { 2845 log_generic.flags |= SOC_SER_LOG_FLAG_ERR_SRC; 2846 } 2847 if (spci->flags & SOC_SER_ERR_MULTI) { 2848 log_generic.flags |= SOC_SER_LOG_FLAG_MULTIBIT; 2849 } 2850 if (spci->double_bit != 0) { 2851 log_generic.flags |= SOC_SER_LOG_FLAG_DOUBLEBIT; 2852 } 2853 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 2854 log_generic.address = spci->addr; 2855 log_generic.acc_type = spci->acc_type; 2856 log_generic.block_type = spci->blk_type; 2857 log_generic.parity_type = spci->parity_type; 2858 log_generic.ser_response_flag = 0; 2859 log_generic.corrected = SOC_SER_UNCORRECTED; 2860 log_generic.pipe_num = spci->pipe_num; 2861 log_generic.time = spci->detect_time; 2862 2863 soc_ser_log_add_tlv(unit, spci->log_id, SOC_SER_LOG_TLV_GENERIC, 2864 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 2865 2866 return SOC_E_NONE; 2867 } 2868 return SOC_E_FAIL; 2869 } 2870 2871 STATIC int 2872 _soc_td3_ser_reg32_get(int unit, soc_reg_t reg, int port, int index, 2873 uint32 *data, int mmu_base_index) 2874 { 2875 int block_num = mmu_base_index; 2876 int base_type_index = mmu_base_index; 2877 soc_block_t blocktype = *SOC_REG_INFO(unit, reg).block; 2878 switch (blocktype) { 2879 case SOC_BLK_MMU_XPE: 2880 return soc_trident3_xpe_reg32_get(unit, reg, block_num, 2881 base_type_index, index, data); 2882 case SOC_BLK_MMU_SC: 2883 return soc_trident3_sc_reg32_get(unit, reg, block_num, 2884 base_type_index, index, data); 2885 case SOC_BLK_MMU_SED: 2886 return soc_trident3_sed_reg32_get(unit, reg, block_num, 2887 base_type_index, index, data); 2888 default: 2889 return soc_reg32_get(unit, reg, port, index, data); 2890 } 2891 } 2892 2893 STATIC int 2894 _soc_td3_ser_reg32_set(int unit, soc_reg_t reg, int port, int index, 2895 uint32 data, int mmu_base_index) 2896 { 2897 int block_num = mmu_base_index; 2898 int base_type_index = mmu_base_index; 2899 soc_block_t blocktype = *SOC_REG_INFO(unit, reg).block; 2900 switch (blocktype) { 2901 case SOC_BLK_MMU_XPE: 2902 return soc_trident3_xpe_reg32_set(unit, reg, block_num, 2903 base_type_index, index, data); 2904 case SOC_BLK_MMU_SC: 2905 return soc_trident3_sc_reg32_set(unit, reg, block_num, 2906 base_type_index, index, data); 2907 case SOC_BLK_MMU_SED: 2908 return soc_trident3_sed_reg32_set(unit, reg, block_num, 2909 base_type_index, index, data); 2910 default: 2911 return soc_reg32_set(unit, reg, port, index, data); 2912 } 2913 } 2914 2915 int 2916 soc_td3_ser_reg_field32_modify(int unit, soc_reg_t reg, soc_port_t port, 2917 soc_field_t field, uint32 value, 2918 int index, int mmu_base_index) 2919 { 2920 uint32 rval; 2921 2922 SOC_IF_ERROR_RETURN 2923 (_soc_td3_ser_reg32_get(unit, reg, port, index, &rval, mmu_base_index)); 2924 soc_reg_field_set(unit, reg, &rval, field, value); 2925 SOC_IF_ERROR_RETURN 2926 (_soc_td3_ser_reg32_set(unit, reg, port, index, rval, mmu_base_index)); 2927 return SOC_E_NONE; 2928 } 2929 2930 STATIC int 2931 _soc_trident3_ser_mmu_mem_remap(_soc_ser_correct_info_t *spci) 2932 { 2933 if (spci == NULL) { 2934 return SOC_E_PARAM; 2935 } 2936 2937 /* LHS views are physical views of mem instances which encounter error and 2938 * are thus reported by HW. 2939 * 2940 * RHS views are logical views for which SW maintains cache and does 2941 * ser_correction writes. 2942 * 2943 * remap function thus maps physical mem views to logical mem views. 2944 */ 2945 2946 switch (spci->mem) { 2947 /* WRED */ 2948 case MMU_WRED_DROP_CURVE_PROFILE_0_Am: 2949 case MMU_WRED_DROP_CURVE_PROFILE_0_Bm: 2950 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_0m; break; 2951 case MMU_WRED_DROP_CURVE_PROFILE_1_Am: 2952 case MMU_WRED_DROP_CURVE_PROFILE_1_Bm: 2953 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_1m; break; 2954 case MMU_WRED_DROP_CURVE_PROFILE_2_Am: 2955 case MMU_WRED_DROP_CURVE_PROFILE_2_Bm: 2956 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_2m; break; 2957 case MMU_WRED_DROP_CURVE_PROFILE_3_Am: 2958 case MMU_WRED_DROP_CURVE_PROFILE_3_Bm: 2959 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_3m; break; 2960 case MMU_WRED_DROP_CURVE_PROFILE_4_Am: 2961 case MMU_WRED_DROP_CURVE_PROFILE_4_Bm: 2962 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_4m; break; 2963 case MMU_WRED_DROP_CURVE_PROFILE_5_Am: 2964 case MMU_WRED_DROP_CURVE_PROFILE_5_Bm: 2965 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_5m; break; 2966 case MMU_WRED_DROP_CURVE_PROFILE_6_Am: 2967 case MMU_WRED_DROP_CURVE_PROFILE_6_Bm: 2968 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_6m; break; 2969 case MMU_WRED_DROP_CURVE_PROFILE_7_Am: 2970 case MMU_WRED_DROP_CURVE_PROFILE_7_Bm: 2971 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_7m; break; 2972 case MMU_WRED_DROP_CURVE_PROFILE_8_Am: 2973 case MMU_WRED_DROP_CURVE_PROFILE_8_Bm: 2974 spci->mem = MMU_WRED_DROP_CURVE_PROFILE_8m; break; 2975 2976 2977 /* THDU */ 2978 case MMU_THDU_RESUME_PORT0_PIPE0m: 2979 case MMU_THDU_RESUME_PORT1_PIPE0m: 2980 case MMU_THDU_RESUME_PORT2_PIPE0m: 2981 spci->mem = MMU_THDU_RESUME_PORT_PIPE0m; break; 2982 case MMU_THDU_RESUME_PORT0_PIPE1m: 2983 case MMU_THDU_RESUME_PORT1_PIPE1m: 2984 case MMU_THDU_RESUME_PORT2_PIPE1m: 2985 spci->mem = MMU_THDU_RESUME_PORT_PIPE1m; break; 2986 2987 case MMU_THDU_CONFIG_PORT0_PIPE0m: 2988 case MMU_THDU_CONFIG_PORT1_PIPE0m: 2989 spci->mem = MMU_THDU_CONFIG_PORT_PIPE0m; break; 2990 case MMU_THDU_CONFIG_PORT0_PIPE1m: 2991 case MMU_THDU_CONFIG_PORT1_PIPE1m: 2992 spci->mem = MMU_THDU_CONFIG_PORT_PIPE1m; break; 2993 2994 case MMU_THDU_CONFIG_QGROUP0_PIPE0m: 2995 case MMU_THDU_CONFIG_QGROUP1_PIPE0m: 2996 spci->mem = MMU_THDU_CONFIG_QGROUP_PIPE0m; break; 2997 case MMU_THDU_CONFIG_QGROUP0_PIPE1m: 2998 case MMU_THDU_CONFIG_QGROUP1_PIPE1m: 2999 spci->mem = MMU_THDU_CONFIG_QGROUP_PIPE1m; break; 3000 3001 case MMU_THDU_OFFSET_QGROUP0_PIPE0m: 3002 case MMU_THDU_OFFSET_QGROUP1_PIPE0m: 3003 spci->mem = MMU_THDU_OFFSET_QGROUP_PIPE0m; break; 3004 case MMU_THDU_OFFSET_QGROUP0_PIPE1m: 3005 case MMU_THDU_OFFSET_QGROUP1_PIPE1m: 3006 spci->mem = MMU_THDU_OFFSET_QGROUP_PIPE1m; break; 3007 3008 case MMU_THDU_CONFIG_QUEUE0_PIPE0m: 3009 case MMU_THDU_CONFIG_QUEUE1_PIPE0m: 3010 spci->mem = MMU_THDU_CONFIG_QUEUE_PIPE0m; break; 3011 case MMU_THDU_CONFIG_QUEUE0_PIPE1m: 3012 case MMU_THDU_CONFIG_QUEUE1_PIPE1m: 3013 spci->mem = MMU_THDU_CONFIG_QUEUE_PIPE1m; break; 3014 3015 case MMU_THDU_OFFSET_QUEUE0_PIPE0m: 3016 case MMU_THDU_OFFSET_QUEUE1_PIPE0m: 3017 spci->mem = MMU_THDU_OFFSET_QUEUE_PIPE0m; break; 3018 case MMU_THDU_OFFSET_QUEUE0_PIPE1m: 3019 case MMU_THDU_OFFSET_QUEUE1_PIPE1m: 3020 spci->mem = MMU_THDU_OFFSET_QUEUE_PIPE1m; break; 3021 3022 case MMU_THDU_Q_TO_QGRP_MAP0_PIPE0m: 3023 case MMU_THDU_Q_TO_QGRP_MAP1_PIPE0m: 3024 case MMU_THDU_Q_TO_QGRP_MAP2_PIPE0m: 3025 spci->mem = MMU_THDU_Q_TO_QGRP_MAP_PIPE0m; break; 3026 case MMU_THDU_Q_TO_QGRP_MAP0_PIPE1m: 3027 case MMU_THDU_Q_TO_QGRP_MAP1_PIPE1m: 3028 case MMU_THDU_Q_TO_QGRP_MAP2_PIPE1m: 3029 spci->mem = MMU_THDU_Q_TO_QGRP_MAP_PIPE1m; break; 3030 3031 3032 /* THDI */ 3033 case THDI_PORT_SP_CONFIG0_PIPE0m: 3034 case THDI_PORT_SP_CONFIG1_PIPE0m: 3035 case THDI_PORT_SP_CONFIG2_PIPE0m: 3036 spci->mem = THDI_PORT_SP_CONFIG_PIPE0m; break; 3037 case THDI_PORT_SP_CONFIG0_PIPE1m: 3038 case THDI_PORT_SP_CONFIG1_PIPE1m: 3039 case THDI_PORT_SP_CONFIG2_PIPE1m: 3040 spci->mem = THDI_PORT_SP_CONFIG_PIPE1m; break; 3041 3042 3043 /* MTRO */ 3044 case MMU_MTRO_EGRMETERINGCONFIG_MEM_Am: 3045 case MMU_MTRO_EGRMETERINGCONFIG_MEM_Bm: 3046 spci->mem = MMU_MTRO_EGRMETERINGCONFIG_MEMm; break; 3047 case MMU_MTRO_EGRMETERINGCONFIG_MEM_A_PIPE0m: 3048 case MMU_MTRO_EGRMETERINGCONFIG_MEM_B_PIPE0m: 3049 spci->mem = MMU_MTRO_EGRMETERINGCONFIG_MEM_PIPE0m; break; 3050 case MMU_MTRO_EGRMETERINGCONFIG_MEM_A_PIPE1m: 3051 case MMU_MTRO_EGRMETERINGCONFIG_MEM_B_PIPE1m: 3052 spci->mem = MMU_MTRO_EGRMETERINGCONFIG_MEM_PIPE1m; break; 3053 case MMU_MTRO_L0_MEM_Am: 3054 case MMU_MTRO_L0_MEM_Bm: 3055 spci->mem = MMU_MTRO_L0_MEMm; break; 3056 case MMU_MTRO_L1_MEM_Am: 3057 case MMU_MTRO_L1_MEM_Bm: 3058 spci->mem = MMU_MTRO_L1_MEMm; break; 3059 3060 /* THDM */ 3061 case MMU_THDM_MCQE_QUEUE_CONFIG_A_PIPE0m: 3062 case MMU_THDM_MCQE_QUEUE_CONFIG_B_PIPE0m: 3063 case MMU_THDM_MCQE_QUEUE_CONFIG_C_PIPE0m: 3064 spci->mem = MMU_THDM_MCQE_QUEUE_CONFIG_PIPE0m; break; 3065 case MMU_THDM_MCQE_QUEUE_CONFIG_A_PIPE1m: 3066 case MMU_THDM_MCQE_QUEUE_CONFIG_B_PIPE1m: 3067 case MMU_THDM_MCQE_QUEUE_CONFIG_C_PIPE1m: 3068 spci->mem = MMU_THDM_MCQE_QUEUE_CONFIG_PIPE1m; break; 3069 3070 case MMU_THDM_DB_QUEUE_CONFIG_A_PIPE0m: 3071 case MMU_THDM_DB_QUEUE_CONFIG_B_PIPE0m: 3072 case MMU_THDM_DB_QUEUE_CONFIG_C_PIPE0m: 3073 spci->mem = MMU_THDM_DB_QUEUE_CONFIG_PIPE0m; break; 3074 case MMU_THDM_DB_QUEUE_CONFIG_A_PIPE1m: 3075 case MMU_THDM_DB_QUEUE_CONFIG_B_PIPE1m: 3076 case MMU_THDM_DB_QUEUE_CONFIG_C_PIPE1m: 3077 spci->mem = MMU_THDM_DB_QUEUE_CONFIG_PIPE1m; break; 3078 3079 case MMU_THDM_MCQE_PORTSP_CONFIG_A_PIPE0m: 3080 case MMU_THDM_MCQE_PORTSP_CONFIG_B_PIPE0m: 3081 case MMU_THDM_MCQE_PORTSP_CONFIG_C_PIPE0m: 3082 spci->mem = MMU_THDM_MCQE_PORTSP_CONFIG_PIPE0m; break; 3083 case MMU_THDM_MCQE_PORTSP_CONFIG_A_PIPE1m: 3084 case MMU_THDM_MCQE_PORTSP_CONFIG_B_PIPE1m: 3085 case MMU_THDM_MCQE_PORTSP_CONFIG_C_PIPE1m: 3086 spci->mem = MMU_THDM_MCQE_PORTSP_CONFIG_PIPE1m; break; 3087 3088 case MMU_THDM_DB_PORTSP_CONFIG_A_PIPE0m: 3089 case MMU_THDM_DB_PORTSP_CONFIG_B_PIPE0m: 3090 case MMU_THDM_DB_PORTSP_CONFIG_C_PIPE0m: 3091 spci->mem = MMU_THDM_DB_PORTSP_CONFIG_PIPE0m; break; 3092 case MMU_THDM_DB_PORTSP_CONFIG_A_PIPE1m: 3093 case MMU_THDM_DB_PORTSP_CONFIG_B_PIPE1m: 3094 case MMU_THDM_DB_PORTSP_CONFIG_C_PIPE1m: 3095 spci->mem = MMU_THDM_DB_PORTSP_CONFIG_PIPE1m; break; 3096 3097 case MMU_THDM_MCQE_QUEUE_OFFSET_A_PIPE0m: 3098 case MMU_THDM_MCQE_QUEUE_OFFSET_B_PIPE0m: 3099 case MMU_THDM_MCQE_QUEUE_OFFSET_C_PIPE0m: 3100 spci->mem = MMU_THDM_MCQE_QUEUE_OFFSET_PIPE0m; break; 3101 case MMU_THDM_MCQE_QUEUE_OFFSET_A_PIPE1m: 3102 case MMU_THDM_MCQE_QUEUE_OFFSET_B_PIPE1m: 3103 case MMU_THDM_MCQE_QUEUE_OFFSET_C_PIPE1m: 3104 spci->mem = MMU_THDM_MCQE_QUEUE_OFFSET_PIPE1m; break; 3105 3106 case MMU_THDM_DB_QUEUE_OFFSET_A_PIPE0m: 3107 case MMU_THDM_DB_QUEUE_OFFSET_B_PIPE0m: 3108 case MMU_THDM_DB_QUEUE_OFFSET_C_PIPE0m: 3109 spci->mem = MMU_THDM_DB_QUEUE_OFFSET_PIPE0m; break; 3110 case MMU_THDM_DB_QUEUE_OFFSET_A_PIPE1m: 3111 case MMU_THDM_DB_QUEUE_OFFSET_B_PIPE1m: 3112 case MMU_THDM_DB_QUEUE_OFFSET_C_PIPE1m: 3113 spci->mem = MMU_THDM_DB_QUEUE_OFFSET_PIPE1m; break; 3114 3115 case TCB_THRESHOLD_PROFILE_MAP_A_XPE0m: 3116 case TCB_THRESHOLD_PROFILE_MAP_B_XPE0m: 3117 spci->mem = TCB_THRESHOLD_PROFILE_MAP_XPE0m; break; 3118 3119 /* RQE */ 3120 case MMU_REPL_GROUP_INITIAL_COPY_COUNT0_SC0m: 3121 case MMU_REPL_GROUP_INITIAL_COPY_COUNT1_SC0m: 3122 spci->mem = MMU_REPL_GROUP_INITIAL_COPY_COUNT_SC0m; break; 3123 3124 default: 3125 break; 3126 } 3127 return SOC_E_NONE; 3128 } 3129 3130 /* correction routine for MMU_WRED_CONFIG mem */ 3131 STATIC int 3132 _soc_td3_mmu_wred_correction(int unit, _soc_ser_correct_info_t *spci, 3133 uint32 *addr, int *second_pass) 3134 { 3135 #if 0 3136 if ((spci == NULL) || (addr == NULL) || (second_pass == NULL)) { 3137 return SOC_E_PARAM; 3138 } 3139 switch (spci->mem) { 3140 case MMU_WRED_CONFIG_PIPE0m: 3141 spci->mem = MMU_WRED_CONFIG_PIPE1m; 3142 spci->mem_reported = MMU_WRED_CONFIG_PIPE1m; 3143 *addr &= _SOC_MMU_ADDR_ZERO_OUT_SEG_FIELD; 3144 *addr |= _SOC_MMU_ADDR_SEG1; 3145 spci->index = *addr - soc_mem_base(unit, spci->mem); 3146 spci->addr = *addr; 3147 *second_pass = 1; 3148 break; 3149 default: 3150 *second_pass = 0; 3151 break; 3152 } 3153 #endif 3154 return SOC_E_NONE; 3155 } 3156 3157 STATIC int 3158 _soc_trident3_ser_process_mmu_err(int unit, int block_info_idx, 3159 const _soc_td3_ser_info_t *info_list, 3160 char *prefix_str, int mmu_base_index) 3161 { 3162 int rv, type = 0, multi = 0; 3163 uint32 addr = 0, rval, rval_fifo_status, rval_intr_status_reg; 3164 uint32 non_ser_intr_status_mask; 3165 uint32 entry[SOC_MAX_MEM_WORDS]; 3166 soc_reg_t fifo_status_reg, mem_fail_ctr_reg; 3167 soc_reg_t parity_enable_reg = INVALIDr; 3168 soc_mem_t parity_enable_mem = INVALIDm; 3169 soc_field_t parity_enable_field = INVALIDf; 3170 soc_field_t *fields_stat = NULL; 3171 int parity_enable_field_position = -1; 3172 soc_mem_t ser_fifo_mem; 3173 soc_block_t blocktype = SOC_BLK_NONE; 3174 uint8 blk_idx; 3175 uint32 sblk = 0; 3176 _soc_ser_correct_info_t spci; 3177 int second_pass = 0; 3178 int i; 3179 int f, parity_error = 0; 3180 static int acc_type[] = {_SOC_ACC_TYPE_PIPE_ANY, _SOC_ACC_TYPE_PIPE_ANY}; 3181 soc_stat_t *stat = SOC_STAT(unit); 3182 3183 switch(info_list->type) { 3184 case _SOC_TD3_PARITY_TYPE_MMU_SER: { 3185 /* When we are here, we have been called by soc_td3_ser_process. 3186 * info_list points to 1st entry in _soc_td3_mmu_top_ser_info[]. 3187 * Goal is to find src_sub_block in mmu: MMU_GLB, XPE0,1,2,3, SC0,1 */ 3188 _soc_td3_ser_info_t *info = NULL; 3189 3190 /* find src of interrupt in mmu */ 3191 SOC_IF_ERROR_RETURN 3192 (soc_reg32_get(unit, info_list->intr_status_reg, REG_PORT_ANY, 0, 3193 &rval)); /* status_reg has BT,AT = CHIP,SINGLE */ 3194 for (i = 0; mmu_intr_info[i].int_statf != INVALIDf; i++) { 3195 if (soc_reg_field_get(unit, info_list->intr_status_reg, rval, 3196 mmu_intr_info[i].int_statf)) { 3197 #define MMU_INTR_SRC(i)\ 3198 ((i) == 0? "MMU_GLB" : \ 3199 (i) == 1? "MMU_XPE" : \ 3200 (i) == 2? "MMU_SC" : \ 3201 (i) == 3? "MMU_SED" : \ 3202 "MMU_UNNOWN") 3203 LOG_VERBOSE(BSL_LS_SOC_SER, 3204 (BSL_META_U(unit, 3205 "intr_status_reg = 0x%08x, " 3206 "int_statf = %d is set, mmu_intr_info_idx " 3207 "= %d (%s) !!\n"), 3208 rval, mmu_intr_info[i].int_statf, i, MMU_INTR_SRC(i))); 3209 info = &(info_list->info[mmu_intr_info[i].ser_info_index]); 3210 /* 'info' now points to entry info_index[i] 3211 * in _soc_td3_mmu_ser_info[] */ 3212 rv = _soc_trident3_ser_process_mmu_err(unit, block_info_idx, 3213 info, prefix_str, 3214 mmu_intr_info[i].mmu_base_index); 3215 if (SOC_FAILURE(rv)) { 3216 LOG_CLI((BSL_META_U(unit, 3217 "process_mmu_err: Error processing %s !!\n"), 3218 info->mem_str)); 3219 return rv; 3220 } 3221 } 3222 } 3223 if (info == NULL) { 3224 LOG_CLI((BSL_META_U(unit, 3225 "In MMU SER processing with no error bit set " 3226 "0x%08x !!\n"), rval)); 3227 return SOC_E_NONE; 3228 } 3229 } break; 3230 case _SOC_TD3_PARITY_TYPE_MMU_GLB: 3231 case _SOC_TD3_PARITY_TYPE_MMU_XPE: 3232 case _SOC_TD3_PARITY_TYPE_MMU_SC: 3233 case _SOC_TD3_PARITY_TYPE_MMU_SED: { 3234 /* we are here when we were recursively called by process_mmu_ser itself 3235 * and info_list is pointing to one of the entries in 3236 * _soc_td3_mmu_ser_info[] 3237 */ 3238 switch(info_list->type) { 3239 case _SOC_TD3_PARITY_TYPE_MMU_GLB: /* all of these regs,mem have BT,AT = CHIP,SINGLE */ 3240 fifo_status_reg = MMU_GCFG_MEM_SER_FIFO_STSr; 3241 ser_fifo_mem = MMU_GCFG_MEM_FAIL_ADDR_64m; 3242 mem_fail_ctr_reg = MMU_GCFG_MEM_FAIL_INT_CTRr; 3243 blocktype = SOC_BLK_MMU_GLB; 3244 acc_type[0] = _SOC_ACC_TYPE_PIPE_ANY; 3245 non_ser_intr_status_mask = ~0x1; 3246 /* MMU_GCFG_GLB_CPU_INT_STAT has only MEM_PAR_ERR_STATf */ 3247 break; 3248 case _SOC_TD3_PARITY_TYPE_MMU_XPE: /* all of these regs,mem have BT,AT = XPE,SINGLE */ 3249 fifo_status_reg = MMU_XCFG_MEM_SER_FIFO_STSr; 3250 ser_fifo_mem = MMU_XCFG_MEM_FAIL_ADDR_64_XPE0m; 3251 mem_fail_ctr_reg = MMU_XCFG_MEM_FAIL_INT_CTRr; 3252 blocktype = SOC_BLK_MMU_XPE; 3253 acc_type[0] = mmu_base_index; 3254 non_ser_intr_status_mask = ~0x1; 3255 /* bit 0 in MMU_XCFG_XPE_CPU_INT_STAT is MEM_PAR_ERR_STATf */ 3256 break; 3257 case _SOC_TD3_PARITY_TYPE_MMU_SC: /* all of these regs,mem have BT,AT = SLICE,SINGLE */ 3258 fifo_status_reg = MMU_SCFG_MEM_SER_FIFO_STSr; 3259 ser_fifo_mem = MMU_SCFG_MEM_FAIL_ADDR_64_SC0m; 3260 mem_fail_ctr_reg = MMU_SCFG_MEM_FAIL_INT_CTRr; 3261 blocktype = SOC_BLK_MMU_SC; 3262 acc_type[0] = mmu_base_index; 3263 non_ser_intr_status_mask = ~0x1; 3264 /* bit 0 in MMU_SCFG_SC_CPU_INT_STAT is MEM_PAR_ERR_STATf */ 3265 break; 3266 case _SOC_TD3_PARITY_TYPE_MMU_SED: 3267 fifo_status_reg = MMU_SEDCFG_MEM_SER_FIFO_STSr; 3268 ser_fifo_mem = MMU_SEDCFG_MEM_FAIL_ADDR_64m; 3269 mem_fail_ctr_reg = MMU_SEDCFG_MEM_FAIL_INT_CTRr; 3270 blocktype = SOC_BLK_MMU_SED; 3271 acc_type[0] = mmu_base_index; 3272 non_ser_intr_status_mask = ~0x2; 3273 /* bit 1 in MMU_SEDCFG_SED_CPU_INT_STAT is MEM_PAR_ERR_STATf */ 3274 break; 3275 default: 3276 return SOC_E_NONE; 3277 } 3278 SOC_IF_ERROR_RETURN 3279 (_soc_td3_ser_reg32_get(unit, info_list->intr_status_reg, 3280 REG_PORT_ANY, 0, &rval_intr_status_reg, mmu_base_index)); 3281 if (info_list->intr_status_field_list) { 3282 fields_stat = info_list->intr_status_field_list; 3283 for (f=0 ;; f++) { 3284 if (fields_stat[f] == INVALIDf) { 3285 break; 3286 } 3287 if ((fields_stat[f] == MEM_PAR_ERR_STATf) && 3288 soc_reg_field_get(unit, info_list->intr_status_reg, 3289 rval_intr_status_reg, fields_stat[f])) { 3290 parity_error = 1; 3291 } 3292 } 3293 } else if (info_list->intr_status_field == MEM_PAR_ERR_STATf) { 3294 if (soc_reg_field_get(unit, info_list->intr_status_reg, 3295 rval_intr_status_reg, info_list->intr_status_field)) { 3296 parity_error = 1; 3297 } 3298 } 3299 3300 if (parity_error == 1) { 3301 /* Now we know that one of the reasons for interrupt from MMU is 3302 * parity error for sure, so mmu_ser_fifo has to be non-empty */ 3303 SOC_IF_ERROR_RETURN 3304 (_soc_td3_ser_reg32_get(unit, fifo_status_reg, REG_PORT_ANY, 0, 3305 &rval_fifo_status, mmu_base_index)); 3306 if (soc_reg_field_get(unit, fifo_status_reg, rval_fifo_status, EMPTYf)) { 3307 LOG_ERROR(BSL_LS_SOC_SER, 3308 (BSL_META_U(unit, 3309 "unit %d %s SER interrupt with empty fifo !!\n"), 3310 unit, info_list->mem_str)); 3311 SOC_IF_ERROR_RETURN 3312 (soc_td3_ser_reg_field32_modify(unit, 3313 info_list->intr_clr_reg, 3314 REG_PORT_ANY, 3315 MEM_PAR_ERR_CLRf, 3316 1, 0, mmu_base_index)); 3317 return SOC_E_NONE; 3318 } 3319 SOC_IF_ERROR_RETURN 3320 (_soc_td3_ser_reg32_get(unit, mem_fail_ctr_reg, REG_PORT_ANY, 0, 3321 &rval, mmu_base_index)); 3322 LOG_WARN(BSL_LS_SOC_SER, 3323 (BSL_META_U(unit, 3324 "unit %d %s mem error interrupt count: %d\n"), 3325 unit, info_list->mem_str, rval)); 3326 SOC_BLOCK_ITER(unit, blk_idx, blocktype) { 3327 sblk = SOC_BLOCK2SCH(unit, blk_idx); 3328 break; 3329 } 3330 do { 3331 if (!second_pass) { 3332 SOC_IF_ERROR_RETURN 3333 (soc_mem_pop(unit, ser_fifo_mem, MEM_BLOCK_ANY, entry)); 3334 /* process entry */ 3335 LOG_WARN(BSL_LS_SOC_SER, 3336 (BSL_META_U(unit, 3337 "%s\n"), info_list->mem_str)); 3338 multi = soc_mem_field32_get(unit, ser_fifo_mem, entry, 3339 ERR_MULTf); 3340 type = soc_mem_field32_get(unit, ser_fifo_mem, entry, 3341 ERR_TYPEf); 3342 addr = soc_mem_field32_get(unit, ser_fifo_mem, entry, EADDRf); 3343 LOG_WARN(BSL_LS_SOC_SER, 3344 (BSL_META_U(unit, 3345 "unit %d %s %s %s error at address 0x%08x\n"), 3346 unit, info_list->mem_str, multi ? "multiple" : "", 3347 type ? ((type == 1) ? "1bit": "parity/2bit") : "", addr)); 3348 3349 sal_memset(&spci, 0, sizeof(spci)); 3350 spci.flags |= SOC_SER_SRC_MEM; 3351 if (multi) { 3352 spci.flags |= SOC_SER_ERR_MULTI; 3353 } 3354 if (type != 1) { 3355 spci.double_bit = 1; 3356 } 3357 spci.reg = INVALIDr; 3358 spci.mem = INVALIDm; 3359 spci.blk_type = blocktype; 3360 spci.pipe_num = -1; 3361 spci.sblk = sblk; 3362 spci.acc_type = -1; 3363 spci.detect_time = sal_time_usecs(); 3364 spci.addr = addr; 3365 parity_enable_reg = INVALIDr; 3366 parity_enable_field = INVALIDf; 3367 3368 /* Try to decode memory */ 3369 for (i = 0; ; i++) { 3370 spci.mem = soc_addr_to_mem_extended(unit, sblk, 3371 acc_type[i], 3372 addr); 3373 if (spci.mem != INVALIDm) { 3374 LOG_VERBOSE(BSL_LS_SOC_SER, 3375 (BSL_META_U(unit, 3376 "unit %d acc_type = %d " 3377 "got us mem %s \n"), 3378 unit, acc_type[i], 3379 SOC_MEM_NAME(unit,spci.mem))); 3380 break; 3381 } 3382 if (_SOC_ACC_TYPE_PIPE_ANY == acc_type[i]) { 3383 break; 3384 } 3385 } 3386 if (spci.mem != INVALIDm) { 3387 spci.index = addr - soc_mem_base(unit, spci.mem); 3388 spci.flags |= SOC_SER_REG_MEM_KNOWN; 3389 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 3390 /* ser_correction will fill cache part in ser_log */ 3391 spci.mem_reported = spci.mem; /* before remap */ 3392 spci.flags |= SOC_SER_LOG_MEM_REPORTED; 3393 SOC_IF_ERROR_RETURN 3394 (_soc_trident3_ser_mmu_mem_remap(&spci)); 3395 spci.parity_type = _soc_td3_mem_has_ecc(unit, spci.mem)? 3396 SOC_PARITY_TYPE_ECC : 3397 SOC_PARITY_TYPE_PARITY; 3398 LOG_VERBOSE(BSL_LS_SOC_SER, 3399 (BSL_META_U(unit, 3400 "unit %d mem for ser_correction =" 3401 " %s \n"), 3402 unit, SOC_MEM_NAME(unit,spci.mem))); 3403 _soc_td3_ser_control_reg_get(unit, 3404 (const _soc_mem_ser_en_info_t *)SOC_MMU_MEM_SER_INFO(unit), 3405 spci.mem, /* after remap */ 3406 &parity_enable_reg, 3407 &parity_enable_mem, 3408 &parity_enable_field, 3409 &parity_enable_field_position); 3410 3411 } else { 3412 spci.flags |= SOC_SER_REG_MEM_UNKNOWN; 3413 spci.mem_reported = INVALIDm; 3414 parity_enable_reg = INVALIDr; 3415 parity_enable_field = INVALIDf; 3416 } 3417 } /* !second_pass */ 3418 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3419 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 3420 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, 3421 addr); 3422 3423 spci.log_id = _soc_td3_populate_ser_log(unit, 3424 parity_enable_reg, 3425 parity_enable_mem, 3426 parity_enable_field, 3427 parity_enable_field_position, 3428 spci.mem_reported, 3429 blk_idx, 3430 spci.pipe_num, 3431 spci.index, 3432 spci.detect_time, 3433 spci.sblk, 3434 spci.addr, 3435 1, /* disable_parity */ 3436 0, /* disable_mem_read */ 3437 0, /* disable_fill_cache_log */ 3438 1, /* force_cache_log */ 3439 FALSE, 0); 3440 if ((spci.mem != INVALIDm) && 3441 (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != 0)) { 3442 spci.inst = mmu_base_index; 3443 3444 if ((SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) == 3445 SOC_MEM_FLAG_SER_ENTRY_CLEAR) && 3446 (info_list->type == _SOC_TD3_PARITY_TYPE_MMU_XPE)) { 3447 3448 spci.flags |= SOC_SER_ALSO_UPDATE_SW_COUNTER; 3449 /* xpe0, 1, 2, 3 */ 3450 spci.pipe_num = (spci.addr >> 15) & 0x3; 3451 /* bits 16:15 */ 3452 switch (spci.mem) { 3453 #if 0 3454 case MMU_CTR_COLOR_DROP_MEM_XPE0_PIPE0m: 3455 spci.counter_base_mem = MMU_CTR_COLOR_DROP_MEMm; 3456 spci.pipe_num = 0; /* Note */ 3457 break; 3458 case MMU_CTR_COLOR_DROP_MEM_XPE0_PIPE1m: 3459 spci.counter_base_mem = MMU_CTR_COLOR_DROP_MEMm; 3460 spci.pipe_num = 1; /* Note */ 3461 break; 3462 #endif 3463 case MMU_CTR_ING_DROP_MEM_XPE0_PIPE0m: 3464 spci.counter_base_mem = MMU_CTR_ING_DROP_MEMm; 3465 spci.pipe_num = 0; 3466 break; 3467 case MMU_CTR_MC_DROP_MEM_XPE0_PIPE0m: 3468 case MMU_CTR_MC_DROP_MEM_XPE0_PIPE1m: 3469 spci.counter_base_mem = MMU_CTR_MC_DROP_MEMm; 3470 break; 3471 3472 case MMU_CTR_UC_DROP_MEM_XPE0_PIPE0m: 3473 case MMU_CTR_UC_DROP_MEM_XPE0_PIPE1m: 3474 spci.counter_base_mem = MMU_CTR_UC_DROP_MEMm; 3475 break; 3476 3477 case MMU_CTR_WRED_DROP_MEM_XPE0_PIPE0m: 3478 case MMU_CTR_WRED_DROP_MEM_XPE0_PIPE1m: 3479 spci.counter_base_mem = MMU_CTR_WRED_DROP_MEMm; 3480 break; 3481 3482 /* Instantaneous counts */ 3483 case MMU_THDM_DB_PORTSP_BST_XPE0_PIPE0m: 3484 case MMU_THDM_DB_PORTSP_BST_XPE0_PIPE1m: 3485 spci.counter_base_mem = MMU_THDM_DB_PORTSP_BSTm; 3486 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3487 break; 3488 3489 /* Instantaneous counts */ 3490 case MMU_THDM_DB_QUEUE_BST_XPE0_PIPE0m: 3491 case MMU_THDM_DB_QUEUE_BST_XPE0_PIPE1m: 3492 spci.counter_base_mem = MMU_THDM_DB_QUEUE_BSTm; 3493 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3494 break; 3495 3496 /* Instantaneous counts */ 3497 case MMU_THDM_MCQE_PORTSP_BST_XPE0_PIPE0m: 3498 case MMU_THDM_MCQE_PORTSP_BST_XPE0_PIPE1m: 3499 spci.counter_base_mem = MMU_THDM_MCQE_PORTSP_BSTm; 3500 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3501 break; 3502 3503 /* Instantaneous counts */ 3504 case MMU_THDM_MCQE_QUEUE_BST_XPE0_PIPE0m: 3505 case MMU_THDM_MCQE_QUEUE_BST_XPE0_PIPE1m: 3506 spci.counter_base_mem = MMU_THDM_MCQE_QUEUE_BSTm; 3507 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3508 break; 3509 3510 /* Not collected by SW */ 3511 case THDI_PORT_PG_BST_XPE0_PIPE0m: 3512 spci.counter_base_mem = THDI_PORT_PG_BSTm; 3513 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3514 break; 3515 3516 /* Not collected by SW */ 3517 case THDI_PORT_SP_BST_XPE0_PIPE0m: 3518 spci.counter_base_mem = THDI_PORT_SP_BSTm; 3519 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3520 break; 3521 3522 /* Unexpected mems */ 3523 default: 3524 spci.flags &= ~SOC_SER_ALSO_UPDATE_SW_COUNTER; 3525 /* use HW only clear */ 3526 spci.counter_base_mem = INVALIDm; 3527 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, 3528 "Mem %s (sbus_addr: 0x%08x), will use hw_only_clear, " 3529 "inst %d, pipe %d\n"), 3530 SOC_MEM_NAME(unit, spci.mem), addr, 3531 spci.inst, spci.pipe_num)); 3532 break; 3533 } 3534 } 3535 rv = soc_ser_correction(unit, &spci); 3536 if (SOC_FAILURE(rv)) { 3537 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3538 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3539 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, 3540 addr); 3541 soc_ser_stat_update(unit, 0, spci.blk_type, 3542 spci.parity_type, 3543 spci.double_bit, 3544 SocSerCorrectTypeFailedToCorrect, 3545 stat); 3546 /* Dont 'return' here - as it will skip clearing of 3547 * interrupt and thus will result in processing of empty 3548 * ser fifo */ 3549 } 3550 } else if (spci.mem == INVALIDm) { 3551 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3552 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3553 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, 3554 addr); 3555 soc_ser_stat_update(unit, 0, spci.blk_type, 3556 (type == 1) ? SOC_PARITY_TYPE_ECC : 3557 SOC_PARITY_TYPE_PARITY, 3558 spci.double_bit, 3559 SocSerCorrectTypeNoAction, 3560 stat); 3561 LOG_ERROR(BSL_LS_SOC_SER, 3562 (BSL_META_U(unit, 3563 "unit %d %s address 0x%08x: decoding of address to mem FAILED !!\n"), 3564 unit, info_list->mem_str, addr)); 3565 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3566 SOC_SWITCH_EVENT_DATA_ERROR_FATAL, 3567 INVALIDm, 3568 spci.index); 3569 /* Dont 'return' here - as it will skip clearing of 3570 * interrupt and thus will result in processing of empty 3571 * ser fifo */ 3572 } else { 3573 rv = SOC_E_NONE; 3574 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3575 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 3576 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, 3577 addr); 3578 soc_ser_stat_update(unit, 0, spci.blk_type, 3579 (type == 1) ? SOC_PARITY_TYPE_ECC : 3580 SOC_PARITY_TYPE_PARITY, 3581 spci.double_bit, 3582 SocSerCorrectTypeNoAction, 3583 stat); 3584 } 3585 3586 if (spci.log_id != 0) { 3587 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3588 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3589 spci.log_id, 0); 3590 if (soc_property_get(unit, "ser_log_print_one", 0)) { 3591 soc_ser_log_print_one(unit, spci.log_id); 3592 } 3593 } 3594 3595 if (second_pass) { 3596 /* already in second_pass, move to next fifo entry */ 3597 SOC_IF_ERROR_RETURN 3598 (_soc_td3_ser_reg32_get(unit, fifo_status_reg, 3599 REG_PORT_ANY, 0, 3600 &rval_fifo_status, 3601 mmu_base_index)); 3602 second_pass = 0; 3603 /* start next fifo entry with second_pass=0 */ 3604 } else { /* in first_pass */ 3605 SOC_IF_ERROR_RETURN 3606 (_soc_td3_mmu_wred_correction(unit, &spci, &addr, 3607 &second_pass)); 3608 if (!second_pass) { 3609 /* second_pass not needed */ 3610 SOC_IF_ERROR_RETURN 3611 (_soc_td3_ser_reg32_get(unit, fifo_status_reg, 3612 REG_PORT_ANY, 0, 3613 &rval_fifo_status, 3614 mmu_base_index)); 3615 } 3616 /* else, second_pass is needed, don't read next fifo entry 3617 * yet */ 3618 } 3619 } while (!soc_reg_field_get(unit, fifo_status_reg, rval_fifo_status, EMPTYf)); 3620 SOC_IF_ERROR_RETURN 3621 (soc_td3_ser_reg_field32_modify(unit, info_list->intr_clr_reg, 3622 REG_PORT_ANY, 3623 MEM_PAR_ERR_CLRf, 1, 3624 0, mmu_base_index)); 3625 } 3626 3627 /* non_ser mmu interrupts in same status reg are asserted */ 3628 if (rval_intr_status_reg & non_ser_intr_status_mask) { 3629 3630 rv = soc_td3_mmu_non_ser_intr_handler(unit, 3631 blocktype, 3632 /* can be SOC_BLK_MMU_XPE, SOC_BLK_MMU_SED */ 3633 mmu_base_index, 3634 /* specifies xpe0 in case of SOC_BLK_MMU_XPE */ 3635 /* specifies sc0 in case of SOC_BLK_MMU_SC */ 3636 rval_intr_status_reg & 3637 non_ser_intr_status_mask); 3638 /* value of intr_status_reg */ 3639 } 3640 } break; 3641 default: 3642 break; 3643 } 3644 3645 return SOC_E_NONE; 3646 } 3647 3648 STATIC int 3649 _soc_trident3_ser_process_ecc(int unit, int block_info_idx, int pipe, int port, 3650 const _soc_td3_ser_info_t *info, 3651 char *prefix_str, char *mem_str, 3652 soc_block_t blocktype, int idb_scan_thread) 3653 { 3654 _soc_td3_ser_reg_t reg_entry[2], *reg_ptr; 3655 soc_reg_t reg, parity_enable_reg; 3656 soc_field_t ecc_field = ECC_ERRf, parity_enable_field; 3657 uint32 rval, minfo; 3658 uint32 entry_idx, idx, has_error; 3659 uint32 multiple = 0, double_bit = 0; 3660 char *mem_str_ptr; 3661 _soc_ser_correct_info_t spci; 3662 int rv; 3663 soc_stat_t *stat = SOC_STAT(unit); 3664 uint64 rval64; 3665 /* 3666 * info can be 3667 * _soc_td3_pm_clp_ser_info[] for which info->mem is always INVALIDm 3668 * _soc_td3_pm_xlp_ser_info[] for which info->mem is always INVALIDm 3669 * _soc_td3_idb_ser_info[] for which info->mem may not be INVALIDm 3670 */ 3671 if (info->intr_status_reg != INVALIDr) { 3672 reg_entry[0].reg = info->intr_status_reg; 3673 reg_entry[0].mem_str = NULL; 3674 reg_entry[1].reg = INVALIDr; 3675 reg_ptr = reg_entry; 3676 } else if (info->intr_status_reg_list != NULL) { 3677 reg_ptr = info->intr_status_reg_list; 3678 } else { 3679 return SOC_E_NONE; 3680 } 3681 3682 if (INVALIDf != info->intr_status_field) { 3683 ecc_field = info->intr_status_field; 3684 } 3685 3686 has_error = FALSE; 3687 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 3688 reg = reg_ptr[idx].reg; 3689 if ((blocktype == SOC_BLK_IPIPE || blocktype == SOC_BLK_EPIPE) && 3690 (SOC_REG_UNIQUE_ACC(unit, reg) != NULL)) { 3691 reg = SOC_REG_UNIQUE_ACC(unit, reg)[pipe]; 3692 } 3693 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 3694 reg_ptr[idx].mem_str : mem_str; 3695 3696 sal_memset(&spci, 0, sizeof(spci)); 3697 3698 rv = soc_reg32_get(unit, reg, port, 0, &rval); 3699 if (SOC_FAILURE(rv)) { 3700 return rv; 3701 } 3702 3703 /* LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, "idb_status_reg %s, = 0x%x\n"), SOC_REG_NAME(unit, reg), rval)); */ 3704 if (soc_reg_field_get(unit, reg, rval, ecc_field)) { 3705 has_error = TRUE; 3706 if (reg == CENTRAL_CTR_EVICTION_INTR_STATUSr) { 3707 rv = soc_reg32_get(unit, CENTRAL_CTR_EVICTION_FIFO_PARITY_ERRORr, 3708 port, 0, &rval); 3709 if (SOC_FAILURE(rv)) { 3710 return rv; 3711 } 3712 3713 entry_idx = soc_reg_field_get(unit, 3714 CENTRAL_CTR_EVICTION_FIFO_PARITY_ERRORr, 3715 rval, MEMINDEXf); 3716 } else { 3717 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 3718 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf); 3719 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 3720 } 3721 _soc_td3_mem_parity_info(unit, block_info_idx, pipe, 3722 info->group_reg_status_field, &minfo); 3723 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3724 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 3725 SOC_SER_ERROR_ENTRY_ID_MINFO_SET | entry_idx, minfo); 3726 LOG_VERBOSE(BSL_LS_SOC_SER, 3727 (BSL_META_U(unit, 3728 "idb_status_reg %s, = 0x%x\n"), 3729 SOC_REG_NAME(unit, reg), rval)); 3730 if (double_bit) { 3731 /* Entry Idx: 3732 * 0-15 Port 0 3733 * 16-31 Port 1 3734 * 32-47 Port 2 3735 * 48-63 Port 3 3736 * In case of double-bit error we need to reset MIB counters 3737 * for that port to recover 3738 * 3739 * Currently only PORT MIB errors are marked _SOC_TD3_PARITY_TYPE_ECC 3740 */ 3741 rval = 0x1 << ((entry_idx & 63) / 16); 3742 if (blocktype == SOC_BLK_XLPORT) { 3743 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, XLPORT_MIB_RESETr, port, 0, rval)); 3744 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, XLPORT_MIB_RESETr, port, 0, 0x0)); 3745 } else if (blocktype == SOC_BLK_CLPORT) { 3746 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, CLPORT_MIB_RESETr, port, 0, rval)); 3747 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, CLPORT_MIB_RESETr, port, 0, 0x0)); 3748 } 3749 3750 LOG_WARN(BSL_LS_SOC_SER, 3751 (BSL_META_U(unit, 3752 "%s %s (pipe %0d) entry %d double-bit ECC error\n"), 3753 prefix_str, mem_str_ptr, pipe, entry_idx)); 3754 } else { 3755 LOG_WARN(BSL_LS_SOC_SER, 3756 (BSL_META_U(unit, 3757 "%s %s (pipe %0d) entry %d ECC error\n"), 3758 prefix_str, mem_str_ptr, pipe, entry_idx)); 3759 } 3760 if (multiple) { 3761 LOG_WARN(BSL_LS_SOC_SER, 3762 (BSL_META_U(unit, 3763 "%s %s (pipe %0d) has multiple ECC errors\n"), 3764 prefix_str, mem_str_ptr, pipe)); 3765 } 3766 3767 if (IDB_IS_TDM_CAL_ECC_STATUSr == reg_ptr[idx].reg) { 3768 if (double_bit) { 3769 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3770 SOC_SWITCH_EVENT_DATA_ERROR_FATAL, 3771 INVALIDm, 3772 entry_idx); 3773 } 3774 } 3775 3776 spci.flags = SOC_SER_SRC_MEM; 3777 if (multiple) { 3778 spci.flags |= SOC_SER_ERR_MULTI; 3779 } 3780 spci.double_bit = double_bit; 3781 spci.reg = INVALIDr; 3782 if (reg_ptr[idx].reg == IDB_IS_TDM_CAL_ECC_STATUSr) { 3783 if (entry_idx >= soc_mem_index_count(unit, IS_TDM_CALENDAR0m)) { 3784 /* entry_idx shared between IS_TDM_CALENDAR0/1m */ 3785 spci.mem = IS_TDM_CALENDAR1m; 3786 entry_idx -= soc_mem_index_count(unit, IS_TDM_CALENDAR0m); 3787 } else { 3788 spci.mem = IS_TDM_CALENDAR0m; 3789 } 3790 /* programming on each pipe can be different */ 3791 if (SOC_MEM_UNIQUE_ACC(unit, spci.mem) != NULL) { 3792 spci.mem = SOC_MEM_UNIQUE_ACC(unit, 3793 spci.mem)[pipe]; 3794 } 3795 parity_enable_reg = IDB_SER_CONTROLr; 3796 parity_enable_field = IS_TDM_ECC_ENf; 3797 } else { 3798 spci.mem = INVALIDm; /* non sbus-accessible */ 3799 parity_enable_reg = INVALIDr; 3800 parity_enable_field = INVALIDf; 3801 } 3802 spci.blk_type = blocktype; 3803 spci.index = entry_idx; 3804 spci.parity_type = SOC_PARITY_TYPE_ECC; 3805 spci.detect_time = sal_time_usecs(); 3806 spci.pipe_num = pipe; 3807 spci.acc_type = -1; 3808 spci.addr = (spci.mem != INVALIDm)? SOC_MEM_BASE(unit, spci.mem) : 0; 3809 if (spci.mem != INVALIDm) { 3810 spci.flags |= SOC_SER_REG_MEM_KNOWN; 3811 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 3812 } 3813 if (!idb_scan_thread) { 3814 spci.log_id = _soc_td3_populate_ser_log(unit, 3815 parity_enable_reg, 3816 INVALIDm, 3817 parity_enable_field, 3818 -1, 3819 spci.mem, 3820 (spci.mem != INVALIDm) ? SOC_MEM_BLOCK_ANY(unit, spci.mem) : 0, 3821 spci.pipe_num, 3822 spci.index, 3823 spci.detect_time, 3824 spci.sblk, /* 0 */ 3825 spci.addr, 3826 1, /* disable_parity */ 3827 0, /* disable_mem_read */ 3828 0, /* disable_fill_cache_log */ 3829 1, /* force_cache_log */ 3830 FALSE, 0); 3831 } /* for idb_scan_thread, spci.log_id will be 0 */ 3832 if (spci.mem != INVALIDm) { 3833 rv = soc_ser_correction(unit, &spci); 3834 if (spci.log_id != 0) { 3835 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3836 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3837 spci.log_id, 0); 3838 if (soc_property_get(unit, "ser_log_print_one", 0)) { 3839 soc_ser_log_print_one(unit, spci.log_id); 3840 } 3841 } 3842 if (SOC_FAILURE(rv)) { 3843 /* Add reporting failed to correct event flag to 3844 * application */ 3845 soc_event_generate(unit, 3846 SOC_SWITCH_EVENT_PARITY_ERROR, 3847 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3848 spci.sblk | (spci.pipe_num << SOC_SER_ERROR_PIPE_BP) | 3849 SOC_SER_ERROR_DATA_BLK_ADDR_SET, spci.addr); 3850 soc_ser_stat_update(unit, 0, spci.blk_type, 3851 spci.parity_type, 3852 spci.double_bit, 3853 SocSerCorrectTypeFailedToCorrect, 3854 stat); 3855 return rv; 3856 } 3857 } else { 3858 soc_ser_stat_update(unit, 0, spci.blk_type, 3859 spci.parity_type, 3860 spci.double_bit, 3861 SocSerCorrectTypeNoAction, 3862 stat); 3863 } 3864 if ((spci.mem == INVALIDm) && (spci.log_id != 0)) { 3865 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3866 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3867 spci.log_id, 0); 3868 rv = _soc_td3_add_log_generic(unit, &spci); 3869 if (SOC_FAILURE(rv)) { 3870 return rv; 3871 } 3872 if (soc_property_get(unit, "ser_log_print_one", 0)) { 3873 soc_ser_log_print_one(unit, spci.log_id); 3874 } 3875 } 3876 3877 if (spci.mem == INVALIDm) { 3878 /* Add reporting failed to correct event flag to application */ 3879 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3880 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3881 SOC_SER_ERROR_ENTRY_ID_MINFO_SET | entry_idx, minfo); 3882 } 3883 3884 /* Clear parity status */ 3885 rv = soc_reg32_set(unit, reg, port, 0, 0); 3886 if (SOC_FAILURE(rv)) { 3887 return rv; 3888 } 3889 3890 if ((info->intr_clr_reg != INVALIDr) && (INVALIDf != info->intr_clr_field)) { 3891 COMPILER_64_ZERO(rval64); 3892 /* write 1 to clear */ 3893 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval64, info->intr_clr_field, 1); 3894 rv = soc_reg_set(unit, info->intr_clr_reg, port, 0, rval64); 3895 if (SOC_FAILURE(rv)) { 3896 return rv; 3897 } 3898 } 3899 } 3900 } 3901 3902 if (!has_error && !idb_scan_thread) { 3903 LOG_VERBOSE(BSL_LS_SOC_SER, 3904 (BSL_META_U(unit, 3905 "%s %s ECC hardware inconsistency (pipe %d)\n"), 3906 prefix_str, mem_str, pipe)); 3907 } 3908 return SOC_E_NONE; 3909 } 3910 3911 int 3912 soc_td3_scan_idb_mem_ecc_status(int unit) 3913 { 3914 int pipe; 3915 int block_info_idx; 3916 int port = REG_PORT_ANY; 3917 char prefix_str[10]; 3918 char *mem_str = "IP IDB memory"; 3919 soc_block_t blocktype = SOC_BLK_IPIPE; 3920 static const _soc_td3_ser_info_t *info = &_soc_td3_idb_ser_info[0]; 3921 /* only OBM queue buffer */ 3922 int idb_scan_thread = 1; 3923 /* Scan is needed only for A0 */ 3924 sal_sprintf(prefix_str, "\nUnit: %d ", unit); 3925 SOC_BLOCK_ITER(unit, block_info_idx, blocktype) { 3926 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 3927 SOC_IF_ERROR_RETURN( 3928 _soc_trident3_ser_process_ecc(unit, 3929 block_info_idx, 3930 pipe, port, info, 3931 prefix_str, mem_str, 3932 blocktype, idb_scan_thread)); 3933 } 3934 } 3935 return SOC_E_NONE; 3936 } 3937 3938 STATIC int 3939 _soc_trident3_ser_process_parity(int unit, int block_info_idx, int pipe, int port, 3940 const _soc_td3_ser_info_t *info, 3941 char *prefix_str, char *mem_str, 3942 soc_block_t blocktype) 3943 { 3944 _soc_td3_ser_reg_t reg_entry[2], *reg_ptr; 3945 soc_reg_t reg; 3946 soc_field_t parity_error_field = PARITY_ERRORf; 3947 uint32 rval, minfo; 3948 uint32 multiple, entry_idx, idx, has_error; 3949 char *mem_str_ptr; 3950 _soc_ser_correct_info_t spci; 3951 soc_stat_t *stat = SOC_STAT(unit); 3952 3953 /* 3954 * info can be 3955 * _soc_td3_idb_ser_info[] for which info->mem cannot be INVALIDm 3956 */ 3957 if (info->intr_status_reg != INVALIDr) { 3958 reg_entry[0].reg = info->intr_status_reg; 3959 reg_entry[0].mem_str = NULL; 3960 reg_entry[1].reg = INVALIDr; 3961 reg_ptr = reg_entry; 3962 } else if (info->intr_status_reg_list != NULL) { 3963 reg_ptr = info->intr_status_reg_list; 3964 } else { 3965 return SOC_E_NONE; 3966 } 3967 3968 if (INVALIDf != info->intr_status_field) { 3969 parity_error_field = info->intr_status_field; 3970 } 3971 3972 has_error = FALSE; 3973 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 3974 reg = reg_ptr[idx].reg; 3975 if ((blocktype == SOC_BLK_IPIPE || blocktype == SOC_BLK_EPIPE) && 3976 (SOC_REG_UNIQUE_ACC(unit, reg) != NULL)) { 3977 reg = SOC_REG_UNIQUE_ACC(unit, reg)[pipe]; 3978 } 3979 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 3980 reg_ptr[idx].mem_str : mem_str; 3981 3982 sal_memset(&spci, 0, sizeof(spci)); 3983 3984 SOC_IF_ERROR_RETURN 3985 (soc_reg32_get(unit, reg, port, 0, &rval)); 3986 if (soc_reg_field_get(unit, reg, rval, parity_error_field)) { 3987 has_error = TRUE; 3988 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 3989 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 3990 _soc_td3_mem_parity_info(unit, block_info_idx, pipe, 3991 info->group_reg_status_field, &minfo); 3992 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3993 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3994 SOC_SER_ERROR_ENTRY_ID_MINFO_SET | entry_idx, minfo); 3995 3996 LOG_VERBOSE(BSL_LS_SOC_SER, 3997 (BSL_META_U(unit, 3998 "idb_status_reg %s, = 0x%x\n"), 3999 SOC_REG_NAME(unit, reg), rval)); 4000 LOG_WARN(BSL_LS_SOC_SER, 4001 (BSL_META_U(unit, 4002 "%s %s (pipe %0d) entry %d parity error\n"), 4003 prefix_str, mem_str_ptr, pipe, entry_idx)); 4004 if (multiple) { 4005 LOG_WARN(BSL_LS_SOC_SER, 4006 (BSL_META_U(unit, 4007 "%s %s (pipe %0d) has multiple parity errors\n"), 4008 prefix_str, mem_str_ptr, pipe)); 4009 } 4010 4011 spci.flags = SOC_SER_SRC_MEM; 4012 if (multiple) { 4013 spci.flags |= SOC_SER_ERR_MULTI; 4014 } 4015 spci.double_bit = 0; 4016 spci.reg = INVALIDr; 4017 spci.mem = info->mem; 4018 if ((spci.mem != INVALIDm) && 4019 (SOC_MEM_UNIQUE_ACC(unit, spci.mem) != NULL)) { 4020 spci.mem = SOC_MEM_UNIQUE_ACC(unit, spci.mem)[pipe]; 4021 } 4022 spci.blk_type = blocktype; 4023 spci.index = entry_idx; 4024 spci.parity_type = SOC_PARITY_TYPE_PARITY; 4025 spci.detect_time = sal_time_usecs(); 4026 spci.pipe_num = pipe; 4027 spci.acc_type = -1; 4028 spci.addr = (spci.mem != INVALIDm)? SOC_MEM_BASE(unit, spci.mem) : 0; 4029 if (spci.mem != INVALIDm) { 4030 spci.flags |= SOC_SER_REG_MEM_KNOWN; 4031 } 4032 spci.log_id = _soc_td3_populate_ser_log(unit, 4033 info->enable_reg, 4034 INVALIDm, 4035 info->enable_field, 4036 -1, 4037 spci.mem, 4038 (spci.mem != INVALIDm)? SOC_MEM_BLOCK_ANY(unit, spci.mem) : 0, 4039 spci.pipe_num, 4040 spci.index, 4041 spci.detect_time, 4042 spci.sblk, /* 0 */ 4043 spci.addr, 4044 1, /* disable_parity */ 4045 0, /* disable_mem_read */ 4046 0, /* disable_fill_cache_log */ 4047 0, /* force_cache_log */ 4048 FALSE, 0); 4049 /* for all memories in this list, ser_resonse is NONE */ 4050 4051 /* rv = soc_ser_correction(unit, &spci); */ 4052 soc_ser_stat_update(unit, 0, spci.blk_type, 4053 spci.parity_type, 4054 spci.double_bit, 4055 SocSerCorrectTypeNoAction, 4056 stat); 4057 4058 if (spci.log_id != 0) { 4059 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4060 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4061 spci.log_id, 0); 4062 SOC_IF_ERROR_RETURN(_soc_td3_add_log_generic(unit, &spci)); 4063 if (soc_property_get(unit, "ser_log_print_one", 0)) { 4064 soc_ser_log_print_one(unit, spci.log_id); 4065 } 4066 } 4067 4068 /* Add reporting failed to correct event flag to application */ 4069 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4070 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 4071 SOC_SER_ERROR_ENTRY_ID_MINFO_SET | entry_idx, minfo); 4072 4073 /* Clear parity status */ 4074 SOC_IF_ERROR_RETURN 4075 (soc_reg32_set(unit, reg, port, 0, 0)); 4076 } 4077 } 4078 4079 if (!has_error) { 4080 LOG_VERBOSE(BSL_LS_SOC_SER, 4081 (BSL_META_U(unit, 4082 "%s %s parity hardware inconsistency (pipe %d)\n"), 4083 prefix_str, mem_str, pipe)); 4084 } 4085 4086 return SOC_E_NONE; 4087 } 4088 4089 STATIC int 4090 _soc_trident3_ser_process_mac(int unit, int block_info_idx, 4091 const _soc_td3_ser_info_t *info, 4092 char *prefix_str, char *mem_str, soc_block_t blocktype) 4093 { 4094 uint32 rval = 0; 4095 uint64 rval64; 4096 uint32 has_error = FALSE; 4097 soc_stat_t *stat = SOC_STAT(unit); 4098 int log_port; 4099 int single_bit = 0, double_bit = 0; 4100 4101 if ((info->intr_status_reg == INVALIDr) || (INVALIDf == info->intr_status_field)) { 4102 return SOC_E_NONE; 4103 } 4104 4105 COMPILER_64_ZERO(rval64); 4106 PBMP_ITER(SOC_BLOCK_BITMAP(unit, block_info_idx), log_port) { 4107 single_bit = 0; 4108 double_bit = 0; 4109 if (SOC_REG_IS_64(unit, info->intr_status_reg)) { 4110 SOC_IF_ERROR_RETURN 4111 (soc_reg_get(unit, info->intr_status_reg, log_port, 0, &rval64)); 4112 if (soc_reg64_field32_get(unit, info->intr_status_reg, 4113 rval64, info->intr_status_field)) { 4114 has_error = TRUE; 4115 if (info->intr_status_field == SUM_RX_TS_MEM_SINGLE_BIT_ERRf || 4116 info->intr_status_field == SUM_RX_CDC_SINGLE_BIT_ERRf || 4117 info->intr_status_field == SUM_TX_CDC_SINGLE_BIT_ERRf) { 4118 single_bit = 1; 4119 } 4120 if (info->intr_status_field == SUM_RX_TS_MEM_DOUBLE_BIT_ERRf || 4121 info->intr_status_field == SUM_RX_CDC_DOUBLE_BIT_ERRf || 4122 info->intr_status_field == SUM_TX_CDC_DOUBLE_BIT_ERRf) { 4123 double_bit = 1; 4124 } 4125 } 4126 if ((info->intr_clr_reg != INVALIDr) && (INVALIDf != info->intr_clr_field)) { 4127 COMPILER_64_ZERO(rval64); 4128 SOC_IF_ERROR_RETURN(soc_reg_get(unit, info->intr_clr_reg, log_port, 0, &rval64)); 4129 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval64, info->intr_clr_field, 4130 0); 4131 SOC_IF_ERROR_RETURN 4132 (soc_reg_set(unit, info->intr_clr_reg, log_port, 0, rval64)); 4133 } 4134 } else { 4135 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, info->intr_status_reg, log_port, 0, &rval)); 4136 if (soc_reg_field_get(unit, info->intr_status_reg, rval, 4137 info->intr_status_field)) { 4138 has_error = TRUE; 4139 if (info->intr_status_field == SUM_RX_TS_MEM_SINGLE_BIT_ERRf || 4140 info->intr_status_field == SUM_RX_CDC_SINGLE_BIT_ERRf || 4141 info->intr_status_field == SUM_TX_CDC_SINGLE_BIT_ERRf) { 4142 single_bit = 1; 4143 } 4144 if (info->intr_status_field == SUM_RX_TS_MEM_DOUBLE_BIT_ERRf || 4145 info->intr_status_field == SUM_RX_CDC_DOUBLE_BIT_ERRf || 4146 info->intr_status_field == SUM_TX_CDC_DOUBLE_BIT_ERRf) { 4147 double_bit = 1; 4148 } 4149 } 4150 if ((info->intr_clr_reg != INVALIDr) && (INVALIDf != info->intr_clr_field)) { 4151 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, info->intr_clr_reg, log_port, 0, &rval)); 4152 soc_reg_field_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field,0); 4153 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, log_port, 0, rval)); 4154 } 4155 } 4156 if (single_bit) { 4157 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4158 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0); 4159 } 4160 if (double_bit) { 4161 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4162 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 4163 } 4164 } 4165 4166 if (has_error) { 4167 soc_ser_stat_update(unit, 0, blocktype, SOC_PARITY_TYPE_PARITY, 4168 0, SocSerCorrectTypeNoAction, stat); 4169 } 4170 4171 if (!has_error) { 4172 LOG_VERBOSE(BSL_LS_SOC_SER, 4173 (BSL_META_U(unit, 4174 "%s %s hardware inconsistency\n"), 4175 prefix_str, mem_str)); 4176 } 4177 return SOC_E_NONE; 4178 } 4179 4180 int 4181 soc_td3_ser_process(int unit, int block_info_idx, int inst, int pipe, 4182 int port, soc_reg_t group_reg, uint64 group_rval, 4183 const _soc_td3_ser_info_t *info_list, 4184 soc_block_t blocktype, 4185 char *prefix_str) 4186 { 4187 const _soc_td3_ser_info_t *info; 4188 int info_index; 4189 char *mem_str = "INVALIDm"; 4190 /*uint32 minfo;*/ 4191 4192 /* This func (soc_td3_ser_process) is called by 4193 * _soc_trident3_ser_process_all which passes 4194 * _soc_td3_mmu_top_ser_info[] as param to this func. 4195 * And, _soc_td3_mmu_top_ser_info[] list has only one entry with type 4196 * _SOC_TD3_PARITY_TYPE_MMU_SER and 'info' for that entry pointing to 4197 * _soc_td3_mmu_ser_info 4198 */ 4199 for (info_index = 0; ; info_index++) { /* Loop through each info entry in the mmu_top_ser_info list */ 4200 info = &info_list[info_index]; /* LHS points to 1st entry in _soc_td3_mmu_top_ser_info[] */ 4201 if (info->type == _SOC_TD3_PARITY_TYPE_NONE) { 4202 /* End of table */ 4203 break; 4204 } 4205 4206 if ((group_reg != INVALIDr) && (info->group_reg_status_field != INVALIDf)) { 4207 /* Check status for the info entry in the group register */ 4208 /* for SOC_BLK_MMU, group_reg is INVALIDr */ 4209 if (!soc_reg64_field32_get(unit, group_reg, group_rval, 4210 info->group_reg_status_field)) { 4211 continue; 4212 } 4213 } 4214 4215 if (info->mem_str) { 4216 mem_str = info->mem_str; /* "MMU MME PAR" for SOC_BLK_MMU */ 4217 } else if (info->mem != INVALIDm) { 4218 mem_str = SOC_MEM_NAME(unit, info->mem); 4219 } else if (info->group_reg_status_field != INVALIDf) { 4220 mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field); 4221 } 4222 4223 /* Handle different parity error reporting style */ 4224 switch (info->type) { 4225 4226 case _SOC_TD3_PARITY_TYPE_MMU_SER: 4227 /* we can never be here for following 3 types. 4228 * _soc_td3_mmu_top_ser_info has only one entry with type 4229 * _SOC_TD3_PARITY_TYPE_MMU_SER 4230 */ 4231 case _SOC_TD3_PARITY_TYPE_MMU_GLB: 4232 case _SOC_TD3_PARITY_TYPE_MMU_XPE: 4233 case _SOC_TD3_PARITY_TYPE_MMU_SC: 4234 case _SOC_TD3_PARITY_TYPE_MMU_SED: 4235 SOC_IF_ERROR_RETURN 4236 (_soc_trident3_ser_process_mmu_err(unit, block_info_idx, 4237 info, prefix_str, -1)); 4238 /* info points to _soc_td3_mmu_top_ser_info[0] */ 4239 break; 4240 case _SOC_TD3_PARITY_TYPE_ECC: 4241 SOC_IF_ERROR_RETURN 4242 (_soc_trident3_ser_process_ecc(unit, block_info_idx, pipe, 4243 port, info, prefix_str, 4244 mem_str, blocktype, 0)); 4245 break; 4246 case _SOC_TD3_PARITY_TYPE_PARITY: 4247 SOC_IF_ERROR_RETURN 4248 (_soc_trident3_ser_process_parity(unit, block_info_idx, pipe, 4249 port, info, prefix_str, 4250 mem_str, blocktype)); 4251 break; 4252 case _SOC_TD3_PARITY_TYPE_XLMAC: 4253 case _SOC_TD3_PARITY_TYPE_CLMAC: 4254 SOC_IF_ERROR_RETURN 4255 (_soc_trident3_ser_process_mac(unit, block_info_idx, info, 4256 prefix_str, mem_str, blocktype)); 4257 break; 4258 default: 4259 break; 4260 } /* Handle different parity error reporting style */ 4261 } /* Loop through each info entry in the list */ 4262 4263 return SOC_E_NONE; 4264 } 4265 4266 STATIC char *_soc_td3_ser_hwmem_base_info[] = { 4267 /* from SER_STATUS_BUS format in regsfile */ 4268 "OBM_QUEUE_FIFO - In Idb", /* 0x0 */ 4269 "OBM_DATA_FIFO - In Idb", /* 0x1 */ 4270 "CELL_ASSEM_BUFFER - In Idb", /* 0x2 */ 4271 "CPU_CELL_ASSEM_BUFFER - In Idb", /* 0x3 */ 4272 "LPBK_CELL_ASSEM_BUFFER - In Idb", /* 0x4 */ 4273 "MGMT_CELL_ASSEM_BUFFER - In Idb", /* 0x5 */ 4274 "SOP_EVENT_BUFFER - In Idb", /* 0x6 */ 4275 "EOP_EVENT_BUFFER - In Idb", /* 0x7 */ 4276 "INGRESS_PACKET_BUFFER - In Ipars", /* 0x8 */ 4277 "ISW3_EOP_BUFFER_B - In Isw3", /* 0x9 */ 4278 "BUBBLE_MOP - In Isw2", /* 0xa */ 4279 "Invalid value", /* 0xb */ 4280 "Invalid value", /* 0xc */ 4281 "Invalid value", /* 0xd */ 4282 "Invalid value", /* 0xe */ 4283 "Invalid value", /* 0xf */ 4284 "Invalid value", /* 0x10 */ 4285 "IPARS1_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x11 */ 4286 "VXLT1_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x12 */ 4287 "IVP_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x13 */ 4288 "IPARS2_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x14 */ 4289 "VXLT2_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x15 */ 4290 "IFWD1_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x16 */ 4291 "IFWD2_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x17 */ 4292 "IRSEL1_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x18 */ 4293 "ISW1_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x19 */ 4294 "IFP_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x1a */ 4295 "IRSEL2_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x1b */ 4296 "ISW2_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x1c */ 4297 "Invalid value", /* 0x1d */ 4298 "Invalid value", /* 0x1e */ 4299 "Invalid value", /* 0x1f */ 4300 "IPARS1_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x20 */ 4301 "IVXLT1_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x21 */ 4302 "IVP_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x22 */ 4303 "IPARS2_PT_BUF - In IPARS2, Passthru buffer for SOP_UNUSED_PT sigs", /* 0x23 */ 4304 "IVXLT2_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x24 */ 4305 "IFWD1_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x25 */ 4306 "IFWD2_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x26 */ 4307 "IRSEL1_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x27 */ 4308 "IFP_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x28 */ 4309 "IRSEL2_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x29 */ 4310 "ISW2_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x2a */ 4311 "ICFG_ISW3_PT_BUF - PassThrought buffer for ALL_CELLS_ICFG_TO_ISW3_PT_HWY_BUS",/* 0x2b */ 4312 "IRSEL1_FPEM_DELAY_BUFFER - In Irsel1_fp, delay fpem_rst_bus", /* 0x2c */ 4313 "FT_PT_BUF - PassThrought buffer for FT learn module", /* 0x2d */ 4314 "FT_LEARN_FIFO - In IFWD2, for FT learn module0", /* 0x2e */ 4315 "Invalid value", /* 0x2f */ 4316 "LEARN_FIFO - In L2MM", /* 0x30 */ 4317 "Invalid value", /* 0x31 */ 4318 "Invalid value", /* 0x32 */ 4319 "Invalid value", /* 0x33 */ 4320 "Invalid value", /* 0x34 */ 4321 "Invalid value", /* 0x35 */ 4322 "Invalid value", /* 0x36 */ 4323 "Invalid value", /* 0x37 */ 4324 "CENTRAL_EVICTION_FIFO - In CEV", /* 0x38 */ 4325 "IPARS2_PT_BUF1 - In IPARS2, Passthru buffer for SOP_USED_PT sigs", /* 0x39 */ 4326 "IRSEL1_FLEX_CTR_BUS_FIFO - In IRSEL1, passthru buffer for flex counter bus", /* 0x3a */ 4327 "IFWD1_NEW_HWY_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x3b */ 4328 "IFWD2_NEW_HWY_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x3c */ 4329 "IVXLT2_NEW_HWY_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x3d */ 4330 "Invalid value", /* 0x3e */ 4331 "Invalid value", /* 0x3f */ 4332 "EP_MPB_DATA - In El3", /* 0x40 */ 4333 "EP_INITBUF - In Ehcpm", /* 0x41 */ 4334 "CM_DATA_BUFFER - In Edatabuf", /* 0x42 */ 4335 "PM0_DATA_BUFFER - In Edatabuf", /* 0x43 */ 4336 "PM1_DATA_BUFFER - In Edatabuf", /* 0x44 */ 4337 "PM2_DATA_BUFFER - In Edatabuf", /* 0x45 */ 4338 "PM3_DATA_BUFFER - In Edatabuf", /* 0x46 */ 4339 "PM4_DATA_BUFFER - In Edatabuf", /* 0x47 */ 4340 "PM5_DATA_BUFFER - In Edatabuf", /* 0x48 */ 4341 "PM6_DATA_BUFFER - In Edatabuf", /* 0x49 */ 4342 "PM7_DATA_BUFFER - In Edatabuf", /* 0x4a */ 4343 "LBP_DATA_BUFFER - In Edatabuf", /* 0x4b */ 4344 "PM_RESI0_DATA_BUFFER - In Edatabuf", /* 0x4c */ 4345 "PM_RESI1_DATA_BUFFER - In Edatabuf", /* 0x4d */ 4346 "Invalid value", /* 0x4e */ 4347 "Invalid value", /* 0x4f */ 4348 "CM_EDB_CTRL_BUFFER - In Edatabuf", /* 0x50 */ 4349 "PM0_EDB_CTRL_BUFFER - In Edatabuf", /* 0x51 */ 4350 "PM1_EDB_CTRL_BUFFER - In Edatabuf", /* 0x52 */ 4351 "PM2_EDB_CTRL_BUFFER - In Edatabuf", /* 0x53 */ 4352 "PM3_EDB_CTRL_BUFFER - In Edatabuf", /* 0x54 */ 4353 "PM4_EDB_CTRL_BUFFER - In Edatabuf", /* 0x55 */ 4354 "PM5_EDB_CTRL_BUFFER - In Edatabuf", /* 0x56 */ 4355 "PM6_EDB_CTRL_BUFFER - In Edatabuf", /* 0x57 */ 4356 "PM7_EDB_CTRL_BUFFER - In Edatabuf", /* 0x58 */ 4357 "LBP_EDB_CTRL_BUFFER - In Edatabuf", /* 0x59 */ 4358 "EGR_VLAN_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x5a */ 4359 "EGR_PMOD_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x5b */ 4360 "EFP_BUS - PassThrought bus parity check, MEMINDEX is 0", /* 0x5c */ 4361 "Invalid value", /* 0x5d */ 4362 "EGR_VLAN_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x5e */ 4363 "EGR_PMOD_PT_BUF - PassThrought buffer for SOP_UNUSED_PT", /* 0x5f */ 4364 "PM8_DATA_BUFFER - In Edatabuf", /* 0x60 */ 4365 "PM9_DATA_BUFFER - In Edatabuf", /* 0x61 */ 4366 "PM10_DATA_BUFFER - In Edatabuf", /* 0x62 */ 4367 "PM11_DATA_BUFFER - In Edatabuf", /* 0x63 */ 4368 "PM12_DATA_BUFFER - In Edatabuf", /* 0x64 */ 4369 "PM13_DATA_BUFFER - In Edatabuf", /* 0x65 */ 4370 "PM14_DATA_BUFFER - In Edatabuf", /* 0x66 */ 4371 "PM15_DATA_BUFFER - In Edatabuf", /* 0x67 */ 4372 "PM8_EDB_CTRL_BUFFER - In Edatabuf", /* 0x68 */ 4373 "PM9_EDB_CTRL_BUFFER - In Edatabuf", /* 0x69 */ 4374 "PM10_EDB_CTRL_BUFFER - In Edatabuf", /* 0x6a */ 4375 "PM11_EDB_CTRL_BUFFER - In Edatabuf", /* 0x6b */ 4376 "PM12_EDB_CTRL_BUFFER - In Edatabuf", /* 0x6c */ 4377 "PM13_EDB_CTRL_BUFFER - In Edatabuf", /* 0x6d */ 4378 "PM14_EDB_CTRL_BUFFER - In Edatabuf", /* 0x6e */ 4379 "PM15_EDB_CTRL_BUFFER - In Edatabuf", /* 0x6f */ 4380 "PM_RESI2_DATA_BUFFER - In Edatabuf", /* 0x70 */ 4381 "PM_RESI3_DATA_BUFFER - In Edatabuf", /* 0x71 */ 4382 "MGP_DATA_BUFFER - In Edatabuf", /* 0x72 */ 4383 "MGP_EDB_CTRL_BUFFER - In Edatabuf", /* 0x73 */ 4384 "Invalid value", /* 0x74 */ 4385 "EFP_DATA_PT_BUF - In EFP, PassThrough buffer for DATA", /* 0x75 */ 4386 "EGR_VLAN_HWY1_BUF - HWY1 buffer for misc EVLAN buses", /* 0x76 */ 4387 "EGR_VLAN_HWY2_BUF - HWY2 buffer for misc EVLAN buses", /* 0x77 */ 4388 "EGR_EL3_HWY1_BUF - HWY1 buffer for misc EVLAN buses", /* 0x78 */ 4389 "EGR_EL3_HWY2_BUF - HWY2 buffer for misc EVLAN buses", /* 0x79 */ 4390 "IRSEL1_USED_PT_BUF - PassThrought buffer for Irsel1 SOP_USED_FIELDS buses", /* 0x7a */ 4391 "Invalid value", /* 0x7b */ 4392 "Invalid value", /* 0x7c */ 4393 "Invalid value", /* 0x7d */ 4394 "Invalid value", /* 0x7e */ 4395 "Invalid value", /* 0x7f */ 4396 "PM16_DATA_BUFFER - In Edatabuf", /* 0x80 */ 4397 "PM17_DATA_BUFFER - In Edatabuf", /* 0x81 */ 4398 "PM18_DATA_BUFFER - In Edatabuf", /* 0x82 */ 4399 "PM19_DATA_BUFFER - In Edatabuf", /* 0x83 */ 4400 "PM16_EDB_CTRL_BUFFER - In Edatabuf", /* 0x84 */ 4401 "PM17_EDB_CTRL_BUFFER - In Edatabuf", /* 0x85 */ 4402 "PM18_EDB_CTRL_BUFFER - In Edatabuf", /* 0x86 */ 4403 "PM19_EDB_CTRL_BUFFER - In Edatabuf", /* 0x87 */ 4404 "PM_RESI4_DATA_BUFFER - In Edatabuf", /* 0x88 */ 4405 "Invalid value", /* 0x89 */ 4406 "Invalid value", /* 0x8a */ 4407 "Invalid value", 4408 "Invalid value", 4409 "Invalid value", 4410 "Invalid value", 4411 "Invalid value", 4412 "Invalid value", /* 0x90 */ 4413 "Invalid value", 4414 "Invalid value", 4415 "Invalid value", 4416 "Invalid value", 4417 "Invalid value", 4418 "Invalid value", 4419 "Invalid value", 4420 "Invalid value", 4421 "Invalid value", 4422 "Invalid value", 4423 "Invalid value", 4424 "Invalid value", 4425 "Invalid value", 4426 "Invalid value", 4427 "Invalid value", 4428 "BS_KT_CONEXT_BUF - In Broadscan, Key_table context_buffer for key", /* 0xA0 */ 4429 "BS_DT_PKT_HDR_BUF - In Broadscan, Data_table Packet Header Buffer", /* 0xA1 */ 4430 }; 4431 4432 #define _SOC_TD3_SER_REG 1 4433 #define _SOC_TD3_SER_MEM 0 4434 4435 STATIC void 4436 _soc_trident3_print_ser_fifo_details(int unit, uint8 regmem, soc_block_t blk, 4437 uint32 sblk, int pipe, uint32 address, 4438 uint32 stage, uint32 base, uint32 index, 4439 uint32 type, uint8 drop, uint8 non_sbus, 4440 int l2_mgmt_ser_fifo) 4441 { 4442 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityError, unit)) { 4443 switch (type) { 4444 case 0: 4445 LOG_WARN(BSL_LS_SOC_SER, 4446 (BSL_META_U(unit, 4447 "Error in: SOP cell.\n"))); 4448 break; 4449 case 1: 4450 LOG_WARN(BSL_LS_SOC_SER, 4451 (BSL_META_U(unit, 4452 "Error in: MOP cell.\n"))); 4453 break; 4454 case 2: 4455 LOG_WARN(BSL_LS_SOC_SER, 4456 (BSL_META_U(unit, 4457 "Error in: EOP cell.\n"))); 4458 break; 4459 case 3: 4460 LOG_WARN(BSL_LS_SOC_SER, 4461 (BSL_META_U(unit, 4462 "Error in: SBUS transaction.\n"))); 4463 break; 4464 case 4: 4465 LOG_WARN(BSL_LS_SOC_SER, 4466 (BSL_META_U(unit, 4467 "Error in: transaction - refresh, aging etc.\n"))); 4468 break; 4469 default: 4470 LOG_ERROR(BSL_LS_SOC_SER, 4471 (BSL_META_U(unit, 4472 "Invalid error reported !!\n"))); 4473 } 4474 LOG_WARN(BSL_LS_SOC_SER, 4475 (BSL_META_U(unit, 4476 "Blk: %d, Pipe: %d, Address: 0x%08x, base: 0x%x, " 4477 "stage: %d, index: %d\n"), 4478 sblk, pipe, address, base, stage, index)); 4479 if (regmem == _SOC_TD3_SER_MEM) { 4480 if (l2_mgmt_ser_fifo) { 4481 if (non_sbus) { 4482 LOG_WARN(BSL_LS_SOC_SER, 4483 (BSL_META_U(unit, 4484 "unit %0d: L2 LEARN_FIFO parity " 4485 "error\n"), 4486 unit)); 4487 } else { 4488 LOG_WARN(BSL_LS_SOC_SER, 4489 (BSL_META_U(unit, 4490 "unit %0d: L2_MOD_FIFO parity " 4491 "error\n"), 4492 unit)); 4493 } 4494 } else { 4495 if (non_sbus) { 4496 LOG_WARN(BSL_LS_SOC_SER, 4497 (BSL_META_U(unit, 4498 "Mem hwbase: 0x%x [%s]\n"), base, 4499 _soc_td3_ser_hwmem_base_info[base])); 4500 } 4501 } 4502 } 4503 if (drop) { 4504 LOG_WARN(BSL_LS_SOC_SER, 4505 (BSL_META_U(unit, 4506 "SER caused packet drop.\n"))); 4507 } 4508 } 4509 } 4510 4511 STATIC uint32 4512 _soc_td3_check_flex_ctr_addr(int unit, uint32 address, soc_block_t blk, uint32 stage, 4513 uint32 index) 4514 { 4515 uint32 index2 = index; 4516 if ((SOC_BLK_IPIPE == blk) && (21 == stage)) { 4517 switch (address & 0xfffff000) { 4518 /* pool 0 */ 4519 case 0x86800000: 4520 case 0x86801000: 4521 case 0x86802000: 4522 case 0x86803000: 4523 4524 case 0x86804000: 4525 case 0x86808000: 4526 case 0x8680c000: 4527 case 0x86810000: 4528 4529 /* pool 1 */ 4530 case 0x86820000: 4531 case 0x86821000: 4532 case 0x86822000: 4533 case 0x86823000: 4534 4535 case 0x86824000: 4536 case 0x86828000: 4537 case 0x8682c000: 4538 case 0x86830000: 4539 4540 /* pool 2 */ 4541 case 0x86840000: 4542 case 0x86841000: 4543 case 0x86842000: 4544 case 0x86843000: 4545 4546 case 0x86844000: 4547 case 0x86848000: 4548 case 0x8684c000: 4549 case 0x86850000: 4550 4551 /* pool 3 */ 4552 case 0x86880000: 4553 case 0x86881000: 4554 case 0x86882000: 4555 case 0x86883000: 4556 4557 case 0x86884000: 4558 case 0x86888000: 4559 case 0x8688c000: 4560 case 0x86890000: 4561 4562 /* pool 4 */ 4563 case 0x868a0000: 4564 case 0x868a1000: 4565 case 0x868a2000: 4566 case 0x868a3000: 4567 4568 case 0x868a4000: 4569 case 0x868a8000: 4570 case 0x868ac000: 4571 case 0x868b0000: 4572 index2 = address & 0xfff; break; /* 4K depth */ 4573 default: 4574 break; 4575 } 4576 } else if ((SOC_BLK_EPIPE == blk) && (10 == stage)) { 4577 switch (address & 0xfffff000) { 4578 /* pool 0 */ 4579 case 0x2a800000: 4580 case 0x2a801000: 4581 case 0x2a802000: 4582 case 0x2a803000: 4583 4584 case 0x2a804000: 4585 case 0x2a808000: 4586 case 0x2a80c000: 4587 case 0x2a810000: 4588 index2 = address & 0xfff; break; /* 4K depth */ 4589 default: 4590 break; 4591 } 4592 } 4593 if (index2 != index) { 4594 LOG_VERBOSE(BSL_LS_SOC_SER, 4595 (BSL_META_U(unit, 4596 "flex_ctr_addr_detected: index %d was remapped " 4597 "to %d\n"), 4598 index, index2)); 4599 } 4600 return index2; 4601 } 4602 4603 STATIC int 4604 _soc_td3_check_counter_with_ecc(int unit, soc_mem_t mem) 4605 { 4606 int mem_is_ctr_with_ecc = 0; 4607 4608 if (mem == DLB_ECMP_FLOWSETm || 4609 mem == DLB_ECMP_FLOWSET_TIMESTAMP_PAGEm || 4610 mem == DLB_ECMP_PORT_AVG_QUALITY_MEASUREm || 4611 mem == DLB_HGT_LAG_FLOWSETm || 4612 mem == DLB_HGT_LAG_FLOWSET_TIMESTAMP_PAGEm) { 4613 return mem_is_ctr_with_ecc; 4614 } 4615 4616 if ((mem != INVALIDm) && 4617 SOC_MEM_IS_VALID(unit, mem) && 4618 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_ENTRY_CLEAR) && 4619 SOC_MEM_FIELD_VALID(unit, mem, ECCf)) { 4620 mem_is_ctr_with_ecc = 1; 4621 } 4622 if (mem_is_ctr_with_ecc) { 4623 LOG_VERBOSE(BSL_LS_SOC_SER, 4624 (BSL_META_U(unit, 4625 "counter_with_ecc_detected: mem %s \n"), 4626 SOC_MEM_NAME(unit, mem))); 4627 } 4628 return mem_is_ctr_with_ecc; 4629 } 4630 4631 STATIC int 4632 _soc_td3_force_unique_mode(int unit, soc_mem_t mem) 4633 { 4634 int force_unique_mode = 0; 4635 4636 if (!SOC_MEM_IS_VALID(unit, mem)) { 4637 return 0; 4638 } 4639 if (((SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_ENTRY_CLEAR) && 4640 SOC_MEM_FIELD_VALID(unit, mem, ECCf)) || 4641 /* above covers 4642 * ING_FLX_CTR_COUNTER_TABLEs, 4643 * EFP_COUNTER_TABLE, 4644 * EGR_FLEX_CTR_COUNTER_TABLEs 4645 */ 4646 /* SER_ENTRY_CLEAR, but with PARITY */ 4647 (ING_PW_TERM_SEQ_NUMm == mem) || 4648 (EGR_PERQ_XMT_COUNTERSm == mem) || 4649 (EGR_PW_INIT_COUNTERSm == mem) || 4650 /* SER_CACHE_RESTORE */ 4651 /* (EGR_FRAGMENT_ID_TABLEm == mem) || - same values written to all pipes 4652 * using global view - esw/firebolt/l3.c */ 4653 (EGR_XMIT_START_COUNTm == mem) 4654 ) { 4655 force_unique_mode = 1; 4656 } 4657 if (force_unique_mode) { 4658 LOG_VERBOSE(BSL_LS_SOC_SER, 4659 (BSL_META_U(unit, 4660 "Will force unique mode for: mem %s \n"), 4661 SOC_MEM_NAME(unit, mem))); 4662 } 4663 return force_unique_mode; 4664 } 4665 4666 STATIC int 4667 _soc_trident3_tcam_only_remap(int unit, soc_mem_t *mem, int *index) 4668 { 4669 if (!SOC_MEM_IS_VALID(unit, *mem)) { 4670 return SOC_E_PARAM; 4671 } 4672 4673 switch(*mem) { 4674 case L3_TUNNEL_ONLYm: 4675 *mem = L3_TUNNELm; 4676 break; 4677 case ING_SNAT_ONLYm: 4678 *mem = ING_SNATm; 4679 break; 4680 case VLAN_SUBNET_ONLYm: 4681 *mem = VLAN_SUBNETm; 4682 break; 4683 case MY_STATION_TCAM_ENTRY_ONLYm: 4684 *mem = MY_STATION_TCAMm; 4685 break; 4686 case MY_STATION_TCAM_2_ENTRY_ONLYm: 4687 *mem = MY_STATION_TCAM_2m; 4688 break; 4689 case L2_USER_ENTRY_ONLYm: 4690 *mem = L2_USER_ENTRYm; 4691 break; 4692 case SRC_COMPRESSION_TCAM_ONLYm: 4693 *mem = SRC_COMPRESSIONm; 4694 break; 4695 case DST_COMPRESSION_TCAM_ONLYm: 4696 *mem = DST_COMPRESSIONm; 4697 break; 4698 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 4699 *mem = IFP_LOGICAL_TABLE_SELECTm; 4700 break; 4701 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 4702 *mem = EXACT_MATCH_LOGICAL_TABLE_SELECTm; 4703 break; 4704 case CPU_COS_MAP_ONLYm: 4705 *mem = CPU_COS_MAPm; 4706 break; 4707 case L3_DEFIP_ONLYm: 4708 *mem = L3_DEFIPm; 4709 break; 4710 case L3_DEFIP_PAIR_128_ONLYm: 4711 *mem = L3_DEFIP_PAIR_128m; 4712 break; 4713 case PHB_SELECT_TCAM_ONLYm: 4714 *mem = PHB_SELECT_TCAMm; 4715 break; 4716 case FLEX_RTAG7_HASH_TCAM_ONLYm: 4717 *mem = FLEX_RTAG7_HASH_TCAMm; 4718 break; 4719 case PKT_FLOW_SELECT_TCAM_0_ONLYm: 4720 *mem = PKT_FLOW_SELECT_TCAM_0m; 4721 break; 4722 case PKT_FLOW_SELECT_TCAM_1_ONLYm: 4723 *mem = PKT_FLOW_SELECT_TCAM_1m; 4724 break; 4725 case PKT_FLOW_SELECT_TCAM_2_ONLYm: 4726 *mem = PKT_FLOW_SELECT_TCAM_2m; 4727 break; 4728 case IP_PARSER1_MICE_TCAM_ONLY_0m: 4729 *mem = IP_PARSER1_MICE_TCAM_0m; 4730 break; 4731 case IP_PARSER1_MICE_TCAM_ONLY_1m: 4732 *mem = IP_PARSER1_MICE_TCAM_1m; 4733 break; 4734 case IP_PARSER2_MICE_TCAM_ONLY_0m: 4735 *mem = IP_PARSER2_MICE_TCAM_0m; 4736 break; 4737 case IP_PARSER2_MICE_TCAM_ONLY_1m: 4738 *mem = IP_PARSER2_MICE_TCAM_1m; 4739 break; 4740 case EGR_ZONE_0_EDITOR_CONTROL_TCAM_ONLYm: 4741 *mem = EGR_ZONE_0_EDITOR_CONTROL_TCAMm; 4742 break; 4743 case EGR_ZONE_1_EDITOR_CONTROL_TCAM_ONLYm: 4744 *mem = EGR_ZONE_1_EDITOR_CONTROL_TCAMm; 4745 break; 4746 case EGR_ZONE_2_EDITOR_CONTROL_TCAM_ONLYm: 4747 *mem = EGR_ZONE_2_EDITOR_CONTROL_TCAMm; 4748 break; 4749 case EGR_ZONE_3_EDITOR_CONTROL_TCAM_ONLYm: 4750 *mem = EGR_ZONE_3_EDITOR_CONTROL_TCAMm; 4751 break; 4752 case EGR_ZONE_4_EDITOR_CONTROL_TCAM_ONLYm: 4753 *mem = EGR_ZONE_4_EDITOR_CONTROL_TCAMm; 4754 break; 4755 case EGR_PKT_FLOW_SELECT_TCAM_ONLYm: 4756 *mem = EGR_PKT_FLOW_SELECT_TCAMm; 4757 break; 4758 case EGR_FIELD_EXTRACTION_PROFILE_1_TCAM_ONLYm: 4759 *mem = EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm; 4760 break; 4761 case EGR_FIELD_EXTRACTION_PROFILE_2_TCAM_ONLYm: 4762 *mem = EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm; 4763 break; 4764 case EGR_QOS_CTRL_TCAM_ONLYm: 4765 *mem = EGR_QOS_CTRL_TCAMm; 4766 break; 4767 default: 4768 break; 4769 } 4770 if (NUM_PIPE(unit) == 1) { 4771 /* 4772 * Map physical index to logical index 4773 * This is similar to what is done in _soc_ser_recovery_hw_cache for 4774 * multi-pipe devices. Doing this here saves us the trouble of modifying 4775 * SER correction event info 4776 */ 4777 switch(*mem) { 4778 soc_mem_t report_mem; 4779 case L3_DEFIPm: 4780 case L3_DEFIP_DATA_ONLYm: 4781 *index = soc_trident2_l3_defip_mem_index_get(unit, *index, &report_mem); 4782 *mem = report_mem == L3_DEFIP_PAIR_128m ? 4783 L3_DEFIP_PAIR_128_DATA_ONLYm : *mem; 4784 break; 4785 case L3_DEFIP_PAIR_128m: 4786 case L3_DEFIP_PAIR_128_DATA_ONLYm: 4787 *index = soc_trident2_l3_defip_index_remap(unit, *mem, *index); 4788 break; 4789 default: break; 4790 } 4791 } 4792 4793 return SOC_E_NONE; 4794 } 4795 4796 soc_field_info_t ing_ser_fifo_field_info[] = { 4797 { ADDRESSf, 32, 5, SOCF_LE | SOCF_GLOBAL }, 4798 { DATAf, 50, 0, SOCF_LE | SOCF_GLOBAL }, 4799 { DROPf, 1, 37, 0 | SOCF_GLOBAL }, 4800 { ECC_PARITYf, 2, 38, SOCF_LE | SOCF_GLOBAL }, 4801 { HWMEMBASEf, 8, 23, SOCF_LE | SOCF_GLOBAL }, 4802 { INSTRUCTION_TYPEf, 4, 1, SOCF_LE | SOCF_GLOBAL }, 4803 { MEMBASEf, 8, 23, SOCF_LE | SOCF_GLOBAL }, 4804 { MEMINDEXf, 18, 5, SOCF_LE | SOCF_GLOBAL }, 4805 { MEM_TYPEf, 1, 40, 0 | SOCF_GLOBAL }, 4806 { MULTIPLEf, 1, 42, 0 | SOCF_GLOBAL }, 4807 { NON_SBUSf, 1, 41, 0 | SOCF_GLOBAL }, 4808 { PIPE_STAGEf, 6, 31, SOCF_LE | SOCF_GLOBAL }, 4809 { REGBASEf, 17, 13, SOCF_LE | SOCF_GLOBAL }, 4810 { REGINDEXf, 8, 5, SOCF_LE | SOCF_GLOBAL }, 4811 { RESERVED_0f, 6, 44, SOCF_LE|SOCF_RES | SOCF_GLOBAL }, 4812 { VALIDf, 1, 0, 0 | SOCF_GLOBAL }, 4813 { INVALIDf } 4814 }; 4815 4816 #define FIX_MEM_ORDER_E_TEMPLE(v,m) (((m)->flags & SOC_MEM_FLAG_BE) ? \ 4817 BYTES2WORDS((m)->bytes)-1-(v) : \ 4818 (v)) 4819 void 4820 soc_mem_field_get_temple(int unit, soc_mem_t mem, soc_field_t field, const uint32 *entbuf, 4821 uint32 *fldbuf, uint32 fldbuf_size) 4822 { 4823 soc_field_info_t *fieldinfo = NULL; 4824 soc_mem_info_t *meminfo = &SOC_MEM_INFO(unit, mem); 4825 int i, wp, bp, len; 4826 4827 i = 0; 4828 while(ing_ser_fifo_field_info[i].field != INVALIDf) { 4829 if (ing_ser_fifo_field_info[i].field == field) { 4830 fieldinfo = &ing_ser_fifo_field_info[i]; 4831 break; 4832 } 4833 4834 i++; 4835 } 4836 4837 if (fieldinfo == NULL) { 4838 return; 4839 } 4840 4841 bp = fieldinfo->bp; 4842 len = fieldinfo->len; 4843 assert(len / 32 <= fldbuf_size); /* assert we do not write beyond the end of the output buffer */ 4844 4845 if (len == 1) { /* special case single bits */ 4846 wp = bp / 32; 4847 bp = bp & (32 - 1); 4848 if (entbuf[FIX_MEM_ORDER_E_TEMPLE(wp, meminfo)] & (1<<bp)) { 4849 fldbuf[0] = 1; 4850 } else { 4851 fldbuf[0] = 0; 4852 } 4853 return; 4854 } 4855 4856 if (fieldinfo->flags & SOCF_LE) { 4857 wp = bp / 32; 4858 bp = bp & (32 - 1); 4859 i = 0; 4860 4861 for (; len > 0; len -= 32) { 4862 if (bp) { 4863 fldbuf[i] = 4864 entbuf[FIX_MEM_ORDER_E_TEMPLE(wp++, meminfo)] >> bp & 4865 ((1 << (32 - bp)) - 1); 4866 if ( len > (32 - bp) ) { 4867 fldbuf[i] |= entbuf[FIX_MEM_ORDER_E_TEMPLE(wp, meminfo)] << 4868 (32 - bp); 4869 } 4870 } else { 4871 fldbuf[i] = entbuf[FIX_MEM_ORDER_E_TEMPLE(wp++, meminfo)]; 4872 } 4873 4874 if (len < 32) { 4875 fldbuf[i] &= ((1 << len) - 1); 4876 } 4877 4878 i++; 4879 } 4880 } else { 4881 i = (len - 1) / 32; 4882 4883 while (len > 0) { 4884 assert(i >= 0); 4885 4886 fldbuf[i] = 0; 4887 4888 do { 4889 fldbuf[i] = 4890 (fldbuf[i] << 1) | 4891 ((entbuf[FIX_MEM_ORDER_E_TEMPLE(bp / 32, meminfo)] >> 4892 (bp & (32 - 1))) & 1); 4893 len--; 4894 bp++; 4895 } while (len & (32 - 1)); 4896 4897 i--; 4898 } 4899 } 4900 } 4901 4902 STATIC void 4903 _soc_trident3_counter_reg_check(int unit, uint32 blk, int acc_type, uint32 addr, 4904 uint32 *read_again) 4905 { 4906 soc_regaddrinfo_t ainfo; 4907 4908 soc_regaddrinfo_extended_get(unit, &ainfo, blk, acc_type, addr); 4909 if (ainfo.reg == IBCAST_64r || ainfo.reg == IUNKOPC_64r || 4910 ainfo.reg == IIPMC_64r || ainfo.reg == ILTOMC_64r || 4911 ainfo.reg == IMRP4_64r || ainfo.reg == IMRP6_64r || 4912 ainfo.reg == RDBGC0_64r || ainfo.reg == RDBGC1_64r || 4913 ainfo.reg == RDBGC2_64r || ainfo.reg == RDBGC3_64r || 4914 ainfo.reg == RDBGC4_64r || ainfo.reg == RDBGC5_64r || 4915 ainfo.reg == RDBGC6_64r || ainfo.reg == RDBGC7_64r || 4916 ainfo.reg == RDBGC8_64r || ainfo.reg == RDBGC9_64r || 4917 ainfo.reg == RDBGC10_64r || ainfo.reg == RDBGC11_64r || 4918 ainfo.reg == RDBGC12_64r || ainfo.reg == RDBGC13_64r || 4919 ainfo.reg == RDBGC14_64r || ainfo.reg == RDBGC15_64r || 4920 ainfo.reg == RIPC4_64r || ainfo.reg == RIPC6_64r || 4921 ainfo.reg == RIPD4_64r || ainfo.reg == RIPD6_64r || 4922 ainfo.reg == RIPHE4_64r || ainfo.reg == RIPHE6_64r || 4923 ainfo.reg == RPARITYDr || ainfo.reg == RPORTD_64r || 4924 ainfo.reg == RTUNr || ainfo.reg == RUC_64r) { 4925 *read_again = 1; 4926 } 4927 } 4928 4929 int 4930 soc_trident3_process_ser_fifo(int unit, soc_block_t blk, int pipe, 4931 char *prefix_str, int l2_mgmt_ser_fifo) 4932 { 4933 int rv, disable_ser_correction; 4934 int mem_mode = 0; 4935 uint8 bidx; 4936 soc_mem_t mem; 4937 char blk_str[30]; 4938 soc_reg_t reg = INVALIDr; 4939 _soc_ser_correct_info_t spci; 4940 _soc_mem_ser_en_info_t *ser_info_table = NULL; 4941 soc_reg_t parity_enable_reg = INVALIDr; 4942 soc_mem_t parity_enable_mem = INVALIDm; 4943 soc_field_t parity_enable_field = INVALIDf; 4944 int parity_enable_field_position = -1; 4945 uint32 ecc_parity = 0, address = 0, valid = 0, multiple = 0; 4946 uint32 reg_val, mask, entry[SOC_MAX_MEM_WORDS]; 4947 uint32 stage = 0, addrbase = 0, index = 0, type = 0; 4948 uint32 sblk = 0, regmem = 0, non_sbus = 0, drop = 0; 4949 soc_mem_t ipsf[] = { ING_SER_FIFO_PIPE0m, ING_SER_FIFO_PIPE1m }; 4950 soc_mem_t epsf[] = { EGR_SER_FIFO_PIPE0m, EGR_SER_FIFO_PIPE1m }; 4951 soc_reg_t epsr[] = { EGR_INTR_STATUS_PIPE0r, EGR_INTR_STATUS_PIPE1r }; 4952 uint32 stat_flags = 0; 4953 uint32 read_again = 0; 4954 soc_stat_t *stat = SOC_STAT(unit); 4955 4956 LOG_VERBOSE(BSL_LS_SOC_SER, 4957 (BSL_META_U(unit, 4958 "In process fifo.\n"))); 4959 switch (blk) { 4960 case SOC_BLK_IPIPE: 4961 if (l2_mgmt_ser_fifo) { /* L2_MGMT_SER_FIFO is not per pipe */ 4962 mem = L2_MGMT_SER_FIFOm; 4963 reg = L2_MGMT_INTRr; 4964 mask = 0x00000002; /* SER_FIFO_NOT_EMPTY */ 4965 sal_sprintf(blk_str, "IPIPE_L2_MGMT_SER_FIFO"); 4966 } else { 4967 mem = ipsf[pipe]; 4968 mask = soc_td3_ip_pipe_fifo_bmask[unit][pipe]; 4969 sal_sprintf(blk_str, "IPIPE"); 4970 } 4971 ser_info_table = SOC_IP_MEM_SER_INFO(unit); 4972 /* also lists L2_MOD_FIFOm */ 4973 break; 4974 case SOC_BLK_EPIPE: 4975 mem = epsf[pipe]; 4976 mask = 0x00000001; /* SER_FIFO_NON_EMPTYf */ 4977 reg = epsr[pipe]; 4978 sal_sprintf(blk_str, "EPIPE"); 4979 ser_info_table = SOC_EP_MEM_SER_INFO(unit); 4980 break; 4981 default: return SOC_E_PARAM; 4982 } 4983 4984 if (reg != INVALIDr) { 4985 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 4986 0, ®_val)); 4987 if (!(reg_val & mask)) { 4988 /* SER FIFO is empty */ 4989 return SOC_E_NONE; 4990 } 4991 } 4992 4993 do { 4994 if (SOC_HW_ACCESS_DISABLE(unit)) { 4995 break; 4996 } 4997 sal_memset(entry, 0, sizeof(entry)); 4998 SOC_IF_ERROR_RETURN 4999 (soc_mem_pop(unit, mem, MEM_BLOCK_ANY, entry)); 5000 /* process entry */ 5001 soc_mem_field_get_temple(unit, mem, VALIDf, entry, &valid, 1); 5002 if (valid) { 5003 disable_ser_correction = 0; 5004 parity_enable_reg = INVALIDr; 5005 parity_enable_field = INVALIDf; 5006 sal_memset(&spci, 0, sizeof(spci)); 5007 soc_mem_field_get_temple(unit, mem, ECC_PARITYf, entry, &ecc_parity, 1); 5008 soc_mem_field_get_temple(unit, mem, MEM_TYPEf, entry, ®mem, 1); 5009 soc_mem_field_get_temple(unit, mem, ADDRESSf, entry, &address, 1); 5010 soc_mem_field_get_temple(unit, mem, PIPE_STAGEf, entry, &stage, 1); 5011 soc_mem_field_get_temple(unit, mem, INSTRUCTION_TYPEf, entry, &type, 1); 5012 soc_mem_field_get_temple(unit, mem, DROPf, entry, &drop, 1); 5013 SOC_BLOCK_ITER(unit, bidx, blk) { 5014 sblk = SOC_BLOCK2SCH(unit, bidx); 5015 break; 5016 } 5017 LOG_WARN(BSL_LS_SOC_SER, 5018 (BSL_META_U(unit, 5019 "%s\n"), prefix_str)); 5020 soc_mem_field_get_temple(unit, mem, MULTIPLEf, entry, &multiple, 1); 5021 if (multiple) { 5022 LOG_WARN(BSL_LS_SOC_SER, 5023 (BSL_META_U(unit, 5024 "Multiple: "))); 5025 } 5026 if (regmem == _SOC_TD3_SER_REG) { 5027 LOG_WARN(BSL_LS_SOC_SER, 5028 (BSL_META_U(unit, 5029 "Reg: "))); 5030 } else { 5031 LOG_WARN(BSL_LS_SOC_SER, 5032 (BSL_META_U(unit, 5033 "Mem: "))); 5034 } 5035 switch (ecc_parity) { 5036 case 0: 5037 LOG_WARN(BSL_LS_SOC_SER, 5038 (BSL_META_U(unit, 5039 "Parity error..\n"))); 5040 break; 5041 case 1: 5042 LOG_WARN(BSL_LS_SOC_SER, 5043 (BSL_META_U(unit, 5044 "Corrected single bit ECC error..\n"))); 5045 /* NOTE: This is supressed by default, 5046 we can choose not to supress it */ 5047 break; 5048 case 2: 5049 LOG_WARN(BSL_LS_SOC_SER, 5050 (BSL_META_U(unit, 5051 "Double or Multiple bit ECC error..\n"))); 5052 spci.double_bit = 1; 5053 break; 5054 default: 5055 LOG_ERROR(BSL_LS_SOC_SER, 5056 (BSL_META_U(unit, 5057 "Invalid SER issue !!\n"))); 5058 return SOC_E_INTERNAL; 5059 } 5060 if (regmem == _SOC_TD3_SER_MEM) { 5061 /* process mem */ 5062 soc_mem_field_get_temple(unit, mem, NON_SBUSf, entry, &non_sbus, 1); 5063 soc_mem_field_get_temple(unit, mem, MEMBASEf, entry, &addrbase, 1); 5064 soc_mem_field_get_temple(unit, mem, MEMINDEXf, entry, &index, 1); 5065 /* Max index of L2/L3 is more than 256k */ 5066 if ((stage == 26) && (addrbase == 0xdb || addrbase == 0xdf)) { 5067 index |= 1 << 18; 5068 } 5069 if (non_sbus == 0) { 5070 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5071 ecc_parity == 0 ? 5072 SOC_SWITCH_EVENT_DATA_ERROR_PARITY : 5073 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 5074 sblk | (pipe << SOC_SER_ERROR_PIPE_BP) | 5075 SOC_SER_ERROR_DATA_BLK_ADDR_SET, 5076 address); 5077 5078 index = _soc_td3_check_flex_ctr_addr(unit, address, blk, 5079 stage, index); 5080 5081 _soc_trident3_print_ser_fifo_details(unit, 0, blk, sblk, 5082 pipe, address, 5083 stage, addrbase, index, 5084 type, drop, non_sbus, 5085 l2_mgmt_ser_fifo); 5086 spci.flags = SOC_SER_SRC_MEM; 5087 spci.reg = INVALIDr; 5088 spci.mem = INVALIDm; 5089 spci.blk_type = blk; 5090 spci.pipe_num = l2_mgmt_ser_fifo? -1 : pipe; 5091 spci.sblk = sblk; 5092 spci.addr = address - index; 5093 spci.index = index; 5094 spci.stage = stage; 5095 spci.acc_type = -1; /* ignore acc_type for addr2_mem_decode */ 5096 spci.detect_time = sal_time_usecs(); 5097 5098 /* Try to decode mem first */ 5099 if (l2_mgmt_ser_fifo) { 5100 spci.mem = L2_MOD_FIFOm; 5101 } else { 5102 spci.mem = soc_addr_to_mem_extended(unit, spci.sblk, 5103 spci.acc_type, 5104 spci.addr); 5105 rv = _soc_trident3_tcam_only_remap(unit, &spci.mem, &spci.index); 5106 if (rv < 0) { 5107 LOG_ERROR(BSL_LS_SOC_SER, 5108 (BSL_META_U(unit, 5109 "mem %s is invalid !!\n"), 5110 SOC_MEM_NAME(unit, spci.mem))); 5111 } 5112 } 5113 if (spci.mem != INVALIDm) { 5114 spci.flags |= SOC_SER_REG_MEM_KNOWN; 5115 5116 if (!spci.double_bit) { 5117 disable_ser_correction = 5118 _soc_td3_check_counter_with_ecc(unit, spci.mem); 5119 } 5120 5121 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 5122 5123 if (SOC_MEM_INFO(unit, spci.mem).flags & SOC_MEM_FLAG_CAM) { 5124 _soc_td3_ser_tcam_control_reg_get(unit, spci.mem, 5125 &parity_enable_reg, 5126 &parity_enable_field); 5127 } else { 5128 _soc_td3_ser_control_reg_get(unit, ser_info_table, 5129 spci.mem, 5130 &parity_enable_reg, 5131 &parity_enable_mem, 5132 &parity_enable_field, 5133 &parity_enable_field_position); 5134 } 5135 5136 if ((SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) == 5137 SOC_MEM_FLAG_SER_ENTRY_CLEAR) && 5138 (spci.mem != EGR_PW_INIT_COUNTERSm) && 5139 (spci.mem != ING_PW_TERM_SEQ_NUMm)) { 5140 spci.flags |= SOC_SER_ALSO_UPDATE_SW_COUNTER; 5141 spci.counter_base_mem = spci.mem; 5142 switch (spci.mem) { 5143 case ING_FLEX_CTR_COUNTER_TABLE_1m: 5144 spci.inst = 1; 5145 break; 5146 case ING_FLEX_CTR_COUNTER_TABLE_2m: 5147 spci.inst = 2; 5148 break; 5149 case ING_FLEX_CTR_COUNTER_TABLE_3m: 5150 spci.inst = 3; 5151 break; 5152 case ING_FLEX_CTR_COUNTER_TABLE_4m: 5153 spci.inst = 4; 5154 break; 5155 case ING_FLEX_CTR_COUNTER_TABLE_5m: 5156 spci.inst = 5; 5157 break; 5158 case ING_FLEX_CTR_COUNTER_TABLE_6m: 5159 spci.inst = 6; 5160 break; 5161 case ING_FLEX_CTR_COUNTER_TABLE_7m: 5162 spci.inst = 7; 5163 break; 5164 case ING_FLEX_CTR_COUNTER_TABLE_8m: 5165 spci.inst = 8; 5166 break; 5167 case ING_FLEX_CTR_COUNTER_TABLE_9m: 5168 spci.inst = 9; 5169 break; 5170 case ING_FLEX_CTR_COUNTER_TABLE_10m: 5171 spci.inst = 10; 5172 break; 5173 case ING_FLEX_CTR_COUNTER_TABLE_11m: 5174 spci.inst = 11; 5175 break; 5176 case ING_FLEX_CTR_COUNTER_TABLE_12m: 5177 spci.inst = 12; 5178 break; 5179 case ING_FLEX_CTR_COUNTER_TABLE_13m: 5180 spci.inst = 13; 5181 break; 5182 case ING_FLEX_CTR_COUNTER_TABLE_14m: 5183 spci.inst = 14; 5184 break; 5185 case ING_FLEX_CTR_COUNTER_TABLE_15m: 5186 spci.inst = 15; 5187 break; 5188 case ING_FLEX_CTR_COUNTER_TABLE_16m: 5189 spci.inst = 16; 5190 break; 5191 case ING_FLEX_CTR_COUNTER_TABLE_17m: 5192 spci.inst = 17; 5193 break; 5194 case ING_FLEX_CTR_COUNTER_TABLE_18m: 5195 spci.inst = 18; 5196 break; 5197 case ING_FLEX_CTR_COUNTER_TABLE_19m: 5198 spci.inst = 19; 5199 break; 5200 5201 case EGR_FLEX_CTR_COUNTER_TABLE_1m: 5202 spci.inst = 1; 5203 break; 5204 case EGR_FLEX_CTR_COUNTER_TABLE_2m: 5205 spci.inst = 2; 5206 break; 5207 case EGR_FLEX_CTR_COUNTER_TABLE_3m: 5208 spci.inst = 3; 5209 break; 5210 5211 default: 5212 /* ING_FLEX_CTR_COUNTER_TABLE_0m 5213 * EGR_FLEX_CTR_COUNTER_TABLE_0m 5214 * EFP_COUNTER_TABLEm 5215 * EGR_PERQ_XMT_COUNTERSm */ 5216 spci.inst = 0; 5217 break; 5218 } 5219 } 5220 rv = soc_td3_ser_mem_mode_get(unit, spci.mem, 5221 &mem_mode); 5222 if ((rv == SOC_E_NONE) && 5223 (mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) && 5224 (spci.mem != SRC_COMPRESSION_DATA_ONLYm && 5225 spci.mem != DST_COMPRESSION_DATA_ONLYm && 5226 spci.mem != IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm && 5227 spci.mem != EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm)) { 5228 if (SOC_MEM_UNIQUE_ACC(unit, spci.mem) != NULL) { 5229 spci.mem = SOC_MEM_UNIQUE_ACC(unit, 5230 spci.mem)[pipe]; 5231 } 5232 } else if ((rv != SOC_E_NONE) && 5233 (rv != SOC_E_UNAVAIL)) { 5234 LOG_ERROR(BSL_LS_SOC_SER, 5235 (BSL_META_U(unit, 5236 "Could not determine unique-global mode for" 5237 "mem %s - will assume global mode !!\n"), 5238 SOC_MEM_NAME(unit, mem))); 5239 } else if (_soc_td3_force_unique_mode(unit, spci.mem)) { 5240 /* For counters, and other mems which have response 5241 * type ENTRY_CLEAR, we must clear ONLY affected 5242 * instance and not all instances - even if field module says 5243 * it is global mode */ 5244 if (SOC_MEM_UNIQUE_ACC(unit, spci.mem) != NULL) { 5245 spci.mem = SOC_MEM_UNIQUE_ACC(unit, 5246 spci.mem)[pipe]; 5247 } 5248 } 5249 /* In general, for mems that can operate in both local, unique mode, we want 5250 * to check the current mode and if current mode is unique we want to 5251 * do ser_correction for _PIPE0,1 view. Thus, for such mems we need to 5252 * change mem to mem_PIPE0,1 here. 5253 * 5254 * For _DATA_ONLY mems are exception to above rule because for these, 5255 * ser_correction logic will first remap them to aggr_view and then do 5256 * correction. For such mems, by specifying them in above equation, 5257 * we dont change them to _PIPE0,1 in this function. 5258 * These will be remapped to aggr and then aggr_PIPE0,1 view in 5259 * common/ser.c 5260 * 5261 * By not specifying mems in above equation, we change them to _PIPE0,1 5262 * view. Why do we not mention following mems in above equation ? 5263 * L3_TUNNEL_DATA_ONLY - this mem never operateds in UNIQUE mode 5264 * 5265 * FPEM_ECC - mem_mode_get will return GLOBAL for this mem. 5266 * common/ser.c will remap it to EXACT_MATCH_2, 4 and then 5267 * change it to _PIPE0,1 5268 * 5269 * EXACT_MATCH_2, 4 - HW cannot report error for these views (HW will always report error with FPEM_ECC view) 5270 * 5271 * FP_UDF_OFFSET - field module accesses data view separately 5272 * VFP_POLICY_TABLE - field module accesses data view separately 5273 * EFP_POLICY_TABLE - field module accesses data view separately 5274 * IFP_POLICY_TABLE - field module accesses data view separately 5275 * EFP_COUNTER_TABLE - field module accesses data view separately 5276 * EFP_METER_TABLE - field module accesses data view separately 5277 * and so on... 5278 */ 5279 spci.parity_type = _soc_td3_mem_has_ecc(unit, spci.mem)? 5280 SOC_PARITY_TYPE_ECC : 5281 SOC_PARITY_TYPE_PARITY; 5282 } else { 5283 spci.flags |= SOC_SER_REG_MEM_UNKNOWN; 5284 } 5285 #ifdef ALPM_ENABLE 5286 if ((spci.mem == L3_DEFIP_ALPM_ECCm)) { 5287 SOC_ALPM_LPM_LOCK(unit); 5288 } 5289 #endif 5290 if ((spci.mem != INVALIDm) && (spci.mem != L3_DEFIP_ALPM_ECCm)) { 5291 MEM_LOCK(unit,spci.mem); 5292 } 5293 spci.log_id = _soc_td3_populate_ser_log(unit, 5294 parity_enable_reg, 5295 parity_enable_mem, 5296 parity_enable_field, 5297 parity_enable_field_position, 5298 spci.mem, 5299 bidx, 5300 spci.pipe_num, 5301 spci.index, 5302 spci.detect_time, 5303 spci.sblk, 5304 spci.addr, 5305 1, /* disable_parity */ 5306 0, /* disable_mem_read */ 5307 0, /* disable_fill_cache_log */ 5308 1, /* force_cache_log */ 5309 TRUE, 0); 5310 5311 if ((spci.mem != INVALIDm) && (spci.mem != L3_DEFIP_ALPM_ECCm)) { 5312 MEM_UNLOCK(unit,spci.mem); 5313 } 5314 #ifdef ALPM_ENABLE 5315 if (spci.mem == L3_DEFIP_ALPM_ECCm) { 5316 SOC_ALPM_LPM_UNLOCK(unit); 5317 } 5318 #endif 5319 if (!disable_ser_correction && !l2_mgmt_ser_fifo) { 5320 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, 5321 "unit %d will try ser_correction for mem %s, pipe %d\n"), 5322 unit, SOC_MEM_NAME(unit, spci.mem), spci.pipe_num)); 5323 rv = soc_ser_correction(unit, &spci); 5324 } else { 5325 rv = SOC_E_NONE; 5326 } 5327 if (spci.log_id != 0) { 5328 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5329 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 5330 spci.log_id, 0); 5331 if (soc_property_get(unit, "ser_log_print_one", 0)) { 5332 soc_ser_log_print_one(unit, spci.log_id); 5333 } 5334 } 5335 if (SOC_FAILURE(rv)) { 5336 /* Add reporting failed to correct event flag to 5337 * application */ 5338 soc_event_generate(unit, 5339 SOC_SWITCH_EVENT_PARITY_ERROR, 5340 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 5341 sblk | (pipe << SOC_SER_ERROR_PIPE_BP) | 5342 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 5343 if ((spci.mem != INVALIDm) && 5344 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) { 5345 stat_flags = SOC_SER_STAT_TCAM; 5346 } else { 5347 stat_flags = 0; 5348 } 5349 soc_ser_stat_update(unit, stat_flags, blk, 5350 ecc_parity == 0 ? SOC_PARITY_TYPE_PARITY : 5351 SOC_PARITY_TYPE_ECC, 5352 spci.double_bit, 5353 SocSerCorrectTypeFailedToCorrect, 5354 stat); 5355 return rv; 5356 } 5357 } else { 5358 LOG_ERROR(BSL_LS_SOC_SER, 5359 (BSL_META_U(unit, 5360 "%s SER mem address un-accessable !!\n"), 5361 blk_str)); 5362 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5363 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 5364 soc_ser_stat_update(unit, 0, blk, 5365 ecc_parity == 0 ? SOC_PARITY_TYPE_PARITY : 5366 SOC_PARITY_TYPE_ECC, 5367 spci.double_bit, 5368 SocSerCorrectTypeNoAction, 5369 stat); 5370 _soc_trident3_print_ser_fifo_details(unit, 0, blk, sblk, 5371 pipe, address, 5372 stage, addrbase, index, 5373 type, drop, non_sbus, 5374 l2_mgmt_ser_fifo); 5375 _soc_td3_populate_ser_log(unit, INVALIDr, INVALIDm, INVALIDf, 5376 -1, INVALIDm, bidx, 0, index, 5377 sal_time_usecs(), 0, 0, 1, 0, 0, 1, 5378 FALSE, addrbase); 5379 } 5380 } else { 5381 /* process reg */ 5382 soc_mem_field_get_temple(unit, mem, NON_SBUSf, entry, &non_sbus, 1); 5383 soc_mem_field_get_temple(unit, mem, REGBASEf, entry, &addrbase, 1); 5384 soc_mem_field_get_temple(unit, mem, REGINDEXf, entry, &index, 1); 5385 if (l2_mgmt_ser_fifo) { 5386 LOG_WARN(BSL_LS_SOC_SER, 5387 (BSL_META_U(unit, 5388 "%s SER reg address reported in " 5389 "L2_MGMT_SER_FIRO !!\n"), 5390 blk_str)); 5391 _soc_trident3_print_ser_fifo_details(unit, 0, blk, sblk, 5392 pipe, address, 5393 stage, addrbase, index, 5394 type, drop, non_sbus, 5395 1); 5396 } else if (non_sbus == 0) { 5397 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5398 ecc_parity == 0 ? 5399 SOC_SWITCH_EVENT_DATA_ERROR_PARITY : 5400 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 5401 sblk | (pipe << SOC_SER_ERROR_PIPE_BP) | 5402 SOC_SER_ERROR_DATA_BLK_ADDR_SET, 5403 address); 5404 _soc_trident3_print_ser_fifo_details(unit, 1, blk, sblk, 5405 pipe, address, 5406 stage, addrbase, index, 5407 type, drop, non_sbus, 5408 0); 5409 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_UNKNOWN; 5410 spci.reg = INVALIDr; 5411 spci.mem = INVALIDm; 5412 spci.blk_type = blk; 5413 spci.pipe_num = pipe; 5414 spci.sblk = sblk; 5415 spci.addr = address; 5416 spci.index = index; 5417 spci.stage = stage; 5418 spci.acc_type = -1; /* ignore acc_type for addr2_reg_decode */ 5419 spci.detect_time = sal_time_usecs(); 5420 spci.parity_type = SOC_PARITY_TYPE_PARITY; 5421 spci.log_id = soc_ser_log_create_entry(unit, 5422 sizeof(soc_ser_log_tlv_generic_t) + 5423 sizeof(soc_ser_log_tlv_register_t) + 5424 sizeof(soc_ser_log_tlv_hdr_t) *3); 5425 _soc_trident3_counter_reg_check(unit, sblk, -1, address, &read_again); 5426 if (read_again) { 5427 spci.flags |= SOC_SER_REG_READ_AGAIN; 5428 } 5429 rv = soc_ser_correction(unit, &spci); 5430 if (spci.log_id != 0) { 5431 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5432 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 5433 spci.log_id, 0); 5434 if (soc_property_get(unit, "ser_log_print_one", 0)) { 5435 soc_ser_log_print_one(unit, spci.log_id); 5436 } 5437 } 5438 if (SOC_FAILURE(rv)) { 5439 /* Add reporting failed to correct event flag to 5440 * application */ 5441 soc_event_generate(unit, 5442 SOC_SWITCH_EVENT_PARITY_ERROR, 5443 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 5444 sblk | (pipe << SOC_SER_ERROR_PIPE_BP) | 5445 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 5446 soc_ser_stat_update(unit, 0, blk, 5447 ecc_parity == 0 ? SOC_PARITY_TYPE_PARITY : 5448 SOC_PARITY_TYPE_ECC, 5449 spci.double_bit, 5450 SocSerCorrectTypeFailedToCorrect, 5451 stat); 5452 return rv; 5453 } 5454 } else { 5455 LOG_ERROR(BSL_LS_SOC_SER, 5456 (BSL_META_U(unit, 5457 "%s SER reg address un-accessable !!\n"), 5458 blk_str)); 5459 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5460 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 5461 soc_ser_stat_update(unit, 0, blk, 5462 ecc_parity == 0 ? SOC_PARITY_TYPE_PARITY : 5463 SOC_PARITY_TYPE_ECC, 5464 spci.double_bit, 5465 SocSerCorrectTypeNoAction, 5466 stat); 5467 _soc_trident3_print_ser_fifo_details(unit, 0, blk, sblk, 5468 pipe, address, 5469 stage, addrbase, index, 5470 type, drop, non_sbus, 5471 0); 5472 } 5473 } 5474 } else { 5475 LOG_ERROR(BSL_LS_SOC_SER, 5476 (BSL_META_U(unit, 5477 "unit %d Got invalid mem pop from %s !!\n"), 5478 unit, SOC_MEM_NAME(unit, mem))); 5479 } 5480 /* check if any more pending */ 5481 if (reg == INVALIDr) { 5482 /* coverity[result_independent_of_operands] */ 5483 SOC_IF_ERROR_RETURN 5484 (soc_iproc_getreg(unit, soc_reg_addr(unit, 5485 ICFG_CHIP_LP_INTR_RAW_STATUS_REG0r, 5486 REG_PORT_ANY, 0), 5487 ®_val)); 5488 } else { 5489 SOC_IF_ERROR_RETURN 5490 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, ®_val)); 5491 } 5492 } while (reg_val & mask); 5493 return SOC_E_NONE; 5494 } 5495 5496 STATIC int 5497 _soc_trident3_ser_process_all(int unit, int reg_type, int bit) 5498 { 5499 uint8 rbi; 5500 int port = REG_PORT_ANY; 5501 uint32 cmic_bit; 5502 uint64 rb_rval64; 5503 const _soc_td3_ser_route_block_t *rb; 5504 char prefix_str[10]; 5505 int block_info_idx; 5506 soc_reg_t tmp_reg; 5507 int processed_an_intr = 0; 5508 soc_stat_t *stat = SOC_STAT(unit); 5509 COMPILER_64_ZERO(rb_rval64); 5510 5511 sal_sprintf(prefix_str, "\nUnit: %d ", unit); 5512 5513 LOG_VERBOSE(BSL_LS_SOC_SER, 5514 (BSL_META_U(unit, 5515 "unit %d, _soc_trident3_ser_process_all called: reg_type %d, bit %d \n"), 5516 unit, reg_type, bit)); 5517 5518 /* Loop through each place-and-route block entry */ 5519 for (rbi = 0; ; rbi++) { 5520 rb = &_soc_td3_ser_route_blocks[rbi]; 5521 cmic_bit = rb->cmic_bit; 5522 if (cmic_bit == 0) { 5523 /* End of table */ 5524 break; 5525 } 5526 if (!((rb->cmic_reg == reg_type) && (cmic_bit == 1 << bit))) { 5527 continue; 5528 } 5529 if ((rb->blocktype == SOC_BLK_IPIPE || rb->blocktype == SOC_BLK_EPIPE) 5530 && (rb->cmic_bit != _SOC_TD3_IPIPE0_IDB_INTR) 5531 && (rb->cmic_bit != _SOC_TD3_IPIPE1_IDB_INTR) 5532 && (rb->cmic_bit != _SOC_TD3_IPIPE0_ISW4_INTR) 5533 && (rb->cmic_bit != _SOC_TD3_IPIPE1_ISW4_INTR) 5534 && (rb->cmic_bit != _SOC_TD3_CEV_INTR)) { 5535 /* New fifo style processing */ 5536 (void)soc_trident3_process_ser_fifo(unit, rb->blocktype, rb->pipe, 5537 prefix_str, 0); 5538 stat->ser_err_fifo++; 5539 processed_an_intr = 1; 5540 } else { 5541 /* Legacy processing */ 5542 /* for rb->blocktype = SOC_BLK_MMU, we will be here */ 5543 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 5544 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 5545 port = SOC_BLOCK_PORT(unit, block_info_idx); 5546 break; 5547 } 5548 /* ??? Because entry for mmu in _soc_td3_ser_route_blocks array uses 5549 * SOC_BLK_MMU which is illegal for Tomahawk, so block_info_idx 5550 * determined above is incorrect for mmu. Does it matter ? 5551 */ 5552 } 5553 if (rb->enable_reg != INVALIDr) { 5554 /* for SOC_BLK_MMU, enable_reg is INVALIDr */ 5555 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 5556 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 5557 /* This port block is not configured */ 5558 LOG_ERROR(BSL_LS_SOC_SER, 5559 (BSL_META_U(unit, 5560 "unit %d SER error on disabled " 5561 "port block %d !!\n"), 5562 unit, block_info_idx)); 5563 continue; 5564 } 5565 } 5566 /* Read per route block parity status register */ 5567 if (rb->status_reg != INVALIDr) { 5568 /* for SOC_BLK_MMU, status_reg is INVALIDr */ 5569 if ((rb->blocktype == SOC_BLK_IPIPE || 5570 rb->blocktype == SOC_BLK_EPIPE) && 5571 (SOC_REG_UNIQUE_ACC(unit, rb->status_reg) != NULL)) { 5572 tmp_reg = SOC_REG_UNIQUE_ACC(unit, 5573 rb->status_reg)[rb->pipe]; 5574 } else { 5575 tmp_reg = rb->status_reg; 5576 } 5577 SOC_IF_ERROR_RETURN 5578 (soc_reg_get(unit, tmp_reg, port, 0, &rb_rval64)); 5579 5580 /* 5581 * For SOC_BLK_MMU, rb->status_reg is INVALIDr, 5582 * so rb_rval64 will always be 0, so we will skip all of 5583 * following for mmu 5584 * so we will never call soc_td3_ser_process, 5585 * and hence process_mmu_err at all !! 5586 */ 5587 if (COMPILER_64_IS_ZERO(rb_rval64)) { 5588 continue; 5589 } 5590 } 5591 processed_an_intr = 1; 5592 SOC_IF_ERROR_RETURN 5593 (soc_td3_ser_process(unit, block_info_idx, rb->id, 5594 rb->pipe, port, rb->status_reg, 5595 rb_rval64, rb->info, rb->blocktype, 5596 prefix_str)); 5597 5598 stat->ser_err_int++; 5599 } /* legacy processing */ 5600 } 5601 if (!processed_an_intr) { 5602 LOG_WARN(BSL_LS_SOC_SER, 5603 (BSL_META_U(unit, 5604 "unit %d, reg_type %d, bit %d " 5605 "could not process interrupt !!\n"), 5606 unit, reg_type, bit)); 5607 5608 } 5609 return SOC_E_NONE; 5610 } 5611 5612 void 5613 soc_trident3_ser_error(void *unit_vp, void *d1, void *d2, void *d3, 5614 void *d4) 5615 { 5616 int unit = PTR_TO_INT(unit_vp); 5617 5618 (void)_soc_trident3_ser_process_all(unit, PTR_TO_INT(d3), PTR_TO_INT(d4)); 5619 sal_usleep(SAL_BOOT_QUICKTURN ? 1000000 : 10000); 5620 5621 soc_ser_top_intr_reg_enable(unit, PTR_TO_INT(d3), PTR_TO_INT(d4), 1); 5622 soc_cmic_intr_enable(unit, CHIP_INTR_LOW_PRIORITY); 5623 } 5624 5625 static _soc_td3_tcam_wrapper_info_t _soc_td3_tcam_wrapper_table[] = { 5626 { L3_TUNNELm, IVXLT1_SER_CONTROLr, L3_TUNNEL_ONLY_PARITY_ENf, TCAM_PARITY_MASKf}, 5627 { ING_SNATm, RSEL2_CAM_DBGCTRLr, ING_SNAT_ONLY_PARITY_ENf, TCAM_PARITY_MASKf}, 5628 { VLAN_SUBNETm, IVXLT2_SER_CONTROLr, VLAN_SUBNET_ONLY_PARITY_ENf, TCAM_PARITY_MASKf}, 5629 { MY_STATION_TCAMm, IVP_MY_STATION_CAM_CONTROLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5630 { MY_STATION_TCAM_2m, IFWD1_SER_CONTROLr, MY_STATION_TCAM_2_PARITY_ENf, TCAM_PARITY_MASKf}, 5631 { L2_USER_ENTRYm, IFWD2_SER_CONTROLr, L2_USER_ENTRY_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5632 { SRC_COMPRESSIONm, SRC_COMPRESSION_CAM_DBGCTRLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5633 { DST_COMPRESSIONm, DST_COMPRESSION_CAM_DBGCTRLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5634 /*{ UDF_TCAMm, UDF_CAM_SERCTRLr, PARITY_ENf, TCAM_PARITY_MASKf},*/ 5635 { VFP_TCAMm, VFP_CAM_CONTROL_SLICE_3_0r, PARITY_ENf, TCAM_PARITY_MASKf}, 5636 { IFP_LOGICAL_TABLE_SELECTm, IFP_LOGICAL_TABLE_SELECT_CAM_DBGCTRLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5637 { EXACT_MATCH_LOGICAL_TABLE_SELECTm, EXACT_MATCH_LOGICAL_TABLE_SELECT_CAM_DBGCTRLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5638 { IP_MULTICAST_TCAMm, IFWD1_SER_CONTROLr, IP_MULTICAST_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5639 { CPU_COS_MAPm, CPU_COS_CAM_DBGCTRLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5640 { L3_DEFIPm, ILPM_SER_CONTROLr, L3_DEFIP_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5641 { L3_DEFIP_PAIR_128m, ILPM_SER_CONTROLr, L3_DEFIP_TCAM_PARITY_ENf, TCAM_PARITY_MASK_UPRf}, 5642 { IFP_TCAMm, IFP_TCAM_CAM_CONTROLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5643 { IFP_TCAM_WIDEm, IFP_TCAM_CAM_CONTROLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5644 { PHB_SELECT_TCAMm, IRSEL1_SER_CONTROLr, PHB_SELECT_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5645 { FLEX_RTAG7_HASH_TCAMm, IFWD2_SER_CONTROLr, FLEX_RTAG7_HASH_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5646 { PKT_FLOW_SELECT_TCAM_0m, ICFG_SER_CONTROLr, PKT_FLOW_SELECT_TCAM_0_PARITY_ENf, TCAM_PARITY_MASKf}, 5647 { PKT_FLOW_SELECT_TCAM_1m, IPARS1_SER_CONTROLr, PKT_FLOW_SELECT_TCAM_1_PARITY_ENf, TCAM_PARITY_MASKf}, 5648 { PKT_FLOW_SELECT_TCAM_2m, IFWD1_SER_CONTROLr, PKT_FLOW_SELECT_TCAM_2_PARITY_ENf, TCAM_PARITY_MASKf}, 5649 { FORWARDING_1_LOGICAL_TBL_SEL_TCAMm, FORWARDING_1_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5650 { FORWARDING_2_LOGICAL_TBL_SEL_TCAMm, FORWARDING_2_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5651 { FORWARDING_3_LOGICAL_TBL_SEL_TCAMm, FORWARDING_3_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5652 { TUNNEL_ADAPT_1_LOGICAL_TBL_SEL_TCAMm, TUNNEL_ADAPT_1_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5653 { TUNNEL_ADAPT_2_LOGICAL_TBL_SEL_TCAMm, TUNNEL_ADAPT_2_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5654 { TUNNEL_ADAPT_3_LOGICAL_TBL_SEL_TCAMm, TUNNEL_ADAPT_3_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5655 { TUNNEL_ADAPT_4_LOGICAL_TBL_SEL_TCAMm, TUNNEL_ADAPT_4_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5656 { EFP_TCAMm, EFP_TCAM_CONTROLr, EFP_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5657 { EGR_ZONE_0_EDITOR_CONTROL_TCAMm, EGR_VLAN_TCAM_SER_CONTROLr, EGR_ZONE_0_EDITOR_CONTROL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5658 { EGR_ZONE_1_EDITOR_CONTROL_TCAMm, EGR_VLAN_TCAM_SER_CONTROLr, EGR_ZONE_1_EDITOR_CONTROL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5659 { EGR_ZONE_2_EDITOR_CONTROL_TCAMm, EGR_VLAN_TCAM_SER_CONTROLr, EGR_ZONE_2_EDITOR_CONTROL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5660 { EGR_ZONE_3_EDITOR_CONTROL_TCAMm, EGR_VLAN_TCAM_SER_CONTROLr, EGR_ZONE_3_EDITOR_CONTROL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5661 { EGR_ZONE_4_EDITOR_CONTROL_TCAMm, EGR_VLAN_TCAM_SER_CONTROLr, EGR_ZONE_4_EDITOR_CONTROL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5662 { EGR_PKT_FLOW_SELECT_TCAMm, EGR_EL3_TCAM_SER_CONTROLr, EGR_PKT_FLOW_SELECT_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5663 { EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm, EGR_EL3_TCAM_SER_CONTROLr, EGR_FIELD_EXTRACTION_PROFILE_1_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5664 { EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm, EGR_EL3_TCAM_SER_CONTROLr, EGR_FIELD_EXTRACTION_PROFILE_2_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5665 { EGR_QOS_CTRL_TCAMm, EGR_EL3_TCAM_SER_CONTROLr, EGR_QOS_CTRL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5666 { EGR_ADAPT_1_LOGICAL_TBL_SEL_TCAMm, EGR_ADAPT_1_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5667 { EGR_ADAPT_2_LOGICAL_TBL_SEL_TCAMm, EGR_ADAPT_2_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5668 { IP_PARSER0_HME_STAGE_TCAM_ONLY_0m, IP_PARSER0_HME_STAGE_TCAM_SER_CONTROL_0r, SER_ENf, TCAM_PARITY_MASK0f}, 5669 { IP_PARSER1_HME_STAGE_TCAM_ONLY_0m, IP_PARSER1_HME_STAGE_TCAM_SER_CONTROL_0r, SER_ENf, TCAM_PARITY_MASK0f}, 5670 { IP_PARSER1_HME_STAGE_TCAM_ONLY_1m, IP_PARSER1_HME_STAGE_TCAM_SER_CONTROL_1r, SER_ENf, TCAM_PARITY_MASK0f}, 5671 { IP_PARSER1_HME_STAGE_TCAM_NARROW_ONLY_2m, IP_PARSER1_HME_STAGE_TCAM_SER_CONTROL_2r, SER_ENf, TCAM_PARITY_MASKf}, 5672 { IP_PARSER1_HME_STAGE_TCAM_ONLY_3m, IP_PARSER1_HME_STAGE_TCAM_SER_CONTROL_3r, SER_ENf, TCAM_PARITY_MASK0f}, 5673 { IP_PARSER1_HME_STAGE_TCAM_ONLY_4m, IP_PARSER1_HME_STAGE_TCAM_SER_CONTROL_4r, SER_ENf, TCAM_PARITY_MASK0f}, 5674 { IP_PARSER1_MICE_TCAM_0m, IP_PARSER1_MICE_TCAM_SER_CONTROL_0r, SER_ENf, TCAM_PARITY_MASKf}, 5675 { IP_PARSER1_MICE_TCAM_1m, IP_PARSER1_MICE_TCAM_SER_CONTROL_1r, SER_ENf, TCAM_PARITY_MASKf}, 5676 { IP_PARSER2_HME_STAGE_TCAM_ONLY_0m, IP_PARSER2_HME_STAGE_TCAM_SER_CONTROL_0r, SER_ENf, TCAM_PARITY_MASK0f}, 5677 { IP_PARSER2_HME_STAGE_TCAM_ONLY_1m, IP_PARSER2_HME_STAGE_TCAM_SER_CONTROL_1r, SER_ENf, TCAM_PARITY_MASK0f}, 5678 { IP_PARSER2_HME_STAGE_TCAM_NARROW_ONLY_2m, IP_PARSER2_HME_STAGE_TCAM_SER_CONTROL_2r, SER_ENf, TCAM_PARITY_MASKf}, 5679 { IP_PARSER2_HME_STAGE_TCAM_NARROW_ONLY_3m, IP_PARSER2_HME_STAGE_TCAM_SER_CONTROL_3r, SER_ENf, TCAM_PARITY_MASKf}, 5680 { IP_PARSER2_HME_STAGE_TCAM_ONLY_4m, IP_PARSER2_HME_STAGE_TCAM_SER_CONTROL_4r, SER_ENf, TCAM_PARITY_MASK0f}, 5681 { IP_PARSER2_MICE_TCAM_0m, IP_PARSER2_MICE_TCAM_SER_CONTROL_0r, SER_ENf, TCAM_PARITY_MASKf}, 5682 { IP_PARSER2_MICE_TCAM_1m, IP_PARSER2_MICE_TCAM_SER_CONTROL_1r, SER_ENf, TCAM_PARITY_MASKf}, 5683 #ifdef BCM_HELIX5_SUPPORT 5684 { EGR_PKT_FLOW_SELECT_TCAMm, EGR_EPFS_TCAM_SER_CONTROLr, EGR_PKT_FLOW_SELECT_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5685 { EGR_QOS_CTRL_TCAMm, EGR_EPFS_TCAM_SER_CONTROLr, EGR_QOS_CTRL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5686 { BSK_FTFP_TCAMm, BSK_FTFP_CAM_CONTROLr, PARITY_ENf, TCAM_PARITY_MASKf}, 5687 { BSK_FTFP_LTS_LOGICAL_TBL_SEL_TCAMm, BSK_FTFP_LTS_A_KEY_GEN_SER_CONTROLr, LOGICAL_TBL_SEL_TCAM_PARITY_ENf, TCAM_PARITY_MASKf}, 5688 #endif 5689 { INVALIDm}, 5690 }; 5691 5692 int 5693 soc_trident3_mem_ser_control(int unit, soc_mem_t mem, int copyno, 5694 int enable) 5695 { 5696 if (enable) { 5697 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr, 5698 REG_PORT_ANY, TOP_MMU_RST_Lf, 0)); 5699 sal_usleep(1000); 5700 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr, 5701 REG_PORT_ANY, TOP_MMU_RST_Lf, 1)); 5702 sal_usleep(1000); 5703 SOC_IF_ERROR_RETURN(soc_trident3_clear_mmu_memory(unit)); 5704 } 5705 5706 if (enable) { 5707 if (soc_property_get(unit, spn_PARITY_ENABLE, FALSE)) { 5708 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_all(unit, enable)); 5709 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table_all(unit, enable)); 5710 } 5711 } else { 5712 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_all(unit, enable)); 5713 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table_all(unit, enable)); 5714 } 5715 5716 if (enable) { 5717 uint32 rval; 5718 /* Initialize MMU memory */ 5719 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, 0)); 5720 rval = 0; 5721 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, INIT_MEMf, 1); 5722 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 5723 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, 0)); 5724 } 5725 return SOC_E_NONE; 5726 } 5727 5728 void 5729 soc_trident3_ser_register(int unit) 5730 { 5731 soc_cmic_intr_handler_t handle; 5732 5733 #ifdef INCLUDE_MEM_SCAN 5734 WRITE_IP_PARSER1_HME_STAGE_CONFIG_2r(unit, 0); 5735 WRITE_IP_PARSER2_HME_STAGE_CONFIG_2r(unit, 0); 5736 WRITE_IP_PARSER2_HME_STAGE_CONFIG_3r(unit, 0); 5737 soc_mem_scan_ser_list_register(unit, TRUE, _soc_td3_tcam_ser_info[unit]); 5738 #endif 5739 memset(&_td3_ser_functions, 0, sizeof(soc_ser_functions_t)); 5740 _td3_ser_functions._soc_ser_parity_error_cmicx_intr_f = 5741 &soc_trident3_ser_error; 5742 soc_ser_function_register(unit, &_td3_ser_functions); 5743 5744 5745 handle.num = CHIP_INTR_LOW_PRIORITY; 5746 handle.intr_fn = soc_ser_cmicx_intr_handler; 5747 handle.intr_data = NULL; 5748 soc_cmic_intr_register(unit, &handle, 1); 5749 } 5750 5751 int 5752 soc_trident3_mem_sram_info_get(int unit, soc_mem_t mem, int index, 5753 _soc_ser_sram_info_t *sram_info) 5754 { 5755 int i, base, base_index, offset, base_bucket, bkt_offset; 5756 int entries_per_ram = 0, entries_per_bank, contiguous = 0; 5757 5758 switch (mem) { 5759 case L2_ENTRY_ECCm: 5760 sram_info->disable_mem = L2_ENTRY_HASH_CONTROLm; 5761 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 5762 sram_info->disable_mem_index = 0; 5763 if (index < SOC_TD3_NUM_ENTRIES_L2_BANK) { 5764 /* dedicated L2 entries - hash table */ 5765 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5766 entries_per_ram = SOC_TD3_NUM_ENTRIES_L2_DEDICATE_RAM; 5767 entries_per_bank = entries_per_ram * sram_info->ram_count; 5768 base = (index/entries_per_bank)*entries_per_bank; 5769 offset = index % entries_per_ram; 5770 base += offset; 5771 } else { 5772 /* hash_xor mems, stride 8K */ 5773 /* 5774 * sram_info->force_reg = ISS_MEMORY_CONTROL_84r; 5775 * sram_info->force_field = FORCE_XOR_GENERATIONf; 5776 */ 5777 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5778 /* #indexes to be corrected */ 5779 entries_per_ram = SOC_TD3_NUM_ENTRIES_L2_SHARE_RAM; 5780 /* #entries / xor_bank in a shared bank */ 5781 entries_per_bank = entries_per_ram * sram_info->ram_count; 5782 /* #entries / uft bank */ 5783 base_index = index - SOC_TD3_NUM_ENTRIES_L2_BANK; 5784 /* index in uft space */ 5785 base = (base_index/entries_per_bank)*entries_per_bank; 5786 /* base addr of uft bank */ 5787 offset = base_index % entries_per_ram; 5788 /* 1st entry within uft bank */ 5789 base += SOC_TD3_NUM_ENTRIES_L2_BANK + offset; 5790 /* 1st index for correction */ 5791 } 5792 break; 5793 case L3_ENTRY_ECCm: 5794 sram_info->disable_mem = L3_ENTRY_HASH_CONTROLm; 5795 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 5796 sram_info->disable_mem_index = 0; 5797 if (index < SOC_TD3_NUM_ENTRIES_L3_BANK) { 5798 /* dedicated L3 entries - hash table */ 5799 sram_info->ram_count = 1; 5800 entries_per_ram = SOC_TD3_NUM_ENTRIES_L3_BANK; 5801 base = index; 5802 } else { 5803 /* hash_xor mems, stride 8K */ 5804 /* 5805 * sram_info->force_reg = ISS_MEMORY_CONTROL_84r; 5806 * sram_info->force_field = FORCE_XOR_GENERATIONf; 5807 */ 5808 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5809 /* #indexes to be corrected */ 5810 entries_per_ram = SOC_TD3_NUM_ENTRIES_XOR_BANK; 5811 /* #entries / xor_bank in a shared bank */ 5812 entries_per_bank = entries_per_ram * sram_info->ram_count; 5813 /* #entries / uft bank */ 5814 base_index = index - SOC_TD3_NUM_ENTRIES_L3_BANK; 5815 /* index in uft space */ 5816 base = (base_index/entries_per_bank)*entries_per_bank; 5817 /* base addr of uft bank */ 5818 offset = base_index % entries_per_ram; 5819 /* 1st entry within uft bank */ 5820 base += SOC_TD3_NUM_ENTRIES_L3_BANK + offset; 5821 /* 1st index for correction */ 5822 } 5823 break; 5824 case EXACT_MATCH_ECCm: 5825 /* hash_xor mems, stride 8K */ 5826 /* 5827 * sram_info->force_reg = ISS_MEMORY_CONTROL_84r; 5828 * sram_info->force_field = FORCE_XOR_GENERATIONf; 5829 */ 5830 sram_info->disable_mem = EXACT_MATCH_HASH_CONTROLm; 5831 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 5832 sram_info->disable_mem_index = 0; 5833 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5834 /* #indexes to be corrected */ 5835 entries_per_ram = SOC_TD3_NUM_ENTRIES_XOR_BANK; 5836 /* #entries / xor_bank in a shared bank */ 5837 entries_per_bank = entries_per_ram * sram_info->ram_count; 5838 /* #entries / uft bank */ 5839 base_index = index; 5840 /* index - (SOC_TD3_NUM_ENTRIES_FPEM_BANK=0) */ 5841 /* index in uft space */ 5842 base = (base_index/entries_per_bank)*entries_per_bank; 5843 /* base addr of uft bank */ 5844 offset = base_index % entries_per_ram; 5845 /* 1st entry within uft bank */ 5846 base += offset; 5847 /* base += (SOC_TD3_NUM_ENTRIES_FPEM_BANK=0) + offset; */ 5848 /* 1st index for correction */ 5849 break; 5850 case L3_DEFIP_ALPM_ECCm: 5851 if (!soc_trident3_alpm_mode_get(unit)) { 5852 return SOC_E_PARAM; 5853 } 5854 /* 5855 * sram_info->disable_reg = ILPM_SER_CONTROLr; 5856 * sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 5857 * sram_info->force_reg = ISS_MEMORY_CONTROL_84r; 5858 * sram_info->force_field = FORCE_XOR_GENERATIONf; 5859 */ 5860 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5861 5862 #ifdef BCM_MAVERICK2_SUPPORT 5863 if (NUM_PIPE(unit) == 1) { 5864 entries_per_ram = SOC_TD3_NUM_ENTRIES_XOR_BANK; 5865 entries_per_bank = entries_per_ram * sram_info->ram_count; 5866 5867 /* index in uft space */ 5868 base_index = index; 5869 base = (base_index/entries_per_bank)*entries_per_bank; 5870 offset = base_index % entries_per_ram; 5871 base += offset; 5872 5873 for (i = 0; i < sram_info->ram_count; i++) { 5874 base_bucket = base % soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 5875 5876 sram_info->view[i] = L3_DEFIP_ALPM_RAWm; 5877 /* 1:4 Need to fix 1 entry for each ECC entry */ 5878 sram_info->index_count[i] = 1; 5879 sram_info->mem_indexes[i][0] = base_bucket; 5880 5881 base += entries_per_ram; 5882 } 5883 return SOC_E_NONE; 5884 } 5885 #endif 5886 if (soc_trident3_get_alpm_banks(unit) == 8) { 5887 base = index & 0x7; /* 8 uft_bank mode */ 5888 base_bucket = ((index >> 3) & SOC_TD3_ALPM_BKT_MASK(unit)); 5889 LOG_VERBOSE(BSL_LS_SOC_SER, 5890 (BSL_META_U(unit, 5891 "reported bucket: 0x%08x, uft_bank:%d\n"), 5892 base_bucket, base)); 5893 base_bucket = base_bucket % SOC_TD3_ALPM_BKT_OFFFSET; 5894 LOG_VERBOSE(BSL_LS_SOC_SER, 5895 (BSL_META_U(unit, 5896 "base bucket: 0x%08x\n"), 5897 base_bucket)); 5898 for (i = 0; i < SOC_TD3_NUM_EL_SHARED; i++) { 5899 sram_info->view[i] = mem; 5900 sram_info->index_count[i] = 1; 5901 bkt_offset = base_bucket + SOC_TD3_ALPM_BKT_OFFFSET*i; 5902 sram_info->mem_indexes[i][0] = 5903 (index & SOC_TD3_ALPM_MODE0_BKT_MASK) | 5904 (bkt_offset << 3) | base; 5905 } 5906 } else { 5907 base = index & 0x3; /* 4 uft_bank mode */ 5908 base_bucket = ((index >> 2) & SOC_TD3_ALPM_BKT_MASK(unit)); 5909 LOG_VERBOSE(BSL_LS_SOC_SER, 5910 (BSL_META_U(unit, 5911 "reported bucket: 0x%08x, uft_bank:%d\n"), 5912 base_bucket, base)); 5913 base_bucket = base_bucket % SOC_TD3_ALPM_BKT_OFFFSET; 5914 LOG_VERBOSE(BSL_LS_SOC_SER, 5915 (BSL_META_U(unit, 5916 "base bucket: 0x%08x\n"), 5917 base_bucket)); 5918 for (i = 0; i < SOC_TD3_NUM_EL_SHARED; i++) { 5919 sram_info->view[i] = mem; 5920 sram_info->index_count[i] = 1; 5921 bkt_offset = base_bucket + SOC_TD3_ALPM_BKT_OFFFSET*i; 5922 sram_info->mem_indexes[i][0] = 5923 (index & SOC_TD3_ALPM_MODE1_BKT_MASK) | 5924 (bkt_offset << 2) | base; 5925 } 5926 } 5927 return SOC_E_NONE; 5928 case FPEM_LPm: 5929 sram_info->disable_reg = FPEM_CONTROLr; 5930 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 5931 /* sram_info->force_reg = ISS_MEMORY_CONTROL_84r; */ 5932 /* sram_info->force_field = FORCE_XOR_GENERATIONf; */ 5933 5934 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5935 /* #indexes to be corrected */ 5936 entries_per_ram = SOC_TD3_LP_ENTRIES_IN_XOR_BANK;; 5937 /* #lp_entries / lp_xor_bank of uft bank */ 5938 base = index % entries_per_ram; 5939 /* 1st lp_entry within uft bank */ 5940 entries_per_bank = SOC_TD3_NUM_ENTRIES_XOR_BANK * sram_info->ram_count; 5941 /* #phy_entries / uft bank */ 5942 offset = entries_per_bank * (index / SOC_TD3_LP_ENTRIES_IN_UFT_BANK); 5943 /* of 1st_phy_entry in uft space */ 5944 for (i = 0; i < sram_info->ram_count; i++) { 5945 sram_info->mem_indexes[i][0] = offset; 5946 if (i < 2) { 5947 sram_info->view[i] = EXACT_MATCH_2m; 5948 sram_info->mem_indexes[i][0] += 8*(base + i*entries_per_ram); 5949 /* indexes 0 to 4K-1 correspond to em2 type entries */ 5950 /* each index in FPEM_LP corresponds to 4 consecutive em2 5951 * entries */ 5952 } else if (i == 2) { 5953 sram_info->view[i] = EXACT_MATCH_4m; 5954 sram_info->mem_indexes[i][0] += 16*base; 5955 /* indexes 4K to 6K-1 correspond to em4 type entries */ 5956 /* each index in FPEM_LP corresponds to 4 consecutive em4 5957 * entries */ 5958 } else { 5959 sram_info->view[i] = mem; 5960 offset = SOC_TD3_LP_ENTRIES_IN_UFT_BANK * 5961 (index / SOC_TD3_LP_ENTRIES_IN_UFT_BANK); 5962 /* of 1st_lp_entry in uft_space */ 5963 offset += base; 5964 /* of 1st_lp_entry to be corrected */ 5965 sram_info->mem_indexes[i][0] = offset + i*entries_per_ram; 5966 /* of 4th_lp_entry to be corrected */ 5967 } 5968 } 5969 return SOC_E_NONE; 5970 case VLAN_XLATE_LPm: 5971 case EGR_VLAN_XLATE_LPm: 5972 sram_info->view[0] = mem; 5973 sram_info->index_count[0] = 1; 5974 sram_info->ram_count = 1; 5975 entries_per_ram = 0; /* x */ 5976 base = index; /* index of 1st lp_entry */ 5977 break; 5978 case L2_ENTRY_ISS_LPm: 5979 case L3_ENTRY_ISS_LPm: 5980 /* hash_xor mems, stride 2K */ 5981 for (i=0; i < SOC_TD3_NUM_EL_SHARED; i++) { 5982 sram_info->view[i] = mem; 5983 sram_info->index_count[i] = 1; 5984 } 5985 sram_info->ram_count = SOC_TD3_NUM_EL_SHARED; 5986 /* #indexes to be corrected */ 5987 entries_per_ram = SOC_TD3_LP_ENTRIES_IN_XOR_BANK; 5988 entries_per_bank = SOC_TD3_LP_ENTRIES_IN_UFT_BANK; 5989 base_index = index; /* index of lp_entry */ 5990 base = (base_index/entries_per_bank)*entries_per_bank; 5991 /* lp_entry0 in uft bank */ 5992 offset = base_index % entries_per_ram; 5993 /* lp_entry in 1st xor_bank */ 5994 base += offset; /* index of 1st lp_entry */ 5995 break; 5996 case VLAN_XLATE_1_ECCm: 5997 contiguous = 1; 5998 /* 5999 * sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r; 6000 * sram_info->force_field = FORCE_XOR_GENf; 6001 */ 6002 sram_info->disable_mem = VLAN_XLATE_1_HASH_CONTROLm; 6003 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 6004 sram_info->disable_mem_index = 0; 6005 sram_info->ram_count = SOC_TD3_NUM_EL_VLAN_XLATE; 6006 base = (index/4) * 4; 6007 break; 6008 case VLAN_XLATE_2_ECCm: 6009 contiguous = 1; 6010 /* 6011 * sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r; 6012 * sram_info->force_field = FORCE_XOR_GENf; 6013 */ 6014 sram_info->disable_mem = VLAN_XLATE_2_HASH_CONTROLm; 6015 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 6016 sram_info->disable_mem_index = 0; 6017 sram_info->ram_count = SOC_TD3_NUM_EL_VLAN_XLATE; 6018 base = (index/4) * 4; 6019 break; 6020 case EGR_VLAN_XLATE_1_ECCm: 6021 contiguous = 1; 6022 /* 6023 * sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr; 6024 * sram_info->force_field = FORCE_XOR_GENf; 6025 */ 6026 sram_info->disable_mem = EGR_VLAN_XLATE_1_HASH_CONTROLm; 6027 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 6028 sram_info->disable_mem_index = 0; 6029 sram_info->ram_count = SOC_TD3_NUM_EL_EGR_VLAN_XLATE; 6030 base = (index/4) * 4; 6031 break; 6032 case EGR_VLAN_XLATE_2_ECCm: 6033 contiguous = 1; 6034 /* 6035 * sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr; 6036 * sram_info->force_field = FORCE_XOR_GENf; 6037 */ 6038 sram_info->disable_mem = EGR_VLAN_XLATE_2_HASH_CONTROLm; 6039 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 6040 sram_info->disable_mem_index = 0; 6041 sram_info->ram_count = SOC_TD3_NUM_EL_EGR_VLAN_XLATE; 6042 base = (index/4) * 4; 6043 break; 6044 case MPLS_ENTRY_ECCm: 6045 contiguous = 1; 6046 sram_info->disable_mem = MPLS_ENTRY_HASH_CONTROLm; 6047 sram_info->disable_mem_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 6048 sram_info->disable_mem_index = 0; 6049 sram_info->ram_count = SOC_TD3_NUM_EL_MPLS_ENTRY; 6050 base = (index/4) * 4; 6051 break; 6052 case L2_ENTRY_LPm: 6053 case L3_ENTRY_LPm: 6054 case EXACT_MATCH_LPm: 6055 case VLAN_XLATE_1_LPm: 6056 case VLAN_XLATE_2_LPm: 6057 case EGR_VLAN_XLATE_1_LPm: 6058 case EGR_VLAN_XLATE_2_LPm: 6059 case MPLS_ENTRY_LPm: 6060 if (NUM_PIPE(unit) == 1) { 6061 /* Special handling needed for LP mems 6062 * No HW cache for single pipe devices 6063 */ 6064 return SOC_E_UNAVAIL; 6065 } 6066 sram_info->view[0] = mem; 6067 sram_info->index_count[0] = 1; 6068 sram_info->ram_count = 1; 6069 entries_per_ram = 0; /* x */ 6070 base = index; /* index of 1st lp_entry */ 6071 break; 6072 case ING_DNAT_ADDRESS_TYPE_ECCm: 6073 case ING_VP_VLAN_MEMBERSHIP_ECCm: 6074 case EGR_VP_VLAN_MEMBERSHIP_ECCm: 6075 case SUBPORT_ID_TO_SGPP_MAP_ECCm: 6076 if (NUM_PIPE(unit) == 1) { 6077 contiguous = 1; 6078 sram_info->view[0] = mem; 6079 sram_info->index_count[0] = 1; 6080 sram_info->ram_count = 1; 6081 base = index; 6082 } else { 6083 return SOC_E_UNAVAIL; 6084 } 6085 break; 6086 default: return SOC_E_PARAM; 6087 } 6088 sram_info->mem_indexes[0][0] = base; 6089 if (contiguous) { 6090 for (i=1; i < sram_info->ram_count; i++) { 6091 sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 1; 6092 } 6093 } else { 6094 for (i=1; i < sram_info->ram_count; i++) { 6095 sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 6096 entries_per_ram; 6097 } 6098 } 6099 return SOC_E_NONE; 6100 } 6101 6102 void 6103 soc_trident3_vlan_xlate_mem_remap(soc_mem_t *mem, int *index) 6104 { 6105 switch(*mem) { 6106 case VLAN_XLATE_1_SINGLEm: 6107 *mem = VLAN_XLATE_1_ECCm; 6108 break; 6109 case VLAN_XLATE_1_DOUBLEm: 6110 *mem = VLAN_XLATE_1_ECCm; 6111 *index *= 2; 6112 break; 6113 case EGR_VLAN_XLATE_1_SINGLEm: 6114 *mem = EGR_VLAN_XLATE_1_ECCm; 6115 break; 6116 case EGR_VLAN_XLATE_1_DOUBLEm: 6117 *mem = EGR_VLAN_XLATE_1_ECCm; 6118 *index *= 2; 6119 break; 6120 case VLAN_XLATE_2_SINGLEm: 6121 *mem = VLAN_XLATE_2_ECCm; 6122 break; 6123 case VLAN_XLATE_2_DOUBLEm: 6124 *mem = VLAN_XLATE_2_ECCm; 6125 *index *= 2; 6126 break; 6127 case EGR_VLAN_XLATE_2_SINGLEm: 6128 *mem = EGR_VLAN_XLATE_2_ECCm; 6129 break; 6130 case EGR_VLAN_XLATE_2_DOUBLEm: 6131 *mem = EGR_VLAN_XLATE_2_ECCm; 6132 *index *= 2; 6133 break; 6134 default: 6135 break; 6136 } 6137 } 6138 6139 int 6140 soc_trident3_l3_memwr_parity_check(int unit, soc_mem_t mem, int disable) 6141 { 6142 int rv = SOC_E_NONE; 6143 soc_field_t disable_field = DISABLE_SBUS_MEMWR_ECC_CHECKf; 6144 soc_mem_t disable_mem = INVALIDm; 6145 l3_entry_hash_control_entry_t hash_control_entry; 6146 6147 switch(mem) { 6148 case L3_ENTRY_ONLY_SINGLEm: 6149 case L3_ENTRY_ONLY_DOUBLEm: 6150 case L3_ENTRY_ONLY_QUADm: 6151 case L3_ENTRY_SINGLEm: 6152 case L3_ENTRY_DOUBLEm: 6153 case L3_ENTRY_QUADm: 6154 disable_mem = L3_ENTRY_HASH_CONTROLm; 6155 break; 6156 default: 6157 return SOC_E_NONE; 6158 } 6159 6160 sal_memset(&hash_control_entry, 0, sizeof(hash_control_entry)); 6161 rv = soc_mem_read(unit, disable_mem, MEM_BLOCK_ANY, 0, (void *)&hash_control_entry); 6162 soc_mem_field32_set(unit, disable_mem , (void *)&hash_control_entry, disable_field, 6163 disable ? 1 : 0); 6164 rv = soc_mem_write(unit, disable_mem, MEM_BLOCK_ALL, 0, (void *)&hash_control_entry); 6165 6166 return rv; 6167 } 6168 6169 int 6170 soc_trident3_ifp_slice_mode_hw_get(int unit, int pipe, int slice_num, int *slice_type, 6171 int *slice_enabled) 6172 { 6173 soc_reg_t ifp_cfg_r; 6174 uint32 ifp_cfg_rval = 0; 6175 static soc_reg_t ifp_cfg_r_list[] = { 6176 IFP_CONFIG_PIPE0r, 6177 IFP_CONFIG_PIPE1r}; 6178 int rv = 0; 6179 6180 rv = soc_th_ifp_slice_mode_get(unit, pipe, slice_num, 6181 slice_type, slice_enabled); 6182 if (rv != SOC_E_INIT) { 6183 return rv; 6184 } 6185 6186 /* coverity[Logically dead code:FALSE]*/ 6187 if ((slice_type == NULL) || (slice_enabled == NULL) || 6188 (pipe >= NUM_PIPE(unit))) { 6189 return SOC_E_PARAM; 6190 } 6191 6192 if (pipe < 0) { /* global mode */ 6193 ifp_cfg_r = IFP_CONFIGr; 6194 } else { 6195 ifp_cfg_r = ifp_cfg_r_list[pipe]; 6196 } 6197 SOC_IF_ERROR_RETURN( 6198 soc_reg32_get(unit, ifp_cfg_r, REG_PORT_ANY, slice_num, &ifp_cfg_rval)); 6199 6200 if (soc_feature(unit, soc_feature_ifp_no_narrow_mode_support)) { 6201 *slice_type = _SOC_TD3_IFP_SLICE_MODE_WIDE; 6202 } else { 6203 *slice_type = soc_reg_field_get(unit, ifp_cfg_r, ifp_cfg_rval, 6204 IFP_SLICE_MODEf); 6205 } 6206 *slice_enabled = soc_reg_field_get(unit, ifp_cfg_r, ifp_cfg_rval, 6207 IFP_SLICE_LOOKUP_ENABLEf); 6208 return SOC_E_NONE; 6209 } 6210 6211 /* Returns FALSE if mem is not one of the dual_mode mems tracked by SER engine 6212 * Else returns TRUE, base_mem, pipe 6213 * Note: pipe will be -1 when mem == base_mem 6214 * pipe will be >=0 when mem != base_mem 6215 */ 6216 int soc_td3_mem_is_dual_mode(int unit, soc_mem_t mem, soc_mem_t *base_mem, int *pipe) 6217 { 6218 int i, p; 6219 int rv_dual_mode = FALSE; 6220 static const soc_mem_t mem_list[] = { 6221 SRC_COMPRESSIONm, 6222 DST_COMPRESSIONm, 6223 FP_UDF_TCAMm, 6224 VFP_TCAMm, 6225 IFP_LOGICAL_TABLE_SELECTm, 6226 EXACT_MATCH_LOGICAL_TABLE_SELECTm, 6227 EFP_TCAMm, 6228 IFP_TCAMm, 6229 IFP_TCAM_WIDEm, 6230 INVALIDm}; 6231 if (!SOC_MEM_IS_VALID(unit, mem)) { 6232 return FALSE; 6233 } 6234 for (i = 0; mem_list[i] != INVALIDm; i++) { 6235 /* test for base_view */ 6236 p = -1; 6237 if (mem == mem_list[i]) { 6238 rv_dual_mode = TRUE; 6239 break; 6240 } 6241 /* test for base_PIPE0,1 views */ 6242 if (SOC_MEM_UNIQUE_ACC(unit, mem_list[i]) != NULL) { 6243 for (p = 0; p < NUM_PIPE(unit); p++) { 6244 if (mem == SOC_MEM_UNIQUE_ACC(unit, mem_list[i])[p]) { 6245 rv_dual_mode = TRUE; 6246 break; /* from p loop */ 6247 } 6248 } 6249 if (rv_dual_mode) { 6250 break; /* from i loop */ 6251 } 6252 } 6253 } 6254 if (FALSE != rv_dual_mode) { 6255 if (NULL != pipe) { 6256 *pipe = p; 6257 } 6258 if (NULL != base_mem) { 6259 *base_mem = mem_list[i]; 6260 } 6261 } 6262 return rv_dual_mode; 6263 } 6264 6265 int 6266 soc_td3_mem_index_invalid(int unit, soc_mem_t mem, int index, uint8 dual_mode, 6267 soc_mem_t in_base_mem, int in_pipe) 6268 { 6269 int slice_num, slice_type, rv; 6270 int cfg_slice_enabled = 0; 6271 int cfg_slice_type = 0; 6272 int mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 6273 soc_mem_t base_mem = INVALIDm; 6274 int pipe = -1, mode_ok = 0; 6275 int8 dual_mode_mem; 6276 6277 if (0xFF == dual_mode) { 6278 dual_mode_mem = soc_td3_mem_is_dual_mode(unit, mem, &base_mem, &pipe); 6279 } else { 6280 base_mem = in_base_mem; 6281 pipe = in_pipe; 6282 dual_mode_mem = dual_mode; 6283 } 6284 6285 if (dual_mode_mem) { 6286 if (!SOC_FAILURE(soc_td3_check_hw_global_mode(unit, base_mem, 6287 &mem_mode))) { 6288 mode_ok = ((_SOC_SER_MEM_MODE_GLOBAL == mem_mode) && (pipe < 0)) || 6289 ((_SOC_SER_MEM_MODE_GLOBAL != mem_mode) && (pipe >= 0)); 6290 if (!mode_ok) { 6291 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, 6292 "Denied access to mem %s, pipe %d, index %d in %s mode !!\n"), 6293 SOC_MEM_NAME(unit, mem), pipe, index, mem_mode? "UNIQUE" : "GLOBAL")); 6294 return TRUE; /* skip: dual mode, but !mode_ok */ 6295 } 6296 6297 if (base_mem != IFP_TCAMm && base_mem != IFP_TCAM_WIDEm) { 6298 return FALSE; /* allow: dual_mode && mode_ok */ 6299 } 6300 6301 /* IFP_TCAMm or IFP_TCAM_WIDEm */ 6302 if (base_mem == IFP_TCAMm) { 6303 slice_num = index/512; slice_type = 0; 6304 } else { 6305 slice_num = index/256; slice_type = 1; 6306 } 6307 if ((slice_num < 0) || (slice_num >= 12)) { 6308 return TRUE; /* invalid - skip mem_acc */ 6309 } 6310 6311 rv = soc_trident3_ifp_slice_mode_hw_get(unit, pipe, slice_num, 6312 &cfg_slice_type, &cfg_slice_enabled); 6313 if (SOC_FAILURE(rv)) { 6314 /* only case where this can happen: 6315 * When slice is in global mode and we pass 'pipe != -1' or 6316 * invalid input parameters. 6317 * For example, if we are trying to access location 5 in IFP_TCAM_WIDE_PIPE2, 6318 * but if slice_0 is part of IFP_TCAM then field module will return 6319 * SOC_E_CONFIG - to indicate that slice must be skipped. 6320 */ 6321 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, 6322 "unit %d, slice_mode_get failed: mem %s, " 6323 "pipe: %d, index %d, slice_num %d !!\n"), 6324 unit, SOC_MEM_NAME(unit, mem), pipe, index, slice_num)); 6325 return TRUE; /* invalid - skip mem_acc */ 6326 } else if (slice_type != cfg_slice_type) { 6327 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, 6328 "Denied access to mem %s, pipe %d, index %d slice %d in %s slice_mode !!\n"), 6329 SOC_MEM_NAME(unit, mem), pipe, index, slice_num, cfg_slice_type? "WIDE" : "NARROW")); 6330 return TRUE; /* invalid - skip mem_acc */ 6331 } else { 6332 return FALSE; /* proceed with mem_acc */ 6333 } 6334 } else { 6335 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit, 6336 "Denied access to mem %s, pipe %d, index %d in %s mode !!\n"), 6337 SOC_MEM_NAME(unit, mem), pipe, index, "UNKNOWN_MODE")); 6338 return TRUE; /* skip: dual mode, but could not find mode */ 6339 } 6340 } 6341 return FALSE; /* allow: !dual_mode */ 6342 } 6343 6344 /* For use during WB. 6345 * Looks at SER_RANGE_ENABLEr and determines if mem is in global mode / unique 6346 * mode. 6347 * Works ONLY for mems listed in mem_list[] below. 6348 * Cannot use: soc_td3_field_mem_mode_get during WB 6349 * Note: Bit positions are HARD-CODED to match with order of entries in 6350 _soc_generic_ser_info_t _soc_td3_tcam_ser_info_template[] 6351 MUST change these values if we change above array !! 6352 */ 6353 int 6354 soc_td3_check_hw_global_mode(int unit, soc_mem_t mem, int *mem_mode) 6355 { 6356 int i = 0; 6357 uint32 range_enable; 6358 static const struct { 6359 soc_mem_t mem; 6360 int bit_position; 6361 } mem_list[] = { 6362 {SRC_COMPRESSIONm, 10}, 6363 {DST_COMPRESSIONm, 12}, 6364 {FP_UDF_TCAMm, 14}, 6365 {VFP_TCAMm, 16}, 6366 {IFP_LOGICAL_TABLE_SELECTm, 18}, 6367 {EXACT_MATCH_LOGICAL_TABLE_SELECTm, 20}, 6368 {EFP_TCAMm, 22}, 6369 {IFP_TCAMm, 24}, 6370 {IFP_TCAM_WIDEm, 26}, 6371 {INVALIDm, 0 } 6372 }; 6373 if (!SOC_MEM_IS_VALID(unit,mem)) { 6374 return SOC_E_PARAM; 6375 } 6376 if (NULL == mem_mode) { 6377 return SOC_E_PARAM; 6378 } 6379 *mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 6380 for (i = 0; mem_list[i].mem != INVALIDm; i++) { 6381 if (mem_list[i].mem == mem) { 6382 SOC_IF_ERROR_RETURN( 6383 READ_SER_RANGE_ENABLEr(unit, &range_enable)); 6384 if ((range_enable >> mem_list[i].bit_position) & 0x1) { 6385 *mem_mode = _SOC_SER_MEM_MODE_PIPE_UNIQUE; 6386 } 6387 return SOC_E_NONE; 6388 } 6389 } 6390 return SOC_E_NONE; 6391 } 6392 6393 int 6394 soc_td3_ser_mem_mode_get(int unit, soc_mem_t mem, int *mem_mode) 6395 { 6396 int rv = SOC_E_NONE; 6397 6398 /* first query field module */ 6399 /* trident3/field.c didn't implement. Waiting*/ 6400 rv = soc_th_field_mem_mode_get(unit, mem, mem_mode); 6401 6402 if (rv == SOC_E_INIT) { 6403 rv = soc_trident3_tcam_mode_get(unit, mem, mem_mode); 6404 if (rv == SOC_E_NOT_FOUND) { 6405 *mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 6406 } 6407 rv = SOC_E_NONE; 6408 } 6409 6410 return rv; 6411 } 6412 6413 int 6414 soc_td3_ifp_slice_mode_check(int unit, soc_mem_t mem, int slice, int *slice_skip) 6415 { 6416 #define _SOC_TD3_IFP_SLICE_MODE_NARROW 0 6417 #define _SOC_TD3_IFP_SLICE_MODE_WIDE 1 6418 soc_reg_t reg; 6419 uint32 rval; 6420 int exp_slice_width_narrow, slice_width_narrow, slice_enabled; 6421 6422 if (NULL == slice_skip) { 6423 return SOC_E_PARAM; 6424 } 6425 *slice_skip = 0; 6426 switch (mem) { 6427 case IFP_TCAMm: 6428 exp_slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_NARROW; 6429 reg = IFP_CONFIGr; 6430 break; 6431 case IFP_TCAM_PIPE0m: 6432 exp_slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_NARROW; 6433 reg = IFP_CONFIG_PIPE0r; 6434 break; 6435 case IFP_TCAM_PIPE1m: 6436 exp_slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_NARROW; 6437 reg = IFP_CONFIG_PIPE1r; 6438 break; 6439 case IFP_TCAM_WIDEm: 6440 exp_slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_WIDE; 6441 reg = IFP_CONFIGr; 6442 break; 6443 case IFP_TCAM_WIDE_PIPE0m: 6444 exp_slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_WIDE; 6445 reg = IFP_CONFIG_PIPE0r; 6446 break; 6447 case IFP_TCAM_WIDE_PIPE1m: 6448 exp_slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_WIDE; 6449 reg = IFP_CONFIG_PIPE1r; 6450 break; 6451 default: 6452 return SOC_E_PARAM; 6453 } 6454 SOC_IF_ERROR_RETURN( 6455 soc_reg32_get(unit, reg, REG_PORT_ANY, slice, &rval)); 6456 if (soc_feature(unit, soc_feature_ifp_no_narrow_mode_support)) { 6457 slice_width_narrow = _SOC_TD3_IFP_SLICE_MODE_WIDE; 6458 } else { 6459 slice_width_narrow = soc_reg_field_get(unit, reg, rval, IFP_SLICE_MODEf); 6460 } 6461 6462 slice_enabled = soc_reg_field_get(unit, reg, rval, IFP_SLICE_ENABLEf); 6463 if (!slice_enabled || (exp_slice_width_narrow != slice_width_narrow)) { 6464 *slice_skip = 1; 6465 } 6466 LOG_VERBOSE(BSL_LS_SOC_SER, 6467 (BSL_META_U(unit, "soc_td3_ifp_slice_mode_check: For mem %s, read reg %s, slice_enabled = %0d, slice_width = %0d, slice_skip = %0d\n"), 6468 SOC_MEM_NAME(unit, mem), SOC_REG_NAME(unit, reg), slice_enabled, 6469 slice_width_narrow, *slice_skip)); 6470 return SOC_E_NONE; 6471 } 6472 6473 /* 6474 * 0. Must not read IFP_TCAM_WIDEm for slices that are in 80b mode. 6475 * Must not read IFP_TCAMm for slices in 160b mode. 6476 * Must breakdown dma read into read of slices 6477 * 6478 * 1. Issues dma_read for each slice of mem and collects data into *table. 6479 * 6480 * 2. used for reloading sw_cache from hw_tables during WB. 6481 * This requires reading of IFP_CONFIGr to determine slice_mode. Thus 6482 * we cannot use soc_td3_ifp_slice_mode_get() which will be eventually 6483 * replaced by field' module. 6484 * 6485 * 3. used for scrubbing IFP_TCAM, IFP_TCAM_WIDE views before CPU goes offline 6486 * We still cannot use standard soc_td3_ifp_slice_mode_get() as defined earlier, 6487 * because exit_clean in appl/diag/shell.c first invokes _bcm_shutdown 6488 * (which de-inits field module) and then soc_shutdown (which calls this 6489 * function) 6490 */ 6491 int 6492 soc_td3_ifp_tcam_dma_read(int unit, soc_mem_t mem, int blk, uint32 *table, 6493 int en_per_pipe_read) 6494 { 6495 int slice, slice_skip = 0, slice_size; 6496 int slice_start_addr, slice_end_addr, entry_dw; 6497 int rv = SOC_E_NONE; 6498 6499 if (!SOC_MEM_IS_VALID(unit,mem)) { 6500 return SOC_E_PARAM; 6501 } 6502 if (NULL == table) { 6503 return SOC_E_PARAM; 6504 } 6505 6506 switch (mem) { 6507 case IFP_TCAMm: 6508 case IFP_TCAM_PIPE0m: 6509 case IFP_TCAM_PIPE1m: 6510 slice_size = 512; 6511 break; 6512 case IFP_TCAM_WIDEm: 6513 case IFP_TCAM_WIDE_PIPE0m: 6514 case IFP_TCAM_WIDE_PIPE1m: 6515 slice_size = 256; 6516 break; 6517 default: 6518 return SOC_E_PARAM; 6519 } 6520 6521 entry_dw = soc_mem_entry_words(unit, mem); 6522 6523 slice_start_addr = soc_mem_index_min(unit, mem); 6524 for (slice = 0; slice < 12; slice++) { 6525 slice_end_addr = slice_start_addr + slice_size - 1; 6526 SOC_IF_ERROR_RETURN( 6527 soc_td3_ifp_slice_mode_check(unit, mem, slice, 6528 &slice_skip)); 6529 if (!slice_skip) { 6530 if (en_per_pipe_read) { 6531 int i; 6532 uint32 ser_flags; 6533 int acc_type_list[] = { 6534 _SOC_TD3_ACC_TYPE_UNIQUE_PIPE0, 6535 _SOC_TD3_ACC_TYPE_UNIQUE_PIPE1}; 6536 for (i = 0; i < NUM_PIPE(unit); i++) { 6537 ser_flags = 0; 6538 ser_flags |= _SOC_SER_FLAG_DISCARD_READ; 6539 ser_flags |= _SOC_SER_FLAG_MULTI_PIPE; 6540 ser_flags |= acc_type_list[i]; 6541 LOG_VERBOSE(BSL_LS_SOC_SER, 6542 (BSL_META_U(unit, 6543 "soc_td3_ifp_tcam_dma_read: will read slice %0d for mem %s, pipe %d\n"), 6544 slice, SOC_MEM_NAME(unit, mem), acc_type_list[i])); 6545 if (soc_mem_ser_read_range(unit, mem, blk, 6546 slice_start_addr, slice_end_addr, 6547 ser_flags, 6548 &table[slice_start_addr * entry_dw] 6549 ) < 0) { 6550 rv = SOC_E_FAIL; 6551 } 6552 } 6553 } else { 6554 LOG_VERBOSE(BSL_LS_SOC_SER, 6555 (BSL_META_U(unit, 6556 "soc_td3_ifp_tcam_dma_read: will read slice %0d for mem %s\n"), 6557 slice, SOC_MEM_NAME(unit, mem))); 6558 if (soc_mem_read_range(unit, mem, blk, 6559 slice_start_addr, slice_end_addr, 6560 &table[slice_start_addr * entry_dw]) < 0) { 6561 rv = SOC_E_FAIL; 6562 } 6563 } 6564 } else { 6565 LOG_VERBOSE(BSL_LS_SOC_SER, 6566 (BSL_META_U(unit, 6567 "soc_td3_ifp_tcam_dma_read: skipped slice %0d for mem %s\n"), 6568 slice, SOC_MEM_NAME(unit, mem))); 6569 } 6570 slice_start_addr = slice_end_addr + 1; 6571 } 6572 return rv; 6573 } 6574 6575 int 6576 soc_trident3_check_cache_skip(int unit, soc_mem_t mem) 6577 { 6578 if (!SOC_MEM_IS_VALID(unit,mem)) { 6579 return 1; 6580 } 6581 6582 switch (mem) { 6583 case L3_TUNNEL_DATA_ONLYm: 6584 6585 case DST_COMPRESSION_DATA_ONLYm: 6586 case DST_COMPRESSION_DATA_ONLY_PIPE0m: 6587 case DST_COMPRESSION_DATA_ONLY_PIPE1m: 6588 6589 case SRC_COMPRESSION_DATA_ONLYm: 6590 case SRC_COMPRESSION_DATA_ONLY_PIPE0m: 6591 case SRC_COMPRESSION_DATA_ONLY_PIPE1m: 6592 6593 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm: 6594 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE0m: 6595 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE1m: 6596 6597 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm: 6598 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE0m: 6599 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE1m: 6600 6601 case EXACT_MATCH_2_ENTRY_ONLYm: 6602 case EXACT_MATCH_2_ENTRY_ONLY_PIPE0m: 6603 case EXACT_MATCH_2_ENTRY_ONLY_PIPE1m: 6604 6605 case EXACT_MATCH_4_ENTRY_ONLYm: 6606 case EXACT_MATCH_4_ENTRY_ONLY_PIPE0m: 6607 case EXACT_MATCH_4_ENTRY_ONLY_PIPE1m: 6608 6609 case L2_ENTRY_ONLY_TILEm: 6610 6611 case L2_ENTRY_ONLY_ECCm: 6612 case L3_ENTRY_ONLY_ECCm: 6613 case L3_DEFIP_ALPM_ECCm: 6614 case EXACT_MATCH_ECCm: 6615 case EXACT_MATCH_ECC_PIPE0m: 6616 case EXACT_MATCH_ECC_PIPE1m: 6617 case MPLS_ENTRY_ECCm: 6618 case VLAN_XLATE_ECCm: 6619 case EGR_VLAN_XLATE_ECCm: 6620 case SUBPORT_ID_TO_SGPP_MAP_ECCm: 6621 case ING_DNAT_ADDRESS_TYPE_ECCm: 6622 case EGR_VP_VLAN_MEMBERSHIP_ECCm: 6623 case ING_VP_VLAN_MEMBERSHIP_ECCm: 6624 6625 case EXACT_MATCH_LPm: 6626 case L2_ENTRY_ISS_LPm: 6627 case L3_ENTRY_ISS_LPm: 6628 6629 case EGR_FRAGMENT_ID_TABLEm: 6630 case EGR_FRAGMENT_ID_TABLE_PIPE0m: 6631 case EGR_FRAGMENT_ID_TABLE_PIPE1m: 6632 case L3_ECMP_RRLB_CNTm: 6633 case L3_ECMP_RRLB_CNT_PIPE0m: 6634 case L3_ECMP_RRLB_CNT_PIPE1m: 6635 6636 #ifdef BCM_FLOWTRACKER_SUPPORT 6637 /* Flowtracker Group counter memories */ 6638 case BSC_KG_FLOW_AGE_OUT_COUNTERm: 6639 case BSC_KG_FLOW_LEARNED_COUNTERm: 6640 case BSC_KG_FLOW_EXCEED_COUNTERm: 6641 case BSC_KG_FLOW_MISSED_COUNTERm: 6642 case BSC_DG_FLOW_METER_EXCEED_COUNTERm: 6643 case BSC_AG_AGE_TABLEm: 6644 #endif 6645 6646 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, "cache_skip: skipping mem %s (soc_trident3_check_cache_skip)\n"), SOC_MEM_NAME(unit, mem))); 6647 return 1; 6648 6649 default: 6650 return 0; 6651 } 6652 /* 6653 case L2_ENTRY_TILEm: 6654 6655 case L3_DEFIP_ALPM_IPV4m: 6656 case L3_DEFIP_ALPM_IPV4_1m: 6657 case L3_DEFIP_ALPM_IPV6_64m: 6658 case L3_DEFIP_ALPM_IPV6_64_1m: 6659 case L3_DEFIP_ALPM_IPV6_128m: 6660 case L3_DEFIP_ALPM_RAWm: 6661 */ 6662 } 6663 6664 /* 6665 * following implement assist functions for soc_system_scrub() in 6666 * src/soc/esw/drv.c 6667 * 6668 * 1. Must not scrub 80b slices with _WIDE view and 160b slices with narrow view 6669 * 2. Must not scrub IFP_TCAM, IFP_TCAM_WIDE when in pipe_unique mode 6670 * 3. Must NOT scrub read_clear counters 6671 * 3. Can remove scrubbing of MEMm, if we are already scrubbing MEM_PIPE0-3m 6672 * 4. Are all mmu instances being scrubbed 6673 * 5. Views for which cachable=0 will not be scrubbed - so don't need to worry 6674 * about 6675 */ 6676 int 6677 soc_td3_check_scrub_skip(int unit, soc_mem_t mem, int check_hw_global_mode) 6678 { 6679 if (!SOC_MEM_IS_VALID(unit,mem)) { 6680 return 1; /* skip */ 6681 } 6682 if (soc_mem_is_cam(unit, mem) && 6683 SOC_TD3_MEM_CHK_TCAM_GLOBAL_UNIQUE_MODE(mem)) { 6684 /* For tcams that can operate in both global, unique modes, 6685 * we must skip read of global views when in unique mode. 6686 * This is because SER_ENGINE when configured to track tcam in unique 6687 * mode may not know which parity bits to use for comparison when it 6688 * sees read of global_view (with acc_type = 9) 6689 * Note: for srams, this skip is not necessary, because these are 6690 * not covered by SER_ENGINE 6691 * 6692 * We cannot skip read of global views when in global mode. 6693 * This is because, even though we scrub _PIPE0,1,2,3 views - these 6694 * will result in detection of error - but not correction !! 6695 * So we must scrub global views. 6696 * We can optimize by skipping scrub of _PIPE0,1,2,3 views when in 6697 * global mode. But this is not needed - because this will happen only 6698 * once during exit_clean and not during non_tcam_iterations (because 6699 * when doing non_tcam_iterations, we will be skipping all tcams) */ 6700 int rv; 6701 int mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 6702 if (check_hw_global_mode) { 6703 rv = soc_td3_check_hw_global_mode(unit, mem, &mem_mode); 6704 /* field module may already be de-initialized */ 6705 } else { 6706 rv = SOC_E_NONE;/*soc_td3_field_mem_mode_get(unit, mem, &mem_mode);*/ 6707 /* field module is active */ 6708 } 6709 if ((rv == SOC_E_NONE) && (mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE)) { 6710 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, "scrub: skipping mem %s (cannot read this mem in pipe_unique_mode)\n"), SOC_MEM_NAME(unit, mem))); 6711 return 1; /* skip */ 6712 } else { 6713 return 0; /* we know for sure this mem is not in 'skip_list' */ 6714 } 6715 } 6716 6717 switch (mem) { 6718 /* ECC views need not be scrubbed */ 6719 case L2_ENTRY_ONLY_ECCm: 6720 /* 1:1 mapping with L2Xm, so scan L2Xm */ 6721 6722 /* case L3_ENTRY_ONLY_ECCm: */ 6723 case L3_ENTRY_IPV4_UNICASTm: 6724 case L3_ENTRY_IPV4_MULTICASTm: 6725 case L3_ENTRY_IPV6_UNICASTm: 6726 case L3_ENTRY_IPV6_MULTICASTm: 6727 case L3_ENTRY_ONLYm: 6728 6729 /* case L3_DEFIP_ALPM_ECCm: */ 6730 case L3_DEFIP_ALPM_IPV4m: 6731 case L3_DEFIP_ALPM_IPV4_1m: 6732 case L3_DEFIP_ALPM_IPV6_64m: 6733 case L3_DEFIP_ALPM_IPV6_64_1m: 6734 case L3_DEFIP_ALPM_IPV6_128m: 6735 case L3_DEFIP_ALPM_RAWm: 6736 6737 case FPEM_ECCm: 6738 /* Has unique acc type, so only pipe0 will be scanned. 6739 * Instead, scan the _pipe0-3 views */ 6740 /* case FPEM_ECC_PIPE0m: */ 6741 /* case FPEM_ECC_PIPE1m: */ 6742 /* case FPEM_ECC_PIPE2m: */ 6743 /* case FPEM_ECC_PIPE3m: */ 6744 6745 case EXACT_MATCH_2m: 6746 case EXACT_MATCH_2_PIPE0m: 6747 case EXACT_MATCH_2_PIPE1m: 6748 6749 case EXACT_MATCH_4m: 6750 case EXACT_MATCH_4_PIPE0m: 6751 case EXACT_MATCH_4_PIPE1m: 6752 6753 case MPLS_ENTRY_ECCm: 6754 case VLAN_XLATE_ECCm: 6755 case EGR_VLAN_XLATE_ECCm: 6756 6757 /* DATA_ONLY, ENTRY_ONLY views need not be scrubbed */ 6758 /* 6759 case L2_USER_ENTRY_DATA_ONLYm: 6760 case L2_USER_ENTRY_ONLYm: 6761 */ 6762 case L3_TUNNEL_DATA_ONLYm: 6763 case L3_TUNNEL_ONLYm: 6764 6765 case VLAN_SUBNET_DATA_ONLYm: 6766 case VLAN_SUBNET_ONLYm: 6767 6768 case MY_STATION_TCAM_DATA_ONLYm: 6769 case MY_STATION_TCAM_ENTRY_ONLYm: 6770 6771 case ING_SNAT_DATA_ONLYm: 6772 case ING_SNAT_ONLYm: 6773 6774 case DST_COMPRESSION_DATA_ONLYm: 6775 case DST_COMPRESSION_DATA_ONLY_PIPE0m: 6776 case DST_COMPRESSION_DATA_ONLY_PIPE1m: 6777 /* 6778 case DST_COMPRESSION_TCAM_ONLYm: 6779 case DST_COMPRESSION_TCAM_ONLY_PIPE0m: 6780 case DST_COMPRESSION_TCAM_ONLY_PIPE1m: 6781 case DST_COMPRESSION_TCAM_ONLY_PIPE2m: 6782 case DST_COMPRESSION_TCAM_ONLY_PIPE3m: 6783 */ 6784 6785 case SRC_COMPRESSION_DATA_ONLYm: 6786 case SRC_COMPRESSION_DATA_ONLY_PIPE0m: 6787 case SRC_COMPRESSION_DATA_ONLY_PIPE1m: 6788 /* 6789 case SRC_COMPRESSION_TCAM_ONLYm: 6790 case SRC_COMPRESSION_TCAM_ONLY_PIPE0m: 6791 case SRC_COMPRESSION_TCAM_ONLY_PIPE1m: 6792 case SRC_COMPRESSION_TCAM_ONLY_PIPE2m: 6793 case SRC_COMPRESSION_TCAM_ONLY_PIPE3m: 6794 6795 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm: 6796 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE0m: 6797 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE1m: 6798 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE2m: 6799 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE3m: 6800 6801 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 6802 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE0m: 6803 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE1m: 6804 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE2m: 6805 case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE3m: 6806 */ 6807 6808 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm: 6809 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE0m: 6810 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLY_PIPE1m: 6811 /* 6812 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm: 6813 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE0m: 6814 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE1m: 6815 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE2m: 6816 case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLY_PIPE3m: 6817 */ 6818 6819 /* specials which need not be scrubbed */ 6820 case L2_BULKm: 6821 case L2_ENTRY_ONLY_TILEm: 6822 case L2_ENTRY_TILEm: 6823 case L2_LEARN_INSERT_FAILUREm: 6824 6825 case EXACT_MATCH_2_ENTRY_ONLYm: 6826 case EXACT_MATCH_2_ENTRY_ONLY_PIPE0m: 6827 case EXACT_MATCH_2_ENTRY_ONLY_PIPE1m: 6828 6829 case EXACT_MATCH_4_ENTRY_ONLYm: 6830 case EXACT_MATCH_4_ENTRY_ONLY_PIPE0m: 6831 case EXACT_MATCH_4_ENTRY_ONLY_PIPE1m: 6832 6833 /* global views which already have _PIPE0-PIPE3 views */ 6834 6835 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, "scrub: skipping mem %s (soc_td3_check_scrub_skip)\n"), SOC_MEM_NAME(unit, mem))); 6836 return 1; 6837 default: 6838 /* 6839 * Must NOT BE skipped 6840 * ------------------- 6841 * LP views - they could have parity errors 6842 * Mems scanned by memscan - we need to scrub them 6843 * MEMm if scanning MEM_PIPE0-3m 6844 */ 6845 break; 6846 } 6847 return 0; 6848 } 6849 6850 int 6851 soc_td3_mem_is_eligible_for_scan(int unit, soc_mem_t mem) 6852 { 6853 switch (mem) { 6854 case L3_ENTRY_ONLY_ECCm: 6855 case L3_DEFIP_ALPM_ECCm: 6856 case FPEM_ECC_PIPE0m: 6857 case FPEM_ECC_PIPE1m: 6858 case FPEM_ECC_PIPE2m: 6859 case FPEM_ECC_PIPE3m: 6860 case L2_ENTRY_ISS_LPm: 6861 case L2_ENTRY_LPm: 6862 case L3_ENTRY_ISS_LPm: 6863 case L3_ENTRY_LPm: 6864 case FPEM_LPm: 6865 case VLAN_XLATE_LPm: 6866 case EGR_VLAN_XLATE_LPm: 6867 return 1; 6868 default: 6869 break; 6870 } 6871 return 0; 6872 } 6873 6874 void 6875 soc_td3_mem_scan_info_get(int unit, soc_mem_t mem, int block, 6876 int *num_pipe, int *ser_flags) 6877 { 6878 int k, num_inst_to_scrub = 0, acc_type_list[8], copyno = block; 6879 (void) soc_td3_check_scrub_info(unit, mem, block, copyno, 6880 &num_inst_to_scrub, 6881 acc_type_list); 6882 /* in case of SOC_FAILURE(rv), num_inst_to_scrub = 0, so 6883 * will be handled below as if we need to scrub only one 6884 * pipe */ 6885 assert(num_inst_to_scrub <= 8); 6886 if (num_inst_to_scrub == 0) { 6887 *num_pipe = 1; 6888 ser_flags[0] = 0; 6889 if (!soc_mem_dmaable(unit, mem, block)) { 6890 ser_flags[0] = _SOC_SER_FLAG_NO_DMA; 6891 } 6892 } else { 6893 if (1 == NUM_PIPE(unit)) { 6894 6895 num_inst_to_scrub = 1; 6896 } 6897 *num_pipe = num_inst_to_scrub; 6898 for (k = 0; k < num_inst_to_scrub; k++) { 6899 ser_flags[k] = 0; 6900 ser_flags[k] |= _SOC_SER_FLAG_DISCARD_READ; 6901 if (num_inst_to_scrub > 1) { 6902 ser_flags[k] |= _SOC_SER_FLAG_MULTI_PIPE; 6903 } 6904 ser_flags[k] |= acc_type_list[k]; 6905 if (!soc_mem_dmaable(unit, mem, block)) { 6906 ser_flags[k] |= _SOC_SER_FLAG_NO_DMA; 6907 } 6908 } 6909 } 6910 } 6911 6912 int 6913 soc_td3_check_scrub_info(int unit, soc_mem_t mem, int blk, int copyno, 6914 int *num_inst_to_scrub, int *acc_type_list) 6915 { 6916 int mem_acc_type = SOC_MEM_ACC_TYPE(unit, mem); 6917 int mmu_base_type; 6918 soc_block_t blk_type; 6919 6920 if (copyno == COPYNO_ALL) { 6921 return SOC_E_PARAM; 6922 } 6923 blk_type = SOC_BLOCK_TYPE(unit, copyno); 6924 6925 if ((NULL == acc_type_list) || (NULL == num_inst_to_scrub)) { 6926 return SOC_E_PARAM; 6927 } 6928 6929 *num_inst_to_scrub = 0; 6930 6931 if (!SOC_MEM_IS_VALID(unit,mem)) { 6932 return SOC_E_NONE; 6933 } 6934 6935 if (((mem_acc_type == _SOC_TD3_ACC_TYPE_DUPLICATE) && 6936 ((blk_type == SOC_BLK_IPIPE) || (blk_type == SOC_BLK_EPIPE)) && 6937 (SOC_MEM_UNIQUE_ACC(unit, mem) == NULL)) || 6938 SOC_TD3_MEM_CHK_TCAM_GLOBAL_UNIQUE_MODE(mem)) { 6939 /* 2nd last term: sw has not already created per-instance unique views */ 6940 *num_inst_to_scrub = NUM_PIPE(unit); 6941 acc_type_list[0] = _SOC_TD3_ACC_TYPE_UNIQUE_PIPE0; 6942 acc_type_list[1] = _SOC_TD3_ACC_TYPE_UNIQUE_PIPE1; 6943 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, "scrub: mem.blk.blk_type %s.%d.%d has acc_type = %s (%d), num_inst_to_scrub = %0d\n"), 6944 SOC_MEM_NAME(unit,mem), blk, blk_type, 6945 _SOC_TD3_ACC_TYPE_NAME(mem_acc_type), mem_acc_type, 6946 *num_inst_to_scrub)); 6947 return SOC_E_NONE; 6948 } /* need_per_pipe_scrub */ 6949 6950 if ((mem_acc_type == _SOC_TD3_ACC_TYPE_DUPLICATE) && 6951 ((blk_type == SOC_BLK_MMU_GLB) || 6952 (blk_type == SOC_BLK_MMU_XPE) || 6953 (blk_type == SOC_BLK_MMU_SC))) { 6954 6955 mmu_base_type = SOC_MEM_BASE_TYPE(unit, mem); 6956 6957 6958 switch (blk_type) { 6959 case SOC_BLK_MMU_XPE: 6960 switch (mmu_base_type) { 6961 case SOC_TD3_MMU_BASE_TYPE_IPIPE: 6962 *num_inst_to_scrub = 1; 6963 acc_type_list[0] = 0; 6964 break; 6965 case SOC_TD3_MMU_BASE_TYPE_EPIPE: 6966 *num_inst_to_scrub = 1; 6967 acc_type_list[0] = 0; 6968 break; 6969 case SOC_TD3_MMU_BASE_TYPE_CHIP: 6970 /* must read each xpe instance */ 6971 *num_inst_to_scrub = 1; 6972 acc_type_list[0] = 0; 6973 break; 6974 case SOC_TD3_MMU_BASE_TYPE_SLICE: 6975 *num_inst_to_scrub = 1; 6976 acc_type_list[0] = 0; 6977 break; 6978 case SOC_TD3_MMU_BASE_TYPE_LAYER: 6979 *num_inst_to_scrub = 1; 6980 acc_type_list[0] = 0; 6981 break; 6982 default: /* IPORT, EPORT, XPE */ 6983 /* should not find any TD3 memories here */ 6984 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit, "scrub_ERROR: mem.blk.blk_type %s.%d.%d has acc_type = %s (%d), num_inst_to_scrub = %0d, mmu_base_type = %0d\n"), 6985 SOC_MEM_NAME(unit,mem), blk, blk_type, 6986 _SOC_TD3_ACC_TYPE_NAME(mem_acc_type), mem_acc_type, 6987 *num_inst_to_scrub, mmu_base_type)); 6988 return SOC_E_FAIL; 6989 } /* mmu_base_type */ 6990 break; /* case: SOC_BLK_MMU_XPE */ 6991 6992 default: /* SOC_BLK_MMU_GLB, SOC_BLK_MMU_SC */ 6993 /* should not find any TD3 memories here */ 6994 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit, "scrub_ERROR: mem.blk.blk_type %s.%d.%d has acc_type = %s (%d), num_inst_to_scrub = %0d, mmu_base_type = %0d\n"), 6995 SOC_MEM_NAME(unit,mem), blk, blk_type, 6996 _SOC_TD3_ACC_TYPE_NAME(mem_acc_type), mem_acc_type, 6997 *num_inst_to_scrub, mmu_base_type)); 6998 return SOC_E_FAIL; 6999 } /* blk_type */ 7000 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, "scrub: mem.blk.blk_type %s.%d.%d has acc_type = %s (%d), num_inst_to_scrub = %0d, mmu_base_type = %0d\n"), 7001 SOC_MEM_NAME(unit,mem), blk, blk_type, 7002 _SOC_TD3_ACC_TYPE_NAME(mem_acc_type), mem_acc_type, 7003 *num_inst_to_scrub, mmu_base_type)); 7004 return SOC_E_NONE; 7005 } /* need_per_mmu_membase_scrub */ 7006 return SOC_E_NONE; 7007 } 7008 7009 /* For lookup operations to folded hash tables, SER event could be on LP view or 7010 * functional view (fv), even when search is issued to functional view. 7011 * In case when there is error on LP view, rsp_word 7012 * carries index to LP view and not the functinal view. 7013 * Following function helps remap the fv_index to lp_index. 7014 * It assumes that err_info received by caller is '1' meaning HW is indicating 7015 * that error is in LP view. Because this can happen only for folded hash 7016 * tables, any other mem passed as param to this function will result in return 7017 * with error from this function. 7018 */ 7019 int 7020 soc_td3_lp_to_fv_index_remap(int unit, soc_mem_t mem, int *rpt_index) 7021 { 7022 int em_lp_bank, em_lp_addr, index, rv = SOC_E_NONE; 7023 7024 if (NULL == rpt_index) { 7025 return SOC_E_PARAM; 7026 } 7027 index = *rpt_index; /* default */ 7028 switch(mem) { 7029 case VLAN_MACm: 7030 case VLAN_XLATEm: 7031 /* Error in VLAN_XLATE_LPm */ 7032 index = index << 2; /* = 4*index; for cache read */ 7033 break; 7034 case EGR_VLAN_XLATEm: 7035 /* Error in EGR_VLAN_XLATE_LPm */ 7036 index = index << 2; /* = 4*index; for cache read */ 7037 break; 7038 case EXACT_MATCH_2m: 7039 case EXACT_MATCH_2_PIPE0m: 7040 case EXACT_MATCH_2_PIPE1m: 7041 /* Error in FPEM_LPm */ 7042 assert(index < 32768); 7043 em_lp_bank = (index >> 13) & 0x3; /* = index/8K; can be 0,1,2,3 */ 7044 em_lp_addr = index & 0x1FFF; /* = index%8K; adr within lp bank */ 7045 assert(em_lp_addr < 4096); /* For EM_2 */ 7046 index = (16384 * em_lp_bank) + (4 * em_lp_addr); 7047 /* each lp bank is 8K deep, total of 4 lp banks, 1 per each uft_bank */ 7048 /* each uft bank can have 16K EM_2 entries */ 7049 /* each lp_entry covers 4 consec EM_2 entries */ 7050 /* index is the addr of first em2_entry in the bkt pointed by 7051 * lp_adr reported in err_rsp */ 7052 index = 2*index; 7053 /* Each em2 entry has 2 FPEM_ECC entries. 7054 Now index is addr of first fpem_ecc entry in the bkt pointed 7055 by lp_adr reported in err_rsp */ 7056 LOG_WARN(BSL_LS_SOC_SER, 7057 (BSL_META_U(unit, 7058 "unit %d, td3_lp_to_fv_index_remap: " 7059 "mem %s, em_lp_bank %d, em_lp_addr %0d \n"), 7060 unit, SOC_MEM_NAME(unit, mem), em_lp_bank, em_lp_addr)); 7061 break; 7062 case EXACT_MATCH_4m: 7063 case EXACT_MATCH_4_PIPE0m: 7064 case EXACT_MATCH_4_PIPE1m: 7065 /* Error in FPEM_LPm */ 7066 assert(index < 32768); 7067 em_lp_bank = (index >> 13) & 0x3; /* = index/8K; can be 0,1,2,3 */ 7068 em_lp_addr = index & 0x1FFF; /* = index%8K; adr within lp bank */ 7069 assert(em_lp_addr >= 4096); /* For EM_4 */ 7070 assert(em_lp_addr < 6144); /* For EM_4 */ 7071 index = (8192 * em_lp_bank) + (4 * (em_lp_addr - 4096)); 7072 /* each lp bank is 8K deep, total of 4 lp banks, 1 per each uft_bank */ 7073 /* each uft bank can have 8K EM_4 entries */ 7074 /* each lp_entry covers 4 consec EM_4 entries */ 7075 /* index is the addr of first em4_entry in the bkt pointed by 7076 * lp_adr reported in err_rsp */ 7077 index = 4*index; 7078 /* Each em4 entry has 4 FPEM_ECC entries. 7079 Now index is addr of first fpem_ecc entry in the bkt pointed 7080 by lp_adr reported in err_rsp */ 7081 LOG_WARN(BSL_LS_SOC_SER, 7082 (BSL_META_U(unit, 7083 "unit %d, td3_lp_to_fv_index_remap: " 7084 "mem %s, em_lp_bank %d, em_lp_addr %0d \n"), 7085 unit, SOC_MEM_NAME(unit, mem), em_lp_bank, em_lp_addr)); 7086 break; 7087 default: 7088 LOG_ERROR(BSL_LS_SOC_SER, 7089 (BSL_META_U(unit, 7090 "soc_td3_lp_to_fv_index_remap: mem %s is not folded hash table !! index %d\n"), 7091 SOC_MEM_NAME(unit, mem), index)); 7092 rv = SOC_E_PARAM; 7093 } 7094 7095 LOG_WARN(BSL_LS_SOC_SER, 7096 (BSL_META_U(unit, 7097 "unit %d, td3_lp_to_fv_index_remap: " 7098 "mem %s, rpt_lp_index %0d, fv_index %0d \n"), 7099 unit, SOC_MEM_NAME(unit, mem), *rpt_index, index)); 7100 *rpt_index = index; 7101 return rv; 7102 } 7103 7104 STATIC 7105 int 7106 _soc_td3_reg32_par_en_modify(int unit, soc_reg_t reg, soc_field_t field, 7107 int enable) 7108 { 7109 uint64 rval64; 7110 uint32 rval; 7111 int port = REG_PORT_ANY; 7112 static char *mmu_base_type[8] = { 7113 "IPORT", "EPORT", "IPIPE", "EPIPE", "CHIP", "XPE", "SLICE", "LAYER"}; 7114 7115 if (SOC_REG_IS_VALID(unit, reg) && INVALIDf != field) { 7116 if (SOC_REG_IS_64(unit, reg)) { 7117 SOC_IF_ERROR_RETURN 7118 (soc_reg_get(unit, reg, port, 0, &rval64)); 7119 soc_reg64_field32_set(unit, reg, &rval64, field, enable? 1 : 0); 7120 SOC_IF_ERROR_RETURN 7121 (soc_reg_set(unit, reg, port, 0, rval64)); 7122 } else { 7123 int at, bt; 7124 SOC_IF_ERROR_RETURN 7125 (soc_reg32_get(unit, reg, port, 0, &rval)); 7126 soc_reg_field_set(unit, reg, &rval, field, 7127 enable ? 1 : 0); 7128 at = SOC_REG_ACC_TYPE(unit, reg); 7129 bt = SOC_REG_BASE_TYPE(unit, reg); 7130 if (20 == at) { /* ACC_TYPE_SINGLE - used only in MMU blocks */ 7131 int inst, pipe, max_pipe; 7132 switch (bt) { 7133 case 2: /* IPIPE */ 7134 case 3: /* EPIPE */ 7135 max_pipe = NUM_PIPE(unit); break; 7136 case 4: /* CHIP */ 7137 max_pipe = 1; break; 7138 case 5: /* XPE */ 7139 max_pipe = NUM_XPE(unit); break; 7140 case 6: /* SLICE */ 7141 max_pipe = NUM_SLICE(unit); break; 7142 case 7: /* LAYER */ 7143 max_pipe = NUM_LAYER(unit); break; 7144 default: 7145 /* 0: IPORT */ 7146 /* 1: EPORT */ 7147 max_pipe = -1; 7148 LOG_ERROR(BSL_LS_SOC_SER, 7149 (BSL_META_U(unit, 7150 "unit %d, reg %s has unexpected " 7151 "base_type %s, will skip enable of " 7152 "1b err reporting\n"), 7153 unit, SOC_REG_NAME(unit, reg), 7154 mmu_base_type[bt])); 7155 break; 7156 } 7157 LOG_VERBOSE(BSL_LS_SOC_SER, 7158 (BSL_META_U(unit, 7159 "unit %d, reg %s has base_type %s\n"), 7160 unit, SOC_REG_NAME(unit, reg), 7161 mmu_base_type[bt])); 7162 for (pipe = 0; pipe < max_pipe; pipe++) { 7163 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 7164 SOC_IF_ERROR_RETURN 7165 (soc_reg32_set(unit, reg, inst, 0, rval)); 7166 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, 7167 "HF detected: setting reg.field[%s.%s]=0, mmu_base_type %s, pipe %d, using acc_type %0d\n"), 7168 SOC_REG_NAME(unit, reg), SOC_FIELD_NAME(unit, field), 7169 mmu_base_type[bt], pipe, at)); 7170 } 7171 } else { 7172 SOC_IF_ERROR_RETURN 7173 (soc_reg32_set(unit, reg, port, 0, rval)); 7174 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, 7175 "HF detected: setting reg.field[%s.%s]=0, using acc_type %0d (default)\n"), 7176 SOC_REG_NAME(unit, reg), SOC_FIELD_NAME(unit, field), 7177 at)); 7178 } 7179 } /* reg32 */ 7180 return SOC_E_NONE; 7181 } 7182 return SOC_E_UNAVAIL; 7183 } 7184 7185 STATIC int 7186 soc_td3_mem_parity_set(int unit, soc_mem_t mem, int copyno, 7187 _soc_mem_ser_en_info_t *ser_info_list, 7188 int en, int en_1b) 7189 { 7190 int i = 0; 7191 7192 for (i = 0; INVALIDm != ser_info_list[i].mem; i++) { 7193 if (ser_info_list[i].mem == mem) { 7194 if (ser_info_list[i].en_ctrl.flag_reg_mem == 0) { 7195 SOC_IF_ERROR_RETURN( 7196 _soc_td3_reg32_par_en_modify(unit, 7197 ser_info_list[i].en_ctrl.ctrl_type.en_reg, 7198 ser_info_list[i].en_ctrl.en_fld, 7199 en)); 7200 SOC_IF_ERROR_RETURN( 7201 _soc_td3_reg32_par_en_modify(unit, 7202 ser_info_list[i].ecc1b_ctrl.ctrl_type.en_reg, 7203 ser_info_list[i].ecc1b_ctrl.en_fld, 7204 en_1b)); 7205 } 7206 return SOC_E_NONE; 7207 } 7208 } 7209 7210 return SOC_E_UNAVAIL; 7211 7212 } 7213 7214 int soc_td3_mem_parity_control(int unit, soc_mem_t mem, int copyno, 7215 int en, int en_1b) 7216 { 7217 int rv = SOC_E_NONE; 7218 7219 if (!SOC_MEM_IS_VALID(unit, mem)) { 7220 return SOC_E_UNAVAIL; 7221 } 7222 7223 rv = soc_td3_mem_parity_set(unit, mem, copyno, SOC_IP_MEM_SER_INFO(unit), en, en_1b); 7224 if (rv == SOC_E_NONE) { 7225 return rv; 7226 } 7227 7228 rv = soc_td3_mem_parity_set(unit, mem, copyno, SOC_EP_MEM_SER_INFO(unit), en, en_1b); 7229 if (rv == SOC_E_NONE) { 7230 return rv; 7231 } 7232 7233 rv = soc_td3_mem_parity_set(unit, mem, copyno, SOC_MMU_MEM_SER_INFO(unit), en, en_1b); 7234 if (rv == SOC_E_NONE) { 7235 return rv; 7236 } 7237 7238 return SOC_E_UNAVAIL; 7239 } 7240 7241 #if defined(SER_TR_TEST_SUPPORT) 7242 7243 #define TR_MEM_NAME_SIZE_MAX 100 7244 #ifdef SOC_MEM_NAME 7245 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) do { \ 7246 const char *_mem_name = SOC_MEM_NAME(_unit_, _mem); \ 7247 if (sal_strlen(_mem_name) < TR_MEM_NAME_SIZE_MAX) { \ 7248 sal_strcpy(_msg, _mem_name); \ 7249 } \ 7250 } while (0) 7251 #else 7252 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) 7253 #endif 7254 7255 #define TR_TEST_MEM_PRINT(_unit, _msg, _mem) do { \ 7256 sal_sprintf(_msg, "Mem ID: %d", _mem); \ 7257 TR_TEST_MEM_NAME_GET(_unit, _msg, _mem); \ 7258 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(_unit, \ 7259 "Memory %s is valid, but not currently testable.\n"), \ 7260 _msg)); \ 7261 } while (0) 7262 7263 #define _SER_TEST_MEM_TD3_ALPM_MASK(num_uft_banks) ((num_uft_banks) == 8? 0xFFFF : 0x7FFF) 7264 #define _SER_TEST_MEM_TD3_ALPM_SHIFT(num_uft_banks) ((num_uft_banks) == 8? 16 : 15) 7265 7266 #define _SOC_TD3_TR144_LONG_SLEEP_TIME_US 200000 7267 7268 int 7269 ser_test_td3_mem_index_remap(int unit, ser_test_data_t *test_data, 7270 int *mem_has_ecc) 7271 { 7272 int num_uft_banks = 0; 7273 int uft_bkt_bank = 0; 7274 int uft_le_fv = 0; 7275 int uft_le_ecc = 0; 7276 7277 int remap_status = 0; /* no error */ 7278 7279 if ((NULL == test_data) || (NULL == mem_has_ecc)) { 7280 return SOC_E_PARAM; 7281 } 7282 if (!SOC_MEM_IS_VALID(unit, test_data->mem_fv)) { 7283 LOG_ERROR(BSL_LS_SOC_SER, 7284 (BSL_META_U(unit, 7285 "unit %d, mem %d is INVALID or not valid " 7286 "for this unit !!\n"), 7287 unit, test_data->mem_fv)); 7288 return SOC_E_UNAVAIL; 7289 } 7290 *mem_has_ecc = 0; 7291 test_data->mem = test_data->mem_fv; 7292 test_data->index = test_data->index_fv; 7293 7294 num_uft_banks = soc_trident3_get_alpm_banks(unit); 7295 switch (test_data->mem_fv) { 7296 case VLAN_XLATE_1_SINGLEm: 7297 test_data->mem = VLAN_XLATE_1_ECCm; 7298 test_data->index = test_data->index_fv; 7299 *mem_has_ecc = 1; 7300 break; 7301 case VLAN_XLATE_2_SINGLEm: 7302 test_data->mem = VLAN_XLATE_2_ECCm; 7303 test_data->index = test_data->index_fv; 7304 *mem_has_ecc = 1; 7305 break; 7306 case VLAN_XLATE_1_DOUBLEm: 7307 test_data->mem = VLAN_XLATE_1_ECCm; 7308 test_data->index = test_data->index_fv * 2; 7309 *mem_has_ecc = 1; 7310 break; 7311 case VLAN_XLATE_2_DOUBLEm: 7312 test_data->mem = VLAN_XLATE_2_ECCm; 7313 test_data->index = test_data->index_fv * 2; 7314 *mem_has_ecc = 1; 7315 break; 7316 case EGR_VLAN_XLATE_1_SINGLEm: 7317 test_data->mem = EGR_VLAN_XLATE_1_ECCm; 7318 test_data->index = test_data->index_fv; 7319 *mem_has_ecc = 1; 7320 break; 7321 case EGR_VLAN_XLATE_2_SINGLEm: 7322 test_data->mem = EGR_VLAN_XLATE_2_ECCm; 7323 test_data->index = test_data->index_fv; 7324 *mem_has_ecc = 1; 7325 break; 7326 case EGR_VLAN_XLATE_1_DOUBLEm: 7327 test_data->mem = EGR_VLAN_XLATE_1_ECCm; 7328 test_data->index = test_data->index_fv * 2; 7329 *mem_has_ecc = 1; 7330 break; 7331 case EGR_VLAN_XLATE_2_DOUBLEm: 7332 test_data->mem = EGR_VLAN_XLATE_2_ECCm; 7333 test_data->index = test_data->index_fv * 2; 7334 *mem_has_ecc = 1; 7335 break; 7336 case MPLS_ENTRYm: 7337 test_data->mem = MPLS_ENTRY_ECCm; 7338 test_data->index = test_data->index_fv * 2; 7339 *mem_has_ecc = 1; 7340 break; 7341 case MPLS_ENTRY_SINGLEm: 7342 test_data->mem = MPLS_ENTRY_ECCm; 7343 test_data->index = test_data->index_fv; 7344 *mem_has_ecc = 1; 7345 break; 7346 case L2Xm: 7347 case L2_ENTRY_ONLY_SINGLEm: 7348 case L2_ENTRY_SINGLEm: 7349 test_data->mem = L2_ENTRY_ECCm; 7350 *mem_has_ecc = 1; 7351 break; 7352 case L3_ENTRY_ONLY_SINGLEm: 7353 case L3_ENTRY_SINGLEm: 7354 test_data->mem = L3_ENTRY_ECCm; 7355 test_data->index = test_data->index_fv; 7356 *mem_has_ecc = 1; 7357 break; 7358 case L3_ENTRY_ONLY_DOUBLEm: 7359 case L3_ENTRY_DOUBLEm: 7360 test_data->mem = L3_ENTRY_ECCm; 7361 test_data->index = test_data->index_fv*2; 7362 *mem_has_ecc = 1; 7363 break; 7364 case L3_ENTRY_ONLY_QUADm: 7365 case L3_ENTRY_QUADm: 7366 test_data->mem = L3_ENTRY_ECCm; 7367 test_data->index = test_data->index_fv*4; 7368 *mem_has_ecc = 1; 7369 break; 7370 case EXACT_MATCH_2m: 7371 case EXACT_MATCH_2_PIPE0m: 7372 case EXACT_MATCH_2_PIPE1m: 7373 test_data->mem = EXACT_MATCH_ECCm; 7374 test_data->index = test_data->index_fv*2; 7375 *mem_has_ecc = 1; 7376 break; 7377 case EXACT_MATCH_4m: 7378 case EXACT_MATCH_4_PIPE0m: 7379 case EXACT_MATCH_4_PIPE1m: 7380 test_data->mem = EXACT_MATCH_ECCm; 7381 test_data->index = test_data->index_fv*4; 7382 *mem_has_ecc = 1; 7383 break; 7384 case EXACT_MATCH_LPm: 7385 test_data->mem = EXACT_MATCH_LPm; 7386 test_data->index = test_data->index_fv; 7387 *mem_has_ecc = 1; 7388 break; 7389 case L3_DEFIP_ALPM_IPV4m: /* 6:4 */ 7390 *mem_has_ecc = 1; 7391 test_data->mem = L3_DEFIP_ALPM_ECCm; 7392 uft_bkt_bank = test_data->index_fv % 7393 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7394 uft_le_fv = test_data->index_fv / 7395 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7396 switch (uft_le_fv) { 7397 case 0: uft_le_ecc = 0; break; 7398 case 1: uft_le_ecc = 0; break; /* or 1 */ 7399 case 2: uft_le_ecc = 1; break; 7400 case 3: uft_le_ecc = 2; break; 7401 case 4: uft_le_ecc = 2; break; /* or 3 */ 7402 case 5: uft_le_ecc = 3; break; 7403 default: remap_status = -1; uft_le_ecc = uft_le_fv; break; 7404 } 7405 test_data->index = 7406 uft_le_ecc * soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm) + 7407 uft_bkt_bank; 7408 break; 7409 case L3_DEFIP_ALPM_IPV4_1m: /* 4:4 */ 7410 case L3_DEFIP_ALPM_IPV6_64m: 7411 *mem_has_ecc = 1; 7412 test_data->mem = L3_DEFIP_ALPM_ECCm; 7413 test_data->index = test_data->index_fv; 7414 break; 7415 case L3_DEFIP_ALPM_IPV6_64_1m: /* 3:4 */ 7416 *mem_has_ecc = 1; 7417 test_data->mem = L3_DEFIP_ALPM_ECCm; 7418 uft_bkt_bank = test_data->index_fv % 7419 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7420 uft_le_fv = test_data->index_fv / 7421 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7422 switch (uft_le_fv) { 7423 case 0: uft_le_ecc = 0; break; /* or 1 */ 7424 case 1: uft_le_ecc = 1; break; /* or 2 */ 7425 case 2: uft_le_ecc = 2; break; /* or 3 */ 7426 default: remap_status = -1; uft_le_ecc = uft_le_fv; break; 7427 } 7428 test_data->index = 7429 uft_le_ecc * soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm) + 7430 uft_bkt_bank; 7431 break; 7432 case L3_DEFIP_ALPM_IPV6_128m: /* 2:4 */ 7433 *mem_has_ecc = 1; 7434 test_data->mem = L3_DEFIP_ALPM_ECCm; 7435 uft_bkt_bank = test_data->index_fv % 7436 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7437 uft_le_fv = test_data->index_fv / 7438 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7439 switch (uft_le_fv) { 7440 case 0: uft_le_ecc = 0; break; /* or 1 */ 7441 case 1: uft_le_ecc = 2; break; /* or 3 */ 7442 default: remap_status = -1; uft_le_ecc = uft_le_fv; break; 7443 } 7444 test_data->index = 7445 uft_le_ecc * soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm) + 7446 uft_bkt_bank; 7447 break; 7448 case L3_DEFIP_ALPM_RAWm: /* 1:4 */ 7449 *mem_has_ecc = 1; 7450 test_data->mem = L3_DEFIP_ALPM_ECCm; 7451 uft_bkt_bank = test_data->index_fv % 7452 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7453 uft_le_fv = test_data->index_fv / 7454 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm); 7455 switch (uft_le_fv) { 7456 case 0: uft_le_ecc = 0; break; /* or 1,2,3 */ 7457 default: remap_status = -1; uft_le_ecc = uft_le_fv; break; 7458 } 7459 test_data->index = 7460 uft_le_ecc * soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm) + 7461 uft_bkt_bank; 7462 break; 7463 case MMU_INTFO_TC2PRI_MAPPINGm: 7464 test_data->mem = MMU_INTFO_TC2PRI_MAPPING0m; 7465 break; 7466 case ING_DNAT_ADDRESS_TYPEm: 7467 test_data->mem = ING_DNAT_ADDRESS_TYPE_ECCm; 7468 test_data->index = test_data->index_fv / 2; 7469 *mem_has_ecc = 1; 7470 break; 7471 case EGR_VP_VLAN_MEMBERSHIPm: 7472 test_data->mem = EGR_VP_VLAN_MEMBERSHIP_ECCm; 7473 test_data->index = test_data->index_fv / 2; 7474 *mem_has_ecc = 1; 7475 break; 7476 case ING_VP_VLAN_MEMBERSHIPm: 7477 test_data->mem = ING_VP_VLAN_MEMBERSHIP_ECCm; 7478 test_data->index = test_data->index_fv / 2; 7479 *mem_has_ecc = 1; 7480 break; 7481 case SUBPORT_ID_TO_SGPP_MAPm: 7482 test_data->mem = SUBPORT_ID_TO_SGPP_MAP_ECCm; 7483 test_data->index = test_data->index_fv / 2; 7484 *mem_has_ecc = 1; 7485 break; 7486 default: 7487 test_data->mem = test_data->mem_fv; 7488 test_data->index = test_data->index_fv; 7489 break; 7490 } 7491 if ((test_data->mem != test_data->mem_fv) || 7492 (test_data->index != test_data->index_fv)) { 7493 LOG_VERBOSE(BSL_LS_SOC_SER, 7494 (BSL_META_U(unit, 7495 "unit %d, ser_test_td3_mem_index_remap: " 7496 "mem_fv %s, index_fv %0d, mem %s, index %0d, " 7497 "#uft_banks %0d, uft_bkt_bank %0d, uft_le_fv %0d, " 7498 "uft_le_ecc %0d, remap_status %0d \n"), 7499 unit, SOC_MEM_NAME(unit, test_data->mem_fv), test_data->index_fv, 7500 SOC_MEM_NAME(unit, test_data->mem), test_data->index, num_uft_banks, 7501 uft_bkt_bank, uft_le_fv, uft_le_ecc, remap_status)); 7502 } 7503 return remap_status; 7504 } 7505 7506 static soc_ser_test_functions_t ser_trident3_test_fun; 7507 7508 typedef struct ser_td3_skipped_mem_s { 7509 soc_mem_t mem; 7510 soc_acc_type_t acc_type; 7511 int allow_error_inj; 7512 } ser_td3_skipped_mem_t; 7513 7514 const ser_td3_skipped_mem_t td3_skipped_mems[] = { 7515 /* Report only views */ 7516 { VLAN_XLATE_1_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7517 { VLAN_XLATE_2_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7518 { MPLS_ENTRY_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7519 { FPEM_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7520 { FPEM_ECC_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7521 { FPEM_ECC_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7522 { L2_ENTRY_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7523 { L3_ENTRY_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7524 { L3_DEFIP_ALPM_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7525 { EGR_VLAN_XLATE_1_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7526 { EGR_VLAN_XLATE_2_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7527 { EXACT_MATCH_ECCm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7528 { EXACT_MATCH_ECC_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7529 7530 /* FIFO Supports only POP operation */ 7531 { CENTRAL_CTR_EVICTION_FIFOm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7532 7533 { L2_BULKm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7534 { L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7535 { MMU_THDU_UCQ_STATS_TABLEm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7536 { MMU_THDU_UCQ_STATS_TABLE_XPE0_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7537 { MMU_THDU_UCQ_STATS_TABLE_XPE0_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7538 { L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7539 7540 { L3_DEFIP_ALPM_IPV4m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7541 { L3_DEFIP_ALPM_IPV4_1m, _SOC_ACC_TYPE_PIPE_ANY, 1}, 7542 { L3_DEFIP_ALPM_IPV6_64m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7543 { L3_DEFIP_ALPM_IPV6_64_1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7544 { L3_DEFIP_ALPM_IPV6_128m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7545 { L3_DEFIP_ALPM_RAWm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7546 7547 /* 2b error in IS_TDM_CALENDAR0,1 is fatal 7548 * Allow error_injection - but not tr 144 testing 7549 */ 7550 { IS_TDM_CALENDAR0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7551 { IS_TDM_CALENDAR0_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7552 { IS_TDM_CALENDAR0_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7553 { IS_TDM_CALENDAR1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7554 { IS_TDM_CALENDAR1_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7555 { IS_TDM_CALENDAR1_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7556 7557 { TDM_CALENDAR0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7558 { TDM_CALENDAR0_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7559 { TDM_CALENDAR0_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7560 { TDM_CALENDAR1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7561 { TDM_CALENDAR1_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7562 { TDM_CALENDAR1_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7563 { MMU_CFAP_BANK0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7564 { MMU_CFAP_BANK0_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7565 { MMU_CFAP_BANK1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7566 { MMU_CFAP_BANK1_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7567 { MMU_CFAP_BANK2m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7568 { MMU_CFAP_BANK2_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7569 { MMU_CFAP_BANK3m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7570 { MMU_CFAP_BANK3_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7571 { MMU_CFAP_BANK4m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7572 { MMU_CFAP_BANK4_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7573 { MMU_CFAP_BANK5m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7574 { MMU_CFAP_BANK5_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7575 { MMU_CFAP_BANK6m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7576 { MMU_CFAP_BANK6_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7577 { MMU_CFAP_BANK7m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7578 { MMU_CFAP_BANK7_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7579 { MMU_CFAP_BANK8m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7580 { MMU_CFAP_BANK8_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7581 { MMU_CFAP_BANK9m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7582 { MMU_CFAP_BANK9_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7583 { MMU_CFAP_BANK10m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7584 { MMU_CFAP_BANK10_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7585 { MMU_CFAP_BANK11m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7586 { MMU_CFAP_BANK11_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7587 { MMU_CFAP_BANK12m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7588 { MMU_CFAP_BANK12_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7589 { MMU_CFAP_BANK13m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7590 { MMU_CFAP_BANK13_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7591 { MMU_CFAP_BANK14m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7592 { MMU_CFAP_BANK14_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7593 { MMU_CFAP_BANK15m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7594 { MMU_CFAP_BANK15_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7595 { MMU_CFAP_BANK16m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7596 { MMU_CFAP_BANK16_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7597 { MMU_CFAP_BANK17m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7598 { MMU_CFAP_BANK17_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7599 { MMU_CFAP_BANK18m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7600 { MMU_CFAP_BANK18_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7601 { MMU_CFAP_BANK19m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7602 { MMU_CFAP_BANK19_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7603 { MMU_CFAP_BANK20m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7604 { MMU_CFAP_BANK20_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7605 { MMU_CFAP_BANK21m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7606 { MMU_CFAP_BANK21_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7607 { MMU_CFAP_BANK22m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7608 { MMU_CFAP_BANK22_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7609 { MMU_CFAP_BANK23m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7610 { MMU_CFAP_BANK23_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7611 { MMU_CFAP_BANK24m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7612 { MMU_CFAP_BANK24_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7613 { MMU_CFAP_BANK25m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7614 { MMU_CFAP_BANK25_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7615 { MMU_CFAP_BANK26m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7616 { MMU_CFAP_BANK26_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7617 { MMU_CFAP_BANK27m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7618 { MMU_CFAP_BANK27_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7619 { MMU_CFAP_BANK28m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7620 { MMU_CFAP_BANK28_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7621 { MMU_CFAP_BANK29m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7622 { MMU_CFAP_BANK29_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7623 { MMU_CFAP_BANK30m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7624 { MMU_CFAP_BANK30_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7625 { MMU_CFAP_BANK31m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7626 { MMU_CFAP_BANK31_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7627 { REPLICATION_FIFO_BANK0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7628 { REPLICATION_FIFO_BANK0_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7629 { REPLICATION_FIFO_BANK0_XPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7630 { REPLICATION_FIFO_BANK1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7631 { REPLICATION_FIFO_BANK1_XPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7632 { REPLICATION_FIFO_BANK1_XPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7633 { MMU_ENQS_PBI_DBm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7634 { MMU_ENQS_PBI_DB_SED0_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7635 { MMU_ENQS_PBI_DB_SED0_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7636 { MMU_ENQS_PBI_DB_SED1_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7637 { MMU_ENQS_PBI_DB_SED1_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7638 { RH_ECMP_FLOWSETm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7639 { RH_ECMP_FLOWSET_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7640 { RH_ECMP_FLOWSET_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7641 { RH_HGT_FLOWSETm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7642 { RH_HGT_FLOWSET_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7643 { RH_HGT_FLOWSET_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7644 { RH_LAG_FLOWSETm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7645 { RH_LAG_FLOWSET_PIPE0m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7646 { RH_LAG_FLOWSET_PIPE1m, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7647 #ifdef BCM_HELIX5_SUPPORT 7648 /* Read-only memory */ 7649 { BSC_AG_AGE_TABLEm , _SOC_ACC_TYPE_PIPE_ANY, 0 }, 7650 7651 /* Not cached and SER_RESPONSE => NONE */ 7652 { BSC_DT_FLEX_SESSION_DATA_SINGLEm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7653 { BSC_DT_FLEX_SESSION_DATA_DOUBLEm, _SOC_ACC_TYPE_PIPE_ANY, 1 }, 7654 #endif 7655 7656 /* End */ 7657 { INVALIDm } 7658 }; 7659 7660 STATIC soc_acc_type_t 7661 _soc_trident3_pipe_to_acc_type(int pipe) 7662 { 7663 soc_acc_type_t rv; 7664 switch (pipe) { 7665 case SOC_PIPE_SELECT_ANY: 7666 case SOC_PIPE_SELECT_0: rv = _SOC_UNIQUE_ACC_TYPE_PIPE_0; break; 7667 case SOC_PIPE_SELECT_1: rv = _SOC_UNIQUE_ACC_TYPE_PIPE_1; break; 7668 default: rv =_SOC_ACC_TYPE_PIPE_ALL; break; 7669 } 7670 return rv; 7671 /* For TD3, ONLY possible values of test_data->acc_type 7672 * are: ACC_TYPE_PIPE_0, 1, ALL 7673 */ 7674 } 7675 7676 STATIC soc_pipe_select_t 7677 _soc_trident3_acc_type_to_pipe(soc_acc_type_t acc_type) 7678 { 7679 soc_pipe_select_t rv; 7680 switch (acc_type) { 7681 case _SOC_UNIQUE_ACC_TYPE_PIPE_0: rv = SOC_PIPE_SELECT_0; break; 7682 case _SOC_UNIQUE_ACC_TYPE_PIPE_1: rv = SOC_PIPE_SELECT_1; break; 7683 case _SOC_ACC_TYPE_PIPE_ANY: rv = SOC_PIPE_SELECT_ANY; break; 7684 default: rv = SOC_PIPE_SELECT_ALL; break; 7685 } 7686 return rv; 7687 } 7688 7689 int 7690 soc_trident3_pipe_select(int unit, int egress, int pipe) 7691 { 7692 soc_reg_t reg; 7693 7694 reg = egress ? EGR_SBS_CONTROLr : SBS_CONTROLr; 7695 if ((pipe >= 0) && (pipe <= 1)) { 7696 return soc_reg_field32_modify(unit, reg, REG_PORT_ANY, PIPE_SELECTf, 7697 pipe); 7698 } else { 7699 return soc_reg_field32_modify(unit, reg, REG_PORT_ANY, PIPE_SELECTf, 0); 7700 } 7701 } 7702 7703 soc_error_t 7704 soc_td3_ser_parity_control_reg_set(int unit, ser_test_data_t *test_data, int enable) 7705 { 7706 7707 uint32 rval; 7708 uint64 regData; 7709 7710 SOC_IF_ERROR_RETURN 7711 (soc_reg32_get(unit, test_data->parity_enable_reg, test_data->port, 0, 7712 &rval)); 7713 LOG_VERBOSE(BSL_LS_SOC_SER, 7714 (BSL_META_U(unit, 7715 "soc_td3_ser_parity_control_reg_set READ: reg %s, rval_rdat = 0x%x, bit %d \n"), 7716 SOC_REG_NAME(unit, test_data->parity_enable_reg), 7717 rval, 7718 test_data->tcam_parity_bit 7719 )); 7720 if (enable) { 7721 rval |= (1 << test_data->tcam_parity_bit); 7722 } else { 7723 rval &= ~(1 << test_data->tcam_parity_bit); 7724 } 7725 LOG_VERBOSE(BSL_LS_SOC_SER, 7726 (BSL_META_U(unit, 7727 "soc_td3_ser_parity_control_reg_set WROTE: reg %s, rval_wdat = 0x%x, bit %d \n"), 7728 SOC_REG_NAME(unit, test_data->parity_enable_reg), 7729 rval, 7730 test_data->tcam_parity_bit 7731 )); 7732 COMPILER_64_SET(regData, 0, rval); 7733 return soc_reg_set(unit, test_data->parity_enable_reg, test_data->port, 0, 7734 regData); 7735 } 7736 7737 STATIC soc_error_t 7738 _ser_td3_ser_support_mem_found(int unit, soc_mem_t mem, 7739 _soc_mem_ser_en_info_t *ser_info_list) 7740 { 7741 int i = 0; 7742 7743 for (i = 0; ser_info_list[i].mem != INVALIDm; i++) { 7744 if ((ser_info_list[i].mem == mem) && 7745 (soc_mem_index_count(unit, mem))) { 7746 return SOC_E_NONE; /* found */ 7747 } 7748 } 7749 7750 return SOC_E_UNAVAIL; 7751 } 7752 7753 soc_error_t 7754 soc_td3_ser_error_injection_support(int unit, soc_mem_t mem, 7755 int pipe_target) 7756 { 7757 int rv = SOC_E_UNAVAIL; 7758 int i, p; 7759 _soc_td3_tcam_wrapper_info_t *tcams = _soc_td3_tcam_wrapper_table; 7760 soc_acc_type_t soc_acc_type_target = 7761 _soc_trident3_pipe_to_acc_type(pipe_target); 7762 7763 if (!SOC_MEM_IS_VALID(unit, mem) || 7764 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) { 7765 LOG_ERROR(BSL_LS_SOC_SER, 7766 (BSL_META_U(unit, 7767 "unit %d, mem %s is INVALID or not valid " 7768 "or parity is disabled for this mem !!\n"), 7769 unit, SOC_MEM_NAME(unit,mem))); 7770 return rv; 7771 } 7772 7773 /* Check if memory is listed in skipped mems structure */ 7774 for (i = 0; td3_skipped_mems[i].mem != INVALIDm; i++) { 7775 if ((td3_skipped_mems[i].mem == mem) && 7776 ((_SOC_ACC_TYPE_PIPE_ANY == td3_skipped_mems[i].acc_type) || 7777 (td3_skipped_mems[i].acc_type == soc_acc_type_target))) { 7778 if (td3_skipped_mems[i].allow_error_inj) { 7779 return SOC_E_NONE; 7780 } else { 7781 return rv; 7782 } 7783 } 7784 } 7785 7786 /* Search TCAMs */ 7787 for (i = 0; tcams[i].mem != INVALIDm; i++) { 7788 if(!SOC_REG_FIELD_VALID(unit, tcams[i].enable_reg, tcams[i].enable_field)) { 7789 continue; 7790 } 7791 if (tcams[i].mem == mem) { 7792 return SOC_E_NONE; /* found */ 7793 } 7794 if (SOC_MEM_UNIQUE_ACC(unit, tcams[i].mem) != NULL) { 7795 for (p = 0; p < NUM_PIPE(unit); p++) { 7796 if (SOC_MEM_UNIQUE_ACC(unit, tcams[i].mem)[p] == mem) { 7797 return SOC_E_NONE; /* found */ 7798 } 7799 } 7800 } 7801 } 7802 7803 /* Search for mems listed in: 7804 * _soc_bcm56870_a0_ip_mem_ser_info, 7805 * _soc_bcm56870_a0_ep_mem_ser_info, 7806 * _soc_bcm56870_a0_mmu_mem_ser_info, 7807 */ 7808 rv = _ser_td3_ser_support_mem_found(unit, mem, SOC_IP_MEM_SER_INFO(unit)); 7809 if(rv == SOC_E_NONE) { 7810 return rv; 7811 } 7812 rv = _ser_td3_ser_support_mem_found(unit, mem, SOC_EP_MEM_SER_INFO(unit)); 7813 if(rv == SOC_E_NONE) { 7814 return rv; 7815 } 7816 rv = _ser_td3_ser_support_mem_found(unit, mem, SOC_MMU_MEM_SER_INFO(unit)); 7817 if(rv == SOC_E_NONE) { 7818 return rv; 7819 } 7820 7821 return rv; 7822 } 7823 7824 soc_error_t 7825 soc_td3_ser_correction_info_get(int unit, 7826 ser_correction_info_t *corr_info) 7827 { 7828 if (!SOC_MEM_IS_VALID(unit, corr_info->inject_mem)) { 7829 LOG_ERROR(BSL_LS_SOC_SER, 7830 (BSL_META_U(unit, 7831 "unit %d, mem %d is INVALID or not valid " 7832 "for this unit !!\n"), 7833 unit, corr_info->inject_mem)); 7834 return SOC_E_UNAVAIL; 7835 } 7836 switch (corr_info->inject_mem) { 7837 /* compare index only */ 7838 case VLAN_MACm: 7839 case VLAN_XLATEm: 7840 case EGR_VLAN_XLATEm: 7841 case MPLS_ENTRYm: 7842 case MODPORT_MAP_M0m: 7843 case MODPORT_MAP_M1m: 7844 case MODPORT_MAP_M2m: 7845 case MODPORT_MAP_M3m: 7846 case L2_ENTRY_TILEm: 7847 case L2_ENTRY_ONLY_TILEm: 7848 case L3_ENTRY_ONLYm: 7849 case L3_ENTRY_IPV4_UNICASTm: 7850 corr_info->compare_mem = 0; 7851 corr_info->compare_index = 1; 7852 break; 7853 7854 /* must NOT compare view or index */ 7855 case L3_ENTRY_IPV4_MULTICASTm: 7856 case L3_ENTRY_IPV6_UNICASTm: 7857 case L3_ENTRY_IPV6_MULTICASTm: 7858 case L3_DEFIP_ALPM_IPV4m: 7859 case L3_DEFIP_ALPM_IPV4_1m: 7860 case L3_DEFIP_ALPM_IPV6_64m: 7861 case L3_DEFIP_ALPM_IPV6_64_1m: 7862 case L3_DEFIP_ALPM_IPV6_128m: 7863 case L3_DEFIP_ALPM_RAWm: 7864 case EXACT_MATCH_2m: 7865 case EXACT_MATCH_2_ENTRY_ONLYm: 7866 case EXACT_MATCH_4m: 7867 case EXACT_MATCH_4_ENTRY_ONLYm: 7868 case FPEM_LPm: 7869 corr_info->compare_mem = 0; 7870 corr_info->compare_index = 0; 7871 break; 7872 7873 /* can compare both view and index */ 7874 default: 7875 corr_info->compare_mem = 1; 7876 corr_info->compare_index = 1; 7877 break; 7878 } 7879 7880 LOG_VERBOSE(BSL_LS_SOC_SER, 7881 (BSL_META_U(unit, 7882 "==== predict: mem = %s, " 7883 "compare_mem,index = %d,%d\n"), 7884 SOC_MEM_NAME(unit, corr_info->inject_mem), 7885 corr_info->compare_mem, 7886 corr_info->compare_index)); 7887 7888 return SOC_E_NONE; 7889 } 7890 7891 typedef struct ser_td3_mems_test_field_s { 7892 soc_mem_t mem; 7893 soc_acc_type_t acc_type; 7894 soc_field_t test_field; 7895 } ser_td3_mems_test_field_t; 7896 7897 const ser_td3_mems_test_field_t td3_mems_test_field[] = { 7898 /* mem with acc_type=data_split, has separate parity field for each pipe */ 7899 { EGR_VLAN_STGm, _SOC_UNIQUE_ACC_TYPE_PIPE_0, ECCP0f }, 7900 { EGR_VLAN_STGm, _SOC_UNIQUE_ACC_TYPE_PIPE_1, ECCP2f }, 7901 { EGR_VLAN_VFI_MEMBERSHIPm, _SOC_UNIQUE_ACC_TYPE_PIPE_0, ECCP0f }, 7902 { EGR_VLAN_VFI_MEMBERSHIPm, _SOC_UNIQUE_ACC_TYPE_PIPE_1, ECCP1f }, 7903 { EGR_VLAN_VFI_UNTAGm, _SOC_UNIQUE_ACC_TYPE_PIPE_0, ECCP0f }, 7904 { EGR_VLAN_VFI_UNTAGm, _SOC_UNIQUE_ACC_TYPE_PIPE_1, ECCP1f }, 7905 7906 /* mem with acc_type=data_split, has separate parity field for each pipe */ 7907 { SRC_MODID_INGRESS_BLOCKm, _SOC_UNIQUE_ACC_TYPE_PIPE_0, ECCP_P0f }, 7908 { SRC_MODID_INGRESS_BLOCKm, _SOC_UNIQUE_ACC_TYPE_PIPE_1, ECCP_P1f }, 7909 7910 { ING_L3_NEXT_HOPm, _SOC_ACC_TYPE_PIPE_ANY, ECC_1f}, 7911 7912 { INVALIDm, _SOC_ACC_TYPE_PIPE_ANY, INVALIDf } 7913 }; 7914 7915 STATIC void 7916 _soc_td3_ser_find_test_field(int unit, soc_mem_t mem, 7917 soc_acc_type_t soc_acc_type_target, 7918 soc_field_t *test_field) 7919 { 7920 int i; 7921 for (i = 0; td3_mems_test_field[i].mem != INVALIDm; i++) { 7922 if ((td3_mems_test_field[i].mem == mem) && 7923 ((td3_mems_test_field[i].acc_type == soc_acc_type_target) || 7924 (td3_mems_test_field[i].acc_type == _SOC_ACC_TYPE_PIPE_ANY)) 7925 ) { 7926 if (!SOC_MEM_FIELD_VALID(unit, mem, td3_mems_test_field[i].test_field)) { 7927 continue; 7928 } 7929 *test_field = td3_mems_test_field[i].test_field; 7930 LOG_VERBOSE(BSL_LS_SOC_SER, 7931 (BSL_META_U(unit, 7932 "===== Selected field %s for Memory %s \n"), 7933 SOC_FIELD_NAME(unit, *test_field), 7934 SOC_MEM_NAME(unit,mem))); 7935 break; 7936 } 7937 } 7938 return; 7939 } 7940 7941 /* 7942 * Function: 7943 * _soc_trident3_perform_ser_test 7944 * Purpose: 7945 * Performs test operations common to TCAM and FIFO memory tests before 7946 * invoking common SER test. 7947 * Parameters: 7948 * unit - (IN) Device Number 7949 * test_data - (IN) Test data required for SER test 7950 * test_type - (IN) How many indices to test for each memory 7951 * mem_failed - (OUT) Incremented when memories fail the test. 7952 * Returns: 7953 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors are 7954 * possible.) 7955 */ 7956 STATIC soc_error_t 7957 _soc_trident3_perform_ser_test(int unit, uint32 flags, ser_test_data_t *test_data, 7958 _soc_ser_test_t test_type, 7959 int *mem_skipped, int *mem_failed) 7960 { 7961 int k, skip_mem = FALSE; 7962 soc_error_t rv = SOC_E_NONE; 7963 soc_pipe_select_t pipe_target; 7964 uint32 mem_acc_type; 7965 7966 if (!SOC_MEM_IS_VALID(unit, test_data->mem_fv)) { 7967 LOG_ERROR(BSL_LS_SOC_SER, 7968 (BSL_META_U(unit, 7969 "unit %d, mem %d is INVALID or not valid " 7970 "for this unit !!\n"), 7971 unit, test_data->mem_fv)); 7972 skip_mem = TRUE; 7973 } 7974 for (k = 0; td3_skipped_mems[k].mem != INVALIDm; k++) { 7975 if ((td3_skipped_mems[k].mem == test_data->mem_fv) && 7976 ((_SOC_ACC_TYPE_PIPE_ANY == td3_skipped_mems[k].acc_type) || 7977 (td3_skipped_mems[k].acc_type == test_data->acc_type))) { 7978 skip_mem = TRUE; 7979 break; 7980 } 7981 } 7982 /* skip mems for which SW does not need to do error correction */ 7983 if (!(SOC_MEM_INFO(unit, test_data->mem_fv).flags & SOC_MEM_SER_FLAGS)) { 7984 LOG_VERBOSE(BSL_LS_SOC_SER, 7985 (BSL_META_U(unit, 7986 "SOC_MEM_SER_FLAGS is not set for %s " 7987 "(flags 0x%8x). Skipping.\n"), 7988 SOC_MEM_NAME(unit, test_data->mem_fv), 7989 SOC_MEM_INFO(unit,test_data->mem_fv).flags)); 7990 skip_mem = TRUE; 7991 } 7992 /* skip mems which could be of 0 depth due to config properties */ 7993 /* coverity[overrun-call] */ 7994 if (!soc_mem_index_count(unit, test_data->mem_fv)) { 7995 LOG_VERBOSE(BSL_LS_SOC_SER, 7996 (BSL_META_U(unit, 7997 "Index_Count is 0 for %s (flags 0x%8x). Skipping.\n"), 7998 SOC_MEM_NAME(unit, test_data->mem_fv), 7999 SOC_MEM_INFO(unit,test_data->mem_fv).flags)); 8000 skip_mem = TRUE; 8001 } 8002 /* skip mems which have addr_split */ 8003 mem_acc_type = SOC_MEM_ACC_TYPE(unit, test_data->mem_fv); 8004 if ((mem_acc_type == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_DIST) || 8005 (mem_acc_type == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_SPLIT)) { 8006 LOG_VERBOSE(BSL_LS_SOC_SER, 8007 (BSL_META_U(unit, 8008 "Memory %s has acc_type ADDR_SPLIT (%0d) \n"), 8009 SOC_MEM_NAME(unit,test_data->mem_fv), mem_acc_type)); 8010 /* skip_mem = TRUE; */ 8011 } 8012 8013 if (!skip_mem) { 8014 pipe_target = _soc_trident3_acc_type_to_pipe(test_data->acc_type); 8015 _soc_td3_ser_find_test_field(unit, test_data->mem_fv, test_data->acc_type, 8016 &test_data->test_field); 8017 soc_trident3_pipe_select(unit, TRUE, pipe_target); 8018 soc_trident3_pipe_select(unit, FALSE, pipe_target); 8019 /* 8020 if (_soc_td3_check_counter_with_ecc(unit, test_data->mem_fv)) { 8021 flags = flags | SOC_INJECT_ERROR_2BIT_ECC; 8022 } 8023 */ 8024 rv = ser_test_mem(unit, flags, test_data, test_type, mem_failed); 8025 if (SOC_FAILURE(rv)) { 8026 LOG_VERBOSE(BSL_LS_SOC_SER, 8027 (BSL_META_U(unit, 8028 "===== ser_test for Memory %s, Acc_type %d FAILED !!" 8029 " \n"), 8030 SOC_MEM_NAME(unit,test_data->mem_fv), test_data->acc_type)); 8031 } else { 8032 LOG_VERBOSE(BSL_LS_SOC_SER, 8033 (BSL_META_U(unit, 8034 "===== ser_test for Memory %s, Acc_type %d PASSED !!" 8035 " \n"), 8036 SOC_MEM_NAME(unit,test_data->mem_fv), test_data->acc_type)); 8037 } 8038 soc_trident3_pipe_select(unit, TRUE, 0); 8039 soc_trident3_pipe_select(unit, FALSE, 0); 8040 } else { 8041 LOG_VERBOSE(BSL_LS_SOC_SER, 8042 (BSL_META_U(unit, 8043 "===== ser_test for Memory %s, Acc_type %d " 8044 "SKIPPED \n"), 8045 SOC_MEM_NAME(unit,test_data->mem_fv), test_data->acc_type)); 8046 (*mem_skipped)++; 8047 } 8048 return rv; 8049 } 8050 8051 STATIC int 8052 _soc_td3_refresh_modify(int unit, int enable) { 8053 struct { 8054 soc_reg_t ref_reg; 8055 soc_field_t en_field; 8056 } rf_list[] = { 8057 {AUX_ARB_CONTROLr, FP_REFRESH_ENABLEf}, 8058 {EFP_METER_CONTROLr, EFP_REFRESH_ENABLEf}, 8059 {MMU_GCFG_MISCCONFIGr, REFRESH_ENf}, 8060 {INVALIDr, INVALIDf} 8061 }; 8062 uint32 rval; 8063 int i; 8064 for (i = 0; rf_list[i].ref_reg != INVALIDr; i++) { 8065 if (!SOC_REG_IS_VALID(unit, rf_list[i].ref_reg)) { 8066 continue; 8067 } 8068 SOC_IF_ERROR_RETURN 8069 (soc_reg32_get(unit, rf_list[i].ref_reg, REG_PORT_ANY, 0, &rval)); 8070 soc_reg_field_set(unit, rf_list[i].ref_reg, &rval, rf_list[i].en_field, 8071 enable ? 1 : 0); 8072 SOC_IF_ERROR_RETURN 8073 (soc_reg32_set(unit, rf_list[i].ref_reg, REG_PORT_ANY, 0, rval)); 8074 } 8075 return SOC_E_NONE; 8076 } 8077 8078 soc_error_t 8079 soc_td3_test_mem_create(int unit, soc_mem_t mem, int block, int index, 8080 uint32 *flags, soc_acc_type_t soc_acc_type_target, 8081 uint32 * tmp_entry, uint32 * field_data, 8082 ser_test_data_t * p_test_data, 8083 _soc_mem_ser_en_info_t *ser_info_list) 8084 { 8085 int i = 0 ,found_mem = FALSE; 8086 soc_field_t test_field = INVALIDf; 8087 int mem_has_ecc = 0; 8088 soc_mem_t en_mem; 8089 soc_reg_t en_reg; 8090 8091 for (i = 0; ser_info_list[i].mem != INVALIDm; i++) { 8092 if ((ser_info_list[i].mem == mem) && 8093 (soc_mem_index_count(unit, mem))) { 8094 test_field = ECCf; 8095 _soc_td3_ser_find_test_field(unit, mem, soc_acc_type_target, 8096 &test_field); 8097 8098 en_reg = ser_info_list[i].en_ctrl.flag_reg_mem ? INVALIDr : 8099 ser_info_list[i].en_ctrl.ctrl_type.en_reg; 8100 en_mem = ser_info_list[i].en_ctrl.flag_reg_mem ? 8101 ser_info_list[i].en_ctrl.ctrl_type.en_mem : INVALIDm; 8102 soc_ser_create_test_data_with_new_format(unit, tmp_entry, field_data, 8103 en_reg, 8104 en_mem, 8105 SOC_INVALID_TCAM_PARITY_BIT, 8106 ser_info_list[i].en_ctrl.en_fld, 8107 ser_info_list[i].en_ctrl.en_fld_position, 8108 mem, test_field, block, 8109 REG_PORT_ANY, 8110 soc_acc_type_target, 8111 index, p_test_data); 8112 found_mem = TRUE; 8113 if ((SOC_REG_IS_VALID(unit, ser_info_list[i].ecc1b_ctrl.ctrl_type.en_reg) || 8114 SOC_MEM_IS_VALID(unit, ser_info_list[i].ecc1b_ctrl.ctrl_type.en_mem)) && 8115 (INVALIDf != ser_info_list[i].ecc1b_ctrl.en_fld)) { 8116 *flags |= SOC_INJECT_ERROR_2BIT_ECC; 8117 } 8118 8119 SOC_IF_ERROR_RETURN 8120 (ser_test_mem_index_remap(unit, p_test_data, &mem_has_ecc)); 8121 if (mem_has_ecc) { 8122 *flags |= SOC_INJECT_ERROR_2BIT_ECC; 8123 } 8124 break; 8125 } 8126 } 8127 8128 if (found_mem) { 8129 return SOC_E_NONE; 8130 }else { 8131 return SOC_E_UNAVAIL; 8132 } 8133 8134 } 8135 8136 /* 8137 * Function: 8138 * soc_td3_ser_inject_or_test_mem 8139 * Purpose: 8140 * Provide a common function for injecting errors and testing single 8141 * single memories 8142 * Parameters: 8143 * unit - (IN) Device Number 8144 * mem - (IN) The memory into which an error will be injected 8145 * pipeTarget - (IN) The pipe (x/y) to use when injecting the error 8146 * index - (IN) The index into which the error will be injected. 8147 * test_type - (IN) How many indices to test in the passes memory 8148 * cmd - (IN) TRUE if a command-line test is desired. 8149 * Returns: 8150 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors 8151 * are possible.) 8152 */ 8153 soc_error_t 8154 soc_td3_ser_inject_or_test_mem(int unit, soc_mem_t mem, int pipe_target, int block, 8155 int index, _soc_ser_test_t test_type, 8156 int inject_only, int cmd, uint32 flags) 8157 { 8158 uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS]; 8159 ser_test_data_t test_data; 8160 _soc_td3_tcam_wrapper_info_t *tcams = _soc_td3_tcam_wrapper_table; 8161 int i, p, error_count = 0, skip_count = 0, found_mem = FALSE; 8162 char fail_message[TR_MEM_NAME_SIZE_MAX + 1]; 8163 soc_error_t rv = SOC_E_NONE; 8164 soc_acc_type_t soc_acc_type_target, mem_acc_type; 8165 ser_correction_info_t corr_info; 8166 8167 if (!SOC_MEM_IS_VALID(unit, mem) || 8168 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) { 8169 LOG_ERROR(BSL_LS_SOC_SER, 8170 (BSL_META_U(unit, 8171 "unit %d, mem %s is INVALID or not valid " 8172 "or parity is disabled for this mem !!\n"), 8173 unit, SOC_MEM_NAME(unit,mem))); 8174 return SOC_E_UNAVAIL; 8175 } 8176 8177 mem_acc_type = SOC_MEM_ACC_TYPE(unit, mem); 8178 if (mem_acc_type <= _SOC_UNIQUE_ACC_TYPE_PIPE_1) { 8179 soc_acc_type_target = mem_acc_type; 8180 LOG_VERBOSE(BSL_LS_SOC_SER, 8181 (BSL_META_U(unit, 8182 "soc_td3_ser_inject_or_test_mem: unit %d, mem %s, " 8183 "pipe_target %d, BUT mem_acc_type %d will be " 8184 "used\n"), 8185 unit, SOC_MEM_NAME(unit, mem), 8186 pipe_target, soc_acc_type_target)); 8187 } else if ((mem_acc_type == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_DIST) || 8188 (mem_acc_type == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_SPLIT)) { 8189 /* 1. ignore pipe_target, because pipe is determined by index param 8190 * 2. For such mem, ser_en_info in bcm56870_a0.c file will not have 8191 * _PIPE0,1 views (these are created only for mems with UNIQUE 8192 * acc type. 8193 */ 8194 soc_acc_type_target = _SOC_ACC_TYPE_PIPE_ANY; 8195 } else { 8196 soc_acc_type_target = _soc_trident3_pipe_to_acc_type(pipe_target); 8197 } 8198 8199 corr_info.inject_mem = mem; 8200 soc_td3_ser_correction_info_get(unit, &corr_info); 8201 8202 /* Check if the memory is to be skipped */ 8203 for (i = 0; td3_skipped_mems[i].mem != INVALIDm; i++) { 8204 if ((td3_skipped_mems[i].mem == mem) && 8205 ((_SOC_ACC_TYPE_PIPE_ANY == td3_skipped_mems[i].acc_type) || 8206 (td3_skipped_mems[i].acc_type == soc_acc_type_target))) { 8207 /* coverity[secure_coding] */ 8208 if (inject_only && td3_skipped_mems[i].allow_error_inj) { 8209 break; 8210 } 8211 TR_TEST_MEM_PRINT(unit, fail_message, mem); 8212 return SOC_E_UNAVAIL; 8213 } 8214 } 8215 8216 /* Search for TCAM memories */ 8217 for (i = 0; tcams[i].mem != INVALIDm; i++) { 8218 if (!SOC_REG_FIELD_VALID(unit, tcams[i].enable_reg, tcams[i].enable_field)) { 8219 continue; 8220 } 8221 if (tcams[i].mem == mem) { 8222 soc_ser_create_test_data_with_new_format(unit, tmp_entry, field_data, 8223 tcams[i].enable_reg, 8224 INVALIDm, 8225 SOC_INVALID_TCAM_PARITY_BIT, 8226 tcams[i].enable_field, 8227 -1, mem, 8228 tcams[i].parity_field, block, 8229 REG_PORT_ANY, 8230 soc_acc_type_target, 8231 index, &test_data); 8232 found_mem = TRUE; 8233 break; /*A memory was found that matched, so stop searching.*/ 8234 } 8235 if (SOC_MEM_UNIQUE_ACC(unit, tcams[i].mem) != NULL) { 8236 for (p = 0; p < NUM_PIPE(unit); p++) { 8237 if (SOC_MEM_UNIQUE_ACC(unit, tcams[i].mem)[p] == mem) { 8238 /*Note: Need to confirm if the enable register's acc_type is unique, 8239 * once set the parity enable with global view whether the each pipe's enable 8240 * register can be set correctly 8241 */ 8242 soc_ser_create_test_data_with_new_format(unit, tmp_entry, 8243 field_data, 8244 tcams[i].enable_reg, 8245 INVALIDm, 8246 SOC_INVALID_TCAM_PARITY_BIT, 8247 tcams[i].enable_field, 8248 -1, mem, 8249 tcams[i].parity_field, 8250 block, REG_PORT_ANY, 8251 soc_acc_type_target, 8252 index, &test_data); 8253 found_mem = TRUE; 8254 break; /* from pipe loop */ 8255 } 8256 } 8257 } 8258 if (found_mem) { 8259 break; 8260 } 8261 } 8262 8263 /* Search for mems listed in: 8264 * _soc_bcm56870_a0_ip_mem_ser_info, 8265 * _soc_bcm56870_a0_ep_mem_ser_info 8266 */ 8267 if (!found_mem) { 8268 rv = soc_td3_test_mem_create(unit, mem, block, index, &flags, 8269 soc_acc_type_target, tmp_entry, 8270 field_data, &test_data, 8271 SOC_IP_MEM_SER_INFO(unit)); 8272 if (rv == SOC_E_NONE) { 8273 found_mem = TRUE; 8274 }else { 8275 rv = soc_td3_test_mem_create(unit, mem, block, index, &flags, 8276 soc_acc_type_target, tmp_entry, 8277 field_data, &test_data, 8278 SOC_EP_MEM_SER_INFO(unit)); 8279 if (rv == SOC_E_NONE) { 8280 found_mem = TRUE; 8281 } else { 8282 rv = soc_td3_test_mem_create(unit, mem, block, index, &flags, _SOC_ACC_TYPE_PIPE_ANY, 8283 tmp_entry, field_data, &test_data, SOC_MMU_MEM_SER_INFO(unit)); 8284 if (rv == SOC_E_NONE) { 8285 found_mem = TRUE; 8286 } 8287 } 8288 } 8289 } 8290 8291 if (found_mem) { 8292 LOG_VERBOSE(BSL_LS_SOC_SER, 8293 (BSL_META_U(unit, 8294 "soc_td3_ser_inject_or_test_mem: unit %d, mem %s, " 8295 "pipe_target %d, block %d, index %d, test_type %d, " 8296 "inject_only %d, cmd %d, flags 0x%x \n"), 8297 unit, SOC_MEM_NAME(unit, mem), 8298 pipe_target, block, index, test_type, inject_only, cmd, flags)); 8299 if (inject_only) { 8300 /* Set pipe select */ 8301 soc_trident3_pipe_select(unit, TRUE, pipe_target); 8302 soc_trident3_pipe_select(unit, FALSE, pipe_target); 8303 8304 /* Disable parity */ 8305 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0)); 8306 8307 /* Read the memory (required for successful injection) */ 8308 rv = ser_test_mem_read(unit, 0, &test_data); 8309 if (SOC_FAILURE(rv)) { 8310 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit, 8311 "soc_td3_ser_inject_or_test_mem: unit %d, Error_inject: Read for mem %s FAILED\n"), 8312 unit, SOC_MEM_NAME(unit, mem))); 8313 return rv; 8314 } 8315 8316 /* Inject error */ 8317 rv = soc_ser_test_inject_full(unit, flags, &test_data); 8318 if (SOC_FAILURE(rv)) { 8319 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit, 8320 "soc_td3_ser_inject_or_test_mem: unit %d, Error_inject: error inject for mem %s FAILED\n"), 8321 unit, SOC_MEM_NAME(unit, mem))); 8322 return rv; 8323 } 8324 8325 /* Enable parity */ 8326 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1)); 8327 8328 soc_trident3_pipe_select(unit, TRUE, 0); 8329 soc_trident3_pipe_select(unit, FALSE, 0); 8330 } else { 8331 if (cmd) { 8332 ser_test_cmd_generate(unit, &test_data); 8333 } else { 8334 int def_soc_ser_test_long_sleep; 8335 int def_soc_ser_test_long_sleep_time_us; 8336 8337 /* save default values, choose TD3 specific values */ 8338 def_soc_ser_test_long_sleep = soc_ser_test_long_sleep; 8339 def_soc_ser_test_long_sleep_time_us = soc_ser_test_long_sleep_time_us; 8340 soc_ser_test_long_sleep = TRUE; 8341 soc_ser_test_long_sleep_time_us = 8342 soc_property_get(unit, "tr144_long_sleep_time_us", 8343 _SOC_TD3_TR144_LONG_SLEEP_TIME_US); 8344 LOG_VERBOSE(BSL_LS_SOC_SER, 8345 (BSL_META_U(unit, 8346 "tr 144 test will use:long_sleep = %d," 8347 "long_sleep_time = %d uS\n"), 8348 soc_ser_test_long_sleep, 8349 soc_ser_test_long_sleep_time_us)); 8350 8351 (void) _soc_td3_refresh_modify(unit, 0); /* disable refresh */ 8352 rv = _soc_trident3_perform_ser_test(unit, flags, &test_data, test_type, 8353 &skip_count, &error_count); 8354 (void) _soc_td3_refresh_modify(unit, 1); /* re-enable refresh */ 8355 8356 /* restore default values */ 8357 soc_ser_test_long_sleep = def_soc_ser_test_long_sleep; 8358 soc_ser_test_long_sleep_time_us = def_soc_ser_test_long_sleep_time_us; 8359 8360 if (!SOC_FAILURE(rv)) { 8361 if ((error_count == 0) && !skip_count) { 8362 LOG_VERBOSE(BSL_LS_SOC_SER, 8363 (BSL_META_U(unit, 8364 "SER test PASSED for memory" 8365 "%s\n"), 8366 test_data.mem_name)); 8367 } 8368 if (skip_count !=0) { 8369 LOG_VERBOSE(BSL_LS_SOC_SER, 8370 (BSL_META_U(unit, 8371 "SER test SKIPPED for memory" 8372 "%s\n"), 8373 test_data.mem_name)); 8374 } 8375 } 8376 } 8377 } 8378 } else { 8379 TR_TEST_MEM_PRINT(unit, fail_message, mem); 8380 rv = SOC_E_UNAVAIL; 8381 } 8382 return rv; 8383 } 8384 8385 /* 8386 * Function: 8387 * soc_td3_ser_inject_error 8388 * Purpose: 8389 * Injects an error into a single td3 memory 8390 * Parameters: 8391 * unit - (IN) Device Number 8392 * mem - (IN) The memory into which an error will be injected 8393 * pipeTarget - (IN) The pipe to use when injecting the error 8394 * index - (IN) The index into which the error will be injected. 8395 */ 8396 STATIC soc_error_t 8397 soc_td3_ser_inject_error(int unit, uint32 flags, soc_mem_t mem, int pipe_target, 8398 int block, int index) 8399 { 8400 return soc_td3_ser_inject_or_test_mem(unit, mem, pipe_target, block, index, 8401 SER_SINGLE_INDEX, TRUE, FALSE, flags); 8402 } 8403 8404 /* 8405 * Function: 8406 * soc_td3_ser_test_mem 8407 * Purpose: 8408 * Perform SER test on a single memory, or generate a test the user can 8409 * enter by the command line. 8410 * Parameters: 8411 * unit - (IN) Device Number 8412 * mem - (IN) The memory into which an error will be injected 8413 * test_type - (IN) How many indices to test in the passes memory 8414 * cmd - (IN) TRUE if a command-line test is desired. 8415 * Returns: 8416 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors 8417 * are possible.) 8418 */ 8419 STATIC soc_error_t 8420 soc_td3_ser_test_mem(int unit, soc_mem_t mem, _soc_ser_test_t test_type, 8421 int cmd) 8422 { 8423 return soc_td3_ser_inject_or_test_mem(unit, mem, -1, MEM_BLOCK_ANY, 0, 8424 test_type, FALSE, cmd, FALSE); 8425 } 8426 8427 /* 8428 * Function: 8429 * soc_td3_ser_tcam_test 8430 * Purpose: 8431 * Tests that SER is working for fifo and SRAM memories 8432 * Parameters: 8433 * unit - (IN) Device Number 8434 * test_type - (IN) How many indices to test for each memory 8435 * Returns: 8436 * the number of tests which are failed 8437 */ 8438 STATIC int 8439 soc_td3_ser_tcam_test(int unit, _soc_ser_test_t test_type) 8440 { 8441 uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS]; 8442 ser_test_data_t test_data; 8443 int mem_failed = 0, mem_tests = 0, mem_skipped = 0; 8444 int i; 8445 int mem_index = 0; /* dont_care */ 8446 soc_acc_type_t wrapper_at; 8447 8448 for (i = 0; _soc_td3_tcam_wrapper_table[i].mem != INVALIDm; i++) { 8449 if(!SOC_REG_FIELD_VALID(unit, _soc_td3_tcam_wrapper_table[i].enable_reg, 8450 _soc_td3_tcam_wrapper_table[i].enable_field)) { 8451 continue; 8452 } 8453 for (wrapper_at = _SOC_UNIQUE_ACC_TYPE_PIPE_0; 8454 wrapper_at < NUM_PIPE(unit); 8455 wrapper_at++) { 8456 mem_tests++; 8457 if (!SOC_MEM_IS_VALID(unit, _soc_td3_tcam_wrapper_table[i].mem) || 8458 (SOC_MEM_INFO(unit, _soc_td3_tcam_wrapper_table[i].mem).flags & 8459 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) { 8460 LOG_WARN(BSL_LS_SOC_SER, 8461 (BSL_META_U(unit, 8462 "unit %d, mem %s is INVALID or not valid " 8463 "or parity is disabled for this mem !!\n"), 8464 unit, SOC_MEM_NAME(unit, _soc_td3_tcam_wrapper_table[i].mem))); 8465 mem_skipped++; 8466 continue; 8467 } 8468 8469 soc_ser_create_test_data_with_new_format(unit, tmp_entry, field_data, 8470 _soc_td3_tcam_wrapper_table[i].enable_reg, 8471 INVALIDm, SOC_INVALID_TCAM_PARITY_BIT, 8472 _soc_td3_tcam_wrapper_table[i].enable_field, 8473 -1, _soc_td3_tcam_wrapper_table[i].mem, 8474 _soc_td3_tcam_wrapper_table[i].parity_field, 8475 MEM_BLOCK_ANY, REG_PORT_ANY, 8476 wrapper_at, 8477 mem_index, &test_data); 8478 8479 _soc_trident3_perform_ser_test(unit, 0, &test_data, test_type, 8480 &mem_skipped, &mem_failed); 8481 } 8482 } 8483 8484 LOG_CLI((BSL_META_U(unit, "\nTCAM memories tested on unit %d: %d\n"), 8485 unit, mem_tests - mem_skipped)); 8486 LOG_CLI((BSL_META_U(unit, "TCAM tests passed:\t%d\n"), 8487 mem_tests - mem_failed - mem_skipped)); 8488 LOG_VERBOSE(BSL_LS_SOC_SER, 8489 (BSL_META_U(unit, "TCAM tests skipped:\t%d \n"), 8490 0)); 8491 LOG_CLI((BSL_META_U(unit, "TCAM tests failed:\t%d\n\n"), mem_failed)); 8492 return mem_failed; 8493 } 8494 8495 STATIC int 8496 soc_td3_ser_block_test(int unit, _soc_ser_test_t test_type, 8497 int *p_mem_failed, int *p_mem_tests, int *p_mem_skipped, 8498 _soc_mem_ser_en_info_t *ser_info_list, soc_block_t blocktype) 8499 { 8500 uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS]; 8501 ser_test_data_t test_data; 8502 int num_inst_to_test = 0; 8503 int i; 8504 uint32 mem_acc_type, flags = 0; 8505 soc_acc_type_t acc_type; 8506 int mem_index = 0; 8507 soc_mem_t en_mem = INVALIDm; 8508 soc_reg_t en_reg = INVALIDr; 8509 #if defined(_SER_DBG_EXIT_ON_FIRST_FAILURE) 8510 int rv = SOC_E_NONE; 8511 #endif 8512 8513 for (i = 0; ser_info_list[i].mem != INVALIDm; i++) { 8514 if (!SOC_MEM_IS_VALID(unit, ser_info_list[i].mem) || 8515 !soc_mem_index_count(unit, ser_info_list[i].mem) || 8516 (SOC_MEM_INFO(unit, ser_info_list[i].mem).flags & 8517 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) { 8518 LOG_VERBOSE(BSL_LS_SOC_SER, 8519 (BSL_META_U(unit, 8520 "unit %d, mem %s is INVALID or not valid " 8521 "or parity is disabled for this mem !!\n"), 8522 unit, SOC_MEM_NAME(unit, ser_info_list[i].mem))); 8523 continue; 8524 } 8525 flags = 0; /* for every mem */ 8526 mem_acc_type = SOC_MEM_ACC_TYPE(unit, ser_info_list[i].mem); 8527 if (blocktype == SOC_BLK_MMU_GLB) { 8528 num_inst_to_test = 1; 8529 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 8530 } else if (mem_acc_type <= _SOC_UNIQUE_ACC_TYPE_PIPE_1) { 8531 num_inst_to_test = 1; 8532 acc_type = mem_acc_type; 8533 } else if ((mem_acc_type == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_DIST) || 8534 (mem_acc_type == _SOC_TD3_ACC_TYPE_ADDR_SPLIT_SPLIT)) { 8535 /* 8536 * For such mems, pipe is determined by address. 8537 * Ideally, we want to test all 4 pipes, but as 8538 * simplification, we may test only 3 instances if tr test 8539 * is being run with T=spread option (because addr=0 means 8540 * pipe0, addr=last means pipe3 and addr=last/2 means 8541 * pipe1/pipe2 8542 */ 8543 num_inst_to_test = 1; 8544 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 8545 } else { 8546 /* test all instances */ 8547 num_inst_to_test = NUM_PIPE(unit); 8548 acc_type = _SOC_UNIQUE_ACC_TYPE_PIPE_0; 8549 } 8550 *p_mem_tests += num_inst_to_test; 8551 test_data.test_field = ECCf; 8552 en_reg = ser_info_list[i].en_ctrl.flag_reg_mem ? INVALIDr : 8553 ser_info_list[i].en_ctrl.ctrl_type.en_reg; 8554 en_mem = ser_info_list[i].en_ctrl.flag_reg_mem ? 8555 ser_info_list[i].en_ctrl.ctrl_type.en_mem : INVALIDm; 8556 soc_ser_create_test_data_with_new_format(unit, tmp_entry, field_data, 8557 en_reg, en_mem, SOC_INVALID_TCAM_PARITY_BIT, 8558 ser_info_list[i].en_ctrl.en_fld, 8559 ser_info_list[i].en_ctrl.en_fld_position, 8560 ser_info_list[i].mem, 8561 test_data.test_field, MEM_BLOCK_ANY, 8562 REG_PORT_ANY, acc_type, mem_index, 8563 &test_data); 8564 if (test_data.mem_info == NULL) { 8565 *p_mem_skipped += num_inst_to_test; 8566 LOG_VERBOSE(BSL_LS_SOC_SER, 8567 (BSL_META_U(unit, 8568 "Memory %s skipped due to lack of" 8569 " mem_info structure.\n"), 8570 SOC_MEM_NAME(unit,test_data.mem))); 8571 continue; 8572 } 8573 if (SOC_REG_IS_VALID(unit, ser_info_list[i].ecc1b_ctrl.ctrl_type.en_reg) && 8574 (INVALIDf != ser_info_list[i].ecc1b_ctrl.en_fld)) { 8575 flags |= SOC_INJECT_ERROR_2BIT_ECC; 8576 } 8577 #if defined(_SER_DBG_EXIT_ON_FIRST_FAILURE) 8578 rv = _soc_trident3_perform_ser_test(unit, flags, &test_data, test_type, 8579 p_mem_skipped, p_mem_failed); 8580 if (SOC_FAILURE(rv)) { 8581 return SOC_E_FAIL; 8582 } 8583 #else 8584 _soc_trident3_perform_ser_test(unit, flags, &test_data, test_type, 8585 p_mem_skipped, p_mem_failed); 8586 #endif 8587 if (num_inst_to_test > 1) { 8588 for (test_data.acc_type = _SOC_UNIQUE_ACC_TYPE_PIPE_0; 8589 test_data.acc_type < NUM_PIPE(unit); 8590 test_data.acc_type++) { 8591 #if defined(_SER_DBG_EXIT_ON_FIRST_FAILURE) 8592 rv = _soc_trident3_perform_ser_test(unit, flags, &test_data, 8593 test_type, 8594 p_mem_skipped, 8595 p_mem_failed); 8596 if (SOC_FAILURE(rv)) { 8597 return SOC_E_FAIL; 8598 } 8599 #else 8600 _soc_trident3_perform_ser_test(unit, flags, &test_data, 8601 test_type, 8602 p_mem_skipped, 8603 p_mem_failed); 8604 #endif 8605 } 8606 } 8607 } 8608 8609 return SOC_E_NONE; 8610 } 8611 8612 /* #define _SER_DBG_EXIT_ON_FIRST_FAILURE */ 8613 /* 8614 * Function: 8615 * soc_td3_ser_hardware_test 8616 * Purpose: 8617 * Tests that SER is working for fio and SRAM memories 8618 * Parameters: 8619 * unit - (IN) Device Number 8620 * test_type - (IN) How many indices to test for each memory 8621 * Returns: 8622 * the number of tests which are failed 8623 */ 8624 STATIC int 8625 soc_td3_ser_hardware_test(int unit, _soc_ser_test_t test_type) { 8626 int mem_failed = 0, mem_tests = 0, mem_skipped = 0; 8627 int rv = SOC_E_NONE; 8628 8629 (void) _soc_td3_refresh_modify(unit, 0); /* disable refresh */ 8630 8631 rv = soc_td3_ser_block_test(unit, test_type, &mem_failed, &mem_tests, &mem_skipped, 8632 SOC_IP_MEM_SER_INFO(unit), SOC_BLK_IPIPE); 8633 8634 8635 #if defined(_SER_DBG_EXIT_ON_FIRST_FAILURE) 8636 if (SOC_SUCCESS(rv)) 8637 #endif 8638 { 8639 rv = soc_td3_ser_block_test(unit, test_type, &mem_failed, &mem_tests, &mem_skipped, 8640 SOC_EP_MEM_SER_INFO(unit), SOC_BLK_EPIPE); 8641 } 8642 8643 #if defined(_SER_DBG_EXIT_ON_FIRST_FAILURE) 8644 if (SOC_SUCCESS(rv)) 8645 #endif 8646 { 8647 rv = soc_td3_ser_block_test(unit, test_type, &mem_failed, &mem_tests, &mem_skipped, 8648 SOC_MMU_MEM_SER_INFO(unit), SOC_BLK_MMU_GLB); 8649 } 8650 8651 if (SOC_FAILURE(rv)) { 8652 LOG_CLI((BSL_META_U(unit, "H/W memories test fail.\n"))); 8653 } else { 8654 LOG_CLI((BSL_META_U(unit, "H/W memories test success.\n"))); 8655 } 8656 8657 LOG_CLI((BSL_META_U(unit, "\nH/W memories tested on unit %d: %d\n"), 8658 unit, mem_tests - mem_skipped)); 8659 LOG_CLI((BSL_META_U(unit, "H/W tests passed:\t%d\n"), 8660 mem_tests - mem_failed - mem_skipped)); 8661 LOG_VERBOSE(BSL_LS_SOC_SER, 8662 (BSL_META_U(unit, "H/W tests skipped:\t%d \n"), 8663 0)); 8664 LOG_CLI((BSL_META_U(unit, "H/W tests failed:\t%d\n\n"), mem_failed)); 8665 (void) _soc_td3_refresh_modify(unit, 1); /* re-enable refresh */ 8666 return mem_failed; 8667 } 8668 8669 #define TD3_XLPORT_INFO 0 8670 #define TD3_CLPORT_INFO 1 8671 8672 soc_error_t 8673 soc_td3_ser_port_parity_control_check(int unit, _soc_td3_ser_info_t *info_list, int type) 8674 { 8675 int i; 8676 int match = 0; 8677 int port; 8678 soc_info_t *si = &SOC_INFO(unit); 8679 _soc_td3_ser_info_t *info; 8680 soc_reg_t reg = INVALIDr; 8681 soc_field_t field = INVALIDf; 8682 uint32 value = 0; 8683 uint32 rval = 0; 8684 uint64 rval64; 8685 uint32 total_count = 0; 8686 uint32 pass_count = 0; 8687 8688 for (i = 0; ; i++) { 8689 info = &info_list[i]; 8690 if (info->type == _SOC_TD3_PARITY_TYPE_NONE) { 8691 break; 8692 } 8693 8694 reg = info->enable_reg; 8695 field = info->enable_field; 8696 if (SOC_REG_IS_VALID(unit, reg)) { 8697 PBMP_PORT_ITER(unit, port) { 8698 if ((SOC_PBMP_MEMBER(si->management_pbm, port) && (type != TD3_XLPORT_INFO)) || 8699 (!SOC_PBMP_MEMBER(si->management_pbm, port) && (type == TD3_XLPORT_INFO))) { 8700 continue; 8701 } 8702 if (SOC_REG_IS_64(unit,reg)) { 8703 COMPILER_64_ZERO(rval64); 8704 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64)); 8705 value = soc_reg64_field32_get(unit, reg, rval64, field); 8706 } else { 8707 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 8708 value = soc_reg_field_get(unit, reg, rval, field); 8709 } 8710 if (0 == value) { 8711 match = 0; 8712 LOG_WARN(BSL_LS_SOC_SER, 8713 (BSL_META_U(unit, 8714 "parity control %s.%s is disabled !!\n"), 8715 SOC_REG_NAME(unit, reg), 8716 SOC_FIELD_NAME(unit, field))); 8717 } else { 8718 match = 1; 8719 } 8720 total_count++; 8721 if (match) { 8722 pass_count++; 8723 } 8724 } 8725 } 8726 } 8727 LOG_CLI((BSL_META_U(unit, "\nPort parity control checked on unit %d: %d\n"), 8728 unit, total_count)); 8729 LOG_CLI((BSL_META_U(unit, "Passed fields:\t%d\n"), pass_count)); 8730 LOG_CLI((BSL_META_U(unit, "Failed fields::\t%d\n\n"), (total_count - pass_count))); 8731 8732 return SOC_E_NONE; 8733 } 8734 8735 void 8736 soc_td3_ser_parity_control_check_all(int unit) 8737 { 8738 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_MEM, 8739 (void*) SOC_IP_MEM_SER_INFO(unit)); 8740 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_MEM, 8741 (void*) SOC_EP_MEM_SER_INFO(unit)); 8742 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_MEM, 8743 (void*) SOC_MMU_MEM_SER_INFO(unit)); 8744 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_REG, 8745 (void*) SOC_IP_REG_SER_INFO(unit)); 8746 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_REG, 8747 (void*) SOC_EP_REG_SER_INFO(unit)); 8748 #if defined(BCM_56870_A0) 8749 if (SOC_IS_TRIDENT3(unit)) { 8750 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUS, 8751 (void*) _soc_bcm56870_a0_ip_bus_ser_info); 8752 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUS, 8753 (void*) _soc_bcm56870_a0_ep_bus_ser_info); 8754 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUF, 8755 (void*) _soc_bcm56870_a0_ip_buffer_ser_info); 8756 (void)soc_ser_test_parity_control_check(unit, _SOC_SER_TYPE_BUF, 8757 (void*) _soc_bcm56870_a0_ep_buffer_ser_info); 8758 (void)soc_td3_ser_port_parity_control_check(unit, _soc_td3_pm_clp_ser_info, TD3_CLPORT_INFO); 8759 (void)soc_td3_ser_port_parity_control_check(unit, _soc_td3_pm_xlp_ser_info, TD3_XLPORT_INFO); 8760 } 8761 #endif 8762 8763 } 8764 8765 /* 8766 * Function: 8767 * soc_td3_ser_test 8768 * Purpose: 8769 * Tests that SER is working for all supported memories. 8770 * Parameters: 8771 * unit - (IN) Device Number 8772 * test_type - (IN) How many indices to test for each memory 8773 * Returns: 8774 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors are 8775 * possible.) 8776 */ 8777 soc_error_t 8778 soc_td3_ser_test(int unit, _soc_ser_test_t test_type) { 8779 int errors = 0; 8780 int def_soc_ser_test_long_sleep; 8781 int def_soc_ser_test_long_sleep_time_us; 8782 8783 /* save default values, choose TD3 specific values */ 8784 def_soc_ser_test_long_sleep = soc_ser_test_long_sleep; 8785 def_soc_ser_test_long_sleep_time_us = soc_ser_test_long_sleep_time_us; 8786 soc_ser_test_long_sleep = TRUE; 8787 soc_ser_test_long_sleep_time_us = 8788 soc_property_get(unit, "tr144_long_sleep_time_us", 8789 _SOC_TD3_TR144_LONG_SLEEP_TIME_US); 8790 8791 LOG_VERBOSE(BSL_LS_SOC_SER, 8792 (BSL_META_U(unit, 8793 "tr 144 test will use:long_sleep = %d," 8794 "long_sleep_time = %d uS\n"), 8795 soc_ser_test_long_sleep, 8796 soc_ser_test_long_sleep_time_us)); 8797 8798 /* Check parity controls before testing */ 8799 soc_td3_ser_parity_control_check_all(unit); 8800 /*Test TCAM memories*/ 8801 errors += soc_td3_ser_tcam_test(unit, test_type); 8802 /*Test for FIFO memories*/ 8803 errors += soc_td3_ser_hardware_test(unit, test_type); 8804 8805 /* restore default values */ 8806 soc_ser_test_long_sleep = def_soc_ser_test_long_sleep; 8807 soc_ser_test_long_sleep_time_us = def_soc_ser_test_long_sleep_time_us; 8808 8809 if (errors == 0) { 8810 return SOC_E_NONE; 8811 } else { 8812 LOG_CLI((BSL_META_U(unit, 8813 "TR 144 test failed.\n"))); 8814 return SOC_E_FAIL; 8815 } 8816 } 8817 8818 void 8819 soc_td3_ser_test_register(int unit) 8820 { 8821 /*Initialize chip-specific functions for SER testing*/ 8822 memset(&ser_trident3_test_fun, 0, sizeof(soc_ser_test_functions_t)); 8823 ser_trident3_test_fun.inject_error_f = &soc_td3_ser_inject_error; 8824 ser_trident3_test_fun.test_mem = &soc_td3_ser_test_mem; 8825 ser_trident3_test_fun.test = &soc_td3_ser_test; 8826 ser_trident3_test_fun.parity_control = &soc_td3_ser_parity_control_reg_set; 8827 ser_trident3_test_fun.injection_support = &soc_td3_ser_error_injection_support; 8828 ser_trident3_test_fun.correction_info_get = &soc_td3_ser_correction_info_get; 8829 soc_ser_test_functions_register(unit, &ser_trident3_test_fun); 8830 } 8831 8832 #endif /*defined(SER_TR_TEST_SUPPORT)*/ 8833 8834 STATIC soc_error_t 8835 _soc_td3_ser_tcam_control_reg_get(int unit, soc_mem_t mem, 8836 soc_reg_t *ser_control_reg, 8837 soc_field_t *ser_enable_field) 8838 { 8839 int i; 8840 for (i = 0; _soc_td3_tcam_wrapper_table[i].mem != INVALIDm; i++) { 8841 if(!SOC_REG_FIELD_VALID(unit, _soc_td3_tcam_wrapper_table[i].enable_reg, 8842 _soc_td3_tcam_wrapper_table[i].enable_field)) { 8843 continue; 8844 } 8845 if (_soc_td3_tcam_wrapper_table[i].mem == mem ) { 8846 *ser_control_reg = _soc_td3_tcam_wrapper_table[i].enable_reg; 8847 *ser_enable_field = _soc_td3_tcam_wrapper_table[i].enable_field; 8848 return SOC_E_NONE; /* found */ 8849 } 8850 } 8851 return SOC_E_UNAVAIL; 8852 } 8853 8854 int 8855 soc_td3_tcam_engine_enable(int unit, int enable) 8856 { 8857 uint64 config; 8858 COMPILER_64_ZERO(config); 8859 8860 if (enable) { 8861 SOC_IF_ERROR_RETURN(soc_reg_field32_modify 8862 (unit, AUX_ARB_CONTROLr, REG_PORT_ANY, FP_REFRESH_ENABLEf, 1)); 8863 8864 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, START_IDXf, 0); 8865 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, MAX_IDXf, 1023); 8866 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, OP_BLOCKf, 0); 8867 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, INTERVALf, 64); 8868 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, ENABLEf, 1); 8869 SOC_IF_ERROR_RETURN(soc_reg64_set 8870 (unit, IDB_SER_SCAN_CONFIGr, REG_PORT_ANY, 0, config)); 8871 8872 /* config EP HW ser scan engine */ 8873 COMPILER_64_ZERO(config); 8874 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, START_IDXf, 0); 8875 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, MAX_IDXf, 1023); 8876 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, OP_BLOCKf, 0); 8877 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, INTERVALf, 64); 8878 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, ENABLEf, 1); 8879 SOC_IF_ERROR_RETURN(soc_reg64_set 8880 (unit, EGR_ARB_SER_SCAN_CONFIGr, REG_PORT_ANY, 0, config)); 8881 } else { 8882 SOC_IF_ERROR_RETURN(soc_reg_field32_modify 8883 (unit, AUX_ARB_CONTROLr, REG_PORT_ANY, FP_REFRESH_ENABLEf, 0)); 8884 8885 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, START_IDXf, 0); 8886 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, MAX_IDXf, 1023); 8887 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, OP_BLOCKf, 0); 8888 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, INTERVALf, 64); 8889 soc_reg64_field32_set(unit, IDB_SER_SCAN_CONFIGr, &config, ENABLEf, 0); 8890 SOC_IF_ERROR_RETURN(soc_reg64_set 8891 (unit, IDB_SER_SCAN_CONFIGr, REG_PORT_ANY, 0, config)); 8892 8893 /* config EP HW ser scan engine */ 8894 COMPILER_64_ZERO(config); 8895 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, START_IDXf, 0); 8896 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, MAX_IDXf, 1023); 8897 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, OP_BLOCKf, 0); 8898 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, INTERVALf, 64); 8899 soc_reg64_field32_set(unit, EGR_ARB_SER_SCAN_CONFIGr, &config, ENABLEf, 0); 8900 SOC_IF_ERROR_RETURN(soc_reg64_set 8901 (unit, EGR_ARB_SER_SCAN_CONFIGr, REG_PORT_ANY, 0, config)); 8902 } 8903 8904 return SOC_E_NONE; 8905 } 8906 8907 soc_error_t 8908 soc_td3_ser_tcam_wrapper_enable(int unit, int enable) 8909 { 8910 int i; 8911 uint32 val = 0; 8912 uint64 rval64; 8913 soc_reg_t ser_control_reg; 8914 soc_field_t ser_enable_field; 8915 8916 for (i = 0; _soc_td3_tcam_wrapper_table[i].mem != INVALIDm; i++) { 8917 8918 if(!SOC_REG_FIELD_VALID(unit, _soc_td3_tcam_wrapper_table[i].enable_reg, 8919 _soc_td3_tcam_wrapper_table[i].enable_field)) { 8920 continue; 8921 } 8922 8923 if (!SOC_MEM_IS_VALID(unit, _soc_td3_tcam_wrapper_table[i].mem)) { 8924 continue; 8925 } 8926 ser_control_reg = _soc_td3_tcam_wrapper_table[i].enable_reg; 8927 ser_enable_field = _soc_td3_tcam_wrapper_table[i].enable_field; 8928 8929 if (SOC_REG_IS_64(unit,ser_control_reg)) { 8930 COMPILER_64_ZERO(rval64); 8931 SOC_IF_ERROR_RETURN 8932 (soc_reg64_get(unit, ser_control_reg, REG_PORT_ANY, 0, &rval64)); 8933 soc_reg64_field32_set(unit, ser_control_reg, &rval64, ser_enable_field, enable ? 1 : 0); 8934 SOC_IF_ERROR_RETURN 8935 (soc_reg64_set(unit, ser_control_reg, REG_PORT_ANY, 0, rval64)); 8936 } else { 8937 SOC_IF_ERROR_RETURN 8938 (soc_reg32_get(unit, ser_control_reg, REG_PORT_ANY, 0, &val)); 8939 soc_reg_field_set(unit, ser_control_reg, &val, ser_enable_field, enable ? 1 : 0); 8940 SOC_IF_ERROR_RETURN 8941 (soc_reg32_set(unit, ser_control_reg, REG_PORT_ANY, 0, val)); 8942 } 8943 } 8944 return SOC_E_NONE; 8945 } 8946 8947 #endif /* BCM_TRIDENT3_SUPPORT */ 8948