bradley.c (137698B)
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: bradley.c 8 * Purpose: 9 * Requires: 10 */ 11 12 13 #include <sal/core/boot.h> 14 #include <shared/bsl.h> 15 #include <soc/bradley.h> 16 #include <soc/drv.h> 17 #include <soc/mem.h> 18 #include <soc/hash.h> 19 #include <soc/lpm.h> 20 #include <soc/error.h> 21 #include <soc/debug.h> 22 #include <soc/l2x.h> 23 #include <soc/soc_ser_log.h> 24 25 #ifdef BCM_BRADLEY_SUPPORT 26 27 /* 28 * bradley chip driver functions. 29 */ 30 soc_functions_t soc_bradley_drv_funs = { 31 soc_bradley_misc_init, 32 soc_bradley_mmu_init, 33 soc_bradley_age_timer_get, 34 soc_bradley_age_timer_max_get, 35 soc_bradley_age_timer_set, 36 }; 37 38 static soc_ser_functions_t _bradley_ser_functions; 39 STATIC void 40 _soc_hbs_mem_parity_info(int unit, int block_info_idx, int pipe, 41 soc_field_t field_enum, uint32 *minfo); 42 43 STATIC int 44 soc_bradley_pipe_mem_clear(int unit) 45 { 46 uint32 rval; 47 int pipe_init_usec; 48 soc_timeout_t to; 49 50 /* 51 * Reset the IPIPE and EPIPE block 52 */ 53 rval = 0; 54 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 55 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 56 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 57 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 58 SOC_IS_SC_CQ(unit) ? 0x8000 : 0x4000); 59 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 60 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2_Xr(unit, rval)); 61 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2_Yr(unit, rval)); 62 63 rval = 0; 64 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 65 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 66 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 67 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, 68 SOC_IS_SC_CQ(unit) ? 0x4000 : 0x2000); 69 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 70 71 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 72 if (SAL_BOOT_SIMULATION) { 73 pipe_init_usec = 10000000; 74 } else { 75 pipe_init_usec = 50000; 76 } 77 soc_timeout_init(&to, pipe_init_usec, 0); 78 79 /* Wait for IPIPE memory initialization done. */ 80 do { 81 SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval)); 82 if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) { 83 break; 84 } 85 if (soc_timeout_check(&to)) { 86 LOG_WARN(BSL_LS_SOC_COMMON, 87 (BSL_META_U(unit, 88 "unit %d : ING_HW_RESET timeout\n"), unit)); 89 break; 90 } 91 } while (TRUE); 92 do { 93 SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2_Xr(unit, &rval)); 94 if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2_Xr, rval, DONEf)) { 95 break; 96 } 97 if (soc_timeout_check(&to)) { 98 LOG_WARN(BSL_LS_SOC_COMMON, 99 (BSL_META_U(unit, 100 "unit %d : ING_HW_RESET X timeout\n"), unit)); 101 break; 102 } 103 } while (TRUE); 104 do { 105 SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2_Yr(unit, &rval)); 106 if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2_Yr, rval, DONEf)) { 107 break; 108 } 109 if (soc_timeout_check(&to)) { 110 LOG_WARN(BSL_LS_SOC_COMMON, 111 (BSL_META_U(unit, 112 "unit %d : ING_HW_RESET Y timeout\n"), unit)); 113 break; 114 } 115 } while (TRUE); 116 117 /* Wait for EPIPE memory initialization done. */ 118 do { 119 SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval)); 120 if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) { 121 break; 122 } 123 if (soc_timeout_check(&to)) { 124 LOG_WARN(BSL_LS_SOC_COMMON, 125 (BSL_META_U(unit, 126 "unit %d : EGR_HW_RESET timeout\n"), unit)); 127 break; 128 } 129 } while (TRUE); 130 131 rval = 0; 132 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 133 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 134 135 return SOC_E_NONE; 136 } 137 138 #ifdef BCM_SCORPION_SUPPORT 139 140 int 141 soc_scorpion_pipe_select(int unit, int egress, int pipe_select) { 142 soc_reg_t select_reg; 143 144 select_reg = egress ? EGR_SBS_CONTROLr : SBS_CONTROLr; 145 146 SOC_IF_ERROR_RETURN 147 (soc_reg_field32_modify(unit, select_reg, REG_PORT_ANY, 148 PIPE_SELECTf, pipe_select)); 149 return SOC_E_NONE; 150 } 151 152 /* Forward declaration */ 153 STATIC int _soc_sc_pipe_parity_enable(int unit, int enable); 154 155 /* 156 * The object of this function is to program the TDM arbiter table 157 * so that the ports have enough bandwidth for the given device 158 * port configuration. cf. Scorpion Arbiter document for details of 159 * determining these settings. 160 */ 161 static int _sc_tdm_arbiter_table_1x[] = { 162 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 163 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 164 1, 2, 3, 4, 5, 6, 0, 7, 8, 9, 10, 11, 12, 165 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 166 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 167 -1 168 }; 169 170 static int _sc_tdm_arbiter_table_1y[] = { 171 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 172 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 173 13, 14, 15, 16, 17, 18, 25, 19, 20, 21, 22, 23, 24, 174 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 175 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 176 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 177 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 178 13, 14, 15, 16, 17, 18, 27, 19, 20, 21, 22, 23, 24, 179 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 180 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 28, 181 -1 182 }; 183 184 static int _sc_tdm_arbiter_table_2x[] = { 185 1, 5, 2, 6, 3, 7, 4, 8, 1, 9, 2, 10, 3, 5, 186 4, 6, 1, 7, 2, 8, 3, 9, 4, 10, 1, 5, 2, 0, 187 3, 6, 4, 7, 1, 8, 2, 9, 3, 10, 4, 5, 1, 6, 188 2, 7, 3, 8, 4, 9, 1, 10, 2, 5, 3, 6, 4, 0, 189 7, 1, 8, 2, 9, 3, 10, 4, 5, 1, 6, 2, 7, 3, 190 8, 4, 9, 1, 10, 2, 5, 3, 6, 4, 7, 1, 8, 2, 0, 191 9, 3, 10, 4, 5, 1, 6, 2, 7, 3, 8, 4, 9, 1, 192 10, 2, 5, 3, 6, 4, 7, 1, 8, 2, 9, 3, 10, 4, 0, 193 -1 194 }; 195 196 static int _sc_tdm_arbiter_table_2y[] = { 197 24, 20, 23, 19, 22, 18, 21, 17, 24, 16, 23, 15, 22, 20, 198 21, 19, 24, 18, 23, 17, 22, 16, 21, 15, 24, 20, 23, 25, 199 22, 19, 21, 18, 24, 17, 23, 16, 22, 15, 21, 20, 24, 19, 200 23, 18, 22, 17, 21, 16, 24, 15, 23, 20, 22, 19, 21, 26, 201 18, 24, 17, 23, 16, 22, 15, 21, 20, 24, 19, 23, 18, 22, 202 17, 21, 16, 24, 15, 23, 20, 22, 19, 21, 18, 24, 17, 23, 27, 203 16, 22, 15, 21, 20, 24, 19, 23, 18, 22, 17, 21, 16, 24, 204 15, 23, 20, 22, 19, 21, 18, 24, 17, 23, 16, 22, 15, 21, 28, 205 -1 206 }; 207 208 static int _sc_tdm_arbiter_table_3x[] = { 209 7, 8, 9, 10, 11, 12, 0x1f, 210 7, 8, 9, 10, 11, 12, 0x1f, 211 7, 8, 9, 10, 11, 12, 0x1f, 212 7, 8, 9, 10, 11, 12, 0, 213 -1 214 }; 215 216 static int _sc_tdm_arbiter_table_3y[] = { 217 13, 14, 15, 16, 17, 18, 0x1f, 218 13, 14, 15, 16, 17, 18, 0x1f, 219 13, 14, 15, 16, 17, 18, 0x1f, 220 13, 14, 15, 16, 17, 18, 25, 221 13, 14, 15, 16, 17, 18, 0x1f, 222 13, 14, 15, 16, 17, 18, 0x1f, 223 13, 14, 15, 16, 17, 18, 0x1f, 224 13, 14, 15, 16, 17, 18, 26, 225 13, 14, 15, 16, 17, 18, 0x1f, 226 13, 14, 15, 16, 17, 18, 0x1f, 227 13, 14, 15, 16, 17, 18, 0x1f, 228 13, 14, 15, 16, 17, 18, 27, 229 13, 14, 15, 16, 17, 18, 0x1f, 230 13, 14, 15, 16, 17, 18, 0x1f, 231 13, 14, 15, 16, 17, 18, 0x1f, 232 13, 14, 15, 16, 17, 18, 28, 233 -1 234 }; 235 236 static int _sc_tdm_arbiter_table_4x[] = { 237 5, 6, 7, 8, 9, 10, 11, 12, 238 5, 6, 7, 8, 9, 10, 11, 12, 239 5, 6, 7, 8, 9, 10, 11, 12, 240 5, 6, 7, 8, 9, 10, 11, 12, 241 5, 6, 7, 8, 9, 10, 11, 12, 242 5, 6, 7, 8, 9, 10, 11, 12, 243 5, 6, 7, 8, 9, 10, 11, 12, 244 5, 6, 7, 8, 9, 10, 11, 12, 245 0, -1 246 }; 247 248 static int _sc_tdm_arbiter_table_4y[] = { 249 13, 14, 15, 16, 17, 18, 19, 20, 250 13, 14, 15, 16, 17, 18, 19, 20, 251 13, 14, 15, 16, 17, 18, 19, 20, 252 13, 14, 15, 16, 17, 18, 19, 20, 253 13, 14, 15, 16, 17, 18, 19, 20, 254 13, 14, 15, 16, 17, 18, 19, 20, 255 13, 14, 15, 16, 17, 18, 19, 20, 256 13, 14, 15, 16, 17, 18, 19, 20, 257 0x1f, -1 258 }; 259 260 static int _sc_tdm_arbiter_table_5x[] = { 261 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 262 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 263 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 264 0, -1 265 }; 266 267 static int _sc_tdm_arbiter_table_5y[] = { 268 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 269 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 270 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 271 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 272 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 273 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 274 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 275 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 276 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 27, 277 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 278 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 279 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 28, 280 -1 281 }; 282 283 static int _sc_tdm_arbiter_table_6x[] = { 284 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 285 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 286 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 287 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 288 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 289 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 290 1, 2, 3, 4, 9, 10, 11, 12, 5, 6, 7, 8, 9, 10, 11, 12, 291 0, -1 292 }; 293 294 static int _sc_tdm_arbiter_table_6y[] = { 295 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 296 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 297 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 298 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 299 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 300 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 301 17, 18, 19, 20, 13, 14, 15, 16, 21, 22, 23, 24, 13, 14, 15, 16, 302 25, -1 303 }; 304 305 STATIC int 306 soc_sc_tdm_arbiter_init(int unit) 307 { 308 int *x_list, *y_list; 309 int arb_index, max_arb_index; 310 arb_tdm_table_entry_t arb_entry; 311 uint32 tdm_en; 312 uint16 dev_id; 313 uint8 rev_id; 314 315 soc_cm_get_id(unit, &dev_id, &rev_id); 316 317 switch (dev_id) { 318 case BCM56820_DEVICE_ID: 319 case BCM88732_DEVICE_ID: 320 x_list = _sc_tdm_arbiter_table_1x; 321 y_list = _sc_tdm_arbiter_table_1y; 322 break; 323 case BCM56821_DEVICE_ID: 324 if (soc_property_get(unit, spn_BCM56821_20X12, 0)) { 325 x_list = _sc_tdm_arbiter_table_5x; 326 y_list = _sc_tdm_arbiter_table_5y; 327 } else { 328 x_list = _sc_tdm_arbiter_table_2x; 329 y_list = _sc_tdm_arbiter_table_2y; 330 } 331 break; 332 case BCM56822_DEVICE_ID: 333 if (soc_property_get(unit, spn_BCM56822_8X16, 0)) { 334 x_list = _sc_tdm_arbiter_table_4x; 335 } else { 336 x_list = _sc_tdm_arbiter_table_3x; 337 } 338 y_list = _sc_tdm_arbiter_table_1y; 339 break; 340 case BCM56823_DEVICE_ID: 341 x_list = _sc_tdm_arbiter_table_3x; 342 y_list = _sc_tdm_arbiter_table_3y; 343 break; 344 case BCM56825_DEVICE_ID: 345 x_list = _sc_tdm_arbiter_table_6x; 346 y_list = _sc_tdm_arbiter_table_6y; 347 break; 348 case BCM56725_DEVICE_ID: 349 if (soc_property_get(unit, spn_BCM56725_16X16, 0)) { 350 x_list = _sc_tdm_arbiter_table_4x; 351 y_list = _sc_tdm_arbiter_table_4y; 352 } else { 353 x_list = _sc_tdm_arbiter_table_3x; 354 y_list = _sc_tdm_arbiter_table_3y; 355 } 356 break; 357 case BCM56720_DEVICE_ID: 358 case BCM56721_DEVICE_ID: 359 x_list = _sc_tdm_arbiter_table_4x; 360 y_list = _sc_tdm_arbiter_table_4y; 361 break; 362 default: 363 return SOC_E_UNAVAIL; 364 } 365 366 max_arb_index = soc_mem_index_max(unit, ARB_TDM_TABLEm); 367 368 /* Ingress pipe select X */ 369 SOC_IF_ERROR_RETURN 370 (soc_scorpion_pipe_select(unit, FALSE, SOC_PIPE_SELECT_X)); 371 372 arb_index = 0; 373 sal_memset(&arb_entry, 0, sizeof(arb_entry)); 374 while ((arb_index <= max_arb_index) && (x_list[arb_index] >= 0)) { 375 soc_mem_field32_set(unit, X_ARB_TDM_TABLEm, &arb_entry, 376 PORT_NUMf, x_list[arb_index]); 377 if (x_list[arb_index + 1] < 0) { 378 soc_mem_field32_set(unit, X_ARB_TDM_TABLEm, &arb_entry, 379 WRAP_ENf, 1); 380 } 381 /* MMU table */ 382 SOC_IF_ERROR_RETURN 383 (WRITE_X_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, 384 arb_index, &arb_entry)); 385 /* Ingress (X) table */ 386 SOC_IF_ERROR_RETURN 387 (WRITE_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, 388 arb_index, &arb_entry)); 389 arb_index++; 390 } 391 392 SOC_IF_ERROR_RETURN 393 (soc_scorpion_pipe_select(unit, FALSE, SOC_PIPE_SELECT_Y)); 394 arb_index = 0; 395 sal_memset(&arb_entry, 0, sizeof(arb_entry)); 396 while ((arb_index <= max_arb_index) && (y_list[arb_index] >= 0)) { 397 soc_mem_field32_set(unit, Y_ARB_TDM_TABLEm, &arb_entry, 398 PORT_NUMf, y_list[arb_index]); 399 if (y_list[arb_index + 1] < 0) { 400 soc_mem_field32_set(unit, Y_ARB_TDM_TABLEm, &arb_entry, 401 WRAP_ENf, 1); 402 } 403 /* MMU table */ 404 SOC_IF_ERROR_RETURN 405 (WRITE_Y_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, 406 arb_index, &arb_entry)); 407 /* Ingress (Y) table */ 408 SOC_IF_ERROR_RETURN 409 (WRITE_ARB_TDM_TABLEm(unit, SOC_BLOCK_ALL, 410 arb_index, &arb_entry)); 411 arb_index++; 412 } 413 414 /* While still in Y pipe */ 415 tdm_en = 1; 416 SOC_IF_ERROR_RETURN(WRITE_TDM_ENr(unit, tdm_en)); 417 418 /* Return to default */ 419 SOC_IF_ERROR_RETURN 420 (soc_scorpion_pipe_select(unit, FALSE, SOC_PIPE_SELECT_X)); 421 422 /* Turn everything on */ 423 SOC_IF_ERROR_RETURN(WRITE_TDM_ENr(unit, tdm_en)); 424 SOC_IF_ERROR_RETURN(WRITE_X_TDM_ENr(unit, tdm_en)); 425 SOC_IF_ERROR_RETURN(WRITE_Y_TDM_ENr(unit, tdm_en)); 426 427 return SOC_E_NONE; 428 } 429 430 STATIC int 431 soc_sc_cam_tuning(int unit) 432 { 433 int i, pipe_select; 434 int defip_cam_tm_val, fp_cam_tm_val, vfp_cam_tm_val, efp_cam_tm_val; 435 uint32 rval; 436 437 defip_cam_tm_val = soc_property_get(unit, spn_DEFIP_CAM_TM, 0x10); 438 fp_cam_tm_val = soc_property_get(unit, spn_FP_CAM_TM, 0x10); 439 vfp_cam_tm_val = soc_property_get(unit, spn_VFP_CAM_TM, 0x10); 440 efp_cam_tm_val = soc_property_get(unit, spn_EFP_CAM_TM, 0x10); 441 442 443 for (i = 0; i < 2; i++) { 444 pipe_select = (i == 0) ? SOC_PIPE_SELECT_Y : SOC_PIPE_SELECT_X; 445 446 /* Ingress pipe select */ 447 SOC_IF_ERROR_RETURN 448 (soc_scorpion_pipe_select(unit, FALSE, pipe_select)); 449 rval = 0; 450 SOC_IF_ERROR_RETURN(READ_FP_CAM_CONTROL_TM_7_THRU_0r(unit, &rval)); 451 soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, 452 &rval, ALL_TCAMS_TM_7_0f, fp_cam_tm_val); 453 SOC_IF_ERROR_RETURN(WRITE_FP_CAM_CONTROL_TM_7_THRU_0r(unit, rval)); 454 455 if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) { 456 continue; 457 } 458 459 rval = 0; 460 SOC_IF_ERROR_RETURN(READ_L3_DEFIP_CAM_DBGCTRL0r(unit, &rval)); 461 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, 462 &rval, CAM0_TMf, defip_cam_tm_val); 463 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL0r(unit, rval)); 464 465 rval = 0; 466 SOC_IF_ERROR_RETURN(READ_VFP_CAM_CONTROL_TM_7_THRU_0r(unit, &rval)); 467 soc_reg_field_set(unit, VFP_CAM_CONTROL_TM_7_THRU_0r, 468 &rval, TMf, vfp_cam_tm_val); 469 SOC_IF_ERROR_RETURN(WRITE_VFP_CAM_CONTROL_TM_7_THRU_0r(unit, rval)); 470 471 /* Egress pipe select */ 472 SOC_IF_ERROR_RETURN 473 (soc_scorpion_pipe_select(unit, TRUE, pipe_select)); 474 rval = 0; 475 SOC_IF_ERROR_RETURN(READ_EFP_RAM_CONTROLr(unit, &rval)); 476 soc_reg_field_set(unit, EFP_RAM_CONTROLr, 477 &rval, EFP_CAM_SAMf, efp_cam_tm_val); 478 SOC_IF_ERROR_RETURN(WRITE_EFP_RAM_CONTROLr(unit, rval)); 479 } 480 481 /* End of loop leaves pipe selects set to X */ 482 return SOC_E_NONE; 483 } 484 #endif 485 486 int 487 soc_bradley_misc_init(int unit) 488 { 489 uint32 rval; 490 uint64 reg64; 491 int port; 492 uint32 addr; 493 soc_pbmp_t pbmp; 494 int divisor, dividend; 495 uint16 dev_id; 496 uint8 rev_id; 497 #if defined(BCM_HB_GW_SUPPORT) 498 int i, tm_val; 499 #endif 500 501 soc_cm_get_id(unit, &dev_id, &rev_id); 502 503 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 504 /* Clear IPIPE/EPIPE Memories */ 505 SOC_IF_ERROR_RETURN(soc_bradley_pipe_mem_clear(unit)); 506 } 507 508 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 509 soc_reg_field_set(unit, MISCCONFIGr, &rval, 510 METERING_CLK_ENf, 1); 511 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 512 513 #ifdef BCM_HB_GW_SUPPORT 514 if (soc_reg_field_valid(unit, CMIC_XGXS0_PLL_CONTROL_2r, 515 XGPLL_EN125f)) { 516 /* coverity[dead_error_begin : FALSE] */ 517 SOC_IF_ERROR_RETURN(READ_CMIC_XGXS0_PLL_CONTROL_2r(unit, &rval)); 518 soc_reg_field_set(unit, CMIC_XGXS0_PLL_CONTROL_2r, &rval, 519 XGPLL_EN125f, 1); 520 /* coverity[dead_error_begin : FALSE] */ 521 SOC_IF_ERROR_RETURN(WRITE_CMIC_XGXS0_PLL_CONTROL_2r(unit, rval)); 522 } 523 #endif 524 525 #ifdef BCM_SCORPION_SUPPORT 526 if (SOC_IS_SC_CQ(unit)) { 527 soc_field_t fields[3]; 528 uint32 values[3]; 529 530 /* Bypass control settings */ 531 if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) { 532 rval = 0; 533 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 534 IVXLT_BYPASS_ENABLEf, 1); 535 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 536 IL3_BYPASS_ENABLEf, 1); 537 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 538 IL3MC_BYPASS_ENABLEf, 1); 539 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 540 IRSEL1_BYPASS_ENABLEf, 1); 541 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 542 IRSEL2_BYPASS_ENABLEf, 1); 543 if (SOC_SWITCH_BYPASS_MODE(unit) == 544 SOC_SWITCH_BYPASS_MODE_L3_AND_FP) { 545 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 546 IFP_BYPASS_ENABLEf, 1); 547 } 548 SOC_IF_ERROR_RETURN(WRITE_ING_BYPASS_CTRLr(unit, rval)); 549 550 rval = 0; 551 soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval, 552 EL3_BYPASSf, 1); 553 soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval, 554 EVXLT_BYPASSf, 1); 555 soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval, 556 EFP_BYPASSf, 1); 557 SOC_IF_ERROR_RETURN(WRITE_EGR_BYPASS_CTRLr(unit, rval)); 558 } 559 560 /* Enable dual hash on L2 and L3 tables */ 561 fields[0] = ENABLEf; 562 values[0] = 1; 563 fields[1] = HASH_SELECTf; 564 values[1] = FB_HASH_CRC32_LOWER; 565 fields[2] = INSERT_LEAST_FULL_HALFf; 566 values[2] = 1; 567 SOC_IF_ERROR_RETURN 568 (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 569 3, fields, values)); 570 SOC_IF_ERROR_RETURN 571 (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 572 3, fields, values)); 573 574 rval = 0; 575 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_0_4r, 576 &rval, REMAP_PORT_0f, 25); 577 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_0_4r, 578 &rval, REMAP_PORT_1f, 26); 579 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_0_4r, 580 &rval, REMAP_PORT_2f, 27); 581 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_0_4r, 582 &rval, REMAP_PORT_3f, 28); 583 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_0_4r, 584 &rval, REMAP_PORT_4f, 6); 585 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_0_4r(unit, rval)); 586 587 rval = 0; 588 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_5_9r, 589 &rval, REMAP_PORT_5f, 5); 590 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_5_9r, 591 &rval, REMAP_PORT_6f, 4); 592 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_5_9r, 593 &rval, REMAP_PORT_7f, 3); 594 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_5_9r, 595 &rval, REMAP_PORT_8f, 2); 596 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_5_9r, 597 &rval, REMAP_PORT_9f, 1); 598 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_5_9r(unit, rval)); 599 600 rval = 0; 601 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_10_14r, 602 &rval, REMAP_PORT_10f, 12); 603 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_10_14r, 604 &rval, REMAP_PORT_11f, 11); 605 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_10_14r, 606 &rval, REMAP_PORT_12f, 10); 607 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_10_14r, 608 &rval, REMAP_PORT_13f, 9); 609 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_10_14r, 610 &rval, REMAP_PORT_14f, 8); 611 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_10_14r(unit, rval)); 612 rval = 0; 613 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_15_19r, 614 &rval, REMAP_PORT_15f, 7); 615 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_15_19r, 616 &rval, REMAP_PORT_16f, 13); 617 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_15_19r, 618 &rval, REMAP_PORT_17f, 14); 619 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_15_19r, 620 &rval, REMAP_PORT_18f, 15); 621 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_15_19r, 622 &rval, REMAP_PORT_19f, 16); 623 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_15_19r(unit, rval)); 624 625 rval = 0; 626 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_20_24r, 627 &rval, REMAP_PORT_20f, 17); 628 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_20_24r, 629 &rval, REMAP_PORT_21f, 18); 630 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_20_24r, 631 &rval, REMAP_PORT_22f, 19); 632 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_20_24r, 633 &rval, REMAP_PORT_23f, 20); 634 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_20_24r, 635 &rval, REMAP_PORT_24f, 21); 636 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_20_24r(unit, rval)); 637 638 rval = 0; 639 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_25_29r, 640 &rval, REMAP_PORT_25f, 22); 641 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_25_29r, 642 &rval, REMAP_PORT_26f, 23); 643 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_25_29r, 644 &rval, REMAP_PORT_27f, 24); 645 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_25_29r, 646 &rval, REMAP_PORT_28f, 0); 647 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_25_29r, 648 &rval, REMAP_PORT_29f, 29); 649 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_25_29r(unit, rval)); 650 651 rval = 0; 652 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_30_34r, 653 &rval, REMAP_PORT_30f, 30); 654 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_30_34r, 655 &rval, REMAP_PORT_31f, 31); 656 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_30_34r, 657 &rval, REMAP_PORT_32f, 32); 658 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_30_34r, 659 &rval, REMAP_PORT_33f, 33); 660 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_30_34r, 661 &rval, REMAP_PORT_34f, 34); 662 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_30_34r(unit, rval)); 663 664 rval = 0; 665 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_35_39r, 666 &rval, REMAP_PORT_35f, 35); 667 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_35_39r, 668 &rval, REMAP_PORT_36f, 36); 669 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_35_39r, 670 &rval, REMAP_PORT_37f, 37); 671 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_35_39r, 672 &rval, REMAP_PORT_38f, 38); 673 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_35_39r, 674 &rval, REMAP_PORT_39f, 39); 675 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_35_39r(unit, rval)); 676 677 rval = 0; 678 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_40_44r, 679 &rval, REMAP_PORT_40f, 40); 680 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_40_44r, 681 &rval, REMAP_PORT_41f, 41); 682 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_40_44r, 683 &rval, REMAP_PORT_42f, 42); 684 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_40_44r, 685 &rval, REMAP_PORT_43f, 43); 686 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_40_44r, 687 &rval, REMAP_PORT_44f, 44); 688 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_40_44r(unit, rval)); 689 690 rval = 0; 691 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_45_49r, 692 &rval, REMAP_PORT_45f, 45); 693 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_45_49r, 694 &rval, REMAP_PORT_46f, 46); 695 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_45_49r, 696 &rval, REMAP_PORT_47f, 47); 697 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_45_49r, 698 &rval, REMAP_PORT_48f, 48); 699 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_45_49r, 700 &rval, REMAP_PORT_49f, 49); 701 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_45_49r(unit, rval)); 702 703 rval = 0; 704 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_50_54r, 705 &rval, REMAP_PORT_50f, 50); 706 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_50_54r, 707 &rval, REMAP_PORT_51f, 51); 708 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_50_54r, 709 &rval, REMAP_PORT_52f, 52); 710 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_50_54r, 711 &rval, REMAP_PORT_53f, 53); 712 soc_reg_field_set(unit,CMIC_LED_PORT_ORDER_REMAP_50_54r, 713 &rval, REMAP_PORT_54f, 54); 714 SOC_IF_ERROR_RETURN(WRITE_CMIC_LED_PORT_ORDER_REMAP_50_54r(unit, rval)); 715 716 rval = 0; 717 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP_CTRLr(unit, &rval)); 718 soc_reg_field_set(unit,CMIC_LEDUP_CTRLr, 719 &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 3); 720 soc_reg_field_set(unit,CMIC_LEDUP_CTRLr, 721 &rval, LEDUP_SCAN_START_DELAYf, 3); 722 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP_CTRLr(unit, rval)); 723 } 724 #endif /* BCM_SCORPION_SUPPORT */ 725 726 /* 727 * Egress Enable 728 */ 729 rval = 0; 730 soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1); 731 PBMP_ALL_ITER(unit, port) { 732 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval)); 733 } 734 735 rval = 0; 736 soc_reg_field_set(unit, EPC_LINK_BMAPr, &rval, PORT_BITMAPf, 737 SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 0)); 738 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPr(unit, rval)); 739 740 /* GMAC init should be moved to mac */ 741 rval = 0; 742 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1); 743 PBMP_GX_ITER(unit, port) { 744 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 745 } 746 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0); 747 PBMP_GX_ITER(unit, port) { 748 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 749 } 750 if (soc_reg_field_valid(unit, GPORT_CONFIGr, GPORT_ENf)) { 751 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, GPORT_ENf, 1); 752 } 753 SOC_PBMP_ASSIGN(pbmp, PBMP_GX_ALL(unit)); 754 SOC_PBMP_AND(pbmp, PBMP_E_ALL(unit)); 755 PBMP_ITER(pbmp, port) { 756 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 757 } 758 759 /* Enable CRC regen to avoid CRC in LAG failover */ 760 PBMP_E_ITER(unit, port) { 761 SOC_IF_ERROR_RETURN 762 (soc_reg_field32_modify(unit, EGR_DBGr, port, 763 ALWAYS_CRC_REGENf, 1)); 764 } 765 766 /* XMAC init should be moved to mac */ 767 rval = 0; 768 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1); 769 PBMP_HG_ITER(unit, port) { 770 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 771 } 772 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0); 773 PBMP_XE_ITER(unit, port) { 774 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 775 } 776 777 if (SOC_IS_SC_CQ(unit)) { 778 rval = 0; 779 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, XPORT_MODE_BITSf, 1); 780 PBMP_HG_ITER(unit, port) { 781 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 782 } 783 PBMP_XE_ITER(unit, port) { 784 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 785 } 786 787 /* Drop the packet when traffic exceeds available IP bandwidth */ 788 rval = 0; 789 soc_reg_field_set(unit, PKT_DROP_ENABLEr, &rval, 790 PKT_DROP_ENABLEf, 1); 791 PBMP_GX_ITER(unit, port) { 792 SOC_IF_ERROR_RETURN(WRITE_PKT_DROP_ENABLEr(unit, port, rval)); 793 } 794 795 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, XPORT_MODE_BITSf, 2); 796 SOC_PBMP_ASSIGN(pbmp, PBMP_GX_ALL(unit)); 797 SOC_PBMP_AND(pbmp, PBMP_GE_ALL(unit)); 798 PBMP_ITER(pbmp, port) { 799 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 800 } 801 802 /* QG ports only */ 803 SOC_PBMP_ASSIGN(pbmp, PBMP_GE_ALL(unit)); 804 SOC_PBMP_REMOVE(pbmp, PBMP_GX_ALL(unit)); 805 rval = 0; 806 soc_reg_field_set(unit, QGPORT_CONFIGr, &rval, CLR_CNTf, 1); 807 PBMP_ITER(pbmp, port) { 808 SOC_IF_ERROR_RETURN(WRITE_QGPORT_CONFIGr(unit, port, rval)); 809 } 810 soc_reg_field_set(unit, QGPORT_CONFIGr, &rval, CLR_CNTf, 0); 811 PBMP_ITER(pbmp, port) { 812 SOC_IF_ERROR_RETURN(WRITE_QGPORT_CONFIGr(unit, port, rval)); 813 } 814 if (soc_reg_field_valid(unit, QGPORT_CONFIGr, GPORT_ENf)) { 815 soc_reg_field_set(unit, QGPORT_CONFIGr, &rval, GPORT_ENf, 1); 816 } 817 PBMP_ITER(pbmp, port) { 818 SOC_IF_ERROR_RETURN(WRITE_QGPORT_CONFIGr(unit, port, rval)); 819 } 820 821 /* Clear 8 beat accumulation on QG ports only */ 822 rval = 0; 823 PBMP_ITER(pbmp, port) { 824 SOC_IF_ERROR_RETURN(WRITE_EGR_ACCU_8BEATSr(unit, port, rval)); 825 } 826 } 827 828 if (soc_feature(unit, soc_feature_ctr_xaui_activity)) { 829 PBMP_PORT_ITER(unit, port) { 830 break; 831 } 832 addr = soc_reg_addr(unit, XPORT_CONFIGr, port, 0); 833 addr &= ~(0x3F << SOC_REGIDX_BP); 834 835 rval = 0; 836 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1); 837 /* 838 * For correct LED operation, XPORT must be enabled also on 839 * all unused ports, however the soc_reg_addr function only 840 * works on valid ports, so the registers address must be 841 * calculated 'manually'. 842 */ 843 for (port = 0; port < 20; port++) { 844 if (!SOC_PORT_VALID(unit, port)) { 845 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, 846 addr | (port << SOC_REGIDX_BP), rval)); 847 } 848 } 849 } 850 851 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 852 * causes the outer tag to be removed from packets that don't have 853 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 854 */ 855 if (SOC_REG_IS_VALID(unit, EGR_VLAN_CONTROL_1r)) { 856 rval = 0; 857 if (SOC_REG_FIELD_VALID(unit, EGR_VLAN_CONTROL_1r, REMARK_OUTER_DOT1Pf)) { 858 /* Enable pri/cfi remarking on egress ports. */ 859 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf, 860 1); 861 } 862 PBMP_ALL_ITER(unit, port) { 863 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval)); 864 } 865 } 866 867 /* 868 * ING_CONFIG 869 */ 870 if (SOC_IS_SC_CQ(unit)) { 871 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®64)); 872 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 873 L3SRC_HIT_ENABLEf, 1); 874 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 875 L2DST_HIT_ENABLEf, 1); 876 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 877 APPLY_EGR_MASK_ON_L2f, 1); 878 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 879 APPLY_EGR_MASK_ON_L3f, 1); 880 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 881 ARP_VALIDATION_ENf, 1); 882 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 883 DRACO1_5_MIRRORf, 1); 884 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 885 ARP_RARP_TO_FPf, 0x3); 886 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 887 ARP_VALIDATION_ENf, 1); 888 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64)); 889 } else { 890 SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, &rval)); 891 soc_reg_field_set(unit, ING_CONFIGr, &rval, L3SRC_HIT_ENABLEf, 1); 892 soc_reg_field_set(unit, ING_CONFIGr, &rval, L2DST_HIT_ENABLEf, 1); 893 soc_reg_field_set(unit, ING_CONFIGr, &rval, 894 APPLY_EGR_MASK_ON_L2f, 1); 895 soc_reg_field_set(unit, ING_CONFIGr, &rval, 896 APPLY_EGR_MASK_ON_L3f, 1); 897 soc_reg_field_set(unit, ING_CONFIGr, &rval, DRACO1_5_MIRRORf, 1); 898 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIGr(unit, rval)); 899 } 900 901 /* Backwards compatible mirroring by default */ 902 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 903 soc_reg_field_set(unit, MISCCONFIGr, &rval, 904 DRACO_1_5_MIRRORING_MODE_ENf, 1); 905 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 906 /* Ingress mirror above */ 907 SOC_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, &rval)); 908 soc_reg_field_set(unit, EGR_CONFIGr, &rval, DRACO1_5_MIRRORf, 1); 909 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIGr(unit, rval)); 910 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval)); 911 soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, RING_MODEf, 1); 912 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval)); 913 914 /* Multicast range initialization */ 915 SOC_IF_ERROR_RETURN 916 (soc_hbx_higig2_mcast_sizes_set(unit, 917 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 918 SOC_HBX_MULTICAST_RANGE_DEFAULT), 919 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 920 SOC_HBX_MULTICAST_RANGE_DEFAULT), 921 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 922 SOC_HBX_MULTICAST_RANGE_DEFAULT))); 923 SOC_IF_ERROR_RETURN 924 (soc_hbx_mcast_size_set(unit, soc_property_get(unit, 925 spn_MULTICAST_L2_RANGE, SOC_HBX_MULTICAST_RANGE_DEFAULT))); 926 SOC_IF_ERROR_RETURN 927 (soc_hbx_ipmc_size_set(unit, soc_property_get(unit, 928 spn_MULTICAST_L3_RANGE, soc_mem_index_count(unit, L3_IPMCm)))); 929 930 rval = 0x01; /* 125KHz I2C sampling rate */ 931 SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval)); 932 933 #if defined(BCM_HB_GW_SUPPORT) 934 if (SOC_IS_HB_GW(unit)) { 935 /* 936 * Set reference clock (based on 180MHz core clock) 937 * to be 180MHz * (1/36) = 5MHz 938 * so MDC output frequency is 0.5 * 5MHz = 2.5MHz 939 */ 940 941 divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, 36); 942 dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1); 943 rval = 0; 944 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor); 945 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend); 946 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval)); 947 } else 948 #endif 949 if (SOC_IS_SC_CQ(unit)) { 950 int ext_mdio_divisor, ext_mdio_dividend, 951 int_mdio_divisor, int_mdio_dividend, 952 stdma_divisor, stdma_dividend, 953 i2c_divisor, i2c_dividend; 954 955 /* 956 * Premises of the calculation: 957 * 958 * Core clock speed 959 * 56820 (220 MHz) 960 * 56821/56720/56721 (225 MHz) 961 * 56822/56823/56725 (245 MHz) 962 * 56825 (290 MHz) 963 * 964 * EXT_MDIO result = INT_MDIO result = 5 MHz 965 * I2C result / (2 * 10) = 250-400 kHz 966 * I2C result = 5-8 MHz 967 * STDMA result = 25 MHz 968 * 969 * result = core * dividend / divisor 970 * ==> 971 * dividend : divisor = result : core 972 */ 973 974 switch (dev_id) { 975 case BCM56820_DEVICE_ID: 976 case BCM88732_DEVICE_ID: 977 ext_mdio_dividend = 1; 978 ext_mdio_divisor = 44; 979 int_mdio_dividend = 1; 980 int_mdio_divisor = 44; 981 stdma_dividend = 1; 982 stdma_divisor = 9; 983 i2c_dividend = 1; 984 i2c_divisor = 40; 985 break; 986 case BCM56821_DEVICE_ID: 987 case BCM56720_DEVICE_ID: 988 case BCM56721_DEVICE_ID: 989 ext_mdio_dividend = 1; 990 ext_mdio_divisor = 45; 991 int_mdio_dividend = 1; 992 int_mdio_divisor = 45; 993 stdma_dividend = 1; 994 stdma_divisor = 9; 995 i2c_dividend = 1; 996 i2c_divisor = 40; 997 break; 998 case BCM56822_DEVICE_ID: 999 case BCM56823_DEVICE_ID: 1000 case BCM56725_DEVICE_ID: 1001 ext_mdio_dividend = 1; 1002 ext_mdio_divisor = 49; 1003 int_mdio_dividend = 1; 1004 int_mdio_divisor = 49; 1005 stdma_dividend = 1; 1006 stdma_divisor = 10; 1007 i2c_dividend = 1; 1008 i2c_divisor = 49; 1009 break; 1010 case BCM56825_DEVICE_ID: 1011 ext_mdio_dividend = 1; 1012 ext_mdio_divisor = 58; 1013 int_mdio_dividend = 1; 1014 int_mdio_divisor = 58; 1015 stdma_dividend = 1; 1016 stdma_divisor = 12; 1017 i2c_dividend = 1; 1018 i2c_divisor = 58; 1019 break; 1020 default: 1021 return SOC_E_UNAVAIL; 1022 } 1023 1024 divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, 1025 ext_mdio_divisor); 1026 dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1027 ext_mdio_dividend); 1028 rval = 0; 1029 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, 1030 DIVISORf, divisor); 1031 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, 1032 DIVIDENDf, dividend); 1033 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval)); 1034 1035 divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, 1036 int_mdio_divisor); 1037 dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1038 int_mdio_dividend); 1039 rval = 0; 1040 soc_reg_field_set(unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, 1041 DIVISORf, divisor); 1042 soc_reg_field_set(unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, 1043 DIVIDENDf, dividend); 1044 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval)); 1045 1046 divisor = soc_property_get(unit, spn_RATE_I2C_DIVISOR, 1047 i2c_divisor); 1048 dividend = soc_property_get(unit, spn_RATE_I2C_DIVIDEND, 1049 i2c_dividend); 1050 rval = 0; 1051 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, 1052 DIVISORf, divisor); 1053 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, 1054 DIVIDENDf, dividend); 1055 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval)); 1056 1057 divisor = soc_property_get(unit, spn_RATE_STDMA_DIVISOR, 1058 stdma_divisor); 1059 dividend = soc_property_get(unit, spn_RATE_STDMA_DIVIDEND, 1060 stdma_dividend); 1061 rval = 0; 1062 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, 1063 DIVISORf, divisor); 1064 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, 1065 DIVIDENDf, dividend); 1066 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval)); 1067 } 1068 1069 #if defined(BCM_HB_GW_SUPPORT) 1070 if (SOC_IS_HB_GW(unit)) { 1071 tm_val = soc_property_get(unit, spn_DEFIP_CAM_TM, 0x300); 1072 SOC_IF_ERROR_RETURN(READ_L3_DEFIP_CAM_DBGCTRL0r(unit, &rval)); 1073 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval, 1074 CAM0_TMf, tm_val); 1075 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL0r(unit, rval)); 1076 1077 tm_val = soc_property_get(unit, spn_FP_CAM_TM, 0x300); 1078 for (i = 0; i < 8; i++) { 1079 SOC_IF_ERROR_RETURN(READ_FP_CAM_CONTROLr(unit, i, &rval)); 1080 soc_reg_field_set(unit, FP_CAM_CONTROLr, &rval, TMf, tm_val); 1081 SOC_IF_ERROR_RETURN(WRITE_FP_CAM_CONTROLr(unit, i, rval)); 1082 } 1083 1084 /* incorrect HB_GW rev A0 reset value */ 1085 SOC_IF_ERROR_RETURN 1086 (READ_L2_AGE_DEBUGr(unit, &rval)); 1087 soc_reg_field_set(unit, L2_AGE_DEBUGr, &rval, 1088 AGE_COUNTf, 0x7ff); 1089 SOC_IF_ERROR_RETURN 1090 (WRITE_L2_AGE_DEBUGr(unit, rval)); 1091 } 1092 #endif 1093 #ifdef BCM_SCORPION_SUPPORT 1094 else if (SOC_IS_SC_CQ(unit)) { 1095 /* CAM tuning */ 1096 if (SOC_SWITCH_BYPASS_MODE(unit) != 1097 SOC_SWITCH_BYPASS_MODE_L3_AND_FP) { 1098 SOC_IF_ERROR_RETURN(soc_sc_cam_tuning(unit)); 1099 } 1100 } 1101 #endif 1102 /* Enable MMU parity error reporting */ 1103 SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0)); 1104 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_ENr(unit, &rval)); 1105 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1106 MTRO_PAR_ERR_ENf, 1); 1107 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1108 TOQ1_VLAN_TBL_PAR_ERR_ENf, 1); 1109 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1110 TOQ1_IPMC_TBL_PAR_ERR_ENf, 1); 1111 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1112 TOQ1_CELLLINK_PAR_ERR_ENf, 1); 1113 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1114 TOQ1_PKTLINK_PAR_ERR_ENf, 1); 1115 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1116 TOQ1_PKTHDR1_PAR_ERR_ENf, 1); 1117 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1118 TOQ1_CELLHDR_PAR_ERR_ENf, 1); 1119 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1120 TOQ0_VLAN_TBL_PAR_ERR_ENf, 1); 1121 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1122 TOQ0_IPMC_TBL_PAR_ERR_ENf, 1); 1123 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1124 TOQ0_CELLLINK_PAR_ERR_ENf, 1); 1125 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1126 TOQ0_PKTLINK_PAR_ERR_ENf, 1); 1127 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1128 TOQ0_PKTHDR1_PAR_ERR_ENf, 1); 1129 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1130 TOQ0_CELLHDR_PAR_ERR_ENf, 1); 1131 if (soc_feature(unit, soc_feature_ip_mcast_repl)) { 1132 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1133 MEM1_VLAN_TBL_PAR_ERR_ENf, 1); 1134 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1135 MEM1_IPMC_TBL_PAR_ERR_ENf, 1); 1136 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1137 ENQ_IPMC_TBL_PAR_ERR_ENf, 1); 1138 } 1139 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1140 DEQ1_CELLCRC_ERR_ENf, 1); 1141 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1142 DEQ0_CELLCRC_ERR_ENf, 1); 1143 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1144 DEQ1_NOT_IP_ERR_ENf, 1); 1145 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1146 DEQ0_NOT_IP_ERR_ENf, 1); 1147 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1148 DEQ_PKTHDR0_ERR_ENf, 1); 1149 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1150 DEQ_PKTHDR_CPU_ERR_ENf, 1); 1151 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1152 CFAP_MEM_FAIL_ENf, 1); 1153 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1154 CFAP_PAR_ERR_ENf, 1); 1155 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1156 CCP_PAR_ERR_ENf, 1); 1157 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1158 AGING_EXP_PAR_ERR_ENf, 1); 1159 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1160 AGING_CTR_PAR_ERR_ENf, 1); 1161 #ifdef BCM_SCORPION_SUPPORT 1162 if (SOC_IS_SC_CQ(unit)) { 1163 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1164 WRED_PAR_ERR_ENf, 1); 1165 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1166 DEQ0_LENGTH_PAR_ERR_ENf, 1); 1167 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1168 DEQ1_LENGTH_PAR_ERR_ENf, 1); 1169 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1170 START_BY_START_ERR_ENf, 1); 1171 } 1172 #endif 1173 SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_ENr(unit, rval)); 1174 1175 1176 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1177 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 1178 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1179 1180 memset(&_bradley_ser_functions, 0, sizeof(soc_ser_functions_t)); 1181 1182 if (soc_property_get(unit, spn_PARITY_ENABLE, 1)) { 1183 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 1); 1184 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 1); 1185 _bradley_ser_functions._soc_ser_parity_error_intr_f = &soc_bradley_mmu_parity_error; 1186 soc_ser_function_register(unit, &_bradley_ser_functions); 1187 } 1188 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 1189 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1190 1191 #ifdef BCM_SCORPION_SUPPORT 1192 if (SOC_IS_SC_CQ(unit)) { 1193 soc_field_t fields[] = { HGTRUNK_RES_ENf, LAG_RES_ENf }; 1194 uint32 values[] = { 1, 1 }; 1195 1196 /* Enable vrf based l3 lookup by default. */ 1197 SOC_IF_ERROR_RETURN 1198 (soc_reg_field32_modify(unit, VRF_MASKr, REG_PORT_ANY, MASKf, 0)); 1199 1200 /* Initialize TDM arbiter tables so all ports are operable */ 1201 SOC_IF_ERROR_RETURN(soc_sc_tdm_arbiter_init(unit)); 1202 1203 /* Setup SW2_FP_DST_ACTION_CONTROL */ 1204 SOC_IF_ERROR_RETURN 1205 (soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr, 1206 REG_PORT_ANY, 2, fields, values)); 1207 1208 /* Turn on ingress/egress parity */ 1209 if (soc_property_get(unit, spn_PARITY_ENABLE, 1)) { 1210 SOC_IF_ERROR_RETURN(_soc_sc_pipe_parity_enable(unit, TRUE)); 1211 _bradley_ser_functions._soc_ser_parity_error_intr_f = &soc_scorpion_parity_error; 1212 soc_ser_function_register(unit, &_bradley_ser_functions); 1213 } 1214 } 1215 1216 if (soc_feature(unit, soc_feature_priority_flow_control)) { 1217 int class; 1218 soc_field_t unimac_fields[] = 1219 { PFC_REFRESH_ENf, PFC_REFRESH_TIMERf }; 1220 soc_field_t bigmac_fields[] = 1221 { PP_REFRESH_ENf, PP_REFRESH_TIMERf }; 1222 uint32 values[] = { 1, 0xc000 }; 1223 1224 /* Initialize the ports which might perform PFC */ 1225 PBMP_GX_ITER(unit, port) { 1226 SOC_IF_ERROR_RETURN 1227 (soc_reg_fields32_modify(unit, MAC_PFC_REFRESH_CTRLr, 1228 port, 2, unimac_fields, values)); 1229 SOC_IF_ERROR_RETURN 1230 (soc_reg_fields32_modify(unit, MAC_TXPPPCTRLr, 1231 port, 2, bigmac_fields, values)); 1232 SOC_IF_ERROR_RETURN 1233 (soc_reg_field32_modify(unit, UNIMAC_PFC_CTRLr, port, 1234 RX_PASS_PFC_FRMf, 1)); 1235 SOC_IF_ERROR_RETURN 1236 (soc_reg_field32_modify(unit, BMAC_PFC_CTRLr, port, 1237 RX_PASS_PFC_FRMf, 1)); 1238 } 1239 for (class = 0; class < 8; class++) { 1240 /* Initialize 1-1 mapping */ 1241 SOC_IF_ERROR_RETURN(READ_PRIO2COSr(unit, class, &rval)); 1242 soc_reg_field_set(unit, PRIO2COSr, &rval, COS0_7_BMPf, 1243 (1 << class)); 1244 SOC_IF_ERROR_RETURN(WRITE_PRIO2COSr(unit, class, rval)); 1245 } 1246 } 1247 #endif 1248 1249 soc_intr_enable(unit, IRQ_MEM_FAIL); 1250 1251 return SOC_E_NONE; 1252 } 1253 1254 /* 1255 * Bradley/HUMV MMU Configuration 1256 * 1257 * Since port modes can be changed dynamically between HG and XE, 1258 * the default configuration will support HG ports, i.e. we enable 1259 * the SC and QM queues. 1260 * 1261 * Configuration supports only a single priority group (PG2). 1262 */ 1263 1264 /* Configure all COS queues by default */ 1265 #ifndef BRADLEY_MMU_NUM_COS 1266 #define BRADLEY_MMU_NUM_COS 8 1267 #endif 1268 1269 /* Enable SC and QM queues by default */ 1270 #ifndef BRADLEY_MMU_USE_SC_QM 1271 #define BRADLEY_MMU_USE_SC_QM 1 1272 #endif 1273 1274 /* Standard Ethernet MTU (1 cell = 128 bytes) */ 1275 #ifndef BRADLEY_MMU_MTU_CELLS 1276 #define BRADLEY_MMU_MTU_CELLS 12 1277 #endif 1278 1279 /* Jumbo Frame MTU (1 cell = 128 bytes) */ 1280 #ifndef BRADLEY_MMU_JUMBO_CELLS 1281 #define BRADLEY_MMU_JUMBO_CELLS 80 1282 #endif 1283 1284 /* The following number of cells is based on packet simulations */ 1285 #define BRADLEY_MMU_PORT_MIN 72 1286 1287 /* Configure CPU port by default */ 1288 #ifndef BRADLEY_MMU_CONFIG_CPU 1289 #define BRADLEY_MMU_CONFIG_CPU 1 1290 #endif 1291 1292 #if BRADLEY_MMU_CONFIG_CPU == 1 1293 #define PBMP_MMU_ITER PBMP_ALL_ITER 1294 #else 1295 #define PBMP_MMU_ITER PBMP_GX_ITER 1296 #endif 1297 1298 #if BRADLEY_MMU_USE_SC_QM == 1 1299 #define BRADLEY_MMU_SC_MIN 12 1300 #define BRADLEY_MMU_QM_MIN 12 1301 #else 1302 #define BRADLEY_MMU_SC_MIN 0 1303 #define BRADLEY_MMU_QM_MIN 0 1304 #endif 1305 1306 #define SCORPION_PG_MAX 8 1307 1308 #define SCORPION_RESET_GRAN_SHIFT 4 1309 1310 /* Alternative disabling method b/c PORT_LIMIT_ENABLE bit is broken */ 1311 #define BRADLEY_OP_SHARED_LIMIT_DISABLE 0x3000 1312 #define SCORPION_OP_SHARED_LIMIT_DISABLE 0x3fff 1313 1314 /* CFAP adjustments */ 1315 #define BRADLEY_CFAP_FULL_SET_POINT_OFFSET 0x100 1316 #define BRADLEY_CFAP_FULL_RESET_POINT_OFFSET 0x1b0 1317 1318 /* This limit is in units of 8 cells */ 1319 #define SCORPION_COLOR_LIMIT 0x7ff 1320 1321 /* An "alpha" value of 1/2 */ 1322 #define BRADLEY_OP_QUEUE_SHARED_LIMIT_CMIC_ENCODING 4 1323 /* An "alpha" value of 1/4, but the encoding is different between devices */ 1324 #define SCORPION_OP_QUEUE_SHARED_LIMIT_CMIC_ENCODING 2 1325 1326 int 1327 soc_bradley_mmu_init(int unit) 1328 { 1329 uint32 rval, rval2, rval_cpu, wr_val; 1330 uint32 pg[SCORPION_PG_MAX]; 1331 int port, i; 1332 int num_ports, num_cos; 1333 int total_cells; 1334 int pg_max_hdrm_limit; 1335 int global_hdrm_limit; 1336 int total_shared_limit; 1337 int q_min, q_shared_limit_encoding_cmic; 1338 int op_buffer_shared_limit; 1339 int num_pg, kcells; 1340 int op_shared_limit_disable; 1341 1342 if (SOC_IS_SC_CQ(unit)) { 1343 kcells = 16; 1344 num_pg = 8; 1345 op_shared_limit_disable = SCORPION_OP_SHARED_LIMIT_DISABLE; 1346 q_shared_limit_encoding_cmic = 1347 SCORPION_OP_QUEUE_SHARED_LIMIT_CMIC_ENCODING; 1348 } else { 1349 kcells = 12; 1350 num_pg = 3; 1351 op_shared_limit_disable = BRADLEY_OP_SHARED_LIMIT_DISABLE; 1352 q_shared_limit_encoding_cmic = 1353 BRADLEY_OP_QUEUE_SHARED_LIMIT_CMIC_ENCODING; 1354 } 1355 1356 /* Number of port to configure */ 1357 num_ports = NUM_GX_PORT(unit) + BRADLEY_MMU_CONFIG_CPU; 1358 1359 /* Number of COS queues */ 1360 num_cos = BRADLEY_MMU_NUM_COS; 1361 1362 /* Total number of cells */ 1363 total_cells = kcells * 1024; 1364 1365 /* 1366 * Ingress based threshholds 1367 */ 1368 1369 /* Enough to absorb in-flight data during PAUSE response */ 1370 pg_max_hdrm_limit = 1371 SOC_IS_SC_CQ(unit) ? (3 * BRADLEY_MMU_MTU_CELLS) : 32; 1372 1373 /* Per-device limit: 1 Ethernet MTU per port */ 1374 global_hdrm_limit = num_ports * BRADLEY_MMU_MTU_CELLS; 1375 1376 /* Use whatever is left over for shared cells */ 1377 total_shared_limit = total_cells; 1378 total_shared_limit -= global_hdrm_limit; 1379 total_shared_limit -= (NUM_GX_PORT(unit) * pg_max_hdrm_limit); 1380 total_shared_limit -= (num_ports * BRADLEY_MMU_PORT_MIN); 1381 total_shared_limit -= (num_ports * BRADLEY_MMU_SC_MIN); 1382 total_shared_limit -= (num_ports * BRADLEY_MMU_QM_MIN); 1383 if (SOC_IS_SC_CQ(unit)) { 1384 1385 /* Output port reserved */ 1386 total_shared_limit -= (num_ports * num_cos * BRADLEY_MMU_MTU_CELLS); 1387 } 1388 rval = 0; 1389 soc_reg_field_set(unit, TOTAL_SHARED_LIMITr, &rval, 1390 TOTAL_SHARED_LIMITf, total_shared_limit); 1391 SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMITr(unit, rval)); 1392 1393 rval = 0; 1394 soc_reg_field_set(unit, GLOBAL_HDRM_LIMITr, &rval, 1395 GLOBAL_HDRM_LIMITf, global_hdrm_limit); 1396 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_HDRM_LIMITr(unit, rval)); 1397 1398 rval = 0; 1399 soc_reg_field_set(unit, PORT_MINr, &rval, PORT_MINf, BRADLEY_MMU_PORT_MIN); 1400 PBMP_MMU_ITER(unit, port) { 1401 SOC_IF_ERROR_RETURN(WRITE_PORT_MINr(unit, port, rval)); 1402 } 1403 1404 rval = 0; 1405 soc_reg_field_set(unit, PORT_MAX_PKT_SIZEr, &rval, 1406 PORT_MAX_PKT_SIZEf, BRADLEY_MMU_JUMBO_CELLS); 1407 PBMP_MMU_ITER(unit, port) { 1408 SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_PKT_SIZEr(unit, port, rval)); 1409 } 1410 1411 rval = 0; 1412 /* The following values may change when link is established */ 1413 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &rval, 1414 PORT_SHARED_LIMITf, op_shared_limit_disable); 1415 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &rval, 1416 PORT_SHARED_DYNAMICf, 0); 1417 PBMP_MMU_ITER(unit, port) { 1418 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMITr(unit, port, rval)); 1419 } 1420 1421 rval = 0; 1422 if (SOC_IS_SC_CQ(unit)) { 1423 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1424 PG0_THRESH_SELf, 0x7); 1425 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1426 PG1_THRESH_SELf, 0x7); 1427 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1428 PG2_THRESH_SELf, 0x7); 1429 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1430 PG3_THRESH_SELf, 0x7); 1431 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1432 PG4_THRESH_SELf, 0x7); 1433 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1434 PG5_THRESH_SELf, 0x7); 1435 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1436 PG6_THRESH_SELf, 0x7); 1437 } else { 1438 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1439 PG0_THRESH_SELf, 0x6); 1440 soc_reg_field_set(unit, PG_THRESH_SELr, &rval, 1441 PG1_THRESH_SELf, 0x7); 1442 } 1443 1444 PBMP_MMU_ITER(unit, port) { 1445 SOC_IF_ERROR_RETURN(WRITE_PG_THRESH_SELr(unit, port, rval)); 1446 } 1447 1448 if (SOC_IS_SC_CQ(unit)) { 1449 rval = 0; 1450 soc_reg_field_set(unit, PG_RESET_OFFSETr, &rval, 1451 PG_RESET_OFFSETf, 1452 2 * BRADLEY_MMU_MTU_CELLS); 1453 PBMP_MMU_ITER(unit, port) { 1454 for (i = 0; i < num_pg; i++) { 1455 SOC_IF_ERROR_RETURN 1456 (WRITE_PG_RESET_OFFSETr(unit, port, i, rval)); 1457 } 1458 } 1459 } 1460 #ifdef BCM_HB_GW_SUPPORT 1461 else { 1462 rval = 0; 1463 soc_reg_field_set(unit, PG_RESET_SELr, &rval, 1464 PG0_RESET_SELf, 0x7); 1465 soc_reg_field_set(unit, PG_RESET_SELr, &rval, 1466 PG1_RESET_SELf, 0x7); 1467 soc_reg_field_set(unit, PG_RESET_SELr, &rval, 1468 PG2_RESET_SELf, 0x7); 1469 PBMP_MMU_ITER(unit, port) { 1470 SOC_IF_ERROR_RETURN(WRITE_PG_RESET_SELr(unit, port, rval)); 1471 } 1472 } 1473 #endif 1474 1475 /* Currently everything is zero, but keep code for reference */ 1476 for (i = 0; i < num_pg; i++) { 1477 pg[i] = 0; 1478 soc_reg_field_set(unit, PG_RESET_FLOORr, &pg[i], 1479 PG_RESET_FLOORf, 0); 1480 1481 } 1482 PBMP_MMU_ITER(unit, port) { 1483 for (i = 0; i < num_pg; i++) { 1484 SOC_IF_ERROR_RETURN(WRITE_PG_RESET_FLOORr(unit, port, i, pg[i])); 1485 } 1486 } 1487 1488 rval = 0; 1489 /* With only one PG in use PORT_MIN should be sufficient */ 1490 soc_reg_field_set(unit, PG_MINr, &rval, 1491 PG_MINf, 0); 1492 PBMP_MMU_ITER(unit, port) { 1493 for (i = 0; i < num_pg; i++) { 1494 SOC_IF_ERROR_RETURN(WRITE_PG_MINr(unit, port, i, rval)); 1495 } 1496 } 1497 1498 /* Note that only PG max is being used */ 1499 for (i = 0; i < num_pg; i++) { 1500 pg[i] = 0; 1501 if (i == (num_pg - 1)) { 1502 soc_reg_field_set(unit, PG_HDRM_LIMITr, &pg[i], 1503 PG_HDRM_LIMITf, pg_max_hdrm_limit); 1504 soc_reg_field_set(unit, PG_HDRM_LIMITr, &pg[i], 1505 PG_GEf, 1); 1506 } else { 1507 soc_reg_field_set(unit, PG_HDRM_LIMITr, &pg[i], 1508 PG_HDRM_LIMITf, 0); 1509 soc_reg_field_set(unit, PG_HDRM_LIMITr, &pg[i], 1510 PG_GEf, 0); 1511 } 1512 } 1513 rval_cpu = 0; 1514 soc_reg_field_set(unit, PG_HDRM_LIMITr, &rval_cpu, 1515 PG_HDRM_LIMITf, 0); 1516 soc_reg_field_set(unit, PG_HDRM_LIMITr, &rval_cpu, 1517 PG_GEf, 0); 1518 PBMP_MMU_ITER(unit, port) { 1519 for (i = 0; i < num_pg; i++) { 1520 if (IS_CPU_PORT(unit, port) && (i == (num_pg - 1))) { 1521 wr_val = rval_cpu; 1522 } else { 1523 wr_val = pg[i]; 1524 } 1525 SOC_IF_ERROR_RETURN 1526 (WRITE_PG_HDRM_LIMITr(unit, port, i, wr_val)); 1527 } 1528 } 1529 1530 if (SOC_IS_SC_CQ(unit)) { 1531 rval = 0; 1532 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI0_GRPf, num_pg - 1); 1533 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI1_GRPf, num_pg - 1); 1534 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI2_GRPf, num_pg - 1); 1535 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI3_GRPf, num_pg - 1); 1536 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI4_GRPf, num_pg - 1); 1537 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI5_GRPf, num_pg - 1); 1538 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval, PRI6_GRPf, num_pg - 1); 1539 PBMP_MMU_ITER(unit, port) { 1540 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP0r(unit, port, rval)); 1541 } 1542 rval = 0; 1543 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI7_GRPf, num_pg - 1); 1544 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI8_GRPf, num_pg - 1); 1545 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI9_GRPf, num_pg - 1); 1546 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI10_GRPf, num_pg - 1); 1547 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI11_GRPf, num_pg - 1); 1548 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI12_GRPf, num_pg - 1); 1549 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval, PRI13_GRPf, num_pg - 1); 1550 PBMP_MMU_ITER(unit, port) { 1551 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP1r(unit, port, rval)); 1552 } 1553 } 1554 #ifdef BCM_HB_GW_SUPPORT 1555 else { 1556 rval = 0; 1557 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG0_GRPf, num_pg - 1); 1558 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG1_GRPf, num_pg - 1); 1559 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG2_GRPf, num_pg - 1); 1560 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG3_GRPf, num_pg - 1); 1561 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG4_GRPf, num_pg - 1); 1562 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG5_GRPf, num_pg - 1); 1563 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG6_GRPf, num_pg - 1); 1564 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG7_GRPf, num_pg - 1); 1565 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG8_GRPf, num_pg - 1); 1566 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG9_GRPf, num_pg - 1); 1567 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG10_GRPf, num_pg - 1); 1568 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG11_GRPf, num_pg - 1); 1569 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG12_GRPf, num_pg - 1); 1570 soc_reg_field_set(unit, PORT_PRI_GRPr, &rval, PG13_GRPf, num_pg - 1); 1571 PBMP_MMU_ITER(unit, port) { 1572 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRPr(unit, port, rval)); 1573 } 1574 } 1575 #endif 1576 1577 rval = 0; 1578 soc_reg_field_set(unit, PORT_SC_MINr, &rval, 1579 PORT_SC_MINf, BRADLEY_MMU_SC_MIN); 1580 PBMP_MMU_ITER(unit, port) { 1581 SOC_IF_ERROR_RETURN(WRITE_PORT_SC_MINr(unit, port, rval)); 1582 } 1583 1584 rval = 0; 1585 soc_reg_field_set(unit, PORT_QM_MINr, &rval, 1586 PORT_QM_MINf, BRADLEY_MMU_QM_MIN); 1587 PBMP_MMU_ITER(unit, port) { 1588 SOC_IF_ERROR_RETURN(WRITE_PORT_QM_MINr(unit, port, rval)); 1589 } 1590 1591 /* 1592 * Output queue threshold settings 1593 */ 1594 1595 q_min = BRADLEY_MMU_MTU_CELLS; 1596 1597 op_buffer_shared_limit = total_cells; 1598 op_buffer_shared_limit -= (q_min * num_ports * num_cos); 1599 op_buffer_shared_limit -= (num_ports * BRADLEY_MMU_SC_MIN); 1600 op_buffer_shared_limit -= (num_ports * BRADLEY_MMU_QM_MIN); 1601 1602 rval = 0; 1603 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMITr, &rval, 1604 OP_BUFFER_SHARED_LIMITf, op_buffer_shared_limit); 1605 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMITr(unit, rval)); 1606 1607 /* 1608 * OP_SHARED_LIMIT should be ((op_buffer_shared_limit * 3) / 4) 1609 * OP_SHARED_RESET_VALUE should be (op_buffer_shared_limit / 4) 1610 * 1611 * Since PORT_LIMIT_ENABLE does not work, the above limits 1612 * can be disabled by configuring values larger than the 1613 * OP_BUFFER_SHARED_LIMIT value. 1614 */ 1615 rval = 0; 1616 soc_reg_field_set(unit, OP_PORT_CONFIGr, &rval, 1617 OP_SHARED_LIMITf, op_shared_limit_disable); 1618 soc_reg_field_set(unit, OP_PORT_CONFIGr, &rval, 1619 OP_SHARED_RESET_VALUEf, op_shared_limit_disable); 1620 soc_reg_field_set(unit, OP_PORT_CONFIGr, &rval, 1621 PORT_LIMIT_ENABLEf, 0); 1622 rval_cpu = 0; 1623 soc_reg_field_set(unit, OP_PORT_CONFIGr, &rval_cpu, 1624 OP_SHARED_LIMITf, op_shared_limit_disable); 1625 soc_reg_field_set(unit, OP_PORT_CONFIGr, &rval_cpu, 1626 OP_SHARED_RESET_VALUEf, 0x733); 1627 soc_reg_field_set(unit, OP_PORT_CONFIGr, &rval_cpu, 1628 PORT_LIMIT_ENABLEf, 0); 1629 PBMP_MMU_ITER(unit, port) { 1630 if (IS_CPU_PORT(unit, port)) { 1631 wr_val = rval_cpu; 1632 } else { 1633 wr_val = rval; 1634 } 1635 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIGr(unit, port, wr_val)); 1636 } 1637 1638 if (SOC_IS_SC_CQ(unit)) { 1639 PBMP_MMU_ITER(unit, port) { 1640 rval = 0; 1641 soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOWr, &rval, 1642 OP_LIMIT_YELLOWf, SCORPION_COLOR_LIMIT); 1643 SOC_IF_ERROR_RETURN 1644 (WRITE_OP_PORT_LIMIT_YELLOWr(unit, port, rval)); 1645 rval = 0; 1646 soc_reg_field_set(unit, OP_PORT_LIMIT_REDr, &rval, 1647 OP_LIMIT_REDf, SCORPION_COLOR_LIMIT); 1648 SOC_IF_ERROR_RETURN 1649 (WRITE_OP_PORT_LIMIT_REDr(unit, port, rval)); 1650 1651 rval = 0; 1652 soc_reg_field_set(unit, OP_QUEUE_LIMIT_YELLOWr, &rval, 1653 Q_LIMIT_YELLOWf, SCORPION_COLOR_LIMIT); 1654 for (i = 0; i < num_cos; i++) { 1655 SOC_IF_ERROR_RETURN 1656 (WRITE_OP_QUEUE_LIMIT_YELLOWr(unit, port, i, rval)); 1657 } 1658 #if BRADLEY_MMU_USE_SC_QM == 1 1659 for (i = 8; i <= 9; i++) { 1660 SOC_IF_ERROR_RETURN 1661 (WRITE_OP_QUEUE_LIMIT_YELLOWr(unit, port, i, rval)); 1662 } 1663 #endif 1664 1665 rval = 0; 1666 soc_reg_field_set(unit, OP_QUEUE_LIMIT_REDr, &rval, 1667 Q_LIMIT_REDf, SCORPION_COLOR_LIMIT); 1668 for (i = 0; i < num_cos; i++) { 1669 SOC_IF_ERROR_RETURN 1670 (WRITE_OP_QUEUE_LIMIT_REDr(unit, port, i, rval)); 1671 } 1672 #if BRADLEY_MMU_USE_SC_QM == 1 1673 for (i = 8; i <= 9; i++) { 1674 SOC_IF_ERROR_RETURN 1675 (WRITE_OP_QUEUE_LIMIT_REDr(unit, port, i, rval)); 1676 } 1677 #endif 1678 1679 } 1680 1681 rval = 0; 1682 soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOWr, &rval, 1683 OP_BUFFER_LIMIT_YELLOWf, SCORPION_COLOR_LIMIT); 1684 SOC_IF_ERROR_RETURN 1685 (WRITE_OP_BUFFER_LIMIT_YELLOWr(unit, rval)); 1686 rval = 0; 1687 soc_reg_field_set(unit, OP_BUFFER_LIMIT_REDr, &rval, 1688 OP_BUFFER_LIMIT_REDf, SCORPION_COLOR_LIMIT); 1689 SOC_IF_ERROR_RETURN 1690 (WRITE_OP_BUFFER_LIMIT_REDr(unit, rval)); 1691 } 1692 1693 rval = 0; 1694 rval2 = 0; 1695 #ifdef BCM_HB_GW_SUPPORT 1696 if (soc_reg_field_valid(unit, OP_QUEUE_CONFIGr, Q_RESET_SELf)) { 1697 /* Make it 87.5 % of original threshold */ 1698 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 1699 Q_RESET_SELf, 0x7); 1700 } else 1701 #endif 1702 if (soc_reg_field_valid 1703 (unit, OP_QUEUE_RESET_OFFSETr, Q_RESET_OFFSETf)) { 1704 soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSETr, &rval2, 1705 Q_RESET_OFFSETf, 1706 2 * BRADLEY_MMU_MTU_CELLS); 1707 } 1708 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 1709 Q_MINf, q_min); 1710 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 1711 Q_LIMIT_ENABLEf, 0x1); 1712 /* Use dynamic threshold limits */ 1713 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 1714 Q_LIMIT_DYNAMICf, 0x1); 1715 /* Dynamic threshold limit is alpha of 4 for Bradley, .25 for Scorpion */ 1716 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 1717 Q_SHARED_LIMITf, SOC_IS_SC_CQ(unit) ? 0x2 : 0x7); 1718 rval_cpu = rval; 1719 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval_cpu, 1720 Q_SHARED_LIMITf, q_shared_limit_encoding_cmic); 1721 PBMP_MMU_ITER(unit, port) { 1722 if (IS_CPU_PORT(unit, port)) { 1723 wr_val = rval_cpu; 1724 } else { 1725 wr_val = rval; 1726 } 1727 for (i = 0; i < num_cos; i++) { 1728 SOC_IF_ERROR_RETURN 1729 (WRITE_OP_QUEUE_CONFIGr(unit, port, i, wr_val)); 1730 if (soc_reg_field_valid 1731 (unit, OP_QUEUE_RESET_OFFSETr, Q_RESET_OFFSETf)) { 1732 SOC_IF_ERROR_RETURN 1733 (WRITE_OP_QUEUE_RESET_OFFSETr(unit, port, i, rval2)); 1734 } 1735 } 1736 #if BRADLEY_MMU_USE_SC_QM == 1 1737 for (i = 8; i <= 9; i++) { 1738 SOC_IF_ERROR_RETURN 1739 (WRITE_OP_QUEUE_CONFIGr(unit, port, i, wr_val)); 1740 if (soc_reg_field_valid 1741 (unit, OP_QUEUE_RESET_OFFSETr, Q_RESET_OFFSETf)) { 1742 SOC_IF_ERROR_RETURN 1743 (WRITE_OP_QUEUE_RESET_OFFSETr(unit, port, i, rval2)); 1744 } 1745 } 1746 #endif 1747 } 1748 1749 rval = 0; 1750 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, 1751 ASF_PKT_SIZEf, 0x3); 1752 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, 1753 ASF_QUEUE_SIZEf, 0x3); 1754 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, 1755 MOP_POLICYf, 0x7); 1756 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, 1757 SOP_POLICYf, 0); 1758 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval)); 1759 1760 rval = 0; 1761 soc_reg_field_set(unit, CFAPCONFIGr, &rval, 1762 CFAPPOOLSIZEf, total_cells - 1); 1763 SOC_IF_ERROR_RETURN(WRITE_CFAPCONFIGr(unit, rval)); 1764 1765 rval = 0; 1766 soc_reg_field_set(unit, CFAPFULLTHRESHOLDr, &rval, 1767 CFAPFULLSETPOINTf, 1768 total_cells - BRADLEY_CFAP_FULL_SET_POINT_OFFSET); 1769 soc_reg_field_set(unit, CFAPFULLTHRESHOLDr, &rval, 1770 CFAPFULLRESETPOINTf, 1771 total_cells - BRADLEY_CFAP_FULL_RESET_POINT_OFFSET); 1772 SOC_IF_ERROR_RETURN(WRITE_CFAPFULLTHRESHOLDr(unit, rval)); 1773 1774 /* No flow control for COS 0-7 */ 1775 rval = 0; 1776 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 1777 PORT_PRI_XON_ENABLEf, 0); 1778 PBMP_MMU_ITER(unit, port) { 1779 SOC_IF_ERROR_RETURN 1780 (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval)); 1781 } 1782 1783 /* Port enable */ 1784 rval = 0; 1785 soc_reg_field_set(unit, INPUT_PORT_RX_ENABLEr, &rval, INPUT_PORT_RX_ENABLEf, 1786 SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0)); 1787 SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLEr(unit, rval)); 1788 SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLEr(unit, rval)); 1789 1790 return SOC_E_NONE; 1791 } 1792 1793 #ifdef BCM_SCORPION_SUPPORT 1794 soc_reg_t _soc_sc_parity_wred_reg[] = { 1795 WREDAVGQSIZE_CELLr, 1796 WREDCONFIG_CELLr, 1797 WREDPARAM_CELLr, 1798 WREDPARAM_YELLOW_CELLr, 1799 WREDPARAM_RED_CELLr, 1800 WREDPARAM_NONTCP_CELLr, 1801 PORT_WREDAVGQSIZE_CELLr, 1802 PORT_WREDCONFIG_CELLr, 1803 PORT_WREDPARAM_CELLr, 1804 PORT_WREDPARAM_YELLOW_CELLr, 1805 PORT_WREDPARAM_RED_CELLr, 1806 PORT_WREDPARAM_NONTCP_CELLr 1807 }; 1808 1809 soc_mem_t _soc_sc_parity_wred_mem[] = { 1810 MMU_WRED_CFG_CELLm, 1811 MMU_WRED_CFG_CELLm, 1812 MMU_WRED_THD_0_CELLm, 1813 MMU_WRED_THD_0_CELLm, 1814 MMU_WRED_THD_1_CELLm, 1815 MMU_WRED_THD_1_CELLm, 1816 MMU_WRED_PORT_CFG_CELLm, 1817 MMU_WRED_PORT_CFG_CELLm, 1818 MMU_WRED_PORT_THD_0_CELLm, 1819 MMU_WRED_PORT_THD_0_CELLm, 1820 MMU_WRED_PORT_THD_1_CELLm, 1821 MMU_WRED_PORT_THD_1_CELLm, 1822 }; 1823 #define SOC_SC_WRED_PARITY_NUM 12 1824 #endif 1825 1826 #ifdef BCM_SCORPION_SUPPORT 1827 #define SOC_SC_MTRO_MAX_GROUP 15 1828 #define SOC_SC_MTRO_COS 8 1829 #define SOC_SC_MTRO_MAX_PORT_IN_GROUP 4 1830 1831 STATIC int mtro_port[SOC_SC_MTRO_MAX_GROUP][SOC_SC_MTRO_MAX_PORT_IN_GROUP] = { 1832 {1, 4, 7, 10}, {1, 4, 7, 10}, {2, 5, 8, 11}, {2, 5, 8, 11}, 1833 {3, 6, 9, 12}, {3, 6, 9, 12}, {13, 17, 21, 25}, {13, 17, 21, 25}, 1834 {14, 18, 22, 26}, {14, 18, 22, 26}, {14, 18, 22, 26}, {14, 18, 22, 26}, 1835 {15, 19, 23, 27}, {15, 19, 23, 27}, {REG_PORT_ANY, 0, 0, 0} 1836 }; 1837 1838 STATIC 1839 int _soc_scorpion_mtro_mmu_port_index_get(int instance_num, int ptr, 1840 int *port, int *index) 1841 { 1842 if ((instance_num >= SOC_SC_MTRO_MAX_GROUP) || 1843 (ptr >= (SOC_SC_MTRO_MAX_PORT_IN_GROUP * SOC_SC_MTRO_COS)) || 1844 (port == NULL) || (index == NULL)) { 1845 return SOC_E_INTERNAL; 1846 } 1847 if (instance_num == (SOC_SC_MTRO_MAX_GROUP - 1)) { 1848 *port = REG_PORT_ANY; 1849 *index = ptr; 1850 } else { 1851 *port = mtro_port[instance_num][ptr / SOC_SC_MTRO_COS]; 1852 *index = ptr % SOC_SC_MTRO_COS; 1853 } 1854 return SOC_E_NONE; 1855 } 1856 1857 STATIC int 1858 _soc_scorpion_parity_mmu_clear(int unit, soc_field_t status_field) 1859 { 1860 uint32 rval; 1861 SOC_IF_ERROR_RETURN 1862 (READ_MEM_FAIL_INT_STATr(unit, &rval)); 1863 if (soc_reg_field_valid(unit, MEM_FAIL_INT_STATr, status_field)) { 1864 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, status_field, 0); 1865 } else { 1866 return SOC_E_INTERNAL; 1867 } 1868 SOC_IF_ERROR_RETURN 1869 (WRITE_MEM_FAIL_INT_STATr(unit, rval)); 1870 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1871 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 1872 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1873 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1874 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 1875 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1876 return SOC_E_NONE; 1877 } 1878 1879 STATIC 1880 int soc_scorpion_mmu_mtro_process(int unit) 1881 { 1882 static soc_reg_t mtro1_regs[] = { 1883 MINBUCKETCONFIGr, 1884 MINBUCKETCONFIG1r, 1885 MAXBUCKETCONFIGr, 1886 MAXBUCKETCONFIG1r 1887 }; 1888 static soc_reg_t mtro2_regs[] = { 1889 MINBUCKETr, 1890 MAXBUCKETr 1891 }; 1892 1893 static soc_reg_t cpu_mtro_regs[] = { 1894 CPUPKTMAXBUCKETCONFIGr, 1895 CPUPKTMAXBUCKETr 1896 }; 1897 soc_reg_t *mtro_regs; 1898 uint32 i, rval, status, val; 1899 _soc_ser_correct_info_t spci; 1900 int port, index, instance_num, ptr, mtro_num = 0; 1901 int rv = SOC_E_NONE; 1902 int block_info_idx = 0; 1903 uint32 minfo = 0; 1904 1905 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1906 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 1907 spci.mem = INVALIDm; 1908 spci.blk_type = SOC_BLK_MMU; 1909 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status)); 1910 if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, 1911 MTRO_PAR_ERRf)) { 1912 LOG_ERROR(BSL_LS_SOC_COMMON, 1913 (BSL_META_U(unit, 1914 "unit %d MTRO: parity hardware" 1915 " inconsistency\n"), 1916 unit)); 1917 return SOC_E_NONE; 1918 } 1919 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, EGRSHAPEPARITYERRORPTRr, 1920 REG_PORT_ANY, 0, &rval)); 1921 instance_num = soc_reg_field_get(unit, EGRSHAPEPARITYERRORPTRr, 1922 rval, INSTANCE_NUMf); 1923 ptr = soc_reg_field_get(unit, EGRSHAPEPARITYERRORPTRr, rval, PTRf); 1924 SOC_IF_ERROR_RETURN( 1925 _soc_scorpion_mtro_mmu_port_index_get(instance_num, ptr, 1926 &port, &index)); 1927 /* Disable parity */ 1928 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1929 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0); 1930 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1931 1932 if (port == REG_PORT_ANY) { 1933 for (i = 0; i < COUNTOF(cpu_mtro_regs); i++) { 1934 spci.port = port; 1935 spci.index = index; 1936 spci.reg = cpu_mtro_regs[i]; 1937 rv = soc_ser_correction(unit, &spci); 1938 if (SOC_FAILURE(rv)) { 1939 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_MMU) { 1940 if (SOC_BLOCK_INFO(unit, block_info_idx).number == 0) { 1941 break; 1942 } 1943 } 1944 _soc_hbs_mem_parity_info(unit, block_info_idx, -1, 1945 MTRO_PAR_ERRf, &minfo); 1946 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1947 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1948 spci.index, minfo); 1949 }; 1950 } 1951 } else if (port >=1 && port <= 28) { 1952 if (instance_num % 2) { 1953 mtro_regs = mtro2_regs; 1954 mtro_num = 2; 1955 } else { 1956 mtro_regs = mtro1_regs; 1957 mtro_num = 4; 1958 } 1959 for (i = 0; i < mtro_num; i++) { 1960 spci.port = port; 1961 spci.index = index; 1962 spci.reg = mtro_regs[i]; 1963 rv = soc_ser_correction(unit, &spci); 1964 if (SOC_FAILURE(rv)) { 1965 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_MMU) { 1966 if (SOC_BLOCK_INFO(unit, block_info_idx).number == 0) { 1967 break; 1968 } 1969 } 1970 _soc_hbs_mem_parity_info(unit, block_info_idx, -1, 1971 MTRO_PAR_ERRf, &minfo); 1972 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1973 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1974 spci.index, minfo); 1975 }; 1976 } 1977 } else { 1978 LOG_ERROR(BSL_LS_SOC_COMMON, 1979 (BSL_META_U(unit, 1980 "unit %d MTRO: parity hardware inconsistency\n"), 1981 unit)); 1982 } 1983 SOC_IF_ERROR_RETURN(_soc_scorpion_parity_mmu_clear(unit, MTRO_PAR_ERRf)); 1984 /* Enable parity */ 1985 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1986 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1); 1987 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1988 return SOC_E_NONE; 1989 1990 1991 } 1992 #endif 1993 1994 STATIC void 1995 _soc_hbs_mem_parity_info(int unit, int block_info_idx, int pipe, 1996 soc_field_t field_enum, uint32 *minfo) 1997 { 1998 *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) 1999 | ((pipe & 0xff) << SOC_ERROR_PIPE_BP) 2000 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK); 2001 } 2002 2003 int 2004 _soc_hbs_parity_generic_clear(int unit, soc_block_t blocktype, int pipe, 2005 soc_reg_t group_reg, soc_field_t group_field, 2006 char *prefix_str, char *mem_str) 2007 { 2008 uint32 rval; 2009 2010 /* Clear parity error status */ 2011 if (blocktype == SOC_BLK_MMU) { 2012 SOC_IF_ERROR_RETURN 2013 (soc_reg32_get(unit, group_reg, REG_PORT_ANY, 0, &rval)); 2014 2015 soc_reg_field_set(unit, group_reg, &rval, group_field, 0); 2016 2017 SOC_IF_ERROR_RETURN 2018 (soc_reg32_set(unit, group_reg, REG_PORT_ANY, 0, rval)); 2019 2020 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2021 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 2022 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2023 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2024 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 2025 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2026 2027 LOG_INFO(BSL_LS_SOC_COMMON, 2028 (BSL_META_U(unit, 2029 "%s %s asserted, status register %s, field %s\n"), 2030 prefix_str, mem_str, SOC_REG_NAME(unit, group_reg), 2031 SOC_FIELD_NAME(unit, group_field))); 2032 return SOC_E_NONE; 2033 } else { 2034 LOG_ERROR(BSL_LS_SOC_COMMON, 2035 (BSL_META_U(unit, 2036 "%s %s asserted\n"), 2037 prefix_str, mem_str)); 2038 /* need to add new way to clear parity status */ 2039 return SOC_E_NONE; 2040 } 2041 } 2042 2043 STATIC int 2044 _soc_hbs_mmu_party_error_callback_notify(int unit, soc_field_t field, int clear) 2045 { 2046 char *mem_str; 2047 uint32 minfo; 2048 int block_info_idx; 2049 int pipe = -1; 2050 char prefix_str[10]; 2051 2052 sal_sprintf(prefix_str, "unit %d", unit); 2053 2054 mem_str = SOC_FIELD_NAME(unit, field); 2055 2056 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_MMU) { 2057 if (SOC_BLOCK_INFO(unit, block_info_idx).number == 0) { 2058 break; 2059 } 2060 } 2061 2062 _soc_hbs_mem_parity_info(unit, block_info_idx, pipe, 2063 field, &minfo); 2064 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2065 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0, 2066 minfo); 2067 if (clear) { 2068 SOC_IF_ERROR_RETURN(_soc_hbs_parity_generic_clear(unit, SOC_BLK_MMU, pipe, 2069 MEM_FAIL_INT_STATr, field, prefix_str, mem_str)); 2070 } 2071 return SOC_E_NONE; 2072 } 2073 2074 /* 2075 * _soc_hbs_mmu_parity_error 2076 * HBS MMU parity error decoder 2077 */ 2078 int _soc_hbs_mmu_parity_error(int unit) 2079 { 2080 uint32 istat, val, val2; 2081 uint32 rval; 2082 soc_control_t *soc = SOC_CONTROL(unit); 2083 _soc_ser_correct_info_t spci; 2084 int rv = SOC_E_NONE; 2085 2086 sal_memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 2087 2088 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &istat)); 2089 if (istat != 0) { 2090 soc->stat.intr_mmu++; 2091 } 2092 2093 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_CTRr(unit, &val)); 2094 LOG_ERROR(BSL_LS_SOC_COMMON, 2095 (BSL_META_U(unit, 2096 "soc_hb_mmu_parity_error:unit = %d," 2097 "INTSTATUS = 0x%08x Fail Count = %d\n"), 2098 unit, istat, val)); 2099 2100 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, istat, CFAP_MEM_FAILf)) { 2101 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2102 CFAP_MEM_FAILf, 1)); 2103 LOG_ERROR(BSL_LS_SOC_COMMON, 2104 (BSL_META_U(unit, 2105 "unit = %d, CFAP_MEM_FAIL\n"), unit)); 2106 } 2107 2108 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, istat, CFAP_PAR_ERRf)) { 2109 soc->stat.err_cfap++; 2110 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2111 CFAP_PAR_ERRf, 1)); 2112 SOC_IF_ERROR_RETURN(READ_CFAPPARITYERRORPTRr(unit, &val)); 2113 LOG_ERROR(BSL_LS_SOC_COMMON, 2114 (BSL_META_U(unit, 2115 "unit = %d, CFAPPARITYERRORPTR 0x%08x\n"), 2116 unit, val)); 2117 } 2118 2119 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, istat, CCP_PAR_ERRf)) { 2120 soc->stat.err_cpcrc++; 2121 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2122 CCP_PAR_ERRf, 1)); 2123 SOC_IF_ERROR_RETURN(READ_CCPPARITYERRORPTRr(unit, &val)); 2124 LOG_ERROR(BSL_LS_SOC_COMMON, 2125 (BSL_META_U(unit, 2126 "unit = %d, CCPPARITYERRORPTR 0x%08x\n"), 2127 unit, val)); 2128 } 2129 2130 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2131 istat, AGING_CTR_PAR_ERRf)) { 2132 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2133 AGING_CTR_PAR_ERRf, 1)); 2134 LOG_ERROR(BSL_LS_SOC_COMMON, 2135 (BSL_META_U(unit, 2136 "unit = %d, AGING_CTR parity error\n"), unit)); 2137 } 2138 2139 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2140 istat, AGING_EXP_PAR_ERRf)) { 2141 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2142 AGING_EXP_PAR_ERRf, 1)); 2143 LOG_ERROR(BSL_LS_SOC_COMMON, 2144 (BSL_META_U(unit, 2145 "unit = %d, AGING_EXP parity error\n"), unit)); 2146 } 2147 2148 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2149 istat, DEQ_PKTHDR_CPU_ERRf)) { 2150 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2151 DEQ_PKTHDR_CPU_ERRf, 1)); 2152 LOG_ERROR(BSL_LS_SOC_COMMON, 2153 (BSL_META_U(unit, 2154 "unit = %d, DEQ_PKTHDR_CPU_ERR\n"), unit)); 2155 } 2156 2157 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2158 istat, DEQ_PKTHDR0_ERRf)) { 2159 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2160 DEQ_PKTHDR0_ERRf, 1)); 2161 LOG_ERROR(BSL_LS_SOC_COMMON, 2162 (BSL_META_U(unit, 2163 "unit = %d, DEQ_PKTHDR0_ERR\n"), unit)); 2164 } 2165 2166 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2167 istat, DEQ0_NOT_IP_ERRf)) { 2168 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2169 DEQ0_NOT_IP_ERRf, 1)); 2170 LOG_ERROR(BSL_LS_SOC_COMMON, 2171 (BSL_META_U(unit, 2172 "unit = %d, DEQ0_NOT_IP_ERR\n"), unit)); 2173 } 2174 2175 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2176 istat, DEQ1_NOT_IP_ERRf)) { 2177 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2178 DEQ1_NOT_IP_ERRf, 1)); 2179 LOG_ERROR(BSL_LS_SOC_COMMON, 2180 (BSL_META_U(unit, 2181 "unit = %d, DEQ1_NOT_IP_ERR\n"), unit)); 2182 } 2183 2184 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2185 istat, DEQ0_CELLCRC_ERRf)) { 2186 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2187 DEQ0_CELLCRC_ERRf, 1)); 2188 LOG_ERROR(BSL_LS_SOC_COMMON, 2189 (BSL_META_U(unit, 2190 "unit = %d, DEQ0_CELLCRC_ERR\n"), unit)); 2191 } 2192 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2193 istat, DEQ1_CELLCRC_ERRf)) { 2194 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2195 DEQ1_CELLCRC_ERRf, 1)); 2196 LOG_ERROR(BSL_LS_SOC_COMMON, 2197 (BSL_META_U(unit, 2198 "unit = %d, DEQ1_CELLCRC_ERR\n"), unit)); 2199 } 2200 2201 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2202 istat, TOQ0_CELLHDR_PAR_ERRf)) { 2203 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2204 TOQ0_CELLHDR_PAR_ERRf, 1)); 2205 LOG_ERROR(BSL_LS_SOC_COMMON, 2206 (BSL_META_U(unit, 2207 "unit = %d, TOQ0_CELLHDR_PAR_ERR\n"), unit)); 2208 } 2209 2210 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2211 istat, TOQ0_PKTHDR1_PAR_ERRf)) { 2212 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2213 TOQ0_PKTHDR1_PAR_ERRf, 1)); 2214 LOG_ERROR(BSL_LS_SOC_COMMON, 2215 (BSL_META_U(unit, 2216 "unit = %d, TOQ0_PKTHDR1_PAR_ERR\n"), unit)); 2217 } 2218 2219 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2220 istat, TOQ0_PKTLINK_PAR_ERRf)) { 2221 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2222 TOQ0_PKTLINK_PAR_ERRf, 1)); 2223 LOG_ERROR(BSL_LS_SOC_COMMON, 2224 (BSL_META_U(unit, 2225 "unit = %d, TOQ0_PKTLINK_PAR_ERR\n"), unit)); 2226 } 2227 2228 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2229 istat, TOQ0_CELLLINK_PAR_ERRf)) { 2230 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2231 TOQ0_CELLLINK_PAR_ERRf, 1)); 2232 LOG_ERROR(BSL_LS_SOC_COMMON, 2233 (BSL_META_U(unit, 2234 "unit = %d, TOQ0_CELLLINK_PAR_ERR\n"), unit)); 2235 } 2236 2237 #ifdef BCM_SCORPION_SUPPORT 2238 if (SOC_IS_SCORPION(unit)) { 2239 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2240 istat, TOQ0_VLAN_TBL_PAR_ERRf) || 2241 soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2242 istat, TOQ0_IPMC_TBL_PAR_ERRf) || 2243 soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2244 istat, TOQ1_VLAN_TBL_PAR_ERRf) || 2245 soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2246 istat, TOQ1_IPMC_TBL_PAR_ERRf)) { 2247 2248 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2249 istat, TOQ0_VLAN_TBL_PAR_ERRf)) { 2250 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify( 2251 unit, TOQ0_VLAN_TBL_PAR_ERRf, 0)); 2252 } 2253 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2254 istat, TOQ0_IPMC_TBL_PAR_ERRf)) { 2255 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify( 2256 unit, TOQ0_IPMC_TBL_PAR_ERRf, 0)); 2257 } 2258 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2259 istat, TOQ1_VLAN_TBL_PAR_ERRf)) { 2260 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify( 2261 unit, TOQ1_VLAN_TBL_PAR_ERRf, 0)); 2262 } 2263 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2264 istat, TOQ1_IPMC_TBL_PAR_ERRf)) { 2265 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify( 2266 unit, TOQ1_IPMC_TBL_PAR_ERRf, 0)); 2267 } 2268 2269 SOC_IF_ERROR_RETURN 2270 (READ_TOQ_IPMCERRINTRr(unit, &val)); 2271 SOC_IF_ERROR_RETURN 2272 (READ_TOQ_IPMCVLANERRPTRr(unit, &val2)); 2273 2274 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 2275 spci.reg = INVALIDr; 2276 spci.mem = MMU_IPMC_VLAN_TBLm; 2277 spci.blk_type = -1; 2278 spci.index = val2; 2279 spci.sblk = 0; 2280 rv = soc_ser_correction(unit, &spci); 2281 if (SOC_FAILURE(rv)) { 2282 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2283 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2284 spci.mem, 2285 spci.index); 2286 } 2287 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2288 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 2289 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2290 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 2291 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2292 } 2293 } else 2294 #endif 2295 { 2296 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2297 istat, TOQ0_VLAN_TBL_PAR_ERRf)) { 2298 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2299 TOQ0_VLAN_TBL_PAR_ERRf, 1)); 2300 LOG_ERROR(BSL_LS_SOC_COMMON, 2301 (BSL_META_U(unit, 2302 "unit = %d, TOQ0_VLAN_TBL_PAR_ERR\n"), unit)); 2303 } 2304 2305 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2306 istat, TOQ0_IPMC_TBL_PAR_ERRf)) { 2307 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2308 TOQ0_IPMC_TBL_PAR_ERRf, 1)); 2309 LOG_ERROR(BSL_LS_SOC_COMMON, 2310 (BSL_META_U(unit, 2311 "unit = %d, TOQ0_IPMC_TBL_PAR_ERR\n"), unit)); 2312 } 2313 2314 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2315 istat, TOQ1_VLAN_TBL_PAR_ERRf)) { 2316 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2317 TOQ1_VLAN_TBL_PAR_ERRf, 1)); 2318 2319 LOG_ERROR(BSL_LS_SOC_COMMON, 2320 (BSL_META_U(unit, 2321 "unit = %d, TOQ1_VLAN_TBL_PAR_ERR\n"), unit)); 2322 } 2323 2324 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2325 istat, TOQ1_IPMC_TBL_PAR_ERRf)) { 2326 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2327 TOQ1_IPMC_TBL_PAR_ERRf, 1)); 2328 LOG_ERROR(BSL_LS_SOC_COMMON, 2329 (BSL_META_U(unit, 2330 "unit = %d, TOQ1_IPMC_TBL_PAR_ERR\n"), unit)); 2331 } 2332 } 2333 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2334 istat, TOQ1_CELLHDR_PAR_ERRf)) { 2335 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2336 TOQ1_CELLHDR_PAR_ERRf, 1)); 2337 LOG_ERROR(BSL_LS_SOC_COMMON, 2338 (BSL_META_U(unit, 2339 "unit = %d, TOQ1_CELLHDR_PAR_ERR\n"), unit)); 2340 } 2341 2342 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2343 istat, TOQ1_PKTHDR1_PAR_ERRf)) { 2344 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2345 TOQ1_PKTHDR1_PAR_ERRf, 1)); 2346 LOG_ERROR(BSL_LS_SOC_COMMON, 2347 (BSL_META_U(unit, 2348 "unit = %d, TOQ1_PKTHDR1_PAR_ERR\n"), unit)); 2349 } 2350 2351 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2352 istat, TOQ1_PKTLINK_PAR_ERRf)) { 2353 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2354 TOQ1_PKTLINK_PAR_ERRf, 1)); 2355 LOG_ERROR(BSL_LS_SOC_COMMON, 2356 (BSL_META_U(unit, 2357 "unit = %d, TOQ1_PKTLINK_PAR_ERR\n"), unit)); 2358 } 2359 2360 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2361 istat, TOQ1_CELLLINK_PAR_ERRf)) { 2362 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2363 TOQ1_CELLLINK_PAR_ERRf, 1)); 2364 LOG_ERROR(BSL_LS_SOC_COMMON, 2365 (BSL_META_U(unit, 2366 "unit = %d, TOQ1_CELLLINK_PAR_ERR\n"), unit)); 2367 } 2368 2369 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2370 istat, MTRO_PAR_ERRf)) { 2371 #ifdef BCM_SCORPION_SUPPORT 2372 if (SOC_IS_SCORPION(unit)) { 2373 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2374 MTRO_PAR_ERRf, 0)); 2375 SOC_IF_ERROR_RETURN(soc_scorpion_mmu_mtro_process(unit)); 2376 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2377 MTRO_PAR_ERRf, 0)); 2378 } else 2379 #endif 2380 { 2381 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2382 MTRO_PAR_ERRf, 1)); 2383 LOG_ERROR(BSL_LS_SOC_COMMON, 2384 (BSL_META_U(unit, 2385 "unit = %d, MTRO_PAR_ERR\n"), unit)); 2386 } 2387 } 2388 2389 #define SOC_IPMC_GROUP_TABLE_NUM(unit) \ 2390 (SOC_IS_SC_CQ(unit) ? 7 : 4) 2391 2392 if (soc_feature(unit, soc_feature_ip_mcast_repl)) { 2393 int i, ix, num_tables = SOC_IPMC_GROUP_TABLE_NUM(unit); 2394 2395 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2396 istat, ENQ_IPMC_TBL_PAR_ERRf)) { 2397 #ifdef BCM_HB_GW_SUPPORT 2398 if (SOC_REG_IS_VALID(unit, ENQ_IPMCGRP_TBL_PARITYERROR_STATUSr)) { 2399 SOC_IF_ERROR_RETURN 2400 (READ_ENQ_IPMCGRP_TBL_PARITYERROR_STATUSr(unit, &val2)); 2401 2402 for (ix = 0; ix < num_tables; ix++) { 2403 if (val2 & (1 << ix)) { 2404 SOC_IF_ERROR_RETURN 2405 (READ_ENQ_IPMCGRP_TBL_PARITYERRORPTRr(unit, ix, &val)); 2406 LOG_ERROR(BSL_LS_SOC_COMMON, 2407 (BSL_META_U(unit, 2408 "unit = %d, ENQ MMU_IPMC_GROUP_TBL%d, entry %d parity error\n"), 2409 unit, ix, val)); 2410 } 2411 } 2412 2413 /* Clear errors */ 2414 SOC_IF_ERROR_RETURN 2415 (WRITE_ENQ_IPMCGRP_TBL_PARITYERROR_STATUSr(unit, 0)); 2416 } else 2417 #endif 2418 if(SOC_IS_SCORPION(unit)){ 2419 2420 soc_reg_t enq_ipmc_grp_err_ptr[] = 2421 {TOQ_ENQIPMCGRPERRPTR0r, TOQ_ENQIPMCGRPERRPTR1r}; 2422 soc_mem_t ipmc_grp_mem[] = {MMU_IPMC_GROUP_TBL0m, MMU_IPMC_GROUP_TBL1m, 2423 MMU_IPMC_GROUP_TBL2m, MMU_IPMC_GROUP_TBL3m, 2424 MMU_IPMC_GROUP_TBL4m, MMU_IPMC_GROUP_TBL5m, 2425 MMU_IPMC_GROUP_TBL6m}; 2426 2427 SOC_IF_ERROR_RETURN 2428 (READ_TOQ_IPMCERRINTRr(unit, &val)); 2429 2430 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 2431 spci.reg = INVALIDr; 2432 spci.blk_type = -1; 2433 spci.sblk = 0; 2434 2435 /* Check for each IPMC_GROUP table */ 2436 for (ix = 0; ix < num_tables; ix++) { 2437 for (i = 0; i < 2; i++) { 2438 /* ENQ error starts from bit 9 */ 2439 if(val & (1 << (9 + ix))) { 2440 SOC_IF_ERROR_RETURN 2441 (soc_reg32_get(unit, enq_ipmc_grp_err_ptr[i], 2442 REG_PORT_ANY, 0, &val2)); 2443 spci.index = val2; 2444 spci.mem = ipmc_grp_mem[ix]; 2445 2446 /* Perform SER correction */ 2447 rv = soc_ser_correction(unit, &spci); 2448 if (SOC_FAILURE(rv)) { 2449 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2450 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2451 spci.mem, 2452 spci.index); 2453 } 2454 } 2455 } 2456 } 2457 2458 /* Clear errors */ 2459 SOC_IF_ERROR_RETURN 2460 (WRITE_TOQ_IPMCERRINTRr(unit, 0)); 2461 2462 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2463 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 2464 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2465 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 2466 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2467 } 2468 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2469 ENQ_IPMC_TBL_PAR_ERRf, 0)); 2470 } 2471 2472 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2473 istat, MEM1_IPMC_TBL_PAR_ERRf)) { 2474 SOC_IF_ERROR_RETURN 2475 (READ_MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr(unit, &val2)); 2476 2477 for (ix = 0; ix < num_tables; ix++) { 2478 if (val2 & (1 << ix)) { 2479 SOC_IF_ERROR_RETURN 2480 (READ_MEM1_IPMCGRP_TBL_PARITYERRORPTRr(unit, ix, &val)); 2481 LOG_ERROR(BSL_LS_SOC_COMMON, 2482 (BSL_META_U(unit, 2483 "unit = %d, ENQ MMU_IPMC_GROUP_TBL%d, entry %d parity error\n"), 2484 unit, ix, val)); 2485 } 2486 } 2487 2488 SOC_IF_ERROR_RETURN 2489 (WRITE_MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr(unit, 0)); 2490 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2491 MEM1_IPMC_TBL_PAR_ERRf, 1)); 2492 } 2493 2494 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2495 istat, MEM1_VLAN_TBL_PAR_ERRf)) { 2496 SOC_IF_ERROR_RETURN 2497 (READ_MEM1_IPMCVLAN_TBL_PARITYERROR_STATUSr(unit, &val2)); 2498 2499 num_tables = 2; 2500 for (ix = 0; ix < num_tables; ix++) { 2501 if (val2 & (1 << ix)) { 2502 SOC_IF_ERROR_RETURN 2503 (READ_MEM1_IPMCVLAN_TBL_PARITYERRORPTRr(unit, ix, &val)); 2504 2505 LOG_ERROR(BSL_LS_SOC_COMMON, 2506 (BSL_META_U(unit, 2507 "unit = %d, ENQ MMU_IPMC_GROUP_TBL%d, entry %d parity error\n"), 2508 unit, ix, val)); 2509 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 2510 spci.reg = INVALIDr; 2511 spci.mem = MMU_IPMC_VLAN_TBLm; 2512 spci.blk_type = -1; 2513 spci.index = val; 2514 spci.sblk = 0; 2515 rv = soc_ser_correction(unit, &spci); 2516 if (SOC_FAILURE(rv)) { 2517 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2518 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2519 spci.mem, 2520 spci.index); 2521 } 2522 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2523 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 2524 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2525 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 2526 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2527 } 2528 } 2529 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2530 MEM1_VLAN_TBL_PAR_ERRf, 0)); 2531 } 2532 } 2533 2534 #ifdef BCM_SCORPION_SUPPORT 2535 if (SOC_IS_SC_CQ(unit)) { 2536 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2537 istat, WRED_PAR_ERRf)) { 2538 int bit, index; 2539 2540 SOC_IF_ERROR_RETURN(READ_WRED_PARITY_ERROR_INFOr(unit, &val)); 2541 index = soc_reg_field_get(unit, WRED_PARITY_ERROR_INFOr, 2542 val, POINTERf); 2543 SOC_IF_ERROR_RETURN(READ_WRED_PARITY_ERROR_BITMAPr(unit, &val2)); 2544 for (bit = 0; bit < SOC_SC_WRED_PARITY_NUM; bit++) { 2545 if (val2 & (1 << bit)) { 2546 LOG_ERROR(BSL_LS_SOC_COMMON, 2547 (BSL_META_U(unit, 2548 "unit = %d, %s[%d]\n"), unit, SOC_REG_NAME(unit, 2549 _soc_sc_parity_wred_reg[bit]), index)); 2550 2551 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 2552 spci.reg = INVALIDr; 2553 spci.mem = _soc_sc_parity_wred_mem[bit]; 2554 spci.blk_type = -1; 2555 spci.index = index; 2556 spci.sblk = 0; 2557 2558 rv = soc_ser_correction(unit, &spci); 2559 if (SOC_FAILURE(rv)) { 2560 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2561 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2562 spci.mem, 2563 spci.index); 2564 } 2565 } 2566 } 2567 2568 SOC_IF_ERROR_RETURN(WRITE_WRED_PARITY_ERROR_BITMAPr(unit, 0)); 2569 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2570 WRED_PAR_ERRf, 0)); 2571 } 2572 2573 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2574 istat, DEQ0_LENGTH_PAR_ERRf)) { 2575 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2576 DEQ0_LENGTH_PAR_ERRf, 1)); 2577 LOG_ERROR(BSL_LS_SOC_COMMON, 2578 (BSL_META_U(unit, 2579 "unit = %d, DEQ0_LENGTH_PAR_ERR\n"), unit)); 2580 } 2581 2582 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2583 istat, DEQ1_LENGTH_PAR_ERRf)) { 2584 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2585 DEQ1_LENGTH_PAR_ERRf, 1)); 2586 LOG_ERROR(BSL_LS_SOC_COMMON, 2587 (BSL_META_U(unit, 2588 "unit = %d, DEQ1_LENGTH_PAR_ERR\n"), unit)); 2589 } 2590 2591 if (soc_reg_field_get(unit, MEM_FAIL_INT_STATr, 2592 istat, START_BY_START_ERRf)) { 2593 SOC_IF_ERROR_RETURN(_soc_hbs_mmu_party_error_callback_notify(unit, 2594 START_BY_START_ERRf, 1)); 2595 LOG_ERROR(BSL_LS_SOC_COMMON, 2596 (BSL_META_U(unit, 2597 "unit = %d, START_BY_START_ERR\n"), unit)); 2598 } 2599 } 2600 #endif /* BCM_SCORPION_SUPPORT */ 2601 2602 SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0)); 2603 2604 return SOC_E_NONE; 2605 } 2606 2607 /* 2608 * _soc_hb_ipipe_parity_error 2609 * HB L2/L3 parity error decoder 2610 */ 2611 int _soc_hb_ipipe_parity_error(int unit) 2612 { 2613 uint32 istat = 0; 2614 uint32 val = 0; 2615 2616 if (soc_feature(unit, soc_feature_l2x_parity)) { 2617 SOC_IF_ERROR_RETURN(READ_L2_ENTRY_PARITY_STATUSr(unit, &istat)); 2618 if (soc_reg_field_get(unit, L2_ENTRY_PARITY_STATUSr, 2619 istat, PARITY_ERRf)) { 2620 uint32 bucket, entry_bmap; 2621 bucket = soc_reg_field_get(unit, L2_ENTRY_PARITY_STATUSr, 2622 istat, BUCKET_IDXf), 2623 entry_bmap = soc_reg_field_get(unit, L2_ENTRY_PARITY_STATUSr, 2624 istat, ENTRY_BMf); 2625 LOG_ERROR(BSL_LS_SOC_COMMON, 2626 (BSL_META_U(unit, 2627 "_soc_hx_ipipe_parity_error:unit = %d," 2628 "L2_ENTRY_PARITY_STATUS = 0x%08x, " 2629 "Bucket = %d Entry Bitmap 0x%02x\n"), 2630 unit, 2631 istat, 2632 bucket, 2633 entry_bmap)); 2634 /* Clear all parity errors */ 2635 SOC_IF_ERROR_RETURN(READ_L2_ENTRY_PARITY_CONTROLr(unit, &val)); 2636 soc_reg_field_set(unit, L2_ENTRY_PARITY_CONTROLr, &val, 2637 PARITY_IRQ_ENf, 0); 2638 SOC_IF_ERROR_RETURN(WRITE_L2_ENTRY_PARITY_CONTROLr(unit, val)); 2639 soc_reg_field_set(unit, L2_ENTRY_PARITY_CONTROLr, &val, 2640 PARITY_IRQ_ENf, 1); 2641 SOC_IF_ERROR_RETURN(WRITE_L2_ENTRY_PARITY_CONTROLr(unit, val)); 2642 } 2643 } 2644 2645 if (soc_feature(unit, soc_feature_l3x_parity)) { 2646 SOC_IF_ERROR_RETURN(READ_L3_ENTRY_PARITY_STATUSr(unit, &istat)); 2647 if (soc_reg_field_get(unit, L3_ENTRY_PARITY_STATUSr, 2648 istat, PARITY_ERRf)) { 2649 uint32 bucket, entry_bmap; 2650 2651 bucket = soc_reg_field_get(unit, L3_ENTRY_PARITY_STATUSr, 2652 istat, BUCKET_IDXf), 2653 entry_bmap = soc_reg_field_get(unit, L3_ENTRY_PARITY_STATUSr, 2654 istat, ENTRY_BMf); 2655 LOG_ERROR(BSL_LS_SOC_COMMON, 2656 (BSL_META_U(unit, 2657 "_soc_hx_ipipe_parity_error:unit = %d," 2658 "L3_ENTRY_PARITY_STATUS = 0x%08x, " 2659 "Bucket = %d Entry Bitmap 0x%02x\n"), 2660 unit, 2661 istat, 2662 bucket, 2663 entry_bmap)); 2664 SOC_IF_ERROR_RETURN(READ_L3_ENTRY_PARITY_CONTROLr(unit, &val)); 2665 soc_reg_field_set(unit, L3_ENTRY_PARITY_CONTROLr, &val, 2666 PARITY_IRQ_ENf, 0); 2667 SOC_IF_ERROR_RETURN(WRITE_L3_ENTRY_PARITY_CONTROLr(unit, val)); 2668 soc_reg_field_set(unit, L3_ENTRY_PARITY_CONTROLr, &val, 2669 PARITY_IRQ_ENf, 1); 2670 SOC_IF_ERROR_RETURN(WRITE_L3_ENTRY_PARITY_CONTROLr(unit, val)); 2671 } 2672 } 2673 2674 if (soc_feature(unit, soc_feature_l3defip_parity)) { 2675 SOC_IF_ERROR_RETURN(READ_L3_DEFIP_PARITY_STATUSr(unit, &istat)); 2676 if (soc_reg_field_get(unit, L3_DEFIP_PARITY_STATUSr, 2677 istat, PARITY_ERRf)) { 2678 uint32 mem_idx; 2679 2680 mem_idx = soc_reg_field_get(unit, L3_DEFIP_PARITY_STATUSr, 2681 istat, MEMORY_IDXf); 2682 LOG_ERROR(BSL_LS_SOC_COMMON, 2683 (BSL_META_U(unit, 2684 "_soc_fb_ipipe_parity_error:unit = %d," 2685 "L3_DEFIP_PARITY_STATUS = 0x%08x, Index = %d "), 2686 unit, 2687 istat, 2688 mem_idx)); 2689 SOC_IF_ERROR_RETURN(READ_L3_DEFIP_PARITY_CONTROLr(unit, &val)); 2690 soc_reg_field_set(unit, L3_DEFIP_PARITY_CONTROLr, &val, 2691 PARITY_IRQ_ENf, 0); 2692 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_PARITY_CONTROLr(unit, val)); 2693 soc_reg_field_set(unit, L3_DEFIP_PARITY_CONTROLr, &val, 2694 PARITY_IRQ_ENf, 1); 2695 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_PARITY_CONTROLr(unit, val)); 2696 } 2697 } 2698 2699 return SOC_E_NONE; 2700 } 2701 2702 void soc_bradley_mmu_parity_error(void *unit, void *d1, void *d2, 2703 void *d3, void *d4 ) 2704 { 2705 int u = PTR_TO_INT(unit); 2706 2707 COMPILER_REFERENCE(d1); 2708 COMPILER_REFERENCE(d2); 2709 COMPILER_REFERENCE(d3); 2710 COMPILER_REFERENCE(d4); 2711 _soc_hb_ipipe_parity_error(u); 2712 _soc_hbs_mmu_parity_error(u); 2713 soc_intr_enable(u, IRQ_MEM_FAIL); 2714 } 2715 2716 #ifdef BCM_SCORPION_SUPPORT 2717 2718 typedef enum { 2719 SOC_PARITY_TYPE_CELL_DATA, 2720 SOC_PARITY_TYPE_TABLE, 2721 SOC_PARITY_TYPE_DUALHASH, 2722 SOC_PARITY_TYPE_DUALHASH_2 2723 } _soc_parity_error_t; 2724 2725 typedef struct _soc_parity_tree_s { 2726 soc_reg_t block_reg; 2727 soc_field_t error_field; 2728 _soc_parity_error_t error_type; 2729 soc_mem_t mem; 2730 soc_reg_t status_reg; 2731 soc_reg_t control_reg; 2732 } _soc_parity_tree_t; 2733 2734 #define PAR_BLOCK_REG(i) (_soc_sc_parity_trees[i].block_reg) 2735 #define PAR_ERROR_FIELD(i) (_soc_sc_parity_trees[i].error_field) 2736 #define PAR_ERROR_TYPE(i) (_soc_sc_parity_trees[i].error_type) 2737 #define PAR_MEM(i) (_soc_sc_parity_trees[i].mem) 2738 #define PAR_STATUS_REG(i) (_soc_sc_parity_trees[i].status_reg) 2739 #define PAR_CONTROL_REG(i) (_soc_sc_parity_trees[i].control_reg) 2740 2741 _soc_parity_tree_t _soc_sc_parity_trees[] = { 2742 { IP1_PARITY_INTR_STATUSr, SOURCE_TRUNK_MAP_INTRf, 2743 SOC_PARITY_TYPE_TABLE, SOURCE_TRUNK_MAP_TABLEm, 2744 SRC_TRUNK_PARITY_STATUSr, SRC_TRUNK_PARITY_CONTROLr }, 2745 { IP1_PARITY_INTR_STATUSr, VLAN_MAC_OR_XLATE_INTRf, 2746 SOC_PARITY_TYPE_DUALHASH_2, VLAN_XLATEm, 2747 VLAN_MAC_OR_XLATE_PARITY_STATUSr, VLAN_MAC_OR_XLATE_PARITY_CONTROLr }, 2748 { IP1_PARITY_INTR_STATUSr, VFP_POLICY_TABLE_INTRf, 2749 SOC_PARITY_TYPE_TABLE, VFP_POLICY_TABLEm, 2750 VFP_POLICY_TABLE_PARITY_STATUSr, VFP_POLICY_TABLE_PARITY_CONTROLr }, 2751 { IP1_PARITY_INTR_STATUSr, VLAN_TABLE_INTRf, 2752 SOC_PARITY_TYPE_TABLE, VLAN_TABm, 2753 VLAN_PARITY_STATUSr, VLAN_PARITY_CONTROLr }, 2754 { IP2_PARITY_INTR_STATUSr, L2_ENTRY_INTRf, 2755 SOC_PARITY_TYPE_DUALHASH, L2Xm, 2756 L2_ENTRY_PARITY_STATUSr, L2_ENTRY_PARITY_CONTROLr }, 2757 { IP2_PARITY_INTR_STATUSr, L2MC_INTRf, 2758 SOC_PARITY_TYPE_TABLE, L2MCm, 2759 L2MC_PARITY_STATUSr, L2MC_PARITY_CONTROLr }, 2760 { IP2_PARITY_INTR_STATUSr, L3_ENTRY_INTRf, 2761 SOC_PARITY_TYPE_DUALHASH, L3_ENTRY_ONLYm, 2762 L3_ENTRY_PARITY_STATUSr, L3_ENTRY_PARITY_CONTROLr }, 2763 { IP2_PARITY_INTR_STATUSr, L3_DEFIP_DATA_INTRf, 2764 SOC_PARITY_TYPE_TABLE, L3_DEFIPm, 2765 L3_DEFIP_PARITY_STATUSr, L3_DEFIP_PARITY_CONTROLr }, 2766 { IP2_PARITY_INTR_STATUSr, L3_IPMC_INTRf, 2767 SOC_PARITY_TYPE_TABLE, L3_IPMCm, 2768 L3MC_PARITY_STATUSr, L3MC_PARITY_CONTROLr }, 2769 { IP2_PARITY_INTR_STATUSr, INITIAL_ING_L3_NEXT_HOP_INTRf, 2770 SOC_PARITY_TYPE_TABLE, INITIAL_ING_L3_NEXT_HOPm, 2771 INITIAL_ING_L3_NEXT_HOP_PARITY_STATUSr, INITIAL_ING_L3_NEXT_HOP_PARITY_CONTROLr }, 2772 { IP3_PARITY_INTR_STATUSr, IFP_POLICY_TABLE_INTRf, 2773 SOC_PARITY_TYPE_TABLE, FP_POLICY_TABLEm, 2774 IFP_POLICY_TABLE_PARITY_STATUSr, IFP_POLICY_TABLE_PARITY_CONTROLr }, 2775 { IP4_PARITY_STATUSr, IRSEL2_NEXTHOP_PARITY_ERRf, 2776 SOC_PARITY_TYPE_TABLE, ING_L3_NEXT_HOPm, 2777 ING_L3_NEXT_HOP_PARITY_STATUSr, ING_L3_NEXT_HOP_PARITY_CONTROLr }, 2778 { IP4_PARITY_STATUSr, ISW2_EGR_MASK_PARITY_ERRf, 2779 SOC_PARITY_TYPE_TABLE, EGR_MASKm, 2780 EGR_MASK_PARITY_STATUSr, EGR_MASK_PARITY_CONTROLr }, 2781 { IP4_PARITY_STATUSr, ISW2_SRC_MODID_BLOCK_PARITY_ERRf, 2782 SOC_PARITY_TYPE_TABLE, SRC_MODID_BLOCKm, 2783 SRC_MODID_BLOCK_PARITY_STATUSr, SRC_MODID_BLOCK_PARITY_CONTROLr }, 2784 { IP4_PARITY_STATUSr, ISW2_MODPORT_MAP_SW_PARITY_ERRf, 2785 SOC_PARITY_TYPE_TABLE, MODPORT_MAP_SWm, 2786 MODPORT_MAP_SW_PARITY_STATUSr, MODPORT_MAP_SW_PARITY_CONTROLr }, 2787 { IP4_PARITY_STATUSr, ISW2_MODPORT_MAP_IM_PARITY_ERRf, 2788 SOC_PARITY_TYPE_TABLE, MODPORT_MAP_IMm, 2789 MODPORT_MAP_IM_PARITY_STATUSr, MODPORT_MAP_IM_PARITY_CONTROLr }, 2790 { IP4_PARITY_STATUSr, ISW2_MODPORT_MAP_EM_PARITY_ERRf, 2791 SOC_PARITY_TYPE_TABLE, MODPORT_MAP_EMm, 2792 MODPORT_MAP_EM_PARITY_STATUSr, MODPORT_MAP_EM_PARITY_CONTROLr }, 2793 { EP_PARITY_INTR_STATUSr, L3_INTF_INTRf, 2794 SOC_PARITY_TYPE_TABLE, EGR_L3_INTFm, 2795 EGR_L3_INTF_PARITY_STATUSr, EGR_L3_INTF_PARITY_CONTROLr }, 2796 { EP_PARITY_INTR_STATUSr, L3_NEXT_HOP_INTRf, 2797 SOC_PARITY_TYPE_TABLE, EGR_L3_NEXT_HOPm, 2798 EGR_L3_NEXT_HOP_PARITY_STATUSr, EGR_L3_NEXT_HOP_PARITY_CONTROLr }, 2799 { EP_PARITY_INTR_STATUSr, IP_TUNNEL_INTRf, 2800 SOC_PARITY_TYPE_TABLE, EGR_IP_TUNNELm, 2801 EGR_IP_TUNNEL_PARITY_STATUSr, EGR_IP_TUNNEL_PARITY_CONTROLr }, 2802 { EP_PARITY_INTR_STATUSr, VLAN_XLATE_INTRf, 2803 SOC_PARITY_TYPE_TABLE, EGR_VLAN_XLATEm, 2804 EGR_VLAN_XLATE_PARITY_STATUSr, EGR_VLAN_XLATE_PARITY_CONTROLr }, 2805 { EP_PARITY_INTR_STATUSr, VLAN_INTRf, 2806 SOC_PARITY_TYPE_TABLE, EGR_VLANm, 2807 EGR_VLAN_PARITY_STATUSr, EGR_VLAN_PARITY_CONTROLr }, 2808 { EP_PARITY_INTR_STATUSr, CELL_DATA_ERROR_INTRf, 2809 SOC_PARITY_TYPE_CELL_DATA, INVALIDm, 2810 EGR_ECC_STATUSr, EGR_ECC_CONTROLr }, 2811 { INVALIDr, INVALIDf, 2812 SOC_PARITY_TYPE_TABLE, INVALIDm, 2813 INVALIDr, INVALIDr } 2814 }; 2815 2816 #define SOC_SC_PARITY_BUCKET_SIZE 8 2817 2818 STATIC int 2819 _soc_sc_pipe_parity_enable(int unit, int enable) 2820 { 2821 int trix, egress, bypass; 2822 soc_reg_t control_reg; 2823 uint32 control; 2824 2825 control = enable ? 0x3 : 0; 2826 bypass = SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE; 2827 2828 trix = 0; 2829 while ((control_reg = PAR_CONTROL_REG(trix)) != INVALIDr) { 2830 egress = (PAR_BLOCK_REG(trix) == EP_PARITY_INTR_STATUSr); 2831 if (egress && bypass) { 2832 if ((control_reg != EGR_VLAN_PARITY_CONTROLr) && 2833 (control_reg != EGR_ECC_CONTROLr)) { 2834 /* Then L3 related, skip for bypass */ 2835 trix++; 2836 continue; 2837 } 2838 } 2839 SOC_IF_ERROR_RETURN 2840 (soc_scorpion_pipe_select(unit, egress, SOC_PIPE_SELECT_X)); 2841 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, control_reg, REG_PORT_ANY, 0, 2842 control)); 2843 2844 if (PAR_ERROR_TYPE(trix) != SOC_PARITY_TYPE_DUALHASH) { 2845 SOC_IF_ERROR_RETURN 2846 (soc_scorpion_pipe_select(unit, egress, SOC_PIPE_SELECT_Y)); 2847 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, control_reg, REG_PORT_ANY, 2848 0, control)); 2849 } 2850 trix++; 2851 } 2852 2853 SOC_IF_ERROR_RETURN 2854 (soc_scorpion_pipe_select(unit, TRUE, SOC_PIPE_SELECT_X)); 2855 SOC_IF_ERROR_RETURN 2856 (soc_scorpion_pipe_select(unit, FALSE, SOC_PIPE_SELECT_X)); 2857 2858 /* Turn on at the CMIC */ 2859 /* coverity[dead_error_begin : FALSE] */ 2860 SOC_IF_ERROR_RETURN 2861 (WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, enable ? 0xfff : 0)); 2862 return SOC_E_NONE; 2863 } 2864 2865 /* This function takes the parity tree index and assumes the pipe select 2866 * is already set. */ 2867 STATIC int 2868 _soc_sc_pipe_parity_clear(int unit, int pt_idx) 2869 { 2870 soc_reg_t control_reg; 2871 uint32 control; 2872 2873 control_reg = PAR_CONTROL_REG(pt_idx); 2874 2875 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, control_reg, REG_PORT_ANY, 0, 2876 &control)); 2877 soc_reg_field_set(unit, control_reg, &control, PARITY_IRQ_ENf, 0); 2878 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, control_reg, REG_PORT_ANY, 0, 2879 control)); 2880 soc_reg_field_set(unit, control_reg, &control, PARITY_IRQ_ENf, 1); 2881 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, control_reg, REG_PORT_ANY, 0, 2882 control)); 2883 2884 return SOC_E_NONE; 2885 } 2886 2887 /* 2888 * _soc_sc_stage_parity_error 2889 * Scorpion ingress/egress parity error decoder 2890 */ 2891 STATIC int 2892 _soc_sc_stage_parity_error(int unit, soc_reg_t base_reg, int pipe_sel) 2893 { 2894 soc_reg_t cur_base_reg, last_base_reg = INVALIDr, 2895 status_reg; 2896 int tab_index, trix, bucket, bucket_offset; 2897 uint32 rval, status, bmp; 2898 _soc_ser_correct_info_t spci; 2899 int rv = SOC_E_NONE; 2900 2901 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 2902 2903 SOC_IF_ERROR_RETURN 2904 (soc_scorpion_pipe_select(unit, 2905 (base_reg == EP_PARITY_INTR_STATUSr), pipe_sel)); 2906 2907 trix = 0; 2908 rval = 0; 2909 while ((cur_base_reg = PAR_BLOCK_REG(trix)) != INVALIDr) { 2910 if (cur_base_reg == base_reg) { 2911 if (cur_base_reg != last_base_reg) { 2912 SOC_IF_ERROR_RETURN 2913 (soc_reg32_get(unit, cur_base_reg, REG_PORT_ANY, 0, 2914 &rval)); 2915 last_base_reg = cur_base_reg; 2916 } 2917 } else { 2918 trix++; 2919 continue; 2920 } 2921 2922 if (soc_reg_field_get(unit, cur_base_reg, rval, 2923 PAR_ERROR_FIELD(trix)) == 0) { 2924 trix++; 2925 continue; 2926 } 2927 2928 status_reg = PAR_STATUS_REG(trix); 2929 SOC_IF_ERROR_RETURN 2930 (soc_reg32_get(unit, status_reg, REG_PORT_ANY, 0, 2931 &status)); 2932 if (soc_reg_field_get(unit, status_reg, status, PARITY_ERRf) && 2933 !((PAR_ERROR_TYPE(trix) == SOC_PARITY_TYPE_DUALHASH) && 2934 (pipe_sel == SOC_PIPE_SELECT_Y))) { 2935 tab_index = -1; 2936 switch (PAR_ERROR_TYPE(trix)) { 2937 case SOC_PARITY_TYPE_CELL_DATA: 2938 LOG_ERROR(BSL_LS_SOC_COMMON, 2939 (BSL_META_U(unit, 2940 "unit = %d, %s pipe, Egress cell data ECC failure\n"), 2941 unit, 2942 (pipe_sel == SOC_PIPE_SELECT_Y) ? "Y" : "X")); 2943 break; 2944 case SOC_PARITY_TYPE_TABLE: 2945 tab_index = soc_reg_field_get(unit, status_reg, 2946 status, ENTRY_IDXf); 2947 if ((PAR_MEM(trix) == FP_POLICY_TABLEm) && 2948 (tab_index > 1024)) { 2949 /* Adjust for slice size difference */ 2950 tab_index -= 1024; 2951 } 2952 LOG_ERROR(BSL_LS_SOC_COMMON, 2953 (BSL_META_U(unit, 2954 "unit = %d, %s.%s, entry %d parity error\n"), 2955 unit, SOC_MEM_NAME(unit, PAR_MEM(trix)), 2956 (pipe_sel == SOC_PIPE_SELECT_Y) ? "Y" : "X", 2957 tab_index)); 2958 break; 2959 case SOC_PARITY_TYPE_DUALHASH: 2960 /* Only one pipe */ 2961 bmp = soc_reg_field_get(unit, status_reg, 2962 status, ENTRY_BMf); 2963 bucket = soc_reg_field_get(unit, status_reg, 2964 status, BUCKET_IDXf); 2965 for (bucket_offset = 0; 2966 bucket_offset < SOC_SC_PARITY_BUCKET_SIZE; 2967 bucket_offset++) { 2968 if (bucket_offset == (SOC_SC_PARITY_BUCKET_SIZE / 2)) { 2969 2970 } 2971 if (bmp & (1 << bucket_offset)) { 2972 tab_index = 2973 (bucket * SOC_SC_PARITY_BUCKET_SIZE) + 2974 bucket_offset; 2975 LOG_ERROR(BSL_LS_SOC_COMMON, 2976 (BSL_META_U(unit, 2977 "unit = %d, %s, entry %d parity error\n"), 2978 unit, SOC_MEM_NAME(unit, PAR_MEM(trix)), 2979 tab_index)); 2980 } 2981 } 2982 break; 2983 case SOC_PARITY_TYPE_DUALHASH_2: 2984 bmp = soc_reg_field_get(unit, status_reg, 2985 status, PARITY_ERR_BMf); 2986 bucket = soc_reg_field_get(unit, status_reg, 2987 status, BUCKET_IDX_0f); 2988 for (bucket_offset = 0; 2989 bucket_offset < SOC_SC_PARITY_BUCKET_SIZE; 2990 bucket_offset++) { 2991 if (bucket_offset == (SOC_SC_PARITY_BUCKET_SIZE / 2)) { 2992 bucket = soc_reg_field_get(unit, status_reg, 2993 status, BUCKET_IDX_1f); 2994 } 2995 if (bmp & (1 << bucket_offset)) { 2996 tab_index = 2997 (bucket * SOC_SC_PARITY_BUCKET_SIZE) + 2998 bucket_offset; 2999 LOG_ERROR(BSL_LS_SOC_COMMON, 3000 (BSL_META_U(unit, 3001 "unit = %d, %s.%s, entry %d parity error\n"), 3002 unit, SOC_MEM_NAME(unit, PAR_MEM(trix)), 3003 (pipe_sel == SOC_PIPE_SELECT_Y) ? "Y" : "X", 3004 tab_index)); 3005 } 3006 } 3007 break; 3008 default: 3009 break; 3010 } 3011 if (PAR_MEM(trix) != INVALIDm) { 3012 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3013 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3014 PAR_MEM(trix), 3015 tab_index); 3016 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 3017 spci.reg = INVALIDr; 3018 spci.mem = PAR_MEM(trix); 3019 spci.blk_type = -1; 3020 spci.index = tab_index; 3021 rv = soc_ser_correction(unit, &spci); 3022 if (SOC_FAILURE(rv)) { 3023 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3024 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3025 PAR_MEM(trix), 3026 tab_index); 3027 } 3028 } 3029 SOC_IF_ERROR_RETURN 3030 (_soc_sc_pipe_parity_clear(unit, trix)); 3031 } 3032 trix++; 3033 } 3034 3035 return SOC_E_NONE; 3036 } 3037 3038 typedef struct _soc_sc_parity_stage_s { 3039 uint32 cpi_bit; 3040 soc_reg_t block_reg; 3041 int pipe_sel; 3042 } _soc_sc_parity_stage_t; 3043 3044 _soc_sc_parity_stage_t _soc_sc_parity_stages[] = { 3045 {0x001, IP1_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_X}, 3046 {0x002, IP1_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_Y}, 3047 {0x004, IP2_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_X}, 3048 {0x008, IP2_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_Y}, 3049 {0x010, IP3_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_X}, 3050 {0x020, IP3_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_Y}, 3051 {0x040, IP4_PARITY_STATUSr, SOC_PIPE_SELECT_X}, 3052 {0x080, IP4_PARITY_STATUSr, SOC_PIPE_SELECT_Y}, 3053 {0x100, EP_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_X}, 3054 {0x200, EP_PARITY_INTR_STATUSr, SOC_PIPE_SELECT_Y}, 3055 {0xffffffff, INVALIDr, SOC_PIPE_SELECT_X} 3056 }; 3057 3058 #define PAR_STAGE_BIT(i) (_soc_sc_parity_stages[i].cpi_bit) 3059 #define PAR_STAGE_BLOCK_REG(i) (_soc_sc_parity_stages[i].block_reg) 3060 #define PAR_STAGE_PIPE_SELECT(i) (_soc_sc_parity_stages[i].pipe_sel) 3061 3062 /* 3063 * _soc_sc_pipe_parity_error 3064 * Scorpion ingress/egress parity error decoder 3065 */ 3066 STATIC int 3067 _soc_sc_pipe_parity_error(int unit) 3068 { 3069 uint32 cpi_reg; 3070 int ix; 3071 /* coverity[dead_error_begin : FALSE] */ 3072 SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit, &cpi_reg)); 3073 3074 ix = 0; 3075 while (PAR_STAGE_BIT(ix) != 0xffffffff) { 3076 if (cpi_reg & PAR_STAGE_BIT(ix)) { 3077 SOC_IF_ERROR_RETURN 3078 (_soc_sc_stage_parity_error(unit, PAR_STAGE_BLOCK_REG(ix), 3079 PAR_STAGE_PIPE_SELECT(ix))); 3080 } 3081 ix++; 3082 } 3083 3084 SOC_IF_ERROR_RETURN 3085 (soc_scorpion_pipe_select(unit, FALSE, SOC_PIPE_SELECT_X)); 3086 SOC_IF_ERROR_RETURN 3087 (soc_scorpion_pipe_select(unit, TRUE, SOC_PIPE_SELECT_X)); 3088 3089 if (cpi_reg & 0x400) { 3090 3091 } 3092 3093 if (cpi_reg & 0x800) { 3094 _soc_hbs_mmu_parity_error(unit); 3095 } 3096 3097 return SOC_E_NONE; 3098 } 3099 3100 void soc_scorpion_parity_error(void *unit, void *d1, void *d2, 3101 void *d3, void *d4 ) 3102 { 3103 int u = PTR_TO_INT(unit); 3104 3105 COMPILER_REFERENCE(d1); 3106 COMPILER_REFERENCE(d2); 3107 COMPILER_REFERENCE(d3); 3108 COMPILER_REFERENCE(d4); 3109 _soc_sc_pipe_parity_error(u); 3110 soc_intr_enable(u, IRQ_MEM_FAIL); 3111 } 3112 #endif /* BCM_SCORPION_SUPPORT */ 3113 3114 int 3115 soc_bradley_age_timer_get(int unit, int *age_seconds, int *enabled) 3116 { 3117 uint32 value; 3118 3119 SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &value)); 3120 *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_ENAf); 3121 *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_VALf); 3122 3123 return SOC_E_NONE; 3124 } 3125 3126 int 3127 soc_bradley_age_timer_max_get(int unit, int *max_seconds) 3128 { 3129 *max_seconds = 3130 soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf); 3131 3132 return SOC_E_NONE; 3133 } 3134 3135 int 3136 soc_bradley_age_timer_set(int unit, int age_seconds, int enable) 3137 { 3138 uint32 value; 3139 3140 value = 0; 3141 soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_ENAf, enable); 3142 soc_reg_field_set(unit, L2_AGE_TIMERr, &value, AGE_VALf, age_seconds); 3143 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, value)); 3144 3145 return SOC_E_NONE; 3146 } 3147 3148 int 3149 soc_hbx_higig2_mcast_sizes_set(int unit, int bcast_size, 3150 int mcast_size, int ipmc_size) 3151 { 3152 uint32 mc_ctrl; 3153 soc_control_t *soc = SOC_CONTROL(unit); 3154 3155 if ((bcast_size > SOC_HBX_HIGIG2_MULTICAST_RANGE_MAX) || 3156 (mcast_size > SOC_HBX_HIGIG2_MULTICAST_RANGE_MAX) || 3157 (ipmc_size > SOC_HBX_HIGIG2_MULTICAST_RANGE_MAX) || 3158 ((bcast_size + mcast_size + ipmc_size) > 3159 SOC_HBX_HIGIG2_MULTICAST_RANGE_MAX)) { 3160 return SOC_E_PARAM; 3161 } 3162 3163 mc_ctrl = 0; 3164 soc_reg_field_set(unit, MC_CONTROL_1r, &mc_ctrl, 3165 HIGIG2_BC_BASE_OFFSETf, 0); 3166 soc_reg_field_set(unit, MC_CONTROL_1r, &mc_ctrl, 3167 HIGIG2_BC_SIZEf, bcast_size); 3168 SOC_IF_ERROR_RETURN 3169 (WRITE_MC_CONTROL_1r(unit, mc_ctrl)); 3170 3171 mc_ctrl = 0; 3172 soc_reg_field_set(unit, MC_CONTROL_2r, &mc_ctrl, 3173 HIGIG2_L2MC_BASE_OFFSETf, bcast_size); 3174 soc_reg_field_set(unit, MC_CONTROL_2r, &mc_ctrl, 3175 HIGIG2_L2MC_SIZEf, mcast_size); 3176 SOC_IF_ERROR_RETURN 3177 (WRITE_MC_CONTROL_2r(unit, mc_ctrl)); 3178 3179 mc_ctrl = 0; 3180 soc_reg_field_set(unit, MC_CONTROL_3r, &mc_ctrl, 3181 HIGIG2_IPMC_BASE_OFFSETf, mcast_size + bcast_size); 3182 soc_reg_field_set(unit, MC_CONTROL_3r, &mc_ctrl, 3183 HIGIG2_IPMC_SIZEf, ipmc_size); 3184 SOC_IF_ERROR_RETURN 3185 (WRITE_MC_CONTROL_3r(unit, mc_ctrl)); 3186 3187 mc_ctrl = 0; 3188 #ifdef BCM_TRIDENT3_SUPPORT 3189 if (SOC_IS_TRIDENT3X(unit)) { 3190 soc_reg_field_set(unit, MC_CONTROL_4r, &mc_ctrl, 3191 ALLOW_IPMC_INDEX_WRAP_AROUNDf, 1); 3192 } 3193 #endif 3194 SOC_IF_ERROR_RETURN 3195 (WRITE_MC_CONTROL_4r(unit, mc_ctrl)); 3196 3197 mc_ctrl = 0; 3198 soc_reg_field_set(unit, EGR_MC_CONTROL_1r, &mc_ctrl, 3199 HIGIG2_BC_BASE_OFFSETf, 0); 3200 soc_reg_field_set(unit, EGR_MC_CONTROL_1r, &mc_ctrl, 3201 HIGIG2_L2MC_BASE_OFFSETf, bcast_size); 3202 SOC_IF_ERROR_RETURN 3203 (WRITE_EGR_MC_CONTROL_1r(unit, mc_ctrl)); 3204 3205 mc_ctrl = 0; 3206 soc_reg_field_set(unit, EGR_MC_CONTROL_2r, &mc_ctrl, 3207 HIGIG2_IPMC_BASE_OFFSETf, mcast_size + bcast_size); 3208 SOC_IF_ERROR_RETURN 3209 (WRITE_EGR_MC_CONTROL_2r(unit, mc_ctrl)); 3210 3211 soc->higig2_bcast_size = bcast_size; 3212 soc->higig2_mcast_size = mcast_size; 3213 soc->higig2_ipmc_size = ipmc_size; 3214 3215 return SOC_E_NONE; 3216 } 3217 3218 int 3219 soc_hbx_higig2_mcast_sizes_get(int unit, int *bcast_size, 3220 int *mcast_size, int *ipmc_size) 3221 { 3222 soc_control_t *soc = SOC_CONTROL(unit); 3223 3224 *bcast_size = soc->higig2_bcast_size; 3225 *mcast_size = soc->higig2_mcast_size; 3226 *ipmc_size = soc->higig2_ipmc_size; 3227 return SOC_E_NONE; 3228 } 3229 3230 3231 int 3232 soc_hbx_mcast_size_set(int unit, int mc_size) 3233 { 3234 uint32 mc_ctrl; 3235 soc_control_t *soc = SOC_CONTROL(unit); 3236 int l2mc_table_size = soc_mem_index_count(unit, L2MCm); 3237 3238 if (((mc_size + soc->ipmc_size) > l2mc_table_size) || 3239 (mc_size == l2mc_table_size)) { 3240 return SOC_E_PARAM; 3241 } 3242 3243 SOC_IF_ERROR_RETURN(READ_MC_CONTROL_5r(unit, &mc_ctrl)); 3244 soc_reg_field_set(unit, MC_CONTROL_5r, &mc_ctrl, 3245 SHARED_TABLE_L2MC_SIZEf, mc_size); 3246 SOC_IF_ERROR_RETURN(WRITE_MC_CONTROL_5r(unit, mc_ctrl)); 3247 soc->mcast_size = mc_size; 3248 return SOC_E_NONE; 3249 } 3250 3251 int 3252 soc_hbx_mcast_size_get(int unit, int *mc_base, int *mc_size) 3253 { 3254 *mc_base = 0; 3255 *mc_size = SOC_CONTROL(unit)->mcast_size; 3256 return SOC_E_NONE; 3257 } 3258 3259 int 3260 soc_hbx_ipmc_size_set(int unit, int mc_size) 3261 { 3262 uint32 mc_ctrl; 3263 soc_control_t *soc = SOC_CONTROL(unit); 3264 int l2mc_table_size = soc_mem_index_count(unit, L2MCm); 3265 3266 if (((mc_size + soc->mcast_size) > l2mc_table_size) || 3267 (mc_size == l2mc_table_size)) { 3268 return SOC_E_PARAM; 3269 } 3270 3271 SOC_IF_ERROR_RETURN(READ_MC_CONTROL_5r(unit, &mc_ctrl)); 3272 soc_reg_field_set(unit, MC_CONTROL_5r, &mc_ctrl, 3273 SHARED_TABLE_IPMC_SIZEf, mc_size); 3274 SOC_IF_ERROR_RETURN(WRITE_MC_CONTROL_5r(unit, mc_ctrl)); 3275 soc->ipmc_size = mc_size; 3276 return SOC_E_NONE; 3277 } 3278 3279 int 3280 soc_hbx_ipmc_size_get(int unit, int *mc_base, int *mc_size) 3281 { 3282 soc_control_t *soc = SOC_CONTROL(unit); 3283 3284 *mc_base = soc->mcast_size; 3285 *mc_size = soc->ipmc_size; 3286 return SOC_E_NONE; 3287 } 3288 3289 #ifdef BCM_SCORPION_SUPPORT 3290 void 3291 soc_scorpion_mem_config(int unit) 3292 { 3293 soc_persist_t *sop; 3294 sop_memstate_t *memState; 3295 3296 sop = SOC_PERSIST(unit); 3297 memState = sop->memState; 3298 3299 if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) { 3300 if (SOC_SWITCH_BYPASS_MODE(unit) == 3301 SOC_SWITCH_BYPASS_MODE_L3_AND_FP) { 3302 memState[IFP_REDIRECTION_PROFILEm].index_max = -1; 3303 memState[FP_COUNTER_TABLE_Xm].index_max = -1; 3304 memState[FP_COUNTER_TABLE_Ym].index_max = -1; 3305 memState[FP_METER_TABLEm].index_max = -1; 3306 memState[FP_POLICY_TABLEm].index_max = -1; 3307 memState[FP_PORT_FIELD_SELm].index_max = -1; 3308 memState[FP_RANGE_CHECKm].index_max = -1; 3309 memState[FP_SLICE_KEY_CONTROLm].index_max = -1; 3310 memState[FP_SLICE_MAPm].index_max = -1; 3311 memState[FP_TCAMm].index_max = -1; 3312 memState[FP_TCAM_Xm].index_max = -1; 3313 memState[FP_TCAM_Ym].index_max = -1; 3314 } 3315 memState[FP_STORM_CONTROL_METERSm].index_max = -1; 3316 memState[VFP_POLICY_TABLEm].index_max = -1; 3317 memState[VFP_TCAMm].index_max = -1; 3318 memState[EFP_COUNTER_TABLEm].index_max = -1; 3319 memState[EFP_COUNTER_TABLE_Xm].index_max = -1; 3320 memState[EFP_COUNTER_TABLE_Ym].index_max = -1; 3321 memState[EFP_METER_TABLEm].index_max = -1; 3322 memState[EFP_METER_TABLE_Xm].index_max = -1; 3323 memState[EFP_METER_TABLE_Ym].index_max = -1; 3324 memState[EFP_POLICY_TABLEm].index_max = -1; 3325 memState[EFP_TCAMm].index_max = -1; 3326 memState[L3_ENTRY_HIT_ONLYm].index_max = -1; 3327 memState[L3_ENTRY_IPV4_MULTICASTm].index_max = -1; 3328 memState[L3_ENTRY_IPV4_MULTICAST_SCRATCHm].index_max = -1; 3329 memState[L3_ENTRY_IPV4_UNICASTm].index_max = -1; 3330 memState[L3_ENTRY_IPV4_UNICAST_SCRATCHm].index_max = -1; 3331 memState[L3_ENTRY_IPV6_MULTICASTm].index_max = -1; 3332 memState[L3_ENTRY_IPV6_MULTICAST_SCRATCHm].index_max = -1; 3333 memState[L3_ENTRY_IPV6_UNICASTm].index_max = -1; 3334 memState[L3_ENTRY_IPV6_UNICAST_SCRATCHm].index_max = -1; 3335 memState[L3_ENTRY_ONLYm].index_max = -1; 3336 memState[L3_ENTRY_VALID_ONLYm].index_max = -1; 3337 memState[L3_IPMCm].index_max = -1; 3338 memState[L3_TUNNELm].index_max = -1; 3339 memState[L3_DEFIPm].index_max = -1; 3340 memState[L3_DEFIP_128m].index_max = -1; 3341 memState[L3_DEFIP_128_DATA_ONLYm].index_max = -1; 3342 memState[L3_DEFIP_128_HIT_ONLYm].index_max = -1; 3343 memState[L3_DEFIP_128_ONLYm].index_max = -1; 3344 memState[L3_DEFIP_DATA_ONLYm].index_max = -1; 3345 memState[L3_DEFIP_HIT_ONLYm].index_max = -1; 3346 memState[L3_DEFIP_ONLYm].index_max = -1; 3347 memState[L3_ECMPm].index_max = -1; 3348 memState[L3_ECMP_COUNTm].index_max = -1; 3349 memState[EGR_L3_NEXT_HOPm].index_max = -1; 3350 memState[EGR_VLAN_XLATEm].index_max = -1; 3351 memState[EGR_VLAN_XLATE_SCRATCHm].index_max = -1; 3352 memState[EGR_L3_INTFm].index_max = -1; 3353 memState[EGR_PRI_CNG_MAPm].index_max = -1; 3354 memState[EGR_IP_TUNNELm].index_max = -1; 3355 memState[EGR_IP_TUNNEL_IPV6m].index_max = -1; 3356 memState[EGR_DSCP_TABLEm].index_max = -1; 3357 memState[EGR_DSCP_ECN_MAPm].index_max = -1; 3358 memState[DSCP_TABLEm].index_max = -1; 3359 memState[IPV4_IN_IPV6_PREFIX_MATCH_TABLEm].index_max = -1; 3360 memState[VLAN_SUBNETm].index_max = -1; 3361 memState[VLAN_SUBNET_DATA_ONLYm].index_max = -1; 3362 memState[VLAN_SUBNET_ONLYm].index_max = -1; 3363 memState[VLAN_PROTOCOLm].index_max = -1; 3364 memState[VLAN_PROTOCOL_DATAm].index_max = -1; 3365 memState[VLAN_XLATEm].index_max = -1; 3366 memState[VLAN_XLATE_SCRATCHm].index_max = -1; 3367 memState[VLAN_MACm].index_max = -1; 3368 memState[VLAN_MAC_SCRATCHm].index_max = -1; 3369 memState[INITIAL_L3_ECMPm].index_max = -1; 3370 memState[INITIAL_L3_ECMP_COUNTm].index_max = -1; 3371 memState[INITIAL_ING_L3_NEXT_HOPm].index_max = -1; 3372 memState[ING_VLAN_TAG_ACTION_PROFILEm].index_max = -1; 3373 memState[ING_PRI_CNG_MAPm].index_max = -1; 3374 memState[ING_VLAN_RANGEm].index_max = -1; 3375 memState[ING_L3_NEXT_HOPm].index_max = -1; 3376 memState[PORT_CBL_TABLEm].index_max = -1; 3377 memState[TRUNK_CBL_TABLEm].index_max = -1; 3378 memState[IPV6_PROXY_ENABLE_TABLEm].index_max = -1; 3379 memState[EGR_ERSPANm].index_max = -1; 3380 memState[EGR_IM_MTP_INDEXm].index_max = -1; 3381 memState[EGR_EM_MTP_INDEXm].index_max = -1; 3382 memState[EGR_VLAN_TAG_ACTION_PROFILEm].index_max = -1; 3383 } 3384 } 3385 3386 #define L2_OVERFLOW_TABLE_DEPTH 2 3387 STATIC int 3388 _soc_scorpion_l2_overflow_entry_get(int unit, l2x_entry_t *l2x_entry, int *count) 3389 { 3390 int i=0, rv=0; 3391 uint32 entry_valid=0; 3392 3393 /* Read all entries in L2_ENTRY_OVERFLOWm */ 3394 (*count) = 0; 3395 for (i = 0; i < L2_OVERFLOW_TABLE_DEPTH; i++) { 3396 rv = READ_L2_ENTRY_OVERFLOWm(unit, COPYNO_ALL, i, &(l2x_entry[i])); 3397 if (SOC_FAILURE(rv)) { 3398 LOG_ERROR(BSL_LS_SOC_L2, (BSL_META_U(unit, 3399 "Error reading L2_ENTRY_OVERFLOW, index %d, %s\n"), 3400 i, soc_errmsg(rv))); 3401 return (rv); 3402 } 3403 soc_L2Xm_field_get(unit, &(l2x_entry[i]), VALIDf, &entry_valid); 3404 if (entry_valid) { 3405 (*count)++; 3406 } 3407 } 3408 return SOC_E_NONE; 3409 } 3410 3411 STATIC int 3412 _soc_scorpion_l2_overflow_disable(int unit) 3413 { 3414 SOC_IF_ERROR_RETURN 3415 (soc_reg_field32_modify(unit, L2_LEARN_CONTROLr, REG_PORT_ANY, 3416 OVERFLOW_BUCKET_ENABLEf, 0)); 3417 /* Mark as inactive */ 3418 SOC_CONTROL_LOCK(unit); 3419 SOC_CONTROL(unit)->l2_overflow_active = FALSE; 3420 SOC_CONTROL_UNLOCK(unit); 3421 soc_intr_disable(unit, IRQ_CHIP_FUNC_0); 3422 return SOC_E_NONE; 3423 } 3424 3425 STATIC int 3426 _soc_scorpion_l2_overflow_enable(int unit) 3427 { 3428 SOC_IF_ERROR_RETURN 3429 (soc_reg_field32_modify(unit, L2_LEARN_CONTROLr, REG_PORT_ANY, 3430 OVERFLOW_BUCKET_ENABLEf, 1)); 3431 /* Mark as active */ 3432 SOC_CONTROL_LOCK(unit); 3433 SOC_CONTROL(unit)->l2_overflow_active = TRUE; 3434 SOC_CONTROL_UNLOCK(unit); 3435 /* Enable interrupt */ 3436 soc_intr_enable(unit, IRQ_CHIP_FUNC_0); 3437 return SOC_E_NONE; 3438 } 3439 3440 STATIC int 3441 _soc_scorpion_l2_overflow_fill(int unit, uint8 zeros_or_ones) 3442 { 3443 l2x_entry_t entry; 3444 int i; 3445 3446 if (zeros_or_ones) { 3447 sal_memset(&entry, 0xffffffff, sizeof(entry)); 3448 for (i = 0; i < L2_OVERFLOW_TABLE_DEPTH; i++) { 3449 SOC_IF_ERROR_RETURN 3450 (WRITE_L2_ENTRY_OVERFLOWm(unit, COPYNO_ALL, i, &entry)); 3451 } 3452 } else { 3453 SOC_IF_ERROR_RETURN 3454 (soc_mem_clear(unit, L2_ENTRY_OVERFLOWm, COPYNO_ALL, FALSE)); 3455 } 3456 return SOC_E_NONE; 3457 } 3458 3459 int 3460 soc_scorpion_l2_overflow_start(int unit) 3461 { 3462 if (!SOC_CONTROL(unit)->l2_overflow_enable) { 3463 return SOC_E_NONE; 3464 } 3465 if (SOC_CONTROL(unit)->l2_overflow_active) { 3466 return SOC_E_NONE; 3467 } 3468 SOC_IF_ERROR_RETURN(_soc_scorpion_l2_overflow_fill(unit, 0)); 3469 SOC_IF_ERROR_RETURN(_soc_scorpion_l2_overflow_enable(unit)); 3470 return SOC_E_NONE; 3471 } 3472 3473 int 3474 soc_scorpion_l2_overflow_stop(int unit) 3475 { 3476 if (!SOC_CONTROL(unit)->l2_overflow_enable) { 3477 return SOC_E_NONE; 3478 } 3479 SOC_IF_ERROR_RETURN(_soc_scorpion_l2_overflow_fill(unit, 1)); 3480 SOC_IF_ERROR_RETURN(_soc_scorpion_l2_overflow_disable(unit)); 3481 return SOC_E_NONE; 3482 } 3483 3484 void 3485 soc_scorpion_l2_overflow_interrupt_handler(void *unit_vp, void *d1, void *d2, 3486 void *d3, void *d4) 3487 { 3488 l2x_entry_t entry[L2_OVERFLOW_TABLE_DEPTH]; 3489 int count = 0, i; 3490 int unit = PTR_TO_INT(unit_vp); 3491 3492 if (!SOC_CONTROL(unit)->l2_overflow_active) { 3493 LOG_ERROR(BSL_LS_SOC_L2, (BSL_META_U(unit, \ 3494 "Received L2 overflow event with no app handler\n"))); 3495 } 3496 3497 if (_soc_scorpion_l2_overflow_disable(unit)) { 3498 return; 3499 } 3500 3501 /* Read Oerflow entries */ 3502 sal_memset(entry, 0, sizeof(entry)); 3503 if (_soc_scorpion_l2_overflow_entry_get(unit, entry, &count)) { 3504 return; 3505 } 3506 if (count > L2_OVERFLOW_TABLE_DEPTH) { 3507 LOG_ERROR(BSL_LS_SOC_L2, (BSL_META_U(unit, \ 3508 "Overflow entry count more than overflow table depth\n"))); 3509 return; 3510 } 3511 3512 /* Callback L2 handler with Overflow entries */ 3513 for (i = 0; i < count; i++) { 3514 soc_l2x_callback(unit, SOC_L2X_ENTRY_OVERFLOW, NULL, &entry[i]); 3515 } 3516 3517 /* Restart Overflow processing */ 3518 soc_scorpion_l2_overflow_start(unit); 3519 } 3520 #endif /* BCM_SCORPION_SUPPORT */ 3521 3522 #endif /* BCM_BRADLEY_SUPPORT */