enduro.c (141880B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: enduro.c 8 * Purpose: 9 * Requires: 10 */ 11 12 13 #include <sal/core/boot.h> 14 #include <shared/bsl.h> 15 #include <soc/firebolt.h> 16 #include <soc/bradley.h> 17 #include <soc/enduro.h> 18 #include <soc/drv.h> 19 #include <soc/mem.h> 20 #include <soc/hash.h> 21 #include <soc/lpm.h> 22 #include <soc/error.h> 23 #include <soc/debug.h> 24 #include <soc/er_tcam.h> 25 #include <soc/memtune.h> 26 #include <soc/devids.h> 27 #include <soc/soc_ser_log.h> 28 29 #ifdef BCM_ENDURO_SUPPORT 30 31 /* 32 * Enduro chip driver functions. 33 */ 34 soc_functions_t soc_enduro_drv_funs = { 35 soc_enduro_misc_init, 36 soc_enduro_mmu_init, 37 soc_enduro_age_timer_get, 38 soc_enduro_age_timer_max_get, 39 soc_enduro_age_timer_set, 40 }; 41 42 typedef enum { 43 _SOC_PARITY_INFO_TYPE_GENERIC, 44 _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 45 _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 46 _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER, 47 _SOC_PARITY_INFO_TYPE_DUAL_PARITY, 48 _SOC_PARITY_INFO_TYPE_MMU_PARITY, 49 _SOC_PARITY_INFO_TYPE_MMUIPMC, 50 _SOC_PARITY_INFO_TYPE_MMUWRED, 51 _SOC_PARITY_INFO_TYPE_MMUMTRO, 52 _SOC_PARITY_INFO_TYPE_MMUE2EFC, 53 _SOC_PARITY_INFO_TYPE_OAM, /* Not parity, but same interrupt */ 54 _SOC_PARITY_INFO_TYPE_SER, /* Parity error from CMIC SER module */ 55 _SOC_PARITY_INFO_TYPE_NUM 56 } _soc_parity_info_type_t; 57 58 typedef struct _soc_parity_info_s { 59 soc_field_t enable_field; 60 soc_field_t error_field; 61 char *msg; 62 soc_mem_t mem; 63 _soc_parity_info_type_t type; 64 soc_reg_t control_reg; 65 soc_reg_t intr_status0_reg; 66 soc_reg_t intr_status1_reg; /* Also SBE force for ECC */ 67 soc_reg_t nack_status0_reg; 68 soc_reg_t nack_status1_reg; /* Also DBE force for ECC */ 69 } _soc_parity_info_t; 70 71 #if defined(SER_TR_TEST_SUPPORT) 72 soc_ser_test_functions_t ser_enduro_test_fun; 73 #endif 74 75 /* 76 * _SOC_PARITY_INFO_TYPE_SINGLE_PARITY 77 * PARITY_EN 78 * ENTRY_IDX, MULTIPLE_ERR, PARITY_ERR 79 * 80 * _SOC_PARITY_INFO_TYPE_SINGLE_ECC 81 * ECC_EN 82 * ENTRY_IDX, DOUBLE_BIT_ERR, MULTIPLE_ERR, ECC_ERR 83 * 84 * _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER 85 * PARITY_EN 86 * PORT_IDX, COUNTER_IDX, MULTIPLE_ERR, PARITY_ERR 87 * 88 * _SOC_PARITY_INFO_TYPE_DUAL_PARITY 89 * PARITY_EN 90 * BUCKET_IDX, MULTIPLE_ERR, PARITY_ERR_BM 91 */ 92 93 static _soc_parity_info_t _soc_en_ip0_parity_info[] = { 94 { PARITY_ENf, VXLT_PAR_ERRf, NULL, 95 VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY, 96 VLAN_XLATE_PARITY_CONTROLr, 97 VLAN_XLATE_PARITY_STATUS_0r, VLAN_XLATE_PARITY_STATUS_1r, 98 INVALIDr, INVALIDr }, 99 /* { PPA_CMD_COMPLETEf }, */ 100 /* { MEM_RESET_COMPLETEf }, */ 101 /* { AGE_CMD_COMPLETEf }, */ 102 { PARITY_ENf, VLAN_SUBNET_DATA_PARITY_ERRf, NULL, 103 VLAN_SUBNET_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 104 VLAN_SUBNET_DATA_PARITY_CONTROLr, 105 VLAN_SUBNET_DATA_PARITY_STATUSr, INVALIDr, 106 INVALIDr, INVALIDr }, 107 { PARITY_ENf, VLAN_PROTOCOL_DATA_PARITY_ERRf, NULL, 108 VLAN_PROTOCOL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 109 VLAN_PROTOCOL_DATA_PARITY_CONTROLr, 110 VLAN_PROTOCOL_DATA_PARITY_STATUSr, INVALIDr, 111 INVALIDr, INVALIDr }, 112 { PARITY_ENf, VLAN_PARITY_ERRf, NULL, 113 VLAN_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 114 VLAN_PARITY_CONTROLr, 115 VLAN_PARITY_STATUSr, INVALIDr, 116 INVALIDr, INVALIDr }, 117 { PARITY_ENf, VLAN_STG_PARITY_ERRf, NULL, 118 STG_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 119 VLAN_STG_PARITY_CONTROLr, 120 VLAN_STG_PARITY_STATUSr, INVALIDr, 121 INVALIDr, INVALIDr }, 122 { PARITY_ENf, L3_TUNNEL_RAM_PARITY_ERRf, NULL, 123 L3_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 124 L3_TUNNEL_DATA_ONLY_PARITY_CONTROLr, 125 L3_TUNNEL_DATA_ONLY_PARITY_STATUSr, INVALIDr, 126 INVALIDr, INVALIDr }, 127 { PARITY_ENf, SOURCE_TRUNK_MAP_PARITY_ERRf, NULL, 128 SOURCE_TRUNK_MAP_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 129 SOURCE_TRUNK_MAP_PARITY_CONTROLr, 130 SOURCE_TRUNK_MAP_PARITY_STATUSr, INVALIDr, 131 INVALIDr, INVALIDr }, 132 { PARITY_ENf, VFP_POLICY_PAR_ERRf, NULL, 133 VFP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 134 VFP_POLICY_PARITY_CONTROLr, 135 VFP_POLICY_PARITY_STATUS_INTRr, INVALIDr, 136 INVALIDr, INVALIDr }, 137 { PARITY_ENf, LMEP_PAR_ERRf, NULL, 138 LMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 139 LMEP_PARITY_CONTROLr, 140 LMEP_PARITY_STATUSr, INVALIDr, 141 INVALIDr, INVALIDr }, 142 { ECC_ENf, IARB_PKT_ECC_INTRf, "Iarb packet ecc error", 143 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 144 IARB_PKT_ECC_CONTROLr, 145 IARB_PKT_ECC_STATUS_INTRr, INVALIDr, 146 INVALIDr, INVALIDr }, 147 { ECC_ENf, IARB_HDR_ECC_INTRf, "Iarb header ecc error", 148 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 149 IARB_HDR_ECC_CONTROLr, 150 IARB_HDR_ECC_STATUS_INTRr, INVALIDr, 151 INVALIDr, INVALIDr }, 152 { INVALIDf, INVALIDf }, /* table terminator */ 153 }; 154 155 static _soc_parity_info_t _soc_en_ip1_parity_info[] = { 156 { PARITY_ENf, VFI_PAR_ERRf, NULL, 157 VFIm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 158 VFI_PARITY_CONTROLr, 159 VFI_PARITY_STATUS_INTRr, INVALIDr, 160 VFI_PARITY_STATUS_NACKr, INVALIDr }, 161 { PARITY_ENf, SVP_PAR_ERRf, NULL, 162 SOURCE_VPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 163 SOURCE_VP_PARITY_CONTROLr, 164 SOURCE_VP_PARITY_STATUS_INTRr, INVALIDr, 165 SOURCE_VP_PARITY_STATUS_NACKr, INVALIDr }, 166 { PARITY_ENf, L3_IIF_PAR_ERRf, NULL, 167 L3_IIFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 168 L3_IIF_PARITY_CONTROLr, 169 L3_IIF_PARITY_STATUS_INTRr, INVALIDr, 170 L3_IIF_PARITY_STATUS_NACKr, INVALIDr }, 171 { PARITY_ENf, MPLS_ENTRY_PAR_ERRf, NULL, 172 MPLS_ENTRYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY, 173 MPLS_ENTRY_PARITY_CONTROLr, 174 MPLS_ENTRY_PARITY_STATUS_INTR_0r, MPLS_ENTRY_PARITY_STATUS_INTR_1r, 175 MPLS_ENTRY_PARITY_STATUS_NACK_0r, MPLS_ENTRY_PARITY_STATUS_NACK_1r }, 176 { PARITY_ENf, L2_ENTRY_PAR_ERRf, NULL, 177 L2Xm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY, 178 L2_ENTRY_PARITY_CONTROLr, 179 L2_ENTRY_PARITY_STATUS_0r, L2_ENTRY_PARITY_STATUS_1r, 180 INVALIDr, INVALIDr }, 181 { PARITY_ENf, L2MC_PAR_ERRf, NULL, 182 L2MCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 183 L2MC_PARITY_CONTROLr, 184 L2MC_PARITY_STATUSr, INVALIDr, 185 INVALIDr, INVALIDr }, 186 { PARITY_ENf, L3_ENTRY_PAR_ERRf, NULL, 187 L3_ENTRY_ONLYm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY, 188 L3_ENTRY_PARITY_CONTROLr, 189 L3_ENTRY_PARITY_STATUS_0r, L3_ENTRY_PARITY_STATUS_1r, 190 INVALIDr, INVALIDr }, 191 { PARITY_ENf, L3_DEFIP_DATA_PAR_ERRf, NULL, 192 L3_DEFIP_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 193 L3_DEFIP_PARITY_CONTROLr, 194 L3_DEFIP_PARITY_STATUSr, INVALIDr, 195 INVALIDr, INVALIDr }, 196 { PARITY_ENf, L3MC_PAR_ERRf, NULL, 197 L3_IPMCm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 198 L3MC_PARITY_CONTROLr, 199 L3MC_PARITY_STATUSr, INVALIDr, 200 INVALIDr, INVALIDr }, 201 { PARITY_ENf, MA_STATE_PAR_ERRf, NULL, 202 MA_STATEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 203 MA_STATE_PARITY_CONTROLr, 204 MA_STATE_PARITY_STATUSr, INVALIDr, 205 INVALIDr, INVALIDr }, 206 { PARITY_ENf, RMEP_PAR_ERRf, NULL, 207 RMEPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 208 RMEP_PARITY_CONTROLr, 209 RMEP_PARITY_STATUSr, INVALIDr, 210 INVALIDr, INVALIDr }, 211 { PARITY_ENf, MAID_REDUCTION_PAR_ERRf, NULL, 212 MAID_REDUCTIONm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 213 MAID_REDUCTION_PARITY_CONTROLr, 214 MAID_REDUCTION_PARITY_STATUSr, INVALIDr, 215 INVALIDr, INVALIDr }, 216 { PARITY_ENf, MA_INDEX_PAR_ERRf, NULL, 217 MA_INDEXm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 218 MA_INDEX_PARITY_CONTROLr, 219 MA_INDEX_PARITY_STATUSr, INVALIDr, 220 INVALIDr, INVALIDr }, 221 { PARITY_ENf, PORT_CBL_TABLE_PAR_ERRf, NULL, 222 PORT_CBL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 223 PORT_CBL_TABLE_PARITY_CONTROLr, 224 PORT_CBL_TABLE_PARITY_STATUSr, INVALIDr, 225 INVALIDr, INVALIDr }, 226 { PARITY_ENf, INITIAL_NHOP_PAR_ERRf, NULL, 227 INITIAL_ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 228 INITIAL_NHOP_PARITY_CONTROLr, 229 INITIAL_NHOP_PARITY_STATUSr, INVALIDr, 230 INVALIDr, INVALIDr }, 231 /* Start of parity-unrelated OAM faults */ 232 233 { ANY_RMEP_TLV_PORT_DOWN_INTRf, ANY_RMEP_TLV_PORT_DOWN_INTRf, NULL, 234 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 235 INVALIDr, 236 INVALIDr, INVALIDr, 237 INVALIDr, INVALIDr }, 238 239 { ANY_RMEP_TLV_PORT_UP_INTRf, ANY_RMEP_TLV_PORT_UP_INTRf, NULL, 240 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 241 INVALIDr, 242 INVALIDr, INVALIDr, 243 INVALIDr, INVALIDr }, 244 245 { ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, ANY_RMEP_TLV_INTERFACE_DOWN_INTRf, NULL, 246 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 247 INVALIDr, 248 INVALIDr, INVALIDr, 249 INVALIDr, INVALIDr }, 250 251 { ANY_RMEP_TLV_INTERFACE_UP_INTRf, ANY_RMEP_TLV_INTERFACE_UP_INTRf, NULL, 252 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 253 INVALIDr, 254 INVALIDr, INVALIDr, 255 INVALIDr, INVALIDr }, 256 257 { XCON_CCM_DEFECT_INTRf, XCON_CCM_DEFECT_INTRf, NULL, 258 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 259 INVALIDr, 260 INVALIDr, INVALIDr, 261 INVALIDr, INVALIDr }, 262 263 { ERROR_CCM_DEFECT_INTRf, ERROR_CCM_DEFECT_INTRf, NULL, 264 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 265 INVALIDr, 266 INVALIDr, INVALIDr, 267 INVALIDr, INVALIDr }, 268 269 { SOME_RDI_DEFECT_INTRf, SOME_RDI_DEFECT_INTRf, NULL, 270 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 271 INVALIDr, 272 INVALIDr, INVALIDr, 273 INVALIDr, INVALIDr }, 274 275 { SOME_RMEP_CCM_DEFECT_INTRf, SOME_RMEP_CCM_DEFECT_INTRf, NULL, 276 INVALIDm, _SOC_PARITY_INFO_TYPE_OAM, 277 INVALIDr, 278 INVALIDr, INVALIDr, 279 INVALIDr, INVALIDr }, 280 281 /* End of parity-unrelated OAM faults */ 282 { PARITY_ENf, VFI_1_PAR_INTRf, NULL, 283 VFI_1m, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 284 VFI_1_PARITY_CONTROLr, 285 VFI_1_PARITY_STATUS_INTRr, INVALIDr, 286 VFI_1_PARITY_STATUS_NACKr, INVALIDr }, 287 { INVALIDf, INVALIDf }, /* table terminator */ 288 }; 289 290 static _soc_parity_info_t _soc_en_ip2_parity_info[] = { 291 { PARITY_ENf, ING_NHOP_PAR_ERRf, NULL, 292 ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 293 ING_L3_NEXT_HOP_PARITY_CONTROLr, 294 ING_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr, 295 INVALIDr, INVALIDr }, 296 { PARITY_ENf, IFP_METER_PAR_ERRf, NULL, 297 FP_METER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 298 IFP_METER_PARITY_CONTROLr, 299 IFP_METER_PARITY_STATUSr, INVALIDr, 300 INVALIDr, INVALIDr }, 301 { PARITY_ENf, IFP_COUNTER_PAR_ERRf, NULL, 302 FP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 303 IFP_COUNTER_PARITY_CONTROLr, 304 IFP_COUNTER_PARITY_STATUSr, INVALIDr, 305 INVALIDr, INVALIDr }, 306 { PARITY_ENf, IFP_POLICY_PAR_ERRf, NULL, 307 FP_POLICY_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 308 IFP_POLICY_PARITY_CONTROLr, 309 IFP_POLICY_PARITY_STATUSr, INVALIDr, 310 INVALIDr, INVALIDr }, 311 { PARITY_ENf, IFP_STORM_CONTROL_PAR_ERRf, NULL, 312 FP_STORM_CONTROL_METERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 313 IFP_STORM_CONTROL_PARITY_CONTROLr, 314 IFP_STORM_CONTROL_PARITY_STATUSr, INVALIDr, 315 INVALIDr, INVALIDr }, 316 { PARITY_ENf, L3_MTU_VALUES_PAR_ERRf, NULL, 317 L3_MTU_VALUESm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 318 L3_MTU_VALUES_PARITY_CONTROLr, 319 L3_MTU_VALUES_PARITY_STATUSr, INVALIDr, 320 INVALIDr, INVALIDr }, 321 { PARITY_ENf, EGR_MASK_PAR_ERRf, NULL, 322 EGR_MASKm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 323 EGR_MASK_PARITY_CONTROLr, 324 EGR_MASK_PARITY_STATUSr, INVALIDr, 325 INVALIDr, INVALIDr }, 326 { PARITY_ENf, MODPORT_MAP_SW_PAR_ERRf, NULL, 327 MODPORT_MAP_SWm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 328 MODPORT_MAP_SW_PARITY_CONTROLr, 329 MODPORT_MAP_SW_PARITY_STATUSr, INVALIDr, 330 INVALIDr, INVALIDr }, 331 { PARITY_ENf, MODPORT_MAP_IM_PAR_ERRf, NULL, 332 MODPORT_MAP_IMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 333 MODPORT_MAP_IM_PARITY_CONTROLr, 334 MODPORT_MAP_IM_PARITY_STATUSr, INVALIDr, 335 INVALIDr, INVALIDr }, 336 { PARITY_ENf, MODPORT_MAP_EM_PAR_ERRf, NULL, 337 MODPORT_MAP_EMm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 338 MODPORT_MAP_EM_PARITY_CONTROLr, 339 MODPORT_MAP_EM_PARITY_STATUSr, INVALIDr, 340 INVALIDr, INVALIDr }, 341 { INVALIDf, INVALIDf }, /* table terminator */ 342 }; 343 344 static _soc_parity_info_t _soc_en_ep_parity_info[] = { 345 { PARITY_ENf, EGR_NHOP_PAR_ERRf, NULL, 346 EGR_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 347 EGR_L3_NEXT_HOP_PARITY_CONTROLr, 348 EGR_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr, 349 INVALIDr, INVALIDr }, 350 { PARITY_ENf, EGR_L3_INTF_PAR_ERRf, NULL, 351 EGR_L3_INTFm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 352 EGR_L3_INTF_PARITY_CONTROLr, 353 EGR_L3_INTF_PARITY_STATUSr, INVALIDr, 354 INVALIDr, INVALIDr }, 355 { PARITY_ENf, EGR_MPLS_LABEL_PAR_ERRf, NULL, 356 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 357 EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_CONTROLr, 358 EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_STATUSr, INVALIDr, 359 INVALIDr, INVALIDr }, 360 { PARITY_ENf, EGR_VLAN_PAR_ERRf, NULL, 361 EGR_VLANm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 362 EGR_VLAN_PARITY_CONTROLr, 363 EGR_VLAN_PARITY_STATUSr, INVALIDr, 364 INVALIDr, INVALIDr }, 365 { PARITY_ENf, EGR_VLAN_STG_PAR_ERRf, NULL, 366 EGR_VLAN_STGm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 367 EGR_VLAN_STG_PARITY_CONTROLr, 368 EGR_VLAN_STG_PARITY_STATUSr, INVALIDr, 369 INVALIDr, INVALIDr }, 370 { PARITY_ENf, EGR_VXLT_PAR_ERRf, NULL, 371 EGR_VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_PARITY, 372 EGR_VLAN_XLATE_PARITY_CONTROLr, 373 EGR_VLAN_XLATE_PARITY_STATUS_0r, EGR_VLAN_XLATE_PARITY_STATUS_1r, 374 INVALIDr, INVALIDr }, 375 { PARITY_ENf, EGR_IP_TUNNEL_PAR_ERRf, NULL, 376 EGR_IP_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 377 EGR_IP_TUNNEL_PARITY_CONTROLr, 378 EGR_IP_TUNNEL_PARITY_STATUSr, INVALIDr, 379 INVALIDr, INVALIDr }, 380 { PARITY_ENf, EGR_PW_COUNT_PAR_ERRf, NULL, 381 EGR_PW_INIT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 382 EGR_PW_INIT_COUNTERS_PARITY_CONTROLr, 383 EGR_PW_INIT_COUNTERS_PARITY_STATUSr, INVALIDr, 384 INVALIDr, INVALIDr }, 385 /* { PARITY_ENf, EGR_IPFIX_SESS_PAR_ERRf, NULL, 386 EGR_IPFIX_SESSION_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 387 EGR_IPFIX_SESSION_PARITY_CONTROLr, 388 EGR_IPFIX_SESSION_PARITY_STATUSr, INVALIDr, 389 INVALIDr, INVALIDr }, 390 { PARITY_ENf, EGR_IPFIX_EXPORT_PAR_ERRf, NULL, 391 EGR_IPFIX_EXPORT_FIFOm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 392 EGR_IPFIX_EXPORT_FIFO_PARITY_CONTROLr, 393 EGR_IPFIX_EXPORT_FIFO_PARITY_STATUSr, INVALIDr, 394 INVALIDr, INVALIDr }, */ 395 { ECC_ENf, EP_INITBUF_DBEf, "EP_INITBUF double-bit ECC error", 396 INVALIDm,_SOC_PARITY_INFO_TYPE_SINGLE_ECC, 397 EGR_INITBUF_ECC_CONTROLr, 398 EGR_INITBUF_ECC_STATUS_DBEr, INVALIDr, 399 INVALIDr, INVALIDr }, 400 { ECC_ENf, EP_INITBUF_SBEf, "EP_INITBUF single-bit ECC error (corrected)", 401 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 402 EGR_INITBUF_ECC_CONTROLr, 403 EGR_INITBUF_ECC_STATUS_SBEr, INVALIDr, 404 INVALIDr, INVALIDr }, 405 { PARITY_ENf, EGR_PERQ_COUNTERf, "EP_PERQ_COUNTER table parity error", 406 EGR_PERQ_XMT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 407 EGR_PERQ_COUNTER_PARITY_CONTROLr, 408 EGR_PERQ_COUNTER_PARITY_STATUSr, INVALIDr, 409 INVALIDr, INVALIDr }, 410 { PARITY_ENf, EGR_FP_COUNTERf, NULL, 411 EFP_COUNTER_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 412 EGR_FP_COUNTER_PARITY_CONTROLr, 413 EGR_FP_COUNTER_PARITY_STATUSr, INVALIDr, 414 INVALIDr, INVALIDr }, 415 { PARITY_ENf, EGR_GP0_DBUFf, "EP_GP0_DATABUF memory parity error", 416 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 417 EGR_GP0_DBUF_PARITY_CONTROLr, 418 EGR_GP0_DBUF_PARITY_STATUSr, INVALIDr, 419 INVALIDr, INVALIDr }, 420 { PARITY_ENf, EGR_GP1_DBUFf, "EP_GP1_DATABUF memory parity error", 421 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 422 EGR_GP1_DBUF_PARITY_CONTROLr, 423 EGR_GP1_DBUF_PARITY_STATUSr, INVALIDr, 424 INVALIDr, INVALIDr }, 425 { PARITY_ENf, EGR_GP2_DBUFf, "EP_GP2_DATABUF memory parity error", 426 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 427 EGR_GP2_DBUF_PARITY_CONTROLr, 428 EGR_GP2_DBUF_PARITY_STATUSr, INVALIDr, 429 INVALIDr, INVALIDr }, 430 { PARITY_ENf, EGR_XQ0_DBUFf, "EP_XQ0_DATABUF memory parity error", 431 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 432 EGR_XQ0_DBUF_PARITY_CONTROLr, 433 EGR_XQ0_DBUF_PARITY_STATUSr, INVALIDr, 434 INVALIDr, INVALIDr }, 435 { PARITY_ENf, EGR_XQ1_DBUFf, "EP_XQ1_DATABUF memory parity error", 436 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 437 EGR_XQ1_DBUF_PARITY_CONTROLr, 438 EGR_XQ1_DBUF_PARITY_STATUSr, INVALIDr, 439 INVALIDr, INVALIDr }, 440 { PARITY_ENf, EGR_XQ2_DBUFf, "EP_XQ2_DATABUF memory parity error", 441 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 442 EGR_XQ2_DBUF_PARITY_CONTROLr, 443 EGR_XQ2_DBUF_PARITY_STATUSr, INVALIDr, 444 INVALIDr, INVALIDr }, 445 { PARITY_ENf, EGR_XQ3_DBUFf, "EP_XQ3_DATABUF memory parity error", 446 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 447 EGR_XQ3_DBUF_PARITY_CONTROLr, 448 EGR_XQ3_DBUF_PARITY_STATUSr, INVALIDr, 449 INVALIDr, INVALIDr }, 450 { PARITY_ENf, EGR_LP_DBUFf, "EP_LP_DATABUF memory parity error", 451 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 452 EGR_LP_DBUF_PARITY_CONTROLr, 453 EGR_LP_DBUF_PARITY_STATUSr, INVALIDr, 454 INVALIDr, INVALIDr }, 455 { PARITY_ENf, EGR_CM_DBUFf, "EGR_CM_DBUF memory parity error", 456 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_PARITY, 457 EGR_CM_DBUF_PARITY_CONTROLr, 458 EGR_CM_DBUF_PARITY_STATUSr, INVALIDr, 459 INVALIDr, INVALIDr }, 460 { INVALIDf, INVALIDf }, /* table terminator */ 461 }; 462 463 /* 464 * Is DEQ_CBPERRPTRr for MMU_CBPDATA0 - MMU_CBPDATA31 (15-bit address)? 465 * How does MMU_CELLCHKm (15-bit address) report parity error? 466 */ 467 static _soc_parity_info_t _soc_en_mmu_parity_info[] = { 468 { AGING_CTR_PAR_ERR_ENf, AGING_CTR_PAR_ERRf, NULL, 469 MMU_AGING_CTRm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 470 INVALIDr, 471 INVALIDr, INVALIDr, 472 INVALIDr, INVALIDr }, 473 { AGING_EXP_PAR_ERR_ENf, AGING_EXP_PAR_ERRf, NULL, 474 MMU_AGING_EXPm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 475 INVALIDr, 476 INVALIDr, INVALIDr, 477 INVALIDr, INVALIDr }, 478 { CCP_PAR_ERR_ENf, CCP_PAR_ERRf, NULL, 479 MMU_CCP_MEMm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 480 INVALIDr, 481 CCPPARITYERRORPTRr, INVALIDr, 482 INVALIDr, INVALIDr }, 483 { CFAP_PAR_ERR_ENf, CFAP_PAR_ERRf, NULL, 484 MMU_CFAP_MEMm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 485 INVALIDr, 486 CFAPPARITYERRORPTRr, INVALIDr, 487 INVALIDr, INVALIDr }, 488 { CFAP_MEM_FAIL_ENf, CFAP_MEM_FAILf, NULL, 489 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 490 INVALIDr, 491 INVALIDr, INVALIDr, 492 INVALIDr, INVALIDr }, 493 { DEQ_PKTHDR_CPU_ERR_ENf, DEQ_PKTHDR_CPU_ERRf, NULL, 494 MMU_CBPPKTHEADERCPUm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 495 INVALIDr, 496 DEQ_PKTHDRCPUERRPTRr, INVALIDr, 497 INVALIDr, INVALIDr }, 498 { DEQ_PKTHDR0_ERR_ENf, DEQ_PKTHDR0_ERRf, NULL, 499 MMU_CBPPKTHEADER0_MEM0m, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 500 INVALIDr, 501 DEQ_PKTHDR0ERRPTRr, INVALIDr, 502 INVALIDr, INVALIDr }, 503 { DEQ0_NOT_IP_ERR_ENf, DEQ0_NOT_IP_ERRf, NULL, 504 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 505 INVALIDr, 506 INVALIDr, INVALIDr, 507 INVALIDr, INVALIDr }, 508 { DEQ0_CELLCRC_ERR_ENf, DEQ0_CELLCRC_ERRf, NULL, 509 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 510 INVALIDr, 511 INVALIDr, INVALIDr, 512 INVALIDr, INVALIDr }, 513 { START_BY_START_ERR_ENf, START_BY_START_ERRf, NULL, 514 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 515 INVALIDr, 516 INVALIDr, INVALIDr, 517 INVALIDr, INVALIDr }, 518 { MEM1_IPMC_TBL_PAR_ERR_ENf, MEM1_IPMC_TBL_PAR_ERRf, "MMU_IPMC_GROUP_TBL", 519 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 520 INVALIDr, 521 MEM1_IPMCGRP_TBL_PARITYERRORPTRr, MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr, 522 INVALIDr, INVALIDr }, 523 { MEM1_VLAN_TBL_PAR_ERR_ENf, MEM1_VLAN_TBL_PAR_ERRf, NULL, 524 MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 525 INVALIDr, 526 MEM1_IPMCVLAN_TBL_PARITYERRORPTRr, INVALIDr, 527 INVALIDr, INVALIDr }, 528 { TOQ0_CELLHDR_PAR_ERR_ENf, TOQ0_CELLHDR_PAR_ERRf, NULL, 529 MMU_CBPCELLHEADERm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 530 INVALIDr, 531 TOQ_CELLHDRERRPTRr, INVALIDr, 532 INVALIDr, INVALIDr }, 533 { TOQ0_PKTHDR1_PAR_ERR_ENf, TOQ0_PKTHDR1_PAR_ERRf, NULL, 534 MMU_CBPPKTHEADER1_MEM0m, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 535 INVALIDr, 536 TOQ_PKTHDR1ERRPTRr, INVALIDr, 537 INVALIDr, INVALIDr }, 538 { TOQ0_PKTLINK_PAR_ERR_ENf, TOQ0_PKTLINK_PAR_ERRf, NULL, 539 MMU_PKTLINK0m, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 540 INVALIDr, 541 TOQ_PKTLINKERRPTRr, INVALIDr, 542 INVALIDr, INVALIDr }, 543 { TOQ0_CELLLINK_PAR_ERR_ENf, TOQ0_CELLLINK_PAR_ERRf, NULL, 544 MMU_CELLLINKm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 545 INVALIDr, 546 TOQ_CELLLINKERRPTRr, INVALIDr, 547 INVALIDr, INVALIDr }, 548 { TOQ0_IPMC_TBL_PAR_ERR_ENf, TOQ0_IPMC_TBL_PAR_ERRf, NULL, 549 INVALIDm, _SOC_PARITY_INFO_TYPE_MMUIPMC, 550 INVALIDr, 551 TOQ_IPMCGRPERRPTR0r, TOQ_ERRINTR1r, 552 INVALIDr, INVALIDr }, 553 { TOQ0_VLAN_TBL_PAR_ERR_ENf, TOQ0_VLAN_TBL_PAR_ERRf, NULL, 554 MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 555 INVALIDr, 556 TOQ_IPMCVLANERRPTRr, INVALIDr, 557 INVALIDr, INVALIDr }, 558 { MTRO_PAR_ERR_ENf, MTRO_PAR_ERRf, NULL, 559 INVALIDm, _SOC_PARITY_INFO_TYPE_MMUMTRO, 560 INVALIDr, 561 INVALIDr, INVALIDr, 562 INVALIDr, INVALIDr }, 563 { PFAP_PAR_ERR_ENf, PFAP_PAR_ERRf, NULL, 564 MMU_PFAP_MEMm, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 565 INVALIDr, 566 PFAPPARITYERRORPTRr, INVALIDr, 567 INVALIDr, INVALIDr }, 568 { PFAP_MEM_FAIL_ENf, PFAP_MEM_FAILf, NULL, 569 MMU_PFAP_MEMm, _SOC_PARITY_INFO_TYPE_GENERIC, 570 INVALIDr, 571 INVALIDr, INVALIDr, 572 INVALIDr, INVALIDr }, 573 { WRED_PAR_ERR_ENf, WRED_PAR_ERRf, NULL, 574 INVALIDm, _SOC_PARITY_INFO_TYPE_MMUWRED, 575 INVALIDr, 576 WRED_PARITY_ERROR_INFOr, WRED_PARITY_ERROR_BITMAPr, 577 INVALIDr, INVALIDr }, 578 { DEQ_PKTHDR2_ERR_ENf, DEQ_PKTHDR2_PAR_ERRf, NULL, 579 MMU_CBPPKTHEADER2m, _SOC_PARITY_INFO_TYPE_MMU_PARITY, 580 INVALIDr, 581 DEQ_PKTHDR2ERRPTRr, INVALIDr, 582 INVALIDr, INVALIDr }, 583 { E2EFC_ERR_ENf, E2EFC_PAR_ERRf, NULL, 584 INVALIDm, _SOC_PARITY_INFO_TYPE_MMUE2EFC, 585 INVALIDr, 586 INVALIDr, INVALIDr, 587 INVALIDr, INVALIDr }, 588 { INVALIDf, INVALIDf }, /* table terminator */ 589 }; 590 591 static _soc_parity_info_t _soc_en_xqp_parity_info[] = { 592 { EHG_TX_DATAf, EHG_TX_DATAf, NULL, 593 XQPORT_EHG_TX_TUNNEL_DATAm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 594 XQPORT_PARITY_CONTROLr, 595 XQPORT_EHG_TX_DATA_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr, 596 XQPORT_EHG_TX_DATA_PARITY_STATUS_NACKr, XQPORT_FORCE_DOUBLE_BIT_ERRORr }, 597 598 { XQBOD_RXFIFOf, XQBOD_RXFIFOf, "XQBOD_RXFIFO", 599 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 600 XQPORT_PARITY_CONTROLr, 601 XQPORT_XQBOD_RXFIFO_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr, 602 INVALIDr, XQPORT_FORCE_DOUBLE_BIT_ERRORr }, 603 { XQBODE_TXFIFOf, XQBODE_TXFIFOf, "XQBODE_TXFIFO", 604 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_ECC, 605 XQPORT_PARITY_CONTROLr, 606 XQPORT_XQBODE_TXFIFO_PARITY_STATUS_INTRr, XQPORT_FORCE_SINGLE_BIT_ERRORr, 607 INVALIDr, XQPORT_FORCE_DOUBLE_BIT_ERRORr }, 608 { INVALIDf, INVALIDf }, /* table terminator */ 609 }; 610 611 static struct { 612 uint32 cpi_bit; 613 soc_block_t blocktype; 614 soc_reg_t enable_reg; 615 soc_reg_t status_reg; 616 _soc_parity_info_t *info; 617 } _soc_en_parity_group_info[] = { 618 { 0x00001, SOC_BLK_MMU, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, _soc_en_mmu_parity_info }, 619 { 0x00002, SOC_BLK_EPIPE, EP_INTR_ENABLEr, EP_INTR_STATUSr, _soc_en_ep_parity_info }, 620 { 0x00004, SOC_BLK_IPIPE, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, _soc_en_ip0_parity_info }, 621 { 0x00008, SOC_BLK_IPIPE, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, _soc_en_ip1_parity_info }, 622 { 0x00010, SOC_BLK_IPIPE, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, _soc_en_ip2_parity_info }, 623 /* { 0x00020, PCIE_REPLAY_PERR, }, */ 624 { 0x00040, SOC_BLK_XQPORT, XQPORT_INTR_ENABLEr, XQPORT_INTR_STATUSr, _soc_en_xqp_parity_info }, /* x4 */ 625 { 0 }, /* table terminator */ 626 }; 627 628 soc_enduro_oam_handler_t en_oam_handler[SOC_MAX_NUM_DEVICES] = {NULL}; 629 630 static soc_ser_functions_t _enduro_ser_functions; 631 632 #define _SOC_ENDURO_SER_REG 1 633 #define _SOC_ENDURO_SER_MEM 0 634 635 typedef union _enduro_ser_nack_reg_mem_u { 636 soc_reg_t reg; 637 soc_mem_t mem; 638 } _enduro_ser_nack_reg_mem_t; 639 640 STATIC int 641 _soc_enduro_parity_block_port(int unit, soc_block_t block, soc_port_t *port) 642 { 643 *port = SOC_BLOCK_PORT(unit, block); 644 if ((*port != REG_PORT_ANY) && !SOC_PORT_VALID(unit, *port)) { 645 return SOC_E_PORT; 646 } 647 648 return SOC_E_NONE; 649 } 650 651 STATIC int 652 _soc_enduro_parity_enable(int unit, int enable) 653 { 654 int group, table; 655 uint32 addr, group_enable, regval, misc_cfg, cmic_enable = 0, cpi_blk_bit; 656 _soc_parity_info_t *info; 657 soc_reg_t group_reg, reg; 658 soc_port_t block_port; 659 soc_field_t enable_field; 660 soc_block_t blk; 661 662 /* loop through each group */ 663 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 664 info = _soc_en_parity_group_info[group].info; 665 group_reg = _soc_en_parity_group_info[group].enable_reg; 666 group_enable = 0; 667 668 cpi_blk_bit = _soc_en_parity_group_info[group].cpi_bit; 669 670 SOC_BLOCK_ITER(unit, blk, 671 _soc_en_parity_group_info[group].blocktype) { 672 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 673 cpi_blk_bit <<= 1; 674 continue; 675 } 676 /* loop through each table in the group */ 677 for (table = 0; info[table].enable_field != INVALIDf; table++) { 678 /* handle different parity error reporting style */ 679 switch (info[table].type) { 680 case _SOC_PARITY_INFO_TYPE_GENERIC: 681 case _SOC_PARITY_INFO_TYPE_MMU_PARITY: 682 case _SOC_PARITY_INFO_TYPE_MMUIPMC: 683 case _SOC_PARITY_INFO_TYPE_MMUWRED: 684 case _SOC_PARITY_INFO_TYPE_MMUMTRO: 685 case _SOC_PARITY_INFO_TYPE_MMUE2EFC: 686 case _SOC_PARITY_INFO_TYPE_OAM: 687 enable_field = info[table].enable_field; 688 break; 689 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY: 690 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC: 691 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER: 692 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY: 693 reg = info[table].control_reg; 694 if (!SOC_REG_IS_VALID(unit, reg)) { 695 continue; 696 } 697 addr = soc_reg_addr(unit, reg, block_port, 0); 698 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, ®val)); 699 soc_reg_field_set(unit, reg, ®val, 700 info[table].enable_field, 701 enable ? 1 : 0); 702 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, regval)); 703 enable_field = info[table].error_field; 704 break; 705 default: 706 enable_field = INVALIDf; 707 break; 708 } /* handle different parity error reporting style */ 709 if (enable_field != INVALIDf) { 710 soc_reg_field_set(unit, group_reg, &group_enable, 711 enable_field, enable ? 1 : 0); 712 } 713 } /* loop through each table in the group */ 714 715 if (!SOC_REG_IS_VALID(unit, group_reg)) { 716 cpi_blk_bit <<= 1; 717 continue; 718 } 719 addr = soc_reg_addr(unit, group_reg, block_port, 0); 720 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable)); 721 cmic_enable |= cpi_blk_bit; 722 cpi_blk_bit <<= 1; 723 } 724 } /* loop through each group */ 725 726 /* coverity[result_independent_of_operands] */ 727 SOC_IF_ERROR_RETURN(WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, 728 cmic_enable)); 729 730 /* MMU enables */ 731 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg)); 732 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_STAT_CLEARf, 1); 733 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 734 735 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 1); 736 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 1); 737 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_STAT_CLEARf, 0); 738 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 739 740 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, ®val)); 741 soc_intr_enable(unit, IRQ_MEM_FAIL); 742 743 return SOC_E_NONE; 744 } 745 746 STATIC void 747 _soc_enduro_mem_parity_info(int unit, int block_info_idx, 748 soc_field_t field_enum, uint32 *minfo) 749 { 750 *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) 751 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK); 752 } 753 754 int 755 _soc_enduro_mem_parity_control(int unit, soc_mem_t mem, 756 int copyno, int enable) 757 { 758 int group, table; 759 uint32 cpi_blk_bit, misc_cfg; 760 _soc_parity_info_t *info; 761 soc_reg_t group_reg, reg; 762 soc_port_t block_port; 763 soc_field_t enable_field; 764 soc_block_t blk; 765 766 if (!soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 767 /* Parity checking is not enabled, nothing to do */ 768 return SOC_E_NONE; 769 } 770 771 /* Convert component/aggregate memories to the table for which 772 * the parity registers correspond. */ 773 switch(mem) { 774 case VLAN_SUBNETm: 775 mem = VLAN_SUBNET_DATA_ONLYm; /* Should be VLAN_SUBNET? */ 776 break; 777 case VLAN_MACm: 778 mem = VLAN_XLATEm; 779 break; 780 case L2_ENTRY_ONLYm: 781 mem = L2Xm; 782 break; 783 case L2_USER_ENTRY_ONLYm: 784 case L2_USER_ENTRY_DATA_ONLYm: 785 mem = L2_USER_ENTRYm; 786 break; 787 case L3_ENTRY_IPV4_UNICASTm: 788 case L3_ENTRY_IPV6_UNICASTm: 789 case L3_ENTRY_IPV4_MULTICASTm: 790 case L3_ENTRY_IPV6_MULTICASTm: 791 mem = L3_ENTRY_ONLYm; 792 break; 793 case L3_DEFIPm: 794 mem = L3_DEFIP_DATA_ONLYm; 795 break; 796 case L3_DEFIP_128m: 797 mem = L3_DEFIP_128_DATA_ONLYm; 798 break; 799 case EGR_IP_TUNNEL_IPV6m: 800 case EGR_IP_TUNNEL_MPLSm: 801 mem = EGR_IP_TUNNELm; 802 break; 803 default: 804 /* Do nothing, keep memory as provided */ 805 break; 806 } 807 808 809 /* loop through each group */ 810 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 811 info = _soc_en_parity_group_info[group].info; 812 group_reg = _soc_en_parity_group_info[group].enable_reg; 813 cpi_blk_bit = _soc_en_parity_group_info[group].cpi_bit; 814 815 SOC_BLOCK_ITER(unit, blk, 816 _soc_en_parity_group_info[group].blocktype) { 817 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 818 cpi_blk_bit <<= 1; 819 continue; 820 } 821 if ((copyno != MEM_BLOCK_ANY) && (blk != copyno)) { 822 cpi_blk_bit <<= 1; 823 continue; 824 } 825 826 /* loop through each table in the group */ 827 for (table = 0; info[table].enable_field != INVALIDf; table++) { 828 if (mem != info[table].mem) { 829 continue; 830 } 831 832 /* handle different parity error reporting style */ 833 switch (info[table].type) { 834 case _SOC_PARITY_INFO_TYPE_GENERIC: 835 case _SOC_PARITY_INFO_TYPE_MMU_PARITY: 836 case _SOC_PARITY_INFO_TYPE_MMUIPMC: 837 case _SOC_PARITY_INFO_TYPE_MMUWRED: 838 case _SOC_PARITY_INFO_TYPE_MMUMTRO: 839 case _SOC_PARITY_INFO_TYPE_MMUE2EFC: 840 enable_field = info[table].enable_field; 841 SOC_IF_ERROR_RETURN 842 (soc_reg_field32_modify(unit, group_reg, block_port, 843 enable_field, 844 enable ? 1 : 0)); 845 break; 846 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY: 847 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC: 848 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER: 849 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY: 850 reg = info[table].control_reg; 851 if (!SOC_REG_IS_VALID(unit, reg)) { 852 return SOC_E_NONE; 853 } 854 SOC_IF_ERROR_RETURN 855 (soc_reg_field32_modify(unit, reg, block_port, 856 info[table].enable_field, 857 enable ? 1 : 0)); 858 break; 859 default: 860 /* coverity[assigned_value] */ 861 enable_field = INVALIDf; 862 break; 863 } /* handle different parity error reporting style */ 864 } /* loop through each table in the group */ 865 cpi_blk_bit <<= 1; 866 } 867 } /* loop through each group */ 868 869 /* MMU controls */ 870 if (enable) { 871 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg)); 872 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, 873 PARITY_STAT_CLEARf, 1); 874 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 875 876 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 1); 877 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 1); 878 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, 879 PARITY_STAT_CLEARf, 0); 880 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, METERING_CLK_ENf, 1); 881 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 882 } else { 883 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg)); 884 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 0); 885 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 0); 886 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, METERING_CLK_ENf, 0); 887 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 888 } 889 890 return SOC_E_NONE; 891 } 892 893 STATIC int 894 _soc_enduro_process_single_parity_error(int unit, int group, 895 soc_port_t block_port, int table, 896 int schan, char *msg, soc_block_t block) 897 { 898 _soc_parity_info_t *info; 899 soc_reg_t status_reg; 900 uint32 addr, reg_val, minfo; 901 int index, multiple, error, rv; 902 _soc_ser_correct_info_t spci; 903 904 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 905 906 info = _soc_en_parity_group_info[group].info; 907 908 status_reg = schan ? info[table].nack_status0_reg : 909 info[table].intr_status0_reg; 910 if (status_reg == INVALIDr) { 911 return SOC_E_INTERNAL; 912 } 913 addr = soc_reg_addr(unit, status_reg, block_port, 0); 914 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, ®_val)); 915 index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf); 916 multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf); 917 error = soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERRf); 918 919 if (error) { 920 _soc_enduro_mem_parity_info(unit, block, info[table].error_field, 921 &minfo); 922 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 923 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 924 index, minfo); 925 926 LOG_ERROR(BSL_LS_SOC_COMMON, 927 (BSL_META_U(unit, 928 "unit %d %s entry %d parity error\n"), 929 unit, msg, index)); 930 if (multiple) { 931 LOG_ERROR(BSL_LS_SOC_COMMON, 932 (BSL_META_U(unit, 933 "unit %d %s has multiple parity errors\n"), 934 unit, msg)); 935 } 936 if (info[table].mem != INVALIDm) { 937 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 938 spci.reg = INVALIDr; 939 spci.mem = info[table].mem; 940 spci.blk_type = block; 941 spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index); 942 rv = soc_ser_correction(unit, &spci); 943 if (SOC_FAILURE(rv)) { 944 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 945 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 946 index, minfo); 947 } 948 } 949 } else { 950 LOG_ERROR(BSL_LS_SOC_COMMON, 951 (BSL_META_U(unit, 952 "unit %d %s: parity hardware inconsistency\n"), 953 unit, msg)); 954 } 955 956 /* Clear parity status */ 957 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 958 return SOC_E_NONE; 959 } 960 961 STATIC int 962 _soc_enduro_process_single_ecc_error(int unit, int group, 963 soc_port_t block_port, int table, 964 int schan, char *msg, soc_block_t block) 965 { 966 _soc_parity_info_t *info; 967 soc_reg_t status_reg; 968 uint32 addr, reg_val, minfo; 969 int rv, index, single_bit = 0, double_bit = 0, multiple = 0, error = 0; 970 _soc_ser_correct_info_t spci; 971 972 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 973 974 info = _soc_en_parity_group_info[group].info; 975 976 status_reg = schan ? info[table].nack_status0_reg : 977 info[table].intr_status0_reg; 978 if (status_reg == INVALIDr) { 979 return SOC_E_INTERNAL; 980 } 981 addr = soc_reg_addr(unit, status_reg, block_port, 0); 982 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, ®_val)); 983 index = soc_reg_field_get(unit, status_reg, reg_val, ENTRY_IDXf); 984 985 if (soc_reg_field_valid(unit, status_reg, SINGLE_BIT_ERRf)) { 986 single_bit = soc_reg_field_get(unit, status_reg, 987 reg_val, SINGLE_BIT_ERRf); 988 } 989 if (soc_reg_field_valid(unit, status_reg, DOUBLE_BIT_ERRf)) { 990 double_bit = soc_reg_field_get(unit, status_reg, 991 reg_val, DOUBLE_BIT_ERRf); 992 } 993 994 if (soc_reg_field_valid(unit, status_reg, ECC_ERRf)) { 995 error = soc_reg_field_get(unit, status_reg, reg_val, ECC_ERRf); 996 } 997 998 multiple = soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf); 999 1000 if (single_bit || double_bit || error) { 1001 LOG_ERROR(BSL_LS_SOC_COMMON, 1002 (BSL_META_U(unit, 1003 "unit %d %s entry %d %s ECC error\n"), 1004 unit, msg, index, double_bit ? "double-bit" : "single-bit")); 1005 _soc_enduro_mem_parity_info(unit, block, 1006 info[table].error_field, &minfo); 1007 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1008 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 1009 index, minfo); 1010 1011 if (multiple) { 1012 LOG_ERROR(BSL_LS_SOC_COMMON, 1013 (BSL_META_U(unit, 1014 "unit %d %s has multiple ECC errors\n"), 1015 unit, msg)); 1016 } 1017 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 1018 spci.reg = INVALIDr; 1019 spci.mem = info[table].mem; 1020 spci.blk_type = block; 1021 spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index); 1022 spci.double_bit = (double_bit == 0) ? 0 : 1; 1023 spci.parity_type = SOC_PARITY_TYPE_ECC; 1024 rv = soc_ser_correction(unit, &spci); 1025 if (SOC_FAILURE(rv)) { 1026 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1027 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1028 index, minfo); 1029 } 1030 } else { 1031 LOG_ERROR(BSL_LS_SOC_COMMON, 1032 (BSL_META_U(unit, 1033 "unit %d %s: parity hardware inconsistency\n"), 1034 unit, msg)); 1035 } 1036 1037 /* Clear parity status */ 1038 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 1039 return SOC_E_NONE; 1040 } 1041 1042 STATIC int 1043 _soc_enduro_process_dual_parity_error(int unit, int group, 1044 soc_port_t block_port, int table, 1045 int schan, char *msg, soc_block_t block) 1046 { 1047 _soc_parity_info_t *info; 1048 soc_reg_t status_reg; 1049 uint32 addr, reg_val, minfo, bitmap = 0; 1050 int rv, index, bucket_index = 0, multiple = 0, ix, bits, size = 0; 1051 _soc_ser_correct_info_t spci; 1052 1053 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1054 1055 info = _soc_en_parity_group_info[group].info; 1056 1057 for (ix = 0; ix < 2; ix ++) { 1058 if (ix == 1) { 1059 status_reg = schan ? info[table].nack_status1_reg : 1060 info[table].intr_status1_reg; 1061 } else { 1062 status_reg = schan ? info[table].nack_status0_reg : 1063 info[table].intr_status0_reg; 1064 } 1065 1066 if (status_reg == INVALIDr) { 1067 continue; 1068 } 1069 1070 addr = soc_reg_addr(unit, status_reg, block_port, 0); 1071 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, ®_val)); 1072 if (soc_reg_field_valid(unit, status_reg, BUCKET_IDXf)) { 1073 bucket_index = 1074 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDXf); 1075 multiple = 1076 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf); 1077 bitmap = 1078 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf); 1079 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf); 1080 } else if (soc_reg_field_valid(unit, status_reg, BUCKET_IDX_0f)) { 1081 bucket_index = 1082 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDX_0f); 1083 if (MPLS_ENTRYm == info[table].mem) { 1084 multiple = 1085 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf); 1086 bitmap = 1087 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf); 1088 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf); 1089 } else { 1090 multiple = 1091 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERR_0f); 1092 bitmap = 1093 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BM_0f); 1094 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BM_0f); 1095 } 1096 } else if (soc_reg_field_valid(unit, status_reg, BUCKET_IDX_1f)) { 1097 bucket_index = 1098 soc_reg_field_get(unit, status_reg, reg_val, BUCKET_IDX_1f); 1099 if (MPLS_ENTRYm == info[table].mem) { 1100 multiple = 1101 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERRf); 1102 bitmap = 1103 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BMf); 1104 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BMf); 1105 } else { 1106 multiple = 1107 soc_reg_field_get(unit, status_reg, reg_val, MULTIPLE_ERR_1f); 1108 bitmap = 1109 soc_reg_field_get(unit, status_reg, reg_val, PARITY_ERR_BM_1f); 1110 size = soc_reg_field_length(unit, status_reg, PARITY_ERR_BM_1f); 1111 } 1112 } 1113 1114 if (multiple) { 1115 LOG_ERROR(BSL_LS_SOC_COMMON, 1116 (BSL_META_U(unit, 1117 "unit %d %s has multiple parity errors\n"), 1118 unit, msg)); 1119 } 1120 1121 if (bitmap != 0) { 1122 for (bits = 0; bits < size; bits++) { 1123 if (bitmap & (1 << bits)) { 1124 index = 1125 bucket_index * size * 2 + bits + (ix * size); 1126 if (info[table].mem == L2Xm) { 1127 /* Check the valid index range before reporting the error.*/ 1128 if (index > soc_mem_index_max(unit, L2Xm)){ 1129 LOG_ERROR(BSL_LS_SOC_COMMON, 1130 (BSL_META_U(unit, 1131 "L2X entry parity error index" 1132 " %d out of valid range !\n"), 1133 index)); 1134 continue; 1135 } 1136 } 1137 _soc_enduro_mem_parity_info(unit, block, 1138 info[table].error_field, &minfo); 1139 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1140 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1141 index, minfo); 1142 1143 LOG_ERROR(BSL_LS_SOC_COMMON, 1144 (BSL_META_U(unit, 1145 "unit %d %s entry %d parity error\n"), 1146 unit, msg, index)); 1147 1148 if (info[table].mem != INVALIDm) { 1149 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 1150 spci.reg = INVALIDr; 1151 spci.mem = info[table].mem; 1152 spci.blk_type = block; 1153 spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index); 1154 rv = soc_ser_correction(unit, &spci); 1155 if (SOC_FAILURE(rv)) { 1156 soc_event_generate(unit, 1157 SOC_SWITCH_EVENT_PARITY_ERROR, 1158 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1159 index, minfo); 1160 } 1161 } 1162 } 1163 } 1164 } 1165 1166 /* Clear parity status */ 1167 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 1168 } 1169 1170 return SOC_E_NONE; 1171 } 1172 1173 STATIC int 1174 _soc_enduro_parity_mmu_clear(int unit, soc_field_t status_field) 1175 { 1176 uint32 rval; 1177 SOC_IF_ERROR_RETURN 1178 (READ_MEM_FAIL_INT_STATr(unit, &rval)); 1179 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, status_field, 0); 1180 SOC_IF_ERROR_RETURN 1181 (WRITE_MEM_FAIL_INT_STATr(unit, rval)); 1182 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1183 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 1184 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1185 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1186 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 1187 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1188 return SOC_E_NONE; 1189 } 1190 1191 STATIC int 1192 _soc_enduro_process_mmu_parity_error(int unit, int group, 1193 soc_port_t block_port, int table, 1194 char *msg, soc_block_t block) 1195 { 1196 _soc_parity_info_t *info; 1197 soc_reg_t status_reg, index_reg, group_reg; 1198 uint32 addr, reg_val, group_status, minfo; 1199 int index, rv; 1200 _soc_ser_correct_info_t spci; 1201 1202 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1203 1204 info = _soc_en_parity_group_info[group].info; 1205 group_reg = _soc_en_parity_group_info[group].status_reg; 1206 addr = soc_reg_addr(unit, group_reg, block_port, 0); 1207 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_status)); 1208 1209 status_reg = info[table].intr_status1_reg; 1210 index_reg = info[table].intr_status0_reg; 1211 if (index_reg == INVALIDr) { 1212 LOG_ERROR(BSL_LS_SOC_COMMON, 1213 (BSL_META_U(unit, 1214 "unit %d %s parity error\n"), 1215 unit, msg)); 1216 return SOC_E_NONE; 1217 } 1218 if (status_reg != INVALIDr) { 1219 addr = soc_reg_addr(unit, status_reg, block_port, 0); 1220 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, ®_val)); 1221 if (reg_val == 0) { 1222 LOG_ERROR(BSL_LS_SOC_COMMON, 1223 (BSL_META_U(unit, 1224 "unit %d %s: parity hardware inconsistency\n"), 1225 unit, msg)); 1226 return SOC_E_NONE; 1227 } 1228 } 1229 addr = soc_reg_addr(unit, index_reg, block_port, 0); 1230 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, ®_val)); 1231 index = reg_val; 1232 _soc_enduro_mem_parity_info(unit, block, 1233 info[table].error_field, &minfo); 1234 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1235 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1236 index, minfo); 1237 1238 LOG_ERROR(BSL_LS_SOC_COMMON, 1239 (BSL_META_U(unit, 1240 "unit %d %s entry %d parity error\n"), 1241 unit, msg, index)); 1242 1243 if (info[table].mem != INVALIDm) { 1244 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 1245 spci.reg = INVALIDr; 1246 spci.mem = info[table].mem; 1247 spci.blk_type = block; 1248 spci.index = soc_enduro_mem_index_remap(unit, spci.mem, index); 1249 rv = soc_ser_correction(unit, &spci); 1250 if (SOC_FAILURE(rv)) { 1251 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1252 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1253 index, minfo); 1254 } 1255 } 1256 1257 /* update soc stats for some cases */ 1258 if (info[table].error_field == CCP_PAR_ERRf) { 1259 SOC_CONTROL(unit)->stat.err_cpcrc++; 1260 } else if (info[table].error_field == CFAP_PAR_ERRf) { 1261 SOC_CONTROL(unit)->stat.err_cfap++; 1262 } 1263 SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, info[table].error_field)); 1264 return SOC_E_NONE; 1265 } 1266 1267 STATIC int 1268 _soc_enduro_process_mmu_ipmc_parity_error(int unit, _soc_parity_info_t *info, 1269 soc_port_t block_port, soc_block_t block) 1270 { 1271 static soc_mem_t ipmc_mems[] = 1272 { 1273 MMU_IPMC_GROUP_TBL0m, 1274 MMU_IPMC_GROUP_TBL1m, 1275 MMU_IPMC_GROUP_TBL2m, 1276 MMU_IPMC_GROUP_TBL3m 1277 }; 1278 static soc_field_t ipmc_mem_fields[] = 1279 { 1280 IGPERR0f, 1281 IGPERR1f, 1282 IGPERR2f, 1283 IGPERR3f 1284 }; 1285 int index, rv; 1286 soc_reg_t mem_id_reg, index_reg; 1287 uint32 addr, mem_bitmap, entry_index, status, minfo; 1288 _soc_ser_correct_info_t spci; 1289 1290 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1291 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status)); 1292 if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, 1293 TOQ0_IPMC_TBL_PAR_ERRf)) { 1294 LOG_ERROR(BSL_LS_SOC_COMMON, 1295 (BSL_META_U(unit, 1296 "unit %d IPMC: parity hardware inconsistency\n"), 1297 unit)); 1298 return SOC_E_NONE; 1299 } 1300 /* 1301 * status0 (TOQ_IPMCGRPERRPTR0r) is index 1302 * status1 (TOQ_ERRINTR1r) is table id 1303 * MMU_IPMC_GROUP_TBL0m - MMU_IPMC_GROUP_TBL3m 1304 */ 1305 index_reg = info->intr_status0_reg; 1306 addr = soc_reg_addr(unit, index_reg, block_port, 0); 1307 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &entry_index)); 1308 mem_id_reg = info->intr_status1_reg; 1309 addr = soc_reg_addr(unit, mem_id_reg, block_port, 0); 1310 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &mem_bitmap)); 1311 for (index = 0; index < COUNTOF(ipmc_mem_fields); index++) { 1312 if (!soc_reg_field_get(unit, mem_id_reg, mem_bitmap, 1313 ipmc_mem_fields[index])) { 1314 continue; 1315 } 1316 _soc_enduro_mem_parity_info(unit, block, 1317 info->error_field, &minfo); 1318 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1319 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1320 entry_index, minfo); 1321 LOG_ERROR(BSL_LS_SOC_COMMON, 1322 (BSL_META_U(unit, 1323 "unit %d IPMC%d entry %d parity error\n"), 1324 unit, index, entry_index)); 1325 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 1326 spci.reg = INVALIDr; 1327 spci.mem = ipmc_mems[index]; 1328 spci.blk_type = SOC_BLK_MMU; 1329 spci.index = soc_enduro_mem_index_remap(unit, spci.mem, entry_index); 1330 rv = soc_ser_correction(unit, &spci); 1331 if (SOC_FAILURE(rv)) { 1332 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1333 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1334 entry_index, minfo); 1335 } 1336 /* Clear memory id register explicitly */ 1337 soc_reg_field_set(unit, mem_id_reg, &mem_bitmap, ipmc_mem_fields[index], 0); 1338 addr = soc_reg_addr(unit, mem_id_reg, block_port, 0); 1339 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, mem_bitmap)); 1340 break; 1341 } 1342 SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, TOQ0_IPMC_TBL_PAR_ERRf)); 1343 return SOC_E_NONE; 1344 } 1345 1346 STATIC int 1347 _soc_enduro_process_mmu_e2efc_parity_error(int unit, _soc_parity_info_t *info, 1348 soc_port_t block_port, soc_block_t block) 1349 { 1350 static soc_reg_t e2efc_regs[] = { 1351 INVALIDr, 1352 E2EFC_CNT_SET_LIMITr, 1353 E2EFC_CNT_RESET_LIMITr, 1354 E2EFC_CNT_DISC_LIMITr 1355 }; 1356 int rv; 1357 soc_reg_t err_reg; 1358 uint32 reg_val, val, status, entry_index, mem_id, minfo; 1359 _soc_ser_correct_info_t spci; 1360 1361 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1362 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status)); 1363 if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, E2EFC_PAR_ERRf)) { 1364 LOG_ERROR(BSL_LS_SOC_COMMON, 1365 (BSL_META_U(unit, 1366 "unit %d E2EFC: parity hardware inconsistency\n"), 1367 unit)); 1368 return SOC_E_NONE; 1369 } 1370 1371 err_reg = E2EFC_PARITYERRORPTRr; 1372 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, err_reg, 1373 block_port, 0, ®_val)); 1374 1375 /* Disable parity */ 1376 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1377 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0); 1378 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1379 1380 mem_id = soc_reg_field_get(unit, err_reg, reg_val, INSTf); 1381 /* CHECK if the error is valid */ 1382 if (mem_id == 0) { 1383 LOG_ERROR(BSL_LS_SOC_COMMON, 1384 (BSL_META_U(unit, 1385 "unit %d E2EFC: parity hardware inconsistency\n"), 1386 unit)); 1387 return SOC_E_NONE; 1388 } 1389 entry_index = soc_reg_field_get(unit, err_reg, reg_val, PTRf); 1390 1391 _soc_enduro_mem_parity_info(unit, block, 1392 info->error_field, &minfo); 1393 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1394 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1395 entry_index, minfo); 1396 LOG_ERROR(BSL_LS_SOC_COMMON, 1397 (BSL_META_U(unit, 1398 "unit %d E2EFC entry %d parity error\n"), 1399 unit, entry_index)); 1400 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 1401 spci.reg = e2efc_regs[mem_id]; 1402 spci.mem = INVALIDm; 1403 spci.blk_type = SOC_BLK_MMU; 1404 spci.index = entry_index; 1405 rv = soc_ser_correction(unit, &spci); 1406 if (SOC_FAILURE(rv)) { 1407 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1408 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1409 entry_index, minfo); 1410 } 1411 SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, E2EFC_PAR_ERRf)); 1412 /* Enable parity */ 1413 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1414 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1); 1415 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1416 return SOC_E_NONE; 1417 } 1418 1419 STATIC int 1420 _soc_enduro_process_mmu_mtro_parity_error(int unit, _soc_parity_info_t *info, 1421 soc_port_t block_port, soc_block_t block) 1422 { 1423 static soc_reg_t mtro_regs[] = { 1424 MINBUCKETCONFIG_64r, 1425 MINBUCKETr, 1426 MAXBUCKETCONFIG_64r, 1427 MAXBUCKETr 1428 }; 1429 static soc_reg_t cpu_mtro_regs[] = { 1430 CPUMAXBUCKETCONFIG_64r, 1431 CPUMAXBUCKETr 1432 }; 1433 uint32 i, addr, status, val, minfo, index = 0; 1434 _soc_ser_correct_info_t spci; 1435 int rv, port = 0; 1436 1437 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1438 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 1439 spci.mem = INVALIDm; 1440 spci.blk_type = SOC_BLK_MMU; 1441 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status)); 1442 if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, MTRO_PAR_ERRf)) { 1443 LOG_ERROR(BSL_LS_SOC_COMMON, 1444 (BSL_META_U(unit, 1445 "unit %d MTRO: parity hardware inconsistency\n"), 1446 unit)); 1447 return SOC_E_NONE; 1448 } 1449 SOC_IF_ERROR_RETURN(READ_EGRSHAPEPARITYERRORPTRr(unit, &addr)); 1450 1451 /* Disable parity */ 1452 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1453 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0); 1454 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1455 1456 if (addr < 8) { 1457 /* port lb0 */ 1458 port = 1; 1459 index = addr; 1460 } else if (addr >= 0x40 && addr <= 0x6f) { 1461 /* port ge0 ~ ge5 */ 1462 port = ((addr - 0x40) / 0x8) + 0x2; 1463 index = (addr - 0x40) % 0x8; 1464 } else if (addr >= 0x80 && addr <= 0xaf) { 1465 /* port ge6 ~ ge11 */ 1466 port = ((addr - 0x80) / 0x8) + 0x8; 1467 index = (addr - 0x80) % 0x8; 1468 } else if (addr >= 0xc0 && addr <= 0xef) { 1469 /* port ge12 ~ ge17 */ 1470 port = ((addr - 0xc0) / 0x8) + 0xe; 1471 index = (addr - 0xc0) % 0x8; 1472 } else if (addr >= 0x100 && addr <= 0x12f) { 1473 /* port ge18 ~ ge23 */ 1474 port = ((addr - 0x100) / 0x8) + 0x14; 1475 index = (addr - 0x100) % 0x8; 1476 } else if (addr >= 0x140 && addr <= 0x16f) { 1477 /* port hg0 ~ hg1 */ 1478 port = ((addr - 0x140) / 0x18) + 0x1a; 1479 index = (addr - 0x140) % 0x18; 1480 } else if (addr >= 0x180 && addr <= 0x1af) { 1481 /* port hg2 ~ hg3 */ 1482 port = ((addr - 0x180) / 0x18) + 0x1c; 1483 index = (addr - 0x180) % 0x18; 1484 } else if (addr >= 0x1c0 && addr <= 0x1c7) { 1485 /* port hg0 ~ hg3 */ 1486 port = ((addr - 0x1c0) / 0x2) + 0x1a; 1487 index = (addr - 0x1c0) % 0x2 + 0x18; 1488 } else if (addr >= 0x200 && addr <= 0x22f) { 1489 port = REG_PORT_ANY; 1490 index = (addr - 0x200) % 0x30; 1491 } 1492 if (port == REG_PORT_ANY) { 1493 for (i = 0; i < COUNTOF(cpu_mtro_regs); i++) { 1494 spci.port = port; 1495 spci.index = index; 1496 spci.reg = cpu_mtro_regs[i]; 1497 _soc_enduro_mem_parity_info(unit, block, 1498 info->error_field, &minfo); 1499 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1500 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1501 index, minfo); 1502 rv = soc_ser_correction(unit, &spci); 1503 if (SOC_FAILURE(rv)) { 1504 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1505 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1506 index, minfo); 1507 } 1508 } 1509 } else if (port >=1 && port <= 29) { 1510 for (i = 0; i < COUNTOF(mtro_regs); i++) { 1511 spci.port = port; 1512 spci.index = index; 1513 spci.reg = mtro_regs[i]; 1514 _soc_enduro_mem_parity_info(unit, block, 1515 info->error_field, &minfo); 1516 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1517 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1518 index, minfo); 1519 rv = soc_ser_correction(unit, &spci); 1520 if (SOC_FAILURE(rv)) { 1521 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1522 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1523 index, minfo); 1524 } 1525 } 1526 } else { 1527 LOG_ERROR(BSL_LS_SOC_COMMON, 1528 (BSL_META_U(unit, 1529 "unit %d MTRO: parity hardware inconsistency\n"), 1530 unit)); 1531 } 1532 SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, MTRO_PAR_ERRf)); 1533 /* Enable parity */ 1534 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1535 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1); 1536 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1537 return SOC_E_NONE; 1538 } 1539 1540 STATIC int 1541 _soc_enduro_process_mmu_wred_parity_error(int unit, _soc_parity_info_t *info, 1542 soc_port_t block_port, soc_block_t block) 1543 { 1544 int rv; 1545 soc_mem_t mem; 1546 soc_reg_t mem_id_reg, index_reg; 1547 uint32 addr, mem_bitmap, entry_index, status, minfo; 1548 _soc_ser_correct_info_t spci; 1549 1550 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1551 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status)); 1552 if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, WRED_PAR_ERRf)) { 1553 LOG_ERROR(BSL_LS_SOC_COMMON, 1554 (BSL_META_U(unit, 1555 "unit %d WRED: parity hardware inconsistency\n"), 1556 unit)); 1557 return SOC_E_NONE; 1558 } 1559 /* 1560 * status0 (WRED_PARITY_ERROR_INFOr) is index 1561 * status1 (WRED_PARITY_ERROR_BITMAPr) is table id 1562 */ 1563 index_reg = info->intr_status0_reg; 1564 addr = soc_reg_addr(unit, index_reg, block_port, 0); 1565 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &entry_index)); 1566 1567 mem_id_reg = info->intr_status1_reg; 1568 addr = soc_reg_addr(unit, mem_id_reg, block_port, 0); 1569 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &mem_bitmap)); 1570 1571 if (mem_bitmap & 0x000003) { 1572 mem = MMU_WRED_CFG_CELLm; 1573 } else if (mem_bitmap & 0x00000c) { 1574 mem = MMU_WRED_THD_0_CELLm; 1575 } else if (mem_bitmap & 0x000030) { 1576 mem = MMU_WRED_THD_1_CELLm; 1577 } else if (mem_bitmap & 0x0000c0) { 1578 mem = MMU_WRED_CFG_PACKETm; 1579 } else if (mem_bitmap & 0x000300) { 1580 mem = MMU_WRED_THD_0_PACKETm; 1581 } else if (mem_bitmap & 0x000c00) { 1582 mem = MMU_WRED_THD_1_PACKETm; 1583 } else if (mem_bitmap & 0x003000) { 1584 mem = MMU_WRED_PORT_CFG_CELLm; 1585 } else if (mem_bitmap & 0x00c000) { 1586 mem = MMU_WRED_PORT_THD_0_CELLm; 1587 } else if (mem_bitmap & 0x030000) { 1588 mem = MMU_WRED_PORT_THD_1_CELLm; 1589 } else if (mem_bitmap & 0x0c0000) { 1590 mem = MMU_WRED_PORT_CFG_PACKETm; 1591 } else if (mem_bitmap & 0x300000) { 1592 mem = MMU_WRED_PORT_THD_0_PACKETm; 1593 } else if (mem_bitmap & 0xc00000) { 1594 mem = MMU_WRED_PORT_THD_1_PACKETm; 1595 } else { 1596 mem = INVALIDm; 1597 } 1598 if (mem != INVALIDm) { 1599 _soc_enduro_mem_parity_info(unit, block, info->error_field, &minfo); 1600 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1601 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1602 entry_index, minfo); 1603 LOG_ERROR(BSL_LS_SOC_COMMON, 1604 (BSL_META_U(unit, 1605 "unit %d %s entry %d parity error\n"), 1606 unit, SOC_MEM_NAME(unit, mem), entry_index)); 1607 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 1608 spci.reg = INVALIDr; 1609 spci.mem = mem; 1610 spci.blk_type = block; 1611 spci.index = soc_enduro_mem_index_remap(unit, spci.mem, entry_index); 1612 rv = soc_ser_correction(unit, &spci); 1613 if (SOC_FAILURE(rv)) { 1614 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1615 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1616 entry_index, minfo); 1617 } 1618 } else { 1619 LOG_ERROR(BSL_LS_SOC_COMMON, 1620 (BSL_META_U(unit, 1621 "unit %d WRED: parity hardware inconsistency\n"), 1622 unit)); 1623 } 1624 SOC_IF_ERROR_RETURN(_soc_enduro_parity_mmu_clear(unit, WRED_PAR_ERRf)); 1625 return SOC_E_NONE; 1626 } 1627 1628 STATIC int 1629 _soc_enduro_process_parity_error(int unit) 1630 { 1631 int group, table; 1632 uint32 addr, cmic_status, group_status; 1633 uint32 group_enable, cpi_blk_bit, minfo; 1634 1635 _soc_parity_info_t *info; 1636 soc_reg_t group_reg, reg; 1637 soc_port_t block_port; 1638 soc_block_t blk; 1639 char *msg; 1640 soc_enduro_oam_handler_t oam_handler_snapshot; 1641 1642 /* coverity[result_independent_of_operands] */ 1643 SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit, 1644 &cmic_status)); 1645 1646 /* loop through each group */ 1647 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 1648 info = _soc_en_parity_group_info[group].info; 1649 group_reg = _soc_en_parity_group_info[group].status_reg; 1650 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1651 (BSL_META_U(unit, 1652 "unit %d %s parity processing\n"), 1653 unit, SOC_REG_NAME(unit, group_reg))); 1654 cpi_blk_bit = _soc_en_parity_group_info[group].cpi_bit; 1655 1656 SOC_BLOCK_ITER(unit, blk, 1657 _soc_en_parity_group_info[group].blocktype) { 1658 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 1659 cpi_blk_bit <<= 1; 1660 continue; 1661 } 1662 if (!(cmic_status & cpi_blk_bit)) { 1663 cpi_blk_bit <<= 1; 1664 continue; 1665 } 1666 1667 addr = soc_reg_addr(unit, group_reg, block_port, 0); 1668 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_status)); 1669 1670 /* loop through each table in the group */ 1671 for (table = 0; info[table].error_field != INVALIDf; table++) { 1672 if (!soc_reg_field_valid(unit, group_reg, 1673 info[table].error_field) && 1674 (info[table].mem != INVALIDm)) { 1675 LOG_ERROR(BSL_LS_SOC_COMMON, 1676 (BSL_META_U(unit, 1677 "unit %d %s has bad error field\n"), 1678 unit, SOC_MEM_NAME(unit, info[table].mem))); 1679 continue; 1680 } 1681 1682 if (!soc_reg_field_get(unit, group_reg, group_status, 1683 info[table].error_field)) { 1684 continue; 1685 } 1686 if (info[table].msg) { 1687 msg = info[table].msg; 1688 } else if (info[table].mem != INVALIDm) { 1689 msg = SOC_MEM_NAME(unit, info[table].mem); 1690 } else { 1691 msg = SOC_FIELD_NAME(unit, info[table].error_field); 1692 } 1693 1694 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1695 (BSL_META_U(unit, 1696 "unit %d %s analysis\n"), 1697 unit, msg)); 1698 1699 /* Handle different parity error reporting style */ 1700 switch (info[table].type) { 1701 case _SOC_PARITY_INFO_TYPE_GENERIC: 1702 _soc_enduro_mem_parity_info(unit, blk, 1703 info[table].error_field, 1704 &minfo); 1705 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1706 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1707 0, minfo); 1708 1709 if (info[table].enable_field == START_BY_START_ERR_ENf) { 1710 uint64 rr64; 1711 uint32 msw; 1712 uint32 lsw; 1713 uint32 regval; 1714 1715 /* Clear the START_BY_START port bitmap */ 1716 SOC_IF_ERROR_RETURN 1717 (READ_START_BY_START_ERRORr(unit, &rr64)); 1718 COMPILER_64_TO_32_HI(msw, rr64); 1719 COMPILER_64_TO_32_LO(lsw, rr64); 1720 LOG_ERROR(BSL_LS_SOC_COMMON, 1721 (BSL_META_U(unit, 1722 "unit %d START_BY_START_ERRROR" 1723 " = 0x%x%08x\n"), 1724 unit, msw, lsw)); 1725 COMPILER_64_ZERO(rr64); 1726 SOC_IF_ERROR_RETURN 1727 (WRITE_START_BY_START_ERRORr(unit, rr64)); 1728 1729 /* Clear the START_BY_START error indication */ 1730 SOC_IF_ERROR_RETURN 1731 (READ_MEM_FAIL_INT_STATr(unit, ®val)); 1732 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, ®val, 1733 START_BY_START_ERRf, 0); 1734 SOC_IF_ERROR_RETURN 1735 (WRITE_MEM_FAIL_INT_STATr(unit, regval)); 1736 } else if (info[table].enable_field 1737 == DEQ0_CELLCRC_ERR_ENf) { 1738 uint32 regval; 1739 1740 /* Clear the DEQ0_CELLCRC error indication */ 1741 SOC_IF_ERROR_RETURN 1742 (READ_MEM_FAIL_INT_STATr(unit, ®val)); 1743 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, ®val, 1744 DEQ0_CELLCRC_ERRf, 0); 1745 SOC_IF_ERROR_RETURN 1746 (WRITE_MEM_FAIL_INT_STATr(unit, regval)); 1747 } 1748 1749 LOG_ERROR(BSL_LS_SOC_COMMON, 1750 (BSL_META_U(unit, 1751 "unit %d %s asserted\n"), 1752 unit, msg)); 1753 break; 1754 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY: 1755 SOC_IF_ERROR_RETURN 1756 (_soc_enduro_process_single_parity_error(unit, 1757 group, block_port, table, FALSE, msg, blk)); 1758 break; 1759 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC: 1760 SOC_IF_ERROR_RETURN 1761 (_soc_enduro_process_single_ecc_error(unit, 1762 group, block_port, table, FALSE, msg, blk)); 1763 break; 1764 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY: 1765 SOC_IF_ERROR_RETURN 1766 (_soc_enduro_process_dual_parity_error(unit, 1767 group, block_port, table, FALSE, msg, blk)); 1768 break; 1769 case _SOC_PARITY_INFO_TYPE_MMU_PARITY: 1770 SOC_IF_ERROR_RETURN 1771 (_soc_enduro_process_mmu_parity_error(unit, 1772 group, block_port, table, msg, blk)); 1773 break; 1774 case _SOC_PARITY_INFO_TYPE_MMUMTRO: 1775 SOC_IF_ERROR_RETURN 1776 (_soc_enduro_process_mmu_mtro_parity_error(unit, 1777 &info[table], block_port, blk)); 1778 break; 1779 case _SOC_PARITY_INFO_TYPE_MMUE2EFC: 1780 SOC_IF_ERROR_RETURN 1781 (_soc_enduro_process_mmu_e2efc_parity_error(unit, 1782 &info[table], block_port, blk)); 1783 break; 1784 case _SOC_PARITY_INFO_TYPE_MMUIPMC: 1785 SOC_IF_ERROR_RETURN 1786 (_soc_enduro_process_mmu_ipmc_parity_error(unit, 1787 &info[table], block_port, blk)); 1788 break; 1789 case _SOC_PARITY_INFO_TYPE_MMUWRED: 1790 SOC_IF_ERROR_RETURN 1791 (_soc_enduro_process_mmu_wred_parity_error(unit, 1792 &info[table], block_port, blk)); 1793 break; 1794 case _SOC_PARITY_INFO_TYPE_OAM: 1795 /* OAM isn't parity-related but shares an interrupt */ 1796 1797 oam_handler_snapshot = en_oam_handler[unit]; 1798 1799 if (oam_handler_snapshot != NULL) 1800 { 1801 SOC_IF_ERROR_RETURN(oam_handler_snapshot(unit, 1802 info[table].error_field)); 1803 } 1804 1805 break; 1806 default: 1807 break; 1808 } /* handle different parity error reporting style */ 1809 } /* loop through each table in the group */ 1810 1811 reg = _soc_en_parity_group_info[group].enable_reg; 1812 addr = soc_reg_addr(unit, reg, block_port, 0); 1813 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &group_enable)); 1814 /* Exclude non-parity status bits */ 1815 group_status &= group_enable; 1816 group_enable &= ~group_status; 1817 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable)); 1818 group_enable |= group_status; 1819 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, group_enable)); 1820 } /* loop through each block for the group */ 1821 } /* loop through each group */ 1822 1823 return SOC_E_NONE; 1824 } 1825 1826 1827 void 1828 soc_enduro_parity_error(void *unit_vp, void *d1, void *d2, 1829 void *d3, void *d4) 1830 { 1831 int unit = PTR_TO_INT(unit_vp); 1832 1833 _soc_enduro_process_parity_error(unit); 1834 soc_intr_enable(unit, IRQ_MEM_FAIL); 1835 } 1836 1837 STATIC int 1838 _soc_enduro_mem_nack_error_process(int unit, _enduro_ser_nack_reg_mem_t nack_reg_mem, 1839 soc_block_t block, int reg_mem) 1840 { 1841 int group, table; 1842 _soc_parity_info_t *info; 1843 soc_port_t block_port; 1844 soc_block_t blk; 1845 char *msg; 1846 1847 if (nack_reg_mem.mem == INVALIDm) { 1848 return SOC_E_PARAM; 1849 } 1850 1851 /* loop through each group */ 1852 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 1853 info = _soc_en_parity_group_info[group].info; 1854 1855 SOC_BLOCK_ITER(unit, blk, 1856 _soc_en_parity_group_info[group].blocktype) { 1857 if (block != SOC_BLOCK_INFO(unit, blk).schan) { 1858 continue; 1859 } 1860 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 1861 continue; 1862 } 1863 /* loop through each table in the group */ 1864 for (table = 0; info[table].error_field != INVALIDf; table++) { 1865 if (info[table].mem != nack_reg_mem.mem) { 1866 continue; 1867 } 1868 if (info[table].nack_status0_reg == INVALIDr) { 1869 return SOC_E_NONE; 1870 } 1871 if (info[table].msg) { 1872 msg = info[table].msg; 1873 } else { /* mem must be valid to get her */ 1874 msg = SOC_MEM_NAME(unit, info[table].mem); 1875 } 1876 1877 /* handle different parity error reporting style */ 1878 switch (info[table].type) { 1879 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY: 1880 SOC_IF_ERROR_RETURN 1881 (_soc_enduro_process_single_parity_error(unit, 1882 group, block_port, table, TRUE, msg, block)); 1883 break; 1884 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC: 1885 SOC_IF_ERROR_RETURN 1886 (_soc_enduro_process_single_ecc_error(unit, 1887 group, block_port, table, TRUE, msg, block)); 1888 break; 1889 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY: 1890 SOC_IF_ERROR_RETURN 1891 (_soc_enduro_process_dual_parity_error(unit, 1892 group, block_port, table, TRUE, msg, block)); 1893 break; 1894 default: 1895 break; 1896 } /* handle different parity error reporting style */ 1897 } /* loop through each table in the group */ 1898 } /* loop through each block of the group */ 1899 } /* loop through each group */ 1900 1901 return SOC_E_NONE; 1902 } 1903 1904 void 1905 soc_enduro_mem_nack(void *unit_vp, void *addr_vp, void *blk_vp, 1906 void *d3, void *d4) 1907 { 1908 soc_mem_t mem = INVALIDm; 1909 int reg_mem = PTR_TO_INT(d3); 1910 int rv, unit = PTR_TO_INT(unit_vp); 1911 uint32 address = PTR_TO_INT(addr_vp); 1912 uint32 block = PTR_TO_INT(blk_vp); 1913 uint32 offset = 0, min_addr = 0, max_addr = 0; 1914 soc_regaddrinfo_t ainfo; 1915 _enduro_ser_nack_reg_mem_t nack_reg_mem; 1916 nack_reg_mem.mem = INVALIDm; 1917 nack_reg_mem.reg = INVALIDr; 1918 1919 if (reg_mem == _SOC_ENDURO_SER_REG) { 1920 if (address) { 1921 soc_regaddrinfo_get(unit, &ainfo, address); 1922 nack_reg_mem.reg = ainfo.reg; 1923 } 1924 } else { 1925 offset = address & ~0xC0f00000; /* Strip block ID */ 1926 mem = soc_addr_to_mem(unit, address, &block); 1927 if (mem == INVALIDm) { 1928 LOG_ERROR(BSL_LS_SOC_COMMON, 1929 (BSL_META_U(unit, 1930 "unit %d mem decode failed, " 1931 "SCHAN NACK analysis failure\n"), unit)); 1932 return; 1933 } 1934 1935 nack_reg_mem.mem = mem; 1936 1937 min_addr = max_addr = SOC_MEM_INFO(unit, mem).base; 1938 min_addr += SOC_MEM_INFO(unit, mem).index_min; 1939 max_addr += SOC_MEM_INFO(unit, mem).index_max; 1940 } 1941 1942 if ((rv = _soc_enduro_mem_nack_error_process(unit, nack_reg_mem, (soc_block_t)block, 1943 reg_mem)) < 0) { 1944 if (reg_mem == _SOC_ENDURO_SER_REG) { 1945 LOG_ERROR(BSL_LS_SOC_COMMON, 1946 (BSL_META_U(unit, 1947 "unit %d REG SCHAN NACK analysis failure\n"), 1948 unit)); 1949 } else { 1950 LOG_ERROR(BSL_LS_SOC_COMMON, 1951 (BSL_META_U(unit, 1952 "unit %d %s entry %d SCHAN NACK analysis failure\n"), 1953 unit, SOC_MEM_NAME(unit, mem), 1954 min_addr - offset)); 1955 } 1956 } 1957 if (reg_mem == _SOC_ENDURO_SER_REG) { 1958 LOG_ERROR(BSL_LS_SOC_COMMON, 1959 (BSL_META_U(unit, 1960 "unit %d REG SCHAN NACK analysis\n"), 1961 unit)); 1962 } else { 1963 LOG_INFO(BSL_LS_SOC_SCHAN, 1964 (BSL_META_U(unit, 1965 "unit %d %s entry %d SCHAN NACK analysis\n"), 1966 unit, SOC_MEM_NAME(unit, mem), 1967 min_addr - offset)); 1968 } 1969 } 1970 1971 STATIC int 1972 _soc_enduro_mem_ecc_force(int unit, soc_port_t block_port, 1973 _soc_parity_info_t *info) 1974 { 1975 soc_reg_t force_sbe_reg, force_dbe_reg; 1976 soc_field_t force_field; 1977 1978 force_field = info->error_field; 1979 if (force_field == RX_FIFO_MEM_ERRf) { 1980 force_field = RX_FIFO_MEMf; 1981 } else if (force_field == TX_FIFO_MEM_ERRf) { 1982 force_field = TX_FIFO_MEMf; 1983 } 1984 1985 force_sbe_reg = info->intr_status1_reg; 1986 force_dbe_reg = info->nack_status1_reg; 1987 1988 /* Single-bit error force */ 1989 if (SOC_REG_IS_VALID(unit, force_sbe_reg) && 1990 soc_reg_field_valid(unit, force_sbe_reg, force_field)) { 1991 SOC_IF_ERROR_RETURN 1992 (soc_reg_field32_modify(unit, force_sbe_reg, 1993 block_port, force_field, 1)); 1994 } else { 1995 LOG_ERROR(BSL_LS_SOC_COMMON, 1996 (BSL_META_U(unit, 1997 "unit %d %s.%s not valid\n"), 1998 unit, SOC_REG_NAME(unit, force_sbe_reg), 1999 SOC_FIELD_NAME(unit, force_field))); 2000 } 2001 2002 sal_usleep(1000); /* Wait for interrupt-mode logic to kick in */ 2003 2004 /* Double-bit error force */ 2005 if (SOC_REG_IS_VALID(unit, force_dbe_reg) && 2006 soc_reg_field_valid(unit, force_dbe_reg, force_field)) { 2007 SOC_IF_ERROR_RETURN 2008 (soc_reg_field32_modify(unit, force_dbe_reg, 2009 block_port, force_field, 1)); 2010 } else { 2011 LOG_ERROR(BSL_LS_SOC_COMMON, 2012 (BSL_META_U(unit, 2013 "unit %d %s.%s not valid\n"), 2014 unit, SOC_REG_NAME(unit, force_dbe_reg), 2015 SOC_FIELD_NAME(unit, force_field))); 2016 } 2017 2018 return SOC_E_NONE; 2019 } 2020 2021 int 2022 _soc_enduro_mem_nack_error_test(int unit) 2023 { 2024 int group, table, index, rv; 2025 uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 2026 uint32 parity; 2027 _soc_parity_info_t *info; 2028 soc_mem_t mem; 2029 int index_min, index_max, index_range; 2030 soc_port_t block_port; 2031 soc_block_t blk; 2032 soc_field_t par_ecc_field; 2033 _enduro_ser_nack_reg_mem_t nack_reg_mem; 2034 2035 /* loop through each group */ 2036 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 2037 info = _soc_en_parity_group_info[group].info; 2038 2039 SOC_BLOCK_ITER(unit, blk, 2040 _soc_en_parity_group_info[group].blocktype) { 2041 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 2042 continue; 2043 } 2044 2045 for (table = 0; info[table].error_field != INVALIDf; table++) { 2046 mem = info[table].mem; 2047 if (mem == INVALIDm) { 2048 continue; 2049 } 2050 if ((info[table].control_reg == INVALIDr) || 2051 !soc_reg_field_valid(unit, info[table].control_reg, 2052 info[table].enable_field)) { 2053 LOG_ERROR(BSL_LS_SOC_COMMON, 2054 (BSL_META_U(unit, 2055 "unit %d %s has no parity toggle\n"), 2056 unit, SOC_MEM_NAME(unit, mem))); 2057 continue; 2058 } 2059 2060 index_min = soc_mem_index_min(unit, mem); 2061 index_max = soc_mem_index_max(unit, mem); 2062 index_range = index_max - index_min + 1; 2063 index = index_min + (index_range / 2); 2064 2065 if ((rv = soc_mem_write(unit, mem, blk, index, 2066 soc_mem_entry_null(unit, mem))) < 0) { 2067 LOG_ERROR(BSL_LS_SOC_COMMON, 2068 (BSL_META_U(unit, 2069 "unit %d %s entry %d mem write error\n"), 2070 unit, SOC_MEM_NAME(unit, mem), index)); 2071 continue; 2072 } 2073 2074 /* Disable parity */ 2075 SOC_IF_ERROR_RETURN 2076 (soc_reg_field32_modify(unit, info[table].control_reg, 2077 block_port, info[table].enable_field, 0)); 2078 2079 if ((rv = soc_mem_read(unit, mem, blk, index, tmp_entry)) < 0) { 2080 LOG_ERROR(BSL_LS_SOC_COMMON, 2081 (BSL_META_U(unit, 2082 "unit %d %s entry %d mem read error\n"), 2083 unit, SOC_MEM_NAME(unit, mem), index)); 2084 continue; 2085 } 2086 2087 switch (info[table].type) { 2088 case _SOC_PARITY_INFO_TYPE_SINGLE_PARITY: 2089 case _SOC_PARITY_INFO_TYPE_SINGLE_COUNTER: 2090 case _SOC_PARITY_INFO_TYPE_DUAL_PARITY: 2091 par_ecc_field = EVEN_PARITYf; 2092 if (mem == L3_ECMP_COUNTm) { 2093 par_ecc_field = EVEN_PARITY_0f; 2094 } 2095 break; 2096 case _SOC_PARITY_INFO_TYPE_SINGLE_ECC: 2097 if (block_port != REG_PORT_ANY) { 2098 /* Force registers exist */ 2099 SOC_IF_ERROR_RETURN 2100 (_soc_enduro_mem_ecc_force(unit, block_port, 2101 &(info[table]))); 2102 } 2103 par_ecc_field = ECCf; 2104 break; 2105 default: 2106 /* coverity[assigned_value] */ 2107 par_ecc_field = INVALIDf; 2108 continue; 2109 } 2110 2111 if (!soc_mem_field_valid(unit, mem, par_ecc_field)) { 2112 #if !defined(SOC_NO_NAMES) 2113 LOG_ERROR(BSL_LS_SOC_COMMON, 2114 (BSL_META_U(unit, 2115 "unit %d %s doesn't contain %s\n"), 2116 unit, SOC_MEM_NAME(unit, mem), 2117 soc_fieldnames[par_ecc_field])); 2118 #endif 2119 continue; 2120 } 2121 2122 parity = 2123 soc_mem_field32_get(unit, mem, tmp_entry, par_ecc_field); 2124 parity ^= 0x1; /* Bad parity */ 2125 soc_mem_field32_set(unit, mem, tmp_entry, par_ecc_field, parity); 2126 2127 2128 if ((rv = soc_mem_write(unit, mem, blk, index, tmp_entry)) < 0) { 2129 LOG_ERROR(BSL_LS_SOC_COMMON, 2130 (BSL_META_U(unit, 2131 "unit %d %s entry %d mem write error\n"), 2132 unit, SOC_MEM_NAME(unit, mem), index)); 2133 continue; 2134 } 2135 2136 /* Enable parity */ 2137 SOC_IF_ERROR_RETURN 2138 (soc_reg_field32_modify(unit, info[table].control_reg, 2139 block_port, info[table].enable_field, 1)); 2140 2141 if ((rv = soc_mem_read(unit, mem, blk, index, tmp_entry)) < 0) { 2142 if (rv == SOC_E_FAIL) { 2143 LOG_ERROR(BSL_LS_SOC_COMMON, 2144 (BSL_META_U(unit, 2145 "unit %d NACK received for %s entry %d:\n\t"), 2146 unit, SOC_MEM_NAME(unit, mem), index)); 2147 nack_reg_mem.mem = mem; 2148 if ((rv = _soc_enduro_mem_nack_error_process(unit, 2149 nack_reg_mem, blk, _SOC_ENDURO_SER_MEM)) < 0) { 2150 LOG_ERROR(BSL_LS_SOC_COMMON, 2151 (BSL_META_U(unit, 2152 "unit %d %s entry %d SCHAN NACK analysis failure\n"), 2153 unit, SOC_MEM_NAME(unit, mem), index)); 2154 } 2155 } else { 2156 LOG_ERROR(BSL_LS_SOC_COMMON, 2157 (BSL_META_U(unit, 2158 "unit %d %s entry %d mem read error\n"), 2159 unit, SOC_MEM_NAME(unit, mem), index)); 2160 } 2161 } else { 2162 LOG_ERROR(BSL_LS_SOC_COMMON, 2163 (BSL_META_U(unit, 2164 "unit %d %s entry %d mem parity induction failed\n"), 2165 unit, SOC_MEM_NAME(unit, mem), index)); 2166 } 2167 sal_usleep(1000); 2168 } 2169 } 2170 } 2171 2172 return SOC_E_NONE; 2173 } 2174 2175 STATIC int 2176 soc_enduro_pipe_mem_clear(int unit) 2177 { 2178 uint32 rval; 2179 int pipe_init_usec; 2180 soc_timeout_t to; 2181 2182 /* 2183 * Reset the IPIPE and EPIPE block 2184 */ 2185 rval = 0; 2186 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 2187 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 2188 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 2189 /* Set count to # entries in largest IPIPE table, L2_ENTRYm */ 2190 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x8000); 2191 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 2192 2193 rval = 0; 2194 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 2195 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 2196 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 2197 /* Set count to # entries in largest EPIPE table, EGR_L3_NEXT_HOPm */ 2198 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, 0x4000); 2199 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 2200 2201 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 2202 if (SAL_BOOT_SIMULATION) { 2203 pipe_init_usec = 10000000; 2204 } else { 2205 pipe_init_usec = 50000; 2206 } 2207 soc_timeout_init(&to, pipe_init_usec, 0); 2208 2209 /* Wait for IPIPE memory initialization done. */ 2210 do { 2211 SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval)); 2212 if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) { 2213 break; 2214 } 2215 if (soc_timeout_check(&to)) { 2216 LOG_WARN(BSL_LS_SOC_COMMON, 2217 (BSL_META_U(unit, 2218 "unit %d : ING_HW_RESET timeout\n"), unit)); 2219 break; 2220 } 2221 } while (TRUE); 2222 2223 /* Wait for EPIPE memory initialization done. */ 2224 do { 2225 SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval)); 2226 if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) { 2227 break; 2228 } 2229 if (soc_timeout_check(&to)) { 2230 LOG_WARN(BSL_LS_SOC_COMMON, 2231 (BSL_META_U(unit, 2232 "unit %d : EGR_HW_RESET timeout\n"), unit)); 2233 break; 2234 } 2235 } while (TRUE); 2236 2237 rval = 0; 2238 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 2239 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 2240 2241 SOC_IF_ERROR_RETURN 2242 (soc_mem_clear(unit, XQPORT_EHG_RX_TUNNEL_DATAm, COPYNO_ALL, TRUE)); 2243 SOC_IF_ERROR_RETURN 2244 (soc_mem_clear(unit, XQPORT_EHG_RX_TUNNEL_MASKm, COPYNO_ALL, TRUE)); 2245 SOC_IF_ERROR_RETURN 2246 (soc_mem_clear(unit, XQPORT_EHG_TX_TUNNEL_DATAm, COPYNO_ALL, TRUE)); 2247 2248 /* LMEP and LMEP_1 table is not properly handled by reset control */ 2249 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, LMEPm, COPYNO_ALL, TRUE)); 2250 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, LMEP_1m, COPYNO_ALL, TRUE)); 2251 2252 return SOC_E_NONE; 2253 } 2254 2255 /* SER processing for TCAMs */ 2256 STATIC _soc_ser_parity_info_t _soc_enduro_ser_parity_info[] = { 2257 { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 2258 CMIC_SER_START_ADDR_0r, CMIC_SER_END_ADDR_0r, 2259 CMIC_SER_MEM_ADDR_0r, CMIC_SER_PARITY_MODE_SELr, 2260 RANGE_0_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ}, 2261 { EGR_ERSPANm, _SOC_SER_PARITY_MODE_2BITS, 2262 CMIC_SER_START_ADDR_1r, CMIC_SER_END_ADDR_1r, 2263 CMIC_SER_MEM_ADDR_1r, CMIC_SER_PARITY_MODE_SELr, 2264 RANGE_1_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ}, 2265 { FP_SLICE_MAPm, _SOC_SER_PARITY_MODE_2BITS, 2266 CMIC_SER_START_ADDR_2r, CMIC_SER_END_ADDR_2r, 2267 CMIC_SER_MEM_ADDR_2r, CMIC_SER_PARITY_MODE_SELr, 2268 RANGE_2_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ}, 2269 { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 2270 CMIC_SER_START_ADDR_3r, CMIC_SER_END_ADDR_3r, 2271 CMIC_SER_MEM_ADDR_3r, CMIC_SER_PARITY_MODE_SELr, 2272 RANGE_3_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ}, 2273 { MPLS_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 2274 CMIC_SER_START_ADDR_4r, CMIC_SER_END_ADDR_4r, 2275 CMIC_SER_MEM_ADDR_4r, CMIC_SER_PARITY_MODE_SELr, 2276 RANGE_4_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ}, 2277 { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 2278 CMIC_SER_START_ADDR_5r, CMIC_SER_END_ADDR_5r, 2279 CMIC_SER_MEM_ADDR_5r, CMIC_SER_PARITY_MODE_SELr, 2280 RANGE_5_PARITY_BITSf, -1, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_XY_READ}, 2281 { INVALIDm, _SOC_SER_PARITY_MODE_NUM}, 2282 }; 2283 2284 #define SOC_ENDURO_SER_MEM_AVAILABLE (2048 * 32) /* bits */ 2285 2286 STATIC int 2287 _soc_enduro_ser_init(int unit) 2288 { 2289 return soc_ser_init(unit, _soc_enduro_ser_parity_info, 2290 SOC_ENDURO_SER_MEM_AVAILABLE); 2291 } 2292 2293 void 2294 soc_enduro_ser_fail(int unit) 2295 2296 { 2297 soc_process_ser_parity_error(unit, _soc_enduro_ser_parity_info, 2298 SOC_SWITCH_EVENT_DATA_ERROR_PARITY); 2299 return; 2300 } 2301 2302 uint32 tdm[84] = {2,10,18,26,27,28,29, 2303 3,11,19,26,27,28,29, 2304 4,12,20,26,27,28,29, 2305 5,13,21,26,27,28,29, 2306 6,14,22,26,27,28,29, 2307 7,15,23,26,27,28,29, 2308 8,16,24,26,27,28,29, 2309 9,17,25,26,27,28,29, 2310 1,30,30,26,27,28,29, 2311 1,30,30,26,27,28,29, 2312 1,30,30,26,27,28,29, 2313 0,30,30,26,27,28,29}; 2314 2315 uint32 tdm_56333_lp[56] = {2,10,1,30,30,30,30, 2316 3,11,1,30,30,30,30, 2317 4,12,30,30,30,30,30, 2318 5,13,30,30,30,30,30, 2319 6,14,0,30,30,30,30, 2320 7,15,30,30,30,30,30, 2321 8,16,30,30,30,30,30, 2322 9,17,30,30,30,30,30}; 2323 2324 uint32 tdm_56333_ge_linerate[84] = {2,10,18,26,27,28,29, 2325 3,11,19,26,27,28,29, 2326 4,12,20,26,27,28,29, 2327 5,13,21,26,27,28,29, 2328 6,14,22,26,27,28,29, 2329 7,15,23,30,30,0,30, 2330 8,16,24,30,30,0,1, 2331 9,17,25,30,30,30,1, 2332 30,30,30,30,30,30,30, 2333 30,30,30,30,30,30,30, 2334 30,30,30,30,30,30,30, 2335 30,30,30,30,30,0,30}; 2336 2337 int 2338 soc_enduro_misc_init(int unit) 2339 { 2340 #define NUM_XQPORT 4 2341 uint32 rval; 2342 uint32 prev_reg_addr; 2343 uint64 reg64; 2344 int port, i; 2345 uint32 mode; 2346 uint32 *arr; 2347 int tdm_size; 2348 iarb_tdm_table_entry_t iarb_tdm; 2349 arb_tdm_table_entry_t arb_tdm; 2350 uint64 multipass; 2351 uint16 dev_id; 2352 uint8 rev_id; 2353 uint32 bm; 2354 soc_field_t fields[3]; 2355 uint32 values[3]; 2356 soc_pbmp_t pbmp_ge_linerate; 2357 2358 /* set the mode for XQPORT blocks */ 2359 PBMP_XQ_ITER(unit, port) { 2360 mode = 1; /* gport-mode */ 2361 if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) { 2362 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE); 2363 mode = 2; /* xport-mode */ 2364 } 2365 SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval)); 2366 soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, 2367 XQPORT_MODE_BITSf, mode); 2368 SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval)); 2369 } 2370 2371 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 2372 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 1); 2373 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 2374 2375 /* Program for Different TDM mode */ 2376 soc_cm_get_id(unit, &dev_id, &rev_id); 2377 if((dev_id == BCM56333_DEVICE_ID) || (dev_id == BCM56331_DEVICE_ID)){ 2378 SOC_PBMP_CLEAR(pbmp_ge_linerate); 2379 pbmp_ge_linerate = soc_property_get_pbmp_default(unit, 2380 spn_BCM56333_PBMP_GE_LINERATE, pbmp_ge_linerate); 2381 if (SOC_PBMP_NOT_NULL(pbmp_ge_linerate)) { 2382 /* Use config variable to decide which 12 ports out of 24 2383 get guarantee line rate bandwidth on 56333 */ 2384 i = 0; 2385 SOC_PBMP_ITER(pbmp_ge_linerate, port) { 2386 if ((i % 4) == 0) { 2387 tdm_56333_ge_linerate[56 + (i / 4)] = port; 2388 } else if ((i % 4) == 1) { 2389 tdm_56333_ge_linerate[63 + (i / 4)] = port; 2390 } else if ((i % 4) == 2) { 2391 tdm_56333_ge_linerate[70 + (i / 4)] = port; 2392 } else if ((i % 4) == 3) { 2393 tdm_56333_ge_linerate[77 + (i / 4)] = port; 2394 } 2395 i++; 2396 if (i == 12) { 2397 break; 2398 } 2399 } 2400 tdm_size = 84; 2401 arr = tdm_56333_ge_linerate; 2402 } else { 2403 if (dev_id == BCM56333_DEVICE_ID) { 2404 tdm_size = 56; 2405 arr = tdm_56333_lp; 2406 } else { 2407 tdm_size = 84; 2408 arr = tdm; 2409 } 2410 } 2411 } else if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) { 2412 tdm_size = 56; 2413 arr = tdm_56333_lp; 2414 } else { 2415 tdm_size = 84; 2416 arr = tdm; 2417 } 2418 for (i = 0; i < tdm_size; i++) { 2419 sal_memset(&iarb_tdm, 0, sizeof(iarb_tdm_table_entry_t)); 2420 sal_memset(&arb_tdm, 0, sizeof(arb_tdm_table_entry_t)); 2421 soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 2422 arr[i]); 2423 soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, 2424 arr[i]); 2425 /* Cache the CPU slot entry */ 2426 if (IS_CPU_PORT(unit, arr[i])) { 2427 sal_memcpy(&(SOC_CONTROL(unit)->iarb_tdm), &iarb_tdm, 2428 sizeof(iarb_tdm)); 2429 SOC_CONTROL(unit)->iarb_tdm_idx = i; 2430 } 2431 if (i == tdm_size - 1) { 2432 soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, WRAP_ENf, 1); 2433 } 2434 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 2435 &iarb_tdm)); 2436 SOC_IF_ERROR_RETURN(WRITE_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, i, 2437 &arb_tdm)); 2438 } 2439 rval = 0; 2440 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0); 2441 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, 2442 tdm_size -1); 2443 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 2444 2445 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 2446 /* Clear IPIPE/EIPIE Memories */ 2447 SOC_IF_ERROR_RETURN(soc_enduro_pipe_mem_clear(unit)); 2448 } 2449 2450 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 2451 2452 /* Turn on ingress/egress/mmu parity */ 2453 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 2454 #if defined(SER_TR_TEST_SUPPORT) 2455 /*Initialize chip-specific functions for SER testing*/ 2456 memset(&ser_enduro_test_fun, 0, sizeof(soc_ser_test_functions_t)); 2457 ser_enduro_test_fun.inject_error_f = &soc_enduro_ser_inject_error; 2458 ser_enduro_test_fun.injection_support = &soc_enduro_ser_error_injection_support; 2459 soc_ser_test_functions_register(unit, &ser_enduro_test_fun); 2460 #endif /*defined(SER_TR_TEST_SUPPORT*/ 2461 _soc_enduro_parity_enable(unit, TRUE); 2462 if (soc_feature(unit, soc_feature_ser_parity)) { 2463 SOC_IF_ERROR_RETURN(_soc_enduro_ser_init(unit)); 2464 #ifdef INCLUDE_MEM_SCAN 2465 soc_mem_scan_ser_list_register(unit, FALSE, 2466 _soc_enduro_ser_parity_info); 2467 #endif /* INCLUDE_MEM_SCAN */ 2468 } 2469 2470 sal_memset(&_enduro_ser_functions, 0, sizeof(soc_ser_functions_t)); 2471 _enduro_ser_functions._soc_ser_fail_f = &soc_enduro_ser_fail; 2472 _enduro_ser_functions._soc_ser_parity_error_intr_f = &soc_enduro_parity_error; 2473 _enduro_ser_functions._soc_ser_mem_nack_f = &soc_enduro_mem_nack; 2474 soc_ser_function_register(unit, &_enduro_ser_functions); 2475 } 2476 2477 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2478 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 2479 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2480 2481 /* Enable dual hash on L2, L3 and MPLS_ENTRY tables */ 2482 fields[0] = ENABLEf; 2483 values[0] = 1; 2484 fields[1] = HASH_SELECTf; 2485 values[1] = FB_HASH_CRC32_LOWER; 2486 fields[2] = INSERT_LEAST_FULL_HALFf; 2487 values[2] = 1; 2488 SOC_IF_ERROR_RETURN 2489 (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3, 2490 fields, values)); 2491 SOC_IF_ERROR_RETURN 2492 (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3, 2493 fields, values)); 2494 SOC_IF_ERROR_RETURN 2495 (soc_reg_field32_modify(unit, MPLS_ENTRY_HASH_CONTROLr, REG_PORT_ANY, 2496 INSERT_LEAST_FULL_HALFf, 1)); 2497 2498 /* 2499 * Egress Enable 2500 */ 2501 rval= 0; 2502 soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1); 2503 PBMP_ALL_ITER(unit, port) { 2504 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval)); 2505 } 2506 2507 COMPILER_64_ZERO(reg64); 2508 soc_reg64_field32_set(unit, EPC_LINK_BMAP_64r, ®64, PORT_BITMAP_LOf, 2509 SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 0)); 2510 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAP_64r(unit, reg64)); 2511 2512 /* GMAC init should be moved to mac */ 2513 rval = 0; 2514 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1); 2515 prev_reg_addr = 0xffffffff; 2516 PBMP_E_ITER(unit, port) { 2517 uint32 reg_addr; 2518 if (IS_XQ_PORT(unit, port)) { 2519 continue; 2520 } 2521 reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0); 2522 if (reg_addr != prev_reg_addr) { 2523 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 2524 prev_reg_addr = reg_addr; 2525 } 2526 } 2527 prev_reg_addr = 0xffffffff; 2528 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0); 2529 PBMP_E_ITER(unit, port) { 2530 uint32 reg_addr; 2531 if (IS_XQ_PORT(unit, port)) { 2532 continue; 2533 } 2534 reg_addr = soc_reg_addr(unit, GPORT_CONFIGr, port, 0); 2535 if (reg_addr != prev_reg_addr) { 2536 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 2537 prev_reg_addr = reg_addr; 2538 } 2539 } 2540 2541 /* XMAC init should be moved to mac */ 2542 if (SOC_PBMP_NOT_NULL(PBMP_XE_ALL(unit)) || 2543 SOC_PBMP_NOT_NULL(PBMP_HG_ALL(unit))) { 2544 rval = 0; 2545 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1); 2546 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1); 2547 PBMP_HG_ITER(unit, port) { 2548 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 2549 } 2550 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0); 2551 PBMP_XE_ITER(unit, port) { 2552 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 2553 } 2554 } 2555 2556 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®64)); 2557 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2558 L3SRC_HIT_ENABLEf, 1); 2559 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2560 L2DST_HIT_ENABLEf, 1); 2561 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2562 APPLY_EGR_MASK_ON_L2f, 1); 2563 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2564 APPLY_EGR_MASK_ON_L3f, 1); 2565 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2566 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 2567 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2568 ARP_VALIDATION_ENf, 1); 2569 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2570 IGNORE_HG_HDR_LAG_FAILOVERf, 1); 2571 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64)); 2572 2573 /* Backwards compatible mirroring by default */ 2574 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2575 soc_reg_field_set(unit, MISCCONFIGr, &rval, 2576 DRACO_1_5_MIRRORING_MODE_ENf, 1); 2577 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2578 2579 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®64)); 2580 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2581 DRACO1_5_MIRRORf, 1); 2582 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64)); 2583 2584 SOC_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, &rval)); 2585 soc_reg_field_set(unit, EGR_CONFIGr, &rval, DRACO1_5_MIRRORf, 1); 2586 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIGr(unit, rval)); 2587 2588 2589 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval)); 2590 soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, RING_MODEf, 1); 2591 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval)); 2592 2593 /* 2594 * Set reference clock (based on 200MHz core clock) 2595 * to be 200MHz * (1/40) = 5MHz 2596 */ 2597 rval = 0; 2598 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, 40); 2599 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, 1); 2600 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval)); 2601 2602 /* Match the Internal MDC freq with above for External MDC */ 2603 rval = 0; 2604 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 40); 2605 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 1); 2606 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval)); 2607 2608 /* 2609 * Set reference clock (based on 200MHz core clock) 2610 * to be 200MHz * (1/8) = 25MHz 2611 */ 2612 rval = 0; 2613 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVISORf, 8); 2614 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVIDENDf, 1); 2615 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval)); 2616 2617 rval = 0; 2618 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVISORf, 8); 2619 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVIDENDf, 1); 2620 /* coverity[result_independent_of_operands] */ 2621 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval)); 2622 2623 rval = 0x01; /* 125KHz I2C sampling rate based on 5Mhz reference clock */ 2624 SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval)); 2625 2626 /* GMAC init should be moved to mac */ 2627 rval = 0; 2628 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1); 2629 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, GPORT_ENf, 1); 2630 PBMP_E_ITER(unit, port) { 2631 if (IS_XQ_PORT(unit, port)) { 2632 continue; 2633 } 2634 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 2635 } 2636 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0); 2637 PBMP_E_ITER(unit, port) { 2638 if (IS_XQ_PORT(unit, port)) { 2639 continue; 2640 } 2641 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 2642 } 2643 2644 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 2645 * causes the outer tag to be removed from packets that don't have 2646 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 2647 */ 2648 rval = 0; 2649 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0); 2650 2651 /* Enable pri/cfi remarking on egress ports. */ 2652 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf, 2653 1); 2654 PBMP_ALL_ITER(unit, port) { 2655 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval)); 2656 } 2657 2658 /* Multicast range initialization */ 2659 SOC_IF_ERROR_RETURN 2660 (soc_hbx_higig2_mcast_sizes_set(unit, 2661 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 2662 SOC_EN_BROADCAST_RANGE_DEFAULT), 2663 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 2664 SOC_EN_L2_MULTICAST_RANGE_DEFAULT), 2665 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 2666 SOC_EN_IP_MULTICAST_RANGE_DEFAULT))); 2667 2668 /* Enable vrf based l3 lookup by default. */ 2669 SOC_IF_ERROR_RETURN 2670 (soc_reg_field32_modify(unit, VRF_MASKr, REG_PORT_ANY, MASKf, 0)); 2671 2672 /* Setup SW2_FP_DST_ACTION_CONTROL */ 2673 fields[0] = HGTRUNK_RES_ENf; 2674 fields[1] = LAG_RES_ENf; 2675 values[0] = values[1] = 1; 2676 SOC_IF_ERROR_RETURN 2677 (soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr, 2678 REG_PORT_ANY, 2, fields, values)); 2679 2680 /* Initialize the multipass loopback bitmap to the loopback port */ 2681 COMPILER_64_ZERO(multipass); 2682 bm=0x0; 2683 PBMP_ALL_ITER(unit, port) { 2684 if (IS_LB_PORT(unit, port)) { 2685 bm = bm | (1 << port); 2686 } 2687 } 2688 soc_reg64_field32_set(unit, MULTIPASS_LOOPBACK_BITMAP_64r, &multipass, 2689 BITMAPf, bm); 2690 SOC_IF_ERROR_RETURN(WRITE_MULTIPASS_LOOPBACK_BITMAP_64r(unit, multipass)); 2691 2692 /* Apply delay so LEDUP can capture correct status. */ 2693 /* coverity[result_independent_of_operands] */ 2694 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP_CTRLr(unit, &rval)); 2695 soc_reg_field_set(unit,CMIC_LEDUP_CTRLr, 2696 &rval, LEDUP_SCAN_START_DELAYf, 0x5); 2697 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP_CTRLr(unit, rval)); 2698 2699 /* Enable shaping mode. */ 2700 if (soc_reg_field_valid(unit, EGR_Q_BEGINr, DWRR_OR_SHAPINGf)) { 2701 SOC_IF_ERROR_RETURN(READ_EGR_Q_BEGINr(unit, &rval)); 2702 soc_reg_field_set(unit,EGR_Q_BEGINr, &rval, DWRR_OR_SHAPINGf, 0x1); 2703 SOC_IF_ERROR_RETURN(WRITE_EGR_Q_BEGINr(unit, rval)); 2704 } 2705 2706 /* Cache LMEP/LMEP_1 table */ 2707 SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, LMEPm, MEM_BLOCK_ALL, TRUE)); 2708 SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, LMEP_1m, MEM_BLOCK_ALL, TRUE)); 2709 2710 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 2711 return SOC_E_NONE; 2712 } 2713 2714 #define TR_MMU_NUM_PG 8 2715 #define TR_MMU_NUM_COS 8 2716 2717 /* Standard Ethernet MTU, 1536 bytes (1 cell = 128 bytes) */ 2718 #define TR_MMU_ETH_FRAME_CELLS 12 2719 2720 /* Jumbo Frame MTU, 9216 (1 cell = 128 bytes) */ 2721 #define TR_MMU_JUMBO_FRAME_CELLS 72 2722 2723 /* MAX Frame MTU, 16384 (1 cell = 128 bytes) */ 2724 #define TR_MMU_MAX_FRAME_CELLS 128 2725 2726 #define EN_MMU_IN_PG_MIN_CELLS 12 2727 #define EN_MMU_IN_PG_MIN_PACKETS 12 2728 2729 #define TR_MMU_IN_PORT_MIN_CELLS 72 2730 #define TR_MMU_IN_PORT_MIN_PKTS 1 2731 #define DAGGER_MMU_IN_PORT_MIN_PKTS 72 2732 #define TR_MMU_PG_HDRM_LIMIT_CELLS 36 2733 #define TR_MMU_PG_HDRM_LIMIT_PKTS 36 2734 #define TR_MMU_PG_RESET_OFFSET_CELLS 24 2735 #define TR_MMU_PG_RESET_OFFSET_PKTS 1 2736 2737 #define TR_MMU_OUT_PORT_MIN_CELLS 12 2738 #define TR_MMU_OUT_PORT_MIN_PKTS 1 2739 #define DAGGER_MMU_OUT_PORT_MIN_PKTS 4 2740 #define TR_MMU_OUT_RESET_OFFSET_CELLS 24 2741 #define TR_MMU_OUT_RESET_OFFSET_PKTS 2 2742 #define TR_MMU_SOP_POLICY 0 2743 #define TR_MMU_MOP_POLICY 7 2744 int 2745 soc_enduro_mmu_init(int unit) 2746 { 2747 uint16 dev_id; 2748 uint8 rev_id; 2749 uint32 rval, tm; 2750 uint32 rval0, rval1, cell_rval, pkt_rval; 2751 int port; 2752 int total_cells, total_pkts; 2753 int in_reserved_cells, in_reserved_pkts; 2754 int out_reserved_cells, out_reserved_pkts; 2755 int out_shared_cells, out_shared_pkts; 2756 int idx, count; 2757 soc_pbmp_t pbmp_8pg; 2758 2759 soc_cm_get_id(unit, &dev_id, &rev_id); 2760 2761 /* Total number of cells */ 2762 if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) { 2763 total_cells = 8 * 1024; /* 8K cells */ 2764 } else { 2765 total_cells = 16 * 1024; /* 16K cells */ 2766 } 2767 2768 /* Total number of packet pointers */ 2769 total_pkts = 6 * 1024; /* 6K packet pointers */ 2770 2771 /* Ports with 8PG (1PG for other ports) */ 2772 SOC_PBMP_CLEAR(pbmp_8pg); 2773 SOC_PBMP_WORD_SET(pbmp_8pg, 0, 0x3c000000); /* 26-29 */ 2774 SOC_PBMP_AND(pbmp_8pg, PBMP_ALL(unit)); 2775 2776 /* 2777 * Reserved space calculation: 2778 * Input port: 2779 * per-port minimum 2780 * per-PG minimum (config to 0) 2781 * per-PG headroom 2782 * per-device headroom 2783 * per-port minimum for SC and QM traffic (config to 0) 2784 * Output port: 2785 * per-port per-COS minimum space 2786 * Shared space calculation: 2787 * Input port: total - input port reserved - output port reserved 2788 * Output port: total - output port reserved 2789 */ 2790 in_reserved_cells = (NUM_PORT(unit) + 1) * TR_MMU_IN_PORT_MIN_CELLS + 2791 NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_CELLS + 2792 (NUM_PORT(unit) + 1) * TR_MMU_ETH_FRAME_CELLS; 2793 out_reserved_cells = 2794 (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) * 2795 TR_MMU_OUT_PORT_MIN_CELLS; 2796 if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) { 2797 in_reserved_pkts = (NUM_PORT(unit) + 1) * DAGGER_MMU_IN_PORT_MIN_PKTS + 2798 NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_PKTS; 2799 out_reserved_pkts = 2800 (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) * 2801 DAGGER_MMU_OUT_PORT_MIN_PKTS; 2802 } else { 2803 in_reserved_pkts = (NUM_PORT(unit) + 1) * TR_MMU_IN_PORT_MIN_PKTS + 2804 NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_PKTS; 2805 out_reserved_pkts = 2806 (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) * 2807 TR_MMU_OUT_PORT_MIN_PKTS; 2808 } 2809 2810 /* 2811 * Input PGs threshold 2812 */ 2813 cell_rval = 0; 2814 soc_reg_field_set(unit, PG_MIN_CELLr, &cell_rval, PG_MINf, 2815 EN_MMU_IN_PG_MIN_CELLS); 2816 pkt_rval = 0; 2817 soc_reg_field_set(unit, PG_MIN_PACKETr, &pkt_rval, PG_MINf, 2818 EN_MMU_IN_PG_MIN_PACKETS); 2819 PBMP_PORT_ITER(unit, port) { 2820 idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0; 2821 SOC_IF_ERROR_RETURN(WRITE_PG_MIN_CELLr(unit, port, idx, 2822 cell_rval)); 2823 SOC_IF_ERROR_RETURN(WRITE_PG_MIN_PACKETr(unit, port, idx, 2824 pkt_rval)); 2825 } 2826 2827 /* 2828 * Input ports threshold 2829 */ 2830 /* Reserved space: Input port per-port minimum */ 2831 cell_rval = 0; 2832 soc_reg_field_set(unit, PORT_MIN_CELLr, &cell_rval, PORT_MINf, 2833 TR_MMU_IN_PORT_MIN_CELLS); 2834 pkt_rval = 0; 2835 if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) { 2836 soc_reg_field_set(unit, PORT_MIN_PACKETr, &pkt_rval, PORT_MINf, 2837 DAGGER_MMU_IN_PORT_MIN_PKTS); 2838 } else { 2839 soc_reg_field_set(unit, PORT_MIN_PACKETr, &pkt_rval, PORT_MINf, 2840 TR_MMU_IN_PORT_MIN_PKTS); 2841 } 2842 PBMP_ALL_ITER(unit, port) { 2843 SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_CELLr(unit, port, cell_rval)); 2844 SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_PACKETr(unit, port, pkt_rval)); 2845 } 2846 2847 /* Reserved space: Input port per-PG minimum 2848 * Use defalt value 0 2849 * With only one PG in use PORT_MIN should be sufficient */ 2850 2851 /* Reserved space: Input port per-PG headroom 2852 * Use only 1PG (highest priority PG for the port) */ 2853 cell_rval = 0; 2854 soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &cell_rval, PG_HDRM_LIMITf, 2855 TR_MMU_PG_HDRM_LIMIT_CELLS); 2856 soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &cell_rval, PG_GEf, 1); 2857 pkt_rval = 0; 2858 soc_reg_field_set(unit, PG_HDRM_LIMIT_PACKETr, &pkt_rval, PG_HDRM_LIMITf, 2859 TR_MMU_PG_HDRM_LIMIT_PKTS); 2860 PBMP_PORT_ITER(unit, port) { 2861 idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0; 2862 SOC_IF_ERROR_RETURN(WRITE_PG_HDRM_LIMIT_CELLr(unit, port, idx, 2863 cell_rval)); 2864 SOC_IF_ERROR_RETURN(WRITE_PG_HDRM_LIMIT_PACKETr(unit, port, idx, 2865 pkt_rval)); 2866 } 2867 2868 /* Reserved space: Input port per-device headroom */ 2869 cell_rval = 0; 2870 soc_reg_field_set(unit, GLOBAL_HDRM_LIMITr, &cell_rval, 2871 GLOBAL_HDRM_LIMITf, 2872 (NUM_PORT(unit) + 1) * TR_MMU_ETH_FRAME_CELLS); 2873 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_HDRM_LIMITr(unit, cell_rval)); 2874 2875 /* Input port shared space */ 2876 cell_rval = 0; 2877 soc_reg_field_set(unit, TOTAL_SHARED_LIMIT_CELLr, &cell_rval, 2878 TOTAL_SHARED_LIMITf, 2879 total_cells - in_reserved_cells - out_reserved_cells); 2880 SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMIT_CELLr(unit, cell_rval)); 2881 pkt_rval = 0; 2882 soc_reg_field_set(unit, TOTAL_SHARED_LIMIT_PACKETr, &pkt_rval, 2883 TOTAL_SHARED_LIMITf, 2884 total_pkts - in_reserved_pkts - out_reserved_pkts); 2885 SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMIT_PACKETr(unit, pkt_rval)); 2886 2887 /* Input port per-port shared space limit - no limit */ 2888 cell_rval = 0; 2889 soc_reg_field_set(unit, PORT_SHARED_LIMIT_CELLr, &cell_rval, 2890 PORT_SHARED_LIMITf, total_cells - 1); 2891 pkt_rval = 0; 2892 soc_reg_field_set(unit, PORT_SHARED_LIMIT_PACKETr, &pkt_rval, 2893 PORT_SHARED_LIMITf, total_pkts - 1); 2894 PBMP_ALL_ITER(unit, port) { 2895 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMIT_CELLr(unit, port, 2896 cell_rval)); 2897 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMIT_PACKETr(unit, port, 2898 pkt_rval)); 2899 } 2900 2901 /* Input port per-PG reset offset 2902 * Use only 1PG (highest priority PG for the port) 2903 * Use default value 0 for CPU */ 2904 cell_rval = 0; 2905 soc_reg_field_set(unit, PG_RESET_OFFSET_CELLr, &cell_rval, 2906 PG_RESET_OFFSETf, TR_MMU_PG_RESET_OFFSET_CELLS); 2907 pkt_rval = 0; 2908 soc_reg_field_set(unit, PG_RESET_OFFSET_PACKETr, &pkt_rval, 2909 PG_RESET_OFFSETf, TR_MMU_PG_RESET_OFFSET_PKTS); 2910 PBMP_PORT_ITER(unit, port) { 2911 idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0; 2912 SOC_IF_ERROR_RETURN(WRITE_PG_RESET_OFFSET_CELLr(unit, port, idx, 2913 cell_rval)); 2914 SOC_IF_ERROR_RETURN(WRITE_PG_RESET_OFFSET_PACKETr(unit, port, idx, 2915 pkt_rval)); 2916 } 2917 2918 /* Input port per-PG reset floor (cell). Use default value 0 */ 2919 2920 /* Reserved space: Input port per-port minimum for SC and QM traffic 2921 * Use default value 0 */ 2922 2923 /* Input port priority XON disable */ 2924 2925 /* Input port max packet size in cells */ 2926 rval0 = 0; 2927 soc_reg_field_set(unit, PORT_MAX_PKT_SIZEr, &rval0, PORT_MAX_PKT_SIZEf, 2928 TR_MMU_JUMBO_FRAME_CELLS); 2929 PBMP_ALL_ITER(unit, port) { 2930 SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_PKT_SIZEr(unit, port, rval0)); 2931 } 2932 2933 /* Input port per-PG threshold */ 2934 rval0 = 0; 2935 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG0_THRESH_SELf, 0x8); 2936 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG1_THRESH_SELf, 0x8); 2937 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG2_THRESH_SELf, 0x8); 2938 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG3_THRESH_SELf, 0x8); 2939 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG4_THRESH_SELf, 0x8); 2940 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG5_THRESH_SELf, 0x8); 2941 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG6_THRESH_SELf, 0x8); 2942 PBMP_ITER(pbmp_8pg, port) { 2943 SOC_IF_ERROR_RETURN(WRITE_PG_THRESH_SELr(unit, port, rval0)); 2944 } 2945 2946 idx = TR_MMU_NUM_PG - 1; 2947 rval0 = 0; 2948 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI0_GRPf, idx); 2949 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI1_GRPf, idx); 2950 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI2_GRPf, idx); 2951 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI3_GRPf, idx); 2952 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI4_GRPf, idx); 2953 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI5_GRPf, idx); 2954 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI6_GRPf, idx); 2955 rval1 = 0; 2956 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI7_GRPf, idx); 2957 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI8_GRPf, idx); 2958 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI9_GRPf, idx); 2959 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI10_GRPf, idx); 2960 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI11_GRPf, idx); 2961 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI12_GRPf, idx); 2962 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI13_GRPf, idx); 2963 PBMP_ITER(pbmp_8pg, port) { 2964 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP0r(unit, port, rval0)); 2965 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP1r(unit, port, rval1)); 2966 } 2967 2968 /* 2969 * Output ports threshold 2970 */ 2971 /* Reserved space: Output port per-port per-COS minimum space */ 2972 cell_rval = 0; 2973 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, Q_MIN_CELLf, 2974 TR_MMU_OUT_PORT_MIN_CELLS); 2975 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, 2976 Q_LIMIT_ENABLE_CELLf, 0x1); 2977 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, 2978 Q_LIMIT_DYNAMIC_CELLf, 0x1); 2979 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, 2980 Q_SHARED_LIMIT_CELLf, 2); /* alpha index 2 */ 2981 pkt_rval = 0; 2982 if ((dev_id == BCM56230_DEVICE_ID) || (dev_id == BCM56231_DEVICE_ID)) { 2983 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 2984 Q_MIN_PACKETf, DAGGER_MMU_OUT_PORT_MIN_PKTS); 2985 } else { 2986 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 2987 Q_MIN_PACKETf, TR_MMU_OUT_PORT_MIN_PKTS); 2988 } 2989 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 2990 Q_LIMIT_ENABLE_PACKETf, 0x1); 2991 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 2992 Q_LIMIT_DYNAMIC_PACKETf, 0x1); 2993 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 2994 Q_SHARED_LIMIT_PACKETf, 2); /* alpha index 2 */ 2995 PBMP_ALL_ITER(unit, port) { 2996 count = IS_CPU_PORT(unit, port) ? 2997 SOC_INFO(unit).num_cpu_cosq : TR_MMU_NUM_COS; 2998 for (idx = 0; idx < count; idx++) { 2999 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIG_CELLr(unit, port, idx, 3000 cell_rval)); 3001 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIG_PACKETr(unit, port, idx, 3002 pkt_rval)); 3003 } 3004 } 3005 3006 /* Output port per-port per-COS reset offset */ 3007 cell_rval = 0; 3008 soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_CELLr, &cell_rval, 3009 Q_RESET_OFFSET_CELLf, TR_MMU_OUT_RESET_OFFSET_CELLS); 3010 pkt_rval = 0; 3011 soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_PACKETr, &pkt_rval, 3012 Q_RESET_OFFSET_PACKETf, TR_MMU_OUT_RESET_OFFSET_PKTS); 3013 PBMP_ALL_ITER(unit, port) { 3014 count = IS_CPU_PORT(unit, port) ? 3015 SOC_INFO(unit).num_cpu_cosq : TR_MMU_NUM_COS; 3016 for (idx = 0; idx < count; idx++) { 3017 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_RESET_OFFSET_CELLr(unit, port, 3018 idx, 3019 cell_rval)); 3020 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_RESET_OFFSET_PACKETr(unit, port, 3021 idx, 3022 pkt_rval)); 3023 } 3024 } 3025 3026 out_shared_cells = total_cells - out_reserved_cells; 3027 out_shared_pkts = total_pkts - out_reserved_pkts; 3028 3029 /* Output port per-device shared */ 3030 cell_rval = 0; 3031 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, &cell_rval, 3032 OP_BUFFER_SHARED_LIMIT_CELLf, out_shared_cells); 3033 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_CELLr(unit, cell_rval)); 3034 pkt_rval = 0; 3035 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_PACKETr, &pkt_rval, 3036 OP_BUFFER_SHARED_LIMIT_PACKETf, out_shared_pkts); 3037 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_PACKETr(unit, pkt_rval)); 3038 3039 /* Output port per-device shared for YELLOW traffic */ 3040 cell_rval = 0; 3041 soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, &cell_rval, 3042 OP_BUFFER_LIMIT_YELLOW_CELLf, out_shared_cells >> 3); 3043 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_YELLOW_CELLr(unit, cell_rval)); 3044 pkt_rval = 0; 3045 soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_PACKETr, &pkt_rval, 3046 OP_BUFFER_LIMIT_YELLOW_PACKETf, out_shared_pkts >> 2); 3047 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_YELLOW_PACKETr(unit, pkt_rval)); 3048 3049 /* Output port per-device shared for RED traffic */ 3050 cell_rval = 0; 3051 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_CELLr, &cell_rval, 3052 OP_BUFFER_LIMIT_RED_CELLf, out_shared_cells >> 3); 3053 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_RED_CELLr(unit, cell_rval)); 3054 pkt_rval = 0; 3055 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_PACKETr, &pkt_rval, 3056 OP_BUFFER_LIMIT_RED_PACKETf, out_shared_pkts >> 2); 3057 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_RED_PACKETr(unit, pkt_rval)); 3058 3059 /* Output port per-device shared */ 3060 cell_rval = 0; 3061 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_CELLr, &cell_rval, 3062 OP_BUFFER_SHARED_LIMIT_RESUME_CELLf, out_shared_cells * 85 / 100); 3063 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_RESUME_CELLr(unit, cell_rval)); 3064 pkt_rval = 0; 3065 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_PACKETr, &pkt_rval, 3066 OP_BUFFER_SHARED_LIMIT_RESUME_PACKETf, out_shared_pkts * 85 / 100); 3067 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_RESUME_PACKETr(unit, pkt_rval)); 3068 3069 /* 3070 * Output port per-port shared 3071 * Limit check disabled, however still keep code as reference 3072 * OP_SHARED_LIMIT set to 3/4 of total shared space 3073 * OP_SHARED_RESET_VALUE set to 1/2 of total shared space 3074 */ 3075 cell_rval = 0; 3076 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval, 3077 OP_SHARED_LIMIT_CELLf, out_shared_cells * 3 / 4); 3078 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval, 3079 OP_SHARED_RESET_VALUE_CELLf, out_shared_cells / 2); 3080 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval, 3081 PORT_LIMIT_ENABLE_CELLf, 0); 3082 pkt_rval = 0; 3083 soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval, 3084 OP_SHARED_LIMIT_PACKETf, out_shared_pkts * 3 / 4); 3085 soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval, 3086 OP_SHARED_RESET_VALUE_PACKETf, out_shared_pkts / 2); 3087 soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval, 3088 PORT_LIMIT_ENABLE_PACKETf, 0); 3089 PBMP_ALL_ITER(unit, port) { 3090 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIG_CELLr(unit, port, cell_rval)); 3091 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIG_PACKETr(unit, port, 3092 pkt_rval)); 3093 } 3094 3095 /* Output port per-port shared for YELLOW traffic */ 3096 cell_rval = 0; 3097 soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOW_CELLr, &cell_rval, 3098 OP_PORT_LIMIT_YELLOW_CELLf, 3099 (out_shared_cells * 3 / 4) >> 3); 3100 pkt_rval = 0; 3101 soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOW_PACKETr, &pkt_rval, 3102 OP_PORT_LIMIT_YELLOW_PACKETf, 3103 (out_shared_pkts * 3 / 4) >> 2); 3104 PBMP_ALL_ITER(unit, port) { 3105 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_YELLOW_CELLr(unit, port, 3106 cell_rval)); 3107 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_YELLOW_PACKETr(unit, port, 3108 pkt_rval)); 3109 } 3110 3111 /* Output port per-port shared for RED traffic */ 3112 cell_rval = 0; 3113 soc_reg_field_set(unit, OP_PORT_LIMIT_RED_CELLr, &cell_rval, 3114 OP_PORT_LIMIT_RED_CELLf, 3115 (out_shared_cells * 3 / 4) >> 3); 3116 pkt_rval = 0; 3117 soc_reg_field_set(unit, OP_PORT_LIMIT_RED_PACKETr, &pkt_rval, 3118 OP_PORT_LIMIT_RED_PACKETf, 3119 (out_shared_pkts * 3 / 4) >> 2); 3120 PBMP_ALL_ITER(unit, port) { 3121 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_RED_CELLr(unit, port, 3122 cell_rval)); 3123 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_RED_PACKETr(unit, port, 3124 pkt_rval)); 3125 } 3126 3127 /* Output port configuration */ 3128 rval0 = 0; 3129 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, 3130 MOP_POLICYf, TR_MMU_MOP_POLICY); 3131 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, 3132 SOP_POLICYf, TR_MMU_SOP_POLICY); 3133 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval0)); 3134 3135 /* Apply TM setting on MMU_CELLLINK */ 3136 rval = 0x20; 3137 SOC_IF_ERROR_RETURN(WRITE_CELLLINKMEMDEBUGr(unit, rval)); 3138 3139 /* Apply TM=0x10 setting for all CAMs */ 3140 rval = 0; 3141 tm=0x10; 3142 soc_reg_field_set(unit, SW2_RAM_CONTROL_4r, &rval, 3143 CPU_COS_MAP_TCAM_TMf, tm); 3144 SOC_IF_ERROR_RETURN(WRITE_SW2_RAM_CONTROL_4r_REG32(unit, rval)); 3145 3146 rval = 0; 3147 soc_reg_field_set(unit, EFP_RAM_CONTROLr, &rval, 3148 EFP_CAM_TM_7_THRU_0f, tm); 3149 SOC_IF_ERROR_RETURN(WRITE_EFP_RAM_CONTROLr(unit, rval)); 3150 3151 rval = 0; 3152 soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &rval, 3153 ALL_TCAMS_TM_7_0f, tm); 3154 soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &rval, 3155 ALL_GLOBAL_MASK_TCAMS_TM_7_0f, tm); 3156 SOC_IF_ERROR_RETURN(WRITE_FP_CAM_CONTROL_TM_7_THRU_0r(unit, rval)); 3157 3158 rval = 0; 3159 soc_reg_field_set(unit, VLAN_SUBNET_CAM_DBGCTRLr, &rval, 3160 TMf, tm); 3161 SOC_IF_ERROR_RETURN(WRITE_VLAN_SUBNET_CAM_DBGCTRLr(unit, rval)); 3162 3163 rval = 0; 3164 soc_reg_field_set(unit, L2_USER_ENTRY_CAM_DBGCTRLr, &rval, 3165 TMf, tm); 3166 SOC_IF_ERROR_RETURN(WRITE_L2_USER_ENTRY_CAM_DBGCTRLr(unit, rval)); 3167 3168 rval = 0; 3169 soc_reg_field_set(unit, L3_DEFIP_128_CAM_DBGCTRLr, &rval, 3170 CAM0_TMf, tm); 3171 soc_reg_field_set(unit, L3_DEFIP_128_CAM_DBGCTRLr, &rval, 3172 CAM1_TMf, tm); 3173 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_128_CAM_DBGCTRLr(unit, rval)); 3174 3175 rval = 0; 3176 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval, 3177 CAM0_TMf, tm); 3178 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval, 3179 CAM1_TMf, tm); 3180 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL0r(unit, rval)); 3181 3182 rval = 0; 3183 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL1r, &rval, 3184 CAM2_TMf, tm); 3185 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL1r, &rval, 3186 CAM3_TMf, tm); 3187 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL1r(unit, rval)); 3188 3189 rval = 0; 3190 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL2r, &rval, 3191 CAM4_TMf, tm); 3192 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL2r, &rval, 3193 CAM5_TMf, tm); 3194 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL2r(unit, rval)); 3195 3196 rval = 0; 3197 soc_reg_field_set(unit, L3_TUNNEL_CAM_DBGCTRLr, &rval, 3198 TMf, tm); 3199 SOC_IF_ERROR_RETURN(WRITE_L3_TUNNEL_CAM_DBGCTRLr(unit, rval)); 3200 3201 rval = 0; 3202 soc_reg_field_set(unit, MPLS_STATION_CAM_DBGCTRLr, &rval, 3203 CAM0_TMf, tm); 3204 SOC_IF_ERROR_RETURN(WRITE_MPLS_STATION_CAM_DBGCTRLr(unit, rval)); 3205 3206 rval = 0; 3207 soc_reg_field_set(unit, VFP_CAM_CONTROL_TM_7_THRU_0r, &rval, 3208 TMf, tm); 3209 SOC_IF_ERROR_RETURN(WRITE_VFP_CAM_CONTROL_TM_7_THRU_0r(unit, rval)); 3210 3211 /* Input port enable */ 3212 rval=0; 3213 soc_reg_field_set(unit, INPUT_PORT_RX_ENABLEr, &rval, 3214 INPUT_PORT_RX_ENABLEf, 3215 SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0)); 3216 SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLEr(unit, rval)); 3217 SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLEr(unit, rval)); 3218 return SOC_E_NONE; 3219 } 3220 3221 int 3222 soc_enduro_age_timer_get(int unit, int *age_seconds, int *enabled) 3223 { 3224 uint32 value; 3225 3226 SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &value)); 3227 *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_ENAf); 3228 *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_VALf); 3229 3230 return SOC_E_NONE; 3231 } 3232 3233 int 3234 soc_enduro_age_timer_max_get(int unit, int *max_seconds) 3235 { 3236 *max_seconds = 3237 soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf); 3238 3239 return SOC_E_NONE; 3240 } 3241 3242 int 3243 soc_enduro_age_timer_set(int unit, int age_seconds, int enable) 3244 { 3245 uint32 value; 3246 3247 value = 0; 3248 soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_ENAf, enable); 3249 soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_VALf, age_seconds); 3250 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, value)); 3251 3252 return SOC_E_NONE; 3253 } 3254 3255 void soc_enduro_oam_handler_register(int unit, soc_enduro_oam_handler_t handler) 3256 { 3257 en_oam_handler[unit] = handler; 3258 soc_intr_enable(unit, IRQ_MEM_FAIL); 3259 } 3260 3261 void 3262 soc_enduro_mem_config(int unit) 3263 { 3264 uint16 dev_id; 3265 uint8 rev_id; 3266 soc_persist_t *sop; 3267 3268 sop = SOC_PERSIST(unit); 3269 soc_cm_get_id(unit, &dev_id, &rev_id); 3270 3271 switch (dev_id) { 3272 case BCM56320_DEVICE_ID: 3273 sop->memState[MPLS_ENTRYm].index_max = 0; 3274 sop->memState[OAM_LM_COUNTERSm].index_max = 0; 3275 sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 0; 3276 break; 3277 case BCM56321_DEVICE_ID: 3278 sop->memState[MPLS_ENTRYm].index_max = 0; 3279 sop->memState[OAM_LM_COUNTERSm].index_max = 0; 3280 sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 0; 3281 sop->memState[L2Xm].index_max = 16383; 3282 sop->memState[L2_ENTRY_ONLYm].index_max = 16383; 3283 sop->memState[L2_HITDA_ONLYm].index_max = 2047; 3284 sop->memState[L2_HITSA_ONLYm].index_max = 2047; 3285 sop->memState[L3_DEFIPm].index_max = 511; 3286 sop->memState[L3_DEFIP_ONLYm].index_max = 511; 3287 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 511; 3288 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 511; 3289 sop->memState[L3_TUNNELm].index_max = 127; 3290 break; 3291 case BCM56230_DEVICE_ID: 3292 case BCM56231_DEVICE_ID: 3293 /* L2 MAC Address : 16K */ 3294 sop->memState[L2Xm].index_max = 16383; 3295 sop->memState[L2_ENTRY_ONLYm].index_max = 16383; 3296 sop->memState[L2_HITDA_ONLYm].index_max = 2047; 3297 sop->memState[L2_HITSA_ONLYm].index_max = 2047; 3298 3299 /* MPLS Labels : 1K */ 3300 sop->memState[EGR_IP_TUNNELm].index_max = 255; 3301 sop->memState[EGR_IP_TUNNEL_IPV6m].index_max = 127; 3302 sop->memState[EGR_IP_TUNNEL_MPLSm].index_max = 255; 3303 sop->memState[MPLS_ENTRYm].index_max = 1023; 3304 sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 1023; 3305 3306 /* VPLS VFI : 1K */ 3307 sop->memState[VFIm].index_max = 1023; 3308 sop->memState[VFI_1m].index_max = 1023; 3309 sop->memState[VLAN_OR_VFI_MAC_COUNTm].index_max = 5119; 3310 sop->memState[VLAN_OR_VFI_MAC_LIMITm].index_max = 5119; 3311 3312 /* Virtual Ports : 4K */ 3313 sop->memState[SOURCE_VPm].index_max = 4095; 3314 sop->memState[SVP_DISABLE_VLAN_CHECKS_TABm].index_max = 4095; 3315 sop->memState[ING_DVP_TABLEm].index_max = 4095; 3316 3317 /* IPMc Groups : 512 */ 3318 sop->memState[EGR_IPMCm].index_max = 511; 3319 sop->memState[L3_IPMCm].index_max = 511; 3320 sop->memState[MMU_IPMC_GROUP_TBL0m].index_max = 511; 3321 sop->memState[MMU_IPMC_GROUP_TBL1m].index_max = 511; 3322 sop->memState[MMU_IPMC_GROUP_TBL2m].index_max = 511; 3323 sop->memState[MMU_IPMC_GROUP_TBL3m].index_max = 511; 3324 sop->memState[L3_MTU_VALUESm].index_max = 8703; 3325 3326 /* IPv4 LPM : 4K */ 3327 sop->memState[L3_DEFIPm].index_max = 2047; 3328 sop->memState[L3_DEFIP_ONLYm].index_max = 2047; 3329 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 2047; 3330 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 2047; 3331 SOC_CONTROL(unit)->l3_defip_index_remap = 2048; 3332 3333 /* L3 Next Hop : 2K */ 3334 sop->memState[EGR_L3_NEXT_HOPm].index_max = 2047; 3335 sop->memState[ING_L3_NEXT_HOPm].index_max = 2047; 3336 sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 2047; 3337 break; 3338 default: 3339 break; 3340 } 3341 return; 3342 } 3343 3344 #define _ENDURO_INDEX_1K_ENTRIES 1023 3345 /* Map logical (always starts from 0 and contiguous) index to physical index 3346 which can have a starting offset and/or holes. 3347 Input : logical index 3348 Returns: physical index */ 3349 int 3350 soc_enduro_l3_defip_index_map(int unit, soc_mem_t mem, int index) 3351 { 3352 if (SOC_CONTROL(unit)->l3_defip_index_remap == 0) { 3353 return index; 3354 } 3355 3356 if (index > _ENDURO_INDEX_1K_ENTRIES) { 3357 return index + SOC_CONTROL(unit)->l3_defip_index_remap; 3358 } 3359 3360 return index; 3361 } 3362 3363 /* Map physical (always starts from 0 and contiguous) index to logic index 3364 which can have a starting offset and/or holes. 3365 Input : physical index 3366 Returns: logical index */ 3367 int 3368 soc_enduro_l3_defip_index_remap(int unit, soc_mem_t mem, int index) 3369 { 3370 if (SOC_CONTROL(unit)->l3_defip_index_remap == 0) { 3371 return index; 3372 } 3373 3374 if (SOC_CONTROL(unit)->l3_defip_urpf) { /* URPF mode */ 3375 int tmp_index; 3376 3377 tmp_index = index - SOC_CONTROL(unit)->l3_defip_index_remap; 3378 if (tmp_index > _ENDURO_INDEX_1K_ENTRIES) { 3379 return tmp_index; 3380 } 3381 } 3382 3383 return index; 3384 } 3385 3386 int 3387 soc_enduro_mem_index_remap(int unit, soc_mem_t mem, int index) 3388 { 3389 switch (mem) { 3390 case L3_DEFIPm: 3391 case L3_DEFIP_ONLYm: 3392 case L3_DEFIP_DATA_ONLYm: 3393 case L3_DEFIP_HIT_ONLYm: 3394 return soc_enduro_l3_defip_index_remap(unit, mem, index); 3395 default: 3396 return index; 3397 } 3398 } 3399 3400 #if defined(SER_TR_TEST_SUPPORT) 3401 /* 3402 * Function: 3403 * soc_enduro_ser_inject_error 3404 * Purpose: 3405 * Injects an error into a single enduro memory 3406 * Parameters: 3407 * unit - (IN) Device Number 3408 * mem - (IN) The memory to test 3409 * pipeTarget - (IN) The pipe (x/y) to use when injecting the error 3410 * block - (IN) The index into which block will be injected. 3411 * index - (IN) The index into which the error will be injected. 3412 */ 3413 int soc_enduro_ser_inject_error(int unit, uint32 flags, soc_mem_t mem, 3414 int pipeTarget, int block, int index) 3415 { 3416 int group, table; 3417 _soc_parity_info_t *info; 3418 soc_mem_t memTable; 3419 soc_port_t block_port; 3420 soc_block_t blk; 3421 ser_test_data_t test_data; 3422 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 3423 3424 /*H/W memory Test*/ 3425 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 3426 info = _soc_en_parity_group_info[group].info; 3427 3428 SOC_BLOCK_ITER(unit, blk, 3429 _soc_en_parity_group_info[group].blocktype) { 3430 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 3431 continue; 3432 } 3433 3434 for (table = 0; info[table].error_field != INVALIDf; table++) { 3435 memTable = info[table].mem; 3436 if (memTable == INVALIDm) { 3437 continue; 3438 } 3439 3440 if (memTable == mem) { 3441 if((blk == block) || (block == MEM_BLOCK_ANY)) { 3442 /*Inject error*/ 3443 test_data.mem = mem; 3444 test_data.tcam_parity_bit = -1; 3445 if (_soc_en_parity_group_info[group].blocktype 3446 == SOC_BLK_MMU) { 3447 soc_ser_create_test_data(unit, tmp_entry, fieldData, 3448 MISCCONFIGr, 3449 SOC_INVALID_TCAM_PARITY_BIT, 3450 PARITY_CHECK_ENf, 3451 mem, EVEN_PARITYf, blk, 3452 block_port, _SOC_ACC_TYPE_PIPE_ANY, 3453 index, &test_data); 3454 } else { 3455 soc_ser_create_test_data(unit, tmp_entry, fieldData, 3456 info[table].control_reg, 3457 SOC_INVALID_TCAM_PARITY_BIT, 3458 info[table].enable_field, 3459 mem, EVEN_PARITYf, blk, 3460 block_port, _SOC_ACC_TYPE_PIPE_ANY, 3461 index, &test_data); 3462 } 3463 /*Disable parity*/ 3464 SOC_IF_ERROR_RETURN(_ser_test_parity_control( 3465 unit, &test_data, 0)); 3466 /*Read the memory for successful injection*/ 3467 SOC_IF_ERROR_RETURN(ser_test_mem_read( 3468 unit, 0, &test_data)); 3469 /*Inject error*/ 3470 SOC_IF_ERROR_RETURN(soc_ser_test_inject_full( 3471 unit, flags, &test_data)); 3472 /*Enable parity*/ 3473 SOC_IF_ERROR_RETURN(_ser_test_parity_control( 3474 unit, &test_data, 1)); 3475 } 3476 } 3477 } 3478 } 3479 } 3480 return SOC_E_NONE; 3481 } 3482 3483 /* 3484 * Function: 3485 * soc_enduro_ser_error_injection_support 3486 * Purpose: 3487 * Checks if a memory is supported by error injection interface 3488 * 3489 * Parameters: 3490 * unit - (IN) Device Number 3491 * memory - (IN) Test data required for SER test 3492 * pipe - (IN) How many indices to test for each memory 3493 * 3494 * Returns: 3495 * SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported 3496 */ 3497 soc_error_t 3498 soc_enduro_ser_error_injection_support (int unit, soc_mem_t mem, int pipe) 3499 { 3500 int rv = SOC_E_UNAVAIL; 3501 _soc_parity_info_t *info = NULL; 3502 int group, table; 3503 soc_port_t block_port; 3504 soc_block_t blk; 3505 3506 for (group = 0; _soc_en_parity_group_info[group].cpi_bit; group++) { 3507 info = _soc_en_parity_group_info[group].info; 3508 SOC_BLOCK_ITER(unit, blk, 3509 _soc_en_parity_group_info[group].blocktype) { 3510 if (_soc_enduro_parity_block_port(unit, blk, &block_port) < 0) { 3511 continue; 3512 } 3513 for (table = 0; info[table].error_field != INVALIDf; table++) { 3514 if (info[table].mem != mem) { 3515 continue; 3516 } 3517 return SOC_E_NONE; 3518 } 3519 } 3520 } 3521 return rv; 3522 } 3523 3524 #endif /* SER_TR_TEST_SUPPORT */ 3525 #endif /* BCM_ENDURO_SUPPORT */