l2xmsg.c (4564B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: l2xmsg.c 8 * Purpose: Provide needed routines for L2 overflow. 9 */ 10 11 #include <sal/core/libc.h> 12 #include <shared/alloc.h> 13 #include <sal/core/spl.h> 14 #include <sal/core/time.h> 15 #include <shared/bsl.h> 16 #include <soc/mem.h> 17 #include <soc/debug.h> 18 #include <soc/cm.h> 19 #include <soc/drv.h> 20 #include <soc/l2x.h> 21 #include <soc/ism_hash.h> 22 #include <soc/intr.h> 23 #include <soc/iproc.h> 24 #include <soc/mcm/intr_iproc.h> 25 #include <soc/trident2.h> 26 #include <soc/tomahawk.h> 27 28 #ifdef BCM_TRIDENT2_SUPPORT 29 30 int 31 soc_td2_l2_overflow_disable(int unit) 32 { 33 int rv = SOC_E_NONE; 34 soc_reg_t reg = (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) ? L2_MGMT_INTR_MASKr : IL2LU_INTR_ENABLEr; 35 36 SOC_CONTROL_LOCK(unit); 37 rv = soc_reg_field32_modify(unit, reg, REG_PORT_ANY, 38 L2_LEARN_INSERT_FAILUREf, 0); 39 if (SOC_FAILURE(rv)) { 40 SOC_CONTROL_UNLOCK(unit); 41 return rv; 42 } 43 /* Mark as inactive */ 44 SOC_CONTROL(unit)->l2_overflow_active = FALSE; 45 SOC_CONTROL_UNLOCK(unit); 46 /* But don't disable interrupt as its shared by various IL2LU events */ 47 return SOC_E_NONE; 48 } 49 50 int 51 soc_td2_l2_overflow_enable(int unit) 52 { 53 int rv = SOC_E_NONE; 54 soc_reg_t reg = (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) ? L2_MGMT_INTR_MASKr : IL2LU_INTR_ENABLEr; 55 56 SOC_CONTROL_LOCK(unit); 57 rv = soc_reg_field32_modify(unit, reg, REG_PORT_ANY, 58 L2_LEARN_INSERT_FAILUREf, 1); 59 if (SOC_FAILURE(rv)) { 60 SOC_CONTROL_UNLOCK(unit); 61 return rv; 62 } 63 /* Mark as active */ 64 SOC_CONTROL(unit)->l2_overflow_active = TRUE; 65 SOC_CONTROL_UNLOCK(unit); 66 /* Enable interrupt */ 67 #ifdef BCM_CMICX_SUPPORT 68 if (SOC_IS_TRIDENT3X(unit)) { 69 if (soc_feature(unit, soc_feature_cmicx)) { 70 uint32 cmic_rval0; 71 soc_iproc_getreg(unit,soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG0r, REG_PORT_ANY, 0), 72 &cmic_rval0); 73 cmic_rval0 |= 1 << 1; /* Bit 1 is used for l2_mgmt to cmic interupt */ 74 soc_iproc_setreg(unit, 75 soc_reg_addr(unit, ICFG_CHIP_LP_INTR_ENABLE_REG0r, REG_PORT_ANY, 0), 76 cmic_rval0); 77 soc_cmic_intr_enable(unit, CHIP_INTR_LOW_PRIORITY); 78 } 79 return SOC_E_NONE; 80 } 81 #endif 82 #ifdef BCM_CMICM_SUPPORT 83 if (SOC_IS_TOMAHAWKX(unit)) { 84 (void)soc_cmicm_intr3_enable(unit, _SOC_TH_L2_MGMT_INTR_MASK); 85 } else { 86 (void)soc_cmicm_intr1_enable(unit, _SOC_TD2_L2LU_INTR_MASK); 87 } 88 #endif 89 return SOC_E_NONE; 90 } 91 92 int 93 soc_td2_l2_overflow_fill(int unit, uint8 zeros_or_ones) 94 { 95 l2_learn_insert_failure_entry_t entry; 96 97 if (zeros_or_ones) { 98 sal_memset(&entry, 0xffffffff, sizeof(entry)); 99 SOC_IF_ERROR_RETURN 100 (WRITE_L2_LEARN_INSERT_FAILUREm(unit, COPYNO_ALL, 0, &entry)); 101 } else { 102 SOC_IF_ERROR_RETURN 103 (soc_mem_clear(unit, L2_LEARN_INSERT_FAILUREm, COPYNO_ALL, FALSE)); 104 } 105 return SOC_E_NONE; 106 } 107 108 void 109 soc_td2_l2_overflow_interrupt_handler(int unit) 110 { 111 l2x_entry_t l2x_entry; 112 113 if (!SOC_CONTROL(unit)->l2_overflow_active) { 114 LOG_ERROR(BSL_LS_SOC_L2, 115 (BSL_META_U(unit, 116 "Received L2 overflow event with no app handler or" \ 117 " processing inactive !!\n"))); 118 } 119 if (soc_td2_l2_overflow_disable(unit)) { 120 return; 121 } 122 123 if (READ_L2_LEARN_INSERT_FAILUREm(unit, COPYNO_ALL, 0, &l2x_entry)) { 124 return; 125 } 126 127 /* Callback */ 128 soc_l2x_callback(unit, SOC_L2X_ENTRY_OVERFLOW, NULL, &l2x_entry); 129 } 130 131 int 132 soc_td2_l2_overflow_stop(int unit) 133 { 134 if (!SOC_CONTROL(unit)->l2_overflow_enable) { 135 return SOC_E_NONE; 136 } 137 SOC_IF_ERROR_RETURN(soc_td2_l2_overflow_disable(unit)); 138 SOC_IF_ERROR_RETURN(soc_td2_l2_overflow_fill(unit, 1)); 139 return SOC_E_NONE; 140 } 141 142 int 143 soc_td2_l2_overflow_start(int unit) 144 { 145 if (!SOC_CONTROL(unit)->l2_overflow_enable) { 146 return SOC_E_NONE; 147 } 148 if (SOC_CONTROL(unit)->l2_overflow_active) { 149 return SOC_E_NONE; 150 } 151 SOC_IF_ERROR_RETURN(soc_td2_l2_overflow_fill(unit, 0)); 152 SOC_IF_ERROR_RETURN(soc_td2_l2_overflow_enable(unit)); 153 return SOC_E_NONE; 154 } 155 156 #endif /* BCM_TRIUMPH3_SUPPORT */