intr.c (149663B)
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 * SOC Interrupt Handlers 8 * 9 * NOTE: These handlers are called from an interrupt context, so their 10 * actions are restricted accordingly. 11 */ 12 13 #include <shared/bsl.h> 14 15 #include <sal/core/libc.h> 16 #include <shared/alloc.h> 17 #include <shared/util.h> 18 #include <sal/core/spl.h> 19 #include <sal/core/sync.h> 20 #include <sal/core/dpc.h> 21 #include <sal/core/time.h> 22 #include <sal/types.h> 23 24 #include <soc/drv.h> 25 #include <soc/dma.h> 26 #include <soc/i2c.h> 27 #include <soc/intr.h> 28 29 #ifdef BCM_CMICM_SUPPORT 30 #include <soc/cmicm.h> 31 #endif 32 33 #ifdef BCM_CMICX_SUPPORT 34 #include <soc/intr_cmicx.h> 35 #endif 36 37 38 #ifdef BCM_FIREBOLT_SUPPORT 39 #include <soc/firebolt.h> 40 #endif /* BCM_FIREBOLT_SUPPORT */ 41 42 #ifdef BCM_BRADLEY_SUPPORT 43 #include <soc/bradley.h> 44 #endif /* BCM_BRADLEY_SUPPORT */ 45 46 #ifdef BCM_TRIUMPH_SUPPORT 47 #include <soc/triumph.h> 48 #endif /* BCM_TRIUMPH_SUPPORT */ 49 50 #ifdef BCM_TRIUMPH2_SUPPORT 51 #include <soc/triumph2.h> 52 #endif /* BCM_TRIUMPH2_SUPPORT */ 53 54 #ifdef BCM_TRIDENT_SUPPORT 55 #include <soc/trident.h> 56 #endif /* BCM_TRIDENT_SUPPORT */ 57 58 #ifdef BCM_ENDURO_SUPPORT 59 #include <soc/enduro.h> 60 #endif /* BCM_ENDURO_SUPPORT */ 61 62 #ifdef BCM_HURRICANE_SUPPORT 63 #include <soc/hurricane.h> 64 #endif /* BCM_HURRICANE_SUPPORT */ 65 66 #ifdef BCM_DFE_SUPPORT 67 #include <soc/dfe/cmn/dfe_drv.h> 68 #include <soc/dfe/cmn/dfe_interrupt.h> 69 #include <soc/dfe/cmn/dfe_warm_boot.h> 70 #endif 71 #ifdef BCM_PETRA_SUPPORT 72 #include <shared/swstate/access/sw_state_access.h> 73 #include <soc/dpp/ARAD/arad_interrupts.h> 74 #include <soc/dpp/ARAD/arad_sw_db.h> 75 #endif 76 #ifdef BCM_JERICHO_SUPPORT 77 #include <soc/dpp/JER/jer_intr.h> 78 #endif 79 #ifdef BCM_JERICHO_SUPPORT 80 #include <soc/dpp/QAX/qax_intr.h> 81 #endif 82 #ifdef BCM_JERICHO_PLUS_SUPPORT 83 #include <soc/dpp/JERP/jerp_intr.h> 84 #endif 85 #ifdef BCM_QUX_SUPPORT 86 #include <soc/dpp/QUX/qux_intr.h> 87 #endif 88 #ifdef BCM_PETRA_SUPPORT 89 #include <soc/dpp/mbcm.h> 90 #endif 91 #if defined(BCM_JERICHO_SUPPORT) || defined(BCM_88950_SUPPORT) 92 #include <soc/dcmn/dcmn_intr_handler.h> 93 #endif 94 #ifdef BCM_DNXF_SUPPORT 95 #include <soc/dnxf/ramon/ramon_intr.h> 96 /*dnxf sw state*/ 97 #include <soc/dnxf/swstate/auto_generated/access/dnxf_access.h> 98 #endif 99 #ifdef BCM_DNX_SUPPORT 100 #include <soc/dnxc/intr.h> 101 #include <soc/dnx/dnx_data/auto_generated/dnx_data_intr.h> 102 #include <soc/dnx/swstate/auto_generated/access/interrupt_access.h> 103 #include <soc/dnx/intr/dnx_intr.h> 104 #endif 105 #ifdef BCM_CMICX_SUPPORT 106 #include <soc/iproc.h> 107 #endif 108 #ifdef INCLUDE_KNET 109 #include <soc/knet.h> 110 #define IRQ_MASK_SET(_u,_a,_m) soc_knet_irq_mask_set(_u,_a,_m) 111 #else 112 #define IRQ_MASK_SET(_u,_a,_m) soc_pci_write(_u,_a,_m) 113 #endif 114 115 #define INTR_CMN_ERROR_MAX_INTERRUPTS_SIZE 50 116 #define SOC_INTERRUPT_DB_PRIORITY_MECHANISM_MAX_LEVELS 300 117 #define FIRST_PORT_BLOCK_INTER 727 118 119 #ifdef BCM_CMICX_SUPPORT 120 soc_cmic_intr_op_t _cmic_intr_op[SOC_MAX_NUM_DEVICES]; 121 #endif 122 123 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT) 124 125 /* Declare static functions for interrupt handler array */ 126 STATIC void soc_intr_schan_done(int unit, uint32 ignored); 127 STATIC void soc_intr_pci_parity(int unit, uint32 ignored); 128 STATIC void soc_intr_pci_fatal(int unit, uint32 ignored); 129 STATIC void soc_intr_link_stat(int unit, uint32 ignored); 130 STATIC void soc_intr_gbp_full(int unit, uint32 ignored); 131 STATIC void soc_intr_arl_xfer(int unit, uint32 ignored); 132 STATIC void soc_intr_arl_cnt0(int unit, uint32 ignored); 133 STATIC void soc_intr_arl_drop(int unit, uint32 ignored); 134 STATIC void soc_intr_arl_mbuf(int unit, uint32 ignored); 135 STATIC void soc_intr_schan_error(int unit, uint32 ignored); 136 STATIC void soc_intr_i2c(int unit, uint32 ignored); 137 STATIC void soc_intr_miim_op(int unit, uint32 ignored); 138 STATIC void soc_intr_stat_dma(int unit, uint32 ignored); 139 STATIC void soc_intr_bit21(int unit, uint32 ignored); 140 STATIC void soc_intr_bit22(int unit, uint32 ignored); 141 STATIC void soc_intr_bit23(int unit, uint32 ignored); 142 #ifdef BCM_HERCULES_SUPPORT 143 STATIC void soc_intr_mmu_stat(int unit, uint32 ignored); 144 #endif 145 #if defined(BCM_XGS12_SWITCH_SUPPORT) 146 STATIC void soc_intr_arl_error(int unit, uint32 ignored); 147 #endif 148 STATIC void soc_intr_lpm_lo_parity(int unit, uint32 ignored); 149 STATIC void soc_intr_bit25(int unit, uint32 ignored); 150 STATIC void soc_intr_bit26(int unit, uint32 ignored); 151 STATIC void soc_intr_bit27(int unit, uint32 ignored); 152 STATIC void soc_intr_bit28(int unit, uint32 ignored); 153 STATIC void soc_intr_bit31(int unit, uint32 ignored); 154 STATIC void soc_intr_tdma_done(int unit, uint32 ignored); 155 STATIC void soc_intr_tslam_done(int unit, uint32 ignored); 156 STATIC void soc_intr_block(int unit, uint32 block); 157 158 /* 159 * SOC Interrupt Table 160 * 161 * The table is stored in priority order: Interrupts that are listed 162 * first have their handlers called first. 163 * 164 * A handler can clear more than one interrupt bit to prevent a 165 * subsequent handler from being called. E.g., if the DMA CHAIN_DONE 166 * handler clears both CHAIN_DONE and DESC_DONE, the DESC_DONE handler 167 * will not be called. 168 */ 169 170 typedef void (*ifn_t)(int unit, uint32 data); 171 172 typedef struct { 173 uint32 mask; 174 ifn_t intr_fn; 175 uint32 intr_data; 176 char *intr_name; 177 } intr_handler_t; 178 179 STATIC intr_handler_t soc_intr_handlers[] = { 180 181 /* Errors (Highest priority) [0..3] */ 182 183 { IRQ_PCI_PARITY_ERR, soc_intr_pci_parity, 0, "PCI_PARITY_ERR" }, 184 { IRQ_PCI_FATAL_ERR, soc_intr_pci_fatal, 0, "PCI_FATAL_ERR" }, 185 { IRQ_SCHAN_ERR, soc_intr_schan_error, 0, "SCHAN_ERR" }, 186 { IRQ_GBP_FULL, soc_intr_gbp_full, 0, "GBP_FULL" }, 187 188 /* S-Channel [4] */ 189 190 { IRQ_SCH_MSG_DONE, soc_intr_schan_done, 0, "SCH_MSG_DONE" }, 191 192 /* MII [5-6] */ 193 194 { IRQ_MIIM_OP_DONE, soc_intr_miim_op, 0, "MIIM_OP_DONE" }, 195 { IRQ_LINK_STAT_MOD, soc_intr_link_stat, 0, "LINK_STAT_MOD" }, 196 197 /* ARL messages [7-10] */ 198 199 { IRQ_ARL_MBUF, soc_intr_arl_mbuf, 0, "ARL_MBUF" }, 200 { IRQ_ARL_MBUF_DROP, soc_intr_arl_drop, 0, "ARL_MBUF_DROP" }, 201 { IRQ_ARL_DMA_CNT0, soc_intr_arl_cnt0, 0, "ARL_DMA_CNT0" }, 202 { IRQ_ARL_DMA_XFER, soc_intr_arl_xfer, 0, "ARL_DMA_XFER" }, 203 204 /* TDMA/TSLAM [11-12] */ 205 { IRQ_TDMA_DONE, soc_intr_tdma_done, 0, "TDMA_DONE" }, 206 { IRQ_TSLAM_DONE, soc_intr_tslam_done, 0, "TSLAM_DONE" }, 207 208 /* Packet DMA [13-20] */ 209 210 { IRQ_CHAIN_DONE(0), soc_dma_done_chain, 0, "CH0_CHAIN_DONE" }, 211 { IRQ_CHAIN_DONE(1), soc_dma_done_chain, 1, "CH1_CHAIN_DONE" }, 212 { IRQ_CHAIN_DONE(2), soc_dma_done_chain, 2, "CH2_CHAIN_DONE" }, 213 { IRQ_CHAIN_DONE(3), soc_dma_done_chain, 3, "CH3_CHAIN_DONE" }, 214 215 { IRQ_DESC_DONE(0), soc_dma_done_desc, 0, "CH0_DESC_DONE" }, 216 { IRQ_DESC_DONE(1), soc_dma_done_desc, 1, "CH1_DESC_DONE" }, 217 { IRQ_DESC_DONE(2), soc_dma_done_desc, 2, "CH2_DESC_DONE" }, 218 { IRQ_DESC_DONE(3), soc_dma_done_desc, 3, "CH3_DESC_DONE" }, 219 220 /* Other (lowest priority) [21-28] */ 221 222 { IRQ_BIT21, soc_intr_bit21, 0, "MMU_IRQ_STAT" }, 223 { IRQ_BIT22, soc_intr_bit22, 0, "IRQ_FIFO_CH1_DMA" }, 224 { IRQ_BIT23, soc_intr_bit23, 0, "IRQ_FIFO_CH2_DMA" }, 225 { IRQ_STAT_ITER_DONE, soc_intr_stat_dma, 0, "STAT_ITER_DONE" }, 226 { IRQ_I2C_INTR, soc_intr_i2c, 0, "I2C_INTR" }, 227 { IRQ_ARL_LPM_LO_PAR, soc_intr_lpm_lo_parity, 0, "LPM_LO_PARITY" }, 228 { IRQ_BIT25, soc_intr_bit25, 0, "LPM_HI_PARITY/BSE" }, 229 { IRQ_BIT26, soc_intr_bit26, 0, "L3_PARITY/CSE" }, 230 { IRQ_BIT27, soc_intr_bit27, 0, "L2_PARITY/HSE" }, 231 { IRQ_BIT28, soc_intr_bit28, 0, "VLAN_PARITY/MEMFAIL"}, 232 { IRQ_BROADSYNC_INTR, soc_intr_bit31, 0, "BSAFE_OP_DONE/BROADSYNC_INTR"}, 233 234 }; 235 236 #define INTR_HANDLERS_COUNT COUNTOF(soc_intr_handlers) 237 238 /* 239 * define some short cuts to start processing interrupts quickly 240 * start2: skip to packet processing 241 * start1: skip low probability errors 242 * else start at 0 243 */ 244 #define INTR_START1_MASK (IRQ_PCI_PARITY_ERR | \ 245 IRQ_PCI_FATAL_ERR | \ 246 IRQ_SCHAN_ERR | \ 247 IRQ_GBP_FULL) 248 #define INTR_START1_POS 4 249 #define INTR_START2_MASK (INTR_START1_MASK | \ 250 IRQ_SCH_MSG_DONE | \ 251 IRQ_MIIM_OP_DONE | \ 252 IRQ_LINK_STAT_MOD | \ 253 IRQ_ARL_MBUF | \ 254 IRQ_ARL_MBUF_DROP | \ 255 IRQ_ARL_DMA_CNT0 | \ 256 IRQ_ARL_DMA_XFER) 257 #define INTR_START2_POS 11 258 259 STATIC intr_handler_t soc_intr_block_lo_handlers[] = { 260 { IRQ_BLOCK(0), soc_intr_block, 0, "BLOCK_0_ERR" }, 261 { IRQ_BLOCK(1), soc_intr_block, 1, "BLOCK_1_ERR" }, 262 { IRQ_BLOCK(2), soc_intr_block, 2, "BLOCK_2_ERR" }, 263 { IRQ_BLOCK(3), soc_intr_block, 3, "BLOCK_3_ERR" }, 264 { IRQ_BLOCK(4), soc_intr_block, 4, "BLOCK_4_ERR" }, 265 { IRQ_BLOCK(5), soc_intr_block, 5, "BLOCK_5_ERR" }, 266 { IRQ_BLOCK(6), soc_intr_block, 6, "BLOCK_6_ERR" }, 267 { IRQ_BLOCK(7), soc_intr_block, 7, "BLOCK_7_ERR" }, 268 { IRQ_BLOCK(8), soc_intr_block, 8, "BLOCK_8_ERR" }, 269 { IRQ_BLOCK(9), soc_intr_block, 9, "BLOCK_9_ERR" }, 270 { IRQ_BLOCK(10), soc_intr_block, 10, "BLOCK_10_ERR" }, 271 { IRQ_BLOCK(11), soc_intr_block, 11, "BLOCK_11_ERR" }, 272 { IRQ_BLOCK(12), soc_intr_block, 12, "BLOCK_12_ERR" }, 273 { IRQ_BLOCK(13), soc_intr_block, 13, "BLOCK_13_ERR" }, 274 { IRQ_BLOCK(14), soc_intr_block, 14, "BLOCK_14_ERR" }, 275 { IRQ_BLOCK(15), soc_intr_block, 15, "BLOCK_15_ERR" }, 276 { IRQ_BLOCK(16), soc_intr_block, 16, "BLOCK_16_ERR" }, 277 { IRQ_BLOCK(17), soc_intr_block, 17, "BLOCK_17_ERR" }, 278 { IRQ_BLOCK(18), soc_intr_block, 18, "BLOCK_18_ERR" }, 279 { IRQ_BLOCK(19), soc_intr_block, 19, "BLOCK_19_ERR" }, 280 { IRQ_BLOCK(20), soc_intr_block, 20, "BLOCK_20_ERR" }, 281 { IRQ_BLOCK(21), soc_intr_block, 21, "BLOCK_21_ERR" }, 282 { IRQ_BLOCK(22), soc_intr_block, 22, "BLOCK_22_ERR" }, 283 { IRQ_BLOCK(23), soc_intr_block, 23, "BLOCK_23_ERR" }, 284 { IRQ_BLOCK(24), soc_intr_block, 24, "BLOCK_24_ERR" }, 285 { IRQ_BLOCK(25), soc_intr_block, 25, "BLOCK_25_ERR" }, 286 { IRQ_BLOCK(26), soc_intr_block, 26, "BLOCK_26_ERR" }, 287 { IRQ_BLOCK(27), soc_intr_block, 27, "BLOCK_27_ERR" }, 288 { IRQ_BLOCK(28), soc_intr_block, 28, "BLOCK_28_ERR" }, 289 { IRQ_BLOCK(29), soc_intr_block, 29, "BLOCK_29_ERR" }, 290 { IRQ_BLOCK(30), soc_intr_block, 30, "BLOCK_30_ERR" }, 291 { IRQ_BLOCK(31), soc_intr_block, 31, "BLOCK_31_ERR" }, 292 }; 293 STATIC intr_handler_t soc_intr_block_hi_handlers[] = { 294 { IRQ_BLOCK(0), soc_intr_block, 32, "BLOCK_32_ERR" }, 295 { IRQ_BLOCK(1), soc_intr_block, 33, "BLOCK_33_ERR" }, 296 { IRQ_BLOCK(2), soc_intr_block, 34, "BLOCK_34_ERR" }, 297 { IRQ_BLOCK(3), soc_intr_block, 35, "BLOCK_35_ERR" }, 298 { IRQ_BLOCK(4), soc_intr_block, 36, "BLOCK_36_ERR" }, 299 { IRQ_BLOCK(5), soc_intr_block, 37, "BLOCK_37_ERR" }, 300 { IRQ_BLOCK(6), soc_intr_block, 38, "BLOCK_38_ERR" }, 301 { IRQ_BLOCK(7), soc_intr_block, 39, "BLOCK_39_ERR" }, 302 { IRQ_BLOCK(8), soc_intr_block, 40, "BLOCK_40_ERR" }, 303 { IRQ_BLOCK(9), soc_intr_block, 41, "BLOCK_41_ERR" }, 304 { IRQ_BLOCK(10), soc_intr_block, 42, "BLOCK_42_ERR" }, 305 { IRQ_BLOCK(11), soc_intr_block, 43, "BLOCK_43_ERR" }, 306 { IRQ_BLOCK(12), soc_intr_block, 44, "BLOCK_44_ERR" }, 307 { IRQ_BLOCK(13), soc_intr_block, 45, "BLOCK_45_ERR" }, 308 { IRQ_BLOCK(14), soc_intr_block, 46, "BLOCK_46_ERR" }, 309 { IRQ_BLOCK(15), soc_intr_block, 47, "BLOCK_47_ERR" }, 310 { IRQ_BLOCK(16), soc_intr_block, 48, "BLOCK_48_ERR" }, 311 { IRQ_BLOCK(17), soc_intr_block, 49, "BLOCK_49_ERR" }, 312 { IRQ_BLOCK(18), soc_intr_block, 50, "BLOCK_50_ERR" }, 313 { IRQ_BLOCK(19), soc_intr_block, 51, "BLOCK_51_ERR" }, 314 { IRQ_BLOCK(20), soc_intr_block, 52, "BLOCK_52_ERR" }, 315 { IRQ_BLOCK(21), soc_intr_block, 53, "BLOCK_53_ERR" }, 316 { IRQ_BLOCK(22), soc_intr_block, 54, "BLOCK_54_ERR" }, 317 { IRQ_BLOCK(23), soc_intr_block, 55, "BLOCK_55_ERR" }, 318 { IRQ_BLOCK(24), soc_intr_block, 56, "BLOCK_56_ERR" }, 319 { IRQ_BLOCK(25), soc_intr_block, 57, "BLOCK_57_ERR" }, 320 { IRQ_BLOCK(26), soc_intr_block, 58, "BLOCK_58_ERR" }, 321 { IRQ_BLOCK(27), soc_intr_block, 59, "BLOCK_59_ERR" }, 322 { IRQ_BLOCK(28), soc_intr_block, 60, "BLOCK_60_ERR" }, 323 { IRQ_BLOCK(29), soc_intr_block, 61, "BLOCK_61_ERR" }, 324 { IRQ_BLOCK(30), soc_intr_block, 62, "BLOCK_62_ERR" }, 325 { IRQ_BLOCK(31), soc_intr_block, 63, "BLOCK_63_ERR" }, 326 }; 327 #define INTR_BLOCK_LO_HANDLERS_COUNT COUNTOF(soc_intr_block_lo_handlers) 328 #define INTR_BLOCK_HI_HANDLERS_COUNT COUNTOF(soc_intr_block_hi_handlers) 329 330 #define SOC_CMIC_BLK_CLP_0_INDX 24 331 #define SOC_CMIC_BLK_CLP_1_INDX 25 332 #define SOC_CMIC_BLK_XLP_0_INDX 27 333 #define SOC_CMIC_BLK_XLP_1_INDX 28 334 335 #define _PORT_BLOCK_FROM_IRQ_STATE2(unit, cmic_irq_state_2, stat2_field, block_bit) \ 336 ( (soc_reg_field_get(unit, CMIC_CMC0_IRQ_STAT2r, (cmic_irq_state_2), stat2_field) != 0 ) << block_bit ) 337 338 /* 339 * Interrupt handler functions 340 */ 341 342 STATIC void 343 soc_intr_schan_done(int unit, uint32 ignored) 344 { 345 soc_control_t *soc = SOC_CONTROL(unit); 346 347 COMPILER_REFERENCE(ignored); 348 349 /* Record the schan control regsiter */ 350 soc->schan_result[SOC_PCI_CMC(unit)] = soc_pci_read(unit, CMIC_SCHAN_CTRL); 351 352 soc->stat.intr_sc++; 353 354 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_MSG_DONE_CLR); 355 356 if (soc->schanIntr[SOC_PCI_CMC(unit)]) { 357 sal_sem_give(soc->schanIntr[SOC_PCI_CMC(unit)]); 358 } 359 } 360 361 STATIC soc_schan_err_t 362 soc_schan_error_type(int unit, int err_code) 363 { 364 int bitcount = 0; 365 soc_schan_err_t err = SOC_SCERR_INVALID; 366 367 switch (SOC_CHIP_GROUP(unit)) { 368 case SOC_CHIP_BCM5673: 369 case SOC_CHIP_BCM5674: 370 if (err_code & 0x10) { 371 err = SOC_SCERR_MMU_NPKT_CELLS; 372 ++bitcount; 373 } 374 if (err_code & 0x20) { 375 err = SOC_SCERR_MEMORY_PARITY; 376 ++bitcount; 377 } 378 /* Fall through */ 379 case SOC_CHIP_BCM5690: 380 case SOC_CHIP_BCM5695: 381 if (err_code & 0x1) { 382 err = SOC_SCERR_CFAP_OVER_UNDER; 383 ++bitcount; 384 } 385 if (err_code & 0x2) { 386 err = SOC_SCERR_MMU_SOFT_RST; 387 ++bitcount; 388 } 389 if (err_code & 0x4) { 390 err = SOC_SCERR_CBP_CELL_CRC; 391 ++bitcount; 392 } 393 if (err_code & 0x8) { 394 err = SOC_SCERR_CBP_HEADER_PARITY; 395 ++bitcount; 396 } 397 break; 398 case SOC_CHIP_BCM5665: 399 case SOC_CHIP_BCM5650: 400 if (err_code & 0x1) { 401 err = SOC_SCERR_CELL_PTR_CRC; 402 ++bitcount; 403 } 404 if (err_code & 0x2) { 405 err = SOC_SCERR_CELL_DATA_CRC; 406 ++bitcount; 407 } 408 if (err_code & 0x4) { 409 err = SOC_SCERR_FRAME_DATA_CRC; 410 ++bitcount; 411 } 412 if (err_code & 0x8) { 413 err = SOC_SCERR_CELL_PTR_BLOCK_CRC; 414 ++bitcount; 415 } 416 if (err_code & 0x10) { 417 err = SOC_SCERR_MEMORY_PARITY; 418 ++bitcount; 419 } 420 if (err_code & 0x20) { 421 err = SOC_SCERR_PLL_DLL_LOCK_LOSS; 422 ++bitcount; 423 } 424 break; 425 default: 426 break; 427 } 428 429 if (bitcount > 1) { 430 err = SOC_SCERR_MULTIPLE_ERR; 431 } 432 433 return err; 434 } 435 436 STATIC void 437 _soc_sch_error_unblock(void *p_unit, void *p2, void *p3, void *p4, void *p5) 438 { 439 COMPILER_REFERENCE(p2); 440 COMPILER_REFERENCE(p3); 441 COMPILER_REFERENCE(p4); 442 COMPILER_REFERENCE(p5); 443 444 soc_intr_enable(PTR_TO_INT(p_unit), IRQ_SCHAN_ERR); 445 } 446 447 STATIC void 448 soc_intr_schan_error(int unit, uint32 ignored) 449 { 450 soc_control_t *soc = SOC_CONTROL(unit); 451 uint32 scerr, slot; 452 int vld, src, dst, opc, err; 453 454 COMPILER_REFERENCE(ignored); 455 456 /* 457 * Read the beginning of the S-chan message so its contents are 458 * visible when a PCI bus analyzer is connected. 459 */ 460 461 soc_pci_analyzer_trigger(unit); 462 463 if (bsl_check(bslLayerSoc, bslSourceIntr, bslSeverityNormal, unit)) { 464 slot = soc_pci_read(unit, 0); 465 slot = soc_pci_read(unit, 4); 466 slot = soc_pci_read(unit, 8); 467 slot = soc_pci_read(unit, 0xC); 468 } 469 470 scerr = soc_pci_read(unit, CMIC_SCHAN_ERR); /* Clears intr */ 471 soc_pci_write(unit, CMIC_SCHAN_ERR, 0); /* Clears intr in some devs */ 472 473 soc->stat.intr_sce++; 474 475 /* 476 * If the valid bit is not set, it's probably because the error 477 * occurred at the same time the software was starting an unrelated 478 * S-channel operation. There is no way to prevent this conflict. 479 * We'll indicate that that the valid bit was not set and continue, 480 * since the error is probably still latched. 481 */ 482 483 vld = soc_reg_field_get(unit, CMIC_SCHAN_ERRr, scerr, 484 (SOC_IS_XGS3_SWITCH(unit)) ? ERRBITf : VALIDf); 485 src = soc_reg_field_get(unit, CMIC_SCHAN_ERRr, scerr, SRC_PORTf); 486 dst = soc_reg_field_get(unit, CMIC_SCHAN_ERRr, scerr, DST_PORTf); 487 opc = soc_reg_field_get(unit, CMIC_SCHAN_ERRr, scerr, OP_CODEf); 488 err = soc_reg_field_get(unit, CMIC_SCHAN_ERRr, scerr, ERR_CODEf); 489 490 if ((!soc->mmu_error_block) || (opc != MEMORY_FAIL_NOTIFY)) { 491 LOG_ERROR(BSL_LS_SOC_COMMON, 492 (BSL_META_U(unit, 493 "UNIT %d SCHAN ERROR: V/E=%d SRC=%d DST=%d " 494 "OPCODE=%d(%s) ERRCODE=0x%x\n"), 495 unit, vld, src, dst, 496 opc, soc_schan_op_name(opc), err)); 497 } 498 499 #ifdef BCM_XGS3_SWITCH_SUPPORT 500 if (SOC_IS_XGS3_SWITCH(unit)) { 501 LOG_ERROR(BSL_LS_SOC_COMMON, 502 (BSL_META_U(unit, 503 "UNIT %d SCHAN ERROR: Unknown reason\n"), 504 unit)); 505 } else 506 #endif 507 if (opc == MEMORY_FAIL_NOTIFY) { 508 switch (soc_schan_error_type(unit, err)) { 509 case SOC_SCERR_CFAP_OVER_UNDER: 510 /* 511 * The CFAP is empty but a request for a cell pointer came 512 * in, or the CFAP is full but a request to return a cell 513 * pointer came in. 514 */ 515 soc->stat.err_cfap++; 516 LOG_ERROR(BSL_LS_SOC_COMMON, 517 (BSL_META_U(unit, 518 "UNIT %d SCHAN ERROR: CFAP oversubscribed\n"), 519 unit)); 520 break; 521 case SOC_SCERR_SDRAM_CHKSUM: 522 /* 523 * Checksum error occurred when fetching a slot from SDRAM. 524 */ 525 soc->stat.err_sdram++; 526 slot = soc_pci_read(unit, CMIC_MEM_FAIL); 527 LOG_ERROR(BSL_LS_SOC_COMMON, 528 (BSL_META_U(unit, 529 "UNIT %d SCHAN ERROR: SDRAM checksum error, " 530 "slot=0x%x (GBP index 0x%x)\n"), 531 unit, slot, slot * 0x40)); 532 break; 533 case SOC_SCERR_UNEXP_FIRST_CELL: 534 /* 535 * Unexpected first cell 536 */ 537 soc->stat.err_fcell++; 538 LOG_ERROR(BSL_LS_SOC_COMMON, 539 (BSL_META_U(unit, 540 "UNIT %d SCHAN ERROR: Unexpected first cell\n"), 541 unit)); 542 break; 543 case SOC_SCERR_MMU_SOFT_RST: 544 /* 545 * MMU soft reset: received a second start cell without 546 * receiving and end cell for the previous packet. 547 */ 548 soc->stat.err_sr++; 549 LOG_ERROR(BSL_LS_SOC_COMMON, 550 (BSL_META_U(unit, 551 "UNIT %d SCHAN ERROR: MMU soft reset\n"), 552 unit)); 553 break; 554 case SOC_SCERR_CBP_CELL_CRC: 555 soc->stat.err_cellcrc++; 556 LOG_ERROR(BSL_LS_SOC_COMMON, 557 (BSL_META_U(unit, 558 "UNIT %d SCHAN ERROR: CBP Cell CRC error\n"), 559 unit)); 560 break; 561 case SOC_SCERR_CBP_HEADER_PARITY: 562 soc->stat.err_cbphp++; 563 LOG_ERROR(BSL_LS_SOC_COMMON, 564 (BSL_META_U(unit, 565 "UNIT %d SCHAN ERROR: CBP Header parity error\n"), 566 unit)); 567 break; 568 case SOC_SCERR_MMU_NPKT_CELLS: 569 soc->stat.err_npcell++; 570 LOG_ERROR(BSL_LS_SOC_COMMON, 571 (BSL_META_U(unit, 572 "UNIT %d SCHAN ERROR: " 573 "MMU sent cells not in packet\n"), 574 unit)); 575 break; 576 case SOC_SCERR_MEMORY_PARITY: 577 soc->stat.err_mp++; 578 break; 579 case SOC_SCERR_CELL_PTR_CRC: 580 soc->stat.err_cpcrc++; 581 LOG_ERROR(BSL_LS_SOC_COMMON, 582 (BSL_META_U(unit, 583 "UNIT %d SCHAN ERROR: Cell data CRC error\n"), 584 unit)); 585 break; 586 case SOC_SCERR_CELL_DATA_CRC: 587 soc->stat.err_cdcrc++; 588 LOG_ERROR(BSL_LS_SOC_COMMON, 589 (BSL_META_U(unit, 590 "UNIT %d SCHAN ERROR: Cell data CRC error\n"), 591 unit)); 592 break; 593 case SOC_SCERR_FRAME_DATA_CRC: 594 soc->stat.err_fdcrc++; 595 LOG_ERROR(BSL_LS_SOC_COMMON, 596 (BSL_META_U(unit, 597 "UNIT %d SCHAN ERROR: Frame data CRC error\n"), 598 unit)); 599 break; 600 case SOC_SCERR_CELL_PTR_BLOCK_CRC: 601 soc->stat.err_cpbcrc++; 602 LOG_ERROR(BSL_LS_SOC_COMMON, 603 (BSL_META_U(unit, 604 "UNIT %d SCHAN ERROR: " 605 "Cell pointer block CRC error\n"), 606 unit)); 607 break; 608 case SOC_SCERR_PLL_DLL_LOCK_LOSS: 609 soc->stat.err_pdlock++; 610 break; 611 case SOC_SCERR_MULTIPLE_ERR: 612 soc->stat.err_multi++; 613 LOG_ERROR(BSL_LS_SOC_COMMON, 614 (BSL_META_U(unit, 615 "UNIT %d SCHAN ERROR: Multiple errors: 0x%x\n"), 616 unit, err)); 617 break; 618 case SOC_SCERR_INVALID: 619 soc->stat.err_invalid++; 620 LOG_ERROR(BSL_LS_SOC_COMMON, 621 (BSL_META_U(unit, 622 "UNIT %d SCHAN ERROR: Unknown memory error\n"), 623 unit)); 624 break; 625 default: 626 assert(0); 627 break; 628 } 629 } 630 631 if (soc->schanIntrBlk != 0) { 632 soc_intr_disable(unit, IRQ_SCHAN_ERR); 633 634 sal_dpc_time(soc->schanIntrBlk, _soc_sch_error_unblock, 635 INT_TO_PTR(unit), 0, 0, 0, 0); 636 } 637 } 638 639 STATIC void 640 soc_intr_arl_mbuf(int unit, uint32 ignored) 641 { 642 soc_control_t *soc = SOC_CONTROL(unit); 643 644 COMPILER_REFERENCE(ignored); 645 646 #if defined(BCM_SCORPION_SUPPORT) 647 if (SOC_IS_SCORPION(unit)) { 648 /* Disbale Interrupt, same will be enbled after interrupt handling */ 649 soc_intr_disable(unit, IRQ_CHIP_FUNC_0); 650 soc->stat.intr_chip_func[0]++; 651 sal_dpc(soc_scorpion_l2_overflow_interrupt_handler, INT_TO_PTR(unit), 652 0, 0, 0, 0); 653 return; 654 } 655 #endif 656 657 #if defined(BCM_TRX_SUPPORT) 658 if (SOC_IS_TRX(unit)) { 659 /* IRQ_CHIP_FUNC_0 */ 660 soc_intr_disable(unit, IRQ_CHIP_FUNC_0); 661 soc->stat.intr_chip_func[0]++; 662 return; 663 } 664 #endif 665 666 /* 667 * Disable the interrupt; it is re-enabled by the ARL thread after 668 * it processes the messages. 669 */ 670 671 soc_intr_disable(unit, IRQ_ARL_MBUF); 672 673 soc->stat.intr_arl_m++; 674 675 if (soc->arl_notify) { 676 soc->arl_mbuf_done = 1; 677 if (!soc->arl_notified) { 678 soc->arl_notified = 1; 679 sal_sem_give(soc->arl_notify); 680 } 681 } 682 } 683 684 STATIC void 685 soc_intr_arl_drop(int unit, uint32 ignored) 686 { 687 soc_control_t *soc = SOC_CONTROL(unit); 688 689 COMPILER_REFERENCE(ignored); 690 691 #if defined(BCM_TRX_SUPPORT) 692 if (SOC_IS_TRX(unit)) { 693 /* IRQ_CHIP_FUNC_1 */ 694 soc_intr_disable(unit, IRQ_CHIP_FUNC_1); 695 soc->stat.intr_chip_func[1]++; 696 return; 697 } 698 #endif 699 700 soc_pci_analyzer_trigger(unit); 701 702 soc_intr_disable(unit, IRQ_ARL_MBUF_DROP); 703 704 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_ARL_MSG_DROPPED_CLR); 705 706 soc->stat.intr_arl_d++; 707 708 if (soc->arl_notify) { 709 soc->arl_msg_drop = 1; 710 if (!soc->arl_notified) { 711 soc->arl_notified = 1; 712 sal_sem_give(soc->arl_notify); 713 } 714 } 715 } 716 717 STATIC void 718 soc_intr_arl_cnt0(int unit, uint32 ignored) 719 { 720 soc_control_t *soc = SOC_CONTROL(unit); 721 722 COMPILER_REFERENCE(ignored); 723 724 #if defined(BCM_TRX_SUPPORT) 725 if (SOC_IS_TRX(unit)) { 726 /* IRQ_CHIP_FUNC_4 */ 727 soc_intr_disable(unit, IRQ_CHIP_FUNC_4); 728 #if defined(BCM_TRIUMPH_SUPPORT) 729 if (SOC_IS_TRIUMPH(unit)) { 730 sal_dpc(soc_triumph_esm_intr_status, INT_TO_PTR(unit), 731 0, 0, 0, 0); 732 } 733 #endif /* BCM_TRIUMPH_SUPPORT */ 734 #if defined(BCM_TRIUMPH2_SUPPORT) 735 if (SOC_IS_TRIUMPH2(unit)) { 736 sal_dpc(soc_triumph2_esm_intr_status, INT_TO_PTR(unit), 737 0, 0, 0, 0); 738 } 739 #endif /* BCM_TRIUMPH2_SUPPORT */ 740 soc->stat.intr_chip_func[4]++; 741 return; 742 } 743 #endif 744 745 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_ARL_DMA_EN_CLR); 746 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_ARL_DMA_DONE_CLR); 747 748 soc->stat.intr_arl_0++; 749 750 if (soc->arl_notify) { 751 soc->arl_dma_cnt0 = 1; 752 if (!soc->arl_notified) { 753 soc->arl_notified = 1; 754 sal_sem_give(soc->arl_notify); 755 } 756 } 757 } 758 759 STATIC void 760 soc_intr_arl_xfer(int unit, uint32 ignored) 761 { 762 soc_control_t *soc = SOC_CONTROL(unit); 763 764 COMPILER_REFERENCE(ignored); 765 766 #if defined(BCM_TRX_SUPPORT) 767 if (SOC_IS_TRX(unit)) { 768 /* IRQ_CHIP_FUNC_3 */ 769 soc_intr_disable(unit, IRQ_CHIP_FUNC_3); 770 #if defined(BCM_TRIUMPH_SUPPORT) 771 if (SOC_IS_TRIUMPH(unit)) { 772 sal_dpc(soc_triumph_esm_intr_status, INT_TO_PTR(unit), 773 0, 0, 0, 0); 774 } 775 #endif /* BCM_TRIUMPH_SUPPORT */ 776 #if defined(BCM_TRIUMPH2_SUPPORT) 777 if (SOC_IS_TRIUMPH2(unit)) { 778 sal_dpc(soc_triumph2_esm_intr_status, INT_TO_PTR(unit), 779 0, 0, 0, 0); 780 } 781 #endif /* BCM_TRIUMPH2_SUPPORT */ 782 soc->stat.intr_chip_func[3]++; 783 return; 784 } 785 #endif 786 787 soc_intr_disable(unit, IRQ_ARL_DMA_XFER); 788 789 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_ARL_DMA_XFER_DONE_CLR); 790 791 soc->stat.intr_arl_x++; 792 793 if (soc->arl_notify) { 794 soc->arl_dma_xfer = 1; 795 if (!soc->arl_notified) { 796 soc->arl_notified = 1; 797 sal_sem_give(soc->arl_notify); 798 } 799 } 800 } 801 802 STATIC void 803 soc_intr_tdma_done(int unit, uint32 ignored) 804 { 805 soc_control_t *soc = SOC_CONTROL(unit); 806 int cmc = SOC_PCI_CMC(unit); 807 int ch = soc->tdma_ch; 808 809 COMPILER_REFERENCE(ignored); 810 811 soc_intr_disable(unit, IRQ_TDMA_DONE); 812 813 soc->stat.intr_tdma++; 814 815 if (soc->tableDmaIntrEnb) { 816 sal_sem_give(soc->sbusDmaIntrs[cmc][ch]); 817 } 818 819 } 820 821 STATIC void 822 soc_intr_tslam_done(int unit, uint32 ignored) 823 { 824 soc_control_t *soc = SOC_CONTROL(unit); 825 int cmc = SOC_PCI_CMC(unit); 826 int ch = soc->tslam_ch; 827 828 COMPILER_REFERENCE(ignored); 829 830 soc_intr_disable(unit, IRQ_TSLAM_DONE); 831 832 soc->stat.intr_tslam++; 833 834 if (soc->tslamDmaIntrEnb) { 835 sal_sem_give(soc->sbusDmaIntrs[cmc][ch]); 836 } 837 } 838 839 STATIC void 840 soc_intr_gbp_full(int unit, uint32 ignored) 841 { 842 soc_control_t *soc = SOC_CONTROL(unit); 843 844 COMPILER_REFERENCE(ignored); 845 846 #if defined(BCM_TRX_SUPPORT) 847 if (SOC_IS_TRX(unit)) { 848 /* IRQ_CHIP_FUNC_2 */ 849 soc_intr_disable(unit, IRQ_CHIP_FUNC_2); 850 soc->stat.intr_chip_func[2]++; 851 return; 852 } 853 #endif 854 855 soc->stat.intr_gbp++; 856 857 soc_pci_analyzer_trigger(unit); 858 859 /* 860 * It doesn't make sense to "clear" this interrupt, so we disable 861 * the interrupt in the mask register and re-enable it some time 862 * later using a deferred procedure call. 863 */ 864 865 soc_intr_disable(unit, IRQ_GBP_FULL); 866 867 #ifdef BCM_GBP_SUPPORT 868 sal_dpc(_soc_gbp_full_block, INT_TO_PTR(unit), 0, 0, 0, 0); 869 #endif 870 } 871 872 STATIC void 873 soc_intr_link_stat(int unit, uint32 ignored) 874 { 875 soc_control_t *soc = SOC_CONTROL(unit); 876 877 COMPILER_REFERENCE(ignored); 878 879 soc_pci_analyzer_trigger(unit); 880 881 soc->stat.intr_ls++; 882 883 /* Clear interrupt */ 884 885 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_LINK_STAT_MSG_CLR); 886 887 /* Perform user callout, if one is registered */ 888 889 if (soc->soc_link_callout != NULL) { 890 (*soc->soc_link_callout)(unit); 891 } 892 } 893 894 /* 895 * PCI Parity and Fatal Error Reporting 896 * 897 * If the interrupt routine prints a message on each error, 898 * the console can be frozen or VxWorks workq overflow can occur. 899 * 900 * For this reason errors are counted for a period of time and 901 * reported together at a maximum rate. 902 */ 903 904 #define PCI_REPORT_TYPE_PARITY 1 905 #define PCI_REPORT_TYPE_FATAL 2 906 #define PCI_REPORT_PERIOD (SECOND_USEC / 4) 907 908 STATIC char *_soc_pci_dma_types[] = { 909 "DMA CH0", 910 "DMA CH1", 911 "DMA CH2", 912 "DMA CH3" 913 }; 914 915 STATIC char *_soc_pci_extended_dma_types[] = { 916 "Status write for TX and RX DMA CH0", /* 0 */ 917 "Table DMA", /* 1 */ 918 "Memory write for RX DMA CH0", /* 2 */ 919 "Stats DMA", /* 3 */ 920 "Status write for TX and RX DMA CH1", /* 4 */ 921 "Unknown", /* 5 */ 922 "Memory write for RX DMA CH1", /* 6 */ 923 "Unknown", /* 7 */ 924 "Status write for TX and RX DMA CH2", /* 8 */ 925 "Unknown", /* 9 */ 926 "Memory write for RX DMA CH2", /* 10 */ 927 "Unknown", /* 11 */ 928 "Status write for TX and RX DMA CH3", /* 12 */ 929 "Unknown", /* 13 */ 930 "Memory write for RX DMA CH3", /* 14 */ 931 "Unknown", /* 15 */ 932 "Descriptor read for TX and RX DMA CH0", /* 16 */ 933 "SLAM DMA", /* 17 */ 934 "Memory read for TX DMA CH0", /* 18 */ 935 "Unknown", /* 19 */ 936 "Descriptor read for TX and RX DMA CH1", /* 20 */ 937 "Unknown", /* 21 */ 938 "Memory read for TX DMA CH1", /* 22 */ 939 "Unknown", /* 23 */ 940 "Descriptor read for TX and RX DMA CH2", /* 24 */ 941 "Unknown", /* 25 */ 942 "Memory read for TX DMA CH2", /* 26 */ 943 "Unknown", /* 27 */ 944 "Descriptor read for TX and RX DMA CH3", /* 28 */ 945 "Unknown", /* 29 */ 946 "Memory read for TX DMA CH3", /* 30 */ 947 "Unknown" /* 31 */ 948 }; 949 950 STATIC char *_soc_pci_extended_trx_dma_types[] = { 951 "Table DMA", /* 0 */ 952 "Stats DMA", /* 1 */ 953 "Memory write for RX DMA CH0", /* 2 */ 954 "Memory write for RX DMA CH1", /* 3 */ 955 "Memory write for RX DMA CH2", /* 4 */ 956 "Memory write for RX DMA CH3", /* 5 */ 957 "Status write for TX and RX DMA CH0", /* 6 */ 958 "Status write for TX and RX DMA CH1", /* 7 */ 959 "Status write for TX and RX DMA CH2", /* 8 */ 960 "Status write for TX and RX DMA CH3", /* 9 */ 961 "SLAM DMA", /* 10 */ 962 "Memory read for TX DMA CH0", /* 11 */ 963 "Memory read for TX DMA CH1", /* 12 */ 964 "Memory read for TX DMA CH2", /* 13 */ 965 "Memory read for TX DMA CH3", /* 14 */ 966 "Descriptor read for TX and RX DMA CH0", /* 15 */ 967 "Descriptor read for TX and RX DMA CH1", /* 16 */ 968 "Descriptor read for TX and RX DMA CH2", /* 17 */ 969 "Descriptor read for TX and RX DMA CH3", /* 18 */ 970 "FIFO DMA CH0", /* 19 */ 971 "FIFO DMA CH1", /* 20 */ 972 "FIFO DMA CH2", /* 21 */ 973 "FIFO DMA CH3", /* 22 */ 974 "Unknown", /* 23 */ 975 "Unknown", /* 24 */ 976 "Unknown", /* 25 */ 977 "Unknown", /* 26 */ 978 "Unknown", /* 27 */ 979 "Unknown", /* 28 */ 980 "Unknown", /* 29 */ 981 "Unknown", /* 30 */ 982 "Unknown" /* 31 */ 983 }; 984 985 STATIC void 986 _soc_pci_report_error(void *p_unit, void *stat, void *type, 987 void *errcnt_dpc, void *p5) 988 { 989 int unit = PTR_TO_INT(p_unit); 990 soc_control_t *soc = SOC_CONTROL(unit); 991 uint32 errcnt_cur = 0, dmatype_code = 0; 992 char *errtype = NULL, *dmatype = NULL; 993 994 COMPILER_REFERENCE(p5); 995 996 switch (PTR_TO_INT(type)) { 997 case PCI_REPORT_TYPE_PARITY: 998 soc->pciParityDPC = 0; 999 errcnt_cur = soc->stat.intr_pci_pe; 1000 errtype = "Parity"; 1001 if (soc_feature(unit, soc_feature_extended_pci_error)) { 1002 dmatype_code = DS_EXT_PCI_PARITY_ERR(PTR_TO_INT(stat)); 1003 } else { 1004 dmatype_code = DS_PCI_PARITY_ERR(PTR_TO_INT(stat)); 1005 } 1006 break; 1007 case PCI_REPORT_TYPE_FATAL: 1008 soc->pciFatalDPC = 0; 1009 errcnt_cur = soc->stat.intr_pci_fe; 1010 errtype = "Fatal"; 1011 if (soc_feature(unit, soc_feature_extended_pci_error)) { 1012 dmatype_code = DS_EXT_PCI_FATAL_ERR(PTR_TO_INT(stat)); 1013 } else { 1014 dmatype_code = DS_PCI_FATAL_ERR(PTR_TO_INT(stat)); 1015 } 1016 break; 1017 } 1018 1019 if (soc_feature(unit, soc_feature_extended_pci_error)) { 1020 if (SOC_IS_TRX(unit)) { 1021 dmatype = 1022 _soc_pci_extended_trx_dma_types[dmatype_code]; 1023 } else { 1024 dmatype = _soc_pci_extended_dma_types[dmatype_code]; 1025 } 1026 } else { 1027 dmatype = _soc_pci_dma_types[dmatype_code]; 1028 } 1029 1030 if (errcnt_cur == PTR_TO_INT(errcnt_dpc) + 1) { 1031 LOG_ERROR(BSL_LS_SOC_COMMON, 1032 (BSL_META_U(unit, 1033 "UNIT %d ERROR interrupt: " 1034 "CMIC_DMA_STAT = 0x%08x " 1035 "PCI %s Error on %s\n"), 1036 unit, 1037 PTR_TO_INT(stat), 1038 errtype, dmatype)); 1039 } else { 1040 LOG_ERROR(BSL_LS_SOC_COMMON, 1041 (BSL_META_U(unit, 1042 "UNIT %d ERROR interrupt: " 1043 "%d PCI %s Errors on %s\n"), 1044 unit, errcnt_cur - PTR_TO_INT(errcnt_dpc), 1045 errtype, dmatype)); 1046 } 1047 } 1048 1049 STATIC void 1050 soc_intr_pci_parity(int unit, uint32 ignored) 1051 { 1052 soc_control_t *soc = SOC_CONTROL(unit); 1053 uint32 stat; 1054 int errcnt; 1055 1056 COMPILER_REFERENCE(ignored); 1057 1058 soc_pci_analyzer_trigger(unit); 1059 1060 stat = soc_pci_read(unit, CMIC_DMA_STAT); 1061 1062 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_PCI_PARITY_ERR_CLR); 1063 1064 errcnt = soc->stat.intr_pci_pe++; 1065 1066 if (!soc->pciParityDPC) { 1067 soc->pciParityDPC = 1; 1068 sal_dpc_time(PCI_REPORT_PERIOD, _soc_pci_report_error, 1069 INT_TO_PTR(unit), INT_TO_PTR(stat), 1070 INT_TO_PTR(PCI_REPORT_TYPE_PARITY), 1071 INT_TO_PTR(errcnt), 0); 1072 } 1073 } 1074 1075 STATIC void 1076 soc_intr_pci_fatal(int unit, uint32 ignored) 1077 { 1078 soc_control_t *soc = SOC_CONTROL(unit); 1079 uint32 stat; 1080 int errcnt; 1081 1082 COMPILER_REFERENCE(ignored); 1083 1084 soc_pci_analyzer_trigger(unit); 1085 1086 stat = soc_pci_read(unit, CMIC_DMA_STAT); 1087 1088 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_PCI_FATAL_ERR_CLR); 1089 1090 errcnt = soc->stat.intr_pci_fe++; 1091 1092 if (!soc->pciFatalDPC) { 1093 soc->pciFatalDPC = 1; 1094 sal_dpc_time(PCI_REPORT_PERIOD, _soc_pci_report_error, 1095 INT_TO_PTR(unit), INT_TO_PTR(stat), 1096 INT_TO_PTR(PCI_REPORT_TYPE_FATAL), 1097 INT_TO_PTR(errcnt), 0); 1098 } 1099 } 1100 1101 STATIC void 1102 soc_intr_i2c(int unit, uint32 ignored) 1103 { 1104 soc_control_t *soc = SOC_CONTROL(unit); 1105 1106 COMPILER_REFERENCE(ignored); 1107 1108 soc->stat.intr_i2c++; 1109 1110 #if defined (INCLUDE_I2C) && !defined (BCM_SAND_SUPPORT) 1111 soc_i2c_intr(unit); 1112 #else 1113 soc_intr_disable(unit, IRQ_I2C_INTR); 1114 #endif 1115 } 1116 1117 STATIC void 1118 soc_intr_miim_op(int unit, uint32 ignored) 1119 { 1120 soc_control_t *soc = SOC_CONTROL(unit); 1121 1122 COMPILER_REFERENCE(ignored); 1123 1124 soc_pci_write(unit, CMIC_SCHAN_CTRL, SC_MIIM_OP_DONE_CLR); 1125 1126 soc->stat.intr_mii++; 1127 1128 if (soc->miimIntr) { 1129 sal_sem_give(soc->miimIntr); 1130 } 1131 } 1132 1133 STATIC void 1134 soc_intr_stat_dma(int unit, uint32 ignored) 1135 { 1136 soc_control_t *soc = SOC_CONTROL(unit); 1137 1138 COMPILER_REFERENCE(ignored); 1139 1140 soc_pci_write(unit, CMIC_DMA_STAT, DS_STAT_DMA_ITER_DONE_CLR); 1141 1142 soc->stat.intr_stats++; 1143 1144 if (soc->counter_intr) { 1145 sal_sem_give(soc->counter_intr); 1146 } 1147 } 1148 1149 #ifdef BCM_HERCULES_SUPPORT 1150 1151 STATIC void 1152 _soc_intr_mmu_analyze(void *p_unit, void *p2, void *p3, void *p4, void *p5) 1153 { 1154 int unit = PTR_TO_INT(p_unit); 1155 1156 COMPILER_REFERENCE(p2); 1157 COMPILER_REFERENCE(p3); 1158 COMPILER_REFERENCE(p4); 1159 COMPILER_REFERENCE(p5); 1160 1161 if (soc_mmu_error_all(unit) < 0) { 1162 LOG_ERROR(BSL_LS_SOC_COMMON, 1163 (BSL_META_U(unit, 1164 "MMU error analysis failed, MMU interrupt disabled\n"))); 1165 } else { 1166 soc_intr_enable(unit, IRQ_MMU_IRQ_STAT); 1167 } 1168 } 1169 1170 STATIC void 1171 soc_intr_mmu_stat(int unit, uint32 ignored) 1172 { 1173 uint32 src, mask; 1174 soc_control_t *soc = SOC_CONTROL(unit); 1175 1176 COMPILER_REFERENCE(ignored); 1177 1178 src = soc_pci_read(unit, CMIC_MMUIRQ_STAT); 1179 mask = soc_pci_read(unit, CMIC_MMUIRQ_MASK); 1180 1181 mask &= ~src; 1182 1183 /* We know about the port(s), don't interrupt again until serviced */ 1184 soc_pci_write(unit, CMIC_MMUIRQ_MASK, mask); 1185 1186 soc->stat.intr_mmu++; 1187 1188 /* We'll turn this back on if we succeed in the analysis */ 1189 soc_intr_disable(unit, IRQ_MMU_IRQ_STAT); 1190 sal_dpc(_soc_intr_mmu_analyze, INT_TO_PTR(unit), 0, 0, 0, 0); 1191 } 1192 1193 #endif /* BCM_HERCULES_SUPPORT */ 1194 1195 1196 #if defined(BCM_XGS12_SWITCH_SUPPORT) 1197 STATIC void 1198 soc_intr_arl_error(int unit, uint32 ignored) 1199 { 1200 soc_control_t *soc; 1201 1202 COMPILER_REFERENCE(ignored); 1203 1204 soc = SOC_CONTROL(unit); 1205 soc->stat.intr_mmu++; /* should use separate counter */ 1206 soc_intr_disable(unit, IRQ_ARL_ERROR); 1207 1208 1209 LOG_ERROR(BSL_LS_SOC_COMMON, 1210 (BSL_META_U(unit, 1211 "UNIT %d ARL ERROR (bucket overflow or parity error\n"), 1212 unit)); 1213 } 1214 1215 #endif /* BCM_XGS12_SWITCH_SUPPORT */ 1216 1217 STATIC void 1218 soc_intr_bit21(int unit, uint32 ignored) 1219 { 1220 #ifdef BCM_TRX_SUPPORT 1221 if (SOC_IS_TRX(unit)) { 1222 soc_control_t *soc; 1223 soc = SOC_CONTROL(unit); 1224 1225 /* IRQ_FIFO_CH0_DMA */ 1226 soc_intr_disable(unit, IRQ_FIFO_CH0_DMA); 1227 soc->stat.intr_fifo_dma[0]++; 1228 1229 /* Clear FIFO_CH0_DMA_HOSTMEM_TIMEOUT bit */ 1230 WRITE_CMIC_FIFO_RD_DMA_DEBUGr(unit, 1); 1231 1232 if (soc->ipfixIntr) { 1233 /* Ingress IPFIX */ 1234 sal_sem_give(soc->ipfixIntr); 1235 } 1236 return; 1237 } 1238 #endif 1239 #ifdef BCM_HERCULES_SUPPORT 1240 if (SOC_IS_HERCULES(unit)) { 1241 soc_intr_mmu_stat(unit, ignored); 1242 } 1243 #endif /* BCM_HERCULES_SUPPORT */ 1244 1245 #if defined(BCM_XGS12_SWITCH_SUPPORT) 1246 if (SOC_IS_XGS12_SWITCH(unit)) { 1247 soc_intr_arl_error(unit, ignored); 1248 } 1249 #endif /* BCM_XGS_SWITCH_SUPPORT */ 1250 } 1251 1252 STATIC void 1253 soc_intr_bit22(int unit, uint32 ignored) 1254 { 1255 #ifdef BCM_TRX_SUPPORT 1256 if (SOC_IS_TRX(unit)) { 1257 soc_control_t *soc; 1258 soc = SOC_CONTROL(unit); 1259 1260 /* IRQ_FIFO_CH1_DMA */ 1261 soc_intr_disable(unit, IRQ_FIFO_CH1_DMA); 1262 soc->stat.intr_fifo_dma[1]++; 1263 1264 /* Clear FIFO_CH1_DMA_HOSTMEM_TIMEOUT bit */ 1265 WRITE_CMIC_FIFO_RD_DMA_DEBUGr(unit, 3); 1266 1267 if (soc->arl_notify) { 1268 /* Internal L2_MOD_FIFO */ 1269 sal_sem_give(soc->arl_notify); 1270 } 1271 return; 1272 } 1273 #endif 1274 } 1275 1276 STATIC void 1277 soc_intr_bit23(int unit, uint32 ignored) 1278 { 1279 #ifdef BCM_TRX_SUPPORT 1280 if (SOC_IS_TRX(unit)) { 1281 soc_control_t *soc; 1282 soc = SOC_CONTROL(unit); 1283 1284 /* IRQ_FIFO_CH2_DMA */ 1285 soc_intr_disable(unit, IRQ_FIFO_CH2_DMA); 1286 soc->stat.intr_fifo_dma[2]++; 1287 1288 /* Clear FIFO_CH2_DMA_HOSTMEM_TIMEOUT bit */ 1289 WRITE_CMIC_FIFO_RD_DMA_DEBUGr(unit, 5); 1290 1291 if (soc->arl_notify) { 1292 /* External EXT_L2_MOD_FIFO */ 1293 sal_sem_give(soc->arl_notify); 1294 } 1295 return; 1296 } 1297 #endif 1298 } 1299 1300 STATIC void 1301 soc_intr_lpm_lo_parity(int unit, uint32 ignored) 1302 { 1303 #ifdef BCM_TRX_SUPPORT 1304 if (SOC_IS_TRX(unit)) { 1305 soc_control_t *soc; 1306 soc = SOC_CONTROL(unit); 1307 1308 /* IRQ_FIFO_CH3_DMA */ 1309 soc_intr_disable(unit, IRQ_FIFO_CH3_DMA); 1310 soc->stat.intr_fifo_dma[3]++; 1311 1312 /* Clear FIFO_CH3_DMA_HOSTMEM_TIMEOUT bit */ 1313 WRITE_CMIC_FIFO_RD_DMA_DEBUGr(unit, 7); 1314 1315 if (soc->ipfixIntr) { 1316 /* Egress IPFIX */ 1317 sal_sem_give(soc->ipfixIntr); 1318 } 1319 return; 1320 } 1321 #endif 1322 } 1323 1324 STATIC void 1325 soc_intr_bit25(int unit, uint32 ignored) 1326 { 1327 } 1328 1329 STATIC void 1330 soc_intr_bit26(int unit, uint32 ignored) 1331 { 1332 } 1333 1334 STATIC void 1335 soc_intr_bit27(int unit, uint32 ignored) 1336 { 1337 } 1338 1339 STATIC void 1340 soc_intr_bit28(int unit, uint32 ignored) 1341 { 1342 soc_pci_analyzer_trigger(unit); 1343 1344 #if defined(BCM_XGS_SUPPORT) 1345 (void)soc_ser_parity_error_intr(unit); 1346 #endif 1347 } 1348 1349 STATIC void 1350 soc_intr_bit31(int unit, uint32 ignored) 1351 { 1352 #ifdef BCM_TRIUMPH2_SUPPORT 1353 if (soc_feature(unit, soc_feature_time_support)) { 1354 soc_control_t *soc = SOC_CONTROL(unit); 1355 soc_intr_disable(unit, IRQ_BROADSYNC_INTR); 1356 1357 /* Perform user callout, if one is registered */ 1358 if (soc->soc_time_callout != NULL) { 1359 (*soc->soc_time_callout)(unit); 1360 } 1361 soc_intr_enable(unit, IRQ_BROADSYNC_INTR); 1362 } 1363 #endif /* BCM_TRIUMPH2_SUPPORT */ 1364 } 1365 1366 1367 STATIC void 1368 soc_intr_block(int unit, uint32 block) 1369 { 1370 if (block < 32) { 1371 soc_intr_block_lo_disable(unit, (1<<block)); 1372 } else { 1373 soc_intr_block_hi_disable(unit, (1<<(block-32))); 1374 } 1375 sal_dpc(soc_cmn_block_error, INT_TO_PTR(unit), INT_TO_PTR(block), 0, 0, 0); 1376 } 1377 1378 /* 1379 * Enable (unmask) or disable (mask) a set of CMIC interrupts. These 1380 * routines should be used instead of manipulating CMIC_IRQ_MASK 1381 * directly, since a read-modify-write is required. The return value is 1382 * the previous mask (can pass mask of 0 to just get the current mask). 1383 */ 1384 1385 uint32 1386 soc_intr_enable(int unit, uint32 mask) 1387 { 1388 uint32 oldMask; 1389 uint32 newMask; 1390 int s; 1391 1392 s = sal_splhi(); 1393 oldMask = SOC_IRQ_MASK(unit); 1394 SOC_IRQ_MASK(unit) |= mask; 1395 newMask = SOC_IRQ_MASK(unit); 1396 /* In polled mode, the hardware IRQ mask is always zero */ 1397 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1398 newMask = 0; 1399 } 1400 IRQ_MASK_SET(unit, CMIC_IRQ_MASK, newMask); 1401 sal_spl(s); 1402 1403 return oldMask; 1404 } 1405 1406 uint32 1407 soc_intr_disable(int unit, uint32 mask) 1408 { 1409 uint32 oldMask; 1410 uint32 newMask; 1411 int s; 1412 1413 s = sal_splhi(); 1414 oldMask = SOC_IRQ_MASK(unit); 1415 SOC_IRQ_MASK(unit) &= ~mask; 1416 newMask = SOC_IRQ_MASK(unit); 1417 /* In polled mode, the hardware IRQ mask is always zero */ 1418 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1419 newMask = 0; 1420 } 1421 IRQ_MASK_SET(unit, CMIC_IRQ_MASK, newMask); 1422 sal_spl(s); 1423 1424 return oldMask; 1425 } 1426 1427 1428 /* 1429 * Enable (unmask) or disable (mask) a set of CMIC block specific interrupts. 1430 * soc_intr_block_lo_enable/disable handle block 0-31, while 1431 * soc_intr_block_hi_enable/disable handle block 32-63. 1432 * These routines should be used instead of manipulating CMIC_IRQ_MASK_1/CMIC_IRQ_MASK_2 1433 * directly, since a read-modify-write is required. The return value is 1434 * the previous mask (can pass mask of 0 to just get the current mask). 1435 */ 1436 1437 uint32 1438 soc_intr_block_lo_enable(int unit, uint32 mask) 1439 { 1440 uint32 oldMask = 0; 1441 1442 #ifdef BCM_DFE_SUPPORT 1443 { 1444 uint32 newMask; 1445 int s; 1446 1447 if (SOC_IS_DFE(unit)) { 1448 s = sal_splhi(); 1449 oldMask = SOC_IRQ1_MASK(unit); 1450 SOC_IRQ1_MASK(unit) |= mask; 1451 newMask = SOC_IRQ1_MASK(unit); 1452 LOG_VERBOSE(BSL_LS_SOC_INTR, 1453 (BSL_META("%s(): oldMask=0x%x, mask=0x%x, newMask=0x%x\n"), 1454 FUNCTION_NAME(), oldMask, mask, newMask)); 1455 /* In polled mode, the hardware IRQ mask is always zero */ 1456 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1457 newMask = 0; 1458 } 1459 soc_pci_write(unit, CMIC_IRQ_MASK_1, newMask); 1460 sal_spl(s); 1461 } 1462 } 1463 #endif /* BCM_DFE_SUPPORT */ 1464 return oldMask; 1465 } 1466 1467 uint32 1468 soc_intr_block_lo_disable(int unit, uint32 mask) 1469 { 1470 uint32 oldMask = 0; 1471 1472 #ifdef BCM_DFE_SUPPORT 1473 { 1474 uint32 newMask; 1475 int s; 1476 1477 if (SOC_IS_DFE(unit)) { 1478 s = sal_splhi(); 1479 oldMask = SOC_IRQ1_MASK(unit); 1480 SOC_IRQ1_MASK(unit) &= ~mask; 1481 newMask = SOC_IRQ1_MASK(unit); 1482 LOG_VERBOSE(BSL_LS_SOC_INTR, 1483 (BSL_META("%s(): oldMask=0x%x, mask=0x%x, newMask=0x%x\n"), 1484 FUNCTION_NAME(), oldMask, mask, newMask)); 1485 /* In polled mode, the hardware IRQ mask is always zero */ 1486 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1487 newMask = 0; 1488 } 1489 soc_pci_write(unit, CMIC_IRQ_MASK_1, newMask); 1490 sal_spl(s); 1491 } 1492 } 1493 #endif /* BCM_DFE_SUPPORT */ 1494 return oldMask; 1495 } 1496 1497 uint32 1498 soc_intr_block_hi_enable(int unit, uint32 mask) 1499 { 1500 uint32 oldMask = 0; 1501 1502 #ifdef BCM_DFE_SUPPORT 1503 { 1504 uint32 newMask; 1505 int s; 1506 1507 if (SOC_IS_DFE(unit)) { 1508 s = sal_splhi(); 1509 oldMask = SOC_IRQ2_MASK(unit); 1510 SOC_IRQ2_MASK(unit) |= mask; 1511 newMask = SOC_IRQ2_MASK(unit); 1512 LOG_VERBOSE(BSL_LS_SOC_INTR, 1513 (BSL_META("%s(): oldMask=0x%x, mask=0x%x, newMask=0x%x\n"), 1514 FUNCTION_NAME(), oldMask, mask, newMask)); 1515 /* In polled mode, the hardware IRQ mask is always zero */ 1516 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1517 newMask = 0; 1518 } 1519 soc_pci_write(unit, CMIC_IRQ_MASK_2, newMask); 1520 sal_spl(s); 1521 } 1522 } 1523 #endif /* BCM_DFE_SUPPORT */ 1524 1525 return oldMask; 1526 } 1527 1528 uint32 1529 soc_intr_block_hi_disable(int unit, uint32 mask) 1530 { 1531 uint32 oldMask = 0; 1532 1533 #ifdef BCM_DFE_SUPPORT 1534 { 1535 uint32 newMask; 1536 int s; 1537 1538 if (SOC_IS_DFE(unit)) { 1539 s = sal_splhi(); 1540 oldMask = SOC_IRQ2_MASK(unit); 1541 SOC_IRQ2_MASK(unit) &= ~mask; 1542 newMask = SOC_IRQ2_MASK(unit); 1543 LOG_VERBOSE(BSL_LS_SOC_INTR, 1544 (BSL_META("%s(): oldMask=0x%x, mask=0x%x, newMask=0x%x\n"), 1545 FUNCTION_NAME(), oldMask, mask, newMask)); 1546 /* In polled mode, the hardware IRQ mask is always zero */ 1547 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1548 newMask = 0; 1549 } 1550 soc_pci_write(unit, CMIC_IRQ_MASK_2, newMask); 1551 sal_spl(s); 1552 } 1553 } 1554 #endif /* BCM_DFE_SUPPORT */ 1555 return oldMask; 1556 } 1557 1558 /* 1559 * SOC Interrupt Service Routine 1560 * 1561 * In PLI simulation, the intr thread can call this routine at any 1562 * time. The connection is protected at the level of pli_{set/get}reg. 1563 */ 1564 1565 #define POLL_LIMIT 100000 1566 1567 void 1568 soc_intr(void *_unit) 1569 { 1570 uint32 irqStat, irqMask; 1571 soc_control_t *soc; 1572 int i = 0; 1573 int poll_limit = POLL_LIMIT; 1574 int unit = PTR_TO_INT(_unit); 1575 #ifdef SAL_SPL_LOCK_ON_IRQ 1576 int s; 1577 1578 s = sal_splhi(); 1579 #endif 1580 1581 soc = SOC_CONTROL(unit); 1582 1583 /* 1584 * Our handler is permanently registered in soc_probe(). If our 1585 * unit is not attached yet, it could not have generated this 1586 * interrupt. The interrupt line must be shared by multiple PCI 1587 * cards. Simply ignore the interrupt and let another handler 1588 * process it. 1589 */ 1590 if (soc == NULL || (soc->soc_flags & SOC_F_BUSY) || 1591 !(soc->soc_flags & SOC_F_ATTACHED)) { 1592 #ifdef SAL_SPL_LOCK_ON_IRQ 1593 sal_spl(s); 1594 #endif 1595 return; 1596 } 1597 1598 soc->stat.intr++; /* Update count */ 1599 1600 /* 1601 * Read IRQ Status and IRQ Mask and AND to determine active ints. 1602 * These are re-read each time since either can be changed by ISRs. 1603 * 1604 * Since interrupts are edge-driven, it's necessary to continue 1605 * processing them until the IRQ_STAT register reads zero. If we 1606 * return without doing that, we may never see another interrupt! 1607 */ 1608 for (;;) { 1609 irqStat = soc_pci_read(unit, CMIC_IRQ_STAT); 1610 if (irqStat == 0) { 1611 break; 1612 } 1613 irqMask = SOC_IRQ_MASK(unit); 1614 irqStat &= irqMask; 1615 if (irqStat == 0) { 1616 break; 1617 } 1618 1619 /* 1620 * find starting point for handler search 1621 * skip over blocks of high-priority but unlikely entries 1622 */ 1623 if ((irqStat & INTR_START2_MASK) == 0) { 1624 i = INTR_START2_POS; 1625 } else if ((irqStat & INTR_START1_MASK) == 0) { 1626 i = INTR_START1_POS; 1627 } else { 1628 i = 0; 1629 } 1630 1631 /* 1632 * We may have received an interrupt before all data has been 1633 * posted from the device or intermediate bridge. 1634 * The PCI specification requires that we read a device register 1635 * to make sure pending data is flushed. 1636 * Some bridges (we have determined through testing) require more 1637 * than one read. 1638 */ 1639 soc_pci_read(unit, CMIC_SCHAN_CTRL); 1640 soc_pci_read(unit, CMIC_IRQ_MASK); 1641 1642 for (; i < INTR_HANDLERS_COUNT; i++) { 1643 if (irqStat & soc_intr_handlers[i].mask) { 1644 1645 /* 1646 * Bit found, dispatch interrupt 1647 */ 1648 1649 LOG_INFO(BSL_LS_SOC_INTR, 1650 (BSL_META_U(unit, 1651 "soc_intr unit %d: dispatch %s\n"), 1652 unit, soc_intr_handlers[i].intr_name)); 1653 1654 (*soc_intr_handlers[i].intr_fn) 1655 (unit, soc_intr_handlers[i].intr_data); 1656 1657 /* 1658 * Prevent infinite loop in interrupt handler by 1659 * disabling the offending interrupt(s). 1660 */ 1661 1662 if (--poll_limit == 0) { 1663 LOG_ERROR(BSL_LS_SOC_COMMON, 1664 (BSL_META_U(unit, 1665 "soc_intr unit %d: " 1666 "ERROR can't clear interrupt(s): " 1667 "IRQ=0x%x (disabling 0x%x)\n"), 1668 unit, irqStat, soc_intr_handlers[i].mask)); 1669 soc_intr_disable(unit, soc_intr_handlers[i].mask); 1670 poll_limit = POLL_LIMIT; 1671 } 1672 1673 /* 1674 * Go back and re-read IRQ status. Start processing 1675 * from scratch since handler may clear more than one 1676 * bit. We don't leave the ISR until all of the bits 1677 * have been cleared and their handlers called. 1678 */ 1679 break; 1680 } 1681 } 1682 } 1683 1684 if (soc_feature(unit, soc_feature_extended_cmic_error)) { 1685 /* process block specific interrupts for block 0 - 31 */ 1686 for (;;) { 1687 irqStat = soc_pci_read(unit, CMIC_IRQ_STAT_1); 1688 if (irqStat == 0) { 1689 break; 1690 } 1691 irqMask = SOC_IRQ1_MASK(unit); 1692 irqStat &= irqMask; 1693 if (irqStat == 0) { 1694 break; 1695 } 1696 1697 /* 1698 * We may have received an interrupt before all data has been 1699 * posted from the device or intermediate bridge. 1700 * The PCI specification requires that we read a device register 1701 * to make sure pending data is flushed. 1702 * Some bridges (we have determined through testing) require more 1703 * than one read. 1704 */ 1705 soc_pci_read(unit, CMIC_SCHAN_CTRL); 1706 soc_pci_read(unit, CMIC_IRQ_MASK_1); 1707 1708 for (i=0 ; i < INTR_BLOCK_LO_HANDLERS_COUNT; i++) { 1709 if (irqStat & soc_intr_block_lo_handlers[i].mask) { 1710 1711 /* 1712 * Bit found, dispatch interrupt 1713 */ 1714 1715 LOG_INFO(BSL_LS_SOC_INTR, 1716 (BSL_META_U(unit, 1717 "soc_intr unit %d: dispatch %s\n"), 1718 unit, soc_intr_block_lo_handlers[i].intr_name)); 1719 1720 (*soc_intr_block_lo_handlers[i].intr_fn) 1721 (unit, soc_intr_block_lo_handlers[i].intr_data); 1722 1723 /* 1724 * Prevent infinite loop in interrupt handler by 1725 * disabling the offending interrupt(s). 1726 */ 1727 1728 if (--poll_limit == 0) { 1729 LOG_ERROR(BSL_LS_SOC_COMMON, 1730 (BSL_META_U(unit, 1731 "soc_intr unit %d: " 1732 "ERROR can't clear interrupt(s): " 1733 "IRQ=0x%x (disabling 0x%x)\n"), 1734 unit, irqStat, soc_intr_block_lo_handlers[i].mask)); 1735 soc_intr_block_lo_disable(unit, soc_intr_block_lo_handlers[i].mask); 1736 poll_limit = POLL_LIMIT; 1737 } 1738 1739 /* 1740 * Go back and re-read IRQ status. Start processing 1741 * from scratch since handler may clear more than one 1742 * bit. We don't leave the ISR until all of the bits 1743 * have been cleared and their handlers called. 1744 */ 1745 break; 1746 } 1747 } 1748 } 1749 1750 /* process block specific interrupts for block 32 - 63 */ 1751 for (;;) { 1752 irqStat = soc_pci_read(unit, CMIC_IRQ_STAT_2); 1753 if (irqStat == 0) { 1754 break; 1755 } 1756 irqMask = SOC_IRQ2_MASK(unit); 1757 irqStat &= irqMask; 1758 if (irqStat == 0) { 1759 break; 1760 } 1761 1762 /* 1763 * We may have received an interrupt before all data has been 1764 * posted from the device or intermediate bridge. 1765 * The PCI specification requires that we read a device register 1766 * to make sure pending data is flushed. 1767 * Some bridges (we have determined through testing) require more 1768 * than one read. 1769 */ 1770 soc_pci_read(unit, CMIC_SCHAN_CTRL); 1771 soc_pci_read(unit, CMIC_IRQ_MASK_2); 1772 1773 for (i=0; i < INTR_BLOCK_HI_HANDLERS_COUNT; i++) { 1774 if (irqStat & soc_intr_block_hi_handlers[i].mask) { 1775 1776 /* 1777 * Bit found, dispatch interrupt 1778 */ 1779 1780 LOG_INFO(BSL_LS_SOC_INTR, 1781 (BSL_META_U(unit, 1782 "soc_intr unit %d: dispatch %s\n"), 1783 unit, soc_intr_block_hi_handlers[i].intr_name)); 1784 1785 (*soc_intr_block_hi_handlers[i].intr_fn) 1786 (unit, soc_intr_block_hi_handlers[i].intr_data); 1787 1788 /* 1789 * Prevent infinite loop in interrupt handler by 1790 * disabling the offending interrupt(s). 1791 */ 1792 1793 if (--poll_limit == 0) { 1794 LOG_ERROR(BSL_LS_SOC_COMMON, 1795 (BSL_META_U(unit, 1796 "soc_intr unit %d: " 1797 "ERROR can't clear interrupt(s): " 1798 "IRQ=0x%x (disabling 0x%x)\n"), 1799 unit, irqStat, soc_intr_block_hi_handlers[i].mask)); 1800 soc_intr_block_hi_disable(unit, soc_intr_block_hi_handlers[i].mask); 1801 poll_limit = POLL_LIMIT; 1802 } 1803 1804 /* 1805 * Go back and re-read IRQ status. Start processing 1806 * from scratch since handler may clear more than one 1807 * bit. We don't leave the ISR until all of the bits 1808 * have been cleared and their handlers called. 1809 */ 1810 break; 1811 } 1812 } 1813 } 1814 } 1815 1816 if (soc_feature(unit, soc_feature_short_cmic_error)) { 1817 /* Using sal_dpc since there are schan reads in this function 1818 * and schan read cant be done from interrupt context. 1819 * the function soc_cmn_error will be excecuted only after this 1820 * function will end. 1821 */ 1822 sal_dpc(soc_cmn_error, INT_TO_PTR(unit), 0, 0, 0, 0); 1823 } 1824 1825 /* In polled mode, the hardware IRQ mask is always zero */ 1826 if (SOC_CONTROL(unit)->soc_flags & SOC_F_POLLED) { 1827 #ifdef SAL_SPL_LOCK_ON_IRQ 1828 sal_spl(s); 1829 #endif 1830 return; 1831 } 1832 /* 1833 * If the interrupt handler is not run in interrupt context, but 1834 * rather as a thread or a signal handler, the interrupt handler 1835 * must reenable interrupts on the switch controller. Currently 1836 * we don't distinguish between the two modes of operation, so 1837 * we always reenable interrupts here. 1838 */ 1839 IRQ_MASK_SET(unit, CMIC_IRQ_MASK, SOC_IRQ_MASK(unit)); 1840 if (soc_feature(unit, soc_feature_extended_cmic_error)) { 1841 soc_pci_write(unit, CMIC_IRQ_MASK_1, SOC_IRQ1_MASK(unit)); 1842 soc_pci_write(unit, CMIC_IRQ_MASK_2, SOC_IRQ2_MASK(unit)); 1843 } 1844 1845 1846 #ifdef SAL_SPL_LOCK_ON_IRQ 1847 sal_spl(s); 1848 #endif 1849 } 1850 1851 void soc_cmn_block_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4) 1852 { 1853 int blk, rc = SOC_E_NONE, is_valid, idx, i, nof_interrupts, is_enabled; 1854 soc_block_info_t* bi = NULL; 1855 soc_interrupt_db_t* interrupt, *prev_interrupt = NULL; 1856 int unit = PTR_TO_INT(unit_vp); /*unit should be set before SOC_INIT_FUNC_DEFS*/ 1857 soc_reg_above_64_val_t data, field; 1858 int interrupt_action; 1859 1860 if(!SOC_INTR_IS_SUPPORTED(unit)) { 1861 LOG_ERROR(BSL_LS_SOC_INTR, 1862 (BSL_META_U(unit, 1863 "No interrupts for device\n"))); 1864 return; 1865 } 1866 1867 blk = PTR_TO_INT(d1); 1868 1869 LOG_VERBOSE(BSL_LS_SOC_INTR, 1870 (BSL_META_U(unit, 1871 "enter \n"))); 1872 1873 for (i = 0; SOC_BLOCK_INFO(unit, i).type >= 0; i++) { 1874 if (SOC_INFO(unit).block_valid[i] && SOC_BLOCK2SCH(unit,i) == blk) { 1875 bi = &(SOC_BLOCK_INFO(unit, i)); 1876 break; 1877 } 1878 } 1879 1880 if (NULL == bi) { 1881 LOG_ERROR(BSL_LS_SOC_INTR, 1882 (BSL_META_U(unit, 1883 "Interrupt for unknown block %d\n"), 1884 blk)); 1885 return; 1886 } 1887 /* Coverity : 21737 */ 1888 if (NULL == SOC_CONTROL(unit)->interrupts_info->interrupt_db_info) { 1889 LOG_ERROR(BSL_LS_SOC_INTR, 1890 (BSL_META_U(unit, "No interrupts for device\n"))); 1891 return; 1892 } 1893 soc_nof_interrupts(unit, &nof_interrupts); 1894 1895 for (idx = 0; idx < nof_interrupts; idx++) { 1896 /* Advance to next interrupt */ 1897 interrupt = &SOC_CONTROL(unit)->interrupts_info->interrupt_db_info[idx]; 1898 1899 rc = soc_interrupt_is_valid(unit, bi, interrupt, &is_valid); 1900 if (SOC_FAILURE(rc)) { 1901 LOG_ERROR(BSL_LS_SOC_INTR, 1902 (BSL_META_U(unit, 1903 "%s\n"), soc_errmsg(rc))); 1904 return; 1905 } 1906 if(!is_valid) { 1907 continue; 1908 } 1909 1910 rc = soc_interrupt_is_enabled(unit, bi->number, interrupt, &is_enabled); 1911 if (SOC_FAILURE(rc)) { 1912 LOG_ERROR(BSL_LS_SOC_INTR, 1913 (BSL_META_U(unit, 1914 "%s\n"), soc_errmsg(rc))); 1915 return; 1916 } 1917 if (!is_enabled) { 1918 continue; 1919 } 1920 1921 interrupt_action = 0; 1922 if ((NULL != prev_interrupt) && (prev_interrupt->reg == interrupt->reg) && (prev_interrupt->reg_index == interrupt->reg_index)) { 1923 soc_reg_above_64_field_get(unit, interrupt->reg, data, interrupt->field, field); 1924 } else { 1925 rc = soc_reg_above_64_get(unit, interrupt->reg, bi->number, interrupt->reg_index, data); 1926 if(SOC_FAILURE(rc)) { 1927 prev_interrupt = NULL; 1928 LOG_ERROR(BSL_LS_SOC_INTR, 1929 (BSL_META_U(unit, 1930 "%s\n"), soc_errmsg(rc))); 1931 return; 1932 } 1933 1934 prev_interrupt = interrupt; 1935 soc_reg_above_64_field_get(unit, interrupt->reg, data, interrupt->field, field); 1936 } 1937 1938 if (!SOC_REG_ABOVE_64_IS_ZERO(field)) { 1939 if(interrupt->bit_in_field!= SOC_INTERRUPT_BIT_FIELD_DONT_CARE ) { 1940 interrupt_action = SHR_BITGET(field, interrupt->bit_in_field); 1941 } else { 1942 interrupt_action = 1; 1943 } 1944 } 1945 1946 /* CallBack */ 1947 if(interrupt_action) { 1948 soc_event_generate(unit, SOC_SWITCH_EVENT_DEVICE_INTERRUPT, idx, bi->number, 0); 1949 } 1950 } 1951 1952 if (blk < 32) { 1953 soc_intr_block_lo_enable(unit, (1<<blk)); 1954 } else { 1955 soc_intr_block_hi_enable(unit, (1<<(blk-32))); 1956 } 1957 } 1958 1959 void soc_cmn_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4) 1960 { 1961 int rc = SOC_E_NONE, i; 1962 int unit = PTR_TO_INT(unit_vp); 1963 int flags = 0; 1964 int max_interrupts_size = INTR_CMN_ERROR_MAX_INTERRUPTS_SIZE; 1965 soc_interrupt_cause_t interrupts[INTR_CMN_ERROR_MAX_INTERRUPTS_SIZE]; 1966 int total_interrupts = 0; 1967 int interrupt_num = INTR_CMN_ERROR_MAX_INTERRUPTS_SIZE; 1968 1969 sal_memset(interrupts, 0x0, INTR_CMN_ERROR_MAX_INTERRUPTS_SIZE * sizeof(soc_interrupt_cause_t)); 1970 1971 /* Get all current Active interrupts */ 1972 flags = SOC_ACTIVE_INTERRUPTS_GET_UNMASKED_ONLY; 1973 rc = soc_active_interrupts_get(unit, flags, max_interrupts_size, interrupts, &total_interrupts); 1974 if (SOC_FAILURE(rc)) { 1975 LOG_ERROR(BSL_LS_SOC_INTR, 1976 (BSL_META_U(unit, 1977 "%s\n"), soc_errmsg(rc))); 1978 return; 1979 } 1980 1981 LOG_VERBOSE(BSL_LS_SOC_INTR, 1982 (BSL_META_U(unit, 1983 "interrupt_num=%d, max_interrupts_size=%d, total_interrupts=%d\n"), 1984 interrupt_num, max_interrupts_size, total_interrupts)); 1985 1986 if (interrupt_num > total_interrupts) { 1987 interrupt_num = total_interrupts; 1988 } 1989 1990 /* sort interrupts according to priority */ 1991 if(interrupt_num > 1) { 1992 rc = soc_sort_interrupts_according_to_priority(unit, interrupts, interrupt_num); 1993 if (SOC_FAILURE(rc)) { 1994 LOG_ERROR(BSL_LS_SOC_INTR, 1995 (BSL_META_U(unit, 1996 "%s\n"), soc_errmsg(rc))); 1997 return; 1998 } 1999 } 2000 2001 /* Call CB for every Active interrupt */ 2002 for (i = 0; i < interrupt_num; i++) { 2003 #if defined(BCM_JERICHO_SUPPORT) || defined(BCM_88950_SUPPORT) 2004 uint32 interrupt_flags; 2005 /* at Jericho & FE3200 new interrupt mechanism applied, we need to call bcm cb (dcmn_intr_switch_event_cb) and also to user cb only if applicable */ 2006 if (SOC_IS_JERICHO(unit) || SOC_IS_FE3200(unit)) { 2007 dcmn_intr_switch_event_cb(unit, SOC_SWITCH_EVENT_DEVICE_INTERRUPT, interrupts[i].id, interrupts[i].index, 0, 0); 2008 rc = soc_interrupt_flags_get(unit, interrupts[i].id, &interrupt_flags); 2009 if (SOC_FAILURE(rc)) { 2010 LOG_ERROR(BSL_LS_SOC_INTR, (BSL_META_U(unit, "%s\n"), soc_errmsg(rc))); 2011 return; 2012 } 2013 if (((interrupt_flags & SOC_INTERRUPT_DB_FLAGS_BCM_AND_USR_CB) == 0) && (SHR_BITGET(&interrupt_flags, SOC_INTERRUPT_DB_FLAGS_CORR_ACT_OVERRIDE_ENABLE) == 0)) { 2014 continue; 2015 } 2016 } 2017 #endif 2018 soc_event_generate(unit, SOC_SWITCH_EVENT_DEVICE_INTERRUPT, interrupts[i].id, interrupts[i].index, 0); 2019 } 2020 2021 /* Enable interrups */ 2022 if (soc_feature(unit, soc_feature_cmicm)) { 2023 if (SOC_IS_ARAD(unit)) { 2024 #ifdef BCM_CMICM_SUPPORT 2025 int cmc = SOC_PCI_CMC(unit); 2026 soc_pci_write(unit, CMIC_CMCx_PCIE_IRQ_MASK3_OFFSET(cmc), SOC_CMCx_IRQ3_MASK(unit, cmc)); 2027 soc_pci_write(unit, CMIC_CMCx_PCIE_IRQ_MASK4_OFFSET(cmc), SOC_CMCx_IRQ4_MASK(unit, cmc)); 2028 if (soc_feature(unit, soc_feature_cmicm_extended_interrupts)) { 2029 soc_pci_write(unit, CMIC_CMCx_PCIE_IRQ_MASK5_OFFSET(cmc), SOC_CMCx_IRQ5_MASK(unit, cmc)); 2030 soc_pci_write(unit, CMIC_CMCx_PCIE_IRQ_MASK6_OFFSET(cmc), SOC_CMCx_IRQ6_MASK(unit, cmc)); 2031 } else { 2032 soc_pci_write(unit, CMIC_CMCx_PCIE_IRQ_MASK2_OFFSET(cmc), SOC_CMCx_IRQ2_MASK(unit, cmc)); 2033 } 2034 #endif 2035 } 2036 } else { 2037 soc_pci_write(unit, CMIC_IRQ_MASK_1, SOC_IRQ1_MASK(unit)); 2038 soc_pci_write(unit, CMIC_IRQ_MASK_2, SOC_IRQ2_MASK(unit)); 2039 } 2040 2041 #ifdef PLISIM 2042 if (SAL_BOOT_PLISIM) { 2043 /* Turn off Interrupts in PCID - to avoid endless loop */ 2044 if (soc_feature(unit, soc_feature_cmicm)) { 2045 if (SOC_IS_ARAD(unit)) { 2046 #ifdef BCM_CMICM_SUPPORT 2047 int cmc = SOC_PCI_CMC(unit); 2048 soc_pci_write(unit, CMIC_CMCx_IRQ_STAT2_OFFSET(cmc), 0x0); 2049 soc_pci_write(unit, CMIC_CMCx_IRQ_STAT4_OFFSET(cmc), 0x0); 2050 soc_pci_write(unit, CMIC_CMCx_IRQ_STAT3_OFFSET(cmc), 0x0); 2051 #endif 2052 } 2053 } else { 2054 soc_pci_write(unit, CMIC_IRQ_STAT_1, 0x0); 2055 soc_pci_write(unit, CMIC_IRQ_STAT_2, 0x0); 2056 } 2057 } 2058 #endif 2059 } 2060 2061 int soc_interrupt_is_valid(int unit, const soc_block_info_t* bi, const soc_interrupt_db_t* inter, int* is_valid /*out*/) 2062 { 2063 if (bi == NULL || inter == NULL || is_valid == NULL) { 2064 LOG_ERROR(BSL_LS_SOC_INTR, 2065 (BSL_META_U(unit, 2066 "Null parameter\n"))); 2067 return SOC_E_PARAM; 2068 } 2069 2070 if(!SOC_REG_IS_VALID(unit, inter->reg)){ 2071 *is_valid = 0; 2072 } else { 2073 if(SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit,inter->reg).block, bi->type)) { 2074 *is_valid = 1; 2075 } else { 2076 *is_valid = 0; 2077 } 2078 } 2079 2080 return SOC_E_NONE; 2081 } 2082 2083 /* 2084 */ 2085 int soc_interrupt_get(int unit, int block_instance , const soc_interrupt_db_t* inter, int* inter_val /*out*/) 2086 { 2087 soc_reg_above_64_val_t data, field, field_mask; 2088 int rc = SOC_E_NONE; 2089 2090 if (inter == NULL || inter_val == NULL) { 2091 LOG_ERROR(BSL_LS_SOC_INTR, 2092 (BSL_META_U(unit, 2093 "Null parameter\n"))); 2094 return SOC_E_PARAM; 2095 } 2096 2097 if(!SOC_REG_IS_VALID(unit, inter->reg)){ 2098 LOG_ERROR(BSL_LS_SOC_INTR, 2099 (BSL_META_U(unit, 2100 "Invalid register for the device\n"))); 2101 return SOC_E_INTERNAL; 2102 } 2103 2104 rc = soc_reg_above_64_get(unit, inter->reg, block_instance, inter->reg_index, data); 2105 if (SOC_FAILURE(rc)) { 2106 LOG_ERROR(BSL_LS_SOC_INTR, 2107 (BSL_META_U(unit, 2108 "%s\n"), soc_errmsg(rc))); 2109 return rc; 2110 } 2111 2112 soc_reg_above_64_field_get(unit, inter->reg, data, inter->field, field); 2113 2114 if (inter->bit_in_field != SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2115 SOC_REG_ABOVE_64_CREATE_MASK(field_mask, 0x1, inter->bit_in_field); 2116 SOC_REG_ABOVE_64_AND(field, field_mask); 2117 } 2118 2119 *inter_val = (SOC_REG_ABOVE_64_IS_ZERO(field) ? 0x0 : 0x1); 2120 2121 return rc; 2122 } 2123 2124 /* 2125 * Function: 2126 * soc_interrupt_force_get 2127 * Description: 2128 * Set/Clear interrupt test registers bits & appropriate mask register 2129 * Parameters: 2130 * unit - Device unit number 2131 * block_instance - block_instance 2132 * inter - interrupt info 2133 * *inter_val - return value 2134 * Returns: 2135 * BCM_E_xxx 2136 */ 2137 int soc_interrupt_force_get(int unit, int block_instance, const soc_interrupt_db_t* inter, int* inter_val) 2138 { 2139 #if defined(BCM_SAND_SUPPORT) 2140 soc_reg_above_64_val_t data , field_mask; 2141 soc_field_info_t *finfop; 2142 int rc = SOC_E_NONE; 2143 int curr_bit; 2144 2145 if (inter == NULL) { 2146 LOG_ERROR(BSL_LS_SOC_INTR, 2147 (BSL_META_U(unit, 2148 "Null parameter\n"))); 2149 return SOC_E_PARAM; 2150 } 2151 2152 SOC_REG_ABOVE_64_CLEAR(data); 2153 2154 *inter_val = 0; /* When force is not supported */ 2155 2156 if (inter->reg_test != INVALIDr && inter->vector_id != 1) { 2157 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2158 LOG_ERROR(BSL_LS_SOC_INTR, 2159 (BSL_META_U(unit, 2160 "Invalid mask register for the device\n"))); 2161 return SOC_E_INTERNAL; 2162 } 2163 2164 rc = soc_reg_above_64_get(unit, inter->reg_test, block_instance, inter->mask_reg_index, data); 2165 if (SOC_FAILURE(rc)) { 2166 LOG_ERROR(BSL_LS_SOC_INTR, 2167 (BSL_META_U(unit, 2168 "%s\n"), soc_errmsg(rc))); 2169 return rc; 2170 } 2171 2172 SOC_FIND_FIELD(inter->field, 2173 SOC_REG_INFO(unit, inter->reg).fields, 2174 SOC_REG_INFO(unit, inter->reg).nFields, 2175 finfop); 2176 if (finfop == NULL) { 2177 LOG_ERROR(BSL_LS_SOC_INTR, 2178 (BSL_META_U(unit, 2179 "Invalid Field Name for the event\n"))); 2180 return SOC_E_INTERNAL; 2181 } 2182 2183 curr_bit = finfop->bp; 2184 if (inter->bit_in_field != SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2185 curr_bit += inter->bit_in_field; 2186 } 2187 2188 SOC_REG_ABOVE_64_CREATE_MASK(field_mask, 0x1, curr_bit); 2189 SOC_REG_ABOVE_64_AND(data, field_mask); 2190 *inter_val = (SOC_REG_ABOVE_64_IS_ZERO(data) ? 0x0 : 0x1); 2191 } 2192 2193 2194 return rc; 2195 #else 2196 return 0; 2197 #endif 2198 } 2199 2200 int soc_interrupt_enable(int unit, int block_instance, const soc_interrupt_db_t* inter) 2201 { 2202 soc_reg_above_64_val_t data, field; 2203 int rc = SOC_E_NONE; 2204 2205 if (inter == NULL) { 2206 LOG_ERROR(BSL_LS_SOC_INTR, 2207 (BSL_META_U(unit, 2208 "Null parameter\n"))); 2209 return SOC_E_PARAM; 2210 } 2211 2212 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2213 LOG_ERROR(BSL_LS_SOC_INTR, 2214 (BSL_META_U(unit, 2215 "Invalid mask register for the device\n"))); 2216 return SOC_E_INTERNAL; 2217 } 2218 2219 rc = soc_reg_above_64_get(unit, inter->mask_reg, block_instance, inter->mask_reg_index, data); 2220 if (SOC_FAILURE(rc)) { 2221 LOG_ERROR(BSL_LS_SOC_INTR, 2222 (BSL_META_U(unit, 2223 "%s\n"), soc_errmsg(rc))); 2224 return rc; 2225 } 2226 2227 if (inter->bit_in_field == SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2228 SOC_REG_ABOVE_64_CLEAR(field); 2229 SHR_BITSET(field, 0x0); 2230 } else { 2231 soc_reg_above_64_field_get(unit, inter->mask_reg, data, inter->mask_field, field); 2232 SHR_BITSET(field, inter->bit_in_field); 2233 } 2234 2235 soc_reg_above_64_field_set(unit, inter->mask_reg, data, inter->mask_field, field); 2236 2237 rc = soc_reg_above_64_set(unit, inter->mask_reg, block_instance, inter->mask_reg_index, data); 2238 if (SOC_FAILURE(rc)) { 2239 LOG_ERROR(BSL_LS_SOC_INTR, 2240 (BSL_META_U(unit, 2241 "%s\n"), soc_errmsg(rc))); 2242 } 2243 2244 return rc; 2245 } 2246 2247 /* 2248 * Function: 2249 * soc_interrupt_force 2250 * Description: 2251 * Set/Clear interrupt test registers bits & appropriate mask register 2252 * Parameters: 2253 * unit - Device unit number 2254 * block_instance - block_instance 2255 * inter - interrupt info 2256 * action - action to do - 0 enable force interrupts, 1 - disable it 2257 * Returns: 2258 * BCM_E_xxx 2259 */ 2260 int soc_interrupt_force(int unit, int block_instance, const soc_interrupt_db_t* inter, int action) 2261 { 2262 #if defined(BCM_SAND_SUPPORT) 2263 soc_reg_above_64_val_t data; /* , field; */ 2264 soc_field_info_t *finfop; 2265 int rc = SOC_E_NONE; 2266 int curr_bit; 2267 2268 if (inter == NULL) { 2269 LOG_ERROR(BSL_LS_SOC_INTR, 2270 (BSL_META_U(unit, 2271 "Null parameter\n"))); 2272 return SOC_E_PARAM; 2273 } 2274 2275 if (inter->reg_test != INVALIDr && inter->vector_id != 1) { 2276 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2277 LOG_ERROR(BSL_LS_SOC_INTR, 2278 (BSL_META_U(unit, 2279 "Invalid mask register for the device\n"))); 2280 return SOC_E_INTERNAL; 2281 } 2282 2283 rc = soc_reg_above_64_get(unit, inter->reg_test, block_instance, inter->reg_index, data); 2284 if (SOC_FAILURE(rc)) { 2285 LOG_ERROR(BSL_LS_SOC_INTR, 2286 (BSL_META_U(unit, 2287 "%s\n"), soc_errmsg(rc))); 2288 return rc; 2289 } 2290 2291 SOC_FIND_FIELD(inter->field, 2292 SOC_REG_INFO(unit, inter->reg).fields, 2293 SOC_REG_INFO(unit, inter->reg).nFields, 2294 finfop); 2295 if (finfop == NULL) { 2296 LOG_ERROR(BSL_LS_SOC_INTR, 2297 (BSL_META_U(unit, 2298 "Invalid Field Name for the event\n"))); 2299 return SOC_E_INTERNAL; 2300 } 2301 2302 curr_bit = finfop->bp; 2303 if (inter->bit_in_field != SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2304 curr_bit += inter->bit_in_field; 2305 } 2306 2307 2308 if (action == 0) { /* enable force*/ 2309 /* SOC_REG_ABOVE_64_CLEAR(data); */ 2310 SHR_BITSET(data, curr_bit); 2311 } else if (action == 1){ /* disable force*/ 2312 SHR_BITCLR(data, curr_bit); 2313 } else { 2314 LOG_ERROR(BSL_LS_SOC_INTR, 2315 (BSL_META_U(unit, 2316 "Invalid action\n"))); 2317 return SOC_E_INTERNAL; 2318 } 2319 2320 rc = soc_reg_above_64_set(unit, inter->reg_test, block_instance, inter->reg_index, data); 2321 if (SOC_FAILURE(rc)) { 2322 LOG_ERROR(BSL_LS_SOC_INTR, 2323 (BSL_META_U(unit, 2324 "%s\n"), soc_errmsg(rc))); 2325 return rc; 2326 } 2327 } 2328 2329 return rc; 2330 2331 #else 2332 return 0; 2333 #endif 2334 } 2335 2336 int soc_interrupt_disable(int unit, int block_instance, const soc_interrupt_db_t* inter) 2337 { 2338 soc_reg_above_64_val_t data, field; 2339 int rc = SOC_E_NONE; 2340 2341 if (inter == NULL) { 2342 LOG_ERROR(BSL_LS_SOC_INTR, 2343 (BSL_META_U(unit, 2344 "Null parameter\n"))); 2345 return SOC_E_PARAM; 2346 } 2347 2348 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2349 LOG_ERROR(BSL_LS_SOC_INTR, 2350 (BSL_META_U(unit, 2351 "Invalid mask register for the device\n"))); 2352 return SOC_E_INTERNAL; 2353 } 2354 2355 rc = soc_reg_above_64_get(unit, inter->mask_reg, block_instance, inter->mask_reg_index, data); 2356 if (SOC_FAILURE(rc)) { 2357 LOG_ERROR(BSL_LS_SOC_INTR, 2358 (BSL_META_U(unit, 2359 "%s\n"), soc_errmsg(rc))); 2360 return rc; 2361 } 2362 2363 if (inter->bit_in_field == SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2364 SOC_REG_ABOVE_64_CLEAR(field); 2365 } else { 2366 soc_reg_above_64_field_get(unit, inter->mask_reg, data, inter->mask_field, field); 2367 SHR_BITCLR(field, inter->bit_in_field); 2368 } 2369 2370 soc_reg_above_64_field_set(unit, inter->mask_reg, data, inter->mask_field, field); 2371 2372 rc = soc_reg_above_64_set(unit, inter->mask_reg, block_instance, inter->mask_reg_index, data); 2373 if (SOC_FAILURE(rc)) { 2374 LOG_ERROR(BSL_LS_SOC_INTR, 2375 (BSL_META_U(unit, 2376 "%s\n"), soc_errmsg(rc))); 2377 } 2378 2379 return rc; 2380 } 2381 2382 int soc_interrupt_is_enabled(int unit, int block_instance, const soc_interrupt_db_t* inter, int* is_enabled /*out*/) 2383 { 2384 soc_reg_above_64_val_t data, field, field_mask; 2385 int rc = SOC_E_NONE; 2386 2387 if (inter == NULL) { 2388 LOG_ERROR(BSL_LS_SOC_INTR, 2389 (BSL_META_U(unit, 2390 "Null parameter\n"))); 2391 return SOC_E_PARAM; 2392 } 2393 2394 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2395 LOG_ERROR(BSL_LS_SOC_INTR, 2396 (BSL_META_U(unit, 2397 "Invalid mask register for the device\n"))); 2398 return SOC_E_INTERNAL; 2399 } 2400 2401 rc = soc_reg_above_64_get(unit, inter->mask_reg, block_instance, inter->mask_reg_index, data); 2402 if (SOC_FAILURE(rc)) { 2403 LOG_ERROR(BSL_LS_SOC_INTR, 2404 (BSL_META_U(unit, 2405 "%s\n"), soc_errmsg(rc))); 2406 return rc; 2407 } 2408 2409 soc_reg_above_64_field_get(unit, inter->mask_reg, data, inter->mask_field, field); 2410 2411 if (inter->bit_in_field != SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2412 SOC_REG_ABOVE_64_CREATE_MASK(field_mask, 0x1, inter->bit_in_field); 2413 SOC_REG_ABOVE_64_AND(field, field_mask); 2414 } 2415 2416 *is_enabled = (SOC_REG_ABOVE_64_IS_ZERO(field) ? 0x0 : 0x1); 2417 2418 return rc; 2419 } 2420 2421 int soc_interrupt_is_supported(int unit, int block_instance, int inter_id) 2422 { 2423 int rc; 2424 int is_block_valid; 2425 int nof_interrupts; 2426 soc_interrupt_db_t *inter, *interrupts; 2427 soc_block_types_t block_types; 2428 int blk; 2429 2430 interrupts = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2431 if (interrupts == NULL) { 2432 return FALSE; 2433 } 2434 2435 /* verify interrupt_id */ 2436 soc_nof_interrupts(unit, &nof_interrupts); 2437 if ((inter_id > nof_interrupts) || inter_id < 0) { 2438 return FALSE; 2439 } 2440 2441 inter = &(interrupts[inter_id]); 2442 if (!SOC_REG_IS_VALID(unit, inter->reg)) { 2443 return FALSE; 2444 } 2445 2446 if (inter->vector_id) { 2447 /* it is vector */ 2448 return FALSE; 2449 } 2450 block_types = SOC_REG_INFO(unit, inter->reg).block; 2451 2452 rc = soc_is_valid_block_instance(unit, block_types, block_instance, &is_block_valid); 2453 if(SOC_FAILURE(rc) || !is_block_valid) { 2454 return FALSE; 2455 } 2456 2457 SOC_BLOCK_ITER(unit, blk, *block_types) { 2458 if (SOC_BLOCK_INFO(unit, blk).number == block_instance) { 2459 return TRUE; 2460 } 2461 } 2462 2463 return FALSE; 2464 } 2465 2466 /* 2467 * Interrupt Clear Functions 2468 */ 2469 int soc_interrupt_clear_on_write(int unit, int block_instance, int interrupt_id) 2470 { 2471 soc_reg_above_64_val_t data, field; 2472 int rc = SOC_E_NONE; 2473 int nof_interrupts; 2474 soc_interrupt_db_t *inter, *interrupts; 2475 2476 if (!SOC_INTR_IS_SUPPORTED(unit)) { 2477 LOG_ERROR(BSL_LS_SOC_INTR, 2478 (BSL_META_U(unit, 2479 "No interrupts for device\n"))); 2480 return SOC_E_UNAVAIL; 2481 } 2482 2483 interrupts = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2484 if (interrupts == NULL) { 2485 LOG_ERROR(BSL_LS_SOC_INTR, 2486 (BSL_META_U(unit, 2487 "Null parameter\n"))); 2488 return SOC_E_PARAM; 2489 } 2490 2491 /*verify interrupt_id*/ 2492 soc_nof_interrupts(unit, &nof_interrupts); 2493 if ((interrupt_id > nof_interrupts) || interrupt_id < 0) { 2494 LOG_ERROR(BSL_LS_SOC_INTR, 2495 (BSL_META_U(unit, 2496 "event_id is unavail\n"))); 2497 return SOC_E_UNAVAIL; 2498 } 2499 2500 inter = &(interrupts[interrupt_id]); 2501 if (!SOC_REG_IS_VALID(unit, inter->reg)) { 2502 LOG_ERROR(BSL_LS_SOC_INTR, 2503 (BSL_META_U(unit, 2504 "Invalid register for the device\n"))); 2505 return SOC_E_INTERNAL; 2506 } 2507 2508 if (!SOC_REG_IS_VALID(unit, inter->mask_reg)) { 2509 LOG_ERROR(BSL_LS_SOC_INTR, 2510 (BSL_META_U(unit, 2511 "Invalid mask register for the device\n"))); 2512 return SOC_E_INTERNAL; 2513 } 2514 2515 SOC_REG_ABOVE_64_CLEAR(data); 2516 SOC_REG_ABOVE_64_CLEAR(field); 2517 2518 if (inter->bit_in_field == SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2519 SHR_BITSET(field, 0x0); 2520 } else { 2521 SHR_BITSET(field, inter->bit_in_field); 2522 } 2523 2524 soc_reg_above_64_field_set(unit, inter->reg, data, inter->field, field); 2525 2526 rc = soc_reg_above_64_set(unit, inter->reg, block_instance, inter->reg_index, data); 2527 if (SOC_FAILURE(rc)) { 2528 LOG_ERROR(BSL_LS_SOC_INTR, 2529 (BSL_META_U(unit, 2530 "%s\n"), soc_errmsg(rc))); 2531 } 2532 2533 return rc; 2534 } 2535 2536 int soc_interrupt_clear_on_reg_write(int unit, int block_instance, int interrupt_id) 2537 { 2538 int rc = SOC_E_NONE; 2539 int nof_interrupts; 2540 soc_interrupt_db_t *inter, *interrupts; 2541 2542 if (!SOC_INTR_IS_SUPPORTED(unit)) { 2543 LOG_ERROR(BSL_LS_SOC_INTR, 2544 (BSL_META_U(unit, 2545 "No interrupts for device\n"))); 2546 return SOC_E_UNAVAIL; 2547 } 2548 2549 interrupts = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2550 if (interrupts == NULL) { 2551 LOG_ERROR(BSL_LS_SOC_INTR, 2552 (BSL_META_U(unit, 2553 "Null parameter\n"))); 2554 return SOC_E_PARAM; 2555 } 2556 2557 /*verify interrupt_id*/ 2558 soc_nof_interrupts(unit, &nof_interrupts); 2559 if ((interrupt_id > nof_interrupts) || interrupt_id < 0) { 2560 LOG_ERROR(BSL_LS_SOC_INTR, 2561 (BSL_META_U(unit, 2562 "event_id is unavail\n"))); 2563 return SOC_E_UNAVAIL; 2564 } 2565 2566 inter = &(interrupts[interrupt_id]); 2567 if(!SOC_REG_IS_VALID(unit, ((soc_interrupt_clear_reg_write_t*)inter->interrupt_clear_param1)->status_reg)){ 2568 LOG_ERROR(BSL_LS_SOC_INTR, 2569 (BSL_META_U(unit, 2570 "Invalid register for the device\n"))); 2571 return SOC_E_INTERNAL; 2572 } 2573 2574 rc = soc_reg_above_64_set(unit, 2575 ((soc_interrupt_clear_reg_write_t*)inter->interrupt_clear_param1)->status_reg, 2576 block_instance, 2577 inter->reg_index, 2578 ((soc_interrupt_clear_reg_write_t*)inter->interrupt_clear_param1)->data); 2579 if (SOC_FAILURE(rc)) { 2580 LOG_ERROR(BSL_LS_SOC_INTR, 2581 (BSL_META_U(unit, 2582 "%s\n"), soc_errmsg(rc))); 2583 } 2584 2585 return rc; 2586 } 2587 2588 int soc_interrupt_clear_on_clear(int unit, int block_instance, int interrupt_id) 2589 { 2590 soc_reg_above_64_val_t data, field; 2591 int rc = SOC_E_NONE; 2592 int nof_interrupts; 2593 soc_interrupt_db_t *inter, *interrupts; 2594 2595 if (!SOC_INTR_IS_SUPPORTED(unit)) { 2596 LOG_ERROR(BSL_LS_SOC_INTR, 2597 (BSL_META_U(unit, 2598 "No interrupts for device\n"))); 2599 return SOC_E_UNAVAIL; 2600 } 2601 2602 interrupts = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2603 if (interrupts == NULL) { 2604 LOG_ERROR(BSL_LS_SOC_INTR, 2605 (BSL_META_U(unit, 2606 "Null parameter\n"))); 2607 return SOC_E_PARAM; 2608 } 2609 2610 /*verify interrupt_id*/ 2611 soc_nof_interrupts(unit, &nof_interrupts); 2612 if ((interrupt_id > nof_interrupts) || interrupt_id < 0) { 2613 LOG_ERROR(BSL_LS_SOC_INTR, 2614 (BSL_META_U(unit, 2615 "event_id is unavail\n"))); 2616 return SOC_E_UNAVAIL; 2617 } 2618 2619 inter = &(interrupts[interrupt_id]); 2620 if(!SOC_REG_IS_VALID(unit, inter->reg)){ 2621 LOG_ERROR(BSL_LS_SOC_INTR, 2622 (BSL_META_U(unit, 2623 "Invalid register for the device\n"))); 2624 return SOC_E_INTERNAL; 2625 } 2626 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2627 LOG_ERROR(BSL_LS_SOC_INTR, 2628 (BSL_META_U(unit, 2629 "Invalid mask register for the device\n"))); 2630 return SOC_E_INTERNAL; 2631 } 2632 2633 SOC_REG_ABOVE_64_CLEAR(data); 2634 SOC_REG_ABOVE_64_CLEAR(field); 2635 2636 rc = soc_reg_above_64_get(unit, inter->reg, block_instance, inter->reg_index, data); 2637 if (SOC_FAILURE(rc)) { 2638 LOG_ERROR(BSL_LS_SOC_INTR, 2639 (BSL_META_U(unit, 2640 "%s\n"), soc_errmsg(rc))); 2641 return rc; 2642 } 2643 2644 if (inter->bit_in_field != SOC_INTERRUPT_BIT_FIELD_DONT_CARE) { 2645 soc_reg_above_64_field_get(unit, inter->reg, data, inter->field, field); 2646 SHR_BITCLR(field, inter->bit_in_field); 2647 } 2648 2649 soc_reg_above_64_field_set(unit, inter->reg, data, inter->field, field); 2650 2651 rc = soc_reg_above_64_set(unit, inter->reg, block_instance, inter->reg_index, data); 2652 if (SOC_FAILURE(rc)) { 2653 LOG_ERROR(BSL_LS_SOC_INTR, 2654 (BSL_META_U(unit, 2655 "%s\n"), soc_errmsg(rc))); 2656 } 2657 2658 return rc; 2659 } 2660 2661 /* 2662 */ 2663 int soc_interrupt_clear_on_read_fifo(int unit, int block_instance, int interrupt_id) 2664 { 2665 soc_interrupt_db_t *inter, *interrupts; 2666 int nof_interrupts; 2667 int rc = SOC_E_NONE, read_count; 2668 soc_reg_above_64_val_t data ; 2669 int inter_get; 2670 2671 if (!SOC_INTR_IS_SUPPORTED(unit)) { 2672 LOG_ERROR(BSL_LS_SOC_INTR, 2673 (BSL_META_U(unit, 2674 "No interrupts for device\n"))); 2675 return SOC_E_UNAVAIL; 2676 } 2677 2678 interrupts = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2679 if (interrupts == NULL) { 2680 LOG_ERROR(BSL_LS_SOC_INTR, 2681 (BSL_META_U(unit, 2682 "Null parameter\n"))); 2683 return SOC_E_PARAM; 2684 } 2685 2686 /*verify interrupt_id*/ 2687 soc_nof_interrupts(unit, &nof_interrupts); 2688 if ((interrupt_id > nof_interrupts) || interrupt_id < 0) { 2689 LOG_ERROR(BSL_LS_SOC_INTR, 2690 (BSL_META_U(unit, 2691 "event_id is unavail\n"))); 2692 return SOC_E_UNAVAIL; 2693 } 2694 inter = &(interrupts[interrupt_id]); 2695 if(!SOC_REG_IS_VALID(unit, inter->reg)){ 2696 LOG_ERROR(BSL_LS_SOC_INTR, 2697 (BSL_META_U(unit, 2698 "Invalid register for the device\n"))); 2699 return SOC_E_INTERNAL; 2700 } 2701 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2702 LOG_ERROR(BSL_LS_SOC_INTR, 2703 (BSL_META_U(unit, 2704 "Invalid mask register for the device\n"))); 2705 return SOC_E_INTERNAL; 2706 } 2707 2708 for(read_count = 0; read_count < ((soc_interrupt_clear_read_fifo_t*)(inter->interrupt_clear_param1))->read_count; read_count++){ 2709 rc = soc_reg_above_64_get(unit, ((soc_interrupt_clear_read_fifo_t*)(inter->interrupt_clear_param1))->fifo_reg, block_instance, inter->reg_index, data); 2710 if (SOC_FAILURE(rc)) { 2711 LOG_ERROR(BSL_LS_SOC_INTR, 2712 (BSL_META_U(unit, 2713 "%s\n"), soc_errmsg(rc))); 2714 return rc; 2715 } 2716 2717 rc = soc_interrupt_get(unit, block_instance , inter, &inter_get); 2718 if (SOC_FAILURE(rc)) { 2719 LOG_ERROR(BSL_LS_SOC_INTR, 2720 (BSL_META_U(unit, 2721 "%s\n"), soc_errmsg(rc))); 2722 return rc; 2723 } 2724 2725 if (!inter_get) { 2726 break; 2727 } 2728 } 2729 2730 return rc; 2731 } 2732 2733 /* 2734 */ 2735 int soc_interrupt_clear_on_read_array_index(int unit, int block_instance, int interrupt_id) 2736 { 2737 soc_interrupt_db_t *inter, *interrupts; 2738 int nof_interrupts; 2739 int rc = SOC_E_NONE, read_count; 2740 soc_reg_above_64_val_t data ; 2741 int inter_get; 2742 2743 if (!SOC_INTR_IS_SUPPORTED(unit)) { 2744 LOG_ERROR(BSL_LS_SOC_INTR, 2745 (BSL_META_U(unit, 2746 "No interrupts for device\n"))); 2747 return SOC_E_UNAVAIL; 2748 } 2749 2750 interrupts = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2751 if (interrupts == NULL) { 2752 LOG_ERROR(BSL_LS_SOC_INTR, 2753 (BSL_META_U(unit, 2754 "Null parameter\n"))); 2755 return SOC_E_PARAM; 2756 } 2757 2758 /*verify interrupt_id*/ 2759 soc_nof_interrupts(unit, &nof_interrupts); 2760 if ((interrupt_id > nof_interrupts) || interrupt_id < 0) { 2761 LOG_ERROR(BSL_LS_SOC_INTR, 2762 (BSL_META_U(unit, 2763 "event_id is unavail\n"))); 2764 return SOC_E_UNAVAIL; 2765 } 2766 inter = &(interrupts[interrupt_id]); 2767 if(!SOC_REG_IS_VALID(unit, inter->reg)){ 2768 LOG_ERROR(BSL_LS_SOC_INTR, 2769 (BSL_META_U(unit, 2770 "Invalid register for the device\n"))); 2771 return SOC_E_INTERNAL; 2772 } 2773 if(!SOC_REG_IS_VALID(unit, inter->mask_reg)){ 2774 LOG_ERROR(BSL_LS_SOC_INTR, 2775 (BSL_META_U(unit, 2776 "Invalid mask register for the device\n"))); 2777 return SOC_E_INTERNAL; 2778 } 2779 2780 for(read_count = 0; read_count < ((soc_interrupt_clear_array_index_t*)(inter->interrupt_clear_param1))->read_count; read_count++){ 2781 rc = soc_reg_above_64_get(unit, 2782 ((soc_interrupt_clear_array_index_t*)(inter->interrupt_clear_param1))->fifo_reg, 2783 block_instance, 2784 ((soc_interrupt_clear_array_index_t*)(inter->interrupt_clear_param1))->reg_index, 2785 data); 2786 if (SOC_FAILURE(rc)) { 2787 LOG_ERROR(BSL_LS_SOC_INTR, 2788 (BSL_META_U(unit, 2789 "%s\n"), soc_errmsg(rc))); 2790 return rc; 2791 } 2792 2793 rc = soc_interrupt_get(unit, block_instance , inter, &inter_get); 2794 if (SOC_FAILURE(rc)) { 2795 LOG_ERROR(BSL_LS_SOC_INTR, 2796 (BSL_META_U(unit, 2797 "%s\n"), soc_errmsg(rc))); 2798 return rc; 2799 } 2800 2801 if (!inter_get) { 2802 break; 2803 } 2804 } 2805 2806 return rc; 2807 } 2808 2809 2810 static int 2811 soc_active_interrupts_handle_vector(int unit, int int_port, int blk, int int_id, int is_unmasked_flag, int max_interrupts_size, soc_interrupt_cause_t *interrupts, int* index) 2812 { 2813 int rc = SOC_E_NONE; 2814 int vector_int_bit_idx = 0; 2815 int vector_int_id; 2816 int vector_id; 2817 soc_interrupt_db_t *interrupts_arr; 2818 soc_reg_above_64_val_t vector_int_data, vector_int_mask_data, vector_int_bitmap; 2819 soc_field_info_t *finfop; 2820 2821 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2822 2823 rc = soc_reg_above_64_get(unit, interrupts_arr[int_id].vector_info->int_reg, int_port, interrupts_arr[int_id].vector_info->index, vector_int_data); 2824 if (SOC_FAILURE(rc)) { 2825 LOG_ERROR(BSL_LS_SOC_INTR, 2826 (BSL_META_U(unit, 2827 "%s\n"), soc_errmsg(rc))); 2828 return rc; 2829 } 2830 rc = soc_reg_above_64_get(unit, interrupts_arr[int_id].vector_info->int_mask_reg, int_port, interrupts_arr[int_id].vector_info->index, vector_int_mask_data); 2831 if (SOC_FAILURE(rc)) { 2832 LOG_ERROR(BSL_LS_SOC_INTR, 2833 (BSL_META_U(unit, 2834 "%s\n"), soc_errmsg(rc))); 2835 return rc; 2836 } 2837 2838 /* Calc interrupt bit map according to 'flags' */ 2839 SOC_REG_ABOVE_64_COPY(vector_int_bitmap, vector_int_data); 2840 if (is_unmasked_flag) { 2841 SOC_REG_ABOVE_64_AND(vector_int_bitmap, vector_int_mask_data); 2842 } 2843 LOG_VERBOSE(BSL_LS_SOC_INTR, 2844 (BSL_META_U(unit, 2845 "\t\tvector_int_data=0x%x%x%x%x, vector_int_mask_data=0x%x%x%x%x, vector_int_bitmap=0x%x%x%x%x,\n"), 2846 vector_int_data[3], vector_int_data[2], vector_int_data[1], vector_int_data[0], 2847 vector_int_mask_data[3], vector_int_mask_data[2], vector_int_mask_data[1], vector_int_mask_data[0], 2848 vector_int_bitmap[3], vector_int_bitmap[2], vector_int_bitmap[1], vector_int_bitmap[0])); 2849 2850 for (; vector_int_bit_idx < SOC_INTERRUPT_INTERRUPT_PER_REG_NUM_MAX; vector_int_bit_idx++) { 2851 if (!(vector_int_bitmap[vector_int_bit_idx / (8 * sizeof(int))] & (1 << (vector_int_bit_idx % (8 * sizeof(int)))))) { 2852 LOG_DEBUG(BSL_LS_SOC_INTR, 2853 (BSL_META_U(unit, 2854 "no interrupt for vector_int_bit_idx=%d\n"), 2855 vector_int_bit_idx)); 2856 continue; 2857 } 2858 2859 vector_int_id = interrupts_arr[int_id].vector_info->int_id[vector_int_bit_idx]; 2860 if (vector_int_id == -1) { 2861 LOG_VERBOSE(BSL_LS_SOC_INTR, 2862 (BSL_META_U(unit, 2863 "Reached hidden interrupt. vector_int_bit_idx=%d,\n"), 2864 vector_int_bit_idx)); 2865 continue; 2866 } 2867 2868 #if !defined(SOC_NO_NAMES) 2869 LOG_VERBOSE(BSL_LS_SOC_INTR, 2870 (BSL_META_U(unit, 2871 "\t\tblk=%d, int_id=%d, vector_int_bit_idx=%d, vector_int_id=%d, name=%s,\n"), 2872 blk, int_id, vector_int_bit_idx, vector_int_id, interrupts_arr[vector_int_id].name)); 2873 #else 2874 LOG_VERBOSE(BSL_LS_SOC_INTR, 2875 (BSL_META_U(unit, 2876 "\t\tblk=%d, int_id=%d, vector_int_bit_idx=%d, vector_int_id=%d,\n"), 2877 blk, int_id, vector_int_bit_idx, vector_int_id)); 2878 #endif 2879 2880 /* Senity check between the interrupt field and the register bit */ 2881 SOC_FIND_FIELD(interrupts_arr[vector_int_id].field, SOC_REG_INFO(unit, interrupts_arr[vector_int_id].reg).fields, SOC_REG_INFO(unit, interrupts_arr[vector_int_id].reg).nFields, finfop); 2882 if ((finfop->len == 0x1) && (finfop->bp != vector_int_bit_idx)) { 2883 LOG_ERROR(BSL_LS_SOC_INTR, 2884 (BSL_META_U(unit, 2885 "Error: Where finfop->len=%d. finfop->bp=%d != vector_int_bit_idx=%d.\n"), 2886 finfop->len, finfop->bp, vector_int_bit_idx)); 2887 LOG_ERROR(BSL_LS_SOC_INTR, 2888 (BSL_META_U(unit, 2889 "No match between interrupt bit and interrupt field\n"))); 2890 return SOC_E_UNAVAIL; 2891 } 2892 2893 vector_id = interrupts_arr[vector_int_id].vector_id; 2894 if (vector_id == 0) { 2895 /* no vector - real int*/ 2896 if (*index < max_interrupts_size ) { 2897 2898 interrupts[*index].index = int_port; 2899 interrupts[*index].id = vector_int_id; 2900 LOG_VERBOSE(BSL_LS_SOC_INTR, 2901 (BSL_META_U(unit, 2902 "\tinterrupts[%d].index=%d, interrupts[%d].id=%d,\n"), 2903 *index, interrupts[*index].index, *index, interrupts[*index].id)); 2904 *index = *index + 1; 2905 } 2906 } else { 2907 rc = soc_active_interrupts_handle_vector(unit, int_port, blk, vector_int_id, is_unmasked_flag, max_interrupts_size, interrupts, index); 2908 if (rc != SOC_E_NONE) { 2909 return rc; 2910 } 2911 } 2912 } 2913 2914 return rc; 2915 } 2916 2917 2918 /* 2919 */ 2920 int 2921 soc_active_interrupts_get(int unit, int flags, int max_interrupts_size, soc_interrupt_cause_t *interrupts, int *total_interrupts) 2922 { 2923 int rc = SOC_E_NONE; 2924 int i = 0, blk = 0, int_bit_idx = 0, vector_int_bit_idx = 0, j; 2925 int index = 0; 2926 int int_id, int_port=0; 2927 int vector_id; 2928 int is_unmasked_flag = 0, is_cont_prev_flag = 0, is_blk_intr_assert = 0; 2929 static int cont_prev_i_blk = 0, cont_prev_bit_idx = 0, cont_prev_vector_bit_idx = 0; 2930 int cont_prev_start_i_blk = 0; 2931 int first_blk_loop = 1; 2932 2933 uint32 cmic_irq_stat[4];/*4 is the amount which needed for maximum 128 blocks per device*/ 2934 2935 soc_block_info_t *bi; 2936 soc_interrupt_db_t *interrupts_arr; 2937 soc_interrupt_tree_t *interrupt_tree; 2938 2939 soc_reg_above_64_val_t block_int_data, block_int_mask_data, block_int_bitmap; 2940 #ifdef BCM_DNX_SUPPORT 2941 soc_reg_above_64_val_t eci_irq_status; 2942 #endif 2943 soc_field_info_t *finfop; 2944 2945 #ifdef BCM_PETRA_SUPPORT 2946 uint32 cmic_irq_state_2; 2947 #endif /* BCM_PETRA_SUPPORT */ 2948 2949 if (!SOC_INTR_IS_SUPPORTED(unit)) { 2950 LOG_ERROR(BSL_LS_SOC_INTR, 2951 (BSL_META_U(unit, 2952 "No interrupts for device\n"))); 2953 return SOC_E_UNAVAIL; 2954 } 2955 2956 if (interrupts == NULL || total_interrupts == NULL) { 2957 LOG_ERROR(BSL_LS_SOC_INTR, 2958 (BSL_META_U(unit, 2959 "Null parameter\n"))); 2960 return SOC_E_PARAM; 2961 } 2962 2963 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 2964 if (interrupts_arr == NULL) { 2965 LOG_ERROR(BSL_LS_SOC_INTR, 2966 (BSL_META_U(unit, 2967 "Null parameter\n"))); 2968 return SOC_E_PARAM; 2969 } 2970 2971 interrupt_tree = SOC_CONTROL(unit)->interrupts_info->interrupt_tree_info; 2972 if (interrupt_tree == NULL) { 2973 LOG_ERROR(BSL_LS_SOC_INTR, 2974 (BSL_META_U(unit, 2975 "Null parameter\n"))); 2976 return SOC_E_PARAM; 2977 } 2978 2979 sal_memset(cmic_irq_stat, 0x0, sizeof(cmic_irq_stat)); 2980 2981 if (flags & SOC_ACTIVE_INTERRUPTS_GET_UNMASKED_ONLY) { 2982 is_unmasked_flag = 1; 2983 } 2984 2985 if (flags & SOC_ACTIVE_INTERRUPTS_GET_CONT_PREV) { 2986 is_cont_prev_flag = 1; 2987 } 2988 2989 if (is_cont_prev_flag) { 2990 cont_prev_start_i_blk = i = cont_prev_i_blk; 2991 int_bit_idx = 0 /*cont_prev_bit_idx*/; 2992 vector_int_bit_idx = 0 /*cont_prev_vector_bit_idx*/; 2993 } else { 2994 i = 0; 2995 int_bit_idx = 0; 2996 vector_int_bit_idx = 0; 2997 } 2998 2999 if (soc_feature(unit, soc_feature_cmicm)) { 3000 #ifdef BCM_CMICM_SUPPORT 3001 int cmc = SOC_PCI_CMC(unit); 3002 cmic_irq_stat[0] = soc_pci_read(unit, CMIC_CMCx_IRQ_STAT3_OFFSET(cmc)); 3003 cmic_irq_stat[0] &= SOC_CMCx_IRQ3_MASK(unit,cmc); 3004 cmic_irq_stat[1] = soc_pci_read(unit, CMIC_CMCx_IRQ_STAT4_OFFSET(cmc)); 3005 cmic_irq_stat[1] &= SOC_CMCx_IRQ4_MASK(unit,cmc); 3006 #ifdef BCM_PETRA_SUPPORT 3007 /* add to cimic_irq_stat[0] the port interrupts bits from irq_state2 */ 3008 if ( SOC_IS_ARAD(unit) && !(SOC_IS_ARDON(unit)) && !(SOC_IS_JERICHO(unit))) { 3009 cmic_irq_state_2 = soc_pci_read(unit, CMIC_CMCx_IRQ_STAT2_OFFSET(cmc)); 3010 cmic_irq_state_2 &= SOC_CMCx_IRQ2_MASK(unit,cmc); 3011 cmic_irq_stat[0] |= _PORT_BLOCK_FROM_IRQ_STATE2(unit, cmic_irq_state_2, PARITY_INTERRUPT_4f, SOC_CMIC_BLK_CLP_0_INDX) 3012 | _PORT_BLOCK_FROM_IRQ_STATE2(unit, cmic_irq_state_2, PARITY_INTERRUPT_3f, SOC_CMIC_BLK_CLP_1_INDX) 3013 | _PORT_BLOCK_FROM_IRQ_STATE2(unit, cmic_irq_state_2, PARITY_INTERRUPT_2f, SOC_CMIC_BLK_XLP_0_INDX) 3014 | _PORT_BLOCK_FROM_IRQ_STATE2(unit, cmic_irq_state_2, PARITY_INTERRUPT_1f, SOC_CMIC_BLK_XLP_1_INDX); 3015 } 3016 #endif /* BCM_PETRA_SUPPORT */ 3017 if (soc_feature(unit, soc_feature_cmicm_extended_interrupts)) { 3018 cmic_irq_stat[2] = soc_pci_read(unit, CMIC_CMCx_IRQ_STAT5_OFFSET(cmc)); 3019 cmic_irq_stat[2] &= SOC_CMCx_IRQ5_MASK(unit,cmc); 3020 cmic_irq_stat[3] = soc_pci_read(unit, CMIC_CMCx_IRQ_STAT6_OFFSET(cmc)); 3021 cmic_irq_stat[3] &= SOC_CMCx_IRQ6_MASK(unit,cmc); 3022 } 3023 #endif 3024 } 3025 #ifdef BCM_CMICX_SUPPORT 3026 else if (soc_feature(unit, soc_feature_cmicx)) { 3027 int ii; 3028 soc_reg_t cmicx_status_reg[4] = {ICFG_CHIP_LP_INTR_RAW_STATUS_REG0r, 3029 ICFG_CHIP_LP_INTR_RAW_STATUS_REG1r, 3030 ICFG_CHIP_LP_INTR_RAW_STATUS_REG2r, 3031 ICFG_CHIP_LP_INTR_RAW_STATUS_REG3r}; 3032 soc_reg_t cmicx_enable_reg[4] = {ICFG_CHIP_LP_INTR_ENABLE_REG0r, 3033 ICFG_CHIP_LP_INTR_ENABLE_REG1r, 3034 ICFG_CHIP_LP_INTR_ENABLE_REG2r, 3035 ICFG_CHIP_LP_INTR_ENABLE_REG3r}; 3036 #ifdef BCM_DNX_SUPPORT 3037 if (SOC_IS_DNX(unit)) 3038 { 3039 soc_reg_above_64_val_t eci_irq_enable; 3040 3041 SOC_REG_ABOVE_64_CLEAR(eci_irq_status); 3042 SOC_REG_ABOVE_64_CLEAR(eci_irq_enable); 3043 (void)soc_reg_above_64_get(unit, ECI_ECI_INTERRUPTSr, REG_PORT_ANY, 0, eci_irq_status); 3044 (void)soc_reg_above_64_get(unit, ECI_ECI_INTERRUPTS_MASKr, REG_PORT_ANY, 0, eci_irq_enable); 3045 3046 SOC_REG_ABOVE_64_AND(eci_irq_status, eci_irq_enable); 3047 } else 3048 #endif 3049 { 3050 uint32 cmic_irq_enable[4] = {0}; 3051 /* ICFG_CHIP_LP_INTR_ENABLE_REG be used for DNX device, but ICFG_CHIP_LP_INTR_RAW_STATUS_REG not */ 3052 for (ii = 0; ii < 4; ii++) { 3053 (void)soc_cmic_or_iproc_getreg(unit, cmicx_status_reg[ii], &cmic_irq_stat[ii]); 3054 (void)soc_cmic_or_iproc_getreg(unit, cmicx_enable_reg[ii], &cmic_irq_enable[ii]); 3055 cmic_irq_stat[ii] &= cmic_irq_enable[ii]; 3056 } 3057 } 3058 } 3059 #endif 3060 else { 3061 cmic_irq_stat[0] = soc_pci_read(unit, CMIC_IRQ_STAT_1); 3062 cmic_irq_stat[1] = soc_pci_read(unit, CMIC_IRQ_STAT_2); 3063 } 3064 3065 #ifdef BCM_DNX_SUPPORT 3066 if (SOC_IS_DNX(unit)) { 3067 /* do nothing */ 3068 } else 3069 #endif 3070 { 3071 for (j = 0; j < 4; j++) { 3072 LOG_VERBOSE(BSL_LS_SOC_INTR, 3073 (BSL_META_U(unit, 3074 "%s(): cmic_irq_stat[%u]=0x%x\n"), 3075 FUNCTION_NAME(), j, cmic_irq_stat[j])); 3076 } 3077 } 3078 while (1) { 3079 3080 if (SOC_BLOCK_INFO(unit, i).type < 0) { 3081 i = 0; 3082 } 3083 3084 if ((i == cont_prev_start_i_blk) && (first_blk_loop == 0)) { 3085 break; 3086 } 3087 3088 first_blk_loop = 0; 3089 3090 if (!(SOC_INFO(unit).block_valid[i])) { 3091 i++; 3092 continue; 3093 } 3094 3095 bi = &(SOC_BLOCK_INFO(unit, i)); 3096 blk=bi->cmic; 3097 3098 #ifdef BCM_DNX_SUPPORT 3099 if (SOC_IS_DNX(unit)) 3100 { 3101 is_blk_intr_assert = soc_dnx_is_block_eci_intr_assert(unit, blk, eci_irq_status); 3102 } else 3103 #endif 3104 { 3105 is_blk_intr_assert = SHR_BITGET(cmic_irq_stat, blk); 3106 } 3107 if ((!is_blk_intr_assert && (is_unmasked_flag == 1)) || (interrupt_tree[blk].int_reg == INVALIDr)){ 3108 LOG_DEBUG(BSL_LS_SOC_INTR, 3109 (BSL_META_U(unit, 3110 "no interrupt for blk=%d\n"), 3111 blk)); 3112 i++; 3113 continue; 3114 } 3115 3116 LOG_VERBOSE(BSL_LS_SOC_INTR, 3117 (BSL_META_U(unit, 3118 "blk=%d, bi->number=%d,\n"), 3119 blk, bi->number)); 3120 3121 /* Read block interrupt register */ 3122 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) 3123 /* dnxf device have no clp/xlp block */ 3124 if((SOC_IS_ARAD(unit) || SOC_IS_DNX(unit)) && (bi->type == SOC_BLK_CLP || bi->type == SOC_BLK_XLP )) { 3125 int_port = SOC_BLOCK_PORT(unit, i); 3126 } else 3127 #endif /* BCM_PETRA_SUPPORT */ 3128 { 3129 int_port = bi->number; 3130 } 3131 3132 rc = soc_reg_above_64_get(unit, interrupt_tree[blk].int_reg, int_port, interrupt_tree[blk].index, block_int_data); 3133 if (SOC_FAILURE(rc)) { 3134 LOG_ERROR(BSL_LS_SOC_INTR, 3135 (BSL_META_U(unit, 3136 "%s\n"), soc_errmsg(rc))); 3137 return rc; 3138 } 3139 rc = soc_reg_above_64_get(unit, interrupt_tree[blk].int_mask_reg, int_port, interrupt_tree[blk].index, block_int_mask_data); 3140 if (SOC_FAILURE(rc)) { 3141 LOG_ERROR(BSL_LS_SOC_INTR, 3142 (BSL_META_U(unit, 3143 "%s\n"), soc_errmsg(rc))); 3144 return rc; 3145 } 3146 3147 /* Calc interrupt bit map according to 'flags' */ 3148 SOC_REG_ABOVE_64_COPY(block_int_bitmap, block_int_data); 3149 if (is_unmasked_flag) { 3150 SOC_REG_ABOVE_64_AND(block_int_bitmap, block_int_mask_data); 3151 } 3152 LOG_VERBOSE(BSL_LS_SOC_INTR, 3153 (BSL_META_U(unit, 3154 "block_int_data=0x%x 0x%x 0x%x 0x%x, block_int_mask_data=0x%x 0x%x 0x%x 0x%x, block_int_bitmap=0x%x 0x%x 0x%x 0x%x,\n"), 3155 block_int_data[0], block_int_data[2], block_int_data[2], block_int_data[3], 3156 block_int_mask_data[0], block_int_mask_data[1], block_int_mask_data[2], block_int_mask_data[3], 3157 block_int_bitmap[0], block_int_bitmap[1], block_int_bitmap[2], block_int_bitmap[3])); 3158 3159 for (; int_bit_idx < SOC_INTERRUPT_INTERRUPT_PER_REG_NUM_MAX; int_bit_idx++) { 3160 int_id = interrupt_tree[blk].int_id[int_bit_idx]; 3161 if (int_id == -1) { 3162 LOG_VERBOSE(BSL_LS_SOC_INTR, 3163 (BSL_META_U(unit, 3164 "Reached hidden interrupt. int_bit_idx=%d,\n"), 3165 int_bit_idx)); 3166 continue; 3167 } 3168 3169 vector_id = interrupts_arr[int_id].vector_id; 3170 if ((SHR_BITGET(block_int_bitmap, int_bit_idx) == 0) && (!(vector_id == 1 && is_unmasked_flag == 0))) { 3171 LOG_DEBUG(BSL_LS_SOC_INTR, 3172 (BSL_META_U(unit, 3173 "no interrupt for int_bit_idx=%d\n"), 3174 int_bit_idx)); 3175 continue; 3176 } 3177 3178 #if !defined(SOC_NO_NAMES) 3179 LOG_VERBOSE(BSL_LS_SOC_INTR, 3180 (BSL_META_U(unit, 3181 "\tgettind int_id: blk=%d, int_bit_idx=%d, int_id=%d, name=%s, vector_id=%d,\n"), 3182 blk, int_bit_idx, int_id, interrupts_arr[int_id].name, vector_id)); 3183 #else 3184 LOG_VERBOSE(BSL_LS_SOC_INTR, 3185 (BSL_META_U(unit, 3186 "\tgettind int_id: blk=%d, int_bit_idx=%d, int_id=%d, vector_id=%d,\n"), 3187 blk, int_bit_idx, int_id, vector_id)); 3188 #endif 3189 3190 /* Senity check between the interrupt field and the register bit */ 3191 SOC_FIND_FIELD(interrupts_arr[int_id].field, SOC_REG_INFO(unit, interrupts_arr[int_id].reg).fields, SOC_REG_INFO(unit, interrupts_arr[int_id].reg).nFields, finfop); 3192 if ((finfop->len == 0x1) && (finfop->bp != int_bit_idx)) { 3193 LOG_ERROR(BSL_LS_SOC_INTR, 3194 (BSL_META_U(unit, 3195 "Error: Where finfop->len=%d. finfop->bp=%d != int_bit_idx=%d.\n"), 3196 finfop->len, finfop->bp, int_bit_idx)); 3197 LOG_ERROR(BSL_LS_SOC_INTR, 3198 (BSL_META_U(unit, 3199 "No match between interrupt bit and interrupt field\n"))); 3200 return SOC_E_UNAVAIL; 3201 } 3202 3203 /* handle vecor */ 3204 if (vector_id == 0) { 3205 /* no vecotr - real int*/ 3206 if (index < max_interrupts_size ) { 3207 3208 interrupts[index].index = int_port; 3209 interrupts[index].id = int_id; 3210 cont_prev_i_blk = i; 3211 cont_prev_bit_idx = int_bit_idx; 3212 cont_prev_vector_bit_idx = vector_int_bit_idx; 3213 LOG_VERBOSE(BSL_LS_SOC_INTR, 3214 (BSL_META_U(unit, 3215 "\tinterrupts[%d].index=%d, interrupts[%d].id=%d,\n"), 3216 index, interrupts[index].index, index, interrupts[index].id)); 3217 index++; 3218 } 3219 } else { 3220 rc = soc_active_interrupts_handle_vector(unit, int_port, blk, int_id, is_unmasked_flag, max_interrupts_size, interrupts, &index); 3221 if (rc != SOC_E_NONE) { 3222 return rc; 3223 } else { 3224 if (index < max_interrupts_size ) { 3225 cont_prev_i_blk = i; 3226 cont_prev_bit_idx = int_bit_idx; 3227 cont_prev_vector_bit_idx = vector_int_bit_idx; 3228 } 3229 } 3230 } 3231 } 3232 int_bit_idx = 0; 3233 i++; 3234 } 3235 3236 *total_interrupts = index; 3237 LOG_VERBOSE(BSL_LS_SOC_INTR, 3238 (BSL_META_U(unit, 3239 "index=%d, *total_interrupts=%d, cont_prev_i_blk=%d, cont_prev_bit_idx=%d, cont_prev_vector_bit_idx=%d.\n"), 3240 index, *total_interrupts, cont_prev_i_blk, cont_prev_bit_idx, cont_prev_vector_bit_idx)); 3241 3242 return rc; 3243 } 3244 3245 int 3246 soc_interrupt_info_get(int unit, int interrupt_id, soc_interrupt_db_t *inter) 3247 { 3248 soc_interrupt_db_t *interrupts_arr; 3249 int nof_interrupts; 3250 int rc = SOC_E_NONE; 3251 3252 if (!SOC_INTR_IS_SUPPORTED(unit)) { 3253 LOG_ERROR(BSL_LS_SOC_INTR, 3254 (BSL_META_U(unit, 3255 "No interrupts for device\n"))); 3256 return SOC_E_UNAVAIL; 3257 } 3258 3259 if (inter == NULL) { 3260 LOG_ERROR(BSL_LS_SOC_INTR, 3261 (BSL_META_U(unit, 3262 "Null parameter\n"))); 3263 return SOC_E_PARAM; 3264 } 3265 3266 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 3267 if (interrupts_arr == NULL) { 3268 LOG_ERROR(BSL_LS_SOC_INTR, 3269 (BSL_META_U(unit, 3270 "Null parameter\n"))); 3271 return SOC_E_PARAM; 3272 } 3273 3274 rc = soc_nof_interrupts(unit, &nof_interrupts); 3275 if (SOC_FAILURE(rc)) { 3276 LOG_ERROR(BSL_LS_SOC_INTR, 3277 (BSL_META_U(unit, 3278 "%s\n"), soc_errmsg(rc))); 3279 return rc; 3280 } 3281 if (interrupt_id > nof_interrupts) { 3282 LOG_ERROR(BSL_LS_SOC_INTR, 3283 (BSL_META_U(unit, 3284 "interrupt_id is unavail\n"))); 3285 return SOC_E_UNAVAIL; 3286 } 3287 3288 #if !defined(SOC_NO_NAMES) 3289 inter->name = interrupts_arr[interrupt_id].name; 3290 #endif 3291 inter->reg = interrupts_arr[interrupt_id].reg; 3292 inter->reg_index = interrupts_arr[interrupt_id].reg_index; 3293 inter->field = interrupts_arr[interrupt_id].field; 3294 inter->mask_reg = interrupts_arr[interrupt_id].mask_reg; 3295 inter->mask_reg_index = interrupts_arr[interrupt_id].mask_reg_index; 3296 inter->mask_field = interrupts_arr[interrupt_id].mask_field; 3297 inter->bit_in_field = interrupts_arr[interrupt_id].bit_in_field; 3298 inter->reg_test = interrupts_arr[interrupt_id].reg_test; 3299 3300 return rc; 3301 } 3302 3303 int 3304 soc_get_interrupt_id(int unit, soc_reg_t reg, int reg_index, soc_field_t field, int bit_in_field, int* interrupt_id) 3305 { 3306 soc_interrupt_db_t *interrupts_arr; 3307 int nof_interrupts; 3308 int i; 3309 int rc = SOC_E_NONE; 3310 3311 if (!SOC_INTR_IS_SUPPORTED(unit)) { 3312 LOG_ERROR(BSL_LS_SOC_INTR, 3313 (BSL_META_U(unit, 3314 "No interrupts for device\n"))); 3315 return SOC_E_UNAVAIL; 3316 } 3317 3318 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 3319 if (interrupts_arr == NULL) { 3320 LOG_ERROR(BSL_LS_SOC_INTR, 3321 (BSL_META_U(unit, 3322 "Null parameter\n"))); 3323 return SOC_E_PARAM; 3324 } 3325 3326 if (interrupt_id == NULL) { 3327 LOG_ERROR(BSL_LS_SOC_INTR, 3328 (BSL_META_U(unit, 3329 "Null parameter\n"))); 3330 return SOC_E_PARAM; 3331 } 3332 *interrupt_id = -1; 3333 3334 /* look for interrupt id*/ 3335 rc = soc_nof_interrupts(unit, &nof_interrupts); 3336 if (SOC_FAILURE(rc)) { 3337 LOG_ERROR(BSL_LS_SOC_INTR, 3338 (BSL_META_U(unit, 3339 "%s\n"), soc_errmsg(rc))); 3340 return rc; 3341 } 3342 for(i=0; i < nof_interrupts; i++) { 3343 if(reg == interrupts_arr[i].reg && field == interrupts_arr[i].field && reg_index == interrupts_arr[i].reg_index) { 3344 3345 if (interrupts_arr[i].bit_in_field == SOC_INTERRUPT_BIT_FIELD_DONT_CARE || 3346 interrupts_arr[i].bit_in_field == bit_in_field) { 3347 *interrupt_id = i; 3348 break; 3349 } 3350 } 3351 } 3352 3353 if(*interrupt_id == -1) { 3354 LOG_ERROR(BSL_LS_SOC_INTR, 3355 (BSL_META_U(unit, 3356 "interrupt ID was not found\n"))); 3357 return SOC_E_UNAVAIL; 3358 } 3359 3360 return rc; 3361 } 3362 3363 int 3364 soc_get_interrupt_id_specific(int unit, int reg_adress, int reg_block, int field_bit, int* interrupt_id) 3365 { 3366 soc_interrupt_db_t *interrupts_arr; 3367 int nof_interrupts; 3368 soc_field_info_t *finfop; 3369 int i, blk_indx; 3370 int rc = SOC_E_NONE; 3371 3372 if (!SOC_INTR_IS_SUPPORTED(unit)) { 3373 LOG_ERROR(BSL_LS_SOC_INTR, 3374 (BSL_META_U(unit, 3375 "No interrupts for device\n"))); 3376 return SOC_E_UNAVAIL; 3377 } 3378 3379 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 3380 if (interrupts_arr == NULL) { 3381 LOG_ERROR(BSL_LS_SOC_INTR, 3382 (BSL_META_U(unit, 3383 "Null parameter\n"))); 3384 return SOC_E_PARAM; 3385 } 3386 3387 *interrupt_id = -1; 3388 3389 /* find the block index */ 3390 for(blk_indx = 0 ; SOC_BLOCK_INFO(unit, blk_indx).type >= 0; ++blk_indx ) { 3391 if (SOC_INFO(unit).block_valid[blk_indx]) { 3392 if (reg_block == SOC_BLOCK_INFO(unit, blk_indx).cmic) { 3393 break; 3394 } 3395 } 3396 } 3397 3398 if(SOC_BLOCK_INFO(unit, blk_indx).type < 0) { 3399 LOG_ERROR(BSL_LS_SOC_INTR, 3400 (BSL_META_U(unit, 3401 "Block number invalid\n"))); 3402 return SOC_E_PARAM; 3403 } 3404 3405 rc = soc_nof_interrupts(unit, &nof_interrupts); 3406 if (SOC_FAILURE(rc)) { 3407 LOG_ERROR(BSL_LS_SOC_INTR, 3408 (BSL_META_U(unit, 3409 "%s\n"), soc_errmsg(rc))); 3410 return rc; 3411 } 3412 3413 /* look for interrupt id*/ 3414 for(i=0; i < nof_interrupts; i++) { 3415 /* check block */ 3416 if(soc_interrupt_is_supported(unit, SOC_BLOCK_INFO(unit, blk_indx).number, i) == 0x0) { 3417 continue; 3418 } 3419 3420 if(SOC_BLOCK_INFO(unit, blk_indx).type != SOC_REG_INFO(unit, interrupts_arr[i].reg).block[0]) { 3421 continue; 3422 } 3423 3424 /* check address */ 3425 if(reg_adress == (SOC_REG_INFO(unit, interrupts_arr[i].reg ).offset + interrupts_arr[i].reg_index)){ 3426 3427 3428 SOC_FIND_FIELD( interrupts_arr[i].field, 3429 SOC_REG_INFO(unit, interrupts_arr[i].reg).fields, 3430 SOC_REG_INFO(unit, interrupts_arr[i].reg).nFields, 3431 finfop); 3432 3433 if(!finfop) { 3434 continue; 3435 } 3436 /* check interrupt bit */ 3437 if(interrupts_arr[i].bit_in_field == SOC_INTERRUPT_BIT_FIELD_DONT_CARE ) { 3438 if(field_bit != finfop->bp ) { 3439 continue; 3440 } 3441 }else { 3442 if(field_bit != finfop->bp + interrupts_arr[i].bit_in_field ) { 3443 continue; 3444 } 3445 } 3446 3447 *interrupt_id = i; 3448 3449 break; 3450 } 3451 } 3452 3453 if(*interrupt_id == -1) { 3454 LOG_ERROR(BSL_LS_SOC_INTR, 3455 (BSL_META_U(unit, 3456 "interrupt ID was not found\n"))); 3457 return SOC_E_NOT_FOUND; 3458 } 3459 3460 return rc; 3461 } 3462 3463 /*number of interrupts per block instance*/ 3464 int soc_nof_interrupts(int unit, int* nof_interrupts) { 3465 int rc = SOC_E_NONE; 3466 3467 if (nof_interrupts == NULL) { 3468 LOG_ERROR(BSL_LS_SOC_INTR, 3469 (BSL_META_U(unit, 3470 "Null parameter\n"))); 3471 return SOC_E_PARAM; 3472 } 3473 3474 *nof_interrupts = 0; 3475 3476 #ifdef BCM_DFE_SUPPORT 3477 if(SOC_IS_DFE(unit)) { 3478 rc = soc_dfe_nof_interrupts(unit, nof_interrupts); 3479 if (SOC_FAILURE(rc)) { 3480 LOG_ERROR(BSL_LS_SOC_INTR, 3481 (BSL_META_U(unit, 3482 "%s\n"), soc_errmsg(rc))); 3483 return rc; 3484 } 3485 } 3486 #endif 3487 #ifdef BCM_PETRA_SUPPORT 3488 #ifdef BCM_QUX_SUPPORT 3489 if (SOC_IS_QUX(unit)) { 3490 rc = soc_qux_nof_interrupts(unit, nof_interrupts); 3491 if (SOC_FAILURE(rc)) { 3492 LOG_ERROR(BSL_LS_SOC_INTR, 3493 (BSL_META_U(unit, 3494 "%s\n"), soc_errmsg(rc))); 3495 return rc; 3496 } 3497 } else 3498 #endif 3499 #ifdef BCM_JERICHO_PLUS_SUPPORT 3500 if (SOC_IS_JERICHO_PLUS_ONLY(unit)) { 3501 rc = soc_jerp_nof_interrupts(unit, nof_interrupts); 3502 if (SOC_FAILURE(rc)) { 3503 LOG_ERROR(BSL_LS_SOC_INTR, 3504 (BSL_META_U(unit, 3505 "%s\n"), soc_errmsg(rc))); 3506 return rc; 3507 } 3508 } else 3509 #endif 3510 if(SOC_IS_ARAD(unit)) { 3511 MBCM_DPP_DRIVER_CALL(unit, mbcm_dpp_nof_interrupts, (unit,nof_interrupts)); 3512 } 3513 #endif 3514 #ifdef BCM_DNXF_SUPPORT 3515 if(SOC_IS_RAMON(unit)){ 3516 rc = soc_ramon_nof_interrupts(unit, nof_interrupts); 3517 if (SOC_FAILURE(rc)) { 3518 LOG_ERROR(BSL_LS_SOC_INTR, 3519 (BSL_META_U(unit, 3520 "%s\n"), soc_errmsg(rc))); 3521 return rc; 3522 } 3523 } 3524 #endif 3525 #ifdef BCM_DNX_SUPPORT 3526 if(SOC_IS_DNX(unit)) { 3527 *nof_interrupts = dnx_data_intr.general.nof_interrupts_get(unit); 3528 } 3529 #endif 3530 return rc; 3531 } 3532 3533 int soc_interrupt_get_block_index_from_port(int unit, int interrupt_id, int port) 3534 { 3535 int index = port; 3536 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) 3537 soc_interrupt_db_t *interrupts_arr; 3538 soc_block_types_t block_types; 3539 3540 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 3541 3542 block_types = SOC_REG_INFO(unit, interrupts_arr[interrupt_id].reg).block; 3543 3544 if(SOC_IS_ARAD(unit) || SOC_IS_DNXF(unit) || SOC_IS_DNX(unit)){ 3545 if(SOC_BLOCK_IN_LIST(block_types, SOC_BLK_CLP)) { 3546 index = SOC_PORT_BLOCK_NUMBER(unit, port); 3547 } else if(SOC_BLOCK_IN_LIST(block_types, SOC_BLK_XLP)){ 3548 index = (SOC_IS_JERICHO(unit) || SOC_IS_DNXF(unit) || SOC_IS_DNX(unit)) ? SOC_PORT_BLOCK_NUMBER(unit, port) : SOC_PORT_BLOCK_NUMBER(unit, port) + SOC_MAX_NUM_CLP_BLKS; 3549 } 3550 } 3551 #endif /* BCM_PETRA_SUPPORT */ 3552 3553 return index; 3554 } 3555 3556 int soc_interrupt_get_intr_port_from_index(int unit, int interrupt_id, int block_instance) 3557 { 3558 int port=block_instance; 3559 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) 3560 int bi_index; 3561 soc_interrupt_db_t *interrupts_arr; 3562 soc_block_types_t block_types; 3563 soc_block_info_t *bi; 3564 3565 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 3566 block_types = SOC_REG_INFO(unit, interrupts_arr[interrupt_id].reg).block; 3567 3568 if((SOC_IS_ARAD(unit) || SOC_IS_DNXF(unit) || SOC_IS_DNX(unit)) && 3569 (SOC_BLOCK_IN_LIST(block_types, SOC_BLK_CLP) || SOC_BLOCK_IN_LIST(block_types, SOC_BLK_XLP))) { 3570 3571 /* find the block index */ 3572 for (bi_index = 0; SOC_BLOCK_INFO(unit, bi_index).type >= 0; bi_index++ ) { 3573 bi = &(SOC_BLOCK_INFO(unit, bi_index)); 3574 if(bi->type == block_types[0] && bi->number == block_instance) { 3575 break; 3576 } 3577 3578 } 3579 3580 port = SOC_BLOCK_PORT(unit, bi_index); 3581 } 3582 #endif /* BCM_PETRA_SUPPORT */ 3583 3584 return port; 3585 } 3586 3587 /* 3588 * Interrupt aplication Functions - uses Soc DB 3589 */ 3590 int soc_interrupt_flags_set(int unit, int interrupt_id, uint32 flags) 3591 { 3592 int rc = SOC_E_NONE; 3593 3594 #ifdef BCM_PETRA_SUPPORT 3595 if(SOC_IS_ARAD(unit)) { 3596 rc = sw_state_access[unit].dpp.soc.arad.tm.interrupts.interrupt_data.flags.set(unit, interrupt_id, flags); 3597 if (SOC_FAILURE(rc)) { 3598 LOG_ERROR(BSL_LS_SOC_INTR, 3599 (BSL_META_U(unit, 3600 "%s\n"), soc_errmsg(rc))); 3601 return rc; 3602 } 3603 } else 3604 #endif /* BCM_PETRA_SUPPORT */ 3605 #ifdef BCM_DNXF_SUPPORT 3606 if(SOC_IS_DNXF(unit)) { 3607 rc = dnxf_state.intr.flags.set(unit, interrupt_id, flags); 3608 if (SOC_FAILURE(rc)) { 3609 LOG_ERROR(BSL_LS_SOC_INTR, (BSL_META_U(unit, "%s\n"), soc_errmsg(rc))); 3610 return rc; 3611 } 3612 } else 3613 #endif 3614 #ifdef BCM_DNX_SUPPORT 3615 if(SOC_IS_DNX(unit)) { 3616 rc = intr_db.flags.set(unit, interrupt_id, flags); 3617 if (SOC_FAILURE(rc)) { 3618 LOG_ERROR(BSL_LS_SOC_INTR, (BSL_META_U(unit, "%s\n"), soc_errmsg(rc))); 3619 return rc; 3620 } 3621 } else 3622 #endif 3623 #ifdef BCM_DFE_SUPPORT 3624 if(SOC_IS_DFE(unit)) { 3625 int nof_interrupts; 3626 3627 rc = soc_dfe_nof_interrupts(unit, &nof_interrupts); 3628 if (SOC_FAILURE(rc)) { 3629 LOG_ERROR(BSL_LS_SOC_INTR, 3630 (BSL_META_U(unit, 3631 "%s\n"), soc_errmsg(rc))); 3632 return rc; 3633 } 3634 3635 if(interrupt_id < 0 || interrupt_id >= nof_interrupts) { 3636 LOG_ERROR(BSL_LS_SOC_INTR, 3637 (BSL_META_U(unit, 3638 "Interrupt_id is out of range\n"))); 3639 return SOC_E_PARAM; 3640 } 3641 3642 rc = SOC_DFE_WARM_BOOT_ARR_VAR_SET(unit, INTR_FLAGS, interrupt_id, &flags); 3643 if (SOC_FAILURE(rc)) { 3644 LOG_ERROR(BSL_LS_SOC_INTR, 3645 (BSL_META_U(unit, 3646 "%s\n"), soc_errmsg(rc))); 3647 return rc; 3648 } 3649 } else 3650 #endif /* BCM_DFE_SUPPORT */ 3651 { 3652 LOG_ERROR(BSL_LS_SOC_INTR, 3653 (BSL_META_U(unit, 3654 "Unsupported in this unit type\n"))); 3655 return SOC_E_UNIT; 3656 } 3657 3658 return rc; 3659 } 3660 3661 int soc_interrupt_flags_get(int unit, int interrupt_id, uint32* flags) 3662 { 3663 int rc = SOC_E_NONE; 3664 3665 if (flags == NULL) { 3666 LOG_ERROR(BSL_LS_SOC_INTR, 3667 (BSL_META_U(unit, 3668 "Null parameter\n"))); 3669 return SOC_E_PARAM; 3670 } 3671 3672 #ifdef BCM_PETRA_SUPPORT 3673 if(SOC_IS_ARAD(unit)) { 3674 rc = sw_state_access[unit].dpp.soc.arad.tm.interrupts.interrupt_data.flags.get(unit, interrupt_id, flags); 3675 if (SOC_FAILURE(rc)) { 3676 LOG_ERROR(BSL_LS_SOC_INTR, 3677 (BSL_META_U(unit, 3678 "%s\n"), soc_errmsg(rc))); 3679 return rc; 3680 } 3681 } else 3682 #endif /* BCM_PETRA_SUPPORT */ 3683 #ifdef BCM_DNXF_SUPPORT 3684 if(SOC_IS_DNXF(unit)){ 3685 rc = dnxf_state.intr.flags.get(unit, interrupt_id, flags); 3686 if (SOC_FAILURE(rc)) { 3687 LOG_ERROR(BSL_LS_SOC_INTR, 3688 (BSL_META_U(unit, 3689 "%s\n"), soc_errmsg(rc))); 3690 return rc; 3691 } 3692 } else 3693 #endif 3694 #ifdef BCM_DNX_SUPPORT 3695 if(SOC_IS_DNX(unit)) { 3696 rc = intr_db.flags.get(unit, interrupt_id, flags); 3697 if (SOC_FAILURE(rc)) { 3698 LOG_ERROR(BSL_LS_SOC_INTR, 3699 (BSL_META_U(unit, 3700 "%s\n"), soc_errmsg(rc))); 3701 return rc; 3702 } 3703 } else 3704 #endif 3705 #ifdef BCM_DFE_SUPPORT 3706 if(SOC_IS_DFE(unit)) { 3707 int nof_interrupts; 3708 3709 rc = soc_dfe_nof_interrupts(unit, &nof_interrupts); 3710 if (SOC_FAILURE(rc)) { 3711 LOG_ERROR(BSL_LS_SOC_INTR, 3712 (BSL_META_U(unit, 3713 "%s\n"), soc_errmsg(rc))); 3714 return rc; 3715 } 3716 3717 if(interrupt_id < 0 || interrupt_id >= nof_interrupts) { 3718 LOG_ERROR(BSL_LS_SOC_INTR, 3719 (BSL_META_U(unit, 3720 "Interrupt_id is out of range\n"))); 3721 return SOC_E_PARAM; 3722 } 3723 3724 rc = SOC_DFE_WARM_BOOT_ARR_VAR_GET(unit, INTR_FLAGS, interrupt_id, flags); 3725 if (SOC_FAILURE(rc)) { 3726 LOG_ERROR(BSL_LS_SOC_INTR, 3727 (BSL_META_U(unit, 3728 "%s\n"), soc_errmsg(rc))); 3729 return rc; 3730 } 3731 } else 3732 #endif /* BCM_DFE_SUPPORT */ 3733 { 3734 LOG_ERROR(BSL_LS_SOC_INTR, 3735 (BSL_META_U(unit, 3736 "Unsupported in this unit type\n"))); 3737 return SOC_E_UNIT; 3738 } 3739 3740 return rc; 3741 } 3742 3743 int soc_interrupt_storm_timed_period_set(int unit, int interrupt_id, uint32 storm_timed_period) 3744 { 3745 int rc = SOC_E_NONE; 3746 3747 #ifdef BCM_PETRA_SUPPORT 3748 if(SOC_IS_ARAD(unit)) { 3749 rc = sw_state_access[unit].dpp.soc.arad.tm.interrupts.interrupt_data.storm_timed_period.set(unit, interrupt_id, storm_timed_period); 3750 if (SOC_FAILURE(rc)) { 3751 LOG_ERROR(BSL_LS_SOC_INTR, 3752 (BSL_META_U(unit, 3753 "%s\n"), soc_errmsg(rc))); 3754 return rc; 3755 } 3756 } else 3757 #endif /* BCM_PETRA_SUPPORT */ 3758 #ifdef BCM_DNXF_SUPPORT 3759 if(SOC_IS_DNXF(unit)) { 3760 rc = dnxf_state.intr.storm_timed_period.set(unit, interrupt_id, storm_timed_period); 3761 if (SOC_FAILURE(rc)) { 3762 LOG_ERROR(BSL_LS_SOC_INTR, 3763 (BSL_META_U(unit, 3764 "%s\n"), soc_errmsg(rc))); 3765 return rc; 3766 } 3767 } else 3768 #endif /* BCM_PETRA_SUPPORT */ 3769 #ifdef BCM_DNX_SUPPORT 3770 if(SOC_IS_DNX(unit)) { 3771 rc = intr_db.storm_timed_period.set(unit, interrupt_id, storm_timed_period); 3772 if (SOC_FAILURE(rc)) { 3773 LOG_ERROR(BSL_LS_SOC_INTR, 3774 (BSL_META_U(unit, 3775 "%s\n"), soc_errmsg(rc))); 3776 return rc; 3777 } 3778 } else 3779 #endif /* BCM_PETRA_SUPPORT */ 3780 #ifdef BCM_DFE_SUPPORT 3781 if(SOC_IS_DFE(unit)) { 3782 int nof_interrupts; 3783 3784 /* get num of interrupts */ 3785 rc = soc_dfe_nof_interrupts(unit, &nof_interrupts); 3786 if (SOC_FAILURE(rc)) { 3787 LOG_ERROR(BSL_LS_SOC_INTR, 3788 (BSL_META_U(unit, 3789 "%s\n"), soc_errmsg(rc))); 3790 return rc; 3791 } 3792 3793 if(interrupt_id < 0 || interrupt_id >= nof_interrupts) { 3794 LOG_ERROR(BSL_LS_SOC_INTR, 3795 (BSL_META_U(unit, 3796 "Interrupt_id is out of range\n"))); 3797 return SOC_E_PARAM; 3798 } 3799 3800 rc = SOC_DFE_WARM_BOOT_ARR_VAR_SET(unit, INTR_STORM_TIMED_PERIOD, interrupt_id, &storm_timed_period); 3801 if (SOC_FAILURE(rc)) { 3802 LOG_ERROR(BSL_LS_SOC_INTR, 3803 (BSL_META_U(unit, 3804 "%s\n"), soc_errmsg(rc))); 3805 return rc; 3806 } 3807 } else 3808 #endif /* BCM_DFE_SUPPORT */ 3809 { 3810 LOG_ERROR(BSL_LS_SOC_INTR, 3811 (BSL_META_U(unit, 3812 "Unsupported in this unit type\n"))); 3813 return SOC_E_UNIT; 3814 } 3815 3816 return rc; 3817 } 3818 3819 int soc_interrupt_storm_timed_period_get(int unit, int interrupt_id, uint32* storm_timed_period) 3820 { 3821 int rc = SOC_E_NONE; 3822 3823 if (storm_timed_period == NULL) { 3824 LOG_ERROR(BSL_LS_SOC_INTR, 3825 (BSL_META_U(unit, 3826 "Null parameter\n"))); 3827 return SOC_E_PARAM; 3828 } 3829 3830 #ifdef BCM_PETRA_SUPPORT 3831 if(SOC_IS_ARAD(unit)) { 3832 rc = sw_state_access[unit].dpp.soc.arad.tm.interrupts.interrupt_data.storm_timed_period.get(unit, interrupt_id, storm_timed_period); 3833 if (SOC_FAILURE(rc)) { 3834 LOG_ERROR(BSL_LS_SOC_INTR, 3835 (BSL_META_U(unit, 3836 "%s\n"), soc_errmsg(rc))); 3837 return rc; 3838 } 3839 } else 3840 #endif /* BCM_PETRA_SUPPORT */ 3841 #ifdef BCM_DNXF_SUPPORT 3842 if(SOC_IS_DNXF(unit)) { 3843 rc = dnxf_state.intr.storm_timed_period.get(unit, interrupt_id, storm_timed_period); 3844 if (SOC_FAILURE(rc)) { 3845 LOG_ERROR(BSL_LS_SOC_INTR, 3846 (BSL_META_U(unit, 3847 "%s\n"), soc_errmsg(rc))); 3848 return rc; 3849 } 3850 } else 3851 #endif /* BCM_DNXF_SUPPORT */ 3852 #ifdef BCM_DNX_SUPPORT 3853 if(SOC_IS_DNX(unit)) { 3854 rc = intr_db.storm_timed_period.get(unit, interrupt_id, storm_timed_period); 3855 if (SOC_FAILURE(rc)) { 3856 LOG_ERROR(BSL_LS_SOC_INTR, 3857 (BSL_META_U(unit, 3858 "%s\n"), soc_errmsg(rc))); 3859 return rc; 3860 } 3861 } else 3862 #endif 3863 #ifdef BCM_DFE_SUPPORT 3864 if(SOC_IS_DFE(unit)) { 3865 int nof_interrupts; 3866 3867 rc = soc_dfe_nof_interrupts(unit, &nof_interrupts); 3868 if (SOC_FAILURE(rc)) { 3869 LOG_ERROR(BSL_LS_SOC_INTR, 3870 (BSL_META_U(unit, 3871 "%s\n"), soc_errmsg(rc))); 3872 return rc; 3873 } 3874 3875 if(interrupt_id < 0 || interrupt_id >= nof_interrupts) { 3876 LOG_ERROR(BSL_LS_SOC_INTR, 3877 (BSL_META_U(unit, 3878 "Interrupt_id is out of range\n"))); 3879 return SOC_E_PARAM; 3880 } 3881 3882 rc = SOC_DFE_WARM_BOOT_ARR_VAR_GET(unit, INTR_STORM_TIMED_PERIOD, interrupt_id, storm_timed_period); 3883 if (SOC_FAILURE(rc)) { 3884 LOG_ERROR(BSL_LS_SOC_INTR, 3885 (BSL_META_U(unit, 3886 "%s\n"), soc_errmsg(rc))); 3887 return rc; 3888 } 3889 } else 3890 #endif /* BCM_DFE_SUPPORT */ 3891 { 3892 LOG_ERROR(BSL_LS_SOC_INTR, 3893 (BSL_META_U(unit, 3894 "Unsupported in this unit type\n"))); 3895 return SOC_E_UNIT; 3896 } 3897 3898 return rc; 3899 } 3900 3901 int soc_interrupt_storm_timed_count_set(int unit, int interrupt_id, uint32 storm_timed_count) 3902 { 3903 int rc = SOC_E_NONE; 3904 3905 #ifdef BCM_PETRA_SUPPORT 3906 if(SOC_IS_ARAD(unit)) { 3907 rc = sw_state_access[unit].dpp.soc.arad.tm.interrupts.interrupt_data.storm_timed_count.set(unit, interrupt_id, storm_timed_count); 3908 if (SOC_FAILURE(rc)) { 3909 LOG_ERROR(BSL_LS_SOC_INTR, 3910 (BSL_META_U(unit, 3911 "%s\n"), soc_errmsg(rc))); 3912 return rc; 3913 } 3914 } else 3915 #endif /* BCM_PETRA_SUPPORT */ 3916 #ifdef BCM_DNXF_SUPPORT 3917 if(SOC_IS_DNXF(unit)) { 3918 rc = dnxf_state.intr.storm_timed_count.set(unit, interrupt_id, storm_timed_count); 3919 if (SOC_FAILURE(rc)) { 3920 LOG_ERROR(BSL_LS_SOC_INTR, 3921 (BSL_META_U(unit, 3922 "%s\n"), soc_errmsg(rc))); 3923 return rc; 3924 } 3925 } else 3926 #endif /* BCM_DNXF_SUPPORT */ 3927 #ifdef BCM_DNX_SUPPORT 3928 if(SOC_IS_DNX(unit)) { 3929 rc = intr_db.storm_timed_count.set(unit, interrupt_id, storm_timed_count); 3930 if (SOC_FAILURE(rc)) { 3931 LOG_ERROR(BSL_LS_SOC_INTR, 3932 (BSL_META_U(unit, 3933 "%s\n"), soc_errmsg(rc))); 3934 return rc; 3935 } 3936 } else 3937 #endif /* BCM_DNXF_SUPPORT */ 3938 #ifdef BCM_DFE_SUPPORT 3939 if(SOC_IS_DFE(unit)) { 3940 int nof_interrupts; 3941 3942 /* get num of interrupts */ 3943 rc = soc_dfe_nof_interrupts(unit, &nof_interrupts); 3944 if (SOC_FAILURE(rc)) { 3945 LOG_ERROR(BSL_LS_SOC_INTR, 3946 (BSL_META_U(unit, 3947 "%s\n"), soc_errmsg(rc))); 3948 return rc; 3949 } 3950 3951 if(interrupt_id < 0 || interrupt_id >= nof_interrupts) { 3952 LOG_ERROR(BSL_LS_SOC_INTR, 3953 (BSL_META_U(unit, 3954 "Interrupt_id is out of range\n"))); 3955 return SOC_E_PARAM; 3956 } 3957 3958 rc = SOC_DFE_WARM_BOOT_ARR_VAR_SET(unit, INTR_STORM_TIMED_COUNT, interrupt_id, &storm_timed_count); 3959 if (SOC_FAILURE(rc)) { 3960 LOG_ERROR(BSL_LS_SOC_INTR, 3961 (BSL_META_U(unit, 3962 "%s\n"), soc_errmsg(rc))); 3963 return rc; 3964 } 3965 } else 3966 #endif /* BCM_DFE_SUPPORT */ 3967 { 3968 LOG_ERROR(BSL_LS_SOC_INTR, 3969 (BSL_META_U(unit, 3970 "Unsupported in this unit type\n"))); 3971 return SOC_E_UNIT; 3972 } 3973 3974 return rc; 3975 } 3976 3977 int soc_interrupt_storm_timed_count_get(int unit, int interrupt_id, uint32* storm_timed_count) 3978 { 3979 int rc = SOC_E_NONE; 3980 3981 if (storm_timed_count == NULL) { 3982 LOG_ERROR(BSL_LS_SOC_INTR, 3983 (BSL_META_U(unit, 3984 "Null parameter\n"))); 3985 return SOC_E_PARAM; 3986 } 3987 3988 #ifdef BCM_PETRA_SUPPORT 3989 if(SOC_IS_ARAD(unit)) { 3990 rc = sw_state_access[unit].dpp.soc.arad.tm.interrupts.interrupt_data.storm_timed_count.get(unit, interrupt_id, storm_timed_count); 3991 if (SOC_FAILURE(rc)) { 3992 LOG_ERROR(BSL_LS_SOC_INTR, 3993 (BSL_META_U(unit, 3994 "%s\n"), soc_errmsg(rc))); 3995 return rc; 3996 } 3997 } else 3998 #endif /* BCM_PETRA_SUPPORT */ 3999 #ifdef BCM_DNXF_SUPPORT 4000 if(SOC_IS_DNXF(unit)) { 4001 rc = dnxf_state.intr.storm_timed_count.get(unit, interrupt_id, storm_timed_count); 4002 if (SOC_FAILURE(rc)) { 4003 LOG_ERROR(BSL_LS_SOC_INTR, 4004 (BSL_META_U(unit, 4005 "%s\n"), soc_errmsg(rc))); 4006 return rc; 4007 } 4008 } else 4009 #endif /* BCM_DNXF_SUPPORT */ 4010 #ifdef BCM_DNX_SUPPORT 4011 if(SOC_IS_DNX(unit)) { 4012 rc = intr_db.storm_timed_count.get(unit, interrupt_id, storm_timed_count); 4013 if (SOC_FAILURE(rc)) { 4014 LOG_ERROR(BSL_LS_SOC_INTR, 4015 (BSL_META_U(unit, 4016 "%s\n"), soc_errmsg(rc))); 4017 return rc; 4018 } 4019 } else 4020 #endif 4021 #ifdef BCM_DFE_SUPPORT 4022 if(SOC_IS_DFE(unit)) { 4023 int nof_interrupts; 4024 4025 rc = soc_dfe_nof_interrupts(unit, &nof_interrupts); 4026 if (SOC_FAILURE(rc)) { 4027 LOG_ERROR(BSL_LS_SOC_INTR, 4028 (BSL_META_U(unit, 4029 "%s\n"), soc_errmsg(rc))); 4030 return rc; 4031 } 4032 4033 if(interrupt_id < 0 || interrupt_id >= nof_interrupts) { 4034 LOG_ERROR(BSL_LS_SOC_INTR, 4035 (BSL_META_U(unit, 4036 "Interrupt_id is out of range\n"))); 4037 return SOC_E_PARAM; 4038 } 4039 4040 rc = SOC_DFE_WARM_BOOT_ARR_VAR_GET(unit, INTR_STORM_TIMED_COUNT, interrupt_id, storm_timed_count); 4041 if (SOC_FAILURE(rc)) { 4042 LOG_ERROR(BSL_LS_SOC_INTR, 4043 (BSL_META_U(unit, 4044 "%s\n"), soc_errmsg(rc))); 4045 return rc; 4046 } 4047 } else 4048 #endif /* BCM_DFE_SUPPORT */ 4049 { 4050 LOG_ERROR(BSL_LS_SOC_INTR, 4051 (BSL_META_U(unit, 4052 "Unsupported in this unit type\n"))); 4053 return SOC_E_UNIT; 4054 } 4055 4056 return rc; 4057 } 4058 4059 int soc_interrupt_update_storm_detection(int unit, int block_instance, soc_interrupt_db_t *inter) 4060 { 4061 uint32 current_time, storm_timed_period, storm_timed_count; 4062 int inf_index ; 4063 int rc = SOC_E_NONE; 4064 4065 if (inter == NULL) { 4066 LOG_ERROR(BSL_LS_SOC_INTR, 4067 (BSL_META_U(unit, 4068 "Null parameter\n"))); 4069 return SOC_E_PARAM; 4070 } 4071 4072 current_time = sal_time(); 4073 4074 inf_index = soc_interrupt_get_block_index_from_port(unit, inter->id, block_instance); 4075 if(inf_index < 0) { 4076 LOG_ERROR(BSL_LS_SOC_INTR, 4077 (BSL_META_U(unit, 4078 "Invalid parameters\n"))); 4079 return SOC_E_PARAM; 4080 } 4081 4082 rc = soc_interrupt_storm_timed_period_get(unit, inter->id, &storm_timed_period); 4083 if (SOC_FAILURE(rc)) { 4084 LOG_ERROR(BSL_LS_SOC_INTR, 4085 (BSL_META_U(unit, 4086 "%s\n"), soc_errmsg(rc))); 4087 return rc; 4088 } 4089 4090 rc = soc_interrupt_storm_timed_count_get(unit, inter->id, &storm_timed_count); 4091 if (SOC_FAILURE(rc)) { 4092 LOG_ERROR(BSL_LS_SOC_INTR, 4093 (BSL_META_U(unit, 4094 "%s\n"), soc_errmsg(rc))); 4095 return rc; 4096 } 4097 4098 if (storm_timed_count > 0 && storm_timed_period > 0) { 4099 4100 if ((current_time - inter->storm_detection_start_time[inf_index]) > storm_timed_period) { 4101 inter->storm_detection_start_time[inf_index] = current_time; 4102 inter->storm_detection_occurrences[inf_index] = 0; 4103 } 4104 (inter->storm_detection_occurrences[inf_index])++; 4105 } 4106 4107 if (SOC_SWITCH_EVENT_NOMINAL_STORM(unit) > 0) { 4108 if (inter->storm_nominal_count[inf_index] >= SOC_SWITCH_EVENT_NOMINAL_STORM(unit)) { 4109 inter->storm_nominal_count[inf_index] = 0; 4110 } else { 4111 (inter->storm_nominal_count[inf_index])++; 4112 } 4113 } 4114 4115 return rc; 4116 } 4117 4118 int soc_interrupt_is_storm(int unit, int block_instance, soc_interrupt_db_t *inter, int *is_storm_count_period,int *is_storm_nominal) { 4119 4120 int inf_index = block_instance; 4121 uint32 storm_timed_count; 4122 int rc = SOC_E_NONE; 4123 4124 if (inter == NULL || is_storm_count_period == NULL || is_storm_nominal == NULL) { 4125 LOG_ERROR(BSL_LS_SOC_INTR, 4126 (BSL_META_U(unit, 4127 "Null parameter\n"))); 4128 return SOC_E_PARAM; 4129 } 4130 4131 *is_storm_count_period = 0x0; 4132 *is_storm_nominal = 0x0; 4133 4134 inf_index = soc_interrupt_get_block_index_from_port(unit, inter->id, block_instance); 4135 if(inf_index < 0) { 4136 LOG_ERROR(BSL_LS_SOC_INTR, 4137 (BSL_META_U(unit, 4138 "Invalid parameters\n"))); 4139 return SOC_E_PARAM; 4140 } 4141 4142 rc = soc_interrupt_storm_timed_count_get(unit, inter->id, &storm_timed_count); 4143 if (SOC_FAILURE(rc)) { 4144 LOG_ERROR(BSL_LS_SOC_INTR, 4145 (BSL_META_U(unit, 4146 "%s\n"), soc_errmsg(rc))); 4147 return rc; 4148 } 4149 4150 if ((storm_timed_count != 0x0) && (inter->storm_detection_occurrences[inf_index] >= storm_timed_count)) { 4151 inter->storm_detection_occurrences[inf_index] = 0x0; 4152 *is_storm_count_period = 0x1; 4153 } 4154 4155 if ((SOC_SWITCH_EVENT_NOMINAL_STORM(unit) != 0x0) && (inter->storm_nominal_count[inf_index] >= SOC_SWITCH_EVENT_NOMINAL_STORM(unit))){ 4156 inter->storm_nominal_count[inf_index] = 0x0; 4157 *is_storm_nominal = 0x1; 4158 } 4159 4160 return rc; 4161 } 4162 4163 int soc_interrupt_clear_all(int unit){ 4164 int is_valid; 4165 int nof_interrupts; 4166 int inter; 4167 int bi_index, int_port; 4168 int rc = SOC_E_NONE; 4169 soc_block_info_t *bi; 4170 int is_on; 4171 soc_interrupt_db_t *interrupts_arr; 4172 4173 if(!SOC_INTR_IS_SUPPORTED(unit)) { 4174 LOG_ERROR(BSL_LS_SOC_INTR, 4175 (BSL_META_U(unit, 4176 "No interrupts for device\n"))); 4177 return SOC_E_UNAVAIL; 4178 } 4179 4180 interrupts_arr = SOC_CONTROL(unit)->interrupts_info->interrupt_db_info; 4181 4182 soc_nof_interrupts(unit, &nof_interrupts); 4183 for (bi_index = 0; SOC_BLOCK_INFO(unit, bi_index).type >= 0; bi_index++ ) { 4184 for (inter = 0; inter < nof_interrupts ; inter++) { 4185 if (!SOC_INFO(unit).block_valid[bi_index]) { 4186 continue; 4187 } 4188 4189 bi = &(SOC_BLOCK_INFO(unit, bi_index)); 4190 if(NULL == bi) { 4191 /* 4192 * Coverity 4193 * This is defencive statement. 4194 * 4195 * coverity[dead_error_begin] 4196 */ 4197 LOG_ERROR(BSL_LS_SOC_INTR, 4198 (BSL_META_U(unit, 4199 "Unknown block %d\n"), bi_index)); 4200 return SOC_E_FAIL; 4201 } 4202 4203 if (!SOC_INFO(unit).block_valid[bi_index]) { 4204 continue; 4205 } 4206 4207 rc = soc_interrupt_is_valid(unit, bi, &(interrupts_arr[inter]), &is_valid); 4208 if (SOC_FAILURE(rc)) { 4209 LOG_ERROR(BSL_LS_SOC_INTR, 4210 (BSL_META_U(unit, 4211 "%s\n"), soc_errmsg(rc))); 4212 return rc; 4213 } 4214 if (!is_valid) { 4215 continue; 4216 } 4217 4218 #if defined(BCM_PETRA_SUPPORT) 4219 if(SOC_IS_ARAD(unit) && (bi->type == SOC_BLK_CLP || bi->type == SOC_BLK_XLP )) { 4220 soc_port_if_t if_type; 4221 int_port = SOC_BLOCK_PORT(unit, bi_index); 4222 if (int_port & SOC_REG_ADDR_INSTANCE_MASK) { 4223 continue; 4224 } 4225 4226 rc = soc_port_sw_db_interface_type_get(unit, int_port, &if_type); 4227 if (if_type == SOC_PORT_IF_ILKN) { 4228 continue; 4229 } 4230 } else 4231 #endif /* BCM_PETRA_SUPPORT */ 4232 int_port = bi->number; 4233 4234 rc = soc_interrupt_get(unit, int_port, &(interrupts_arr[inter]), &is_on ); 4235 4236 if (is_on) { 4237 if(NULL != interrupts_arr[inter].interrupt_clear) { 4238 rc = interrupts_arr[inter].interrupt_clear(unit, int_port , inter); 4239 if (SOC_FAILURE(rc)) { 4240 LOG_ERROR(BSL_LS_SOC_INTR, 4241 (BSL_META_U(unit, 4242 "%s\n"), soc_errmsg(rc))); 4243 return rc; 4244 } 4245 } 4246 } 4247 } 4248 } 4249 4250 return rc; 4251 } 4252 4253 int soc_interrupt_is_all_clear(int unit, int *is_all_clear){ 4254 soc_interrupt_cause_t interrupt; 4255 int total = 0; 4256 int rc = SOC_E_NONE; 4257 4258 if (is_all_clear == NULL) { 4259 LOG_ERROR(BSL_LS_SOC_INTR, 4260 (BSL_META_U(unit, 4261 "Null parameter\n"))); 4262 return SOC_E_PARAM; 4263 } 4264 4265 rc = soc_active_interrupts_get(unit, 0x0 ,1, &interrupt, &total); 4266 if (SOC_FAILURE(rc)) { 4267 LOG_ERROR(BSL_LS_SOC_INTR, 4268 (BSL_META_U(unit, 4269 "%s\n"), soc_errmsg(rc))); 4270 return rc; 4271 } 4272 4273 *is_all_clear = (total == 0); 4274 4275 return rc; 4276 } 4277 4278 int soc_interrupt_is_all_mask(int unit, int *is_all_mask){ 4279 uint32 mask[4];/*4 is the amount which needed for maximum 128 blocks per device*/ 4280 int i; 4281 int rc = SOC_E_NONE; 4282 4283 if (is_all_mask == NULL) { 4284 LOG_ERROR(BSL_LS_SOC_INTR, 4285 (BSL_META_U(unit, 4286 "Null parameter\n"))); 4287 return SOC_E_PARAM; 4288 } 4289 4290 sal_memset(mask, 0x0, sizeof(mask)); 4291 4292 #ifdef BCM_CMICX_SUPPORT 4293 if (soc_feature(unit, soc_feature_cmicx)) { 4294 /* interrupt number is CHIP_INTR_LOW_PRIORITY=119 */ 4295 return soc_cmic_intr_is_mask(unit, CHIP_INTR_LOW_PRIORITY, is_all_mask); 4296 } 4297 #endif 4298 4299 if (!soc_feature(unit, soc_feature_cmicm)) { 4300 mask[0] = SOC_IRQ1_MASK(unit); 4301 mask[1] = SOC_IRQ2_MASK(unit); 4302 } else { 4303 #ifdef BCM_CMICM_SUPPORT 4304 mask[0] = SOC_CMCx_IRQ3_MASK(unit, SOC_PCI_CMC(unit)); 4305 mask[1] = SOC_CMCx_IRQ4_MASK(unit, SOC_PCI_CMC(unit)); 4306 if (soc_feature(unit, soc_feature_cmicm_extended_interrupts)) { 4307 mask[2] = SOC_CMCx_IRQ3_MASK(unit, SOC_PCI_CMC(unit)); 4308 mask[3] = SOC_CMCx_IRQ4_MASK(unit, SOC_PCI_CMC(unit)); 4309 } 4310 #endif 4311 } 4312 for(i = 0; i < 4; i++) { 4313 if (mask[i]) { 4314 *is_all_mask = FALSE; 4315 return rc; 4316 } 4317 } 4318 4319 *is_all_mask = TRUE; 4320 4321 return rc; 4322 } 4323 4324 /* 4325 * Statistics functions 4326 */ 4327 int soc_interrupt_stat_cnt_increase(int unit, int bi, int interrupt_id) 4328 { 4329 int nof_interrupts; 4330 soc_interrupt_db_t *intr_id_db; 4331 int rc = SOC_E_NONE; 4332 4333 if(!SOC_INTR_IS_SUPPORTED(unit)) { 4334 LOG_ERROR(BSL_LS_SOC_INTR, 4335 (BSL_META_U(unit, 4336 "No interrupts for device\n"))); 4337 return SOC_E_UNAVAIL; 4338 } 4339 4340 /*verify interrupt_id*/ 4341 soc_nof_interrupts(unit, &nof_interrupts); 4342 if ((interrupt_id > nof_interrupts) || interrupt_id < 0) { 4343 LOG_ERROR(BSL_LS_SOC_INTR, 4344 (BSL_META_U(unit, 4345 "event_id is unavail\n"))); 4346 return SOC_E_UNAVAIL; 4347 } 4348 4349 /* Get specific interrupt soc db */ 4350 intr_id_db = &(SOC_CONTROL(unit)->interrupts_info->interrupt_db_info[interrupt_id]); 4351 4352 /* Increase statistics count */ 4353 (intr_id_db->statistics_count[bi]) ++; 4354 4355 return rc; 4356 } 4357 4358 /* 4359 * Sort interrupts according to priority 4360 */ 4361 int soc_sort_interrupts_according_to_priority(int unit, soc_interrupt_cause_t* interrupts, uint32 interrupts_size) 4362 { 4363 4364 int i,j; 4365 int left_interrupt_priority,right_interrupt_priority; 4366 int stop_check_flag; 4367 uint32 left_intr_flags, right_intr_flags; 4368 soc_interrupt_cause_t tmp; 4369 int rc = SOC_E_NONE; 4370 4371 if(!SOC_INTR_IS_SUPPORTED(unit)) { 4372 LOG_ERROR(BSL_LS_SOC_INTR, 4373 (BSL_META_U(unit, 4374 "No interrupts for device\n"))); 4375 return SOC_E_UNAVAIL; 4376 } 4377 4378 if (interrupts == NULL) { 4379 LOG_ERROR(BSL_LS_SOC_INTR, 4380 (BSL_META_U(unit, 4381 "Null parameter\n"))); 4382 return SOC_E_PARAM; 4383 } 4384 4385 for(i=interrupts_size-2 ;i>=0;--i) { 4386 stop_check_flag=1; 4387 4388 for(j=0;j<=i;j++) { 4389 rc = soc_interrupt_flags_get(unit, interrupts[j].id, &left_intr_flags); 4390 if (SOC_FAILURE(rc)) { 4391 LOG_ERROR(BSL_LS_SOC_INTR, 4392 (BSL_META_U(unit, 4393 "%s\n"), soc_errmsg(rc))); 4394 return rc; 4395 } 4396 rc = soc_interrupt_flags_get(unit, interrupts[j+1].id, &right_intr_flags); 4397 if (SOC_FAILURE(rc)) { 4398 LOG_ERROR(BSL_LS_SOC_INTR, 4399 (BSL_META_U(unit, 4400 "%s\n"), soc_errmsg(rc))); 4401 return rc; 4402 } 4403 left_interrupt_priority = ((left_intr_flags & SOC_INTERRUPT_DB_FLAGS_PRIORITY_MASK) >> SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LSB); 4404 right_interrupt_priority = ((right_intr_flags & SOC_INTERRUPT_DB_FLAGS_PRIORITY_MASK) >> SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LSB); 4405 4406 if(left_interrupt_priority > right_interrupt_priority) { 4407 tmp = interrupts[j]; 4408 interrupts[j] = interrupts[j+1]; 4409 interrupts[j+1] = tmp; 4410 stop_check_flag = 0; 4411 } 4412 } 4413 4414 if(stop_check_flag == 1) { 4415 break; 4416 } 4417 } 4418 4419 return rc; 4420 } 4421 4422 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_DFE_SUPPORT)|| defined(BCM_PETRA_SUPPORT) || defined(PORTMOD_SUPPORT)*/ 4423 4424 #ifdef BCM_CMICX_SUPPORT 4425 4426 /******************************************* 4427 * @function soc_cmic_intr_enable 4428 * purpose Enable a particular interrupt 4429 * 4430 * @param unit [in] unit 4431 * @param param [in] intr_num_t, Interrupt Number 4432 * 4433 * @returns SOC_E_NONE 4434 * @returns SOC_E_XXX 4435 * 4436 * @end 4437 */ 4438 int 4439 soc_cmic_intr_enable(int unit, intr_num_t intr) 4440 { 4441 int rv; 4442 4443 if (_cmic_intr_op[unit].soc_cmic_intr_enable == NULL) { 4444 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4445 "soc_cmic_intr_enable function is undefined\n"))); 4446 rv = SOC_E_FAIL; 4447 } else { 4448 rv = _cmic_intr_op[unit].soc_cmic_intr_enable(unit, intr); 4449 } 4450 4451 return rv; 4452 } 4453 4454 /******************************************* 4455 * @function soc_cmic_intr_disable 4456 * purpose Enable a particular interrupt 4457 * 4458 * @param unit [in] unit 4459 * @param param [in] intr_num_t, Interrupt Number 4460 * 4461 * @returns SOC_E_NONE 4462 * @returns SOC_E_XXX 4463 * 4464 * @end 4465 */ 4466 int 4467 soc_cmic_intr_disable(int unit, intr_num_t intr) 4468 { 4469 int rv; 4470 4471 if (_cmic_intr_op[unit].soc_cmic_intr_disable == NULL) { 4472 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4473 "soc_cmic_intr_disable function is undefined\n"))); 4474 rv = SOC_E_FAIL; 4475 } else { 4476 rv = _cmic_intr_op[unit].soc_cmic_intr_disable(unit, intr); 4477 } 4478 4479 return rv; 4480 } 4481 4482 /******************************************* 4483 * @function soc_cmic_intr_dump 4484 * purpose dump registers particular interrupt 4485 * 4486 * @param unit [in] unit 4487 * @param param [in] intr_num_t, Interrupt Number 4488 * 4489 * @returns SOC_E_NONE 4490 * @returns SOC_E_XXX 4491 * 4492 * @end 4493 */ 4494 extern int 4495 soc_cmic_intr_dump(int unit, intr_num_t intr) 4496 { 4497 int rv; 4498 4499 if (_cmic_intr_op[unit].soc_cmic_intr_dump == NULL) { 4500 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4501 "soc_cmic_intr_dump function is undefined\n"))); 4502 rv = SOC_E_FAIL; 4503 } else { 4504 rv = _cmic_intr_op[unit].soc_cmic_intr_dump(unit, intr); 4505 } 4506 4507 return rv; 4508 } 4509 4510 4511 /******************************************* 4512 * @function soc_cmic_intr_all_enable 4513 * purpose Enable a particular interrupt 4514 * 4515 * @param unit [in] unit 4516 * 4517 * @returns SOC_E_NONE 4518 * @returns SOC_E_XXX 4519 * 4520 * @end 4521 */ 4522 int 4523 soc_cmic_intr_all_enable(int unit) 4524 { 4525 int rv; 4526 4527 if (_cmic_intr_op[unit].soc_cmic_intr_all_enable == NULL) { 4528 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4529 "soc_cmic_intr_all_enable function is undefined\n"))); 4530 rv = SOC_E_FAIL; 4531 } else { 4532 rv = _cmic_intr_op[unit].soc_cmic_intr_all_enable(unit); 4533 } 4534 4535 return rv; 4536 } 4537 4538 /******************************************* 4539 * @function soc_cmic_intr_all_disable 4540 * purpose Enable a particular interrupt 4541 * 4542 * @param unit [in] unit 4543 * 4544 * @returns SOC_E_NONE 4545 * @returns SOC_E_XXX 4546 * 4547 * @end 4548 */ 4549 int 4550 soc_cmic_intr_all_disable(int unit) 4551 { 4552 int rv; 4553 4554 if (_cmic_intr_op[unit].soc_cmic_intr_all_disable == NULL) { 4555 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4556 "soc_cmic_intr_all_disable function is undefined\n"))); 4557 rv = SOC_E_FAIL; 4558 } else { 4559 rv = _cmic_intr_op[unit].soc_cmic_intr_all_disable(unit); 4560 } 4561 4562 return rv; 4563 } 4564 4565 /******************************************* 4566 * @function soc_cmic_intr_is_mask 4567 * purpose Get a particular interrupt mask 4568 * 4569 * @param unit [in] unit 4570 * @param param [in] intr_num_t, Interrupt Number 4571 * @praram param [out] int, mask 4572 * 4573 * @returns SOC_E_NONE 4574 * @returns SOC_E_XXX 4575 * 4576 * @end 4577 */ 4578 int 4579 soc_cmic_intr_is_mask(int unit, intr_num_t intr, int *mask) 4580 { 4581 int rv; 4582 4583 if (_cmic_intr_op[unit].soc_cmic_intr_is_mask == NULL) { 4584 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4585 "soc_cmic_intr_is_mask function is undefined\n"))); 4586 rv = SOC_E_FAIL; 4587 } else { 4588 rv = _cmic_intr_op[unit].soc_cmic_intr_is_mask(unit, intr, mask); 4589 } 4590 4591 return rv; 4592 } 4593 4594 /******************************************* 4595 * @function soc_cmic_intr_register 4596 * purpose Register the interrupt handler 4597 * 4598 * @param unit [in] unit 4599 * @param param [in] soc_cmic_intr_handler_t pointer 4600 * @param param [in] int, size of the array elements 4601 * 4602 * @returns SOC_E_NONE 4603 * @returns SOC_E_XXX 4604 * 4605 * @end 4606 */ 4607 int 4608 soc_cmic_intr_register(int unit, soc_cmic_intr_handler_t *handle, int size) 4609 { 4610 int rv; 4611 4612 if (_cmic_intr_op[unit].soc_cmic_intr_register == NULL) { 4613 LOG_FATAL(BSL_LS_SOC_INTR, (BSL_META_U(unit, 4614 "soc_cmicx_intr_register function is undefined\n"))); 4615 rv = SOC_E_FAIL; 4616 } else { 4617 rv = _cmic_intr_op[unit].soc_cmic_intr_register(unit, 4618 handle, 4619 size); 4620 } 4621 4622 return rv; 4623 } 4624 4625 /******************************************* 4626 * @function soc_cmic_intr_init 4627 * purpose initialize CMICX interrupt framework 4628 * 4629 * @param unit [in] unit 4630 * 4631 * @returns SOC_E_NONE 4632 * @returns SOC_E_XXX 4633 * 4634 * @end 4635 */ 4636 int 4637 soc_cmic_intr_init(int unit) 4638 { 4639 int rv = SOC_E_FAIL; 4640 4641 #ifdef BCM_CMICX_SUPPORT 4642 if (soc_feature(unit, soc_feature_cmicx)) { 4643 rv = soc_cmicx_intr_init(unit, &_cmic_intr_op[unit]); 4644 } 4645 #endif 4646 4647 return rv; 4648 } 4649 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)*/