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

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