intr.h (13725B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 */ 8 9 #ifndef _SOC_INTER_H_ 10 #define _SOC_INTER_H_ 11 12 #include <soc/chip.h> 13 #include <sal/core/sync.h> 14 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) 15 #include <soc/mcm/allenum.h> 16 #endif 17 18 #if defined (BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 19 #define SOC_CMCS_NUM_MAX (5) 20 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 21 22 #ifdef BCM_PETRA_SUPPORT 23 #include <shared/swstate/sw_state.h> 24 #endif /* BCM_PETRA_SUPPORT */ 25 26 /* 27 * Defines 28 */ 29 30 #define SOC_INTERRUPT_INTERRUPT_PER_REG_NUM_MAX 128 /* max number of interrupts at on register for Jericho */ 31 32 #define SOC_INTERRUPT_BIT_FIELD_DONT_CARE -1 33 #define SOC_ACTIVE_INTERRUPTS_GET_UNMASKED_ONLY 0x1 34 #define SOC_ACTIVE_INTERRUPTS_GET_CONT_PREV 0x2 35 36 #define SOC_INTERRUPT_DB_FLAGS_PRINT_ENABLE 0 37 #define SOC_INTERRUPT_DB_FLAGS_CORR_ACT_OVERRIDE_ENABLE 1 38 /* priority bit 2 --5, 4 bits length */ 39 #define SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LSB 2 40 #define SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LEN 4 41 #define SOC_INTERRUPT_DB_FLAGS_UNMASK_AND_CLEAR_DISABLE_BITS 6 42 #define SOC_INTERRUPT_DB_FLAGS_FORCE_UNMASK_BITS 7 43 #define SOC_INTERRUPT_DB_FLAGS_BCM_AND_USR_CB_BIT 8 44 #define SOC_INTERRUPT_DB_FLAGS_FORCE_MASK_BIT 9 45 #define SOC_INTERRUPT_DB_FLAGS_PRIORITY_MAX_VAL 15 46 #define SOC_INTERRUPT_DB_FLAGS_PRIORITY_MASK (((1 << (SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LEN + SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LSB)) - 1) &(~(( 1 << SOC_INTERRUPT_DB_FLAGS_PRIORITY_BITS_LSB) -1))) 47 48 #define SOC_INTERRUPT_DB_FLAGS_UNMASK_AND_CLEAR_DISABLE 0x40 49 #define SOC_INTERRUPT_DB_FLAGS_FORCE_UNMASK 0x80 50 #define SOC_INTERRUPT_DB_FLAGS_BCM_AND_USR_CB 0x100 51 #define SOC_INTERRUPT_DB_FLAGS_FORCE_MASK 0x200 52 53 /* 54 * Types Def 55 */ 56 57 typedef struct soc_interrupt_clear_read_fifo_s { 58 soc_reg_t fifo_reg; 59 uint32 read_count; 60 } soc_interrupt_clear_read_fifo_t; 61 62 typedef struct soc_interrupt_clear_reg_write_s { 63 soc_reg_t status_reg; 64 soc_reg_above_64_val_t data; 65 } soc_interrupt_clear_reg_write_t; 66 67 typedef struct soc_interrupt_clear_array_index_s { 68 soc_reg_t fifo_reg; 69 uint32 read_count; 70 uint32 reg_index; 71 } soc_interrupt_clear_array_index_t; 72 73 typedef struct soc_interrupt_cause_s { 74 int id; 75 int index; 76 } soc_interrupt_cause_t; 77 78 typedef struct soc_interrupt_tree_s { 79 soc_reg_t int_reg; 80 soc_reg_t int_mask_reg; 81 int index; 82 int int_id[SOC_INTERRUPT_INTERRUPT_PER_REG_NUM_MAX]; 83 }soc_interrupt_tree_t; 84 85 typedef int (* clear_func)(int unit, int block_instance, int interrupt_id); 86 87 typedef int (* soc_handle_interrupt_func)(int unit, int block_instance, uint32 en_interrupt, char *msg); 88 89 typedef struct soc_interrupt_db_s { 90 #if !defined(SOC_NO_NAMES) 91 char *name; 92 #endif 93 int id; 94 soc_reg_t reg; 95 soc_reg_t reg_test; 96 int reg_index; 97 soc_field_t field; 98 soc_reg_t mask_reg; 99 int mask_reg_index; 100 soc_reg_t cnt_reg; 101 soc_field_t mask_field; 102 int vector_id; 103 CONST soc_interrupt_tree_t *vector_info; 104 soc_block_type_t block_type; 105 clear_func interrupt_clear; 106 107 /* for clear function */ 108 void *interrupt_clear_param1; 109 void *interrupt_clear_param2; 110 111 /* per block instance*/ 112 uint32 *statistics_count; 113 uint32 *storm_detection_occurrences; 114 uint32 *storm_detection_start_time; 115 uint32 *storm_nominal_count; 116 117 int bit_in_field; 118 119 soc_handle_interrupt_func func_arr;/*interrupt action, always run it*/ 120 121 /* recurring action function/params */ 122 soc_handle_interrupt_func func_arr_recurring_action;/*interrupt action, run it only in a storm*/ 123 int recurring_action_counters; 124 int recurring_action_time; 125 int recurring_action_cycle_time; /*time in seconds of each cycle, -1 is without recurring_action*/ 126 int recurring_action_cycle_counting; /*threshold in each cycle, -1 is without recurring_action*/ 127 char *msg; /*used to give a guidness for manually handled interrupts*/ 128 129 } soc_interrupt_db_t; 130 131 typedef struct soc_interrupt_s { 132 soc_interrupt_db_t *interrupt_db_info; 133 soc_interrupt_tree_t *interrupt_tree_info; /* interrupts array */ 134 sal_sem_t interrupt_sem; 135 } soc_interrupt_t; 136 137 #ifdef BCM_PETRA_SUPPORT 138 typedef struct{ 139 140 uint32 flags; 141 uint32 storm_timed_count; 142 uint32 storm_timed_period; 143 144 } ARAD_INTERRUPT_DATA; 145 146 typedef struct 147 { 148 /* The following 3 variables are not used and remain for future use */ 149 uint32 cmc_irq2_mask[SOC_CMCS_NUM_MAX]; /* Cached copy of CMIC_CMCx_PCIE_IRQ_MASK2 */ 150 uint32 cmc_irq3_mask[SOC_CMCS_NUM_MAX]; /* Cached copy of CMIC_CMCx_PCIE_IRQ_MASK3 */ 151 uint32 cmc_irq4_mask[SOC_CMCS_NUM_MAX]; /* Cached copy of CMIC_CMCx_PCIE_IRQ_MASK4 */ 152 153 PARSER_HINT_ARR ARAD_INTERRUPT_DATA* interrupt_data; 154 155 } ARAD_INTERRUPTS; 156 #endif /* BCM_PETRA_SUPPORT */ 157 158 #define SOC_INTR_IS_SUPPORTED(unit) \ 159 (NULL != SOC_CONTROL(unit)->interrupts_info) 160 161 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT) 162 /* 163 * Functions 164 */ 165 166 /* Main interrupt handling SOC function */ 167 void soc_cmn_block_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4); 168 void soc_cmn_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4); 169 170 /* Per interrupt functions*/ 171 int soc_interrupt_is_valid(int unit, const soc_block_info_t* bi, const soc_interrupt_db_t* inter, int* is_valid /*out*/); 172 int soc_interrupt_get(int unit, int block_instance, const soc_interrupt_db_t* inter, int* inter_val /*out*/); 173 int soc_interrupt_force_get (int unit, int block_instance, const soc_interrupt_db_t* inter, int* inter_val); 174 int soc_interrupt_enable(int unit, int block_instance, const soc_interrupt_db_t* inter); 175 int soc_interrupt_force(int unit, int block_instance, const soc_interrupt_db_t* inter, int action); 176 int soc_interrupt_disable(int unit, int block_instance, const soc_interrupt_db_t* inter); 177 int soc_interrupt_is_enabled(int unit, int block_instance, const soc_interrupt_db_t* inter, int* is_enabled /*out*/); 178 int soc_interrupt_is_supported(int unit, int block_instance, int inter_id); 179 int soc_interrupt_stat_cnt_increase(int unit, int bi, int interrupt_id); 180 181 int soc_interrupt_flags_set(int unit, int interrupt_id, uint32 flags); 182 int soc_interrupt_flags_get(int unit, int interrupt_id, uint32* flags); 183 184 /* Global interrupt functions */ 185 int soc_nof_interrupts(int unit, int* nof_interrupts); 186 int soc_interrupt_is_all_mask(int unit, int *is_all_mask); 187 188 /* get the index of the block from the blocks port and interrupt id*/ 189 int soc_interrupt_get_block_index_from_port(int unit, int interrupt_id, int port); 190 /* get the port of a interrupt from interrupt ID and block index. */ 191 int soc_interrupt_get_intr_port_from_index(int unit, int interrupt_id, int block_instance); 192 193 /* Storm functions */ 194 int soc_interrupt_storm_timed_period_set(int unit, int interrupt_id, uint32 storm_timed_period); 195 int soc_interrupt_storm_timed_period_get(int unit, int intrrupt_id, uint32* storm_timed_period); 196 197 int soc_interrupt_storm_timed_count_set(int unit, int interrupt_id, uint32 storm_timed_count); 198 int soc_interrupt_storm_timed_count_get(int unit, int interrupt_id, uint32* storm_timed_count); 199 200 int soc_interrupt_update_storm_detection(int unit, int block_instance, soc_interrupt_db_t *inter); 201 int soc_interrupt_is_storm(int unit, int block_instance, soc_interrupt_db_t *inter, int *is_storm_count_period,int *is_storm_nominal); 202 203 /* Clear functions */ 204 int soc_interrupt_clear_on_write(int unit, int block_instance, int interrupt_id); 205 int soc_interrupt_clear_on_reg_write(int unit, int block_instance, int interrupt_id); 206 int soc_interrupt_clear_on_clear(int unit, int block_instance, int interrupt_id); 207 int soc_interrupt_clear_on_read_fifo(int unit, int block_instance, int interrupt_id); 208 int soc_interrupt_clear_on_read_array_index(int unit, int block_instance, int interrupt_id); 209 int soc_interrupt_clear_all(int unit); 210 int soc_interrupt_is_all_clear(int unit, int *is_all_clear); 211 212 /* 213 *flags available: 214 * SOC_ACTIVE_INTERRUPTS_GET_ALL - returns all active interrupts 215 * SOC_ACTIVE_INTERRUPTS_GET_UNMASKED_ONLY - returns just active and unmasked interrupts. 216 * SOC_ACTIVE_INTERRUPTS_GET_CONT_PREV - continue checking from th place the function stopped last time. 217 * 218 * output: 219 * total_interrupts - the number of active interrupts (all or unmasked). 220 * interrupts[1..min(max_interrupts_size, *total_interrupts) - 1] - <cause, index> of each active interrupts. 221 * if *total_interrupts > max_interrupts_size interrupts do not include all active interrupts - 222 * for more interrupts run again with the flag SOC_ACTIVE_INTERRUPTS_GET_CONT_PREV. 223 */ 224 extern int 225 soc_active_interrupts_get(int unit, int flags, int max_interrupts_size, 226 soc_interrupt_cause_t *interrupts, 227 int *total_interrupts); 228 229 /* 230 * returns: inter which togther with block_instance identifies the bits of the interrupt. 231 */ 232 extern int 233 soc_interrupt_info_get(int unit, int interrupt_id, soc_interrupt_db_t *inter); 234 235 /* find the interupt ID of the register, register index and field*/ 236 extern int 237 soc_get_interrupt_id(int unit, soc_reg_t reg, int reg_index, soc_field_t field, int bit_in_field, int* interrupt_id); 238 /* find the interrupt ID of register address, block and bit index */ 239 extern int 240 soc_get_interrupt_id_specific(int unit, int reg_adress, int reg_block, int field_bit, int* interrupt_id); 241 /* Order interrupts according to priority */ 242 extern int 243 soc_sort_interrupts_according_to_priority(int unit, soc_interrupt_cause_t *interrupts, uint32 interrupts_size); 244 245 #endif /* #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)*/ 246 247 /* 248 * Following is the CMIC interrupt framework 249 * The frame work will be applicable for CMICX onwards 250 */ 251 252 #ifdef BCM_CMICX_SUPPORT 253 254 #define INTR_NAME_MAX 32 255 typedef unsigned int intr_num_t; 256 257 /* Interrupt handler structure used during registration */ 258 typedef struct soc_cmic_intr_handler_s { 259 intr_num_t num; 260 void (*intr_fn)(int unit, void *data); 261 void *intr_data; 262 char intr_name[INTR_NAME_MAX]; 263 } soc_cmic_intr_handler_t; 264 265 typedef void (*intr_fn_t)(int unit, void *data); 266 267 /* 268 * CMIC operation structure to hold CMIC sprecific 269 * function pointer table 270 */ 271 typedef struct soc_cmic_intr_op_s { 272 int (*soc_cmic_intr_enable)(int unit, intr_num_t intr); 273 int (*soc_cmic_intr_disable)(int unit, intr_num_t intr); 274 int (*soc_cmic_intr_dump)(int unit, intr_num_t intr); 275 int (*soc_cmic_intr_all_enable)(int unit); 276 int (*soc_cmic_intr_all_disable)(int unit); 277 int (*soc_cmic_intr_is_mask)(int unit, intr_num_t intr, int *mask); 278 int (*soc_cmic_intr_register)(int unit, soc_cmic_intr_handler_t *handle, 279 int size); 280 } soc_cmic_intr_op_t; 281 282 283 /******************************************* 284 * @function soc_cmic_intr_enable 285 * purpose Enable a particular interrupt 286 * 287 * @param unit [in] unit 288 * @param param [in] intr_num_t, Interrupt Number 289 * 290 * @returns SOC_E_NONE 291 * @returns SOC_E_XXX 292 * 293 * @end 294 */ 295 extern int 296 soc_cmic_intr_enable(int unit, intr_num_t intr); 297 298 /******************************************* 299 * @function soc_cmic_intr_disable 300 * purpose Enable a particular interrupt 301 * 302 * @param unit [in] unit 303 * @param param [in] intr_num_t, Interrupt Number 304 * 305 * @returns SOC_E_NONE 306 * @returns SOC_E_XXX 307 * 308 * @end 309 */ 310 extern int 311 soc_cmic_intr_disable(int unit, intr_num_t intr); 312 313 314 /******************************************* 315 * @function soc_cmic_intr_dump 316 * purpose dump registers particular interrupt 317 * 318 * @param unit [in] unit 319 * @param param [in] intr_num_t, Interrupt Number 320 * 321 * @returns SOC_E_NONE 322 * @returns SOC_E_XXX 323 * 324 * @end 325 */ 326 extern int 327 soc_cmic_intr_dump(int unit, intr_num_t intr); 328 329 330 331 /******************************************* 332 * @function soc_cmic_intr_all_enable 333 * purpose Enable a particular interrupt 334 * 335 * @param unit [in] unit 336 * 337 * @returns SOC_E_NONE 338 * @returns SOC_E_XXX 339 * 340 * @end 341 */ 342 extern int 343 soc_cmic_intr_all_enable(int unit); 344 345 /******************************************* 346 * @function soc_cmic_all_intr_disable 347 * purpose Enable a particular interrupt 348 * 349 * @param unit [in] unit 350 * 351 * @returns SOC_E_NONE 352 * @returns SOC_E_XXX 353 * 354 * @end 355 */ 356 extern int 357 soc_cmic_intr_all_disable(int unit); 358 359 /******************************************* 360 * @function soc_cmic_intr_is_mask 361 * purpose Get a particular interrupt mask 362 * 363 * @param unit [in] unit 364 * @param param [in] intr_num_t, Interrupt Number 365 * @praram param [out] int, mask 366 * 367 * @returns SOC_E_NONE 368 * @returns SOC_E_XXX 369 * 370 * @end 371 */ 372 extern int 373 soc_cmic_intr_is_mask(int unit, intr_num_t intr, int *mask); 374 375 /******************************************* 376 * @function soc_cmic_intr_register 377 * purpose Register the interrupt handler 378 * 379 * @param unit [in] unit 380 * @param param [in] soc_cmic_intr_handler_t pointer 381 * @param param [in] int, size of the array elements 382 * 383 * @returns SOC_E_NONE 384 * @returns SOC_E_XXX 385 * 386 * @end 387 */ 388 extern int 389 soc_cmic_intr_register(int unit, soc_cmic_intr_handler_t *handle, int size); 390 391 /******************************************* 392 * @function soc_cmic_intr_init 393 * purpose initialize CMIC interrupt framework 394 * 395 * @param unit [in] unit 396 * 397 * @returns SOC_E_NONE 398 * @returns SOC_E_XXX 399 * 400 * @end 401 */ 402 extern int 403 soc_cmic_intr_init(int unit); 404 405 #endif /* BCM_CMICX_SUPPORT */ 406 407 #endif /* _SOC_INTER_H_ */ 408 409