ser.c (307610B)
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 * SER common code. 8 * 9 * Common code for memory SER protection. 10 */ 11 12 #include <shared/bsl.h> 13 14 #include <sal/core/libc.h> 15 #include <sal/core/dpc.h> 16 #include <soc/drv.h> 17 #include <soc/debug.h> 18 #include <soc/util.h> 19 #include <soc/mem.h> 20 #include <soc/l2x.h> 21 #include <soc/l2u.h> 22 #include <soc/l3x.h> 23 #include <soc/dma.h> 24 #include <soc/soc_ser_log.h> 25 #include <soc/iproc.h> 26 #ifdef BCM_CMICM_SUPPORT 27 #include <soc/cmicm.h> 28 #endif 29 #ifdef BCM_CMICX_SUPPORT 30 #include <soc/intr_cmicx.h> 31 #endif 32 #ifdef BCM_TSN_SUPPORT 33 #include <bcm_int/esw/tsn_stat.h> 34 #endif /* BCM_TSN_SUPPORT */ 35 36 #if defined(BCM_TRIUMPH2_SUPPORT) 37 #include <soc/triumph2.h> 38 #include <soc/triumph.h> 39 #endif /* BCM_TRIUMPH2_SUPPORT */ 40 #if defined(BCM_TRIDENT_SUPPORT) 41 #include <soc/trident.h> 42 #endif /* BCM_TRIDENT_SUPPORT */ 43 #if defined(BCM_TRIDENT2_SUPPORT) 44 #include <soc/trident2.h> 45 #endif /* BCM_TRIDENT2_SUPPORT */ 46 #if defined(BCM_TRIUMPH3_SUPPORT) 47 #include <soc/triumph3.h> 48 #endif /* BCM_TRIUMPH3_SUPPORT */ 49 #if defined(BCM_HELIX4_SUPPORT) 50 #include <soc/helix4.h> 51 #endif /* BCM_HELIX4_SUPPORT */ 52 #if defined(BCM_KATANA_SUPPORT) 53 #include <soc/katana.h> 54 #endif /* BCM_KATANA_SUPPORT */ 55 #if defined(BCM_KATANA2_SUPPORT) 56 #include <soc/katana2.h> 57 #endif /* BCM_KATANA2_SUPPORT */ 58 #if defined(BCM_ENDURO_SUPPORT) 59 #include <soc/enduro.h> 60 #endif /* BCM_ENDURO_SUPPORT */ 61 #if defined(BCM_HURRICANE2_SUPPORT) 62 #include <soc/hurricane2.h> 63 #endif /* BCM_HURRICANE2_SUPPORT */ 64 #if defined(BCM_GREYHOUND_SUPPORT) 65 #include <soc/greyhound.h> 66 #endif /* BCM_GREYHOUND_SUPPORT */ 67 #if defined(BCM_TOMAHAWK_SUPPORT) 68 #include <soc/tomahawk.h> 69 #endif /* BCM_TOMAHAWK_SUPPORT */ 70 #if defined(BCM_TOMAHAWK2_SUPPORT) 71 #include <soc/tomahawk2.h> 72 #endif /* BCM_TOMAHAWK2_SUPPORT */ 73 #if defined(BCM_TOMAHAWK3_SUPPORT) 74 #include <soc/tomahawk3.h> 75 #endif 76 #if defined(BCM_HURRICANE3_SUPPORT) 77 #include <soc/hurricane3.h> 78 #endif /* BCM_HURRICANE3_SUPPORT */ 79 #if defined(BCM_GREYHOUND2_SUPPORT) 80 #include <soc/greyhound2.h> 81 #endif /* BCM_GREYHOUND2_SUPPORT */ 82 #if defined(BCM_APACHE_SUPPORT) 83 #include <soc/apache.h> 84 #endif /* BCM_APACHE_SUPPORT */ 85 #if defined(BCM_MONTEREY_SUPPORT) 86 #include <soc/monterey.h> 87 #endif /* BCM_MONTEREY_SUPPORT */ 88 #if defined(BCM_TRIDENT3_SUPPORT) 89 #include <soc/trident3.h> 90 #endif 91 #if defined(BCM_HELIX5_SUPPORT) 92 #include <soc/helix5.h> 93 #endif 94 #if defined(BCM_MAVERICK2_SUPPORT) 95 #include <soc/maverick2.h> 96 #endif 97 98 #if defined(BCM_XGS_SUPPORT) 99 100 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 101 #include <soc/esw/ecmp.h> 102 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 103 104 #define _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, field) \ 105 if (SOC_MEM_FIELD_VALID(unit, mem, field)) { \ 106 soc_mem_field32_set(unit, mem, entry, field, 0); \ 107 } 108 109 #define _SOC_DRV_MEM_CHK_L2_MEM(mem) \ 110 (mem == L2Xm || mem == L2_ENTRY_1m || mem == L2_ENTRY_2m) 111 112 /* Keep this size in sync with the items in the 2 lists below */ 113 #define SOC_SER_REG_CACHE_MAX 30 114 115 #define _SOC_SER_CACHE_REG_CASES \ 116 case DMVOQ_WRED_CONFIGr: \ 117 case GLOBAL_SP_WRED_CONFIGr: \ 118 case MAXBUCKETCONFIG_64r: \ 119 case MINBUCKETCONFIG_64r: \ 120 case PG_RESET_FLOOR_CELLr: \ 121 case PG_RESET_OFFSET_CELLr: \ 122 case PORT_SHARED_LIMIT_CELLr: \ 123 case PORT_SP_WRED_CONFIGr: \ 124 case S2_MAXBUCKETCONFIG_64r: \ 125 case S2_MINBUCKETCONFIG_64r: \ 126 case S3_MAXBUCKETCONFIG_64r: \ 127 case S3_MINBUCKETCONFIG_64r: \ 128 case S2_COSWEIGHTSr: \ 129 case S3_COSWEIGHTSr: \ 130 case WRED_CONFIGr: \ 131 case ING_TRILL_ADJACENCYr: \ 132 case EGR_VLAN_CONTROL_2r: \ 133 case EGR_PVLAN_EPORT_CONTROLr: \ 134 case E2EFC_CNT_SET_LIMITr: \ 135 case E2EFC_CNT_RESET_LIMITr: \ 136 case E2EFC_CNT_DISC_LIMITr: \ 137 case CPUMAXBUCKETCONFIG_64r: \ 138 case EGR_1588_LINK_DELAY_64r: \ 139 case STORM_CONTROL_METER_CONFIGr: \ 140 case EGR_SF_SRC_MODID_CHECKr: \ 141 case EGR_VLAN_CONTROL_3r: \ 142 case SFLOW_ING_THRESHOLDr: \ 143 case PG_SHARED_LIMIT_CELLr: \ 144 case EGR_VLAN_CONTROL_1r: \ 145 case EGR_IPMC_CFG2r: \ 146 147 148 #define _SOC_TH_ACC_TYPE_FOR_PIPE(pipe) \ 149 (((pipe) == 0)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_0 : \ 150 ((pipe) == 1)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_1 : \ 151 ((pipe) == 2)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_2 : \ 152 ((pipe) == 3)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_3 : \ 153 ((pipe) == 4)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_4 : \ 154 ((pipe) == 5)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_5 : \ 155 ((pipe) == 6)? _SOC_MEM_ADDR_ACC_TYPE_PIPE_6 : \ 156 _SOC_MEM_ADDR_ACC_TYPE_PIPE_7) 157 #if defined(BCM_TOMAHAWK_SUPPORT) 158 #define _SOC_TH_ACC_TYPE_DUPLICATE 9 159 #define _SOC_TH_ACC_TYPE_DUPLICATE_2 15 160 #define _SOC_TH_ACC_TYPE_DUPLICATE_4 16 161 #endif /* BCM_TOMAHAWK_SUPPORT */ 162 163 #if defined(ALPM_ENABLE) 164 #define _ALPM_LOCK(unit) \ 165 L3_LOCK(unit); \ 166 _alpm_lock = 1 167 #define _ALPM_UNLOCK(unit) \ 168 if (_alpm_lock) { \ 169 L3_UNLOCK(unit); \ 170 } 171 #else 172 #define _ALPM_LOCK(unit) 173 #define _ALPM_UNLOCK(unit) 174 #endif /* ALPM_ENABLE */ 175 176 177 #define _L2_LOCK(unit) \ 178 MEM_LOCK(unit, L2Xm); 179 180 #define _L2_UNLOCK(unit, lock) \ 181 if ((lock)) { \ 182 MEM_UNLOCK(unit, L2Xm); \ 183 } 184 185 #define _SOC_SER_NUM_EM_ENTRIES_PER_LP_ENTRY 4 186 187 #define _SOC_FPEM_EM2(pipe, mem_mode) \ 188 ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_2m \ 189 : ((pipe == 1)? EXACT_MATCH_2_PIPE1m : \ 190 (pipe == 2)? EXACT_MATCH_2_PIPE2m : \ 191 (pipe == 3)? EXACT_MATCH_2_PIPE3m : \ 192 EXACT_MATCH_2_PIPE0m)) 193 194 #define _SOC_FPEM_EM4(pipe, mem_mode) \ 195 ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_4m \ 196 : ((pipe == 1)? EXACT_MATCH_4_PIPE1m : \ 197 (pipe == 2)? EXACT_MATCH_4_PIPE2m : \ 198 (pipe == 3)? EXACT_MATCH_4_PIPE3m : \ 199 EXACT_MATCH_4_PIPE0m)) 200 201 #define _SOC_FPEM_EM2_ENTRY_ONLY(pipe, mem_mode) \ 202 ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_2_ENTRY_ONLYm \ 203 : ((pipe == 1)? EXACT_MATCH_2_ENTRY_ONLY_PIPE1m : \ 204 (pipe == 2)? EXACT_MATCH_2_ENTRY_ONLY_PIPE2m : \ 205 (pipe == 3)? EXACT_MATCH_2_ENTRY_ONLY_PIPE3m : \ 206 EXACT_MATCH_2_ENTRY_ONLY_PIPE0m)) 207 208 #define _SOC_FPEM_EM4_ENTRY_ONLY(pipe, mem_mode) \ 209 ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_4_ENTRY_ONLYm \ 210 : ((pipe == 1)? EXACT_MATCH_4_ENTRY_ONLY_PIPE1m : \ 211 (pipe == 2)? EXACT_MATCH_4_ENTRY_ONLY_PIPE2m : \ 212 (pipe == 3)? EXACT_MATCH_4_ENTRY_ONLY_PIPE3m : \ 213 EXACT_MATCH_4_ENTRY_ONLY_PIPE0m)) 214 215 #define _SOC_FPEM_ECC(pipe, mem_mode) \ 216 ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? FPEM_ECCm \ 217 : ((pipe == 1)? FPEM_ECC_PIPE1m : \ 218 (pipe == 2)? FPEM_ECC_PIPE2m : \ 219 (pipe == 3)? FPEM_ECC_PIPE3m : \ 220 FPEM_ECC_PIPE0m)) 221 222 #define _SOC_EXACT_MATCH_ECC(pipe, mem_mode) \ 223 ((mem_mode == _SOC_SER_MEM_MODE_GLOBAL)? EXACT_MATCH_ECCm \ 224 : ((pipe == 1)? EXACT_MATCH_ECC_PIPE1m : \ 225 EXACT_MATCH_ECC_PIPE0m)) 226 227 #define _SOC_MEM_CHK_FPEM_MEM(mem) \ 228 (mem == EXACT_MATCH_2m || \ 229 mem == EXACT_MATCH_2_PIPE0m || mem == EXACT_MATCH_2_PIPE1m || \ 230 mem == EXACT_MATCH_2_PIPE2m || mem == EXACT_MATCH_2_PIPE3m || \ 231 mem == EXACT_MATCH_4m || \ 232 mem == EXACT_MATCH_4_PIPE0m || mem == EXACT_MATCH_4_PIPE1m || \ 233 mem == EXACT_MATCH_4_PIPE2m || mem == EXACT_MATCH_4_PIPE3m) 234 235 static int _soc_ser_reg_cache_list[SOC_SER_REG_CACHE_MAX] = { 236 DMVOQ_WRED_CONFIGr, /* 1 */ 237 GLOBAL_SP_WRED_CONFIGr, /* 2 */ 238 MAXBUCKETCONFIG_64r, /* 3 */ 239 MINBUCKETCONFIG_64r, /* 4 */ 240 PG_RESET_FLOOR_CELLr, /* 5 */ 241 PG_RESET_OFFSET_CELLr, /* 6 */ 242 PORT_SHARED_LIMIT_CELLr, /* 7 */ 243 PORT_SP_WRED_CONFIGr, /* 8 */ 244 S2_MAXBUCKETCONFIG_64r, /* 9 */ 245 S2_MINBUCKETCONFIG_64r, /* 10 */ 246 S3_MAXBUCKETCONFIG_64r, /* 11 */ 247 S3_MINBUCKETCONFIG_64r, /* 12 */ 248 S2_COSWEIGHTSr, /* 13 */ 249 S3_COSWEIGHTSr, /* 14 */ 250 WRED_CONFIGr, /* 15 */ 251 ING_TRILL_ADJACENCYr, /* 16 */ 252 EGR_VLAN_CONTROL_2r, /* 17 */ 253 EGR_PVLAN_EPORT_CONTROLr, /* 18 */ 254 E2EFC_CNT_SET_LIMITr, /* 19 */ 255 E2EFC_CNT_RESET_LIMITr, /* 20 */ 256 E2EFC_CNT_DISC_LIMITr, /* 21 */ 257 CPUMAXBUCKETCONFIG_64r, /* 22 */ 258 EGR_1588_LINK_DELAY_64r, /* 23 */ 259 STORM_CONTROL_METER_CONFIGr, /* 24 */ 260 EGR_SF_SRC_MODID_CHECKr, /* 25 */ 261 EGR_VLAN_CONTROL_3r, /* 26 */ 262 SFLOW_ING_THRESHOLDr, /* 27 */ 263 PG_SHARED_LIMIT_CELLr, /* 28 */ 264 EGR_VLAN_CONTROL_1r, /* 29 */ 265 EGR_IPMC_CFG2r /* 30 */ 266 }; 267 268 #define _SOC_SER_CLEAR_REG_CASES \ 269 case GLOBAL_SP_WRED_AVG_QSIZEr: \ 270 case PORT_SP_WRED_AVG_QSIZEr: \ 271 case WRED_AVG_QSIZEr: \ 272 case VOQ_WRED_AVG_QSIZEr: \ 273 case EGR_FCOE_DELIMITER_ERROR_FRAMESr: \ 274 case EGR_FCOE_INVALID_CRC_FRAMESr: \ 275 case EGR_FCOE_DELIMITER_ERROR_FRAMES_64r: \ 276 case EGR_FCOE_DELIMITER_ERROR_FRAMES_64_PIPE0r: \ 277 case EGR_FCOE_DELIMITER_ERROR_FRAMES_64_PIPE1r: \ 278 case EGR_FCOE_INVALID_CRC_FRAMES_64r: \ 279 case EGR_FCOE_INVALID_CRC_FRAMES_64_PIPE0r: \ 280 case EGR_FCOE_INVALID_CRC_FRAMES_64_PIPE1r: \ 281 case MINBUCKETr: \ 282 case MAXBUCKETr: \ 283 case S3_MINBUCKETr: \ 284 case S3_MAXBUCKETr: \ 285 case S2_MINBUCKETr: \ 286 case S2_MAXBUCKETr: \ 287 case S3_WERRCOUNTr: \ 288 case S2_WERRCOUNTr: \ 289 case CPUMAXBUCKETr: \ 290 case HG_PKT_SIGNATURE_1r: \ 291 case HG_PKT_SIGNATURE_2r: \ 292 case HG_PKT_SIGNATURE_3r: 293 294 #define _SOC_MAX_PORTS_NUMS 170 295 #define _SOC_SER_REG_INDEX_MAX 79 296 297 typedef struct _soc_ser_reg_cache_s { 298 uint64 data[_SOC_MAX_PORTS_NUMS][_SOC_SER_REG_INDEX_MAX]; 299 } _soc_ser_reg_cache_t; 300 typedef struct _soc_ser_reg_cache_array_s { 301 _soc_ser_reg_cache_t reg_cache[SOC_SER_REG_CACHE_MAX]; 302 } _soc_ser_reg_cache_array_t; 303 _soc_ser_reg_cache_array_t *_soc_ser_reg_cache[SOC_MAX_NUM_DEVICES] = {NULL}; 304 305 typedef struct mem_ser_info { 306 uint32 next_idx; 307 soc_mem_t ser_mem; 308 uint32 hw_idx; 309 uint32 entry_data[SOC_MAX_MEM_WORDS]; 310 } mem_ser_info_t; 311 312 typedef struct _mem_ser_info_head_t { 313 mem_ser_info_t *base_addr; 314 uint32 head_idx; 315 uint32 tail_idx; 316 int counter; 317 } mem_ser_info_head_t; 318 319 typedef struct soc_ser_alpm_cache_flag_s { 320 uint32 flag_defip; 321 uint32 flag_defip_128; 322 uint32 flag_defip_alpm_v4; 323 uint32 flag_defip_alpm_v4_1; 324 uint32 flag_defip_alpm_v6; 325 uint32 flag_defip_alpm_v6_1; 326 uint32 flag_defip_alpm_v6_128; 327 uint32 flag_defip_aux; 328 } soc_ser_alpm_cache_flag_t; 329 330 static mem_ser_info_head_t mem_ser_info_head[SOC_MAX_NUM_DEVICES]; 331 332 #define SER_MEM_INFO_MAX_NUM 32 333 #define SER_MEM_INFO_BASE_ADDR(unit) mem_ser_info_head[unit].base_addr 334 #define SER_MEM_INFO_HEAD_IDX(unit) mem_ser_info_head[unit].head_idx 335 #define SER_MEM_INFO_TAIL_IDX(unit) mem_ser_info_head[unit].tail_idx 336 #define SER_MEM_INFO_COUNTER(unit) mem_ser_info_head[unit].counter 337 #define SER_MEM_INFO_NEXT_IDX(unit, cur_idx) mem_ser_info_head[unit].base_addr[cur_idx].next_idx 338 339 static soc_ser_functions_t *_soc_ser_functions[SOC_MAX_NUM_DEVICES]; 340 static soc_oam_event_functions_t *_soc_oam_event_functions[SOC_MAX_NUM_DEVICES]; 341 static soc_ser_alpm_cache_flag_t alpm_no_cache_flag[SOC_MAX_NUM_DEVICES]; 342 #ifdef BCM_TSN_SUPPORT 343 static soc_ser_tsn_stat_functions_t *soc_ser_tsn_stat_functions[SOC_MAX_NUM_DEVICES]; 344 #endif /* BCM_TSN_SUPPORT */ 345 #if defined(INCLUDE_FLOWTRACKER) 346 STATIC int _soc_ft_em_ser_correction(int unit, int pipe, soc_mem_t mem, int index); 347 #endif /* BCM_TOMAHAWK_SUPPORT */ 348 349 /* scrub_load: 0=scrub, 1=load cache */ 350 int soc_ser_reg_load_scrub(int unit, int scrub_load) 351 { 352 uint64 rval64; 353 soc_reg_t reg; 354 int r, i, blk, port, mindex; 355 soc_block_types_t regblktype; 356 357 /* Access all cacheable regs (store in cache if requested) */ 358 for (r = 0; r < SOC_SER_REG_CACHE_MAX; r++) { 359 reg = _soc_ser_reg_cache_list[r]; 360 if (!SOC_REG_IS_VALID(unit, reg)) { 361 continue; 362 } 363 if (SOC_REG_INFO(unit, reg).regtype == soc_genreg) { 364 SOC_IF_ERROR_RETURN 365 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 366 if (scrub_load) { 367 soc_ser_reg_cache_set(unit, reg, 0, 0, rval64); 368 } 369 LOG_VERBOSE(BSL_LS_SOC_SER, 370 (BSL_META_U(unit, 371 "Reg: %s port:%d index:%d\n"), SOC_REG_NAME(unit, reg), 0, 0)); 372 } else if (SOC_REG_INFO(unit, reg).regtype == soc_cosreg) { 373 regblktype = SOC_REG_INFO(unit, reg).block; 374 for (i = 0; i < NUM_COS(unit); i++) { 375 SOC_BLOCKS_ITER(unit, blk, regblktype) { 376 port = SOC_BLOCK_PORT(unit, blk); 377 SOC_IF_ERROR_RETURN 378 (soc_reg_get(unit, reg, port, i, &rval64)); 379 if (scrub_load) { 380 soc_ser_reg_cache_set(unit, reg, port, i, rval64); 381 } 382 LOG_VERBOSE(BSL_LS_SOC_SER, 383 (BSL_META_U(unit, 384 "Reg: %s port:%d index:%d\n"), SOC_REG_NAME(unit, reg), port, i)); 385 } 386 } 387 } else if ((SOC_REG_INFO(unit, reg).regtype == soc_portreg) || 388 (SOC_REG_INFO(unit, reg).regtype == soc_ppportreg)) { 389 mindex = 1; 390 switch (reg) { 391 case DMVOQ_WRED_CONFIGr: 392 case S3_COSWEIGHTSr: mindex = 72; break; 393 case PG_RESET_OFFSET_CELLr: 394 case PORT_SHARED_LIMIT_CELLr: 395 case WRED_CONFIGr: mindex = 8; break; 396 case PORT_SP_WRED_CONFIGr: 397 case S2_MINBUCKETCONFIG_64r: 398 case S2_MAXBUCKETCONFIG_64r: 399 case S3_MINBUCKETCONFIG_64r: 400 case S3_MAXBUCKETCONFIG_64r: mindex = 4; break; 401 case S2_COSWEIGHTSr: mindex = 12; break; 402 default: break; 403 } 404 PBMP_ALL_ITER(unit, port) { 405 switch (reg) { 406 case DMVOQ_WRED_CONFIGr: 407 if (!SOC_INFO(unit).port_num_ext_cosq[port]) { 408 continue; 409 } 410 break; 411 case MINBUCKETCONFIG_64r: 412 case MINBUCKETr: 413 case MAXBUCKETCONFIG_64r: 414 case MAXBUCKETr: 415 #ifdef BCM_ENDURO_SUPPORT 416 if (SOC_IS_ENDURO(unit)) { 417 if (IS_CPU_PORT(unit, port)) { 418 continue; 419 } else if (IS_XQ_PORT(unit, port)) { 420 mindex = 26; 421 } else { 422 mindex = 8; 423 } 424 } else { 425 #endif 426 if (IS_CPU_PORT(unit, port)) { 427 mindex = 48; 428 } else if (IS_LB_PORT(unit, port)) { 429 mindex = 5; 430 } else if (!SOC_INFO(unit).port_num_ext_cosq[port]) { 431 mindex = 15; 432 } else { 433 mindex = 79; 434 } 435 #ifdef BCM_TRIUMPH_SUPPORT 436 if (SOC_IS_TRIUMPH(unit)) { 437 if (IS_CPU_PORT(unit, port)) { 438 continue; 439 } 440 } 441 #endif 442 #ifdef BCM_ENDURO_SUPPORT 443 } 444 #endif 445 break; 446 case PORT_SP_WRED_CONFIGr: 447 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 448 continue; 449 } 450 break; 451 case S2_MINBUCKETCONFIG_64r: 452 case S2_MAXBUCKETCONFIG_64r: 453 case S3_MINBUCKETCONFIG_64r: 454 case S3_MAXBUCKETCONFIG_64r: 455 case S2_COSWEIGHTSr: 456 if (IS_CPU_PORT(unit, port)) { 457 continue; 458 } 459 break; 460 case S3_COSWEIGHTSr: 461 if (!SOC_INFO(unit).port_num_ext_cosq[port]) { 462 mindex = 8; 463 } 464 break; 465 case WRED_CONFIGr: 466 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 467 continue; 468 } 469 break; 470 default: break; 471 } 472 for (i = 0; i < mindex; i++) { 473 SOC_IF_ERROR_RETURN 474 (soc_reg_get(unit, reg, port, i, &rval64)); 475 if (scrub_load) { 476 soc_ser_reg_cache_set(unit, reg, port, i, rval64); 477 } 478 LOG_VERBOSE(BSL_LS_SOC_SER, 479 (BSL_META_U(unit, 480 "Reg: %s port:%d index:%d\n"), SOC_REG_NAME(unit, reg), port, i)); 481 } 482 } 483 } 484 } 485 return SOC_E_NONE; 486 } 487 488 int 489 soc_ser_reg_cache_clear(int unit, soc_reg_t reg, int port) 490 { 491 int i; 492 493 if (reg == INVALIDr) { 494 sal_memset(&_soc_ser_reg_cache[unit]->reg_cache, 0, sizeof(_soc_ser_reg_cache_t)); 495 } else { 496 for (i = 0; i < SOC_SER_REG_CACHE_MAX; i++) { 497 if (reg == _soc_ser_reg_cache_list[i]) { 498 if (port == REG_PORT_ANY) { 499 sal_memset(&_soc_ser_reg_cache[unit]->reg_cache[i].data[0][0], 500 0, sizeof(_soc_ser_reg_cache_t)); 501 } else { 502 sal_memset(&_soc_ser_reg_cache[unit]->reg_cache[i].data[port][0], 503 0, sizeof(_soc_ser_reg_cache_t) / _SOC_MAX_PORTS_NUMS); 504 } 505 break; 506 } 507 } 508 } 509 return SOC_E_NONE; 510 } 511 512 int 513 soc_ser_reg_cache_init(int unit) 514 { 515 if (_soc_ser_reg_cache[unit] == NULL) { 516 _soc_ser_reg_cache[unit] = sal_alloc(sizeof(_soc_ser_reg_cache_array_t), "reg-cache"); 517 } 518 if (SOC_WARM_BOOT(unit) && (SOC_CONTROL(unit)->mem_scache_ptr == NULL)) { 519 return soc_ser_reg_load_scrub(unit, 1); 520 } else { 521 return soc_ser_reg_cache_clear(unit, INVALIDr, REG_PORT_ANY); 522 } 523 } 524 525 void 526 soc_ser_reg_cache_info(int unit, int *count, int *size) 527 { 528 *count = SOC_SER_REG_CACHE_MAX; 529 *size = sizeof(_soc_ser_reg_cache_array_t); 530 } 531 532 int 533 soc_ser_reg_cache_set(int unit, soc_reg_t reg, int port, int index, uint64 data) 534 { 535 int i; 536 537 if (_soc_ser_reg_cache[unit] == NULL || SOC_MEM_TEST_SKIP_CACHE(unit)) { 538 return SOC_E_NONE; 539 } 540 switch (reg) { 541 _SOC_SER_CACHE_REG_CASES 542 break; 543 default: 544 return SOC_E_NONE; 545 } 546 assert(port < _SOC_MAX_PORTS_NUMS); 547 assert(index < _SOC_SER_REG_INDEX_MAX); 548 if (port >= _SOC_MAX_PORTS_NUMS) { 549 return SOC_E_PARAM; 550 } 551 if (index >= _SOC_SER_REG_INDEX_MAX) { 552 return SOC_E_PARAM; 553 } 554 for (i = 0; i < SOC_SER_REG_CACHE_MAX; i++) { 555 if (reg == _soc_ser_reg_cache_list[i]) { 556 if (port == REG_PORT_ANY) { 557 port = 0; 558 } 559 if (index < 0) { 560 index = 0; 561 } 562 LOG_VERBOSE(BSL_LS_SOC_SER, 563 (BSL_META_U(unit, 564 "Set cache: reg:%d port:%d index:%d " 565 "data:0x%x%x\n"), reg, port, index, 566 COMPILER_64_HI(data), COMPILER_64_LO(data))); 567 _soc_ser_reg_cache[unit]->reg_cache[i].data[port][index] = data; 568 break; 569 } 570 } 571 return SOC_E_NONE; 572 } 573 574 int 575 soc_ser_reg32_cache_set(int unit, soc_reg_t reg, int port, int index, uint32 data) 576 { 577 uint64 val; 578 579 if (_soc_ser_reg_cache[unit] == NULL || SOC_MEM_TEST_SKIP_CACHE(unit)) { 580 return SOC_E_NONE; 581 } 582 COMPILER_64_SET(val, 0, data); 583 return soc_ser_reg_cache_set(unit, reg, port, index, val); 584 } 585 586 int 587 soc_ser_reg_cache_get(int unit, soc_reg_t reg, int port, int index, uint64 *data) 588 { 589 int i; 590 591 if (_soc_ser_reg_cache[unit] == NULL) { 592 return SOC_E_UNAVAIL; 593 } 594 switch (reg) { 595 _SOC_SER_CACHE_REG_CASES 596 break; 597 default: 598 return SOC_E_UNAVAIL; 599 } 600 assert(port < _SOC_MAX_PORTS_NUMS); 601 assert(index < _SOC_SER_REG_INDEX_MAX); 602 if (port >= _SOC_MAX_PORTS_NUMS) { 603 return SOC_E_PARAM; 604 } 605 if (index >= _SOC_SER_REG_INDEX_MAX) { 606 return SOC_E_PARAM; 607 } 608 for (i = 0; i < SOC_SER_REG_CACHE_MAX; i++) { 609 if (reg == _soc_ser_reg_cache_list[i]) { 610 if (port == REG_PORT_ANY) { 611 port = 0; 612 } 613 if (index < 0) { 614 index = 0; 615 } 616 *data = _soc_ser_reg_cache[unit]->reg_cache[i].data[port][index]; 617 LOG_VERBOSE(BSL_LS_SOC_SER, 618 (BSL_META_U(unit, 619 "Get cache: reg:%d port:%d index:%d " 620 "data:0x%x%x\n"), reg, port, index, 621 COMPILER_64_HI(*data), COMPILER_64_LO(*data))); 622 break; 623 } 624 } 625 return SOC_E_NONE; 626 } 627 628 int 629 soc_ser_reg32_cache_get(int unit, soc_reg_t reg, int port, int index, uint32 *data) 630 { 631 uint64 val; 632 633 if (_soc_ser_reg_cache[unit] == NULL) { 634 return SOC_E_UNAVAIL; 635 } 636 COMPILER_64_ZERO(val); 637 SOC_IF_ERROR_RETURN(soc_ser_reg_cache_get(unit, reg, port, index, &val)); 638 *data = COMPILER_64_LO(val); 639 return SOC_E_NONE; 640 } 641 642 int SOC_REG_IS_DYNAMIC(int unit, soc_reg_t reg) 643 { 644 switch (reg) { 645 _SOC_SER_CLEAR_REG_CASES 646 return TRUE; 647 default: return FALSE; 648 } 649 } 650 651 int 652 soc_ser_reg_clear(int unit, soc_reg_t reg, int port, int index, uint64 data) 653 { 654 if (SOC_REG_IS_DYNAMIC(unit, reg)) { 655 SOC_IF_ERROR_RETURN(soc_reg_set_nocache(unit, reg, port, index, data)); 656 } 657 return SOC_E_NONE; 658 } 659 660 void 661 soc_ser_function_register(int unit, soc_ser_functions_t *functions) 662 { 663 _soc_ser_functions[unit] = functions; 664 } 665 666 void 667 soc_oam_event_function_register(int unit, soc_oam_event_functions_t *functions) 668 { 669 _soc_oam_event_functions[unit] = functions; 670 } 671 672 #ifdef BCM_TSN_SUPPORT 673 int 674 soc_ser_tsn_stat_function_register( 675 int unit, 676 soc_ser_tsn_stat_functions_t *functions) 677 { 678 soc_ser_tsn_stat_functions[unit] = functions; 679 return SOC_E_NONE; 680 } 681 #endif /* BCM_TSN_SUPPORT */ 682 683 int 684 soc_ser_populate_tcam_log(int unit, soc_mem_t mem, soc_acc_type_t target_pipe, int index) 685 { 686 if ((_soc_ser_functions[unit] != NULL) && 687 (_soc_ser_functions[unit]->_soc_ser_populate_tcam_log_f != NULL)) { 688 return (*(_soc_ser_functions[unit]->_soc_ser_populate_tcam_log_f)) 689 (unit, mem, target_pipe, index); 690 } 691 /*Should return 0 as the invalid log id*/ 692 return 0; 693 } 694 695 int 696 soc_ser_stat_error(int unit, int port) 697 { 698 int fixed = 0; 699 soc_stat_t *stat = SOC_STAT(unit); 700 701 if ((_soc_ser_functions[unit] != NULL) && 702 (_soc_ser_functions[unit]->_soc_ser_stat_nack_f != NULL)) { 703 (*(_soc_ser_functions[unit]->_soc_ser_stat_nack_f))(unit, &fixed); 704 } else { 705 return SOC_E_UNAVAIL; 706 } 707 708 if (!fixed) { 709 return SOC_E_INTERNAL; 710 } 711 stat->ser_err_stat++; 712 return SOC_E_NONE; 713 } 714 715 int 716 soc_process_ser_parity_error(int unit, 717 _soc_ser_parity_info_t *_ser_parity_info, 718 int parity_err_type) 719 { 720 int info_ix, index_min, index_max, ser_mem_count, copyno, mem_index, rv; 721 uint32 start_addr, end_addr; 722 uint32 fail_count, addr; 723 uint32 pipe_acc; 724 _soc_ser_parity_info_t *cur_spi; 725 _soc_ser_correct_info_t spci = {0}; 726 soc_stat_t *stat = SOC_STAT(unit); 727 728 /* coverity[result_independent_of_operands] */ 729 SOC_IF_ERROR_RETURN(READ_CMIC_SER_FAIL_CNTr(unit, &fail_count)); 730 731 if (!fail_count) { 732 LOG_ERROR(BSL_LS_SOC_SER, 733 (BSL_META_U(unit, 734 "SER parity failure without valid count\n"))); 735 } else { 736 /*coverity[result_independent_of_operands]*/ 737 SOC_IF_ERROR_RETURN(READ_CMIC_SER_FAIL_ENTRYr(unit, &addr)); 738 739 info_ix = 0; 740 while (_ser_parity_info[info_ix].mem != INVALIDm) { 741 cur_spi = &(_ser_parity_info[info_ix]); 742 index_min = soc_mem_index_min(unit, cur_spi->mem); 743 index_max = soc_mem_index_max(unit, cur_spi->mem); 744 pipe_acc = cur_spi->ser_flags & _SOC_SER_FLAG_ACC_TYPE_MASK; 745 ser_mem_count = index_max - index_min + 1; 746 if (!ser_mem_count) { 747 info_ix++; 748 continue; 749 } 750 SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) { 751 break; 752 } 753 start_addr = 754 soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_min); 755 end_addr = 756 soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_max); 757 758 if (0 != pipe_acc) { 759 /* Override ACC_TYPE in addresses */ 760 start_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK << 761 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 762 start_addr |= (pipe_acc & _SOC_MEM_ADDR_ACC_TYPE_MASK) << 763 _SOC_MEM_ADDR_ACC_TYPE_SHIFT; 764 765 end_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK << 766 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 767 end_addr |= (pipe_acc & _SOC_MEM_ADDR_ACC_TYPE_MASK) << 768 _SOC_MEM_ADDR_ACC_TYPE_SHIFT; 769 } 770 771 if ((addr >= start_addr) && (addr <= end_addr)) { 772 /* Addr in memory range */ 773 mem_index = (addr - start_addr) + index_min; 774 #ifdef BCM_KATANA_SUPPORT 775 if (0 != (cur_spi->ser_flags & _SOC_SER_FLAG_REMAP_READ)) { 776 if (SOC_IS_KATANA(unit)) { 777 mem_index = 778 soc_kt_l3_defip_index_remap(unit, cur_spi->mem, 779 mem_index); 780 } 781 } 782 #endif /* BCM_KATANA_SUPPORT */ 783 LOG_WARN(BSL_LS_SOC_SER, 784 (BSL_META_U(unit, 785 "%s entry %d TCAM parity error\n"), 786 SOC_MEM_NAME(unit, cur_spi->mem), 787 mem_index)); 788 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 789 parity_err_type, addr, 790 0); 791 stat->ser_err_tcam++; 792 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 793 spci.reg = INVALIDr; 794 spci.mem = cur_spi->mem; 795 spci.blk_type = copyno; 796 spci.index = mem_index; 797 spci.detect_time = sal_time_usecs(); 798 spci.log_id = soc_ser_populate_tcam_log(unit, 799 spci.mem, pipe_acc, spci.index); 800 rv = soc_ser_correction(unit, &spci); 801 if (spci.log_id != 0) { 802 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 803 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 804 spci.log_id, 0); 805 } 806 if (SOC_FAILURE(rv)) { 807 /* Report failed to correct event flag to 808 * application */ 809 soc_event_generate(unit, 810 SOC_SWITCH_EVENT_PARITY_ERROR, 811 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 812 addr, 813 0); 814 return rv; 815 } 816 break; 817 } 818 info_ix++; 819 } 820 } 821 /* coverity[result_independent_of_operands] */ 822 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_ENTRYr(unit, 0)); 823 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_CNTr(unit, 0)); 824 return SOC_E_NONE; 825 } 826 827 int 828 soc_process_cmicm_ser_parity_error(int unit, 829 _soc_ser_parity_info_t *_ser_parity_info, 830 int parity_err_type) 831 { 832 uint8 at, fail = 0; 833 int info_ix, index_min, index_max, phys_index_min, phys_index_max; 834 int ser_mem_count, copyno, mem_index, rv; 835 uint32 start_addr, end_addr; 836 uint32 fail_count, addr; 837 _soc_ser_parity_info_t *cur_spi; 838 _soc_ser_correct_info_t spci = {0}; 839 soc_stat_t *stat = SOC_STAT(unit); 840 841 /* First work on ser0 */ 842 /*coverity[result_independent_of_operands]*/ 843 SOC_IF_ERROR_RETURN(READ_CMIC_SER0_FAIL_CNTr(unit, &fail_count)); 844 if (fail_count) { 845 fail++; 846 /*coverity[result_independent_of_operands]*/ 847 SOC_IF_ERROR_RETURN(READ_CMIC_SER0_FAIL_ENTRYr(unit, &addr)); 848 info_ix = 0; 849 while (_ser_parity_info[info_ix].mem != INVALIDm) { 850 cur_spi = &(_ser_parity_info[info_ix]); 851 if (cur_spi->cmic_ser_id == 1) { 852 info_ix++; 853 continue; 854 } 855 phys_index_min = index_min = 856 soc_mem_index_min(unit, cur_spi->mem); 857 phys_index_max = index_max = 858 soc_mem_index_max(unit, cur_spi->mem); 859 if (0 != (cur_spi->ser_flags & _SOC_SER_FLAG_REMAP_READ)) { 860 861 /* Skip index map lkup if table is 0 size */ 862 if (soc_feature(unit, soc_feature_skip_null_table_lkup)) { 863 if (0 == soc_mem_index_count(unit, cur_spi->mem)) { 864 info_ix++; 865 continue; 866 } 867 } 868 #ifdef BCM_TRIUMPH3_SUPPORT 869 if (SOC_IS_TRIUMPH3(unit)) { 870 phys_index_min = 871 soc_tr3_l3_defip_index_map(unit, 872 cur_spi->mem, 873 index_min); 874 phys_index_max = 875 soc_tr3_l3_defip_index_map(unit, 876 cur_spi->mem, 877 index_max); 878 } 879 #endif /* BCM_TRIUMPH3_SUPPORT */ 880 #ifdef BCM_KATANA2_SUPPORT 881 if (SOC_IS_KATANA2(unit)) { 882 phys_index_min = 883 soc_kt2_l3_defip_index_map(unit, 884 cur_spi->mem, 885 index_min); 886 phys_index_max = 887 soc_kt2_l3_defip_index_map(unit, 888 cur_spi->mem, 889 index_max); 890 } 891 #endif /* BCM_KATANA2_SUPPORT */ 892 } 893 ser_mem_count = phys_index_max - phys_index_min + 1; 894 if (!ser_mem_count) { 895 info_ix++; 896 continue; 897 } 898 SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) { 899 break; 900 } 901 start_addr = 902 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, 903 phys_index_min, &at); 904 end_addr = 905 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, 906 phys_index_max, &at); 907 LOG_VERBOSE(BSL_LS_SOC_SER, 908 (BSL_META_U(unit, 909 "Mem: %s addr: %x start: %x end: %x\n"), 910 SOC_MEM_NAME(unit, cur_spi->mem), addr, 911 start_addr, end_addr)); 912 913 if ((addr >= start_addr) && (addr <= end_addr)) { 914 /* Addr in memory range */ 915 mem_index = (addr - start_addr) + phys_index_min; 916 if (0 != (cur_spi->ser_flags & _SOC_SER_FLAG_REMAP_READ)) { 917 /* Now, mem_index is the physical index. 918 * The correction routines expect the logical index. 919 * Reverse the mapping. 920 */ 921 #ifdef BCM_TRIUMPH3_SUPPORT 922 if (SOC_IS_TRIUMPH3(unit)) { 923 mem_index = 924 soc_tr3_l3_defip_index_remap(unit, cur_spi->mem, 925 mem_index); 926 } 927 #endif /* BCM_TRIUMPH3_SUPPORT */ 928 #ifdef BCM_KATANA2_SUPPORT 929 if (SOC_IS_KATANA2(unit)) { 930 mem_index = 931 soc_kt2_l3_defip_index_remap(unit, cur_spi->mem, 932 mem_index); 933 } 934 #endif /* BCM_KATANA2_SUPPORT */ 935 } 936 LOG_WARN(BSL_LS_SOC_SER, 937 (BSL_META_U(unit, 938 "ser0 %s entry %d TCAM parity error\n"), 939 SOC_MEM_NAME(unit, cur_spi->mem), 940 mem_index)); 941 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 942 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 943 cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET, 944 mem_index); 945 stat->ser_err_tcam++; 946 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 947 spci.reg = INVALIDr; 948 spci.mem = cur_spi->mem; 949 spci.blk_type = copyno; 950 spci.index = mem_index; 951 spci.detect_time = sal_time_usecs(); 952 spci.log_id = soc_ser_log_create_entry(unit, 953 sizeof(soc_ser_log_tlv_generic_t) + 954 sizeof(soc_ser_log_tlv_memory_t) + 955 sizeof(soc_ser_log_tlv_hdr_t) *3); 956 rv = soc_ser_correction(unit, &spci); 957 if (spci.log_id != 0) { 958 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 959 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 960 spci.log_id, 0); 961 } 962 if (SOC_FAILURE(rv)) { 963 /* Report failed to correct event flag to 964 * application */ 965 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 966 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 967 cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET, 968 mem_index); 969 return rv; 970 } 971 break; 972 } 973 info_ix++; 974 } 975 /*coverity[result_independent_of_operands]*/ 976 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_ENTRYr(unit, 0)); 977 /*coverity[result_independent_of_operands]*/ 978 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_CNTr(unit, 0)); 979 } 980 981 /* Then work on ser1 */ 982 /*coverity[result_independent_of_operands]*/ 983 SOC_IF_ERROR_RETURN(READ_CMIC_SER1_FAIL_CNTr(unit, &fail_count)); 984 if (fail_count) { 985 fail++; 986 /*coverity[result_independent_of_operands]*/ 987 SOC_IF_ERROR_RETURN(READ_CMIC_SER1_FAIL_ENTRYr(unit, &addr)); 988 info_ix = 0; 989 while (_ser_parity_info[info_ix].mem != INVALIDm) { 990 cur_spi = &(_ser_parity_info[info_ix]); 991 if (cur_spi->cmic_ser_id == 0) { 992 info_ix++; 993 continue; 994 } 995 index_min = soc_mem_index_min(unit, cur_spi->mem); 996 index_max = soc_mem_index_max(unit, cur_spi->mem); 997 SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) { 998 break; 999 } 1000 start_addr = 1001 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, index_min, &at); 1002 end_addr = 1003 soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, index_max, &at); 1004 1005 if ((addr >= start_addr) && (addr <= end_addr)) { 1006 /* Addr in memory range */ 1007 mem_index = (addr - start_addr) + index_min; 1008 LOG_WARN(BSL_LS_SOC_SER, 1009 (BSL_META_U(unit, 1010 "ser1 %s entry %d TCAM parity error\n"), 1011 SOC_MEM_NAME(unit, cur_spi->mem), 1012 mem_index)); 1013 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1014 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1015 cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET, 1016 mem_index); 1017 stat->ser_err_tcam++; 1018 sal_memset(&spci, 0, sizeof(spci)); 1019 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 1020 spci.mem = cur_spi->mem; 1021 spci.blk_type = copyno; 1022 spci.index = mem_index; 1023 spci.detect_time = sal_time_usecs(); 1024 spci.log_id = soc_ser_log_create_entry(unit, 1025 sizeof(soc_ser_log_tlv_generic_t) + 1026 sizeof(soc_ser_log_tlv_memory_t) + 1027 sizeof(soc_ser_log_tlv_hdr_t) *3); 1028 rv = soc_ser_correction(unit, &spci); 1029 if (spci.log_id != 0) { 1030 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1031 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 1032 spci.log_id, 0); 1033 } 1034 if (SOC_FAILURE(rv)) { 1035 /* Report failed to correct event flag to 1036 * application */ 1037 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1038 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1039 cur_spi->mem | SOC_SER_ERROR_DATA_ID_OFFSET_SET, 1040 mem_index); 1041 return rv; 1042 } 1043 break; 1044 } 1045 info_ix++; 1046 } 1047 /*coverity[result_independent_of_operands]*/ 1048 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_ENTRYr(unit, 0)); 1049 /*coverity[result_independent_of_operands]*/ 1050 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_CNTr(unit, 0)); 1051 } 1052 if (!fail) { 1053 LOG_ERROR(BSL_LS_SOC_SER, 1054 (BSL_META_U(unit, 1055 "SER parity failure without valid count\n"))); 1056 } 1057 return SOC_E_NONE; 1058 } 1059 1060 int 1061 soc_ser_mem_nack(void *unit_vp, void *addr_vp, void *d2, 1062 void *d3, void *d4) 1063 { 1064 int unit = PTR_TO_INT(unit_vp); 1065 1066 if ((_soc_ser_functions[unit] != NULL) && 1067 (_soc_ser_functions[unit]->_soc_ser_mem_nack_f != NULL)) { 1068 sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_mem_nack_f), unit_vp, 1069 addr_vp, d2, d3, d4); 1070 return TRUE; 1071 } 1072 1073 return FALSE; 1074 } 1075 1076 int 1077 soc_ser_parity_error_intr(int unit) 1078 { 1079 if ((_soc_ser_functions[unit] != NULL) && 1080 (_soc_ser_functions[unit]->_soc_ser_parity_error_intr_f != NULL)) { 1081 soc_intr_disable(unit, IRQ_MEM_FAIL); 1082 sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_parity_error_intr_f), 1083 INT_TO_PTR(unit), 0, 0, 0, 0); 1084 return TRUE; 1085 } else if ((_soc_oam_event_functions[unit] != NULL) && 1086 (_soc_oam_event_functions[unit]->_soc_oam_event_intr_f != NULL)) { 1087 soc_intr_disable(unit, IRQ_MEM_FAIL); 1088 sal_dpc(*(_soc_oam_event_functions[unit]->_soc_oam_event_intr_f), 1089 INT_TO_PTR(unit), 0, 0, 0, 0); 1090 return TRUE; 1091 } 1092 return FALSE; 1093 } 1094 1095 soc_error_t 1096 soc_ser_tcam_scan_engine_enable(int unit, int enable) 1097 { 1098 /* 1099 uint64 config; 1100 COMPILER_64_ZERO(config); 1101 */ 1102 1103 #ifdef BCM_TOMAHAWK2_SUPPORT 1104 if (SOC_IS_TOMAHAWK2(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) { 1105 return soc_th2_tcam_engine_enable(unit, enable); 1106 } 1107 #endif 1108 1109 #ifdef BCM_TRIDENT3_SUPPORT 1110 if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) { 1111 return soc_td3_tcam_engine_enable(unit, enable); 1112 } 1113 #endif 1114 1115 #ifdef BCM_TOMAHAWK3_SUPPORT 1116 if (SOC_IS_TOMAHAWK3(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) { 1117 return soc_th3_tcam_engine_enable(unit, enable); 1118 } 1119 #endif 1120 return SOC_E_NONE; 1121 } 1122 1123 int 1124 soc_ser_parity_error_cmicm_intr(void *unit_vp, void *d1, void *d2, 1125 void *d3, void *d4) 1126 { 1127 int unit = PTR_TO_INT(unit_vp); 1128 1129 if ((_soc_ser_functions[unit] != NULL) && 1130 (_soc_ser_functions[unit]->_soc_ser_parity_error_cmicm_intr_f != NULL)) { 1131 sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_parity_error_cmicm_intr_f), 1132 unit_vp, d1, d2, d3, d4); 1133 return TRUE; 1134 } else if ((_soc_oam_event_functions[unit] != NULL) && 1135 (_soc_oam_event_functions[unit]->_soc_oam_event_intr_f != NULL)) { 1136 sal_dpc(*(_soc_oam_event_functions[unit]->_soc_oam_event_intr_f), 1137 unit_vp, d1, d2, d3, d4); 1138 return TRUE; 1139 } 1140 1141 return FALSE; 1142 } 1143 1144 #ifdef BCM_CMICX_SUPPORT 1145 int 1146 soc_ser_parity_error_cmicx_intr(void *unit_vp, void *d1, void *d2, 1147 void *d3, void *d4) 1148 { 1149 int unit = PTR_TO_INT(unit_vp); 1150 1151 if ((_soc_ser_functions[unit] != NULL) && 1152 (_soc_ser_functions[unit]->_soc_ser_parity_error_cmicx_intr_f != NULL)) { 1153 sal_dpc(*(_soc_ser_functions[unit]->_soc_ser_parity_error_cmicx_intr_f), 1154 unit_vp, d1, d2, d3, d4); 1155 return TRUE; 1156 } 1157 1158 return FALSE; 1159 } 1160 #endif 1161 1162 void 1163 soc_ser_fail(void *unit_vp, void *addr_vp, void *d2, 1164 void *d3, void *d4) 1165 1166 { 1167 int unit = PTR_TO_INT(unit_vp); 1168 1169 if ((_soc_ser_functions[unit] != NULL) && 1170 (_soc_ser_functions[unit]->_soc_ser_fail_f != NULL)) { 1171 (*(_soc_ser_functions[unit]->_soc_ser_fail_f))(unit); 1172 } 1173 1174 return; 1175 } 1176 1177 STATIC int 1178 _soc_ser_granularity(_soc_ser_parity_mode_t parity_mode) 1179 { 1180 int ser_mem_granularity; 1181 1182 switch (parity_mode) { 1183 case _SOC_SER_PARITY_MODE_2BITS: 1184 ser_mem_granularity = 2; 1185 break; 1186 case _SOC_SER_PARITY_MODE_4BITS: 1187 ser_mem_granularity = 4; 1188 break; 1189 case _SOC_SER_PARITY_MODE_8BITS: 1190 ser_mem_granularity = 8; 1191 break; 1192 case _SOC_SER_PARITY_MODE_1BIT: 1193 default: 1194 ser_mem_granularity = 1; 1195 break; 1196 } 1197 return ser_mem_granularity; 1198 } 1199 1200 int 1201 soc_ser_mem_clear(int unit, _soc_ser_parity_info_t *_ser_parity_info, 1202 soc_mem_t mem) 1203 { 1204 int info_ix, ser_mem_count, ser_mem_granularity; 1205 uint32 addr_valid = 0; 1206 _soc_ser_parity_info_t *cur_spi; 1207 1208 /* coverity[result_independent_of_operands] */ 1209 SOC_IF_ERROR_RETURN 1210 (READ_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, &addr_valid)); 1211 1212 if (!addr_valid) { 1213 /* No SER protection, do nothing */ 1214 return SOC_E_NONE; 1215 } 1216 1217 info_ix = 0; 1218 while (_ser_parity_info[info_ix].mem != INVALIDm) { 1219 if (_ser_parity_info[info_ix].mem == mem) { 1220 break; 1221 } 1222 info_ix++; 1223 } 1224 1225 if ((_ser_parity_info[info_ix].mem != INVALIDm) && 1226 (addr_valid & (1 << info_ix))) { 1227 cur_spi = &(_ser_parity_info[info_ix]); 1228 1229 addr_valid &= ~(1 << info_ix); 1230 /* Disable SER protection on this memory */ 1231 /*coverity[result_independent_of_operands]*/ 1232 SOC_IF_ERROR_RETURN 1233 (WRITE_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid)); 1234 1235 ser_mem_granularity = 1236 _soc_ser_granularity(cur_spi->parity_mode); 1237 1238 /* Flush SER memory segment for the table */ 1239 for (ser_mem_count = cur_spi->ser_section_start; 1240 ser_mem_count < cur_spi->ser_section_end; 1241 ser_mem_count += ser_mem_granularity) { 1242 /* coverity[result_independent_of_operands] */ 1243 SOC_IF_ERROR_RETURN 1244 (WRITE_CMIC_SER_MEM_ADDRr(unit, ser_mem_count)); 1245 /* coverity[result_independent_of_operands] */ 1246 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_MEM_DATAr(unit, 0)); 1247 } 1248 1249 addr_valid |= (1 << info_ix); 1250 /* Enable SER protection on this memory */ 1251 /*coverity[result_independent_of_operands]*/ 1252 SOC_IF_ERROR_RETURN 1253 (WRITE_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid)); 1254 1255 LOG_VERBOSE(BSL_LS_SOC_SER, 1256 (BSL_META_U(unit, 1257 "\t%s: SER[%d-%d]\n"), 1258 SOC_MEM_NAME(unit, cur_spi->mem), 1259 cur_spi->ser_section_start, cur_spi->ser_section_end)); 1260 } 1261 1262 return SOC_E_NONE; 1263 } 1264 1265 int 1266 soc_cmicm_ser_mem_clear(int unit, _soc_ser_parity_info_t *_ser_parity_info, 1267 soc_mem_t mem) 1268 { 1269 int info_ix, ser_mem_count, ser_mem_granularity; 1270 uint32 addr_valid = 0; 1271 _soc_ser_parity_info_t *cur_spi; 1272 1273 /* First work on ser0 */ 1274 SOC_IF_ERROR_RETURN 1275 (READ_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, &addr_valid)); 1276 1277 if (!addr_valid) { 1278 /* No SER protection, do nothing */ 1279 goto check_ser1; 1280 } 1281 1282 info_ix = 0; 1283 while (_ser_parity_info[info_ix].mem != INVALIDm) { 1284 if ((_ser_parity_info[info_ix].mem == mem) && 1285 (_ser_parity_info[info_ix].cmic_ser_id == 0)) { 1286 break; 1287 } 1288 info_ix++; 1289 } 1290 1291 if ((_ser_parity_info[info_ix].mem != INVALIDm) && 1292 (addr_valid & (1 << info_ix))) { 1293 cur_spi = &(_ser_parity_info[info_ix]); 1294 1295 addr_valid &= ~(1 << info_ix); 1296 /* Disable SER protection on this memory */ 1297 /*coverity[result_independent_of_operands]*/ 1298 SOC_IF_ERROR_RETURN 1299 (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid)); 1300 1301 ser_mem_granularity = 1302 _soc_ser_granularity(cur_spi->parity_mode); 1303 1304 /* Flush SER memory segment for the table */ 1305 for (ser_mem_count = cur_spi->ser_section_start; 1306 ser_mem_count < cur_spi->ser_section_end; 1307 ser_mem_count += ser_mem_granularity) { 1308 SOC_IF_ERROR_RETURN 1309 (WRITE_CMIC_SER0_MEM_ADDRr(unit, ser_mem_count)); 1310 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_MEM_DATAr(unit, 0)); 1311 } 1312 1313 addr_valid |= (1 << info_ix); 1314 /* Enable SER protection on this memory */ 1315 /*coverity[result_independent_of_operands]*/ 1316 SOC_IF_ERROR_RETURN 1317 (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid)); 1318 1319 LOG_VERBOSE(BSL_LS_SOC_SER, 1320 (BSL_META_U(unit, 1321 "\t%s: SER0[%d-%d]\n"), 1322 SOC_MEM_NAME(unit, cur_spi->mem), 1323 cur_spi->ser_section_start, cur_spi->ser_section_end)); 1324 } 1325 1326 check_ser1: 1327 /* Then work on ser1 */ 1328 /* coverity[result_independent_of_operands] */ 1329 SOC_IF_ERROR_RETURN 1330 (READ_CMIC_SER1_PROTECT_ADDR_RANGE_VALIDr(unit, &addr_valid)); 1331 1332 if (!addr_valid) { 1333 /* No SER protection, do nothing */ 1334 return SOC_E_NONE; 1335 } 1336 1337 info_ix = 0; 1338 while (_ser_parity_info[info_ix].mem != INVALIDm) { 1339 if ((_ser_parity_info[info_ix].mem == mem) && 1340 (_ser_parity_info[info_ix].cmic_ser_id == 1)) { 1341 break; 1342 } 1343 info_ix++; 1344 } 1345 1346 if ((_ser_parity_info[info_ix].mem != INVALIDm) && 1347 (addr_valid & (1 << info_ix))) { 1348 cur_spi = &(_ser_parity_info[info_ix]); 1349 1350 addr_valid &= ~(1 << info_ix); 1351 /* Disable SER protection on this memory */ 1352 /*coverity[result_independent_of_operands]*/ 1353 SOC_IF_ERROR_RETURN 1354 (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid)); 1355 1356 ser_mem_granularity = 1357 _soc_ser_granularity(cur_spi->parity_mode); 1358 1359 /* Flush SER memory segment for the table */ 1360 for (ser_mem_count = cur_spi->ser_section_start; 1361 ser_mem_count < cur_spi->ser_section_end; 1362 ser_mem_count += ser_mem_granularity) { 1363 /* coverity[result_independent_of_operands] */ 1364 SOC_IF_ERROR_RETURN 1365 (WRITE_CMIC_SER1_MEM_ADDRr(unit, ser_mem_count)); 1366 /* coverity[result_independent_of_operands] */ 1367 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_MEM_DATAr(unit, 0)); 1368 } 1369 1370 addr_valid |= (1 << info_ix); 1371 /* Enable SER protection on this memory */ 1372 /*coverity[result_independent_of_operands]*/ 1373 SOC_IF_ERROR_RETURN 1374 (WRITE_CMIC_SER1_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid)); 1375 1376 LOG_VERBOSE(BSL_LS_SOC_SER, 1377 (BSL_META_U(unit, 1378 "\t%s: SER0[%d-%d]\n"), 1379 SOC_MEM_NAME(unit, cur_spi->mem), 1380 cur_spi->ser_section_start, cur_spi->ser_section_end)); 1381 } 1382 return SOC_E_NONE; 1383 } 1384 1385 int 1386 soc_ser_init(int unit, _soc_ser_parity_info_t *_ser_parity_info, int max_mem) 1387 { 1388 int info_ix, o_info_ix; 1389 int index_min, index_max, copyno, ser_mem_granularity; 1390 int i, ser_mem_count, ser_mem_total = 0; 1391 uint32 start_addr, end_addr, ser_mem_addr = 0, reg_addr; 1392 uint32 addr_valid0 = 0; 1393 uint32 acc_type; 1394 uint8 wb_flag = 0; 1395 #ifdef BCM_CMICM_SUPPORT 1396 uint8 at; 1397 uint32 addr_valid1 = 0, ser_mem_addr0 = 0, ser_mem_addr1 = 0; 1398 uint32 ser_mem_total0 = 0, ser_mem_total1 = 0; 1399 #endif /* BCM_CMICM_SUPPORT */ 1400 _soc_ser_parity_info_t *cur_spi, *multi_pipe_spi; 1401 1402 LOG_VERBOSE(BSL_LS_SOC_SER, 1403 (BSL_META_U(unit, 1404 "Unit %d: SER parity initialization:\n"), unit)); 1405 1406 soc_ser_function_register(unit, NULL); 1407 1408 info_ix = 0; 1409 while (_ser_parity_info[info_ix].mem != INVALIDm) { 1410 cur_spi = &(_ser_parity_info[info_ix]); 1411 1412 if (cur_spi->ser_flags & _SOC_SER_FLAG_SW_COMPARE) { 1413 if (SOC_MEM_INFO(unit, cur_spi->mem).flags & SOC_MEM_FLAG_BE) { 1414 LOG_ERROR(BSL_LS_SOC_SER, 1415 (BSL_META_U(unit, 1416 "\tSW SER init of Big Endian TCAMs is not supported: %s\n"), 1417 SOC_MEM_NAME(unit, cur_spi->mem))); 1418 return SOC_E_INTERNAL; 1419 } 1420 1421 LOG_VERBOSE(BSL_LS_SOC_SER, 1422 (BSL_META_U(unit, 1423 "\tSkipping HW SER init of manual scan mem: %s\n"), 1424 SOC_MEM_NAME(unit, cur_spi->mem))); 1425 SOC_MEM_INFO(unit, cur_spi->mem).flags |= SOC_MEM_FLAG_SER_ENGINE; 1426 info_ix++; 1427 continue; 1428 } 1429 1430 index_min = soc_mem_index_min(unit, cur_spi->mem); 1431 index_max = soc_mem_index_max(unit, cur_spi->mem); 1432 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 1433 defined(BCM_KATANA_SUPPORT) 1434 if (soc_feature(unit, soc_feature_l3_defip_map) && 1435 ((cur_spi->mem == L3_DEFIP_PAIR_128m) || 1436 (cur_spi->mem == L3_DEFIPm))) { 1437 /* Override SOC memory impression for overlay 1438 * LPM tables. */ 1439 index_min = 0; 1440 index_max = (SOC_CONTROL(unit)->l3_defip_max_tcams * 1441 SOC_CONTROL(unit)->l3_defip_tcam_size) - 1; 1442 if (cur_spi->mem == L3_DEFIP_PAIR_128m) { 1443 index_max /= 2; 1444 } 1445 } 1446 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT */ 1447 ser_mem_count = index_max - index_min + 1; 1448 if (!ser_mem_count) { 1449 LOG_VERBOSE(BSL_LS_SOC_SER, 1450 (BSL_META_U(unit, 1451 "\tSkipping empty mem: %s\n"), 1452 SOC_MEM_NAME(unit, cur_spi->mem))); 1453 info_ix++; 1454 continue; 1455 } 1456 1457 ser_mem_granularity = _soc_ser_granularity(cur_spi->parity_mode); 1458 ser_mem_count *= ser_mem_granularity; 1459 1460 /* Round up to words for simplicity */ 1461 ser_mem_count = 32 * ((ser_mem_count + 31) / 32); 1462 if ((ser_mem_count + ser_mem_total) > max_mem) { 1463 /* Can't fit requested parity bits in SER memory */ 1464 LOG_VERBOSE(BSL_LS_SOC_SER, 1465 (BSL_META_U(unit, 1466 "SER mem full: Skipping further config.\n"))); 1467 break; 1468 } 1469 1470 /* Parity bits fit, so on with the config */ 1471 SOC_MEM_BLOCK_ITER(unit, cur_spi->mem, copyno) { 1472 break; 1473 } 1474 #ifdef BCM_CMICM_SUPPORT 1475 if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) { 1476 start_addr = soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, 1477 index_min, &at); 1478 end_addr = soc_mem_addr_get(unit, cur_spi->mem, 0, copyno, 1479 index_max, &at); 1480 } else 1481 #endif /* BCM_CMICM_SUPPORT */ 1482 { 1483 start_addr = soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_min); 1484 end_addr = soc_mem_addr(unit, cur_spi->mem, 0, copyno, index_max); 1485 } 1486 1487 /* Flush SER memory */ 1488 #ifdef BCM_CMICM_SUPPORT 1489 if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) { 1490 if (cur_spi->cmic_ser_id) { 1491 ser_mem_addr1 = ser_mem_total1; /* Previous total */ 1492 ser_mem_total1 += ser_mem_count; /* New total */ 1493 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 1494 for (i=ser_mem_addr1; i<ser_mem_total1; i++) { 1495 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_MEM_ADDRr(unit, i)); 1496 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_MEM_DATAr(unit, 0)); 1497 } 1498 } 1499 /* Record section for mem_clear use */ 1500 cur_spi->ser_section_start = ser_mem_addr1; 1501 cur_spi->ser_section_end = ser_mem_total1 - ser_mem_granularity; 1502 } else { 1503 ser_mem_addr0 = ser_mem_total0; /* Previous total */ 1504 ser_mem_total0 += ser_mem_count; /* New total */ 1505 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 1506 for (i=ser_mem_addr0; i<ser_mem_total0; i++) { 1507 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_MEM_ADDRr(unit, i)); 1508 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_MEM_DATAr(unit, 0)); 1509 } 1510 } 1511 /* Record section for mem_clear use */ 1512 cur_spi->ser_section_start = ser_mem_addr0; 1513 cur_spi->ser_section_end = ser_mem_total0 - ser_mem_granularity; 1514 } 1515 ser_mem_total += ser_mem_count; /* New total */ 1516 } else 1517 #endif /* BCM_CMICM_SUPPORT */ 1518 { 1519 ser_mem_addr = ser_mem_total; /* Previous total */ 1520 ser_mem_total += ser_mem_count; /* New total */ 1521 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 1522 for (i=ser_mem_addr; i<ser_mem_total; i++) { 1523 /* coverity[result_independent_of_operands] */ 1524 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_MEM_ADDRr(unit, i)); 1525 /* coverity[result_independent_of_operands] */ 1526 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_MEM_DATAr(unit, 0)); 1527 } 1528 } 1529 /* Record section for mem_clear use */ 1530 cur_spi->ser_section_start = ser_mem_addr; 1531 cur_spi->ser_section_end = ser_mem_total - ser_mem_granularity; 1532 } 1533 1534 /* For multiple pipeline units, different pipeline's hardware 1535 * instances are duplicates. The SER parity bits are thus 1536 * shared, but the configuration registers in the CMIC must be 1537 * different to capture the different SBUS ranges of the 1538 * read accesses. 1539 */ 1540 multi_pipe_spi = cur_spi; 1541 o_info_ix = info_ix; 1542 if (SOC_WARM_BOOT(unit) && SOC_IS_KATANA(unit)) { 1543 wb_flag = 1; 1544 } 1545 while (cur_spi->mem == multi_pipe_spi->mem) { 1546 if (cur_spi != multi_pipe_spi) { 1547 info_ix++; /* Advance the index */ 1548 if (0 != (multi_pipe_spi->ser_flags & 1549 _SOC_SER_FLAG_MULTI_PIPE)) { 1550 /* Get the non-default pipeline access type */ 1551 acc_type = multi_pipe_spi->ser_flags & 1552 _SOC_SER_FLAG_ACC_TYPE_MASK; 1553 1554 /* Override ACC_TYPE in address */ 1555 /* Note, this function does not support the 1556 * extended sbus addressing for multiple pipeline 1557 * devices. 1558 * soc_generic_ser_init _must_ be used 1559 * for such devices. 1560 */ 1561 start_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK << 1562 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 1563 start_addr |= 1564 (acc_type & _SOC_MEM_ADDR_ACC_TYPE_MASK) << 1565 _SOC_MEM_ADDR_ACC_TYPE_SHIFT; 1566 end_addr &= ~(_SOC_MEM_ADDR_ACC_TYPE_MASK << 1567 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 1568 end_addr |= 1569 (acc_type & _SOC_MEM_ADDR_ACC_TYPE_MASK) << 1570 _SOC_MEM_ADDR_ACC_TYPE_SHIFT; 1571 } else { 1572 LOG_VERBOSE(BSL_LS_SOC_SER, 1573 (BSL_META_U(unit, 1574 "SER mem muliple pipeline mismatch %s vs. %s.\n"), 1575 SOC_MEM_NAME(unit, cur_spi->mem), 1576 SOC_MEM_NAME(unit, multi_pipe_spi->mem))); 1577 return SOC_E_INTERNAL; 1578 } 1579 } 1580 1581 reg_addr = 1582 soc_reg_addr(unit, multi_pipe_spi->start_addr_reg, 1583 REG_PORT_ANY, 0); 1584 if (!wb_flag) { 1585 /* coverity[result_independent_of_operands] */ 1586 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, start_addr)); 1587 } 1588 reg_addr = 1589 soc_reg_addr(unit, multi_pipe_spi->end_addr_reg, 1590 REG_PORT_ANY, 0); 1591 if (!wb_flag) { 1592 /* coverity[result_independent_of_operands] */ 1593 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, end_addr)); 1594 } 1595 reg_addr = 1596 soc_reg_addr(unit, multi_pipe_spi->cmic_mem_addr_reg, 1597 REG_PORT_ANY, 0); 1598 1599 1600 #ifdef BCM_CMICM_SUPPORT 1601 if (soc_feature(unit, soc_feature_cmicm) && 1602 !SOC_IS_KATANA(unit)) { 1603 if (multi_pipe_spi->cmic_ser_id) { 1604 /* coverity[result_independent_of_operands] */ 1605 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, 1606 ser_mem_addr1)); 1607 addr_valid1 |= (1 << info_ix); 1608 } else { 1609 /* coverity[result_independent_of_operands] */ 1610 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, 1611 ser_mem_addr0)); 1612 addr_valid0 |= (1 << info_ix); 1613 } 1614 } else 1615 #endif /* BCM_CMICM_SUPPORT */ 1616 { 1617 if (!wb_flag) { 1618 /* coverity[result_independent_of_operands] */ 1619 SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, 1620 ser_mem_addr)); 1621 } 1622 addr_valid0 |= (1 << info_ix); 1623 } 1624 1625 if (multi_pipe_spi->bit_offset != -1) { 1626 if (!wb_flag) { 1627 /* coverity[result_independent_of_operands] */ 1628 SOC_IF_ERROR_RETURN 1629 (soc_pci_write(unit, soc_reg_addr(unit, 1630 multi_pipe_spi->entry_len_reg, 1631 REG_PORT_ANY, 0), 1632 multi_pipe_spi->bit_offset)); 1633 } 1634 } 1635 SOC_IF_ERROR_RETURN 1636 (soc_reg_field32_modify(unit, multi_pipe_spi->parity_mode_reg, 1637 REG_PORT_ANY, multi_pipe_spi->parity_mode_field, 1638 multi_pipe_spi->parity_mode)); 1639 1640 multi_pipe_spi = &(_ser_parity_info[info_ix + 1]); 1641 } 1642 1643 #ifdef BCM_CMICM_SUPPORT 1644 if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) { 1645 LOG_VERBOSE(BSL_LS_SOC_SER, 1646 (BSL_META_U(unit, 1647 "\t%s(%d-%d): Sbus range (0x%08x-0x%08x) SER[%d][%d](0x%03x)\n"), 1648 SOC_MEM_NAME(unit, cur_spi->mem), 1649 index_min, index_max, start_addr, end_addr, 1650 cur_spi->cmic_ser_id, o_info_ix, 1651 cur_spi->cmic_ser_id ? 1652 ser_mem_addr1 : ser_mem_addr0)); 1653 } else 1654 #endif /* BCM_CMICM_SUPPORT */ 1655 { 1656 LOG_VERBOSE(BSL_LS_SOC_SER, 1657 (BSL_META_U(unit, 1658 "\t%s(%d-%d): Sbus range (0x%08x-0x%08x) SER[%d](0x%03x)\n"), 1659 SOC_MEM_NAME(unit, cur_spi->mem), 1660 index_min, index_max, start_addr, end_addr, 1661 o_info_ix, ser_mem_addr)); 1662 } 1663 if (cur_spi->bit_offset != -1) { 1664 LOG_VERBOSE(BSL_LS_SOC_SER, 1665 (BSL_META_U(unit, 1666 "\tBits protected per entry: %d\n"), 1667 cur_spi->bit_offset)); 1668 } 1669 SOC_MEM_INFO(unit, cur_spi->mem).flags |= SOC_MEM_FLAG_SER_ENGINE; 1670 info_ix++; 1671 } 1672 1673 #ifdef BCM_CMICM_SUPPORT 1674 if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) { 1675 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_ENTRYr(unit, 0)); 1676 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER0_FAIL_CNTr(unit, 0)); 1677 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_ENTRYr(unit, 0)); 1678 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER1_FAIL_CNTr(unit, 0)); 1679 } else 1680 #endif /* BCM_CMICM_SUPPORT */ 1681 { 1682 if (!wb_flag) { 1683 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_ENTRYr(unit, 0)); 1684 SOC_IF_ERROR_RETURN(WRITE_CMIC_SER_FAIL_CNTr(unit, 0)); 1685 } 1686 } 1687 1688 /* Enable SER protection last */ 1689 #ifdef BCM_CMICM_SUPPORT 1690 if (soc_feature(unit, soc_feature_cmicm) && !SOC_IS_KATANA(unit)) { 1691 SOC_IF_ERROR_RETURN 1692 (WRITE_CMIC_SER0_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid0)); 1693 /* coverity[result_independent_of_operands] */ 1694 SOC_IF_ERROR_RETURN 1695 (WRITE_CMIC_SER1_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid1)); 1696 } else 1697 #endif /* BCM_CMICM_SUPPORT */ 1698 { 1699 if (!wb_flag) { 1700 /* coverity[result_independent_of_operands] */ 1701 SOC_IF_ERROR_RETURN 1702 (WRITE_CMIC_SER_PROTECT_ADDR_RANGE_VALIDr(unit, addr_valid0)); 1703 } 1704 } 1705 return SOC_E_NONE; 1706 } 1707 1708 STATIC int 1709 _soc_generic_ser_granularity(_soc_ser_protection_type_t prot_type, 1710 _soc_ser_protection_mode_t prot_mode, 1711 __soc_ser_start_end_bits_t *bits) 1712 { 1713 int i, words = 0, ser_mem_gran; 1714 1715 for (i = 0; i < SOC_NUM_GENERIC_PROT_SECTIONS; i++) { 1716 if (bits[i].start_bit >= 0) { 1717 words++; 1718 } 1719 } 1720 if (prot_type == _SOC_SER_TYPE_PARITY) { 1721 switch (prot_mode) { 1722 case _SOC_SER_PARITY_2BITS: 1723 ser_mem_gran = 2; 1724 break; 1725 case _SOC_SER_PARITY_4BITS: 1726 ser_mem_gran = 4; 1727 break; 1728 case _SOC_SER_PARITY_8BITS: 1729 ser_mem_gran = 8; 1730 break; 1731 case _SOC_SER_PARITY_1BIT: 1732 default: 1733 ser_mem_gran = 1; 1734 break; 1735 } 1736 return ser_mem_gran; 1737 } else { 1738 switch (prot_mode) { 1739 case _SOC_SER_ECC_2FLD: 1740 ser_mem_gran = 2; 1741 break; 1742 case _SOC_SER_ECC_4FLD: 1743 ser_mem_gran = 4; 1744 break; 1745 case _SOC_SER_ECC_1FLD: 1746 default: 1747 ser_mem_gran = 1; 1748 break; 1749 } 1750 return ser_mem_gran * words * 9; 1751 } 1752 } 1753 1754 int 1755 soc_generic_ser_process_error(int unit, _soc_generic_ser_info_t *ser_info, 1756 int err_type) 1757 { 1758 uint8 at; 1759 int info_ix, hw_ix, acc_type, rv; 1760 int index_min, index_max, phys_index_min, phys_index_max; 1761 int ser_mem_count, copyno, mem_index; 1762 uint32 start_addr, end_addr, count; 1763 uint32 ser_err[2], addr; 1764 _soc_generic_ser_info_t *cur_ser_info; 1765 _soc_ser_correct_info_t spci = {0}; 1766 soc_stat_t *stat = SOC_STAT(unit); 1767 ser_result_0_entry_t err_result; 1768 soc_mem_t cur_mem; 1769 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \ 1770 defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \ 1771 defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_APACHE_SUPPORT) 1772 uint8 *corrupt = NULL; 1773 int is_l3_defip = FALSE; 1774 #endif 1775 #if defined(ALPM_ENABLE) 1776 uint8 _alpm_lock = 0; 1777 #endif /* ALPM_ENABLE */ 1778 int block_type = 0; 1779 1780 sal_memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1781 1782 SOC_IF_ERROR_RETURN(READ_SER_ERROR_0r(unit, &ser_err[0])); 1783 SOC_IF_ERROR_RETURN(READ_SER_ERROR_1r(unit, &ser_err[1])); 1784 1785 if (!soc_reg_field_get(unit, SER_ERROR_0r, ser_err[0], ERROR_0_VALf) && 1786 !soc_reg_field_get(unit, SER_ERROR_1r, ser_err[1], ERROR_1_VALf)) { 1787 LOG_ERROR(BSL_LS_SOC_SER, 1788 (BSL_META_U(unit, 1789 "SER parity failure without valid error !!\n"))); 1790 return SOC_E_NONE; 1791 } 1792 do { 1793 if (soc_reg_field_get(unit, SER_ERROR_0r, ser_err[0], 1794 ERROR_0_VALf)) { 1795 SOC_IF_ERROR_RETURN 1796 (soc_mem_read(unit, SER_RESULT_0m, MEM_BLOCK_ANY, 1797 0, &err_result)); 1798 hw_ix = soc_mem_field32_get(unit, SER_RESULT_0m, 1799 &err_result, RANGEf); 1800 addr = soc_mem_field32_get(unit, SER_RESULT_0m, 1801 &err_result, SBUS_ADDRf); 1802 acc_type = soc_mem_field32_get(unit, SER_RESULT_0m, 1803 &err_result, ACC_TYPEf); 1804 SOC_IF_ERROR_RETURN(WRITE_SER_ERROR_0r(unit, 0)); 1805 } else { 1806 SOC_IF_ERROR_RETURN 1807 (soc_mem_read(unit, SER_RESULT_1m, MEM_BLOCK_ANY, 1808 0, &err_result)); 1809 hw_ix = soc_mem_field32_get(unit, SER_RESULT_1m, 1810 &err_result, RANGEf); 1811 addr = soc_mem_field32_get(unit, SER_RESULT_1m, 1812 &err_result, SBUS_ADDRf); 1813 acc_type = soc_mem_field32_get(unit, SER_RESULT_1m, 1814 &err_result, ACC_TYPEf); 1815 SOC_IF_ERROR_RETURN(WRITE_SER_ERROR_1r(unit, 0)); 1816 } 1817 1818 info_ix = 0; 1819 while (ser_info[info_ix].mem != INVALIDm) { 1820 if (0 == (ser_info[info_ix].ser_flags & _SOC_SER_FLAG_SW_COMPARE)) { 1821 if ((ser_info[info_ix].ser_hw_index != -1) && 1822 (ser_info[info_ix].ser_hw_index == hw_ix)) { 1823 break; 1824 } 1825 } 1826 info_ix++; 1827 } 1828 if (ser_info[info_ix].mem == INVALIDm) { 1829 LOG_ERROR(BSL_LS_SOC_SER, 1830 (BSL_META_U(unit, 1831 "SER parity failure with invalid mem range !!\n"))); 1832 return SOC_E_NONE; 1833 } 1834 cur_ser_info = &(ser_info[info_ix]); 1835 phys_index_min = index_min = 1836 soc_mem_index_min(unit, cur_ser_info->mem); 1837 phys_index_max = index_max = 1838 soc_mem_index_max(unit, cur_ser_info->mem); 1839 if (0 != (cur_ser_info->ser_flags & _SOC_SER_FLAG_REMAP_READ)) { 1840 #ifdef BCM_TRIDENT2_SUPPORT 1841 if (SOC_IS_TD2_TT2(unit)) { 1842 if (soc_feature(unit, soc_feature_l3_defip_map)) { 1843 /* coverity[Improper use of negative value]*/ 1844 phys_index_min = 1845 soc_trident2_l3_defip_index_map(unit, 1846 cur_ser_info->mem, 1847 index_min); 1848 /* coverity[Improper use of negative value]*/ 1849 phys_index_max = 1850 soc_trident2_l3_defip_index_map(unit, 1851 cur_ser_info->mem, 1852 index_max); 1853 } 1854 } 1855 #endif /* BCM_TRIDENT2_SUPPORT */ 1856 #ifdef BCM_APACHE_SUPPORT 1857 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)){ 1858 phys_index_min = 1859 soc_apache_l3_defip_index_map(unit, 1860 cur_ser_info->mem, 1861 index_min); 1862 phys_index_max = 1863 soc_apache_l3_defip_index_map(unit, 1864 cur_ser_info->mem, 1865 index_max); 1866 } 1867 #endif /* BCM_APACHE_SUPPORT */ 1868 #ifdef BCM_MONTEREY_SUPPORT 1869 if (SOC_IS_MONTEREY(unit)) { 1870 phys_index_min = 1871 soc_monterey_l3_defip_index_map(unit, 1872 cur_ser_info->mem, 1873 index_min); 1874 phys_index_max = 1875 soc_monterey_l3_defip_index_map(unit, 1876 cur_ser_info->mem, 1877 index_max); 1878 } 1879 #endif /* BCM_MONTEREY_SUPPORT */ 1880 #ifdef BCM_HELIX4_SUPPORT 1881 if (SOC_IS_HELIX4(unit)) { 1882 /* Helix4 uses the Triumph3 mapping logic */ 1883 phys_index_min = 1884 soc_tr3_l3_defip_index_map(unit, 1885 cur_ser_info->mem, 1886 index_min); 1887 phys_index_max = 1888 soc_tr3_l3_defip_index_map(unit, 1889 cur_ser_info->mem, 1890 index_max); 1891 } 1892 #endif /* BCM_HELIX4_SUPPORT */ 1893 #ifdef BCM_KATANA2_SUPPORT 1894 if (SOC_IS_KATANA2(unit)) { 1895 phys_index_min = 1896 soc_kt2_l3_defip_index_map(unit, 1897 cur_ser_info->mem, 1898 index_min); 1899 phys_index_max = 1900 soc_kt2_l3_defip_index_map(unit, 1901 cur_ser_info->mem, 1902 index_max); 1903 } 1904 #endif /* BCM_KATANA2_SUPPORT */ 1905 } 1906 ser_mem_count = phys_index_max - phys_index_min + 1; 1907 if (!ser_mem_count) { 1908 LOG_ERROR(BSL_LS_SOC_SER, 1909 (BSL_META_U(unit, 1910 "SER parity failure with unavailable mem range !!\n"))); 1911 return SOC_E_NONE; 1912 } 1913 SOC_MEM_BLOCK_ITER(unit, cur_ser_info->mem, copyno) { 1914 break; 1915 } 1916 start_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno, 1917 phys_index_min, &at); 1918 end_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno, 1919 phys_index_max, &at); 1920 if ((addr >= start_addr) && (addr <= end_addr)) { 1921 /* Addr in memory range */ 1922 mem_index = (addr - start_addr) + phys_index_min; 1923 if (0 != (cur_ser_info->ser_flags & _SOC_SER_FLAG_REMAP_READ)) { 1924 /* Now, mem_index is the physical index. 1925 * The correction routines expect the logical index. 1926 * Reverse the mapping. 1927 */ 1928 #ifdef BCM_APACHE_SUPPORT 1929 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 1930 mem_index = 1931 soc_apache_l3_defip_index_remap(unit, 1932 cur_ser_info->mem, 1933 mem_index); 1934 } 1935 #endif /* BCM_APACHE_SUPPORT */ 1936 #ifdef BCM_MONTEREY_SUPPORT 1937 if (SOC_IS_MONTEREY(unit)) { 1938 mem_index = 1939 soc_monterey_l3_defip_index_remap(unit, 1940 cur_ser_info->mem, 1941 mem_index); 1942 } 1943 #endif 1944 #ifdef BCM_HELIX4_SUPPORT 1945 if (SOC_IS_HELIX4(unit)) { 1946 /* Helix4 uses the Triumph3 remapping logic */ 1947 /* Coverity 1948 * return value of mem_index from TRIDENT2 1949 * case will not affect HELIX4_SUPPORT case 1950 */ 1951 /* coverity[negative_returns] */ 1952 mem_index = 1953 soc_tr3_l3_defip_index_remap(unit, 1954 cur_ser_info->mem, 1955 mem_index); 1956 } 1957 #endif /* BCM_HELIX4_SUPPORT */ 1958 #ifdef BCM_KATANA2_SUPPORT 1959 if (SOC_IS_KATANA2(unit)) { 1960 /* coverity[negative_returns] */ 1961 mem_index = 1962 soc_kt2_l3_defip_index_remap(unit, 1963 cur_ser_info->mem, 1964 mem_index); 1965 } 1966 #endif /* BCM_KATANA2_SUPPORT */ 1967 } 1968 1969 cur_mem = cur_ser_info->mem; 1970 #if defined(SOC_UNIQUE_ACC_TYPE_ACCESS) 1971 if ((cur_ser_info->ser_flags & _SOC_SER_FLAG_ACC_TYPE_CHK) && 1972 soc_feature(unit, soc_feature_unique_acc_type_access) && 1973 (SOC_MEM_UNIQUE_ACC(unit, cur_ser_info->mem) != NULL)) { 1974 cur_mem = SOC_MEM_UNIQUE_ACC(unit, 1975 cur_ser_info->mem)[acc_type]; 1976 if (!SOC_MEM_IS_VALID(unit, cur_mem)) { 1977 LOG_WARN(BSL_LS_SOC_SER, 1978 (BSL_META_U(unit, "Assume _PIPE0 view for ser_correction - could not find unique view for mem %s, acc_type %d \n"), 1979 SOC_MEM_NAME(unit, cur_ser_info->mem), acc_type)); 1980 cur_mem = SOC_MEM_UNIQUE_ACC( 1981 unit, cur_ser_info->mem)[0]; 1982 } 1983 } 1984 #endif /* SOC_UNIQUE_ACC_TYPE_ACCESS */ 1985 1986 #if defined(BCM_TRIDENT2_SUPPORT) 1987 if (SOC_IS_TD2_TT2(unit)) { 1988 if (cur_mem == L3_DEFIP_PAIR_128m || cur_mem == L3_DEFIPm) { 1989 /* We cannot be here for any L3_DEFIP_ALPM views or 1990 * for L3_DEFIP_AUX_TABLE views */ 1991 is_l3_defip = TRUE; 1992 _ALPM_LOCK(unit); 1993 } 1994 } 1995 #endif 1996 1997 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \ 1998 defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \ 1999 defined(BCM_GREYHOUND_SUPPORT) 2000 MEM_LOCK(unit, cur_mem); 2001 corrupt = SOC_MEM_STATE(unit, cur_mem).corrupt[copyno]; 2002 /* For L3_DEFIP* tables, we cannot use cache for SER correction on 2003 * multi-pipe devices. Because the data may be updated by H/W. 2004 */ 2005 if (is_l3_defip && NUM_PIPE(unit) > 1) { 2006 corrupt = NULL; 2007 } 2008 /* coverity[negative_shift] */ 2009 if ((corrupt == NULL) || (TCAM_CORRUPT_MAP_TST(corrupt, mem_index))) { 2010 #endif 2011 LOG_WARN(BSL_LS_SOC_SER, 2012 (BSL_META_U(unit, 2013 "Unit %d: %s entry %d TCAM parity error\n"), 2014 unit, SOC_MEM_NAME(unit, cur_mem), 2015 mem_index)); 2016 /* The value of err_type vary depending different chip since the 2017 * err_type is defined in the chip related code specially. The 2018 * original code just used the err_type as the event type directly, 2019 * as a result, the events reported in different chip are different. 2020 * In fact the only thing needed here is a 2021 * SOC_SWITCH_EVENT_DATA_ERROR_PARITY raised. 2022 * So err_type is never known. 2023 */ 2024 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2025 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, addr, 0); 2026 stat->ser_err_tcam++; 2027 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 2028 spci.reg = INVALIDr; 2029 spci.mem = cur_mem; 2030 spci.blk_type = copyno; 2031 spci.index = mem_index; 2032 spci.acc_type = acc_type; 2033 spci.addr = addr; 2034 2035 #if defined(BCM_TOMAHAWK_SUPPORT) 2036 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2037 if (acc_type <= _SOC_MEM_ADDR_ACC_TYPE_PIPE_3) { 2038 spci.pipe_num = acc_type; 2039 } else { 2040 spci.pipe_num = 0; 2041 } 2042 } else 2043 #endif /* BCM_TOMAHAWK_SUPPORT */ 2044 { 2045 spci.pipe_num = 2046 (_SOC_MEM_ADDR_ACC_TYPE_PIPE_Y == acc_type) ? 1 : 0; 2047 } 2048 spci.detect_time = sal_time_usecs(); 2049 spci.log_id = soc_ser_log_create_entry(unit, 2050 sizeof(soc_ser_log_tlv_generic_t) + 2051 sizeof(soc_ser_log_tlv_memory_t) + 2052 sizeof(soc_ser_log_tlv_hdr_t) *3); 2053 rv = soc_ser_correction(unit, &spci); 2054 if (spci.log_id != 0) { 2055 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2056 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 2057 spci.log_id, 0); 2058 } 2059 if (SOC_FAILURE(rv)) { 2060 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \ 2061 defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \ 2062 defined(BCM_GREYHOUND_SUPPORT) 2063 2064 MEM_UNLOCK(unit, cur_mem); 2065 #endif 2066 /* Report failed to correct event flag to 2067 * application */ 2068 soc_event_generate(unit, 2069 SOC_SWITCH_EVENT_PARITY_ERROR, 2070 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2071 addr, 2072 0); 2073 block_type = SOC_BLOCK_INFO(unit, copyno).type; 2074 soc_ser_stat_update(unit, SOC_SER_STAT_TCAM, block_type, 2075 SOC_PARITY_TYPE_PARITY, 2076 spci.double_bit, 2077 SocSerCorrectTypeFailedToCorrect, 2078 stat); 2079 _ALPM_UNLOCK(unit); 2080 return rv; 2081 } 2082 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HELIX4_SUPPORT) || \ 2083 defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \ 2084 defined(BCM_GREYHOUND_SUPPORT) 2085 /* Clear corrupt bit after correction, no matter how many times 2086 * the parity error at this index in this table has been detected. 2087 */ 2088 if (corrupt != NULL) { 2089 TCAM_CORRUPT_MAP_CLR(corrupt, mem_index); 2090 } 2091 LOG_VERBOSE(BSL_LS_SOC_SER, 2092 (BSL_META_U(unit, 2093 "Unit %d: %s entry %d TCAM parity error indicating bit is cleared.\n"), 2094 unit, SOC_MEM_NAME(unit, cur_mem), 2095 mem_index)); 2096 } 2097 MEM_UNLOCK(unit, cur_mem); 2098 #endif 2099 _ALPM_UNLOCK(unit); 2100 } 2101 SOC_IF_ERROR_RETURN(READ_SER_ERROR_0r(unit, &ser_err[0])); 2102 SOC_IF_ERROR_RETURN(READ_SER_ERROR_1r(unit, &ser_err[1])); 2103 } while (soc_reg_field_get(unit, SER_ERROR_0r, ser_err[0], ERROR_0_VALf) || 2104 soc_reg_field_get(unit, SER_ERROR_1r, ser_err[1], ERROR_1_VALf)); 2105 SOC_IF_ERROR_RETURN(READ_SER_MISSED_EVENTr(unit, &count)); 2106 if (count) { 2107 LOG_VERBOSE(BSL_LS_SOC_SER, 2108 (BSL_META_U(unit, 2109 "Overflow events: %d.\n"), count)); 2110 } 2111 return SOC_E_NONE; 2112 } 2113 2114 int 2115 soc_generic_ser_init(int unit, _soc_generic_ser_info_t *ser_info) 2116 { 2117 int info_ix, hw_ser_ix; 2118 int index_min=0, index_max=0, copyno, ser_mem_gran; 2119 int i = 0, ser_mem_count; 2120 uint32 rval = 0, start_addr, end_addr; 2121 uint32 addr_valid = 0, ser_mem_addr = 0, ser_mem_total = 0; 2122 uint32 acc_type, at_bmp; 2123 _soc_generic_ser_info_t *cur_ser_info; 2124 ser_memory_entry_t ser_mem; 2125 uint8 at, alias; 2126 2127 static soc_reg_t range_cfg[] = { 2128 SER_RANGE_0_CONFIGr, SER_RANGE_1_CONFIGr, SER_RANGE_2_CONFIGr, 2129 SER_RANGE_3_CONFIGr, 2130 SER_RANGE_4_CONFIGr, SER_RANGE_5_CONFIGr, SER_RANGE_6_CONFIGr, 2131 SER_RANGE_7_CONFIGr, 2132 SER_RANGE_8_CONFIGr, SER_RANGE_9_CONFIGr, SER_RANGE_10_CONFIGr, 2133 SER_RANGE_11_CONFIGr, 2134 SER_RANGE_12_CONFIGr, SER_RANGE_13_CONFIGr, SER_RANGE_14_CONFIGr, 2135 SER_RANGE_15_CONFIGr, 2136 SER_RANGE_16_CONFIGr, SER_RANGE_17_CONFIGr, SER_RANGE_18_CONFIGr, 2137 SER_RANGE_19_CONFIGr, 2138 SER_RANGE_20_CONFIGr, SER_RANGE_21_CONFIGr, SER_RANGE_22_CONFIGr, 2139 SER_RANGE_23_CONFIGr, 2140 SER_RANGE_24_CONFIGr, SER_RANGE_25_CONFIGr, SER_RANGE_26_CONFIGr, 2141 SER_RANGE_27_CONFIGr, 2142 SER_RANGE_28_CONFIGr, SER_RANGE_29_CONFIGr, SER_RANGE_30_CONFIGr, 2143 SER_RANGE_31_CONFIGr 2144 }; 2145 static soc_reg_t addr_mask[] = { 2146 SER_RANGE_0_ADDR_MASKr, SER_RANGE_1_ADDR_MASKr, SER_RANGE_2_ADDR_MASKr, 2147 SER_RANGE_3_ADDR_MASKr, 2148 SER_RANGE_4_ADDR_MASKr, SER_RANGE_5_ADDR_MASKr, SER_RANGE_6_ADDR_MASKr, 2149 SER_RANGE_7_ADDR_MASKr, 2150 SER_RANGE_8_ADDR_MASKr, SER_RANGE_9_ADDR_MASKr, SER_RANGE_10_ADDR_MASKr, 2151 SER_RANGE_11_ADDR_MASKr, 2152 SER_RANGE_12_ADDR_MASKr, SER_RANGE_13_ADDR_MASKr, SER_RANGE_14_ADDR_MASKr, 2153 SER_RANGE_15_ADDR_MASKr, 2154 SER_RANGE_16_ADDR_MASKr, SER_RANGE_17_ADDR_MASKr, SER_RANGE_18_ADDR_MASKr, 2155 SER_RANGE_19_ADDR_MASKr, 2156 SER_RANGE_20_ADDR_MASKr, SER_RANGE_21_ADDR_MASKr, SER_RANGE_22_ADDR_MASKr, 2157 SER_RANGE_23_ADDR_MASKr, 2158 SER_RANGE_24_ADDR_MASKr, SER_RANGE_25_ADDR_MASKr, SER_RANGE_26_ADDR_MASKr, 2159 SER_RANGE_27_ADDR_MASKr, 2160 SER_RANGE_28_ADDR_MASKr, SER_RANGE_29_ADDR_MASKr, SER_RANGE_30_ADDR_MASKr, 2161 SER_RANGE_31_ADDR_MASKr 2162 }; 2163 static soc_reg_t range_start[] = { 2164 SER_RANGE_0_STARTr, SER_RANGE_1_STARTr, SER_RANGE_2_STARTr, 2165 SER_RANGE_3_STARTr, 2166 SER_RANGE_4_STARTr, SER_RANGE_5_STARTr, SER_RANGE_6_STARTr, 2167 SER_RANGE_7_STARTr, 2168 SER_RANGE_8_STARTr, SER_RANGE_9_STARTr, SER_RANGE_10_STARTr, 2169 SER_RANGE_11_STARTr, 2170 SER_RANGE_12_STARTr, SER_RANGE_13_STARTr, SER_RANGE_14_STARTr, 2171 SER_RANGE_15_STARTr, 2172 SER_RANGE_16_STARTr, SER_RANGE_17_STARTr, SER_RANGE_18_STARTr, 2173 SER_RANGE_19_STARTr, 2174 SER_RANGE_20_STARTr, SER_RANGE_21_STARTr, SER_RANGE_22_STARTr, 2175 SER_RANGE_23_STARTr, 2176 SER_RANGE_24_STARTr, SER_RANGE_25_STARTr, SER_RANGE_26_STARTr, 2177 SER_RANGE_27_STARTr, 2178 SER_RANGE_28_STARTr, SER_RANGE_29_STARTr, SER_RANGE_30_STARTr, 2179 SER_RANGE_31_STARTr 2180 }; 2181 static soc_reg_t range_end[] = { 2182 SER_RANGE_0_ENDr, SER_RANGE_1_ENDr, SER_RANGE_2_ENDr, SER_RANGE_3_ENDr, 2183 SER_RANGE_4_ENDr, SER_RANGE_5_ENDr, SER_RANGE_6_ENDr, SER_RANGE_7_ENDr, 2184 SER_RANGE_8_ENDr, SER_RANGE_9_ENDr, SER_RANGE_10_ENDr, SER_RANGE_11_ENDr, 2185 SER_RANGE_12_ENDr, SER_RANGE_13_ENDr, SER_RANGE_14_ENDr, SER_RANGE_15_ENDr, 2186 SER_RANGE_16_ENDr, SER_RANGE_17_ENDr, SER_RANGE_18_ENDr, SER_RANGE_19_ENDr, 2187 SER_RANGE_20_ENDr, SER_RANGE_21_ENDr, SER_RANGE_22_ENDr, SER_RANGE_23_ENDr, 2188 SER_RANGE_24_ENDr, SER_RANGE_25_ENDr, SER_RANGE_26_ENDr, SER_RANGE_27_ENDr, 2189 SER_RANGE_28_ENDr, SER_RANGE_29_ENDr, SER_RANGE_30_ENDr, SER_RANGE_31_ENDr 2190 }; 2191 static soc_reg_t range_result[] = { 2192 SER_RANGE_0_RESULTr, SER_RANGE_1_RESULTr, SER_RANGE_2_RESULTr, 2193 SER_RANGE_3_RESULTr, 2194 SER_RANGE_4_RESULTr, SER_RANGE_5_RESULTr, SER_RANGE_6_RESULTr, 2195 SER_RANGE_7_RESULTr, 2196 SER_RANGE_8_RESULTr, SER_RANGE_9_RESULTr, SER_RANGE_10_RESULTr, 2197 SER_RANGE_11_RESULTr, 2198 SER_RANGE_12_RESULTr, SER_RANGE_13_RESULTr, SER_RANGE_14_RESULTr, 2199 SER_RANGE_15_RESULTr, 2200 SER_RANGE_16_RESULTr, SER_RANGE_17_RESULTr, SER_RANGE_18_RESULTr, 2201 SER_RANGE_19_RESULTr, 2202 SER_RANGE_20_RESULTr, SER_RANGE_21_RESULTr, SER_RANGE_22_RESULTr, 2203 SER_RANGE_23_RESULTr, 2204 SER_RANGE_24_RESULTr, SER_RANGE_25_RESULTr, SER_RANGE_26_RESULTr, 2205 SER_RANGE_27_RESULTr, 2206 SER_RANGE_28_RESULTr, SER_RANGE_29_RESULTr, SER_RANGE_30_RESULTr, 2207 SER_RANGE_31_RESULTr 2208 }; 2209 static soc_reg_t prot_word[][SOC_NUM_GENERIC_PROT_SECTIONS] = { 2210 { SER_RANGE_0_PROT_WORD_0r, SER_RANGE_0_PROT_WORD_1r, 2211 SER_RANGE_0_PROT_WORD_2r, SER_RANGE_0_PROT_WORD_3r }, 2212 { SER_RANGE_1_PROT_WORD_0r, SER_RANGE_1_PROT_WORD_1r, 2213 SER_RANGE_1_PROT_WORD_2r, SER_RANGE_1_PROT_WORD_3r }, 2214 { SER_RANGE_2_PROT_WORD_0r, SER_RANGE_2_PROT_WORD_1r, 2215 SER_RANGE_2_PROT_WORD_2r, SER_RANGE_2_PROT_WORD_3r }, 2216 { SER_RANGE_3_PROT_WORD_0r, SER_RANGE_3_PROT_WORD_1r, 2217 SER_RANGE_3_PROT_WORD_2r, SER_RANGE_3_PROT_WORD_3r }, 2218 { SER_RANGE_4_PROT_WORD_0r, SER_RANGE_4_PROT_WORD_1r, 2219 SER_RANGE_4_PROT_WORD_2r, SER_RANGE_4_PROT_WORD_3r }, 2220 { SER_RANGE_5_PROT_WORD_0r, SER_RANGE_5_PROT_WORD_1r, 2221 SER_RANGE_5_PROT_WORD_2r, SER_RANGE_5_PROT_WORD_3r }, 2222 { SER_RANGE_6_PROT_WORD_0r, SER_RANGE_6_PROT_WORD_1r, 2223 SER_RANGE_6_PROT_WORD_2r, SER_RANGE_6_PROT_WORD_3r }, 2224 { SER_RANGE_7_PROT_WORD_0r, SER_RANGE_7_PROT_WORD_1r, 2225 SER_RANGE_7_PROT_WORD_2r, SER_RANGE_7_PROT_WORD_3r }, 2226 { SER_RANGE_8_PROT_WORD_0r, SER_RANGE_8_PROT_WORD_1r, 2227 SER_RANGE_8_PROT_WORD_2r, SER_RANGE_8_PROT_WORD_3r }, 2228 { SER_RANGE_9_PROT_WORD_0r, SER_RANGE_9_PROT_WORD_1r, 2229 SER_RANGE_9_PROT_WORD_2r, SER_RANGE_9_PROT_WORD_3r }, 2230 { SER_RANGE_10_PROT_WORD_0r, SER_RANGE_10_PROT_WORD_1r, 2231 SER_RANGE_10_PROT_WORD_2r, SER_RANGE_10_PROT_WORD_3r }, 2232 { SER_RANGE_11_PROT_WORD_0r, SER_RANGE_11_PROT_WORD_1r, 2233 SER_RANGE_11_PROT_WORD_2r, SER_RANGE_11_PROT_WORD_3r }, 2234 { SER_RANGE_12_PROT_WORD_0r, SER_RANGE_12_PROT_WORD_1r, 2235 SER_RANGE_12_PROT_WORD_2r, SER_RANGE_12_PROT_WORD_3r }, 2236 { SER_RANGE_13_PROT_WORD_0r, SER_RANGE_13_PROT_WORD_1r, 2237 SER_RANGE_13_PROT_WORD_2r, SER_RANGE_13_PROT_WORD_3r }, 2238 { SER_RANGE_14_PROT_WORD_0r, SER_RANGE_14_PROT_WORD_1r, 2239 SER_RANGE_14_PROT_WORD_2r, SER_RANGE_14_PROT_WORD_3r }, 2240 { SER_RANGE_15_PROT_WORD_0r, SER_RANGE_15_PROT_WORD_1r, 2241 SER_RANGE_15_PROT_WORD_2r, SER_RANGE_15_PROT_WORD_3r }, 2242 { SER_RANGE_16_PROT_WORD_0r, SER_RANGE_16_PROT_WORD_1r, 2243 SER_RANGE_16_PROT_WORD_2r, SER_RANGE_16_PROT_WORD_3r }, 2244 { SER_RANGE_17_PROT_WORD_0r, SER_RANGE_17_PROT_WORD_1r, 2245 SER_RANGE_17_PROT_WORD_2r, SER_RANGE_17_PROT_WORD_3r }, 2246 { SER_RANGE_18_PROT_WORD_0r, SER_RANGE_18_PROT_WORD_1r, 2247 SER_RANGE_18_PROT_WORD_2r, SER_RANGE_18_PROT_WORD_3r }, 2248 { SER_RANGE_19_PROT_WORD_0r, SER_RANGE_19_PROT_WORD_1r, 2249 SER_RANGE_19_PROT_WORD_2r, SER_RANGE_19_PROT_WORD_3r }, 2250 { SER_RANGE_20_PROT_WORD_0r, SER_RANGE_20_PROT_WORD_1r, 2251 SER_RANGE_20_PROT_WORD_2r, SER_RANGE_20_PROT_WORD_3r }, 2252 { SER_RANGE_21_PROT_WORD_0r, SER_RANGE_21_PROT_WORD_1r, 2253 SER_RANGE_21_PROT_WORD_2r, SER_RANGE_21_PROT_WORD_3r }, 2254 { SER_RANGE_22_PROT_WORD_0r, SER_RANGE_22_PROT_WORD_1r, 2255 SER_RANGE_22_PROT_WORD_2r, SER_RANGE_22_PROT_WORD_3r }, 2256 { SER_RANGE_23_PROT_WORD_0r, SER_RANGE_23_PROT_WORD_1r, 2257 SER_RANGE_23_PROT_WORD_2r, SER_RANGE_23_PROT_WORD_3r }, 2258 { SER_RANGE_24_PROT_WORD_0r, SER_RANGE_24_PROT_WORD_1r, 2259 SER_RANGE_24_PROT_WORD_2r, SER_RANGE_24_PROT_WORD_3r }, 2260 { SER_RANGE_25_PROT_WORD_0r, SER_RANGE_25_PROT_WORD_1r, 2261 SER_RANGE_25_PROT_WORD_2r, SER_RANGE_25_PROT_WORD_3r }, 2262 { SER_RANGE_26_PROT_WORD_0r, SER_RANGE_26_PROT_WORD_1r, 2263 SER_RANGE_26_PROT_WORD_2r, SER_RANGE_26_PROT_WORD_3r }, 2264 { SER_RANGE_27_PROT_WORD_0r, SER_RANGE_27_PROT_WORD_1r, 2265 SER_RANGE_27_PROT_WORD_2r, SER_RANGE_27_PROT_WORD_3r }, 2266 { SER_RANGE_28_PROT_WORD_0r, SER_RANGE_28_PROT_WORD_1r, 2267 SER_RANGE_28_PROT_WORD_2r, SER_RANGE_28_PROT_WORD_3r }, 2268 { SER_RANGE_29_PROT_WORD_0r, SER_RANGE_29_PROT_WORD_1r, 2269 SER_RANGE_29_PROT_WORD_2r, SER_RANGE_29_PROT_WORD_3r }, 2270 { SER_RANGE_30_PROT_WORD_0r, SER_RANGE_30_PROT_WORD_1r, 2271 SER_RANGE_30_PROT_WORD_2r, SER_RANGE_30_PROT_WORD_3r }, 2272 { SER_RANGE_31_PROT_WORD_0r, SER_RANGE_31_PROT_WORD_1r, 2273 SER_RANGE_31_PROT_WORD_2r, SER_RANGE_31_PROT_WORD_3r } 2274 }; 2275 2276 static soc_reg_t range_addr_bits[] = { 2277 SER_RANGE_0_ADDR_BITSr, SER_RANGE_1_ADDR_BITSr, 2278 SER_RANGE_2_ADDR_BITSr, SER_RANGE_3_ADDR_BITSr, 2279 SER_RANGE_4_ADDR_BITSr, SER_RANGE_5_ADDR_BITSr, 2280 SER_RANGE_6_ADDR_BITSr, SER_RANGE_7_ADDR_BITSr, 2281 SER_RANGE_8_ADDR_BITSr, SER_RANGE_9_ADDR_BITSr, 2282 SER_RANGE_10_ADDR_BITSr, SER_RANGE_11_ADDR_BITSr, 2283 SER_RANGE_12_ADDR_BITSr, SER_RANGE_13_ADDR_BITSr, 2284 SER_RANGE_14_ADDR_BITSr, SER_RANGE_15_ADDR_BITSr, 2285 SER_RANGE_16_ADDR_BITSr, SER_RANGE_17_ADDR_BITSr, 2286 SER_RANGE_18_ADDR_BITSr, SER_RANGE_19_ADDR_BITSr, 2287 SER_RANGE_20_ADDR_BITSr, SER_RANGE_21_ADDR_BITSr, 2288 SER_RANGE_22_ADDR_BITSr, SER_RANGE_23_ADDR_BITSr, 2289 SER_RANGE_24_ADDR_BITSr, SER_RANGE_25_ADDR_BITSr, 2290 SER_RANGE_26_ADDR_BITSr, SER_RANGE_27_ADDR_BITSr, 2291 SER_RANGE_28_ADDR_BITSr, SER_RANGE_29_ADDR_BITSr, 2292 SER_RANGE_30_ADDR_BITSr, SER_RANGE_31_ADDR_BITSr 2293 }; 2294 2295 static soc_reg_t range_disable[] = { 2296 SER_RANGE_0_DISABLEr, SER_RANGE_1_DISABLEr, 2297 SER_RANGE_2_DISABLEr, SER_RANGE_3_DISABLEr, 2298 SER_RANGE_4_DISABLEr, SER_RANGE_5_DISABLEr, 2299 SER_RANGE_6_DISABLEr, SER_RANGE_7_DISABLEr, 2300 SER_RANGE_8_DISABLEr, SER_RANGE_9_DISABLEr, 2301 SER_RANGE_10_DISABLEr, SER_RANGE_11_DISABLEr, 2302 SER_RANGE_12_DISABLEr, SER_RANGE_13_DISABLEr, 2303 SER_RANGE_14_DISABLEr, SER_RANGE_15_DISABLEr, 2304 SER_RANGE_16_DISABLEr, SER_RANGE_17_DISABLEr, 2305 SER_RANGE_18_DISABLEr, SER_RANGE_19_DISABLEr, 2306 SER_RANGE_20_DISABLEr, SER_RANGE_21_DISABLEr, 2307 SER_RANGE_22_DISABLEr, SER_RANGE_23_DISABLEr, 2308 SER_RANGE_24_DISABLEr, SER_RANGE_25_DISABLEr, 2309 SER_RANGE_26_DISABLEr, SER_RANGE_27_DISABLEr, 2310 SER_RANGE_28_DISABLEr, SER_RANGE_29_DISABLEr, 2311 SER_RANGE_30_DISABLEr, SER_RANGE_31_DISABLEr 2312 }; 2313 2314 LOG_VERBOSE(BSL_LS_SOC_SER, 2315 (BSL_META_U(unit, 2316 "SER engine init:\n"))); 2317 2318 info_ix = 0; 2319 hw_ser_ix = 0; 2320 sal_memset(&ser_mem, 0, sizeof(ser_mem)); 2321 /* Clear parity/ecc memory */ 2322 if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) { 2323 SOC_IF_ERROR_RETURN 2324 (soc_mem_clear(unit, SER_MEMORYm, COPYNO_ALL, TRUE)); 2325 } 2326 while (ser_info[info_ix].mem != INVALIDm) { 2327 alias = FALSE; 2328 cur_ser_info = &(ser_info[info_ix]); 2329 cur_ser_info->ser_hw_index = -1; 2330 if ((info_ix > 0) && 2331 (cur_ser_info->ser_flags & _SOC_SER_FLAG_CONFIG_SKIP)) { 2332 /* This entry does not require separate range in ser_engine. 2333 * But, this entry is used by memscan and therefore must have all 2334 * the info needed by memscan. 2335 * This entry should inherit property of previous entry as they map 2336 * to same range in ser_engine */ 2337 cur_ser_info->ser_section_start = 2338 ser_info[info_ix - 1].ser_section_start; 2339 cur_ser_info->ser_section_end = 2340 ser_info[info_ix - 1].ser_section_end; 2341 cur_ser_info->ser_hw_index = 2342 ser_info[info_ix - 1].ser_hw_index; 2343 info_ix++; 2344 continue; 2345 } 2346 2347 if (cur_ser_info->ser_flags & _SOC_SER_FLAG_SW_COMPARE) { 2348 if (SOC_MEM_INFO(unit, cur_ser_info->mem).flags & 2349 SOC_MEM_FLAG_BE) { 2350 LOG_ERROR(BSL_LS_SOC_SER, 2351 (BSL_META_U(unit, 2352 "\tSW SER init of Big Endian TCAMs is not supported: %s\n"), 2353 SOC_MEM_NAME(unit, cur_ser_info->mem))); 2354 return SOC_E_INTERNAL; 2355 } 2356 2357 LOG_VERBOSE(BSL_LS_SOC_SER, 2358 (BSL_META_U(unit, 2359 "\tSkipping HW SER init of manual scan mem: %s\n"), 2360 SOC_MEM_NAME(unit, cur_ser_info->mem))); 2361 SOC_MEM_INFO(unit, ser_info[info_ix].mem).flags |= SOC_MEM_FLAG_SER_ENGINE; 2362 info_ix++; 2363 continue; 2364 } 2365 index_min = soc_mem_index_min(unit, cur_ser_info->mem); 2366 index_max = soc_mem_index_max(unit, cur_ser_info->mem); 2367 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 2368 if (soc_feature(unit, soc_feature_l3_defip_map) && 2369 ((cur_ser_info->mem == L3_DEFIP_PAIR_128m) || 2370 (cur_ser_info->mem == L3_DEFIPm))) { 2371 /* Override SOC memory impression for overlay 2372 * LPM tables. */ 2373 index_min = 0; 2374 index_max = (SOC_CONTROL(unit)->l3_defip_max_tcams * 2375 SOC_CONTROL(unit)->l3_defip_tcam_size) - 1; 2376 if (cur_ser_info->mem == L3_DEFIP_PAIR_128m) { 2377 index_max /= 2; 2378 } 2379 } 2380 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT*/ 2381 2382 ser_mem_count = index_max - index_min + 1; 2383 if (!ser_mem_count || !SOC_MEM_IS_VALID(unit, cur_ser_info->mem)) { 2384 LOG_VERBOSE(BSL_LS_SOC_SER, 2385 (BSL_META_U(unit, 2386 "\tSkipping empty mem: %s\n"), 2387 SOC_MEM_NAME(unit, cur_ser_info->mem))); 2388 #if defined(BCM_TOMAHAWK_SUPPORT) 2389 if (SOC_IS_TOMAHAWKX(unit)) { 2390 /* For different latency modes, we want to keep constant map 2391 * between info_ix and hw_ser_ix. In other words, if some mem 2392 * is not enabled in lower latency mode, we want to keep the 2393 * bit position for that mem in SER_RANGE_ENABLE constant 2394 * - because in tomahawk/ser.c, this bit position is hard-coded 2395 * based on max_latency_mode. Otherwise, we will have to keep 2396 * track of this position for mem based on latency modes. 2397 */ 2398 LOG_VERBOSE(BSL_LS_SOC_SER, 2399 (BSL_META_U(unit, 2400 "\tRange[%2d](0x%04x, %08d): %s(%d-%d): " 2401 "Sbus range (0x%08x-0x%08x), info_ix=%d, <======= skipped\n"), 2402 hw_ser_ix, 0, 0, 2403 SOC_MEM_NAME(unit, cur_ser_info->mem), 2404 index_min, index_max, 0, 0, info_ix)); 2405 hw_ser_ix++; 2406 } 2407 #endif 2408 info_ix++; 2409 continue; 2410 } 2411 2412 ser_mem_gran = _soc_generic_ser_granularity(cur_ser_info->prot_type, 2413 cur_ser_info->prot_mode, 2414 cur_ser_info->start_end_bits); 2415 ser_mem_count *= ser_mem_gran; 2416 2417 /* Round up to entry size for simplicity */ 2418 ser_mem_count = ((ser_mem_count + 31) / 32); /* Changed from 36 per DE input */ 2419 2420 if (cur_ser_info->alias_mem != INVALIDm) { 2421 /* See if the aliased memory has already been configured */ 2422 for (i = 0; i < info_ix; i++) { 2423 if (ser_info[i].mem == cur_ser_info->alias_mem) { 2424 LOG_VERBOSE(BSL_LS_SOC_SER, 2425 (BSL_META_U(unit, 2426 "\tSER alias mem.\n"))); 2427 alias = TRUE; 2428 break; 2429 } 2430 } 2431 } 2432 2433 if (!alias && (cur_ser_info->ser_flags & _SOC_SER_FLAG_ACC_TYPE_CHK)) { 2434 ser_mem_count *= cur_ser_info->num_instances; 2435 } 2436 2437 if (!alias && 2438 (cur_ser_info->ser_flags & _SOC_SER_FLAG_MULTI_PIPE)) { 2439 i = info_ix - 1; 2440 if ((i >= 0) && (ser_info[i].mem == cur_ser_info->mem) && 2441 !(ser_info[i].ser_flags & _SOC_SER_FLAG_CONFIG_SKIP)) { 2442 /* For multiple pipeline units, different pipeline's hardware 2443 * instances are duplicates. The SER parity bits are thus 2444 * shared, but the configuration registers in the CMIC 2445 * must be different to capture the different SBUS ranges 2446 * of the read accesses. 2447 */ 2448 LOG_VERBOSE(BSL_LS_SOC_SER, 2449 (BSL_META_U(unit, 2450 "\tSER multiple pipeline mem.\n"))); 2451 /* Get the non-default pipeline access type */ 2452 acc_type = cur_ser_info->ser_flags & 2453 _SOC_SER_FLAG_ACC_TYPE_MASK; 2454 2455 /* Copy info for mem clear */ 2456 cur_ser_info->ser_section_start = 2457 ser_info[i].ser_section_start; 2458 cur_ser_info->ser_section_end = 2459 ser_info[i].ser_section_end; 2460 cur_ser_info->ser_hw_index = 2461 ser_info[i].ser_hw_index; 2462 2463 /* For multi-pipe, we can use the access type bitmap 2464 * point multiple SBUS accesses to the same HW 2465 * range checker. 2466 * The HW index advanced when the first entry was set, 2467 * so we need to use the previous valid HW index. */ 2468 if (0 == hw_ser_ix) { 2469 return SOC_E_INTERNAL; 2470 } 2471 SOC_IF_ERROR_RETURN 2472 (soc_reg32_set(unit, range_cfg[hw_ser_ix - 1], 2473 REG_PORT_ANY, 0, rval)); 2474 at_bmp = 2475 soc_reg_field_get(unit, SER_RANGE_0_CONFIGr, rval, 2476 ACC_TYPEf); 2477 at_bmp |= (1 << acc_type); 2478 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, 2479 ACC_TYPEf, at_bmp); 2480 SOC_IF_ERROR_RETURN 2481 (soc_reg32_set(unit, range_cfg[hw_ser_ix - 1], 2482 REG_PORT_ANY, 0, rval)); 2483 info_ix++; 2484 /* Don't advance hw_ser_ix again in case of designs with 2485 * more than two pipes */ 2486 continue; 2487 } 2488 } 2489 2490 if (!alias && ((ser_mem_count + ser_mem_total) > 2491 soc_mem_index_count(unit, SER_MEMORYm))) { 2492 /* Can't fit requested parity bits in SER memory */ 2493 LOG_VERBOSE(BSL_LS_SOC_SER, 2494 (BSL_META_U(unit, 2495 "SER mem full: Skipping further config.\n"))); 2496 break; 2497 } 2498 2499 /* Parity bits fit, so on with the config */ 2500 SOC_MEM_BLOCK_ITER(unit, cur_ser_info->mem, copyno) { 2501 break; 2502 } 2503 start_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno, 2504 index_min, &at); 2505 end_addr = soc_mem_addr_get(unit, cur_ser_info->mem, 0, copyno, 2506 index_max, &at); 2507 2508 /* Flush SER memory if not aliased */ 2509 ser_mem_addr = alias ? ser_info[i].ser_section_start : 2510 ser_mem_total; /* Previous total */ 2511 if (alias) { 2512 LOG_VERBOSE(BSL_LS_SOC_SER, 2513 (BSL_META_U(unit, 2514 "\tReuse SER_MEM (%d) from index: %d - %d\n"), 2515 ser_mem_count, ser_info[i].ser_section_start, 2516 ser_info[i].ser_section_end)); 2517 } else { 2518 ser_mem_total += ser_mem_count; /* New total */ 2519 LOG_VERBOSE(BSL_LS_SOC_SER, 2520 (BSL_META_U(unit, 2521 "\tClear SER_MEM (%d) from index: %d - %d\n"), 2522 ser_mem_count, ser_mem_addr, ser_mem_total-1)); 2523 for (i = ser_mem_addr; i < ser_mem_total; i++) { 2524 /* mem clear */ 2525 SOC_IF_ERROR_RETURN 2526 (WRITE_SER_MEMORYm(unit, MEM_BLOCK_ALL, i, &ser_mem)); 2527 } 2528 } 2529 2530 /* Record section for mem_clear use */ 2531 cur_ser_info->ser_section_start = ser_mem_addr; 2532 cur_ser_info->ser_section_end = alias ? ser_info[i].ser_section_end : 2533 (ser_mem_total-1); 2534 cur_ser_info->ser_hw_index = hw_ser_ix; 2535 2536 SOC_IF_ERROR_RETURN 2537 (soc_reg32_set(unit, range_start[hw_ser_ix], REG_PORT_ANY, 0, 2538 start_addr)); 2539 SOC_IF_ERROR_RETURN 2540 (soc_reg32_set(unit, range_end[hw_ser_ix], REG_PORT_ANY, 0, 2541 end_addr)); 2542 if (SOC_REG_IS_VALID(unit, range_disable[0])) { 2543 if (cur_ser_info->ser_flags & _SOC_SER_FLAG_RANGE_DISABLE) { 2544 SOC_IF_ERROR_RETURN 2545 (soc_reg32_set(unit, range_addr_bits[hw_ser_ix], REG_PORT_ANY, 0, 2546 cur_ser_info->addr_start_bit)); 2547 SOC_IF_ERROR_RETURN 2548 (soc_reg32_set(unit, range_disable[hw_ser_ix], REG_PORT_ANY, 0, 2549 cur_ser_info->addr_mask)); 2550 } 2551 } else { 2552 SOC_IF_ERROR_RETURN 2553 (soc_reg32_set(unit, addr_mask[hw_ser_ix], REG_PORT_ANY, 0, 2554 cur_ser_info->addr_mask ? 2555 cur_ser_info->addr_mask : 0xffffffff)); 2556 } 2557 SOC_IF_ERROR_RETURN 2558 (soc_reg32_set(unit, range_result[hw_ser_ix], REG_PORT_ANY, 0, 2559 ser_mem_addr)); 2560 if ((!(cur_ser_info->ser_flags & _SOC_SER_FLAG_VIEW_DISABLE)) && 2561 (!(SOC_MEM_INFO(unit, cur_ser_info->mem).flags & 2562 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP))) { 2563 addr_valid |= (1 << hw_ser_ix); 2564 } 2565 2566 for (i = 0; i < SOC_NUM_GENERIC_PROT_SECTIONS; i++) { 2567 if (cur_ser_info->start_end_bits[i].start_bit != -1) { 2568 rval = 0; 2569 soc_reg_field_set(unit, SER_RANGE_0_PROT_WORD_0r, &rval, 2570 DATA_STARTf, 2571 cur_ser_info->start_end_bits[i].start_bit); 2572 soc_reg_field_set(unit, SER_RANGE_0_PROT_WORD_0r, &rval, 2573 DATA_ENDf, 2574 cur_ser_info->start_end_bits[i].end_bit); 2575 SOC_IF_ERROR_RETURN 2576 (soc_reg32_set(unit, prot_word[hw_ser_ix][i], 2577 REG_PORT_ANY, 0, rval)); 2578 } 2579 } 2580 rval = 0; 2581 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, BLOCKf, 2582 SOC_BLOCK2SCH(unit, copyno)); 2583 if (soc_reg_field_valid(unit, SER_RANGE_0_CONFIGr, ACC_TYPEf)) { 2584 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, ACC_TYPEf, 2585 1 << at); 2586 } 2587 #if defined(BCM_TOMAHAWK_SUPPORT) 2588 if (soc_reg_field_valid(unit, SER_RANGE_0_CONFIGr, ACC_TYPE_MODEf)) { 2589 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, ACC_TYPE_MODEf, 2590 (cur_ser_info->ser_flags & _SOC_SER_FLAG_ACC_TYPE_CHK)? 1 : 0); 2591 } 2592 #endif /* BCM_TOMAHAWK_SUPPORT */ 2593 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, PROT_TYPEf, 2594 cur_ser_info->prot_type); 2595 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, PROT_MODEf, 2596 cur_ser_info->prot_mode); 2597 soc_reg_field_set(unit, SER_RANGE_0_CONFIGr, &rval, INTERLEAVE_MODEf, 2598 cur_ser_info->intrlv_mode); 2599 SOC_IF_ERROR_RETURN 2600 (soc_reg32_set(unit, range_cfg[hw_ser_ix], REG_PORT_ANY, 0, rval)); 2601 2602 LOG_VERBOSE(BSL_LS_SOC_SER, 2603 (BSL_META_U(unit, 2604 "\tRange[%2d](0x%04x, %08d): %s(%d-%d): " 2605 "Sbus range (0x%08x-0x%08x), info_ix=%d\n"), 2606 hw_ser_ix, ser_mem_addr, ser_mem_addr, 2607 SOC_MEM_NAME(unit, cur_ser_info->mem), 2608 index_min, index_max, start_addr, end_addr, info_ix)); 2609 SOC_MEM_INFO(unit, ser_info[info_ix].mem).flags |= SOC_MEM_FLAG_SER_ENGINE; 2610 #if defined(SOC_UNIQUE_ACC_TYPE_ACCESS) 2611 if (soc_feature(unit, soc_feature_unique_acc_type_access) && 2612 (SOC_MEM_UNIQUE_ACC(unit, ser_info[info_ix].mem) != NULL)) { 2613 int pipe; 2614 soc_mem_t mem1 = ser_info[info_ix].mem; 2615 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2616 SOC_MEM_INFO(unit, 2617 SOC_MEM_UNIQUE_ACC(unit, mem1)[pipe] 2618 ).flags |= SOC_MEM_FLAG_SER_ENGINE; 2619 } 2620 /* Non-tcam-iterations loop should also skip the _PIPE0,1,2,3,etc 2621 * views */ 2622 } 2623 #endif /* SOC_UNIQUE_ACC_TYPE_ACCESS */ 2624 info_ix++; 2625 hw_ser_ix++; 2626 } 2627 2628 SOC_IF_ERROR_RETURN 2629 (WRITE_SER_RING_ERR_CTRLr(unit, 0xf)); 2630 /* Enable SER protection last */ 2631 SOC_IF_ERROR_RETURN 2632 (WRITE_SER_RANGE_ENABLEr(unit, addr_valid)); 2633 if (soc_feature(unit, soc_feature_ser_hw_bg_read)) { 2634 SOC_IF_ERROR_RETURN 2635 (WRITE_SER_CONFIG_REGr(unit, 0x3)); 2636 } else { 2637 SOC_IF_ERROR_RETURN 2638 (WRITE_SER_CONFIG_REGr(unit, 0x1)); 2639 } 2640 /* Kick off s/w background scan if applicable */ 2641 if (!soc_feature(unit, soc_feature_ser_hw_bg_read)) { 2642 2643 } 2644 return SOC_E_NONE; 2645 } 2646 2647 int 2648 soc_generic_ser_at_map_init(int unit, uint32 map[], int items) 2649 { 2650 int i = 0; 2651 uint32 fld_val; 2652 ser_acc_type_map_entry_t ser_acc_type; 2653 2654 if (items > soc_mem_index_count(unit, SER_ACC_TYPE_MAPm)) { 2655 return SOC_E_PARAM; 2656 } 2657 while (items--) { 2658 sal_memset(&ser_acc_type, 0, sizeof(ser_acc_type)); 2659 fld_val = map[i]; 2660 soc_mem_field_set(unit, SER_ACC_TYPE_MAPm, 2661 (uint32 *)&ser_acc_type, COMPRESSED_ACC_TYPEf, &fld_val); 2662 SOC_IF_ERROR_RETURN 2663 (soc_mem_write(unit, SER_ACC_TYPE_MAPm, MEM_BLOCK_ALL, i++, 2664 &ser_acc_type)); 2665 } 2666 return SOC_E_NONE; 2667 } 2668 2669 int 2670 soc_generic_ser_mem_scan_start(int unit) 2671 { 2672 #ifdef INCLUDE_MEM_SCAN 2673 /* Kick off s/w background scan */ 2674 if (soc_property_get(unit, spn_MEM_SCAN_ENABLE, 2675 (SAL_BOOT_SIMULATION || SOC_IS_TOMAHAWK3(unit)) ? 0 : 1)) { 2676 sal_usecs_t interval = 0; 2677 int rate = 0; 2678 2679 if (soc_mem_scan_running(unit, &rate, &interval)) { 2680 if (soc_mem_scan_stop(unit)) { 2681 return SOC_E_INTERNAL; 2682 } 2683 } 2684 rate = rate ? rate : soc_property_get(unit, spn_MEM_SCAN_RATE, 2685 SOC_MEMSCAN_RATE_DEFAULT); 2686 interval = interval ? interval : 2687 soc_property_get(unit, spn_MEM_SCAN_INTERVAL, 2688 SAL_BOOT_SIMULATION ? SOC_MEMSCAN_INTERVAL_SIM_DEFAULT : 2689 SOC_MEMSCAN_INTERVAL_DEFAULT); 2690 if (soc_mem_scan_start(unit, rate, interval)) { 2691 return SOC_E_INTERNAL; 2692 } 2693 } 2694 #endif /* INCLUDE_MEM_SCAN */ 2695 return SOC_E_NONE; 2696 } 2697 2698 int 2699 soc_generic_sram_mem_scan_start(int unit) 2700 { 2701 #ifdef BCM_SRAM_SCAN_SUPPORT 2702 if (soc_property_get(unit, spn_SRAM_SCAN_ENABLE, SAL_BOOT_SIMULATION ? 0 : 2703 (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) 2704 || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)))) { 2705 sal_usecs_t interval = 0; 2706 int rate = 0; 2707 2708 if (soc_sram_scan_running(unit, &rate, &interval)) { 2709 if (soc_sram_scan_stop(unit)) { 2710 return SOC_E_INTERNAL; 2711 } 2712 } 2713 rate = rate ? rate : soc_property_get(unit, spn_SRAM_SCAN_RATE, 2714 SOC_SRAMSCAN_RATE_DEFAULT); 2715 interval = interval ? interval : 2716 soc_property_get(unit, spn_SRAM_SCAN_INTERVAL, 2717 SAL_BOOT_SIMULATION ? SOC_SRAMSCAN_INTERVAL_SIM_DEFAULT : 2718 SOC_SRAMSCAN_INTERVAL_DEFAULT); 2719 if (soc_sram_scan_start(unit, rate, interval)) { 2720 return SOC_E_INTERNAL; 2721 } 2722 } 2723 #endif 2724 return SOC_E_NONE; 2725 } 2726 2727 int 2728 soc_generic_ser_mem_scan_stop(int unit) 2729 { 2730 #ifdef INCLUDE_MEM_SCAN 2731 sal_usecs_t interval = 0; 2732 int rate = 0; 2733 2734 if (soc_mem_scan_running(unit, &rate, &interval)) { 2735 if (soc_mem_scan_stop(unit)) { 2736 return SOC_E_INTERNAL; 2737 } 2738 } 2739 #endif /* INCLUDE_MEM_SCAN */ 2740 return SOC_E_NONE; 2741 } 2742 2743 int 2744 soc_generic_sram_mem_scan_stop(int unit) 2745 { 2746 #ifdef BCM_SRAM_SCAN_SUPPORT 2747 sal_usecs_t interval = 0; 2748 int rate = 0; 2749 2750 if (soc_sram_scan_running(unit, &rate, &interval)) { 2751 if (soc_sram_scan_stop(unit)) { 2752 return SOC_E_INTERNAL; 2753 } 2754 } 2755 #endif /* INCLUDE_SRAM_SCAN */ 2756 return SOC_E_NONE; 2757 } 2758 2759 int 2760 soc_generic_ser_mem_update(int unit, soc_mem_t mem, int stage, int mode) 2761 { 2762 int rv = SOC_E_NONE; 2763 #ifdef INCLUDE_MEM_SCAN 2764 int i, info_ix = 0, hw_ser_ix = 0; 2765 _soc_generic_ser_info_t *ser_info; 2766 uint32 range_enable; 2767 2768 /* 1. It is possible that mem is marked invalid due to latency mode (eg: TH) 2769 * 2. It is possible that parity is disabled for this mem by property */ 2770 if (!SOC_MEM_IS_VALID(unit, mem) || 2771 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)) { 2772 LOG_VERBOSE(BSL_LS_SOC_SER, 2773 (BSL_META_U(unit, "mem_update DISABLED for mem = %s as " 2774 "mem is INVALID or parity is disabled by config property \n"), 2775 SOC_MEM_NAME(unit,mem))); 2776 return rv; 2777 } 2778 2779 if (soc_property_get(unit, spn_MEM_SCAN_ENABLE, SAL_BOOT_SIMULATION ? 0 : 1)) { 2780 /* search the memory and update the engine config */ 2781 ser_info = soc_mem_scan_ser_info_get(unit); 2782 if (ser_info == NULL) { 2783 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 2784 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) { 2785 rv = SOC_E_NONE; 2786 } else { 2787 rv = SOC_E_INIT; 2788 LOG_ERROR(BSL_LS_SOC_SER, 2789 (BSL_META_U(unit, "mem_update FAILED for mem = %s as " 2790 "ser_info is NULL\n"), SOC_MEM_NAME(unit,mem))); 2791 } 2792 } 2793 goto _error; 2794 } 2795 while (ser_info[info_ix].mem != INVALIDm) { 2796 /* Note: This will be the global view index */ 2797 #ifdef BCM_TRIDENT3_SUPPORT 2798 if (SOC_IS_TRIDENT3X(unit)) { 2799 if (ser_info[info_ix].mem != mem) { 2800 info_ix++; 2801 continue; 2802 } 2803 (void)soc_trident3_tcam_mode_set(unit, stage, mode); 2804 if (mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) { 2805 ser_info[info_ix].ser_dynamic_state |= 2806 _SOC_SER_STATE_PIPE_MODE_UNIQUE; 2807 ser_info[info_ix + 1].ser_dynamic_state |= 2808 _SOC_SER_STATE_PIPE_MODE_UNIQUE; 2809 } else { 2810 ser_info[info_ix].ser_dynamic_state &= 2811 ~_SOC_SER_STATE_PIPE_MODE_UNIQUE; 2812 ser_info[info_ix + 1].ser_dynamic_state &= 2813 ~_SOC_SER_STATE_PIPE_MODE_UNIQUE; 2814 } 2815 break; 2816 } 2817 #endif 2818 if (ser_info[info_ix].mem == mem) { 2819 rv = READ_SER_RANGE_ENABLEr(unit, &range_enable); 2820 if (SOC_FAILURE(rv)) { 2821 goto _error; 2822 } 2823 /* ASSUMPTION: _soc_th_tcam_ser_info_template[] table 2824 * lists entries for global, unique view consecutively at 2825 * {info_ix +0, +1, +2, +3}, info_ix +4 respectively and 2826 * because no ranges are configured for info_ix +1, +2, +3 2827 * so enable bits for global, unique views 2828 * will be at consecutive hw_ser_ix, hw_ser_ix+1 positions 2829 * in SER_RANGE_ENABLE REGISTER 2830 * 2831 * Summary: 2832 * 2833 * Global view: 2834 * info_ix +0, +1, +2, +3 point to 4 entries in _template[] 2835 * hw_ser_ix will point to enable bit in SER_RANGE_CONTROL 2836 * 2837 * Unique view: 2838 * info_ix+NUM_PIPE will point to entry in _template[] 2839 * hw_ser_ix+1 will point to enable bit for unique view because 2840 * entries at info_ix +1, +2, +3 do not need separate ranges in 2841 * ser_engine 2842 * 2843 * memscan: 2844 * Irrespective of global/unique mode, memscan always scans 2845 * entries at info_ix +0, +1, +2, +3 2846 */ 2847 hw_ser_ix = ser_info[info_ix].ser_hw_index; 2848 LOG_VERBOSE(BSL_LS_SOC_SER, 2849 (BSL_META_U(unit, "mem_update for mem = %s, " 2850 "range_enable = 0x%x, hw_ser_ix = %0d, " 2851 "request to change mode to %s \n"), 2852 SOC_MEM_NAME(unit,mem), range_enable, hw_ser_ix, 2853 mode? "PIPE_UNIQUE" : "GLOBAL")); 2854 if (mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) { 2855 /* Break before make to avoid any spurious schan 2856 * transaction errors 2857 */ 2858 range_enable &= ~(1 << hw_ser_ix); /* disable global */ 2859 range_enable |= (1 << (hw_ser_ix + 1)); /* enable unique */ 2860 2861 for (i = 0; i < NUM_PIPE(unit); i++) { 2862 ser_info[info_ix + i].ser_dynamic_state |= 2863 _SOC_SER_STATE_PIPE_MODE_UNIQUE; 2864 } 2865 } else { 2866 range_enable &= ~(1 << (hw_ser_ix + 1)); /* disable unique */ 2867 range_enable |= (1 << hw_ser_ix); /* enable global */ 2868 2869 for (i = 0; i < NUM_PIPE(unit); i++) { 2870 ser_info[info_ix + i].ser_dynamic_state &= 2871 ~_SOC_SER_STATE_PIPE_MODE_UNIQUE; 2872 } 2873 } 2874 rv = WRITE_SER_RANGE_ENABLEr(unit, range_enable); 2875 LOG_VERBOSE(BSL_LS_SOC_SER, 2876 (BSL_META_U(unit, "mem_update for mem = %s, " 2877 "range_enable = 0x%x, hw_ser_ix = %0d\n"), 2878 SOC_MEM_NAME(unit,mem), range_enable, hw_ser_ix)); 2879 if (SOC_FAILURE(rv)) { 2880 goto _error; 2881 } 2882 break; 2883 } 2884 info_ix++; 2885 } 2886 _error: 2887 return rv; 2888 } 2889 #endif /* INCLUDE_MEM_SCAN */ 2890 return rv; 2891 } 2892 2893 STATIC int 2894 _soc_ser_sync_mac_limits(int unit, soc_mem_t mem) 2895 { 2896 LOG_VERBOSE(BSL_LS_SOC_SER, 2897 (BSL_META_U(unit, 2898 "th_dbg: entered _soc_ser_sync_mac_limits " 2899 "routine\n"))); 2900 #ifdef BCM_XGS_SWITCH_SUPPORT 2901 2902 SOC_IF_ERROR_RETURN(soc_l2x_freeze(unit)); 2903 if (_SOC_DRV_MEM_CHK_L2_MEM(mem)) { 2904 /* Read L2 table from hardware and update the */ 2905 /* Decrement port/trunk and vlan/vfi counts */ 2906 #if defined(BCM_TRIUMPH3_SUPPORT) 2907 if (SOC_IS_TRIUMPH3(unit)) { 2908 soc_tr3_l2_entry_limit_count_update(unit); 2909 } 2910 #endif 2911 #if defined(BCM_GREYHOUND_SUPPORT) 2912 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 2913 soc_gh_l2_entry_limit_count_update(unit); 2914 } 2915 #endif 2916 #if defined(BCM_TRIUMPH2_SUPPORT) 2917 if (SOC_IS_TRIUMPH2(unit) || 2918 SOC_IS_KATANA(unit) || 2919 SOC_IS_APOLLO(unit)) { 2920 soc_triumph_l2_entry_limit_count_update(unit); 2921 } 2922 #endif 2923 } else { 2924 /* Calculate and restore port/trunk and vlan/vfi counts */ 2925 if (mem == VLAN_OR_VFI_MAC_COUNTm) { 2926 #if defined(BCM_TRIUMPH3_SUPPORT) 2927 if (SOC_IS_TRIUMPH3(unit)) { 2928 soc_tr3_l2_entry_limit_count_update(unit); 2929 } 2930 #endif 2931 #if defined(BCM_TRIUMPH2_SUPPORT) 2932 if (SOC_IS_TRIUMPH2(unit) || 2933 SOC_IS_KATANA(unit) || 2934 SOC_IS_APOLLO(unit)) { 2935 soc_triumph_l2_entry_limit_count_update(unit); 2936 } 2937 #endif 2938 } 2939 } 2940 SOC_IF_ERROR_RETURN(soc_l2x_thaw(unit)); 2941 #endif /* BCM_XGS_SWITCH_SUPPORT */ 2942 return SOC_E_NONE; 2943 } 2944 2945 STATIC int 2946 _soc_ser_check_hard_fault(int unit, soc_mem_t mem, int at, 2947 int copyno, int index, uint32 *cptr, 2948 int at_other, int pipe, int is_physical_index) 2949 { 2950 int rv; 2951 uint8 hf = FALSE; 2952 uint32 *entry = NULL; 2953 uint32 flags = SOC_MEM_NO_FLAGS; 2954 uint32 bytes = soc_mem_entry_bytes(unit, mem); 2955 2956 entry = sal_alloc((4 * SOC_MAX_MEM_WORDS), "hw_fault entry"); 2957 if (entry == NULL) { 2958 return SOC_E_MEMORY; 2959 } 2960 sal_memset(entry, 0, (4 * SOC_MAX_MEM_WORDS)); 2961 LOG_VERBOSE(BSL_LS_SOC_SER, 2962 (BSL_META_U(unit, 2963 "th_dbg: entered _soc_ser_check_hard_fault " 2964 "routine\n"))); 2965 2966 if (soc_feature(unit, soc_feature_efp_meter_table_write_ignore_nack) || 2967 SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2968 if ((mem == EFP_METER_TABLEm || 2969 mem == EFP_METER_TABLE_PIPE0m || 2970 mem == EFP_METER_TABLE_PIPE1m || 2971 mem == EFP_METER_TABLE_PIPE2m || 2972 mem == EFP_METER_TABLE_PIPE3m || 2973 mem == EFP_METER_TABLE_Xm || 2974 mem == EFP_METER_TABLE_Ym) && ((index % 2) == 1)) { 2975 /* 2976 * When parity error happened in odd entry 2977 * Skip checking 2978 */ 2979 rv = SOC_E_NONE; 2980 goto free_exit; 2981 } 2982 } 2983 2984 if (is_physical_index) { 2985 flags = SOC_MEM_DONT_MAP_INDEX; 2986 } 2987 /* Read back to ensure correction happened properly OR if there 2988 * is a hard fault. 2989 */ 2990 if (((1 == pipe) && 2991 ((_SOC_ACC_TYPE_PIPE_BCAST == at) || 2992 (_SOC_ACC_TYPE_PIPE_SBS == at))) || 2993 (_SOC_ACC_TYPE_PIPE_Y == at)) { /* Use h/w (other pipe) cache */ 2994 IP_ARBITER_LOCK(unit); 2995 #if defined(BCM_TRIDENT_SUPPORT) 2996 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 2997 soc_trident_pipe_select(unit, TRUE, 1); 2998 soc_trident_pipe_select(unit, FALSE, 1); 2999 } 3000 #endif 3001 #if defined(BCM_TRIDENT2_SUPPORT) 3002 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2X(unit)) { 3003 soc_trident2_pipe_select(unit, TRUE, 1); 3004 soc_trident2_pipe_select(unit, FALSE, 1); 3005 } 3006 #endif 3007 rv = soc_mem_pipe_select_read(unit, flags, mem, 3008 copyno, at, index, entry); 3009 #if defined(BCM_TRIDENT_SUPPORT) 3010 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 3011 soc_trident_pipe_select(unit, TRUE, 0); 3012 soc_trident_pipe_select(unit, FALSE, 0); 3013 } 3014 #endif 3015 #if defined(BCM_TRIDENT2_SUPPORT) 3016 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2X(unit)) { 3017 soc_trident2_pipe_select(unit, TRUE, 0); 3018 soc_trident2_pipe_select(unit, FALSE, 0); 3019 } 3020 #endif 3021 IP_ARBITER_UNLOCK(unit); 3022 } else { 3023 rv = soc_mem_read_extended(unit, flags | SOC_MEM_SCHAN_ERR_RETURN, 3024 mem, 0, copyno, index, entry); 3025 } 3026 if (SOC_FAILURE(rv)) { 3027 /* Obvious hard fault */ 3028 hf = TRUE; 3029 LOG_ERROR(BSL_LS_SOC_SER, 3030 (BSL_META_U(unit, 3031 "Hard fault detected (read) at: %s.%s[%d] !!\n"), 3032 SOC_MEM_NAME(unit, mem), 3033 SOC_BLOCK_NAME(unit, copyno), 3034 index)); 3035 } else { 3036 /* Check for multi bit or other forms of un-detectable errors 3037 by comparing read back data from h/w with cache(s/w or h/w) */ 3038 if (cptr != NULL) { 3039 if (at != -1) { 3040 soc_mem_parity_field_clear(unit, mem, entry, cptr); 3041 if (sal_memcmp(entry, cptr, bytes) != 0) { 3042 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_MEM_SCAN) 3043 uint32 *mask = NULL; 3044 uint32 dw = 0; 3045 uint32 entry_dw = soc_mem_entry_words(unit, mem); 3046 uint32 mask_length = SOC_MAX_MEM_WORDS * sizeof(uint32); 3047 3048 mask = sal_alloc((4 * SOC_MAX_MEM_WORDS), "mask entry"); 3049 if (mask == NULL) { 3050 rv = SOC_E_MEMORY; 3051 goto free_exit; 3052 } 3053 sal_memset((void *)mask, 0xff, mask_length); 3054 soc_mem_scan_mask_get(unit, mem, copyno, at, mask, mask_length); 3055 for (dw = 0; dw < entry_dw; dw++) { 3056 if (((entry[dw] ^ cptr[dw]) & 3057 mask[dw]) != 0) { 3058 break; 3059 } 3060 } 3061 3062 if (mask != NULL) { 3063 sal_free(mask); 3064 } 3065 if (dw < entry_dw) 3066 #endif 3067 { 3068 hf = TRUE; 3069 LOG_ERROR(BSL_LS_SOC_SER, 3070 (BSL_META_U(unit, 3071 "Hard fault detected (pipe compare) " 3072 "at: %s.%s[%d] !!\n"), 3073 SOC_MEM_NAME(unit, mem), 3074 SOC_BLOCK_NAME(unit, copyno), 3075 index)); 3076 } 3077 } 3078 } else { 3079 3080 3081 } 3082 } 3083 } 3084 if (hf == TRUE) { 3085 /* Raise a hard fault event and disable parity if applicable */ 3086 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3087 SOC_SWITCH_EVENT_DATA_ERROR_FATAL, mem, 3088 index); 3089 #if defined(BCM_TRIDENT2_SUPPORT) 3090 if (SOC_IS_TD2_TT2(unit)) { 3091 #if defined(BCM_TOMAHAWK_SUPPORT) 3092 if (SOC_IS_TOMAHAWKX(unit)) { 3093 soc_th_mem_parity_control(unit, mem, copyno, FALSE, FALSE); 3094 } else 3095 #endif 3096 #if defined(BCM_TRIDENT3_SUPPORT) 3097 if (SOC_IS_TRIDENT3X(unit)) { 3098 soc_td3_mem_parity_control(unit, mem, copyno, FALSE, FALSE); 3099 } else 3100 #endif 3101 { 3102 soc_trident2_mem_parity_control(unit, mem, copyno, FALSE); 3103 } 3104 } 3105 #endif 3106 #if defined(BCM_TRIDENT_SUPPORT) 3107 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 3108 _soc_trident_mem_parity_control(unit, mem, copyno, FALSE); 3109 } 3110 #endif 3111 } 3112 free_exit: 3113 if (entry != NULL) { 3114 sal_free(entry); 3115 } 3116 return rv; 3117 } 3118 3119 STATIC int 3120 _soc_ser_correction_event_generate(int unit, soc_switch_event_t event, _soc_ser_correct_info_t *si, 3121 uint32 arg1, uint32 arg2) 3122 { 3123 if (soc_property_get(unit, spn_ENHANCED_SER_CORRECTION_EVENT_REPORT, 0)) { 3124 if (si != NULL) { 3125 if (si->parity_type == SOC_PARITY_TYPE_ECC) { 3126 if (si->double_bit) { 3127 soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_ECC_2BIT_CORRECTED, arg1, arg2); 3128 } else { 3129 soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_ECC_1BIT_CORRECTED, arg1, arg2); 3130 } 3131 } else { 3132 soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_PARITY_CORRECTED, arg1, arg2); 3133 } 3134 } 3135 } else { 3136 soc_event_generate(unit, event, SOC_SWITCH_EVENT_DATA_ERROR_CORRECTED, arg1, arg2); 3137 } 3138 return SOC_E_NONE; 3139 } 3140 3141 STATIC int 3142 _soc_ser_recovery_hw_cache(int unit, int pipe, soc_mem_t mem, int copyno, 3143 int index, _soc_ser_correct_info_t *si, int is_physical_index) 3144 { 3145 int acc_type=0, cache_acc_type=0; 3146 uint32 *entry = NULL; 3147 uint32 flags = SOC_MEM_NO_FLAGS; 3148 soc_stat_t *stat = SOC_STAT(unit); 3149 int rv; 3150 void *null_entry; 3151 int entry_dw; 3152 #if defined(BCM_TOMAHAWK_SUPPORT) 3153 int restore_pipe = 0; 3154 #endif /* BCM_TOMAHAWK_SUPPORT */ 3155 soc_mem_t report_mem = mem; 3156 int report_index = index; 3157 3158 LOG_VERBOSE(BSL_LS_SOC_SER, 3159 (BSL_META_U(unit, 3160 "th_dbg: entered _soc_ser_recovery_hw_cache " 3161 "routine\n"))); 3162 3163 entry = sal_alloc((4 * SOC_MAX_MEM_WORDS), "hw_cache entry"); 3164 if (entry == NULL) { 3165 return SOC_E_MEMORY; 3166 } 3167 sal_memset(entry, 0, (4 * SOC_MAX_MEM_WORDS)); 3168 if ((SOC_IS_TD2P_TT2P(unit) || 3169 SOC_IS_TD2_TT2(unit) || SOC_IS_TD_TT(unit)) && \ 3170 (!SOC_IS_APACHE(unit))) { 3171 if (pipe == SOC_PIPE_ANY) { 3172 pipe = 0; 3173 } 3174 switch (mem) { 3175 case L3_DEFIP_ALPM_RAWm: 3176 case L3_DEFIP_ALPM_IPV4m: 3177 case L3_DEFIP_ALPM_IPV4_1m: 3178 case L3_DEFIP_ALPM_IPV6_64m: 3179 case L3_DEFIP_ALPM_IPV6_64_1m: 3180 case L3_DEFIP_ALPM_IPV6_128m: 3181 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 3182 case L3_DEFIP_ALPM_ECCm: 3183 case L2_ENTRY_LPm: 3184 case L2_ENTRY_ISS_LPm: 3185 case L3_ENTRY_LPm: 3186 case L3_ENTRY_ISS_LPm: 3187 case VLAN_XLATE_LPm: 3188 case EGR_VLAN_XLATE_LPm: 3189 #endif /* BCM_TOMAHAWK_SUPPORT */ 3190 #if defined(BCM_TRIDENT3_SUPPORT) 3191 case ING_DNAT_ADDRESS_TYPE_ECCm: 3192 case ING_VP_VLAN_MEMBERSHIP_ECCm: 3193 case EGR_VP_VLAN_MEMBERSHIP_ECCm: 3194 case SUBPORT_ID_TO_SGPP_MAP_ECCm: 3195 case EXACT_MATCH_LPm: 3196 case VLAN_XLATE_1_LPm: 3197 case VLAN_XLATE_2_LPm: 3198 case EGR_VLAN_XLATE_1_LPm: 3199 case EGR_VLAN_XLATE_2_LPm: 3200 case MPLS_ENTRY_LPm: 3201 #endif 3202 #if defined(BCM_TOMAHAWK3_SUPPORT) 3203 case L3_DEFIP_ALPM_LEVEL2_ECCm: 3204 case L3_DEFIP_ALPM_LEVEL3_ECCm: 3205 case L3_DEFIP_LEVEL1m: 3206 case L3_DEFIP_PAIR_LEVEL1m: 3207 case L3_DEFIP_TCAM_LEVEL1m: 3208 case L3_DEFIP_DATA_LEVEL1m: 3209 #endif 3210 case L3_DEFIP_AUX_TABLEm: 3211 case L3_DEFIP_PAIR_128m: 3212 case L3_DEFIPm: 3213 case L3_DEFIP_128_DATA_ONLYm: 3214 case L3_DEFIP_PAIR_128_DATA_ONLYm: 3215 case L3_DEFIP_DATA_ONLYm: 3216 #if defined(BCM_TOMAHAWK_SUPPORT) 3217 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 3218 if (NUM_PIPE(unit) == 1) { 3219 rv = SOC_E_UNAVAIL; 3220 goto free_exit; 3221 } 3222 if (pipe >= NUM_PIPE(unit)) { 3223 rv = SOC_E_PARAM; 3224 goto free_exit; 3225 } 3226 #ifdef BCM_TOMAHAWK3_SUPPORT 3227 if (SOC_IS_TOMAHAWK3(unit)) { 3228 if (mem == L3_DEFIP_ALPM_LEVEL3_ECCm) { 3229 pipe = (pipe == 1 || pipe == 6 || pipe == 7) ? 0 : 3230 (pipe == 2 || pipe == 3 || pipe == 5) ? 4 : 3231 pipe; 3232 restore_pipe = pipe ? 0 : 4; 3233 } else if (mem == L3_DEFIP_ALPM_LEVEL2_ECCm) { 3234 pipe = (pipe == 1) ? 0 : 3235 (pipe == 2) ? 3 : 3236 (pipe == 5) ? 4 : 3237 (pipe == 6) ? 7 : 3238 pipe; 3239 restore_pipe = pipe ? 0 : 3; 3240 } else { 3241 restore_pipe = pipe ? 0 : 1; 3242 } 3243 } else 3244 #endif 3245 { 3246 restore_pipe = pipe ? 0 : 1; 3247 } 3248 acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe); 3249 cache_acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(restore_pipe); 3250 /* LOG_VERBOSE(BSL_LS_SOC_SER, 3251 * (BSL_META_U(unit, 3252 * "th_dbg: pipe=%0d, restore_pipe=%0d, acc_type=%0d, cache_acc_type=%0d\n"), 3253 * unit, pipe, restore_pipe, acc_type, 3254 * cache_acc_type)); 3255 */ 3256 } else 3257 #endif /* BCM_TOMAHAWK_SUPPORT */ 3258 { 3259 if (pipe == 0) { 3260 acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_X; 3261 cache_acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y; 3262 } else if (pipe == 1) { 3263 acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y; 3264 cache_acc_type = _SOC_MEM_ADDR_ACC_TYPE_PIPE_X; 3265 } else { 3266 rv = SOC_E_PARAM; 3267 goto free_exit; 3268 } 3269 } 3270 if (is_physical_index) { 3271 flags = SOC_MEM_DONT_MAP_INDEX; 3272 } 3273 if ((SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) && 3274 (mem == L3_DEFIP_ALPM_RAWm)) { 3275 null_entry = soc_mem_entry_null(unit, mem); 3276 sal_memcpy(entry, null_entry, soc_mem_entry_words(unit, mem) * 3277 sizeof(uint32)); 3278 } else { 3279 rv = soc_mem_pipe_select_read(unit, flags, mem, 3280 copyno, cache_acc_type, 3281 index, entry); 3282 if (SOC_FAILURE(rv)) { 3283 null_entry = soc_mem_entry_null(unit, mem); 3284 sal_memcpy(entry, null_entry, soc_mem_entry_words(unit, mem) * 3285 sizeof(uint32)); 3286 LOG_ERROR(BSL_LS_SOC_SER, 3287 (BSL_META_U(unit, 3288 "Un-expected error in %s[%d] blk: %s at same " 3289 "index[%d] in multiple pipes.\n"), 3290 SOC_MEM_NAME(unit, mem), mem, 3291 SOC_BLOCK_NAME(unit, copyno), index)); 3292 } 3293 } 3294 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HITf); 3295 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT0f); 3296 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT1f); 3297 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_0f); 3298 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_1f); 3299 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_2f); 3300 _SOC_ENTRY_FIELD_CHK_CLR(unit, mem, entry, HIT_3f); 3301 rv = soc_mem_pipe_select_write(unit, flags, mem, 3302 copyno, acc_type, index, entry); 3303 if (rv != SOC_E_NONE) { 3304 goto free_exit; 3305 } 3306 /* If mem == L3_DEFIP_ALPM_RAWm, it means we are recovering 3307 * the ALPM bucket which is unused, the memory view of this 3308 * bucket is not determined, so we used raw view for recovering, 3309 * and since it's not used, event generation is not necessary. 3310 */ 3311 if (mem != L3_DEFIP_ALPM_RAWm) { 3312 #if defined(BCM_TRIDENT2_SUPPORT) 3313 /* For L3_DEFIP/L3_DEFIP_DATA_ONLY view the input index is physical 3314 * index, so need to remap to logical index. For L3_DEFIP_PAIR_128_DATA_ONLY view 3315 * when correcting the view will be changed to L3_DEFIP_DATA_ONLY. 3316 * For L3_DEFIP_PAIR_128 view, When L3_ALPM_ENABLE=2, the physical index 3317 * is equal to logical index, but When L3_ALPM_ENABLE=1, the physical index 3318 * is not equal to logical index, so need to remap physical index to logical one. 3319 */ 3320 if (is_physical_index && SOC_IS_TD2_TT2(unit) && !SOC_IS_APACHE(unit)) { 3321 if (mem == L3_DEFIPm || mem == L3_DEFIP_DATA_ONLYm) { 3322 report_index = 3323 soc_trident2_l3_defip_mem_index_get(unit, 3324 index, 3325 &report_mem); 3326 if (report_mem == L3_DEFIP_PAIR_128m) { 3327 report_mem = L3_DEFIP_PAIR_128_DATA_ONLYm; 3328 } else if (report_mem != mem) { 3329 report_mem = mem; 3330 } 3331 } else if (mem == L3_DEFIP_PAIR_128m) { 3332 report_index= 3333 soc_trident2_l3_defip_index_remap(unit, 3334 mem, 3335 index); 3336 } 3337 } 3338 #endif 3339 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3340 si, report_mem, report_index); 3341 } 3342 #if defined(BCM_TOMAHAWK_SUPPORT) 3343 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 3344 LOG_WARN(BSL_LS_SOC_SER, 3345 (BSL_META_U(unit, 3346 "RESTORE pipe %0d [from pipe %0d]: %s[%d] " 3347 "blk: %s index: %d\n"), 3348 pipe, restore_pipe, SOC_MEM_NAME(unit, report_mem), 3349 report_mem, SOC_BLOCK_NAME(unit, copyno), report_index)); 3350 } else 3351 #endif /* BCM_TOMAHAWK_SUPPORT */ 3352 { 3353 LOG_WARN(BSL_LS_SOC_SER, 3354 (BSL_META_U(unit, 3355 "RESTORE[from %c pipe]: %s[%d] " 3356 "blk: %s index: %d\n"), 3357 pipe ? 'X':'Y', SOC_MEM_NAME(unit, report_mem), 3358 report_mem, SOC_BLOCK_NAME(unit, copyno), report_index)); 3359 } 3360 stat->ser_err_restor++; 3361 if (NULL != si) { 3362 entry_dw = soc_mem_entry_words(unit, mem); 3363 if ((si->log_id != 0) && 3364 (si->flags & SOC_SER_LOG_WRITE_CACHE)) { 3365 if (si->index == index) { 3366 (void)soc_ser_log_add_tlv(unit, si->log_id, 3367 SOC_SER_LOG_TLV_CACHE, 3368 entry_dw*4, entry); 3369 } else { 3370 LOG_VERBOSE(BSL_LS_SOC_SER, 3371 (BSL_META_U(unit, 3372 "skipped updating tlv_cache index: %d\n"), 3373 index)); 3374 } 3375 } 3376 si->ctype = socSerCorrectTypeHwCacheRestore; 3377 } 3378 if (NULL != si) { 3379 if (si->flags & SOC_SER_SKIP_HARD_FALT_CHECK) { 3380 return SOC_E_NONE; 3381 } 3382 } 3383 rv = _soc_ser_check_hard_fault(unit, mem, acc_type, copyno, 3384 index, entry, cache_acc_type, 3385 pipe, is_physical_index); 3386 goto free_exit; 3387 default: 3388 rv = SOC_E_UNAVAIL; 3389 goto free_exit; 3390 } 3391 } 3392 rv = SOC_E_UNAVAIL; 3393 free_exit: 3394 if(entry != NULL) { 3395 sal_free(entry); 3396 } 3397 return rv; 3398 } 3399 3400 #if defined(BCM_TOMAHAWK_SUPPORT) 3401 STATIC int 3402 _soc_ser_mem_mode_get(int unit, soc_mem_t mem) { 3403 int rv; 3404 int tmp_mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 3405 rv = soc_th_ser_mem_mode_get(unit, mem, &tmp_mem_mode); 3406 if ((rv == SOC_E_NONE) && (tmp_mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE)) { 3407 return _SOC_SER_MEM_MODE_PIPE_UNIQUE; 3408 } else { 3409 if (rv != SOC_E_NONE) { 3410 LOG_ERROR(BSL_LS_SOC_SER, 3411 (BSL_META_U(unit, 3412 "Could not determine unique-global mode for" 3413 "mem %s - will assume global mode !!\n"), 3414 SOC_MEM_NAME(unit, mem))); 3415 } 3416 return _SOC_SER_MEM_MODE_GLOBAL; 3417 } 3418 } 3419 #endif /* BCM_TOMAHAWK_SUPPORT */ 3420 3421 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 3422 /* Following maps ecc_entry_index to lp_entry_index */ 3423 STATIC int 3424 _soc_fv_lp_index_remap(int fpem_ecc_index, int em2) 3425 { 3426 int uft_bank, fpem_ecc_index_in_uft_bank, lp_bkt_adr; 3427 3428 /* Each uft bank has 32K _ecc entries */ 3429 uft_bank = fpem_ecc_index / 32768; 3430 3431 /* address within uft_bank */ 3432 fpem_ecc_index_in_uft_bank = fpem_ecc_index % 32768; 3433 3434 if (em2) { 3435 /* Each em2 entry has 2 fpem_ecc entries and every 3436 * lp_bkt has 4 em2 entries and thus 8 _ecc entries. 3437 * Each uft_bank has 8K lp entries */ 3438 lp_bkt_adr = fpem_ecc_index_in_uft_bank / 8; 3439 return (uft_bank * 8192) + lp_bkt_adr; 3440 } else { 3441 /* Each em4 entry has 4 fpem_ecc entries and every 3442 * lp_bkt has 4 em4 entries and thus 16 _ecc entries. 3443 * Each uft_bank has 8K lp entries */ 3444 lp_bkt_adr = fpem_ecc_index_in_uft_bank / 16; 3445 return (uft_bank * 8192) + lp_bkt_adr + 4096; 3446 } 3447 } 3448 #endif 3449 3450 /* hw_cpu: Need special handling for hw vs cpu error on some devices/mems. 3451 hw=0, cpu=1. 3452 */ 3453 #define _SOC_SER_MEM_OVERLAY_SET 6 3454 STATIC int 3455 _soc_ser_overlay_mem_correction(int unit, int hw_cpu, int pipe, int sblk, int addr, 3456 soc_mem_t reported_mem, int copyno, int index, 3457 _soc_ser_correct_info_t *si) 3458 { 3459 soc_mem_t mem = INVALIDm; 3460 soc_mem_t mem_for_write = INVALIDm; 3461 void *null_entry; 3462 int rv, entry_dw; 3463 uint8 fix = 0, *vmap; 3464 int i, m, vindex = 0, index_for_write = 0; 3465 int num_mems = 1; 3466 int clear_mems = 1; 3467 soc_stat_t *stat = SOC_STAT(unit); 3468 uint32 entry[SOC_MAX_MEM_WORDS], *cache; 3469 int num_indexes[_SOC_SER_MEM_OVERLAY_SET] = {1, 1, 1, 1, 1, 1}; 3470 int iratio[_SOC_SER_MEM_OVERLAY_SET] = {1, 1, 1, 1, 1, 1}; 3471 soc_mem_t mem_list[_SOC_SER_MEM_OVERLAY_SET] = 3472 {INVALIDm, INVALIDm, INVALIDm, INVALIDm}; 3473 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 3474 soc_field_t ecc_data_field = INVALIDf; 3475 #endif /* BCM_TOMAHAWK_SUPPORT */ 3476 #if defined(BCM_TOMAHAWK_SUPPORT) 3477 int fpem_mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 3478 #endif 3479 #if defined(BCM_TRIDENT2_SUPPORT) 3480 int defip_cam_size = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit); 3481 int phy_index = 0; 3482 #endif 3483 3484 int reported_mem_is_fpem_lp = 0; /* reported_mem in ser_fifo */ 3485 int use_pipe_select_write = 0, acc_type = 0; 3486 3487 LOG_VERBOSE(BSL_LS_SOC_SER, 3488 (BSL_META_U(unit, 3489 "th_dbg: entered " 3490 "_soc_ser_overlay_mem_correction routine\n"))); 3491 3492 if (copyno == MEM_BLOCK_ANY) { 3493 copyno = SOC_MEM_BLOCK_ANY(unit, reported_mem); 3494 } 3495 3496 mem_list[0] = reported_mem; 3497 switch (reported_mem) { 3498 case MODPORT_MAP_SWm: 3499 if (SOC_IS_TRX(unit) && 3500 !(SOC_IS_TRIUMPH3(unit) || SOC_IS_TD_TT(unit) || SOC_IS_TD2_TT2(unit) || 3501 SOC_IS_KATANA2(unit) || SOC_IS_GREYHOUND(unit) || 3502 SOC_IS_HURRICANEX(unit))) { 3503 num_mems = 1; 3504 mem_list[0] = MODPORT_MAPm; 3505 break; 3506 } else { 3507 LOG_VERBOSE(BSL_LS_SOC_SER, 3508 (BSL_META_U(unit, 3509 "th_dbg: returning SOC_E_UNAVAIL " 3510 "for MODPORT_MAP_SW\n"))); 3511 return SOC_E_UNAVAIL; 3512 } 3513 case MODPORT_MAP_M0m: 3514 case MODPORT_MAP_M1m: 3515 case MODPORT_MAP_M2m: 3516 case MODPORT_MAP_M3m: 3517 num_mems = 1; 3518 mem_list[0] = MODPORT_MAP_MIRRORm; 3519 break; 3520 case ESM_PKT_TYPE_ID_DATA_ONLYm: 3521 num_mems = 1; 3522 mem_list[0] = ESM_PKT_TYPE_IDm; 3523 break; 3524 case ING_SNAT_DATA_ONLYm: 3525 num_mems = 1; 3526 mem_list[0] = ING_SNATm; 3527 break; 3528 case VLAN_SUBNET_DATA_ONLYm: 3529 num_mems = 1; 3530 mem_list[0] = VLAN_SUBNETm; 3531 break; 3532 case MY_STATION_TCAM_DATA_ONLYm: 3533 num_mems = 1; 3534 mem_list[0] = MY_STATION_TCAMm; 3535 break; 3536 case L2_USER_ENTRY_DATA_ONLYm: 3537 num_mems = 1; 3538 mem_list[0] = L2_USER_ENTRYm; 3539 break; 3540 case L3_TUNNEL_DATA_ONLYm: 3541 num_mems = 1; 3542 mem_list[0] = L3_TUNNELm; 3543 break; 3544 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 3545 /* swname for following is L2_USER_ENTRY_DATA_ONLYm which is 3546 * already covered above 3547 case L2_USER_ENTRY_DATAm: 3548 num_mems = 1; 3549 mem_list[0] = L2_USER_ENTRYm; 3550 break; 3551 */ 3552 case SRC_COMPRESSION_DATA_ONLYm: 3553 num_mems = 1; 3554 mem_list[0] = SRC_COMPRESSIONm; 3555 if (_SOC_SER_MEM_MODE_PIPE_UNIQUE == 3556 _soc_ser_mem_mode_get(unit, mem_list[0]) && 3557 (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL) && 3558 (pipe < NUM_PIPE(unit))) { 3559 mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe]; 3560 } 3561 break; 3562 case DST_COMPRESSION_DATA_ONLYm: 3563 num_mems = 1; 3564 mem_list[0] = DST_COMPRESSIONm; 3565 if (_SOC_SER_MEM_MODE_PIPE_UNIQUE == 3566 _soc_ser_mem_mode_get(unit, mem_list[0]) && 3567 (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL) && 3568 (pipe < NUM_PIPE(unit))) { 3569 mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe]; 3570 } 3571 break; 3572 case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm: 3573 num_mems = 1; 3574 mem_list[0] = EXACT_MATCH_LOGICAL_TABLE_SELECTm; 3575 if (_SOC_SER_MEM_MODE_PIPE_UNIQUE == 3576 _soc_ser_mem_mode_get(unit, mem_list[0]) && 3577 (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL) && 3578 (pipe < NUM_PIPE(unit))) { 3579 mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe]; 3580 } 3581 break; 3582 case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm: 3583 num_mems = 1; 3584 mem_list[0] = IFP_LOGICAL_TABLE_SELECTm; 3585 if (_SOC_SER_MEM_MODE_PIPE_UNIQUE == 3586 _soc_ser_mem_mode_get(unit, mem_list[0]) && 3587 (SOC_MEM_UNIQUE_ACC(unit, mem_list[0]) != NULL) && 3588 (pipe < NUM_PIPE(unit))) { 3589 mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, mem_list[0])[pipe]; 3590 } 3591 break; 3592 #endif /* BCM_TOMAHAWK_SUPPORT */ 3593 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 3594 case ING_VP_VLAN_MEMBERSHIP_ECCm: 3595 num_mems = 1; 3596 if (SOC_IS_TOMAHAWK2(unit)) { 3597 mem_list[0] = ING_VP_VLAN_MEMBERSHIPm; 3598 } else if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) { 3599 /* In TD3 based devices one entry in ECC view corresponds to 3600 * two entries in the functional view 3601 */ 3602 index *= 2; 3603 mem_list[0] = ING_VP_VLAN_MEMBERSHIPm; 3604 num_indexes[0] = 2; 3605 } 3606 break; 3607 case EGR_VP_VLAN_MEMBERSHIP_ECCm: 3608 num_mems = 1; 3609 if (SOC_IS_TOMAHAWK2(unit)) { 3610 mem_list[0] = EGR_VP_VLAN_MEMBERSHIPm; 3611 } else if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) { 3612 index *= 2; 3613 mem_list[0] = EGR_VP_VLAN_MEMBERSHIPm; 3614 num_indexes[0] = 2; 3615 } 3616 break; 3617 case ING_DNAT_ADDRESS_TYPE_ECCm: 3618 num_mems = 1; 3619 if (SOC_IS_TOMAHAWK2(unit)) { 3620 mem_list[0] = ING_DNAT_ADDRESS_TYPEm; 3621 } else if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) { 3622 index *= 2; 3623 mem_list[0] = ING_DNAT_ADDRESS_TYPEm; 3624 num_indexes[0] = 2; 3625 } 3626 break; 3627 case SUBPORT_ID_TO_SGPP_MAP_ECCm: 3628 num_mems = 1; 3629 if (SOC_IS_TRIDENT3X(unit) && (NUM_PIPE(unit) == 1)) { 3630 index *= 2; 3631 mem_list[0] = SUBPORT_ID_TO_SGPP_MAPm; 3632 num_indexes[0] = 2; 3633 } 3634 break; 3635 #endif 3636 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 3637 case MY_STATION_TCAM_2_DATA_ONLYm: 3638 num_mems = 1; 3639 mem_list[0] = MY_STATION_TCAM_2m; 3640 break; 3641 case SUBPORT_TAG_SGPP_MAP_DATA_ONLYm: 3642 num_mems = 1; 3643 mem_list[0] = SUBPORT_TAG_SGPP_MAPm; 3644 break; 3645 #endif 3646 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 3647 case CPU_COS_MAP_DATA_ONLYm: 3648 num_mems = 1; 3649 mem_list[0] = CPU_COS_MAPm; 3650 break; 3651 #endif 3652 #if defined(BCM_TRIDENT3_SUPPORT) 3653 case PHB_SELECT_TCAM_DATA_ONLYm: 3654 num_mems = 1; 3655 mem_list[0] = PHB_SELECT_TCAMm; 3656 break; 3657 case FLEX_RTAG7_HASH_TCAM_DATA_ONLYm: 3658 num_mems = 1; 3659 mem_list[0] = FLEX_RTAG7_HASH_TCAMm; 3660 break; 3661 case PKT_FLOW_SELECT_TCAM_1_DATA_ONLYm: 3662 num_mems = 1; 3663 mem_list[0] = PKT_FLOW_SELECT_TCAM_1m; 3664 break; 3665 case PKT_FLOW_SELECT_TCAM_2_DATA_ONLYm: 3666 num_mems = 1; 3667 mem_list[0] = PKT_FLOW_SELECT_TCAM_2m; 3668 break; 3669 case IP_PARSER1_MICE_TCAM_DATA_ONLY_0m: 3670 num_mems = 1; 3671 mem_list[0] = IP_PARSER1_MICE_TCAM_0m; 3672 break; 3673 case IP_PARSER1_MICE_TCAM_DATA_ONLY_1m: 3674 num_mems = 1; 3675 mem_list[0] = IP_PARSER1_MICE_TCAM_1m; 3676 break; 3677 case IP_PARSER2_MICE_TCAM_DATA_ONLY_0m: 3678 num_mems = 1; 3679 mem_list[0] = IP_PARSER2_MICE_TCAM_0m; 3680 break; 3681 case IP_PARSER2_MICE_TCAM_DATA_ONLY_1m: 3682 num_mems = 1; 3683 mem_list[0] = IP_PARSER2_MICE_TCAM_1m; 3684 break; 3685 case EGR_ZONE_0_EDITOR_CONTROL_TCAM_DATA_ONLYm: 3686 num_mems = 1; 3687 mem_list[0] = EGR_ZONE_0_EDITOR_CONTROL_TCAMm; 3688 break; 3689 case EGR_ZONE_1_EDITOR_CONTROL_TCAM_DATA_ONLYm: 3690 num_mems = 1; 3691 mem_list[0] = EGR_ZONE_1_EDITOR_CONTROL_TCAMm; 3692 break; 3693 case EGR_ZONE_2_EDITOR_CONTROL_TCAM_DATA_ONLYm: 3694 num_mems = 1; 3695 mem_list[0] = EGR_ZONE_2_EDITOR_CONTROL_TCAMm; 3696 break; 3697 case EGR_ZONE_3_EDITOR_CONTROL_TCAM_DATA_ONLYm: 3698 num_mems = 1; 3699 mem_list[0] = EGR_ZONE_3_EDITOR_CONTROL_TCAMm; 3700 break; 3701 case EGR_ZONE_4_EDITOR_CONTROL_TCAM_DATA_ONLYm: 3702 num_mems = 1; 3703 mem_list[0] = EGR_ZONE_4_EDITOR_CONTROL_TCAMm; 3704 break; 3705 case EGR_PKT_FLOW_SELECT_TCAM_DATA_ONLYm: 3706 num_mems = 1; 3707 mem_list[0] = EGR_PKT_FLOW_SELECT_TCAMm; 3708 break; 3709 case EGR_FIELD_EXTRACTION_PROFILE_1_TCAM_DATA_ONLYm: 3710 num_mems = 1; 3711 mem_list[0] = EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm; 3712 break; 3713 case EGR_FIELD_EXTRACTION_PROFILE_2_TCAM_DATA_ONLYm: 3714 num_mems = 1; 3715 mem_list[0] = EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm; 3716 break; 3717 case EGR_QOS_CTRL_TCAM_DATA_ONLYm: 3718 num_mems = 1; 3719 mem_list[0] = EGR_QOS_CTRL_TCAMm; 3720 break; 3721 #endif 3722 case L2_ENTRY_1m: 3723 num_mems = 2; 3724 mem_list[1] = L2_ENTRY_2m; iratio[1] = 2; 3725 break; 3726 case MPLS_ENTRYm: 3727 case MPLS_ENTRY_1m: 3728 if (soc_feature(unit, soc_feature_ism_memory)) { 3729 num_mems = 2; 3730 mem_list[1] = MPLS_ENTRY_EXTDm; iratio[1] = 2; 3731 break; 3732 } else { 3733 return SOC_E_UNAVAIL; 3734 } 3735 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 3736 case MPLS_ENTRY_ECCm: 3737 if (SOC_IS_TRIDENT3X(unit)) { 3738 num_mems = 2; 3739 mem_list[0] = MPLS_ENTRY_SINGLEm; iratio[0] = 1; 3740 mem_list[1] = MPLS_ENTRYm; iratio[1] = 2; 3741 } else if (SOC_IS_TOMAHAWK3(unit)) { 3742 num_mems = 1; 3743 mem_list[0] = MPLS_ENTRY_SINGLEm; 3744 } else { 3745 num_mems = 1; 3746 mem_list[0] = MPLS_ENTRYm; 3747 } 3748 break; 3749 #endif /* BCM_TOMAHAWK_SUPPORT */ 3750 #if defined(BCM_TRIDENT3_SUPPORT) 3751 case VLAN_XLATE_1_ECCm: 3752 num_mems = 2; 3753 mem_list[0] = VLAN_XLATE_1_SINGLEm; iratio[0] = 1; 3754 mem_list[1] = VLAN_XLATE_1_DOUBLEm; iratio[1] = 2; 3755 break; 3756 case VLAN_XLATE_2_ECCm: 3757 num_mems = 2; 3758 mem_list[0] = VLAN_XLATE_2_SINGLEm; iratio[0] = 1; 3759 mem_list[1] = VLAN_XLATE_2_DOUBLEm; iratio[1] = 2; 3760 break; 3761 case EGR_VLAN_XLATE_1_ECCm: 3762 num_mems = 2; 3763 mem_list[0] = EGR_VLAN_XLATE_1_SINGLEm; iratio[0] = 1; 3764 mem_list[1] = EGR_VLAN_XLATE_1_DOUBLEm; iratio[1] = 2; 3765 break; 3766 case EGR_VLAN_XLATE_2_ECCm: 3767 num_mems = 2; 3768 mem_list[0] = EGR_VLAN_XLATE_2_SINGLEm; iratio[0] = 1; 3769 mem_list[1] = EGR_VLAN_XLATE_2_DOUBLEm; iratio[1] = 2; 3770 break; 3771 #endif /* BCM_TRIDENT3_SUPPORT */ 3772 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 3773 case IFP_POLICY_TABLEm: 3774 if (SOC_IS_TRIDENT3X(unit)) { 3775 num_mems = 2; 3776 mem_list[0] = IFP_POLICY_TABLEm; iratio[0] = 1; 3777 mem_list[1] = IFP_POLICY_TABLE_WIDEm; iratio[1] = 1; 3778 } else { 3779 return SOC_E_UNAVAIL; 3780 } 3781 break; 3782 case IFP_POLICY_TABLE_WIDEm: 3783 if (SOC_IS_TRIDENT3X(unit)) { 3784 num_mems = 3; 3785 mem_list[0] = IFP_POLICY_TABLEm; iratio[0] = 1; 3786 mem_list[1] = IFP_POLICY_TABLEm; iratio[1] = 1; 3787 mem_list[2] = IFP_POLICY_TABLE_WIDEm; iratio[2] = 1; 3788 } else { 3789 return SOC_E_UNAVAIL; 3790 } 3791 break; 3792 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK3_SUPPORT */ 3793 #ifdef BCM_TOMAHAWK3_SUPPORT 3794 case L3_TUNNEL_ECCm: 3795 if (SOC_IS_TOMAHAWK3(unit)) { 3796 num_mems = 3; 3797 mem_list[0] = L3_TUNNEL_SINGLEm; iratio[0] = 1; 3798 mem_list[1] = L3_TUNNEL_DOUBLEm; iratio[1] = 2; 3799 mem_list[2] = L3_TUNNEL_QUADm; iratio[2] = 4; 3800 } 3801 break; 3802 #endif 3803 3804 case VLAN_XLATE_1m: 3805 num_mems = 2; 3806 mem_list[1] = VLAN_XLATE_EXTDm; iratio[1] = 2; 3807 break; 3808 case L3_ENTRY_1m: 3809 num_mems = 3; 3810 mem_list[1] = L3_ENTRY_2m; iratio[1] = 2; 3811 mem_list[2] = L3_ENTRY_4m; iratio[2] = 4; 3812 break; 3813 case EGR_IP_TUNNELm: 3814 if (soc_feature(unit, soc_feature_common_egr_ip_tunnel_ser)) { 3815 num_mems = 0; 3816 if (SOC_MEM_IS_VALID(unit, EGR_IP_TUNNELm)) { 3817 mem_list[num_mems] = EGR_IP_TUNNELm; 3818 num_mems++; 3819 } else if (SOC_MEM_IS_VALID(unit, EGR_IP_TUNNEL_MPLSm)) { 3820 mem_list[num_mems] = EGR_IP_TUNNEL_MPLSm; 3821 num_mems++; 3822 } else if (SOC_MEM_IS_VALID(unit, EGR_IP_TUNNEL_IPV6m)) { 3823 mem_list[num_mems] = EGR_IP_TUNNEL_IPV6m; iratio[num_mems] = 2; 3824 num_mems++; 3825 } 3826 } else if (SOC_IS_TRIDENT(unit) && 3827 !(soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser))) { 3828 num_mems = 3; 3829 if (hw_cpu) { 3830 /* Sbus read */ 3831 mem_list[0] = EGR_IP_TUNNELm; 3832 mem_list[1] = EGR_IP_TUNNEL_MPLSm; 3833 mem_list[2] = EGR_IP_TUNNEL_IPV6m; 3834 } else { 3835 index *= 4; /* To keep the index ratio based logic below, consistent */ 3836 num_indexes[0] = 4; num_indexes[1] = 4; 3837 num_indexes[2] = 2; 3838 mem_list[0] = EGR_IP_TUNNELm; 3839 mem_list[1] = EGR_IP_TUNNEL_MPLSm; 3840 mem_list[2] = EGR_IP_TUNNEL_IPV6m; iratio[2] = 2; 3841 } 3842 } else if (soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser)) { 3843 /* Note: This is an exception case where the wider memories index is 3844 * used for reporting the error on a hw lookup while view name 3845 * received is always EGR_IP_TUNNEL in the correction routine. 3846 * On a cpu access error the actual view used for access is 3847 * used for reporting the error index but again the view name 3848 * is always EGR_IP_TUNNEL. 3849 * So for a reported index 'n' we will need to check/fix 3850 * index n/2 and n*2 as well. 3851 */ 3852 num_mems = 3; 3853 if (hw_cpu) { 3854 /* Sbus read */ 3855 mem_list[0] = EGR_IP_TUNNELm; 3856 mem_list[1] = EGR_IP_TUNNEL_MPLSm; 3857 if (soc_mem_index_valid(unit, EGR_IP_TUNNEL_IPV6m, index)) { 3858 mem_list[2] = EGR_IP_TUNNEL_IPV6m; 3859 } else { 3860 num_mems--; 3861 } 3862 } else { 3863 index *= 2; /* To keep the index ratio based logic below, consistent */ 3864 num_indexes[0] = 2; num_indexes[1] = 2; 3865 mem_list[0] = EGR_IP_TUNNELm; 3866 mem_list[1] = EGR_IP_TUNNEL_MPLSm; 3867 mem_list[2] = EGR_IP_TUNNEL_IPV6m; iratio[2] = 2; 3868 } 3869 } 3870 #if defined(BCM_TRIDENT3_SUPPORT) 3871 else if (soc_feature(unit, soc_feature_td3_style_mpls)) { 3872 num_mems = 4; 3873 mem_list[1] = EGR_IP_TUNNEL_MPLSm; 3874 mem_list[2] = EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm; iratio[2] = 2; 3875 mem_list[3] = EGR_IP_TUNNEL_IPV6m; iratio[3] = 2; 3876 } 3877 #endif /* BCM_TRIDENT3_SUPPORT */ 3878 else { 3879 num_mems = 3; 3880 mem_list[1] = EGR_IP_TUNNEL_MPLSm; 3881 mem_list[2] = EGR_IP_TUNNEL_IPV6m; iratio[2] = 2; 3882 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 3883 if (SOC_IS_APACHE(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TOMAHAWK3(unit)) { 3884 /* Index reported for EGR_IP_TUNNEL_MPLSm is different for apache. 3885 * Index reported is changed by factor of two. 3886 * Adjust index ratio accordingly 3887 */ 3888 iratio[1] = 2; 3889 } 3890 #endif /* BCM_APACHE_SUPPORT */ 3891 } 3892 break; 3893 case L3_ENTRY_ONLYm: 3894 if (SOC_MEM_IS_VALID(unit, L3_ENTRY_IPV4_UNICASTm)) { 3895 mem_list[0] = L3_ENTRY_IPV4_UNICASTm; 3896 } 3897 /* passthru */ 3898 /* coverity[fallthrough: FALSE] */ 3899 case L3_ENTRY_IPV4_UNICASTm: 3900 num_mems = 4; 3901 mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1; 3902 #ifdef BCM_SCORPION_SUPPORT 3903 if (SOC_IS_SCORPION(unit)) { 3904 mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 1; 3905 } else 3906 #endif 3907 { 3908 mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2; 3909 } 3910 mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2; 3911 mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4; 3912 break; 3913 case L3_ENTRY_IPV4_MULTICASTm: 3914 /* The iratio array is for IPv4_UC view, so need to convert the index to right one */ 3915 index *= 2; 3916 num_mems = 4; 3917 mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1; 3918 mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2; 3919 mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2; 3920 mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4; 3921 break; 3922 case L3_ENTRY_IPV6_UNICASTm: 3923 /* The iratio array is for IPv4_UC view, so need to convert the index to right one */ 3924 index *= 2; 3925 num_mems = 4; 3926 mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1; 3927 mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2; 3928 mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2; 3929 mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4; 3930 break; 3931 case L3_ENTRY_IPV6_MULTICASTm: 3932 /* The iratio array is for IPv4_UC view, so need to convert the index to right one */ 3933 index *= 4; 3934 num_mems = 4; 3935 mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1; 3936 mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2; 3937 mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2; 3938 mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4; 3939 break; 3940 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 3941 case L3_ENTRY_ONLY_ECCm: 3942 num_mems = 4; 3943 mem_list[0] = L3_ENTRY_IPV4_UNICASTm; iratio[0] = 1; 3944 mem_list[1] = L3_ENTRY_IPV4_MULTICASTm; iratio[1] = 2; 3945 mem_list[2] = L3_ENTRY_IPV6_UNICASTm; iratio[2] = 2; 3946 mem_list[3] = L3_ENTRY_IPV6_MULTICASTm; iratio[3] = 4; 3947 break; 3948 #endif 3949 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 3950 case L3_ENTRY_ECCm: 3951 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) { 3952 num_mems = 3; 3953 mem_list[0] = L3_ENTRY_SINGLEm; iratio[0] = 1; 3954 mem_list[1] = L3_ENTRY_DOUBLEm; iratio[1] = 2; 3955 mem_list[2] = L3_ENTRY_QUADm; iratio[2] = 4; 3956 } 3957 break; 3958 #ifdef SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT 3959 case INITIAL_L3_ECMPm: 3960 if (soc_esw_ecmp_protected_enabled(unit)) { 3961 rv = soc_esw_ecmp_protected_ser_update(unit, reported_mem, index); 3962 } 3963 break; 3964 #endif /* SOC_L3_ECMP_PROTECTED_ACCESS_SUPPORT */ 3965 case IFP_TCAMm: 3966 if (SOC_IS_TRIDENT3X(unit)) { 3967 num_mems = 2; 3968 mem_list[0] = IFP_TCAMm; iratio[0] = 1; num_indexes[0] = 1; 3969 /* In order to support the bcmFieldQualifyInPorts qualifier in 3970 * Global Mode, reads/writes on IFP_TCAM_WIDE should always be 3971 * in per pipe mode. 3972 */ 3973 mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe]; 3974 iratio[1] = 2; num_indexes[1] = 1; 3975 break; 3976 } else { 3977 return SOC_E_UNAVAIL; 3978 } 3979 case IFP_TCAM_PIPE0m: 3980 case IFP_TCAM_PIPE1m: 3981 if (SOC_IS_TRIDENT3X(unit)) { 3982 num_mems = 2; 3983 mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAMm)[pipe]; 3984 iratio[0] = 1; num_indexes[0] = 1; 3985 mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe]; 3986 iratio[1] = 2; num_indexes[1] = 1; 3987 break; 3988 } else { 3989 return SOC_E_UNAVAIL; 3990 } 3991 case IFP_TCAM_WIDEm: 3992 if (SOC_IS_TRIDENT3X(unit)) { 3993 index *= 2; 3994 num_mems = 2; 3995 mem_list[0] = IFP_TCAMm; iratio[0] = 1; num_indexes[0] = 2; 3996 /* In order to support the bcmFieldQualifyInPorts qualifier in 3997 * Global Mode, reads/writes on IFP_TCAM_WIDE should always be 3998 * in per pipe mode. 3999 */ 4000 mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe]; 4001 iratio[1] = 2; num_indexes[1] = 1; 4002 break; 4003 } else { 4004 return SOC_E_UNAVAIL; 4005 } 4006 case IFP_TCAM_WIDE_PIPE0m: 4007 case IFP_TCAM_WIDE_PIPE1m: 4008 if (SOC_IS_TRIDENT3X(unit)) { 4009 index *= 2; 4010 num_mems = 2; 4011 mem_list[0] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAMm)[pipe]; 4012 iratio[0] = 1; num_indexes[0] = 2; 4013 mem_list[1] = SOC_MEM_UNIQUE_ACC(unit, IFP_TCAM_WIDEm)[pipe]; 4014 iratio[1] = 2; num_indexes[1] = 1; 4015 break; 4016 } else { 4017 return SOC_E_UNAVAIL; 4018 } 4019 #endif 4020 #if defined(BCM_TOMAHAWK_SUPPORT) 4021 case FPEM_ECCm: 4022 case EXACT_MATCH_ECCm: 4023 /* Note: Assume both EM2, EM4 are always in same mode */ 4024 fpem_mem_mode = _soc_ser_mem_mode_get(unit, EXACT_MATCH_2m); 4025 num_mems = 2; 4026 mem_list[0] = _SOC_FPEM_EM2(pipe, fpem_mem_mode); iratio[0] = 2; 4027 mem_list[1] = _SOC_FPEM_EM4(pipe, fpem_mem_mode); iratio[1] = 4; 4028 break; 4029 case EXACT_MATCH_2m: 4030 reported_mem_is_fpem_lp = 1; 4031 /* means mem reported in ser_fifo is FPEM_LPm */ 4032 fpem_mem_mode = _soc_ser_mem_mode_get(unit, reported_mem); 4033 num_mems = 1; 4034 mem_list[0] = _SOC_FPEM_EM2(pipe, fpem_mem_mode); iratio[0] = 2; 4035 num_indexes[0] = _SOC_SER_NUM_EM_ENTRIES_PER_LP_ENTRY; 4036 /* each FPEM_LP entry covers 4 EM2 entries */ 4037 break; 4038 case EXACT_MATCH_4m: 4039 reported_mem_is_fpem_lp = 1; 4040 /* means mem reported in ser_fifo is FPEM_LPm */ 4041 fpem_mem_mode = _soc_ser_mem_mode_get(unit, reported_mem); 4042 num_mems = 1; 4043 mem_list[0] = _SOC_FPEM_EM4(pipe, fpem_mem_mode); iratio[0] = 4; 4044 num_indexes[0] = _SOC_SER_NUM_EM_ENTRIES_PER_LP_ENTRY; 4045 /* each FPEM_LP entry covers 4 EM4 entries */ 4046 break; 4047 #endif /* BCM_TOMAHAWK_SUPPORT */ 4048 case L3_DEFIP_128_DATA_ONLYm: 4049 num_mems = 1; 4050 mem_list[0] = L3_DEFIP_128m; 4051 break; 4052 #if defined(BCM_TRIDENT2_SUPPORT) 4053 case L3_DEFIP_PAIR_128_DATA_ONLYm: 4054 num_mems = 1; 4055 mem_list[0] = L3_DEFIP_PAIR_128_DATA_ONLYm; 4056 if (NUM_PIPE(unit) == 1) { 4057 /* Using cache restore from aggregated memory */ 4058 mem_list[0] = L3_DEFIP_PAIR_128m; 4059 } else if (SOC_IS_TD2_TT2(unit)) { 4060 num_indexes[0] = 2; 4061 index = (index / defip_cam_size) * defip_cam_size * 2 + 4062 (index % defip_cam_size); 4063 } 4064 break; 4065 #endif /* BCM_TRIDENT2_SUPPORT */ 4066 case L3_DEFIP_DATA_ONLYm: 4067 if (soc_feature(unit, soc_feature_l3_defip_map)) { 4068 num_mems = 1; 4069 #ifdef BCM_TRIUMPH3_SUPPORT 4070 if ((SOC_IS_TRIUMPH3(unit)) || ((SOC_IS_HELIX4(unit)) && 4071 (!soc_feature(unit, soc_feature_l3_256_defip_table))) ) { 4072 index = soc_tr3_l3_defip_mem_index_get(unit, index, 4073 &mem_list[0]); 4074 } else 4075 #endif /* BCM_TRIUMPH3_SUPPORT */ 4076 #ifdef BCM_KATANA_SUPPORT 4077 if (SOC_IS_KATANA(unit)) { 4078 index = soc_kt_l3_defip_mem_index_get(unit, index, 4079 &mem_list[0]); 4080 } else 4081 #endif /* BCM_TRIUMPH3_SUPPORT */ 4082 #ifdef BCM_KATANA2_SUPPORT 4083 if (SOC_IS_KATANA2(unit)) { 4084 index = soc_kt2_l3_defip_index_map(unit, mem_list[0], index); 4085 index = soc_kt2_l3_defip_mem_index_get(unit, index, 4086 &mem_list[0]); 4087 if (mem_list[0] == L3_DEFIP_DATA_ONLYm) { 4088 mem_list[0] = L3_DEFIPm; 4089 } else if (mem_list[0] == L3_DEFIP_PAIR_128_DATA_ONLYm) { 4090 mem_list[0] = L3_DEFIP_PAIR_128m; 4091 } 4092 } else 4093 #endif /* BCM_KATANA2_SUPPORT */ 4094 #if defined(BCM_MONTEREY_SUPPORT) 4095 if (SOC_IS_MONTEREY(unit)) { 4096 LOG_VERBOSE(BSL_LS_SOC_SER, 4097 (BSL_META_U(unit, 4098 "ap_dbg: " 4099 "phys_index = %0d for mem = %0d\n"), 4100 index, mem_list[0])); 4101 /* The index is logical index, we need convert to physical index first*/ 4102 index = soc_monterey_l3_defip_index_map(unit, mem_list[0], index); 4103 4104 index = soc_monterey_l3_defip_mem_index_get(unit, index, 4105 &mem_list[0]); 4106 LOG_VERBOSE(BSL_LS_SOC_SER, 4107 (BSL_META_U(unit, 4108 "ap_dbg: " 4109 "logical_index = %0d for mem = %0d\n"), 4110 index, mem_list[0])); 4111 } else 4112 #endif /* BCM_MONTEREY_SUPPORT */ 4113 #if defined(BCM_APACHE_SUPPORT) 4114 if (SOC_IS_APACHE(unit)) { 4115 LOG_VERBOSE(BSL_LS_SOC_SER, 4116 (BSL_META_U(unit, 4117 "ap_dbg: " 4118 "phys_index = %0d for mem = %0d\n"), 4119 index, mem_list[0])); 4120 /* The index is logical index, we need convert to physical index first*/ 4121 index = soc_apache_l3_defip_index_map(unit, mem_list[0], index); 4122 4123 index = soc_apache_l3_defip_mem_index_get(unit, index, 4124 &mem_list[0]); 4125 LOG_VERBOSE(BSL_LS_SOC_SER, 4126 (BSL_META_U(unit, 4127 "ap_dbg: " 4128 "logical_index = %0d for mem = %0d\n"), 4129 index, mem_list[0])); 4130 } else 4131 #endif /* BCM_APACHE_SUPPORT */ 4132 #if defined(BCM_TRIDENT3_SUPPORT) 4133 if (SOC_IS_TRIDENT3X(unit) && NUM_PIPE(unit) == 1) { 4134 /* Using cache restore from aggregated memory 4135 * Index remaping already done 4136 */ 4137 mem_list[0] = L3_DEFIPm; 4138 } else 4139 #endif 4140 #if defined(BCM_TRIDENT2_SUPPORT) 4141 if (SOC_IS_TD2_TT2(unit)) { 4142 LOG_VERBOSE(BSL_LS_SOC_SER, 4143 (BSL_META_U(unit, 4144 "th_dbg: " 4145 "phys_index = %0d for mem = %0d\n"), 4146 index, mem_list[0])); 4147 4148 (void)soc_trident2_l3_defip_mem_index_get(unit, index, 4149 &mem_list[0]); 4150 LOG_VERBOSE(BSL_LS_SOC_SER, 4151 (BSL_META_U(unit, 4152 "th_dbg: " 4153 "logical_index = %0d for mem = %0d\n"), 4154 index, mem_list[0])); 4155 /* Lets only correct the data portion of the TCAM to avoid 4156 getting into deadlock situation in bulk op retry for TD2. 4157 Note that mem cache is not used for this memory anyways. */ 4158 if (mem_list[0] == L3_DEFIPm) { 4159 mem_list[0] = L3_DEFIP_DATA_ONLYm; 4160 LOG_VERBOSE(BSL_LS_SOC_SER, 4161 (BSL_META_U(unit, 4162 "th_dbg: mem_for_restore=%0d:" 4163 "L3_DEFIP_DATA_ONLYm\n"), mem_list[0])); 4164 } else if (mem_list[0] == L3_DEFIP_PAIR_128m) { 4165 mem_list[0] = L3_DEFIP_PAIR_128_DATA_ONLYm; 4166 num_indexes[0] = 2; 4167 LOG_VERBOSE(BSL_LS_SOC_SER, 4168 (BSL_META_U(unit, 4169 "th_dbg: mem_for_restore=%0d:" 4170 "L3_DEFIP_PAIR_128_DATA_ONLYm\n"), 4171 mem_list[0])); 4172 } 4173 if (SOC_CONTROL(unit)->alpm_bulk_retry) { 4174 sal_sem_give(SOC_CONTROL(unit)->alpm_bulk_retry); 4175 } 4176 } else 4177 #endif /* BCM_TRIDENT2_SUPPORT */ 4178 #if defined(BCM_TRIUMPH_SUPPORT) 4179 if (SOC_IS_TRIUMPH(unit)) { 4180 num_mems = 1; 4181 mem_list[0] = L3_DEFIPm; 4182 break; 4183 } else 4184 #endif /* BCM_TRIUMPH_SUPPORT */ 4185 { 4186 4187 return SOC_E_UNAVAIL; 4188 } 4189 break; 4190 } else 4191 #if defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_ENDURO_SUPPORT) 4192 if (SOC_IS_TRIUMPH(unit) || SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || 4193 SOC_IS_HURRICANE3(unit)) { 4194 #ifdef BCM_ENDURO_SUPPORT 4195 if (SOC_IS_ENDURO(unit)) { 4196 index = soc_enduro_l3_defip_index_map(unit, mem_list[0], index); 4197 } 4198 #endif /* BCM_ENDURO_SUPPORT */ 4199 num_mems = 1; 4200 mem_list[0] = L3_DEFIPm; 4201 break; 4202 } else 4203 #endif 4204 { 4205 return SOC_E_UNAVAIL; 4206 } 4207 default: 4208 return SOC_E_UNAVAIL; 4209 } 4210 for (m = 0; m < num_mems; m++) { 4211 mem = mem_list[m]; 4212 entry_dw = soc_mem_entry_words(unit, mem); 4213 4214 MEM_LOCK(unit, mem_list[m]); 4215 4216 #ifdef BCM_TRIDENT3_SUPPORT 4217 if (SOC_IS_TRIDENT3X(unit) && NUM_PIPE(unit) == 1) { 4218 if (reported_mem == ING_VP_VLAN_MEMBERSHIP_ECCm || 4219 reported_mem == EGR_VP_VLAN_MEMBERSHIP_ECCm || 4220 reported_mem == ING_DNAT_ADDRESS_TYPE_ECCm || 4221 reported_mem == SUBPORT_ID_TO_SGPP_MAP_ECCm) { 4222 /* There is no DISABLE_SBUS_MEMWR_ECC_CHECK field in following mems 4223 * ING_VP_VLAN_MEMBERSHIP_HASH_CONTROL 4224 * EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROL 4225 * ING_DNAT_ADDRESS_TYPE_HASH_CONTROL 4226 * SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROL 4227 * So we need to clear the error entry first to be able to 4228 * CACHE_RESTORE entries in functional view 4229 */ 4230 null_entry = soc_mem_entry_null(unit, reported_mem); 4231 (void)soc_mem_write(unit, reported_mem, copyno, index/2, null_entry); 4232 } 4233 } 4234 #endif 4235 /* coverity[negative_returns] */ 4236 cache = SOC_MEM_STATE(unit, mem).cache[copyno]; 4237 vmap = SOC_MEM_STATE(unit, mem).vmap[copyno]; 4238 vindex = index/iratio[m]; 4239 #ifdef BCM_TRIDENT3_SUPPORT 4240 if (SOC_IS_TRIDENT3X(unit)) { 4241 if ((mem == IFP_POLICY_TABLE_WIDEm) && (reported_mem == IFP_POLICY_TABLEm)) { 4242 vindex = vindex / SOC_TD3_FP_SLICE_ENTRY_NARROW_VIEW * 4243 SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW + 4244 vindex % SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW; 4245 } else if ((mem == IFP_POLICY_TABLEm) && (reported_mem == IFP_POLICY_TABLE_WIDEm)) { 4246 /* One IFP_POLICY_TABLE_WIDE entry has two IFP_POLICY_TABLE entries. 4247 * Need to calculate the index twice. 4248 */ 4249 if (m == 0) { 4250 vindex = vindex / SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW * 4251 SOC_TD3_FP_SLICE_ENTRY_NARROW_VIEW + 4252 vindex % SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW; 4253 } else if (m == 1) { 4254 vindex = vindex / SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW * 4255 SOC_TD3_FP_SLICE_ENTRY_NARROW_VIEW + 4256 vindex % SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW; 4257 /* calculate second single entry's index */ 4258 vindex += SOC_TD3_FP_SLICE_ENTRY_WIDE_VIEW; 4259 } 4260 } 4261 } 4262 #endif 4263 for (i = 0; i < num_indexes[m]; i++) { 4264 if (cache != NULL && CACHE_VMAP_TST(vmap, vindex+i)) { 4265 sal_memcpy(entry, cache + ((vindex+i) * entry_dw), 4266 entry_dw * 4); 4267 mem_for_write = mem; 4268 index_for_write = vindex + i; 4269 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 4270 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || 4271 SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 4272 switch (mem) { 4273 case L3_ENTRY_IPV4_UNICASTm: 4274 ecc_data_field = ECC_DATAf; 4275 soc_mem_field_get(unit, mem, 4276 cache + ((vindex+i) * entry_dw), 4277 ecc_data_field, entry); 4278 mem_for_write = L3_ENTRY_ONLY_ECCm; 4279 index_for_write = index + i; 4280 break; 4281 case L3_ENTRY_IPV4_MULTICASTm: 4282 case L3_ENTRY_IPV6_UNICASTm: 4283 case L3_ENTRY_IPV6_MULTICASTm: 4284 switch(index % iratio[m]) { 4285 case 1: ecc_data_field = ECC_DATA1f; break; 4286 case 2: ecc_data_field = ECC_DATA2f; break; 4287 case 3: ecc_data_field = ECC_DATA3f; break; 4288 default: ecc_data_field = ECC_DATA0f; break; 4289 } 4290 soc_mem_field_get(unit, mem, 4291 cache + ((vindex+i) * entry_dw), 4292 ecc_data_field, entry); 4293 mem_for_write = L3_ENTRY_ONLY_ECCm; 4294 index_for_write = index + i; 4295 break; 4296 #if defined(BCM_TOMAHAWK_SUPPORT) 4297 case EXACT_MATCH_2m: 4298 case EXACT_MATCH_2_PIPE0m: 4299 case EXACT_MATCH_2_PIPE1m: 4300 case EXACT_MATCH_2_PIPE2m: 4301 case EXACT_MATCH_2_PIPE3m: 4302 case EXACT_MATCH_4m: 4303 case EXACT_MATCH_4_PIPE0m: 4304 case EXACT_MATCH_4_PIPE1m: 4305 case EXACT_MATCH_4_PIPE2m: 4306 case EXACT_MATCH_4_PIPE3m: 4307 if (!reported_mem_is_fpem_lp) { 4308 /* reported_mem is FPEM_ECC or EXACT_MATCH_ECCm */ 4309 switch (index % iratio[m]) { 4310 case 1: ecc_data_field = ECC_DATA1f; break; 4311 case 2: ecc_data_field = ECC_DATA2f; break; 4312 case 3: ecc_data_field = ECC_DATA3f; break; 4313 default: ecc_data_field = ECC_DATA0f; break; 4314 } 4315 soc_mem_field_get(unit, mem, 4316 cache + ((vindex+i)*entry_dw), 4317 ecc_data_field, entry); 4318 #ifdef BCM_TOMAHAWK3_SUPPORT 4319 if (SOC_IS_TOMAHAWK3(unit)) { 4320 mem_for_write = EXACT_MATCH_ECCm; 4321 } else 4322 #endif 4323 if (SOC_IS_TRIDENT3X(unit)) { 4324 mem_for_write = _SOC_EXACT_MATCH_ECC(pipe, 4325 fpem_mem_mode); 4326 } else { 4327 mem_for_write = _SOC_FPEM_ECC(pipe, 4328 fpem_mem_mode); 4329 } 4330 index_for_write = index + i; 4331 } 4332 break; 4333 #endif /* BCM_TOMAHAWK_SUPPORT */ 4334 case MPLS_ENTRYm: 4335 if (SOC_IS_TOMAHAWKX(unit)) { 4336 mem_for_write = MPLS_ENTRY_ECCm; 4337 } 4338 break; 4339 default: 4340 break; 4341 } 4342 } 4343 #endif /* (BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) */ 4344 rv = soc_mem_write(unit, mem_for_write, copyno, 4345 index_for_write, entry); 4346 if (NULL != si) { 4347 if ((si->log_id != 0) && 4348 (si->flags & SOC_SER_LOG_WRITE_CACHE)) { 4349 if (si->index == index_for_write) { 4350 (void)soc_ser_log_add_tlv(unit, si->log_id, 4351 SOC_SER_LOG_TLV_CACHE, 4352 soc_mem_entry_words(unit, mem_for_write)*4, 4353 entry); 4354 } else { 4355 LOG_VERBOSE(BSL_LS_SOC_SER, 4356 (BSL_META_U(unit, 4357 "skipped updating tlv_cache index: %d\n"), 4358 index_for_write)); 4359 } 4360 } 4361 si->ctype = SocSerCorrectTypeCacheRestore; 4362 } 4363 if (rv < 0) { 4364 LOG_ERROR(BSL_LS_SOC_SER, 4365 (BSL_META_U(unit, 4366 "CACHE_RESTORE %s.%s[%d] failed: %s\n"), 4367 SOC_MEM_NAME(unit, mem_for_write), 4368 SOC_BLOCK_NAME(unit, copyno), index_for_write, 4369 soc_errmsg(rv))); 4370 MEM_UNLOCK(unit, mem_list[m]); 4371 4372 return rv; 4373 } 4374 fix++; 4375 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4376 si, mem, vindex); 4377 LOG_WARN(BSL_LS_SOC_SER, 4378 (BSL_META_U(unit, 4379 "CACHE_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"), 4380 SOC_MEM_NAME(unit, mem_for_write), 4381 mem_for_write, SOC_BLOCK_NAME(unit, copyno), 4382 index_for_write, sblk, addr)); 4383 stat->ser_err_restor++; 4384 LOG_VERBOSE(BSL_LS_SOC_SER, 4385 (BSL_META_U(unit, 4386 "th_dbg: this CACHE_RESTORE was " 4387 "from overlay_mem_correction\n"))); 4388 } 4389 if (cache == NULL) { 4390 /* Do hw cache (from the other pipe) based correction if s/w mem 4391 cache is not available */ 4392 #if defined(BCM_TRIDENT2_SUPPORT) 4393 if (((mem_list[m] == L3_DEFIP_PAIR_128_DATA_ONLYm) || 4394 mem_list[m] == L3_DEFIP_DATA_ONLYm) 4395 && SOC_IS_TD2_TT2(unit) && !SOC_IS_APACHE(unit)) { 4396 mem = L3_DEFIP_DATA_ONLYm; 4397 if (mem_list[m] == L3_DEFIP_PAIR_128_DATA_ONLYm) { 4398 phy_index= ((vindex / (defip_cam_size * 2)) * defip_cam_size * 2) 4399 + (vindex % defip_cam_size) + (i * defip_cam_size); 4400 } else { 4401 phy_index = vindex; 4402 } 4403 rv = _soc_ser_recovery_hw_cache(unit, pipe, mem, copyno, 4404 phy_index, si, TRUE); 4405 } else 4406 #endif 4407 { 4408 rv = _soc_ser_recovery_hw_cache(unit, pipe, mem, copyno, 4409 vindex+i, si, FALSE); 4410 } 4411 if (!(rv == SOC_E_NONE || rv == SOC_E_UNAVAIL)) { 4412 return rv; 4413 } else if (rv == SOC_E_NONE) { 4414 fix++; 4415 } 4416 } 4417 if (reported_mem_is_fpem_lp && (fix > 0)) { 4418 /* reported_mem_is_fpem_lp implies that we are doing indirect 4419 * restore of LP control word by writing to one of the 4420 * functional views (EXACT_MATCH_2,4) 4421 * We need to restore only one of the 4 entries for 4422 * corresponding LP control word to be recomputed. 4423 * Thus, after we do the 1st restore - exit. 4424 * 4425 * reported_mem_is_fpem_lp also implies that 'mem' is either 4426 * EXACT_MATCH_2m or 4427 * EXACT_MATCH_2_PIPE0m or 4428 * EXACT_MATCH_2_PIPE1m or 4429 * EXACT_MATCH_2_PIPE2m or 4430 * EXACT_MATCH_2_PIPE3m or 4431 * EXACT_MATCH_4m or 4432 * EXACT_MATCH_4_PIPE0m or 4433 * EXACT_MATCH_4_PIPE1m or 4434 * EXACT_MATCH_4_PIPE2m or 4435 * EXACT_MATCH_4_PIPE3m 4436 */ 4437 break; 4438 } 4439 } /* each index */ 4440 MEM_UNLOCK(unit, mem_list[m]); 4441 4442 if ((mem == L3_ENTRY_ONLYm) || (mem == L3_ENTRY_IPV4_UNICASTm) || 4443 (mem == L3_ENTRY_IPV4_MULTICASTm) || (mem == L3_ENTRY_IPV6_UNICASTm) || 4444 (mem == L3_ENTRY_IPV6_MULTICASTm) || 4445 _SOC_MEM_CHK_FPEM_MEM(mem)) { 4446 if (fix != 0) { 4447 break; 4448 } 4449 } 4450 } /* each mem */ 4451 if (fix == 0) { 4452 LOG_VERBOSE(BSL_LS_SOC_SER, 4453 (BSL_META_U(unit, 4454 "th_dbg: overlay_mem_correction falling " 4455 "back to CLEAR_RESTORE\n"))); 4456 /* Fall back to clear - this is always the widest view */ 4457 #if defined(BCM_TRX_SUPPORT) 4458 /* For L3_ENTRY_*, clear the entry in L3_ENTRY_IPV4_UNICAST view */ 4459 if (SOC_IS_TRX(unit)) { 4460 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 4461 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || 4462 SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 4463 vindex = index; 4464 switch (mem) { 4465 case MPLS_ENTRYm: 4466 #ifdef BCM_TOMAHAWK3_SUPPORT 4467 case MPLS_ENTRY_SINGLEm: 4468 #endif 4469 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 4470 mem = MPLS_ENTRY_ECCm; 4471 } 4472 break; 4473 case L3_ENTRY_IPV6_MULTICASTm: 4474 mem = L3_ENTRY_ONLY_ECCm; 4475 break; 4476 #if defined(BCM_TOMAHAWK3_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 4477 case L3_ENTRY_QUADm: 4478 mem = L3_ENTRY_ECCm; 4479 break; 4480 #endif 4481 #if defined(BCM_TOMAHAWK3_SUPPORT) 4482 case L3_TUNNEL_QUADm: 4483 mem = L3_TUNNEL_ECCm; 4484 break; 4485 #endif 4486 #if defined(BCM_TRIDENT3_SUPPORT) 4487 case EGR_VLAN_XLATE_1_DOUBLEm: 4488 mem = EGR_VLAN_XLATE_1_ECCm; 4489 break; 4490 case EGR_VLAN_XLATE_2_DOUBLEm: 4491 mem = EGR_VLAN_XLATE_2_ECCm; 4492 break; 4493 case VLAN_XLATE_1_DOUBLEm: 4494 mem = VLAN_XLATE_1_ECCm; 4495 break; 4496 case VLAN_XLATE_2_DOUBLEm: 4497 mem = VLAN_XLATE_2_ECCm; 4498 break; 4499 case IFP_TCAM_WIDEm: 4500 case IFP_TCAM_WIDE_PIPE0m: 4501 case IFP_TCAM_WIDE_PIPE1m: 4502 mem = reported_mem; 4503 if ((mem == IFP_TCAM_WIDEm) || 4504 (mem == IFP_TCAM_WIDE_PIPE0m) || 4505 (mem == IFP_TCAM_WIDE_PIPE1m)) { 4506 vindex = index / 2; 4507 } 4508 break; 4509 case IFP_POLICY_TABLE_WIDEm: 4510 mem = reported_mem; 4511 vindex = index; 4512 break; 4513 #endif 4514 case EXACT_MATCH_2m: 4515 /* we can be here only when (reported_mem == FPEM_LPm) */ 4516 /* Write to ENTRY_ONLY view to prevent cache from 4517 * recording that there is EXACT_MATCH_2 type entry at this 4518 * location. 4519 * Clear this FPEM_LPm location 4520 * Because at corresponding locatons in fv, we may have EM4 4521 * entries, so this LP entry is NULL */ 4522 #ifdef BCM_TOMAHAWK3_SUPPORT 4523 if (SOC_IS_TOMAHAWK3(unit)) { 4524 mem = EXACT_MATCH_ECCm; 4525 } else 4526 #endif 4527 #ifdef BCM_TRIDENT3_SUPPORT 4528 if (SOC_IS_TRIDENT3X(unit)) { 4529 mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode);; 4530 } else 4531 #endif 4532 { 4533 mem = FPEM_LPm; 4534 vindex = _soc_fv_lp_index_remap(index, 1); 4535 } 4536 break; 4537 case EXACT_MATCH_2_PIPE0m: 4538 case EXACT_MATCH_2_PIPE1m: 4539 case EXACT_MATCH_2_PIPE2m: 4540 case EXACT_MATCH_2_PIPE3m: 4541 /* Can be here only when (reported_mem == FPEM_LPm) */ 4542 /* Write to ENTRY_ONLY view to prevent cache from 4543 * recording that there is EXACT_MATCH_2 type entry at this 4544 * location. 4545 * Clear this FPEM_LPm location 4546 * Because at corresponding locatons in fv, we may have EM4 4547 * entries, so this LP entry is NULL */ 4548 #ifdef BCM_TRIDENT3_SUPPORT 4549 if (SOC_IS_TRIDENT3X(unit)) { 4550 mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode); 4551 } else 4552 #endif 4553 { 4554 mem = FPEM_LPm; 4555 vindex = _soc_fv_lp_index_remap(index, 1); 4556 use_pipe_select_write = 1; 4557 acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe); 4558 } 4559 break; 4560 case EXACT_MATCH_4m: 4561 #ifdef BCM_TOMAHAWK3_SUPPORT 4562 if (SOC_IS_TOMAHAWK3(unit)) { 4563 mem = EXACT_MATCH_ECCm; 4564 } else 4565 #endif 4566 #ifdef BCM_TRIDENT3_SUPPORT 4567 if (SOC_IS_TRIDENT3X(unit)) { 4568 mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode); 4569 } else 4570 #endif 4571 { 4572 if (!reported_mem_is_fpem_lp) { 4573 /* reported_mem is FPEM_ECCm */ 4574 mem = FPEM_ECCm; 4575 } else { /* (reported_mem == FPEM_LPm) */ 4576 /* Write to ENTRY_ONLY view to prevent cache from 4577 * recording that there is EXACT_MATCH_4 type entry at 4578 * this location. 4579 * Clear this FPEM_LPm location 4580 * Because at corresponding locatons in fv, we may have EM2 4581 * entries, so this LP entry is NULL */ 4582 mem = FPEM_LPm; 4583 vindex = _soc_fv_lp_index_remap(index, 0); 4584 } 4585 } 4586 break; 4587 case EXACT_MATCH_4_PIPE0m: 4588 case EXACT_MATCH_4_PIPE1m: 4589 case EXACT_MATCH_4_PIPE2m: 4590 case EXACT_MATCH_4_PIPE3m: 4591 #ifdef BCM_TRIDENT3_SUPPORT 4592 if (SOC_IS_TRIDENT3X(unit)) { 4593 mem = _SOC_EXACT_MATCH_ECC(pipe, fpem_mem_mode); 4594 } else 4595 #endif 4596 { 4597 if (!reported_mem_is_fpem_lp) { 4598 /* reported_mem is FPEM_ECCm */ 4599 mem = _SOC_FPEM_ECC(pipe, 4600 _SOC_SER_MEM_MODE_PIPE_UNIQUE); 4601 } else { /* (reported_mem == FPEM_LPm) */ 4602 /* Write to ENTRY_ONLY view to prevent cache from 4603 * recording that there is EXACT_MATCH_4 type entry at 4604 * this location. 4605 * Clear this FPEM_LPm location 4606 * Because at corresponding locatons in fv, we may have EM2 4607 * entries, so this LP entry is NULL */ 4608 mem = FPEM_LPm; 4609 vindex = _soc_fv_lp_index_remap(index, 0); 4610 use_pipe_select_write = 1; 4611 acc_type = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe); 4612 } 4613 } 4614 break; 4615 case EGR_IP_TUNNEL_IPV6m: 4616 mem = reported_mem; 4617 vindex = index; 4618 break; 4619 default: 4620 break; 4621 } 4622 } else 4623 #endif /* BCM_TOMAHAWK_SUPPORT */ 4624 { 4625 if (mem == L3_ENTRY_IPV6_MULTICASTm) { 4626 mem = L3_ENTRY_ONLYm; 4627 vindex = index; 4628 } 4629 } 4630 } 4631 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) { 4632 if (mem == L3_ENTRY_4m) { 4633 mem = L3_ENTRY_1m; 4634 vindex = index; 4635 } 4636 } 4637 if (SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT(unit)) { 4638 mem = mem_list[0]; 4639 vindex = index; 4640 } 4641 4642 if (EGR_IP_TUNNELm == reported_mem) { 4643 clear_mems = 2; 4644 if ((SOC_IS_TRIDENT(unit) && 4645 !soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser)) || 4646 soc_feature(unit, soc_feature_special_egr_ip_tunnel_ser)) { 4647 /* SBUS read triggers */ 4648 mem_list[0] = EGR_IP_TUNNELm; 4649 mem_list[1] = EGR_IP_TUNNEL_IPV6m; 4650 iratio[0] = 1; 4651 iratio[1] = 1; 4652 4653 /* Error exists in EGR_IP_TUNNEL if index is bigger than max of ipv6 */ 4654 if (index > soc_mem_index_max(unit, EGR_IP_TUNNEL_IPV6m)) { 4655 clear_mems = 1; 4656 } 4657 } else { 4658 mem_list[0] = EGR_IP_TUNNELm; 4659 mem_list[1] = EGR_IP_TUNNEL_IPV6m; 4660 iratio[0] = 1; 4661 iratio[1] = 2; 4662 } 4663 4664 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || 4665 SOC_IS_TRIDENT3X(unit)) { 4666 int neighbour_index; 4667 soc_mem_t check_mem_list[2] = 4668 {EGR_IP_TUNNELm, EGR_IP_TUNNEL_MPLSm}; 4669 4670 neighbour_index = index % 2? index -1 : index + 1; 4671 4672 /* Check if the neighbour is valid or not for 4673 * EGR_IP_TUNNEL or EGR_IP_TUNNEL_MPLS view. 4674 * If yes, do not clear EGR_IP_TUNNEL_IPV6 view. 4675 * If no, clear EGR_IP_TUNNEL_IPV6 view. 4676 */ 4677 for (i = 0; i < 2; i++) { 4678 cache = SOC_MEM_STATE(unit, check_mem_list[i]).cache[copyno]; 4679 vmap = SOC_MEM_STATE(unit, check_mem_list[i]).vmap[copyno]; 4680 4681 if (cache != NULL && CACHE_VMAP_TST(vmap, neighbour_index)) { 4682 clear_mems = 1; 4683 break; 4684 } 4685 } 4686 } 4687 } 4688 #endif 4689 for (i = 0; i < clear_mems; i++) { 4690 if (EGR_IP_TUNNELm == reported_mem) { 4691 mem = mem_list[i]; 4692 vindex = index / iratio[i]; 4693 } 4694 null_entry = soc_mem_entry_null(unit, mem); 4695 if (use_pipe_select_write) { 4696 rv = soc_mem_pipe_select_write(unit, SOC_MEM_NO_FLAGS, mem, 4697 copyno, acc_type, vindex, 4698 null_entry); 4699 } else { 4700 rv = soc_mem_write(unit, mem, copyno, vindex, null_entry); 4701 } 4702 if (NULL != si) { 4703 si->ctype = SocSerCorrectTypeEntryClear; 4704 } 4705 if (rv < 0) { 4706 LOG_ERROR(BSL_LS_SOC_SER, 4707 (BSL_META_U(unit, 4708 "CLEAR_RESTORE %s.%s[%d] failed: %s\n"), 4709 SOC_MEM_NAME(unit, mem), 4710 SOC_BLOCK_NAME(unit, copyno), 4711 vindex, soc_errmsg(rv))); 4712 return rv; 4713 } 4714 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4715 si, mem, vindex); 4716 LOG_WARN(BSL_LS_SOC_SER, 4717 (BSL_META_U(unit, 4718 "CLEAR_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"), 4719 SOC_MEM_NAME(unit, mem), mem, 4720 SOC_BLOCK_NAME(unit, copyno), 4721 vindex, sblk, addr)); 4722 LOG_VERBOSE(BSL_LS_SOC_SER, 4723 (BSL_META_U(unit, 4724 "th_dbg: overlay_mem_correction did " 4725 "CLEAR_RESTORE !!\n"))); 4726 if (_SOC_DRV_MEM_CHK_L2_MEM(mem) && 4727 soc_feature(unit, soc_feature_mac_learn_limit)) { 4728 /* coverity[stack_use_overflow] */ 4729 if ((rv =_soc_ser_sync_mac_limits(unit, mem)) != SOC_E_NONE) { 4730 LOG_ERROR(BSL_LS_SOC_SER, 4731 (BSL_META_U(unit, 4732 "L2 mac limit sync failed !!\n"))); 4733 return rv; 4734 } 4735 } 4736 } 4737 stat->ser_err_clear++; 4738 } 4739 return SOC_E_NONE; 4740 } 4741 4742 void 4743 _soc_sram_info_init(int unit, _soc_ser_sram_info_t *sram_info) 4744 { 4745 sal_memset(sram_info, 0x00, sizeof(_soc_ser_sram_info_t)); 4746 sram_info->disable_reg = INVALIDr; 4747 sram_info->disable_field = INVALIDf; 4748 sram_info->disable_mem = INVALIDm; 4749 sram_info->disable_mem_field = INVALIDf; 4750 sram_info->disable_mem_index = -1; 4751 sram_info->force_reg = INVALIDr; 4752 sram_info->force_mem = INVALIDm; 4753 sram_info->force_field = INVALIDf; 4754 sram_info->disable_xor_write_field = INVALIDf; 4755 return; 4756 } 4757 4758 STATIC int 4759 _soc_ser_sram_correction(int unit, int pipe, int sblk, int addr, soc_mem_t mem, 4760 int copyno, int index, uint8 mode, 4761 _soc_ser_correct_info_t *si) 4762 { 4763 #define _SOC_SER_SRAM_CHK_RETURN(str) \ 4764 if (rv != SOC_E_NONE) {\ 4765 LOG_ERROR(BSL_LS_SOC_SER, \ 4766 (BSL_META_U(unit, \ 4767 "SER SRAM correction encoutered error(%d) in %s\n"), \ 4768 rv, str));\ 4769 if (mem_to_lock != INVALIDm) { \ 4770 MEM_UNLOCK(unit, mem_to_lock); \ 4771 } \ 4772 goto free_exit;\ 4773 } 4774 4775 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4776 /* 4777 * For TD2+, L2X thread is frozen for L2X memory corrections done 4778 * via L2_ENTRY_ONLY_ECC memory. 4779 * For Apache, L2X thread is also frozen for correcting LP memory 4780 */ 4781 #define _SOC_IF_ERR_L2X_THAW(rv, mem) \ 4782 if (((mem == L2_ENTRY_ONLY_ECCm) && \ 4783 (soc_feature(unit, soc_feature_td2p_a0_sw_war) || \ 4784 soc_feature(unit, soc_feature_l2_activity_freeze_ser))) || \ 4785 (((mem == L2_ENTRY_LPm) || (mem == L2_ENTRY_ISS_LPm)) && \ 4786 soc_feature(unit, soc_feature_l2_activity_freeze_ser))) { \ 4787 if (rv != SOC_E_NONE) { \ 4788 rv1 = soc_l2x_thaw(unit); \ 4789 if (SOC_FAILURE(rv1)) { \ 4790 LOG_WARN(BSL_LS_SOC_SER, \ 4791 (BSL_META_U(unit, \ 4792 "L2 thaw failed in %s correction\n"), \ 4793 SOC_MEM_NAME(unit, mem))); \ 4794 rv = rv1; \ 4795 } \ 4796 if (mem_to_lock != INVALIDm) { \ 4797 MEM_UNLOCK(unit, mem_to_lock); \ 4798 } \ 4799 goto free_exit; \ 4800 } \ 4801 } 4802 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4803 4804 void *null_entry; 4805 int is_l3_defip = FALSE; 4806 uint8 *vmap, at = 0, _l2_lock = 0; 4807 #if defined(ALPM_ENABLE) 4808 uint8 _alpm_lock = 0; 4809 #endif /* ALPM_ENABLE */ 4810 int rv = SOC_E_NONE, i, j, start_index, entry_dw, block; 4811 soc_stat_t *stat = SOC_STAT(unit); 4812 _soc_ser_sram_info_t *sram_info = NULL; 4813 uint32 *entry = NULL, rval, *cache, raddr = 0; 4814 soc_mem_t mem_to_restore = mem, mem_to_lock = mem, mem_for_cache_read = mem; 4815 soc_mem_t mem_to_report = mem; 4816 #if defined(BCM_TOMAHAWK_SUPPORT) 4817 int fpem_mem_mode = _SOC_SER_MEM_MODE_GLOBAL; 4818 #endif /* BCM_TOMAHAWK_SUPPORT */ 4819 int use_overlay_mem_correction = 0; 4820 int use_recovery_hw_cache = 0; 4821 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4822 int rv1; 4823 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4824 uint32 hash_control_entry[4]; 4825 soc_ser_correction_type_t ctype = SocSerCorrectTypeEntryClear; 4826 4827 LOG_VERBOSE(BSL_LS_SOC_SER, 4828 (BSL_META_U(unit, 4829 "th_dbg: entered _soc_ser_sram_correction " 4830 "routine\n"))); 4831 4832 if (!SOC_MEM_IS_VALID(unit, mem) || index < 0 || 4833 !(mode == _SOC_SER_SRAM_CORRECTION_MODE_0 || 4834 mode == _SOC_SER_SRAM_CORRECTION_MODE_1)) { 4835 return SOC_E_PARAM; 4836 } 4837 sram_info = sal_alloc(sizeof(_soc_ser_sram_info_t), "sram info"); 4838 if (sram_info == NULL) { 4839 return SOC_E_MEMORY; 4840 } 4841 entry = sal_alloc((4 * SOC_MAX_MEM_WORDS), "sram_entry"); 4842 if (entry == NULL) { 4843 rv = SOC_E_MEMORY; 4844 goto free_exit; 4845 } 4846 _soc_sram_info_init(unit, sram_info); 4847 /* Determine RAM count and indexes for all RAMs */ 4848 #if defined(BCM_HELIX5_SUPPORT) 4849 if (SOC_IS_HELIX5(unit)) { 4850 rv = soc_helix5_mem_sram_info_get(unit, mem, index, sram_info); 4851 } else 4852 #endif 4853 #if defined(BCM_TRIDENT3_SUPPORT) 4854 if (SOC_IS_TRIDENT3X(unit)) { 4855 rv = soc_trident3_mem_sram_info_get(unit, mem, index, sram_info); 4856 } else 4857 #endif 4858 #if defined(BCM_TOMAHAWK_SUPPORT) 4859 if (SOC_IS_TOMAHAWKX(unit)) { 4860 rv = soc_tomahawk_mem_sram_info_get(unit, mem, index, sram_info); 4861 } else 4862 #endif /* BCM_TOMAHAWK_SUPPORT */ 4863 #if defined(BCM_MONTEREY_SUPPORT) 4864 if (SOC_IS_MONTEREY(unit)) { 4865 rv = _soc_monterey_mem_sram_info_get(unit, mem, index, sram_info); 4866 } else 4867 #endif /* BCM_MONTEREY_SUPPORT */ 4868 #if defined(BCM_APACHE_SUPPORT) 4869 if (SOC_IS_APACHE(unit)) { 4870 rv = _soc_apache_mem_sram_info_get(unit, mem, index, sram_info); 4871 } else 4872 #endif /* BCM_APACHE_SUPPORT */ 4873 #if defined(BCM_TRIDENT2_SUPPORT) 4874 if (SOC_IS_TD2_TT2(unit)) { /* Tomahawk check is made earlier */ 4875 rv = _soc_trident2_mem_sram_info_get(unit, mem, index, sram_info); 4876 } else 4877 #endif /* BCM_TRIDENT2_SUPPORT */ 4878 { 4879 rv = SOC_E_UNAVAIL; 4880 } 4881 if (rv != SOC_E_NONE) { 4882 goto free_exit; 4883 } 4884 4885 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \ 4886 defined(BCM_TRIDENT3_SUPPORT) 4887 /* coverity[Structurally dead code]*/ 4888 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || SOC_IS_TD2P_TT2P(unit)) { 4889 if ((mem == L2_ENTRY_LPm) || (mem == L2_ENTRY_ISS_LPm)) { 4890 _L2_LOCK(unit); 4891 _l2_lock = 1; 4892 } 4893 } 4894 #endif /* BCM_TOMAHAWK_SUPPORT */ 4895 4896 /* Update all RAM indexes with data from cache or null entry */ 4897 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \ 4898 defined(BCM_TRIDENT3_SUPPORT) 4899 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) { 4900 switch (mem) { 4901 case L2_ENTRY_ONLY_ECCm: 4902 mem_to_restore = L2_ENTRY_ONLY_ECCm; 4903 mem_to_lock = L2Xm; 4904 mem_for_cache_read = L2Xm; 4905 mem_to_report = L2Xm; 4906 break; 4907 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 4908 case L2_ENTRY_ECCm: 4909 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) { 4910 mem_to_restore = L2_ENTRY_ECCm; 4911 mem_to_lock = L2Xm; 4912 mem_for_cache_read = L2Xm; 4913 mem_to_report = L2Xm; 4914 } 4915 break; 4916 #endif 4917 case FPEM_ECCm: 4918 case FPEM_LPm: 4919 case L3_ENTRY_ECCm: 4920 case L3_ENTRY_ONLY_ECCm: 4921 case MPLS_ENTRY_ECCm: 4922 case VLAN_XLATE_1_ECCm: 4923 case VLAN_XLATE_2_ECCm: 4924 case EGR_VLAN_XLATE_1_ECCm: 4925 case EGR_VLAN_XLATE_2_ECCm: 4926 case EXACT_MATCH_ECCm: 4927 mem_to_lock = INVALIDm; 4928 use_overlay_mem_correction = 1; 4929 break; 4930 #ifdef BCM_TRIDENT3_SUPPORT 4931 case ING_DNAT_ADDRESS_TYPE_ECCm: 4932 case ING_VP_VLAN_MEMBERSHIP_ECCm: 4933 case EGR_VP_VLAN_MEMBERSHIP_ECCm: 4934 case SUBPORT_ID_TO_SGPP_MAP_ECCm: 4935 if (NUM_PIPE(unit) == 1) { 4936 mem_to_lock = INVALIDm; 4937 use_overlay_mem_correction = 1; 4938 } 4939 break; 4940 #endif 4941 #ifdef BCM_TOMAHAWK3_SUPPORT 4942 case L3_DEFIP_ALPM_LEVEL3_ECCm: 4943 if (SOC_IS_TOMAHAWK3(unit)) { 4944 mem_to_lock = INVALIDm; 4945 use_recovery_hw_cache = 1; 4946 is_l3_defip = TRUE; 4947 } 4948 break; 4949 #endif 4950 case L2_ENTRY_LPm: 4951 case L2_ENTRY_ISS_LPm: 4952 case L3_ENTRY_LPm: 4953 case L3_ENTRY_ISS_LPm: 4954 case VLAN_XLATE_LPm: 4955 case EGR_VLAN_XLATE_LPm: 4956 mem_to_lock = INVALIDm; 4957 use_recovery_hw_cache = 1; 4958 break; 4959 case EXACT_MATCH_LPm: 4960 case VLAN_XLATE_1_LPm: 4961 case VLAN_XLATE_2_LPm: 4962 case EGR_VLAN_XLATE_1_LPm: 4963 case EGR_VLAN_XLATE_2_LPm: 4964 case MPLS_ENTRY_LPm: 4965 if (SOC_IS_TRIDENT3X(unit)) { 4966 mem_to_lock = INVALIDm; 4967 use_recovery_hw_cache = 1; 4968 } 4969 break; 4970 case L3_DEFIP_ALPM_ECCm: 4971 mem_to_lock = INVALIDm; 4972 use_recovery_hw_cache = 1; 4973 is_l3_defip = TRUE; 4974 #ifdef BCM_TRIDENT3_SUPPORT 4975 /* There is no HASH_CONTROL memory to set 4976 * DISABLE_SBUS_MEMWR_ECC_CHECK field 4977 * So we need to clear the error entry first to be able to 4978 * CACHE_RESTORE entries in functional view 4979 */ 4980 if (SOC_IS_TRIDENT3X(unit) && NUM_PIPE(unit) == 1) { 4981 null_entry = soc_mem_entry_null(unit, mem); 4982 (void)soc_mem_write(unit, mem, copyno, index, null_entry); 4983 } 4984 #endif 4985 break; 4986 case VLAN_XLATE_ECCm: 4987 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4988 case VLAN_MACm: 4989 #endif 4990 mem_to_restore = VLAN_XLATE_ECCm; 4991 mem_to_lock = VLAN_XLATEm; 4992 mem_for_cache_read = VLAN_XLATEm; 4993 mem_to_report = VLAN_XLATEm; 4994 break; 4995 case EGR_VLAN_XLATE_ECCm: 4996 mem_to_restore = EGR_VLAN_XLATE_ECCm; 4997 mem_to_lock = EGR_VLAN_XLATEm; 4998 mem_for_cache_read = EGR_VLAN_XLATEm; 4999 mem_to_report = EGR_VLAN_XLATEm; 5000 break; 5001 default: 5002 break; 5003 } 5004 sal_memset(entry, 0, 4*soc_mem_entry_words(unit, mem_to_restore)); 5005 5006 if (NUM_PIPE(unit) == 1) { 5007 /* use_recovery_hw_cache is to be enabled only for multi-pipe devices */ 5008 use_recovery_hw_cache = 0; 5009 } 5010 } 5011 #endif /* BCM_TOMAHAWK_SUPPORT */ 5012 5013 #if defined(BCM_TRIDENT2_SUPPORT) 5014 if (SOC_IS_TD2_TT2(unit)) { 5015 if (mem == L3_DEFIP_ALPM_IPV4m || mem == L3_DEFIP_ALPM_IPV4_1m || 5016 mem == L3_DEFIP_ALPM_IPV6_64m || mem == L3_DEFIP_ALPM_IPV6_64_1m || 5017 mem == L3_DEFIP_ALPM_IPV6_128m || mem == L3_DEFIP_PAIR_128m || 5018 mem == L3_DEFIPm || mem == L3_DEFIP_AUX_TABLEm) { 5019 /* Take ALPM_LOCK during correction for ALPM related tables */ 5020 mem_to_lock = INVALIDm; 5021 is_l3_defip = TRUE; 5022 } 5023 } 5024 #endif 5025 5026 if (mem_to_lock != INVALIDm) { 5027 MEM_LOCK(unit, mem_to_lock); 5028 } else if (is_l3_defip) { 5029 _ALPM_LOCK(unit); 5030 } 5031 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5032 /* 5033 * On Trident2+ A0, disable learning and aging before Reading/Writing 5034 * L2_ENTRY_ONLY_ECCm. Will be re-enabled after SER correction. 5035 */ 5036 if ((mem == L2_ENTRY_ONLY_ECCm) && 5037 (soc_feature(unit, soc_feature_td2p_a0_sw_war) || 5038 soc_feature(unit, soc_feature_l2_activity_freeze_ser))) { 5039 rv = soc_l2x_freeze(unit); 5040 if (SOC_FAILURE(rv)) { 5041 LOG_WARN(BSL_LS_SOC_SER, 5042 (BSL_META_U(unit, 5043 "L2 freeze failed in L2_ENTRY_ONLY_ECCm correction\n"))); 5044 if (mem_to_lock != INVALIDm) { 5045 MEM_UNLOCK(unit, mem_to_lock); 5046 } 5047 goto free_exit; 5048 } 5049 } 5050 #endif 5051 cache = SOC_MEM_STATE(unit, mem_for_cache_read).cache[copyno]; 5052 vmap = SOC_MEM_STATE(unit, mem_for_cache_read).vmap[copyno]; 5053 entry_dw = soc_mem_entry_words(unit, mem_for_cache_read); 5054 if ((mode == _SOC_SER_SRAM_CORRECTION_MODE_0) && 5055 (sram_info->disable_reg != INVALIDr)) { 5056 rv = soc_reg32_get(unit, sram_info->disable_reg, REG_PORT_ANY, 0, &rval); 5057 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5058 _SOC_IF_ERR_L2X_THAW(rv, mem); 5059 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5060 _SOC_SER_SRAM_CHK_RETURN("reg get"); 5061 soc_reg_field_set(unit, sram_info->disable_reg, &rval, 5062 sram_info->disable_field, 1); 5063 raddr = soc_reg_addr_get(unit, sram_info->disable_reg, REG_PORT_ANY, 0, 5064 SOC_REG_ADDR_OPTION_WRITE, &block, &at); 5065 at = 3; 5066 #if defined(BCM_TOMAHAWK_SUPPORT) 5067 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 5068 at = _SOC_TH_ACC_TYPE_DUPLICATE; 5069 if ((mem == FPEM_ECCm) || (mem == FPEM_LPm)) { 5070 fpem_mem_mode = _soc_ser_mem_mode_get(unit, EXACT_MATCH_2m); 5071 /* Note: Assume both EM2, EM4 are always in same mode */ 5072 if (fpem_mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) { 5073 at = _SOC_TH_ACC_TYPE_FOR_PIPE(pipe); 5074 } 5075 } 5076 } 5077 #endif /* BCM_TOMAHAWK_SUPPORT */ 5078 rv = _soc_reg32_set(unit, block, at, raddr, rval); 5079 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5080 _SOC_IF_ERR_L2X_THAW(rv, mem); 5081 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5082 _SOC_SER_SRAM_CHK_RETURN("reg set"); 5083 } else if (sram_info->disable_mem != INVALIDm) { 5084 sal_memset(hash_control_entry, 0, sizeof(hash_control_entry)); 5085 rv = soc_mem_read(unit, sram_info->disable_mem, MEM_BLOCK_ANY, 5086 sram_info->disable_mem_index, hash_control_entry); 5087 5088 _SOC_SER_SRAM_CHK_RETURN("mem read"); 5089 soc_mem_field32_set(unit, sram_info->disable_mem , hash_control_entry, 5090 sram_info->disable_mem_field, 1); 5091 rv = soc_mem_write(unit, sram_info->disable_mem, MEM_BLOCK_ALL, 5092 sram_info->disable_mem_index, hash_control_entry); 5093 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5094 } 5095 5096 for (i = 0; i < sram_info->ram_count; i++) { 5097 /* coverity[uninit_use] */ 5098 start_index = sram_info->mem_indexes[i][0]; 5099 if ((mem == L3_ENTRY_IPV4_UNICASTm) || use_overlay_mem_correction) { 5100 /* To avoid the unnecessary event of correction for Trident2 */ 5101 use_overlay_mem_correction = 1; 5102 if (mem == FPEM_LPm) { 5103 if (sram_info->view[i] == FPEM_LPm) { 5104 null_entry = soc_mem_entry_null(unit, FPEM_LPm); 5105 rv = soc_mem_write(unit, FPEM_LPm, copyno, start_index, 5106 null_entry); 5107 /* Note: we are clearing unused index - so ok to 5108 * clear in all pipes - no need to restrict access 5109 * to per pipe when, 5110 * (fpem_mem_mode == _SOC_SER_MEM_MODE_PIPE_UNIQUE) 5111 */ 5112 5113 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5114 LOG_WARN(BSL_LS_SOC_SER, 5115 (BSL_META_U(unit, 5116 "CLEAR_RESTORE: %s[%d] start_index: %d\n"), 5117 SOC_MEM_NAME(unit, FPEM_LPm), FPEM_LPm, 5118 start_index)); 5119 } else { 5120 rv = _soc_ser_overlay_mem_correction(unit, 0, pipe, sblk, 5121 addr, 5122 sram_info->view[i], 5123 copyno, start_index, 5124 si); 5125 } 5126 } else { 5127 rv = _soc_ser_overlay_mem_correction(unit, 0, pipe, sblk, addr, 5128 mem, copyno, start_index, 5129 si); 5130 } 5131 if (!(rv == SOC_E_NONE || rv == SOC_E_UNAVAIL)) { 5132 5133 LOG_ERROR(BSL_LS_SOC_SER, 5134 (BSL_META_U(unit, 5135 "SER SRAM correction encoutered error(%d) " 5136 "in overlay mem correction\n"), 5137 rv)); 5138 if (mem_to_lock != INVALIDm) { 5139 MEM_UNLOCK(unit, mem_to_lock); 5140 } 5141 goto free_exit; 5142 } 5143 if (si != NULL) { 5144 if (SocSerCorrectTypeCacheRestore == si->ctype || 5145 socSerCorrectTypeHwCacheRestore == si->ctype) { 5146 ctype = si->ctype; 5147 } 5148 } 5149 } else if (((mem == L3_DEFIP_ALPM_IPV4m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4 == 1)) || 5150 ((mem == L3_DEFIP_ALPM_IPV4_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 == 1)) || 5151 ((mem == L3_DEFIP_ALPM_IPV6_64m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6 == 1)) || 5152 ((mem == L3_DEFIP_ALPM_IPV6_64_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 == 1)) || 5153 ((mem == L3_DEFIP_ALPM_IPV6_128m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 == 1)) || 5154 ((mem == L3_DEFIP_PAIR_128m) && (alpm_no_cache_flag[unit].flag_defip_128 == 1)) || 5155 ((mem == L3_DEFIPm) && (alpm_no_cache_flag[unit].flag_defip == 1)) || 5156 ((mem == L3_DEFIP_AUX_TABLEm) && (alpm_no_cache_flag[unit].flag_defip_aux == 1)) || 5157 use_recovery_hw_cache) { 5158 /* To avoid the unnecessary event of correction for Trident2 */ 5159 use_recovery_hw_cache = 1; 5160 for (j = 0; j < sram_info->index_count[i]; j++) { 5161 rv = _soc_ser_recovery_hw_cache(unit, pipe, sram_info->view[i], 5162 copyno, sram_info->mem_indexes[i][j], 5163 si, FALSE); 5164 if (!(rv == SOC_E_NONE || rv == SOC_E_UNAVAIL)) { 5165 5166 LOG_ERROR(BSL_LS_SOC_SER, 5167 (BSL_META_U(unit, 5168 "SER SRAM correction encoutered error(%d) " 5169 "in recovery from hw cache\n"), 5170 rv)); 5171 if (mem_to_lock != INVALIDm) { 5172 MEM_UNLOCK(unit, mem_to_lock); 5173 } 5174 _ALPM_UNLOCK(unit) 5175 _L2_UNLOCK(unit, _l2_lock) 5176 5177 goto free_exit; 5178 } 5179 } 5180 } else if ((sram_info->view[i] == L3_DEFIP_ALPM_IPV4m || 5181 sram_info->view[i] == L3_DEFIP_ALPM_IPV4_1m || 5182 sram_info->view[i] == L3_DEFIP_ALPM_IPV6_64m || 5183 sram_info->view[i] == L3_DEFIP_ALPM_IPV6_64_1m || 5184 sram_info->view[i] == L3_DEFIP_ALPM_IPV6_128m || 5185 sram_info->view[i] == L3_DEFIP_ALPM_RAWm)) { 5186 cache = SOC_MEM_STATE(unit, sram_info->view[i]).cache[copyno]; 5187 vmap = SOC_MEM_STATE(unit, sram_info->view[i]).vmap[copyno]; 5188 entry_dw = soc_mem_entry_words(unit, sram_info->view[i]); 5189 for (j = 0; j < sram_info->index_count[i]; j++) { 5190 if (cache != NULL && CACHE_VMAP_TST(vmap, sram_info->mem_indexes[i][j])) { 5191 sal_memcpy(entry, cache + sram_info->mem_indexes[i][j] * entry_dw, entry_dw * 4); 5192 rv = soc_mem_write(unit, sram_info->view[i], copyno, sram_info->mem_indexes[i][j], entry); 5193 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5194 LOG_WARN(BSL_LS_SOC_SER, 5195 (BSL_META_U(unit, 5196 "CACHE_RESTORE: %s[%d] start_index: %d\n"), 5197 SOC_MEM_NAME(unit, sram_info->view[i]), 5198 sram_info->view[i], sram_info->mem_indexes[i][j])); 5199 stat->ser_err_restor++; 5200 if (NULL != si) { 5201 if ((si->log_id != 0) && 5202 (si->flags & SOC_SER_LOG_WRITE_CACHE)) { 5203 if (si->index == sram_info->mem_indexes[i][j]) { 5204 (void)soc_ser_log_add_tlv(unit, si->log_id, 5205 SOC_SER_LOG_TLV_CACHE, 5206 entry_dw*4, entry); 5207 } else { 5208 LOG_VERBOSE(BSL_LS_SOC_SER, 5209 (BSL_META_U(unit, 5210 "skipped updating tlv_cache index: %d\n"), 5211 sram_info->mem_indexes[i][j])); 5212 } 5213 } 5214 } 5215 ctype = SocSerCorrectTypeCacheRestore; 5216 } else { /* Fall back to clear */ 5217 if (NUM_PIPE(unit) == 1) { 5218 null_entry = soc_mem_entry_null(unit, sram_info->view[i]); 5219 rv = soc_mem_write(unit, sram_info->view[i], copyno, sram_info->mem_indexes[i][j], null_entry); 5220 } else { 5221 rv = _soc_ser_recovery_hw_cache(unit, pipe, sram_info->view[i], 5222 copyno, sram_info->mem_indexes[i][j], 5223 si, FALSE); 5224 } 5225 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5226 LOG_WARN(BSL_LS_SOC_SER, 5227 (BSL_META_U(unit, 5228 "CLEAR_RESTORE: %s[%d] start_index: %d\n"), 5229 SOC_MEM_NAME(unit, sram_info->view[i]), 5230 sram_info->view[i], sram_info->mem_indexes[i][j])); 5231 stat->ser_err_clear++; 5232 } 5233 } 5234 } else { /* Correct from Cache */ 5235 if (cache != NULL && CACHE_VMAP_TST(vmap, start_index)) { 5236 sal_memcpy(entry, cache + start_index * entry_dw, entry_dw * 4); 5237 rv = soc_mem_write(unit, mem_to_restore, copyno, start_index, entry); 5238 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5239 _SOC_IF_ERR_L2X_THAW(rv, mem); 5240 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5241 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5242 LOG_WARN(BSL_LS_SOC_SER, 5243 (BSL_META_U(unit, 5244 "CACHE_RESTORE: %s[%d] start_index: %d\n"), 5245 SOC_MEM_NAME(unit, mem_to_restore), 5246 mem_to_restore, start_index)); 5247 stat->ser_err_restor++; 5248 if (NULL != si) { 5249 if ((si->log_id != 0) && 5250 (si->flags & SOC_SER_LOG_WRITE_CACHE)) { 5251 if (si->index == start_index) { 5252 (void)soc_ser_log_add_tlv(unit, si->log_id, 5253 SOC_SER_LOG_TLV_CACHE, 5254 entry_dw*4, entry); 5255 } else { 5256 LOG_VERBOSE(BSL_LS_SOC_SER, 5257 (BSL_META_U(unit, 5258 "skipped updating tlv_cache index: %d\n"), 5259 start_index)); 5260 } 5261 } 5262 } 5263 ctype = SocSerCorrectTypeCacheRestore; 5264 } else { /* Fall back to clear (write null-entry) */ 5265 5266 null_entry = soc_mem_entry_null(unit, mem_to_restore); 5267 rv = soc_mem_write(unit, mem_to_restore, copyno, start_index, null_entry); 5268 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5269 _SOC_IF_ERR_L2X_THAW(rv, mem); 5270 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5271 5272 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5273 LOG_WARN(BSL_LS_SOC_SER, 5274 (BSL_META_U(unit, 5275 "CLEAR_RESTORE: %s[%d] start_index: %d\n"), 5276 SOC_MEM_NAME(unit, mem_to_restore), 5277 mem_to_restore, start_index)); 5278 stat->ser_err_clear++; 5279 } 5280 } 5281 } 5282 5283 if ((mode == _SOC_SER_SRAM_CORRECTION_MODE_0) && 5284 (sram_info->disable_reg != INVALIDr)) { 5285 soc_reg_field_set(unit, sram_info->disable_reg, &rval, 5286 sram_info->disable_field, 0); 5287 rv = _soc_reg32_set(unit, block, at, raddr, rval); 5288 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5289 _SOC_IF_ERR_L2X_THAW(rv, mem); 5290 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 5291 _SOC_SER_SRAM_CHK_RETURN("reg set"); 5292 } else if (sram_info->disable_mem != INVALIDm) { 5293 soc_mem_field32_set(unit, sram_info->disable_mem , hash_control_entry, 5294 sram_info->disable_mem_field, 0); 5295 rv = soc_mem_write(unit, sram_info->disable_mem, MEM_BLOCK_ALL, 5296 sram_info->disable_mem_index, hash_control_entry); 5297 _SOC_SER_SRAM_CHK_RETURN("mem write"); 5298 } 5299 5300 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5301 /*TD2+ SW WAR. Enabled learning and aging */ 5302 if ((mem == L2_ENTRY_ONLY_ECCm) && 5303 (soc_feature(unit, soc_feature_td2p_a0_sw_war) || 5304 soc_feature(unit, soc_feature_l2_activity_freeze_ser))) { 5305 rv = soc_l2x_thaw(unit); 5306 if (SOC_FAILURE(rv)) { 5307 LOG_WARN(BSL_LS_SOC_SER, 5308 (BSL_META_U(unit, 5309 "L2 thaw failed in L2_ENTRY_ONLY_ECCm correction\n"))); 5310 if (mem_to_lock != INVALIDm) { 5311 MEM_UNLOCK(unit, mem_to_lock); 5312 } 5313 goto free_exit; 5314 } 5315 } 5316 #endif 5317 5318 if (mem_to_lock != INVALIDm) { 5319 MEM_UNLOCK(unit, mem_to_lock); 5320 } 5321 _ALPM_UNLOCK(unit) 5322 _L2_UNLOCK(unit, _l2_lock) 5323 5324 /* resume alpm operations that could have been terminated because of ser 5325 * problem 5326 */ 5327 switch (mem) { 5328 case L3_DEFIP_ALPM_IPV4m: 5329 case L3_DEFIP_ALPM_IPV4_1m: 5330 case L3_DEFIP_ALPM_IPV6_64m: 5331 case L3_DEFIP_ALPM_IPV6_64_1m: 5332 case L3_DEFIP_ALPM_IPV6_128m: 5333 case L3_DEFIP_ALPM_ECCm: 5334 #ifdef BCM_TOMAHAWK3_SUPPORT 5335 case L3_DEFIP_ALPM_LEVEL3_ECCm: 5336 #endif 5337 if (SOC_CONTROL(unit)->alpm_lookup_retry && 5338 SHR_BITGET(&(SOC_CONTROL(unit)->alpm_mem_ops), _SOC_ALPM_LOOKUP)) { 5339 sal_sem_give(SOC_CONTROL(unit)->alpm_lookup_retry); 5340 } 5341 if (SOC_CONTROL(unit)->alpm_insert_retry && 5342 SHR_BITGET(&(SOC_CONTROL(unit)->alpm_mem_ops), _SOC_ALPM_INSERT)) { 5343 sal_sem_give(SOC_CONTROL(unit)->alpm_insert_retry); 5344 } 5345 if (SOC_CONTROL(unit)->alpm_delete_retry && 5346 SHR_BITGET(&(SOC_CONTROL(unit)->alpm_mem_ops), _SOC_ALPM_DELETE)) { 5347 sal_sem_give(SOC_CONTROL(unit)->alpm_delete_retry); 5348 } 5349 break; 5350 default: break; 5351 } 5352 if (NULL != si) { 5353 if (use_recovery_hw_cache) { 5354 ctype = socSerCorrectTypeHwCacheRestore; 5355 } 5356 si->ctype = ctype; 5357 soc_ser_stat_update(unit, 0, si->blk_type, 5358 si->parity_type, si->double_bit, 5359 ctype, stat); 5360 } 5361 if (!(use_overlay_mem_correction || use_recovery_hw_cache)) { 5362 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 5363 si, mem_to_report, index); 5364 stat->ser_err_corr++; 5365 } 5366 rv = SOC_E_NONE; 5367 free_exit: 5368 if (sram_info != NULL) { 5369 sal_free(sram_info); 5370 } 5371 if (entry != NULL) { 5372 sal_free(entry); 5373 } 5374 5375 return rv; 5376 } 5377 5378 int 5379 soc_ser_sram_correction(int unit, int pipe, int sblk, int addr, soc_mem_t mem, 5380 int copyno, int index, _soc_ser_correct_info_t *si) 5381 { 5382 int rv; 5383 LOG_VERBOSE(BSL_LS_SOC_SER, 5384 (BSL_META_U(unit, 5385 "th_dbg: entered soc_ser_sram_correction " 5386 "routine\n"))); 5387 5388 5389 switch (mem) { 5390 case L3_ENTRY_ONLYm: 5391 case L3_ENTRY_IPV4_UNICASTm: 5392 case L3_ENTRY_IPV4_MULTICASTm: 5393 case L3_ENTRY_IPV6_UNICASTm: 5394 case L3_ENTRY_IPV6_MULTICASTm: 5395 rv = _soc_ser_sram_correction(unit, pipe, sblk, addr, 5396 L3_ENTRY_IPV4_UNICASTm, copyno, index, 5397 _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5398 if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) { 5399 return rv; 5400 } 5401 break; 5402 case L2Xm: 5403 case L3_DEFIP_ALPM_IPV4m: 5404 case L3_DEFIP_ALPM_IPV4_1m: 5405 case L3_DEFIP_ALPM_IPV6_64m: 5406 case L3_DEFIP_ALPM_IPV6_64_1m: 5407 case L3_DEFIP_ALPM_IPV6_128m: 5408 case L3_DEFIP_ALPM_RAWm: 5409 case VLAN_XLATEm: 5410 case EGR_VLAN_XLATEm: 5411 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5412 index, _SOC_SER_SRAM_CORRECTION_MODE_0, 5413 si); 5414 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \ 5415 defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 5416 case L2_ENTRY_ONLY_ECCm: 5417 case L2_ENTRY_LPm: 5418 case L2_ENTRY_ISS_LPm: 5419 case L3_ENTRY_ONLY_ECCm: 5420 case L3_ENTRY_LPm: 5421 case L3_ENTRY_ISS_LPm: 5422 case FPEM_LPm: 5423 case L3_DEFIP_ALPM_ECCm: 5424 case VLAN_XLATE_ECCm: 5425 case VLAN_MACm: 5426 case VLAN_XLATE_LPm: 5427 case EGR_VLAN_XLATE_ECCm: 5428 case EGR_VLAN_XLATE_LPm: 5429 case EXACT_MATCH_LPm: 5430 case VLAN_XLATE_1_LPm: 5431 case VLAN_XLATE_2_LPm: 5432 case EGR_VLAN_XLATE_1_LPm: 5433 case EGR_VLAN_XLATE_2_LPm: 5434 case MPLS_ENTRY_LPm: 5435 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || 5436 SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) { 5437 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5438 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5439 } 5440 else { 5441 break; 5442 } 5443 case FPEM_ECCm: 5444 #if defined(INCLUDE_FLOWTRACKER) 5445 if (SOC_CONTROL(unit)->uc_flowtracker_enable) { 5446 return _soc_ft_em_ser_correction(unit, pipe, mem, index); 5447 } 5448 #endif /* INCLUDE_FLOWTRACKER */ 5449 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || 5450 SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) { 5451 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5452 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5453 } 5454 else { 5455 break; 5456 } 5457 #endif /* BCM_TOMAHAWK_SUPPORT */ 5458 #if defined(BCM_TRIDENT3_SUPPORT) 5459 case MPLS_ENTRY_ECCm: 5460 case VLAN_XLATE_1_ECCm: 5461 case VLAN_XLATE_2_ECCm: 5462 case EGR_VLAN_XLATE_1_ECCm: 5463 case EGR_VLAN_XLATE_2_ECCm: 5464 case ING_DNAT_ADDRESS_TYPE_ECCm: 5465 case ING_VP_VLAN_MEMBERSHIP_ECCm: 5466 case EGR_VP_VLAN_MEMBERSHIP_ECCm: 5467 case SUBPORT_ID_TO_SGPP_MAP_ECCm: 5468 if (SOC_IS_TRIDENT3X(unit)) { 5469 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5470 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5471 } else { 5472 break; 5473 } 5474 case VLAN_XLATE_1_SINGLEm: 5475 case VLAN_XLATE_1_DOUBLEm: 5476 case EGR_VLAN_XLATE_1_SINGLEm: 5477 case EGR_VLAN_XLATE_1_DOUBLEm: 5478 case VLAN_XLATE_2_SINGLEm: 5479 case VLAN_XLATE_2_DOUBLEm: 5480 case EGR_VLAN_XLATE_2_SINGLEm: 5481 case EGR_VLAN_XLATE_2_DOUBLEm: 5482 if (SOC_IS_TRIDENT3X(unit)) { 5483 soc_trident3_vlan_xlate_mem_remap(&mem, &index); 5484 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5485 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5486 } else { 5487 break; 5488 } 5489 #endif 5490 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 5491 case L2_ENTRY_ECCm: 5492 case L3_ENTRY_ECCm: 5493 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) { 5494 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5495 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5496 } else { 5497 break; 5498 } 5499 case EXACT_MATCH_ECCm: 5500 #if defined(INCLUDE_FLOWTRACKER) 5501 if (SOC_CONTROL(unit)->uc_flowtracker_enable) { 5502 return _soc_ft_em_ser_correction(unit, pipe, mem, index); 5503 } 5504 #endif /* INCLUDE_FLOWTRACKER */ 5505 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) { 5506 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5507 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5508 } else { 5509 break; 5510 } 5511 #endif 5512 #ifdef BCM_TOMAHAWK3_SUPPORT 5513 case L3_DEFIP_ALPM_LEVEL3_ECCm: 5514 case L3_DEFIP_ALPM_LEVEL3m: 5515 if (SOC_IS_TOMAHAWK3(unit)) { 5516 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5517 index, _SOC_SER_SRAM_CORRECTION_MODE_0, si); 5518 } 5519 break; 5520 #endif 5521 case ING_L3_NEXT_HOPm: 5522 if (SOC_IS_TRIDENT3X(unit)) { 5523 break; 5524 } else { 5525 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5526 index, _SOC_SER_SRAM_CORRECTION_MODE_1, 5527 si); 5528 } 5529 case L3_IPMCm: 5530 case L2MCm: 5531 if (!SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TRIDENT3X(unit)) { 5532 return _soc_ser_sram_correction(unit, pipe, sblk, addr, mem, copyno, 5533 index, 5534 _SOC_SER_SRAM_CORRECTION_MODE_1, 5535 si); 5536 } 5537 break; 5538 default: break; 5539 } 5540 return SOC_E_UNAVAIL; 5541 } 5542 5543 int 5544 soc_mem_alpm_aux_table_correction(int unit, int pipe, int index, soc_mem_t mem) 5545 { 5546 int rv = SOC_E_UNAVAIL; 5547 #if defined(BCM_TRIDENT2_SUPPORT) 5548 int bidx, sblk = 0, blk; 5549 _soc_ser_correct_info_t spci; 5550 #endif 5551 5552 #if defined(BCM_TRIDENT2_SUPPORT) 5553 blk = SOC_BLK_IPIPE; 5554 SOC_BLOCK_ITER(unit, bidx, blk) { 5555 sblk = SOC_BLOCK2SCH(unit, bidx); 5556 break; 5557 } 5558 5559 if (SOC_IS_TD2_TT2(unit)) { 5560 sal_memset(&spci, 0, sizeof(spci)); 5561 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 5562 spci.reg = INVALIDr; 5563 spci.mem = mem; 5564 spci.pipe_num = pipe; 5565 spci.blk_type = blk; 5566 spci.sblk = sblk; 5567 spci.index = index; 5568 spci.parity_type = SOC_PARITY_TYPE_PARITY; 5569 5570 LOG_WARN(BSL_LS_SOC_SER, 5571 (BSL_META_U(unit, 5572 "Inline correction: mem:%s pipe:%d index:%d\n"), 5573 SOC_MEM_NAME(unit, mem), pipe, index)); 5574 5575 return soc_ser_correction(unit, &spci); 5576 } else 5577 #endif 5578 { 5579 return rv; 5580 } 5581 } 5582 5583 /* Writing back to logical table will trigger update to LP mem */ 5584 int 5585 _soc_ser_lp_mem_correction(int unit, soc_mem_t mem, int index, int copyno) 5586 { 5587 #ifdef BCM_XGS_SWITCH_SUPPORT 5588 int rv = SOC_E_NONE, i, entry_dw; 5589 uint32 entry[SOC_MAX_MEM_WORDS]; 5590 soc_mem_t hash_mem[_SOC_SER_MEM_OVERLAY_SET] = 5591 {INVALIDm, INVALIDm, INVALIDm, INVALIDm, INVALIDm, INVALIDm}; 5592 int hash_index[_SOC_SER_MEM_OVERLAY_SET] = {0}; 5593 uint32 *cache = NULL; 5594 uint8 *vmap = NULL; 5595 5596 LOG_VERBOSE(BSL_LS_SOC_SER, 5597 (BSL_META_U(unit, 5598 "th_dbg: entered soc_ser_lp_mem_correction " 5599 "routine\n"))); 5600 5601 #ifdef BCM_HELIX5_SUPPORT 5602 if (SOC_IS_HELIX5(unit)) { 5603 /* Ignore error since index reported can be for a view which is never used 5604 * This happens when LP table is directly written to instead of inserting 5605 * proper entries in functional view 5606 * 5607 * Therefore, we clear erroneous LP entry first and then try to restore it 5608 * from functional view if possible 5609 */ 5610 (void)soc_hx5_ser_lp_mem_info_get(unit, mem, index, 5611 hash_mem, hash_index); 5612 } else 5613 #endif 5614 #ifdef BCM_MAVERICK2_SUPPORT 5615 if (SOC_IS_MAVERICK2(unit)) { 5616 (void)soc_mv2_ser_lp_mem_info_get(unit, mem, index, 5617 hash_mem, hash_index); 5618 } else 5619 #endif 5620 { 5621 switch (mem) { 5622 case L2_ENTRY_ISS_LPm: 5623 hash_mem[0] = L2Xm; 5624 hash_index[0] = (soc_mem_index_count(unit, L2_ENTRY_LPm) + index) * 4; 5625 break; 5626 case L2_ENTRY_LPm: 5627 hash_mem[0] = L2Xm; 5628 hash_index[0] = index * 4; 5629 break; 5630 case L3_ENTRY_ISS_LPm: 5631 /* Restore all views for L3 LP mems */ 5632 hash_mem[0] = L3_ENTRY_IPV4_UNICASTm; 5633 hash_index[0] = (soc_mem_index_count(unit, L3_ENTRY_LPm) + index) * 4; 5634 5635 hash_mem[1] = L3_ENTRY_IPV4_MULTICASTm; 5636 hash_index[1] = hash_index[0] / 2; 5637 5638 hash_mem[2] = L3_ENTRY_IPV6_UNICASTm; 5639 hash_index[2] = hash_index[0] / 2; 5640 5641 hash_mem[3] = L3_ENTRY_IPV6_MULTICASTm; 5642 hash_index[3] = soc_mem_index_count(unit, L3_ENTRY_LPm) + index; 5643 break; 5644 case L3_ENTRY_LPm: 5645 hash_mem[0] = L3_ENTRY_IPV4_UNICASTm; 5646 hash_index[0] = index * 4; 5647 5648 hash_mem[1] = L3_ENTRY_IPV4_MULTICASTm; 5649 hash_index[1] = hash_index[0] / 2; 5650 5651 hash_mem[2] = L3_ENTRY_IPV6_UNICASTm; 5652 hash_index[2] = hash_index[0] / 2; 5653 5654 hash_mem[3] = L3_ENTRY_IPV6_MULTICASTm; 5655 hash_index[3] = index; 5656 break; 5657 case VLAN_XLATE_LPm: 5658 hash_mem[0] = VLAN_XLATEm; 5659 hash_index[0] = index * 4; 5660 break; 5661 case EGR_VLAN_XLATE_LPm: 5662 hash_mem[0] = EGR_VLAN_XLATEm; 5663 hash_index[0] = index * 4; 5664 break; 5665 default: 5666 return SOC_E_PARAM; 5667 } 5668 } 5669 5670 /* Clear erroneous LP entry first, restoration done later */ 5671 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, copyno, 5672 index, soc_mem_entry_null(unit, mem))); 5673 5674 for (i = 0; hash_mem[i] != INVALIDm; i++) { 5675 if (hash_mem[i] != L2Xm) { 5676 MEM_LOCK(unit, hash_mem[i]); 5677 } else if (SOC_FAILURE(soc_l2x_freeze(unit))) { 5678 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 freeze failed\n"))); 5679 } 5680 5681 if (copyno != -1) { 5682 cache = SOC_MEM_STATE(unit, hash_mem[i]).cache[copyno]; 5683 vmap = SOC_MEM_STATE(unit, hash_mem[i]).vmap[copyno]; 5684 } 5685 5686 rv = SOC_E_FAIL; 5687 5688 /* If cache is valid, read from cache */ 5689 if (cache != NULL && vmap != NULL && CACHE_VMAP_TST(vmap, hash_index[i])) { 5690 entry_dw = soc_mem_entry_words(unit, hash_mem[i]); 5691 sal_memcpy(entry, cache + ((hash_index[i]) * entry_dw), entry_dw * 4); 5692 rv = soc_mem_write(unit, hash_mem[i], copyno, hash_index[i], entry); 5693 } 5694 5695 if (hash_mem[i] != L2Xm) { 5696 MEM_UNLOCK(unit, hash_mem[i]); 5697 } else if (SOC_FAILURE(soc_l2x_thaw(unit))) { 5698 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 thaw failed\n"))); 5699 } 5700 5701 if (SOC_SUCCESS(rv)) { 5702 return rv; 5703 } 5704 } 5705 5706 for (i = 0; hash_mem[i] != INVALIDm; i++) { 5707 if (hash_mem[i] != L2Xm) { 5708 MEM_LOCK(unit, hash_mem[i]); 5709 } else if (SOC_FAILURE(soc_l2x_freeze(unit))) { 5710 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 freeze failed\n"))); 5711 } 5712 5713 /* If cache is not valid, read from H/W */ 5714 rv = soc_mem_read(unit, hash_mem[i], copyno, hash_index[i], entry); 5715 if (SOC_FAILURE(rv)) { 5716 /* If read fails, write NULL entry */ 5717 rv = soc_mem_write(unit, hash_mem[i], copyno, 5718 hash_index[i], soc_mem_entry_null(unit, hash_mem[i])); 5719 } else { 5720 rv = soc_mem_write(unit, hash_mem[i], copyno, hash_index[i], entry); 5721 } 5722 5723 if (hash_mem[i] != L2Xm) { 5724 MEM_UNLOCK(unit, hash_mem[i]); 5725 } else if (SOC_FAILURE(soc_l2x_thaw(unit))) { 5726 LOG_WARN(BSL_LS_SOC_SER, (BSL_META_U(unit, "L2 thaw failed\n"))); 5727 } 5728 5729 if (SOC_FAILURE(rv)) { 5730 return rv; 5731 } 5732 5733 } 5734 return rv; 5735 #endif /* BCM_XGS_SWITCH_SUPPORT */ 5736 return SOC_E_NONE; 5737 } 5738 5739 STATIC void 5740 _soc_ser_ism_correction(int unit) 5741 { 5742 #define _SOC_SER_ISM_DMA_CHUNK_SIZE 1024 5743 uint32 *tbl_chnk; 5744 int rv, m, buf_size, chunksize; 5745 int chnk_idx, chnk_idx_max, mem_idx_max; 5746 static soc_mem_t ism_mems[] = { 5747 VLAN_XLATEm, 5748 L2_ENTRY_1m, 5749 L3_ENTRY_1m, 5750 MPLS_ENTRYm, 5751 EGR_VLAN_XLATEm 5752 }; 5753 LOG_VERBOSE(BSL_LS_SOC_SER, 5754 (BSL_META_U(unit, 5755 "th_dbg: entered soc_ser_ism_mem_correction " 5756 "routine\n"))); 5757 5758 chunksize = _SOC_SER_ISM_DMA_CHUNK_SIZE; 5759 buf_size = 4 * SOC_MAX_MEM_WORDS * chunksize; 5760 tbl_chnk = soc_cm_salloc(unit, buf_size, "ism ser correction"); 5761 if (NULL == tbl_chnk) { 5762 LOG_ERROR(BSL_LS_SOC_SER, 5763 (BSL_META_U(unit, 5764 "Memory allocation failure in ser ism " 5765 "correction !!\n"))); 5766 return; 5767 } 5768 5769 for (m=0; m<COUNTOF(ism_mems); m++) { 5770 if (!soc_mem_index_count(unit, ism_mems[m])) { 5771 continue; 5772 } 5773 mem_idx_max = soc_mem_index_max(unit, ism_mems[m]); 5774 MEM_LOCK(unit, ism_mems[m]); 5775 for (chnk_idx = soc_mem_index_min(unit, ism_mems[m]); 5776 chnk_idx <= mem_idx_max; chnk_idx += chunksize) { 5777 sal_memset((void *)tbl_chnk, 0, buf_size); 5778 chnk_idx_max = ((chnk_idx + chunksize) <= mem_idx_max) ? 5779 (chnk_idx + chunksize - 1) : mem_idx_max; 5780 rv = soc_mem_read_range(unit, ism_mems[m], MEM_BLOCK_ANY, chnk_idx, 5781 chnk_idx_max, tbl_chnk); 5782 if (SOC_FAILURE(rv)) { 5783 LOG_ERROR(BSL_LS_SOC_SER, 5784 (BSL_META_U(unit, 5785 "DMA failure in ser ism " 5786 "correction for %s mem !!\n"), 5787 SOC_MEM_NAME(unit, ism_mems[m]))); 5788 MEM_UNLOCK(unit, ism_mems[m]); 5789 soc_cm_sfree(unit, tbl_chnk); 5790 return; 5791 } 5792 } 5793 MEM_UNLOCK(unit, ism_mems[m]); 5794 } 5795 soc_cm_sfree(unit, tbl_chnk); 5796 } 5797 5798 STATIC int check_parity(uint32 *p32, int n32) 5799 { 5800 uint32 parity = 0; 5801 uint32 tmpI = 0; 5802 5803 for (n32--; n32>=0; n32--) { 5804 5805 tmpI=p32[n32]; 5806 tmpI=tmpI^(tmpI>>1); 5807 tmpI=tmpI^(tmpI>>2); 5808 tmpI=tmpI^(tmpI>>4); 5809 tmpI=tmpI^(tmpI>>8); 5810 tmpI=tmpI^(tmpI>>16); 5811 5812 parity = parity ^ (tmpI&1); 5813 } 5814 5815 return parity&1; 5816 } 5817 #ifdef _SER_TIME_STAMP 5818 extern sal_usecs_t ser_time_1; 5819 sal_usecs_t ser_time_5; 5820 #endif 5821 5822 int 5823 _soc_oam_ser_correction(int unit, soc_mem_t mem, int index) 5824 { 5825 LOG_VERBOSE(BSL_LS_SOC_SER, 5826 (BSL_META_U(unit, 5827 "th_dbg: entered _soc_oam_ser_correction " 5828 "routine\n"))); 5829 #ifdef BCM_TRIUMPH3_SUPPORT 5830 if (SOC_IS_TRIUMPH3(unit)) { 5831 return soc_tr3_oam_ser_process(unit, mem, index); 5832 } 5833 #endif /* BCM_TRIUMPH3_SUPPORT */ 5834 #ifdef BCM_HURRICANE2_SUPPORT 5835 if (SOC_IS_HURRICANE2(unit)) { 5836 return soc_hurricane2_oam_ser_process(unit, mem, index); 5837 } 5838 #endif /* BCM_HURRICANE2_SUPPORT */ 5839 #ifdef BCM_GREYHOUND_SUPPORT 5840 if (SOC_IS_GREYHOUND(unit)) { 5841 return soc_greyhound_oam_ser_process(unit, mem, index); 5842 } 5843 #endif /* BCM_GREYHOUND_SUPPORT */ 5844 #ifdef BCM_HURRICANE3_SUPPORT 5845 if (SOC_IS_HURRICANE3(unit)) { 5846 return soc_hr3_oam_ser_process(unit, mem, index); 5847 } 5848 #endif /* BCM_HURRICANE3_SUPPORT */ 5849 #ifdef BCM_GREYHOUND2_SUPPORT 5850 if (SOC_IS_GREYHOUND2(unit)) { 5851 return soc_gh2_oam_ser_process(unit, mem, index); 5852 } 5853 #endif /* BCM_GREYHOUND2_SUPPORT */ 5854 #ifdef BCM_KATANA2_SUPPORT 5855 if (SOC_IS_KATANA2(unit)) { 5856 return soc_kt2_oam_ser_process(unit, mem, index); 5857 } 5858 #endif /* BCM_KATANA2_SUPPORT */ 5859 5860 #ifdef BCM_TRIUMPH2_SUPPORT 5861 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit)) { 5862 return soc_triumph2_oam_ser_process(unit, mem, index); 5863 } 5864 #endif /* BCM_TRIUMPH2_SUPPORT */ 5865 5866 LOG_ERROR(BSL_LS_SOC_SER, 5867 (BSL_META_U(unit, 5868 "SER Handling routine not avaialable\n"))); 5869 return SOC_E_UNAVAIL; 5870 } 5871 5872 #if defined(INCLUDE_FLOWTRACKER) 5873 STATIC int 5874 _soc_ft_em_ser_correction(int unit, int pipe, soc_mem_t mem, int index) 5875 { 5876 LOG_VERBOSE(BSL_LS_SOC_SER, 5877 (BSL_META_U(unit, 5878 "th_dbg: entered _soc_ft_em_ser_correction routine\n"))); 5879 if (soc_feature(unit, soc_feature_uc_flowtracker_learn)) { 5880 return soc_th_ft_em_ser_process(unit, pipe, mem, index); 5881 } 5882 5883 LOG_ERROR(BSL_LS_SOC_SER, 5884 (BSL_META_U(unit, 5885 "SER Handling routine not avaialable\n"))); 5886 return SOC_E_UNAVAIL; 5887 } 5888 #endif /* INCLUDE_FLOWTRACKER */ 5889 5890 STATIC int 5891 _soc_ser_ipfix_correction(int unit, soc_mem_t mem) 5892 { 5893 int port; 5894 int ingress_stage = 0; 5895 int rv; 5896 5897 LOG_VERBOSE(BSL_LS_SOC_SER, 5898 (BSL_META_U(unit, 5899 "th_dbg: entered _soc_ser_ipfix_correction " 5900 "routine\n"))); 5901 /* 5902 * Also need to clear the 5903 * 1. ingress/egress fifo counter 5904 * 2. ingress/egress port record count 5905 * 3. ingress/egress port sampling count 5906 */ 5907 ingress_stage = (mem == ING_IPFIX_SESSION_TABLEm) ? 1 : 0; 5908 5909 if (ingress_stage) { 5910 rv = WRITE_ING_IPFIX_EXPORT_FIFO_COUNTERr(unit, 0); 5911 if (rv < 0) { 5912 LOG_ERROR(BSL_LS_SOC_SER, 5913 (BSL_META_U(unit, 5914 "ING_IPFIX_EXPORT_FIFO_COUNTERr clear failed: %s\n"), 5915 soc_errmsg(rv))); 5916 return rv; 5917 } 5918 } else { 5919 rv = WRITE_EGR_IPFIX_EXPORT_FIFO_COUNTERr(unit, 0); 5920 if (rv < 0) { 5921 LOG_ERROR(BSL_LS_SOC_SER, 5922 (BSL_META_U(unit, 5923 "EGR_IPFIX_EXPORT_FIFO_COUNTERr clear failed: %s\n"), 5924 soc_errmsg(rv))); 5925 return rv; 5926 } 5927 } 5928 5929 PBMP_PORT_ITER(unit, port) { 5930 if (ingress_stage) { 5931 5932 rv = WRITE_ING_IPFIX_PORT_RECORD_COUNTr(unit, port, 0); 5933 if (rv < 0) { 5934 LOG_ERROR(BSL_LS_SOC_SER, 5935 (BSL_META_U(unit, 5936 "ING_IPFIX_PORT_RECORD_COUNTr clear for " 5937 "port(%d) failed: %s\n"), 5938 port, soc_errmsg(rv))); 5939 return rv; 5940 } 5941 5942 rv = WRITE_ING_IPFIX_PORT_SAMPLING_COUNTERr(unit, port, 0); 5943 if (rv < 0) { 5944 LOG_ERROR(BSL_LS_SOC_SER, 5945 (BSL_META_U(unit, 5946 "ING_IPFIX_PORT_SAMPLING_COUNTERr clear for " 5947 "port(%d) failed: %s\n"), 5948 port, soc_errmsg(rv))); 5949 return rv; 5950 } 5951 } else { 5952 5953 rv = WRITE_EGR_IPFIX_PORT_RECORD_COUNTr(unit, port, 0); 5954 if (rv < 0) { 5955 LOG_ERROR(BSL_LS_SOC_SER, 5956 (BSL_META_U(unit, 5957 "EGR_IPFIX_PORT_RECORD_COUNTr clear for " 5958 "port(%d) failed: %s\n"), 5959 port, soc_errmsg(rv))); 5960 return rv; 5961 } 5962 5963 rv = WRITE_EGR_IPFIX_PORT_SAMPLING_COUNTERr(unit, port, 0); 5964 if (rv < 0) { 5965 LOG_ERROR(BSL_LS_SOC_SER, 5966 (BSL_META_U(unit, 5967 "EGR_IPFIX_PORT_SAMPLING_COUNTERr clear for " 5968 "port(%d) failed: %s\n"), 5969 port, soc_errmsg(rv))); 5970 return rv; 5971 } 5972 } 5973 } 5974 return SOC_E_NONE; 5975 } 5976 5977 #ifdef BCM_CMICX_SUPPORT 5978 int 5979 soc_ser_top_intr_reg_enable(int unit, int num, int bit, int enable) 5980 { 5981 int rv = SOC_E_NONE; 5982 uint32 reg_val = 0; 5983 soc_reg_t ser_intr_reg[4] = {ICFG_CHIP_LP_INTR_ENABLE_REG0r, 5984 ICFG_CHIP_LP_INTR_ENABLE_REG1r, 5985 ICFG_CHIP_LP_INTR_ENABLE_REG2r, 5986 ICFG_CHIP_LP_INTR_ENABLE_REG3r}; 5987 5988 rv = soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[num], 5989 REG_PORT_ANY, 0), ®_val); 5990 if (rv == SOC_E_NONE) { 5991 if (enable == 1) { 5992 reg_val |= 1 << bit; 5993 } else { 5994 reg_val &= ~(1 << bit); 5995 } 5996 5997 rv = soc_iproc_setreg(unit, soc_reg_addr(unit, ser_intr_reg[num], 5998 REG_PORT_ANY, 0), reg_val); 5999 } 6000 6001 return rv; 6002 } 6003 6004 void soc_ser_cmicx_intr_handler(int unit, void *data) 6005 { 6006 uint32 reg0_val = 0; 6007 uint32 reg1_val = 0; 6008 uint32 reg2_val = 0; 6009 uint32 reg3_val = 0; 6010 int i = 0, j = 0, k = 0; 6011 soc_reg_t ser_intr_reg[4] = {ICFG_CHIP_LP_INTR_RAW_STATUS_REG0r, 6012 ICFG_CHIP_LP_INTR_RAW_STATUS_REG1r, 6013 ICFG_CHIP_LP_INTR_RAW_STATUS_REG2r, 6014 ICFG_CHIP_LP_INTR_RAW_STATUS_REG3r}; 6015 6016 (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[0], REG_PORT_ANY, 0), 6017 ®0_val); 6018 (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[1], REG_PORT_ANY, 0), 6019 ®1_val); 6020 (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[2], REG_PORT_ANY, 0), 6021 ®2_val); 6022 (void)soc_iproc_getreg(unit, soc_reg_addr(unit, ser_intr_reg[3], REG_PORT_ANY, 0), 6023 ®3_val); 6024 6025 for(i = 0, j = 0, k = 0; i < 32; i++, j++, k++) { 6026 if(reg0_val & 1 << i) { 6027 #ifdef BCM_TRIDENT3_SUPPORT 6028 if (SOC_IS_TRIDENT3X(unit)) { 6029 if((i == 0) || (i >= 4 && i <= 12)) { 6030 (void)soc_ser_top_intr_reg_enable(unit, 0, i, 0); 6031 LOG_INFO(BSL_LS_SOC_INTR, 6032 (BSL_META_U(unit, 6033 "soc_ser_cmicx_intr_handler type 0 unit %d: dispatch\n"), unit)); 6034 if (soc_ser_parity_error_cmicx_intr(INT_TO_PTR(unit), 0, 0, 6035 INT_TO_PTR(0), 6036 INT_TO_PTR(i))) { 6037 } else { 6038 LOG_ERROR(BSL_LS_SOC_COMMON, 6039 (BSL_META_U(unit, 6040 "soc_ser_cmicx_intr_handler unit %d: " 6041 "Disabling unhandled interrupt(s): %d\n"), 6042 unit, PTR_TO_INT(i))); 6043 (void)soc_ser_top_intr_reg_enable(unit, 0, i, 0); 6044 } 6045 } else if (i == 1) { 6046 LOG_INFO(BSL_LS_SOC_INTR, 6047 (BSL_META_U(unit, 6048 "soc_cmicm_intr type 3 unit %d: dispatch\n"), 6049 unit)); 6050 6051 sal_dpc(soc_trident3_process_func_intr, INT_TO_PTR(unit), 6052 0, 0, 0, INT_TO_PTR(i)); 6053 } 6054 } 6055 #endif 6056 } 6057 6058 if (reg1_val & 1 << i) { 6059 #ifdef BCM_TRIDENT3_SUPPORT 6060 if (SOC_IS_TRIDENT3X(unit)) { 6061 (void)soc_ser_top_intr_reg_enable(unit, 1, i, 0); 6062 if (soc_ser_parity_error_cmicx_intr(INT_TO_PTR(unit), 0, 0, 6063 INT_TO_PTR(1), 6064 INT_TO_PTR(i))) { 6065 } else { 6066 LOG_ERROR(BSL_LS_SOC_COMMON, 6067 (BSL_META_U(unit, 6068 "soc_ser_cmicx_intr_handler unit %d: " 6069 "Disabling unhandled interrupt(s): %d\n"), 6070 unit, PTR_TO_INT(i))); 6071 (void)soc_ser_top_intr_reg_enable(unit, 1, i, 0); 6072 } 6073 } 6074 #endif 6075 } 6076 6077 if (reg2_val & 1 << i) { 6078 (void)soc_ser_top_intr_reg_enable(unit, 2, i, 0); 6079 if (soc_ser_parity_error_cmicx_intr(INT_TO_PTR(unit), 0, 0, 6080 INT_TO_PTR(2), 6081 INT_TO_PTR(i))) { 6082 } else { 6083 LOG_ERROR(BSL_LS_SOC_COMMON, 6084 (BSL_META_U(unit, 6085 "soc_ser_cmicx_intr_handler unit %d: " 6086 "Disabling unhandled interrupt(s): %d\n"), 6087 unit, PTR_TO_INT(i))); 6088 (void)soc_ser_top_intr_reg_enable(unit, 2, i, 0); 6089 } 6090 } 6091 } 6092 } 6093 #endif 6094 6095 #ifdef BCM_TSN_SUPPORT 6096 STATIC int 6097 _soc_ser_mem_is_tsn_cnt_mem(int unit, soc_mem_t mem) 6098 { 6099 #ifdef BCM_GREYHOUND2_SUPPORT 6100 if (SOC_IS_GREYHOUND2(unit) && 6101 /* Port cnt */ 6102 (mem == SR_PORT_COUNT_RXm || 6103 mem == SR_PORT_COUNT_RX_TAGGEDm || 6104 mem == SR_PORT_COUNT_RX_WRONG_LANm || 6105 mem == SR_PORT_COUNT_RX_ERRORm || 6106 mem == SR_PORT_COUNT_RX_TAG_ERRORm || 6107 mem == SR_PORT_COUNT_RX_DUPLICATESm || 6108 mem == SR_PORT_COUNT_RX_OUTOFORDERm || 6109 mem == SR_PORT_COUNT_OWN_RXm || 6110 mem == SR_PORT_COUNT_UNEXPECTED_FRAMEm || 6111 mem == SR_PORT_MTU_ERRORm || mem == SR_PORT_STU_ERRORm || 6112 mem == SR_PORT_PROXY_MAC_ERRORm || 6113 mem == SR_PORT_COUNT_RX_PASSEDm || 6114 mem == SR_PORT_COUNT_TXm || 6115 mem == SR_PORT_COUNT_TX_TAGGEDm || 6116 mem == SR_PORT_TX_MTU_ERRORm || mem == SR_PORT_TX_STU_ERRORm || 6117 /* Flow cnt */ 6118 mem == SR_FLOW_COUNT_POOL0m || mem == SR_FLOW_COUNT_POOL1m || 6119 mem == SR_FLOW_COUNT_POOL2m || mem == SR_FLOW_COUNT_POOL3m || 6120 mem == SR_FLOW_COUNT_POOL4m || mem == SR_FLOW_COUNT_POOL5m || 6121 mem == SR_FLOW_COUNT_POOL6m || mem == SR_FLOW_COUNT_POOL7m || 6122 mem == EGR_SR_FLOW_COUNT_POOL0m || mem == EGR_SR_FLOW_COUNT_POOL1m)) { 6123 return TRUE; 6124 } 6125 #endif /* BCM_GREYHOUND2_SUPPORT */ 6126 return FALSE; 6127 } 6128 #endif /* BCM_TSN_SUPPORT */ 6129 6130 STATIC int 6131 _soc_ser_mem_entry_clear(int unit, soc_mem_t mem, int copyno, 6132 int index, _soc_ser_correct_info_t *si, 6133 soc_ser_log_tlv_generic_t *log_generic, 6134 soc_stat_t *stat) 6135 { 6136 int rv = SOC_E_NONE; 6137 void *null_entry = NULL; 6138 #ifdef BCM_TRIUMPH3_SUPPORT 6139 uint32 rval; 6140 #endif 6141 uint32 stat_flags = 0; 6142 int block_type = 0; 6143 int parity_type = 0; 6144 6145 LOG_VERBOSE(BSL_LS_SOC_SER, 6146 (BSL_META_U(unit, 6147 "th_dbg: SER_CORRECTION_TYPE = " 6148 "ENTRY_CLEAR for mem = %0d\n"), mem)); 6149 #ifdef BCM_TRIUMPH3_SUPPORT 6150 if (SOC_IS_TRIUMPH3(unit)) { 6151 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 6152 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 6153 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 6154 } 6155 #endif 6156 6157 if (si->flags & SOC_SER_ALSO_UPDATE_SW_COUNTER) { 6158 rv = SOC_E_FAIL; 6159 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 6160 rv = soc_ser_update_counter( 6161 unit, 6162 0, /* is_reg */ 6163 INVALIDr, /* restore_reg */ 6164 si->mem, /* restore_mem */ 6165 si->index, 6166 copyno, 6167 INVALIDr, /* base_reg */ 6168 si->counter_base_mem, /* base_mem */ 6169 si->inst, /* inst_num */ 6170 si->pipe_num, 6171 SOC_SER_COUNTER_CORRECTION(unit)); /* restore_last */ 6172 } 6173 } else { 6174 null_entry = soc_mem_entry_null(unit, mem); 6175 rv = soc_mem_write(unit, mem, copyno, index, null_entry); 6176 } 6177 6178 if (rv < 0) { 6179 LOG_ERROR(BSL_LS_SOC_SER, 6180 (BSL_META_U(unit, 6181 "ENTRY_CLEAR %s.%s[%d] failed: %s\n"), 6182 SOC_MEM_NAME(unit, mem), 6183 SOC_BLOCK_NAME(unit, copyno), index, soc_errmsg(rv))); 6184 if (si->log_id != 0) { 6185 log_generic->corrected = SOC_SER_UNCORRECTED; 6186 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6187 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6188 } 6189 return rv; 6190 } 6191 #if defined(BCM_TRIDENT_SUPPORT) 6192 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT(unit)) { 6193 soc_ser_counter_info_set(unit, mem, index, null_entry); 6194 } 6195 #endif 6196 #ifdef BCM_TRIUMPH3_SUPPORT 6197 if (SOC_IS_TRIUMPH3(unit)) { 6198 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 6199 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 6200 6201 } 6202 #endif 6203 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 6204 si, mem, index); 6205 LOG_WARN(BSL_LS_SOC_SER, 6206 (BSL_META_U(unit, 6207 "ENTRY_CLEAR: %s[%d] blk: %s index: %d : [%d][%x]\n"), 6208 SOC_MEM_NAME(unit, mem), mem, 6209 SOC_BLOCK_NAME(unit, copyno), index, si->sblk, si->addr)); 6210 6211 /* Handle IPFIX ser */ 6212 if (mem == ING_IPFIX_SESSION_TABLEm || 6213 mem == EGR_IPFIX_SESSION_TABLEm) { 6214 if ((rv = _soc_ser_ipfix_correction(unit, mem)) < 0) { 6215 if (si->log_id != 0) { 6216 log_generic->corrected = SOC_SER_UNCORRECTED; 6217 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6218 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6219 } 6220 return rv; 6221 } 6222 } 6223 6224 stat->ser_err_clear++; 6225 if (si->log_id != 0) { 6226 log_generic->corrected = SOC_SER_CORRECTED; 6227 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6228 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6229 } 6230 if ((si->mem != INVALIDm) && 6231 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) { 6232 stat_flags = SOC_SER_STAT_TCAM; 6233 block_type = SOC_BLOCK_INFO(unit, copyno).type; 6234 parity_type = SOC_PARITY_TYPE_PARITY; 6235 } else { 6236 stat_flags = 0; 6237 block_type = si->blk_type; 6238 parity_type = si->parity_type; 6239 } 6240 soc_ser_stat_update(unit, stat_flags, block_type, 6241 parity_type, si->double_bit, 6242 SocSerCorrectTypeEntryClear, 6243 stat); 6244 #ifdef BCM_TSN_SUPPORT 6245 if (soc_feature(unit, soc_feature_tsn) && 6246 (soc_ser_tsn_stat_functions[unit] != NULL) && 6247 (soc_ser_tsn_stat_functions[unit]->_soc_tsn_stat_counter_update_f != NULL)) { 6248 uint64 new_packet_count; 6249 COMPILER_64_ZERO(new_packet_count); 6250 6251 if (_soc_ser_mem_is_tsn_cnt_mem(unit, mem)) { 6252 rv = (*(soc_ser_tsn_stat_functions[unit]->_soc_tsn_stat_counter_update_f))( 6253 unit, mem, index, new_packet_count); 6254 if (SOC_FAILURE(rv)) { 6255 LOG_ERROR(BSL_LS_SOC_SER, 6256 (BSL_META_U(unit, 6257 "ENTRY_CLEAR %s.%s[%d] " 6258 "tsn cnt clear failed: %s\n"), 6259 SOC_MEM_NAME(unit, mem), 6260 SOC_BLOCK_NAME(unit, copyno), index, soc_errmsg(rv))); 6261 } 6262 } 6263 } 6264 #endif /* BCM_TSN_SUPPORT */ 6265 return SOC_E_NONE; 6266 } 6267 6268 STATIC int 6269 _soc_ser_mem_entry_restore(int unit, soc_mem_t mem, int copyno, 6270 int index, _soc_ser_correct_info_t *si, 6271 soc_ser_log_tlv_generic_t *log_generic, 6272 soc_stat_t *stat, uint32 flags, 6273 uint32 *entry) 6274 { 6275 int rv = SOC_E_NONE; 6276 int is_l3_defip = FALSE; 6277 int entry_dw; 6278 void *null_entry = NULL; 6279 uint32 *cache = NULL; 6280 uint8 *vmap; 6281 #if defined(ALPM_ENABLE) 6282 uint8 _alpm_lock = 0; 6283 #endif /* ALPM_ENABLE */ 6284 uint32 stat_flags = 0; 6285 int block_type = 0; 6286 int parity_type = 0; 6287 soc_ser_correction_type_t ctype; 6288 #ifdef BCM_TOMAHAWK_SUPPORT 6289 uint16 dev_id; 6290 uint8 rev_id; 6291 uint8 at = 0; 6292 int recover_pipe = si->pipe_num; 6293 #endif 6294 6295 LOG_VERBOSE(BSL_LS_SOC_SER, 6296 (BSL_META_U(unit, 6297 "th_dbg: SER_CORRECTION_TYPE = %s for mem = %0d\n"), 6298 ((flags == SOC_MEM_FLAG_SER_ECC_CORRECTABLE) ? "ECC_CORRECTABLE" : 6299 (flags == SOC_MEM_FLAG_SER_CACHE_RESTORE) ? "CACHE_RESTORE" : 6300 (flags == SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE) ? "WRITE_CACHE_RESTORE" : "UNKNOW"), 6301 mem)); 6302 6303 if (SOC_IS_TD2_TT2(unit)) { 6304 if (mem == L3_DEFIP_ALPM_IPV4m || mem == L3_DEFIP_ALPM_IPV4_1m || 6305 mem == L3_DEFIP_ALPM_IPV6_64m || mem == L3_DEFIP_ALPM_IPV6_64_1m || 6306 mem == L3_DEFIP_ALPM_IPV6_128m || mem == L3_DEFIP_AUX_TABLEm || 6307 mem == L3_DEFIPm || mem == L3_DEFIP_PAIR_128m || 6308 mem == L3_DEFIP_ALPM_LEVEL2_ECCm || mem == L3_DEFIP_TCAM_LEVEL1m || 6309 mem == L3_DEFIP_PAIR_LEVEL1m || mem == L3_DEFIP_DATA_LEVEL1m) { 6310 /* Take advantage of SER write cache flow */ 6311 is_l3_defip = TRUE; 6312 } 6313 } 6314 6315 /* In TD2, the HW does SBUS MEMWR error checking 6316 * on the L3_ENTRY table in general. Include both 6317 * XOR and non-XOR mems. 6318 */ 6319 #if defined(BCM_TRIDENT2_SUPPORT) 6320 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) { 6321 soc_trident2_l3_memwr_parity_check(unit, mem, TRUE); 6322 } 6323 #endif /* BCM_TRIDENT2_SUPPORT */ 6324 #if defined(BCM_TRIDENT3_SUPPORT) 6325 if (SOC_IS_TRIDENT3X(unit)) { 6326 soc_trident3_l3_memwr_parity_check(unit, mem, TRUE); 6327 } 6328 #endif 6329 rv = _soc_ser_overlay_mem_correction(unit, si->flags & SOC_SER_ERR_CPU ? 1 : 0, 6330 si->pipe_num, si->sblk, si->addr, mem, 6331 copyno, index, si); 6332 6333 #if defined(BCM_TRIDENT3_SUPPORT) 6334 if (SOC_IS_TRIDENT3X(unit)) { 6335 soc_trident3_l3_memwr_parity_check(unit, mem, FALSE); 6336 } 6337 #endif 6338 #if defined(BCM_TRIDENT_SUPPORT) 6339 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 6340 if (rv == SOC_E_UNAVAIL) { 6341 rv = soc_trident_ser_dual_pipe_correction(unit, mem, copyno, index, si); 6342 } 6343 } 6344 #endif 6345 6346 #if defined(BCM_TRIDENT2_SUPPORT) 6347 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) { 6348 soc_trident2_l3_memwr_parity_check(unit, mem, FALSE); 6349 } 6350 #endif /* BCM_TRIDENT2_SUPPORT */ 6351 if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) { 6352 if (si->log_id != 0) { 6353 log_generic->corrected = (rv == SOC_E_NONE); 6354 if (rv == SOC_E_NONE) { 6355 log_generic->hw_cache = 6356 (si->ctype == socSerCorrectTypeHwCacheRestore) ? TRUE : FALSE; 6357 if (si->ctype == SocSerCorrectTypeEntryClear) { 6358 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR; 6359 } else if (si->ctype == SocSerCorrectTypeCacheRestore) { 6360 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE; 6361 } 6362 } 6363 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6364 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6365 } 6366 if (rv == SOC_E_NONE) { 6367 if ((si->mem != INVALIDm) && 6368 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) { 6369 stat_flags = SOC_SER_STAT_TCAM; 6370 block_type = SOC_BLOCK_INFO(unit, copyno).type; 6371 parity_type = SOC_PARITY_TYPE_PARITY; 6372 } else { 6373 stat_flags = 0; 6374 block_type = si->blk_type; 6375 parity_type = si->parity_type; 6376 } 6377 ctype = si->ctype ? si->ctype : SocSerCorrectTypeCacheRestore; 6378 soc_ser_stat_update(unit, stat_flags, block_type, 6379 parity_type, si->double_bit, 6380 ctype, 6381 stat); 6382 } 6383 return rv; 6384 } 6385 /* Take lock to ensure that cache won't be changed during correction */ 6386 if (is_l3_defip) { 6387 _ALPM_LOCK(unit); 6388 } else { 6389 MEM_LOCK(unit, mem); 6390 } 6391 cache = SOC_MEM_STATE(unit, mem).cache[copyno]; 6392 vmap = SOC_MEM_STATE(unit, mem).vmap[copyno]; 6393 if (is_l3_defip && (NUM_PIPE(unit) > 1)) { 6394 /* For L3_DEFIP* tables, we can't use cache for SER correction 6395 * on multi-pipe devices 6396 */ 6397 if (((mem == L3_DEFIPm) && (alpm_no_cache_flag[unit].flag_defip == 1)) || 6398 ((mem == L3_DEFIP_PAIR_128m) && (alpm_no_cache_flag[unit].flag_defip_128 == 1)) || 6399 ((mem == L3_DEFIP_ALPM_IPV4m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4 == 1)) || 6400 ((mem == L3_DEFIP_ALPM_IPV4_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 == 1)) || 6401 ((mem == L3_DEFIP_ALPM_IPV6_64m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6 == 1)) || 6402 ((mem == L3_DEFIP_ALPM_IPV6_64_1m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 == 1)) || 6403 ((mem == L3_DEFIP_ALPM_IPV6_128m) && (alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 == 1)) || 6404 ((mem == L3_DEFIP_AUX_TABLEm) && (alpm_no_cache_flag[unit].flag_defip_aux == 1)) || 6405 (mem == L3_DEFIP_ALPM_LEVEL2_ECCm) || (mem == L3_DEFIP_TCAM_LEVEL1m) || 6406 (mem == L3_DEFIP_PAIR_LEVEL1m) || (mem == L3_DEFIP_DATA_LEVEL1m) || 6407 ((cache != NULL) && (!CACHE_VMAP_TST(vmap, index)))) { 6408 cache = NULL; 6409 } 6410 } 6411 if ((cache == NULL) && (NUM_PIPE(unit) > 1)) { 6412 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 6413 if ((SOC_IS_TD2_TT2(unit) && 6414 (mem == L3_DEFIPm || 6415 mem == L3_DEFIP_PAIR_128m) )|| 6416 (SOC_IS_TOMAHAWK3(unit) && 6417 (mem == L3_DEFIP_TCAM_LEVEL1m || mem == L3_DEFIP_DATA_LEVEL1m || 6418 mem == L3_DEFIP_PAIR_LEVEL1m))) { 6419 rv = _soc_ser_recovery_hw_cache(unit, si->pipe_num, mem, 6420 copyno, index, si, TRUE); 6421 } else 6422 #endif 6423 { 6424 rv = _soc_ser_recovery_hw_cache(unit, si->pipe_num, mem, 6425 copyno, index, si, FALSE); 6426 } 6427 if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) { 6428 if (rv == SOC_E_NONE && mem == L3_DEFIP_AUX_TABLEm && 6429 SOC_IS_TD2_TT2(unit)) { 6430 if (SOC_CONTROL(unit)->alpm_bulk_retry) { 6431 sal_sem_give(SOC_CONTROL(unit)->alpm_bulk_retry); 6432 } 6433 } 6434 if (si->log_id != 0) { 6435 log_generic->corrected = (rv == SOC_E_NONE); 6436 log_generic->hw_cache = (rv == SOC_E_NONE) ? TRUE : FALSE; 6437 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6438 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6439 } 6440 if (rv == SOC_E_NONE) { 6441 if ((si->mem != INVALIDm) && 6442 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) { 6443 stat_flags = SOC_SER_STAT_TCAM; 6444 block_type = SOC_BLOCK_INFO(unit, copyno).type; 6445 parity_type = SOC_PARITY_TYPE_PARITY; 6446 } else { 6447 stat_flags = 0; 6448 block_type = si->blk_type; 6449 parity_type = si->parity_type; 6450 } 6451 soc_ser_stat_update(unit, stat_flags, block_type, 6452 parity_type, si->double_bit, 6453 socSerCorrectTypeHwCacheRestore, 6454 stat); 6455 } 6456 if (is_l3_defip) { 6457 _ALPM_UNLOCK(unit) 6458 } else { 6459 MEM_UNLOCK(unit,mem); 6460 } 6461 return rv; 6462 } 6463 } 6464 if (cache != NULL && CACHE_VMAP_TST(vmap, index)) { 6465 entry_dw = soc_mem_entry_words(unit, mem); 6466 sal_memcpy(entry, cache + index * entry_dw, entry_dw * 4); 6467 if ((si->log_id != 0) && 6468 (si->flags & SOC_SER_LOG_WRITE_CACHE)) { 6469 (void)soc_ser_log_add_tlv(unit, si->log_id, 6470 SOC_SER_LOG_TLV_CACHE, 6471 entry_dw*4, entry); 6472 } 6473 6474 #ifdef BCM_TOMAHAWK_SUPPORT 6475 soc_cm_get_id(unit, &dev_id, &rev_id); 6476 at = SOC_MEM_ACC_TYPE(unit, mem); 6477 6478 if ((dev_id == BCM56983_DEVICE_ID ) && 6479 ((at == _SOC_TH_ACC_TYPE_DUPLICATE_2) || 6480 (at == _SOC_TH_ACC_TYPE_DUPLICATE_4))) { 6481 if (at == _SOC_TH_ACC_TYPE_DUPLICATE_2) { 6482 if (si->pipe_num == 1) { 6483 recover_pipe = 0; 6484 } else if (si->pipe_num == 6) { 6485 recover_pipe = 7; 6486 } 6487 } 6488 if (at == _SOC_TH_ACC_TYPE_DUPLICATE_4) { 6489 if (si->pipe_num == 1 || si->pipe_num == 6 || si->pipe_num == 7) { 6490 recover_pipe = 0; 6491 } 6492 } 6493 rv = soc_mem_pipe_select_write(unit, SOC_MEM_NO_FLAGS, mem, 6494 copyno, recover_pipe, index, entry); 6495 } else 6496 #endif 6497 { 6498 rv = soc_mem_write(unit, mem, copyno, index, entry); 6499 } 6500 if (rv < 0) { 6501 LOG_ERROR(BSL_LS_SOC_SER, 6502 (BSL_META_U(unit, 6503 "CACHE_RESTORE %s.%s[%d] failed: %s\n"), 6504 SOC_MEM_NAME(unit, mem), 6505 SOC_BLOCK_NAME(unit, copyno), 6506 index, soc_errmsg(rv))); 6507 6508 if (is_l3_defip) { 6509 _ALPM_UNLOCK(unit) 6510 } else { 6511 MEM_UNLOCK(unit,mem); 6512 } 6513 6514 if (si->log_id != 0) { 6515 log_generic->corrected = (rv == SOC_E_NONE); 6516 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6517 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6518 } 6519 return rv; 6520 } 6521 if (si->log_id != 0) { 6522 log_generic->corrected = SOC_SER_CORRECTED; 6523 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6524 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6525 } 6526 if ((si->mem != INVALIDm) && 6527 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) { 6528 stat_flags = SOC_SER_STAT_TCAM; 6529 block_type = SOC_BLOCK_INFO(unit, copyno).type; 6530 parity_type = SOC_PARITY_TYPE_PARITY; 6531 } else { 6532 stat_flags = 0; 6533 block_type = si->blk_type; 6534 parity_type = si->parity_type; 6535 } 6536 soc_ser_stat_update(unit, stat_flags, block_type, 6537 parity_type, si->double_bit, 6538 SocSerCorrectTypeCacheRestore, 6539 stat); 6540 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 6541 si, mem, index); 6542 LOG_WARN(BSL_LS_SOC_SER, 6543 (BSL_META_U(unit, 6544 "CACHE_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"), 6545 SOC_MEM_NAME(unit, mem), mem, 6546 SOC_BLOCK_NAME(unit, copyno), 6547 index, si->sblk, si->addr)); 6548 stat->ser_err_restor++; 6549 #ifdef _SER_TIME_STAMP 6550 ser_time_5 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1); 6551 LOG_CLI((BSL_META_U(unit, 6552 "Total: %d\n"), ser_time_5)); 6553 #endif 6554 } else { /* Fall back to clear */ 6555 LOG_VERBOSE(BSL_LS_SOC_SER, 6556 (BSL_META_U(unit, 6557 "th_dbg: " 6558 "main routine falling back to clear\n"))); 6559 null_entry = soc_mem_entry_null(unit, mem); 6560 #ifdef BCM_TRIDENT2_SUPPORT 6561 if (SOC_IS_TRIDENT2(unit) && 6562 (mem == ES_PIPE0_LLS_PORT_MEMA_CONFIGm) && 6563 (si->index > 52 && si->index < 64)) { 6564 rv = soc_mem_write_extended(unit, 6565 SOC_MEM_DONT_USE_CACHE | SOC_MEM_DONT_CHECK_INDEX, 6566 mem, copyno, index, null_entry); 6567 } else 6568 #endif 6569 { 6570 rv = soc_mem_write(unit, mem, copyno, index, null_entry); 6571 } 6572 if (rv < 0) { 6573 LOG_ERROR(BSL_LS_SOC_SER, 6574 (BSL_META_U(unit, 6575 "CLEAR_RESTORE %s.%s[%d] failed: %s\n"), 6576 SOC_MEM_NAME(unit, mem), 6577 SOC_BLOCK_NAME(unit, copyno), 6578 index, soc_errmsg(rv))); 6579 6580 if (is_l3_defip) { 6581 _ALPM_UNLOCK(unit) 6582 } else { 6583 MEM_UNLOCK(unit, mem); 6584 } 6585 6586 if (si->log_id != 0) { 6587 log_generic->corrected = SOC_SER_UNCORRECTED; 6588 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6589 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6590 } 6591 return rv; 6592 } 6593 6594 if (si->log_id != 0) { 6595 log_generic->corrected = SOC_SER_CORRECTED; 6596 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR; 6597 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6598 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6599 } 6600 if ((si->mem != INVALIDm) && 6601 (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CAM)) { 6602 stat_flags = SOC_SER_STAT_TCAM; 6603 block_type = SOC_BLOCK_INFO(unit, copyno).type; 6604 parity_type = SOC_PARITY_TYPE_PARITY; 6605 } else { 6606 stat_flags = 0; 6607 block_type = si->blk_type; 6608 parity_type = si->parity_type; 6609 } 6610 soc_ser_stat_update(unit, stat_flags, block_type, 6611 parity_type, si->double_bit, 6612 SocSerCorrectTypeEntryClear, 6613 stat); 6614 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 6615 si, mem, index); 6616 LOG_WARN(BSL_LS_SOC_SER, 6617 (BSL_META_U(unit, 6618 "CLEAR_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"), 6619 SOC_MEM_NAME(unit, mem), mem, 6620 SOC_BLOCK_NAME(unit, copyno), 6621 index, si->sblk, si->addr)); 6622 if (_SOC_DRV_MEM_CHK_L2_MEM(mem) && 6623 soc_feature(unit, soc_feature_mac_learn_limit)) { 6624 if ((rv =_soc_ser_sync_mac_limits(unit, mem)) != SOC_E_NONE) { 6625 LOG_ERROR(BSL_LS_SOC_SER, 6626 (BSL_META_U(unit, 6627 "L2 mac limit sync failed !!\n"))); 6628 if (is_l3_defip) { 6629 _ALPM_UNLOCK(unit) 6630 } else { 6631 MEM_UNLOCK(unit, mem); 6632 } 6633 return rv; 6634 } 6635 } 6636 stat->ser_err_clear++; 6637 #ifdef _SER_TIME_STAMP 6638 ser_time_5 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1); 6639 LOG_CLI((BSL_META_U(unit, 6640 "Total: %d\n"), ser_time_5)); 6641 #endif 6642 } 6643 if ((cache != NULL) && !(si->flags & SOC_SER_SKIP_HARD_FALT_CHECK)) { 6644 rv = _soc_ser_check_hard_fault(unit, mem, si->acc_type, copyno, 6645 index, 6646 null_entry == NULL ? 6647 entry : null_entry, 0, 6648 si->pipe_num, FALSE); 6649 if (is_l3_defip) { 6650 _ALPM_UNLOCK(unit) 6651 } else { 6652 MEM_UNLOCK(unit, mem); 6653 } 6654 6655 return rv; 6656 } 6657 6658 if (is_l3_defip) { 6659 _ALPM_UNLOCK(unit) 6660 } else { 6661 MEM_UNLOCK(unit, mem); 6662 } 6663 return SOC_E_NONE; 6664 } 6665 6666 STATIC int 6667 _soc_vfp_ser_correction(int unit, soc_mem_t mem, int index, int copyno) 6668 { 6669 int rv = SOC_E_NONE; 6670 6671 #ifdef BCM_TOMAHAWK2_SUPPORT 6672 if (SOC_IS_TOMAHAWK2(unit) && soc_feature(unit, soc_feature_tcam_scan_engine)) { 6673 int entry_dw; 6674 entry_dw = soc_mem_entry_words(unit, mem); 6675 rv = soc_th2_vfp_ser_correction(unit, mem, index, copyno, entry_dw); 6676 } 6677 #endif 6678 6679 return rv; 6680 } 6681 6682 STATIC int 6683 _soc_ser_mem_entry_special(int unit, soc_mem_t mem, int copyno, 6684 int index, _soc_ser_correct_info_t *si, 6685 soc_ser_log_tlv_generic_t *log_generic, 6686 soc_stat_t *stat) 6687 { 6688 int rv = SOC_E_NONE; 6689 6690 if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) == 6691 SOC_MEM_FLAG_SER_SPECIAL) { 6692 LOG_VERBOSE(BSL_LS_SOC_SER, 6693 (BSL_META_U(unit, 6694 "th_dbg: SER_CORRECTION_TYPE = " 6695 "SPECIAL for mem = %0d\n"), mem)); 6696 } 6697 stat->ser_err_spe++; 6698 6699 switch (mem) { 6700 case L2_ENTRY_LPm: 6701 case L2_ENTRY_ISS_LPm: 6702 case L3_ENTRY_LPm: 6703 case L3_ENTRY_ISS_LPm: 6704 case VLAN_XLATE_LPm: 6705 case EGR_VLAN_XLATE_LPm: 6706 case EXACT_MATCH_LPm: 6707 case VLAN_XLATE_1_LPm: 6708 case VLAN_XLATE_2_LPm: 6709 case EGR_VLAN_XLATE_1_LPm: 6710 case EGR_VLAN_XLATE_2_LPm: 6711 case MPLS_ENTRY_LPm: 6712 LOG_WARN(BSL_LS_SOC_SER, 6713 (BSL_META_U(unit, 6714 "SER_SPECIAL: %s[%d] blk: %s index: %d : [%d][%x]\n"), 6715 SOC_MEM_NAME(unit, mem), mem, 6716 SOC_BLOCK_NAME(unit, copyno), 6717 index, si->sblk, si->addr)); 6718 rv = _soc_ser_lp_mem_correction(unit, mem, index, copyno); 6719 if (SOC_SUCCESS(rv)) { 6720 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 6721 si, mem, index); 6722 stat->ser_err_corr++; 6723 } else { 6724 LOG_ERROR(BSL_LS_SOC_SER, (BSL_META_U(unit, 6725 "SER correction failed for LP memory \n"))); 6726 6727 } 6728 break; 6729 case PORT_OR_TRUNK_MAC_COUNTm: 6730 case VLAN_OR_VFI_MAC_COUNTm: 6731 rv = _soc_ser_sync_mac_limits(unit, mem); 6732 break; 6733 case MA_STATEm: 6734 case RMEPm: 6735 rv = _soc_oam_ser_correction(unit, mem, index); 6736 if (rv != SOC_E_NONE) { 6737 LOG_ERROR(BSL_LS_SOC_SER, 6738 (BSL_META_U(unit, 6739 "Error in SER Handling rv=%d\n"), 6740 rv)); 6741 } 6742 break; 6743 case VFP_TCAMm: 6744 rv = _soc_vfp_ser_correction(unit, mem, index, copyno); 6745 if (rv != SOC_E_NONE) { 6746 LOG_ERROR(BSL_LS_SOC_SER, 6747 (BSL_META_U(unit, 6748 "Error in SER Handling rv=%d\n"), 6749 rv)); 6750 } 6751 break; 6752 default: 6753 LOG_ERROR(BSL_LS_SOC_SER, 6754 (BSL_META_U(unit, 6755 "Unknown ser correction !!\n"))); 6756 rv = SOC_E_INTERNAL; 6757 stat->ser_err_sw++; 6758 break; 6759 } 6760 if (si->log_id != 0) { 6761 log_generic->corrected = (rv == SOC_E_NONE); 6762 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6763 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6764 } 6765 if (rv == SOC_E_NONE) { 6766 soc_ser_stat_update(unit, 0, si->blk_type, 6767 si->parity_type, si->double_bit, 6768 SocSerCorrectTypeSpecial, 6769 stat); 6770 } 6771 return rv; 6772 } 6773 6774 void 6775 soc_ser_stat_update(int unit, uint32 flags, int blk_type, 6776 int parity_type, uint8 db, 6777 soc_ser_correction_type_t ctype, 6778 soc_stat_t *stat) 6779 { 6780 soc_ser_block_type_t btype = 0; 6781 soc_ser_error_type_t etype = 0; 6782 6783 if (!soc_feature(unit, soc_feature_ser_error_stat)) { 6784 return; 6785 } 6786 6787 switch (blk_type) { 6788 case SOC_BLK_MMU: 6789 btype = SocSerBlockTypeMMU; 6790 break; 6791 case SOC_BLK_MMU_GLB: 6792 btype = SocSerBlockTypeMMU_GLB; 6793 break; 6794 case SOC_BLK_MMU_SC: 6795 btype = SocSerBlockTypeMMU_SC; 6796 break; 6797 case SOC_BLK_MMU_SED: 6798 btype = SocSerBlockTypeMMU_SED; 6799 break; 6800 case SOC_BLK_MMU_XPE: 6801 btype = SocSerBlockTypeMMU_XPE; 6802 break; 6803 case SOC_BLK_IPIPE: 6804 btype = SocSerBlockTypeIPIPE; 6805 break; 6806 case SOC_BLK_EPIPE: 6807 btype = SocSerBlockTypeEPIPE; 6808 break; 6809 case SOC_BLK_PGW_CL: 6810 btype = SocSerBlockTypePGW; 6811 break; 6812 case SOC_BLK_CLPORT: 6813 btype = SocSerBlockTypeCLPORT; 6814 break; 6815 case SOC_BLK_XTPORT: 6816 btype = SocSerBlockTypeXLPORT; 6817 break; 6818 case SOC_BLK_MACSEC: 6819 btype = SocSerBlockTypeMACSEC; 6820 break; 6821 default: 6822 break; 6823 } 6824 6825 if (parity_type == SOC_PARITY_TYPE_PARITY) { 6826 etype = SocSerErrorTypeParity; 6827 } else if (parity_type == SOC_PARITY_TYPE_ECC && 6828 db == 0) { 6829 etype = SocSerErrorTypeEccSingleBit; 6830 } else if (parity_type == SOC_PARITY_TYPE_ECC && 6831 db == 1) { 6832 etype = SocSerErrorTypeEccDoubleBit; 6833 } else { 6834 etype = SocSerErrorTypeUnknown; 6835 } 6836 6837 SOC_SER_ERR_STAT_LOCK(unit); 6838 if (flags & SOC_SER_STAT_TCAM) { 6839 stat->ser_tcam_err[btype][etype][ctype]++; 6840 } 6841 stat->ser_err[btype][etype][ctype]++; 6842 6843 SOC_SER_ERR_STAT_UNLOCK(unit); 6844 return; 6845 } 6846 6847 STATIC int 6848 _soc_ser_mem_correction(int unit, _soc_ser_correct_info_t *si, 6849 soc_ser_log_tlv_generic_t *log_generic, 6850 soc_stat_t *stat) 6851 { 6852 soc_mem_t mem = si->mem; 6853 int rv, index = si->index, entry_dw; 6854 int copyno = 0; 6855 uint32 entry[SOC_MAX_MEM_WORDS]; 6856 uint32 flags = 0; 6857 soc_ser_log_tlv_memory_t log_mem; 6858 log_mem.index = index; 6859 6860 if (!(si->flags & SOC_SER_REG_MEM_KNOWN)) { 6861 /* Decode memory from address details */ 6862 mem = soc_addr_to_mem_extended(unit, si->sblk, si->acc_type, si->addr); 6863 if (mem == INVALIDm) { 6864 if (si->log_id != 0) { 6865 log_mem.memory = mem; 6866 log_generic->corrected = SOC_SER_UNCORRECTED; 6867 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_MEMORY, 6868 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 6869 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6870 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6871 } 6872 if (soc_feature(unit, soc_feature_two_ingress_pipes) && 6873 soc_feature(unit, soc_feature_sbusdma)) { 6874 LOG_VERBOSE(BSL_LS_SOC_SER, 6875 (BSL_META_U(unit, 6876 "memory not decoded [%d %d 0x%8x].\n"), 6877 si->sblk, si->acc_type, si->addr)); 6878 return SOC_E_NOT_FOUND; 6879 } else { 6880 LOG_ERROR(BSL_LS_SOC_SER, 6881 (BSL_META_U(unit, 6882 "memory not decoded [%d %d 0x%8x].\n"), 6883 si->sblk, si->acc_type, si->addr)); 6884 stat->ser_err_sw++; 6885 return SOC_E_INTERNAL; 6886 } 6887 } 6888 } 6889 /* In TR3 and HX4, there are several memory names VLAN_XLATEm, 6890 * VLAN_XLATE_1m, VLAN_XLATE_EXTDm for the physical VLAN_XLATE 6891 * table, refering to single or double base entry views. 6892 * When parity errors are detected in the physical table, 6893 * _soc_ser_overlay_mem_correction should be invoked with the parameter 6894 * "reported_mem" as VLAN_XLATE_1m to correct errors in appropiate table 6895 * views. The routine soc_addr_to_mem_extended always returns VLAN_XLATEm, 6896 * not VLAN_XLATE_1m. So overriding memory name is added here. 6897 * The long term way to handle these things which are per device is 6898 * to register a per device memory check and over-ride function and 6899 * call it from soc_ser_correction() */ 6900 if (soc_feature(unit, soc_feature_ism_memory) && mem == VLAN_XLATEm) { 6901 mem = VLAN_XLATE_1m; 6902 } 6903 if (!SOC_MEM_IS_VALID(unit, mem)) { 6904 return SOC_E_INTERNAL; 6905 } 6906 if (si->log_id != 0) { 6907 if (si->flags & SOC_SER_LOG_MEM_REPORTED) { 6908 log_mem.memory = si->mem_reported; 6909 } else { 6910 log_mem.memory = mem; 6911 } 6912 log_generic->ser_response_flag = SOC_MEM_SER_CORRECTION_TYPE(unit, mem); 6913 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_MEMORY, 6914 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 6915 } 6916 6917 if (si->sblk) { 6918 SOC_MEM_BLOCK_ITER(unit, mem, copyno) { 6919 if (SOC_BLOCK2OFFSET(unit, copyno) == si->sblk) { 6920 break; 6921 } 6922 } 6923 } else { 6924 copyno = SOC_MEM_BLOCK_ANY(unit, mem); 6925 } 6926 stat->ser_err_mem++; 6927 LOG_WARN(BSL_LS_SOC_SER, 6928 (BSL_META_U(unit, 6929 "mem: %d=%s blkoffset:%d\n"), mem, 6930 SOC_MEM_NAME(unit, mem), copyno)); 6931 entry_dw = soc_mem_entry_words(unit, mem); 6932 if (soc_feature(unit, soc_feature_shared_hash_mem)) { 6933 rv = soc_ser_sram_correction(unit, si->pipe_num, si->sblk, si->addr, 6934 mem, copyno, index, si); 6935 if (rv == SOC_E_NONE || rv != SOC_E_UNAVAIL) { 6936 if (si->log_id != 0) { 6937 log_generic->corrected = (rv == SOC_E_NONE); 6938 if (si->ctype == SocSerCorrectTypeEntryClear) { 6939 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR; 6940 } else if (si->ctype == SocSerCorrectTypeCacheRestore) { 6941 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE; 6942 } 6943 log_generic->hw_cache = 6944 (si->ctype == socSerCorrectTypeHwCacheRestore) ? TRUE : FALSE; 6945 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6946 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6947 } 6948 return rv; 6949 } 6950 } 6951 if (soc_feature(unit, soc_feature_fp_meter_ser_verify) && 6952 (FP_METER_TABLEm == mem)) { 6953 int i=0; 6954 6955 /* Get data even on parity error */ 6956 if (SOC_E_NONE == soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN, 6957 mem, 0, copyno, index, entry)) { 6958 if (!check_parity(entry, entry_dw)) { 6959 if (si->log_id != 0) { 6960 log_generic->corrected = SOC_SER_UNKNOWN; 6961 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6962 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6963 } 6964 /* No error case. Print and return */ 6965 LOG_WARN(BSL_LS_SOC_SER, 6966 (BSL_META_U(unit, 6967 "NO PARITY ERROR: reg/mem:%d btype:%d sblk:%d at:%d " 6968 "stage:%d addr:0x%08x index: %d\n"), 6969 (si->flags & SOC_SER_SRC_MEM) ? si->mem : si->reg, 6970 si->blk_type, si->sblk, si->acc_type, 6971 si->stage, si->addr, si->index)); 6972 6973 for (i=0;i<entry_dw;i++) { 6974 LOG_WARN(BSL_LS_SOC_SER, 6975 (BSL_META_U(unit, 6976 "NO PARITY ERROR: Entry[%d]:%08X\n"), i, entry[i])); 6977 } 6978 return SOC_E_NONE; 6979 } 6980 } 6981 } else if (soc_feature(unit, soc_feature_ism_memory) && 6982 (mem == RAW_ENTRY_TABLEm)) { 6983 /* Packet lookup encountered an error - dump mems from cpu and do 6984 normal correction */ 6985 _soc_ser_ism_correction(unit); 6986 if (si->log_id != 0) { 6987 log_generic->corrected = SOC_SER_UNKNOWN; 6988 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 6989 sizeof(soc_ser_log_tlv_generic_t), log_generic); 6990 } 6991 return SOC_E_NONE; 6992 } 6993 6994 switch (SOC_MEM_SER_CORRECTION_TYPE(unit, mem)) { 6995 case SOC_MEM_FLAG_SER_ENTRY_CLEAR: 6996 return _soc_ser_mem_entry_clear(unit, mem, copyno,index, si, 6997 log_generic, stat); 6998 case SOC_MEM_FLAG_SER_ECC_CORRECTABLE: 6999 if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) == 7000 SOC_MEM_FLAG_SER_ECC_CORRECTABLE) { 7001 flags = SOC_MEM_FLAG_SER_ECC_CORRECTABLE; 7002 } 7003 stat->ser_err_ecc++; 7004 /* passthru */ 7005 /* coverity[fallthrough: FALSE] */ 7006 case SOC_MEM_FLAG_SER_CACHE_RESTORE: 7007 if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) == 7008 SOC_MEM_FLAG_SER_CACHE_RESTORE) { 7009 flags = SOC_MEM_FLAG_SER_CACHE_RESTORE; 7010 } 7011 /* passthru */ 7012 /* coverity[fallthrough: FALSE] */ 7013 case SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE: 7014 if (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) == 7015 SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE) { 7016 flags = SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE; 7017 } 7018 return _soc_ser_mem_entry_restore(unit, mem, copyno, index, si, 7019 log_generic, stat, flags, entry); 7020 case SOC_MEM_FLAG_SER_SPECIAL: 7021 return _soc_ser_mem_entry_special(unit, mem, copyno, index, si, 7022 log_generic, stat); 7023 default: 7024 if (si->log_id != 0) { 7025 log_generic->corrected = SOC_SER_UNCORRECTED; 7026 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7027 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7028 } 7029 stat->ser_err_sw++; 7030 return SOC_E_INTERNAL; 7031 } 7032 } 7033 7034 STATIC int 7035 _soc_ser_reg_correction(int unit, _soc_ser_correct_info_t *si, 7036 soc_ser_log_tlv_generic_t *log_generic, 7037 soc_stat_t *stat) 7038 { 7039 uint64 rval64; 7040 int rv, index = si->index; 7041 int copyno = 0; 7042 soc_reg_t reg = si->reg; 7043 soc_port_t port = si->port; 7044 soc_ser_log_tlv_register_t log_reg; 7045 7046 if (si->log_id != 0) { 7047 log_reg.index = index; 7048 } 7049 7050 stat->ser_err_reg++; 7051 if (!(si->flags & SOC_SER_REG_MEM_KNOWN)) { 7052 soc_regaddrinfo_t ainfo; 7053 7054 /* Decode register from address details */ 7055 soc_regaddrinfo_extended_get(unit, &ainfo, si->sblk, 7056 si->acc_type, si->addr); 7057 reg = ainfo.reg; 7058 port = ainfo.port; 7059 if (si->log_id != 0) { 7060 log_reg.port = port; 7061 log_reg.reg = reg; 7062 } 7063 if (reg == INVALIDr || port == -1) { 7064 if (si->log_id != 0) { 7065 log_generic->corrected = SOC_SER_UNCORRECTED; 7066 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7067 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7068 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER, 7069 sizeof(soc_ser_log_tlv_register_t), &log_reg); 7070 } 7071 if (soc_feature(unit, soc_feature_two_ingress_pipes) && 7072 soc_feature(unit, soc_feature_sbusdma)) { 7073 LOG_VERBOSE(BSL_LS_SOC_SER, 7074 (BSL_META_U(unit, 7075 "register not decoded [%d %d 0x%8x].\n"), 7076 si->sblk, si->acc_type, si->addr)); 7077 return SOC_E_NOT_FOUND; 7078 } else { 7079 LOG_ERROR(BSL_LS_SOC_SER, 7080 (BSL_META_U(unit, 7081 "register not decoded [%d %d 0x%8x].\n"), 7082 si->sblk, si->acc_type, si->addr)); 7083 stat->ser_err_sw++; 7084 return SOC_E_INTERNAL; 7085 } 7086 } 7087 index = ainfo.idx >= 0 ? ainfo.idx : 0; 7088 LOG_WARN(BSL_LS_SOC_SER, 7089 (BSL_META_U(unit, 7090 "reg: %d=%s port: %d index: %d\n"), 7091 reg, SOC_REG_NAME(unit, reg), ainfo.port, index)); 7092 } 7093 if (reg == INVALIDr || port == -1) { 7094 if (si->log_id != 0) { 7095 log_generic->corrected = SOC_SER_UNCORRECTED; 7096 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7097 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7098 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER, 7099 sizeof(soc_ser_log_tlv_register_t), &log_reg); 7100 } 7101 return SOC_E_PARAM; 7102 } 7103 if (si->blk_type >= 0) { 7104 SOC_BLOCK_ITER(unit, copyno, si->blk_type) { 7105 if (SOC_BLOCK_TYPE(unit, copyno) == si->blk_type) { 7106 break; 7107 } 7108 } 7109 } 7110 if (!SOC_REG_IS_VALID(unit, reg)) { 7111 return SOC_E_INTERNAL; 7112 } 7113 if (SOC_REG_IS_COUNTER(unit, reg)) { 7114 if (si->flags & SOC_SER_REG_READ_AGAIN) { 7115 if (SOC_REG_IS_VALID(unit, ICTRL_64r)) { 7116 (void)soc_reg_get(unit, ICTRL_64r, port, index, &rval64); 7117 } 7118 } 7119 if (SOC_SER_COUNTER_CORRECTION(unit) == 0) { 7120 COMPILER_64_ZERO(rval64); 7121 /* Clear counter in h/w and s/w */ 7122 rv = soc_counter_set(unit, port, reg, index, rval64); 7123 7124 if (si->log_id != 0) { 7125 log_generic->corrected = (rv == SOC_E_NONE); 7126 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR; 7127 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7128 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7129 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER, 7130 sizeof(soc_ser_log_tlv_register_t), &log_reg); 7131 } 7132 7133 SOC_IF_ERROR_RETURN(rv); 7134 LOG_WARN(BSL_LS_SOC_SER, 7135 (BSL_META_U(unit, 7136 "COUNTER_CLEAR: %s[%d] blk: %s index: %d : port[%d]\n"), 7137 SOC_REG_NAME(unit, reg), reg, 7138 SOC_BLOCK_NAME(unit, copyno), 7139 index, port)); 7140 stat->ser_err_clear++; 7141 soc_ser_stat_update(unit, 0, si->blk_type, 7142 si->parity_type, si->double_bit, 7143 SocSerCorrectTypeEntryClear, 7144 stat); 7145 } else { 7146 /* Restore last s/w counter value in h/w */ 7147 rv = soc_counter_get(unit, port, reg, index, &rval64); 7148 7149 if (si->log_id != 0) { 7150 log_generic->corrected = (rv == SOC_E_NONE); 7151 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE; 7152 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7153 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7154 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER, 7155 sizeof(soc_ser_log_tlv_register_t), &log_reg); 7156 } 7157 7158 SOC_IF_ERROR_RETURN(rv); 7159 SOC_IF_ERROR_RETURN(soc_counter_set(unit, port, reg, index, rval64)); 7160 LOG_WARN(BSL_LS_SOC_SER, 7161 (BSL_META_U(unit, 7162 "COUNTER_RESTORE: %s[%d] blk: %s index: %d : port[%d]\n"), 7163 SOC_REG_NAME(unit, reg), reg, 7164 SOC_BLOCK_NAME(unit, copyno), 7165 index, port)); 7166 stat->ser_err_restor++; 7167 soc_ser_stat_update(unit, 0, si->blk_type, 7168 si->parity_type, si->double_bit, 7169 SocSerCorrectTypeCacheRestore, 7170 stat); 7171 } 7172 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, si, 7173 reg | SOC_SER_ERROR_DATA_REG_ID_OFFSET_SET, 7174 port << SOC_SER_ERROR_PIPE_BP | index); 7175 } else { 7176 COMPILER_64_ZERO(rval64); 7177 rv = soc_ser_reg_cache_get(unit, reg, port, index, &rval64); 7178 if (rv == SOC_E_UNAVAIL) { 7179 rv = soc_ser_reg_clear(unit, reg, port, index, rval64); 7180 if (si->log_id != 0) { 7181 log_generic->corrected = (rv == SOC_E_NONE); 7182 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_ENTRY_CLEAR; 7183 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7184 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7185 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER, 7186 sizeof(soc_ser_log_tlv_register_t), &log_reg); 7187 } 7188 7189 SOC_IF_ERROR_RETURN(rv); 7190 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, si, 7191 reg | SOC_SER_ERROR_DATA_REG_ID_OFFSET_SET, 7192 port << SOC_SER_ERROR_PIPE_BP | index); 7193 LOG_WARN(BSL_LS_SOC_SER, 7194 (BSL_META_U(unit, 7195 "REG_CLEAR: %s[%d] blk: %s index: %d : port[%d]\n"), 7196 SOC_REG_NAME(unit, reg), reg, 7197 SOC_BLOCK_NAME(unit, copyno), 7198 index, port)); 7199 stat->ser_err_clear++; 7200 soc_ser_stat_update(unit, 0, si->blk_type, 7201 si->parity_type, si->double_bit, 7202 SocSerCorrectTypeEntryClear, 7203 stat); 7204 } else { 7205 rv = soc_reg_set_nocache(unit, reg, port, index, rval64); 7206 if (si->log_id != 0) { 7207 log_generic->corrected = (rv == SOC_E_NONE); 7208 log_generic->ser_response_flag = SOC_MEM_FLAG_SER_CACHE_RESTORE; 7209 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_GENERIC, 7210 sizeof(soc_ser_log_tlv_generic_t), log_generic); 7211 soc_ser_log_add_tlv(unit, si->log_id, SOC_SER_LOG_TLV_REGISTER, 7212 sizeof(soc_ser_log_tlv_register_t), &log_reg); 7213 } 7214 7215 SOC_IF_ERROR_RETURN(rv); 7216 _soc_ser_correction_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, si, 7217 reg | SOC_SER_ERROR_DATA_REG_ID_OFFSET_SET, 7218 port << SOC_SER_ERROR_PIPE_BP | index); 7219 LOG_WARN(BSL_LS_SOC_SER, 7220 (BSL_META_U(unit, 7221 "REG_RESTORE: %s[%d] blk: %s index: %d : port[%d]\n"), 7222 SOC_REG_NAME(unit, reg), reg, 7223 SOC_BLOCK_NAME(unit, copyno), 7224 index, port)); 7225 stat->ser_err_restor++; 7226 soc_ser_stat_update(unit, 0, si->blk_type, 7227 si->parity_type, si->double_bit, 7228 SocSerCorrectTypeCacheRestore, 7229 stat); 7230 } 7231 } 7232 7233 return SOC_E_NONE; 7234 } 7235 7236 /* Top level SER correction routine */ 7237 int 7238 soc_ser_correction(int unit, _soc_ser_correct_info_t *si) 7239 { 7240 soc_stat_t *stat = SOC_STAT(unit); 7241 soc_ser_log_tlv_generic_t log_generic; 7242 7243 if (!SOC_SER_CORRECTION_SUPPORT(unit)) { 7244 return SOC_E_NONE; 7245 } 7246 if (SOC_HW_ACCESS_DISABLE(unit)) { 7247 LOG_WARN(BSL_LS_SOC_SER, 7248 (BSL_META_U(unit, 7249 "SER_CORRECTION: reg/mem:%d hardware access disable\n"), 7250 (si->flags & SOC_SER_SRC_MEM) ? si->mem : si->reg)); 7251 return SOC_E_NONE; 7252 } 7253 7254 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 7255 7256 if (si->log_id != 0) { 7257 log_generic.flags = 0; 7258 if (si->flags & SOC_SER_ERR_CPU) { 7259 log_generic.flags |= SOC_SER_LOG_FLAG_ERR_SRC; 7260 } 7261 if (si->flags & SOC_SER_ERR_MULTI) { 7262 log_generic.flags |= SOC_SER_LOG_FLAG_MULTIBIT; 7263 } 7264 if (si->double_bit != 0) { 7265 log_generic.flags |= SOC_SER_LOG_FLAG_DOUBLEBIT; 7266 } 7267 log_generic.time = si->detect_time; 7268 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 7269 log_generic.address = si->addr; 7270 log_generic.acc_type = si->acc_type; 7271 log_generic.block_type = si->blk_type; 7272 log_generic.parity_type = si->parity_type; 7273 log_generic.ser_response_flag = 0; 7274 log_generic.corrected = SOC_SER_UNCORRECTED; 7275 log_generic.pipe_num = si->pipe_num; 7276 log_generic.inst = si->inst; 7277 } 7278 7279 LOG_WARN(BSL_LS_SOC_SER, 7280 (BSL_META_U(unit, 7281 "SER_CORRECTION: reg/mem:%d btype:%d sblk:%d at:%d " 7282 "stage:%d addr:0x%08x port: %d index: %d\n"), 7283 (si->flags & SOC_SER_SRC_MEM) ? si->mem : si->reg, si->blk_type, 7284 si->sblk, si->acc_type, si->stage, si->addr, si->port, si->index)); 7285 7286 if (si->flags & SOC_SER_SRC_MEM) { 7287 /* Handle mems */ 7288 return _soc_ser_mem_correction(unit, si, &log_generic, stat); 7289 } else { 7290 /* Handle regs */ 7291 return _soc_ser_reg_correction(unit, si, &log_generic, stat); 7292 } 7293 } 7294 7295 static int 7296 _soc_ser_mem_info_init(int unit) 7297 { 7298 uint32 size_ser_info = sizeof(mem_ser_info_t), i = 0; 7299 7300 SER_MEM_INFO_BASE_ADDR(unit) = 7301 (mem_ser_info_t *)sal_alloc(size_ser_info * SER_MEM_INFO_MAX_NUM, 7302 "mem_ser_info"); 7303 if (SER_MEM_INFO_BASE_ADDR(unit) == NULL) { 7304 LOG_WARN(BSL_LS_SOC_SER, 7305 (BSL_META_U(unit, 7306 "ERR: allocate memory space fail\n"))); 7307 return SOC_E_MEMORY; 7308 } 7309 sal_memset(SER_MEM_INFO_BASE_ADDR(unit), 0, size_ser_info * SER_MEM_INFO_MAX_NUM); 7310 7311 for (i = 0; i < SER_MEM_INFO_MAX_NUM - 1; i++) { 7312 SER_MEM_INFO_NEXT_IDX(unit, i) = i + 1; 7313 } 7314 SER_MEM_INFO_NEXT_IDX(unit, i) = 0; 7315 SER_MEM_INFO_HEAD_IDX(unit) = 0; 7316 SER_MEM_INFO_TAIL_IDX(unit) = 0; 7317 return SOC_E_NONE; 7318 } 7319 7320 void 7321 soc_ser_mem_info_dump(int unit) 7322 { 7323 int counter; 7324 uint32 tail_idx, cur_idx; 7325 mem_ser_info_t *ser_info_p = NULL; 7326 7327 if(!bsl_check(bslLayerSoc, bslSourceSer, bslSeverityNormal, unit)) { 7328 return; 7329 } 7330 counter = SER_MEM_INFO_COUNTER(unit); 7331 cur_idx = SER_MEM_INFO_HEAD_IDX(unit); 7332 tail_idx = SER_MEM_INFO_TAIL_IDX(unit); 7333 7334 LOG_DEBUG(BSL_LS_SOC_SER, 7335 (BSL_META_U(unit, 7336 "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"), 7337 tail_idx, cur_idx, 7338 SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit))); 7339 7340 while (cur_idx != tail_idx || counter) { 7341 ser_info_p = SER_MEM_INFO_BASE_ADDR(unit) + cur_idx; 7342 LOG_DEBUG(BSL_LS_SOC_SER, 7343 (BSL_META_U(unit, 7344 "[mem=%s][idx=%d] at ser_mem_info[%d]\n"), 7345 SOC_MEM_NAME(unit, ser_info_p->ser_mem), ser_info_p->hw_idx, cur_idx)); 7346 cur_idx = SER_MEM_INFO_NEXT_IDX(unit, cur_idx); 7347 counter--; 7348 } 7349 assert(counter == 0); 7350 } 7351 7352 STATIC void 7353 _soc_ser_mem_info_insert(int unit, soc_mem_t rst_mem, uint32 hw_idx, 7354 uint32 *entry_data) 7355 { 7356 mem_ser_info_t *mem_ser_info_addr = NULL; 7357 uint32 entry_bsize = soc_mem_entry_bytes(unit, rst_mem); 7358 uint32 tail_idx = SER_MEM_INFO_TAIL_IDX(unit); 7359 uint32 old_hw_idx = 0; 7360 soc_mem_t old_rst_mem; 7361 7362 mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit) + tail_idx; 7363 7364 soc_ser_mem_info_dump(unit); 7365 7366 old_hw_idx = mem_ser_info_addr->hw_idx; 7367 old_rst_mem = mem_ser_info_addr->ser_mem; 7368 mem_ser_info_addr->ser_mem = rst_mem; 7369 mem_ser_info_addr->hw_idx = hw_idx; 7370 sal_memset(mem_ser_info_addr->entry_data, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 7371 sal_memcpy(mem_ser_info_addr->entry_data, entry_data, entry_bsize); 7372 7373 if (SER_MEM_INFO_COUNTER(unit) < SER_MEM_INFO_MAX_NUM) { 7374 SER_MEM_INFO_COUNTER(unit)++; 7375 LOG_INFO(BSL_LS_SOC_SER, 7376 (BSL_META_U(unit, 7377 "store [mem=%s] [idx=%d] at ser_mem_info[%d]\n"), 7378 SOC_MEM_NAME(unit, rst_mem), hw_idx, tail_idx)); 7379 } else { 7380 /* overlay */ 7381 assert(SER_MEM_INFO_TAIL_IDX(unit) == SER_MEM_INFO_HEAD_IDX(unit)); 7382 LOG_INFO(BSL_LS_SOC_SER, 7383 (BSL_META_U(unit, 7384 "overlay [mem=%s][idx=%d] to [mem=%s][idx=%d] at ser_mem_info[%d]\n"), 7385 SOC_MEM_NAME(unit, rst_mem), hw_idx, 7386 SOC_MEM_NAME(unit, old_rst_mem), old_hw_idx, tail_idx)); 7387 SER_MEM_INFO_HEAD_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, SER_MEM_INFO_HEAD_IDX(unit)); 7388 } 7389 SER_MEM_INFO_TAIL_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, tail_idx); 7390 7391 LOG_VERBOSE(BSL_LS_SOC_SER, 7392 (BSL_META_U(unit, 7393 "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"), 7394 SER_MEM_INFO_TAIL_IDX(unit), SER_MEM_INFO_HEAD_IDX(unit), 7395 SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit))); 7396 } 7397 STATIC void 7398 _soc_ser_mem_info_delete(int unit, uint32 cur_idx, uint32 pre_idx) 7399 { 7400 mem_ser_info_t *mem_ser_info_addr = NULL; 7401 uint32 tail_idx, pre_head_idx; 7402 soc_mem_t rst_mem; 7403 uint32 hw_idx; 7404 int counter; 7405 if (SER_MEM_INFO_COUNTER(unit) <= 0) { 7406 LOG_WARN(BSL_LS_SOC_SER, 7407 (BSL_META_U(unit, 7408 "There is fatal error!!!\n"))); 7409 LOG_WARN(BSL_LS_SOC_SER, 7410 (BSL_META_U(unit, 7411 "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"), 7412 SER_MEM_INFO_TAIL_IDX(unit), SER_MEM_INFO_HEAD_IDX(unit), 7413 SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit))); 7414 return; 7415 } 7416 7417 soc_ser_mem_info_dump(unit); 7418 7419 mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit) + cur_idx; 7420 rst_mem = mem_ser_info_addr->ser_mem; 7421 hw_idx = mem_ser_info_addr->hw_idx; 7422 mem_ser_info_addr->ser_mem = 0; 7423 mem_ser_info_addr->hw_idx = 0; 7424 sal_memset(mem_ser_info_addr->entry_data, 0, SOC_MAX_MEM_WORDS * sizeof(uint32)); 7425 7426 tail_idx = SER_MEM_INFO_TAIL_IDX(unit); 7427 /* full */ 7428 if (SER_MEM_INFO_COUNTER(unit) == SER_MEM_INFO_MAX_NUM) { 7429 assert(SER_MEM_INFO_TAIL_IDX(unit) == SER_MEM_INFO_HEAD_IDX(unit)); 7430 7431 if (cur_idx == tail_idx) { 7432 SER_MEM_INFO_HEAD_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx); 7433 } else if (SER_MEM_INFO_NEXT_IDX(unit, cur_idx) == tail_idx) { 7434 SER_MEM_INFO_TAIL_IDX(unit) = cur_idx; 7435 } else { 7436 /* find previous index of head index */ 7437 pre_head_idx = tail_idx; /* tail index is equal to head index */ 7438 counter = SER_MEM_INFO_COUNTER(unit); 7439 while (SER_MEM_INFO_NEXT_IDX(unit, pre_head_idx) != tail_idx) { 7440 counter--; 7441 pre_head_idx = SER_MEM_INFO_NEXT_IDX(unit, pre_head_idx); 7442 } 7443 assert(counter == 1); 7444 7445 SER_MEM_INFO_TAIL_IDX(unit) = cur_idx; 7446 SER_MEM_INFO_NEXT_IDX(unit, pre_idx) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx); 7447 SER_MEM_INFO_NEXT_IDX(unit, pre_head_idx) = cur_idx; 7448 SER_MEM_INFO_NEXT_IDX(unit, cur_idx) = tail_idx; 7449 } 7450 } else { 7451 if (SER_MEM_INFO_NEXT_IDX(unit, cur_idx) == SER_MEM_INFO_TAIL_IDX(unit)) { 7452 SER_MEM_INFO_TAIL_IDX(unit) = cur_idx; 7453 } else if (cur_idx == SER_MEM_INFO_HEAD_IDX(unit)) { 7454 SER_MEM_INFO_HEAD_IDX(unit) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx); 7455 } else { 7456 /* pre_idx is equal to cur_idx only when cur_idx == SER_MEM_INFO_HEAD_IDX(unit) */ 7457 assert(pre_idx != cur_idx); 7458 SER_MEM_INFO_NEXT_IDX(unit, pre_idx) = SER_MEM_INFO_NEXT_IDX(unit, cur_idx); 7459 SER_MEM_INFO_NEXT_IDX(unit, cur_idx) = SER_MEM_INFO_NEXT_IDX(unit, tail_idx); 7460 SER_MEM_INFO_NEXT_IDX(unit, tail_idx) = cur_idx; 7461 } 7462 } 7463 SER_MEM_INFO_COUNTER(unit)--; 7464 LOG_INFO(BSL_LS_SOC_SER, 7465 (BSL_META_U(unit, 7466 "delete [mem=%s][idx=%d] at ser_mem_info[%d]\n"), 7467 SOC_MEM_NAME(unit, rst_mem), hw_idx, cur_idx)); 7468 LOG_VERBOSE(BSL_LS_SOC_SER, 7469 (BSL_META_U(unit, 7470 "tail-idx=[%d], head-idx=[%d], maximum=[%d], used-num=[%d]\n"), 7471 SER_MEM_INFO_TAIL_IDX(unit), SER_MEM_INFO_HEAD_IDX(unit), 7472 SER_MEM_INFO_MAX_NUM, SER_MEM_INFO_COUNTER(unit))); 7473 } 7474 7475 int 7476 soc_ser_counter_info_set(int unit, soc_mem_t rst_mem, 7477 uint32 hw_idx, uint32 *entry_data) 7478 { 7479 mem_ser_info_t *mem_ser_info_addr = NULL; 7480 soc_mem_t mem_ser_list[] = {EFP_COUNTER_TABLE_Xm, 7481 EFP_COUNTER_TABLE_Ym, 7482 EFP_COUNTER_TABLEm, 7483 FP_COUNTER_TABLE_Xm, 7484 FP_COUNTER_TABLE_Ym, 7485 FP_COUNTER_TABLEm}; 7486 uint32 i, mem_num = sizeof(mem_ser_list)/sizeof(mem_ser_list[0]); 7487 int rv = SOC_E_NONE; 7488 uint32 idx, pre_idx; 7489 7490 for (i = 0; i < mem_num; i++) { 7491 if (mem_ser_list[i] == rst_mem) { 7492 break; 7493 } 7494 } 7495 if (i >= mem_num) { 7496 return SOC_E_UNAVAIL; 7497 } 7498 7499 if (entry_data == NULL) { 7500 LOG_WARN(BSL_LS_SOC_SER, 7501 (BSL_META_U(unit, 7502 "pointer entry_data is NULL\n"))); 7503 return SOC_E_PARAM; 7504 } 7505 7506 if (soc_mem_index_count(unit, rst_mem) <= hw_idx) { 7507 LOG_WARN(BSL_LS_SOC_SER, 7508 (BSL_META_U(unit, 7509 "store mem %s, max index=%d, wrong index=%d\n"), 7510 SOC_MEM_NAME(unit, rst_mem), soc_mem_index_count(unit, rst_mem), hw_idx)); 7511 return SOC_E_INTERNAL; 7512 } 7513 7514 SOC_MEM_SER_INFO_LOCK(unit); 7515 7516 if (SER_MEM_INFO_BASE_ADDR(unit) == NULL) { 7517 rv = _soc_ser_mem_info_init(unit); 7518 if (rv != SOC_E_NONE) { 7519 SOC_MEM_SER_INFO_UNLOCK(unit); 7520 return rv; 7521 } 7522 } 7523 idx = SER_MEM_INFO_HEAD_IDX(unit); 7524 pre_idx = idx; 7525 7526 for (i = 0; i < SER_MEM_INFO_COUNTER(unit); i++) { 7527 mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit); 7528 mem_ser_info_addr += idx; 7529 if (mem_ser_info_addr->ser_mem == rst_mem && 7530 mem_ser_info_addr->hw_idx == hw_idx) { 7531 break; 7532 } 7533 pre_idx = idx; 7534 idx = SER_MEM_INFO_NEXT_IDX(unit, idx); 7535 } 7536 if (i < SER_MEM_INFO_COUNTER(unit)) { /* found */ 7537 /* delete old info */ 7538 _soc_ser_mem_info_delete(unit, idx, pre_idx); 7539 /* insert new info at tail */ 7540 _soc_ser_mem_info_insert(unit, rst_mem, hw_idx, entry_data); 7541 } else { 7542 /* not found */ 7543 assert(idx == SER_MEM_INFO_TAIL_IDX(unit)); 7544 /* insert new info at tail */ 7545 _soc_ser_mem_info_insert(unit, rst_mem, hw_idx, entry_data); 7546 } 7547 SOC_MEM_SER_INFO_UNLOCK(unit); 7548 return SOC_E_NONE; 7549 } 7550 7551 int 7552 soc_ser_counter_info_get(int unit, soc_mem_t rst_mem, 7553 int hw_idx, uint32 *entry_data) 7554 { 7555 mem_ser_info_t *mem_ser_info_addr = NULL; 7556 uint32 entry_bsize = soc_mem_entry_bytes(unit, rst_mem); 7557 soc_mem_t mem_ser_list[] = {EFP_COUNTER_TABLE_Xm, 7558 EFP_COUNTER_TABLE_Ym, 7559 EFP_COUNTER_TABLEm, 7560 FP_COUNTER_TABLE_Xm, 7561 FP_COUNTER_TABLE_Ym, 7562 FP_COUNTER_TABLEm}; 7563 int i = 0, mem_num = sizeof(mem_ser_list)/sizeof(mem_ser_list[0]); 7564 uint32 idx, pre_idx; 7565 7566 for (i = 0; i < mem_num; i++) { 7567 if (mem_ser_list[i] == rst_mem) { 7568 break; 7569 } 7570 } 7571 if (i >= mem_num) { 7572 return SOC_E_NONE; 7573 } 7574 if (entry_data == NULL) { 7575 LOG_WARN(BSL_LS_SOC_SER, 7576 (BSL_META_U(unit, 7577 "pointer entry_data is NULL\n"))); 7578 return SOC_E_PARAM; 7579 } 7580 if (soc_mem_index_count(unit, rst_mem) <= hw_idx) { 7581 LOG_WARN(BSL_LS_SOC_SER, 7582 (BSL_META_U(unit, 7583 "restore mem %s, max index=%d, wrong index=%d\n"), 7584 SOC_MEM_NAME(unit, rst_mem), soc_mem_index_count(unit, rst_mem), hw_idx)); 7585 return SOC_E_INTERNAL; 7586 } 7587 7588 SOC_MEM_SER_INFO_LOCK(unit); 7589 7590 if (SER_MEM_INFO_BASE_ADDR(unit) == NULL) { 7591 LOG_VERBOSE(BSL_LS_SOC_SER, 7592 (BSL_META_U(unit, 7593 "ser mem info is not initialized\n"))); 7594 SOC_MEM_SER_INFO_UNLOCK(unit); 7595 return SOC_E_NOT_FOUND; 7596 } 7597 7598 idx = SER_MEM_INFO_HEAD_IDX(unit); 7599 pre_idx = idx; 7600 7601 for (i = 0; i < SER_MEM_INFO_COUNTER(unit); i++) { 7602 mem_ser_info_addr = SER_MEM_INFO_BASE_ADDR(unit); 7603 mem_ser_info_addr += idx; 7604 if (mem_ser_info_addr->ser_mem == rst_mem && 7605 mem_ser_info_addr->hw_idx == hw_idx) { 7606 break; 7607 } 7608 pre_idx = idx; 7609 idx = SER_MEM_INFO_NEXT_IDX(unit, idx); 7610 } 7611 7612 /* found */ 7613 if (i < SER_MEM_INFO_COUNTER(unit)) { 7614 sal_memcpy(entry_data, mem_ser_info_addr->entry_data, entry_bsize); 7615 _soc_ser_mem_info_delete(unit, idx, pre_idx); 7616 SOC_MEM_SER_INFO_UNLOCK(unit); 7617 return SOC_E_NONE; 7618 } else { 7619 assert(idx == SER_MEM_INFO_TAIL_IDX(unit)); 7620 LOG_WARN(BSL_LS_SOC_SER, 7621 (BSL_META_U(unit, 7622 "not found mem %s, hw idx=%d\n"), 7623 SOC_MEM_NAME(unit, rst_mem), hw_idx)); 7624 7625 SOC_MEM_SER_INFO_UNLOCK(unit); 7626 return SOC_E_NOT_FOUND; 7627 } 7628 } 7629 7630 void soc_ser_alpm_cache_check(int unit) 7631 { 7632 if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) { 7633 alpm_no_cache_flag[unit].flag_defip = soc_property_get(unit, "mem_nocache_L3_DEFIP", 1); 7634 alpm_no_cache_flag[unit].flag_defip_128 = soc_property_get(unit, "mem_nocache_L3_DEFIP_PAIR_128", 1); 7635 alpm_no_cache_flag[unit].flag_defip_alpm_v4 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV4", 1); 7636 alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV4_1", 1); 7637 alpm_no_cache_flag[unit].flag_defip_alpm_v6 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV6_64", 1); 7638 alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV6_64_1", 1); 7639 alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 = soc_property_get(unit, "mem_nocache_L3_DEFIP_ALPM_IPV6_128", 1); 7640 alpm_no_cache_flag[unit].flag_defip_aux = soc_property_get(unit, "mem_nocache_L3_DEFIP_AUX_TABLE", 1); 7641 } else { 7642 alpm_no_cache_flag[unit].flag_defip = 1; 7643 alpm_no_cache_flag[unit].flag_defip_128 = 1; 7644 alpm_no_cache_flag[unit].flag_defip_alpm_v4 = 1; 7645 alpm_no_cache_flag[unit].flag_defip_alpm_v4_1 = 1; 7646 alpm_no_cache_flag[unit].flag_defip_alpm_v6 = 1; 7647 alpm_no_cache_flag[unit].flag_defip_alpm_v6_1 = 1; 7648 alpm_no_cache_flag[unit].flag_defip_alpm_v6_128 = 1; 7649 alpm_no_cache_flag[unit].flag_defip_aux = 1; 7650 } 7651 } 7652 7653 #endif /* BCM_XGS_SUPPORT */