trident.c (478224B)
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: trident.c 8 * Purpose: 9 * Requires: 10 */ 11 12 13 #include <shared/bsl.h> 14 15 #include <sal/core/boot.h> 16 #include <shared/bsl.h> 17 #include <soc/trident.h> 18 #include <soc/bradley.h> 19 #include <soc/drv.h> 20 #include <soc/error.h> 21 #include <soc/debug.h> 22 #include <soc/mem.h> 23 #include <soc/hash.h> 24 #include <sal/appl/config.h> 25 #include <soc/soc_ser_log.h> 26 27 #ifdef BCM_TRIDENT_SUPPORT 28 29 typedef enum { 30 _SOC_PARITY_TYPE_NONE, 31 _SOC_PARITY_TYPE_GENERIC, 32 _SOC_PARITY_TYPE_PARITY, 33 _SOC_PARITY_TYPE_ECC, 34 _SOC_PARITY_TYPE_HASH, 35 _SOC_PARITY_TYPE_EDATABUF, 36 _SOC_PARITY_TYPE_COUNTER, 37 _SOC_PARITY_TYPE_XLPORT, 38 _SOC_PARITY_TYPE_MMU_THDO, 39 _SOC_PARITY_TYPE_START_ERR, 40 _SOC_PARITY_TYPE_MMU_WRED, 41 _SOC_PARITY_TYPE_MMU_THDI, 42 _SOC_PARITY_TYPE_MMU_MTRO, 43 _SOC_PARITY_TYPE_MMU_ES, 44 _SOC_PARITY_TYPE_MMU_IPMC, 45 _SOC_PARITY_TYPE_MMU_VLAN, 46 _SOC_PARITY_TYPE_SER, 47 _SOC_PARITY_TYPE_MMU_AGING, 48 _SOC_PARITY_TYPE_MMU_CTR 49 } _soc_trident_parity_info_type_t; 50 51 typedef struct _soc_trident_parity_reg_s { 52 soc_reg_t reg; 53 char *mem_str; 54 } _soc_trident_parity_reg_t; 55 56 typedef struct _soc_trident_parity_mmu_bit_s { 57 uint32 bit_pos; 58 soc_mem_t mem; 59 } _soc_trident_parity_mmu_bit_t; 60 61 typedef struct _soc_trident_parity_info_s { 62 _soc_trident_parity_info_type_t type; 63 struct _soc_trident_parity_info_s *info; 64 int id; 65 soc_field_t group_reg_enable_field; 66 soc_field_t group_reg_status_field; 67 soc_mem_t mem; 68 char *mem_str; 69 soc_reg_t enable_reg; 70 soc_field_t enable_field; 71 soc_reg_t intr_status_reg; 72 _soc_trident_parity_reg_t *intr_status_reg_list; 73 soc_reg_t nack_status_reg; 74 _soc_trident_parity_reg_t *nack_status_reg_list; 75 } _soc_trident_parity_info_t; 76 77 typedef struct _soc_trident_parity_route_block_s { 78 uint32 cmic_bit; 79 soc_block_t blocktype; 80 int pipe; 81 soc_reg_t enable_reg; 82 soc_reg_t status_reg; 83 _soc_trident_parity_info_t *info; 84 } _soc_trident_parity_route_block_t; 85 86 STATIC _soc_trident_parity_reg_t _soc_trident_egr_vlan_xlate_intr_reg[] = { 87 { EGR_VLAN_XLATE_PARITY_STATUS_INTR_0r, NULL }, 88 { EGR_VLAN_XLATE_PARITY_STATUS_INTR_1r, NULL } }; 89 STATIC _soc_trident_parity_reg_t _soc_trident_egr_vlan_xlate_nack_reg[] = { 90 { EGR_VLAN_XLATE_PARITY_STATUS_NACK_0r, NULL }, 91 { EGR_VLAN_XLATE_PARITY_STATUS_NACK_1r, NULL } }; 92 STATIC _soc_trident_parity_reg_t _soc_trident_vlan_xlate_intr_reg[] = { 93 { VLAN_XLATE_PARITY_STATUS_INTR_0r, NULL }, 94 { VLAN_XLATE_PARITY_STATUS_INTR_1r, NULL } }; 95 STATIC _soc_trident_parity_reg_t _soc_trident_vlan_xlate_nack_reg[] = { 96 { VLAN_XLATE_PARITY_STATUS_NACK_0r, NULL }, 97 { VLAN_XLATE_PARITY_STATUS_NACK_1r, NULL } }; 98 STATIC _soc_trident_parity_reg_t _soc_trident_mpls_entry_intr_reg[] = { 99 { MPLS_ENTRY_PARITY_STATUS_INTR_0r, NULL }, 100 { MPLS_ENTRY_PARITY_STATUS_INTR_1r, NULL } }; 101 STATIC _soc_trident_parity_reg_t _soc_trident_mpls_entry_nack_reg[] = { 102 { MPLS_ENTRY_PARITY_STATUS_NACK_0r, NULL }, 103 { MPLS_ENTRY_PARITY_STATUS_NACK_1r, NULL } }; 104 STATIC _soc_trident_parity_reg_t _soc_trident_l3_entry_only_intr_reg[] = { 105 { L3_ENTRY_PARITY_STATUS_INTR_0r, NULL }, 106 { L3_ENTRY_PARITY_STATUS_INTR_1r, NULL } }; 107 STATIC _soc_trident_parity_reg_t _soc_trident_l3_entry_only_nack_reg[] = { 108 { L3_ENTRY_PARITY_STATUS_NACK_0r, NULL }, 109 { L3_ENTRY_PARITY_STATUS_NACK_1r, NULL } }; 110 STATIC _soc_trident_parity_reg_t _soc_trident_l2_entry_only_intr_reg[] = { 111 { L2_ENTRY_PARITY_STATUS_INTR_0r, NULL }, 112 { L2_ENTRY_PARITY_STATUS_INTR_1r, NULL } }; 113 STATIC _soc_trident_parity_reg_t _soc_trident_l2_entry_only_nack_reg[] = { 114 { L2_ENTRY_PARITY_STATUS_NACK_0r, NULL }, 115 { L2_ENTRY_PARITY_STATUS_NACK_1r, NULL } }; 116 STATIC _soc_trident_parity_reg_t _soc_trident_pg5_fifo_intr_reg[] = { 117 { PORT_GROUP5_XLP0_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP0 BOD FIFO" }, 118 { PORT_GROUP5_XLP0_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP0 CTRL FIFO" }, 119 { PORT_GROUP5_XLP1_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP1 BOD FIFO" }, 120 { PORT_GROUP5_XLP1_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP1 CTRL FIFO" }, 121 { PORT_GROUP5_XLP2_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP2 BOD FIFO" }, 122 { PORT_GROUP5_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP2 CTRL FIFO" }, 123 { PORT_GROUP5_XLP3_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP3 BOD FIFO" }, 124 { PORT_GROUP5_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP3 CTRL FIFO" }, 125 { PORT_GROUP5_XLP4_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP4 BOD FIFO" }, 126 { PORT_GROUP5_XLP4_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP4 CTRL FIFO" }, 127 { INVALIDr } }; 128 STATIC _soc_trident_parity_reg_t _soc_trident_pg4_fifo_intr_reg[] = { 129 { PORT_GROUP4_XLP0_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP0 BOD FIFO" }, 130 { PORT_GROUP4_XLP0_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP0 CTRL FIFO" }, 131 { PORT_GROUP4_XLP1_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP1 BOD FIFO" }, 132 { PORT_GROUP4_XLP1_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP1 CTRL FIFO" }, 133 { PORT_GROUP4_XLP2_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP2 BOD FIFO" }, 134 { PORT_GROUP4_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP2 CTRL FIFO" }, 135 { PORT_GROUP4_XLP3_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP3 BOD FIFO" }, 136 { PORT_GROUP4_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP3 CTRL FIFO" }, 137 { INVALIDr } }; 138 139 STATIC _soc_trident_parity_info_t _soc_trident_xlport_parity_info[] = { 140 { _SOC_PARITY_TYPE_ECC, NULL, 0, 141 TXFIFO_MEM_ERRf, 142 TXFIFO_MEM_ERRf, 143 INVALIDm, "TX FIFO", 144 INVALIDr, INVALIDf, 145 XLPORT_TXFIFO_MEM_ECC_STATUSr, NULL, 146 INVALIDr, NULL }, 147 { _SOC_PARITY_TYPE_ECC, NULL, 0, 148 MIB_TSC_MEM0_ERRf, 149 MIB_TSC_MEM0_ERRf, 150 INVALIDm, "TX MIB MEM0", 151 INVALIDr, INVALIDf, 152 XLPORT_MIB_TSC_MEM0_ECC_STATUSr, NULL, 153 INVALIDr, NULL }, 154 { _SOC_PARITY_TYPE_ECC, NULL, 0, 155 MIB_TSC_MEM1_ERRf, 156 MIB_TSC_MEM1_ERRf, 157 INVALIDm, "TX MIB MEM1", 158 INVALIDr, INVALIDf, 159 XLPORT_MIB_TSC_MEM1_ECC_STATUSr, NULL, 160 INVALIDr, NULL }, 161 { _SOC_PARITY_TYPE_ECC, NULL, 0, 162 MIB_TSC_MEM2_ERRf, 163 MIB_TSC_MEM2_ERRf, 164 INVALIDm, "TX MIB MEM2", 165 INVALIDr, INVALIDf, 166 XLPORT_MIB_TSC_MEM2_ECC_STATUSr, NULL, 167 INVALIDr, NULL }, 168 { _SOC_PARITY_TYPE_ECC, NULL, 0, 169 MIB_TSC_MEM3_ERRf, 170 MIB_TSC_MEM3_ERRf, 171 INVALIDm, "TX MIB MEM3", 172 INVALIDr, INVALIDf, 173 XLPORT_MIB_TSC_MEM3_ECC_STATUSr, NULL, 174 INVALIDr, NULL }, 175 { _SOC_PARITY_TYPE_ECC, NULL, 0, 176 MIB_RSC_MEM0_ERRf, 177 MIB_RSC_MEM0_ERRf, 178 INVALIDm, "RX MIB MEM0", 179 INVALIDr, INVALIDf, 180 XLPORT_MIB_RSC_MEM0_ECC_STATUSr, NULL, 181 INVALIDr, NULL }, 182 { _SOC_PARITY_TYPE_ECC, NULL, 0, 183 MIB_RSC_MEM1_ERRf, 184 MIB_RSC_MEM1_ERRf, 185 INVALIDm, "RX MIB MEM1", 186 INVALIDr, INVALIDf, 187 XLPORT_MIB_RSC_MEM1_ECC_STATUSr, NULL, 188 INVALIDr, NULL }, 189 { _SOC_PARITY_TYPE_ECC, NULL, 0, 190 MIB_RSC_MEM2_ERRf, 191 MIB_RSC_MEM2_ERRf, 192 INVALIDm, "RX MIB MEM2", 193 INVALIDr, INVALIDf, 194 XLPORT_MIB_RSC_MEM2_ECC_STATUSr, NULL, 195 INVALIDr, NULL }, 196 { _SOC_PARITY_TYPE_ECC, NULL, 0, 197 MIB_RSC_MEM3_ERRf, 198 MIB_RSC_MEM3_ERRf, 199 INVALIDm, "RX MIB MEM3", 200 INVALIDr, INVALIDf, 201 XLPORT_MIB_RSC_MEM3_ECC_STATUSr, NULL, 202 INVALIDr, NULL }, 203 { _SOC_PARITY_TYPE_ECC, NULL, 0, 204 MIB_RSC_MEM4_ERRf, 205 MIB_RSC_MEM4_ERRf, 206 INVALIDm, "RX MIB MEM4", 207 INVALIDr, INVALIDf, 208 XLPORT_MIB_RSC_MEM4_ECC_STATUSr, NULL, 209 INVALIDr, NULL }, 210 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 211 }; 212 213 STATIC _soc_trident_parity_info_t _soc_trident_xlport1_parity_info[] = { 214 { _SOC_PARITY_TYPE_ECC, NULL, 0, 215 TXFIFO_MEM_ENf, 216 TXFIFO_MEM_ENf, 217 INVALIDm, "TX FIFO", 218 INVALIDr, INVALIDf, 219 INVALIDr, NULL, 220 INVALIDr, NULL }, 221 { _SOC_PARITY_TYPE_ECC, NULL, 0, 222 MIB_TSC_MEM_ENf, 223 MIB_TSC_MEM_ENf, 224 INVALIDm, "TX FIFO", 225 INVALIDr, INVALIDf, 226 INVALIDr, NULL, 227 INVALIDr, NULL }, 228 { _SOC_PARITY_TYPE_ECC, NULL, 0, 229 MIB_RSC_MEM_ENf, 230 MIB_RSC_MEM_ENf, 231 INVALIDm, "TX FIFO", 232 INVALIDr, INVALIDf, 233 INVALIDr, NULL, 234 INVALIDr, NULL }, 235 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 236 }; 237 238 STATIC _soc_trident_parity_info_t _soc_trident_mmu_parity_info[] = { 239 { _SOC_PARITY_TYPE_MMU_AGING, NULL, 0, 240 AGING_CTR_PAR_ERR_ENf, 241 AGING_CTR_PAR_ERRf, 242 MMU_AGING_CTRm, NULL, 243 INVALIDr, INVALIDf, 244 INVALIDr, NULL, 245 INVALIDr, NULL }, 246 { _SOC_PARITY_TYPE_MMU_AGING, NULL, 0, 247 AGING_EXP_PAR_ERR_ENf, 248 AGING_EXP_PAR_ERRf, 249 MMU_AGING_EXPm, NULL, 250 INVALIDr, INVALIDf, 251 INVALIDr, NULL, 252 INVALIDr, NULL }, 253 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 254 CCP_PAR_ERR_ENf, 255 CCP_PAR_ERRf, 256 INVALIDm, "MMU CCP", 257 INVALIDr, INVALIDf, 258 INVALIDr, NULL, 259 INVALIDr, NULL }, 260 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 261 CFAP_PAR_ERR_ENf, 262 CFAP_PAR_ERRf, 263 INVALIDm, "MMU CFAP", 264 INVALIDr, INVALIDf, 265 INVALIDr, NULL, 266 INVALIDr, NULL }, 267 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 268 CFAP_MEM_FAIL_ENf, 269 CFAP_MEM_FAILf, 270 INVALIDm, "MMU CFAP FAIL", 271 INVALIDr, INVALIDf, 272 INVALIDr, NULL, 273 INVALIDr, NULL }, 274 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 275 DEQ_MPB_ERR_ENf, 276 DEQ_MPB_ERRf, 277 INVALIDm, "MMU DEQ MPB", 278 MEM_FAIL_INT_ENr, DEQ_MPB_ERR_ENf, 279 INVALIDr, NULL, 280 INVALIDr, NULL }, 281 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 282 DEQ_PKTHDR_ERR_ENf, 283 DEQ_PKTHDR_ERRf, 284 INVALIDm, "MMU DEQ PKTHDR", 285 INVALIDr, INVALIDf, 286 INVALIDr, NULL, 287 INVALIDr, NULL }, 288 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 289 DEQ_NOT_IP_ERR_ENf, 290 DEQ_NOT_IP_ERRf, 291 INVALIDm, "MMU DEQ NOT IP", 292 INVALIDr, INVALIDf, 293 INVALIDr, NULL, 294 INVALIDr, NULL }, 295 { _SOC_PARITY_TYPE_MMU_CTR, NULL, 0, 296 CTR_UC_CNT_ENf, 297 CTR_UC_CNTf, 298 MMU_CTR_UC_DROP_MEMm, NULL, 299 INVALIDr, INVALIDf, 300 INVALIDr, NULL, 301 INVALIDr, NULL }, 302 { _SOC_PARITY_TYPE_START_ERR, NULL, 0, 303 START_BY_START_ERR_ENf, 304 START_BY_START_ERRf, 305 INVALIDm, "MMU START BY START", 306 INVALIDr, INVALIDf, 307 INVALIDr, NULL, 308 INVALIDr, NULL }, 309 { _SOC_PARITY_TYPE_MMU_CTR, NULL, 0, 310 CTR_MC_CNT_ENf, 311 CTR_MC_CNTf, 312 MMU_CTR_MC_DROP_MEMm, NULL, 313 INVALIDr, INVALIDf, 314 INVALIDr, NULL, 315 INVALIDr, NULL }, 316 { _SOC_PARITY_TYPE_MMU_CTR, NULL, 0, 317 CTR_COLOR_CNT_ERR_ENf, 318 CTR_COLOR_CNT_ERRf, 319 MMU_CTR_COLOR_DROP_MEMm, NULL, 320 INVALIDr, INVALIDf, 321 INVALIDr, NULL, 322 INVALIDr, NULL }, 323 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 324 TOQ0_UCQ_RP_PAR_ERR_ENf, 325 TOQ0_UCQ_RP_PAR_ERRf, 326 INVALIDm, "MMU UCQ RP", 327 INVALIDr, INVALIDf, 328 INVALIDr, NULL, 329 INVALIDr, NULL }, 330 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 331 TOQ0_UCQ_WP_PAR_ERR_ENf, 332 TOQ0_UCQ_WP_PAR_ERRf, 333 INVALIDm, "MMU UCQ WP", 334 INVALIDr, INVALIDf, 335 INVALIDr, NULL, 336 INVALIDr, NULL }, 337 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 338 TOQ0_PKTLINK_PAR_ERR_ENf, 339 TOQ0_PKTLINK_PAR_ERRf, 340 INVALIDm, "MMU PKTLINK", 341 INVALIDr, INVALIDf, 342 INVALIDr, NULL, 343 INVALIDr, NULL }, 344 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 345 TOQ0_CELLLINK_PAR_ERR_ENf, 346 TOQ0_CELLLINK_PAR_ERRf, 347 INVALIDm, "MMU CELLLINK", 348 INVALIDr, INVALIDf, 349 INVALIDr, NULL, 350 INVALIDr, NULL }, 351 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 352 TOQ0_CPQLINK_PAR_ERR_ENf, 353 TOQ0_CPQLINK_PAR_ERRf, 354 INVALIDm, "MMU CPQLINK", 355 INVALIDr, INVALIDf, 356 INVALIDr, NULL, 357 INVALIDr, NULL }, 358 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 359 TOQ0_IPMC_MC_FIFO_PAR_ERR_ENf, 360 TOQ0_IPMC_MC_FIFO_PAR_ERRf, 361 INVALIDm, "MMU IPMC MC FIFO", 362 INVALIDr, INVALIDf, 363 INVALIDr, NULL, 364 INVALIDr, NULL }, 365 { _SOC_PARITY_TYPE_MMU_IPMC, NULL, 0, 366 TOQ0_IPMC_TBL_PAR_ERR_ENf, 367 TOQ0_IPMC_TBL_PAR_ERRf, 368 INVALIDm, "MMU IPMC TBLI", 369 INVALIDr, INVALIDf, 370 INVALIDr, NULL, 371 INVALIDr, NULL }, 372 { _SOC_PARITY_TYPE_MMU_VLAN, NULL, 0, 373 TOQ0_VLAN_TBL_PAR_ERR_ENf, 374 TOQ0_VLAN_TBL_PAR_ERRf, 375 INVALIDm, "MMU VLAN TBL", 376 INVALIDr, INVALIDf, 377 INVALIDr, NULL, 378 INVALIDr, NULL }, 379 { _SOC_PARITY_TYPE_MMU_MTRO, NULL, 0, 380 MTRO_PAR_ERR_ENf, 381 MTRO_PAR_ERRf, 382 INVALIDm, "MMU MTRO PAR", 383 INVALIDr, INVALIDf, 384 INVALIDr, NULL, 385 INVALIDr, NULL }, 386 { _SOC_PARITY_TYPE_MMU_WRED, NULL, 0, 387 WRED_PAR_ERR_ENf, 388 WRED_PAR_ERRf, 389 INVALIDm, "MMU WRED", 390 INVALIDr, INVALIDf, 391 INVALIDr, NULL, 392 INVALIDr, NULL }, 393 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 394 OVQ_PAR_ERR_ENf, 395 OVQ_PAR_ERRf, 396 INVALIDm, "MMU OVQ", 397 INVALIDr, INVALIDf, 398 INVALIDr, NULL, 399 INVALIDr, NULL }, 400 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 401 PQE_PAR_ERR_ENf, 402 PQE_PAR_ERRf, 403 INVALIDm, "MMU PQE PAR", 404 INVALIDr, INVALIDf, 405 INVALIDr, NULL, 406 INVALIDr, NULL }, 407 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 408 QCN_PAR_ERR_ENf, 409 QCN_PAR_ERRf, 410 INVALIDm, "MMU QCN PAR", 411 INVALIDr, INVALIDf, 412 INVALIDr, NULL, 413 INVALIDr, NULL }, 414 { _SOC_PARITY_TYPE_MMU_THDO, NULL, 0, 415 THDO_PAR_ERR_ENf, 416 THDO_PAR_ERRf, 417 INVALIDm, "MMU THDO", 418 INVALIDr, INVALIDf, 419 INVALIDr, NULL, 420 INVALIDr, NULL }, 421 { _SOC_PARITY_TYPE_MMU_THDI, NULL, 0, 422 THDI_PAR_ERR_ENf, 423 THDI_PAR_ERRf, 424 INVALIDm, "MMU THDI", 425 INVALIDr, INVALIDf, 426 INVALIDr, NULL, 427 INVALIDr, NULL }, 428 { _SOC_PARITY_TYPE_MMU_ES, NULL, 0, 429 ES_PAR_ERR_ENf, 430 ES_PAR_ERRf, 431 INVALIDm, "MMU ES", 432 INVALIDr, INVALIDf, 433 INVALIDr, NULL, 434 INVALIDr, NULL }, 435 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 436 }; 437 438 STATIC _soc_trident_parity_info_t _soc_trident_ep0_parity_info[] = { 439 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 440 EGR_NHOP_PAR_ERRf, 441 EGR_NHOP_PAR_ERRf, 442 EGR_L3_NEXT_HOPm, NULL, 443 EGR_EL3_ECC_PARITY_CONTROLr, EGR_L3_NEXT_HOP_PARITY_ENf, 444 EGR_L3_NEXT_HOP_PARITY_STATUS_INTRr, NULL, 445 EGR_L3_NEXT_HOP_PARITY_STATUS_NACKr, NULL }, 446 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 447 EGR_L3_INTF_PAR_ERRf, 448 EGR_L3_INTF_PAR_ERRf, 449 EGR_L3_INTFm, NULL, 450 EGR_EL3_ECC_PARITY_CONTROLr, EGR_L3_INTF_PARITY_ENf, 451 EGR_L3_INTF_PARITY_STATUS_INTRr, NULL, 452 EGR_L3_INTF_PARITY_STATUS_NACKr, NULL }, 453 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 454 EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PAR_ERRf, 455 EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PAR_ERRf, 456 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, NULL, 457 EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_ENf, 458 EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_STATUS_INTRr, NULL, 459 EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_STATUS_NACKr, NULL }, 460 /* The parity enable scheme does not work for EGR_VLAN table */ 461 /*{ _SOC_PARITY_TYPE_PARITY, NULL, 0, 462 EGR_VLAN_PAR_ERRf, 463 EGR_VLAN_PAR_ERRf, 464 EGR_VLANm, NULL, 465 EGR_VLAN_PARITY_CONTROLr, EGR_VLAN_PARITY_ENf, 466 EGR_VLAN_PARITY_STATUS_INTRr, NULL, 467 EGR_VLAN_PARITY_STATUS_NACKr, NULL },*/ 468 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 469 EGR_VLAN_STG_PAR_ERRf, 470 EGR_VLAN_STG_PAR_ERRf, 471 EGR_VLAN_STGm, NULL, 472 EGR_VLAN_PARITY_CONTROLr, EGR_VLAN_STG_PARITY_ENf, 473 EGR_VLAN_STG_PARITY_STATUS_INTRr, NULL, 474 EGR_VLAN_STG_PARITY_STATUS_NACKr, NULL }, 475 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 476 EGR_IP_TUNNEL_PAR_ERRf, 477 EGR_IP_TUNNEL_PAR_ERRf, 478 EGR_IP_TUNNELm, NULL, 479 EGR_VLAN_PARITY_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf, 480 EGR_IP_TUNNEL_PARITY_STATUS_INTRr, NULL, 481 EGR_IP_TUNNEL_PARITY_STATUS_NACKr, NULL }, 482 { _SOC_PARITY_TYPE_HASH, NULL, 0, 483 EGR_VLAN_XLATE_PAR_ERRf, 484 EGR_VLAN_XLATE_PAR_ERRf, 485 EGR_VLAN_XLATEm, NULL, 486 EGR_VLAN_PARITY_CONTROLr, EGR_VLAN_XLATE_PARITY_ENf, 487 INVALIDr, _soc_trident_egr_vlan_xlate_intr_reg, 488 INVALIDr, _soc_trident_egr_vlan_xlate_nack_reg }, 489 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 490 EGR_FRAGMENT_ID_TABLE_PAR_ERRf, 491 EGR_FRAGMENT_ID_TABLE_PAR_ERRf, 492 EGR_FRAGMENT_ID_TABLEm, NULL, 493 EGR_VLAN_PARITY_CONTROLr, EGR_FRAGMENT_ID_TABLE_PARITY_ENf, 494 EGR_FRAGMENT_ID_TABLE_PARITY_STATUS_INTRr, NULL, 495 EGR_FRAGMENT_ID_TABLE_PARITY_STATUS_NACKr, NULL }, 496 { _SOC_PARITY_TYPE_ECC, NULL, 0, 497 EGR_INITBUF_ECC_ERRf, 498 EGR_INITBUF_ECC_ERRf, 499 INVALIDm, "EGR_INITBUF", 500 EGR_EHCPM_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf, 501 EGR_INITBUF_ECC_STATUS_INTRr, NULL, 502 INVALIDr, NULL }, 503 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 504 EGR_PORT_PAR_ERRf, 505 EGR_PORT_PAR_ERRf, 506 EGR_PORTm, NULL, 507 EGR_EL3_ECC_PARITY_CONTROLr, EGR_PORT_PARITY_ENf, 508 EGR_PORT_PARITY_STATUS_INTRr, NULL, 509 EGR_PORT_PARITY_STATUS_NACKr, NULL }, 510 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 511 EGR_GPP_ATTRIBUTES_PAR_ERRf, 512 EGR_GPP_ATTRIBUTES_PAR_ERRf, 513 EGR_GPP_ATTRIBUTESm, NULL, 514 EGR_VLAN_PARITY_CONTROLr, EGR_GPP_ATTRIBUTES_PARITY_ENf, 515 EGR_GPP_ATTRIBUTES_PARITY_STATUS_INTRr, NULL, 516 EGR_GPP_ATTRIBUTES_PARITY_STATUS_NACKr, NULL }, 517 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 518 EGR_MOD_MAP_TABLE_PAR_ERRf, 519 EGR_MOD_MAP_TABLE_PAR_ERRf, 520 EGR_MOD_MAP_TABLEm, NULL, 521 EGR_EHCPM_ECC_PARITY_CONTROLr, MOD_MAP_PARITY_ENf, 522 EGR_MOD_MAP_PARITY_STATUS_INTRr, NULL, 523 EGR_MOD_MAP_PARITY_STATUS_NACKr, NULL }, 524 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 525 EGR_MAC_DA_PROFILE_PAR_ERRf, 526 EGR_MAC_DA_PROFILE_PAR_ERRf, 527 EGR_MAC_DA_PROFILEm, NULL, 528 EGR_EL3_ECC_PARITY_CONTROLr, EGR_MAC_DA_PROFILE_PARITY_ENf, 529 EGR_MAC_DA_PROFILE_PARITY_STATUS_INTRr, NULL, 530 EGR_MAC_DA_PROFILE_PARITY_STATUS_NACKr, NULL }, 531 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 532 EGR_DVP_ATTRIBUTE_PAR_ERRf, 533 EGR_DVP_ATTRIBUTE_PAR_ERRf, 534 EGR_DVP_ATTRIBUTEm, NULL, 535 EGR_EL3_ECC_PARITY_CONTROLr, EGR_DVP_ATTRIBUTE_PARITY_ENf, 536 EGR_DVP_ATTRIBUTE_PARITY_STATUS_INTRr, NULL, 537 EGR_DVP_ATTRIBUTE_PARITY_STATUS_NACKr, NULL }, 538 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 539 EGR_VFI_PAR_ERRf, 540 EGR_VFI_PAR_ERRf, 541 EGR_VFIm, NULL, 542 EGR_EL3_ECC_PARITY_CONTROLr, EGR_VFI_PARITY_ENf, 543 EGR_VFI_PARITY_STATUS_INTRr, NULL, 544 EGR_VFI_PARITY_STATUS_NACKr, NULL }, 545 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 546 EGR_IPMC_PAR_ERRf, 547 EGR_IPMC_PAR_ERRf, 548 EGR_IPMCm, NULL, 549 EGR_EL3_ECC_PARITY_CONTROLr, EGR_IPMC_PARITY_ENf, 550 EGR_IPMC_PARITY_STATUS_INTRr, NULL, 551 EGR_IPMC_PARITY_STATUS_NACKr, NULL }, 552 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 553 EGR_MPLS_EXP_MAPPING_2_PAR_ERRf, 554 EGR_MPLS_EXP_MAPPING_2_PAR_ERRf, 555 EGR_MPLS_EXP_MAPPING_2m, NULL, 556 EGR_VLAN_PARITY_CONTROLr, EGR_MPLS_EXP_MAPPING_2_PARITY_ENf, 557 EGR_MPLS_EXP_MAPPING_2_PARITY_STATUS_INTRr, NULL, 558 EGR_MPLS_EXP_MAPPING_2_PARITY_STATUS_NACKr, NULL }, 559 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 560 EGR_MPLS_PRI_MAPPING_PAR_ERRf, 561 EGR_MPLS_PRI_MAPPING_PAR_ERRf, 562 EGR_MPLS_PRI_MAPPINGm, NULL, 563 EGR_VLAN_PARITY_CONTROLr, EGR_MPLS_PRI_MAPPING_PARITY_ENf, 564 EGR_MPLS_PRI_MAPPING_PARITY_STATUS_INTRr, NULL, 565 EGR_MPLS_PRI_MAPPING_PARITY_STATUS_NACKr, NULL }, 566 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 567 EGR_PRI_CNG_MAP_PAR_ERRf, 568 EGR_PRI_CNG_MAP_PAR_ERRf, 569 EGR_PRI_CNG_MAPm, NULL, 570 EGR_VLAN_PARITY_CONTROLr, EGR_PRI_CNG_MAP_PARITY_ENf, 571 EGR_PRI_CNG_MAP_PARITY_STATUS_INTRr, NULL, 572 EGR_PRI_CNG_MAP_PARITY_STATUS_NACKr, NULL }, 573 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 574 EGR_DSCP_TABLE_PAR_ERRf, 575 EGR_DSCP_TABLE_PAR_ERRf, 576 EGR_DSCP_TABLEm, NULL, 577 EGR_VLAN_PARITY_CONTROLr, EGR_DSCP_TABLE_PARITY_ENf, 578 EGR_DSCP_TABLE_PARITY_STATUS_INTRr, NULL, 579 EGR_DSCP_TABLE_PARITY_STATUS_NACKr, NULL }, 580 { _SOC_PARITY_TYPE_ECC, NULL, 0, 581 EGR_MPB_ECC_ERRf, 582 EGR_MPB_ECC_ERRf, 583 INVALIDm, "EGR_MPB", 584 EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf, 585 EGR_MPB_ECC_STATUS_INTRr, NULL, 586 INVALIDr, NULL }, 587 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 588 EGR_MAP_MH_PAR_ERRf, 589 EGR_MAP_MH_PAR_ERRf, 590 EGR_MAP_MHm, NULL, 591 EGR_EL3_ECC_PARITY_CONTROLr, EGR_MAP_MH_PARITY_ENf, 592 EGR_MAP_MH_PARITY_STATUS_INTRr, NULL, 593 EGR_MAP_MH_PARITY_STATUS_NACKr, NULL }, 594 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 595 EGR_VLAN_CONTROL_1_PAR_ERRf, 596 EGR_VLAN_CONTROL_1_PAR_ERRf, 597 INVALIDm, "EGR_VLAN_CONTROL_1", 598 EGR_EL3_ECC_PARITY_CONTROLr, EGR_VLAN_CONTROL_1_PARITY_ENf, 599 EGR_VLAN_CONTROL_1_PARITY_STATUS_INTRr, NULL, 600 EGR_VLAN_CONTROL_1_PARITY_STATUS_NACKr, NULL }, 601 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 602 EGR_IPMC_CFG2_PAR_ERRf, 603 EGR_IPMC_CFG2_PAR_ERRf, 604 INVALIDm, "EGR_IPMC_CFG2", 605 EGR_EL3_ECC_PARITY_CONTROLr, EGR_IPMC_CFG2_PARITY_ENf, 606 EGR_IPMC_CFG2_PARITY_STATUS_INTRr, NULL, 607 EGR_IPMC_CFG2_PARITY_STATUS_NACKr, NULL }, 608 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 609 EGR_GPP_ATTRIBUTES_MODBASE_PAR_ERRf, 610 EGR_GPP_ATTRIBUTES_MODBASE_PAR_ERRf, 611 EGR_GPP_ATTRIBUTES_MODBASEm, NULL, 612 EGR_VLAN_PARITY_CONTROLr, EGR_GPP_ATTRIBUTES_MODBASE_PARITY_ENf, 613 EGR_GPP_ATTRIBUTES_MODBASE_PARITY_STATUS_INTRr, NULL, 614 EGR_GPP_ATTRIBUTES_MODBASE_PARITY_STATUS_NACKr, NULL }, 615 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 616 EGR_MPLS_EXP_MAPPING_1_PAR_ERRf, 617 EGR_MPLS_EXP_MAPPING_1_PAR_ERRf, 618 EGR_MPLS_EXP_MAPPING_1m, NULL, 619 EGR_VLAN_PARITY_CONTROLr, EGR_MPLS_EXP_MAPPING_1_PARITY_ENf, 620 EGR_MPLS_EXP_MAPPING_1_PARITY_STATUS_INTRr, NULL, 621 EGR_MPLS_EXP_MAPPING_1_PARITY_STATUS_NACKr, NULL }, 622 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 623 }; 624 625 STATIC _soc_trident_parity_info_t _soc_trident_ep1_parity_info[] = { 626 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 627 CM_PAR_ERRf, 628 CM_PAR_ERRf, 629 INVALIDm, "EP_EDATABUF_CM_MEM", 630 EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf, 631 EGR_CM_BUFFER_STATUS_INTRr, NULL, 632 INVALIDr, NULL }, 633 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 634 XLP0_PAR_ERRf, 635 XLP0_PAR_ERRf, 636 INVALIDm, "EP_EDATABUF_XLP0_MEM", 637 EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf, 638 EGR_XLP0_BUFFER_STATUS_INTRr, NULL, 639 INVALIDr, NULL }, 640 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 641 XLP1_PAR_ERRf, 642 XLP1_PAR_ERRf, 643 INVALIDm, "EP_EDATABUF_XLP1_MEM", 644 EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf, 645 EGR_XLP1_BUFFER_STATUS_INTRr, NULL, 646 INVALIDr, NULL }, 647 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 648 XLP2_PAR_ERRf, 649 XLP2_PAR_ERRf, 650 INVALIDm, "EP_EDATABUF_XLP2_MEM", 651 EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf, 652 EGR_XLP2_BUFFER_STATUS_INTRr, NULL, 653 INVALIDr, NULL }, 654 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 655 XLP3_PAR_ERRf, 656 XLP3_PAR_ERRf, 657 INVALIDm, "EP_EDATABUF_XLP3_MEM", 658 EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf, 659 EGR_XLP3_BUFFER_STATUS_INTRr, NULL, 660 INVALIDr, NULL }, 661 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 662 XLP4_PAR_ERRf, 663 XLP4_PAR_ERRf, 664 INVALIDm, "EP_EDATABUF_XLP4_MEM", 665 EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf, 666 EGR_XLP4_BUFFER_STATUS_INTRr, NULL, 667 INVALIDr, NULL }, 668 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 669 XLP5_PAR_ERRf, 670 XLP5_PAR_ERRf, 671 INVALIDm, "EP_EDATABUF_XLP5_MEM", 672 EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf, 673 EGR_XLP5_BUFFER_STATUS_INTRr, NULL, 674 INVALIDr, NULL }, 675 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 676 XLP6_PAR_ERRf, 677 XLP6_PAR_ERRf, 678 INVALIDm, "EP_EDATABUF_XLP6_MEM", 679 EGR_EDATABUF_PARITY_CONTROLr, XLP6_ECC_ENf, 680 EGR_XLP6_BUFFER_STATUS_INTRr, NULL, 681 INVALIDr, NULL }, 682 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 683 XLP7_PAR_ERRf, 684 XLP7_PAR_ERRf, 685 INVALIDm, "EP_EDATABUF_XLP7_MEM", 686 EGR_EDATABUF_PARITY_CONTROLr, XLP7_ECC_ENf, 687 EGR_XLP7_BUFFER_STATUS_INTRr, NULL, 688 INVALIDr, NULL }, 689 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 690 XLP8_PAR_ERRf, 691 XLP8_PAR_ERRf, 692 INVALIDm, "EP_EDATABUF_XLP8_MEM", 693 EGR_EDATABUF_PARITY_CONTROLr, XLP8_ECC_ENf, 694 EGR_XLP8_BUFFER_STATUS_INTRr, NULL, 695 INVALIDr, NULL }, 696 { _SOC_PARITY_TYPE_EDATABUF, NULL, 0, 697 LBP_PAR_ERRf, 698 LBP_PAR_ERRf, 699 INVALIDm, "EP_EDATABUF_LBP_MEM", 700 EGR_EDATABUF_PARITY_CONTROLr, LBP_ECC_ENf, 701 EGR_LBP_BUFFER_STATUS_INTRr, NULL, 702 INVALIDr, NULL }, 703 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 704 EGR_STATS_COUNTER_TABLE_PAR_ERRf, 705 EGR_STATS_COUNTER_TABLE_PAR_ERRf, 706 INVALIDm, "TX Debug Counter", 707 EGR_EDATABUF_PARITY_CONTROLr, STATS_PAR_ENf, 708 EGR_STATS_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL, 709 EGR_STATS_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL }, 710 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 711 EGR_EFP_COUNTER_TABLE_PAR_ERRf, 712 EGR_EFP_COUNTER_TABLE_PAR_ERRf, 713 EFP_COUNTER_TABLEm, NULL, 714 EGR_EDATABUF_PARITY_CONTROLr, EFPCTR_PAR_ENf, 715 EGR_EFP_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL, 716 EGR_EFP_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL }, 717 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 718 EGR_PERQ_XMT_COUNTERS_PAR_ERRf, 719 EGR_PERQ_XMT_COUNTERS_PAR_ERRf, 720 EGR_PERQ_XMT_COUNTERSm, NULL, 721 EGR_EDATABUF_PARITY_CONTROLr, PERQ_PAR_ENf, 722 EGR_PERQ_XMT_COUNTERS_PARITY_STATUS_INTRr, NULL, 723 EGR_PERQ_XMT_COUNTERS_PARITY_STATUS_NACKr, NULL }, 724 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 725 EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PAR_ERRf, 726 EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PAR_ERRf, 727 EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, NULL, 728 EGR_EDATABUF_PARITY_CONTROLr, PERQ_BASE_ADDR_PAR_ENf, 729 EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PARITY_STATUS_INTRr, NULL, 730 EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PARITY_STATUS_NACKr, NULL }, 731 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 732 EGR_VINTF_COUNTER_TABLE_PAR_ERRf, 733 EGR_VINTF_COUNTER_TABLE_PAR_ERRf, 734 EGR_VINTF_COUNTER_TABLEm, NULL, 735 EGR_EDATABUF_PARITY_CONTROLr, VINTFCTR_PAR_ENf, 736 EGR_VINTF_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL, 737 EGR_VINTF_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL }, 738 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 739 EGR_SERVICE_COUNTER_TABLE_PAR_ERRf, 740 EGR_SERVICE_COUNTER_TABLE_PAR_ERRf, 741 EGR_SERVICE_COUNTER_TABLEm, NULL, 742 EGR_EDATABUF_PARITY_CONTROLr, SVCCTR_PAR_ENf, 743 EGR_SERVICE_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL, 744 EGR_SERVICE_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL }, 745 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 746 EGR_EFP_METER_TABLE_PAR_ERRf, 747 EGR_EFP_METER_TABLE_PAR_ERRf, 748 EFP_METER_TABLEm, NULL, 749 EFP_METER_PARITY_CONTROLr, PARITY_ENf, 750 EFP_METER_PARITY_STATUS_INTRr, NULL, 751 EFP_METER_PARITY_STATUS_NACKr, NULL }, 752 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 753 EGR_EFP_POLICY_TABLE_PAR_ERRf, 754 EGR_EFP_POLICY_TABLE_PAR_ERRf, 755 EFP_POLICY_TABLEm, NULL, 756 EFP_POLICY_PARITY_CONTROLr, PARITY_ENf, 757 EFP_POLICY_PARITY_STATUS_INTRr, NULL, 758 EFP_POLICY_PARITY_STATUS_NACKr, NULL }, 759 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 760 EGR_EFP_PW_INIT_COUNTERS_PAR_ERRf, 761 EGR_EFP_PW_INIT_COUNTERS_PAR_ERRf, 762 EGR_PW_INIT_COUNTERSm, NULL, 763 EGR_PW_INIT_COUNTERS_PARITY_CONTROLr, PARITY_ENf, 764 EGR_PW_INIT_COUNTERS_PARITY_STATUS_INTRr, NULL, 765 EGR_PW_INIT_COUNTERS_PARITY_STATUS_NACKr, NULL }, 766 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 767 }; 768 769 STATIC _soc_trident_parity_info_t _soc_trident_ip0_parity_info[] = { 770 /* IP0_INTR_STATUS.PPA_CMD_COMPLETE */ 771 /* IP0_INTR_STATUS.MEM_RESET_COMPLETE */ 772 /* IP0_INTR_STATUS.AGE_CMD_COMPLETE */ 773 /* LMEP is a broadcom propietary memory, and removed from the regs file 774 before release. 775 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 776 LMEP_PAR_ERRf, 777 LMEP_PAR_ERRf, 778 LMEPm, NULL, 779 LMEP_PARITY_CONTROLr, PARITY_ENf, 780 LMEP_PARITY_STATUS_INTRr, NULL, 781 LMEP_PARITY_STATUS_NACKr, NULL },*/ 782 { _SOC_PARITY_TYPE_ECC, NULL, 0, 783 IARB_PKT_ERRf, 784 IARB_PKT_ERRf, 785 INVALIDm, "IARB_PKT_BUF", 786 IARB_PKT_ECC_CONTROLr, ECC_ENf, 787 IARB_PKT_ECC_STATUS_INTRr, NULL, 788 INVALIDr, NULL }, 789 { _SOC_PARITY_TYPE_ECC, NULL, 0, 790 IARB_HDR_ERRf, 791 IARB_HDR_ERRf, 792 INVALIDm, "IARB_PKT_HDR", 793 IARB_HDR_ECC_CONTROLr, ECC_ENf, 794 IARB_HDR_ECC_STATUS_INTRr, NULL, 795 INVALIDr, NULL }, 796 { _SOC_PARITY_TYPE_ECC, NULL, 0, 797 IARB_PIPE_X_LERAN_FIFO_ECC_ERRf, 798 IARB_PIPE_X_LERAN_FIFO_ECC_ERRf, 799 INVALIDm, "IARB_LERAN_FIFO_PIPE_X", 800 IARB_LEARN_FIFO_ECC_CONTROLr, ECC_ENf, 801 IARB_PIPE_X_LERAN_FIFO_ECC_STATUS_INTRr, NULL, 802 INVALIDr, NULL }, 803 { _SOC_PARITY_TYPE_ECC, NULL, 0, 804 IARB_PIPE_Y_LERAN_FIFO_ECC_ERRf, 805 IARB_PIPE_Y_LERAN_FIFO_ECC_ERRf, 806 INVALIDm, "IARB_LERAN_FIFO_PIPE_Y", 807 IARB_LEARN_FIFO_ECC_CONTROLr, ECC_ENf, 808 IARB_PIPE_Y_LERAN_FIFO_ECC_STATUS_INTRr, NULL, 809 INVALIDr, NULL }, 810 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 811 }; 812 813 STATIC _soc_trident_parity_info_t _soc_trident_ip1_parity_info[] = { 814 { _SOC_PARITY_TYPE_HASH, NULL, 0, 815 VXLT_PAR_ERRf, 816 VXLT_PAR_ERRf, 817 VLAN_XLATEm, NULL, 818 VLAN_XLATE_PARITY_CONTROLr, PARITY_ENf, 819 INVALIDr, _soc_trident_vlan_xlate_intr_reg, 820 INVALIDr, _soc_trident_vlan_xlate_nack_reg }, 821 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 822 VFP_POLICY_PAR_ERRf, 823 VFP_POLICY_PAR_ERRf, 824 VFP_POLICY_TABLEm, NULL, 825 VFP_POLICY_PARITY_CONTROLr, PARITY_ENf, 826 VFP_POLICY_PARITY_STATUS_INTRr, NULL, 827 VFP_POLICY_PARITY_STATUS_NACKr, NULL }, 828 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 829 VLAN_PROT_PAR_ERRf, 830 VLAN_PROT_PAR_ERRf, 831 VLAN_PROTOCOL_DATAm, NULL, 832 VLAN_PROT_PARITY_CONTROLr, PARITY_ENf, 833 VLAN_PROT_PARITY_STATUS_INTRr, NULL, 834 VLAN_PROT_PARITY_STATUS_NACKr, NULL }, 835 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 836 VLAN_SUBNET_PAR_ERRf, 837 VLAN_SUBNET_PAR_ERRf, 838 VLAN_SUBNET_DATA_ONLYm, NULL, 839 VLAN_SUBNET_PARITY_CONTROLr, PARITY_ENf, 840 VLAN_SUBNET_PARITY_STATUS_INTRr, NULL, 841 VLAN_SUBNET_PARITY_STATUS_NACKr, NULL }, 842 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 843 CPU_TS_POLICY_PAR_ERRf, 844 CPU_TS_POLICY_PAR_ERRf, 845 CPU_TS_MAPm, NULL, 846 CPU_TS_PARITY_CONTROLr, PARITY_ENf, 847 CPU_TS_PARITY_STATUS_INTRr, NULL, 848 CPU_TS_PARITY_STATUS_NACKr, NULL }, 849 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 850 VLAN_RANGE_PAR_ERRf, 851 VLAN_RANGE_PAR_ERRf, 852 ING_VLAN_RANGEm, NULL, 853 VLAN_RANGE_PARITY_CONTROLr, PARITY_ENf, 854 VLAN_RANGE_PARITY_STATUS_INTRr, NULL, 855 VLAN_RANGE_PARITY_STATUS_NACKr, NULL }, 856 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 857 MOD_MAP_PAR_ERRf, 858 MOD_MAP_PAR_ERRf, 859 ING_MOD_MAP_TABLEm, NULL, 860 MOD_MAP_PARITY_CONTROLr, PARITY_ENf, 861 MOD_MAP_PARITY_STATUS_INTRr, NULL, 862 MOD_MAP_PARITY_STATUS_NACKr, NULL }, 863 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 864 FP_UDF_PAR_ERRf, 865 FP_UDF_PAR_ERRf, 866 FP_UDF_OFFSETm, NULL, 867 FP_UDF_PARITY_CONTROLr, PARITY_ENf, 868 FP_UDF_PARITY_STATUS_INTRr, NULL, 869 FP_UDF_PARITY_STATUS_NACKr, NULL }, 870 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 871 L3_TUNNEL_PAR_ERRf, 872 L3_TUNNEL_PAR_ERRf, 873 L3_TUNNELm, NULL, 874 L3_TUNNEL_PARITY_CONTROLr, PARITY_ENf, 875 L3_TUNNEL_PARITY_STATUS_INTRr, NULL, 876 L3_TUNNEL_PARITY_STATUS_NACKr, NULL }, 877 /* IP1_INTR_STATUS.WLAN_SVP_PAR_ERR */ 878 { _SOC_PARITY_TYPE_ECC, NULL, 0, 879 SRC_TRUNK_PAR_ERRf, 880 SRC_TRUNK_PAR_ERRf, 881 SOURCE_TRUNK_MAP_TABLEm, NULL, 882 SRC_TRUNK_ECC_CONTROLr, ECC_ENf, 883 SRC_TRUNK_ECC_STATUS_INTRr, NULL, 884 SRC_TRUNK_ECC_STATUS_NACKr, NULL }, 885 { _SOC_PARITY_TYPE_ECC, NULL, 0, 886 LPORT_PAR_ERRf, 887 LPORT_PAR_ERRf, 888 LPORT_TABm, NULL, 889 LPORT_ECC_CONTROLr, ECC_ENf, 890 LPORT_ECC_STATUS_INTRr, NULL, 891 LPORT_ECC_STATUS_NACKr, NULL }, 892 { _SOC_PARITY_TYPE_HASH, NULL, 0, 893 MPLS_ENTRY_PAR_ERRf, 894 MPLS_ENTRY_PAR_ERRf, 895 MPLS_ENTRYm, NULL, 896 MPLS_ENTRY_PARITY_CONTROLr, PARITY_ENf, 897 INVALIDr, _soc_trident_mpls_entry_intr_reg, 898 INVALIDr, _soc_trident_mpls_entry_nack_reg }, 899 { _SOC_PARITY_TYPE_ECC, NULL, 0, 900 PORT_TABLE_PAR_ERRf, 901 PORT_TABLE_PAR_ERRf, 902 PORT_TABm, NULL, 903 PORT_TABLE_ECC_CONTROLr, ECC_ENf, 904 PORT_TABLE_ECC_STATUS_INTRr, NULL, 905 PORT_TABLE_ECC_STATUS_NACKr, NULL }, 906 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 907 SYS_CONFIG_PAR_ERRf, 908 SYS_CONFIG_PAR_ERRf, 909 SYSTEM_CONFIG_TABLEm, NULL, 910 SYSTEM_CONFIG_PARITY_CONTROLr, PARITY_ENf, 911 SYSTEM_CONFIG_PARITY_STATUS_INTRr, NULL, 912 SYSTEM_CONFIG_PARITY_STATUS_NACKr, NULL }, 913 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 914 SYSTEM_CONFIG_MODVIEW_PAR_ERRf, 915 SYSTEM_CONFIG_MODVIEW_PAR_ERRf, 916 SYSTEM_CONFIG_TABLE_MODBASEm, NULL, 917 SYSTEM_CONFIG_MODVIEW_PARITY_CONTROLr, PARITY_ENf, 918 SYSTEM_CONFIG_MODVIEW_PARITY_STATUS_INTRr, NULL, 919 SYSTEM_CONFIG_MODVIEW_PARITY_STATUS_NACKr, NULL }, 920 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 921 SOURCE_TRUNK_MAP_MODVIEW_PAR_ERRf, 922 SOURCE_TRUNK_MAP_MODVIEW_PAR_ERRf, 923 SOURCE_TRUNK_MAP_MODBASEm, NULL, 924 SOURCE_TRUNK_MAP_MODVIEW_PARITY_CONTROLr, PARITY_ENf, 925 SOURCE_TRUNK_MAP_MODVIEW_PARITY_STATUS_INTRr, NULL, 926 SOURCE_TRUNK_MAP_MODVIEW_PARITY_STATUS_NACKr, NULL }, 927 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 928 }; 929 930 STATIC _soc_trident_parity_info_t _soc_trident_ip2_parity_info[] = { 931 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 932 NHOP_PAR_ERRf, 933 NHOP_PAR_ERRf, 934 INITIAL_ING_L3_NEXT_HOPm, NULL, 935 INITIAL_ING_L3_NEXT_HOP_PARITY_CONTROLr, PARITY_ENf, 936 INITIAL_ING_L3_NEXT_HOP_PARITY_STATUS_INTRr, NULL, 937 INITIAL_ING_L3_NEXT_HOP_PARITY_STATUS_NACKr, NULL }, 938 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 939 ECMP_GRP_PAR_ERRf, 940 ECMP_GRP_PAR_ERRf, 941 INITIAL_L3_ECMP_GROUPm, NULL, 942 INITIAL_L3_ECMP_GROUP_PARITY_CONTROLr, PARITY_ENf, 943 INITIAL_L3_ECMP_GROUP_PARITY_STATUS_INTRr, NULL, 944 INITIAL_L3_ECMP_GROUP_PARITY_STATUS_NACKr, NULL }, 945 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 946 L3_ECMP_PAR_ERRf, 947 L3_ECMP_PAR_ERRf, 948 INITIAL_L3_ECMPm, NULL, 949 INITIAL_L3_ECMP_PARITY_CONTROLr, PARITY_ENf, 950 INITIAL_L3_ECMP_PARITY_STATUS_INTRr, NULL, 951 INITIAL_L3_ECMP_PARITY_STATUS_NACKr, NULL }, 952 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 953 ING_DVP_PAR_ERRf, 954 ING_DVP_PAR_ERRf, 955 ING_DVP_TABLEm, NULL, 956 ING_DVP_TABLE_PARITY_CONTROLr, PARITY_ENf, 957 ING_DVP_TABLE_PARITY_STATUS_INTRr, NULL, 958 ING_DVP_TABLE_PARITY_STATUS_NACKr, NULL }, 959 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 960 PROT_NHI_PAR_ERRf, 961 PROT_NHI_PAR_ERRf, 962 INITIAL_PROT_NHI_TABLEm, NULL, 963 INITIAL_PROT_NHI_TABLE_PARITY_CONTROLr, PARITY_ENf, 964 INITIAL_PROT_NHI_TABLE_PARITY_STATUS_INTRr, NULL, 965 INITIAL_PROT_NHI_TABLE_PARITY_STATUS_NACKr, NULL }, 966 /* { _SOC_PARITY_TYPE_PARITY, NULL, 0, 967 PORT_CBL_PAR_ERRf, 968 PORT_CBL_PAR_ERRf, 969 PORT_CBL_TABLEm, NULL, 970 PORT_CBL_TABLE_PARITY_CONTROLr, PARITY_ENf, 971 PORT_CBL_TABLE_PARITY_STATUS_INTRr, NULL, 972 PORT_CBL_TABLE_PARITY_STATUS_NACKr, NULL }, */ 973 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 974 PORT_CBL_MODBASE_PAR_ERRf, 975 PORT_CBL_MODBASE_PAR_ERRf, 976 PORT_CBL_TABLE_MODBASEm, NULL, 977 PORT_CBL_TABLE_MODBASE_PARITY_CONTROLr, PARITY_ENf, 978 PORT_CBL_TABLE_MODBASE_PARITY_STATUS_INTRr, NULL, 979 PORT_CBL_TABLE_MODBASE_PARITY_STATUS_NACKr, NULL }, 980 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 981 L3_IPMC_1_PAR_ERRf, 982 L3_IPMC_1_PAR_ERRf, 983 L3_IPMC_1m, NULL, 984 L3_IPMC_1_PARITY_CONTROLr, PARITY_ENf, 985 L3_IPMC_1_PARITY_STATUS_INTRr, NULL, 986 L3_IPMC_1_PARITY_STATUS_NACKr, NULL }, 987 /* { _SOC_PARITY_TYPE_PARITY, NULL, 0, 988 MA_INDEX_PAR_ERRf, 989 MA_INDEX_PAR_ERRf, 990 MA_INDEXm, NULL, 991 MA_INDEX_PARITY_CONTROLr, PARITY_ENf, 992 MA_INDEX_PARITY_STATUS_INTRr, NULL, 993 MA_INDEX_PARITY_STATUS_NACKr, NULL }, 994 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 995 RMEP_PAR_ERRf, 996 RMEP_PAR_ERRf, 997 RMEPm, NULL, 998 RMEP_PARITY_CONTROLr, PARITY_ENf, 999 RMEP_PARITY_STATUS_INTRr, NULL, 1000 RMEP_PARITY_STATUS_NACKr, NULL }, 1001 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1002 MAID_REDUCTION_PAR_ERRf, 1003 MAID_REDUCTION_PAR_ERRf, 1004 MAID_REDUCTIONm, NULL, 1005 MAID_REDUCTION_PARITY_CONTROLr, PARITY_ENf, 1006 MAID_REDUCTION_PARITY_STATUS_INTRr, NULL, 1007 MAID_REDUCTION_PARITY_STATUS_NACKr, NULL }, 1008 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1009 MA_STATE_PAR_ERRf, 1010 MA_STATE_PAR_ERRf, 1011 MA_STATEm, NULL, 1012 MA_STATE_PARITY_CONTROLr, PARITY_ENf, 1013 MA_STATE_PARITY_STATUS_INTRr, NULL, 1014 MA_STATE_PARITY_STATUS_NACKr, NULL },*/ 1015 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1016 VLAN_PAR_ERRf, 1017 VLAN_PAR_ERRf, 1018 VLAN_TABm, NULL, 1019 VLAN_PARITY_CONTROLr, PARITY_ENf, 1020 VLAN_PARITY_STATUS_INTRr, NULL, 1021 VLAN_PARITY_STATUS_NACKr, NULL }, 1022 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1023 SVP_PAR_ERRf, 1024 SVP_PAR_ERRf, 1025 SOURCE_VPm, NULL, 1026 SOURCE_VP_PARITY_CONTROLr, PARITY_ENf, 1027 SOURCE_VP_PARITY_STATUS_INTRr, NULL, 1028 SOURCE_VP_PARITY_STATUS_NACKr, NULL }, 1029 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1030 L3_IIF_PAR_ERRf, 1031 L3_IIF_PAR_ERRf, 1032 L3_IIFm, NULL, 1033 L3_IIF_PARITY_CONTROLr, PARITY_ENf, 1034 L3_IIF_PARITY_STATUS_INTRr, NULL, 1035 L3_IIF_PARITY_STATUS_NACKr, NULL }, 1036 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1037 VFI_INTRf, 1038 VFI_INTRf, 1039 VFIm, NULL, 1040 VFI_PARITY_CONTROLr, PARITY_ENf, 1041 VFI_PARITY_STATUS_INTRr, NULL, 1042 VFI_PARITY_STATUS_NACKr, NULL }, 1043 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1044 VLAN_MPLS_INTRf, 1045 VLAN_MPLS_INTRf, 1046 VLAN_MPLSm, NULL, 1047 VLAN_MPLS_PARITY_CONTROLr, PARITY_ENf, 1048 VLAN_MPLS_PARITY_STATUS_INTRr, NULL, 1049 VLAN_MPLS_PARITY_STATUS_NACKr, NULL }, 1050 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1051 VLAN_STG_INTRf, 1052 VLAN_STG_INTRf, 1053 STG_TABm, NULL, 1054 VLAN_STG_PARITY_CONTROLr, PARITY_ENf, 1055 VLAN_STG_PARITY_STATUS_INTRr, NULL, 1056 VLAN_STG_PARITY_STATUS_NACKr, NULL }, 1057 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1058 VRF_INTRf, 1059 VRF_INTRf, 1060 VRFm, NULL, 1061 VRF_PARITY_CONTROLr, PARITY_ENf, 1062 VRF_PARITY_STATUS_INTRr, NULL, 1063 VRF_PARITY_STATUS_NACKr, NULL }, 1064 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1065 VFI_1_INTRf, 1066 VFI_1_INTRf, 1067 VFI_1m, NULL, 1068 VFI_1_PARITY_CONTROLr, PARITY_ENf, 1069 VFI_1_PARITY_STATUS_INTRr, NULL, 1070 VFI_1_PARITY_STATUS_NACKr, NULL }, 1071 { _SOC_PARITY_TYPE_HASH, NULL, 0, 1072 L3_ENTRY_PAR_ERRf, 1073 L3_ENTRY_PAR_ERRf, 1074 L3_ENTRY_ONLYm, NULL, 1075 L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, 1076 INVALIDr, _soc_trident_l3_entry_only_intr_reg, 1077 INVALIDr, _soc_trident_l3_entry_only_nack_reg }, 1078 { _SOC_PARITY_TYPE_HASH, NULL, 0, 1079 L3_ENTRY_PAR_ERRf, 1080 L3_ENTRY_PAR_ERRf, 1081 L3_ENTRY_IPV4_UNICASTm, NULL, 1082 L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, 1083 INVALIDr, _soc_trident_l3_entry_only_intr_reg, 1084 INVALIDr, _soc_trident_l3_entry_only_nack_reg }, 1085 { _SOC_PARITY_TYPE_HASH, NULL, 0, 1086 L3_ENTRY_PAR_ERRf, 1087 L3_ENTRY_PAR_ERRf, 1088 L3_ENTRY_IPV4_MULTICASTm, NULL, 1089 L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, 1090 INVALIDr, _soc_trident_l3_entry_only_intr_reg, 1091 INVALIDr, _soc_trident_l3_entry_only_nack_reg }, 1092 { _SOC_PARITY_TYPE_HASH, NULL, 0, 1093 L3_ENTRY_PAR_ERRf, 1094 L3_ENTRY_PAR_ERRf, 1095 L3_ENTRY_IPV6_UNICASTm, NULL, 1096 L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, 1097 INVALIDr, _soc_trident_l3_entry_only_intr_reg, 1098 INVALIDr, _soc_trident_l3_entry_only_nack_reg }, 1099 { _SOC_PARITY_TYPE_HASH, NULL, 0, 1100 L3_ENTRY_PAR_ERRf, 1101 L3_ENTRY_PAR_ERRf, 1102 L3_ENTRY_IPV6_MULTICASTm, NULL, 1103 L3_ENTRY_PARITY_CONTROLr, PARITY_ENf, 1104 INVALIDr, _soc_trident_l3_entry_only_intr_reg, 1105 INVALIDr, _soc_trident_l3_entry_only_nack_reg }, 1106 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1107 L3_DEFIP_DATA_PAR_ERRf, 1108 L3_DEFIP_DATA_PAR_ERRf, 1109 L3_DEFIP_DATA_ONLYm, NULL, 1110 L3_DEFIP_DATA_PARITY_CONTROLr, PARITY_ENf, 1111 L3_DEFIP_DATA_PARITY_STATUS_INTRr, NULL, 1112 L3_DEFIP_DATA_PARITY_STATUS_NACKr, NULL }, 1113 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1114 L3_DEFIP_128_DATA_PAR_ERRf, 1115 L3_DEFIP_128_DATA_PAR_ERRf, 1116 L3_DEFIP_128_DATA_ONLYm, NULL, 1117 L3_DEFIP_128_DATA_PARITY_CONTROLr, PARITY_ENf, 1118 L3_DEFIP_128_DATA_PARITY_STATUS_INTRr, NULL, 1119 L3_DEFIP_128_DATA_PARITY_STATUS_NACKr, NULL }, 1120 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1121 TTL_FN_PAR_ERRf, 1122 TTL_FN_PAR_ERRf, 1123 TTL_FNm, NULL, 1124 TTL_FN_PARITY_CONTROLr, PARITY_ENf, 1125 TTL_FN_PARITY_STATUS_INTRr, NULL, 1126 TTL_FN_PARITY_STATUS_NACKr, NULL }, 1127 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1128 TOS_FN_PAR_ERRf, 1129 TOS_FN_PAR_ERRf, 1130 TOS_FNm, NULL, 1131 TOS_FN_PARITY_CONTROLr, PARITY_ENf, 1132 TOS_FN_PARITY_STATUS_INTRr, NULL, 1133 TOS_FN_PARITY_STATUS_NACKr, NULL }, 1134 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1135 ING_PRI_CNG_MAP_PAR_ERRf, 1136 ING_PRI_CNG_MAP_PAR_ERRf, 1137 ING_PRI_CNG_MAPm, NULL, 1138 ING_PRI_CNG_MAP_PARITY_CONTROLr, PARITY_ENf, 1139 ING_PRI_CNG_MAP_PARITY_STATUS_INTRr, NULL, 1140 ING_PRI_CNG_MAP_PARITY_STATUS_NACKr, NULL }, 1141 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1142 ING_UNTAGGED_PHB_PAR_ERRf, 1143 ING_UNTAGGED_PHB_PAR_ERRf, 1144 ING_UNTAGGED_PHBm, NULL, 1145 ING_UNTAGGED_PHB_PARITY_CONTROLr, PARITY_ENf, 1146 ING_UNTAGGED_PHB_PARITY_STATUS_INTRr, NULL, 1147 ING_UNTAGGED_PHB_PARITY_STATUS_NACKr, NULL }, 1148 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1149 DSCP_TABLE_PAR_ERRf, 1150 DSCP_TABLE_PAR_ERRf, 1151 DSCP_TABLEm, NULL, 1152 DSCP_TABLE_PARITY_CONTROLr, PARITY_ENf, 1153 DSCP_TABLE_PARITY_STATUS_INTRr, NULL, 1154 DSCP_TABLE_PARITY_STATUS_NACKr, NULL }, 1155 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1156 FP_FIELD_SEL_PAR_ERRf, 1157 FP_FIELD_SEL_PAR_ERRf, 1158 FP_PORT_FIELD_SELm, NULL, 1159 FP_FIELD_SEL_PARITY_CONTROLr, PARITY_ENf, 1160 FP_FIELD_SEL_PARITY_STATUS_INTRr, NULL, 1161 FP_FIELD_SEL_PARITY_STATUS_NACKr, NULL }, 1162 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1163 }; 1164 1165 STATIC _soc_trident_parity_info_t _soc_trident_ip2_2_parity_info[] = { 1166 /* IP2_INTR_STATUS_2.SOME_RDI_DEFECT_INTR */ 1167 /* IP2_INTR_STATUS_2.SOME_RMEP_CCM_DEFECT_INTR */ 1168 /* IP2_INTR_STATUS_2.ERROR_CCM_DEFECT_INTR */ 1169 /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_PORT_DOWN_INTR */ 1170 /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_PORT_UP_INTR */ 1171 /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_INTERFACE_DOWN_INTR */ 1172 /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_INTERFACE_UP_INTR */ 1173 /* IP2_INTR_STATUS_2.XCON_CCM_DEFECT_INTR */ 1174 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1175 }; 1176 1177 STATIC _soc_trident_parity_info_t _soc_trident_ip3_parity_info[] = { 1178 { _SOC_PARITY_TYPE_HASH, NULL, 0, 1179 L2_ENTRY_PAR_ERRf, 1180 L2_ENTRY_PAR_ERRf, 1181 L2_ENTRY_ONLYm, NULL, 1182 L2_ENTRY_PARITY_CONTROLr, PARITY_ENf, 1183 INVALIDr, _soc_trident_l2_entry_only_intr_reg, 1184 INVALIDr, _soc_trident_l2_entry_only_nack_reg }, 1185 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1186 L2_MOD_FIFO_INTRf, 1187 L2_MOD_FIFO_INTRf, 1188 L2_MOD_FIFOm, NULL, 1189 L2_MOD_FIFO_PARITY_CONTROLr, PARITY_ENf, 1190 L2_MOD_FIFO_PARITY_STATUS_INTRr, NULL, 1191 L2_MOD_FIFO_PARITY_STATUS_NACKr, NULL }, 1192 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1193 L2_USER_ENTRY_DATA_INTRf, 1194 L2_USER_ENTRY_DATA_INTRf, 1195 L2_USER_ENTRY_DATA_ONLYm, NULL, 1196 L2_USER_ENTRY_DATA_PARITY_CONTROLr, PARITY_ENf, 1197 L2_USER_ENTRY_DATA_PARITY_STATUS_INTRr, NULL, 1198 L2_USER_ENTRY_DATA_PARITY_STATUS_NACKr, NULL }, 1199 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1200 }; 1201 1202 STATIC _soc_trident_parity_info_t _soc_trident_ip4_parity_info[] = { 1203 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1204 IFP_POLICY_PAR_ERRf, 1205 IFP_POLICY_PAR_ERRf, 1206 FP_POLICY_TABLEm, NULL, 1207 IFP_POLICY_PARITY_CONTROLr, PARITY_ENf, 1208 IFP_POLICY_PARITY_STATUS_INTRr, NULL, 1209 IFP_POLICY_PARITY_STATUS_NACKr, NULL }, 1210 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1211 IFP_STORM_CONTROL_PAR_ERRf, 1212 IFP_STORM_CONTROL_PAR_ERRf, 1213 FP_STORM_CONTROL_METERSm, NULL, 1214 IFP_STORM_CONTROL_PARITY_CONTROLr, PARITY_ENf, 1215 IFP_STORM_CONTROL_PARITY_STATUS_INTRr, NULL, 1216 IFP_STORM_CONTROL_PARITY_STATUS_NACKr, NULL }, 1217 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1218 IFP_COUNTER_PAR_ERRf, 1219 IFP_COUNTER_PAR_ERRf, 1220 FP_COUNTER_TABLEm, NULL, 1221 IFP_COUNTER_PARITY_CONTROLr, PARITY_ENf, 1222 IFP_COUNTER_PARITY_STATUS_INTRr, NULL, 1223 IFP_COUNTER_PARITY_STATUS_NACKr, NULL }, 1224 /*{ _SOC_PARITY_TYPE_PARITY, NULL, 0, 1225 IFP_METER_PAR_ERRf, 1226 IFP_METER_PAR_ERRf, 1227 FP_METER_TABLEm, NULL, 1228 IFP_METER_PARITY_CONTROLr, PARITY_ENf, 1229 IFP_METER_PARITY_STATUS_INTRr, NULL, 1230 IFP_METER_PARITY_STATUS_NACKr, NULL },*/ 1231 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1232 IFP_ING_DVP_2_PAR_ERRf, 1233 IFP_ING_DVP_2_PAR_ERRf, 1234 ING_DVP_2_TABLEm, NULL, 1235 IFP_ING_DVP_2_PARITY_CONTROLr, PARITY_ENf, 1236 IFP_ING_DVP_2_PARITY_STATUS_INTRr, NULL, 1237 IFP_ING_DVP_2_PARITY_STATUS_NACKr, NULL }, 1238 #if 0 /* Do not enable parity since there is no simple way to clear these 1239 * 2 memory buffers during init */ 1240 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1241 IFP_METER_MUX_DATA_STAGING_PAR_ERRf, 1242 IFP_METER_MUX_DATA_STAGING_PAR_ERRf, 1243 INVALIDm, "IFP_METER_MUX_DATA_STAGING", 1244 IFP_METER_MUX_DATA_STAGING_PARITY_CONTROLr, PARITY_ENf, 1245 IFP_METER_MUX_DATA_STAGING_PARITY_STATUS_INTRr, NULL, 1246 INVALIDr, NULL }, 1247 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1248 IFP_COUNTER_MUX_DATA_STAGING_PAR_ERRf, 1249 IFP_COUNTER_MUX_DATA_STAGING_PAR_ERRf, 1250 INVALIDm, "IFP_COUNTER_MUX_DATA_STAGING", 1251 IFP_COUNTER_MUX_DATA_STAGING_PARITY_CONTROLr, PARITY_ENf, 1252 IFP_COUNTER_MUX_DATA_STAGING_PARITY_STATUS_INTRr, NULL, 1253 INVALIDr, NULL }, 1254 #endif 1255 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1256 IRSEL2_EGR_MASK_MODBASE_PAR_ERRf, 1257 IRSEL2_EGR_MASK_MODBASE_PAR_ERRf, 1258 EGR_MASK_MODBASEm, NULL, 1259 EGR_MASK_MODBASE_PARITY_CONTROLr, PARITY_ENf, 1260 EGR_MASK_MODBASE_PARITY_STATUS_INTRr, NULL, 1261 EGR_MASK_MODBASE_PARITY_STATUS_NACKr, NULL }, 1262 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1263 IRSEL2_ICONTROL_OPCODE_BITMAP_PAR_ERRf, 1264 IRSEL2_ICONTROL_OPCODE_BITMAP_PAR_ERRf, 1265 ICONTROL_OPCODE_BITMAPm, NULL, 1266 ICONTROL_OPCODE_BITMAP_PARITY_CONTROLr, PARITY_ENf, 1267 ICONTROL_OPCODE_BITMAP_PARITY_STATUS_INTRr, NULL, 1268 ICONTROL_OPCODE_BITMAP_PARITY_STATUS_NACKr, NULL }, 1269 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1270 IRSEL2_IFP_REDIRECTION_PROFILE_PAR_ERRf, 1271 IRSEL2_IFP_REDIRECTION_PROFILE_PAR_ERRf, 1272 IFP_REDIRECTION_PROFILEm, NULL, 1273 IFP_REDIRECTION_PROFILE_PARITY_CONTROLr, PARITY_ENf, 1274 IFP_REDIRECTION_PROFILE_PARITY_STATUS_INTRr, NULL, 1275 IFP_REDIRECTION_PROFILE_PARITY_STATUS_NACKr, NULL }, 1276 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1277 IRSEL2_ING_L3_NEXT_HOP_PAR_ERRf, 1278 IRSEL2_ING_L3_NEXT_HOP_PAR_ERRf, 1279 ING_L3_NEXT_HOPm, NULL, 1280 ING_L3_NEXT_HOP_PARITY_CONTROLr, PARITY_ENf, 1281 ING_L3_NEXT_HOP_PARITY_STATUS_INTRr, NULL, 1282 ING_L3_NEXT_HOP_PARITY_STATUS_NACKr, NULL }, 1283 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1284 IRSEL2_L2MC_PAR_ERRf, 1285 IRSEL2_L2MC_PAR_ERRf, 1286 L2MCm, NULL, 1287 L2MC_PARITY_CONTROLr, PARITY_ENf, 1288 L2MC_PARITY_STATUS_INTRr, NULL, 1289 L2MC_PARITY_STATUS_NACKr, NULL }, 1290 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1291 IRSEL2_L3_ECMP_GROUP_PAR_ERRf, 1292 IRSEL2_L3_ECMP_GROUP_PAR_ERRf, 1293 L3_ECMP_COUNTm, NULL, 1294 L3_ECMP_GROUP_PARITY_CONTROLr, PARITY_ENf, 1295 L3_ECMP_GROUP_PARITY_STATUS_INTRr, NULL, 1296 L3_ECMP_GROUP_PARITY_STATUS_NACKr, NULL }, 1297 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1298 IRSEL2_L3_ECMP_PAR_ERRf, 1299 IRSEL2_L3_ECMP_PAR_ERRf, 1300 L3_ECMPm, NULL, 1301 L3_ECMP_PARITY_CONTROLr, PARITY_ENf, 1302 L3_ECMP_PARITY_STATUS_INTRr, NULL, 1303 L3_ECMP_PARITY_STATUS_NACKr, NULL }, 1304 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1305 IRSEL2_L3_IPMC_PAR_ERRf, 1306 IRSEL2_L3_IPMC_PAR_ERRf, 1307 L3_IPMCm, NULL, 1308 L3_IPMC_PARITY_CONTROLr, PARITY_ENf, 1309 L3_IPMC_PARITY_STATUS_INTRr, NULL, 1310 L3_IPMC_PARITY_STATUS_NACKr, NULL }, 1311 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1312 IRSEL2_L3_IPMC_REMAP_PAR_ERRf, 1313 IRSEL2_L3_IPMC_REMAP_PAR_ERRf, 1314 L3_IPMC_REMAPm, NULL, 1315 L3_IPMC_REMAP_PARITY_CONTROLr, PARITY_ENf, 1316 L3_IPMC_REMAP_PARITY_STATUS_INTRr, NULL, 1317 L3_IPMC_REMAP_PARITY_STATUS_NACKr, NULL }, 1318 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1319 IRSEL2_TRUNK_GROUP_PAR_ERRf, 1320 IRSEL2_TRUNK_GROUP_PAR_ERRf, 1321 TRUNK_GROUPm, NULL, 1322 TRUNK_GROUP_PARITY_CONTROLr, PARITY_ENf, 1323 TRUNK_GROUP_PARITY_STATUS_INTRr, NULL, 1324 TRUNK_GROUP_PARITY_STATUS_NACKr, NULL }, 1325 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1326 }; 1327 1328 STATIC _soc_trident_parity_info_t _soc_trident_ip5_parity_info[] = { 1329 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1330 VOQ_COS_MAP_PAR_ERRf, 1331 VOQ_COS_MAP_PAR_ERRf, 1332 VOQ_COS_MAPm, NULL, 1333 VOQ_COS_MAP_PARITY_CONTROLr, PARITY_ENf, 1334 VOQ_COS_MAP_PARITY_STATUS_INTRr, NULL, 1335 VOQ_COS_MAP_PARITY_STATUS_NACKr, NULL }, 1336 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1337 DLB_HGT_FLOWSET_PORT_PAR_ERRf, 1338 DLB_HGT_FLOWSET_PORT_PAR_ERRf, 1339 DLB_HGT_FLOWSET_PORTm, NULL, 1340 DLB_HGT_FLOWSET_PORT_PARITY_CONTROLr, PARITY_ENf, 1341 DLB_HGT_FLOWSET_PORT_PARITY_STATUS_INTRr, NULL, 1342 DLB_HGT_FLOWSET_PORT_PARITY_STATUS_NACKr, NULL }, 1343 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1344 DLB_HGT_FLOWSET_TIMESTAMP_PAR_ERRf, 1345 DLB_HGT_FLOWSET_TIMESTAMP_PAR_ERRf, 1346 DLB_HGT_FLOWSET_TIMESTAMPm, NULL, 1347 DLB_HGT_FLOWSET_TIMESTAMP_PARITY_CONTROLr, PARITY_ENf, 1348 DLB_HGT_FLOWSET_TIMESTAMP_PARITY_STATUS_INTRr, NULL, 1349 DLB_HGT_FLOWSET_TIMESTAMP_PARITY_STATUS_NACKr, NULL }, 1350 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1351 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PAR_ERRf, 1352 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PAR_ERRf, 1353 DLB_HGT_FLOWSET_TIMESTAMP_PAGEm, NULL, 1354 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_CONTROLr, PARITY_ENf, 1355 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_STATUS_INTRr, NULL, 1356 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_STATUS_NACKr, NULL }, 1357 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1358 }; 1359 1360 STATIC _soc_trident_parity_info_t _soc_trident_ip5_1_parity_info[] = { 1361 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1362 EGR_MASK_PAR_ERRf, 1363 EGR_MASK_PAR_ERRf, 1364 EGR_MASKm, NULL, 1365 EGR_MASK_PARITY_CONTROLr, PARITY_ENf, 1366 EGR_MASK_PARITY_STATUS_INTRr, NULL, 1367 EGR_MASK_PARITY_STATUS_NACKr, NULL }, 1368 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1369 TRUNK_BITMAP_PAR_ERRf, 1370 TRUNK_BITMAP_PAR_ERRf, 1371 TRUNK_BITMAPm, NULL, 1372 TRUNK_BITMAP_TABLE_PARITY_CONTROLr, PARITY_ENf, 1373 TRUNK_BITMAP_TABLE_PARITY_STATUS_INTRr, NULL, 1374 TRUNK_BITMAP_TABLE_PARITY_STATUS_NACKr, NULL }, 1375 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1376 NONUCAST_TRUNK_BLOCK_MASK_PAR_ERRf, 1377 NONUCAST_TRUNK_BLOCK_MASK_PAR_ERRf, 1378 NONUCAST_TRUNK_BLOCK_MASKm, NULL, 1379 NONUCAST_TRUNK_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf, 1380 NONUCAST_TRUNK_BLOCK_MASK_PARITY_STATUS_INTRr, NULL, 1381 NONUCAST_TRUNK_BLOCK_MASK_PARITY_STATUS_NACKr, NULL }, 1382 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1383 MAC_BLOCK_TABLE_PAR_ERRf, 1384 MAC_BLOCK_TABLE_PAR_ERRf, 1385 MAC_BLOCKm, NULL, 1386 MAC_BLOCK_TABLE_PARITY_CONTROLr, PARITY_ENf, 1387 MAC_BLOCK_TABLE_PARITY_STATUS_INTRr, NULL, 1388 MAC_BLOCK_TABLE_PARITY_STATUS_NACKr, NULL }, 1389 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1390 MODPORT_MAP_SW_PAR_ERRf, 1391 MODPORT_MAP_SW_PAR_ERRf, 1392 MODPORT_MAP_SWm, NULL, 1393 MODPORT_MAP_SW_PARITY_CONTROLr, PARITY_ENf, 1394 MODPORT_MAP_SW_PARITY_STATUS_INTRr, NULL, 1395 MODPORT_MAP_SW_PARITY_STATUS_NACKr, NULL }, 1396 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1397 MODPORT_MAP_M0_PAR_ERRf, 1398 MODPORT_MAP_M0_PAR_ERRf, 1399 MODPORT_MAP_M0m, NULL, 1400 MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf, 1401 MODPORT_MAP_M0_PARITY_STATUS_INTRr, NULL, 1402 MODPORT_MAP_M0_PARITY_STATUS_NACKr, NULL }, 1403 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1404 MODPORT_MAP_M1_PAR_ERRf, 1405 MODPORT_MAP_M1_PAR_ERRf, 1406 MODPORT_MAP_M1m, NULL, 1407 MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf, 1408 MODPORT_MAP_M1_PARITY_STATUS_INTRr, NULL, 1409 MODPORT_MAP_M1_PARITY_STATUS_NACKr, NULL }, 1410 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1411 MODPORT_MAP_M2_PAR_ERRf, 1412 MODPORT_MAP_M2_PAR_ERRf, 1413 MODPORT_MAP_M2m, NULL, 1414 MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf, 1415 MODPORT_MAP_M2_PARITY_STATUS_INTRr, NULL, 1416 MODPORT_MAP_M2_PARITY_STATUS_NACKr, NULL }, 1417 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1418 MODPORT_MAP_M3_PAR_ERRf, 1419 MODPORT_MAP_M3_PAR_ERRf, 1420 MODPORT_MAP_M3m, NULL, 1421 MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf, 1422 MODPORT_MAP_M3_PARITY_STATUS_INTRr, NULL, 1423 MODPORT_MAP_M3_PARITY_STATUS_NACKr, NULL }, 1424 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1425 SRC_MODID_INGRESS_BLOCK_PAR_ERRf, 1426 SRC_MODID_INGRESS_BLOCK_PAR_ERRf, 1427 SRC_MODID_INGRESS_BLOCKm, NULL, 1428 SRC_MODID_INGRESS_BLOCK_PARITY_CONTROLr, PARITY_ENf, 1429 SRC_MODID_INGRESS_BLOCK_PARITY_STATUS_INTRr, NULL, 1430 SRC_MODID_INGRESS_BLOCK_PARITY_STATUS_NACKr, NULL }, 1431 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1432 SRC_MODID_EGRESS_PAR_ERRf, 1433 SRC_MODID_EGRESS_PAR_ERRf, 1434 SRC_MODID_EGRESSm, NULL, 1435 SRC_MODID_EGRESS_PARITY_CONTROLr, PARITY_ENf, 1436 SRC_MODID_EGRESS_PARITY_STATUS_INTRr, NULL, 1437 SRC_MODID_EGRESS_PARITY_STATUS_NACKr, NULL }, 1438 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1439 ALTERNATE_EMIRROR_BITMAP_PAR_ERRf, 1440 ALTERNATE_EMIRROR_BITMAP_PAR_ERRf, 1441 ALTERNATE_EMIRROR_BITMAPm, NULL, 1442 ALTERNATE_EMIRROR_BITMAP_PARITY_CONTROLr, PARITY_ENf, 1443 ALTERNATE_EMIRROR_BITMAP_PARITY_STATUS_INTRr, NULL, 1444 ALTERNATE_EMIRROR_BITMAP_PARITY_STATUS_NACKr, NULL }, 1445 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1446 PORT_LAG_FAILOVER_SET_PAR_ERRf, 1447 PORT_LAG_FAILOVER_SET_PAR_ERRf, 1448 PORT_LAG_FAILOVER_SETm, NULL, 1449 PORT_LAG_FAILOVER_SET_PARITY_CONTROLr, PARITY_ENf, 1450 PORT_LAG_FAILOVER_SET_PARITY_STATUS_INTRr, NULL, 1451 PORT_LAG_FAILOVER_SET_PARITY_STATUS_NACKr, NULL }, 1452 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1453 VLAN_PROFILE_2_PAR_ERRf, 1454 VLAN_PROFILE_2_PAR_ERRf, 1455 VLAN_PROFILE_2m, NULL, 1456 VLAN_PROFILE_2_PARITY_CONTROLr, PARITY_ENf, 1457 VLAN_PROFILE_2_PARITY_STATUS_INTRr, NULL, 1458 VLAN_PROFILE_2_PARITY_STATUS_NACKr, NULL }, 1459 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1460 L3_MTU_VALUES_PAR_ERRf, 1461 L3_MTU_VALUES_PAR_ERRf, 1462 L3_MTU_VALUESm, NULL, 1463 L3_MTU_VALUES_PARITY_CONTROLr, PARITY_ENf, 1464 L3_MTU_VALUES_PARITY_STATUS_INTRr, NULL, 1465 L3_MTU_VALUES_PARITY_STATUS_NACKr, NULL }, 1466 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1467 ING_PW_TERM_SEQ_NUM_PAR_ERRf, 1468 ING_PW_TERM_SEQ_NUM_PAR_ERRf, 1469 ING_PW_TERM_SEQ_NUMm, NULL, 1470 ING_PW_TERM_SEQ_NUM_PARITY_CONTROLr, PARITY_ENf, 1471 ING_PW_TERM_SEQ_NUM_PARITY_STATUS_INTRr, NULL, 1472 ING_PW_TERM_SEQ_NUM_PARITY_STATUS_NACKr, NULL }, 1473 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1474 ING_SERVICE_COUNTER_TABLE_PAR_ERRf, 1475 ING_SERVICE_COUNTER_TABLE_PAR_ERRf, 1476 ING_SERVICE_COUNTER_TABLEm, NULL, 1477 ING_SERVICE_COUNTER_TABLE_PARITY_CONTROLr, PARITY_ENf, 1478 ING_SERVICE_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL, 1479 ING_SERVICE_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL }, 1480 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1481 ING_VINTF_COUNTER_TABLE_PAR_ERRf, 1482 ING_VINTF_COUNTER_TABLE_PAR_ERRf, 1483 ING_VINTF_COUNTER_TABLEm, NULL, 1484 ING_VINTF_COUNTER_TABLE_PARITY_CONTROLr, PARITY_ENf, 1485 ING_VINTF_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL, 1486 ING_VINTF_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL }, 1487 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1488 VLAN_COS_MAP_PAR_ERRf, 1489 VLAN_COS_MAP_PAR_ERRf, 1490 VLAN_COS_MAPm, NULL, 1491 VLAN_COS_MAP_PARITY_CONTROLr, PARITY_ENf, 1492 VLAN_COS_MAP_PARITY_STATUS_INTRr, NULL, 1493 VLAN_COS_MAP_PARITY_STATUS_NACKr, NULL }, 1494 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1495 E2E_HOL_STATUS_PAR_ERRf, 1496 E2E_HOL_STATUS_PAR_ERRf, 1497 E2E_HOL_STATUSm, NULL, 1498 E2E_HOL_STATUS_PARITY_CONTROLr, PARITY_ENf, 1499 E2E_HOL_STATUS_PARITY_STATUS_INTRr, NULL, 1500 E2E_HOL_STATUS_PARITY_STATUS_NACKr, NULL }, 1501 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1502 E2E_HOL_STATUS_1_PAR_ERRf, 1503 E2E_HOL_STATUS_1_PAR_ERRf, 1504 E2E_HOL_STATUS_1m, NULL, 1505 E2E_HOL_STATUS_1_PARITY_CONTROLr, PARITY_ENf, 1506 E2E_HOL_STATUS_1_PARITY_STATUS_INTRr, NULL, 1507 E2E_HOL_STATUS_1_PARITY_STATUS_NACKr, NULL }, 1508 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1509 UNKNOWN_UCAST_BLOCK_MASK_PAR_ERRf, 1510 UNKNOWN_UCAST_BLOCK_MASK_PAR_ERRf, 1511 UNKNOWN_UCAST_BLOCK_MASKm, NULL, 1512 UNKNOWN_UCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf, 1513 UNKNOWN_UCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL, 1514 UNKNOWN_UCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL }, 1515 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1516 UNKNOWN_MCAST_BLOCK_MASK_PAR_ERRf, 1517 UNKNOWN_MCAST_BLOCK_MASK_PAR_ERRf, 1518 UNKNOWN_MCAST_BLOCK_MASKm, NULL, 1519 UNKNOWN_MCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf, 1520 UNKNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL, 1521 UNKNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL }, 1522 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1523 BCAST_BLOCK_MASK_PAR_ERRf, 1524 BCAST_BLOCK_MASK_PAR_ERRf, 1525 BCAST_BLOCK_MASKm, NULL, 1526 BCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf, 1527 BCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL, 1528 BCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL }, 1529 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1530 KNOWN_MCAST_BLOCK_MASK_PAR_ERRf, 1531 KNOWN_MCAST_BLOCK_MASK_PAR_ERRf, 1532 KNOWN_MCAST_BLOCK_MASKm, NULL, 1533 KNOWN_MCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf, 1534 KNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL, 1535 KNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL }, 1536 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1537 ING_EGRMSKBMAP_PAR_ERRf, 1538 ING_EGRMSKBMAP_PAR_ERRf, 1539 ING_EGRMSKBMAPm, NULL, 1540 ING_EGRMSKBMAP_PARITY_CONTROLr, PARITY_ENf, 1541 ING_EGRMSKBMAP_PARITY_STATUS_INTRr, NULL, 1542 ING_EGRMSKBMAP_PARITY_STATUS_NACKr, NULL }, 1543 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1544 LOCAL_SW_DISABLE_DEFAULT_PBM_PAR_ERRf, 1545 LOCAL_SW_DISABLE_DEFAULT_PBM_PAR_ERRf, 1546 LOCAL_SW_DISABLE_DEFAULT_PBMm, NULL, 1547 LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_CONTROLr, PARITY_ENf, 1548 LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_STATUS_INTRr, NULL, 1549 LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_STATUS_NACKr, NULL }, 1550 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1551 LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PAR_ERRf, 1552 LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PAR_ERRf, 1553 LOCAL_SW_DISABLE_DEFAULT_PBM_MIRRm, NULL, 1554 LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_CONTROLr, PARITY_ENf, 1555 LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_STATUS_INTRr, NULL, 1556 LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_STATUS_NACKr, NULL }, 1557 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1558 IMIRROR_BITMAP_PAR_ERRf, 1559 IMIRROR_BITMAP_PAR_ERRf, 1560 IMIRROR_BITMAPm, NULL, 1561 IMIRROR_BITMAP_PARITY_CONTROLr, PARITY_ENf, 1562 IMIRROR_BITMAP_PARITY_STATUS_INTRr, NULL, 1563 IMIRROR_BITMAP_PARITY_STATUS_NACKr, NULL }, 1564 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1565 UNKNOWN_HGI_BITMAP_PAR_ERRf, 1566 UNKNOWN_HGI_BITMAP_PAR_ERRf, 1567 UNKNOWN_HGI_BITMAPm, NULL, 1568 UNKNOWN_HGI_BITMAP_PARITY_CONTROLr, PARITY_ENf, 1569 UNKNOWN_HGI_BITMAP_PARITY_STATUS_INTRr, NULL, 1570 UNKNOWN_HGI_BITMAP_PARITY_STATUS_NACKr, NULL }, 1571 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1572 TRUNK_MEMBER_PAR_ERRf, 1573 TRUNK_MEMBER_PAR_ERRf, 1574 TRUNK_MEMBERm, NULL, 1575 TRUNK_MEMBER_PARITY_CONTROLr, PARITY_ENf, 1576 TRUNK_MEMBER_PARITY_STATUS_INTRr, NULL, 1577 TRUNK_MEMBER_PARITY_STATUS_NACKr, NULL }, 1578 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1579 ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PAR_ERRf, 1580 ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PAR_ERRf, 1581 ING_HIGIG_TRUNK_OVERRIDE_PROFILEm, NULL, 1582 ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_CONTROLr, PARITY_ENf, 1583 ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_STATUS_INTRr, NULL, 1584 ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_STATUS_NACKr, NULL }, 1585 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1586 }; 1587 1588 STATIC _soc_trident_parity_info_t _soc_trident_ip5_2_parity_info[] = { 1589 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1590 EMIRROR_CONTROL_PAR_ERRf, 1591 EMIRROR_CONTROL_PAR_ERRf, 1592 EMIRROR_CONTROLm, NULL, 1593 EMIRROR_CONTROL_PARITY_CONTROLr, PARITY_ENf, 1594 EMIRROR_CONTROL_PARITY_STATUS_INTRr, NULL, 1595 EMIRROR_CONTROL_PARITY_STATUS_NACKr, NULL }, 1596 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1597 EMIRROR_CONTROL1_PAR_ERRf, 1598 EMIRROR_CONTROL1_PAR_ERRf, 1599 EMIRROR_CONTROL1m, NULL, 1600 EMIRROR_CONTROL1_PARITY_CONTROLr, PARITY_ENf, 1601 EMIRROR_CONTROL1_PARITY_STATUS_INTRr, NULL, 1602 EMIRROR_CONTROL1_PARITY_STATUS_NACKr, NULL }, 1603 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1604 EMIRROR_CONTROL2_PAR_ERRf, 1605 EMIRROR_CONTROL2_PAR_ERRf, 1606 EMIRROR_CONTROL2m, NULL, 1607 EMIRROR_CONTROL2_PARITY_CONTROLr, PARITY_ENf, 1608 EMIRROR_CONTROL2_PARITY_STATUS_INTRr, NULL, 1609 EMIRROR_CONTROL2_PARITY_STATUS_NACKr, NULL }, 1610 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1611 EMIRROR_CONTROL3_PAR_ERRf, 1612 EMIRROR_CONTROL3_PAR_ERRf, 1613 EMIRROR_CONTROL3m, NULL, 1614 EMIRROR_CONTROL3_PARITY_CONTROLr, PARITY_ENf, 1615 EMIRROR_CONTROL3_PARITY_STATUS_INTRr, NULL, 1616 EMIRROR_CONTROL3_PARITY_STATUS_NACKr, NULL }, 1617 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1618 SW2_EOP_BUFFER_A_PAR_ERRf, 1619 SW2_EOP_BUFFER_A_PAR_ERRf, 1620 INVALIDm, "SW2_EOP_BUFFER_A", 1621 SW2_EOP_BUFFER_A_PARITY_CONTROLr, PARITY_ENf, 1622 SW2_EOP_BUFFER_A_PARITY_STATUS_INTRr, NULL, 1623 INVALIDr, NULL }, 1624 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1625 SW2_EOP_BUFFER_B_PAR_ERRf, 1626 SW2_EOP_BUFFER_B_PAR_ERRf, 1627 INVALIDm, "SW2_EOP_BUFFER_B", 1628 SW2_EOP_BUFFER_B_PARITY_CONTROLr, PARITY_ENf, 1629 SW2_EOP_BUFFER_B_PARITY_STATUS_INTRr, NULL, 1630 INVALIDr, NULL }, 1631 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1632 SW2_EOP_BUFFER_C_PAR_ERRf, 1633 SW2_EOP_BUFFER_C_PAR_ERRf, 1634 INVALIDm, "SW2_EOP_BUFFER_C", 1635 SW2_EOP_BUFFER_C_PARITY_CONTROLr, PARITY_ENf, 1636 SW2_EOP_BUFFER_C_PARITY_STATUS_INTRr, NULL, 1637 INVALIDr, NULL }, 1638 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1639 IP_COUNTERS_PAR_ERRf, 1640 IP_COUNTERS_PAR_ERRf, 1641 INVALIDm, "Ingress Pipeline Counter", 1642 IP_COUNTERS_PARITY_CONTROLr, PARITY_ENf, 1643 IP_COUNTERS_PARITY_STATUS_INTRr, NULL, 1644 IP_COUNTERS_PARITY_STATUS_NACKr, NULL }, 1645 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1646 RDBGC_MEM_INST0_PAR_ERRf, 1647 RDBGC_MEM_INST0_PAR_ERRf, 1648 INVALIDm, "Ingress Pipeline Counter", 1649 RDBGC_MEM_INST0_PARITY_CONTROLr, PARITY_ENf, 1650 RDBGC_MEM_INST0_PARITY_STATUS_INTRr, NULL, 1651 RDBGC_MEM_INST0_PARITY_STATUS_NACKr, NULL }, 1652 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1653 RDBGC_MEM_INST1_PAR_ERRf, 1654 RDBGC_MEM_INST1_PAR_ERRf, 1655 INVALIDm, "RX Debug Counter", 1656 RDBGC_MEM_INST1_PARITY_CONTROLr, PARITY_ENf, 1657 RDBGC_MEM_INST1_PARITY_STATUS_INTRr, NULL, 1658 RDBGC_MEM_INST1_PARITY_STATUS_NACKr, NULL }, 1659 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1660 RDBGC_MEM_INST2_PAR_ERRf, 1661 RDBGC_MEM_INST2_PAR_ERRf, 1662 INVALIDm, "RX Debug Counter", 1663 RDBGC_MEM_INST2_PARITY_CONTROLr, PARITY_ENf, 1664 RDBGC_MEM_INST2_PARITY_STATUS_INTRr, NULL, 1665 RDBGC_MEM_INST2_PARITY_STATUS_NACKr, NULL }, 1666 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1667 HG_COUNTERS_PAR_ERRf, 1668 HG_COUNTERS_PAR_ERRf, 1669 INVALIDm, "Ingress Pipeline HG Counter", 1670 HG_COUNTERS_PARITY_CONTROLr, PARITY_ENf, 1671 HG_COUNTERS_PARITY_STATUS_INTRr, NULL, 1672 HG_COUNTERS_PARITY_STATUS_NACKr, NULL }, 1673 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1674 NIV_ERROR_DROP_PAR_ERRf, 1675 NIV_ERROR_DROP_PAR_ERRf, 1676 INVALIDm, "ING_NIV_RX_FRAMES_ERROR_DROP", 1677 NIV_ERROR_DROP_PARITY_CONTROLr, PARITY_ENf, 1678 NIV_ERROR_DROP_PARITY_STATUS_INTRr, NULL, 1679 NIV_ERROR_DROP_PARITY_STATUS_NACKr, NULL }, 1680 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1681 NIV_FORWARDING_DROP_PAR_ERRf, 1682 NIV_FORWARDING_DROP_PAR_ERRf, 1683 INVALIDm, "ING_NIV_RX_FRAMES_FORWARDING_DROP", 1684 NIV_FORWARDING_DROP_PARITY_CONTROLr, PARITY_ENf, 1685 NIV_FORWARDING_DROP_PARITY_STATUS_INTRr, NULL, 1686 NIV_FORWARDING_DROP_PARITY_STATUS_NACKr, NULL }, 1687 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1688 NIV_VLAN_TAGGED_PAR_ERRf, 1689 NIV_VLAN_TAGGED_PAR_ERRf, 1690 INVALIDm, "ING_NIV_RX_FRAMES_VLAN_TAGGED", 1691 NIV_VLAN_TAGGED_PARITY_CONTROLr, PARITY_ENf, 1692 NIV_VLAN_TAGGED_PARITY_STATUS_INTRr, NULL, 1693 NIV_VLAN_TAGGED_PARITY_STATUS_NACKr, NULL }, 1694 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1695 TRILL_RX_PKTS_PAR_ERRf, 1696 TRILL_RX_PKTS_PAR_ERRf, 1697 INVALIDm, "ING_TRILL_RX_PKTS", 1698 TRILL_RX_PKTS_PARITY_CONTROLr, PARITY_ENf, 1699 TRILL_RX_PKTS_PARITY_STATUS_INTRr, NULL, 1700 TRILL_RX_PKTS_PARITY_STATUS_NACKr, NULL }, 1701 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1702 TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PAR_ERRf, 1703 TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PAR_ERRf, 1704 INVALIDm, "ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED", 1705 TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_CONTROLr, PARITY_ENf, 1706 TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr, NULL, 1707 TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr, NULL }, 1708 { _SOC_PARITY_TYPE_COUNTER, NULL, 0, 1709 TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PAR_ERRf, 1710 TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PAR_ERRf, 1711 INVALIDm, "ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED", 1712 TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_CONTROLr, PARITY_ENf, 1713 TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr, NULL, 1714 TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr, NULL }, 1715 { _SOC_PARITY_TYPE_PARITY, NULL, 0, 1716 CPB_PAR_ERRf, 1717 CPB_PAR_ERRf, 1718 INVALIDm, "CPB", 1719 CPB_PARITY_CONTROLr, PARITY_ENf, 1720 CPB_PARITY_STATUS_INTRr, NULL, 1721 INVALIDr, NULL }, 1722 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1723 }; 1724 1725 STATIC _soc_trident_parity_info_t _soc_trident_pg5_parity_info[] = { 1726 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 0, 1727 XLP0_PERR_INTRf, 1728 XLP0_PERR_INTRf, 1729 INVALIDm, "XLPORT", 1730 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1731 XLPORT_INTR_STATUSr, NULL, /* group status */ 1732 INVALIDr, NULL }, 1733 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 0, 1734 XLP0_PERR_INTRf, 1735 XLP0_PERR_INTRf, 1736 INVALIDm, "XLPORT", 1737 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1738 INVALIDr, NULL, 1739 INVALIDr, NULL }, 1740 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 1, 1741 XLP1_PERR_INTRf, 1742 XLP1_PERR_INTRf, 1743 INVALIDm, "XLPORT", 1744 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1745 XLPORT_INTR_STATUSr, NULL, /* group status */ 1746 INVALIDr, NULL }, 1747 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 1, 1748 XLP1_PERR_INTRf, 1749 XLP1_PERR_INTRf, 1750 INVALIDm, "XLPORT", 1751 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1752 INVALIDr, NULL, 1753 INVALIDr, NULL }, 1754 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 2, 1755 XLP2_PERR_INTRf, 1756 XLP2_PERR_INTRf, 1757 INVALIDm, "XLPORT", 1758 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1759 XLPORT_INTR_STATUSr, NULL, /* group status */ 1760 INVALIDr, NULL }, 1761 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 2, 1762 XLP2_PERR_INTRf, 1763 XLP2_PERR_INTRf, 1764 INVALIDm, "XLPORT", 1765 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1766 INVALIDr, NULL, 1767 INVALIDr, NULL }, 1768 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 3, 1769 XLP3_PERR_INTRf, 1770 XLP3_PERR_INTRf, 1771 INVALIDm, "XLPORT", 1772 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1773 XLPORT_INTR_STATUSr, NULL, /* group status */ 1774 INVALIDr, NULL }, 1775 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 3, 1776 XLP3_PERR_INTRf, 1777 XLP3_PERR_INTRf, 1778 INVALIDm, "XLPORT", 1779 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1780 INVALIDr, NULL, 1781 INVALIDr, NULL }, 1782 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 4, 1783 XLP4_PERR_INTRf, 1784 XLP4_PERR_INTRf, 1785 INVALIDm, "XLPORT", 1786 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1787 XLPORT_INTR_STATUSr, NULL, /* group status */ 1788 INVALIDr, NULL }, 1789 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 4, 1790 XLP4_PERR_INTRf, 1791 XLP4_PERR_INTRf, 1792 INVALIDm, "XLPORT", 1793 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1794 INVALIDr, NULL, 1795 INVALIDr, NULL }, 1796 { _SOC_PARITY_TYPE_ECC, NULL, 0, 1797 PG5_PERR_INTRf, 1798 PG5_PERR_INTRf, 1799 INVALIDm, "PG5 FIFO", 1800 PORT_GROUP5_BOD_FIFO_ECC_ENABLEr, BOD_FIFO_ECC_ENABLEf, 1801 INVALIDr, _soc_trident_pg5_fifo_intr_reg, 1802 INVALIDr, NULL }, 1803 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1804 }; 1805 1806 STATIC _soc_trident_parity_info_t _soc_trident_pg4_parity_info[] = { 1807 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 5, 1808 XLP0_PERR_INTRf, 1809 XLP0_PERR_INTRf, 1810 INVALIDm, "XLPORT", 1811 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1812 XLPORT_INTR_STATUSr, NULL, /* group status */ 1813 INVALIDr, NULL }, 1814 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 5, 1815 XLP0_PERR_INTRf, 1816 XLP0_PERR_INTRf, 1817 INVALIDm, "XLPORT", 1818 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1819 INVALIDr, NULL, 1820 INVALIDr, NULL }, 1821 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 6, 1822 XLP1_PERR_INTRf, 1823 XLP1_PERR_INTRf, 1824 INVALIDm, "XLPORT", 1825 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1826 XLPORT_INTR_STATUSr, NULL, /* group status */ 1827 INVALIDr, NULL }, 1828 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 6, 1829 XLP1_PERR_INTRf, 1830 XLP1_PERR_INTRf, 1831 INVALIDm, "XLPORT", 1832 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1833 INVALIDr, NULL, 1834 INVALIDr, NULL }, 1835 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 7, 1836 XLP2_PERR_INTRf, 1837 XLP2_PERR_INTRf, 1838 INVALIDm, "XLPORT", 1839 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1840 XLPORT_INTR_STATUSr, NULL, /* group status */ 1841 INVALIDr, NULL }, 1842 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 7, 1843 XLP2_PERR_INTRf, 1844 XLP2_PERR_INTRf, 1845 INVALIDm, "XLPORT", 1846 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1847 INVALIDr, NULL, 1848 INVALIDr, NULL }, 1849 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 8, 1850 XLP3_PERR_INTRf, 1851 XLP3_PERR_INTRf, 1852 INVALIDm, "XLPORT", 1853 XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */ 1854 XLPORT_INTR_STATUSr, NULL, /* group status */ 1855 INVALIDr, NULL }, 1856 { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 8, 1857 XLP3_PERR_INTRf, 1858 XLP3_PERR_INTRf, 1859 INVALIDm, "XLPORT", 1860 XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */ 1861 INVALIDr, NULL, 1862 INVALIDr, NULL }, 1863 { _SOC_PARITY_TYPE_ECC, NULL, 0, 1864 PG4_PERR_INTRf, 1865 PG4_PERR_INTRf, 1866 INVALIDm, "PG4 FIFO", 1867 PORT_GROUP4_BOD_FIFO_ECC_ENABLEr, BOD_FIFO_ECC_ENABLEf, 1868 INVALIDr, _soc_trident_pg4_fifo_intr_reg, 1869 INVALIDr, NULL }, 1870 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 1871 }; 1872 1873 STATIC const 1874 _soc_trident_parity_route_block_t _soc_trident_parity_route_blocks[] = { 1875 { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */ 1876 SOC_BLK_MMU, -1, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, 1877 _soc_trident_mmu_parity_info }, 1878 { 0x00000002, /* X_EP1_TO_CMIC_PERR_INTR */ 1879 SOC_BLK_EPIPE, 0, EGR_INTR0_ENABLEr, EGR_INTR0_STATUSr, 1880 _soc_trident_ep0_parity_info }, 1881 { 0x00000004, /* Y_EP1_TO_CMIC_PERR_INTR */ 1882 SOC_BLK_EPIPE, 1, EGR_INTR0_ENABLEr, EGR_INTR0_STATUSr, 1883 _soc_trident_ep0_parity_info }, 1884 { 0x00000008, /* X_EP2_TO_CMIC_PERR_INTR */ 1885 SOC_BLK_EPIPE, 0, EGR_INTR1_ENABLEr, EGR_INTR1_STATUSr, 1886 _soc_trident_ep1_parity_info }, 1887 { 0x00000010, /* Y_EP2_TO_CMIC_PERR_INTR */ 1888 SOC_BLK_EPIPE, 1, EGR_INTR1_ENABLEr, EGR_INTR1_STATUSr, 1889 _soc_trident_ep1_parity_info }, 1890 { 0x00000020, /* X_IP0_TO_CMIC_PERR_INTR */ 1891 SOC_BLK_IPIPE, 0, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, 1892 _soc_trident_ip0_parity_info }, 1893 { 0x00000040, /* Y_IP0_TO_CMIC_PERR_INTR */ 1894 SOC_BLK_IPIPE, 1, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, 1895 _soc_trident_ip0_parity_info }, 1896 { 0x00000080, /* X_IP1_TO_CMIC_PERR_INTR */ 1897 SOC_BLK_IPIPE, 0, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, 1898 _soc_trident_ip1_parity_info }, 1899 { 0x00000100, /* Y_IP1_TO_CMIC_PERR_INTR */ 1900 SOC_BLK_IPIPE, 1, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, 1901 _soc_trident_ip1_parity_info }, 1902 { 0x00000200, /* X_IP2_TO_CMIC_PERR_INTR */ 1903 SOC_BLK_IPIPE, 0, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, 1904 _soc_trident_ip2_parity_info }, 1905 { 0x00000200, /* X_IP2_TO_CMIC_PERR_INTR */ 1906 SOC_BLK_IPIPE, 0, IP2_INTR_ENABLE_2r, IP2_INTR_STATUS_2r, 1907 _soc_trident_ip2_2_parity_info }, 1908 { 0x00000400, /* Y_IP2_TO_CMIC_PERR_INTR */ 1909 SOC_BLK_IPIPE, 1, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, 1910 _soc_trident_ip2_parity_info }, 1911 { 0x00000400, /* Y_IP2_TO_CMIC_PERR_INTR */ 1912 SOC_BLK_IPIPE, 1, IP2_INTR_ENABLE_2r, IP2_INTR_STATUS_2r, 1913 _soc_trident_ip2_2_parity_info }, 1914 { 0x00000800, /* X_IP3_TO_CMIC_PERR_INTR */ 1915 SOC_BLK_IPIPE, 0, IP3_INTR_ENABLEr, IP3_INTR_STATUSr, 1916 _soc_trident_ip3_parity_info }, 1917 { 0x00001000, /* Y_IP3_TO_CMIC_PERR_INTR */ 1918 SOC_BLK_IPIPE, 1, IP3_INTR_ENABLEr, IP3_INTR_STATUSr, 1919 _soc_trident_ip3_parity_info }, 1920 { 0x00002000, /* X_IP4_TO_CMIC_PERR_INTR */ 1921 SOC_BLK_IPIPE, 0, IP4_INTR_ENABLEr, IP4_INTR_STATUSr, 1922 _soc_trident_ip4_parity_info }, 1923 { 0x00004000, /* Y_IP4_TO_CMIC_PERR_INTR */ 1924 SOC_BLK_IPIPE, 1, IP4_INTR_ENABLEr, IP4_INTR_STATUSr, 1925 _soc_trident_ip4_parity_info }, 1926 { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */ 1927 SOC_BLK_IPIPE, 0, IP5_INTR_ENABLEr, IP5_INTR_STATUSr, 1928 _soc_trident_ip5_parity_info }, 1929 { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */ 1930 SOC_BLK_IPIPE, 0, IP5_INTR_ENABLE_1r, IP5_INTR_STATUS_1r, 1931 _soc_trident_ip5_1_parity_info }, 1932 { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */ 1933 SOC_BLK_IPIPE, 0, IP5_INTR_ENABLE_2r, IP5_INTR_STATUS_2r, 1934 _soc_trident_ip5_2_parity_info }, 1935 { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */ 1936 SOC_BLK_IPIPE, 1, IP5_INTR_ENABLEr, IP5_INTR_STATUSr, 1937 _soc_trident_ip5_parity_info }, 1938 { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */ 1939 SOC_BLK_IPIPE, 1, IP5_INTR_ENABLE_1r, IP5_INTR_STATUS_1r, 1940 _soc_trident_ip5_1_parity_info }, 1941 { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */ 1942 SOC_BLK_IPIPE, 1, IP5_INTR_ENABLE_2r, IP5_INTR_STATUS_2r, 1943 _soc_trident_ip5_2_parity_info }, 1944 /* 0x00020000 PCIE_REPLAY_PERR */ 1945 { 0x00040000, /* PG5_0_TO_CMIC_PERR_INTR */ 1946 SOC_BLK_PORT_GROUP5, 0, PG5_INTR_ENABLEr, PG5_INTR_STATUSr, 1947 _soc_trident_pg5_parity_info }, 1948 { 0x00080000, /* PG5_1_TO_CMIC_PERR_INTR */ 1949 SOC_BLK_PORT_GROUP5, 1, PG5_INTR_ENABLEr, PG5_INTR_STATUSr, 1950 _soc_trident_pg5_parity_info }, 1951 { 0x00100000, /* PG4_0_TO_CMIC_PERR_INTR */ 1952 SOC_BLK_PORT_GROUP4, 0, PG4_INTR_ENABLEr, PG4_INTR_STATUSr, 1953 _soc_trident_pg4_parity_info }, 1954 { 0x00200000, /* PG4_1_TO_CMIC_PERR_INTR */ 1955 SOC_BLK_PORT_GROUP4, 1, PG4_INTR_ENABLEr, PG4_INTR_STATUSr, 1956 _soc_trident_pg4_parity_info }, 1957 { 0 } /* table terminator */ 1958 }; 1959 1960 STATIC soc_ser_functions_t _td_ser_functions; 1961 1962 STATIC void 1963 _soc_mem_parity_info(int unit, int block_info_idx, int pipe, 1964 soc_field_t field_enum, uint32 *minfo) 1965 { 1966 *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) 1967 | ((pipe & 0xff) << SOC_ERROR_PIPE_BP) 1968 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK); 1969 } 1970 1971 #if 0 1972 /* 1973 * This code can be used to spit out a C struct database of all 1974 * reportable memory errors and their associated arg3 values. 1975 * 1976 * This database can be used to maintain statistics on reported memory 1977 * errors on a per-memory basis (versus globally). 1978 * 1979 * To generate a new database, set #if 1 above, and run this code 1980 * from a diagnostic shell command. 1981 * 1982 * This code must remain in this file because the error reporting 1983 * information used to generate arg3 values is local to this file. 1984 */ 1985 void 1986 _soc_trident_print_memories(int unit) 1987 { 1988 const _soc_trident_parity_route_block_t *rb; 1989 _soc_trident_parity_info_t *mi, *mi0; 1990 char prefix[64]; 1991 char *mn; 1992 uint32 id; 1993 int ecc, blk_num, blk; 1994 1995 for (rb = _soc_trident_parity_route_blocks; rb->cmic_bit; rb++) { 1996 for (mi = rb->info; mi->type != _SOC_PARITY_TYPE_NONE; mi++) { 1997 if (mi->type != _SOC_PARITY_TYPE_GENERIC 1998 && mi->intr_status_reg == INVALIDr 1999 && !mi->intr_status_reg_list) { 2000 continue; 2001 } 2002 if (mi->type == _SOC_PARITY_TYPE_XLPORT) { 2003 mi0 = mi->info; 2004 } else { 2005 mi0 = mi; 2006 } 2007 2008 if (mi0->mem_str) { 2009 mn = mi0->mem_str; 2010 } else if (mi0->mem != INVALIDm) { 2011 mn = SOC_MEM_NAME(unit, mi0->mem); 2012 } else { 2013 mn = SOC_FIELD_NAME(unit, mi0->group_reg_status_field); 2014 } 2015 2016 blk = rb->blocktype; 2017 if (mi->type == _SOC_PARITY_TYPE_XLPORT) { 2018 blk_num = mi->id + rb->pipe * 9; 2019 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 2020 if (SOC_BLOCK_INFO(unit, blk).number == blk_num) break; 2021 } 2022 sal_sprintf(prefix, "%s,XLPORT%d", mn, blk_num); 2023 _soc_mem_parity_info(unit, blk, rb->pipe, 2024 mi0->group_reg_status_field, &id); 2025 } else { 2026 if (rb->pipe >= 0) { 2027 sal_sprintf(prefix, "%s,%d", mn, rb->pipe); 2028 } else { 2029 sal_sprintf(prefix, "%s", mn); 2030 } 2031 _soc_mem_parity_info(unit, rb->blocktype, rb->pipe, 2032 mi0->group_reg_status_field, &id); 2033 } 2034 ecc = mi0->type == _SOC_PARITY_TYPE_ECC; 2035 LOG_CLI((BSL_META_U(unit, 2036 " {\"%s\"), %d, 0x%08x},\n", prefix, ecc, id)); 2037 } 2038 } 2039 } 2040 #endif 2041 2042 STATIC int 2043 _soc_trident_parity_reg_set(int unit, int block_info_idx, int pipe, 2044 soc_reg_t reg, uint32 rval) 2045 { 2046 int rv, egress, port; 2047 2048 switch (SOC_BLOCK_INFO(unit, block_info_idx).type) { 2049 case SOC_BLK_IPIPE: 2050 egress = 0; 2051 port = REG_PORT_ANY; 2052 break; 2053 case SOC_BLK_EPIPE: 2054 egress = 1; 2055 port = REG_PORT_ANY; 2056 break; 2057 case SOC_BLK_PORT_GROUP4: 2058 case SOC_BLK_PORT_GROUP5: 2059 egress = -1; 2060 port = pipe; 2061 break; 2062 case SOC_BLK_XLPORT: 2063 egress = -1; 2064 port = SOC_BLOCK_PORT(unit, block_info_idx); 2065 break; 2066 default: 2067 egress = -1; 2068 port = REG_PORT_ANY; 2069 break; 2070 } 2071 2072 if (egress != -1) { 2073 SOC_IF_ERROR_RETURN(soc_trident_pipe_select(unit, egress, pipe)); 2074 } 2075 2076 rv = soc_reg32_set(unit, reg, port, 0, rval); 2077 2078 if (egress != -1) { 2079 (void)soc_trident_pipe_select(unit, egress, 0); 2080 } 2081 2082 return rv; 2083 } 2084 2085 STATIC int 2086 _soc_trident_parity_reg_get(int unit, int block_info_idx, int pipe, 2087 soc_reg_t reg, uint32 *rval) 2088 { 2089 int rv, egress, port; 2090 2091 switch (SOC_BLOCK_INFO(unit, block_info_idx).type) { 2092 case SOC_BLK_IPIPE: 2093 egress = 0; 2094 port = REG_PORT_ANY; 2095 break; 2096 case SOC_BLK_EPIPE: 2097 egress = 1; 2098 port = REG_PORT_ANY; 2099 break; 2100 case SOC_BLK_PORT_GROUP4: 2101 case SOC_BLK_PORT_GROUP5: 2102 egress = -1; 2103 port = pipe; 2104 break; 2105 case SOC_BLK_XLPORT: 2106 egress = -1; 2107 port = SOC_BLOCK_PORT(unit, block_info_idx); 2108 break; 2109 default: 2110 egress = -1; 2111 port = REG_PORT_ANY; 2112 break; 2113 } 2114 2115 if (egress != -1) { 2116 SOC_IF_ERROR_RETURN(soc_trident_pipe_select(unit, egress, pipe)); 2117 } 2118 2119 rv = soc_reg32_get(unit, reg, port, 0, rval); 2120 2121 if (egress != -1) { 2122 (void)soc_trident_pipe_select(unit, egress, 0); 2123 } 2124 2125 return rv; 2126 } 2127 2128 STATIC int 2129 _soc_trident_parity_enable_info(int unit, int block_info_idx, int pipe, 2130 soc_reg_t group_reg, uint32 *group_rval, 2131 const _soc_trident_parity_info_t *info_list, 2132 soc_mem_t mem, int enable); 2133 2134 STATIC int 2135 _soc_trident_parity_enable_xlport(int unit, int pipe, 2136 const _soc_trident_parity_info_t *info, 2137 soc_mem_t mem, int enable) 2138 { 2139 soc_reg_t xlport_reg; 2140 uint32 xlport_rval; 2141 int block_info_idx, inst_num, port; 2142 2143 port = -1; 2144 inst_num = info->id + pipe * 9; 2145 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) { 2146 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) { 2147 port = SOC_BLOCK_PORT(unit, block_info_idx); 2148 break; 2149 } 2150 } 2151 if (port < 0) { 2152 return SOC_E_NONE; 2153 } 2154 2155 xlport_reg = info->enable_reg; 2156 SOC_IF_ERROR_RETURN 2157 (soc_reg32_get(unit, xlport_reg, port, 0, &xlport_rval)); 2158 2159 SOC_IF_ERROR_RETURN 2160 (_soc_trident_parity_enable_info(unit, block_info_idx, pipe, 2161 xlport_reg, &xlport_rval, 2162 info->info, mem, enable)); 2163 2164 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, xlport_reg, port, 0, xlport_rval)); 2165 2166 return SOC_E_NONE; 2167 } 2168 2169 STATIC int 2170 _soc_trident_parity_enable_info(int unit, int block_info_idx, int pipe, 2171 soc_reg_t group_reg, uint32 *group_rval, 2172 const _soc_trident_parity_info_t *info_list, 2173 soc_mem_t mem, 2174 int enable) 2175 { 2176 const _soc_trident_parity_info_t *info; 2177 int info_index, rv, rv1; 2178 soc_reg_t reg; 2179 uint32 rval; 2180 2181 rv = SOC_E_NOT_FOUND; 2182 2183 /* Loop through each info entry in the list */ 2184 for (info_index = 0; ; info_index++) { 2185 info = &info_list[info_index]; 2186 if (info->type == _SOC_PARITY_TYPE_NONE) { 2187 /* End of table */ 2188 break; 2189 } 2190 2191 if (mem != INVALIDm && info->mem != mem) { 2192 continue; 2193 } 2194 2195 rv = SOC_E_NONE; 2196 2197 /* Enable the info entry in the group register */ 2198 soc_reg_field_set(unit, group_reg, group_rval, 2199 info->group_reg_enable_field, enable ? 1 : 0); 2200 2201 /* Handle different parity error reporting style */ 2202 switch (info->type) { 2203 case _SOC_PARITY_TYPE_PARITY: 2204 case _SOC_PARITY_TYPE_ECC: 2205 case _SOC_PARITY_TYPE_HASH: 2206 case _SOC_PARITY_TYPE_EDATABUF: 2207 case _SOC_PARITY_TYPE_COUNTER: 2208 reg = info->enable_reg; 2209 if (!SOC_REG_IS_VALID(unit, reg)) { 2210 break; 2211 } 2212 SOC_IF_ERROR_RETURN 2213 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, 2214 &rval)); 2215 soc_reg_field_set(unit, reg, &rval, info->enable_field, 2216 enable ? 1 : 0); 2217 SOC_IF_ERROR_RETURN 2218 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 2219 rval)); 2220 break; 2221 case _SOC_PARITY_TYPE_XLPORT: 2222 /* One more level of report tree structure */ 2223 rv1 = _soc_trident_parity_enable_xlport(unit, pipe, info, mem, 2224 enable); 2225 if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) { 2226 return rv; 2227 } 2228 break; 2229 case _SOC_PARITY_TYPE_GENERIC: 2230 case _SOC_PARITY_TYPE_MMU_THDO: 2231 case _SOC_PARITY_TYPE_START_ERR: 2232 case _SOC_PARITY_TYPE_MMU_WRED: 2233 case _SOC_PARITY_TYPE_MMU_THDI: 2234 case _SOC_PARITY_TYPE_MMU_MTRO: 2235 case _SOC_PARITY_TYPE_MMU_ES: 2236 case _SOC_PARITY_TYPE_MMU_IPMC: 2237 case _SOC_PARITY_TYPE_MMU_VLAN: 2238 default: 2239 break; 2240 } /* Handle different parity error reporting style */ 2241 if (mem != INVALIDm) { 2242 break; 2243 } 2244 2245 } /* Loop through each info entry in the route block */ 2246 2247 return rv; 2248 } 2249 2250 STATIC int 2251 _soc_trident_parity_enable_all(int unit, int enable) 2252 { 2253 const _soc_trident_parity_route_block_t *route_block; 2254 int route_block_index; 2255 uint32 rval; 2256 uint32 cmic_rval, route_block_rval; 2257 uint32 cmic_bit; 2258 int block_info_idx, inst_num; 2259 int rv; 2260 uint16 dev_id, drv_dev_id; 2261 uint8 rev_id, drv_rev_id; 2262 2263 soc_cm_get_id(unit, &dev_id, &rev_id); 2264 soc_cm_get_id_driver(dev_id, rev_id, &drv_dev_id, &drv_rev_id); 2265 2266 /* Read CMIC enable register */ 2267 /* coverity[result_independent_of_operands] */ 2268 SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, &cmic_rval)); 2269 2270 /* Loop through each place-and-route block entry */ 2271 for (route_block_index = 0; ; route_block_index++) { 2272 route_block = &_soc_trident_parity_route_blocks[route_block_index]; 2273 cmic_bit = route_block->cmic_bit; 2274 if (cmic_bit == 0) { 2275 /* End of table */ 2276 break; 2277 } 2278 /* Enable the route block entry in the CMIC register */ 2279 if (enable) { 2280 cmic_rval |= cmic_bit; 2281 } 2282 2283 if (route_block->blocktype == SOC_BLK_PORT_GROUP4 || 2284 route_block->blocktype == SOC_BLK_PORT_GROUP5) { 2285 inst_num = route_block->pipe; 2286 } else { 2287 inst_num = 0; 2288 } 2289 SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) { 2290 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) { 2291 break; 2292 } 2293 } 2294 2295 SOC_IF_ERROR_RETURN 2296 (_soc_trident_parity_reg_get(unit, block_info_idx, 2297 route_block->pipe, 2298 route_block->enable_reg, 2299 &route_block_rval)); 2300 2301 rv = _soc_trident_parity_enable_info(unit, block_info_idx, 2302 route_block->pipe, 2303 route_block->enable_reg, 2304 &route_block_rval, 2305 route_block->info, INVALIDm, 2306 enable); 2307 if (rv == SOC_E_NOT_FOUND) { 2308 continue; 2309 } else if (SOC_FAILURE(rv)) { 2310 return rv; 2311 } 2312 2313 /* Write per route block parity enable register */ 2314 SOC_IF_ERROR_RETURN 2315 (_soc_trident_parity_reg_set(unit, block_info_idx, 2316 route_block->pipe, 2317 route_block->enable_reg, 2318 route_block_rval)); 2319 } /* Loop through each place-and-route block entry */ 2320 2321 /* Write CMIC enable register */ 2322 /* coverity[result_independent_of_operands] */ 2323 SOC_IF_ERROR_RETURN(WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, cmic_rval)); 2324 2325 /* MMU enables */ 2326 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2327 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 2328 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2329 2330 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 1); 2331 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 1); 2332 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 2333 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2334 2335 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval)); 2336 2337 if (!(drv_rev_id == BCM56840_A0_REV_ID && rev_id == BCM56840_A0_REV_ID)) { 2338 /* Do not serve interrupt for Trident A0 */ 2339 soc_intr_enable(unit, IRQ_MEM_FAIL); 2340 } 2341 2342 return SOC_E_NONE; 2343 } 2344 2345 void 2346 _soc_trident_mem_rename(soc_mem_t *memory) 2347 { 2348 soc_mem_t mem = *memory; 2349 2350 switch(*memory) { 2351 case MY_STATION_TCAMm: 2352 mem = MY_STATION_TCAM_DATA_ONLYm; 2353 break; 2354 2355 /* ep0 */ 2356 case EGR_IP_TUNNEL_IPV6m: 2357 case EGR_IP_TUNNEL_MPLSm: 2358 mem = EGR_IP_TUNNELm; 2359 break; 2360 case EGR_FRAGMENT_ID_TABLE_Xm: 2361 case EGR_FRAGMENT_ID_TABLE_Ym: 2362 mem = EGR_FRAGMENT_ID_TABLEm; 2363 break; 2364 case EGR_VLAN_Xm: 2365 case EGR_VLAN_Ym: 2366 mem = EGR_VLANm; 2367 break; 2368 2369 /* ep1 */ 2370 case EFP_COUNTER_TABLE_Xm: 2371 case EFP_COUNTER_TABLE_Ym: 2372 mem = EFP_COUNTER_TABLEm; 2373 break; 2374 case EGR_PERQ_XMT_COUNTERS_Xm: 2375 case EGR_PERQ_XMT_COUNTERS_Ym: 2376 mem = EGR_PERQ_XMT_COUNTERSm; 2377 break; 2378 case EGR_VINTF_COUNTER_TABLE_Xm: 2379 case EGR_VINTF_COUNTER_TABLE_Ym: 2380 mem = EGR_VINTF_COUNTER_TABLEm; 2381 break; 2382 case EGR_SERVICE_COUNTER_TABLE_Xm: 2383 case EGR_SERVICE_COUNTER_TABLE_Ym: 2384 mem = EGR_SERVICE_COUNTER_TABLEm; 2385 break; 2386 case EFP_METER_TABLE_Xm: 2387 case EFP_METER_TABLE_Ym: 2388 mem = EFP_METER_TABLEm; 2389 break; 2390 case EGR_PW_INIT_COUNTERS_Xm: 2391 case EGR_PW_INIT_COUNTERS_Ym: 2392 mem = EGR_PW_INIT_COUNTERSm; 2393 break; 2394 2395 /* ip0 */ 2396 2397 /* ip1 */ 2398 case VLAN_MACm: 2399 mem = VLAN_XLATEm; 2400 break; 2401 case VLAN_SUBNETm: 2402 mem = VLAN_SUBNET_DATA_ONLYm; 2403 break; 2404 2405 /* ip2 */ 2406 case L3_DEFIPm: 2407 case L3_DEFIP_Xm: 2408 case L3_DEFIP_Ym: 2409 mem = L3_DEFIP_DATA_ONLYm; 2410 break; 2411 case L3_DEFIP_128m: 2412 mem = L3_DEFIP_128_DATA_ONLYm; 2413 break; 2414 2415 /* ip2_2 */ 2416 2417 /* ip3 */ 2418 case L2Xm: 2419 mem = L2_ENTRY_ONLYm; 2420 break; 2421 case L2_USER_ENTRYm: 2422 mem = L2_USER_ENTRY_DATA_ONLYm; 2423 break; 2424 2425 /* ip4 */ 2426 case FP_COUNTER_TABLE_Xm: 2427 case FP_COUNTER_TABLE_Ym: 2428 mem = FP_COUNTER_TABLEm; 2429 break; 2430 2431 /* ip5 */ 2432 case DLB_HGT_FLOWSET_PORT_Xm: 2433 case DLB_HGT_FLOWSET_PORT_Ym: 2434 mem = DLB_HGT_FLOWSET_PORTm; 2435 break; 2436 2437 /* ip5_1 */ 2438 case MODPORT_MAP_MIRRORm: 2439 mem = MODPORT_MAP_M0m; 2440 break; 2441 case ING_PW_TERM_SEQ_NUM_Xm: 2442 case ING_PW_TERM_SEQ_NUM_Ym: 2443 mem = ING_PW_TERM_SEQ_NUMm; 2444 break; 2445 case ING_SERVICE_COUNTER_TABLE_Xm: 2446 case ING_SERVICE_COUNTER_TABLE_Ym: 2447 mem = ING_SERVICE_COUNTER_TABLEm; 2448 break; 2449 case ING_VINTF_COUNTER_TABLE_Xm: 2450 case ING_VINTF_COUNTER_TABLE_Ym: 2451 mem = ING_VINTF_COUNTER_TABLEm; 2452 break; 2453 default: 2454 break; 2455 } 2456 *memory = mem; 2457 } 2458 2459 int 2460 _soc_trident_mem_parity_control(int unit, soc_mem_t mem, int copyno, 2461 int enable) 2462 { 2463 const _soc_trident_parity_route_block_t *route_block; 2464 int route_block_index; 2465 uint32 rval; 2466 uint32 cmic_rval, route_block_rval; 2467 uint32 cmic_bit; 2468 int block_info_idx, inst_num; 2469 int rv = SOC_E_NOT_FOUND; 2470 2471 /* coverity[result_independent_of_operands] */ 2472 SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, &cmic_rval)); 2473 if (cmic_rval == 0) { 2474 return SOC_E_NONE; 2475 } 2476 2477 /* Convert component/aggregate memories to the table for which 2478 * the parity registers correspond. */ 2479 _soc_trident_mem_rename(&mem); 2480 2481 /* Loop through each place-and-route block entry */ 2482 for (route_block_index = 0; ; route_block_index++) { 2483 route_block = &_soc_trident_parity_route_blocks[route_block_index]; 2484 cmic_bit = route_block->cmic_bit; 2485 if (cmic_bit == 0) { 2486 /* End of table */ 2487 break; 2488 } 2489 2490 if (route_block->blocktype == SOC_BLK_PORT_GROUP4 || 2491 route_block->blocktype == SOC_BLK_PORT_GROUP5) { 2492 inst_num = route_block->pipe; 2493 } else { 2494 inst_num = 0; 2495 } 2496 SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) { 2497 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) { 2498 break; 2499 } 2500 } 2501 2502 SOC_IF_ERROR_RETURN 2503 (_soc_trident_parity_reg_get(unit, block_info_idx, 2504 route_block->pipe, 2505 route_block->enable_reg, 2506 &route_block_rval)); 2507 2508 rv = _soc_trident_parity_enable_info(unit, block_info_idx, 2509 route_block->pipe, 2510 route_block->enable_reg, 2511 &route_block_rval, 2512 route_block->info, mem, enable); 2513 if ((rv != SOC_E_NOT_FOUND) && (SOC_FAILURE(rv))) { 2514 return rv; 2515 } 2516 2517 /* Write per route block parity enable register */ 2518 SOC_IF_ERROR_RETURN 2519 (_soc_trident_parity_reg_set(unit, block_info_idx, 2520 route_block->pipe, 2521 route_block->enable_reg, 2522 route_block_rval)); 2523 if ((rv == SOC_E_NONE) && ((route_block->pipe == 1) || 2524 (route_block->pipe == -1))) { 2525 /* Both pipes have been configured, or MMU block */ 2526 break; 2527 } 2528 } 2529 2530 if ((rv == SOC_E_NONE) && 2531 (SOC_BLOCK_TYPE(unit, SOC_MEM_BLOCK_ANY(unit, mem))) == SOC_BLK_MMU) { 2532 /* MMU controls */ 2533 if (enable) { 2534 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2535 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 2536 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2537 2538 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 1); 2539 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 1); 2540 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 2541 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 2542 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2543 } else { 2544 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2545 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 0); 2546 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 0); 2547 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 0); 2548 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2549 } 2550 } 2551 2552 return SOC_E_NONE; 2553 } 2554 2555 STATIC int 2556 _soc_trident_mem_is_dyn(int unit, soc_mem_t mem) 2557 { 2558 if (SOC_MEM_FIELD_VALID(unit, mem, HITf) || 2559 SOC_MEM_FIELD_VALID(unit, mem, HIT0f) || 2560 SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) || 2561 SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) || 2562 SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) || 2563 SOC_MEM_FIELD_VALID(unit, mem, HITSAf) || 2564 SOC_MEM_FIELD_VALID(unit, mem, HITDAf) || 2565 SOC_MEM_FIELD_VALID(unit, mem, L3_HIT_DCMf) || 2566 SOC_MEM_FIELD_VALID(unit, mem, L3_HIT_PMf)) { 2567 return 1; 2568 } 2569 return 0; 2570 } 2571 2572 STATIC const char *nack_register_name[] = { 2573 "EGR_VLAN_CONTROL_1", 2574 "EGR_IPMC_CFG2" 2575 }; 2576 2577 /* Registers whose parity error need to be handled by S/W */ 2578 STATIC const soc_reg_t nack_register[] = { 2579 EGR_VLAN_CONTROL_1r, 2580 EGR_IPMC_CFG2r 2581 }; 2582 2583 /* Get the mapping reg for given reg name */ 2584 STATIC int 2585 _soc_trident_nack_reg_get(int unit, soc_reg_t *reg, char *reg_name) 2586 { 2587 int rv = SOC_E_NOT_FOUND,i; 2588 2589 if (reg == NULL || reg_name == NULL) { 2590 return rv; 2591 } 2592 2593 for (i = 0; i < COUNTOF(nack_register); i++) { 2594 if (!sal_strcmp(reg_name, nack_register_name[i])) { 2595 *reg = nack_register[i]; 2596 rv = SOC_E_NONE; 2597 break; 2598 } 2599 } 2600 return rv; 2601 } 2602 2603 /* Check whether the reg is proper to do correction and reg_name is mapping */ 2604 STATIC int 2605 _soc_trident_nack_reg_check(int unit, soc_reg_t reg, char *reg_name) 2606 { 2607 int rv = SOC_E_NOT_FOUND,i; 2608 2609 if ((reg_name == NULL) || !SOC_REG_IS_VALID(unit, reg)) { 2610 return rv; 2611 } 2612 2613 for (i = 0; i < COUNTOF(nack_register); i++) { 2614 if ((nack_register[i] == reg) && 2615 !sal_strcmp(nack_register_name[i], reg_name)) { 2616 rv = SOC_E_NONE; 2617 break; 2618 } 2619 } 2620 return rv; 2621 } 2622 2623 STATIC int 2624 _soc_trident_populate_ser_log(int unit, soc_reg_t parity_enable_reg, 2625 soc_field_t parity_enable_field, 2626 soc_mem_t mem, 2627 soc_block_t mem_block, 2628 soc_acc_type_t acc_type, 2629 int index, 2630 sal_usecs_t detect_time, 2631 uint32 sblk, 2632 uint32 address) 2633 { 2634 uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 2635 int log_entry_size, id, entry_dw; 2636 uint32 *cache; 2637 uint8 *vmap; 2638 soc_ser_log_tlv_memory_t log_mem; 2639 soc_ser_log_tlv_generic_t log_generic; 2640 2641 sal_memset(&log_generic, 0, sizeof(log_generic)); 2642 sal_memset(&log_mem, 0, sizeof(log_mem)); 2643 2644 /* 2645 must be large enough for at least generic and terminator, as well as the 2646 memory type since we might decode it in soc_ser_correction. 2647 */ 2648 log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 + 2649 sizeof(soc_ser_log_tlv_generic_t) + 2650 sizeof(soc_ser_log_tlv_memory_t); 2651 2652 if (mem == INVALIDm) { 2653 mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address); 2654 } 2655 /* 2656 If we have decoded the memory we can record its contents/cache 2657 */ 2658 if((mem != INVALIDm) && 2659 (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != SOC_MEM_FLAG_SER_SPECIAL) && 2660 (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) { 2661 entry_dw = soc_mem_entry_words(unit, mem); 2662 2663 /* Check to make sure this isn't a duplicate */ 2664 /* Search for a log entry with the same mem, and id with within the last 5 seconds */ 2665 if (soc_ser_log_find_recent(unit, mem, index, detect_time) > 0) { 2666 return 0; 2667 } 2668 2669 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2670 2671 cache = SOC_MEM_STATE(unit, mem).cache[mem_block]; 2672 vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block]; 2673 if(cache != NULL && CACHE_VMAP_TST(vmap, index)) { 2674 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2675 } 2676 2677 /* create the entry based on determined size, save id */ 2678 id = soc_ser_log_create_entry(unit, log_entry_size); 2679 2680 /* Add the memory information to the log now so we can detect duplicate errors */ 2681 log_generic.time = detect_time; 2682 log_mem.memory = mem; 2683 log_mem.index = index; 2684 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY, 2685 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 2686 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC, 2687 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 2688 2689 /* Disable Parity */ 2690 if (!_soc_trident_mem_is_dyn(unit, mem) && 2691 (parity_enable_reg != INVALIDr) && 2692 (parity_enable_field != INVALIDf)) { 2693 if (soc_reg_field32_modify(unit, parity_enable_reg, 2694 REG_PORT_ANY, parity_enable_field, 0) < 0) { 2695 return 0; 2696 } 2697 } 2698 2699 /*Don't need to select pipe again, because before invoking this function 2700 it has already select the pipe*/ 2701 /* read the memory into a buffer */ 2702 if (acc_type == _SOC_ACC_TYPE_PIPE_Y) { 2703 soc_mem_pipe_select_read(unit, SOC_MEM_NO_FLAGS, mem, mem_block, 2704 acc_type, index, tmp_entry); 2705 } else { 2706 /*Enable NACK on read */ 2707 soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN, 2708 mem, 0, mem_block, 2709 index, tmp_entry); 2710 } 2711 2712 /* Enable Parity */ 2713 if (!_soc_trident_mem_is_dyn(unit, mem) && 2714 (parity_enable_reg != INVALIDr) && 2715 (parity_enable_field != INVALIDf)) { 2716 if (soc_reg_field32_modify(unit, parity_enable_reg, 2717 REG_PORT_ANY, parity_enable_field, 1) < 0) { 2718 return 0; 2719 } 2720 } 2721 2722 /* fill in the memory contents tlv */ 2723 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS, 2724 entry_dw*4, tmp_entry) < 0) { 2725 return 0; 2726 } 2727 2728 2729 if(cache != NULL && CACHE_VMAP_TST(vmap, index)) { 2730 /* fill in the memory cache tlv */ 2731 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE, 2732 entry_dw*4, (cache + index*entry_dw)) < 0) { 2733 return 0; 2734 } 2735 } 2736 } else { 2737 id = soc_ser_log_create_entry(unit, log_entry_size); 2738 } 2739 2740 return id; 2741 } 2742 2743 static int 2744 _soc_trident_parity_process_info(int unit, soc_block_t blocktype, 2745 int block_info_idx, int pipe, 2746 soc_reg_t reg, uint32 group_rval, 2747 const _soc_trident_parity_info_t *info_list, 2748 char *prefix_str); 2749 2750 /* source: source of h/w access and error: 0=hw, 1=cpu */ 2751 STATIC int 2752 _soc_trident_parity_process_parity(int unit, int source, int block_info_idx, 2753 int pipe, const _soc_trident_parity_info_t *info, 2754 int schan, char *prefix_str, char *mem_str) 2755 { 2756 int at; 2757 _soc_trident_parity_reg_t reg_entry[2], *reg_ptr; 2758 soc_reg_t reg, nack_reg = INVALIDr; 2759 uint32 rval, minfo; 2760 uint32 multiple, entry_idx, idx, has_error; 2761 char *mem_str_ptr; 2762 _soc_ser_correct_info_t spci; 2763 2764 sal_memset(&spci, 0, sizeof(spci)); 2765 if (schan) { 2766 /* Some table does not have NACK register */ 2767 if (info->nack_status_reg == INVALIDr && 2768 info->nack_status_reg_list == NULL) { 2769 return SOC_E_NONE; 2770 } 2771 reg_entry[0].reg = info->nack_status_reg; 2772 reg_entry[0].mem_str = NULL; 2773 reg_entry[1].reg = INVALIDr; 2774 reg_ptr = reg_entry; 2775 } else { 2776 if (info->intr_status_reg != INVALIDr) { 2777 reg_entry[0].reg = info->intr_status_reg; 2778 reg_entry[0].mem_str = NULL; 2779 reg_entry[1].reg = INVALIDr; 2780 reg_ptr = reg_entry; 2781 } else if (info->intr_status_reg_list != NULL) { 2782 reg_ptr = info->intr_status_reg_list; 2783 } else { 2784 return SOC_E_NONE; 2785 } 2786 } 2787 2788 (void)_soc_trident_nack_reg_get(unit, &nack_reg, info->mem_str); 2789 2790 has_error = FALSE; 2791 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2792 reg = reg_ptr[idx].reg; 2793 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2794 reg_ptr[idx].mem_str : mem_str; 2795 SOC_IF_ERROR_RETURN 2796 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, 2797 &rval)); 2798 2799 if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) { 2800 has_error = TRUE; 2801 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2802 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2803 _soc_mem_parity_info(unit, block_info_idx, pipe, 2804 info->group_reg_status_field, &minfo); 2805 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2806 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2807 entry_idx, minfo); 2808 LOG_WARN(BSL_LS_SOC_SER, 2809 (BSL_META_U(unit, 2810 "%s %s entry %d parity error\n"), 2811 prefix_str, mem_str_ptr, entry_idx)); 2812 if (multiple) { 2813 LOG_WARN(BSL_LS_SOC_SER, 2814 (BSL_META_U(unit, 2815 "%s %s has multiple parity errors\n"), 2816 prefix_str, mem_str_ptr)); 2817 } 2818 if (idx == 0 && info->mem != INVALIDm) { 2819 /* Enable pipe select control if needed */ 2820 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \ 2821 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 2822 if ((pipe == 1) && (at == _SOC_MEM_ADDR_ACC_TYPE_PIPE_SBS)) { 2823 soc_trident_pipe_select(unit, 2824 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0, 2825 pipe); 2826 } 2827 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 2828 if (source) { 2829 spci.flags |= SOC_SER_ERR_CPU; 2830 } 2831 if (multiple) { 2832 spci.flags |= SOC_SER_ERR_MULTI; 2833 } 2834 spci.reg = INVALIDr; 2835 spci.mem = info->mem; 2836 spci.blk_type = -1; 2837 spci.index = entry_idx; 2838 spci.acc_type = at; 2839 spci.pipe_num = pipe; 2840 spci.parity_type = info->type; 2841 spci.detect_time = sal_time_usecs(); 2842 spci.log_id = _soc_trident_populate_ser_log(unit, 2843 info->enable_reg, info->enable_field, spci.mem, 2844 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 2845 spci.index, spci.detect_time, spci.sblk, spci.addr); 2846 (void)soc_ser_correction(unit, &spci); 2847 if (spci.log_id != 0) { 2848 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2849 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 2850 spci.log_id, 0); 2851 } 2852 /* Revert pipe select control if needed */ 2853 if ((pipe == 1) && (at == _SOC_MEM_ADDR_ACC_TYPE_PIPE_SBS)) { 2854 soc_trident_pipe_select(unit, 2855 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0, 2856 0); 2857 } 2858 } else if (idx == 0 && SOC_REG_IS_VALID(unit, nack_reg)) { 2859 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 2860 if (source) { 2861 spci.flags |= SOC_SER_ERR_CPU; 2862 } 2863 if (multiple) { 2864 spci.flags |= SOC_SER_ERR_MULTI; 2865 } 2866 spci.reg = nack_reg; 2867 spci.mem = INVALIDm; 2868 spci.blk_type = -1; 2869 spci.port = entry_idx; 2870 spci.index = 0; 2871 spci.pipe_num = pipe; 2872 spci.parity_type = info->type; 2873 spci.detect_time = sal_time_usecs(); 2874 spci.log_id = soc_ser_log_create_entry(unit, 2875 sizeof(soc_ser_log_tlv_generic_t) + 2876 sizeof(soc_ser_log_tlv_register_t) + 2877 sizeof(soc_ser_log_tlv_hdr_t) *3); 2878 (void)soc_ser_correction(unit, &spci); 2879 if (spci.log_id != 0) { 2880 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2881 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 2882 spci.log_id, 0); 2883 } 2884 } 2885 } 2886 2887 /* Clear parity status */ 2888 SOC_IF_ERROR_RETURN 2889 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0)); 2890 } 2891 2892 if (!has_error) { 2893 LOG_ERROR(BSL_LS_SOC_SER, 2894 (BSL_META_U(unit, 2895 "%s %s parity hardware inconsistency\n"), 2896 prefix_str, mem_str)); 2897 } 2898 2899 return SOC_E_NONE; 2900 } 2901 2902 STATIC int 2903 _soc_trident_parity_process_ecc(int unit, int block_info_idx, int pipe, 2904 const _soc_trident_parity_info_t *info, 2905 int schan, char *prefix_str, char *mem_str) 2906 { 2907 int at; 2908 _soc_trident_parity_reg_t reg_entry[2], *reg_ptr; 2909 soc_reg_t reg; 2910 uint32 rval, minfo; 2911 uint32 multiple, double_bit, entry_idx, idx, has_error; 2912 char *mem_str_ptr; 2913 _soc_ser_correct_info_t spci; 2914 2915 sal_memset(&spci, 0, sizeof(spci)); 2916 2917 if (schan) { 2918 /* Some table does not have NACK register */ 2919 if (info->nack_status_reg == INVALIDr && 2920 info->nack_status_reg_list == NULL) { 2921 return SOC_E_NONE; 2922 } 2923 reg_entry[0].reg = info->nack_status_reg; 2924 reg_entry[0].mem_str = NULL; 2925 reg_entry[1].reg = INVALIDr; 2926 reg_ptr = reg_entry; 2927 } else { 2928 if (info->intr_status_reg != INVALIDr) { 2929 reg_entry[0].reg = info->intr_status_reg; 2930 reg_entry[0].mem_str = NULL; 2931 reg_entry[1].reg = INVALIDr; 2932 reg_ptr = reg_entry; 2933 } else if (info->intr_status_reg_list != NULL) { 2934 reg_ptr = info->intr_status_reg_list; 2935 } else { 2936 return SOC_E_NONE; 2937 } 2938 } 2939 2940 has_error = FALSE; 2941 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2942 reg = reg_ptr[idx].reg; 2943 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2944 reg_ptr[idx].mem_str : mem_str; 2945 SOC_IF_ERROR_RETURN 2946 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, 2947 &rval)); 2948 2949 if (soc_reg_field_get(unit, reg, rval, ECC_ERRf)) { 2950 has_error = TRUE; 2951 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2952 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf); 2953 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2954 _soc_mem_parity_info(unit, block_info_idx, pipe, 2955 info->group_reg_status_field, &minfo); 2956 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2957 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 2958 entry_idx, minfo); 2959 if (double_bit) { 2960 spci.double_bit = 1; 2961 LOG_WARN(BSL_LS_SOC_SER, 2962 (BSL_META_U(unit, 2963 "%s %s entry %d double-bit ECC error\n"), 2964 prefix_str, mem_str_ptr, entry_idx)); 2965 } else { 2966 LOG_WARN(BSL_LS_SOC_SER, 2967 (BSL_META_U(unit, 2968 "%s %s entry %d ECC error\n"), 2969 prefix_str, mem_str_ptr, entry_idx)); 2970 } 2971 if (multiple) { 2972 LOG_WARN(BSL_LS_SOC_SER, 2973 (BSL_META_U(unit, 2974 "%s %s has multiple ECC errors\n"), 2975 prefix_str, mem_str_ptr)); 2976 spci.flags |= SOC_SER_ERR_MULTI; 2977 } 2978 if (schan) { 2979 spci.flags |= SOC_SER_ERR_CPU; 2980 } 2981 if (idx == 0 && info->mem != INVALIDm) { 2982 /* Enable pipe select control if needed */ 2983 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \ 2984 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 2985 2986 if (pipe == 1) { 2987 soc_trident_pipe_select(unit, 2988 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0, 2989 pipe); 2990 } 2991 spci.flags |= SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 2992 spci.reg = INVALIDr; 2993 spci.mem = info->mem; 2994 spci.blk_type = -1; 2995 spci.index = entry_idx; 2996 spci.acc_type = at; 2997 spci.pipe_num = pipe; 2998 spci.detect_time = sal_time_usecs(); 2999 spci.parity_type = SOC_PARITY_TYPE_ECC; 3000 spci.log_id = _soc_trident_populate_ser_log(unit, 3001 info->enable_reg, info->enable_field, info->mem, 3002 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 3003 spci.index, spci.detect_time, spci.sblk, spci.addr); 3004 (void)soc_ser_correction(unit, &spci); 3005 if (spci.log_id != 0) { 3006 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3007 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3008 spci.log_id, 0); 3009 } 3010 3011 if (pipe == 1) { 3012 soc_trident_pipe_select(unit, 3013 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0, 3014 0); 3015 } 3016 } 3017 } 3018 3019 /* Clear parity status */ 3020 SOC_IF_ERROR_RETURN 3021 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0)); 3022 } 3023 3024 if (!has_error) { 3025 LOG_ERROR(BSL_LS_SOC_SER, 3026 (BSL_META_U(unit, 3027 "%s %s ECC hardware inconsistency\n"), 3028 prefix_str, mem_str)); 3029 } 3030 3031 return SOC_E_NONE; 3032 } 3033 3034 int 3035 _soc_trident_l3_entry_idx_map(soc_mem_t mem, int entry_idx) 3036 { 3037 int new_id = entry_idx; 3038 3039 switch (mem) { 3040 case L3_ENTRY_IPV6_UNICASTm: 3041 case L3_ENTRY_IPV4_MULTICASTm: 3042 new_id = entry_idx/2; 3043 break; 3044 case L3_ENTRY_IPV6_MULTICASTm: 3045 new_id = entry_idx/4; 3046 break; 3047 default: 3048 break; 3049 } 3050 return new_id; 3051 } 3052 3053 STATIC int 3054 _soc_trident_parity_process_hash(int unit, int block_info_idx, int pipe, 3055 const _soc_trident_parity_info_t *info, 3056 int schan, char *prefix_str, char *mem_str) 3057 { 3058 _soc_trident_parity_reg_t *reg_ptr; 3059 soc_reg_t reg; 3060 uint32 rval, minfo; 3061 uint32 bitmap, multiple, bucket_idx; 3062 int bucket_size, entry_idx, idx, bank_bkt_idx, bits, has_error, at; 3063 _soc_ser_correct_info_t spci; 3064 3065 if (schan) { 3066 reg_ptr = info->nack_status_reg_list; 3067 } else { 3068 reg_ptr = info->intr_status_reg_list; 3069 } 3070 3071 has_error = FALSE; 3072 for (idx = 0; idx < 2; idx ++) { 3073 reg = reg_ptr[idx].reg; 3074 SOC_IF_ERROR_RETURN 3075 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, 3076 &rval)); 3077 3078 bitmap = soc_reg_field_get(unit, reg, rval, PARITY_ERR_BMf); 3079 if (bitmap != 0) { 3080 has_error = TRUE; 3081 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 3082 bucket_size = soc_reg_field_length(unit, reg, PARITY_ERR_BMf); 3083 bucket_idx = soc_reg_field_get(unit, reg, rval, BUCKET_IDXf) * bucket_size * 2; 3084 bank_bkt_idx = idx * bucket_size + bucket_idx; 3085 for (bits = 0; bits < bucket_size; bits++) { 3086 if (bitmap & (1 << bits)) { 3087 entry_idx = bank_bkt_idx + bits; 3088 entry_idx = _soc_trident_l3_entry_idx_map(info->mem, entry_idx); 3089 _soc_mem_parity_info(unit, block_info_idx, pipe, 3090 info->group_reg_status_field, &minfo); 3091 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3092 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3093 entry_idx, minfo); 3094 if (info->mem != INVALIDm) { 3095 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \ 3096 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 3097 3098 if ((pipe ==1) && (at != _SOC_MEM_ADDR_ACC_TYPE_PIPE_X)) { 3099 soc_trident_pipe_select(unit, 3100 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0, 3101 pipe); 3102 } 3103 sal_memset(&spci, 0, sizeof(spci)); 3104 if (schan) { 3105 spci.flags |= SOC_SER_ERR_CPU; 3106 } 3107 if (multiple) { 3108 spci.flags |= SOC_SER_ERR_MULTI; 3109 } 3110 LOG_WARN(BSL_LS_SOC_SER, 3111 (BSL_META_U(unit, 3112 "%s %s entry %d parity error\n"), 3113 prefix_str, mem_str, entry_idx)); 3114 spci.flags |= SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 3115 spci.reg = INVALIDr; 3116 spci.mem = info->mem == L2_ENTRY_ONLYm ? L2Xm : info->mem; 3117 spci.blk_type = -1; 3118 spci.index = entry_idx; 3119 spci.acc_type = at; 3120 spci.pipe_num = pipe; 3121 spci.detect_time = sal_time_usecs(); 3122 spci.log_id = _soc_trident_populate_ser_log(unit, 3123 info->enable_reg, info->enable_field, spci.mem, 3124 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 3125 spci.index, spci.detect_time, spci.sblk, spci.addr); 3126 (void)soc_ser_correction(unit, &spci); 3127 if (spci.log_id != 0) { 3128 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3129 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3130 spci.log_id, 0); 3131 } 3132 3133 if ((pipe ==1) && (at != _SOC_MEM_ADDR_ACC_TYPE_PIPE_X)) { 3134 soc_trident_pipe_select(unit, 3135 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0, 3136 0); 3137 } 3138 } 3139 } 3140 } 3141 if (multiple) { 3142 LOG_WARN(BSL_LS_SOC_SER, 3143 (BSL_META_U(unit, 3144 "%s %s has multiple parity errors\n"), 3145 prefix_str, mem_str)); 3146 } 3147 } 3148 3149 /* Clear parity status */ 3150 SOC_IF_ERROR_RETURN 3151 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0)); 3152 } 3153 3154 if (!has_error) { 3155 LOG_ERROR(BSL_LS_SOC_SER, 3156 (BSL_META_U(unit, 3157 "%s %s parity hardware inconsistency\n"), 3158 prefix_str, mem_str)); 3159 } 3160 3161 return SOC_E_NONE; 3162 } 3163 3164 STATIC soc_acc_type_t 3165 _soc_trident_pipe_to_acc_type(int pipe); 3166 3167 3168 STATIC int 3169 _soc_trident_parity_process_l2x(int unit, int block_info_idx, int pipe, 3170 const _soc_trident_parity_info_t *info, 3171 int schan, char *prefix_str, char *mem_str, uint32 address) 3172 { 3173 uint32 minfo; 3174 int bucket_size, entry_idx, idx, bits, at, entry_base, bucket_boundary; 3175 _soc_ser_correct_info_t spci; 3176 uint32 entry[SOC_MAX_MEM_WORDS] = {0}; 3177 3178 /* process DA table : use original function _soc_trident_parity_process_hash() */ 3179 SOC_IF_ERROR_RETURN(_soc_trident_parity_process_hash(unit, block_info_idx, 3180 pipe, info, schan, 3181 prefix_str, mem_str)); 3182 3183 /* process SA table . 3184 For L2_ENTRY_PARITY_STATUS_NACK_0/1 will not report SA entry_id with parity error, 3185 caculate each entry's parity status in same bucket by sw 3186 */ 3187 bucket_size = 4; 3188 entry_base = address & (~SOC_MEM_INFO(unit, info->mem).index_max); 3189 bucket_boundary = (address - entry_base) >> 3; 3190 bucket_boundary = entry_base + (bucket_boundary << 3); 3191 3192 for (idx = 0; idx < 2; idx ++) { 3193 bucket_boundary += idx * bucket_size; 3194 3195 for (bits = 0; bits < bucket_size; bits++) { 3196 entry_idx = bucket_boundary + bits; 3197 3198 sal_memset(&entry,0,sizeof(entry)); 3199 3200 _soc_mem_parity_info(unit, block_info_idx, pipe, 3201 info->group_reg_status_field, &minfo); 3202 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3203 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3204 (entry_idx - entry_base), minfo); 3205 if (info->mem != INVALIDm) { 3206 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \ 3207 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 3208 sal_memset(&spci, 0, sizeof(spci)); 3209 if (schan) { 3210 spci.flags |= SOC_SER_ERR_CPU; 3211 } 3212 LOG_WARN(BSL_LS_SOC_SER, 3213 (BSL_META_U(unit, 3214 "%s %s entry 0x%x parity error\n"), 3215 prefix_str, mem_str, (entry_idx - entry_base))); 3216 spci.flags |= SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 3217 spci.reg = INVALIDr; 3218 spci.mem = info->mem == L2_ENTRY_ONLYm ? L2Xm : info->mem; 3219 spci.blk_type = -1; 3220 spci.index = entry_idx - entry_base; 3221 spci.acc_type = at; 3222 spci.pipe_num = 0; 3223 spci.detect_time = sal_time_usecs(); 3224 spci.log_id = _soc_trident_populate_ser_log(unit, 3225 info->enable_reg, info->enable_field, spci.mem, 3226 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 3227 spci.index, spci.detect_time, spci.sblk, spci.addr); 3228 (void)soc_ser_correction(unit, &spci); 3229 if (spci.log_id != 0) { 3230 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3231 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3232 spci.log_id, 0); 3233 } 3234 } 3235 } 3236 3237 } 3238 3239 return SOC_E_NONE; 3240 } 3241 3242 3243 STATIC int 3244 _soc_trident_parity_process_edatabuf(int unit, int block_info_idx, int pipe, 3245 const _soc_trident_parity_info_t *info, 3246 int schan, char *prefix_str, 3247 char *mem_str) 3248 { 3249 soc_reg_t reg; 3250 uint32 rval, minfo; 3251 uint32 double_bit = 0, multiple = 0; 3252 soc_ser_log_tlv_generic_t log_generic; 3253 int log_id; 3254 3255 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 3256 3257 if (schan) { 3258 /* Some table may not have NACK status register */ 3259 if (info->nack_status_reg == INVALIDr) { 3260 return SOC_E_NONE; 3261 } 3262 reg = info->nack_status_reg; 3263 } else { 3264 reg = info->intr_status_reg; 3265 } 3266 3267 SOC_IF_ERROR_RETURN 3268 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, &rval)); 3269 3270 if (soc_reg_field_get(unit, reg, rval, ECC_ERR_MGRPf)) { 3271 double_bit = soc_reg_field_get(unit, reg, rval, ECC_ERR_2B_MGRPf); 3272 multiple = soc_reg_field_get(unit, reg, rval, ECC_MULTI_MGRPf); 3273 _soc_mem_parity_info(unit, block_info_idx, pipe, 3274 info->group_reg_status_field, &minfo); 3275 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3276 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0, 3277 minfo); 3278 if (double_bit) { 3279 LOG_WARN(BSL_LS_SOC_SER, 3280 (BSL_META_U(unit, 3281 "%s %s double-bit ECC error\n"), 3282 prefix_str, mem_str)); 3283 } else { 3284 LOG_WARN(BSL_LS_SOC_SER, 3285 (BSL_META_U(unit, 3286 "%s %s ECC error\n"), 3287 prefix_str, mem_str)); 3288 } 3289 if (multiple) { 3290 LOG_WARN(BSL_LS_SOC_SER, 3291 (BSL_META_U(unit, 3292 "%s %s has multiple ECC errors\n"), 3293 prefix_str, mem_str)); 3294 } 3295 } else { 3296 LOG_ERROR(BSL_LS_SOC_SER, 3297 (BSL_META_U(unit, 3298 "%s %s ECC hardware inconsistency\n"), 3299 prefix_str, mem_str)); 3300 } 3301 3302 if (multiple) { 3303 log_generic.flags |= SOC_SER_LOG_FLAG_MULTIBIT; 3304 } 3305 if (double_bit) { 3306 log_generic.flags |= SOC_SER_LOG_FLAG_DOUBLEBIT; 3307 } 3308 if (schan) { 3309 log_generic.flags |= SOC_SER_LOG_FLAG_ERR_SRC; 3310 } 3311 log_generic.time = sal_time_usecs(); 3312 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 3313 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 3314 log_generic.parity_type = info->type; 3315 3316 log_id = soc_ser_log_create_entry(unit, 3317 sizeof(soc_ser_log_tlv_generic_t) + 3318 sizeof(soc_ser_log_tlv_hdr_t) *2); 3319 3320 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 3321 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 3322 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3323 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 3324 /* Clear parity status */ 3325 SOC_IF_ERROR_RETURN 3326 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0)); 3327 3328 return SOC_E_NONE; 3329 } 3330 3331 typedef struct _soc_trident_parity_counter_info_s { 3332 soc_reg_t counter_reg; 3333 soc_reg_t status_reg[2]; 3334 } _soc_trident_parity_counter_info_t; 3335 3336 STATIC _soc_trident_parity_counter_info_t soc_trident_trill_niv_counter_parity_info[] = { 3337 { ING_TRILL_RX_PKTSr, 3338 { TRILL_RX_PKTS_PARITY_STATUS_NACKr, 3339 TRILL_RX_PKTS_PARITY_STATUS_INTRr} 3340 }, 3341 { ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDEDr, 3342 { TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr, 3343 TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr} 3344 }, 3345 { ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDEDr, 3346 { TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr, 3347 TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr} 3348 }, 3349 3350 { ING_NIV_RX_FRAMES_ERROR_DROPr, 3351 { NIV_ERROR_DROP_PARITY_STATUS_NACKr, 3352 NIV_ERROR_DROP_PARITY_STATUS_INTRr} 3353 }, 3354 { ING_NIV_RX_FRAMES_FORWARDING_DROPr, 3355 { NIV_FORWARDING_DROP_PARITY_STATUS_NACKr, 3356 NIV_FORWARDING_DROP_PARITY_STATUS_INTRr} 3357 }, 3358 { ING_NIV_RX_FRAMES_VLAN_TAGGEDr, 3359 { NIV_VLAN_TAGGED_PARITY_STATUS_NACKr, 3360 NIV_VLAN_TAGGED_PARITY_STATUS_INTRr} 3361 }, 3362 3363 { INVALIDr }, 3364 }; 3365 3366 STATIC int 3367 _soc_trident_trill_niv_counter_find(int schan, soc_reg_t status_reg, soc_reg_t * p_reg) 3368 { 3369 uint16 i = 0; 3370 uint16 found = 0; 3371 uint16 reg_select = schan ? 0 : 1; 3372 3373 for( ; soc_trident_trill_niv_counter_parity_info[i].counter_reg!= INVALIDr; i++ ) { 3374 if (soc_trident_trill_niv_counter_parity_info[i].status_reg[reg_select] 3375 == status_reg) { 3376 found = 1; 3377 break; 3378 } 3379 } 3380 3381 if (found) { 3382 *p_reg = soc_trident_trill_niv_counter_parity_info[i].counter_reg; 3383 } 3384 3385 return found; 3386 } 3387 3388 3389 static int _stat_error_fixed[SOC_MAX_NUM_DEVICES]; 3390 3391 STATIC int 3392 _soc_trident_parity_process_counter(int unit, soc_block_t blocktype, 3393 int block_info_idx, int pipe, 3394 const _soc_trident_parity_info_t *info, 3395 int schan, char *prefix_str, char *mem_str) 3396 { 3397 soc_cmap_t *cmap; 3398 soc_reg_t reg; 3399 soc_reg_t counter_reg = INVALIDr; 3400 uint32 rval, minfo; 3401 uint32 multiple, counter_idx, port_idx, entry_idx; 3402 char *counter_name; 3403 _soc_ser_correct_info_t spci; 3404 int trill_niv_counter_found = 0; 3405 sal_memset(&spci, 0, sizeof(spci)); 3406 3407 if (schan) { 3408 reg = info->nack_status_reg; 3409 } else { 3410 reg = info->intr_status_reg; 3411 } 3412 SOC_IF_ERROR_RETURN 3413 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, &rval)); 3414 3415 trill_niv_counter_found = _soc_trident_trill_niv_counter_find(schan, reg, &counter_reg); 3416 3417 if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) { 3418 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 3419 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 3420 if (trill_niv_counter_found) { 3421 port_idx = entry_idx; 3422 } else { 3423 counter_idx = soc_reg_field_get(unit, reg, rval, COUNTER_IDXf); 3424 port_idx = soc_reg_field_get(unit, reg, rval, PORT_IDXf); 3425 3426 /* TDBGC starts at index 0x20 of counter DMA table */ 3427 if (info->group_reg_status_field == EGR_STATS_COUNTER_TABLE_PAR_ERRf) { 3428 counter_idx += 0x20; 3429 } 3430 cmap = soc_port_cmap_get(unit, port_idx); 3431 counter_reg = cmap->cmap_base[counter_idx].reg; 3432 } 3433 3434 if (SOC_REG_IS_VALID(unit, counter_reg)) { 3435 _soc_mem_parity_info(unit, block_info_idx, pipe, 3436 info->group_reg_status_field, &minfo); 3437 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3438 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3439 entry_idx, minfo); 3440 counter_name = SOC_REG_NAME(unit, counter_reg); 3441 LOG_WARN(BSL_LS_SOC_SER, 3442 (BSL_META_U(unit, 3443 "%s %s port %d %s entry %d parity error\n"), 3444 prefix_str, mem_str, port_idx, counter_name, 3445 entry_idx)); 3446 if (schan) { 3447 spci.flags |= SOC_SER_ERR_CPU; 3448 } 3449 if (multiple) { 3450 spci.flags |= SOC_SER_ERR_MULTI; 3451 } 3452 spci.flags |= SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 3453 spci.mem = INVALIDm; 3454 spci.port = port_idx; 3455 spci.index = 0; 3456 spci.pipe_num = pipe; 3457 spci.reg = counter_reg; 3458 spci.blk_type = blocktype; 3459 spci.detect_time = sal_time_usecs(); 3460 spci.parity_type = info->type; 3461 spci.log_id = soc_ser_log_create_entry(unit, 3462 sizeof(soc_ser_log_tlv_generic_t) + 3463 sizeof(soc_ser_log_tlv_register_t) + 3464 sizeof(soc_ser_log_tlv_hdr_t) *3); 3465 (void)soc_ser_correction(unit, &spci); 3466 if (spci.log_id != 0) { 3467 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3468 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3469 spci.log_id, 0); 3470 } 3471 if (multiple) { 3472 LOG_WARN(BSL_LS_SOC_SER, 3473 (BSL_META_U(unit, 3474 "%s %s has multiple parity errors\n"), 3475 prefix_str, mem_str)); 3476 } 3477 _stat_error_fixed[unit]++; 3478 } else { 3479 LOG_ERROR(BSL_LS_SOC_SER, 3480 (BSL_META_U(unit, 3481 "%s %s parity hardware inconsistency\n"), 3482 prefix_str, mem_str)); 3483 } 3484 } else { 3485 if (!schan) { 3486 LOG_ERROR(BSL_LS_SOC_SER, 3487 (BSL_META_U(unit, 3488 "%s %s parity hardware inconsistency\n"), 3489 prefix_str, mem_str)); 3490 } 3491 } 3492 3493 /* Clear parity status */ 3494 SOC_IF_ERROR_RETURN 3495 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0)); 3496 3497 return SOC_E_NONE; 3498 } 3499 3500 STATIC int 3501 _soc_trident_parity_mmu_clear(int unit, soc_field_t status_field); 3502 3503 STATIC int 3504 _soc_trident_parity_process_mmu_thdo(int unit, int block_info_idx, 3505 const _soc_trident_parity_info_t *info, 3506 char *prefix_str) 3507 { 3508 uint64 rval64; 3509 uint32 entry_idx, rval_hi, rval_lo, minfo; 3510 int i, size; 3511 _soc_ser_correct_info_t spci; 3512 3513 static const _soc_trident_parity_mmu_bit_t thdo[] = { 3514 /* { 0, MMU_THDO_QREDRST_EX_1m }, */ 3515 /* { 1, MMU_THDO_QYELRST_EX_1m }, */ 3516 /* { 4, MMU_THDO_QDRPRST_EX_1m }, */ 3517 { 6, THDO_OFFSET_EX_1Bm }, 3518 { 7, THDO_OFFSET_EX_1Am }, 3519 { 8, THDO_CONFIG_EX_1Bm }, 3520 { 9, THDO_CONFIG_EX_1Am }, 3521 /* { 14, MMU_THDO_QREDRST_EX_0m }, */ 3522 /* { 15, MMU_THDO_QYELRST_EX_0m }, */ 3523 /* { 18, MMU_THDO_QDRPRST_EX_0m }, */ 3524 { 20, THDO_OFFSET_EX_0Bm }, 3525 { 21, THDO_OFFSET_EX_0Am }, 3526 { 22, THDO_CONFIG_EX_0Bm }, 3527 { 23, THDO_CONFIG_EX_0Am }, 3528 /* { 28, MMU_THDO_QREDRST_1m }, */ 3529 /* { 29, MMU_THDO_QYELRST_1m }, */ 3530 /* { 30, MMU_THDO_QDRPRST_1m }, */ 3531 { 31, THDO_OFFSET_1Bm }, 3532 { 32, THDO_OFFSET_1Am }, 3533 { 33, THDO_CONFIG_1Bm }, 3534 { 34, THDO_CONFIG_1Am }, 3535 /* { 35, MMU_THDO_QREDRST_0m }, */ 3536 /* { 36, MMU_THDO_QYELRST_0m }, */ 3537 /* { 37, MMU_THDO_QDRPRST_0m }, */ 3538 { 38, THDO_OFFSET_0Bm }, 3539 { 39, THDO_OFFSET_0Am }, 3540 { 40, THDO_CONFIG_0Bm }, 3541 { 41, THDO_CONFIG_0Am } 3542 }; 3543 3544 sal_memset(&spci, 0, sizeof(spci)); 3545 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 3546 spci.reg = INVALIDr; 3547 spci.blk_type = SOC_BLK_MMU; 3548 3549 SOC_IF_ERROR_RETURN(READ_THDO_PARITY_ERROR_STATUS_64r(unit, &rval64)); 3550 rval_hi = COMPILER_64_HI(rval64); 3551 rval_lo = COMPILER_64_LO(rval64); 3552 3553 SOC_IF_ERROR_RETURN(READ_THDO_PARITY_ERROR_ADDRESSr(unit, &entry_idx)); 3554 3555 size = COUNTOF(thdo); 3556 for (i = 0; i < size; i++) { 3557 if (thdo[i].bit_pos < 32) { 3558 if (!(rval_lo & (1 << thdo[i].bit_pos))) { 3559 continue; 3560 } 3561 } else { 3562 if (!(rval_hi & (1 << (thdo[i].bit_pos - 32)))) { 3563 continue; 3564 } 3565 } 3566 spci.mem = thdo[i].mem; 3567 spci.index = entry_idx; 3568 _soc_mem_parity_info(unit, block_info_idx, 0, 3569 info->group_reg_status_field, &minfo); 3570 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3571 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0, 3572 minfo); 3573 spci.detect_time = sal_time_usecs(); 3574 spci.parity_type = info->type; 3575 spci.log_id = _soc_trident_populate_ser_log(unit, 3576 info->enable_reg, info->enable_field, spci.mem, 3577 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 3578 spci.index, spci.detect_time, spci.sblk, spci.addr); 3579 3580 (void)soc_ser_correction(unit, &spci); 3581 if (spci.log_id != 0) { 3582 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3583 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3584 spci.log_id, 0); 3585 } 3586 3587 LOG_WARN(BSL_LS_SOC_SER, 3588 (BSL_META_U(unit, 3589 "%s %s entry %d parity error\n"), prefix_str, 3590 SOC_MEM_NAME(unit, thdo[i].mem), entry_idx)); 3591 } 3592 3593 /* Clear parity error status */ 3594 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 3595 3596 return SOC_E_NONE; 3597 } 3598 3599 STATIC int 3600 _soc_trident_parity_process_start_err(int unit, int block_info_idx, 3601 const _soc_trident_parity_info_t *info, 3602 char *prefix_str) 3603 { 3604 soc_info_t *si; 3605 uint64 rval64; 3606 uint32 pbmp_31_0, pbmp_63_32, pbmp_65_64; 3607 soc_pbmp_t pbmp; 3608 uint32 minfo; 3609 int port, mmu_port, phy_port; 3610 soc_ser_log_tlv_generic_t log_generic; 3611 int log_id; 3612 3613 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 3614 3615 si = &SOC_INFO(unit); 3616 3617 /* mmu port 32-0 */ 3618 SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR0_64r(unit, &rval64)); 3619 pbmp_31_0 = COMPILER_64_LO(rval64); 3620 pbmp_63_32 = COMPILER_64_HI(rval64); 3621 /* mmu port 65-33 */ 3622 SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR1_64r(unit, &rval64)); 3623 pbmp_63_32 |= COMPILER_64_LO(rval64) << 1; 3624 pbmp_65_64 = (COMPILER_64_HI(rval64) << 1) | 3625 (COMPILER_64_LO(rval64) >> 31); 3626 SOC_PBMP_CLEAR(pbmp); 3627 SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0); 3628 SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32); 3629 SOC_PBMP_WORD_SET(pbmp, 2, pbmp_65_64); 3630 3631 SOC_PBMP_ITER(pbmp, mmu_port) { 3632 phy_port = si->port_m2p_mapping[mmu_port]; 3633 port = si->port_p2l_mapping[phy_port]; 3634 _soc_mem_parity_info(unit, block_info_idx, 0, 3635 info->group_reg_status_field, &minfo); 3636 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3637 SOC_SWITCH_EVENT_DATA_ERROR_UNSPECIFIED, 0, 3638 minfo); 3639 3640 log_generic.time = sal_time_usecs(); 3641 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 3642 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 3643 log_generic.parity_type = info->type; 3644 3645 log_id = soc_ser_log_create_entry(unit, 3646 sizeof(soc_ser_log_tlv_generic_t) + 3647 sizeof(soc_ser_log_tlv_hdr_t) *2); 3648 3649 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 3650 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 3651 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3652 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 3653 3654 LOG_WARN(BSL_LS_SOC_SER, 3655 (BSL_META_U(unit, 3656 "%s port %d start error detected\n"), prefix_str, 3657 port)); 3658 } 3659 3660 /* Clear parity status */ 3661 COMPILER_64_ZERO(rval64); 3662 SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR0_64r(unit, rval64)); 3663 SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR1_64r(unit, rval64)); 3664 3665 return SOC_E_NONE; 3666 } 3667 3668 STATIC int 3669 _soc_trident_parity_mmu_clear(int unit, soc_field_t status_field) 3670 { 3671 uint32 rval; 3672 3673 /* Clear parity error status */ 3674 SOC_IF_ERROR_RETURN 3675 (READ_MEM_FAIL_INT_STATr(unit, &rval)); 3676 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, status_field, 0); 3677 SOC_IF_ERROR_RETURN 3678 (WRITE_MEM_FAIL_INT_STATr(unit, rval)); 3679 3680 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 3681 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 3682 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 3683 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 3684 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 3685 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 3686 return SOC_E_NONE; 3687 } 3688 3689 int 3690 _soc_trident_parity_generic_clear(int unit, soc_block_t blocktype, int pipe, 3691 soc_reg_t group_reg, const _soc_trident_parity_info_t *info, 3692 char *prefix_str, char *mem_str) 3693 { 3694 uint32 rval; 3695 soc_field_t group_field = info->group_reg_status_field; 3696 3697 /* Clear parity error status */ 3698 if (blocktype == SOC_BLK_MMU) { 3699 SOC_IF_ERROR_RETURN 3700 (soc_reg32_get(unit, group_reg, REG_PORT_ANY, 0, &rval)); 3701 3702 soc_reg_field_set(unit, group_reg, &rval, group_field, 0); 3703 3704 SOC_IF_ERROR_RETURN 3705 (soc_reg32_set(unit, group_reg, REG_PORT_ANY, 0, rval)); 3706 3707 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 3708 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 3709 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 3710 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 3711 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 3712 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 3713 3714 LOG_INFO(BSL_LS_SOC_SER, 3715 (BSL_META_U(unit, 3716 "%s %s asserted, status register %s, field %s\n"), 3717 prefix_str, mem_str, SOC_REG_NAME(unit, group_reg), 3718 SOC_FIELD_NAME(unit, group_field))); 3719 return SOC_E_NONE; 3720 } else { 3721 LOG_ERROR(BSL_LS_SOC_SER, 3722 (BSL_META_U(unit, 3723 "%s %s asserted\n"), 3724 prefix_str, mem_str)); 3725 /* need to add new way to clear parity status */ 3726 return SOC_E_NONE; 3727 } 3728 } 3729 3730 STATIC int 3731 _soc_trident_parity_process_mmu_wred(int unit, int block_info_idx, 3732 const _soc_trident_parity_info_t *info, 3733 char *prefix_str) 3734 { 3735 int i = 0; 3736 int at = -1; 3737 uint8 found = 0; 3738 uint32 value = 0; 3739 uint32 minfo, rval, rval_bitmap, log; 3740 soc_mem_t mem = INVALIDm; 3741 soc_reg_t clear_reg = INVALIDr; 3742 _soc_ser_correct_info_t spci; 3743 soc_info_t *si = &SOC_INFO(unit); 3744 3745 SOC_IF_ERROR_RETURN(READ_WRED_PARITY_ERROR_BITMAPr(unit, &rval_bitmap)); 3746 LOG_VERBOSE(BSL_LS_SOC_SER, 3747 (BSL_META_U(unit, 3748 "wred bitmap: 0x%08x\n"), rval_bitmap)); 3749 3750 SOC_IF_ERROR_RETURN(READ_WRED_PARITY_ERROR_INFOr(unit, &rval)); 3751 LOG_VERBOSE(BSL_LS_SOC_SER, 3752 (BSL_META_U(unit, 3753 "wred info: 0x%08x\n"), rval)); 3754 log = rval; 3755 3756 for (i = 0; i < 12; i++) { 3757 value = rval_bitmap & 1 << i; 3758 switch(value) { 3759 case 0x1: 3760 case 0x2: 3761 mem = INVALIDm; 3762 found = 1; 3763 break; 3764 case 0x4: 3765 mem = MMU_WRED_DROP_CURVE_PROFILE_0m; 3766 found = 1; 3767 break; 3768 case 0x8: 3769 mem = MMU_WRED_DROP_CURVE_PROFILE_1m; 3770 found = 1; 3771 break; 3772 case 0x10: 3773 mem = MMU_WRED_DROP_CURVE_PROFILE_2m; 3774 found = 1; 3775 break; 3776 case 0x20: 3777 mem = MMU_WRED_DROP_CURVE_PROFILE_3m; 3778 found = 1; 3779 break; 3780 case 0x40: 3781 mem = MMU_WRED_DROP_CURVE_PROFILE_4m; 3782 found = 1; 3783 break; 3784 case 0x80: 3785 mem = MMU_WRED_DROP_CURVE_PROFILE_5m; 3786 found = 1; 3787 break; 3788 case 0x100: 3789 mem = MMU_WRED_DROP_THD_UC_ENQ0m; 3790 found = 1; 3791 break; 3792 case 0x200: 3793 mem = MMU_WRED_DROP_THD_UC_ENQ1m; 3794 found = 1; 3795 break; 3796 case 0x400: 3797 mem = MMU_WRED_DROP_THD_UC_DEQ0m; 3798 found = 1; 3799 break; 3800 case 0x800: 3801 mem = MMU_WRED_DROP_THD_UC_DEQ1m; 3802 found = 1; 3803 break; 3804 default: 3805 found = 0; 3806 break; 3807 } 3808 3809 if (found == 0) { 3810 continue; 3811 } 3812 3813 sal_memset(&spci, 0, sizeof(spci)); 3814 3815 if (mem == INVALIDm) { 3816 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 3817 spci.mem = INVALIDm; 3818 3819 rval = rval & 0xfff; 3820 if ((rval & 0xff0) == 0x540) { 3821 spci.port = REG_PORT_ANY; 3822 spci.index = rval & 0xf; 3823 spci.reg = GLOBAL_SP_WRED_CONFIGr; 3824 clear_reg = GLOBAL_SP_WRED_AVG_QSIZEr; 3825 } else if (((rval & 0xf00) == 0x200) || ((rval & 0xf00) == 0x300)) { 3826 spci.reg = WRED_CONFIGr; 3827 clear_reg = WRED_AVG_QSIZEr; 3828 rval -= 0x200; 3829 if (rval < 0x8) { 3830 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[64]]; 3831 spci.index = rval; 3832 } else if (rval >= 0x108 && rval <= 0x10f) { 3833 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[65]]; 3834 spci.index = rval - 0x108; 3835 } else { 3836 if (rval < 0x108) { 3837 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/8]]; 3838 spci.index = rval % 8; 3839 } else { 3840 rval -= 0x110; 3841 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/8 + 34]]; 3842 spci.index = rval % 8; 3843 } 3844 } 3845 } else if ((rval & 0xf00) == 0x400) { 3846 spci.reg = PORT_SP_WRED_CONFIGr; 3847 clear_reg = PORT_SP_WRED_AVG_QSIZEr; 3848 rval -= 0x400; 3849 if (rval < 0x4) { 3850 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[64]]; 3851 spci.index = rval; 3852 } else if (rval >= 0x84 && rval <= 0x87) { 3853 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[65]]; 3854 spci.index = rval - 0x84; 3855 } else { 3856 if (rval < 0x84) { 3857 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/4]]; 3858 spci.index = rval % 4; 3859 } else { 3860 rval -= 0x88; 3861 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/4 + 34]]; 3862 spci.index = rval % 4; 3863 } 3864 } 3865 } else if ((rval < 0x200) || ((rval & 0xf00) == 0x500)) { 3866 spci.reg = DMVOQ_WRED_CONFIGr; 3867 clear_reg = VOQ_WRED_AVG_QSIZEr; 3868 if (rval < 0x200) { 3869 spci.port = rval/0x40 + 1; 3870 if (spci.port > 4) { 3871 spci.port += 29; 3872 } 3873 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[spci.port]]; 3874 spci.index = rval % 0x40; 3875 } else { 3876 rval -= 0x500; 3877 spci.port = rval/8 + 1; 3878 if (spci.port > 4) { 3879 spci.port += 29; 3880 } 3881 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[spci.port]]; 3882 spci.index = (rval % 8) + 64; 3883 } 3884 } else { 3885 return SOC_E_INTERNAL; 3886 } 3887 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo); 3888 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3889 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, log, minfo); 3890 3891 spci.blk_type = SOC_BLK_MMU; 3892 LOG_WARN(BSL_LS_SOC_SER, 3893 (BSL_META_U(unit, 3894 "%s %s port %d index %d parity error\n"), prefix_str, 3895 SOC_REG_NAME(unit, spci.reg), spci.port, spci.index)); 3896 (void)soc_ser_correction(unit, &spci); 3897 3898 spci.reg = clear_reg; 3899 LOG_WARN(BSL_LS_SOC_SER, 3900 (BSL_META_U(unit, 3901 "%s %s port %d index %d parity error\n"), prefix_str, 3902 SOC_REG_NAME(unit, spci.reg), spci.port, spci.index)); 3903 3904 spci.detect_time = sal_time_usecs(); 3905 spci.parity_type = info->type; 3906 spci.log_id = soc_ser_log_create_entry(unit, 3907 sizeof(soc_ser_log_tlv_generic_t) + 3908 sizeof(soc_ser_log_tlv_register_t) + 3909 sizeof(soc_ser_log_tlv_hdr_t) *3); 3910 (void)soc_ser_correction(unit, &spci); 3911 } else { 3912 at = ((SOC_MEM_INFO(unit, mem).base & 0xE0000) >> \ 3913 _SOC_MEM_ADDR_ACC_TYPE_SHIFT); 3914 3915 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 3916 spci.reg = INVALIDr; 3917 spci.mem = mem; 3918 spci.blk_type = -1; 3919 spci.index = rval; 3920 spci.acc_type = at; 3921 spci.pipe_num = -1; 3922 spci.parity_type = info->type; 3923 spci.detect_time = sal_time_usecs(); 3924 spci.log_id = soc_ser_log_create_entry(unit, 3925 sizeof(soc_ser_log_tlv_generic_t) + 3926 sizeof(soc_ser_log_tlv_register_t) + 3927 sizeof(soc_ser_log_tlv_hdr_t) *3); 3928 (void)soc_ser_correction(unit, &spci); 3929 } 3930 if (spci.log_id != 0) { 3931 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3932 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3933 spci.log_id, 0); 3934 } 3935 } 3936 3937 /* Clear parity error status */ 3938 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 3939 return SOC_E_NONE; 3940 } 3941 3942 STATIC int 3943 _soc_trident_parity_process_mmu_thdi(int unit, int block_info_idx, 3944 const _soc_trident_parity_info_t *info, 3945 char *prefix_str) 3946 { 3947 uint64 rval64; 3948 uint32 rval, addr, minfo; 3949 soc_info_t *si = &SOC_INFO(unit); 3950 _soc_ser_correct_info_t spci; 3951 3952 sal_memset(&spci, 0, sizeof(spci)); 3953 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 3954 spci.mem = INVALIDm; 3955 spci.blk_type = SOC_BLK_MMU; 3956 SOC_IF_ERROR_RETURN(READ_PARITY_ERROR_STATUS_0r(unit, &rval64)); 3957 rval = COMPILER_64_LO(rval64); 3958 if (rval) { 3959 LOG_VERBOSE(BSL_LS_SOC_SER, 3960 (BSL_META_U(unit, 3961 "thdi pipe 0 status: 0x%08x\n"), rval)); 3962 if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_HITf)) { 3963 addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_ADDRf); 3964 spci.reg = PG_RESET_FLOOR_CELLr; 3965 } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_HITf)) { 3966 addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_ADDRf); 3967 spci.reg = PG_RESET_OFFSET_CELLr; 3968 } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_HITf)) { 3969 addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_ADDRf); 3970 spci.reg = PG_SHARED_LIMIT_CELLr; 3971 } else { 3972 return SOC_E_INTERNAL; 3973 } 3974 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]]; 3975 spci.index = addr%8; 3976 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo); 3977 3978 spci.detect_time = sal_time_usecs(); 3979 spci.parity_type = info->type; 3980 spci.log_id = soc_ser_log_create_entry(unit, 3981 sizeof(soc_ser_log_tlv_generic_t) + 3982 sizeof(soc_ser_log_tlv_register_t) + 3983 sizeof(soc_ser_log_tlv_hdr_t) *3); 3984 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3985 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo); 3986 LOG_WARN(BSL_LS_SOC_SER, 3987 (BSL_META_U(unit, 3988 "%s %s port %d index %d parity error\n"), prefix_str, 3989 SOC_REG_NAME(unit, spci.reg), spci.port, spci.index)); 3990 (void)soc_ser_correction(unit, &spci); 3991 if (spci.log_id != 0) { 3992 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3993 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3994 spci.log_id, 0); 3995 } 3996 } 3997 3998 SOC_IF_ERROR_RETURN(READ_PARITY_ERROR_STATUS_1r(unit, &rval64)); 3999 rval = COMPILER_64_LO(rval64); 4000 if (rval) { 4001 LOG_VERBOSE(BSL_LS_SOC_SER, 4002 (BSL_META_U(unit, 4003 "thdi pipe 1 status: 0x%08x\n"), rval)); 4004 if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_HITf)) { 4005 addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_ADDRf); 4006 spci.reg = PG_RESET_FLOOR_CELLr; 4007 } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_HITf)) { 4008 addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_ADDRf); 4009 spci.reg = PG_RESET_OFFSET_CELLr; 4010 } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_HITf)) { 4011 addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_ADDRf); 4012 spci.reg = PG_SHARED_LIMIT_CELLr; 4013 } else { 4014 return SOC_E_INTERNAL; 4015 } 4016 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]]; 4017 spci.index = addr%8; 4018 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo); 4019 4020 spci.detect_time = sal_time_usecs(); 4021 spci.parity_type = info->type; 4022 spci.log_id = soc_ser_log_create_entry(unit, 4023 sizeof(soc_ser_log_tlv_generic_t) + 4024 sizeof(soc_ser_log_tlv_register_t) + 4025 sizeof(soc_ser_log_tlv_hdr_t) *3); 4026 4027 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4028 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo); 4029 LOG_WARN(BSL_LS_SOC_SER, 4030 (BSL_META_U(unit, 4031 "%s %s port %d index %d parity error\n"), prefix_str, 4032 SOC_REG_NAME(unit, spci.reg), spci.port, spci.index)); 4033 (void)soc_ser_correction(unit, &spci); 4034 if (spci.log_id != 0) { 4035 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4036 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4037 spci.log_id, 0); 4038 } 4039 } 4040 /* Clear parity error status */ 4041 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4042 return SOC_E_NONE; 4043 } 4044 4045 STATIC void 4046 __soc_trident_parity_process_mmu_mtro(int unit, int block_info_idx, 4047 const _soc_trident_parity_info_t *info, 4048 _soc_ser_correct_info_t spci, uint32 addr, 4049 char *prefix_str) 4050 { 4051 uint32 minfo; 4052 4053 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo); 4054 LOG_WARN(BSL_LS_SOC_SER, 4055 (BSL_META_U(unit, 4056 "%s %s port %d index %d parity error\n"), prefix_str, 4057 SOC_REG_NAME(unit, spci.reg), spci.port, spci.index)); 4058 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4059 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, addr, minfo); 4060 spci.detect_time = sal_time_usecs(); 4061 spci.parity_type = info->type; 4062 spci.log_id = soc_ser_log_create_entry(unit, 4063 sizeof(soc_ser_log_tlv_generic_t) + 4064 sizeof(soc_ser_log_tlv_register_t) + 4065 sizeof(soc_ser_log_tlv_hdr_t) *3); 4066 (void)soc_ser_correction(unit, &spci); 4067 if (spci.log_id != 0) { 4068 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4069 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4070 spci.log_id, 0); 4071 } 4072 } 4073 4074 STATIC int 4075 _soc_trident_parity_process_mmu_mtro(int unit, int block_info_idx, 4076 const _soc_trident_parity_info_t *info, 4077 char *prefix_str) 4078 { 4079 uint32 val, addr; 4080 soc_info_t *si = &SOC_INFO(unit); 4081 _soc_ser_correct_info_t spci; 4082 4083 sal_memset(&spci, 0, sizeof(spci)); 4084 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 4085 spci.mem = INVALIDm; 4086 spci.blk_type = SOC_BLK_MMU; 4087 4088 SOC_IF_ERROR_RETURN(READ_EGRSHAPEPARITYERRORPTRr(unit, &addr)); 4089 LOG_VERBOSE(BSL_LS_SOC_SER, 4090 (BSL_META_U(unit, 4091 "MTRO addr: %d\n"), addr)); 4092 4093 /* Disable parity */ 4094 SOC_IF_ERROR_RETURN 4095 (READ_MISCCONFIGr(unit, &val)); 4096 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0); 4097 SOC_IF_ERROR_RETURN 4098 (WRITE_MISCCONFIGr(unit, val)); 4099 4100 if (addr < 48) { /* Xpipe first port */ 4101 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[0]]; 4102 spci.index = addr; 4103 spci.reg = MINBUCKETCONFIG_64r; 4104 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4105 addr, prefix_str); 4106 spci.reg = MAXBUCKETCONFIG_64r; 4107 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4108 addr, prefix_str); 4109 spci.reg = MINBUCKETr; 4110 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4111 addr, prefix_str); 4112 spci.reg = MAXBUCKETr; 4113 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4114 addr, prefix_str); 4115 if (addr < 5) { /* Ypipe first port */ 4116 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[0 + 33]]; 4117 spci.reg = MINBUCKETCONFIG_64r; 4118 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4119 addr, prefix_str); 4120 spci.reg = MAXBUCKETCONFIG_64r; 4121 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4122 addr, prefix_str); 4123 spci.reg = MINBUCKETr; 4124 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4125 addr, prefix_str); 4126 spci.reg = MAXBUCKETr; 4127 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4128 addr, prefix_str); 4129 } 4130 } else { 4131 if (addr < 364) { 4132 val = addr; 4133 val -= 48; 4134 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/79 + 1]]; 4135 spci.index = val%79; 4136 spci.reg = MINBUCKETCONFIG_64r; 4137 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4138 addr, prefix_str); 4139 spci.reg = MAXBUCKETCONFIG_64r; 4140 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4141 addr, prefix_str); 4142 spci.reg = MINBUCKETr; 4143 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4144 addr, prefix_str); 4145 spci.reg = MAXBUCKETr; 4146 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4147 addr, prefix_str); 4148 } else if (addr <= 393 || addr >= 396) { /* skip hole */ 4149 val = addr; 4150 if (addr > 393) { /* re-align */ 4151 val -= 2; 4152 } 4153 val -= 364; 4154 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/15 + 5]]; 4155 spci.index = val%15; 4156 spci.reg = MINBUCKETCONFIG_64r; 4157 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4158 addr, prefix_str); 4159 spci.reg = MAXBUCKETCONFIG_64r; 4160 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4161 addr, prefix_str); 4162 spci.reg = MINBUCKETr; 4163 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4164 addr, prefix_str); 4165 spci.reg = MAXBUCKETr; 4166 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4167 addr, prefix_str); 4168 } 4169 if (addr < 321) { 4170 val = addr; 4171 val -= 5; 4172 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/79 + 34]]; 4173 spci.index = val%79; 4174 spci.reg = MINBUCKETCONFIG_64r; 4175 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4176 addr, prefix_str); 4177 spci.reg = MAXBUCKETCONFIG_64r; 4178 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4179 addr, prefix_str); 4180 spci.reg = MINBUCKETr; 4181 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4182 addr, prefix_str); 4183 spci.reg = MAXBUCKETr; 4184 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4185 addr, prefix_str); 4186 } else if (addr <= 350 || addr >= 396) { /* skip hole */ 4187 val = addr; 4188 if (addr > 350) { 4189 val -= 45; /* re-align */ 4190 } 4191 val -= 321; 4192 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/15 + 38]]; 4193 spci.index = val%15; 4194 spci.reg = MINBUCKETCONFIG_64r; 4195 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4196 addr, prefix_str); 4197 spci.reg = MAXBUCKETCONFIG_64r; 4198 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4199 addr, prefix_str); 4200 spci.reg = MINBUCKETr; 4201 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4202 addr, prefix_str); 4203 spci.reg = MAXBUCKETr; 4204 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4205 addr, prefix_str); 4206 } 4207 } 4208 if (addr <= 131) { /* S2, S3 */ 4209 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/4]]; 4210 spci.index = addr%4; 4211 spci.reg = S2_MINBUCKETCONFIG_64r; 4212 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4213 addr, prefix_str); 4214 spci.reg = S2_MAXBUCKETCONFIG_64r; 4215 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4216 addr, prefix_str); 4217 spci.reg = S3_MINBUCKETCONFIG_64r; 4218 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4219 addr, prefix_str); 4220 spci.reg = S3_MAXBUCKETCONFIG_64r; 4221 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4222 addr, prefix_str); 4223 spci.reg = S2_MINBUCKETr; 4224 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4225 addr, prefix_str); 4226 spci.reg = S2_MAXBUCKETr; 4227 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4228 addr, prefix_str); 4229 spci.reg = S3_MINBUCKETr; 4230 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4231 addr, prefix_str); 4232 spci.reg = S3_MAXBUCKETr; 4233 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4234 addr, prefix_str); 4235 4236 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/4 + 33]]; 4237 spci.reg = S2_MINBUCKETCONFIG_64r; 4238 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4239 addr, prefix_str); 4240 spci.reg = S2_MAXBUCKETCONFIG_64r; 4241 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4242 addr, prefix_str); 4243 spci.reg = S3_MINBUCKETCONFIG_64r; 4244 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4245 addr, prefix_str); 4246 spci.reg = S3_MAXBUCKETCONFIG_64r; 4247 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4248 addr, prefix_str); 4249 spci.reg = S2_MINBUCKETr; 4250 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4251 addr, prefix_str); 4252 spci.reg = S2_MAXBUCKETr; 4253 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4254 addr, prefix_str); 4255 spci.reg = S3_MINBUCKETr; 4256 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4257 addr, prefix_str); 4258 spci.reg = S3_MAXBUCKETr; 4259 __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci, 4260 addr, prefix_str); 4261 } 4262 /* Clear parity error status */ 4263 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4264 4265 /* Enable parity */ 4266 SOC_IF_ERROR_RETURN 4267 (READ_MISCCONFIGr(unit, &val)); 4268 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1); 4269 SOC_IF_ERROR_RETURN 4270 (WRITE_MISCCONFIGr(unit, val)); 4271 return SOC_E_NONE; 4272 } 4273 4274 STATIC void 4275 __soc_trident_parity_process_mmu_es(int unit, int block_info_idx, 4276 const _soc_trident_parity_info_t *info, 4277 _soc_ser_correct_info_t spci, uint32 addr, 4278 char *prefix_str) 4279 { 4280 uint32 minfo; 4281 4282 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo); 4283 LOG_WARN(BSL_LS_SOC_SER, 4284 (BSL_META_U(unit, 4285 "%s %s port %d index %d parity error\n"), prefix_str, 4286 SOC_REG_NAME(unit, spci.reg), spci.port, spci.index)); 4287 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4288 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, addr, minfo); 4289 4290 spci.detect_time = sal_time_usecs(); 4291 spci.parity_type = info->type; 4292 spci.log_id = soc_ser_log_create_entry(unit, 4293 sizeof(soc_ser_log_tlv_generic_t) + 4294 sizeof(soc_ser_log_tlv_register_t) + 4295 sizeof(soc_ser_log_tlv_hdr_t) *3); 4296 (void)soc_ser_correction(unit, &spci); 4297 if (spci.log_id != 0) { 4298 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4299 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4300 spci.log_id, 0); 4301 } 4302 } 4303 4304 STATIC int 4305 _soc_trident_parity_process_mmu_es(int unit, int block_info_idx, 4306 const _soc_trident_parity_info_t *info, 4307 char *prefix_str) 4308 { 4309 uint32 val, addr = 0; 4310 uint64 rval64; 4311 soc_info_t *si = &SOC_INFO(unit); 4312 _soc_ser_correct_info_t spci; 4313 4314 sal_memset(&spci, 0, sizeof(spci)); 4315 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 4316 spci.mem = INVALIDm; 4317 spci.blk_type = SOC_BLK_MMU; 4318 4319 SOC_IF_ERROR_RETURN(READ_ES_S2_MEMORY_PARITY_STATUS_0r(unit, &rval64)); 4320 if (!COMPILER_64_IS_ZERO(rval64)) { 4321 LOG_VERBOSE(BSL_LS_SOC_SER, 4322 (BSL_META_U(unit, 4323 "ES S2 pipe 0 status: 0x%02x%08x\n"), 4324 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64))); 4325 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4326 CREDIT_SHAPE_BUS_HITf)) { 4327 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4328 CREDIT_SHAPE_BUS_ADDRESSf); 4329 spci.reg = S2_WERRCOUNTr; 4330 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]]; 4331 spci.index = addr%12; 4332 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4333 addr, prefix_str); 4334 } 4335 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4336 CREDIT_CELL_XMIT_BUS_HITf)) { 4337 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4338 CREDIT_CELL_XMIT_BUS_ADDRESSf); 4339 spci.reg = S2_WERRCOUNTr; 4340 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]]; 4341 spci.index = addr%12; 4342 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4343 addr, prefix_str); 4344 } 4345 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4346 WEIGHT_SHAPE_BUS_HITf)) { 4347 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4348 WEIGHT_SHAPE_BUS_ADDRESSf); 4349 spci.reg = S2_COSWEIGHTSr; 4350 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]]; 4351 spci.index = addr%12; 4352 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4353 addr, prefix_str); 4354 } 4355 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4356 WEIGHT_CELL_XMIT_BUS_HITf)) { 4357 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64, 4358 WEIGHT_CELL_XMIT_BUS_ADDRESSf); 4359 spci.reg = S2_COSWEIGHTSr; 4360 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]]; 4361 spci.index = addr%12; 4362 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4363 addr, prefix_str); 4364 } 4365 } 4366 SOC_IF_ERROR_RETURN(READ_ES_S2_MEMORY_PARITY_STATUS_1r(unit, &rval64)); 4367 if (!COMPILER_64_IS_ZERO(rval64)) { 4368 LOG_VERBOSE(BSL_LS_SOC_SER, 4369 (BSL_META_U(unit, 4370 "ES S2 pipe 1 status: 0x%02x%08x\n"), 4371 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64))); 4372 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4373 CREDIT_SHAPE_BUS_HITf)) { 4374 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4375 CREDIT_SHAPE_BUS_ADDRESSf); 4376 spci.reg = S2_WERRCOUNTr; 4377 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]]; 4378 spci.index = addr%12; 4379 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4380 addr, prefix_str); 4381 } 4382 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4383 CREDIT_CELL_XMIT_BUS_HITf)) { 4384 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4385 CREDIT_CELL_XMIT_BUS_ADDRESSf); 4386 spci.reg = S2_WERRCOUNTr; 4387 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]]; 4388 spci.index = addr%12; 4389 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4390 addr, prefix_str); 4391 } 4392 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4393 WEIGHT_SHAPE_BUS_HITf)) { 4394 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4395 WEIGHT_SHAPE_BUS_ADDRESSf); 4396 spci.reg = S2_COSWEIGHTSr; 4397 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]]; 4398 spci.index = addr%12; 4399 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4400 addr, prefix_str); 4401 } 4402 if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4403 WEIGHT_CELL_XMIT_BUS_HITf)) { 4404 addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64, 4405 WEIGHT_CELL_XMIT_BUS_ADDRESSf); 4406 spci.reg = S2_COSWEIGHTSr; 4407 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]]; 4408 spci.index = addr%12; 4409 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4410 addr, prefix_str); 4411 } 4412 } 4413 SOC_IF_ERROR_RETURN(READ_ES_S3_MEMORY_PARITY_STATUS_0r(unit, &rval64)); 4414 if (!COMPILER_64_IS_ZERO(rval64)) { 4415 LOG_VERBOSE(BSL_LS_SOC_SER, 4416 (BSL_META_U(unit, 4417 "ES S3 pipe 0 status: 0x%04x%08x\n"), 4418 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64))); 4419 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4420 CREDIT_SHAPE_BUS_HITf)) { 4421 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4422 CREDIT_SHAPE_BUS_ADDRESSf); 4423 if (addr > 7 && addr < 296) { 4424 val = addr-8; 4425 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]]; 4426 spci.index = val%72; 4427 } else { 4428 if (addr > 295) { 4429 val = addr - 296; 4430 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]]; 4431 spci.index = val%8; 4432 } else { 4433 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]]; 4434 spci.index = addr%8; 4435 } 4436 } 4437 spci.reg = S3_WERRCOUNTr; 4438 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4439 addr, prefix_str); 4440 } 4441 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4442 CREDIT_CELL_XMIT_BUS_HITf)) { 4443 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4444 CREDIT_CELL_XMIT_BUS_ADDRESSf); 4445 if (addr > 7 && addr < 296) { 4446 val = addr - 8; 4447 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]]; 4448 spci.index = val%72; 4449 } else { 4450 if (addr > 295) { 4451 val = addr - 296; 4452 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]]; 4453 spci.index = val%8; 4454 } else { 4455 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]]; 4456 spci.index = addr%8; 4457 } 4458 } 4459 spci.reg = S3_WERRCOUNTr; 4460 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4461 addr, prefix_str); 4462 } 4463 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4464 WEIGHT_SHAPE_BUS_HITf)) { 4465 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4466 WEIGHT_SHAPE_BUS_ADDRESSf); 4467 if (addr > 7 && addr < 296) { 4468 val = addr - 8; 4469 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]]; 4470 spci.index = val%72; 4471 } else { 4472 if (addr > 295) { 4473 val = addr - 296; 4474 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]]; 4475 spci.index = val%8; 4476 } else { 4477 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]]; 4478 spci.index = addr%8; 4479 } 4480 } 4481 spci.reg = S3_COSWEIGHTSr; 4482 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4483 addr, prefix_str); 4484 } 4485 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4486 WEIGHT_CELL_XMIT_BUS_HITf)) { 4487 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64, 4488 WEIGHT_CELL_XMIT_BUS_ADDRESSf); 4489 if (addr > 7 && addr < 296) { 4490 val = addr - 8; 4491 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]]; 4492 spci.index = val%72; 4493 } else { 4494 if (addr > 295) { 4495 val = addr - 296; 4496 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]]; 4497 spci.index = val%8; 4498 } else { 4499 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]]; 4500 spci.index = addr%8; 4501 } 4502 } 4503 spci.reg = S3_COSWEIGHTSr; 4504 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4505 addr, prefix_str); 4506 } 4507 } 4508 SOC_IF_ERROR_RETURN(READ_ES_S3_MEMORY_PARITY_STATUS_1r(unit, &rval64)); 4509 if (!COMPILER_64_IS_ZERO(rval64)) { 4510 LOG_VERBOSE(BSL_LS_SOC_SER, 4511 (BSL_META_U(unit, 4512 "ES S3 pipe 1 status: 0x%04x%08x\n"), 4513 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64))); 4514 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4515 CREDIT_SHAPE_BUS_HITf)) { 4516 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4517 CREDIT_SHAPE_BUS_ADDRESSf); 4518 if (addr > 7 && addr < 296) { 4519 val = addr - 8; 4520 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]]; 4521 spci.index = val%72; 4522 } else { 4523 if (addr > 295) { 4524 val = addr - 296; 4525 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]]; 4526 spci.index = val%8; 4527 } else { 4528 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]]; 4529 spci.index = addr%8; 4530 } 4531 } 4532 spci.reg = S3_WERRCOUNTr; 4533 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4534 addr, prefix_str); 4535 } 4536 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4537 CREDIT_CELL_XMIT_BUS_HITf)) { 4538 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4539 CREDIT_CELL_XMIT_BUS_ADDRESSf); 4540 if (addr > 7 && addr < 296) { 4541 val = addr - 8; 4542 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]]; 4543 spci.index = val%72; 4544 } else { 4545 if (addr > 295) { 4546 val = addr - 296; 4547 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]]; 4548 spci.index = val%8; 4549 } else { 4550 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]]; 4551 spci.index = addr%8; 4552 } 4553 } 4554 spci.reg = S3_WERRCOUNTr; 4555 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4556 addr, prefix_str); 4557 } 4558 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4559 WEIGHT_SHAPE_BUS_HITf)) { 4560 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4561 WEIGHT_SHAPE_BUS_ADDRESSf); 4562 if (addr > 7 && addr < 296) { 4563 val = addr - 8; 4564 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]]; 4565 spci.index = val%72; 4566 } else { 4567 if (addr > 295) { 4568 val = addr - 296; 4569 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]]; 4570 spci.index = val%8; 4571 } else { 4572 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]]; 4573 spci.index = addr%8; 4574 } 4575 } 4576 spci.reg = S3_COSWEIGHTSr; 4577 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4578 addr, prefix_str); 4579 } 4580 if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4581 WEIGHT_CELL_XMIT_BUS_HITf)) { 4582 addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64, 4583 WEIGHT_CELL_XMIT_BUS_ADDRESSf); 4584 if (addr > 7 && addr < 296) { 4585 val = addr - 8; 4586 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]]; 4587 spci.index = val%72; 4588 } else { 4589 if (addr > 295) { 4590 val = addr - 296; 4591 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]]; 4592 spci.index = val%8; 4593 } else { 4594 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]]; 4595 spci.index = addr%8; 4596 } 4597 } 4598 spci.reg = S3_COSWEIGHTSr; 4599 __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci, 4600 addr, prefix_str); 4601 } 4602 } 4603 4604 /* Clear parity error status */ 4605 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4606 return SOC_E_NONE; 4607 } 4608 4609 STATIC int 4610 _soc_trident_parity_process_mmu_ipmc(int unit, int block_info_idx, 4611 const _soc_trident_parity_info_t *info, 4612 char *prefix_str) 4613 { 4614 #define _SOC_TD_MMU_IPMC_GROUP_MAX 17 4615 #define _SOC_TD_MMU_IPMC_SUB_GROUP_MAX 4 4616 static soc_mem_t ipmc_mems[_SOC_TD_MMU_IPMC_GROUP_MAX] 4617 [_SOC_TD_MMU_IPMC_SUB_GROUP_MAX] = { 4618 { MMU_IPMC_GROUP_TBL1m, MMU_IPMC_GROUP_TBL5m, 4619 MMU_IPMC_GROUP_TBL9m, MMU_IPMC_GROUP_TBL13m }, 4620 { MMU_IPMC_GROUP_TBL2m, MMU_IPMC_GROUP_TBL6m, 4621 MMU_IPMC_GROUP_TBL10m, MMU_IPMC_GROUP_TBL14m }, 4622 { MMU_IPMC_GROUP_TBL3m, MMU_IPMC_GROUP_TBL7m, 4623 MMU_IPMC_GROUP_TBL11m, MMU_IPMC_GROUP_TBL15m }, 4624 { MMU_IPMC_GROUP_TBL4m, MMU_IPMC_GROUP_TBL8m, 4625 MMU_IPMC_GROUP_TBL12m, MMU_IPMC_GROUP_TBL16m }, 4626 { MMU_IPMC_GROUP_TBL17m, MMU_IPMC_GROUP_TBL21m, 4627 MMU_IPMC_GROUP_TBL25m, MMU_IPMC_GROUP_TBL29m }, 4628 { MMU_IPMC_GROUP_TBL18m, MMU_IPMC_GROUP_TBL22m, 4629 MMU_IPMC_GROUP_TBL26m, MMU_IPMC_GROUP_TBL30m }, 4630 { MMU_IPMC_GROUP_TBL19m, MMU_IPMC_GROUP_TBL23m, 4631 MMU_IPMC_GROUP_TBL27m, MMU_IPMC_GROUP_TBL31m }, 4632 { MMU_IPMC_GROUP_TBL20m, MMU_IPMC_GROUP_TBL24m, 4633 MMU_IPMC_GROUP_TBL28m, MMU_IPMC_GROUP_TBL32m }, 4634 { MMU_IPMC_GROUP_TBL34m, MMU_IPMC_GROUP_TBL38m, 4635 MMU_IPMC_GROUP_TBL42m, MMU_IPMC_GROUP_TBL46m }, 4636 { MMU_IPMC_GROUP_TBL35m, MMU_IPMC_GROUP_TBL39m, 4637 MMU_IPMC_GROUP_TBL43m, MMU_IPMC_GROUP_TBL47m }, 4638 { MMU_IPMC_GROUP_TBL36m, MMU_IPMC_GROUP_TBL40m, 4639 MMU_IPMC_GROUP_TBL44m, MMU_IPMC_GROUP_TBL48m }, 4640 { MMU_IPMC_GROUP_TBL37m, MMU_IPMC_GROUP_TBL41m, 4641 MMU_IPMC_GROUP_TBL45m, MMU_IPMC_GROUP_TBL49m }, 4642 { MMU_IPMC_GROUP_TBL50m, MMU_IPMC_GROUP_TBL54m, 4643 MMU_IPMC_GROUP_TBL58m, MMU_IPMC_GROUP_TBL62m }, 4644 { MMU_IPMC_GROUP_TBL51m, MMU_IPMC_GROUP_TBL55m, 4645 MMU_IPMC_GROUP_TBL59m, MMU_IPMC_GROUP_TBL63m }, 4646 { MMU_IPMC_GROUP_TBL52m, MMU_IPMC_GROUP_TBL56m, 4647 MMU_IPMC_GROUP_TBL60m, MMU_IPMC_GROUP_TBL64m }, 4648 { MMU_IPMC_GROUP_TBL53m, MMU_IPMC_GROUP_TBL57m, 4649 MMU_IPMC_GROUP_TBL61m, MMU_IPMC_GROUP_TBL65m }, 4650 { MMU_IPMC_GROUP_TBL33m, INVALIDm, 4651 INVALIDm, INVALIDm }, 4652 }; 4653 uint32 rval, minfo; 4654 uint32 grp, sub_grp, index; 4655 _soc_ser_correct_info_t spci; 4656 4657 sal_memset(&spci, 0, sizeof(spci)); 4658 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 4659 spci.reg = INVALIDr; 4660 spci.blk_type = SOC_BLK_MMU; 4661 4662 SOC_IF_ERROR_RETURN(READ_MCQ_GRPTBLERRPTRr(unit, &rval)); 4663 grp = soc_reg_field_get(unit, MCQ_GRPTBLERRPTRr, rval, GRPTBLERRORINSTANCEf); 4664 sub_grp = grp & 0x3; 4665 grp = grp >> 2; 4666 index = soc_reg_field_get(unit, MCQ_GRPTBLERRPTRr, rval, GRPTBLERRORPOINTERf); 4667 if (grp >= _SOC_TD_MMU_IPMC_GROUP_MAX || 4668 sub_grp >= _SOC_TD_MMU_IPMC_SUB_GROUP_MAX || 4669 index > soc_mem_index_max(unit, ipmc_mems[0][0])) { 4670 return SOC_E_INTERNAL; 4671 } 4672 if (INVALIDm == ipmc_mems[grp][sub_grp]) { 4673 return SOC_E_INTERNAL; 4674 } 4675 spci.mem = ipmc_mems[grp][sub_grp]; 4676 spci.index = index; 4677 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, 4678 &minfo); 4679 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4680 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo); 4681 LOG_WARN(BSL_LS_SOC_SER, 4682 (BSL_META_U(unit, 4683 "%s %s index %d parity error\n"), prefix_str, 4684 SOC_MEM_NAME(unit, spci.mem), spci.index)); 4685 spci.detect_time = sal_time_usecs(); 4686 spci.parity_type = info->type; 4687 spci.log_id = _soc_trident_populate_ser_log(unit, 4688 info->enable_reg, info->enable_field, spci.mem, 4689 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 4690 spci.index, spci.detect_time, spci.sblk, spci.addr); 4691 4692 (void)soc_ser_correction(unit, &spci); 4693 if (spci.log_id != 0) { 4694 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4695 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4696 spci.log_id, 0); 4697 } 4698 /* Clear parity error status */ 4699 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4700 4701 return SOC_E_NONE; 4702 } 4703 4704 STATIC int 4705 _soc_trident_parity_process_mmu_vlan(int unit, int block_info_idx, 4706 const _soc_trident_parity_info_t *info, 4707 char *prefix_str) 4708 { 4709 uint32 index, rval, minfo; 4710 _soc_ser_correct_info_t spci; 4711 4712 sal_memset(&spci, 0, sizeof(spci)); 4713 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 4714 spci.reg = INVALIDr; 4715 spci.blk_type = SOC_BLK_MMU; 4716 4717 SOC_IF_ERROR_RETURN(READ_MCQ_VLANTBLERRPTRr(unit, &rval)); 4718 index = soc_reg_field_get(unit, MCQ_VLANTBLERRPTRr, rval, VLANTBLERRORPOINTERf); 4719 4720 if (index > soc_mem_index_max(unit, MMU_IPMC_VLAN_TBLm)) { 4721 return SOC_E_INTERNAL; 4722 } 4723 spci.mem = MMU_IPMC_VLAN_TBLm; 4724 spci.index = index; 4725 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, 4726 &minfo); 4727 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4728 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo); 4729 LOG_WARN(BSL_LS_SOC_SER, 4730 (BSL_META_U(unit, 4731 "%s %s index %d parity error\n"), prefix_str, 4732 SOC_MEM_NAME(unit, spci.mem), spci.index)); 4733 spci.detect_time = sal_time_usecs(); 4734 spci.parity_type = info->type; 4735 spci.log_id = _soc_trident_populate_ser_log(unit, 4736 info->enable_reg, info->enable_field, spci.mem, 4737 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 4738 spci.index, spci.detect_time, spci.sblk, spci.addr); 4739 (void)soc_ser_correction(unit, &spci); 4740 if (spci.log_id != 0) { 4741 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4742 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4743 spci.log_id, 0); 4744 } 4745 /* Clear parity error status */ 4746 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4747 return SOC_E_NONE; 4748 } 4749 4750 STATIC int 4751 _soc_trident_parity_process_mmu_aging(int unit, int block_info_idx, 4752 const _soc_trident_parity_info_t *info, 4753 char *prefix_str) 4754 { 4755 uint32 index, status, rval, minfo; 4756 _soc_ser_correct_info_t spci; 4757 4758 sal_memset(&spci, 0, sizeof(spci)); 4759 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 4760 spci.reg = INVALIDr; 4761 spci.blk_type = SOC_BLK_MMU; 4762 4763 SOC_IF_ERROR_RETURN(READ_PERR_STATr(unit, &status)); 4764 if (soc_reg_field_get(unit, PERR_STATr, status, EXP_ERRf)) { 4765 SOC_IF_ERROR_RETURN(READ_PERR_PTR_EXPr(unit, &rval)); 4766 index = soc_reg_field_get(unit, PERR_PTR_EXPr, rval, PTRf); 4767 spci.mem = MMU_AGING_EXPm; 4768 } else if (soc_reg_field_get(unit, PERR_STATr, status, CTR_ERRf)) { 4769 SOC_IF_ERROR_RETURN(READ_PERR_PTR_CTRr(unit, &rval)); 4770 index = soc_reg_field_get(unit, PERR_PTR_CTRr, rval, PTRf); 4771 spci.mem = MMU_AGING_CTRm; 4772 } else { 4773 LOG_ERROR(BSL_LS_SOC_SER, 4774 (BSL_META_U(unit, 4775 "%s %s parity hardware inconsistency\n"), 4776 prefix_str, "mmu aging")); 4777 return SOC_E_NONE; 4778 } 4779 4780 spci.index = index; 4781 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, 4782 &minfo); 4783 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4784 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, status, minfo); 4785 LOG_WARN(BSL_LS_SOC_SER, 4786 (BSL_META_U(unit, 4787 "%s %s index %d parity error\n"), prefix_str, 4788 SOC_MEM_NAME(unit, spci.mem), spci.index)); 4789 spci.detect_time = sal_time_usecs(); 4790 spci.parity_type = info->type; 4791 spci.log_id = _soc_trident_populate_ser_log(unit, 4792 info->enable_reg, info->enable_field, spci.mem, 4793 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 4794 spci.index, spci.detect_time, spci.sblk, spci.addr); 4795 (void)soc_ser_correction(unit, &spci); 4796 if (spci.log_id != 0) { 4797 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4798 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4799 spci.log_id, 0); 4800 } 4801 /* Clear parity error status */ 4802 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4803 return SOC_E_NONE; 4804 } 4805 4806 STATIC int 4807 _soc_trident_parity_process_mmu_ctr(int unit, int block_info_idx, 4808 const _soc_trident_parity_info_t *info, 4809 char *prefix_str) 4810 { 4811 uint32 index, status, memid, minfo; 4812 _soc_ser_correct_info_t spci; 4813 4814 sal_memset(&spci, 0, sizeof(spci)); 4815 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 4816 spci.reg = INVALIDr; 4817 spci.blk_type = SOC_BLK_MMU; 4818 4819 SOC_IF_ERROR_RETURN(READ_MMU_CTR_PARITY_ERRr(unit, &status)); 4820 memid = soc_reg_field_get(unit, MMU_CTR_PARITY_ERRr, status, MEMIDf); 4821 if (memid == 0x1 || memid == 0x2) { 4822 spci.mem = MMU_CTR_UC_DROP_MEMm; 4823 } else if (memid == 0x4) { 4824 spci.mem = MMU_CTR_MC_DROP_MEMm; 4825 } else if (memid == 0x8) { 4826 spci.mem = MMU_CTR_COLOR_DROP_MEMm; 4827 } else { 4828 LOG_ERROR(BSL_LS_SOC_SER, 4829 (BSL_META_U(unit, 4830 "%s %s parity hardware inconsistency\n"), 4831 prefix_str, "mmu ctr")); 4832 return SOC_E_NONE; 4833 } 4834 index = soc_reg_field_get(unit, MMU_CTR_PARITY_ERRr, status, ERRADDRf); 4835 spci.index = index; 4836 _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, 4837 &minfo); 4838 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4839 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, status, minfo); 4840 LOG_WARN(BSL_LS_SOC_SER, 4841 (BSL_META_U(unit, 4842 "%s %s index %d parity error\n"), prefix_str, 4843 SOC_MEM_NAME(unit, spci.mem), spci.index)); 4844 spci.detect_time = sal_time_usecs(); 4845 spci.parity_type = info->type; 4846 spci.log_id = _soc_trident_populate_ser_log(unit, 4847 info->enable_reg, info->enable_field, spci.mem, 4848 SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type, 4849 spci.index, spci.detect_time, spci.sblk, spci.addr); 4850 (void)soc_ser_correction(unit, &spci); 4851 if (spci.log_id != 0) { 4852 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4853 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4854 spci.log_id, 0); 4855 } 4856 /* Clear parity error status */ 4857 _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field); 4858 return SOC_E_NONE; 4859 } 4860 4861 4862 STATIC int 4863 _soc_trident_parity_process_xlport(int unit, soc_block_t blocktype, int pipe, 4864 const _soc_trident_parity_info_t *info) 4865 { 4866 soc_reg_t xlport_reg; 4867 uint32 xlport_rval; 4868 int block_info_idx, inst_num, port; 4869 char prefix_str[24]; 4870 4871 if (info->intr_status_reg == INVALIDr) { 4872 return SOC_E_NONE; 4873 } 4874 4875 port = -1; 4876 inst_num = info->id + pipe * 9; 4877 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) { 4878 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) { 4879 port = SOC_BLOCK_PORT(unit, block_info_idx); 4880 break; 4881 } 4882 } 4883 if (port < 0) { 4884 return SOC_E_NONE; 4885 } 4886 4887 xlport_reg = info->intr_status_reg; 4888 SOC_IF_ERROR_RETURN 4889 (soc_reg32_get(unit, xlport_reg, port, 0, &xlport_rval)); 4890 if (xlport_rval == 0) { 4891 return SOC_E_NONE; 4892 } 4893 4894 sal_sprintf(prefix_str, "unit %d XLPORT%d", unit, inst_num); 4895 SOC_IF_ERROR_RETURN 4896 (_soc_trident_parity_process_info(unit, blocktype, block_info_idx, pipe, 4897 xlport_reg, xlport_rval, 4898 info->info, prefix_str)); 4899 4900 return SOC_E_NONE; 4901 } 4902 4903 STATIC int 4904 _soc_trident_parity_process_info(int unit, soc_block_t blocktype, 4905 int block_info_idx, int pipe, 4906 soc_reg_t group_reg, uint32 group_rval, 4907 const _soc_trident_parity_info_t *info_list, 4908 char *prefix_str) 4909 { 4910 const _soc_trident_parity_info_t *info; 4911 int info_index; 4912 char *mem_str; 4913 uint32 minfo; 4914 soc_ser_log_tlv_generic_t log_generic; 4915 int log_id; 4916 4917 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 4918 /* Loop through each info entry in the list */ 4919 for (info_index = 0; ; info_index++) { 4920 info = &info_list[info_index]; 4921 if (info->type == _SOC_PARITY_TYPE_NONE) { 4922 /* End of table */ 4923 break; 4924 } 4925 4926 /* Check status for the info entry in the group register */ 4927 if (!soc_reg_field_get(unit, group_reg, group_rval, 4928 info->group_reg_status_field)) { 4929 continue; 4930 } 4931 4932 if (info->mem_str) { 4933 mem_str = info->mem_str; 4934 } else if (info->mem != INVALIDm) { 4935 mem_str = SOC_MEM_NAME(unit, info->mem); 4936 } else { 4937 mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field); 4938 } 4939 4940 /* Handle different parity error reporting style */ 4941 switch (info->type) { 4942 case _SOC_PARITY_TYPE_GENERIC: 4943 _soc_mem_parity_info(unit, block_info_idx, pipe, 4944 info->group_reg_status_field, &minfo); 4945 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4946 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0, 4947 minfo); 4948 4949 log_generic.time = sal_time_usecs(); 4950 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 4951 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 4952 log_generic.parity_type = info->type; 4953 4954 log_id = soc_ser_log_create_entry(unit, 4955 sizeof(soc_ser_log_tlv_generic_t) + 4956 sizeof(soc_ser_log_tlv_hdr_t) *2); 4957 4958 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 4959 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 4960 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4961 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 4962 4963 _soc_trident_parity_generic_clear(unit, blocktype, pipe, 4964 group_reg, info, prefix_str, mem_str); 4965 break; 4966 case _SOC_PARITY_TYPE_PARITY: 4967 /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */ 4968 SOC_IF_ERROR_RETURN 4969 (_soc_trident_parity_process_parity(unit, 0, block_info_idx, 4970 pipe, info, FALSE, 4971 prefix_str, mem_str)); 4972 break; 4973 case _SOC_PARITY_TYPE_ECC: 4974 /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */ 4975 SOC_IF_ERROR_RETURN 4976 (_soc_trident_parity_process_ecc(unit, block_info_idx, pipe, 4977 info, FALSE, 4978 prefix_str, mem_str)); 4979 break; 4980 case _SOC_PARITY_TYPE_HASH: 4981 /* PARITY_ERR_BMf, MULTIPLE_ERRf, BUCKET_IDXf */ 4982 SOC_IF_ERROR_RETURN 4983 (_soc_trident_parity_process_hash(unit, block_info_idx, 4984 pipe, info, FALSE, 4985 prefix_str, mem_str)); 4986 break; 4987 case _SOC_PARITY_TYPE_EDATABUF: 4988 /* ECC_ERR_MGRPf, ECC_ERR_2B_MGRPf, ECC_MULTI_MGRPf */ 4989 SOC_IF_ERROR_RETURN 4990 (_soc_trident_parity_process_edatabuf(unit, block_info_idx, 4991 pipe, info, FALSE, 4992 prefix_str, mem_str)); 4993 break; 4994 case _SOC_PARITY_TYPE_COUNTER: 4995 /* PARITY_ERRf, MULTIPLE_ERRf, COUNTER_IDXf, PORT_IDX, 4996 ENTRY_IDXf */ 4997 SOC_IF_ERROR_RETURN 4998 (_soc_trident_parity_process_counter(unit, blocktype, block_info_idx, 4999 pipe, info, FALSE, 5000 prefix_str, mem_str)); 5001 break; 5002 case _SOC_PARITY_TYPE_XLPORT: 5003 /* One more level of report tree structure */ 5004 SOC_IF_ERROR_RETURN 5005 (_soc_trident_parity_process_xlport(unit, blocktype, pipe, info)); 5006 break; 5007 case _SOC_PARITY_TYPE_MMU_THDO: 5008 SOC_IF_ERROR_RETURN 5009 (_soc_trident_parity_process_mmu_thdo(unit, block_info_idx, 5010 info, prefix_str)); 5011 break; 5012 case _SOC_PARITY_TYPE_START_ERR: 5013 SOC_IF_ERROR_RETURN 5014 (_soc_trident_parity_process_start_err(unit, block_info_idx, 5015 info, prefix_str)); 5016 break; 5017 case _SOC_PARITY_TYPE_MMU_WRED: 5018 SOC_IF_ERROR_RETURN 5019 (_soc_trident_parity_process_mmu_wred(unit, block_info_idx, 5020 info, prefix_str)); 5021 break; 5022 case _SOC_PARITY_TYPE_MMU_THDI: 5023 SOC_IF_ERROR_RETURN 5024 (_soc_trident_parity_process_mmu_thdi(unit, block_info_idx, 5025 info, prefix_str)); 5026 break; 5027 case _SOC_PARITY_TYPE_MMU_MTRO: 5028 SOC_IF_ERROR_RETURN 5029 (_soc_trident_parity_process_mmu_mtro(unit, block_info_idx, 5030 info, prefix_str)); 5031 break; 5032 case _SOC_PARITY_TYPE_MMU_ES: 5033 SOC_IF_ERROR_RETURN 5034 (_soc_trident_parity_process_mmu_es(unit, block_info_idx, 5035 info, prefix_str)); 5036 break; 5037 case _SOC_PARITY_TYPE_MMU_IPMC: 5038 SOC_IF_ERROR_RETURN 5039 (_soc_trident_parity_process_mmu_ipmc(unit, block_info_idx, 5040 info, prefix_str)); 5041 break; 5042 case _SOC_PARITY_TYPE_MMU_VLAN: 5043 SOC_IF_ERROR_RETURN 5044 (_soc_trident_parity_process_mmu_vlan(unit, block_info_idx, 5045 info, prefix_str)); 5046 break; 5047 case _SOC_PARITY_TYPE_MMU_AGING: 5048 SOC_IF_ERROR_RETURN 5049 (_soc_trident_parity_process_mmu_aging(unit, block_info_idx, 5050 info, prefix_str)); 5051 break; 5052 case _SOC_PARITY_TYPE_MMU_CTR: 5053 SOC_IF_ERROR_RETURN 5054 (_soc_trident_parity_process_mmu_ctr(unit, block_info_idx, 5055 info, prefix_str)); 5056 break; 5057 default: 5058 break; 5059 } /* Handle different parity error reporting style */ 5060 } /* Loop through each info entry in the list */ 5061 5062 return SOC_E_NONE; 5063 } 5064 5065 static int 5066 _soc_trident_parity_process_all(int unit) 5067 { 5068 const _soc_trident_parity_route_block_t *route_block; 5069 int route_block_index; 5070 uint32 cmic_rval, route_block_rval; 5071 uint32 route_block_enable; 5072 uint32 cmic_bit; 5073 int block_info_idx, inst_num; 5074 char prefix_str[10]; 5075 5076 sal_sprintf(prefix_str, "unit %d", unit); 5077 5078 /* Read CMIC parity status register */ 5079 /* coverity[result_independent_of_operands] */ 5080 SOC_IF_ERROR_RETURN 5081 (READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit, &cmic_rval)); 5082 if (cmic_rval == 0) { 5083 return SOC_E_NONE; 5084 } 5085 5086 /* Loop through each place-and-route block entry */ 5087 for (route_block_index = 0; ; route_block_index++) { 5088 route_block = &_soc_trident_parity_route_blocks[route_block_index]; 5089 cmic_bit = route_block->cmic_bit; 5090 if (cmic_bit == 0) { 5091 /* End of table */ 5092 break; 5093 } 5094 5095 /* Check status for the route block in the CMIC register */ 5096 if (!(cmic_rval & cmic_bit)) { 5097 /* No interrupt bit asserted for the route block */ 5098 continue; 5099 } 5100 5101 if (route_block->blocktype == SOC_BLK_PORT_GROUP4 || 5102 route_block->blocktype == SOC_BLK_PORT_GROUP5) { 5103 inst_num = route_block->pipe; 5104 } else { 5105 inst_num = 0; 5106 } 5107 SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) { 5108 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) { 5109 break; 5110 } 5111 } 5112 5113 /* Read per route block parity status register */ 5114 SOC_IF_ERROR_RETURN 5115 (_soc_trident_parity_reg_get(unit, block_info_idx, 5116 route_block->pipe, 5117 route_block->status_reg, 5118 &route_block_rval)); 5119 if (route_block_rval == 0) { 5120 continue; 5121 } 5122 SOC_IF_ERROR_RETURN 5123 (_soc_trident_parity_reg_get(unit, block_info_idx, 5124 route_block->pipe, 5125 route_block->enable_reg, 5126 &route_block_enable)); 5127 route_block_rval &= route_block_enable; 5128 route_block_enable &= ~route_block_rval; 5129 SOC_IF_ERROR_RETURN 5130 (_soc_trident_parity_reg_set(unit, block_info_idx, 5131 route_block->pipe, 5132 route_block->enable_reg, 5133 route_block_enable)); 5134 SOC_IF_ERROR_RETURN 5135 (_soc_trident_parity_process_info(unit, route_block->blocktype, 5136 block_info_idx, 5137 route_block->pipe, 5138 route_block->status_reg, 5139 route_block_rval, 5140 route_block->info, 5141 prefix_str)); 5142 route_block_enable |= route_block_rval; 5143 SOC_IF_ERROR_RETURN 5144 (_soc_trident_parity_reg_set(unit, block_info_idx, 5145 route_block->pipe, 5146 route_block->enable_reg, 5147 route_block_enable)); 5148 } /* Loop through each place-and-route block entry */ 5149 5150 return SOC_E_NONE; 5151 } 5152 #ifdef _SER_TIME_STAMP 5153 extern sal_usecs_t ser_time_1; 5154 sal_usecs_t ser_time_3; 5155 sal_usecs_t ser_time_2; 5156 #endif 5157 STATIC void 5158 soc_trident_parity_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4) 5159 { 5160 int unit = PTR_TO_INT(unit_vp); 5161 soc_stat_t *stat = SOC_STAT(unit); 5162 #ifdef _SER_TIME_STAMP 5163 ser_time_2 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1); 5164 #endif 5165 _soc_trident_parity_process_all(unit); 5166 #ifdef _SER_TIME_STAMP 5167 ser_time_3 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1); 5168 LOG_CLI((BSL_META_U(unit, 5169 "Start after: %d, Exist after: %d\n"), ser_time_2, ser_time_3)); 5170 #endif 5171 sal_usleep(1000); /* Don't reenable too soon */ 5172 soc_intr_enable(unit, IRQ_MEM_FAIL); 5173 stat->ser_err_int++; 5174 } 5175 5176 typedef union _td_ser_nack_reg_mem_u { 5177 soc_reg_t reg; 5178 soc_mem_t mem; 5179 } _td_ser_nack_reg_mem_t; 5180 5181 #define _SOC_TD_SER_REG 1 5182 #define _SOC_TD_SER_MEM 0 5183 5184 STATIC int 5185 _soc_trident_mem_nack_process_info(int unit, int stat, soc_block_t blocktype, 5186 int block_info_idx, int pipe, int reg_mem, 5187 _td_ser_nack_reg_mem_t nack_reg_mem, int copyno, 5188 const _soc_trident_parity_info_t *info_list, 5189 char *prefix_str, uint32 address) 5190 { 5191 const _soc_trident_parity_info_t *info; 5192 int info_index; 5193 char *mem_str; 5194 5195 /* Loop through each info entry in the list */ 5196 for (info_index = 0; ; info_index++) { 5197 info = &info_list[info_index]; 5198 if (info->type == _SOC_PARITY_TYPE_NONE) { 5199 /* End of table */ 5200 break; 5201 } 5202 if (reg_mem == _SOC_TD_SER_MEM && !(info->mem == nack_reg_mem.mem || 5203 info->type == _SOC_PARITY_TYPE_MMU_IPMC)) { 5204 continue; 5205 } 5206 if ((reg_mem == _SOC_TD_SER_REG) && !(info->type == _SOC_PARITY_TYPE_COUNTER || 5207 info->type == _SOC_PARITY_TYPE_MMU_WRED || info->type== _SOC_PARITY_TYPE_PARITY)) { 5208 continue; 5209 } 5210 5211 if ((reg_mem == _SOC_TD_SER_REG) && (info->type== _SOC_PARITY_TYPE_PARITY)) { 5212 int rv = SOC_E_NONE; 5213 /* For parity type, only handle the registers in nack_register array */ 5214 rv = _soc_trident_nack_reg_check(unit, nack_reg_mem.reg, 5215 info->mem_str); 5216 5217 if (rv == SOC_E_NOT_FOUND) { 5218 continue; 5219 } 5220 } 5221 5222 if (info->mem_str) { 5223 mem_str = info->mem_str; 5224 } else { 5225 mem_str = SOC_MEM_NAME(unit, info->mem); 5226 } 5227 /* Handle different parity error reporting style */ 5228 switch (info->type) { 5229 case _SOC_PARITY_TYPE_PARITY: 5230 if (stat) { 5231 continue; 5232 } 5233 /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */ 5234 SOC_IF_ERROR_RETURN 5235 (_soc_trident_parity_process_parity(unit, 1, block_info_idx, 5236 pipe, info, TRUE, 5237 prefix_str, mem_str)); 5238 break; 5239 case _SOC_PARITY_TYPE_ECC: 5240 if (stat) { 5241 continue; 5242 } 5243 /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */ 5244 SOC_IF_ERROR_RETURN 5245 (_soc_trident_parity_process_ecc(unit, block_info_idx, pipe, 5246 info, TRUE, 5247 prefix_str, mem_str)); 5248 break; 5249 case _SOC_PARITY_TYPE_HASH: 5250 if (stat) { 5251 continue; 5252 } 5253 /* PARITY_ERR_BMf, MULTIPLE_ERRf, BUCKET_IDXf */ 5254 if (((info->mem == L2Xm) || (info->mem == L2_ENTRY_ONLYm)) 5255 && (address != 0)) { 5256 SOC_IF_ERROR_RETURN 5257 (_soc_trident_parity_process_l2x(unit, block_info_idx, 5258 pipe, info, TRUE, 5259 prefix_str, mem_str, address)); 5260 } 5261 else { 5262 SOC_IF_ERROR_RETURN 5263 (_soc_trident_parity_process_hash(unit, block_info_idx, 5264 pipe, info, TRUE, 5265 prefix_str, mem_str)); 5266 } 5267 break; 5268 case _SOC_PARITY_TYPE_EDATABUF: 5269 if (stat) { 5270 continue; 5271 } 5272 /* ECC_ERR_MGRPf, ECC_ERR_2B_MGRPf, ECC_MULTI_MGRPf */ 5273 SOC_IF_ERROR_RETURN 5274 (_soc_trident_parity_process_edatabuf(unit, block_info_idx, 5275 pipe, info, TRUE, 5276 prefix_str, mem_str)); 5277 break; 5278 case _SOC_PARITY_TYPE_COUNTER: 5279 /* PARITY_ERRf, MULTIPLE_ERRf, COUNTER_IDXf, PORT_IDX, 5280 ENTRY_IDXf */ 5281 SOC_IF_ERROR_RETURN 5282 (_soc_trident_parity_process_counter(unit, blocktype, block_info_idx, 5283 pipe, info, TRUE, 5284 prefix_str, mem_str)); 5285 break; 5286 case _SOC_PARITY_TYPE_MMU_WRED: 5287 if (stat) { 5288 continue; 5289 } 5290 SOC_IF_ERROR_RETURN 5291 (_soc_trident_parity_process_mmu_wred(unit, block_info_idx, 5292 info, prefix_str)); 5293 break; 5294 case _SOC_PARITY_TYPE_MMU_THDI: 5295 if (stat) { 5296 continue; 5297 } 5298 SOC_IF_ERROR_RETURN 5299 (_soc_trident_parity_process_mmu_thdi(unit, block_info_idx, 5300 info, prefix_str)); 5301 break; 5302 case _SOC_PARITY_TYPE_MMU_MTRO: 5303 if (stat) { 5304 continue; 5305 } 5306 SOC_IF_ERROR_RETURN 5307 (_soc_trident_parity_process_mmu_mtro(unit, block_info_idx, 5308 info, prefix_str)); 5309 break; 5310 case _SOC_PARITY_TYPE_MMU_ES: 5311 if (stat) { 5312 continue; 5313 } 5314 SOC_IF_ERROR_RETURN 5315 (_soc_trident_parity_process_mmu_es(unit, block_info_idx, 5316 info, prefix_str)); 5317 break; 5318 case _SOC_PARITY_TYPE_MMU_IPMC: 5319 if (stat) { 5320 continue; 5321 } 5322 SOC_IF_ERROR_RETURN 5323 (_soc_trident_parity_process_mmu_ipmc(unit, block_info_idx, 5324 info, prefix_str)); 5325 break; 5326 case _SOC_PARITY_TYPE_MMU_VLAN: 5327 if (stat) { 5328 continue; 5329 } 5330 SOC_IF_ERROR_RETURN 5331 (_soc_trident_parity_process_mmu_vlan(unit, block_info_idx, 5332 info, prefix_str)); 5333 break; 5334 default: 5335 break; 5336 } /* Handle different parity error reporting style */ 5337 } /* Loop through each info entry in the list */ 5338 5339 return SOC_E_NONE; 5340 } 5341 5342 STATIC int 5343 _soc_trident_mem_nack_error_process(int unit, int stat, int reg_mem, 5344 _td_ser_nack_reg_mem_t nack_reg_mem, 5345 int copyno, int pipe, uint32 address) 5346 { 5347 const _soc_trident_parity_route_block_t *route_block; 5348 int route_block_index; 5349 uint32 cmic_bit; 5350 int block_info_idx, inst_num; 5351 char prefix_str[10]; 5352 5353 sal_sprintf(prefix_str, "unit %d", unit); 5354 5355 /* Loop through each place-and-route block entry */ 5356 for (route_block_index = 0; ; route_block_index++) { 5357 route_block = &_soc_trident_parity_route_blocks[route_block_index]; 5358 cmic_bit = route_block->cmic_bit; 5359 if (cmic_bit == 0) { 5360 /* End of table */ 5361 break; 5362 } 5363 if (pipe >= 0 && pipe != route_block->pipe) { 5364 continue; 5365 } 5366 5367 if (route_block->blocktype == SOC_BLK_PORT_GROUP4 || 5368 route_block->blocktype == SOC_BLK_PORT_GROUP5) { 5369 inst_num = route_block->pipe; 5370 } else { 5371 inst_num = 0; 5372 } 5373 SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) { 5374 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) { 5375 break; 5376 } 5377 } 5378 5379 SOC_IF_ERROR_RETURN 5380 (_soc_trident_mem_nack_process_info(unit, stat, route_block->blocktype, 5381 block_info_idx, route_block->pipe, 5382 reg_mem, nack_reg_mem, copyno, 5383 route_block->info, 5384 prefix_str, address)); 5385 } /* Loop through each place-and-route block entry */ 5386 5387 return SOC_E_NONE; 5388 } 5389 5390 STATIC void 5391 soc_trident_mem_nack(void *unit_vp, void *addr_vp, void *blk_vp, 5392 void *d3, void *d4) 5393 { 5394 soc_mem_t mem = INVALIDm; 5395 int rv, pipe = PTR_TO_INT(d4), unit = PTR_TO_INT(unit_vp); 5396 uint32 address = PTR_TO_INT(addr_vp); 5397 uint32 block = PTR_TO_INT(blk_vp); 5398 uint32 offset = 0, min_addr = 0, max_addr = 0; 5399 soc_regaddrinfo_t ainfo; 5400 int reg_mem = PTR_TO_INT(d3); 5401 _td_ser_nack_reg_mem_t nack_reg_mem; 5402 soc_stat_t *stat = SOC_STAT(unit); 5403 int at = (reg_mem == _SOC_TD_SER_REG) ? 5404 (address & 0xE00) >> 9 : (address & 0xE0000) >> \ 5405 _SOC_MEM_ADDR_ACC_TYPE_SHIFT; 5406 #ifdef _SER_TIME_STAMP 5407 ser_time_2 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1); 5408 #endif 5409 nack_reg_mem.reg = INVALIDr; 5410 nack_reg_mem.mem = INVALIDm; 5411 if (reg_mem == _SOC_TD_SER_REG) { 5412 if (address) { 5413 soc_regaddrinfo_get(unit, &ainfo, address); 5414 nack_reg_mem.reg = ainfo.reg; 5415 } 5416 } else { 5417 offset = address & ~0xC0f00000; /* Strip block ID */ 5418 mem = soc_addr_to_mem(unit, address, &block); 5419 if (mem == INVALIDm) { 5420 LOG_ERROR(BSL_LS_SOC_SER, 5421 (BSL_META_U(unit, 5422 "unit %d mem decode failed, " 5423 "SCHAN NACK analysis failure\n"), unit)); 5424 return; 5425 } 5426 _soc_trident_mem_rename(&mem); 5427 nack_reg_mem.mem = mem; 5428 5429 min_addr = max_addr = SOC_MEM_INFO(unit, mem).base; 5430 min_addr += SOC_MEM_INFO(unit, mem).index_min; 5431 max_addr += SOC_MEM_INFO(unit, mem).index_max; 5432 5433 } 5434 5435 switch (at) { 5436 case 0: break; 5437 case 1: break; 5438 case 2: pipe = 1; 5439 break; 5440 case 3: break; 5441 case 4: break; 5442 case 5: break; 5443 case 6: break; 5444 default: break; 5445 } 5446 if (reg_mem == _SOC_TD_SER_MEM) { 5447 if ((rv = _soc_trident_mem_nack_error_process(unit, FALSE, reg_mem, 5448 nack_reg_mem, block, pipe, address)) < 0) { 5449 LOG_ERROR(BSL_LS_SOC_SER, 5450 (BSL_META_U(unit, 5451 "unit %d %s entry %d SCHAN NACK analysis failure\n"), 5452 unit, SOC_MEM_NAME(unit, mem), 5453 min_addr - offset)); 5454 } 5455 } else { 5456 /* In stat collection case there is no address info, thus try both pipes */ 5457 if ((rv = _soc_trident_mem_nack_error_process(unit, FALSE, reg_mem, 5458 nack_reg_mem, block, 0, address)) < 0) { 5459 LOG_ERROR(BSL_LS_SOC_SER, 5460 (BSL_META_U(unit, 5461 "unit %d pipe: 0 REG SCHAN NACK analysis failure.\n"), unit)); 5462 } 5463 if ((rv = _soc_trident_mem_nack_error_process(unit, FALSE, reg_mem, 5464 nack_reg_mem, block, 1, address)) < 0) { 5465 LOG_ERROR(BSL_LS_SOC_SER, 5466 (BSL_META_U(unit, 5467 "unit %d pipe: 1 REG SCHAN NACK analysis failure.\n"), unit)); 5468 } 5469 } 5470 #ifdef _SER_TIME_STAMP 5471 ser_time_3 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1); 5472 LOG_CLI((BSL_META_U(unit, 5473 "Start after: %d, Exist after: %d\n"), ser_time_2, ser_time_3)); 5474 #endif 5475 stat->ser_err_nak++; 5476 } 5477 5478 STATIC void 5479 soc_trident_stat_nack(int unit, int *fixed) 5480 { 5481 int rv; 5482 _td_ser_nack_reg_mem_t nack_reg_mem; 5483 5484 _stat_error_fixed[unit] = 0; 5485 nack_reg_mem.reg = -1; 5486 if ((rv = _soc_trident_mem_nack_error_process(unit, TRUE, _SOC_TD_SER_REG, 5487 nack_reg_mem, 0, 0, 0)) < 0) { 5488 LOG_ERROR(BSL_LS_SOC_SER, 5489 (BSL_META_U(unit, 5490 "unit %d pipe: 0 STAT SCHAN NACK analysis failure.\n"), unit)); 5491 } 5492 if ((rv = _soc_trident_mem_nack_error_process(unit, TRUE, _SOC_TD_SER_REG, 5493 nack_reg_mem, 0, 1, 0)) < 0) { 5494 LOG_ERROR(BSL_LS_SOC_SER, 5495 (BSL_META_U(unit, 5496 "unit %d pipe: 1 STAT SCHAN NACK analysis failure.\n"), unit)); 5497 } 5498 *fixed = _stat_error_fixed[unit]; 5499 } 5500 5501 int 5502 _soc_trident_ser_error_test(int unit) 5503 { 5504 return SOC_E_NONE; 5505 } 5506 5507 /* SER processing for TCAMs */ 5508 static _soc_ser_parity_info_t _soc_td_ser_parity_info_template[] = { 5509 { L3_DEFIPm, _SOC_SER_PARITY_MODE_2BITS, 5510 CMIC_SER_START_ADDR_0r, CMIC_SER_END_ADDR_0r, 5511 CMIC_SER_MEM_ADDR_0r, CMIC_SER_PARITY_MODE_SELr, 5512 RANGE_0_PARITY_BITSf, 178, CMIC_SER_RANGE0_DATAENTRY_LENr, 0, 0, 0, 5513 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5514 { L3_DEFIPm, _SOC_SER_PARITY_MODE_2BITS, 5515 CMIC_SER_START_ADDR_1r, CMIC_SER_END_ADDR_1r, 5516 CMIC_SER_MEM_ADDR_1r, CMIC_SER_PARITY_MODE_SELr, 5517 RANGE_1_PARITY_BITSf, 178, CMIC_SER_RANGE1_DATAENTRY_LENr, 0, 0, 0, 5518 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5519 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5520 { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5521 CMIC_SER_START_ADDR_2r, CMIC_SER_END_ADDR_2r, 5522 CMIC_SER_MEM_ADDR_2r, CMIC_SER_PARITY_MODE_SELr, 5523 RANGE_2_PARITY_BITSf, 470, CMIC_SER_RANGE2_DATAENTRY_LENr, 0, 0, 0, 5524 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5525 { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5526 CMIC_SER_START_ADDR_3r, CMIC_SER_END_ADDR_3r, 5527 CMIC_SER_MEM_ADDR_3r, CMIC_SER_PARITY_MODE_SELr, 5528 RANGE_3_PARITY_BITSf, 470, CMIC_SER_RANGE3_DATAENTRY_LENr, 0, 0, 0, 5529 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5530 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5531 { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5532 CMIC_SER_START_ADDR_4r, CMIC_SER_END_ADDR_4r, 5533 CMIC_SER_MEM_ADDR_4r, CMIC_SER_PARITY_MODE_SELr, 5534 RANGE_4_PARITY_BITSf, 470, CMIC_SER_RANGE4_DATAENTRY_LENr, 0, 0, 0, 5535 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5536 { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5537 CMIC_SER_START_ADDR_5r, CMIC_SER_END_ADDR_5r, 5538 CMIC_SER_MEM_ADDR_5r, CMIC_SER_PARITY_MODE_SELr, 5539 RANGE_5_PARITY_BITSf, 470, CMIC_SER_RANGE5_DATAENTRY_LENr, 0, 0, 0, 5540 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5541 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5542 { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5543 CMIC_SER_START_ADDR_6r, CMIC_SER_END_ADDR_6r, 5544 CMIC_SER_MEM_ADDR_6r, CMIC_SER_PARITY_MODE_SELr, 5545 RANGE_6_PARITY_BITSf, 430, CMIC_SER_RANGE6_DATAENTRY_LENr, 0, 0, 0, 5546 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5547 { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5548 CMIC_SER_START_ADDR_7r, CMIC_SER_END_ADDR_7r, 5549 CMIC_SER_MEM_ADDR_7r, CMIC_SER_PARITY_MODE_SELr, 5550 RANGE_7_PARITY_BITSf, 430, CMIC_SER_RANGE7_DATAENTRY_LENr, 0, 0, 0, 5551 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5552 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5553 { L3_TUNNELm, _SOC_SER_PARITY_MODE_2BITS, 5554 CMIC_SER_START_ADDR_8r, CMIC_SER_END_ADDR_8r, 5555 CMIC_SER_MEM_ADDR_8r, CMIC_SER_PARITY_MODE_SELr, 5556 RANGE_8_PARITY_BITSf, 211, CMIC_SER_RANGE8_DATAENTRY_LENr, 0, 0, 0, 5557 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5558 { L3_TUNNELm, _SOC_SER_PARITY_MODE_2BITS, 5559 CMIC_SER_START_ADDR_9r, CMIC_SER_END_ADDR_9r, 5560 CMIC_SER_MEM_ADDR_9r, CMIC_SER_PARITY_MODE_SELr, 5561 RANGE_9_PARITY_BITSf, 211, CMIC_SER_RANGE9_DATAENTRY_LENr, 0, 0, 0, 5562 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5563 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5564 { L3_DEFIP_128m, _SOC_SER_PARITY_MODE_2BITS, 5565 CMIC_SER_START_ADDR_10r, CMIC_SER_END_ADDR_10r, 5566 CMIC_SER_MEM_ADDR_10r, CMIC_SER_PARITY_MODE_SELr, 5567 RANGE_10_PARITY_BITSf, 282, CMIC_SER_RANGE10_DATAENTRY_LENr, 0, 0, 0, 5568 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5569 { L3_DEFIP_128m, _SOC_SER_PARITY_MODE_2BITS, 5570 CMIC_SER_START_ADDR_11r, CMIC_SER_END_ADDR_11r, 5571 CMIC_SER_MEM_ADDR_11r, CMIC_SER_PARITY_MODE_SELr, 5572 RANGE_11_PARITY_BITSf, 282, CMIC_SER_RANGE11_DATAENTRY_LENr, 0, 0, 0, 5573 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5574 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5575 { FP_UDF_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5576 CMIC_SER_START_ADDR_12r, CMIC_SER_END_ADDR_12r, 5577 CMIC_SER_MEM_ADDR_12r, CMIC_SER_PARITY_MODE_SELr, 5578 RANGE_12_PARITY_BITSf, 139, CMIC_SER_RANGE12_DATAENTRY_LENr, 0, 0, 0, 5579 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5580 { FP_UDF_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5581 CMIC_SER_START_ADDR_13r, CMIC_SER_END_ADDR_13r, 5582 CMIC_SER_MEM_ADDR_13r, CMIC_SER_PARITY_MODE_SELr, 5583 RANGE_13_PARITY_BITSf, 139, CMIC_SER_RANGE13_DATAENTRY_LENr, 0, 0, 0, 5584 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5585 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5586 { MY_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5587 CMIC_SER_START_ADDR_14r, CMIC_SER_END_ADDR_14r, 5588 CMIC_SER_MEM_ADDR_14r, CMIC_SER_PARITY_MODE_SELr, 5589 RANGE_14_PARITY_BITSf, 135, CMIC_SER_RANGE14_DATAENTRY_LENr, 0, 0, 0, 5590 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ}, 5591 { MY_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5592 CMIC_SER_START_ADDR_15r, CMIC_SER_END_ADDR_15r, 5593 CMIC_SER_MEM_ADDR_15r, CMIC_SER_PARITY_MODE_SELr, 5594 RANGE_15_PARITY_BITSf, 135, CMIC_SER_RANGE15_DATAENTRY_LENr, 0, 0, 0, 5595 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5596 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5597 { VLAN_SUBNETm, _SOC_SER_PARITY_MODE_2BITS, 5598 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 129, INVALIDr, 5599 0, 0, 0, 5600 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5601 _SOC_SER_FLAG_SW_COMPARE}, 5602 { VLAN_SUBNETm, _SOC_SER_PARITY_MODE_2BITS, 5603 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 129, INVALIDr, 5604 0, 0, 0, 5605 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5606 _SOC_SER_FLAG_SW_COMPARE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5607 { L2_USER_ENTRYm, _SOC_SER_PARITY_MODE_2BITS, 5608 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 123, INVALIDr, 5609 0, 0, 0, 5610 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5611 _SOC_SER_FLAG_SW_COMPARE}, 5612 { L2_USER_ENTRYm, _SOC_SER_PARITY_MODE_2BITS, 5613 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 123, INVALIDr, 5614 0, 0, 0, 5615 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5616 _SOC_SER_FLAG_SW_COMPARE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5617 { CPU_COS_MAPm, _SOC_SER_PARITY_MODE_2BITS, 5618 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 141, INVALIDr, 5619 0, 0, 0, 5620 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5621 _SOC_SER_FLAG_SW_COMPARE}, 5622 { CPU_COS_MAPm, _SOC_SER_PARITY_MODE_2BITS, 5623 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 141, INVALIDr, 5624 0, 0, 0, 5625 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5626 _SOC_SER_FLAG_SW_COMPARE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5627 { FP_GLOBAL_MASK_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5628 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr, 5629 0, 0, 0, 5630 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5631 _SOC_SER_FLAG_SW_COMPARE | _SOC_SER_FLAG_OVERLAY}, 5632 { FP_GLOBAL_MASK_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 5633 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr, 5634 0, 0, 0, 5635 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5636 _SOC_SER_FLAG_SW_COMPARE | _SOC_SER_FLAG_OVERLAY | 5637 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5638 { FP_GM_FIELDSm, _SOC_SER_PARITY_MODE_2BITS, 5639 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr, 5640 0, 0, 0, 5641 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5642 _SOC_SER_FLAG_SW_COMPARE | 5643 _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE}, 5644 { FP_GM_FIELDSm, _SOC_SER_PARITY_MODE_2BITS, 5645 INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr, 5646 0, 0, 0, 5647 _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ | 5648 _SOC_SER_FLAG_SW_COMPARE | 5649 _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE | 5650 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y}, 5651 { INVALIDm, _SOC_SER_PARITY_MODE_NUM}, 5652 }; 5653 5654 static _soc_ser_parity_info_t *_soc_td_ser_parity_info[SOC_MAX_NUM_DEVICES]; 5655 5656 #define SOC_TD_SER_MEM_AVAILABLE (2048 * 32) /* bits */ 5657 5658 STATIC int 5659 _soc_trident_ser_init(int unit) 5660 { 5661 int alloc_size; 5662 5663 /* First, make per-unit copy of the master TCAM list */ 5664 alloc_size = sizeof(_soc_td_ser_parity_info_template); 5665 if (NULL == _soc_td_ser_parity_info[unit]) { 5666 if ((_soc_td_ser_parity_info[unit] = 5667 sal_alloc(alloc_size, "td tcam list")) == NULL) { 5668 return SOC_E_MEMORY; 5669 } 5670 } 5671 /* Make a fresh copy of the TCAM template info */ 5672 sal_memcpy(_soc_td_ser_parity_info[unit], 5673 &(_soc_td_ser_parity_info_template), 5674 alloc_size); 5675 5676 return soc_ser_init(unit, _soc_td_ser_parity_info[unit], 5677 SOC_TD_SER_MEM_AVAILABLE); 5678 } 5679 5680 int 5681 soc_trident_ser_mem_clear(int unit, soc_mem_t mem) 5682 { 5683 return soc_ser_mem_clear(unit, _soc_td_ser_parity_info[unit], mem); 5684 } 5685 5686 STATIC int 5687 soc_trident_populate_tcam_log(int unit, soc_mem_t mem, soc_acc_type_t acc_type_target, int index) 5688 { 5689 int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1; 5690 int i; 5691 soc_acc_type_t acc_type; 5692 _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit]; 5693 uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 5694 int log_entry_size, id = 0, entry_dw, entry_found=0; 5695 uint32 *cache; 5696 uint8 *vmap; 5697 uint32 regAddr; 5698 5699 /* 5700 must be large enough for at least generic and terminator, as well as the 5701 memory type since we might decode it in soc_ser_correction. 5702 */ 5703 log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 + 5704 sizeof(soc_ser_log_tlv_generic_t) + 5705 sizeof(soc_ser_log_tlv_memory_t); 5706 5707 if((mem != INVALIDm) && 5708 (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != SOC_MEM_FLAG_SER_SPECIAL) && 5709 (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) { 5710 for (i = 0; i < num_tcams; i++) { 5711 if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) == 5712 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) { 5713 acc_type = _SOC_ACC_TYPE_PIPE_Y; 5714 } else if ((tcam_info[i].ser_flags & _SOC_SER_FLAG_MULTI_PIPE) == 5715 _SOC_SER_FLAG_MULTI_PIPE) { 5716 acc_type = _SOC_ACC_TYPE_PIPE_X; 5717 } else { 5718 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 5719 } 5720 if (tcam_info[i].mem == mem && 5721 ((acc_type == acc_type_target) || 5722 (acc_type_target == _SOC_ACC_TYPE_PIPE_GROUP))) { 5723 /*Disable parity*/ 5724 MEM_LOCK(unit,mem); 5725 regAddr = soc_reg_addr(unit, CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, 5726 REG_PORT_ANY, i/16); 5727 if (soc_pci_write(unit, regAddr, 0) < 0) { 5728 /* coverity[dead_error_line] */ 5729 MEM_UNLOCK(unit,mem); 5730 return 0; 5731 } 5732 /*Read the memory */ 5733 soc_trident_pipe_select(unit, TRUE, 5734 (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0)); 5735 soc_trident_pipe_select(unit, FALSE, 5736 (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0)); 5737 if (acc_type == _SOC_ACC_TYPE_PIPE_Y) { 5738 soc_mem_pipe_select_read(unit, SOC_MEM_NO_FLAGS, mem, 5739 MEM_BLOCK_ANY, acc_type, 5740 index, tmp_entry); 5741 } else { 5742 /*Enable NACK on read */ 5743 soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN, 5744 mem, 0, MEM_BLOCK_ANY, 5745 index, tmp_entry); 5746 } 5747 5748 soc_trident_pipe_select(unit, TRUE, 0); 5749 soc_trident_pipe_select(unit, FALSE, 0); 5750 /*Enable parity*/ 5751 /* coverity[result_independent_of_operands] */ 5752 if (soc_pci_write(unit, regAddr, 0xFFFF) < 0) { 5753 /* coverity[dead_error_line] */ 5754 MEM_UNLOCK(unit,mem); 5755 return 0; 5756 } 5757 entry_found = 1; 5758 MEM_UNLOCK(unit,mem); 5759 break; 5760 } 5761 } 5762 if (entry_found != 0) { 5763 entry_dw = soc_mem_entry_words(unit, mem); 5764 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 5765 5766 cache = SOC_MEM_STATE(unit, mem).cache[SOC_MEM_BLOCK_ANY(unit, mem)]; 5767 vmap = SOC_MEM_STATE(unit, mem).vmap[SOC_MEM_BLOCK_ANY(unit, mem)]; 5768 if(cache != NULL && CACHE_VMAP_TST(vmap, index)) { 5769 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 5770 } 5771 5772 /* create the entry based on determined size, save id */ 5773 id = soc_ser_log_create_entry(unit, log_entry_size); 5774 5775 /* fill in the memory contents tlv */ 5776 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS, entry_dw*4, tmp_entry) < 0) { 5777 return 0; 5778 } 5779 if(cache != NULL && CACHE_VMAP_TST(vmap, index)) { 5780 /* fill in the memory cache tlv */ 5781 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE, 5782 entry_dw*4, (cache + index*entry_dw)) < 0) { 5783 return 0; 5784 } 5785 } 5786 } 5787 } else { 5788 id = soc_ser_log_create_entry(unit, log_entry_size); 5789 } 5790 return id; 5791 } 5792 5793 STATIC void 5794 soc_trident_ser_fail(int unit) 5795 5796 { 5797 soc_process_ser_parity_error(unit, _soc_td_ser_parity_info[unit], 5798 _SOC_PARITY_TYPE_SER); 5799 return; 5800 } 5801 5802 /* FCOE standard FC header configurations */ 5803 STATIC _soc_fcoe_header_info_t _soc_td_fcoe_header_info[] = { 5804 { SOC_FCOE_HDR_TYPE_STD , 0, 7 }, 5805 { SOC_FCOE_HDR_TYPE_STD , 33, 35 }, 5806 { SOC_FCOE_HDR_TYPE_STD , 50, 51 }, 5807 { SOC_FCOE_HDR_TYPE_STD , 64, 71 }, 5808 { SOC_FCOE_HDR_TYPE_VFT , 80, 80 }, 5809 { SOC_FCOE_HDR_TYPE_IFR , 81, 81 }, 5810 { SOC_FCOE_HDR_TYPE_ENCAP, 82, 82 }, 5811 { SOC_FCOE_HDR_TYPE_STD, 128, 134 }, 5812 { SOC_FCOE_HDR_TYPE_STD, 192, 201 }, 5813 {0} /* end of headers */ 5814 }; 5815 5816 static int 5817 _soc_trident_fcoe_config_init(int unit) 5818 { 5819 int index, rctl; 5820 5821 for (index = 0; ;index++) 5822 { 5823 if (_soc_td_fcoe_header_info[index].fc_hdr_type == 0) { 5824 /* End of the table */ 5825 break; 5826 } 5827 5828 /* Configure FCOE header for routing control indexes */ 5829 for (rctl = _soc_td_fcoe_header_info[index].r_ctl_min; 5830 rctl <= _soc_td_fcoe_header_info[index].r_ctl_max; rctl++) 5831 { 5832 SOC_IF_ERROR_RETURN( 5833 soc_mem_field32_modify(unit, FC_HEADER_TYPEm, rctl, 5834 FC_HDR_ENCODEf, _soc_td_fcoe_header_info[index].fc_hdr_type)); 5835 } 5836 } 5837 return SOC_E_NONE; 5838 } 5839 5840 #define SOC_TD_MAX_EPIPE_TABLE_SIZE (1024 * 16) 5841 5842 STATIC int 5843 _soc_trident_clear_all_memory(int unit) 5844 { 5845 soc_info_t *si; 5846 uint32 rval, fval; 5847 int pipe_init_usec, index, count; 5848 soc_timeout_t to; 5849 uint32 entry[SOC_MAX_MEM_WORDS]; 5850 int port, phy_port, blk_port, blk, bindex; 5851 int tcam_protect_write; 5852 static const soc_mem_t cam[] = { 5853 CPU_COS_MAPm, 5854 FP_GLOBAL_MASK_TCAMm, 5855 FP_TCAMm, 5856 FP_UDF_TCAMm, 5857 L2_USER_ENTRYm, 5858 L3_DEFIP_128m, 5859 L3_DEFIPm, 5860 L3_TUNNELm, 5861 MY_STATION_TCAMm, 5862 VFP_TCAMm, 5863 VLAN_SUBNETm, 5864 EFP_TCAMm, 5865 #ifdef PLISIM 5866 /* In HW, these are the same as FP_GLOBAL_MASK_TCAM. 5867 * In simulation, they are separate instances. 5868 */ 5869 FP_GM_FIELDSm, 5870 FP_GLOBAL_MASK_TCAM_Xm, 5871 FP_GLOBAL_MASK_TCAM_Ym 5872 #endif 5873 }; 5874 5875 si = &SOC_INFO(unit); 5876 5877 /* 5878 * Reset the IPIPE and EPIPE block 5879 */ 5880 rval = 0; 5881 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 5882 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 5883 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 5884 /* Set count to # entries in largest IPIPE table (L2X) */ 5885 count = soc_mem_index_count(unit, L2Xm); 5886 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, count); 5887 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 5888 5889 rval = 0; 5890 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 5891 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 5892 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 5893 /* Set count to maximum table size 16k */ 5894 count = SOC_TD_MAX_EPIPE_TABLE_SIZE; 5895 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, count); 5896 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 5897 5898 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 5899 if (SAL_BOOT_SIMULATION) { 5900 pipe_init_usec = 10000000; 5901 } else { 5902 pipe_init_usec = 50000; 5903 } 5904 soc_timeout_init(&to, pipe_init_usec, 0); 5905 5906 /* Wait for IPIPE memory initialization done. */ 5907 do { 5908 SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval)); 5909 if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) { 5910 break; 5911 } 5912 if (soc_timeout_check(&to)) { 5913 LOG_WARN(BSL_LS_SOC_COMMON, 5914 (BSL_META_U(unit, 5915 "unit %d : ING_HW_RESET timeout\n"), unit)); 5916 break; 5917 } 5918 } while (TRUE); 5919 5920 /* Wait for EPIPE memory initialization done. */ 5921 do { 5922 SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval)); 5923 if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) { 5924 break; 5925 } 5926 if (soc_timeout_check(&to)) { 5927 LOG_WARN(BSL_LS_SOC_COMMON, 5928 (BSL_META_U(unit, 5929 "unit %d : EGR_HW_RESET timeout\n"), unit)); 5930 break; 5931 } 5932 } while (TRUE); 5933 5934 rval = 0; 5935 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 5936 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 5937 5938 /* TCAM tables are not handled by hardware reset control */ 5939 tcam_protect_write = SOC_CONTROL(unit)->tcam_protect_write; 5940 SOC_CONTROL(unit)->tcam_protect_write = FALSE; 5941 for (index = 0; index < sizeof(cam) / sizeof(soc_mem_t); index++) { 5942 #ifdef PLISIM 5943 if (!SAL_BOOT_PLISIM) { 5944 if( (cam[index]==FP_GM_FIELDSm) || 5945 (cam[index]==FP_GLOBAL_MASK_TCAM_Xm) || 5946 (cam[index]==FP_GLOBAL_MASK_TCAM_Ym) ) { 5947 continue; 5948 } 5949 } 5950 #endif 5951 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, cam[index], COPYNO_ALL, TRUE)); 5952 } 5953 SOC_CONTROL(unit)->tcam_protect_write = tcam_protect_write; 5954 5955 /* Do dummy read to clear the parity status latch */ 5956 SOC_IF_ERROR_RETURN 5957 (READ_INITIAL_L3_ECMP_Xm(unit, MEM_BLOCK_ANY, 0, entry)); 5958 SOC_IF_ERROR_RETURN 5959 (READ_INITIAL_L3_ECMP_Ym(unit, MEM_BLOCK_ANY, 0, entry)); 5960 5961 /* Some registers are implemented in memory, need to clear them in order 5962 * to have correct parity value */ 5963 PBMP_ALL_ITER(unit, port) { 5964 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, 0)); 5965 SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2r(unit, port, 0)); 5966 } 5967 5968 /* Reset XLPORT MIB counter (registers implemented in memory). The clear 5969 * function is implemented with read-modify-write, parity needs to be 5970 * disabled */ 5971 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 5972 blk_port = SOC_BLOCK_PORT(unit, blk); 5973 if (blk_port < 0) { 5974 continue; 5975 } 5976 phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1; 5977 fval = 0; 5978 for (bindex = 0; bindex < 4; bindex++) { 5979 if (si->port_p2l_mapping[phy_port + bindex] != -1) { 5980 fval |= 1 << bindex; 5981 } 5982 } 5983 rval = 0; 5984 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, fval); 5985 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, blk_port, rval)); 5986 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, blk_port, 0)); 5987 } 5988 5989 return SOC_E_NONE; 5990 } 5991 5992 int 5993 soc_trident_pipe_select(int unit, int egress, int pipe) 5994 { 5995 soc_reg_t reg; 5996 int rv; 5997 5998 reg = egress ? EGR_SBS_CONTROLr : SBS_CONTROLr; 5999 6000 SOC_ALLOW_WB_WRITE(unit, 6001 soc_reg_field32_modify(unit, reg, REG_PORT_ANY, PIPE_SELECTf, pipe), 6002 rv); 6003 6004 return rv; 6005 } 6006 6007 int 6008 _soc_trident_port_mapping_init(int unit) 6009 { 6010 soc_info_t *si; 6011 soc_mem_t mem; 6012 uint32 rval; 6013 ing_physical_to_logical_port_number_mapping_table_entry_t entry; 6014 int port, phy_port, mmu_port; 6015 int num_port, num_phy_port, num_mmu_port; 6016 6017 si = &SOC_INFO(unit); 6018 6019 /* Ingress physical to logical port mapping */ 6020 mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm; 6021 num_phy_port = soc_mem_index_count(unit, mem); 6022 sal_memset(&entry, 0, sizeof(entry)); 6023 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 6024 port = si->port_p2l_mapping[phy_port]; 6025 soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf, 6026 port == -1 ? 0x7f : port); 6027 SOC_IF_ERROR_RETURN 6028 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry)); 6029 } 6030 6031 /* Ingress logical to physical port mapping */ 6032 num_port = soc_mem_index_count(unit, PORT_TABm); 6033 rval = 0; 6034 for (port = 0; port < num_port; port++) { 6035 phy_port = si->port_l2p_mapping[port]; 6036 soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval, 6037 PHYSICAL_PORT_NUMf, 6038 phy_port == -1 ? 0x7f : phy_port); 6039 SOC_IF_ERROR_RETURN 6040 (WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval)); 6041 } 6042 6043 /* Egress logical to physical port mapping */ 6044 for (port = 0; port < num_port; port++) { 6045 phy_port = si->port_l2p_mapping[port]; 6046 rval = 0; 6047 soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr, 6048 &rval, PHYSICAL_PORT_NUMBERf, 6049 phy_port == -1 ? 0x7f : phy_port); 6050 SOC_IF_ERROR_RETURN 6051 (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port, 6052 rval)); 6053 6054 rval = 0; 6055 soc_reg_field_set(unit, EGR_VLAN_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval, 6056 PHYSICAL_PORT_NUMf, 6057 phy_port == -1 ? 0x7f : phy_port); 6058 SOC_IF_ERROR_RETURN 6059 (WRITE_EGR_VLAN_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval)); 6060 } 6061 6062 /* MMU to physical port mapping and MMU to logical port mapping */ 6063 num_mmu_port = SOC_REG_NUMELS(unit, MMU_TO_PHY_PORT_MAPPINGr); 6064 for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) { 6065 phy_port = si->port_m2p_mapping[mmu_port]; 6066 port = phy_port == -1 ? -1 : si->port_p2l_mapping[phy_port]; 6067 6068 rval = 0; 6069 soc_reg_field_set(unit, MMU_TO_PHY_PORT_MAPPINGr, &rval, PHY_PORTf, 6070 phy_port == -1 ? 0x7f : phy_port); 6071 SOC_IF_ERROR_RETURN 6072 (WRITE_MMU_TO_PHY_PORT_MAPPINGr(unit, mmu_port, rval)); 6073 6074 rval = 0; 6075 soc_reg_field_set(unit, MMU_TO_LOGIC_PORT_MAPPINGr, &rval, LOGIC_PORTf, 6076 port == -1 ? 0x7f : port); 6077 SOC_IF_ERROR_RETURN 6078 (WRITE_MMU_TO_LOGIC_PORT_MAPPINGr(unit, mmu_port, rval)); 6079 } 6080 6081 return SOC_E_NONE; 6082 } 6083 6084 /* 6085 * cpu port (mmu port 0): 48 queues (0-47) 6086 * loopback port (mmu port 33): 9 queues (0-8) 6087 * extended ports (mmu port 1-4, 34-37): 74 unicast queues (0-9, 64-127) 6088 * 5 multicast queues (0-4) 6089 * regular port: 10 unicast queues (0-9) 6090 * 5 multicast queues (0-4) 6091 */ 6092 int 6093 soc_trident_num_cosq_init(int unit) 6094 { 6095 soc_info_t *si; 6096 int port, phy_port, mmu_port, mmu_cmic_port, mmu_lb_port; 6097 int base_x, base_y; 6098 6099 si = &SOC_INFO(unit); 6100 6101 mmu_cmic_port = si->port_p2m_mapping[si->port_l2p_mapping[si->cmic_port]]; 6102 mmu_lb_port = si->port_p2m_mapping[si->port_l2p_mapping[si->lb_port]]; 6103 6104 base_x = 0; 6105 base_y = 0; 6106 6107 PBMP_ALL_ITER(unit, port) { 6108 phy_port = si->port_l2p_mapping[port]; 6109 mmu_port = si->port_p2m_mapping[phy_port]; 6110 6111 si->port_num_cosq[port] = 5; 6112 si->port_num_uc_cosq[port] = 10; 6113 if (phy_port <= 36) { /* X pipe */ 6114 if (mmu_port == mmu_cmic_port) { 6115 si->port_num_cosq[port] = 48; 6116 si->port_num_uc_cosq[port] = 0; 6117 si->port_group[port] = -1; 6118 } else { 6119 if (mmu_port <= mmu_cmic_port + 4) { 6120 si->port_num_ext_cosq[port] = 64; 6121 } 6122 if (phy_port <= 20) { 6123 si->port_group[port] = 0; /* PORT_GROUP5_X */ 6124 } else { 6125 si->port_group[port] = 1; /* PORT_GROUP4_X */ 6126 } 6127 } 6128 if (si->port_num_uc_cosq[port] != 0) { 6129 si->port_uc_cosq_base[port] = base_x; 6130 base_x += si->port_num_uc_cosq[port]; 6131 } 6132 if (si->port_num_cosq[port] != 0) { 6133 si->port_cosq_base[port] = base_x; 6134 base_x += si->port_num_cosq[port]; 6135 } 6136 if (si->port_num_ext_cosq[port] != 0) { 6137 si->port_ext_cosq_base[port] = base_x; 6138 base_x += si->port_num_ext_cosq[port]; 6139 } 6140 } else { /* Y pipe */ 6141 if (mmu_port == mmu_lb_port) { 6142 si->port_num_cosq[port] = 9; 6143 si->port_num_uc_cosq[port] = 0; 6144 si->port_group[port] = -1; 6145 } else { 6146 if (mmu_port <= mmu_lb_port + 4) { 6147 si->port_num_ext_cosq[port] = 64; 6148 } 6149 if (phy_port <= 56) { 6150 si->port_group[port] = 2; /* PORT_GROUP5_Y */ 6151 } else { 6152 si->port_group[port] = 3; /* PORT_GROUP4_Y */ 6153 } 6154 } 6155 if (si->port_num_uc_cosq[port] != 0) { 6156 si->port_uc_cosq_base[port] = base_y; 6157 base_y += si->port_num_uc_cosq[port]; 6158 } 6159 if (si->port_num_cosq[port] != 0) { 6160 si->port_cosq_base[port] = base_y; 6161 base_y += si->port_num_cosq[port]; 6162 } 6163 if (si->port_num_ext_cosq[port] != 0) { 6164 si->port_ext_cosq_base[port] = base_y; 6165 base_y += si->port_num_ext_cosq[port]; 6166 } 6167 } 6168 } 6169 6170 return SOC_E_NONE; 6171 } 6172 6173 /* 6174 * EGR_PERQ_XMT_COUNTERS_BASE_ADDR is indexed by: 6175 * port number[6:0], queue number[6], mcast(1)/ucast(0) 6176 * 6177 * EGR_PERQ_XMT_COUNTERS_X: can hold up to 784 counters 6178 * (cpu + 28 regular + 4 extended) 6179 * EGR_PERQ_XMT_COUNTERS_Y: can hold up to 745 counters 6180 * (loopback + 28 regular + 4 extended) 6181 */ 6182 int 6183 soc_trident_get_egr_perq_xmt_counters_size(int unit, int *num_entries_x, 6184 int *num_entries_y) 6185 { 6186 soc_info_t *si; 6187 soc_port_t port; 6188 6189 si = &SOC_INFO(unit); 6190 6191 *num_entries_x = *num_entries_y = 0; 6192 PBMP_ALL_ITER(unit, port) { 6193 if (IS_CPU_PORT(unit, port) || 6194 (si->port_group[port] >= 0 && si->port_group[port] <= 1)) { 6195 *num_entries_x += si->port_num_cosq[port] + 6196 si->port_num_uc_cosq[port] + si->port_num_ext_cosq[port]; 6197 } else { 6198 *num_entries_y += si->port_num_cosq[port] + 6199 si->port_num_uc_cosq[port] + si->port_num_ext_cosq[port]; 6200 } 6201 } 6202 6203 return SOC_E_NONE; 6204 } 6205 6206 STATIC int 6207 _soc_trident_egr_perq_xmt_counters_init(int unit) 6208 { 6209 soc_info_t *si; 6210 soc_port_t port; 6211 egr_perq_xmt_counters_base_addr_entry_t entry; 6212 6213 si = &SOC_INFO(unit); 6214 sal_memset(&entry, 0, sizeof(entry)); 6215 PBMP_ALL_ITER(unit, port) { 6216 if (si->port_num_uc_cosq[port] != 0) { 6217 soc_mem_field32_set(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, &entry, 6218 BASEf, si->port_uc_cosq_base[port]); 6219 SOC_IF_ERROR_RETURN 6220 (soc_mem_write(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, 6221 MEM_BLOCK_ALL, port << 2, &entry)); 6222 } 6223 if (si->port_num_cosq[port] != 0) { 6224 soc_mem_field32_set(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, &entry, 6225 BASEf, si->port_cosq_base[port]); 6226 SOC_IF_ERROR_RETURN 6227 (soc_mem_write(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, 6228 MEM_BLOCK_ALL, (port << 2) + 1, &entry)); 6229 } 6230 if (si->port_num_ext_cosq[port] != 0) { 6231 soc_mem_field32_set(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, &entry, 6232 BASEf, si->port_ext_cosq_base[port]); 6233 SOC_IF_ERROR_RETURN 6234 (soc_mem_write(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, 6235 MEM_BLOCK_ALL, (port << 2) + 2, &entry)); 6236 } 6237 } 6238 6239 return SOC_E_NONE; 6240 } 6241 6242 6243 #define _TD_BLKS_PER_PIPE 9 6244 #define _TD_BLKS_PER_GROUP 5 /* can be 4 or 5 */ 6245 #define _TD_PORTS_PER_BLK 4 6246 #define _TD_TDM_SLOT_IDLE -1 6247 #define _TD_TDM_SLOT_NULL -2 6248 #define _TD_TDM_NUM_COLUMNS 4 6249 #define _TD_TDM_NUM_SLOTS 8 6250 6251 /* 6252 * Trident port mapping 6253 * 74 physical ports: port 0-36 in X pipe, port 37-73 in Y pipe 6254 * 66 logical ports 6255 * 66 mmu ports: port 0-32 in X pipe, port 33-65 in Y pipe 6256 * cpu port number is fixed: physical 0, logical 0, mmu 0 6257 * loopback port number is fixed: physical 73, logical 65, mmu 33 6258 * physical port 1-4 can be converted to GE port 6259 * mmu port can only map to physical port ID in the same pipe 6260 * This routine will setup: 6261 * SOC_INFO(unit).port_p2l_mapping[] 6262 * SOC_INFO(unit).port_l2p_mapping[] 6263 * SOC_INFO(unit).port_p2m_mapping[] 6264 * SOC_INFO(unit).port_m2p_mapping[] 6265 * SOC_INFO(unit).port_speed_max[] 6266 * SOC_INFO(unit).port_num_lanes[] 6267 * SOC_INFO(unit).eq_pbm 6268 */ 6269 int 6270 soc_trident_port_config_init(int unit, uint16 dev_id) 6271 { 6272 soc_info_t *si; 6273 char *config_str, *sub_str, *sub_str_end; 6274 static const char str_eq[] = "EQ"; 6275 static const char str_2p5[] = "2.5"; 6276 char option1; 6277 char str_buf[8]; 6278 int rv; 6279 int port, phy_port, mmu_port; 6280 int pipe, group, blk; 6281 int port_bandwidth, blk_bandwidth, pg_bandwidth; 6282 int ext_queue, index, count; 6283 int port_count[2], eq_port_count[2]; 6284 int blk_port[4], blk_port_bandwidth[4]; 6285 int eq_port[2][4], mmu_port_base[2]; 6286 int fifo_index, fifo_count[2], extra_fifo_count[2], unused_fifo[12]; 6287 pbmp_t pbmp_4fifo[2], pbmp_2fifo[2], pbmp_1fifo[2]; 6288 6289 6290 si = &SOC_INFO(unit); 6291 6292 switch (dev_id) { 6293 case BCM56841_DEVICE_ID: 6294 case BCM56842_DEVICE_ID: 6295 case BCM56549_DEVICE_ID: 6296 case BCM56053_DEVICE_ID: 6297 case BCM56742_DEVICE_ID: 6298 case BCM56838_DEVICE_ID: 6299 si->bandwidth = 320000; 6300 break; 6301 case BCM56840_DEVICE_ID: 6302 case BCM56843_DEVICE_ID: 6303 case BCM56743_DEVICE_ID: 6304 case BCM56844_DEVICE_ID: 6305 case BCM56744_DEVICE_ID: 6306 si->bandwidth = 480000; 6307 break; 6308 case BCM56845_DEVICE_ID: 6309 case BCM56847_DEVICE_ID: 6310 case BCM56745_DEVICE_ID: 6311 case BCM56846_DEVICE_ID: 6312 case BCM56746_DEVICE_ID: 6313 case BCM56831_DEVICE_ID: 6314 case BCM56835_DEVICE_ID: 6315 case BCM56849_DEVICE_ID: 6316 si->bandwidth = 640000; 6317 break; 6318 default: 6319 return SOC_E_INTERNAL; 6320 } 6321 6322 /* cpu port is physical port 0, logical port 0, mmu port 0 */ 6323 /* coverity[result_independent_of_operands] */ 6324 SOC_PORT_P2L_MAPPING_SET(unit, 0, 0); 6325 /* coverity[result_independent_of_operands] */ 6326 SOC_PORT_P2M_MAPPING_SET(unit, 0, 0); 6327 /* loopback port is physical port 73, logical port 65, mmu port 33 */ 6328 SOC_PORT_P2L_MAPPING_SET(unit, 73, 65); 6329 SOC_PORT_P2M_MAPPING_SET(unit, 73, 33); 6330 for (phy_port = 1; phy_port < 73; phy_port++) { 6331 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, -1); 6332 SOC_PORT_P2M_MAPPING_SET(unit, phy_port, -1); 6333 } 6334 for (port = 0; port < 66; port++) { 6335 SOC_PORT_L2P_MAPPING_SET(unit, port, -1); 6336 SOC_PORT_M2P_MAPPING_SET(unit, port, -1); 6337 SOC_PORT_SPEED_MAX_SET(unit, port, -1); 6338 } 6339 SOC_PBMP_CLEAR(si->eq_pbm); 6340 SOC_PBMP_PORT_SET(si->xpipe_pbm, 0); /* cpu port */ 6341 SOC_PBMP_PORT_SET(si->ypipe_pbm, 65); /* loopback port */ 6342 6343 port_count[0] = eq_port_count[0] = 0; /* X pipe */ 6344 port_count[1] = eq_port_count[1] = 0; /* Y pipe */ 6345 6346 rv = SOC_E_NONE; 6347 6348 if (dev_id == BCM56849_DEVICE_ID) { 6349 if (soc_property_get(unit, spn_BCM56849_56X2POINT5_8X10, 1)) { 6350 /* 56x1GE/2.5GE + 8x10GE */ 6351 for (port = 1; port < 65; port++) { 6352 if (port < 57) { 6353 port_bandwidth = 2500; 6354 if (port < 29) { 6355 phy_port = port; 6356 } else { 6357 phy_port = port + 16; 6358 } 6359 } else { 6360 port_bandwidth = 10000; 6361 if (port < 61) { 6362 phy_port = port - 28; 6363 } else { 6364 phy_port = port - 24; 6365 } 6366 } 6367 6368 if (si->port_p2l_mapping[phy_port] != -1) { 6369 LOG_CLI((BSL_META_U(unit, 6370 "Port %d: Physical port %d is used by port %d\n"), 6371 port, phy_port, si->port_p2l_mapping[phy_port])); 6372 rv = SOC_E_FAIL; 6373 continue; 6374 } 6375 6376 pipe = phy_port < 37 ? 0 : 1; 6377 if (port_count[pipe] >= 32) { 6378 LOG_CLI((BSL_META_U(unit, 6379 "Can not configure more than 32 port in " 6380 "%c pipeline\n"), pipe ? 'Y' : 'X')); 6381 rv = SOC_E_FAIL; 6382 continue; 6383 } 6384 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, port); 6385 SOC_PORT_L2P_MAPPING_SET(unit, port, phy_port); 6386 SOC_PORT_SPEED_MAX_SET(unit, port, port_bandwidth); 6387 port_count[pipe]++; 6388 } 6389 } else { 6390 /* 60x1GE/2.5GE +2x40GE */ 6391 for (port = 1; port < 63; port++) { 6392 if (port < 61) { 6393 port_bandwidth = 2500; 6394 if (port < 31) { 6395 phy_port = port; 6396 } else if (port < 33){ 6397 phy_port = port + 6; 6398 } else { 6399 phy_port = port + 12; 6400 } 6401 } else { 6402 port_bandwidth = 40000; 6403 if (port == 61) { 6404 phy_port = 33; 6405 } else { 6406 phy_port = 41; 6407 } 6408 } 6409 6410 if (si->port_p2l_mapping[phy_port] != -1) { 6411 LOG_CLI((BSL_META_U(unit, 6412 "Port %d: Physical port %d is used by port %d\n"), 6413 port, phy_port, si->port_p2l_mapping[phy_port])); 6414 rv = SOC_E_FAIL; 6415 continue; 6416 } 6417 6418 pipe = phy_port < 37 ? 0 : 1; 6419 if (port_count[pipe] >= 32) { 6420 LOG_CLI((BSL_META_U(unit, 6421 "Can not configure more than 32 port in " 6422 "%c pipeline\n"), pipe ? 'Y' : 'X')); 6423 rv = SOC_E_FAIL; 6424 continue; 6425 } 6426 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, port); 6427 SOC_PORT_L2P_MAPPING_SET(unit, port, phy_port); 6428 SOC_PORT_SPEED_MAX_SET(unit, port, port_bandwidth); 6429 port_count[pipe]++; 6430 } 6431 } 6432 } else { 6433 for (port = 1; port < 65; port++) { 6434 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 6435 if (config_str == NULL) { 6436 continue; 6437 } 6438 6439 /* 6440 * portmap.<port>=<physical port number>:<bandwidth in Gb>[:<4(num lanes)>] 6441 * [:<queue config>] 6442 * [<4(num lanes)>] only used for 20G port. 6443 */ 6444 sub_str = config_str; 6445 6446 /* Parsing physical port number */ 6447 phy_port = sal_ctoi(sub_str, &sub_str_end); 6448 if (sub_str == sub_str_end) { 6449 LOG_CLI((BSL_META_U(unit, 6450 "Port %d: Missing physical port information \"%s\"\n"), 6451 port, config_str)); 6452 rv = SOC_E_FAIL; 6453 continue; 6454 } 6455 if (phy_port < 1 || phy_port > 72) { 6456 LOG_CLI((BSL_META_U(unit, 6457 "Port %d: Invalid physical port number %d\n"), 6458 port, phy_port)); 6459 rv = SOC_E_FAIL; 6460 continue; 6461 } 6462 if (si->port_p2l_mapping[phy_port] != -1) { 6463 LOG_CLI((BSL_META_U(unit, 6464 "Port %d: Physical port %d is used by port %d\n"), 6465 port, phy_port, si->port_p2l_mapping[phy_port])); 6466 rv = SOC_E_FAIL; 6467 continue; 6468 } 6469 pipe = phy_port < 37 ? 0 : 1; 6470 if (port_count[pipe] >= 32) { 6471 LOG_CLI((BSL_META_U(unit, 6472 "Can not configure more than 32 port in " 6473 "%c pipeline\n"), pipe ? 'Y' : 'X')); 6474 rv = SOC_E_FAIL; 6475 continue; 6476 } 6477 6478 /* Skip ':' */ 6479 sub_str = sub_str_end; 6480 if (*sub_str != '\0') { 6481 if (*sub_str != ':') { 6482 LOG_CLI((BSL_META_U(unit, 6483 "Port %d: Bad config string \"%s\"\n"), 6484 port, config_str)); 6485 rv = SOC_E_FAIL; 6486 continue; 6487 } 6488 sub_str++; 6489 } 6490 6491 /* Parsing bandwidth */ 6492 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 6493 if (sub_str[index] == '\0') { 6494 break; 6495 } 6496 str_buf[index] = sub_str[index]; 6497 } 6498 str_buf[index] = '\0'; 6499 if (!sal_strcmp(str_buf, str_2p5)) { 6500 port_bandwidth = 2500; 6501 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 6502 } else { 6503 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 6504 if (sub_str == sub_str_end) { 6505 LOG_CLI((BSL_META_U(unit, 6506 "Port %d: Missing bandwidth information \"%s\"\n"), 6507 port, config_str)); 6508 rv = SOC_E_FAIL; 6509 continue; 6510 } 6511 if (port_bandwidth != 1000 && port_bandwidth != 10000 && 6512 port_bandwidth != 15000 && port_bandwidth != 20000 && 6513 port_bandwidth != 21000 && port_bandwidth != 25000 && 6514 port_bandwidth != 30000 && port_bandwidth != 40000) { 6515 LOG_CLI((BSL_META_U(unit, 6516 "Port %d: Invalid bandwidth %d Gb\n"), 6517 port, port_bandwidth / 1000)); 6518 rv = SOC_E_FAIL; 6519 continue; 6520 } 6521 } 6522 6523 /* Skip ':' */ 6524 sub_str = sub_str_end; 6525 if (*sub_str != '\0') { 6526 if (*sub_str != ':') { 6527 LOG_CLI((BSL_META_U(unit, 6528 "Port %d: Bad config string \"%s\"\n"), 6529 port, config_str)); 6530 rv = SOC_E_FAIL; 6531 continue; 6532 } 6533 sub_str++; 6534 } 6535 6536 /* Parsing optional lane num */ 6537 option1 = 0; 6538 if (*sub_str != '\0') { 6539 if ((*sub_str == '2') || (*sub_str == '4')) { 6540 if (port_bandwidth != 20000) { 6541 LOG_CLI((BSL_META_U(unit, 6542 "Port %d: Invalid bandwidth %d Gb\n"), 6543 port, port_bandwidth / 1000)); 6544 rv = SOC_E_FAIL; 6545 continue; 6546 } 6547 option1 = *sub_str; 6548 sub_str++; 6549 } 6550 } 6551 6552 /* Skip ':' */ 6553 if (*sub_str != '\0' && option1) { 6554 if (*sub_str != ':') { 6555 LOG_CLI((BSL_META_U(unit, 6556 "Port %d: Bad config string \"%s\"\n"), 6557 port, config_str)); 6558 rv = SOC_E_FAIL; 6559 continue; 6560 } 6561 sub_str++; 6562 } 6563 6564 /* Parsing optional queue config */ 6565 ext_queue = FALSE; 6566 for (index = 0; index < sizeof(str_eq) - 1; index++) { 6567 if (sub_str[index] == '\0') { 6568 break; 6569 } 6570 if (sub_str[index] > 'a' && sub_str[index] < 'z') { 6571 str_buf[index] = sub_str[index] & ~0x20; 6572 } else { 6573 str_buf[index] = sub_str[index]; 6574 } 6575 } 6576 str_buf[index] = '\0'; 6577 if (!sal_strcmp(str_buf, str_eq)) { 6578 if ((dev_id == BCM56838_DEVICE_ID) 6579 || (dev_id == BCM56831_DEVICE_ID)) { 6580 LOG_CLI((BSL_META_U(unit, 6581 "Chip %s: Can not support extended " 6582 "queue \n"), 6583 soc_dev_name(unit))); 6584 rv = SOC_E_FAIL; 6585 continue; 6586 } 6587 ext_queue = TRUE; 6588 sub_str += sizeof(str_eq) - 1; 6589 6590 if (eq_port_count[pipe] >= 4) { 6591 LOG_CLI((BSL_META_U(unit, 6592 "Port %d %d %d %d %d: Can not configure more than" 6593 " 4 extended queue port in %c pipeline\n"), 6594 si->port_p2l_mapping[eq_port[pipe][0]], 6595 si->port_p2l_mapping[eq_port[pipe][1]], 6596 si->port_p2l_mapping[eq_port[pipe][2]], 6597 si->port_p2l_mapping[eq_port[pipe][3]], 6598 port, pipe ? 'Y' : 'X')); 6599 rv = SOC_E_FAIL; 6600 continue; 6601 } 6602 } 6603 6604 /* Checking trailing string */ 6605 if (*sub_str != '\0') { 6606 LOG_CLI((BSL_META_U(unit, 6607 "Port %d: Bad config string \"%s\"\n"), 6608 port, config_str)); 6609 rv = SOC_E_FAIL; 6610 continue; 6611 } 6612 6613 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, port); 6614 SOC_PORT_L2P_MAPPING_SET(unit, port, phy_port); 6615 SOC_PORT_SPEED_MAX_SET(unit, port, port_bandwidth); 6616 if (option1 == '4') { 6617 SOC_PORT_NUM_LANES_SET(unit, port, 4); 6618 } 6619 port_count[pipe]++; 6620 if (ext_queue) { 6621 eq_port[pipe][eq_port_count[pipe]] = port; 6622 eq_port_count[pipe]++; 6623 } 6624 } 6625 } 6626 6627 /* Bandwidth check for ports in each XLPORT block */ 6628 for (pipe = 0; pipe < 2; pipe++) { 6629 for (group = 0; group < 2; group++) { 6630 pg_bandwidth = 0; 6631 for (blk = 0; blk < (group ? 4 : 5); blk++) { 6632 /* Skip QGPORT (1G x 4) in XLPORT0 block (if present) */ 6633 if (pipe == 0 && group == 0 && blk == 0) { 6634 for (index = 0; index < _TD_PORTS_PER_BLK; index++) { 6635 port = si->port_p2l_mapping[1 + index]; 6636 if (port != -1 && si->port_speed_max[port] > 1000) { 6637 break; 6638 } 6639 } 6640 if (index == _TD_PORTS_PER_BLK) { 6641 continue; 6642 } 6643 } 6644 blk_bandwidth = 0; 6645 for (index = 0; index < 4; index++) { 6646 phy_port = 1 + pipe * 36 + group * 20 + blk * 4 + index; 6647 port = si->port_p2l_mapping[phy_port]; 6648 blk_port[index] = port; 6649 if (port == -1) { 6650 blk_port_bandwidth[index] = 0; 6651 continue; 6652 } 6653 blk_port_bandwidth[index] = si->port_speed_max[port]; 6654 if ((blk_port_bandwidth[index] > 20000 && index != 0) || 6655 (blk_port_bandwidth[index] > 10000 && (index & 1))) { 6656 LOG_CLI((BSL_META_U(unit, 6657 "Port %d: Physical port %d can not be " 6658 "configured to %d Gb\n"), 6659 port, phy_port, 6660 blk_port_bandwidth[index] / 1000)); 6661 rv = SOC_E_FAIL; 6662 continue; 6663 } 6664 blk_bandwidth += blk_port_bandwidth[index]; 6665 6666 /* 21G uses same bandwidth as 20G in higig2 mode */ 6667 if (blk_port_bandwidth[index] == 21000) { 6668 blk_bandwidth -= 1000; 6669 } 6670 } 6671 if ((blk_port_bandwidth[0] > 20000) || 6672 ((blk_port[0] != -1) && 6673 (si->port_num_lanes[blk_port[0]] == 4))) { 6674 for (index = 1; index < 4; index++) { 6675 if (blk_port[index] == -1) { 6676 continue; 6677 } 6678 LOG_CLI((BSL_META_U(unit, 6679 "Port %d bandwidth %d Gb and " 6680 "port %d can not be both configured\n"), 6681 blk_port[0], blk_port_bandwidth[0] / 1000, 6682 blk_port[index])); 6683 rv = SOC_E_FAIL; 6684 } 6685 } else if (blk_port_bandwidth[0] > 10000 || 6686 blk_port_bandwidth[2] > 10000) { 6687 if (blk_port_bandwidth[0] > 10000 && blk_port[1] != -1) { 6688 LOG_CLI((BSL_META_U(unit, 6689 "Port %d bandwidth %d Gb and " 6690 "port %d can not be both configured\n"), 6691 blk_port[0], 6692 si->port_speed_max[blk_port[0]] / 1000, 6693 blk_port[1])); 6694 rv = SOC_E_FAIL; 6695 } 6696 if (blk_port_bandwidth[2] > 10000 && blk_port[3] != -1) { 6697 LOG_CLI((BSL_META_U(unit, 6698 "Port %d bandwidth %d Gb and " 6699 "port %d can not be both configured\n"), 6700 blk_port[2], 6701 si->port_speed_max[blk_port[2]] / 1000, 6702 blk_port[3])); 6703 rv = SOC_E_FAIL; 6704 } 6705 if (blk_port[0] == -1) { 6706 LOG_CLI((BSL_META_U(unit, 6707 "Physical port %d needs to be configred " 6708 "in order to work with port %d\n"), 6709 1 + pipe * 36 + group * 20 + blk * 4, 6710 blk_port[2])); 6711 rv = SOC_E_FAIL; 6712 } else if (blk_port[2] != -1 && 6713 si->port_speed_max[blk_port[0]] != 6714 si->port_speed_max[blk_port[2]]) { 6715 LOG_CLI((BSL_META_U(unit, 6716 "Port %d bandwidth %d Gb can not have " 6717 "different bandwidth with port %d " 6718 "bandwidth %d Gb\n"), 6719 blk_port[0], 6720 si->port_speed_max[blk_port[0]] / 1000, 6721 blk_port[2], 6722 si->port_speed_max[blk_port[2]] / 1000)); 6723 rv = SOC_E_FAIL; 6724 } 6725 } 6726 if (blk_bandwidth > 40000) { 6727 LOG_CLI((BSL_META_U(unit, 6728 "XLPORT%d bandwidth %d Gb exceed limit\n"), 6729 pipe * 9 + group * 5 + blk, 6730 blk_bandwidth / 1000)); 6731 rv = SOC_E_FAIL; 6732 } 6733 pg_bandwidth += blk_bandwidth; 6734 } 6735 if (pg_bandwidth > si->bandwidth / 4) { 6736 LOG_CLI((BSL_META_U(unit, 6737 "PORT_GROUP%d_%c bandwidth %d Gb exceed limit\n"), 6738 group ? 4 : 5, pipe ? 'Y' : 'X', 6739 pg_bandwidth / 1000)); 6740 rv = SOC_E_FAIL; 6741 } 6742 } 6743 } 6744 6745 if (SOC_FAILURE(rv)) { 6746 for (phy_port = 1; phy_port < 73; phy_port++) { 6747 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, -1); 6748 } 6749 return rv; 6750 } 6751 6752 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 6753 LOG_CLI((BSL_META_U(unit, 6754 "physical to logical mapping:"))); 6755 for (index = 0; index < 74; index++) { 6756 if (index % 16 == 0) { 6757 LOG_CLI((BSL_META_U(unit, 6758 "\n "))); 6759 } 6760 LOG_CLI((BSL_META_U(unit, 6761 " %3d"), 6762 si->port_p2l_mapping[index])); 6763 } 6764 LOG_CLI((BSL_META_U(unit, 6765 "\n"))); 6766 LOG_CLI((BSL_META_U(unit, 6767 "physical port bandwidth:"))); 6768 for (index = 0; index < 74; index++) { 6769 if (index % 16 == 0) { 6770 LOG_CLI((BSL_META_U(unit, 6771 "\n "))); 6772 } 6773 port = si->port_p2l_mapping[index]; 6774 if (port == -1) { 6775 LOG_CLI((BSL_META_U(unit, 6776 " -1"))); 6777 } else if (si->port_speed_max[port] == 2500) { 6778 LOG_CLI((BSL_META_U(unit, 6779 " 2.5"))); 6780 } else { 6781 LOG_CLI((BSL_META_U(unit, 6782 " %3d"), 6783 si->port_speed_max[port] / 1000)); 6784 } 6785 } 6786 LOG_CLI((BSL_META_U(unit, 6787 "\n"))); 6788 } 6789 6790 /* Assign MMU port */ 6791 mmu_port_base[0] = 1; 6792 mmu_port_base[1] = 34; 6793 fifo_count[0] = fifo_count[1] = 0; 6794 6795 /* 6796 * To improve multicast performace, try assigning 4 fifo (instead of 1) 6797 * for ports in single mode or 2 fifo for ports in dual mode. It is not 6798 * always possible to assign such extra fifo when special GE port in 6799 * XLPORT0 is in user portmap. 6800 */ 6801 SOC_PBMP_CLEAR(pbmp_4fifo[0]); 6802 SOC_PBMP_CLEAR(pbmp_4fifo[1]); 6803 SOC_PBMP_CLEAR(pbmp_2fifo[0]); 6804 SOC_PBMP_CLEAR(pbmp_2fifo[1]); 6805 SOC_PBMP_CLEAR(pbmp_1fifo[0]); 6806 SOC_PBMP_CLEAR(pbmp_1fifo[1]); 6807 extra_fifo_count[0] = 0; 6808 extra_fifo_count[1] = 0; 6809 6810 si->port_pipe[0] = 0; 6811 si->port_pipe[65] = 1; 6812 6813 for (port = 1; port < 65; port++) { 6814 phy_port = si->port_l2p_mapping[port]; 6815 if (phy_port == -1) { 6816 continue; 6817 } 6818 if (phy_port < 37) { /* X-pipe */ 6819 pipe = 0; 6820 SOC_PBMP_PORT_ADD(si->xpipe_pbm, port); 6821 } else { /* Y-pipe */ 6822 pipe = 1; 6823 SOC_PBMP_PORT_ADD(si->ypipe_pbm, port); 6824 } 6825 6826 si->port_pipe[port] = pipe; 6827 6828 if (si->port_speed_max[port] > 20000 || 6829 si->port_num_lanes[port] == 4) { 6830 if (port_count[pipe] + extra_fifo_count[pipe] + 3 <= 32) { 6831 /* has more than 3 unused fifo can be assigned to this port */ 6832 SOC_PBMP_PORT_ADD(pbmp_4fifo[pipe], port); 6833 extra_fifo_count[pipe] += 3; 6834 } else { 6835 SOC_PBMP_PORT_ADD(pbmp_1fifo[pipe], port); 6836 } 6837 } else if (si->port_speed_max[port] > 10000) { 6838 /* has more than 1 unused fifo can be assigned to this port */ 6839 if (port_count[pipe] + extra_fifo_count[pipe] + 1 <= 32) { 6840 SOC_PBMP_PORT_ADD(pbmp_2fifo[pipe], port); 6841 extra_fifo_count[pipe] += 1; 6842 } else { 6843 SOC_PBMP_PORT_ADD(pbmp_1fifo[pipe], port); 6844 } 6845 } else { 6846 SOC_PBMP_PORT_ADD(pbmp_1fifo[pipe], port); 6847 } 6848 } 6849 6850 for (pipe = 0; pipe < SOC_MAX_NUM_PIPES; pipe++) { 6851 if (0 == pipe) { 6852 SOC_PBMP_ASSIGN(si->pipe_pbm[pipe], si->xpipe_pbm); 6853 } else if (1 == pipe) { 6854 SOC_PBMP_ASSIGN(si->pipe_pbm[pipe], si->ypipe_pbm); 6855 } 6856 } 6857 6858 /* User specified extended queuing ports */ 6859 for (pipe = 0; pipe < 2; pipe++) { 6860 for (index = 0; index < eq_port_count[pipe]; index++) { 6861 port = eq_port[pipe][index]; 6862 phy_port = si->port_l2p_mapping[port]; 6863 mmu_port = mmu_port_base[pipe] + index; 6864 SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port); 6865 SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port); 6866 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 6867 fifo_count[pipe] += 4; 6868 } 6869 } 6870 6871 /* Assign all 4 fifo in a MCQ group to each single mode XLPORT */ 6872 for (pipe = 0; pipe < 2; pipe++) { 6873 SOC_PBMP_ITER(pbmp_4fifo[pipe], port) { 6874 phy_port = si->port_l2p_mapping[port]; 6875 if (si->port_p2m_mapping[phy_port] != -1) { 6876 continue; 6877 } 6878 if (fifo_count[pipe] == 32) { 6879 break; 6880 } 6881 fifo_index = fifo_count[pipe]; 6882 /* 1, 2, 3, 4, 17, 18, 19, 20 */ 6883 mmu_port = mmu_port_base[pipe] + 6884 ((fifo_index & 0x10) | ((fifo_index & 0xc) >> 2)); 6885 fifo_count[pipe] += 4; 6886 SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port); 6887 SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port); 6888 } 6889 } 6890 6891 /* Assign 2 consective fifo in a MCQ group to each dual mode XLPORT */ 6892 for (pipe = 0; pipe < 2; pipe++) { 6893 /* Find unused fifo from the user specified extended queue ports */ 6894 count = 0; 6895 for (index = 0; index < eq_port_count[pipe]; index++) { 6896 port = eq_port[pipe][index]; 6897 if (!SOC_PBMP_MEMBER(pbmp_4fifo[pipe], port)) { 6898 unused_fifo[count] = index + 8; 6899 count++; 6900 } 6901 } 6902 6903 index = 0; 6904 SOC_PBMP_ITER(pbmp_2fifo[pipe], port) { 6905 phy_port = si->port_l2p_mapping[port]; 6906 if (si->port_p2m_mapping[phy_port] != -1) { 6907 continue; 6908 } 6909 if (index < count) { 6910 mmu_port = mmu_port_base[pipe] + unused_fifo[index]; 6911 index++; 6912 } else if (fifo_count[pipe] == 32) { 6913 break; 6914 } else { 6915 fifo_index = fifo_count[pipe]; 6916 /* 1, 9, 2, 10, 3, 11, 4, 12, 17, 25, 18, 26, 19, 27, 20, 28 */ 6917 mmu_port = mmu_port_base[pipe] + 6918 ((fifo_index & 0x10) | ((fifo_index & 0xc) >> 2) | 6919 ((fifo_index & 0x2) << 2)); 6920 fifo_count[pipe] += 2; 6921 } 6922 SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port); 6923 SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port); 6924 } 6925 } 6926 6927 /* Assign fifo to each quad mode XLPORT */ 6928 for (pipe = 0; pipe < 2; pipe++) { 6929 /* Find unused fifo from the user specified extended queue ports */ 6930 count = 0; 6931 for (index = 0; index < eq_port_count[pipe]; index++) { 6932 port = eq_port[pipe][index]; 6933 if (SOC_PBMP_MEMBER(pbmp_1fifo[pipe], port)) { 6934 unused_fifo[count] = index + 4; 6935 count++; 6936 } 6937 if (!SOC_PBMP_MEMBER(pbmp_4fifo[pipe], port) && 6938 si->port_m2p_mapping[mmu_port_base[pipe] + index + 8] == -1) { 6939 unused_fifo[count] = index + 8; 6940 count++; 6941 unused_fifo[count] = index + 12; 6942 count++; 6943 } 6944 } 6945 6946 index = 0; 6947 SOC_PBMP_ITER(pbmp_1fifo[pipe], port) { 6948 phy_port = si->port_l2p_mapping[port]; 6949 if (si->port_p2m_mapping[phy_port] != -1) { 6950 continue; 6951 } 6952 if (index < count) { 6953 mmu_port = mmu_port_base[pipe] + unused_fifo[index]; 6954 index++; 6955 } else if (fifo_count[pipe] == 32) { 6956 break; 6957 } else { 6958 fifo_index = fifo_count[pipe]; 6959 /* 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16, 6960 * 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31, 20, 24, 6961 * 28, 32 6962 */ 6963 mmu_port = mmu_port_base[pipe] + 6964 ((fifo_index & 0x10) | ((fifo_index & 0xc) >> 2) | 6965 ((fifo_index & 0x3) << 2)); 6966 fifo_count[pipe]++; 6967 } 6968 SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port); 6969 SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port); 6970 } 6971 } 6972 6973 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 6974 LOG_CLI((BSL_META_U(unit, 6975 "physical to mmu mapping:"))); 6976 for (index = 0; index < 74; index++) { 6977 if (index % 16 == 0) { 6978 LOG_CLI((BSL_META_U(unit, 6979 "\n "))); 6980 } 6981 LOG_CLI((BSL_META_U(unit, 6982 " %3d"), 6983 si->port_p2m_mapping[index])); 6984 } 6985 LOG_CLI((BSL_META_U(unit, 6986 "\n"))); 6987 } 6988 6989 return SOC_E_NONE; 6990 } 6991 6992 STATIC void 6993 _soc_trident_tdm_add_spacing(int target_len, int *target, int source_len, 6994 int *source, int pad) 6995 { 6996 int source_index, target_index; 6997 int result[_TD_TDM_NUM_SLOTS]; 6998 6999 /* Space out sequence with IDLE or NULL slot. 7000 * IDLE slot occupies a space in hardware TDM table 7001 * NULL slot will be removed from the merge result of this routine 7002 * Following is the slot usage for spreading sequence into 8 slots: 7003 * 40G bandwidth block: 40-40-40-40-40-40-40-40 7004 * 30G bandwidth block: xx-30-30-30-xx-30-30-30 7005 * 20G bandwidth block: xx-20-xx-20-xx-20-xx-20 7006 * 15G bandwidth block: xx-xx-15-xx-xx-15-xx-15 7007 * 10G bandwidth block: xx-xx-xx-10-xx-xx-xx-10 7008 * 5G bandwidth block: xx-xx-xx-xx-xx-xx-xx-5 (for 1G or 2.5G port) 7009 * Following is the slot usage for spreading sequence into 6 slots: 7010 * 30G bandwidth block: 30-30-30-30-30-30 7011 * 20G bandwidth block: xx-20-20-xx-20-20 7012 * 15G bandwidth block: xx-15-xx-15-xx-15 7013 * 10G bandwidth block: xx-xx-10-xx-xx-10 7014 * 5G bandwidth block: xx-xx-xx-xx-xx-5 (for 1G or 2.5G port) 7015 */ 7016 for (target_index = 0; target_index < target_len; target_index++) { 7017 result[target_index] = pad; 7018 } 7019 for (source_index = 0; source_index < source_len; source_index++) { 7020 target_index = target_len - 1 - 7021 (source_len - 1 - source_index) * target_len / source_len; 7022 result[target_index] = source[source_index]; 7023 } 7024 for (target_index = 0; target_index < target_len; target_index++) { 7025 target[target_index] = result[target_index]; 7026 } 7027 } 7028 7029 STATIC void 7030 _soc_trident_tdm_merge(int target_num_seq, int target_len, int source_num_seq, 7031 int padded_len0, int source_len0, int *seq0, 7032 int padded_len1, int source_len1, int *seq1, 7033 int padded_len2, int source_len2, int *seq2, 7034 int padded_len3, int source_len3, int *seq3) 7035 { 7036 int padded_len[_TD_TDM_NUM_COLUMNS], source_len[_TD_TDM_NUM_COLUMNS]; 7037 int *seq[_TD_TDM_NUM_COLUMNS]; 7038 int adjust_seq[_TD_TDM_NUM_COLUMNS][_TD_TDM_NUM_SLOTS]; 7039 int seq_len, *seq_ptr; 7040 int column, slot, count; 7041 7042 padded_len[0] = padded_len0; 7043 padded_len[1] = padded_len1; 7044 padded_len[2] = padded_len2; 7045 padded_len[3] = padded_len3; 7046 source_len[0] = source_len0; 7047 source_len[1] = source_len1; 7048 source_len[2] = source_len2; 7049 source_len[3] = source_len3; 7050 seq[0] = seq0; 7051 seq[1] = seq1; 7052 seq[2] = seq2; 7053 seq[3] = seq3; 7054 7055 for (column = 0; column < source_num_seq; column++) { 7056 seq_len = source_len[column]; 7057 seq_ptr = seq[column]; 7058 if (padded_len[column] > seq_len) { 7059 /* pad with evenly distributed idle slots */ 7060 _soc_trident_tdm_add_spacing 7061 (padded_len[column], adjust_seq[column], source_len[column], 7062 seq[column], _TD_TDM_SLOT_IDLE); 7063 seq_len = padded_len[column]; 7064 seq_ptr = adjust_seq[column]; 7065 } 7066 /* pad with evenly distributed null slots */ 7067 _soc_trident_tdm_add_spacing(target_len, adjust_seq[column], seq_len, 7068 seq_ptr, _TD_TDM_SLOT_NULL); 7069 } 7070 7071 count = 0; 7072 for (slot = 0; slot < target_len; slot++) { 7073 for (column = 0; column < source_num_seq; column++) { 7074 if (adjust_seq[column][slot] != _TD_TDM_SLOT_NULL) { 7075 seq[count % target_num_seq][count / target_num_seq] = 7076 adjust_seq[column][slot]; 7077 count++; 7078 } 7079 } 7080 } 7081 for (; count < target_len * target_num_seq; count++) { 7082 seq[count % target_num_seq][count / target_num_seq] = 7083 _TD_TDM_SLOT_NULL; 7084 } 7085 } 7086 7087 STATIC int 7088 _soc_trident_calculate_tdm_sequence(int unit, int pipe, int group, 7089 int *tdm_seq, int *tdm_seq_len, 7090 int extra_port, int extra_port_bandwidth) 7091 { 7092 soc_info_t *si; 7093 int group_min, group_max; 7094 int num_blk, blk_offset, blk_offset1; 7095 int num_col, num_row; 7096 int port, phy_port, index, port_index; 7097 int slot, slot_size, count, last_swap; 7098 int port_speed_max; 7099 int slot_count[_TD_PORTS_PER_BLK], max_slot_count; 7100 int blk_bandwidth[_TD_BLKS_PER_GROUP], max_blk_bandwidth; 7101 int blk_seq[_TD_BLKS_PER_GROUP][8], group_seq[2][32]; 7102 int sort_blk_list[_TD_BLKS_PER_GROUP]; 7103 int sort_blk_len[_TD_BLKS_PER_GROUP]; 7104 int blk_count, blk_index; 7105 7106 si = &SOC_INFO(unit); 7107 7108 if (pipe < 0 || pipe > 1 || group < -1 || group > 1) { 7109 return SOC_E_FAIL; 7110 } 7111 7112 if (group == -1) { 7113 group_min = 0; 7114 group_max = 1; 7115 } else { 7116 group_min = group_max = group; 7117 } 7118 7119 /* Collect port information */ 7120 sal_memset(group_seq, -1, sizeof(group_seq)); 7121 slot_size = 5000; 7122 for (group = group_min; group <= group_max; group++) { 7123 sal_memset(sort_blk_list, -1, sizeof(sort_blk_list)); 7124 sal_memset(blk_bandwidth, 0, sizeof(blk_bandwidth)); 7125 sal_memset(blk_seq, -1, sizeof(blk_seq)); 7126 blk_count = 0; 7127 max_blk_bandwidth = 0; 7128 num_blk = group ? 4 : 5; 7129 blk_index = pipe * _TD_BLKS_PER_PIPE + group * _TD_BLKS_PER_GROUP; 7130 for (blk_offset = 0; blk_offset < num_blk; blk_offset++) { 7131 phy_port = 1 + (blk_index + blk_offset) * _TD_PORTS_PER_BLK; 7132 /* Skip QGPORT (1G x 4) in XLPORT0 block (if present) */ 7133 if (phy_port == 1) { 7134 for (port_index = 0; port_index < _TD_PORTS_PER_BLK; 7135 port_index++) { 7136 port = si->port_p2l_mapping[phy_port + port_index]; 7137 if (port != -1 && si->port_speed_max[port] > 1000) { 7138 break; 7139 } 7140 } 7141 if (port_index == _TD_PORTS_PER_BLK) { 7142 continue; 7143 } 7144 } 7145 7146 /* Find the number of slots needed for each port in the block */ 7147 max_slot_count = 0; 7148 for (port_index = 0; port_index < _TD_PORTS_PER_BLK; 7149 port_index++) { 7150 port = si->port_p2l_mapping[phy_port + port_index]; 7151 if (port == -1) { 7152 continue; 7153 } 7154 port_speed_max = si->port_speed_max[port]; 7155 if (port_speed_max == 1000 || port_speed_max == 2500) { 7156 port_speed_max = 5000; 7157 } 7158 blk_bandwidth[blk_offset] += port_speed_max; 7159 slot_count[port_index] = port_speed_max / slot_size; 7160 if (max_slot_count < slot_count[port_index]) { 7161 max_slot_count = slot_count[port_index]; 7162 } 7163 } 7164 7165 if (blk_bandwidth[blk_offset] == 0) { 7166 continue; 7167 } 7168 if (max_blk_bandwidth < blk_bandwidth[blk_offset]) { 7169 max_blk_bandwidth = blk_bandwidth[blk_offset]; 7170 } 7171 blk_count++; 7172 7173 /* Construct per block TDM sequence */ 7174 count = 0; 7175 for (slot = 0; slot < max_slot_count; slot++) { 7176 for (port_index = 0; port_index < _TD_PORTS_PER_BLK; 7177 port_index++) { 7178 port = si->port_p2l_mapping[phy_port + port_index]; 7179 if (port == -1) { 7180 continue; 7181 } 7182 if (slot_count[port_index] == 0) { 7183 continue; 7184 } 7185 blk_seq[blk_offset][count] = port; 7186 slot_count[port_index]--; 7187 count++; 7188 } 7189 } 7190 } 7191 7192 if (blk_count == 0) { 7193 continue; 7194 } 7195 7196 /* Sort block by bandwidth, place highest bandwidth block first */ 7197 count = 0; 7198 for (blk_offset = 0; blk_offset < num_blk; blk_offset++) { 7199 if (blk_bandwidth[blk_offset] > 0) { 7200 sort_blk_list[count++] = blk_offset; 7201 } 7202 } 7203 do { 7204 last_swap = 0; 7205 for (index = 0; index < count - 1; index++) { 7206 blk_offset = sort_blk_list[index]; 7207 blk_offset1 = sort_blk_list[index + 1]; 7208 if (blk_bandwidth[blk_offset] >= blk_bandwidth[blk_offset1]) { 7209 continue; 7210 } 7211 sort_blk_list[index] = blk_offset1; 7212 sort_blk_list[index + 1] = blk_offset; 7213 last_swap = index + 1; 7214 } 7215 count = last_swap; 7216 } while (count > 1); 7217 7218 for (blk_index = 0; blk_index < _TD_BLKS_PER_GROUP; blk_index++) { 7219 blk_offset = sort_blk_list[blk_index]; 7220 sort_blk_len[blk_index] = 7221 blk_offset < 0 ? 0 : blk_bandwidth[blk_offset] / slot_size; 7222 } 7223 7224 if (si->bandwidth == 640000) { /* 640G */ 7225 num_col = 4; 7226 num_row = 8; 7227 if (blk_count == num_col + 1) { /* need to get rid of 1 column */ 7228 if (sort_blk_len[3] + sort_blk_len[4] <= num_row) { 7229 if (sort_blk_len[3] == 6) { /* *-*-*-30-x (x <= 10) */ 7230 /* merge 30, (padded) 10 into 1 column */ 7231 _soc_trident_tdm_merge 7232 (1, num_row, 2, 7233 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7234 2, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7235 -1, 0, 0, -1, 0, 0); 7236 } else { /* *-*-*-x-y (x <= 20, y <= 20) */ 7237 /* merge (padded) 20, (padded) 20 into 1 column */ 7238 _soc_trident_tdm_merge 7239 (1, num_row, 2, 7240 4, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7241 4, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7242 -1, 0, 0, -1, 0, 0); 7243 } 7244 /* add spacing for sort_blk_list[0] is at below */ 7245 _soc_trident_tdm_add_spacing(num_row, 7246 blk_seq[sort_blk_list[1]], 7247 sort_blk_len[1], 7248 blk_seq[sort_blk_list[1]], 7249 _TD_TDM_SLOT_IDLE); 7250 _soc_trident_tdm_add_spacing(num_row, 7251 blk_seq[sort_blk_list[2]], 7252 sort_blk_len[2], 7253 blk_seq[sort_blk_list[2]], 7254 _TD_TDM_SLOT_IDLE); 7255 } else if (sort_blk_len[4] == 6) { /* *-30-30-30-30 */ 7256 /* merge 30, 30, 30, 30 into 3 columns */ 7257 _soc_trident_tdm_merge 7258 (3, num_row, 4, 7259 -1, sort_blk_len[1], blk_seq[sort_blk_list[1]], 7260 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7261 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7262 -1, sort_blk_len[4], blk_seq[sort_blk_list[4]]); 7263 } else { /* *-*-30-30-x (x == 15 || x == 20) */ 7264 /* merge 30, 30, (padded) 20 into 2 columns */ 7265 _soc_trident_tdm_merge 7266 (2, num_row, 3, 7267 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7268 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7269 4, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7270 -1, 0, 0); 7271 /* add spacing for sort_blk_list[0] is at below */ 7272 _soc_trident_tdm_add_spacing(num_row, 7273 blk_seq[sort_blk_list[1]], 7274 sort_blk_len[1], 7275 blk_seq[sort_blk_list[1]], 7276 _TD_TDM_SLOT_IDLE); 7277 } 7278 _soc_trident_tdm_add_spacing(num_row, 7279 blk_seq[sort_blk_list[0]], 7280 sort_blk_len[0], 7281 blk_seq[sort_blk_list[0]], 7282 _TD_TDM_SLOT_IDLE); 7283 } 7284 } else if (max_blk_bandwidth <= 30000) { /* 480G/320G case 1 */ 7285 num_col = 4; 7286 num_row = 6; 7287 if (blk_count == num_col + 1) { /* need to get rid of 1 column */ 7288 if (sort_blk_len[3] + sort_blk_len[4] <= num_row) { 7289 if (sort_blk_len[3] == 4) { /* *-*-*-20-x (x <= 10) */ 7290 /* merge 20, (padded) 10 into 1 column */ 7291 _soc_trident_tdm_merge 7292 (1, num_row, 2, 7293 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7294 2, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7295 -1, 0, 0, -1, 0, 0); 7296 } else { /* *-*-*-x-y (x <= 15, y <= 15) */ 7297 /* merge (padded) 15, (padded) 15 into 1 column */ 7298 _soc_trident_tdm_merge 7299 (1, num_row, 2, 7300 3, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7301 3, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7302 -1, 0, 0, -1, 0, 0); 7303 } 7304 /* add spacing for sort_blk_list[0] is at below */ 7305 /* add spacing for sort_blk_list[1] is at below */ 7306 _soc_trident_tdm_add_spacing(num_row, 7307 blk_seq[sort_blk_list[2]], 7308 sort_blk_len[2], 7309 blk_seq[sort_blk_list[2]], 7310 _TD_TDM_SLOT_IDLE); 7311 } else { /* *-*-20-20-x (x == 15 || x == 20) */ 7312 /* merge 20, 20, (padded) 20 into 2 columns */ 7313 _soc_trident_tdm_merge 7314 (2, num_row, 3, 7315 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7316 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7317 4, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7318 -1, 0, 0); 7319 } 7320 _soc_trident_tdm_add_spacing(num_row, 7321 blk_seq[sort_blk_list[0]], 7322 sort_blk_len[0], 7323 blk_seq[sort_blk_list[0]], 7324 _TD_TDM_SLOT_IDLE); 7325 _soc_trident_tdm_add_spacing(num_row, 7326 blk_seq[sort_blk_list[1]], 7327 sort_blk_len[1], 7328 blk_seq[sort_blk_list[1]], 7329 _TD_TDM_SLOT_IDLE); 7330 } 7331 } else { /* 480G/320G case 2 */ 7332 num_col = 3; 7333 num_row = 8; 7334 if (blk_count == num_col + 1) { /* need to get rid of 1 column */ 7335 if (sort_blk_len[2] + sort_blk_len[3] <= num_row) { 7336 if (sort_blk_len[2] == 6) { /* 40-*-30-x (x <= 10) */ 7337 /* merge 30, (padded) 10 into 1 column */ 7338 _soc_trident_tdm_merge 7339 (1, num_row, 2, 7340 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7341 2, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7342 -1, 0, 0, -1, 0, 0); 7343 } else { /* 40-*-x-y (x <= 20, y <= 20) */ 7344 /* merge (padded) 20, (padded) 20 into 1 column */ 7345 _soc_trident_tdm_merge 7346 (1, num_row, 2, 7347 4, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7348 4, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7349 -1, 0, 0, -1, 0, 0); 7350 } 7351 _soc_trident_tdm_add_spacing(num_row, 7352 blk_seq[sort_blk_list[1]], 7353 sort_blk_len[1], 7354 blk_seq[sort_blk_list[1]], 7355 _TD_TDM_SLOT_IDLE); 7356 } else { /* 40-30-30-x (x == 15 || x == 20) */ 7357 /* merge 30, 30, (padded) 20 into 2 columns */ 7358 _soc_trident_tdm_merge 7359 (2, num_row, 3, 7360 -1, sort_blk_len[1], blk_seq[sort_blk_list[1]], 7361 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7362 4, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7363 -1, 0, 0); 7364 } 7365 } else if (blk_count == num_col + 2) { 7366 /* need to get rid of 2 columns */ 7367 if (sort_blk_len[2] + sort_blk_len[3] + sort_blk_len[4] <= 7368 num_row) { 7369 if (sort_blk_len[2] >= 4) { /* 40-*-x-y-z (x >= 20) */ 7370 /* first merge columns 3 and 4 into 1 column */ 7371 _soc_trident_tdm_merge 7372 (1, num_row, 2, 7373 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7374 -1, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7375 -1, 0, 0, -1, 0, 0); 7376 /* then merge columns 2 and merged 3+4 into 1 column */ 7377 _soc_trident_tdm_merge 7378 (1, num_row, 2, 7379 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7380 -1, sort_blk_len[3] + sort_blk_len[4], 7381 blk_seq[sort_blk_list[3]], 7382 -1, 0, 0, -1, 0, 0); 7383 } else { /* 40-*-x-y-z (x < 20) */ 7384 /* directly merge all 3 columns into 1 column */ 7385 _soc_trident_tdm_merge 7386 (1, num_row, 3, 7387 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7388 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7389 -1, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7390 -1, 0, 0); 7391 } 7392 _soc_trident_tdm_add_spacing(num_row, 7393 blk_seq[sort_blk_list[1]], 7394 sort_blk_len[1], 7395 blk_seq[sort_blk_list[1]], 7396 _TD_TDM_SLOT_IDLE); 7397 } else if (sort_blk_len[1] + sort_blk_len[4] <= 8 && 7398 sort_blk_len[2] + sort_blk_len[3] <= 8) { 7399 /* merge columns 1 and 4 into 1 column */ 7400 _soc_trident_tdm_merge 7401 (1, num_row, 2, 7402 -1, sort_blk_len[1], blk_seq[sort_blk_list[1]], 7403 -1, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7404 -1, 0, 0, -1, 0, 0); 7405 /* merge columns 2 and 3 into 1 column */ 7406 _soc_trident_tdm_merge 7407 (1, num_row, 2, 7408 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7409 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7410 -1, 0, 0, -1, 0, 0); 7411 } else if (sort_blk_len[2] == 6) { /* 40-30-30-15-5 */ 7412 /* first merge columns 3 and 4 into 1 column */ 7413 _soc_trident_tdm_merge 7414 (1, num_row, 2, 7415 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7416 -1, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7417 -1, 0, 0, -1, 0, 0); 7418 /* then merge 30, 30, merged 3+4 into 2 columns */ 7419 _soc_trident_tdm_merge 7420 (2, num_row, 3, 7421 -1, sort_blk_len[1], blk_seq[sort_blk_list[1]], 7422 -1, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7423 -1, sort_blk_len[3] + sort_blk_len[4], 7424 blk_seq[sort_blk_list[3]], 7425 -1, 0, 0); 7426 } else { /* 40-30-x-15-15 (x == 15 || x == 20) */ 7427 /* first merge columns 3 and 4 into 1 column */ 7428 _soc_trident_tdm_merge 7429 (1, num_row, 2, 7430 -1, sort_blk_len[3], blk_seq[sort_blk_list[3]], 7431 -1, sort_blk_len[4], blk_seq[sort_blk_list[4]], 7432 -1, 0, 0, -1, 0, 0); 7433 /* then merge 30, merged 3+4, (padded) 20 into 2 columns */ 7434 _soc_trident_tdm_merge 7435 (2, num_row, 3, 7436 -1, sort_blk_len[1], blk_seq[sort_blk_list[1]], 7437 -1, sort_blk_len[3] + sort_blk_len[4], 7438 blk_seq[sort_blk_list[3]], 7439 4, sort_blk_len[2], blk_seq[sort_blk_list[2]], 7440 -1, 0, 0); 7441 } 7442 } 7443 } 7444 7445 if (blk_count <= num_col) { 7446 /* If no merge was done, just evenly distributed the sequence 7447 * in each block */ 7448 for (blk_index = 0; blk_index < num_col; blk_index++) { 7449 blk_offset = sort_blk_list[blk_index]; 7450 if (blk_offset < 0) { 7451 break; 7452 } 7453 _soc_trident_tdm_add_spacing 7454 (num_row, blk_seq[blk_offset], sort_blk_len[blk_index], 7455 blk_seq[blk_offset], _TD_TDM_SLOT_IDLE); 7456 } 7457 } 7458 7459 for (blk_index = 0; blk_index < num_col; blk_index++) { 7460 blk_offset = sort_blk_list[blk_index]; 7461 if (blk_offset < 0) { 7462 break; 7463 } 7464 for (index = 0; index < num_row; index++) { 7465 group_seq[group][index * num_col + blk_index] = 7466 blk_seq[blk_offset][index]; 7467 } 7468 } 7469 } 7470 7471 /* Construct final TDM sequence from 2 group TDM sequences */ 7472 count = si->bandwidth == 640000 ? 32 : 24; 7473 index = 0; 7474 for (slot = 0; slot < count; slot++) { 7475 for (group = group_min; group <= group_max; group++) { 7476 tdm_seq[index++] = group_seq[group][slot]; 7477 } 7478 if (extra_port != -1) { 7479 if (slot == count - 1 || 7480 (extra_port_bandwidth == 10000 && slot == count / 2 - 1)) { 7481 tdm_seq[index++] = extra_port; 7482 } 7483 } 7484 } 7485 *tdm_seq_len = index; 7486 7487 return SOC_E_NONE; 7488 } 7489 7490 STATIC int 7491 _soc_trident_pg_tdm_init(int unit) 7492 { 7493 static const soc_field_t tdm_field[] = { 7494 TDM_ENTRY0_PORT_IDf, TDM_ENTRY1_PORT_IDf, TDM_ENTRY2_PORT_IDf, 7495 TDM_ENTRY3_PORT_IDf, TDM_ENTRY4_PORT_IDf, TDM_ENTRY5_PORT_IDf, 7496 TDM_ENTRY6_PORT_IDf, TDM_ENTRY7_PORT_IDf, TDM_ENTRY8_PORT_IDf, 7497 TDM_ENTRY9_PORT_IDf, TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf, 7498 TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf, TDM_ENTRY14_PORT_IDf, 7499 TDM_ENTRY15_PORT_IDf, TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf, 7500 TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf, TDM_ENTRY20_PORT_IDf, 7501 TDM_ENTRY21_PORT_IDf, TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf, 7502 TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf, TDM_ENTRY26_PORT_IDf, 7503 TDM_ENTRY27_PORT_IDf, TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf, 7504 TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf 7505 }; 7506 static const soc_reg_t tdm_reg[2][8] = { 7507 { 7508 PORT_GROUP5_TDM_REG_0r, PORT_GROUP5_TDM_REG_1r, 7509 PORT_GROUP5_TDM_REG_2r, PORT_GROUP5_TDM_REG_3r, 7510 PORT_GROUP5_TDM_REG_4r, PORT_GROUP5_TDM_REG_5r, 7511 PORT_GROUP5_TDM_REG_6r, PORT_GROUP5_TDM_REG_7r 7512 }, 7513 { 7514 PORT_GROUP4_TDM_REG_0r, PORT_GROUP4_TDM_REG_1r, 7515 PORT_GROUP4_TDM_REG_2r, PORT_GROUP4_TDM_REG_3r, 7516 PORT_GROUP4_TDM_REG_4r, PORT_GROUP4_TDM_REG_5r, 7517 PORT_GROUP4_TDM_REG_6r, PORT_GROUP4_TDM_REG_7r 7518 } 7519 }; 7520 static const soc_reg_t tdm_control[2] = { 7521 PORT_GROUP5_TDM_CONTROLr, PORT_GROUP4_TDM_CONTROLr 7522 }; 7523 soc_info_t *si; 7524 soc_reg_t reg; 7525 soc_field_t field; 7526 uint32 rval; 7527 int rv, pipe, group, port, phy_port, index; 7528 int tdm_seq[32], tdm_seq_len; 7529 7530 si = &SOC_INFO(unit); 7531 7532 for (pipe = 0; pipe < 2; pipe++) { 7533 for (group = 0; group < 2; group++) { 7534 rv = _soc_trident_calculate_tdm_sequence(unit, pipe, group, 7535 tdm_seq, &tdm_seq_len, -1, 7536 0); 7537 if (rv == SOC_E_EMPTY) { 7538 continue; 7539 } else if (SOC_FAILURE(rv)) { 7540 return rv; 7541 } 7542 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 7543 LOG_CLI((BSL_META_U(unit, 7544 "PORT_GROUP%c_%c TDM:"), 7545 group ? '4' : '5', pipe ? 'Y' : 'X')); 7546 for (index = 0; index < tdm_seq_len; index++) { 7547 if (index % 16 == 0) { 7548 LOG_CLI((BSL_META_U(unit, 7549 "\n "))); 7550 } 7551 LOG_CLI((BSL_META_U(unit, 7552 " %2d"), tdm_seq[index])); 7553 } 7554 LOG_CLI((BSL_META_U(unit, 7555 "\n"))); 7556 } 7557 rval = 0; 7558 for (index = 0; index < tdm_seq_len; index++) { 7559 reg = tdm_reg[group][index / 4]; 7560 field = tdm_field[index]; 7561 port = tdm_seq[index]; 7562 if (port != _TD_TDM_SLOT_IDLE && port != _TD_TDM_SLOT_NULL) { 7563 phy_port = si->port_l2p_mapping[port]; 7564 soc_reg_field_set(unit, reg, &rval, field, phy_port); 7565 } else { 7566 soc_reg_field_set(unit, reg, &rval, field, 0x7f); 7567 } 7568 if (index % 4 == 3 || index == tdm_seq_len - 1) { 7569 SOC_IF_ERROR_RETURN 7570 (soc_reg32_set(unit, reg, pipe, 0, rval)); 7571 rval = 0; 7572 } 7573 } 7574 reg = tdm_control[group]; 7575 rval = 0; 7576 soc_reg_field_set(unit, reg, &rval, TDM_WRAP_PTRf, 7577 tdm_seq_len - 1); 7578 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pipe, 0, rval)); 7579 } 7580 } 7581 7582 return SOC_E_NONE; 7583 } 7584 7585 STATIC int 7586 _soc_trident_mmu_tdm_init(int unit) 7587 { 7588 static const soc_mem_t tdm_mem[] = { 7589 ARB_TDM_TABLE_0m, ARB_TDM_TABLE_1m 7590 }; 7591 soc_info_t *si; 7592 soc_mem_t mem; 7593 union { 7594 arb_tdm_table_0_entry_t table_0; 7595 arb_tdm_table_1_entry_t table_1; 7596 } entry; 7597 int rv, pipe, port, phy_port, mmu_port, index, base; 7598 int tdm_seq[128], tdm_seq_len; 7599 int extra_port; 7600 7601 si = &SOC_INFO(unit); 7602 7603 for (pipe = 0; pipe < 2; pipe++) { 7604 if (pipe == 0) { /* X pipe */ 7605 extra_port = 0; 7606 base = 0; 7607 } else { /* Y pipe */ 7608 extra_port = 65; 7609 base = 33; 7610 } 7611 rv = _soc_trident_calculate_tdm_sequence(unit, pipe, -1, tdm_seq, 7612 &tdm_seq_len, extra_port, 7613 si->bandwidth == 640000 ? 7614 5000 : 10000); 7615 if (rv == SOC_E_EMPTY) { 7616 continue; 7617 } else if (SOC_FAILURE(rv)) { 7618 return rv; 7619 } 7620 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 7621 LOG_CLI((BSL_META_U(unit, 7622 "%c pipe MMU TDM:"), pipe ? 'Y' : 'X')); 7623 for (index = 0; index < tdm_seq_len; index++) { 7624 if (index % 16 == 0) { 7625 LOG_CLI((BSL_META_U(unit, 7626 "\n "))); 7627 } 7628 LOG_CLI((BSL_META_U(unit, 7629 " %2d"), tdm_seq[index])); 7630 } 7631 LOG_CLI((BSL_META_U(unit, 7632 "\n"))); 7633 } 7634 7635 mem = tdm_mem[pipe]; 7636 sal_memset(&entry, 0, sizeof(entry)); 7637 for (index = 0; index < tdm_seq_len; index++) { 7638 port = tdm_seq[index]; 7639 if (port != _TD_TDM_SLOT_IDLE && port != _TD_TDM_SLOT_NULL) { 7640 phy_port = si->port_l2p_mapping[port]; 7641 mmu_port = si->port_p2m_mapping[phy_port]; 7642 soc_mem_field32_set(unit, mem, &entry, PORT_NUMf, 7643 mmu_port - base); 7644 } else { 7645 soc_mem_field32_set(unit, mem, &entry, PORT_NUMf, 0x3f); 7646 } 7647 if (index == tdm_seq_len - 1) { 7648 soc_mem_field32_set(unit, mem, &entry, WRAP_ENf, 1); 7649 } 7650 SOC_IF_ERROR_RETURN 7651 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &entry)); 7652 } 7653 } 7654 7655 return SOC_E_NONE; 7656 } 7657 7658 extern int (*_phy_wc40_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *,int); 7659 7660 int 7661 trident_wc40_firmware_set(int unit, int port, uint8 *array,int datalen) 7662 { 7663 return soc_warpcore_firmware_set(unit, port, array, datalen, 0, 7664 XLPORT_WC_UCMEM_DATAm, 7665 XLPORT_WC_UCMEM_CTRLr); 7666 } 7667 7668 STATIC int 7669 _trident_ledup_init(int unit) 7670 { 7671 int ix; 7672 uint32 rval = 0; 7673 struct led_remap { 7674 uint32 reg_addr; 7675 uint32 port0; 7676 uint32 port1; 7677 uint32 port2; 7678 uint32 port3; 7679 } led1_remap[] = { 7680 {CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, 7681 REMAP_PORT_0f,REMAP_PORT_1f,REMAP_PORT_2f,REMAP_PORT_3f}, 7682 {CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, 7683 REMAP_PORT_4f,REMAP_PORT_5f,REMAP_PORT_6f,REMAP_PORT_7f}, 7684 {CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, 7685 REMAP_PORT_8f,REMAP_PORT_9f,REMAP_PORT_10f,REMAP_PORT_11f}, 7686 {CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, 7687 REMAP_PORT_12f,REMAP_PORT_13f,REMAP_PORT_14f,REMAP_PORT_15f}, 7688 {CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, 7689 REMAP_PORT_16f,REMAP_PORT_17f,REMAP_PORT_18f,REMAP_PORT_19f}, 7690 {CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, 7691 REMAP_PORT_20f,REMAP_PORT_21f,REMAP_PORT_22f,REMAP_PORT_23f}, 7692 {CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, 7693 REMAP_PORT_24f,REMAP_PORT_25f,REMAP_PORT_26f,REMAP_PORT_27f}, 7694 {CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, 7695 REMAP_PORT_28f,REMAP_PORT_29f,REMAP_PORT_30f,REMAP_PORT_31f}, 7696 {CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, 7697 REMAP_PORT_32f,REMAP_PORT_33f,REMAP_PORT_34f,REMAP_PORT_35f} 7698 }; 7699 7700 /* initialize the led1 remap register settings to match the led0's default. 7701 * port 0 entry will not be used for easy index of the physical port starting 1 7702 */ 7703 for (ix = 0; ix < sizeof(led1_remap)/sizeof(led1_remap[0]); ix++) { 7704 rval = 0; 7705 soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 7706 led1_remap[ix].port0, 36 - ix * 4); 7707 soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 7708 led1_remap[ix].port1, 35 - ix * 4); 7709 soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 7710 led1_remap[ix].port2, 34 - ix * 4); 7711 soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 7712 led1_remap[ix].port3, 33 - ix * 4); 7713 /* coverity[result_independent_of_operands] */ 7714 SOC_IF_ERROR_RETURN 7715 (soc_pci_write(unit, 7716 soc_reg_addr(unit, led1_remap[ix].reg_addr, REG_PORT_ANY, 0), 7717 rval)); 7718 } 7719 7720 /* set the LED scanchain start address */ 7721 rval = 0x4A; 7722 /* coverity[result_independent_of_operands] */ 7723 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_SCANCHAIN_ASSEMBLY_ST_ADDRr(unit, rval)); 7724 /* coverity[result_independent_of_operands] */ 7725 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_SCANCHAIN_ASSEMBLY_ST_ADDRr(unit, rval)); 7726 7727 /* configure the LED scan delay cycles */ 7728 /* coverity[result_independent_of_operands] */ 7729 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval)); 7730 soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 11); 7731 /* coverity[result_independent_of_operands] */ 7732 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval)); 7733 7734 /* coverity[result_independent_of_operands] */ 7735 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP1_CTRLr(unit, &rval)); 7736 soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 15); 7737 /* coverity[result_independent_of_operands] */ 7738 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_CTRLr(unit, rval)); 7739 7740 /* initialize the UP0 and UP1 data ram */ 7741 rval = 0; 7742 for (ix = 0; ix < 256; ix++) { 7743 /* coverity[result_independent_of_operands] */ 7744 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval)); 7745 /* coverity[result_independent_of_operands] */ 7746 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_DATA_RAMr(unit,ix, rval)); 7747 } 7748 return SOC_E_NONE; 7749 } 7750 7751 #if defined(SER_TR_TEST_SUPPORT) 7752 soc_ser_test_functions_t ser_trident_test_fun; 7753 #endif 7754 STATIC int 7755 _soc_trident_misc_init(int unit) 7756 7757 { static const soc_field_t port_field[4] = { 7758 PORT0f, PORT1f, PORT2f, PORT3f 7759 }; 7760 static const soc_field_t mac_mode_field[4] = { 7761 PORT0_MAC_MODEf, PORT1_MAC_MODEf, PORT2_MAC_MODEf, PORT3_MAC_MODEf 7762 }; 7763 static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 }; 7764 soc_info_t *si; 7765 uint32 rval; 7766 uint32 reset_status; 7767 uint32 entry[SOC_MAX_MEM_WORDS]; 7768 soc_pbmp_t pbmp; 7769 int port, phy_port, blk_port, blk, bindex; 7770 uint32 core_mode, phy_mode; 7771 int num_lanes; 7772 int blk_bandwidth; 7773 int index, count, sub_sel, offset; 7774 int divisor, dividend, delay; 7775 uint64 reg64; 7776 uint16 dev_id; 7777 uint8 rev_id; 7778 int parity_enable, cache_fpgm; 7779 soc_field_t fields[3]; 7780 uint32 values[3]; 7781 int higig2; 7782 7783 soc_cm_get_id(unit, &dev_id, &rev_id); 7784 7785 si = &SOC_INFO(unit); 7786 7787 /* Stop the mem scan task before all of the parity init takes place */ 7788 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 7789 7790 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 7791 if (parity_enable) { 7792 soc_ser_log_init(unit, NULL, 0); 7793 (void) _soc_trident_ser_init(unit); 7794 #if defined(SER_TR_TEST_SUPPORT) 7795 /*Initialize chip-specific functions for SER testing*/ 7796 memset(&ser_trident_test_fun, 0, sizeof(soc_ser_test_functions_t)); 7797 ser_trident_test_fun.inject_error_f = &soc_td_ser_inject_error; 7798 ser_trident_test_fun.test_mem = &soc_td_ser_mem_test; 7799 ser_trident_test_fun.test = &soc_td_ser_test; 7800 ser_trident_test_fun.parity_control = &_ser_test_parity_control_pci_write; 7801 ser_trident_test_fun.injection_support = &soc_td_ser_error_injection_support; 7802 soc_ser_test_functions_register(unit, &ser_trident_test_fun); 7803 #endif /*defined(SER_TR_TEST_SUPPORT*/ 7804 #ifdef INCLUDE_MEM_SCAN 7805 soc_mem_scan_ser_list_register(unit, FALSE, 7806 _soc_td_ser_parity_info[unit]); 7807 #endif 7808 memset(&_td_ser_functions, 0, sizeof(soc_ser_functions_t)); 7809 _td_ser_functions._soc_ser_stat_nack_f = &soc_trident_stat_nack; 7810 _td_ser_functions._soc_ser_mem_nack_f = &soc_trident_mem_nack; 7811 _td_ser_functions._soc_ser_fail_f = &soc_trident_ser_fail; 7812 _td_ser_functions._soc_ser_parity_error_intr_f = &soc_trident_parity_error; 7813 _td_ser_functions._soc_ser_populate_tcam_log_f = &soc_trident_populate_tcam_log; 7814 soc_ser_function_register(unit, &_td_ser_functions); 7815 } 7816 7817 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 7818 SOC_IF_ERROR_RETURN(_soc_trident_clear_all_memory(unit)); 7819 } 7820 7821 if (parity_enable) { 7822 (void)_soc_trident_parity_enable_all(unit, TRUE); 7823 } 7824 SOC_IF_ERROR_RETURN(_soc_trident_port_mapping_init(unit)); 7825 7826 sal_memset(entry, 0, sizeof(cpu_pbm_entry_t)); 7827 soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit)); 7828 SOC_IF_ERROR_RETURN 7829 (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry)); 7830 7831 sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t)); 7832 soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit)); 7833 SOC_IF_ERROR_RETURN 7834 (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry)); 7835 7836 sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t)); 7837 soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf, 7838 &PBMP_LB(unit)); 7839 SOC_IF_ERROR_RETURN 7840 (soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm, MEM_BLOCK_ALL, 0, 7841 entry)); 7842 7843 sal_memset(entry, 0, sizeof(isbs_port_to_pipe_mapping_entry_t)); 7844 soc_mem_pbmp_field_set(unit, ISBS_PORT_TO_PIPE_MAPPINGm, entry, BITMAPf, 7845 &PBMP_YPIPE(unit)); 7846 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ISBS_PORT_TO_PIPE_MAPPINGm, 7847 MEM_BLOCK_ALL, 0, entry)); 7848 7849 sal_memset(entry, 0, sizeof(esbs_port_to_pipe_mapping_entry_t)); 7850 soc_mem_pbmp_field_set(unit, ESBS_PORT_TO_PIPE_MAPPINGm, entry, BITMAPf, 7851 &PBMP_YPIPE(unit)); 7852 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ESBS_PORT_TO_PIPE_MAPPINGm, 7853 MEM_BLOCK_ALL, 0, entry)); 7854 7855 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 7856 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 7857 PBMP_HG_ITER(unit, port) { 7858 SOC_IF_ERROR_RETURN 7859 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 7860 } 7861 higig2 = soc_property_port_get(unit, CMIC_PORT(unit), spn_HIGIG2_HDR_MODE, 7862 0) ? 1 : 0; 7863 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, higig2); 7864 SOC_IF_ERROR_RETURN 7865 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index, 7866 entry)); 7867 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2); 7868 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, 0); 7869 SOC_IF_ERROR_RETURN 7870 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, LB_PORT(unit), 7871 entry)); 7872 7873 /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to 7874 * initialize the cache until now. This is the time to check for 7875 * the cache permission of this table. 7876 */ 7877 cache_fpgm = soc_feature(unit, soc_feature_mem_cache) && 7878 soc_property_get(unit, spn_MEM_CACHE_ENABLE, 7879 (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1); 7880 if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) { 7881 char mem_name[100]; 7882 char *mptr; 7883 7884 sal_memset(mem_name, 0, sizeof(mem_name)); 7885 sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_")); 7886 mptr = &mem_name[sal_strlen(mem_name)]; 7887 sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm), 7888 sizeof(mem_name) - sal_strlen(mem_name) - 1); 7889 if (soc_property_get(unit, mem_name, 0)) { 7890 cache_fpgm = 0; 7891 } 7892 } 7893 7894 if (cache_fpgm) { 7895 SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |= 7896 SOC_MEM_FLAG_CACHABLE; 7897 SOC_IF_ERROR_RETURN 7898 (soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm, 7899 MEM_BLOCK_ALL, TRUE)); 7900 } 7901 7902 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 7903 /* Must clear FP_GLOBAL_MASK_TCAM after port to pipe mappings 7904 * are initialized. */ 7905 SOC_IF_ERROR_RETURN 7906 (soc_mem_clear(unit, FP_GLOBAL_MASK_TCAMm, COPYNO_ALL, TRUE)); 7907 } 7908 7909 /* Enable XPAUSE (both TX and RX) on higig port */ 7910 values[0] = 0; 7911 soc_reg_field_set(unit, XLPORT_CONFIGr, &values[0], HIGIG_MODEf, 1); 7912 soc_reg_field_set(unit, XLPORT_CONFIGr, &values[0], XPAUSE_ENf, 1); 7913 /* Enable RX XPAUSE on ethernet port to handle XMAC RX pause errata, 7914 * set MY_MODID to any non-zero value */ 7915 values[1] = 0; 7916 soc_reg_field_set(unit, XLPORT_CONFIGr, &values[1], XPAUSE_RX_ENf, 1); 7917 soc_reg_field_set(unit, XLPORT_CONFIGr, &values[1], MY_MODIDf, 2); 7918 PBMP_PORT_ITER(unit, port) { 7919 SOC_IF_ERROR_RETURN 7920 (WRITE_XLPORT_CONFIGr(unit, port, 7921 values[IS_HG_PORT(unit, port) ? 0 : 1])); 7922 } 7923 7924 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 7925 blk_port = SOC_BLOCK_PORT(unit, blk); 7926 if (blk_port < 0) { 7927 continue; 7928 } 7929 /* 7930 * Program XLPORT mode and default Warpcore lanes setting 7931 * core_mode: the number of ports on the system side of XMAC 7932 * phy_mode: the number of ports on the Warpcore side of XMAC 7933 * num_lanes: the number of lanes on the line side of Warpcore 7934 */ 7935 if (si->port_speed_max[blk_port] > 20000) { 7936 core_mode = 0; /* single, XMAC works as a single MAC */ 7937 phy_mode = 0; /* single, use all 16 lanes for a port */ 7938 num_lanes = 4; 7939 } else if (si->port_speed_max[blk_port] > 10000) { 7940 if ((si->port_speed_max[blk_port] == 20000) && 7941 (si->port_num_lanes[blk_port] == 4)){ 7942 core_mode = 0; /* single, XMAC works as a single MAC */ 7943 phy_mode = 1; /* dual, use 8 lanes per port */ 7944 num_lanes = 4; 7945 } else { 7946 core_mode = 1; /* dual, XMAC works as 2 MACs */ 7947 phy_mode = 1; /* dual, use 8 lanes per port */ 7948 num_lanes = 2; 7949 } 7950 } else { 7951 core_mode = 2; /* quad, XMAC works as 4 MACs */ 7952 phy_mode = 2; /* quad, use 4 lanes per port */ 7953 num_lanes = 1; 7954 } 7955 rval = 0; 7956 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, 7957 core_mode); 7958 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, PHY_PORT_MODEf, 7959 phy_mode); 7960 phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1; 7961 for (bindex = 0; bindex < 4; bindex++) { 7962 port = si->port_p2l_mapping[phy_port + bindex]; 7963 if (port == -1) { 7964 continue; 7965 } 7966 if (si->port_speed_max[port] < 10000) { 7967 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, 7968 mac_mode_field[bindex], 1); 7969 } 7970 si->port_num_lanes[port] = num_lanes; 7971 } 7972 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, blk_port, rval)); 7973 7974 /* Do XMAC reset when port mode is changed */ 7975 SOC_IF_ERROR_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, blk_port, &rval)); 7976 reset_status = soc_reg_field_get(unit, XLPORT_XMAC_CONTROLr, rval, XMAC_RESETf); 7977 if (reset_status != 1) { 7978 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 7979 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, blk_port, rval)); 7980 sal_udelay(10); 7981 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 7982 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, blk_port, rval)); 7983 } 7984 7985 /* Enable XLPORT */ 7986 rval = 0; 7987 for (bindex = 0; bindex < 4; bindex++) { 7988 if (si->port_p2l_mapping[phy_port + bindex] != -1) { 7989 soc_reg_field_set(unit, XLPORT_PORT_ENABLEr, &rval, 7990 port_field[bindex], 1); 7991 } 7992 } 7993 SOC_IF_ERROR_RETURN(WRITE_XLPORT_PORT_ENABLEr(unit, blk_port, rval)); 7994 } 7995 7996 /* Enable QGPORT (1G x 4) in XLPORT0 block (if present) */ 7997 blk_bandwidth = 0; 7998 for (phy_port = 1; phy_port < 5; phy_port++) { 7999 port = si->port_p2l_mapping[phy_port]; 8000 if (port != -1) { 8001 blk_bandwidth += si->port_speed_max[port]; 8002 } 8003 } 8004 if (blk_bandwidth > 0 && blk_bandwidth <= 4000) { 8005 rval = 0; 8006 soc_reg_field_set(unit, PORT_GROUP5_QGPORT_ENABLEr, &rval, 8007 QGPORT_ENABLEf, 1); 8008 SOC_IF_ERROR_RETURN(WRITE_PORT_GROUP5_QGPORT_ENABLEr(unit, 0, rval)); 8009 } 8010 8011 /* Setup TDM within each port group */ 8012 SOC_IF_ERROR_RETURN(_soc_trident_pg_tdm_init(unit)); 8013 8014 /* Setup main TDM between each port group */ 8015 sal_memset(entry, 0, sizeof(iarb_main_tdm_entry_t)); 8016 count = si->bandwidth == 640000 ? 64 : 32; 8017 for (index = 0; index < count; index++) { 8018 soc_mem_field32_set(unit, IARB_MAIN_TDMm, entry, TDM_SLOTf, index & 1); 8019 SOC_IF_ERROR_RETURN 8020 (soc_mem_write(unit, IARB_MAIN_TDMm, MEM_BLOCK_ALL, index, entry)); 8021 } 8022 soc_mem_field32_set(unit, IARB_MAIN_TDMm, entry, TDM_SLOTf, 2); 8023 SOC_IF_ERROR_RETURN 8024 (soc_mem_write(unit, IARB_MAIN_TDMm, MEM_BLOCK_ALL, count, entry)); 8025 8026 /* Setup main TDM control */ 8027 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 8028 /* BCMSIM handles Single Cell packets */ 8029 if (SAL_BOOT_BCMSIM) { 8030 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 1); 8031 } else { 8032 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0); 8033 } 8034 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, count); 8035 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 8036 8037 /* Setup EGR_PERQ_XMT_COUNTERS_BASE_ADDR for each port */ 8038 _soc_trident_egr_perq_xmt_counters_init(unit); 8039 8040 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 8041 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 8042 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 8043 8044 /* Enable dual hash on L2, L3 and MPLS_ENTRY tables */ 8045 fields[0] = ENABLEf; 8046 values[0] = 1; 8047 fields[1] = HASH_SELECTf; 8048 values[1] = FB_HASH_CRC32_LOWER; 8049 fields[2] = INSERT_LEAST_FULL_HALFf; 8050 values[2] = 1; 8051 SOC_IF_ERROR_RETURN 8052 (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3, 8053 fields, values)); 8054 SOC_IF_ERROR_RETURN 8055 (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3, 8056 fields, values)); 8057 SOC_IF_ERROR_RETURN 8058 (soc_reg_field32_modify(unit, MPLS_ENTRY_HASH_CONTROLr, REG_PORT_ANY, 8059 INSERT_LEAST_FULL_HALFf, 1)); 8060 8061 if (soc_reg_field_valid(unit, ARB_EOP_DEBUGr, ISW2_TD_B0f)) { 8062 SOC_IF_ERROR_RETURN 8063 (soc_reg_field32_modify(unit, ARB_EOP_DEBUGr, REG_PORT_ANY, 8064 ISW2_TD_B0f, 1)); 8065 } 8066 8067 if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) { 8068 rval = 0; 8069 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, IFP_BYPASS_ENABLEf, 8070 1); 8071 SOC_IF_ERROR_RETURN(WRITE_ING_BYPASS_CTRLr(unit, rval)); 8072 8073 rval = 0; 8074 soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval, EFP_BYPASSf, 1); 8075 SOC_IF_ERROR_RETURN(WRITE_EGR_BYPASS_CTRLr(unit, rval)); 8076 } 8077 8078 /* 8079 * Egress Enable 8080 */ 8081 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 8082 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 8083 PBMP_ALL_ITER(unit, port) { 8084 phy_port = si->port_l2p_mapping[port]; 8085 SOC_IF_ERROR_RETURN 8086 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 8087 } 8088 8089 sal_memset(entry, 0, sizeof(epc_link_bmap_entry_t)); 8090 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, 8091 &PBMP_CMIC(unit)); 8092 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry)); 8093 8094 8095 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®64)); 8096 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8097 L3SRC_HIT_ENABLEf, 1); 8098 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8099 L2DST_HIT_ENABLEf, 1); 8100 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8101 APPLY_EGR_MASK_ON_L2f, 1); 8102 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8103 APPLY_EGR_MASK_ON_L3f, 1); 8104 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8105 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 8106 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8107 ARP_VALIDATION_ENf, 1); 8108 if (soc_feature(unit, soc_feature_port_lag_failover)) { 8109 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8110 IGNORE_HG_HDR_LAG_FAILOVERf, 0); 8111 } else { 8112 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 8113 IGNORE_HG_HDR_LAG_FAILOVERf, 1); 8114 } 8115 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64)); 8116 8117 SOC_IF_ERROR_RETURN 8118 (soc_reg_field32_modify(unit, EGR_CONFIG_1r, REG_PORT_ANY, RING_MODEf, 8119 1)); 8120 8121 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 8122 * causes the outer tag to be removed from packets that don't have 8123 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 8124 */ 8125 rval = 0; 8126 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0); 8127 8128 /* Enable pri/cfi remarking on egress ports. */ 8129 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf, 8130 1); 8131 PBMP_ALL_ITER(unit, port) { 8132 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval)); 8133 } 8134 8135 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 8136 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 8137 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 8138 MEM_BLOCK_ANY, 0, &entry)); 8139 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, 8140 &pbmp); 8141 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 8142 MEM_BLOCK_ANY, 0, &entry)); 8143 8144 /* Multicast range initialization */ 8145 SOC_IF_ERROR_RETURN 8146 (soc_hbx_higig2_mcast_sizes_set(unit, 8147 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 8148 SOC_HBX_MULTICAST_RANGE_DEFAULT), 8149 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 8150 SOC_HBX_MULTICAST_RANGE_DEFAULT), 8151 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 8152 SOC_HBX_MULTICAST_RANGE_DEFAULT))); 8153 SOC_IF_ERROR_RETURN 8154 (soc_hbx_mcast_size_set(unit, soc_property_get(unit, 8155 spn_MULTICAST_L2_RANGE, SOC_HBX_MULTICAST_RANGE_DEFAULT))); 8156 SOC_IF_ERROR_RETURN 8157 (soc_hbx_ipmc_size_set(unit, soc_property_get(unit, 8158 spn_MULTICAST_L3_RANGE, soc_mem_index_count(unit, L3_IPMCm)))); 8159 8160 /* Setup SW2_FP_DST_ACTION_CONTROL */ 8161 fields[0] = HGTRUNK_RES_ENf; 8162 values[0] = 1; 8163 fields[1] = LAG_RES_ENf; 8164 values[1] = 1; 8165 SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, 8166 SW2_FP_DST_ACTION_CONTROLr, REG_PORT_ANY, 2, fields, values)); 8167 8168 /* Populate and enable RTAG7 macro flow offset table */ 8169 if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) { 8170 count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm); 8171 sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t)); 8172 for (index = 0; index < count; ) { 8173 for (sub_sel = 0; sub_sel < 8 && index < count; sub_sel++) { 8174 for (offset = 0; 8175 offset < rtag7_field_width[sub_sel] && index < count; 8176 offset++) { 8177 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 8178 SUB_SEL_ECMPf, sub_sel); 8179 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 8180 OFFSET_ECMPf, offset); 8181 SOC_IF_ERROR_RETURN 8182 (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm, 8183 MEM_BLOCK_ANY, index, &entry)); 8184 index++; 8185 } 8186 } 8187 } 8188 rval = 0; 8189 soc_reg_field_set(unit, RTAG7_HASH_ECMPr, &rval, USE_FLOW_HASHf, 1); 8190 for (index = 0; index < 2; index++) { 8191 SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_ECMPr(unit, index, rval)); 8192 } 8193 rval = 0; 8194 soc_reg_field_set(unit, RTAG7_HASH_TRILL_ECMPr, &rval, USE_FLOW_HASHf, 8195 1); 8196 for (index = 0; index < 2; index++) { 8197 SOC_IF_ERROR_RETURN 8198 (WRITE_RTAG7_HASH_TRILL_ECMPr(unit, index, rval)); 8199 } 8200 } 8201 8202 /* Configure FCOE standard Headers */ 8203 SOC_IF_ERROR_RETURN(_soc_trident_fcoe_config_init(unit)); 8204 8205 /* 8206 * Set I2C freq to 128KHz (495MHz) or 108KHz (415MHz) 8207 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / CCR_divisor / 10 8208 * CCR_divosor = (M + 1) * 2 ** (N + 1) 8209 * The write only CCR register is at the same address as CMIC_I2C_STAT 8210 * M is bit [6:3] of CCR register 8211 * N is bit [2:0] of CCR register 8212 */ 8213 rval = 0x10; /* M=2, N=0, CCR_divisor = (2+1)*2**(0+1)=6 */ 8214 /* coverity[result_independent_of_operands] */ 8215 SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval)); 8216 8217 rval = 0; 8218 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVISORf, 64); 8219 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVIDENDf, 1); 8220 /* coverity[result_independent_of_operands] */ 8221 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval)); 8222 8223 rval = 0; 8224 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVISORf, 16); 8225 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVIDENDf, 1); 8226 /* coverity[result_independent_of_operands] */ 8227 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval)); 8228 8229 /* 8230 * Set external MDIO freq to 6.19MHz (495MHz) or 5.19MHz (415MHz) 8231 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2 8232 */ 8233 divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, 40); 8234 dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1); 8235 rval = 0; 8236 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor); 8237 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend); 8238 /* coverity[result_independent_of_operands] */ 8239 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval)); 8240 8241 /* 8242 * Set internal MDIO freq to 16.5MHz (495MHz) or 13.83MHz (415MHz) 8243 * Valid range is from 2.5MHz to 20MHz 8244 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2 8245 */ 8246 rval = 0; 8247 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 15); 8248 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 1); 8249 /* coverity[result_independent_of_operands] */ 8250 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval)); 8251 8252 delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1); 8253 if (delay >= 1 && delay <= 7) { 8254 /* coverity[result_independent_of_operands] */ 8255 SOC_IF_ERROR_RETURN(READ_CMIC_CONFIGr(unit, &rval)); 8256 soc_reg_field_set(unit, CMIC_CONFIGr, &rval, MDIO_OUT_DELAYf, delay); 8257 /* coverity[result_independent_of_operands] */ 8258 SOC_IF_ERROR_RETURN(WRITE_CMIC_CONFIGr(unit, rval)); 8259 } 8260 8261 /* initialize LED UP0 and LED UP1 */ 8262 if (!SOC_WARM_BOOT(unit)) { 8263 SOC_IF_ERROR_RETURN(_trident_ledup_init(unit)); 8264 } 8265 8266 _phy_wc40_firmware_set_helper[unit] = trident_wc40_firmware_set; 8267 if (parity_enable) { 8268 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 8269 } 8270 8271 return SOC_E_NONE; 8272 } 8273 8274 #define _TD_MMU_MAX_PACKET_BYTES 10240 /* bytes */ 8275 #define _TD_MMU_PACKET_HEADER_BYTES 64 /* bytes */ 8276 #define _TD_MMU_JUMBO_FRAME_BYTES 9216 /* bytes */ 8277 #define _TD_MMU_DEFAULT_MTU_BYTES 1536 /* bytes */ 8278 8279 #define _TD_MMU_TOTAL_CELLS 46080 /* 45k cells */ 8280 8281 #define _TD_MMU_BYTES_PER_CELL 208 /* bytes (1664 bits) */ 8282 #define _TD_MMU_NUM_PG 8 8283 #define _TD_MMU_NUM_POOL 4 8284 8285 #define _TD_MMU_BYTES_TO_CELLS(_byte_) \ 8286 (((_byte_) + _TD_MMU_BYTES_PER_CELL - 1) / _TD_MMU_BYTES_PER_CELL) 8287 8288 /* 8289 * general syntax: buf.object[id].attribute[.port]="string" 8290 * Some examples of "cell value" string type: 8291 * 1000b (b for byte) 8292 * 1000k (k for kilobyte) 8293 * 1000m (m for megabyte) 8294 * 1000c (c for cell) 8295 * 8296 * objects attributes string type 8297 * ======================================================================== 8298 * device 8299 * headroom cell value 8300 * 8301 * pool# # is pool id 8302 * size cell value or % 8303 * This size will affect both ingress and egress 8304 * pool size, it is recommended to use percentage 8305 * since the total pool size calculate for 8306 * ingress and egress are different. 8307 * yellow_size cell value or % 8308 * If the specified value is percentage, it is 8309 * the percentage of the value specified by the 8310 * size attribute 8311 * Use the same value for size, yellow_size, and 8312 * red_size or use 100% for yellow_size and 8313 * red_size to disable color aware. 8314 * red_size cell value or % 8315 * (see notes for yellow_size) 8316 * 8317 * port 8318 * guarantee cell value 8319 * pool_limit cell value 8320 * pool_resume cell value 8321 * pkt_size cell value 8322 * 8323 * prigroup# # is priority group 8324 * guarantee cell value 8325 * specify 0 to disable 8326 * headroom cell value 8327 * user_delay nanosecond 8328 * switch_delay nanosecond 8329 * pkt_size cell value 8330 * device_headroom_enable boolean 8331 * port_guarantee_enable boolean 8332 * port_max_enable boolean 8333 * pool_scale floating point number value between 1/64 and 8 8334 * Dynamic method will be enabled if this 8335 * attribute is specified. 8336 * pool_limit cell value 8337 * pool_resume cell value 8338 * pool_floor cell value 8339 * flow_control_enable boolean 8340 * 8341 * queue# # is queue id 8342 * equeue# # is extended queue id 8343 * mqueue# # is multicast queue id 8344 * guarantee cell value 8345 * discard_enable boolean 8346 * pool_scale floating point number value between 1/64 and 8 8347 * Dynamic method will be enabled if this 8348 * attribute is specified. 8349 * pool_limit cell value 8350 * Specify 0 to indicate disabling queue limit 8351 * and allow to use shared space. 8352 * pool_resume cell value 8353 * color_discard_enable boolean 8354 * yellow_limit cell value for static or % for dynamic 8355 * Use the same value for pool_limit, 8356 * yellow_limit and red_limit to disable color 8357 * aware. 8358 * Use percentage (such as 12.5%, ... 100%) to 8359 * indicate dynamic color limit 8360 * red_limit cell value for static or % for dynamic 8361 * (see notes for yellow_limit) 8362 * yellow_resume cell value 8363 * red_resume cell value 8364 * 8365 * ===== mapping ===== 8366 * general syntax: buf.map.from_object.to_object[.port]="string" 8367 * string is a command separated value list, use 0 if the value is missing 8368 * for example: 8369 * "a,b,c" has same effect as "a,b,c,0,0,0" 8370 * "a,,c" has same effect as "a,0,c" 8371 * 8372 * buf.map.pri.prigroup[.port]="a,b,c,..." 8373 * a is priority group id for priority 0 8374 * b is priority group id for priority 1 8375 * ... 8376 * 8377 * buf.map.prigroup.pool[.port]="a,b,c,..." 8378 * a is service pool id for priority group 0 8379 * b is service pool id for priority group 1 8380 * ... 8381 * 8382 * buf.map.queue.pool[.port]="a,b,c,..." 8383 * buf.map.mqueue.pool[.port]="a,b,c,..." 8384 * a is service pool id for queue 0 8385 * b is service pool id for queue 1 8386 * ... 8387 */ 8388 8389 #define _TD_BUF_DYNAMIC_FLAG (0x80000000) 8390 #define _TD_BUF_PERCENT_FLAG (0x40000000) 8391 8392 typedef struct _soc_trident_buf_prigroup_s { 8393 int pool_idx; /* from mapping variable */ 8394 int guarantee; 8395 int headroom; 8396 int user_delay; 8397 int switch_delay; 8398 int pkt_size; 8399 int device_headroom_enable; 8400 int port_guarantee_enable; 8401 int port_max_enable; 8402 int pool_scale; 8403 int pool_limit; 8404 int pool_resume; 8405 int pool_floor; 8406 int flow_control_enable; 8407 } _soc_trident_buf_prigroup_t; 8408 8409 typedef struct _soc_trident_buf_queue_s 8410 { 8411 int pool_idx; /* from mapping variable */ 8412 int guarantee; 8413 int discard_enable; 8414 int pool_scale; 8415 int pool_limit; 8416 int pool_resume; 8417 int color_discard_enable; 8418 int yellow_limit; 8419 int red_limit; 8420 int yellow_resume; 8421 int red_resume; 8422 } _soc_trident_buf_queue_t; 8423 8424 typedef struct _soc_trident_buf_pool_s { 8425 int size; 8426 int yellow_size; 8427 int red_size; 8428 int total; /* calculated value (not from config variable) */ 8429 int prigroup_guarantee; /* calculated value (not from config variable) */ 8430 int prigroup_headroom; /* calculated value (not from config variable) */ 8431 int queue_guarantee; /* calculated value (not from config variable) */ 8432 } _soc_trident_buf_pool_t; 8433 8434 typedef struct _soc_trident_buf_port_s 8435 { 8436 int guarantee; 8437 int pool_limit; 8438 int pool_resume; 8439 int pkt_size; 8440 _soc_trident_buf_prigroup_t prigroups[8]; 8441 _soc_trident_buf_queue_t *queues; 8442 int pri_to_prigroup[16]; /* from mapping variable */ 8443 } _soc_trident_buf_port_t; 8444 8445 typedef struct _soc_trident_buf_s 8446 { 8447 int headroom; 8448 _soc_trident_buf_pool_t pools[4]; 8449 _soc_trident_buf_port_t ports[66]; 8450 int port_guarantee; /* calculated value (not from config variable) */ 8451 } _soc_trident_buf_t; 8452 8453 STATIC void 8454 _soc_trident_property_get(int unit, soc_port_t port, const char *obj, 8455 int index, const char *attr, int *setting) 8456 { 8457 char suffix; 8458 8459 if (port < 0) { 8460 *setting = soc_property_obj_attr_get 8461 (unit, spn_BUF, obj, index, attr, 0, &suffix, *setting); 8462 } else { 8463 *setting = soc_property_port_obj_attr_get 8464 (unit, port, spn_BUF, obj, index, attr, 0, &suffix, *setting); 8465 } 8466 } 8467 8468 STATIC void 8469 _soc_trident_property_get_cells(int unit, soc_port_t port, const char *obj, 8470 int index, const char *attr, int allow_dynamic, 8471 int *setting) 8472 { 8473 int val; 8474 char suffix; 8475 8476 /* scale up by 10 during calculation */ 8477 if (*setting & _TD_BUF_DYNAMIC_FLAG) { 8478 suffix = '%'; 8479 val = *setting & ~_TD_BUF_DYNAMIC_FLAG; 8480 val = (val + 1) * 125; /* 0:125 (12.5%), ... 7:1000 (100%) */ 8481 8482 } else { 8483 suffix = '\0'; 8484 val = *setting * 10; 8485 } 8486 8487 if (port < 0) { 8488 val = soc_property_obj_attr_get 8489 (unit, spn_BUF, obj, index, attr, 1, &suffix, val); 8490 } else { 8491 val = soc_property_port_obj_attr_get 8492 (unit, port, spn_BUF, obj, index, attr, 1, &suffix, val); 8493 } 8494 8495 if (val < 0) { /* treat negative number as zero */ 8496 val = 0; 8497 } 8498 8499 /* scale down by 10 after calculation */ 8500 if (allow_dynamic && suffix == '%') { 8501 val = val > 1000 ? 7 : (val - 1) / 125; /* each unit represent 12.5% */ 8502 val |= _TD_BUF_DYNAMIC_FLAG; 8503 } else { 8504 val /= 10; 8505 switch (suffix) { 8506 case 'B': /* byte */ 8507 case 'b': 8508 val = _TD_MMU_BYTES_TO_CELLS(val); 8509 break; 8510 case 'K': /* kilobyte */ 8511 case 'k': 8512 val = _TD_MMU_BYTES_TO_CELLS(val * 1024); 8513 break; 8514 case 'M': /* megabyte */ 8515 case 'm': 8516 val = _TD_MMU_BYTES_TO_CELLS(val * 1048576); 8517 break; 8518 default: 8519 break; 8520 } 8521 } 8522 8523 *setting = val; 8524 } 8525 8526 STATIC void 8527 _soc_trident_property_get_percentage_x100(int unit, soc_port_t port, 8528 const char *obj, int index, 8529 const char *attr, int *setting) 8530 { 8531 int val; 8532 char suffix; 8533 8534 if (*setting & _TD_BUF_PERCENT_FLAG) { 8535 suffix = '%'; 8536 val = *setting & ~_TD_BUF_PERCENT_FLAG; 8537 } else { 8538 suffix = '\0'; 8539 val = *setting; 8540 } 8541 8542 if (port < 0) { 8543 val = soc_property_obj_attr_get 8544 (unit, spn_BUF, obj, index, attr, 2, &suffix, val); 8545 } else { 8546 val = soc_property_port_obj_attr_get 8547 (unit, port, spn_BUF, obj, index, attr, 2, &suffix, val); 8548 } 8549 8550 if (suffix == '%') { 8551 if (val < 0) { /* treat negative number as zero */ 8552 val = 0; 8553 } else if (val > 10000) { /* treat number larger than 100% as 100% */ 8554 val = 10000; 8555 } 8556 *setting = val | _TD_BUF_PERCENT_FLAG; 8557 } else { 8558 *setting = val; 8559 } 8560 } 8561 8562 STATIC void 8563 _soc_trident_property_get_scale(int unit, soc_port_t port, 8564 const char *obj, int index, 8565 const char *attr, int *setting) 8566 { 8567 int val, alpha; 8568 char suffix; 8569 8570 alpha = 15625; /* 1/64 = 0.015625, scale up by 1000000 (2**6) */ 8571 val = *setting < 0 ? -1 : alpha << *setting; 8572 8573 if (port < 0) { 8574 val = soc_property_obj_attr_get 8575 (unit, spn_BUF, obj, index, attr, 6, &suffix, val); 8576 } else { 8577 val = soc_property_port_obj_attr_get 8578 (unit, port, spn_BUF, obj, index, attr, 6, &suffix, val); 8579 } 8580 8581 if (val < 0) { /* ignore negative number */ 8582 *setting = -1; 8583 } else { 8584 for (*setting = 0; *setting < 9; (*setting)++) { 8585 if (val <= (alpha << *setting)) { 8586 break; 8587 } 8588 } 8589 } 8590 } 8591 8592 STATIC void 8593 _soc_trident_mmu_config_buf_default(int unit, _soc_trident_buf_t *buf) 8594 { 8595 soc_info_t *si; 8596 _soc_trident_buf_pool_t *buf_pool; 8597 _soc_trident_buf_port_t *buf_port; 8598 _soc_trident_buf_prigroup_t *buf_prigroup; 8599 _soc_trident_buf_queue_t *buf_queue; 8600 int max_packet_cells, jumbo_frame_cells, default_mtu_cells; 8601 int default_pg_headroom_cells; 8602 int port, idx, count, num_cosq; 8603 8604 si = &SOC_INFO(unit); 8605 8606 max_packet_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_MAX_PACKET_BYTES + 8607 _TD_MMU_PACKET_HEADER_BYTES); 8608 jumbo_frame_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_JUMBO_FRAME_BYTES + 8609 _TD_MMU_PACKET_HEADER_BYTES); 8610 default_mtu_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_DEFAULT_MTU_BYTES + 8611 _TD_MMU_PACKET_HEADER_BYTES); 8612 default_pg_headroom_cells = 160; 8613 8614 buf->headroom = NUM_PORT(unit) * default_mtu_cells; 8615 8616 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 8617 buf_pool = &buf->pools[idx]; 8618 8619 if (idx == 0) { /* 100% scale up by 100 */ 8620 buf_pool->size = 10000 | _TD_BUF_PERCENT_FLAG; 8621 buf_pool->yellow_size = 10000 | _TD_BUF_PERCENT_FLAG; 8622 buf_pool->red_size = 10000 | _TD_BUF_PERCENT_FLAG; 8623 } else { 8624 buf_pool->size = 0; 8625 buf_pool->yellow_size = 0; 8626 buf_pool->red_size = 0; 8627 } 8628 } 8629 8630 num_cosq = 0; 8631 PBMP_ALL_ITER(unit, port) { 8632 buf_port = &buf->ports[port]; 8633 8634 buf_port->guarantee = jumbo_frame_cells; 8635 buf_port->pool_limit = _TD_MMU_TOTAL_CELLS; 8636 buf_port->pool_resume = _TD_MMU_TOTAL_CELLS - default_mtu_cells * 2; 8637 buf_port->pkt_size = max_packet_cells; 8638 8639 /* priority group */ 8640 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 8641 buf_prigroup = &buf_port->prigroups[idx]; 8642 8643 buf_prigroup->guarantee = 0; 8644 buf_prigroup->user_delay = -1; 8645 buf_prigroup->switch_delay = -1; 8646 buf_prigroup->pkt_size = max_packet_cells; 8647 buf_prigroup->device_headroom_enable = 1; 8648 buf_prigroup->pool_limit = 0; 8649 buf_prigroup->pool_floor = 0; 8650 if (idx == 7) { 8651 buf_prigroup->headroom = default_pg_headroom_cells; 8652 buf_prigroup->port_guarantee_enable = 1; 8653 buf_prigroup->port_max_enable = 1; 8654 buf_prigroup->pool_scale = 7; 8655 buf_prigroup->pool_resume = default_mtu_cells * 2; 8656 buf_prigroup->flow_control_enable = 1; 8657 } else { 8658 buf_prigroup->headroom = 0; 8659 buf_prigroup->port_guarantee_enable = 0; 8660 buf_prigroup->port_max_enable = 0; 8661 buf_prigroup->pool_scale = -1; 8662 buf_prigroup->pool_resume = 0; 8663 buf_prigroup->flow_control_enable = 0; 8664 } 8665 } 8666 8667 /* multicast queue */ 8668 count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]; 8669 num_cosq += count; 8670 for (idx = 0; idx < count; idx++) { 8671 buf_queue = &buf_port->queues[idx]; 8672 8673 buf_queue->guarantee = default_mtu_cells; 8674 buf_queue->discard_enable = 0; 8675 buf_queue->pool_scale = 7; 8676 buf_queue->pool_limit = 0; 8677 buf_queue->pool_resume = 8; 8678 buf_queue->color_discard_enable = 0; 8679 buf_queue->red_limit = 7 | _TD_BUF_DYNAMIC_FLAG; 8680 } 8681 8682 /* unicast queue */ 8683 num_cosq += si->port_num_uc_cosq[port]; 8684 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 8685 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 8686 8687 buf_queue->guarantee = default_mtu_cells; 8688 buf_queue->discard_enable = 0; 8689 buf_queue->pool_scale = 7; 8690 buf_queue->pool_limit = 0; 8691 buf_queue->pool_resume = 8; 8692 buf_queue->color_discard_enable = 0; 8693 buf_queue->yellow_limit = 7 | _TD_BUF_DYNAMIC_FLAG; 8694 buf_queue->red_limit = 7 | _TD_BUF_DYNAMIC_FLAG; 8695 buf_queue->yellow_resume = 8; 8696 buf_queue->red_resume = 8; 8697 } 8698 8699 /* extended unicast queue */ 8700 count = SOC_PBMP_MEMBER(si->eq_pbm, port) ? 8701 si->port_num_ext_cosq[port] : 0; 8702 num_cosq += count; 8703 for (idx = 0; idx < count; idx++) { 8704 buf_queue = &buf_port->queues[si->port_num_cosq[port] + 8705 si->port_num_uc_cosq[port] + idx]; 8706 8707 buf_queue->guarantee = default_mtu_cells; 8708 buf_queue->discard_enable = 0; 8709 buf_queue->pool_scale = 7; 8710 buf_queue->pool_limit = 0; 8711 buf_queue->pool_resume = 8; 8712 buf_queue->color_discard_enable = 0; 8713 buf_queue->yellow_limit = 7 | _TD_BUF_DYNAMIC_FLAG; 8714 buf_queue->red_limit = 6 | _TD_BUF_DYNAMIC_FLAG; 8715 buf_queue->yellow_resume = 8; 8716 buf_queue->red_resume = 8; 8717 } 8718 8719 /* internal priority to priority group mapping */ 8720 for (idx = 0; idx < 16; idx++) { 8721 buf_port->pri_to_prigroup[idx] = 7; 8722 } 8723 8724 /* priority group to pool mapping */ 8725 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 8726 buf_port->prigroups[idx].pool_idx = 0; 8727 } 8728 8729 /* queue to pool mapping */ 8730 count = si->port_num_cosq[port] + si->port_num_uc_cosq[port] + 8731 si->port_num_ext_cosq[port]; 8732 for (idx = 0; idx < count; idx++) { 8733 buf_port->queues[idx].pool_idx = 0; 8734 } 8735 } 8736 } 8737 8738 STATIC void 8739 _soc_trident_mmu_config_buf_read(int unit, _soc_trident_buf_t *buf) 8740 { 8741 soc_info_t *si; 8742 _soc_trident_buf_pool_t *buf_pool; 8743 _soc_trident_buf_port_t *buf_port; 8744 _soc_trident_buf_prigroup_t *buf_prigroup; 8745 _soc_trident_buf_queue_t *buf_queue; 8746 int port, idx, count; 8747 char name[80]; 8748 int values[64]; 8749 8750 si = &SOC_INFO(unit); 8751 8752 _soc_trident_property_get_cells 8753 (unit, -1, spn_DEVICE, -1, spn_HEADROOM, FALSE, &buf->headroom); 8754 8755 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 8756 buf_pool = &buf->pools[idx]; 8757 8758 _soc_trident_property_get_percentage_x100 8759 (unit, -1, spn_POOL, idx, spn_SIZE, &buf_pool->size); 8760 8761 _soc_trident_property_get_percentage_x100 8762 (unit, -1, spn_POOL, idx, spn_YELLOW_SIZE, &buf_pool->yellow_size); 8763 8764 _soc_trident_property_get_percentage_x100 8765 (unit, -1, spn_POOL, idx, spn_RED_SIZE, &buf_pool->red_size); 8766 } 8767 8768 PBMP_ALL_ITER(unit, port) { 8769 buf_port = &buf->ports[port]; 8770 8771 _soc_trident_property_get_cells 8772 (unit, port, spn_PORT, -1, spn_GUARANTEE, FALSE, 8773 &buf_port->guarantee); 8774 8775 _soc_trident_property_get_cells 8776 (unit, port, spn_PORT, -1, spn_POOL_LIMIT, FALSE, 8777 &buf_port->pool_limit); 8778 8779 _soc_trident_property_get_cells 8780 (unit, port, spn_PORT, -1, spn_POOL_RESUME, FALSE, 8781 &buf_port->pool_resume); 8782 8783 _soc_trident_property_get_cells 8784 (unit, port, spn_PORT, -1, spn_PKT_SIZE, FALSE, 8785 &buf_port->pkt_size); 8786 8787 /* priority group */ 8788 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 8789 buf_prigroup = &buf_port->prigroups[idx]; 8790 8791 _soc_trident_property_get_cells 8792 (unit, port, spn_PRIGROUP, idx, spn_GUARANTEE, FALSE, 8793 &buf_prigroup->guarantee); 8794 buf_prigroup->guarantee = 8795 buf_prigroup->guarantee > 1 ? buf_prigroup->guarantee : 1; 8796 8797 _soc_trident_property_get_cells 8798 (unit, port, spn_PRIGROUP, idx, spn_HEADROOM, FALSE, 8799 &buf_prigroup->headroom); 8800 8801 _soc_trident_property_get 8802 (unit, port, spn_PRIGROUP, idx, spn_USER_DELAY, 8803 &buf_prigroup->user_delay); 8804 8805 _soc_trident_property_get 8806 (unit, port, spn_PRIGROUP, idx, spn_SWITCH_DELAY, 8807 &buf_prigroup->switch_delay); 8808 8809 _soc_trident_property_get_cells 8810 (unit, port, spn_PRIGROUP, idx, spn_PKT_SIZE, FALSE, 8811 &buf_prigroup->pkt_size); 8812 8813 _soc_trident_property_get 8814 (unit, port, spn_PRIGROUP, idx, spn_DEVICE_HEADROOM_ENABLE, 8815 &buf_prigroup->device_headroom_enable); 8816 8817 _soc_trident_property_get 8818 (unit, port, spn_PRIGROUP, idx, spn_PORT_GUARANTEE_ENABLE, 8819 &buf_prigroup->port_guarantee_enable); 8820 8821 _soc_trident_property_get 8822 (unit, port, spn_PRIGROUP, idx, spn_PORT_MAX_ENABLE, 8823 &buf_prigroup->port_max_enable); 8824 8825 _soc_trident_property_get_scale 8826 (unit, port, spn_PRIGROUP, idx, spn_POOL_SCALE, 8827 &buf_prigroup->pool_scale); 8828 8829 _soc_trident_property_get_cells 8830 (unit, port, spn_PRIGROUP, idx, spn_POOL_LIMIT, FALSE, 8831 &buf_prigroup->pool_limit); 8832 8833 _soc_trident_property_get_cells 8834 (unit, port, spn_PRIGROUP, idx, spn_POOL_RESUME, FALSE, 8835 &buf_prigroup->pool_resume); 8836 8837 _soc_trident_property_get_cells 8838 (unit, port, spn_PRIGROUP, idx, spn_POOL_FLOOR, FALSE, 8839 &buf_prigroup->pool_floor); 8840 8841 _soc_trident_property_get 8842 (unit, port, spn_PRIGROUP, idx, spn_FLOW_CONTROL_ENABLE, 8843 &buf_prigroup->flow_control_enable); 8844 } 8845 8846 /* multicast queue */ 8847 count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]; 8848 for (idx = 0; idx < count; idx++) { 8849 buf_queue = &buf_port->queues[idx]; 8850 8851 _soc_trident_property_get_cells 8852 (unit, port, spn_MQUEUE, idx, spn_GUARANTEE, FALSE, 8853 &buf_queue->guarantee); 8854 8855 _soc_trident_property_get 8856 (unit, port, spn_MQUEUE, idx, spn_DISCARD_ENABLE, 8857 &buf_queue->discard_enable); 8858 8859 _soc_trident_property_get_scale 8860 (unit, port, spn_MQUEUE, idx, spn_POOL_SCALE, 8861 &buf_queue->pool_scale); 8862 8863 _soc_trident_property_get_cells 8864 (unit, port, spn_MQUEUE, idx, spn_POOL_LIMIT, FALSE, 8865 &buf_queue->pool_limit); 8866 8867 _soc_trident_property_get_cells 8868 (unit, port, spn_MQUEUE, idx, spn_POOL_RESUME, FALSE, 8869 &buf_queue->pool_resume); 8870 8871 _soc_trident_property_get 8872 (unit, port, spn_MQUEUE, idx, spn_COLOR_DISCARD_ENABLE, 8873 &buf_queue->color_discard_enable); 8874 8875 _soc_trident_property_get_cells 8876 (unit, port, spn_MQUEUE, idx, spn_RED_LIMIT, TRUE, 8877 &buf_queue->red_limit); 8878 } 8879 8880 /* unicast queue */ 8881 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 8882 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 8883 8884 _soc_trident_property_get_cells 8885 (unit, port, spn_QUEUE, idx, spn_GUARANTEE, FALSE, 8886 &buf_queue->guarantee); 8887 8888 _soc_trident_property_get 8889 (unit, port, spn_QUEUE, idx, spn_DISCARD_ENABLE, 8890 &buf_queue->discard_enable); 8891 8892 _soc_trident_property_get_scale 8893 (unit, port, spn_QUEUE, idx, spn_POOL_SCALE, 8894 &buf_queue->pool_scale); 8895 8896 _soc_trident_property_get_cells 8897 (unit, port, spn_QUEUE, idx, spn_POOL_LIMIT, FALSE, 8898 &buf_queue->pool_limit); 8899 8900 _soc_trident_property_get_cells 8901 (unit, port, spn_QUEUE, idx, spn_POOL_RESUME, FALSE, 8902 &buf_queue->pool_resume); 8903 8904 _soc_trident_property_get 8905 (unit, port, spn_QUEUE, idx, spn_COLOR_DISCARD_ENABLE, 8906 &buf_queue->color_discard_enable); 8907 8908 _soc_trident_property_get_cells 8909 (unit, port, spn_QUEUE, idx, spn_YELLOW_LIMIT, TRUE, 8910 &buf_queue->yellow_limit); 8911 8912 _soc_trident_property_get_cells 8913 (unit, port, spn_QUEUE, idx, spn_RED_LIMIT, TRUE, 8914 &buf_queue->red_limit); 8915 8916 _soc_trident_property_get_cells 8917 (unit, port, spn_QUEUE, idx, spn_YELLOW_RESUME, FALSE, 8918 &buf_queue->yellow_resume); 8919 8920 _soc_trident_property_get_cells 8921 (unit, port, spn_QUEUE, idx, spn_RED_RESUME, FALSE, 8922 &buf_queue->red_resume); 8923 } 8924 8925 /* extended unicast queue */ 8926 count = SOC_PBMP_MEMBER(si->eq_pbm, port) ? 8927 si->port_num_ext_cosq[port] : 0; 8928 for (idx = 0; idx < count; idx++) { 8929 buf_queue = &buf_port->queues[si->port_num_cosq[port] + 8930 si->port_num_uc_cosq[port] + idx]; 8931 8932 _soc_trident_property_get_cells 8933 (unit, port, spn_EQUEUE, idx, spn_GUARANTEE, FALSE, 8934 &buf_queue->guarantee); 8935 8936 _soc_trident_property_get 8937 (unit, port, spn_EQUEUE, idx, spn_DISCARD_ENABLE, 8938 &buf_queue->discard_enable); 8939 8940 _soc_trident_property_get_scale 8941 (unit, port, spn_EQUEUE, idx, spn_POOL_SCALE, 8942 &buf_queue->pool_scale); 8943 8944 _soc_trident_property_get_cells 8945 (unit, port, spn_EQUEUE, idx, spn_POOL_LIMIT, FALSE, 8946 &buf_queue->pool_limit); 8947 8948 _soc_trident_property_get_cells 8949 (unit, port, spn_EQUEUE, idx, spn_POOL_RESUME, FALSE, 8950 &buf_queue->pool_resume); 8951 8952 _soc_trident_property_get 8953 (unit, port, spn_EQUEUE, idx, spn_COLOR_DISCARD_ENABLE, 8954 &buf_queue->color_discard_enable); 8955 8956 _soc_trident_property_get_cells 8957 (unit, port, spn_EQUEUE, idx, spn_YELLOW_LIMIT, TRUE, 8958 &buf_queue->yellow_limit); 8959 8960 _soc_trident_property_get_cells 8961 (unit, port, spn_EQUEUE, idx, spn_RED_LIMIT, TRUE, 8962 &buf_queue->red_limit); 8963 8964 _soc_trident_property_get_cells 8965 (unit, port, spn_EQUEUE, idx, spn_YELLOW_RESUME, FALSE, 8966 &buf_queue->yellow_resume); 8967 8968 _soc_trident_property_get_cells 8969 (unit, port, spn_EQUEUE, idx, spn_RED_RESUME, FALSE, 8970 &buf_queue->red_resume); 8971 } 8972 8973 /* internal priority to priority group mapping */ 8974 sal_sprintf(name, "%s.%s.%s.%s", 8975 spn_BUF, spn_MAP, spn_PRI, spn_PRIGROUP); 8976 (void)soc_property_port_get_csv(unit, port, name, 16, 8977 buf_port->pri_to_prigroup); 8978 8979 /* priority group to pool mapping */ 8980 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 8981 values[idx] = buf_port->prigroups[idx].pool_idx; 8982 } 8983 sal_sprintf(name, "%s.%s.%s.%s", 8984 spn_BUF, spn_MAP, spn_PRIGROUP, spn_POOL); 8985 count = soc_property_port_get_csv(unit, port, name, _TD_MMU_NUM_PG, 8986 values); 8987 for (idx = 0; idx < count; idx++) { 8988 buf_port->prigroups[idx].pool_idx = values[idx]; 8989 } 8990 8991 /* multicast queue to pool mapping */ 8992 count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]; 8993 buf_queue = &buf_port->queues[0]; 8994 for (idx = 0; idx < count; idx++) { 8995 values[idx] = buf_queue[idx].pool_idx; 8996 } 8997 sal_sprintf(name, "%s.%s.%s.%s", 8998 spn_BUF, spn_MAP, spn_MQUEUE, spn_POOL); 8999 count = soc_property_port_get_csv(unit, port, name, count, values); 9000 for (idx = 0; idx < count; idx++) { 9001 buf_queue[idx].pool_idx = values[idx]; 9002 } 9003 9004 /* regular unicast queue to pool mapping */ 9005 count = si->port_num_uc_cosq[port]; 9006 if (count > 0) { 9007 buf_queue = &buf_port->queues[si->port_num_cosq[port]]; 9008 for (idx = 0; idx < count; idx++) { 9009 values[idx] = buf_queue[idx].pool_idx; 9010 } 9011 sal_sprintf(name, "%s.%s.%s.%s", 9012 spn_BUF, spn_MAP, spn_QUEUE, spn_POOL); 9013 (void)soc_property_port_get_csv(unit, port, name, count, values); 9014 for (idx = 0; idx < count; idx++) { 9015 buf_queue[idx].pool_idx = values[idx]; 9016 } 9017 } 9018 9019 /* extended unicast queue to pool mapping */ 9020 count = SOC_PBMP_MEMBER(si->eq_pbm, port) ? 9021 si->port_num_ext_cosq[port] : 0; 9022 if (count > 0) { 9023 buf_queue = &buf_port->queues[si->port_num_cosq[port] + 9024 si->port_num_uc_cosq[port]]; 9025 for (idx = 0; idx < count; idx++) { 9026 values[idx] = buf_queue[idx].pool_idx; 9027 } 9028 sal_sprintf(name, "%s.%s.%s.%s", 9029 spn_BUF, spn_MAP, spn_EQUEUE, spn_POOL); 9030 (void)soc_property_port_get_csv(unit, port, name, count, values); 9031 for (idx = 0; idx < count; idx++) { 9032 buf_queue[idx].pool_idx = values[idx]; 9033 } 9034 } 9035 } 9036 } 9037 9038 STATIC void 9039 _soc_trident_mmu_config_buf_calculate(int unit, _soc_trident_buf_t *buf) 9040 { 9041 soc_info_t *si; 9042 _soc_trident_buf_pool_t *buf_pool; 9043 _soc_trident_buf_port_t *buf_port; 9044 _soc_trident_buf_prigroup_t *buf_prigroup; 9045 _soc_trident_buf_queue_t *buf_queue; 9046 int port, idx, count; 9047 9048 si = &SOC_INFO(unit); 9049 9050 PBMP_ALL_ITER(unit, port) { 9051 buf_port = &buf->ports[port]; 9052 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9053 buf_prigroup = &buf_port->prigroups[idx]; 9054 if (buf_prigroup->user_delay != -1 && 9055 buf_prigroup->switch_delay != -1) { 9056 /* 9057 * number of max leftever cells = 9058 * port speed (megabits per sec) * 10**6 (megabits to bit) * 9059 * delay (nsec) / 10**9 (nsecs to second) / 9060 * 8 (bits per byte) / 9061 * (IPG (12 bytes) + preamble (8 bytes) + 9062 * worse case packet size (145 bytes)) * 9063 * worse case packet size (2 cells) 9064 * heandroom = 9065 * mtu (cells) + number of leftover cells 9066 */ 9067 buf_prigroup->headroom = buf_prigroup->pkt_size + 9068 si->port_speed_max[port] * 9069 (buf_prigroup->user_delay + buf_prigroup->switch_delay) * 9070 2 / (8 * (12 + 8 + 145) * 1000); 9071 } 9072 } 9073 } 9074 9075 /* 9076 * Input port pool allocation precedence: 9077 * reserved space: per port per priority group minimum space 9078 * reserved space: per port minimum space (include cpu port) 9079 * shared space = total - input port reserved - output port reserved 9080 * reserved space: per port per priority group headroom 9081 * reserved space: device global headroom 9082 * Output port: 9083 * reserved space: per port per queue minimum space 9084 * shared space = total - output port reserved 9085 * 9086 * Total memory space equals to 9087 * total cells 9088 * minus (#1) device global headroom 9089 * Per pool memory space qeuals to 9090 * total memory space * percentage 9091 * Per pool shared limit equals to 9092 * Per pool memory space 9093 * minus (#2) input port minimum space (include cpu port) 9094 * minus (#3) input port per priority group minimum space (in the pool) 9095 * minus (#4) input port per priority group headroom (in the pool) 9096 * minus (#5) output port per queue minimum space (in the pool) 9097 */ 9098 9099 buf->port_guarantee = 0; 9100 PBMP_ALL_ITER(unit, port) { 9101 buf_port = &buf->ports[port]; 9102 buf->port_guarantee += buf_port->guarantee; /* #2 */ 9103 } 9104 9105 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9106 buf_pool = &buf->pools[idx]; 9107 buf_pool->prigroup_guarantee = 0; 9108 buf_pool->prigroup_headroom = 0; 9109 buf_pool->queue_guarantee = 0; 9110 if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) { 9111 continue; 9112 } 9113 9114 if (buf_pool->size & _TD_BUF_PERCENT_FLAG) { 9115 buf_pool->total = (buf_pool->size & ~_TD_BUF_PERCENT_FLAG) * 9116 (_TD_MMU_TOTAL_CELLS - buf->headroom) / 10000; /* #1 */ 9117 } 9118 buf_pool->total -= buf->port_guarantee; 9119 } 9120 9121 PBMP_ALL_ITER(unit, port) { 9122 buf_port = &buf->ports[port]; 9123 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9124 buf_prigroup = &buf_port->prigroups[idx]; 9125 buf_pool = &buf->pools[buf_prigroup->pool_idx]; 9126 buf_pool->prigroup_guarantee += buf_prigroup->guarantee; /* #3 */ 9127 buf_pool->prigroup_headroom += buf_prigroup->headroom; /* #4 */ 9128 } 9129 count = (IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]) + 9130 si->port_num_uc_cosq[port]; 9131 count += SOC_PBMP_MEMBER(si->eq_pbm, port) ? 9132 si->port_num_ext_cosq[port] : 0; 9133 for (idx = 0; idx < count; idx++) { 9134 buf_queue = &buf_port->queues[idx]; 9135 buf_pool = &buf->pools[buf_queue->pool_idx]; 9136 buf_pool->queue_guarantee += buf_queue->guarantee; /* #5 */ 9137 } 9138 } 9139 9140 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 9141 LOG_CLI((BSL_META_U(unit, 9142 "MMU buffer usage:\n"))); 9143 LOG_CLI((BSL_META_U(unit, 9144 " Global headroom: %d\n"), buf->headroom)); 9145 LOG_CLI((BSL_META_U(unit, 9146 " Total port guarantee: %d\n"), buf->port_guarantee)); 9147 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9148 buf_pool = &buf->pools[idx]; 9149 if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) { 9150 continue; 9151 } 9152 LOG_CLI((BSL_META_U(unit, 9153 " Pool %d total prigroup guarantee: %d\n"), 9154 idx, buf_pool->prigroup_guarantee)); 9155 LOG_CLI((BSL_META_U(unit, 9156 " Pool %d total prigroup headroom: %d\n"), 9157 idx, buf_pool->prigroup_headroom)); 9158 LOG_CLI((BSL_META_U(unit, 9159 " Pool %d total queue guarantee: %d\n"), 9160 idx, buf_pool->queue_guarantee)); 9161 } 9162 } 9163 } 9164 9165 int 9166 _soc_trident_mmu_config_buf_check(int unit, _soc_trident_buf_t *buf) 9167 { 9168 soc_info_t *si; 9169 _soc_trident_buf_pool_t *buf_pool; 9170 _soc_trident_buf_port_t *buf_port; 9171 _soc_trident_buf_prigroup_t *buf_prigroup; 9172 _soc_trident_buf_queue_t *buf_queue; 9173 int yellow_cells, red_cells; 9174 int port, dft_pool, idx, queue_idx, count; 9175 uint32 pool_map; 9176 char queue_name[10]; 9177 9178 si = &SOC_INFO(unit); 9179 9180 _soc_trident_mmu_config_buf_calculate(unit, buf); 9181 9182 count = 0; 9183 dft_pool =0; 9184 pool_map = 0; 9185 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9186 buf_pool = &buf->pools[idx]; 9187 if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) { 9188 continue; 9189 } 9190 9191 if (buf_pool->total <= 9192 buf_pool->prigroup_guarantee + buf_pool->prigroup_headroom + 9193 buf_pool->queue_guarantee) { 9194 LOG_CLI((BSL_META_U(unit, 9195 "MMU config: Pool %d memory space size is zero\n"), 9196 idx)); 9197 return SOC_E_FAIL; 9198 } 9199 9200 if (pool_map == 0) { 9201 dft_pool = idx; 9202 } 9203 pool_map |= 1 << idx; 9204 9205 count += buf_pool->total + buf->port_guarantee; 9206 9207 if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) { 9208 yellow_cells = (buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) * 9209 buf_pool->total / 10000; 9210 } else { 9211 yellow_cells = buf_pool->yellow_size; 9212 } 9213 if (buf_pool->red_size & _TD_BUF_PERCENT_FLAG) { 9214 red_cells = (buf_pool->red_size & ~_TD_BUF_PERCENT_FLAG) * 9215 buf_pool->total / 10000; 9216 } else { 9217 red_cells = buf_pool->red_size; 9218 } 9219 9220 if (yellow_cells > red_cells) { 9221 LOG_CLI((BSL_META_U(unit, 9222 "MMU config pool %d: Yellow cells offset is higher " 9223 "than red cells\n"), idx)); 9224 } 9225 if (red_cells > buf_pool->total) { 9226 LOG_CLI((BSL_META_U(unit, 9227 "MMU config pool %d: Red cells offset is higher " 9228 "than pool shared cells\n"), idx)); 9229 } 9230 } 9231 if (count > _TD_MMU_TOTAL_CELLS - buf->headroom) { 9232 LOG_CLI((BSL_META_U(unit, 9233 "MMU config: The summary of pool shared cells is more " 9234 "than total shared cells available\n"))); 9235 } 9236 9237 9238 9239 PBMP_ALL_ITER(unit, port) { 9240 buf_port = &buf->ports[port]; 9241 9242 /* internal priority to priority group mapping */ 9243 for (idx = 0; idx < 16; idx++) { 9244 if (buf_port->pri_to_prigroup[idx] < 0 || 9245 buf_port->pri_to_prigroup[idx] >= _TD_MMU_NUM_PG) { 9246 LOG_CLI((BSL_META_U(unit, 9247 "MMU config port %d: Invalid prigroup value (%d) " 9248 "for internal priority %d\n"), 9249 port, buf_port->pri_to_prigroup[idx], idx)); 9250 buf_port->pri_to_prigroup[idx] = 0; /* use prigroup 0 */ 9251 } 9252 } 9253 9254 /* priority group to pool mapping */ 9255 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9256 buf_prigroup = &buf_port->prigroups[idx]; 9257 if (buf_prigroup->pool_idx < 0 || 9258 buf_prigroup->pool_idx >= _TD_MMU_NUM_POOL) { 9259 LOG_CLI((BSL_META_U(unit, 9260 "MMU config port %d prigroup %d: " 9261 "Invalid pool value (%d)\n"), 9262 port, idx, buf_prigroup->pool_idx)); 9263 /* use first non-empty pool */ 9264 buf_prigroup->pool_idx = dft_pool; 9265 } else if (!(pool_map & (1 << buf_prigroup->pool_idx))) { 9266 LOG_CLI((BSL_META_U(unit, 9267 "MMU config port %d prigroup %d: " 9268 "Pool %d is empty\n"), 9269 port, idx, buf_prigroup->pool_idx)); 9270 } 9271 } 9272 9273 /* queue to pool mapping */ 9274 count = (IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]) + 9275 si->port_num_uc_cosq[port]; 9276 count += SOC_PBMP_MEMBER(si->eq_pbm, port) ? 9277 si->port_num_ext_cosq[port] : 0; 9278 for (idx = 0; idx < count; idx++) { 9279 buf_queue = &buf->ports[port].queues[idx]; 9280 9281 queue_idx = idx; 9282 if (queue_idx < si->port_num_cosq[port]) { 9283 sal_sprintf(queue_name, "mqueue %d", queue_idx); 9284 } else { 9285 queue_idx -= si->port_num_cosq[port]; 9286 if (queue_idx < si->port_num_uc_cosq[port]) { 9287 sal_sprintf(queue_name, "queue %d", queue_idx); 9288 } else { 9289 queue_idx -= si->port_num_uc_cosq[port]; 9290 sal_sprintf(queue_name, "equeue %d", queue_idx); 9291 } 9292 } 9293 9294 if (buf_queue->pool_idx < 0 || 9295 buf_queue->pool_idx >= _TD_MMU_NUM_POOL) { 9296 LOG_CLI((BSL_META_U(unit, 9297 "MMU config port %d %s: " 9298 "Invalid pool value (%d)\n"), 9299 port, queue_name, buf_queue->pool_idx)); 9300 buf_queue->pool_idx = dft_pool; /* use first non-empty pool */ 9301 } else if (!(pool_map & (1 << buf_queue->pool_idx))) { 9302 LOG_CLI((BSL_META_U(unit, 9303 "MMU config port %d %s: Pool %d is empty\n"), 9304 port, queue_name, buf_queue->pool_idx)); 9305 } 9306 } 9307 } 9308 9309 return SOC_E_NONE; 9310 } 9311 9312 STATIC int 9313 _soc_trident_mmu_config_buf_set_hw(int unit, _soc_trident_buf_t *buf) 9314 { 9315 soc_info_t *si; 9316 _soc_trident_buf_pool_t *buf_pool; 9317 _soc_trident_buf_port_t *buf_port; 9318 _soc_trident_buf_prigroup_t *buf_prigroup; 9319 _soc_trident_buf_queue_t *buf_queue; 9320 soc_reg_t reg = INVALIDr; 9321 soc_mem_t config_mem, offset_mem; 9322 uint32 rval, fval; 9323 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 9324 int default_mtu_cells, limit; 9325 int port, phy_port, mmu_port, base, idx, count; 9326 static const soc_field_t prigroup_reg[] = { 9327 PORT_PRI_GRP0r, PORT_PRI_GRP1r 9328 }; 9329 static const soc_field_t prigroup_field[] = { 9330 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 9331 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 9332 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 9333 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 9334 }; 9335 static const soc_field_t prigroup_spid_field[] = { 9336 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 9337 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 9338 }; 9339 static const soc_field_t uc_spid_field[] = { 9340 COS0_SPIDf, COS1_SPIDf, COS2_SPIDf, COS3_SPIDf, 9341 COS4_SPIDf, COS5_SPIDf, COS6_SPIDf, COS7_SPIDf, 9342 COS8_SPIDf, COS9_SPIDf 9343 }; 9344 static const soc_field_t ext_spid_reg[] = { 9345 OP_EX_PORT_CONFIG_SPID_0r, OP_EX_PORT_CONFIG_SPID_1r, 9346 OP_EX_PORT_CONFIG_SPID_2r, OP_EX_PORT_CONFIG_SPID_3r, 9347 OP_EX_PORT_CONFIG_SPID_4r 9348 }; 9349 static const soc_field_t ext_spid_field[] = { 9350 Q0_SPIDf, Q1_SPIDf, Q2_SPIDf, Q3_SPIDf, 9351 Q4_SPIDf, Q5_SPIDf, Q6_SPIDf, Q7_SPIDf, 9352 Q8_SPIDf, Q9_SPIDf, Q10_SPIDf, Q11_SPIDf, 9353 Q12_SPIDf, Q13_SPIDf, Q14_SPIDf, Q15_SPIDf, 9354 Q16_SPIDf, Q17_SPIDf, Q18_SPIDf, Q19_SPIDf, 9355 Q20_SPIDf, Q21_SPIDf, Q22_SPIDf, Q23_SPIDf, 9356 Q24_SPIDf, Q25_SPIDf, Q26_SPIDf, Q27_SPIDf, 9357 Q28_SPIDf, Q29_SPIDf, Q30_SPIDf, Q31_SPIDf, 9358 Q32_SPIDf, Q33_SPIDf, Q34_SPIDf, Q35_SPIDf, 9359 Q36_SPIDf, Q37_SPIDf, Q38_SPIDf, Q39_SPIDf, 9360 Q40_SPIDf, Q41_SPIDf, Q42_SPIDf, Q43_SPIDf, 9361 Q44_SPIDf, Q45_SPIDf, Q46_SPIDf, Q47_SPIDf, 9362 Q48_SPIDf, Q49_SPIDf, Q50_SPIDf, Q51_SPIDf, 9363 Q52_SPIDf, Q53_SPIDf, Q54_SPIDf, Q55_SPIDf, 9364 Q56_SPIDf, Q57_SPIDf, Q58_SPIDf, Q59_SPIDf, 9365 Q60_SPIDf, Q61_SPIDf, Q62_SPIDf, Q63_SPIDf, 9366 Q64_SPIDf, Q65_SPIDf, Q66_SPIDf, Q67_SPIDf, 9367 Q68_SPIDf, Q69_SPIDf, Q70_SPIDf, Q71_SPIDf, 9368 Q72_SPIDf, Q73_SPIDf 9369 }; 9370 9371 si = &SOC_INFO(unit); 9372 9373 default_mtu_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_DEFAULT_MTU_BYTES + 9374 _TD_MMU_PACKET_HEADER_BYTES); 9375 9376 /* internal priority to priority group mapping */ 9377 PBMP_ALL_ITER(unit, port) { 9378 buf_port = &buf->ports[port]; 9379 9380 for (idx = 0; idx < 16; idx++) { 9381 if (idx % 8 == 0) { /* 8 fields per register */ 9382 reg = prigroup_reg[idx / 8]; 9383 rval = 0; 9384 } 9385 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 9386 buf_port->pri_to_prigroup[idx]); 9387 if (idx % 8 == 7) { /* 8 fields per register */ 9388 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 9389 } 9390 } 9391 } 9392 9393 /* Input port device settings */ 9394 rval = 0; 9395 soc_reg_field_set(unit, GLOBAL_HDRM_LIMITr, &rval, GLOBAL_HDRM_LIMITf, 9396 buf->headroom); 9397 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_HDRM_LIMITr(unit, rval)); 9398 9399 fval = 0; 9400 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9401 if ((buf->pools[idx].size & ~_TD_BUF_PERCENT_FLAG) != 0) { 9402 fval |= 1 << idx; 9403 } 9404 } 9405 rval = 0; 9406 soc_reg_field_set(unit, USE_SP_SHAREDr, &rval, ENABLEf, fval); 9407 SOC_IF_ERROR_RETURN(WRITE_USE_SP_SHAREDr(unit, rval)); 9408 9409 fval = 0; 9410 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9411 buf_pool = &buf->pools[idx]; 9412 if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) { 9413 continue; 9414 } 9415 9416 if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) { 9417 if ((buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) < 10000) { 9418 fval |= 1 << idx; 9419 } 9420 } else { 9421 if (buf->pools[idx].size != buf->pools[idx].yellow_size) { 9422 fval |= 1 << idx; 9423 } 9424 } 9425 } 9426 rval = 0; 9427 soc_reg_field_set(unit, COLOR_AWAREr, &rval, ENABLEf, fval); 9428 SOC_IF_ERROR_RETURN(WRITE_COLOR_AWAREr(unit, rval)); 9429 9430 /* Input port per service pool settings */ 9431 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9432 buf_pool = &buf->pools[idx]; 9433 if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) { 9434 continue; 9435 } 9436 9437 limit = buf_pool->total - buf_pool->prigroup_guarantee - 9438 buf_pool->prigroup_headroom - buf_pool->queue_guarantee; 9439 9440 rval = 0; 9441 soc_reg_field_set(unit, BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit); 9442 SOC_IF_ERROR_RETURN(WRITE_BUFFER_CELL_LIMIT_SPr(unit, idx, rval)); 9443 9444 rval = 0; 9445 soc_reg_field_set(unit, CELL_RESET_LIMIT_OFFSET_SPr, &rval, OFFSETf, 9446 NUM_PORT(unit) * default_mtu_cells / 2); 9447 SOC_IF_ERROR_RETURN 9448 (WRITE_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval)); 9449 9450 if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) { 9451 if ((buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) == 10000) { 9452 continue; 9453 } 9454 } else { 9455 if (buf->pools[idx].size == buf->pools[idx].yellow_size) { 9456 continue; 9457 } 9458 } 9459 9460 if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) { 9461 fval = (buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) * limit / 9462 10000; 9463 } else { 9464 fval = buf_pool->yellow_size; 9465 } 9466 rval = 0; 9467 soc_reg_field_set(unit, CELL_SPAP_YELLOW_OFFSET_SPr, &rval, OFFSETf, 9468 fval); 9469 SOC_IF_ERROR_RETURN 9470 (WRITE_CELL_SPAP_YELLOW_OFFSET_SPr(unit, idx, rval)); 9471 9472 if (buf_pool->red_size & _TD_BUF_PERCENT_FLAG) { 9473 fval = (buf_pool->red_size & ~_TD_BUF_PERCENT_FLAG) * limit / 9474 10000; 9475 } else { 9476 fval = buf_pool->red_size; 9477 } 9478 rval = 0; 9479 soc_reg_field_set(unit, CELL_SPAP_RED_OFFSET_SPr, &rval, OFFSETf, 9480 fval); 9481 SOC_IF_ERROR_RETURN(WRITE_CELL_SPAP_RED_OFFSET_SPr(unit, idx, rval)); 9482 } 9483 9484 /* Input port per port settings */ 9485 PBMP_ALL_ITER(unit, port) { 9486 buf_port = &buf->ports[port]; 9487 9488 rval = 0; 9489 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9490 soc_reg_field_set(unit, PORT_PG_SPIDr, &rval, 9491 prigroup_spid_field[idx], 9492 buf_port->prigroups[idx].pool_idx); 9493 } 9494 SOC_IF_ERROR_RETURN(WRITE_PORT_PG_SPIDr(unit, port, rval)); 9495 9496 rval = 0; 9497 soc_reg_field_set(unit, PORT_MIN_CELLr, &rval, PORT_MINf, 9498 buf_port->guarantee); 9499 SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_CELLr(unit, port, rval)); 9500 9501 rval = 0; 9502 soc_reg_field_set(unit, PORT_MAX_SHARED_CELLr, &rval, PORT_MAXf, 9503 buf_port->pool_limit); 9504 SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_SHARED_CELLr(unit, port, rval)); 9505 9506 rval = 0; 9507 soc_reg_field_set(unit, PORT_RESUME_LIMIT_CELLr, &rval, CELLSf, 9508 buf_port->pool_resume); 9509 SOC_IF_ERROR_RETURN(WRITE_PORT_RESUME_LIMIT_CELLr(unit, port, rval)); 9510 9511 fval = 0; 9512 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9513 if (buf_port->prigroups[idx].port_guarantee_enable != 0) { 9514 fval |= 1 << idx; 9515 } 9516 } 9517 rval = 0; 9518 soc_reg_field_set(unit, PORT_MIN_PG_ENABLEr, &rval, PG_BMPf, fval); 9519 SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_PG_ENABLEr(unit, port, rval)); 9520 9521 fval = 0; 9522 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9523 if (buf_port->prigroups[idx].port_max_enable != 0) { 9524 fval |= 1 << idx; 9525 } 9526 } 9527 rval = 0; 9528 soc_reg_field_set(unit, PORT_SHARED_MAX_PG_ENABLEr, &rval, PG_BMPf, 9529 fval); 9530 SOC_IF_ERROR_RETURN 9531 (WRITE_PORT_SHARED_MAX_PG_ENABLEr(unit, port, rval)); 9532 9533 fval = 0; 9534 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9535 if (buf_port->prigroups[idx].flow_control_enable != 0) { 9536 fval |= 1 << idx; 9537 } 9538 } 9539 rval = 0; 9540 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 9541 PORT_PRI_XON_ENABLEf, fval); 9542 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval)); 9543 9544 rval = 0; 9545 soc_reg_field_set(unit, PORT_MAX_PKT_SIZEr, &rval, PORT_MAX_PKT_SIZEf, 9546 buf_port->pkt_size); 9547 SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_PKT_SIZEr(unit, port, rval)); 9548 9549 /* Input port per port per priority group settings */ 9550 for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) { 9551 buf_prigroup = &buf->ports[port].prigroups[idx]; 9552 9553 rval = 0; 9554 soc_reg_field_set(unit, PG_MIN_CELLr, &rval, PG_MINf, 9555 buf_prigroup->guarantee > 1 ? buf_prigroup->guarantee : 1); 9556 SOC_IF_ERROR_RETURN 9557 (soc_reg32_set(unit, PG_MIN_CELLr, port, idx, rval)); 9558 9559 rval = 0; 9560 soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &rval, PG_GEf, 9561 buf_prigroup->device_headroom_enable); 9562 soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &rval, PG_HDRM_LIMITf, 9563 buf_prigroup->headroom); 9564 SOC_IF_ERROR_RETURN 9565 (soc_reg32_set(unit, PG_HDRM_LIMIT_CELLr, port, idx, rval)); 9566 9567 rval = 0; 9568 if (buf_prigroup->pool_scale != -1) { 9569 soc_reg_field_set(unit, PG_SHARED_LIMIT_CELLr, &rval, 9570 PG_SHARED_DYNAMICf, 1); 9571 soc_reg_field_set(unit, PG_SHARED_LIMIT_CELLr, &rval, 9572 PG_SHARED_LIMITf, buf_prigroup->pool_scale); 9573 } else { 9574 /* PG_SHARED_DYNAMICf is 0 */ 9575 soc_reg_field_set(unit, PG_SHARED_LIMIT_CELLr, &rval, 9576 PG_SHARED_LIMITf, buf_prigroup->pool_limit); 9577 } 9578 SOC_IF_ERROR_RETURN 9579 (soc_reg32_set(unit, PG_SHARED_LIMIT_CELLr, port, idx, rval)); 9580 9581 rval = 0; 9582 soc_reg_field_set(unit, PG_RESET_OFFSET_CELLr, &rval, 9583 PG_RESET_OFFSETf, buf_prigroup->pool_resume); 9584 SOC_IF_ERROR_RETURN 9585 (soc_reg32_set(unit, PG_RESET_OFFSET_CELLr, port, idx, rval)); 9586 9587 rval = 0; 9588 soc_reg_field_set(unit, PG_RESET_FLOOR_CELLr, &rval, 9589 PG_RESET_FLOORf, buf_prigroup->pool_floor); 9590 SOC_IF_ERROR_RETURN 9591 (soc_reg32_set(unit, PG_RESET_FLOOR_CELLr, port, idx, rval)); 9592 } 9593 } 9594 9595 /* Output port per port per queue setting for multicast queue */ 9596 PBMP_ALL_ITER(unit, port) { 9597 count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]; 9598 for (idx = 0; idx < count; idx++) { 9599 buf_queue = &buf->ports[port].queues[idx]; 9600 9601 rval = 0; 9602 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &rval, Q_MIN_CELLf, 9603 buf_queue->guarantee); 9604 if (buf_queue->pool_scale != -1) { 9605 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &rval, 9606 Q_SHARED_ALPHA_CELLf, 9607 buf_queue->pool_scale); 9608 } else { 9609 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &rval, 9610 Q_SHARED_LIMIT_CELLf, 9611 buf_queue->pool_limit); 9612 } 9613 SOC_IF_ERROR_RETURN 9614 (WRITE_OP_QUEUE_CONFIG_CELLr(unit, port, idx, rval)); 9615 9616 rval = 0; 9617 if (buf_queue->discard_enable) { 9618 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 9619 Q_LIMIT_ENABLE_CELLf, 1); 9620 } else { 9621 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 9622 Q_LIMIT_ENABLE_CELLf, 0); 9623 } 9624 if (buf_queue->pool_scale != -1) { 9625 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 9626 Q_LIMIT_DYNAMIC_CELLf, 1); 9627 } 9628 if (buf_queue->color_discard_enable) { 9629 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 9630 Q_COLOR_ENABLE_CELLf, 1); 9631 } 9632 if (buf_queue->red_limit & _TD_BUF_DYNAMIC_FLAG) { 9633 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 9634 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 9635 } 9636 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 9637 Q_SPIDf, buf_queue->pool_idx); 9638 SOC_IF_ERROR_RETURN 9639 (WRITE_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, rval)); 9640 9641 rval = 0; 9642 soc_reg_field_set(unit, OP_QUEUE_LIMIT_COLOR_CELLr, &rval, REDf, 9643 buf_queue->red_limit & ~_TD_BUF_DYNAMIC_FLAG); 9644 SOC_IF_ERROR_RETURN 9645 (WRITE_OP_QUEUE_LIMIT_COLOR_CELLr(unit, port, idx, rval)); 9646 9647 rval = 0; 9648 soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_CELLr, &rval, 9649 Q_RESET_OFFSET_CELLf, 9650 buf_queue->pool_resume / 8); 9651 SOC_IF_ERROR_RETURN 9652 (WRITE_OP_QUEUE_RESET_OFFSET_CELLr(unit, port, idx, rval)); 9653 } 9654 } 9655 9656 /* Output port per port per queue setting for regular unicast queue */ 9657 PBMP_PORT_ITER(unit, port) { 9658 phy_port = si->port_l2p_mapping[port]; 9659 mmu_port = si->port_p2m_mapping[phy_port]; 9660 if (si->port_num_ext_cosq[port] == 0) { 9661 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X pipe */ 9662 config_mem = MMU_THDO_CONFIG_0m; 9663 offset_mem = MMU_THDO_OFFSET_0m; 9664 /* Index starts from mmu port 5, 10 entries per port */ 9665 base = (mmu_port - 5) * 10; 9666 } else { /* Y pipe */ 9667 config_mem = MMU_THDO_CONFIG_1m; 9668 offset_mem = MMU_THDO_OFFSET_1m; 9669 /* Index starts from mmu port 38, 10 entries per port */ 9670 base = (mmu_port - 38) * 10; 9671 } 9672 } else { 9673 /* 9674 * Depends on OP_VOQ_PORT_CONFIG mode setting for the extended 9675 * queue port: 9676 * - cos mode 9677 * use MMU_THDO_CONFIG_SP_x table, 10 entries per port 9678 * - queue mode 9679 * use MMU_THDO_CONFIG_EX_x table, 74 entries per port 9680 * extended unicast queues: index 0-63 9681 * regular unicast queue: index 64-73 9682 */ 9683 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X pipe */ 9684 config_mem = MMU_THDO_CONFIG_EX_0m; 9685 offset_mem = MMU_THDO_OFFSET_EX_0m; 9686 /* Index starts from mmu port 1, 74 entries per port */ 9687 base = (mmu_port - 1) * 74 + 64; 9688 } else { /* Y pipe */ 9689 config_mem = MMU_THDO_CONFIG_EX_1m; 9690 offset_mem = MMU_THDO_OFFSET_EX_1m; 9691 /* Index starts from mmu port 34, 74 entries per port */ 9692 base = (mmu_port - 34) * 74 + 64; 9693 } 9694 } 9695 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 9696 buf_queue = &buf->ports[port].queues 9697 [si->port_num_cosq[port] + idx]; 9698 9699 sal_memset(entry0, 0, sizeof(mmu_thdo_config_0_entry_t)); 9700 sal_memset(entry1, 0, sizeof(mmu_thdo_offset_0_entry_t)); 9701 9702 soc_mem_field32_set(unit, config_mem, entry0, Q_MIN_CELLf, 9703 buf_queue->guarantee); 9704 if (buf_queue->discard_enable) { 9705 soc_mem_field32_set(unit, config_mem, entry0, 9706 Q_LIMIT_ENABLE_CELLf, 1); 9707 } else { 9708 soc_mem_field32_set(unit, config_mem, entry0, 9709 Q_LIMIT_ENABLE_CELLf, 0); 9710 } 9711 if (buf_queue->pool_scale != -1) { 9712 soc_mem_field32_set(unit, config_mem, entry0, 9713 Q_LIMIT_DYNAMIC_CELLf, 1); 9714 soc_mem_field32_set(unit, config_mem, entry0, 9715 Q_SHARED_ALPHA_CELLf, 9716 buf_queue->pool_scale); 9717 } else { 9718 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 9719 soc_mem_field32_set(unit, config_mem, entry0, 9720 Q_SHARED_LIMIT_CELLf, 9721 buf_queue->pool_limit); 9722 } 9723 soc_mem_field32_set(unit, offset_mem, entry1, RESET_OFFSET_CELLf, 9724 buf_queue->pool_resume / 8); 9725 if (buf_queue->color_discard_enable) { 9726 soc_mem_field32_set(unit, config_mem, entry0, 9727 Q_COLOR_ENABLE_CELLf, fval); 9728 } 9729 if (buf_queue->yellow_limit & _TD_BUF_DYNAMIC_FLAG) { 9730 soc_mem_field32_set(unit, config_mem, entry0, 9731 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 9732 soc_mem_field32_set 9733 (unit, config_mem, entry0, LIMIT_YELLOW_CELLf, 9734 buf_queue->yellow_limit & ~_TD_BUF_DYNAMIC_FLAG); 9735 soc_mem_field32_set 9736 (unit, offset_mem, entry1, LIMIT_RED_CELLf, 9737 buf_queue->red_limit & ~_TD_BUF_DYNAMIC_FLAG); 9738 } else { 9739 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 9740 soc_mem_field32_set 9741 (unit, config_mem, entry0, LIMIT_YELLOW_CELLf, 9742 buf_queue->yellow_limit / 8); 9743 soc_mem_field32_set 9744 (unit, offset_mem, entry1, LIMIT_RED_CELLf, 9745 buf_queue->red_limit / 8); 9746 } 9747 soc_mem_field32_set 9748 (unit, offset_mem, entry1, RESET_OFFSET_YELLOW_CELLf, 9749 buf_queue->yellow_resume / 8); 9750 soc_mem_field32_set 9751 (unit, offset_mem, entry1, RESET_OFFSET_RED_CELLf, 9752 buf_queue->red_resume / 8); 9753 SOC_IF_ERROR_RETURN 9754 (soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 9755 base + idx, entry0)); 9756 SOC_IF_ERROR_RETURN 9757 (soc_mem_write(unit, offset_mem, MEM_BLOCK_ALL, 9758 base + idx, entry1)); 9759 } 9760 } 9761 9762 /* Output port per port per queue setting for extended unicast queue */ 9763 SOC_PBMP_ITER(si->eq_pbm, port) { 9764 /* coverity[overrun-local : FALSE] */ 9765 phy_port = si->port_l2p_mapping[port]; 9766 mmu_port = si->port_p2m_mapping[phy_port]; 9767 9768 /* 9769 * 74 entries per port: 9770 * extended unicast queues: index 0-63 9771 * regular unicast queue: index 64-73 (when in queue mode) 9772 */ 9773 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X pipe */ 9774 config_mem = MMU_THDO_CONFIG_EX_0m; 9775 offset_mem = MMU_THDO_OFFSET_EX_0m; 9776 /* Index starts from mmu port 1, 74 entries per port */ 9777 base = (mmu_port - 1) * 74; 9778 } else { /* Y pipe */ 9779 config_mem = MMU_THDO_CONFIG_EX_1m; 9780 offset_mem = MMU_THDO_OFFSET_EX_1m; 9781 /* Index starts from mmu port 34, 74 entries per port */ 9782 base = (mmu_port - 34) * 74; 9783 } 9784 9785 for (idx = 0; idx < si->port_num_ext_cosq[port]; idx++) { 9786 /* coverity[overrun-local : FALSE] */ 9787 buf_queue = &buf->ports[port].queues 9788 [si->port_num_cosq[port] + si->port_num_uc_cosq[port] + idx]; 9789 9790 sal_memset(entry0, 0, sizeof(mmu_thdo_config_ex_0_entry_t)); 9791 sal_memset(entry1, 0, sizeof(mmu_thdo_offset_ex_0_entry_t)); 9792 9793 soc_mem_field32_set(unit, config_mem, entry0, Q_MIN_CELLf, 9794 buf_queue->guarantee); 9795 if (buf_queue->discard_enable) { 9796 soc_mem_field32_set(unit, config_mem, entry0, 9797 Q_LIMIT_ENABLE_CELLf, 1); 9798 } else { 9799 soc_mem_field32_set(unit, config_mem, entry0, 9800 Q_LIMIT_ENABLE_CELLf, 0); 9801 } 9802 if (buf_queue->pool_scale != -1) { 9803 soc_mem_field32_set(unit, config_mem, entry0, 9804 Q_LIMIT_DYNAMIC_CELLf, 1); 9805 soc_mem_field32_set(unit, config_mem, entry0, 9806 Q_SHARED_ALPHA_CELLf, 9807 buf_queue->pool_scale); 9808 } else { 9809 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 9810 soc_mem_field32_set(unit, config_mem, entry0, 9811 Q_SHARED_LIMIT_CELLf, 9812 buf_queue->pool_limit); 9813 } 9814 soc_mem_field32_set(unit, offset_mem, entry1, RESET_OFFSET_CELLf, 9815 buf_queue->pool_resume / 8); 9816 if (buf_queue->color_discard_enable) { 9817 soc_mem_field32_set(unit, config_mem, entry0, 9818 Q_COLOR_ENABLE_CELLf, fval); 9819 } 9820 if (buf_queue->yellow_limit & _TD_BUF_DYNAMIC_FLAG) { 9821 soc_mem_field32_set(unit, config_mem, entry0, 9822 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 9823 soc_mem_field32_set 9824 (unit, config_mem, entry0, LIMIT_YELLOW_CELLf, 9825 buf_queue->yellow_limit & ~_TD_BUF_DYNAMIC_FLAG); 9826 soc_mem_field32_set 9827 (unit, offset_mem, entry1, LIMIT_RED_CELLf, 9828 buf_queue->red_limit & ~_TD_BUF_DYNAMIC_FLAG); 9829 } else { 9830 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 9831 soc_mem_field32_set 9832 (unit, config_mem, entry0, LIMIT_YELLOW_CELLf, 9833 buf_queue->yellow_limit / 8); 9834 soc_mem_field32_set 9835 (unit, offset_mem, entry1, LIMIT_RED_CELLf, 9836 buf_queue->red_limit / 8); 9837 } 9838 soc_mem_field32_set 9839 (unit, offset_mem, entry1, RESET_OFFSET_YELLOW_CELLf, 9840 buf_queue->yellow_resume / 8); 9841 soc_mem_field32_set 9842 (unit, offset_mem, entry1, RESET_OFFSET_RED_CELLf, 9843 buf_queue->red_resume / 8); 9844 SOC_IF_ERROR_RETURN 9845 (soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 9846 base + idx, entry0)); 9847 SOC_IF_ERROR_RETURN 9848 (soc_mem_write(unit, offset_mem, MEM_BLOCK_ALL, 9849 base + idx, entry1)); 9850 } 9851 } 9852 9853 /* Output port per port settings */ 9854 PBMP_PORT_ITER(unit, port) { 9855 buf_port = &buf->ports[port]; 9856 9857 /* regular unicast queue to pool mapping */ 9858 count = si->port_num_uc_cosq[port]; 9859 if (count > 0) { 9860 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port]]; 9861 rval = 0; 9862 if (si->port_num_ext_cosq[port] == 0) { 9863 for (idx = 0; idx < count; idx++) { 9864 soc_reg_field_set(unit, OP_UC_PORT_CONFIG1_CELLr, &rval, 9865 uc_spid_field[idx], 9866 buf_queue[idx].pool_idx); 9867 } 9868 SOC_IF_ERROR_RETURN 9869 (WRITE_OP_UC_PORT_CONFIG1_CELLr(unit, port, rval)); 9870 } else { 9871 for (idx = 0; idx < count; idx++) { 9872 soc_reg_field_set(unit, OP_EX_PORT_CONFIG_SPID_4r, &rval, 9873 ext_spid_field[idx + 64], 9874 buf_queue[idx].pool_idx); 9875 } 9876 SOC_IF_ERROR_RETURN 9877 (WRITE_OP_EX_PORT_CONFIG_SPID_4r(unit, port, rval)); 9878 } 9879 } 9880 9881 /* extended unicast queue to pool mapping */ 9882 count = SOC_PBMP_MEMBER(si->eq_pbm, port) ? 9883 si->port_num_ext_cosq[port] : 0; 9884 if (count > 0) { 9885 buf_queue = &buf_port->queues[si->port_num_cosq[port] + 9886 si->port_num_uc_cosq[port]]; 9887 for (idx = 0; idx < count; idx++) { 9888 if (idx % 16 == 0) { /* 16 fields per register */ 9889 reg = ext_spid_reg[idx / 16]; 9890 rval = 0; 9891 } 9892 soc_reg_field_set(unit, reg, &rval, ext_spid_field[idx], 9893 buf_queue[idx].pool_idx); 9894 if (idx % 16 == 15) { /* 16 fields per register */ 9895 SOC_IF_ERROR_RETURN 9896 (soc_reg32_set(unit, reg, port, 0, rval)); 9897 } 9898 } 9899 } 9900 } 9901 9902 /* Output port per pool settings */ 9903 for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) { 9904 buf_pool = &buf->pools[idx]; 9905 if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) { 9906 continue; 9907 } 9908 limit = buf_pool->total + buf->port_guarantee - 9909 buf_pool->queue_guarantee; 9910 9911 rval = 0; 9912 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, &rval, 9913 OP_BUFFER_SHARED_LIMIT_CELLf, limit); 9914 SOC_IF_ERROR_RETURN 9915 (soc_reg32_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, REG_PORT_ANY, 9916 idx, rval)); 9917 9918 rval = 0; 9919 soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, &rval, 9920 OP_BUFFER_LIMIT_YELLOW_CELLf, limit / 8); 9921 SOC_IF_ERROR_RETURN 9922 (soc_reg32_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, REG_PORT_ANY, 9923 idx, rval)); 9924 9925 rval = 0; 9926 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_CELLr, &rval, 9927 OP_BUFFER_LIMIT_RED_CELLf, limit / 8); 9928 SOC_IF_ERROR_RETURN 9929 (soc_reg32_set(unit, OP_BUFFER_LIMIT_RED_CELLr, REG_PORT_ANY, 9930 idx, rval)); 9931 9932 rval = 0; 9933 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_CELLr, &rval, 9934 OP_BUFFER_SHARED_LIMIT_RESUME_CELLf, limit); 9935 SOC_IF_ERROR_RETURN 9936 (soc_reg32_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_CELLr, 9937 REG_PORT_ANY, idx, rval)); 9938 9939 rval = 0; 9940 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RESUME_YELLOW_CELLr, &rval, 9941 OP_BUFFER_LIMIT_RESUME_YELLOW_CELLf, limit / 8); 9942 SOC_IF_ERROR_RETURN 9943 (soc_reg32_set(unit, OP_BUFFER_LIMIT_RESUME_YELLOW_CELLr, 9944 REG_PORT_ANY, idx, rval)); 9945 9946 rval = 0; 9947 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RESUME_RED_CELLr, &rval, 9948 OP_BUFFER_LIMIT_RESUME_RED_CELLf, limit / 8); 9949 SOC_IF_ERROR_RETURN 9950 (soc_reg32_set(unit, OP_BUFFER_LIMIT_RESUME_RED_CELLr, 9951 REG_PORT_ANY, idx, rval)); 9952 9953 /* Output port per port per pool setting for unicast queues */ 9954 PBMP_PORT_ITER(unit, port) { 9955 rval = 0; 9956 soc_reg_field_set(unit, OP_UC_PORT_CONFIG_CELLr, &rval, 9957 OP_SHARED_LIMIT_CELLf, limit); 9958 soc_reg_field_set(unit, OP_UC_PORT_CONFIG_CELLr, &rval, 9959 OP_SHARED_RESET_VALUE_CELLf, 9960 limit - default_mtu_cells); 9961 SOC_IF_ERROR_RETURN 9962 (WRITE_OP_UC_PORT_CONFIG_CELLr(unit, port, idx, rval)); 9963 9964 rval = 0; 9965 soc_reg_field_set(unit, OP_UC_PORT_LIMIT_COLOR_CELLr, &rval, YELf, 9966 limit / 8); 9967 soc_reg_field_set(unit, OP_UC_PORT_LIMIT_COLOR_CELLr, &rval, REDf, 9968 limit / 8); 9969 SOC_IF_ERROR_RETURN 9970 (WRITE_OP_UC_PORT_LIMIT_COLOR_CELLr(unit, port, idx, rval)); 9971 9972 rval = 0; 9973 soc_reg_field_set 9974 (unit, OP_UC_PORT_LIMIT_RESUME_COLOR_CELLr, &rval, YELf, 9975 (limit - default_mtu_cells) / 8); 9976 soc_reg_field_set 9977 (unit, OP_UC_PORT_LIMIT_RESUME_COLOR_CELLr, &rval, REDf, 9978 (limit - default_mtu_cells) / 8); 9979 SOC_IF_ERROR_RETURN 9980 (WRITE_OP_UC_PORT_LIMIT_RESUME_COLOR_CELLr 9981 (unit, port, idx, rval)); 9982 9983 rval = 0; 9984 } 9985 9986 /* Output port per port per pool setting for multicast queues */ 9987 PBMP_ALL_ITER(unit, port) { 9988 rval = 0; 9989 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &rval, 9990 OP_SHARED_LIMIT_CELLf, limit); 9991 soc_reg_field_set(unit, OP_UC_PORT_CONFIG_CELLr, &rval, 9992 OP_SHARED_RESET_VALUE_CELLf, 9993 limit - default_mtu_cells); 9994 SOC_IF_ERROR_RETURN 9995 (soc_reg32_set(unit, OP_PORT_CONFIG_CELLr, port, idx, rval)); 9996 9997 rval = 0; 9998 soc_reg_field_set(unit, OP_PORT_LIMIT_COLOR_CELLr, &rval, REDf, 9999 limit / 8); 10000 SOC_IF_ERROR_RETURN 10001 (soc_reg32_set(unit, OP_PORT_LIMIT_COLOR_CELLr, port, idx, 10002 rval)); 10003 10004 rval = 0; 10005 soc_reg_field_set 10006 (unit, OP_PORT_LIMIT_RESUME_COLOR_CELLr, &rval, REDf, 10007 (limit - default_mtu_cells) / 8); 10008 SOC_IF_ERROR_RETURN 10009 (soc_reg32_set(unit, OP_PORT_LIMIT_RESUME_COLOR_CELLr, port, 10010 idx, rval)); 10011 } 10012 } 10013 10014 return SOC_E_NONE; 10015 } 10016 10017 int 10018 soc_trident_mmu_config_init(int unit, int test_only) 10019 { 10020 soc_info_t *si; 10021 _soc_trident_buf_t *buf; 10022 _soc_trident_buf_queue_t *buf_queue; 10023 int rv, port, alloc_size, num_cosq; 10024 10025 si = &SOC_INFO(unit); 10026 10027 alloc_size = sizeof(_soc_trident_buf_t); 10028 PBMP_ALL_ITER(unit, port) { 10029 num_cosq = si->port_num_cosq[port] + si->port_num_uc_cosq[port] + 10030 si->port_num_ext_cosq[port]; 10031 alloc_size += sizeof(_soc_trident_buf_queue_t) * num_cosq; 10032 } 10033 buf = sal_alloc(alloc_size, "MMU config buffer"); 10034 if (buf == NULL) { 10035 return SOC_E_MEMORY; 10036 } 10037 10038 sal_memset(buf, 0, alloc_size); 10039 buf_queue = (_soc_trident_buf_queue_t *)&buf[1]; 10040 PBMP_ALL_ITER(unit, port) { 10041 num_cosq = si->port_num_cosq[port] + si->port_num_uc_cosq[port] + 10042 si->port_num_ext_cosq[port]; 10043 buf->ports[port].queues = buf_queue; 10044 buf_queue += num_cosq; 10045 } 10046 10047 _soc_trident_mmu_config_buf_default(unit, buf); 10048 _soc_trident_mmu_config_buf_read(unit, buf); 10049 rv = _soc_trident_mmu_config_buf_check(unit, buf); 10050 if (!test_only) { 10051 if (SOC_FAILURE(rv)) { 10052 LOG_CLI((BSL_META_U(unit, 10053 "MMU config: Use default setting\n"))); 10054 _soc_trident_mmu_config_buf_default(unit, buf); 10055 _soc_trident_mmu_config_buf_calculate(unit, buf); 10056 } 10057 rv = _soc_trident_mmu_config_buf_set_hw(unit, buf); 10058 } 10059 10060 sal_free(buf); 10061 10062 return rv; 10063 } 10064 10065 STATIC int 10066 _soc_trident_mmu_init(int unit) 10067 { 10068 soc_info_t *si; 10069 uint64 r64val0, r64val1, r64val2; 10070 uint32 rval0, rval1; 10071 uint32 rval_base[3][4], rval_credit[3]; 10072 soc_pbmp_t pbmp0, pbmp1; 10073 int credit; 10074 int port, phy_port, mmu_port, idx, mode_idx, mode; 10075 int blk_bandwidth; 10076 uint32 mode4_bmp, mode2_bmp; 10077 static const soc_field_t gb_field[] = { 10078 GB_PORT0f, GB_PORT1f, GB_PORT2f, GB_PORT3f 10079 }; 10080 10081 si = &SOC_INFO(unit); 10082 10083 /* Setup TDM for MMU */ 10084 SOC_IF_ERROR_RETURN(_soc_trident_mmu_tdm_init(unit)); 10085 10086 /* Enable QGPORT (1G x 4) in XLPORT0 block (if present) */ 10087 blk_bandwidth = 0; 10088 for (phy_port = 1; phy_port < 5; phy_port++) { 10089 port = si->port_p2l_mapping[phy_port]; 10090 if (port != -1) { 10091 blk_bandwidth += si->port_speed_max[port]; 10092 } 10093 } 10094 COMPILER_64_ZERO(r64val0); 10095 if (blk_bandwidth > 0 && blk_bandwidth <= 4000) { 10096 for (phy_port = 1; phy_port < 5; phy_port++) { 10097 mmu_port = si->port_p2m_mapping[phy_port]; 10098 if (mmu_port < 0) { 10099 soc_reg64_field32_set(unit, ES_TDM_CONFIGr, &r64val0, 10100 gb_field[phy_port - 1], 0x3f); 10101 } else { 10102 soc_reg64_field32_set(unit, ES_TDM_CONFIGr, &r64val0, 10103 gb_field[phy_port - 1], mmu_port); 10104 } 10105 } 10106 soc_reg64_field32_set(unit, ES_TDM_CONFIGr, &r64val0, 10107 EN_CPU_SLOT_SHARINGf, 1); 10108 } 10109 SOC_IF_ERROR_RETURN(WRITE_ES_TDM_CONFIGr(unit, r64val0)); 10110 10111 mode4_bmp = mode2_bmp = 0; 10112 for (mode_idx = 0; mode_idx < 16; mode_idx++) { 10113 /* 1, 2, 3, 4, 17, 18, 19, 20, 34, 35, 36, 37, 50, 51, 52, 53 */ 10114 mmu_port = (((mode_idx & 0xc) << 2) | (mode_idx & 0x3)) + 10115 (mode_idx < 8 ? 1 : 2); 10116 if (si->port_m2p_mapping[mmu_port] == -1) { 10117 continue; 10118 } 10119 phy_port = si->port_m2p_mapping[mmu_port]; 10120 port = si->port_p2l_mapping[phy_port]; 10121 if (si->port_speed_max[port] > 20000) { 10122 if (si->port_m2p_mapping[mmu_port + 4] == -1 && 10123 si->port_m2p_mapping[mmu_port + 8] == -1 && 10124 si->port_m2p_mapping[mmu_port + 12] == -1) { 10125 mode4_bmp |= 1 << mode_idx; 10126 } 10127 } else if (si->port_speed_max[port] > 10000) { 10128 if ((si->port_speed_max[port] == 20000) && 10129 (si->port_num_lanes[port] == 4)) { 10130 if (si->port_m2p_mapping[mmu_port + 4] == -1 && 10131 si->port_m2p_mapping[mmu_port + 8] == -1 && 10132 si->port_m2p_mapping[mmu_port + 12] == -1) { 10133 mode4_bmp |= 1 << mode_idx; 10134 } 10135 } else { 10136 if (si->port_m2p_mapping[mmu_port + 4] == -1 && 10137 si->port_m2p_mapping[mmu_port + 12] == -1) { 10138 mode2_bmp |= 1 << mode_idx; 10139 } 10140 } 10141 } 10142 } 10143 rval0 = 0; 10144 soc_reg_field_set(unit, MCQ_CONFIGr, &rval0, MODE_4f, mode4_bmp); 10145 soc_reg_field_set(unit, MCQ_CONFIGr, &rval0, MODE_2f, mode2_bmp); 10146 SOC_IF_ERROR_RETURN(WRITE_MCQ_CONFIGr(unit, rval0)); 10147 10148 SOC_IF_ERROR_RETURN(soc_trident_mmu_config_init(unit, FALSE)); 10149 10150 rval0 = 0; 10151 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, MOP_POLICYf, 7); 10152 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, ASF_PKT_SIZEf, 3); 10153 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, ASF_QUEUE_SIZEf, 3); 10154 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, YELLOW_CELL_DS_SELECTf, 1); 10155 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval0)); 10156 10157 /* Set extended queue ports to use queue mode accounting */ 10158 rval0 = 0; 10159 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P1f, 1); 10160 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P2f, 1); 10161 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P3f, 1); 10162 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P4f, 1); 10163 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P34f, 1); 10164 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P35f, 1); 10165 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P36f, 1); 10166 soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P37f, 1); 10167 SOC_IF_ERROR_RETURN(WRITE_OP_VOQ_PORT_CONFIGr(unit, rval0)); 10168 10169 /* OVQ settings */ 10170 rval0 = 0; 10171 soc_reg_field_set(unit, OVQ_DROP_THRESHOLD0r, &rval0, 10172 OVQ_DROP_THRESHOLD0f, _TD_MMU_TOTAL_CELLS / 4); 10173 SOC_IF_ERROR_RETURN(WRITE_OVQ_DROP_THRESHOLD0r(unit, rval0)); 10174 10175 rval0 = 0; 10176 soc_reg_field_set(unit, OVQ_DROP_THRESHOLD_RESET_LIMITr, &rval0, 10177 OVQ_DROP_THRESHOLD_RESET_LIMITf, 10178 _TD_MMU_TOTAL_CELLS / 4); 10179 SOC_IF_ERROR_RETURN 10180 (WRITE_OVQ_DROP_THRESHOLD_RESET_LIMITr(unit, rval0)); 10181 10182 rval0 = 0; 10183 soc_reg_field_set(unit, OVQ_FLOWCONTROL_THRESHOLDr, &rval0, OVQ_FC_ENABLEf, 10184 1); 10185 soc_reg_field_set(unit, OVQ_FLOWCONTROL_THRESHOLDr, &rval0, 10186 OVQ_FC_THRESHOLDf, 11250); 10187 soc_reg_field_set(unit, OVQ_FLOWCONTROL_THRESHOLDr, &rval0, 10188 OVQ_FC_THRESHOLD_RESET_LIMITf, 11249); 10189 SOC_IF_ERROR_RETURN(WRITE_OVQ_FLOWCONTROL_THRESHOLDr(unit, rval0)); 10190 10191 sal_memset(rval_base, 0, sizeof(rval_base)); 10192 sal_memset(rval_credit, 0, sizeof(rval_credit)); 10193 for (mode = 0; mode < 3; mode++) { /* MODE_1, MODE_2, MODE_4 */ 10194 /* MODE_x means a port has x subports, each subport has 1000 credits, 10195 * divide total credit from all subports by 5 multicast queues, 10196 * then truncate the result to multiple of 16 */ 10197 credit = ((1 << mode) * 1000 / 5) & ~0xf; 10198 soc_reg_field_set(unit, OVQ_MCQ_CREDITSr, &rval_credit[mode], CREDITSf, 10199 credit); 10200 for (idx = 0; idx < 4; idx++) { 10201 soc_reg_field_set(unit, MCQ_FIFO_BASE_REGr, &rval_base[mode][idx], 10202 Q_MCQ_FIFO_BASEf, credit / 16 * (idx + 1)); 10203 } 10204 } 10205 PBMP_ALL_ITER(unit, port) { 10206 if (IS_CPU_PORT(unit, port)) { 10207 continue; 10208 } 10209 if (IS_LB_PORT(unit, port)) { 10210 mode = 0; /* MODE_1 */ 10211 } else { 10212 phy_port = si->port_l2p_mapping[port]; 10213 mmu_port = si->port_p2m_mapping[phy_port]; 10214 /* 1, 2, 3, 4, 17, 18, 19, 20, 34, 35, 36, 37, 50, 51, 52, 53 */ 10215 mode_idx = mmu_port - 1 - (mmu_port > 33 ? 1 : 0); 10216 mode_idx = ((mode_idx & 0x30) >> 2) + (mode_idx & 3); 10217 if (mode4_bmp & (1 << mode_idx)) { 10218 mode = 2; /* MODE_4 */ 10219 } else if (mode2_bmp & (1 << mode_idx)) { 10220 mode = 1; /* MODE_2 */ 10221 } else { 10222 mode = 0; /* MODE_1 */ 10223 } 10224 } 10225 for (idx = 0; idx < 5; idx++) { 10226 SOC_IF_ERROR_RETURN 10227 (WRITE_OVQ_MCQ_CREDITSr(unit, port, idx, rval_credit[mode])); 10228 if (idx > 0) { 10229 SOC_IF_ERROR_RETURN 10230 (WRITE_MCQ_FIFO_BASE_REGr(unit, port, idx, 10231 rval_base[mode][idx - 1])); 10232 } 10233 } 10234 } 10235 10236 SOC_PBMP_CLEAR(pbmp0); 10237 SOC_PBMP_CLEAR(pbmp1); 10238 PBMP_ALL_ITER(unit, port) { 10239 mmu_port = si->port_p2m_mapping[si->port_l2p_mapping[port]]; 10240 if (IS_CPU_PORT(unit, port) || 10241 (si->port_group[port] >= 0 && si->port_group[port] <= 1)) { 10242 SOC_PBMP_PORT_ADD(pbmp0, mmu_port); 10243 } else { 10244 SOC_PBMP_PORT_ADD(pbmp1, mmu_port - 33); 10245 } 10246 } 10247 10248 /* Enable pause */ 10249 COMPILER_64_ZERO(r64val0); 10250 soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE0_64r, &r64val0, 10251 PORT_PAUSE_ENABLE_LOf, 10252 SOC_PBMP_WORD_GET(pbmp0, 0)); 10253 soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE0_64r, &r64val0, 10254 PORT_PAUSE_ENABLE_HIf, 10255 SOC_PBMP_WORD_GET(pbmp0, 1)); 10256 SOC_IF_ERROR_RETURN(WRITE_PORT_PAUSE_ENABLE0_64r(unit, r64val0)); 10257 COMPILER_64_ZERO(r64val0); 10258 soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE1_64r, &r64val0, 10259 PORT_PAUSE_ENABLE_LOf, 10260 SOC_PBMP_WORD_GET(pbmp1, 0)); 10261 soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE1_64r, &r64val0, 10262 PORT_PAUSE_ENABLE_HIf, 10263 SOC_PBMP_WORD_GET(pbmp1, 1)); 10264 SOC_IF_ERROR_RETURN(WRITE_PORT_PAUSE_ENABLE1_64r(unit, r64val0)); 10265 10266 /* Enable input port */ 10267 COMPILER_64_ZERO(r64val0); 10268 soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE0_64r, &r64val0, 10269 INPUT_PORT_RX_ENABLE_LOf, 10270 SOC_PBMP_WORD_GET(pbmp0, 0)); 10271 soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE0_64r, &r64val0, 10272 INPUT_PORT_RX_ENABLE_HIf, 10273 SOC_PBMP_WORD_GET(pbmp0, 1)); 10274 SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLE0_64r(unit, r64val0)); 10275 COMPILER_64_ZERO(r64val0); 10276 soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE1_64r, &r64val0, 10277 INPUT_PORT_RX_ENABLE_LOf, 10278 SOC_PBMP_WORD_GET(pbmp1, 0)); 10279 soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE1_64r, &r64val0, 10280 INPUT_PORT_RX_ENABLE_HIf, 10281 SOC_PBMP_WORD_GET(pbmp1, 1)); 10282 SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLE1_64r(unit, r64val0)); 10283 10284 /* Enable output port */ 10285 COMPILER_64_ZERO(r64val0); 10286 soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE0_64r, &r64val0, 10287 OUTPUT_PORT_RX_ENABLE0_LOf, 10288 SOC_PBMP_WORD_GET(pbmp0, 0)); 10289 soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE0_64r, &r64val0, 10290 OUTPUT_PORT_RX_ENABLE0_HIf, 10291 SOC_PBMP_WORD_GET(pbmp0, 1)); 10292 SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLE0_64r(unit, r64val0)); 10293 COMPILER_64_ZERO(r64val0); 10294 soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE1_64r, &r64val0, 10295 OUTPUT_PORT_RX_ENABLE1_LOf, 10296 SOC_PBMP_WORD_GET(pbmp1, 0)); 10297 soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE1_64r, &r64val0, 10298 OUTPUT_PORT_RX_ENABLE1_HIf, 10299 SOC_PBMP_WORD_GET(pbmp1, 1)); 10300 SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLE1_64r(unit, r64val0)); 10301 10302 /* 10303 * default scheduling: 10304 * unicast queue 0 and multicast queue 0 connect to S3.0 10305 * unicast queue 1 and multicast queue 1 connect to S3.1 10306 * unicast queue 2 and multicast queue 2 connect to S3.2 10307 * unicast queue 3 and multicast queue 3 connect to S3.3 10308 * S3.0 - S3.3 and unicast queue 4 - 7 connect to S2.0 10309 * S2.1, S2.2, MC group are not used 10310 */ 10311 rval0 = 0; 10312 soc_reg_field_set(unit, S3_CONFIGr, &rval0, SCHEDULING_SELECTf, 0x55); 10313 10314 rval1 = 0; 10315 soc_reg_field_set(unit, S2_CONFIGr, &rval1, SCHEDULING_SELECTf, 0x15); 10316 10317 /* S3.0 - S3.3 and unicast queues 4 - 7 to S2.0 */ 10318 COMPILER_64_ZERO(r64val0); 10319 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I0f, 0); 10320 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I1f, 1); 10321 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I2f, 2); 10322 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I3f, 3); 10323 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I4f, 8); 10324 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I5f, 9); 10325 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I6f, 10); 10326 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I7f, 11); 10327 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I8f, 10328 0x1f); 10329 10330 COMPILER_64_ZERO(r64val1); 10331 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I0f, 10332 0x1f); 10333 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I1f, 10334 0x1f); 10335 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I2f, 10336 0x1f); 10337 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I3f, 10338 0x1f); 10339 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I4f, 10340 0x1f); 10341 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I5f, 10342 0x1f); 10343 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I6f, 10344 0x1f); 10345 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I7f, 10346 0x1f); 10347 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I7f, 10348 0x1f); 10349 soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I8f, 10350 0x1f); 10351 /* S2.1 and S2.2 are not used */ 10352 r64val2 = r64val1; 10353 10354 PBMP_ALL_ITER(unit, port) { 10355 if (IS_CPU_PORT(unit, port)) { 10356 continue; 10357 } 10358 SOC_IF_ERROR_RETURN(WRITE_S3_CONFIGr(unit, port, rval0)); 10359 SOC_IF_ERROR_RETURN(WRITE_S2_CONFIGr(unit, port, rval1)); 10360 SOC_IF_ERROR_RETURN(WRITE_S2_S3_ROUTINGr(unit, port, 0, r64val0)); 10361 SOC_IF_ERROR_RETURN(WRITE_S2_S3_ROUTINGr(unit, port, 1, r64val1)); 10362 SOC_IF_ERROR_RETURN(WRITE_S2_S3_ROUTINGr(unit, port, 2, r64val2)); 10363 } 10364 10365 return SOC_E_NONE; 10366 } 10367 10368 int 10369 soc_trident_mem_config(int unit) 10370 { 10371 uint16 dev_id; 10372 uint8 rev_id; 10373 int index_max; 10374 int l2_entries; 10375 int l3_entries; 10376 soc_persist_t *sop; 10377 10378 sop = SOC_PERSIST(unit); 10379 10380 soc_cm_get_id(unit, &dev_id, &rev_id); 10381 switch (dev_id) { 10382 case BCM56838_DEVICE_ID: 10383 /* Trunk groups */ 10384 index_max = 127; 10385 sop->memState[TRUNK_GROUPm].index_max = index_max; 10386 sop->memState[TRUNK_BITMAPm].index_max = index_max; 10387 sop->memState[TRUNK_CBL_TABLEm].index_max = index_max; 10388 10389 /* ECMP entry */ 10390 index_max = 1023; 10391 sop->memState[L3_ECMPm].index_max = index_max; 10392 sop->memState[INITIAL_L3_ECMPm].index_max = index_max; 10393 sop->memState[INITIAL_L3_ECMP_Xm].index_max = index_max; 10394 sop->memState[INITIAL_L3_ECMP_Ym].index_max = index_max; 10395 break; 10396 case BCM56831_DEVICE_ID: 10397 /* Trunk groups */ 10398 index_max = 47; 10399 sop->memState[TRUNK_GROUPm].index_max = index_max; 10400 sop->memState[TRUNK_BITMAPm].index_max = index_max; 10401 sop->memState[TRUNK_CBL_TABLEm].index_max = index_max; 10402 10403 /* L2MC */ 10404 sop->memState[L2MCm].index_max = 12287; 10405 break; 10406 case BCM56847_DEVICE_ID: 10407 /* L2 entry : 64K */ 10408 l2_entries = 65536; 10409 sop->memState[L2Xm].index_max = l2_entries - 1; 10410 sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1; 10411 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 8 - 1; 10412 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 8 - 1; 10413 10414 /* L2MC: 4K L2MC + 2K IPMC */ 10415 sop->memState[L2MCm].index_max = 6143; 10416 10417 /* L3 entry : 8K */ 10418 l3_entries = 8192; 10419 sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1; 10420 sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1; 10421 sop->memState[L3_ENTRY_IPV4_UNICAST_Xm].index_max = l3_entries - 1; 10422 sop->memState[L3_ENTRY_IPV4_UNICAST_Ym].index_max = l3_entries - 1; 10423 sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = 10424 l3_entries / 2 - 1; 10425 sop->memState[L3_ENTRY_IPV4_MULTICAST_Xm].index_max = 10426 l3_entries / 2 - 1; 10427 sop->memState[L3_ENTRY_IPV4_MULTICAST_Ym].index_max = 10428 l3_entries / 2 - 1; 10429 sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = 10430 l3_entries/ 2 - 1; 10431 sop->memState[L3_ENTRY_IPV6_UNICAST_Xm].index_max = 10432 l3_entries/ 2 - 1; 10433 sop->memState[L3_ENTRY_IPV6_UNICAST_Ym].index_max = 10434 l3_entries/ 2 - 1; 10435 sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = 10436 l3_entries / 4 - 1; 10437 sop->memState[L3_ENTRY_IPV6_MULTICAST_Xm].index_max = 10438 l3_entries / 4 - 1; 10439 sop->memState[L3_ENTRY_IPV6_MULTICAST_Ym].index_max = 10440 l3_entries / 4 - 1; 10441 sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 16 - 1; 10442 sop->memState[L3_ENTRY_HIT_ONLY_Xm].index_max = l3_entries / 16 - 1; 10443 sop->memState[L3_ENTRY_HIT_ONLY_Ym].index_max = l3_entries / 16 - 1; 10444 10445 /* L3 IPMC groups: 2K */ 10446 sop->memState[L3_IPMCm].index_max = 2047; 10447 sop->memState[L3_IPMC_1m].index_max = 2047; 10448 sop->memState[L3_IPMC_REMAPm].index_max = 2047; 10449 sop->memState[EGR_IPMCm].index_max = 2047; 10450 sop->memState[MMU_REPL_GROUPm].index_max = 2047; 10451 10452 /* L3 Next hop: 4K */ 10453 sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 4095; 10454 sop->memState[ING_L3_NEXT_HOPm].index_max = 4095; 10455 sop->memState[EGR_L3_NEXT_HOPm].index_max = 4095; 10456 sop->memState[INITIAL_PROT_NHI_TABLEm].index_max = 4095; 10457 10458 /* IPv4 LPM : 4K */ 10459 sop->memState[L3_DEFIPm].index_max = 8191; 10460 sop->memState[L3_DEFIP_Xm].index_max = 8191; 10461 sop->memState[L3_DEFIP_Ym].index_max = 8191; 10462 sop->memState[L3_DEFIP_ONLYm].index_max = 8191; 10463 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 8191; 10464 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 8191; 10465 sop->memState[L3_DEFIP_HIT_ONLY_Xm].index_max = 8191; 10466 sop->memState[L3_DEFIP_HIT_ONLY_Ym].index_max = 8191; 10467 10468 /* MPLS Labels : 4K */ 10469 sop->memState[MPLS_ENTRYm].index_max = 4095; 10470 sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 4095; 10471 10472 /* Virtual Ports : 4K */ 10473 sop->memState[SOURCE_VPm].index_max = 4095; 10474 sop->memState[ING_DVP_TABLEm].index_max = 4095; 10475 sop->memState[ING_DVP_2_TABLEm].index_max = 4095; 10476 sop->memState[EGR_DVP_ATTRIBUTEm].index_max = 4095; 10477 sop->memState[EGR_SERVICE_COUNTER_TABLEm].index_max = 4095; 10478 sop->memState[EGR_SERVICE_COUNTER_TABLE_Xm].index_max = 4095; 10479 sop->memState[EGR_SERVICE_COUNTER_TABLE_Ym].index_max = 4095; 10480 sop->memState[EGR_VINTF_COUNTER_TABLEm].index_max = 4095; 10481 sop->memState[EGR_VINTF_COUNTER_TABLE_Xm].index_max = 4095; 10482 sop->memState[EGR_VINTF_COUNTER_TABLE_Ym].index_max = 4095; 10483 10484 /* MSTP : 255 */ 10485 sop->memState[EGR_VLAN_STGm].index_max = 255; 10486 sop->memState[STG_TABm].index_max = 255; 10487 break; 10488 case BCM56835_DEVICE_ID: 10489 /* L2 entry */ 10490 l2_entries = 65536; 10491 sop->memState[L2Xm].index_max = l2_entries - 1; 10492 sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1; 10493 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 8 - 1; 10494 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 8 - 1; 10495 10496 /* L2MC */ 10497 sop->memState[L2MCm].index_max = 4351; 10498 10499 /* L3 IPMC groups */ 10500 sop->memState[L3_IPMCm].index_max = 255; 10501 sop->memState[L3_IPMC_1m].index_max = 255; 10502 sop->memState[L3_IPMC_REMAPm].index_max = 255; 10503 sop->memState[EGR_IPMCm].index_max = 255; 10504 sop->memState[MMU_REPL_GROUPm].index_max = 255; 10505 10506 /* L3 Next hop */ 10507 sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 1023; 10508 sop->memState[ING_L3_NEXT_HOPm].index_max = 1023; 10509 sop->memState[EGR_L3_NEXT_HOPm].index_max = 1023; 10510 sop->memState[INITIAL_PROT_NHI_TABLEm].index_max = 1023; 10511 10512 /* L3 LPM */ 10513 sop->memState[L3_DEFIPm].index_max = 511; 10514 sop->memState[L3_DEFIP_ONLYm].index_max = 511; 10515 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 511; 10516 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 511; 10517 10518 /* MSTP */ 10519 sop->memState[EGR_VLAN_STGm].index_max = 255; 10520 sop->memState[STG_TABm].index_max = 255; 10521 10522 /* Trunk */ 10523 index_max = 511; 10524 sop->memState[TRUNK_GROUPm].index_max = index_max; 10525 sop->memState[TRUNK_BITMAPm].index_max = index_max; 10526 sop->memState[TRUNK_CBL_TABLEm].index_max = index_max; 10527 break; 10528 case BCM56742_DEVICE_ID: 10529 /* L2 entry : 64K */ 10530 l2_entries = 65536; 10531 sop->memState[L2Xm].index_max = l2_entries - 1; 10532 sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1; 10533 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 8 - 1; 10534 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 8 - 1; 10535 break; 10536 default: 10537 break; 10538 } 10539 10540 return SOC_E_NONE; 10541 } 10542 10543 STATIC int 10544 _soc_trident_age_timer_get(int unit, int *age_seconds, int *enabled) 10545 { 10546 uint32 rval; 10547 10548 SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval)); 10549 *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf); 10550 *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf); 10551 10552 return SOC_E_NONE; 10553 } 10554 10555 STATIC int 10556 _soc_trident_age_timer_max_get(int unit, int *max_seconds) 10557 { 10558 *max_seconds = 10559 soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf); 10560 10561 return SOC_E_NONE; 10562 } 10563 10564 STATIC int 10565 _soc_trident_age_timer_set(int unit, int age_seconds, int enable) 10566 { 10567 uint32 rval; 10568 10569 rval = 0; 10570 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable); 10571 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds); 10572 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval)); 10573 10574 return SOC_E_NONE; 10575 } 10576 10577 static const soc_reg_t thermal_reg[] = { 10578 CMIC_THERMAL_MON_RESULT_0r, CMIC_THERMAL_MON_RESULT_1r, 10579 CMIC_THERMAL_MON_RESULT_2r, CMIC_THERMAL_MON_RESULT_3r, 10580 CMIC_THERMAL_MON_RESULT_4r, CMIC_THERMAL_MON_RESULT_5r, 10581 CMIC_THERMAL_MON_RESULT_6r, CMIC_THERMAL_MON_RESULT_7r 10582 }; 10583 10584 int 10585 soc_trident_temperature_monitor_get(int unit, 10586 int temperature_max, 10587 soc_switch_temperature_monitor_t *temperature_array, 10588 int *temperature_count) 10589 10590 { 10591 uint32 rval, addr; 10592 soc_reg_t reg; 10593 int index; 10594 int fval, cur, peak; 10595 uint16 dev_id, drv_dev_id; 10596 uint8 rev_id, drv_rev_id; 10597 int num_entries_out; 10598 10599 if (COUNTOF(thermal_reg) > temperature_max) { 10600 num_entries_out = temperature_max; 10601 } else { 10602 num_entries_out = COUNTOF(thermal_reg); 10603 } 10604 soc_cm_get_id(unit, &dev_id, &rev_id); 10605 soc_cm_get_id_driver(dev_id, rev_id, &drv_dev_id, &drv_rev_id); 10606 10607 if (!(drv_rev_id == BCM56840_A0_REV_ID && rev_id < BCM56840_B0_REV_ID)) { 10608 reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r; 10609 READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval); 10610 soc_reg_field_set(unit, reg, &rval, PVTMON_SELECTf, 0); 10611 soc_reg_field_set(unit, reg, &rval, BG_ADJf, 3); 10612 soc_reg_field_set(unit, reg, &rval, VTMON_7_OR_PVTMON_SELf, 1); 10613 WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval); 10614 } 10615 10616 sal_usleep(1000); 10617 10618 READ_CMIC_THERMAL_MON_CTRLr(unit, &rval); 10619 soc_reg_field_set(unit, CMIC_THERMAL_MON_CTRLr, &rval, BG_ADJf, 1); 10620 soc_reg_field_set(unit, CMIC_THERMAL_MON_CTRLr, &rval, VTMON_RSTBf, 1); 10621 WRITE_CMIC_THERMAL_MON_CTRLr(unit, rval); 10622 10623 sal_usleep(1000); 10624 10625 for (index = 0; index < num_entries_out; index++) { 10626 reg = thermal_reg[index]; 10627 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10628 soc_pci_getreg(unit, addr, &rval); 10629 fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10630 cur = (4100000 - (5424 * fval)) / 1000; 10631 fval = soc_reg_field_get(unit, reg, rval, PEAK_TEMP_DATAf); 10632 peak = (4100000 - (5424 * fval)) / 1000; 10633 (temperature_array + index)->curr = cur; 10634 (temperature_array + index)->peak = peak; 10635 } 10636 10637 READ_CMIC_SOFT_RESET_REGr(unit, &rval); 10638 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, 10639 CMIC_TEMP_MON_PEAK_RST_Lf, 0); 10640 WRITE_CMIC_SOFT_RESET_REGr(unit, rval); 10641 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, 10642 CMIC_TEMP_MON_PEAK_RST_Lf, 1); 10643 WRITE_CMIC_SOFT_RESET_REGr(unit, rval); 10644 10645 *temperature_count=num_entries_out; 10646 return SOC_E_NONE; 10647 } 10648 int 10649 soc_trident_show_material_process(int unit) 10650 { 10651 soc_reg_t reg; 10652 uint32 addr, rval, fval, nmos_4, nmos_7_0, nmos_7_1, n_avg, p_avg; 10653 uint16 dev_id, drv_dev_id; 10654 uint8 rev_id, drv_rev_id; 10655 10656 soc_cm_get_id(unit, &dev_id, &rev_id); 10657 soc_cm_get_id_driver(dev_id, rev_id, &drv_dev_id, &drv_rev_id); 10658 10659 if (drv_rev_id == BCM56840_A0_REV_ID && rev_id < BCM56840_B0_REV_ID) { 10660 return SOC_E_UNAVAIL; 10661 } 10662 10663 n_avg = 0; 10664 p_avg = 0; 10665 10666 /* Read NMOS information */ 10667 reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r; 10668 READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval); 10669 soc_reg_field_set(unit, reg, &rval, PVTMON_SELECTf, 1); 10670 soc_reg_field_set(unit, reg, &rval, PROG_RESISTORf, 3); 10671 soc_reg_field_set(unit, reg, &rval, MEASUREMENT_CALLIBRATIONf, 5); 10672 soc_reg_field_set(unit, reg, &rval, BG_ADJf, 3); 10673 soc_reg_field_set(unit, reg, &rval, VTMON_7_OR_PVTMON_SELf, 1); 10674 WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval); 10675 10676 sal_usleep(1000); 10677 10678 reg = thermal_reg[4]; 10679 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10680 soc_pci_getreg(unit, addr, &rval); 10681 nmos_4 = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10682 n_avg += nmos_4; 10683 10684 reg = thermal_reg[7]; 10685 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10686 soc_pci_getreg(unit, addr, &rval); 10687 nmos_7_1 = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10688 n_avg += nmos_7_1; 10689 10690 READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval); 10691 soc_reg_field_set(unit, CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r, 10692 &rval, VTMON_7_OR_PVTMON_SELf, 0); 10693 WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval); 10694 10695 reg = thermal_reg[7]; 10696 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10697 soc_pci_getreg(unit, addr, &rval); 10698 nmos_7_0 = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10699 n_avg += nmos_7_0; 10700 10701 /* Read PMOS information */ 10702 reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r; 10703 READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval); 10704 soc_reg_field_set(unit, reg, &rval, MEASUREMENT_CALLIBRATIONf, 7); 10705 WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval); 10706 10707 sal_usleep(1000); 10708 10709 reg = thermal_reg[4]; 10710 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10711 soc_pci_getreg(unit, addr, &rval); 10712 fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10713 LOG_CLI((BSL_META_U(unit, 10714 "material process location 4 : NMOS = %3d PMOS = %3d\n"), 10715 nmos_4, fval)); 10716 p_avg += fval; 10717 10718 reg = thermal_reg[7]; 10719 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10720 soc_pci_getreg(unit, addr, &rval); 10721 fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10722 LOG_CLI((BSL_META_U(unit, 10723 "material process location 7-1: NMOS = %3d PMOS = %3d\n"), 10724 nmos_7_1, fval)); 10725 p_avg += fval; 10726 10727 READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval); 10728 soc_reg_field_set(unit, CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r, &rval, 10729 VTMON_7_OR_PVTMON_SELf, 0); 10730 WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval); 10731 10732 reg = thermal_reg[7]; 10733 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 10734 soc_pci_getreg(unit, addr, &rval); 10735 fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 10736 LOG_CLI((BSL_META_U(unit, 10737 "material process location 7-0: NMOS = %3d PMOS = %3d\n"), 10738 nmos_7_0, fval)); 10739 LOG_CLI((BSL_META_U(unit, 10740 "average: NMOS = %3d PMOS = %3d\n"), 10741 n_avg / 3, p_avg / 3)); 10742 10743 reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r; 10744 READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval); 10745 soc_reg_field_set(unit, reg, &rval, PVTMON_SELECTf, 0); 10746 soc_reg_field_set(unit, reg, &rval, BG_ADJf, 3); 10747 soc_reg_field_set(unit, reg, &rval, VTMON_7_OR_PVTMON_SELf, 1); 10748 WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval); 10749 10750 sal_usleep(1000); 10751 10752 READ_CMIC_SOFT_RESET_REGr(unit, &rval); 10753 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, 10754 CMIC_TEMP_MON_PEAK_RST_Lf, 0); 10755 WRITE_CMIC_SOFT_RESET_REGr(unit, rval); 10756 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, 10757 CMIC_TEMP_MON_PEAK_RST_Lf, 1); 10758 WRITE_CMIC_SOFT_RESET_REGr(unit, rval); 10759 10760 return SOC_E_NONE; 10761 } 10762 10763 int 10764 soc_trident_show_ring_osc(int unit) 10765 { 10766 soc_info_t *si; 10767 soc_reg_t reg; 10768 static const soc_field_t fields[] = { 10769 OSC_0_SELf, OSC_1_SELf, IROSC_SELf, IROSC_SELf 10770 }; 10771 static const int counts[] = { 4, 4, 2, 2 }; 10772 static char *names[] = { 10773 "IO ring 0", "IO ring 1", "Core ring 0", "Core ring 1" 10774 }; 10775 uint32 rval; 10776 int ring, set, core_clk, div, quo, rem, frac; 10777 10778 si = &SOC_INFO(unit); 10779 core_clk = (si->bandwidth == 640000 ? 495 : 415) * 1024; 10780 10781 reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r; 10782 if (!soc_reg_field_valid(unit, reg, OSC_ENABLEf)) { 10783 return SOC_E_UNAVAIL; 10784 } 10785 10786 /* 10787 * IO ring osc 0 has 4 sets of value 10788 * IO ring osc 1 has 4 sets of value 10789 * Core ring osc 0 has 2 sets of value 10790 * Core ring osc 1 has 2 sets of value 10791 */ 10792 for (ring = 0; ring < 4; ring++) { 10793 for (set = 0; set < counts[ring]; set++) { 10794 rval = 0; 10795 /* 10796 * set OSC_CNT_RSTBf to 0 to do softreset 10797 * set OSC_CNT_START to 0 to hold the counter until it selects 10798 * the input signal 10799 */ 10800 /* coverity[result_independent_of_operands] */ 10801 SOC_IF_ERROR_RETURN 10802 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval)); 10803 soc_reg_field_set(unit, reg, &rval, OSC_ENABLEf, 1); 10804 soc_reg_field_set(unit, reg, &rval, IROSC_ENf, 1); 10805 soc_reg_field_set(unit, reg, &rval, fields[ring], set); 10806 soc_reg_field_set(unit, reg, &rval, OSC_SELf, ring); 10807 /* coverity[result_independent_of_operands] */ 10808 SOC_IF_ERROR_RETURN 10809 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval)); 10810 soc_reg_field_set(unit, reg, &rval, OSC_CNT_RSTBf, 1); 10811 /* coverity[result_independent_of_operands] */ 10812 SOC_IF_ERROR_RETURN 10813 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval)); 10814 soc_reg_field_set(unit, reg, &rval, OSC_CNT_STARTf, 1); 10815 /* coverity[result_independent_of_operands] */ 10816 SOC_IF_ERROR_RETURN 10817 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval)); 10818 10819 sal_usleep(1000); 10820 10821 /* 10822 * ring_osc_freq = core_clock_freq * 1024 / div 10823 * core ring 0 set 1 or core ring 1 set 1: 10824 * div = CMIC_IRQ_STAT_1[15:0] + 65536 10825 * otherwise 10826 * div = CMIC_IRQ_STAT_1[15:0] 10827 */ 10828 /* coverity[result_independent_of_operands] */ 10829 SOC_IF_ERROR_RETURN(READ_CMIC_IRQ_STAT_1r(unit, &rval)); 10830 div = rval & 0xffff; 10831 if (ring >= 2 && set == 1) { /* core ring 0/1 set 1 */ 10832 div += 65536; 10833 } 10834 quo = core_clk / div; 10835 rem = core_clk - quo * div; 10836 frac = (rem * 10000) / div; 10837 LOG_CLI((BSL_META_U(unit, 10838 "%s set %d: %d.%04d Mhz\n"), 10839 names[ring], set, quo, frac)); 10840 } 10841 } 10842 10843 return SOC_E_NONE; 10844 } 10845 10846 int 10847 soc_trident_cmic_rate_param_get(int unit, int *dividend, int *divisor) 10848 { 10849 uint32 rval; 10850 10851 /* coverity[result_independent_of_operands] */ 10852 SOC_IF_ERROR_RETURN(READ_CMIC_RATE_ADJUSTr(unit, &rval)); 10853 *dividend = soc_reg_field_get(unit, CMIC_RATE_ADJUSTr, rval, DIVIDENDf); 10854 *divisor = soc_reg_field_get(unit, CMIC_RATE_ADJUSTr, rval, DIVISORf); 10855 10856 return SOC_E_NONE; 10857 } 10858 10859 10860 int 10861 soc_trident_cmic_rate_param_set(int unit, int dividend, int divisor) 10862 { 10863 uint32 rval; 10864 10865 rval = 0; 10866 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend); 10867 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor); 10868 /* coverity[result_independent_of_operands] */ 10869 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval)); 10870 10871 return SOC_E_NONE; 10872 } 10873 10874 STATIC int 10875 _soc_trident_parity_block_port(int unit, soc_block_t block, soc_port_t *port) 10876 { 10877 *port = SOC_BLOCK_PORT(unit, block); 10878 if ((*port != REG_PORT_ANY) && !SOC_PORT_VALID(unit, *port)) { 10879 return SOC_E_PORT; 10880 } 10881 10882 return SOC_E_NONE; 10883 } 10884 10885 #if defined(SER_TR_TEST_SUPPORT) 10886 STATIC soc_acc_type_t 10887 _soc_trident_pipe_to_acc_type(int pipe) 10888 { 10889 soc_acc_type_t rv; 10890 switch (pipe) { 10891 case -1: 10892 case 0: 10893 rv = _SOC_ACC_TYPE_PIPE_X; 10894 break; 10895 case 1: 10896 rv = _SOC_ACC_TYPE_PIPE_Y; 10897 break; 10898 default: 10899 rv =_SOC_ACC_TYPE_PIPE_ALL; 10900 }; 10901 return rv; 10902 } 10903 typedef struct skipped_mem_s { 10904 soc_mem_t mem; 10905 soc_acc_type_t acc_type; 10906 } skipped_mem_t; 10907 10908 const skipped_mem_t ser_test_skipped_mems[] = { 10909 { EGR_VLANm, _SOC_ACC_TYPE_PIPE_X}, 10910 { EGR_VLANm, _SOC_ACC_TYPE_PIPE_Y}, 10911 { EGR_VLANm, _SOC_ACC_TYPE_PIPE_ALL}, 10912 { L2MCm, _SOC_ACC_TYPE_PIPE_Y}, 10913 { L3_IPMCm, _SOC_ACC_TYPE_PIPE_Y}, 10914 { EGR_MASKm, _SOC_ACC_TYPE_PIPE_Y}, 10915 { MMU_AGING_CTRm, _SOC_ACC_TYPE_PIPE_ANY}, 10916 { MMU_AGING_EXPm, _SOC_ACC_TYPE_PIPE_ANY}, 10917 { MMU_CTR_UC_DROP_MEMm, _SOC_ACC_TYPE_PIPE_ANY}, 10918 { MMU_CTR_MC_DROP_MEMm, _SOC_ACC_TYPE_PIPE_ANY}, 10919 { MMU_CTR_COLOR_DROP_MEMm, _SOC_ACC_TYPE_PIPE_ANY}, 10920 { L2_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_Y}, 10921 {INVALIDm} 10922 }; 10923 10924 /* 10925 * Function: 10926 * soc_td_ser_error_injection_support 10927 * Purpose: 10928 * Checks if a memory is supported by error injection interface 10929 * 10930 * Parameters: 10931 * unit - (IN) Device Number 10932 * memory - (IN) Test data required for SER test 10933 * pipe - (IN) How many indices to test for each memory 10934 * 10935 * Returns: 10936 * SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported 10937 */ 10938 soc_error_t 10939 soc_td_ser_error_injection_support (int unit, soc_mem_t mem, int pipe) 10940 { 10941 int i; 10942 int rv = SOC_E_UNAVAIL; 10943 _soc_trident_parity_info_t *info = NULL; 10944 int mem_acc_type; 10945 int group, table; 10946 soc_port_t block_port; 10947 soc_block_t blk; 10948 soc_acc_type_t acc_type = _soc_trident_pipe_to_acc_type(pipe); 10949 _soc_ser_parity_info_t *tcams = _soc_td_ser_parity_info[unit]; 10950 const _soc_trident_parity_route_block_t *route_block = _soc_trident_parity_route_blocks; 10951 10952 _soc_trident_mem_rename(&mem); 10953 /* Check if memory is listed in skipped mems structure */ 10954 for (i = 0; ser_test_skipped_mems[i].mem != INVALIDm; i++) { 10955 if ((ser_test_skipped_mems[i].mem == mem) && 10956 (ser_test_skipped_mems[i].acc_type == acc_type)) { 10957 return rv; 10958 } 10959 } 10960 10961 for (group = 0; route_block[group].cmic_bit; group++) { 10962 info = route_block[group].info; 10963 SOC_BLOCK_ITER(unit, blk,route_block[group].blocktype) { 10964 if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) { 10965 continue; 10966 } 10967 mem_acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe); 10968 for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) { 10969 if (info[table].mem != mem) { 10970 continue; 10971 } 10972 if (acc_type != mem_acc_type) { 10973 continue; 10974 } 10975 return SOC_E_NONE; 10976 } 10977 } 10978 } 10979 10980 /*Search TCAMs*/ 10981 for (i = 0; tcams[i].mem != INVALIDm; i++) { 10982 if (tcams[i].mem == mem) { 10983 return SOC_E_NONE; 10984 } 10985 } 10986 10987 return rv; 10988 } 10989 10990 /*This is the maximum number of tcams that have Hardware SER protection*/ 10991 #define MAX_HW_TCAMS 16 10992 10993 STATIC int 10994 _soc_td_mem_nack_error_test(int unit, _soc_ser_test_t test_type) 10995 { 10996 int group, table, i; 10997 _soc_trident_parity_info_t *info; 10998 soc_mem_t memTable; 10999 soc_field_t test_field = INVALIDf; 11000 soc_port_t block_port; 11001 soc_block_t blk; 11002 soc_acc_type_t acc_type; 11003 soc_reg_t enable_reg; 11004 soc_field_t enable_field; 11005 int num_par_mems = 0; 11006 int rv = SOC_E_NONE; 11007 int skip_mem; 11008 int skip_count = 0; 11009 int tests_passed = 0; 11010 int tests_failed = 0; 11011 const _soc_trident_parity_route_block_t *route_block = _soc_trident_parity_route_blocks; 11012 /*H/W memory Test*/ 11013 for (group = 0; route_block[group].cmic_bit; group++) { 11014 info = route_block[group].info; 11015 11016 SOC_BLOCK_ITER (unit, blk,route_block[group].blocktype) { 11017 if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) { 11018 continue; 11019 } 11020 acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe); 11021 for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) { 11022 memTable = info[table].mem; 11023 skip_mem = FALSE; 11024 if (memTable == INVALIDm) { 11025 continue; 11026 } 11027 switch (info[table].type) { 11028 case _SOC_PARITY_TYPE_PARITY: 11029 test_field = EVEN_PARITYf; 11030 if (!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) { 11031 test_field = PARITYf; 11032 if (!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) { 11033 test_field = EVEN_PARITY_0f; 11034 } 11035 } 11036 break; 11037 case _SOC_PARITY_TYPE_SER: 11038 case _SOC_PARITY_TYPE_COUNTER: 11039 case _SOC_PARITY_TYPE_ECC: 11040 break; 11041 default: 11042 /* No field to check. */ 11043 continue; 11044 } 11045 num_par_mems++; 11046 if (!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) { 11047 test_field = INVALIDf; 11048 } 11049 /* 11050 * NOTE: this loop and the skipping of memories it performs SHOULD be temporary 11051 * it exists for now until the memories in ser_test_skipped_mems are investigated. 11052 */ 11053 for (i = 0; ser_test_skipped_mems[i].mem != INVALIDm; i++) { 11054 if (((ser_test_skipped_mems[i].mem == memTable) && 11055 (ser_test_skipped_mems[i].acc_type == acc_type))) { 11056 LOG_VERBOSE(BSL_LS_SOC_SER, 11057 (BSL_META_U(unit, 11058 "SER test disabled for memory %s, skipping.\n"), 11059 SOC_MEM_NAME(unit,memTable))); 11060 skip_mem = TRUE; 11061 skip_count++; 11062 break; 11063 } 11064 } 11065 if (!skip_mem){ 11066 if (info[table].enable_field == INVALIDf) { 11067 enable_field = info[table].group_reg_enable_field; 11068 enable_reg = route_block[group].enable_reg; 11069 } else { 11070 enable_field = info[table].enable_field; 11071 enable_reg = info[table].enable_reg; 11072 } 11073 soc_trident_pipe_select(unit, TRUE, 11074 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0)); 11075 soc_trident_pipe_select(unit, FALSE, 11076 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0)); 11077 rv = ser_test_mem_pipe(unit, enable_reg, -1, enable_field, 11078 info[table].mem, test_field, 11079 test_type, blk, block_port, acc_type, 11080 &tests_failed); 11081 soc_trident_pipe_select(unit, TRUE, 0); 11082 soc_trident_pipe_select(unit, FALSE, 0); 11083 if (rv == SOC_E_NONE) { 11084 tests_passed++; 11085 } 11086 } 11087 } 11088 } 11089 } 11090 LOG_CLI((BSL_META_U(unit, 11091 "\nStandard memories tested on unit %d: %d\n"), 11092 unit, num_par_mems)); 11093 LOG_CLI((BSL_META_U(unit, 11094 "Tests passed: \t%d\n"), tests_passed)); 11095 LOG_CLI((BSL_META_U(unit, 11096 "Tests skipped: \t%d (Use verbose argument to see " 11097 "skipped memories.)\n"), skip_count)); 11098 LOG_CLI((BSL_META_U(unit, 11099 "Tests failed: \t%d\n"), tests_failed)); 11100 11101 if (tests_failed != 0) { 11102 LOG_CLI((BSL_META_U(unit, 11103 "TR 144 test failed.\n"))); 11104 } 11105 11106 return rv; 11107 } 11108 11109 11110 /* 11111 * Function: 11112 * soc_td_ser_mem_test 11113 * Purpose: 11114 * Performs a SER test on a single td memory 11115 * Parameters: 11116 * unit - (IN) Device Number 11117 * memscan - (IN) The memory to test 11118 * test_type - (IN) How many indices in the memory to test 11119 * cmd - (IN) A test flag that if non-0, causes a test to be printed to the 11120 * commandline capable of testing the passed memory. 11121 */ 11122 soc_error_t 11123 soc_td_ser_mem_test(int unit, soc_mem_t mem, _soc_ser_test_t test_type, int cmd) 11124 { 11125 int i, rv = SOC_E_NONE; 11126 int test_errors = 0; 11127 _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit]; 11128 int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1; 11129 int group, table; 11130 _soc_trident_parity_info_t *info; 11131 soc_mem_t memTable; 11132 soc_field_t test_field = INVALIDf; 11133 soc_port_t block_port; 11134 soc_block_t blk; 11135 const _soc_trident_parity_route_block_t *route_block = _soc_trident_parity_route_blocks; 11136 int found_mem = FALSE; 11137 uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_REG_FIELD_WORDS]; 11138 soc_acc_type_t acc_type; 11139 ser_test_data_t test_data; 11140 num_tcams = ((num_tcams > MAX_HW_TCAMS) ? MAX_HW_TCAMS : num_tcams); 11141 /*TCAM_test*/ 11142 _soc_trident_mem_rename(&mem); 11143 for(i = 0; i < num_tcams; i++) { 11144 if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) == 11145 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) { 11146 acc_type = _SOC_ACC_TYPE_PIPE_Y; 11147 } else if ((tcam_info[i].ser_flags & _SOC_SER_FLAG_MULTI_PIPE) == 11148 _SOC_SER_FLAG_MULTI_PIPE) { 11149 acc_type = _SOC_ACC_TYPE_PIPE_X; 11150 } else { 11151 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 11152 } 11153 if(tcam_info[i].mem == mem) { 11154 /*If the user has passed in the cmd flag high, just print a 11155 * command-line method to test this memory instead of testing it. 11156 */ 11157 found_mem = TRUE; 11158 if (mem == L3_DEFIPm) { 11159 test_field = VALID0f; 11160 } else if (mem == L3_DEFIP_PAIR_128m) { 11161 test_field = VALID0_LWRf; 11162 } else { 11163 test_field = VALIDf; 11164 } 11165 soc_ser_create_test_data(unit, tmp_entry, field_data, 11166 CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, i, 11167 INVALIDf, tcam_info[i].mem, test_field, 11168 MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0, 11169 &test_data); 11170 if (cmd) { 11171 ser_test_cmd_generate(unit, &test_data); 11172 } else { 11173 soc_trident_pipe_select(unit, TRUE, 11174 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 11175 1 : 0)); 11176 soc_trident_pipe_select(unit, FALSE, 11177 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 11178 1 : 0)); 11179 rv = ser_test_mem(unit, 0, &test_data, test_type, &test_errors); 11180 soc_trident_pipe_select(unit, TRUE, 0); 11181 soc_trident_pipe_select(unit, FALSE, 0); 11182 if (rv != SOC_E_NONE) { 11183 LOG_CLI((BSL_META_U(unit, 11184 "Error during TCAM test. Aborting.\n"))); 11185 return rv; 11186 } 11187 } 11188 } 11189 } 11190 /*H/W memory Test*/ 11191 for (group = 0; route_block[group].cmic_bit; group++) { 11192 info = route_block[group].info; 11193 11194 SOC_BLOCK_ITER(unit, blk,route_block[group].blocktype) { 11195 if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) { 11196 continue; 11197 } 11198 acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe); 11199 for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) { 11200 memTable = info[table].mem; 11201 if (memTable == INVALIDm) { 11202 continue; 11203 } 11204 /*Select the parity field to be toggled to inject the error.*/ 11205 switch (info[table].type) { 11206 case _SOC_PARITY_TYPE_PARITY: 11207 test_field = EVEN_PARITYf; 11208 if(!SOC_MEM_FIELD_VALID(unit,info[table].mem, 11209 test_field)) { 11210 test_field = PARITYf; 11211 if(!SOC_MEM_FIELD_VALID(unit,info[table].mem, 11212 test_field)) { 11213 test_field = EVEN_PARITY_0f; 11214 } 11215 } 11216 break; 11217 case _SOC_PARITY_TYPE_SER: 11218 case _SOC_PARITY_TYPE_COUNTER: 11219 case _SOC_PARITY_TYPE_ECC: 11220 break; 11221 default: 11222 /* No field to check. */ 11223 continue; 11224 } 11225 if(!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) { 11226 test_field = INVALIDf; 11227 } 11228 if (memTable == mem) { 11229 /*If the user has passed in the cmd flag high, just print a 11230 * command-line method to test this memory instead of 11231 * testing it. 11232 */ 11233 found_mem = TRUE; 11234 soc_ser_create_test_data(unit, tmp_entry, field_data, 11235 info[table].enable_reg, -1, 11236 info[table].enable_field, 11237 info[table].mem, test_field, blk, 11238 block_port, acc_type, 0, &test_data); 11239 if (cmd) { 11240 ser_test_cmd_generate(unit, &test_data); 11241 } else { 11242 soc_trident_pipe_select(unit, TRUE, 11243 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 11244 1 : 0)); 11245 soc_trident_pipe_select(unit, FALSE, 11246 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 11247 1 : 0)); 11248 rv = ser_test_mem(unit, 0, &test_data, test_type, 11249 &test_errors); 11250 soc_trident_pipe_select(unit, TRUE, 0); 11251 soc_trident_pipe_select(unit, FALSE, 0); 11252 if (rv != SOC_E_NONE) { 11253 LOG_CLI((BSL_META_U(unit, 11254 "Error during H/W test. Aborting.\n"))); 11255 return rv; 11256 } 11257 } 11258 } 11259 } 11260 } 11261 } 11262 if (found_mem && !cmd) { 11263 if (test_errors == 0) { 11264 LOG_CLI((BSL_META_U(unit, 11265 "SER Test passed on unit: %d for memory %s\n "), 11266 unit, SOC_MEM_NAME(unit,mem))); 11267 } 11268 else { 11269 LOG_CLI((BSL_META_U(unit, 11270 "SER Test failed on unit: %d for memory %s\n"), 11271 unit, SOC_MEM_NAME(unit,mem))); 11272 rv = SOC_E_INTERNAL; 11273 } 11274 } else if (!cmd){ 11275 LOG_CLI((BSL_META_U(unit, 11276 "Memory %s not found.\n"), SOC_MEM_NAME(unit, mem))); 11277 } 11278 return rv; 11279 } 11280 11281 11282 /* 11283 * Function: 11284 * soc_td_ser_test 11285 * Purpose: 11286 * Parameters: 11287 * unit - (IN) Device Number 11288 * test_type - (IN) Determines how comprehensive of a test to run 11289 */ 11290 soc_error_t 11291 soc_td_ser_test(int unit, _soc_ser_test_t test_type) 11292 { 11293 soc_error_t rv = SOC_E_NONE; 11294 int tcam_failed = 0, tcam_skipped = 0, i; 11295 _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit]; 11296 int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1; 11297 soc_acc_type_t acc_type; 11298 soc_field_t test_field = INVALIDf; 11299 #ifdef INCLUDE_MEM_SCAN 11300 int memscan_running, rate; 11301 sal_usecs_t interval; 11302 11303 memscan_running = soc_mem_scan_running(unit, &rate, &interval); 11304 if (memscan_running) { 11305 rv = soc_mem_scan_stop(unit); 11306 if (rv != SOC_E_NONE) { 11307 LOG_CLI((BSL_META_U(unit, 11308 "Error disabling memscan. Aborting SER test.\n"))); 11309 return rv; 11310 } 11311 } 11312 #endif 11313 soc_td_ser_test_overlay(unit, test_type); 11314 _soc_td_mem_nack_error_test(unit, test_type); 11315 /*This is a NACK test for TCAM memories*/ 11316 for(i = 0; i < num_tcams; i++) { 11317 if (i >= MAX_HW_TCAMS) { 11318 tcam_skipped++; 11319 LOG_VERBOSE(BSL_LS_SOC_SER, 11320 (BSL_META_U(unit, 11321 "SER test disabled for TCAM memory %s, skipping.\n"), 11322 SOC_MEM_NAME(unit, tcam_info[i].mem))); 11323 continue; 11324 } 11325 if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) == 11326 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) { 11327 acc_type = _SOC_ACC_TYPE_PIPE_Y; 11328 } else { 11329 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 11330 } 11331 11332 if (tcam_info[i].mem == L3_DEFIPm) { 11333 test_field = VALID0f; 11334 } else if (tcam_info[i].mem == L3_DEFIP_128m) { 11335 test_field = VALID_0f; 11336 } else { 11337 test_field = VALIDf; 11338 } 11339 11340 soc_trident_pipe_select(unit, TRUE, 11341 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0)); 11342 soc_trident_pipe_select(unit, FALSE, 11343 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0)); 11344 11345 /* coverity[negative_returns : FALSE] */ 11346 rv = ser_test_mem_pipe(unit, CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, i, -1, 11347 tcam_info[i].mem, test_field, test_type, 11348 MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 11349 &tcam_failed); 11350 if (SOC_FAILURE(rv)) { 11351 LOG_CLI((BSL_META_U(unit, 11352 "Error during TCAM:%s SER test\n"), 11353 SOC_MEM_NAME(unit, tcam_info[i].mem))); 11354 } 11355 soc_trident_pipe_select(unit, TRUE, 0); 11356 soc_trident_pipe_select(unit, FALSE, 0); 11357 11358 } 11359 #ifdef INCLUDE_MEM_SCAN 11360 if (memscan_running) { 11361 rv = soc_mem_scan_start(unit, rate, interval); 11362 if (rv != SOC_E_NONE) { 11363 LOG_CLI((BSL_META_U(unit, 11364 "Error starting memscan.\n"))); 11365 return rv; 11366 } 11367 } 11368 #endif 11369 LOG_CLI((BSL_META_U(unit, 11370 "\nTCAM memories tested on unit %d: %d\n"), unit, num_tcams)); 11371 LOG_CLI((BSL_META_U(unit, 11372 "TCAM tests passed:\t%d\n"), 11373 num_tcams - tcam_skipped - tcam_failed)); 11374 LOG_CLI((BSL_META_U(unit, 11375 "TCAM tests skipped:\t%d (use verbose option to see " 11376 "skipped memories)\n"), tcam_skipped)); 11377 LOG_CLI((BSL_META_U(unit, 11378 "TCAM tests failed:\t%d\n"), tcam_failed)); 11379 11380 if (tcam_failed != 0) { 11381 LOG_CLI((BSL_META_U(unit, 11382 "TR 144 test failed.\n"))); 11383 } 11384 11385 /*Re-innitting init soc and misc to enact force_read_through options*/ 11386 /*init soc*/ 11387 return SOC_E_NONE; 11388 } 11389 11390 11391 const soc_ser_overlay_test_t soc_ser_td_overlay_mems[] = { 11392 {EGR_IP_TUNNEL_IPV6m, EGR_VLAN_PARITY_CONTROLr, 11393 EGR_IP_TUNNEL_PARITY_ENf, EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_X}, 11394 {EGR_IP_TUNNEL_MPLSm, EGR_VLAN_PARITY_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf, 11395 EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_X}, 11396 {EGR_FRAGMENT_ID_TABLE_Xm, EGR_VLAN_PARITY_CONTROLr, 11397 EGR_FRAGMENT_ID_TABLE_PARITY_ENf, EGR_FRAGMENT_ID_TABLEm, 11398 _SOC_ACC_TYPE_PIPE_X}, 11399 {EGR_FRAGMENT_ID_TABLE_Ym, EGR_VLAN_PARITY_CONTROLr, 11400 EGR_FRAGMENT_ID_TABLE_PARITY_ENf, EGR_FRAGMENT_ID_TABLEm, 11401 _SOC_ACC_TYPE_PIPE_Y}, 11402 {EFP_COUNTER_TABLE_Xm, EGR_EDATABUF_PARITY_CONTROLr, 11403 EFPCTR_PAR_ENf, EFP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11404 {EFP_COUNTER_TABLE_Ym, EGR_EDATABUF_PARITY_CONTROLr, 11405 EFPCTR_PAR_ENf,EFP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11406 {EGR_PERQ_XMT_COUNTERS_Xm,EGR_EDATABUF_PARITY_CONTROLr, 11407 PERQ_PAR_ENf,EGR_PERQ_XMT_COUNTERSm, _SOC_ACC_TYPE_PIPE_X}, 11408 {EGR_PERQ_XMT_COUNTERS_Ym,EGR_EDATABUF_PARITY_CONTROLr, 11409 PERQ_PAR_ENf,EGR_PERQ_XMT_COUNTERSm, _SOC_ACC_TYPE_PIPE_Y}, 11410 {EGR_VINTF_COUNTER_TABLE_Xm,EGR_EDATABUF_PARITY_CONTROLr, 11411 VINTFCTR_PAR_ENf,EGR_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11412 {EGR_VINTF_COUNTER_TABLE_Ym,EGR_EDATABUF_PARITY_CONTROLr, 11413 VINTFCTR_PAR_ENf,EGR_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11414 {EGR_SERVICE_COUNTER_TABLE_Xm,EGR_EDATABUF_PARITY_CONTROLr, 11415 SVCCTR_PAR_ENf,EGR_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11416 {EGR_SERVICE_COUNTER_TABLE_Ym,EGR_EDATABUF_PARITY_CONTROLr, 11417 SVCCTR_PAR_ENf,EGR_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11418 {EFP_METER_TABLE_Xm, EFP_METER_PARITY_CONTROLr, 11419 PARITY_ENf,EFP_METER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11420 {EFP_METER_TABLE_Ym, EFP_METER_PARITY_CONTROLr, 11421 PARITY_ENf,EFP_METER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11422 {EGR_PW_INIT_COUNTERS_Xm, EGR_PW_INIT_COUNTERS_PARITY_CONTROLr, 11423 PARITY_ENf,EGR_PW_INIT_COUNTERSm, _SOC_ACC_TYPE_PIPE_X}, 11424 {EGR_PW_INIT_COUNTERS_Ym, EGR_PW_INIT_COUNTERS_PARITY_CONTROLr, 11425 PARITY_ENf,EGR_PW_INIT_COUNTERSm, _SOC_ACC_TYPE_PIPE_Y}, 11426 {VLAN_MACm,VLAN_XLATE_PARITY_CONTROLr, PARITY_ENf, VLAN_XLATEm, 11427 _SOC_ACC_TYPE_PIPE_X}, 11428 {VLAN_SUBNETm,VLAN_SUBNET_PARITY_CONTROLr, 11429 PARITY_ENf,VLAN_SUBNET_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11430 {L3_ENTRY_IPV4_UNICASTm,L3_ENTRY_PARITY_CONTROLr, 11431 PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11432 {L3_ENTRY_IPV4_MULTICASTm,L3_ENTRY_PARITY_CONTROLr, 11433 PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11434 {L3_ENTRY_IPV6_UNICASTm,L3_ENTRY_PARITY_CONTROLr, 11435 PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11436 {L3_ENTRY_IPV6_MULTICASTm,L3_ENTRY_PARITY_CONTROLr, 11437 PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11438 {L3_DEFIPm,L3_DEFIP_DATA_PARITY_CONTROLr, 11439 PARITY_ENf,L3_DEFIP_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11440 {L3_DEFIP_Xm,L3_DEFIP_DATA_PARITY_CONTROLr, 11441 PARITY_ENf,L3_DEFIP_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11442 {L3_DEFIP_Ym,L3_DEFIP_DATA_PARITY_CONTROLr, 11443 PARITY_ENf,L3_DEFIP_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_Y}, 11444 {L2Xm ,L2_ENTRY_PARITY_CONTROLr, PARITY_ENf,L2_ENTRY_ONLYm, 11445 _SOC_ACC_TYPE_PIPE_X}, 11446 {L2_USER_ENTRYm, L2_USER_ENTRY_DATA_PARITY_CONTROLr, 11447 PARITY_ENf,L2_USER_ENTRY_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X}, 11448 {FP_COUNTER_TABLE_Xm, IFP_COUNTER_PARITY_CONTROLr, 11449 PARITY_ENf,FP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11450 {FP_COUNTER_TABLE_Ym, IFP_COUNTER_PARITY_CONTROLr, 11451 PARITY_ENf,FP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11452 /* DLB_HGT_FLOWSET_PORT overlay memories disabled as their base address is 11453 currently skipped. When those issues are sorted these can be un-commented 11454 {DLB_HGT_FLOWSET_PORT_Xm, DLB_HGT_FLOWSET_PORT_PARITY_CONTROLr, 11455 PARITY_ENf, DLB_HGT_FLOWSET_PORTm, _SOC_ACC_TYPE_PIPE_X}, 11456 {DLB_HGT_FLOWSET_PORT_Ym, DLB_HGT_FLOWSET_PORT_PARITY_CONTROLr, 11457 PARITY_ENf,DLB_HGT_FLOWSET_PORTm, _SOC_ACC_TYPE_PIPE_Y},*/ 11458 {MODPORT_MAP_MIRRORm, MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf, 11459 MODPORT_MAP_M0m, _SOC_ACC_TYPE_PIPE_X}, 11460 {ING_PW_TERM_SEQ_NUM_Xm, ING_PW_TERM_SEQ_NUM_PARITY_CONTROLr, PARITY_ENf, 11461 ING_PW_TERM_SEQ_NUMm, _SOC_ACC_TYPE_PIPE_X}, 11462 {ING_PW_TERM_SEQ_NUM_Ym, ING_PW_TERM_SEQ_NUM_PARITY_CONTROLr, PARITY_ENf, 11463 ING_PW_TERM_SEQ_NUMm, _SOC_ACC_TYPE_PIPE_Y}, 11464 {ING_SERVICE_COUNTER_TABLE_Xm, ING_SERVICE_COUNTER_TABLE_PARITY_CONTROLr, 11465 PARITY_ENf,ING_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11466 {ING_SERVICE_COUNTER_TABLE_Ym, ING_SERVICE_COUNTER_TABLE_PARITY_CONTROLr, 11467 PARITY_ENf,ING_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11468 {ING_VINTF_COUNTER_TABLE_Xm, ING_VINTF_COUNTER_TABLE_PARITY_CONTROLr, 11469 PARITY_ENf,ING_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X}, 11470 {ING_VINTF_COUNTER_TABLE_Ym, ING_VINTF_COUNTER_TABLE_PARITY_CONTROLr, 11471 PARITY_ENf, ING_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y}, 11472 {INVALIDm} 11473 }; 11474 11475 11476 /* 11477 * Function: 11478 * soc_td_ser_test_overlay 11479 * Purpose: 11480 * performs a test of all overlay memories along with their base memories 11481 * Parameters: 11482 * unit - (IN) Device Number 11483 * test_type - (IN) how to test memories 11484 */ 11485 int 11486 soc_td_ser_test_overlay (int unit, _soc_ser_test_t test_type) 11487 { 11488 int rv = 0; 11489 int numOverlays = COUNTOF(soc_ser_td_overlay_mems) - 1; 11490 rv =soc_ser_test_overlays(unit, test_type, soc_ser_td_overlay_mems, 11491 soc_trident_pipe_select); 11492 if (rv >= 0) { 11493 LOG_CLI((BSL_META_U(unit, 11494 " Overlay memories tested: \t %d\n"), numOverlays)); 11495 LOG_CLI((BSL_META_U(unit, 11496 " Overlay memories passed: \t %d\n"), numOverlays - rv)); 11497 LOG_CLI((BSL_META_U(unit, 11498 " Overlay memories failed: \t %d\n\n"), rv)); 11499 } else { 11500 LOG_CLI((BSL_META_U(unit, 11501 "TR 144 test failed. Internal Error during overlay test.\n"))); 11502 } 11503 return rv; 11504 } 11505 11506 /* 11507 * Function: 11508 * soc_td_ser_inject_error 11509 * Purpose: 11510 * injects an error into a single td memory 11511 * Parameters: 11512 * unit - (IN) Device Number 11513 * mem - (IN) The memory to test 11514 */ 11515 soc_error_t 11516 soc_td_ser_inject_error(int unit, uint32 flags, soc_mem_t mem, int pipe_target, 11517 int block, int index) 11518 { 11519 _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit]; 11520 int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1; 11521 int group, table, i; 11522 soc_acc_type_t acc_type, acc_type_target; 11523 _soc_trident_parity_info_t *info; 11524 soc_mem_t memTable; 11525 soc_port_t block_port; 11526 soc_block_t blk; 11527 uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS]; 11528 const _soc_trident_parity_route_block_t *route_block = 11529 _soc_trident_parity_route_blocks; 11530 ser_test_data_t test_data; 11531 soc_field_t field; 11532 SOC_IF_ERROR_RETURN(soc_td_ser_error_injection_support(unit, mem, 11533 pipe_target)); 11534 acc_type_target = _soc_trident_pipe_to_acc_type(pipe_target); 11535 11536 num_tcams = ((num_tcams > MAX_HW_TCAMS) ? MAX_HW_TCAMS : num_tcams); 11537 /*TCAM_injection*/ 11538 for (i = 0; i < num_tcams; i++) { 11539 if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) == 11540 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) { 11541 acc_type = _SOC_ACC_TYPE_PIPE_Y; 11542 } else if ((tcam_info[i].ser_flags & _SOC_SER_FLAG_MULTI_PIPE) == 11543 _SOC_SER_FLAG_MULTI_PIPE) { 11544 acc_type = _SOC_ACC_TYPE_PIPE_X; 11545 } else { 11546 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 11547 } 11548 if (tcam_info[i].mem == mem && 11549 ((acc_type == acc_type_target) || 11550 (acc_type_target == _SOC_ACC_TYPE_PIPE_ANY))) { 11551 if (mem == L3_DEFIPm) { 11552 field = VALID0f; 11553 } else if (mem == L3_DEFIP_PAIR_128m) { 11554 field = VALID0_LWRf; 11555 } else { 11556 field = VALIDf; 11557 } 11558 /*Inject error*/ 11559 soc_ser_create_test_data(unit, tmp_entry, field_data, 11560 CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, i, 11561 INVALIDf, mem, 11562 field, MEM_BLOCK_ANY, REG_PORT_ANY, 11563 acc_type_target, index, &test_data); 11564 soc_trident_pipe_select(unit, TRUE, 11565 (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0)); 11566 soc_trident_pipe_select(unit, FALSE, 11567 (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0)); 11568 /*Read the memory for successful injection*/ 11569 SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, &test_data)); 11570 /*Disable parity*/ 11571 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0)); 11572 /*Inject error*/ 11573 SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags, 11574 &test_data)); 11575 /*Enable parity*/ 11576 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1)); 11577 soc_trident_pipe_select(unit, TRUE, 0); 11578 soc_trident_pipe_select(unit, FALSE, 0); 11579 return SOC_E_NONE; 11580 } 11581 } 11582 /*H/W memory Test*/ 11583 _soc_trident_mem_rename(&mem); 11584 for (group = 0; route_block[group].cmic_bit; group++) { 11585 info = route_block[group].info; 11586 SOC_BLOCK_ITER(unit, blk,route_block[group].blocktype) { 11587 if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) { 11588 continue; 11589 } 11590 acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe); 11591 for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) { 11592 memTable = info[table].mem; 11593 if ((memTable == INVALIDm) || (memTable != mem)) { 11594 continue; 11595 } 11596 /*Select the parity field to be toggled to inject the error.*/ 11597 switch (info[table].type) { 11598 case _SOC_PARITY_TYPE_PARITY: 11599 test_data.test_field = EVEN_PARITYf; 11600 if(!SOC_MEM_FIELD_VALID(unit, 11601 info[table].mem,test_data.test_field)) { 11602 test_data.test_field = PARITYf; 11603 if(!SOC_MEM_FIELD_VALID(unit, 11604 info[table].mem,test_data.test_field)) { 11605 test_data.test_field = EVEN_PARITY_0f; 11606 } 11607 } 11608 break; 11609 case _SOC_PARITY_TYPE_SER: 11610 case _SOC_PARITY_TYPE_COUNTER: 11611 case _SOC_PARITY_TYPE_ECC: 11612 case _SOC_PARITY_TYPE_HASH: 11613 break; 11614 default: 11615 /* No field to check. */ 11616 continue; 11617 } 11618 if (memTable == mem) { 11619 if (((blk == block) || (block == MEM_BLOCK_ANY)) && 11620 ((acc_type == acc_type_target) || 11621 (acc_type_target == _SOC_ACC_TYPE_PIPE_ANY))) { 11622 /*Inject error*/ 11623 if (mem == SOURCE_TRUNK_MAP_TABLEm) { 11624 field = ECCf; 11625 flags |= SOC_INJECT_ERROR_2BIT_ECC; 11626 } else if (mem == PORT_TABm || mem == LPORT_TABm) { 11627 field = ECC_0f; 11628 flags |= SOC_INJECT_ERROR_2BIT_ECC; 11629 } else { 11630 field = EVEN_PARITYf; 11631 } 11632 soc_ser_create_test_data(unit, tmp_entry, field_data, 11633 info[table].enable_reg, 11634 SOC_INVALID_TCAM_PARITY_BIT, 11635 info[table].enable_field, 11636 mem, field, blk, 11637 block_port, 11638 acc_type, index, 11639 &test_data); 11640 soc_trident_pipe_select(unit, TRUE, 11641 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0)); 11642 soc_trident_pipe_select(unit, FALSE, 11643 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0)); 11644 /*Disable parity*/ 11645 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0)); 11646 /*Read the memory for successful injection*/ 11647 SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, &test_data)); 11648 /*Inject error*/ 11649 SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags, 11650 &test_data)); 11651 /*Enable parity*/ 11652 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1)); 11653 soc_trident_pipe_select(unit, TRUE, 0); 11654 soc_trident_pipe_select(unit, FALSE, 0); 11655 return SOC_E_NONE; 11656 } 11657 } 11658 } 11659 } 11660 } 11661 return SOC_E_UNAVAIL; 11662 } 11663 #endif /*#if defined(SER_TR_TEST_SUPPORT)*/ 11664 11665 /* 11666 * Trident chip driver functions. 11667 */ 11668 soc_functions_t soc_trident_drv_funs = { 11669 _soc_trident_misc_init, 11670 _soc_trident_mmu_init, 11671 _soc_trident_age_timer_get, 11672 _soc_trident_age_timer_max_get, 11673 _soc_trident_age_timer_set, 11674 }; 11675 11676 int soc_trident_ser_dual_pipe_correction(int unit, soc_mem_t reported_mem, int copyno, 11677 int index, _soc_ser_correct_info_t *si ) 11678 { 11679 int entry_dw, rv; 11680 int num_mems = 0, m = 0, cache_restore = 0; 11681 soc_mem_t mem; 11682 soc_mem_t mem_list[3] = {INVALIDm, INVALIDm, INVALIDm}; 11683 uint8 *vmap; 11684 uint32 *cache; 11685 uint32 entry[SOC_MAX_MEM_WORDS]; 11686 11687 mem_list[0] = reported_mem; 11688 switch(reported_mem) 11689 { 11690 case FP_STORM_CONTROL_METERSm: 11691 { 11692 num_mems = 3; 11693 mem_list[1] = FP_STORM_CONTROL_METERS_Xm; 11694 mem_list[2] = FP_STORM_CONTROL_METERS_Ym; 11695 break; 11696 } 11697 case DLB_HGT_FLOWSET_PORTm: 11698 { 11699 num_mems = 3; 11700 mem_list[1] = DLB_HGT_FLOWSET_PORT_Xm; 11701 mem_list[2] = DLB_HGT_FLOWSET_PORT_Ym; 11702 break; 11703 } 11704 case EFP_METER_TABLEm: 11705 { 11706 num_mems = 3; 11707 mem_list[1] = EFP_METER_TABLE_Xm; 11708 mem_list[2] = EFP_METER_TABLE_Ym; 11709 break; 11710 } 11711 break; 11712 default: 11713 break; 11714 } 11715 11716 if (copyno == MEM_BLOCK_ANY) { 11717 copyno = SOC_MEM_BLOCK_ANY(unit, reported_mem); 11718 } 11719 11720 for (m = 0; m < num_mems; m++) { 11721 mem = mem_list[m]; 11722 cache = SOC_MEM_STATE(unit, mem).cache[copyno]; 11723 vmap = SOC_MEM_STATE(unit, mem).vmap[copyno]; 11724 entry_dw = soc_mem_entry_words(unit, mem); 11725 11726 if (cache != NULL && CACHE_VMAP_TST(vmap, index)) 11727 { 11728 sal_memcpy(entry, cache + (index * entry_dw), 11729 entry_dw * 4); 11730 rv = soc_mem_write(unit, mem, copyno, index, entry); 11731 11732 if (rv == SOC_E_NONE) { 11733 cache_restore = 1; 11734 break; 11735 } 11736 } 11737 } 11738 11739 if (cache_restore == 1) { 11740 if (NULL != si) { 11741 if ((si->log_id != 0) && 11742 (si->flags & SOC_SER_LOG_WRITE_CACHE)) { 11743 (void)soc_ser_log_add_tlv(unit, si->log_id, 11744 SOC_SER_LOG_TLV_CACHE, 11745 soc_mem_entry_words(unit, mem) * 4, 11746 entry); 11747 } 11748 11749 if (soc_property_get(unit, spn_ENHANCED_SER_CORRECTION_EVENT_REPORT, 0)) { 11750 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 11751 SOC_SWITCH_EVENT_DATA_ERROR_PARITY_CORRECTED, reported_mem, index); 11752 } else { 11753 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 11754 SOC_SWITCH_EVENT_DATA_ERROR_CORRECTED, reported_mem, index); 11755 } 11756 11757 LOG_WARN(BSL_LS_SOC_SER, 11758 (BSL_META_U(unit, 11759 "CACHE_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"), 11760 SOC_MEM_NAME(unit, mem), mem, 11761 SOC_BLOCK_NAME(unit, copyno), 11762 index, si->sblk, si->addr)); 11763 } 11764 11765 return SOC_E_NONE; 11766 }else { 11767 return SOC_E_UNAVAIL; 11768 } 11769 } 11770 11771 static soc_multi_cp_mem_t soc_td_mem_cp_list[] = { 11772 {MMU_THDO_CONFIG_0m, 11773 {THDO_CONFIG_0Am, THDO_CONFIG_0Bm, INVALIDm, INVALIDm}}, 11774 {MMU_THDO_CONFIG_1m, 11775 {THDO_CONFIG_1Am, THDO_CONFIG_1Bm, INVALIDm, INVALIDm}}, 11776 {MMU_THDO_CONFIG_EX_0m, 11777 {THDO_CONFIG_EX_0Am, THDO_CONFIG_EX_0Bm, INVALIDm, INVALIDm}}, 11778 {MMU_THDO_CONFIG_EX_1m, 11779 {THDO_CONFIG_EX_1Am, THDO_CONFIG_EX_1Bm, INVALIDm, INVALIDm}}, 11780 {MMU_THDO_OFFSET_0m, 11781 {THDO_OFFSET_0Am, THDO_OFFSET_0Bm, INVALIDm, INVALIDm}}, 11782 {MMU_THDO_OFFSET_1m, 11783 {THDO_OFFSET_1Am, THDO_OFFSET_1Bm, INVALIDm, INVALIDm}}, 11784 {MMU_THDO_OFFSET_EX_0m, 11785 {THDO_OFFSET_EX_0Am, THDO_OFFSET_EX_0Bm, INVALIDm, INVALIDm}}, 11786 {MMU_THDO_OFFSET_EX_1m, 11787 {THDO_OFFSET_EX_1Am, THDO_OFFSET_EX_1Bm, INVALIDm, INVALIDm}}, 11788 { INVALIDm }, 11789 }; 11790 11791 /* Get physical copies for specific mem */ 11792 int soc_trident_mem_cp_get(int unit, soc_mem_t mem, 11793 soc_mem_t *mem_cp_array) 11794 { 11795 int i = 0; 11796 int num = COUNTOF(soc_td_mem_cp_list) - 1; 11797 soc_multi_cp_mem_t *mem_info = soc_td_mem_cp_list; 11798 11799 if (NULL == mem_cp_array) { 11800 return SOC_E_PARAM; 11801 } 11802 11803 for (i = 0; i < num; i++) { 11804 if (mem == mem_info[i].mem) { 11805 sal_memcpy(mem_cp_array, mem_info[i].mem_cp, 11806 sizeof(soc_mem_t) * SOC_MEM_CP_MAX_NUM); 11807 return SOC_E_NONE; 11808 } 11809 } 11810 return SOC_E_NOT_FOUND; 11811 } 11812 #endif /* BCM_TRIDENT_SUPPORT */