openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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)*/