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

bst.c (120298B)


      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  * BST - Buffer Statistics Tracking
      8  * Purpose: API to set and manage various BST resources for TH
      9  */
     10 
     11 #include <shared/bsl.h>
     12 #include <soc/defs.h>
     13 #include <sal/core/libc.h>
     14 #include <shared/alloc.h>
     15 #include <sal/core/spl.h>
     16 #include <sal/core/boot.h>
     17 
     18 #include <soc/drv.h>
     19 #include <soc/error.h>
     20 #include <soc/ll.h>
     21 #include <soc/debug.h>
     22 #include <soc/mem.h>
     23 #include <soc/profile_mem.h>
     24 #include <soc/tomahawk.h>
     25 
     26 #include <bcm/switch.h>
     27 #include <bcm/types.h>
     28 #include <bcm/cosq.h>
     29 #include <bcm_int/bst.h>
     30 #include <bcm_int/esw/port.h>
     31 
     32 #if defined(BCM_TOMAHAWK_SUPPORT)
     33 #define TH_BST_THRESHOLD_MAX_HIGH 0x7fff
     34 
     35 extern int _bcm_bst_th_sync_hw_snapshot(int unit, bcm_bst_stat_id_t bid,
     36                                         int port, int index);
     37 extern int _bcm_bst_th_hw_stat_clear(int unit,
     38                                      _bcm_bst_resource_info_t *resInfo,
     39                                      bcm_bst_stat_id_t bid, int port,
     40                                      int index);
     41 static int _bst_th_cmn_profile_set_hw(int unit, int pipe, int xpe, int hw_index,
     42                             bcm_bst_stat_id_t bid,
     43                             bcm_cosq_bst_profile_t *profile, 
     44                             uint32 *p_profile);
     45 extern int _bcm_bst_cmn_profile_delete_hw(int unit, bcm_bst_stat_id_t bid, 
     46                                int id, int profile_index);
     47 STATIC int _bcm_bst_th_sbusdma_desc_sync(int unit);
     48 STATIC int _bcm_bst_th_sbusdma_desc_init(int unit);
     49 STATIC int _bcm_bst_th_sbusdma_desc_deinit(int unit);
     50 
     51 STATIC int
     52 _bcm_bst_th_byte_to_cell(int unit, uint32 bytes)
     53 {
     54     return (bytes + (208 - 1))/208;
     55 }
     56 
     57 STATIC int
     58 _bcm_bst_th_cell_to_byte(int unit, uint32 cells)
     59 {
     60     return cells * 208;
     61 }
     62 
     63 STATIC int
     64 _bcm_th_bst_control_set(int unit, bcm_switch_control_t type, int arg,
     65                         _bcm_bst_thread_oper_t operation)
     66 {
     67     uint32 rval, rval_en, rval_action, i, fval, enable = 0;
     68     uint32 hdrm_en = 0;
     69     _bcm_bst_cmn_unit_info_t *bst_info;
     70     _bcm_bst_resource_info_t *pres = NULL;
     71     soc_reg_t stat_reg = INVALIDr;
     72     soc_field_t stat_field = INVALIDf;
     73     soc_field_t snap_en[] = {BST_HW_SNAPSHOT_EN_THDOf,
     74                              BST_HW_SNAPSHOT_EN_THDIf,
     75                              BST_HW_SNAPSHOT_EN_CFAPf
     76                             };
     77     soc_field_t snap_action[] = {ACTION_EN_THDOf,
     78                                  ACTION_EN_THDIf,
     79                                  ACTION_EN_CFAPf
     80                                 };
     81 
     82     bst_info = _BCM_UNIT_BST_INFO(unit);
     83 
     84     if (!bst_info) {
     85         return BCM_E_INIT;
     86     }
     87 
     88     switch (type) {
     89     case bcmSwitchBstEnable:
     90         BCM_IF_ERROR_RETURN(READ_MMU_GCFG_BST_TRACKING_ENABLEr(unit, &rval));
     91 
     92         fval = arg ? 0xf : 0;
     93 
     94         soc_reg_field_set(unit, MMU_GCFG_BST_TRACKING_ENABLEr, &rval,
     95                           BST_TRACK_EN_THDOf, fval);
     96         soc_reg_field_set(unit, MMU_GCFG_BST_TRACKING_ENABLEr, &rval,
     97                           BST_TRACK_EN_THDIf, fval);
     98         soc_reg_field_set(unit, MMU_GCFG_BST_TRACKING_ENABLEr, &rval,
     99                           BST_TRACK_EN_CFAPf, fval);
    100 
    101         BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_BST_TRACKING_ENABLEr(unit, rval));
    102 
    103         /* Globally Enable/Disable Headroom Pool Monitoring for all
    104            headroom pools */
    105         hdrm_en = arg ? 0xf : 0;
    106         for (i = 0; i < NUM_LAYER(unit); i++) {
    107             BCM_IF_ERROR_RETURN
    108                 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, i, 0, hdrm_en));
    109         }
    110 
    111         if (operation == _bcmBstThreadOperExternal) {
    112             if (fval) {
    113                 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit));
    114             } else {
    115                 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit));
    116             }
    117         } else {
    118             /* Set Enable Flag to True/False, to Run/Pause the Thread
    119              * respectively. Wont Kill the thread.
    120              */
    121             _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, fval ? TRUE : FALSE);
    122         }
    123 
    124         break;
    125     case bcmSwitchBstTrackingMode:
    126         BCM_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval));
    127         soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, BST_TRACKING_MODEf, arg);
    128         BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval));
    129         bst_info->track_mode = arg ? 1 : 0;
    130         /*
    131          * As Headroom Pool has two different stats resource
    132          * for tracking current usage count and peak usage count
    133          * we set up the respective resource accordingly based on
    134          * BST Tracking Mode
    135          */
    136         if (bst_info->track_mode) {
    137             /* Peak Mode */
    138             stat_reg = THDI_HDRM_POOL_PEAK_COUNT_HPr;
    139             stat_field = PEAK_BUFFER_COUNTf;
    140         } else {
    141             /* Current Mode */
    142             stat_reg = THDI_HDRM_POOL_COUNT_HPr;
    143             stat_field = TOTAL_BUFFER_COUNTf;
    144         }
    145         pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool);
    146         if (pres != NULL) {
    147             _BCM_BST_STAT_INFO(pres, pres->stat_mem[0], stat_reg,
    148                                stat_field);
    149         }
    150         break;
    151     case bcmSwitchBstSnapshotEnable:
    152         rval_en = 0;
    153         rval_action = 0;
    154         if (arg != 0) {
    155             BCM_IF_ERROR_RETURN(
    156                 READ_MMU_GCFG_BST_HW_SNAPSHOT_ENr(unit, &rval_en));
    157             BCM_IF_ERROR_RETURN(
    158                 READ_MMU_GCFG_BST_SNAPSHOT_ACTION_ENr(unit, &rval_action));
    159 
    160             for (i = _BCM_BST_SNAPSHOT_THDO; i < _BCM_BST_SNAPSHOT_COUNT; i++) {
    161                 enable = 0;
    162                 if (arg & (0x1 << i)) {
    163                     enable = 0xf;
    164                 } else {
    165                     enable = 0;
    166                 }
    167 
    168                 soc_reg_field_set(unit, MMU_GCFG_BST_HW_SNAPSHOT_ENr, &rval_en,
    169                                   snap_en[i], enable);
    170 
    171                 soc_reg_field_set(unit, MMU_GCFG_BST_SNAPSHOT_ACTION_ENr,
    172                                   &rval_action, snap_action[i], ((enable) ? 1 : 0));
    173             }
    174         }
    175         BCM_IF_ERROR_RETURN(
    176             WRITE_MMU_GCFG_BST_HW_SNAPSHOT_ENr(unit, rval_en));
    177         BCM_IF_ERROR_RETURN(
    178             WRITE_MMU_GCFG_BST_SNAPSHOT_ACTION_ENr(unit, rval_action));
    179         bst_info->snapshot_mode = arg;
    180 
    181         break;
    182 
    183     default:
    184         return BCM_E_UNAVAIL;
    185     }
    186     return BCM_E_NONE;
    187 }
    188 
    189 STATIC int
    190 _bcm_th_bst_control_get(int unit, bcm_switch_control_t type, int *arg)
    191 {
    192     uint32 rval;
    193     _bcm_bst_cmn_unit_info_t *bst_info;
    194     int hdrm_en, cfap_en;
    195 
    196     bst_info = _BCM_UNIT_BST_INFO(unit);
    197 
    198     if (!bst_info) {
    199         return BCM_E_INIT;
    200     }
    201 
    202     switch (type) {
    203     case bcmSwitchBstEnable:
    204         BCM_IF_ERROR_RETURN(READ_MMU_GCFG_BST_TRACKING_ENABLEr(unit, &rval));
    205         cfap_en = soc_reg_field_get(unit, MMU_GCFG_BST_TRACKING_ENABLEr, rval,
    206                                     BST_TRACK_EN_CFAPf);
    207         BCM_IF_ERROR_RETURN
    208             (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, 0, 0, &rval));
    209         hdrm_en = soc_reg_field_get(unit, THDI_HDRM_POOL_CFGr, rval,
    210                                     PEAK_COUNT_UPDATE_EN_HPf);
    211 
    212         if ((cfap_en == 0xf) &&
    213             (hdrm_en == 0xf)) {
    214             /* Only when both cfap and
    215                headroom tracking is enabled */
    216             *arg = 1;
    217         } else {
    218             *arg = 0;
    219         }
    220         break;
    221     case bcmSwitchBstTrackingMode:
    222         *arg = bst_info->track_mode;
    223         break;
    224     case bcmSwitchBstSnapshotEnable:
    225         *arg = bst_info->snapshot_mode;
    226         break;
    227     default:
    228         return BCM_E_UNAVAIL;
    229     }
    230     return BCM_E_NONE;
    231 }
    232 
    233 STATIC int
    234 _bcm_bst_th_intr_enable_set(int unit, int enable)
    235 {
    236     uint32 rval;
    237     if (!soc_property_get(unit, spn_POLLED_IRQ_MODE, 0)) {
    238         if (SOC_REG_IS_VALID(unit, MMU_XCFG_XPE_CPU_INT_ENr)) {
    239             BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_ENr(unit, &rval));
    240             soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval,
    241                               BST_THDO_INT_ENf, enable);
    242             soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval,
    243                               BST_THDI_INT_ENf, enable);
    244             BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_ENr(unit, rval));
    245         }
    246 
    247         if (SOC_IS_TOMAHAWK2(unit)) {
    248             if (SOC_REG_IS_VALID(unit, MMU_SEDCFG_SED_CPU_INT_ENr)) {
    249                 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_SED_CPU_INT_ENr(unit, &rval));
    250                 soc_reg_field_set(unit, MMU_SEDCFG_SED_CPU_INT_ENr, &rval,
    251                                   BST_CFAP_B_INT_ENf, enable);
    252                 soc_reg_field_set(unit, MMU_SEDCFG_SED_CPU_INT_ENr, &rval,
    253                                   BST_CFAP_A_INT_ENf, enable);
    254                 BCM_IF_ERROR_RETURN(WRITE_MMU_SEDCFG_SED_CPU_INT_ENr(unit, rval));
    255             }
    256         } else {
    257             if (SOC_REG_IS_VALID(unit, MMU_SCFG_SC_CPU_INT_ENr)) {
    258                 BCM_IF_ERROR_RETURN(READ_MMU_SCFG_SC_CPU_INT_ENr(unit, &rval));
    259                 soc_reg_field_set(unit, MMU_SCFG_SC_CPU_INT_ENr, &rval,
    260                                   BST_CFAP_B_INT_ENf, enable);
    261                 soc_reg_field_set(unit, MMU_SCFG_SC_CPU_INT_ENr, &rval,
    262                                   BST_CFAP_A_INT_ENf, enable);
    263                 BCM_IF_ERROR_RETURN(WRITE_MMU_SCFG_SC_CPU_INT_ENr(unit, rval));
    264             }
    265         }
    266     }
    267     return BCM_E_NONE;
    268 }
    269 
    270 STATIC int
    271 soc_th_set_hw_intr_cb(int unit)
    272 {
    273     BCM_IF_ERROR_RETURN(soc_th_set_bst_callback(unit, &_bcm_bst_hw_event_cb));
    274     return BCM_E_NONE;
    275 }
    276 
    277 STATIC int
    278 _bst_th_intr_status_reset(int unit)
    279 {
    280     uint32 rval;
    281 
    282     BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, &rval));
    283     soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval,
    284                       BST_THDO_INT_CLRf, 0);
    285     soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval,
    286                       BST_THDI_INT_CLRf, 0);
    287     BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, rval));
    288 
    289     if (SOC_IS_TOMAHAWK2(unit)) {
    290         if (SOC_REG_IS_VALID(unit, MMU_SEDCFG_SED_CPU_INT_CLEARr)) {
    291             BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_SED_CPU_INT_CLEARr(unit, &rval));
    292             soc_reg_field_set(unit, MMU_SEDCFG_SED_CPU_INT_CLEARr, &rval,
    293                               BST_CFAP_A_INT_CLRf, 0);
    294             soc_reg_field_set(unit, MMU_SEDCFG_SED_CPU_INT_CLEARr, &rval,
    295                               BST_CFAP_B_INT_CLRf, 0);
    296             BCM_IF_ERROR_RETURN(WRITE_MMU_SEDCFG_SED_CPU_INT_CLEARr(unit, rval));
    297         }
    298     } else {
    299         if (SOC_REG_IS_VALID(unit, MMU_SCFG_SC_CPU_INT_CLEARr)) {
    300             BCM_IF_ERROR_RETURN(READ_MMU_SCFG_SC_CPU_INT_CLEARr(unit, &rval));
    301             soc_reg_field_set(unit, MMU_SCFG_SC_CPU_INT_CLEARr, &rval,
    302                               BST_CFAP_A_INT_CLRf, 0);
    303             soc_reg_field_set(unit, MMU_SCFG_SC_CPU_INT_CLEARr, &rval,
    304                               BST_CFAP_B_INT_CLRf, 0);
    305             BCM_IF_ERROR_RETURN(WRITE_MMU_SCFG_SC_CPU_INT_CLEARr(unit, rval));
    306         }
    307     }
    308 
    309     return BCM_E_NONE;
    310 }
    311 
    312 STATIC int
    313 _bcm_bst_th_intr_to_resources(int unit, uint32 *flags)
    314 {
    315     uint32 flags_tr = 0;
    316     uint32 fval = 0;
    317     uint32 rval_dev, rval32_type, rval32_status;
    318     uint64 rval_uc, rval_db, rval_rqe;
    319     int index[_bcmResourceMaxCount] = {-1}, i;
    320     int res[_bcmResourceMaxCount] = {-1}, res_ct = 0;
    321     int bid_detect[_bcmResourceMaxCount] = {0};
    322     soc_field_t fld = INVALIDf;
    323     soc_reg_t reg_type = INVALIDr, reg_status = INVALIDr;
    324     int xpe = 0;
    325     uint32 inst,base_index,ipipe_map;
    326     soc_info_t *si;
    327 
    328     si = &SOC_INFO(unit);
    329     _bcm_bst_th_intr_enable_set(unit, 0);
    330     _bst_th_intr_status_reset(unit);
    331 
    332     LOG_VERBOSE(BSL_LS_BCM_COSQ,
    333                 (BSL_META_U(unit,
    334                             "BST interrupt handler: unit=%d flags=0x%x\n"),
    335                  unit, *flags));
    336 
    337     /* _bcmResourceDevice */
    338     BCM_IF_ERROR_RETURN(READ_CFAPBSTTHRSr(unit, &rval_dev));
    339     if (soc_reg_field_get(unit, CFAPBSTTHRSr, rval_dev, BST_THRESHOLDf)) {
    340         if (SOC_IS_TOMAHAWK2(unit)) {
    341             if (SOC_REG_IS_VALID(unit, MMU_SEDCFG_SED_CPU_INT_STATr)) {
    342                 /* For CFAP, it use MMU_SCFG_SC_CPU_INT_STATr to indicate the bst
    343                  * interruptbut not use a trigger status register.
    344                  * MMU_SCFG_SC_CPU_INT_STATr would be cleared in SER handler, so
    345                  * we check _bcmResourceDevice every time here.
    346                  */
    347                 index[res_ct] = 0;
    348                 res[res_ct++] = _bcmResourceDevice;
    349             }
    350         } else {
    351             if (SOC_REG_IS_VALID(unit, MMU_SCFG_SC_CPU_INT_ENr)) {
    352                 /* For CFAP, it use MMU_SCFG_SC_CPU_INT_STATr to indicate the bst
    353                  * interruptbut not use a trigger status register.
    354                  * MMU_SCFG_SC_CPU_INT_STATr would be cleared in SER handler, so
    355                  * we check _bcmResourceDevice every time here.
    356                  */
    357                 index[res_ct] = 0;
    358                 res[res_ct++] = _bcmResourceDevice;
    359             }
    360         }
    361     }
    362 
    363     /* THDI Status/Triggers */
    364     for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    365         reg_type = SOC_REG_UNIQUE_ACC(unit, THDI_BST_TRIGGER_STATUS_TYPEr)[xpe];
    366         reg_status = SOC_REG_UNIQUE_ACC(unit, THDI_BST_TRIGGER_STATUS_32r)[xpe];
    367         ipipe_map = si->xpe_ipipe_map[xpe];
    368 
    369         for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) {
    370             if(!(ipipe_map & (1 << base_index))) {
    371                 continue;
    372             }
    373             inst = base_index | SOC_REG_ADDR_INSTANCE_MASK;
    374             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg_type, inst, 0, &rval32_type));
    375             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg_status, inst, 0, &rval32_status));
    376 
    377             /* _bcmResourceIngPool */
    378             fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type,
    379                                      POOL_SHARED_TRIGGERf);
    380             if (fval && !bid_detect[_bcmResourceIngPool]) {
    381                 fld = POOL_SHARED_TRIGGER_STATUSf;
    382                 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld);
    383                 res[res_ct++] = _bcmResourceIngPool;
    384                 bid_detect[_bcmResourceIngPool] = 1;
    385             }
    386 
    387             /* _bcmResourcePortPool */
    388             fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type,
    389                                      SP_SHARED_TRIGGERf);
    390             if (fval && !bid_detect[_bcmResourcePortPool]) {
    391                 fld = SP_SHARED_TRIGGER_STATUSf;
    392                 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld);
    393                 res[res_ct++] = _bcmResourcePortPool;
    394                 bid_detect[_bcmResourcePortPool] = 1;
    395             }
    396 
    397             /* _bcmResourcePriGroupShared */
    398             fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type,
    399                                      PG_SHARED_TRIGGERf);
    400             if (fval && !bid_detect[_bcmResourcePriGroupShared]) {
    401                 fld = PG_SHARED_TRIGGER_STATUSf;
    402                 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld);
    403                 res[res_ct++] = _bcmResourcePriGroupShared;
    404                 bid_detect[_bcmResourcePriGroupShared] = 1;
    405             }
    406 
    407             /* _bcmResourcePriGroupHeadroom */
    408             fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type,
    409                                      PG_HDRM_TRIGGERf);
    410 
    411             if (fval && !bid_detect[_bcmResourcePriGroupHeadroom]) {
    412                 fld = PG_HDRM_TRIGGER_STATUSf;
    413                 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld);
    414                 res[res_ct++] = _bcmResourcePriGroupHeadroom;
    415                 bid_detect[_bcmResourcePriGroupHeadroom] = 1;
    416             }
    417 
    418             rval32_type = 0;
    419             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg_type, inst, 0, rval32_type));
    420             rval32_status = 0;
    421             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg_status, inst, 0, rval32_status));
    422         }
    423     }
    424 
    425 
    426     /* THDM DB Status/Triggers */
    427     for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    428         BCM_IF_ERROR_RETURN
    429             (soc_reg_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, xpe, 0, &rval_db));
    430         reg_status = MMU_THDM_DB_DEVICE_BST_STATr;
    431 
    432         /* _bcmResourceEgrPool */
    433         fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db,
    434                                      MCUC_SP_BST_STAT_TRIGGEREDf);
    435 
    436         if (fval && !bid_detect[_bcmResourceEgrPool]) {
    437             fld = MCUC_SP_BST_STAT_IDf;
    438             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld);
    439             res[res_ct++] = _bcmResourceEgrPool;
    440             bid_detect[_bcmResourceEgrPool] = 1;
    441         }
    442 
    443         /* _bcmResourceEgrMCastPool */
    444         fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db,
    445                                      MC_SP_BST_STAT_TRIGGEREDf);
    446 
    447         if (fval && !bid_detect[_bcmResourceEgrMCastPool]) {
    448             fld = MC_SP_BST_STAT_IDf;
    449             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld);
    450             res[res_ct++] = _bcmResourceEgrMCastPool;
    451             bid_detect[_bcmResourceEgrMCastPool] = 1;
    452         }
    453 
    454         /* _bcmResourceMcast */
    455         fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db,
    456                                      MC_Q_BST_STAT_TRIGGEREDf);
    457 
    458         if (fval && !bid_detect[_bcmResourceMcast]) {
    459             fld = MC_Q_BST_STAT_IDf;
    460             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld);
    461             res[res_ct++] = _bcmResourceMcast;
    462             bid_detect[_bcmResourceMcast] = 1;
    463         }
    464 
    465         fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db,
    466                                      MC_CPU_Q_BST_STAT_TRIGGEREDf);
    467         if (fval && !bid_detect[_bcmResourceMcast]) {
    468             fld = MC_CPU_Q_BST_STAT_IDf;
    469             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld);
    470             res[res_ct++] = _bcmResourceMcast;
    471             bid_detect[_bcmResourceMcast] = 1;
    472         }
    473 
    474         /* _bcmResourceEgrPortPoolSharedMcast*/
    475         fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db,
    476                                      MC_PORTSP_BST_STAT_TRIGGEREDf);
    477 
    478         if (fval && !bid_detect[_bcmResourceEgrPortPoolSharedMcast]) {
    479             fld = MC_PORTSP_BST_STAT_IDf;
    480             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld);
    481             res[res_ct++] = _bcmResourceEgrPortPoolSharedMcast;
    482             bid_detect[_bcmResourceEgrPortPoolSharedMcast] = 1;
    483         }
    484 
    485         COMPILER_64_ZERO(rval_db);
    486         BCM_IF_ERROR_RETURN
    487             (soc_reg_set(unit, MMU_THDM_DB_DEVICE_BST_STATr, xpe, 0, rval_db));
    488     }
    489 
    490     /* THDU Status/Triggers */
    491     for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    492         BCM_IF_ERROR_RETURN
    493             (soc_reg_get(unit, THDU_BST_STATr, xpe, 0, &rval_uc));
    494         reg_status = THDU_BST_STATr;
    495 
    496         /* _bcmResourceUcast */
    497         fval = soc_reg64_field32_get(unit, reg_status, rval_uc,
    498                                      UC_Q_BST_STAT_TRIGGEREDf);
    499         if (fval && !bid_detect[_bcmResourceUcast]) {
    500             fld = UC_Q_BST_STAT_IDf;
    501             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_uc, fld);
    502             res[res_ct++] = _bcmResourceUcast;
    503             bid_detect[_bcmResourceUcast] = 1;
    504         }
    505 
    506         /* _bcmResourceEgrPortPoolSharedUcast*/
    507         fval = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc,
    508                                      UC_PORT_SP_BST_STAT_TRIGGEREDf);
    509         if (fval && !bid_detect[_bcmResourceEgrPortPoolSharedUcast]) {
    510             fld = UC_Q_BST_STAT_IDf;
    511             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_uc, fld);
    512             res[res_ct++] = _bcmResourceEgrPortPoolSharedUcast;
    513             bid_detect[_bcmResourceEgrPortPoolSharedUcast] = 1;
    514         }
    515 
    516         /* _bcmResourceUCQueueGroup*/
    517         fval = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc,
    518                                      UC_QGROUP_BST_STAT_TRIGGEREDf);
    519         if (fval && !bid_detect[_bcmResourceUCQueueGroup]) {
    520             fld = UC_QGROUP_BST_STAT_IDf;
    521             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_uc, fld);
    522             res[res_ct++] = _bcmResourceUCQueueGroup;
    523             bid_detect[_bcmResourceUCQueueGroup] = 1;
    524         }
    525 
    526         COMPILER_64_ZERO(rval_uc);
    527         BCM_IF_ERROR_RETURN
    528             (soc_reg_set(unit, THDU_BST_STATr, xpe, 0, rval_uc));
    529 
    530     }
    531 
    532     /* THDR Status/Triggers */
    533     for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    534         reg_status = MMU_THDR_DB_BST_STATr;
    535         BCM_IF_ERROR_RETURN
    536             (soc_reg_get(unit, reg_status, xpe, 0, &rval_rqe));
    537 
    538         /* _bcmResourceRQEQueue */
    539         fval = soc_reg64_field32_get(unit, reg_status, rval_rqe,
    540                                     PRIQ_TRIGGEREDf);
    541         if (fval && !bid_detect[_bcmResourceRQEQueue]) {
    542             fld = PRIQ_IDf;
    543             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_rqe, fld);
    544             res[res_ct++] = _bcmResourceRQEQueue;
    545             bid_detect[_bcmResourceRQEQueue] = 1;
    546         }
    547 
    548         /* _bcmResourceRQEPool*/
    549         fval = soc_reg64_field32_get(unit, reg_status, rval_rqe,
    550                                      SP_TRIGGEREDf);
    551         if (fval && !bid_detect[_bcmResourceRQEPool]) {
    552             fld = SP_IDf;
    553             index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_rqe, fld);
    554             res[res_ct++] = _bcmResourceRQEPool;
    555             bid_detect[_bcmResourceRQEPool] = 1;
    556         }
    557 
    558         COMPILER_64_ZERO(rval_rqe);
    559         BCM_IF_ERROR_RETURN
    560             (soc_reg_set(unit, reg_status, xpe, 0, rval_rqe));
    561     }
    562 
    563     if (res_ct == 0) {
    564         _bcm_bst_th_intr_enable_set(unit, 1);
    565         /* No resource to fetch */
    566         return BCM_E_NONE;
    567     }
    568 
    569     for (i = 0; i < res_ct; i++) {
    570         BCM_IF_ERROR_RETURN(
    571             _bcm_bst_th_sync_hw_snapshot(unit, res[i], -1, index[i]));
    572     }
    573 
    574     *flags = flags_tr;
    575     _bcm_bst_th_intr_enable_set(unit, 1);
    576     return BCM_E_NONE;
    577 }
    578 
    579 int
    580 _bcm_bst_th_hw_stat_clear(int unit, _bcm_bst_resource_info_t *resInfo,
    581                     bcm_bst_stat_id_t bid, int port, int index)
    582 {
    583     _bcm_bst_cmn_unit_info_t *bst_info;
    584     int rv, pipe;
    585     uint32 rval;
    586     soc_mem_t base_mem = INVALIDm, mem = INVALIDm;
    587     soc_reg_t reg;
    588     int min_hw_idx, max_hw_idx, idx;
    589     int pipe_num = 1, pipe_offset = 0, inst, stats_per_inst;
    590     int num_entries, mem_wsz;
    591     void *pentry;
    592     char *dmabuf;
    593     int sync_val = 0;
    594     int p_idx;
    595     uint32 mmu_inst_map = 0;
    596 
    597     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
    598         return BCM_E_PARAM;
    599     }
    600 
    601     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
    602         return BCM_E_INIT;
    603     }
    604 
    605     if (bst_info->pre_sync) {
    606         bst_info->pre_sync(unit, bid, &sync_val);
    607     }
    608 
    609     /* sync all the stats */
    610     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
    611         pipe_num = NUM_PIPE(unit);
    612     }
    613     if (index == -1) {
    614         min_hw_idx = resInfo->index_min;
    615         if (resInfo->num_instance > 1) {
    616             max_hw_idx = ((resInfo->index_max + 1) / pipe_num /
    617                           resInfo->num_instance) - 1;
    618         } else {
    619             max_hw_idx = ((resInfo->index_max + 1) / pipe_num) - 1;
    620         }
    621     } else {
    622         min_hw_idx = max_hw_idx = index;
    623     }
    624 
    625     if ((port != -1) && (bst_info->port_to_mmu_inst_map)) {
    626         (void)bst_info->port_to_mmu_inst_map(unit, bid, port, &mmu_inst_map);
    627     }
    628 
    629     for (pipe = 0; pipe < pipe_num; pipe++) {
    630         if ((base_mem = resInfo->stat_mem[0]) != INVALIDm) {
    631             int xpe = 0;
    632             for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    633                 if ((port != -1) && !(mmu_inst_map & (1 << xpe))) {
    634                     continue;
    635                 }
    636                 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
    637                 if (mem == INVALIDm) {
    638                     continue;
    639                 }
    640 
    641                 if (index < 0) {
    642                     num_entries = soc_mem_index_count(unit, mem);
    643                     mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem);
    644 
    645                     dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf");
    646                     if (dmabuf == NULL) {
    647                         return BCM_E_MEMORY;
    648                     }
    649 
    650                     if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL,
    651                                             soc_mem_index_min(unit, mem),
    652                                             soc_mem_index_max(unit, mem),
    653                                             dmabuf)) {
    654                         soc_cm_sfree(unit, dmabuf);
    655                         return BCM_E_INTERNAL;
    656                     }
    657 
    658                     /* Clear stat counter if requested */
    659                     for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
    660                         p_idx = idx;
    661                         if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
    662                             /*
    663                              * Reorder sw stat index
    664                              * HW stat: index 0 - port 0 pool 0
    665                              *          index 1 - port 1 pool 0
    666                              *          index 2 - port 2 pool 0
    667                              *          ...
    668                              *          index n - port n%34 pool n/34
    669                              * SW stat: index 0 - port 0 pool 0
    670                              *          index 1 - port 0 pool 1
    671                              *          index 2 - port 0 pool 2
    672                              *          ...
    673                              *          index n - port n/4 pool n%4
    674                              */
    675                             /* coverity[parameter_hidden: FALSE] */
    676                             int port, pool;
    677                             port = idx / _TH_MMU_NUM_POOL;
    678                             pool = idx % _TH_MMU_NUM_POOL;
    679                             p_idx = pool * _TH_MMU_PORTS_PER_PIPE + port;
    680                         }
    681                         pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
    682                                                               dmabuf, p_idx);
    683                         soc_mem_field32_set(unit, mem, pentry, resInfo->stat_field, 0);
    684                     }
    685 
    686                     if (soc_mem_write_range(unit, mem, MEM_BLOCK_ALL,
    687                                             soc_mem_index_min(unit, mem),
    688                                             soc_mem_index_max(unit, mem),
    689                                             dmabuf)) {
    690                         soc_cm_sfree(unit, dmabuf);
    691                         return BCM_E_INTERNAL;
    692                     }
    693                     soc_cm_sfree(unit, dmabuf);
    694                 } else {
    695                     /* Clear a specific index */
    696                     uint32 entry[SOC_MAX_MEM_WORDS];
    697                     p_idx = index;
    698                     if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
    699                         /*
    700                          * Reorder sw stat index
    701                          * HW stat: index 0 - port 0 pool 0
    702                          *          index 1 - port 1 pool 0
    703                          *          index 2 - port 2 pool 0
    704                          *          ...
    705                          *          index n - port n%34 pool n/34
    706                          * SW stat: index 0 - port 0 pool 0
    707                          *          index 1 - port 0 pool 1
    708                          *          index 2 - port 0 pool 2
    709                          *          ...
    710                          *          index n - port n/4 pool n%4
    711                          */
    712                         int port, pool;
    713                         port = index / _TH_MMU_NUM_POOL;
    714                         pool = index % _TH_MMU_NUM_POOL;
    715                         p_idx = pool * _TH_MMU_PORTS_PER_PIPE + port;
    716                     }
    717                     SOC_IF_ERROR_RETURN(
    718                         soc_mem_read(unit, mem, MEM_BLOCK_ALL, p_idx, entry));
    719                     soc_mem_field32_set(unit, mem, entry,
    720                                         resInfo->stat_field, 0);
    721                     SOC_IF_ERROR_RETURN(
    722                         soc_mem_write(unit, mem, MEM_BLOCK_ALL, p_idx, entry));
    723                 }
    724             }
    725         } else if (resInfo->profile_r[0]) {
    726             pipe_offset += max_hw_idx;
    727         } else if ((reg = resInfo->stat_reg[pipe]) != INVALIDr) {
    728             int stat_idx = 0;
    729             int xpe = 0;
    730             uint32 mmu_inst_map = 0;
    731 
    732             stats_per_inst = resInfo->num_stat_pp / resInfo->num_instance;
    733 
    734             /* Clear stat counters */
    735 
    736             if (port == -1){
    737                 mmu_inst_map = (1 << NUM_XPE(unit)) - 1;
    738             } else {
    739                 if (bst_info->port_to_mmu_inst_map) {
    740                     (void)bst_info->port_to_mmu_inst_map(unit, bid, port,
    741                         &mmu_inst_map);
    742                 }
    743             }
    744 
    745             for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    746                 if (!(mmu_inst_map & (1 << xpe))) {
    747                     continue;
    748                 }
    749                 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
    750                     rval = 0;
    751                     if (stats_per_inst) {
    752                         inst = xpe;
    753                         stat_idx = idx;
    754                     } else {
    755                         inst = REG_PORT_ANY;
    756                         stat_idx = idx;
    757                     }
    758                     if (bid != bcmBstStatIdIngPool) {
    759                         rv = soc_reg32_get(unit, reg, inst, stat_idx, &rval);
    760                         if (rv) {
    761                             return BCM_E_INTERNAL;
    762                         }
    763                         soc_reg_field_set(unit, reg, &rval, resInfo->stat_field, 0);
    764                         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, stat_idx, rval));
    765                     } else if ((bid == bcmBstStatIdIngPool) && SOC_IS_TOMAHAWK(unit)){
    766                         /* IngPool requires clearing using THD_MISC_CONTROL reg */
    767                         soc_field_t ing_sp_clr_fields[] = {
    768                             CLEAR_THDI_BST_SP_GLOBAL_SHARED_CNT0f,
    769                             CLEAR_THDI_BST_SP_GLOBAL_SHARED_CNT1f,
    770                             CLEAR_THDI_BST_SP_GLOBAL_SHARED_CNT2f,
    771                             CLEAR_THDI_BST_SP_GLOBAL_SHARED_CNT3f,
    772                             CLEAR_THDI_BST_SP_GLOBAL_SHARED_CNT4f
    773                         };
    774                         rval = 0;
    775                         /* 4 SP + 1 Public pool */
    776                         soc_reg_field_set(unit, THD_MISC_CONTROLr, &rval,
    777                                           ing_sp_clr_fields[stat_idx], 0);
    778                         BCM_IF_ERROR_RETURN
    779                             (soc_reg32_set(unit, THD_MISC_CONTROLr, inst, stat_idx, rval));
    780 
    781                         soc_reg_field_set(unit, THD_MISC_CONTROLr, &rval,
    782                                           ing_sp_clr_fields[stat_idx], 1);
    783                         BCM_IF_ERROR_RETURN
    784                             (soc_reg32_set(unit, THD_MISC_CONTROLr, inst, stat_idx, rval));
    785 
    786                     }
    787                 }
    788             }
    789 
    790 
    791         } /* if valid reg */
    792     } /* for each pipe */
    793 
    794     if (bst_info->post_sync) {
    795         bst_info->post_sync(unit, bid, sync_val);
    796     }
    797 
    798     return BCM_E_NONE;
    799 }
    800 
    801 int
    802 _bcm_bst_th_sync_hw_snapshot(int unit, bcm_bst_stat_id_t bid,
    803                              int port, int index)
    804 {
    805     _bcm_bst_cmn_unit_info_t *bst_info;
    806     _bcm_bst_resource_info_t *resInfo;
    807     int num_entries, mem_wsz, sync_val = 0;
    808     int idx, idx_offset;
    809     int inst, xpe, xpe_offset, pipe, pipe_offset = 0;
    810     int stats_per_inst = 0; /* stats per mem instance(xpe) */
    811     void *pentry;
    812     char *dmabuf;
    813     uint32 rval, temp_val;
    814     soc_mem_t mem, base_mem;
    815     soc_reg_t reg;
    816     bcm_gport_t gport;
    817     bcm_cos_queue_t cosq;
    818 
    819     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
    820         return BCM_E_INIT;
    821     }
    822 
    823     if (bst_info->pre_sync) {
    824         bst_info->pre_sync(unit, bid, &sync_val);
    825     }
    826 
    827     /* sync all the stats */
    828     resInfo = _BCM_BST_RESOURCE(unit, bid);
    829     if (resInfo == NULL) {
    830         return BCM_E_PARAM;
    831     }
    832 
    833     base_mem = resInfo->stat_mem[0];
    834     reg = resInfo->stat_reg[0];
    835 
    836     if (reg != INVALIDr) {
    837         int stat_idx = 0;
    838         stats_per_inst = resInfo->num_stat_pp / resInfo->num_instance;
    839         pipe_offset = 0;
    840 
    841         for (idx = 0; idx < resInfo->num_stat_pp; idx++) {
    842             rval = 0;
    843             if (stats_per_inst) {
    844                 inst = idx / stats_per_inst;
    845                 stat_idx = idx % stats_per_inst;
    846             } else {
    847                 inst = REG_PORT_ANY;
    848                 stat_idx = idx;
    849                 stats_per_inst = 1;
    850             }
    851 
    852             idx_offset = idx + pipe_offset;
    853             SOC_IF_ERROR_RETURN
    854                 (soc_reg32_get(unit, reg, inst, stat_idx, &rval));
    855             temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field);
    856             if (bst_info->track_mode) {
    857                 /* BST tracking is in Peak mode.
    858                  * Hence store the watermark value only.
    859                  */
    860                 if (resInfo->p_stat[idx_offset] < temp_val) {
    861                     resInfo->p_stat[idx_offset] = temp_val;
    862                 }
    863             } else {
    864                 resInfo->p_stat[idx_offset] = temp_val;
    865             }
    866 
    867             /* Check if there exists threshold for a resource
    868              * continue if we don't have one */
    869             if (resInfo->p_threshold == NULL) {
    870                 continue;
    871             }
    872 
    873             /* coverity[copy_paste_error : FALSE] */
    874             if (resInfo->p_threshold[idx_offset] &&
    875                 (resInfo->p_stat[idx_offset] >=
    876                  (resInfo->p_threshold[idx_offset] * resInfo->threshold_gran)
    877                 )) {
    878                 /* Generate SOC EVENT */
    879                 if (bst_info->handlers.reverse_resolve_index) {
    880                     /* reverse map the inedx to port/cos pair */
    881                     bst_info->handlers.reverse_resolve_index(unit, bid,
    882                                                              port, idx_offset,
    883                                                              &gport, &cosq);
    884                     soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
    885                                        bid, gport, cosq);
    886                 }
    887             }
    888 
    889         }
    890     } else if (base_mem != INVALIDm) {
    891         int min_idx = 0, max_idx = 0;
    892         int stats_per_pipe = 0; /* stats per pipe per mem-instance(xpe) */
    893 
    894         /* Get the mem attributes(Max idx) from the first child,
    895          * which could be used for other instances.
    896          * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
    897          */
    898         mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0);
    899 
    900         if (mem == INVALIDm) {
    901             return BCM_E_PARAM;
    902         }
    903         stats_per_inst = (resInfo->index_max + 1) / resInfo->num_instance;
    904         stats_per_pipe = stats_per_inst / NUM_PIPE(unit);
    905 
    906         num_entries = soc_mem_index_max(unit, mem) + 1;
    907         min_idx = soc_mem_index_min(unit, mem);
    908         max_idx = soc_mem_index_max(unit, mem);
    909         mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem);
    910 
    911         dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf");
    912         if (dmabuf == NULL) {
    913             return BCM_E_MEMORY;
    914         }
    915 
    916         for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    917             xpe_offset = 0;
    918             gport = BCM_GPORT_INVALID;
    919             cosq = -1;
    920 
    921             if (xpe) {
    922                 xpe_offset = stats_per_inst * xpe;
    923             }
    924 
    925             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    926                 pipe_offset = 0;
    927                 if (pipe) {
    928                     pipe_offset = stats_per_pipe * pipe;
    929                 }
    930 
    931                 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
    932                 if (mem == INVALIDm) {
    933                     continue;
    934                 }
    935 
    936                 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL,
    937                                         min_idx, max_idx, dmabuf)) {
    938                     soc_cm_sfree(unit, dmabuf);
    939                     return BCM_E_INTERNAL;
    940                 }
    941 
    942                 for (idx = 0; idx < max_idx; idx++) {
    943                     if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
    944                         /*
    945                          * Reorder sw stat index
    946                          * HW stat: index 0 - port 0 pool 0
    947                          *          index 1 - port 1 pool 0
    948                          *          index 2 - port 2 pool 0
    949                          *          ...
    950                          *          index n - port n%34 pool n/34
    951                          * SW stat: index 0 - port 0 pool 0
    952                          *          index 1 - port 0 pool 1
    953                          *          index 2 - port 0 pool 2
    954                          *          ...
    955                          *          index n - port n/4 pool n%4
    956                          */
    957                         /* coverity[parameter_hidden: FALSE] */
    958                         int port, pool;
    959                         port = idx % _TH_MMU_PORTS_PER_PIPE;
    960                         pool = idx / _TH_MMU_PORTS_PER_PIPE;
    961                         idx_offset = port * _TH_MMU_NUM_POOL + pool +
    962                                      pipe_offset + xpe_offset;
    963                     } else {
    964                         idx_offset = idx + pipe_offset + xpe_offset;
    965                     }
    966                     if (idx_offset >= resInfo->num_stat_pp) {
    967                         continue;
    968                     }
    969                     pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
    970                                                           dmabuf, idx);
    971                     temp_val = soc_mem_field32_get(unit, mem, pentry,
    972                                                    resInfo->stat_field);
    973                     if (bst_info->track_mode) {
    974                         /* BST tracking is in Peak mode.
    975                          * Hence store the watermark value only.
    976                          */
    977                         if (resInfo->p_stat[idx_offset] < temp_val) {
    978                             resInfo->p_stat[idx_offset] = temp_val;
    979                         }
    980                     } else {
    981                         resInfo->p_stat[idx_offset] = temp_val;
    982                     }
    983 
    984                     if (resInfo->p_threshold[idx_offset] &&
    985                         (resInfo->p_stat[idx_offset] >=
    986                          (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
    987                         /* Generate SOC EVENT */
    988                         if (bst_info->handlers.reverse_resolve_index) {
    989                             /* reverse map the inedx to port/cos pair */
    990                             bst_info->handlers.reverse_resolve_index(unit, bid,
    991                                                                      port, idx_offset,
    992                                                                      &gport, &cosq);
    993                             soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
    994                                                bid, gport, cosq);
    995 
    996                         }
    997                     }
    998                 }
    999             }
   1000         }
   1001         soc_cm_sfree(unit, dmabuf);
   1002     }
   1003 
   1004     if (bst_info->post_sync) {
   1005         bst_info->post_sync(unit, bid, sync_val);
   1006     }
   1007 
   1008     return BCM_E_NONE;
   1009 }
   1010 
   1011 /*
   1012  * This function is used to enable and disable headroom
   1013  * pool monitoring for given headroom pool index and pipe.
   1014  */
   1015 STATIC int
   1016 _bcm_th_bst_hdrm_monitor_set(int unit, int hdrm_idx,
   1017                              int pipe, int enable)
   1018 {
   1019     int idx, idx_min, idx_max;
   1020     uint32 rval, hdrm_pool_cfg;
   1021 
   1022     if (pipe == -1) {
   1023         /* Both Layer 0 and Layer 1 */
   1024         idx_min = 0;
   1025         idx_max = NUM_LAYER(unit);
   1026     } else if ((pipe == 0) || (pipe == 3)) {
   1027         /* Layer 0 */
   1028         idx_min = 0;
   1029         idx_max = 1;
   1030     } else if ((pipe == 1) || (pipe == 2)) {
   1031         /* Layer 1 */
   1032         idx_min = 1;
   1033         idx_max = 2;
   1034     } else {
   1035         return BCM_E_PARAM;
   1036     }
   1037 
   1038     for (idx = idx_min; idx < idx_max; idx++) {
   1039         BCM_IF_ERROR_RETURN
   1040             (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, idx, 0, &rval));
   1041         hdrm_pool_cfg = soc_reg_field_get(unit, THDI_HDRM_POOL_CFGr, rval,
   1042                                           PEAK_COUNT_UPDATE_EN_HPf);
   1043         if (enable == 0x1) {
   1044             hdrm_pool_cfg = hdrm_pool_cfg | (0x1 << hdrm_idx);
   1045         } else {
   1046             hdrm_pool_cfg = hdrm_pool_cfg & (~(0x1 << hdrm_idx));
   1047         }
   1048         soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval,
   1049                           PEAK_COUNT_UPDATE_EN_HPf, hdrm_pool_cfg);
   1050         BCM_IF_ERROR_RETURN
   1051             (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, idx, 0, rval));
   1052     }
   1053 
   1054     return BCM_E_NONE;
   1055 }
   1056 
   1057 /*
   1058  * This function is used to clear the hardware stat for
   1059  * the headroom pool usage count for given [Port, Prio].
   1060  */
   1061 STATIC int
   1062 _bcm_th_bst_hdrm_hw_stat_clear(int unit,
   1063                                bcm_gport_t gport,
   1064                                bcm_cos_t cosq,
   1065                                bcm_cosq_buffer_id_t buffer)
   1066 {
   1067     int i, j;
   1068     uint32 rval, hdrm_pool_cfg[2];
   1069     _bcm_bst_cmn_unit_info_t *bst_info;
   1070     _bcm_bst_resource_info_t *resInfo;
   1071     int enable = 0x0;
   1072     uint32 xpe_map = 0;
   1073     int start_hw_index = 0, end_hw_index = 0, pipe = -1;
   1074     soc_info_t *si = NULL;
   1075     int bcm_rv;
   1076 
   1077     if ((buffer < BCM_COSQ_BUFFER_ID_INVALID) || (buffer >= NUM_XPE(unit))) {
   1078         return BCM_E_PARAM;
   1079     }
   1080 
   1081     resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool);
   1082     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   1083         return BCM_E_PARAM;
   1084     }
   1085 
   1086     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1087         return BCM_E_INIT;
   1088     }
   1089 
   1090     xpe_map = (buffer == BCM_COSQ_BUFFER_ID_INVALID) ? 0xf : (1 << buffer);
   1091     if (gport == -1) {
   1092         if (cosq == BCM_COS_INVALID) {
   1093             pipe = -1;
   1094             /* 4 Headroom Pool Ids */
   1095             start_hw_index = 0;
   1096             end_hw_index = 3;
   1097             xpe_map &= 0xf;
   1098         } else {
   1099             return BCM_E_PARAM;
   1100         }
   1101     } else {
   1102         if (bst_info->handlers.resolve_index == NULL) {
   1103             return BCM_E_UNAVAIL;
   1104         }
   1105 
   1106         bst_info->handlers.resolve_index(unit, gport, cosq,
   1107                                          bcmBstStatIdHeadroomPool, &pipe,
   1108                                          &start_hw_index, &end_hw_index,
   1109                                          NULL, NULL, &bcm_rv);
   1110         if (bcm_rv) {
   1111             return bcm_rv;
   1112         }
   1113         si = &SOC_INFO(unit);
   1114         xpe_map &= si->ipipe_xpe_map[pipe];
   1115     }
   1116 
   1117     if (!xpe_map) {
   1118         return BCM_E_PARAM;
   1119     }
   1120 
   1121     for (j = 0; j < NUM_LAYER(unit); j++) {
   1122         rval = 0x0;
   1123         BCM_IF_ERROR_RETURN
   1124             (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, j, 0, &rval));
   1125         hdrm_pool_cfg[j] = soc_reg_field_get(unit, THDI_HDRM_POOL_CFGr, rval,
   1126                                           PEAK_COUNT_UPDATE_EN_HPf);
   1127     }
   1128 
   1129     for (i = start_hw_index; i <= end_hw_index; i++) {
   1130         /* Disable hardware tracking the headroom pool */
   1131         enable = 0x0;
   1132         BCM_IF_ERROR_RETURN
   1133             (_bcm_th_bst_hdrm_monitor_set(unit, i, pipe, enable));
   1134 
   1135         /* Reset Headroom Pool Peak Use-Count */
   1136         for (j = 0; j < NUM_XPE(unit); j++) {
   1137             if (xpe_map & (1 << j)) {
   1138                 BCM_IF_ERROR_RETURN
   1139                     (soc_reg32_get(unit, resInfo->stat_reg[0],
   1140                                    j, i, &rval));
   1141                 soc_reg_field_set(unit, resInfo->stat_reg[0], &rval,
   1142                                   resInfo->stat_field, 0x0);
   1143 
   1144                 BCM_IF_ERROR_RETURN
   1145                     (soc_reg32_set(unit, THDI_HDRM_POOL_PEAK_COUNT_HPr,
   1146                                    j, i, rval));
   1147             }
   1148         }
   1149 
   1150         /* Enable hardware tracking the headroom pool */
   1151         enable = 0x1;
   1152         BCM_IF_ERROR_RETURN
   1153             (_bcm_th_bst_hdrm_monitor_set(unit, i, pipe, enable));
   1154     }
   1155 
   1156     for (j = 0; j < NUM_LAYER(unit); j++) {
   1157         rval = 0x0;
   1158         soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval,
   1159                           PEAK_COUNT_UPDATE_EN_HPf, hdrm_pool_cfg[j]);
   1160         BCM_IF_ERROR_RETURN
   1161             (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, j, 0, rval));
   1162     }
   1163 
   1164     return BCM_E_NONE;
   1165 }
   1166 
   1167 /*
   1168  * This function is used to clear the software stat for
   1169  * the headroom pool usage count for given [Port, Prio].
   1170  */
   1171 STATIC int
   1172 _bcm_th_bst_hdrm_sw_stat_clear(int unit,
   1173                                bcm_gport_t gport,
   1174                                bcm_cos_t cosq,
   1175                                bcm_cosq_buffer_id_t buffer)
   1176 {
   1177     int i = 0, j = 0;
   1178     _bcm_bst_resource_info_t *resInfo;
   1179     _bcm_bst_cmn_unit_info_t *bst_info;
   1180     uint32 xpe_map = 0;
   1181     int start_hw_index = 0, end_hw_index = 0, pipe = -1;
   1182     soc_info_t *si = NULL;
   1183     int bcm_rv;
   1184 
   1185     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1186         return BCM_E_INIT;
   1187     }
   1188 
   1189     if ((buffer < BCM_COSQ_BUFFER_ID_INVALID) || (buffer >= NUM_XPE(unit))) {
   1190         return BCM_E_PARAM;
   1191     }
   1192 
   1193     resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool);
   1194     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   1195         return BCM_E_PARAM;
   1196     }
   1197 
   1198     xpe_map = (buffer == BCM_COSQ_BUFFER_ID_INVALID) ? 0xf : (1 << buffer);
   1199     if (gport == -1) {
   1200         if (cosq == BCM_COS_INVALID) {
   1201             /* 4 Headroom Pool Ids */
   1202             start_hw_index = 0;
   1203             end_hw_index = 3;
   1204             xpe_map &= 0xf;
   1205         } else {
   1206             return BCM_E_PARAM;
   1207         }
   1208     } else {
   1209         if (bst_info->handlers.resolve_index == NULL) {
   1210             return BCM_E_UNAVAIL;
   1211         }
   1212 
   1213         bst_info->handlers.resolve_index(unit, gport, cosq,
   1214                                          bcmBstStatIdHeadroomPool, &pipe,
   1215                                          &start_hw_index, &end_hw_index,
   1216                                          NULL, NULL, &bcm_rv);
   1217         if (bcm_rv) {
   1218             return bcm_rv;
   1219         }
   1220         si = &SOC_INFO(unit);
   1221         xpe_map &= si->ipipe_xpe_map[pipe];
   1222     }
   1223 
   1224     if (!xpe_map) {
   1225         return BCM_E_PARAM;
   1226     }
   1227 
   1228     for (i = start_hw_index; i <= end_hw_index; i++) {
   1229         for (j = 0; j < NUM_XPE(unit); j++) {
   1230             if (xpe_map & (1 << j)) {
   1231                 resInfo->p_stat[i + j * NUM_XPE(unit)] = 0x0;
   1232             }
   1233         }
   1234     }
   1235 
   1236     return BCM_E_NONE;
   1237 }
   1238 
   1239 /*
   1240  * This function is used to clear the software/hardware
   1241  * stat for the headroom pool usage count for given [Port, Prio].
   1242  */
   1243 int
   1244 _bcm_th_bst_hdrm_stat_clear(int unit,
   1245                             bcm_gport_t gport,
   1246                             bcm_cos_queue_t cosq,
   1247                             bcm_cosq_buffer_id_t buffer)
   1248 {
   1249     _bcm_bst_cmn_unit_info_t *bst_info;
   1250     _bcm_bst_resource_info_t *resInfo;
   1251     int bcm_rv = BCM_E_NONE;
   1252 
   1253     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1254         return BCM_E_INIT;
   1255     }
   1256 
   1257     /* sync all the stats */
   1258     resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool);
   1259     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   1260         return BCM_E_PARAM;
   1261     }
   1262 
   1263     sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   1264     bcm_rv = _bcm_th_bst_hdrm_sw_stat_clear(unit, gport, cosq, buffer);
   1265     sal_mutex_give(bst_info->bst_reslock);
   1266     if (BCM_FAILURE(bcm_rv)) {
   1267         return bcm_rv;
   1268     }
   1269 
   1270     if (bst_info->track_mode) {
   1271         /* BST tracking is in peak mode */
   1272         BCM_IF_ERROR_RETURN
   1273             (_bcm_th_bst_hdrm_hw_stat_clear(unit, gport, cosq, buffer));
   1274     }
   1275 
   1276     return BCM_E_NONE;
   1277 }
   1278 
   1279 /*
   1280  * This function is used to get the BST stat for
   1281  * the headroom pool usage count from software cache.
   1282  */
   1283 STATIC int
   1284 _bcm_th_cosq_bst_hdrm_stat_sw_get(int unit,
   1285                                   bcm_gport_t gport,
   1286                                   bcm_cos_t cosq,
   1287                                   bcm_cosq_buffer_id_t buffer,
   1288                                   uint32 *max_hdrm_stat)
   1289 {
   1290     _bcm_bst_resource_info_t *resInfo;
   1291     _bcm_bst_cmn_unit_info_t *bst_info;
   1292     uint32 temp_stat = 0;
   1293     int i = 0, j = 0;
   1294     int start_hw_index = 0, end_hw_index = 0, pipe = -1;
   1295     uint32 xpe_map = 0;
   1296     soc_info_t *si = NULL;
   1297     int bcm_rv;
   1298 
   1299     if ((buffer < BCM_COSQ_BUFFER_ID_INVALID) || (buffer >= NUM_XPE(unit))) {
   1300         return BCM_E_PARAM;
   1301     }
   1302 
   1303     resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool);
   1304     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   1305         return BCM_E_PARAM;
   1306     }
   1307 
   1308     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1309         return BCM_E_INIT;
   1310     }
   1311 
   1312     xpe_map = (buffer == BCM_COSQ_BUFFER_ID_INVALID) ? 0xf : (1 << buffer);
   1313     if (gport == -1) {
   1314         if (cosq == BCM_COS_INVALID) {
   1315             xpe_map &= 0xf;
   1316             start_hw_index = 0;
   1317             end_hw_index = 3;
   1318         } else {
   1319             return BCM_E_PARAM;
   1320         }
   1321     } else {
   1322         if (bst_info->handlers.resolve_index == NULL) {
   1323             return BCM_E_UNAVAIL;
   1324         }
   1325 
   1326         bst_info->handlers.resolve_index(unit, gport, cosq,
   1327                                          bcmBstStatIdHeadroomPool, &pipe,
   1328                                          &start_hw_index, &end_hw_index,
   1329                                          NULL, NULL, &bcm_rv);
   1330         if (bcm_rv) {
   1331             return bcm_rv;
   1332         }
   1333         si = &SOC_INFO(unit);
   1334         xpe_map &= si->ipipe_xpe_map[pipe];
   1335     }
   1336 
   1337     if (!xpe_map) {
   1338         return BCM_E_PARAM;
   1339     }
   1340 
   1341     for (i = start_hw_index; i <= end_hw_index; i++) {
   1342         for (j = 0; j < NUM_XPE(unit); j++) {
   1343             if (xpe_map & (1 << j)) {
   1344                 temp_stat = resInfo->p_stat[i + (j * NUM_XPE(unit))];
   1345                 if (temp_stat > *max_hdrm_stat) {
   1346                     *max_hdrm_stat = temp_stat;
   1347                 }
   1348             }
   1349         }
   1350     }
   1351 
   1352     return BCM_E_NONE;
   1353 }
   1354 
   1355 /*
   1356  * This function is used to get the BST stat for
   1357  * the headroom pool usage count for given [Port, Prio].
   1358  * Note: Regardless of tracking mode this function
   1359  * returns max value of headroom pools.
   1360  */
   1361 int
   1362 _bcm_th_cosq_bst_hdrm_stat_get(int unit,
   1363                                bcm_gport_t gport,
   1364                                bcm_cos_queue_t cosq,
   1365                                bcm_cosq_buffer_id_t buffer,
   1366                                uint32 options,
   1367                                uint64 *pvalue)
   1368 {
   1369     uint32 max_hdrm_stat = 0;
   1370 
   1371     if (pvalue == NULL) {
   1372         return BCM_E_PARAM;
   1373     }
   1374 
   1375     COMPILER_64_ZERO(*pvalue);
   1376 
   1377     BCM_IF_ERROR_RETURN
   1378         (_bcm_th_cosq_bst_hdrm_stat_sw_get(unit, gport, cosq, buffer,
   1379                                            &max_hdrm_stat));
   1380 
   1381     /* Cell Size = 208 bytes */
   1382     COMPILER_64_ADD_32(*pvalue,
   1383                        (max_hdrm_stat * _TH_MMU_BYTES_PER_CELL));
   1384 
   1385     if (options & BCM_COSQ_STAT_CLEAR) {
   1386         BCM_IF_ERROR_RETURN
   1387             (_bcm_th_bst_hdrm_stat_clear(unit, gport, cosq, buffer));
   1388     }
   1389     return BCM_E_NONE;
   1390 }
   1391 
   1392 /* Function to return the corresponding XPE instance for a given gport.
   1393  * Direction(Ingress/Egress) is derived from bid type
   1394  */
   1395 int _bst_th_port_to_mmu_inst_map_get(int unit, bcm_bst_stat_id_t bid,
   1396                                      bcm_gport_t gport, uint32 *mmu_inst_map)
   1397 {
   1398     soc_info_t *si = &SOC_INFO(unit);
   1399     _bcm_bst_resource_info_t *resInfo;
   1400     bcm_port_t local_port;
   1401     bcm_module_t module;
   1402     bcm_trunk_t trunk;
   1403     int id, pipe;
   1404 
   1405     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1406     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   1407         return BCM_E_PARAM;
   1408     }
   1409 
   1410     if (!BCM_GPORT_IS_SET(gport)) {
   1411         if (!SOC_PORT_VALID(unit, gport)) {
   1412             return BCM_E_PORT;
   1413         }
   1414         local_port = gport;
   1415     } else {
   1416         BCM_IF_ERROR_RETURN
   1417             (_bcm_esw_gport_resolve(unit, gport, &module,
   1418                                     &local_port, &trunk, &id));
   1419     }
   1420 
   1421     SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1422 
   1423     if ((bid == bcmBstStatIdEgrPool) || (bid == bcmBstStatIdEgrMCastPool) ||
   1424         (bid == bcmBstStatIdUcast) || (bid == bcmBstStatIdMcast) ||
   1425         (bid == bcmBstStatIdRQEQueue) || (bid == bcmBstStatIdRQEPool) ||
   1426         (bid == bcmBstStatIdUCQueueGroup) ||
   1427         (bid == bcmBstStatIdEgrPortPoolSharedUcast) ||
   1428         (bid == bcmBstStatIdEgrPortPoolSharedMcast)) {
   1429         /* For Egress Res,
   1430          * Pipe 0,1 has XPE 0,2
   1431          * Pipe 2,3 has XPE 1,3
   1432          */
   1433         *mmu_inst_map = si->epipe_xpe_map[pipe];
   1434     } else if ((bid == bcmBstStatIdIngPool) || (bid == bcmBstStatIdPortPool) ||
   1435                (bid == bcmBstStatIdPriGroupShared) ||
   1436                (bid == bcmBstStatIdPriGroupHeadroom)) {
   1437         /* For Ingress Res,
   1438          * Pipe 0,3 has XPE 0,1
   1439          * Pipe 1,2 has XPE 2,3
   1440          */
   1441         *mmu_inst_map = si->ipipe_xpe_map[pipe];
   1442     } else {
   1443         /* For Global res, return all instance */
   1444         *mmu_inst_map = (1 << NUM_XPE(unit)) - 1;
   1445     }
   1446 
   1447     return BCM_E_NONE;
   1448 }
   1449 
   1450 int _bst_th_thd_reg_index_get(int unit, bcm_bst_stat_id_t bid, int pipe,
   1451                                     int hw_index, int *inst, int *index)
   1452 {
   1453     if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
   1454         int phy_port, mmu_port, mmu_port_base;
   1455         soc_info_t *si = &SOC_INFO(unit);
   1456 
   1457         mmu_port_base = SOC_TH_MMU_PORT_STRIDE * pipe;
   1458         mmu_port = hw_index / _TH_MMU_NUM_POOL;
   1459         phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base];
   1460         *inst = si->port_p2l_mapping[phy_port];
   1461         *index = hw_index % _TH_MMU_NUM_POOL;
   1462     }
   1463 
   1464     return BCM_E_NONE;
   1465 }
   1466 
   1467 int _bst_th_cmn_io_op(int unit, int op, int pipe, int hw_index,
   1468                       bcm_bst_stat_id_t bid, soc_mem_t mem, soc_reg_t reg,
   1469                       soc_field_t field, uint32 *resval)
   1470 {
   1471     uint32 entry[SOC_MAX_MEM_WORDS], rval;
   1472     int port = REG_PORT_ANY, reg_index = hw_index;
   1473     _bcm_bst_resource_info_t *resInfo;
   1474 
   1475     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1476     if ((resInfo->flags & _BCM_BST_CMN_RES_F_PORTED) &&
   1477         (op & BST_OP_THD)) {
   1478         BCM_IF_ERROR_RETURN(
   1479             _bst_th_thd_reg_index_get(unit, bid, pipe, hw_index,
   1480                                       &port, &reg_index));
   1481     }
   1482 
   1483     if (mem != INVALIDm) {
   1484         SOC_IF_ERROR_RETURN(
   1485             soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, entry));
   1486         if (op & BST_OP_GET) {
   1487             *resval = soc_mem_field32_get(unit, mem, entry, field);
   1488         } else if (op & BST_OP_SET) {
   1489             soc_mem_field32_set(unit, mem, entry, field, *resval);
   1490             SOC_IF_ERROR_RETURN(
   1491                 soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_index, entry));
   1492         }
   1493     } else if (reg != INVALIDr) {
   1494         SOC_IF_ERROR_RETURN(
   1495             soc_reg32_get(unit, reg, port, reg_index, &rval));
   1496         if (op & BST_OP_GET) {
   1497             *resval = soc_reg_field_get(unit, reg, rval, field);
   1498         } else if (op & BST_OP_SET) {
   1499             if (*resval >= (1 << soc_reg_field_length(unit, reg, field))) {
   1500                 return BCM_E_PARAM;
   1501             }
   1502             /* For TH, the global resource is actually each per XPE */
   1503             if(bid == bcmBstStatIdDevice){
   1504                 for (port = 0; port < NUM_XPE(unit); port++) {
   1505                     int inst;
   1506                     soc_reg_field_set(unit, reg, &rval, field, *resval);
   1507                     inst = port | SOC_REG_ADDR_INSTANCE_MASK;
   1508                     SOC_IF_ERROR_RETURN(
   1509                         soc_reg32_set(unit, reg, inst, reg_index, rval));
   1510                     /* update sw threshold */
   1511                     resInfo->p_threshold[port] = *resval;
   1512                 }
   1513             } else
   1514             {
   1515                 soc_reg_field_set(unit, reg, &rval, field, *resval);
   1516                 SOC_IF_ERROR_RETURN(
   1517                     soc_reg32_set(unit, reg, port, reg_index, rval));
   1518             }
   1519         }
   1520     }
   1521 
   1522     return BCM_E_NONE;
   1523 
   1524 }
   1525 
   1526 /* decide each bid's thd/profile/.. idx based on {pipe+xpe} */
   1527 typedef struct _bcm_bst_id_map_s {
   1528     int pipe;
   1529     int xpe;
   1530     int tid;    /* thd reg idx of resInfo->threshold_reg */
   1531     int pid;    /* profile idx of resInfo->profile_r */
   1532     int pregid; /* profile reg idx of resInfo->profile_reg */
   1533     int idinp;  /* idx of regs which are managed by a same resInfo->profile_r */
   1534 }_bcm_bst_id_map_t;
   1535 
   1536 /* bcmBstStatIdDevice */
   1537 const _bcm_bst_id_map_t _bcm_bst_th_id_map_0[] = {
   1538 /*  pipe    xpe     tid     pid     pregid  idinp */
   1539     {-1,    -1,     0,      -1,     -1,     -1},
   1540 };
   1541 /* bcmBstStatIdIngPool */
   1542 const _bcm_bst_id_map_t _bcm_bst_th_id_map_1i[] = {
   1543 /*  pipe    xpe     tid     pid     pregid  idinp */
   1544     {0,     0,      0,      -1,     -1,     -1},
   1545     {0,     1,      1,      -1,     -1,     -1},
   1546     {1,     2,      2,      -1,     -1,     -1},
   1547     {1,     3,      3,      -1,     -1,     -1},
   1548     {2,     2,      2,      -1,     -1,     -1},
   1549     {2,     3,      3,      -1,     -1,     -1},
   1550     {3,     0,      0,      -1,     -1,     -1},
   1551     {3,     1,      1,      -1,     -1,     -1},
   1552 };
   1553 /* bcmBstStatIdEgrPool */
   1554 /* bcmBstStatIdEgrMCastPool */
   1555 /* bcmBstStatIdRQEQueue */
   1556 /* bcmBstStatIdRQEPool */
   1557 const _bcm_bst_id_map_t _bcm_bst_th_id_map_1e[] = {
   1558 /*  pipe    xpe     tid     pid     pregid  idinp */
   1559     {0,     0,      0,      -1,     -1,     -1},
   1560     {0,     2,      2,      -1,     -1,     -1},
   1561     {1,     0,      0,      -1,     -1,     -1},
   1562     {1,     2,      2,      -1,     -1,     -1},
   1563     {2,     1,      1,      -1,     -1,     -1},
   1564     {2,     3,      3,      -1,     -1,     -1},
   1565     {3,     1,      1,      -1,     -1,     -1},
   1566     {3,     3,      3,      -1,     -1,     -1},
   1567 };
   1568 /* bcmBstStatIdUcast */
   1569 /* bcmBstStatIdEgrPortPoolSharedUcast */
   1570 /* bcmBstStatIdUCQueueGroup */
   1571 const _bcm_bst_id_map_t _bcm_bst_th_id_map_2e[] = {
   1572 /*  pipe    xpe     tid     pid     pregid  idinp */
   1573     {0,     -1,     0,      0,      0,      0},
   1574     {1,     -1,     1,      0,      0,      0},
   1575     {2,     -1,     2,      0,      0,      0},
   1576     {3,     -1,     3,      0,      0,      0},
   1577 };
   1578 /* bcmBstStatIdPortPool */
   1579 /* bcmBstStatIdPriGroupShared */
   1580 /* bcmBstStatIdPriGroupHeadroom */
   1581 const _bcm_bst_id_map_t _bcm_bst_th_id_map_3i[] = {
   1582 /*  pipe    xpe     tid     pid     pregid  idinp */
   1583     {0,     0,      0,      0,      0,      0},
   1584     {0,     1,      0,      0,      1,      1},
   1585     {1,     2,      1,      1,      2,      0},
   1586     {1,     3,      1,      1,      3,      1},
   1587     {2,     2,      2,      1,      2,      0},
   1588     {2,     3,      2,      1,      3,      1},
   1589     {3,     0,      3,      0,      0,      0},
   1590     {3,     1,      3,      0,      1,      1},
   1591 };
   1592 /* bcmBstStatIdMcast */
   1593 const _bcm_bst_id_map_t _bcm_bst_th_id_map_3e[] = {
   1594 /*  pipe    xpe     tid     pid     pregid  idinp */
   1595     {0,     0,      0,      0,      0,      0},
   1596     {0,     2,      0,      0,      2,      1},
   1597     {1,     0,      1,      0,      0,      0},
   1598     {1,     2,      1,      0,      2,      1},
   1599     {2,     1,      2,      1,      1,      0},
   1600     {2,     3,      2,      1,      3,      1},
   1601     {3,     1,      3,      1,      1,      0},
   1602     {3,     3,      3,      1,      3,      1},
   1603 };
   1604 /* bcmBstStatIdEgrPortPoolSharedMcast */
   1605 const _bcm_bst_id_map_t _bcm_bst_th_id_map_4e[] = {
   1606 /*  pipe    xpe     tid     pid     pregid  idinp */
   1607     {0,     0,      0,      0,      0,      0},
   1608     {0,     2,      4,      2,      2,      0},
   1609     {1,     0,      1,      0,      0,      0},
   1610     {1,     2,      5,      2,      2,      0},
   1611     {2,     1,      2,      1,      1,      0},
   1612     {2,     3,      6,      3,      3,      0},
   1613     {3,     1,      3,      1,      1,      0},
   1614     {3,     3,      7,      3,      3,      0},
   1615 };
   1616 
   1617 
   1618 STATIC int _bst_th_id_map_get(int unit, bcm_bst_stat_id_t bid, 
   1619                               const _bcm_bst_id_map_t **map, int *len)
   1620 {
   1621     switch (bid) {
   1622         case bcmBstStatIdDevice:
   1623             *map = &_bcm_bst_th_id_map_0[0];
   1624             *len = sizeof(_bcm_bst_th_id_map_0)/sizeof(_bcm_bst_id_map_t);
   1625             break;
   1626         case bcmBstStatIdIngPool:
   1627             *map = _bcm_bst_th_id_map_1i;
   1628             *len = sizeof(_bcm_bst_th_id_map_1i)/sizeof(_bcm_bst_id_map_t);
   1629             break;
   1630         case bcmBstStatIdEgrPool:
   1631         case bcmBstStatIdEgrMCastPool:
   1632         case bcmBstStatIdRQEQueue:
   1633         case bcmBstStatIdRQEPool:
   1634             *map = _bcm_bst_th_id_map_1e;
   1635             *len = sizeof(_bcm_bst_th_id_map_1e)/sizeof(_bcm_bst_id_map_t);
   1636             break;
   1637         case bcmBstStatIdUcast:
   1638         case bcmBstStatIdEgrPortPoolSharedUcast:
   1639         case bcmBstStatIdUCQueueGroup:
   1640             *map = _bcm_bst_th_id_map_2e;
   1641             *len = sizeof(_bcm_bst_th_id_map_2e)/sizeof(_bcm_bst_id_map_t);
   1642             break;
   1643         case bcmBstStatIdPortPool:
   1644         case bcmBstStatIdPriGroupShared:
   1645         case bcmBstStatIdPriGroupHeadroom:
   1646             *map = _bcm_bst_th_id_map_3i;
   1647             *len = sizeof(_bcm_bst_th_id_map_3i)/sizeof(_bcm_bst_id_map_t);
   1648             break;
   1649         case bcmBstStatIdMcast:
   1650             *map = _bcm_bst_th_id_map_3e;
   1651             *len = sizeof(_bcm_bst_th_id_map_3e)/sizeof(_bcm_bst_id_map_t);
   1652             break;
   1653         case bcmBstStatIdEgrPortPoolSharedMcast:
   1654             *map = _bcm_bst_th_id_map_4e;
   1655             *len = sizeof(_bcm_bst_th_id_map_4e)/sizeof(_bcm_bst_id_map_t);
   1656             break;
   1657         default:
   1658             return BCM_E_PARAM;
   1659     }
   1660     
   1661     return BCM_E_NONE;
   1662 }
   1663 
   1664 STATIC int
   1665 _bst_th_profile_init(int unit)
   1666 {
   1667     _bcm_bst_cmn_unit_info_t *bst_info;
   1668     _bcm_bst_resource_info_t *resInfo;
   1669     const _bcm_bst_id_map_t *map, *map0;
   1670     bcm_bst_stat_id_t bid;
   1671     bcm_cosq_bst_profile_t profile;
   1672     int i, cnt, pcnt, regcnt, xpe, ei, index_max, entry_size, wb;
   1673     uint32 profile_index, thd_bmp;
   1674     soc_mem_t preg[_BCM_MAX_PROFILES][_BCM_MAX_REGS_PER_PROFILE];
   1675 
   1676     wb = SOC_WARM_BOOT(unit) ? 1 : 0;
   1677     bst_info = _BCM_UNIT_BST_INFO(unit);
   1678     profile.byte = bst_info->max_bytes;
   1679 
   1680     _BCM_BST_RESOURCE_ITER(bst_info, bid) {
   1681         resInfo = _BCM_BST_RESOURCE(unit, bid);
   1682         if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID)) {
   1683             continue;
   1684         }
   1685 
   1686         if (resInfo->threshold_gran != 0) {
   1687             profile.byte = bst_info->to_byte(unit,
   1688                            TH_BST_THRESHOLD_MAX_HIGH - (resInfo->threshold_gran - 1));
   1689         }
   1690     
   1691         if (resInfo->threshold_gran != 0) {
   1692             profile.byte = bst_info->to_byte(unit,
   1693                            TH_BST_THRESHOLD_MAX_HIGH - (resInfo->threshold_gran - 1));
   1694         }
   1695     
   1696         BCM_IF_ERROR_RETURN(_bst_th_id_map_get(unit, bid, &map0, &cnt));
   1697         
   1698         /* create profiles */
   1699         resInfo->profile_m = NULL;
   1700         for (i = 0; i < _BCM_MAX_PROFILES; i ++) {
   1701             resInfo->profile_r[i] = NULL;
   1702         }
   1703         if (resInfo->profile_mem != INVALIDm) {
   1704             soc_profile_mem_t_init(&resInfo->iprofile_m);
   1705             entry_size = soc_mem_entry_bytes(unit, resInfo->profile_mem);
   1706             SOC_IF_ERROR_RETURN(
   1707                 soc_profile_mem_create(unit, &resInfo->profile_mem, 
   1708                                    &entry_size, 1, &resInfo->iprofile_m));
   1709             resInfo->profile_m = &resInfo->iprofile_m;
   1710         } else if (resInfo->profile_reg[0] != INVALIDr) {
   1711             for (i = 0, pcnt = 0, regcnt = 0, map = map0; i < cnt; i ++, map ++) {
   1712                 preg[map->pid][map->idinp] = resInfo->profile_reg[map->pregid];
   1713                 if (map->pid >= pcnt) {
   1714                     pcnt = map->pid + 1;
   1715                 }
   1716                 if (map->idinp >= regcnt) {
   1717                     regcnt = map->idinp + 1;
   1718                 }
   1719             }
   1720             for (i = 0; i < pcnt; i ++) {
   1721                 soc_profile_reg_t_init(&resInfo->iprofile_r[i]);
   1722                 SOC_IF_ERROR_RETURN(soc_profile_reg_create
   1723                     (unit, preg[i], regcnt, &resInfo->iprofile_r[i]));
   1724                 if ((bid == bcmBstStatIdUcast) ||
   1725                     (bid == bcmBstStatIdEgrPortPoolSharedUcast)) {
   1726                     resInfo->iprofile_r[i].profile_flag = SOC_PROFILE_FLAG_XPE_SINGLE_ACC;
   1727                 }
   1728                 resInfo->profile_r[i] = &resInfo->iprofile_r[i];
   1729             }
   1730         }
   1731 
   1732         /* init profiles reference */
   1733         index_max = (resInfo->index_max + 1) / 
   1734             (NUM_PIPE(unit) * resInfo->num_instance);
   1735         for (i = 0, map = map0, thd_bmp = 0x0; i < cnt; i ++, map ++) {
   1736             if (thd_bmp & (1 << map->tid)) {
   1737                 continue;
   1738             }
   1739 
   1740             for (ei = 0; ei < index_max; ei ++) {
   1741                 /* get profile index */
   1742                 if (wb) {
   1743                     BCM_IF_ERROR_RETURN(_bst_th_cmn_io_op(unit, 
   1744                                         BST_OP_GET | BST_OP_THD,
   1745                                         map->pipe, ei, bid,
   1746                                         resInfo->threshold_mem[map->pipe],
   1747                                         resInfo->threshold_reg[map->tid],
   1748                                         resInfo->threshold_field,
   1749                                         &profile_index));
   1750                 } else if (ei == 0) {
   1751                     xpe = (resInfo->profile_r[map->pid]->regs_count > 1) ? 
   1752                         BCM_BST_DUP_XPE : map->xpe;
   1753                     BCM_IF_ERROR_RETURN(_bst_th_cmn_profile_set_hw
   1754                         (unit, map->pipe, xpe, -1, bid, &profile, &profile_index));
   1755                     continue;
   1756                 }
   1757                 /* add reference */
   1758                 if (resInfo->profile_r[0]) {
   1759                     BCM_IF_ERROR_RETURN(soc_profile_reg_reference(unit,
   1760                            resInfo->profile_r[map->pid], profile_index, 1));
   1761                 } else if (resInfo->profile_m) {
   1762                     BCM_IF_ERROR_RETURN(soc_profile_mem_reference(unit,
   1763                            resInfo->profile_m, profile_index, 1));
   1764                 }
   1765             }
   1766 
   1767             thd_bmp |= (1 << map->tid);
   1768         }
   1769     }
   1770     
   1771     if (SOC_IS_TOMAHAWKX(unit)) {
   1772         /* Set default threshold for bcmBstStatIdIngPool from zero
   1773          * to max to avoid unexpected trigger.
   1774          */
   1775         int pool_num = 4;
   1776         bcm_cosq_bst_profile_t_init(&profile);
   1777         profile.byte = bst_info->max_bytes;
   1778         for (ei = 0; ei < pool_num; ei++) {
   1779             /* coverity[callee_ptr_arith: FALSE] */
   1780             SOC_IF_ERROR_RETURN(_bst_th_cmn_profile_set_hw(unit, -1, 
   1781                 BCM_BST_DUP_XPE, ei, bcmBstStatIdIngPool, &profile, NULL));
   1782         }
   1783     }
   1784 
   1785     return BCM_E_NONE;
   1786 }
   1787 
   1788 /*
   1789  * Get threshold of specified bid from pipe and hw_index
   1790  *
   1791  * Usage of xpe:
   1792  *  0~3:    single xpe, profile[0] = reg[xpe]
   1793  *   -1:    the first xpe related to the pipe, profile[0] = reg[first xpe]
   1794  *   -2:    all xpe related to the pipe, profile[i] = reg[i]
   1795  */
   1796 STATIC int 
   1797 _bst_th_cmn_profile_get_hw(int unit, int pipe, int xpe, int hw_index, 
   1798                             bcm_bst_stat_id_t bid, 
   1799                             bcm_cosq_bst_profile_t *profile)
   1800 {
   1801     _bcm_bst_cmn_unit_info_t *bst_info;
   1802     _bcm_bst_resource_info_t *resInfo;
   1803     uint32 cells, profile_index, val;
   1804     int i, cnt, xpe_id, pipe_id;
   1805     const _bcm_bst_id_map_t *map;
   1806 
   1807     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1808         return BCM_E_INIT;
   1809     }
   1810 
   1811     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1812 
   1813     BCM_IF_ERROR_RETURN(_bst_th_id_map_get(unit, bid, &map, &cnt));
   1814     for (i = 0; i < cnt; i ++, map ++) {
   1815         if (((pipe >= 0) && (map->pipe >= 0) && (pipe != map->pipe)) ||
   1816             ((xpe >= 0) && (map->xpe >= 0) && (xpe != map->xpe))) {
   1817             continue;
   1818         }
   1819 
   1820         xpe_id = (map->xpe < 0) ? 0: map->xpe;
   1821         pipe_id = (map->pipe < 0) ? 0: map->pipe;
   1822 
   1823         SOC_IF_ERROR_RETURN(        
   1824            _bst_th_cmn_io_op(unit, BST_OP_GET | BST_OP_THD,
   1825                               pipe_id, hw_index, bid,
   1826                               resInfo->threshold_mem[pipe_id],
   1827                               resInfo->threshold_reg[map->tid],
   1828                               resInfo->threshold_field,
   1829                               &val));
   1830         if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
   1831             profile_index = val;
   1832             SOC_IF_ERROR_RETURN(
   1833                _bst_th_cmn_io_op(unit, BST_OP_GET, 
   1834                                   pipe_id, profile_index, bid,
   1835                                   resInfo->profile_mem,
   1836                                   resInfo->profile_reg[map->pregid],
   1837                                   resInfo->profile_field, 
   1838                                   &cells));
   1839         } else {
   1840             cells = val;
   1841         }
   1842 
   1843         /* Taking granularity into count */
   1844         if (resInfo->threshold_gran != 0) {
   1845             cells = cells * resInfo->threshold_gran - resInfo->threshold_adj;
   1846         } else {
   1847             cells -= resInfo->threshold_adj;
   1848         }
   1849         
   1850         if (xpe == BCM_BST_MLT_XPE) {
   1851             profile[xpe_id].byte = bst_info->to_byte(unit, cells);
   1852         } else {
   1853             profile[0].byte = bst_info->to_byte(unit, cells);
   1854             break;
   1855         }
   1856     }
   1857     
   1858     return BCM_E_NONE;
   1859 }
   1860 
   1861 /*
   1862  * Get threshold of specified bid from pipe and hw_index
   1863  *
   1864  * Usage of xpe:
   1865  *  0~3:    single xpe, reg[xpe] = profile[0]
   1866  *   -1:    all xpe related to the pipe with same value, reg[i] = profile[0]
   1867  *   -2:    all xpe related to the pipe with different value, reg[i] = profile[i]
   1868  */
   1869 STATIC int 
   1870 _bst_th_cmn_profile_set_hw(int unit, int pipe, int xpe, int hw_index, 
   1871                             bcm_bst_stat_id_t bid,
   1872                             bcm_cosq_bst_profile_t *profile, 
   1873                             uint32 *p_profile)
   1874 {
   1875     _bcm_bst_cmn_unit_info_t *bst_info;
   1876     _bcm_bst_resource_info_t *resInfo;
   1877     bcm_cosq_bst_profile_t profile_arr[_TH_XPES_PER_DEV];
   1878     uint32 byte, cells[_BCM_MAX_PROFILE_REGS];
   1879     uint32 profile_index, old_profile_index;
   1880     uint32 entry[SOC_MAX_MEM_WORDS];
   1881     void *entries[1];
   1882     uint64 rval[_BCM_MAX_PROFILES][_BCM_MAX_REGS_PER_PROFILE];
   1883     uint64 *prval[_BCM_MAX_PROFILES][_BCM_MAX_REGS_PER_PROFILE];
   1884     int pipe_factor = 1, pipe_offset = 0, offset_per_xpe, num_instance;
   1885     int i, cnt, xpe_id, pipe_id, trigger = 0;
   1886     const _bcm_bst_id_map_t *map;
   1887 
   1888     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1889         return BCM_E_INIT;
   1890     }
   1891 
   1892     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1893 
   1894     num_instance = (resInfo->num_instance > 1) ? resInfo->num_instance : 1;
   1895     offset_per_xpe = (resInfo->index_max + 1) / num_instance;
   1896     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   1897         pipe_factor = NUM_PIPE(unit);
   1898         pipe_offset = pipe * (offset_per_xpe / pipe_factor);
   1899     }
   1900 
   1901     /* in case profile contains multiple regs while api only passing one,
   1902        read hw to get unprovided regs */
   1903     if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
   1904         if ((resInfo->profile_r[0]) && (resInfo->profile_r[0]->regs_count > 1) 
   1905             && (xpe >= 0)) {
   1906             if (xpe >= _TH_XPES_PER_DEV) {
   1907                 return BCM_E_PARAM;
   1908             }
   1909             sal_memset(profile_arr, 0, sizeof(profile_arr));
   1910             BCM_IF_ERROR_RETURN(_bst_th_cmn_profile_get_hw
   1911                 (unit, pipe, BCM_BST_MLT_XPE, hw_index, bid, profile_arr));
   1912             profile_arr[xpe].byte = profile->byte;
   1913             profile = profile_arr;
   1914             xpe = BCM_BST_MLT_XPE;
   1915         }
   1916     }
   1917     
   1918     BCM_IF_ERROR_RETURN(_bst_th_id_map_get(unit, bid, &map, &cnt));
   1919     for (i = 0; i < cnt; i ++, map ++) {
   1920         if (((pipe >= 0) && (map->pipe >= 0) && (pipe != map->pipe)) ||
   1921             ((xpe >= 0) && (map->xpe >= 0) && (xpe != map->xpe))) {
   1922             continue;
   1923         }
   1924 
   1925         xpe_id = (map->xpe < 0) ? 0: map->xpe;
   1926         pipe_id = (map->pipe < 0) ? 0: map->pipe;
   1927 
   1928         if (xpe == BCM_BST_MLT_XPE) {
   1929             byte = profile[xpe_id].byte;
   1930         } else {
   1931             byte = profile[0].byte;
   1932         }
   1933         /* Taking granularity into count */    
   1934         if (resInfo->threshold_gran != 0) {
   1935             cells[xpe_id] = (bst_info->to_cell(unit, byte) +
   1936                     resInfo->threshold_adj + resInfo->threshold_gran - 1) /
   1937                     resInfo->threshold_gran;
   1938         } else {
   1939             cells[xpe_id] = bst_info->to_cell(unit, byte) + resInfo->threshold_adj;
   1940         }
   1941         
   1942         /* update sw thd */
   1943         if (hw_index >= 0) {
   1944             if (BST_THRESHOLD_MAX_HIGH != bst_info->to_cell(unit, byte)) {
   1945                 if (map->xpe == -1) {
   1946                     int xid;
   1947                     for (xid = 0; xid < NUM_XPE(unit); xid++) {
   1948                         resInfo->p_threshold
   1949                             [hw_index + pipe_offset + xid * offset_per_xpe]
   1950                                 = cells[xpe_id];
   1951                     }
   1952                 } else {
   1953                     resInfo->p_threshold
   1954                         [hw_index + pipe_offset + xpe_id * offset_per_xpe]
   1955                             = cells[xpe_id];
   1956                 }
   1957             } else {
   1958                 cells[xpe_id] = bst_info->to_cell(unit, byte);
   1959             }
   1960         }
   1961 
   1962         if ((cells[xpe_id] > 0) && (cells[xpe_id] < BST_THRESHOLD_MAX_HIGH)) {
   1963             trigger = 1;
   1964         }
   1965 
   1966         if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
   1967             profile_index = old_profile_index = -1;
   1968 
   1969             /* add profile */
   1970             if (resInfo->profile_r[0]) {
   1971                 COMPILER_64_ZERO(rval[map->pid][map->idinp]);
   1972                 soc_reg64_field32_set(unit, resInfo->profile_reg[0], 
   1973                     &rval[map->pid][map->idinp], resInfo->profile_field, 
   1974                     cells[xpe_id]);
   1975                 prval[map->pid][map->idinp] = &rval[map->pid][map->idinp];
   1976                 /* hold settings in rval until all regs of that profile 
   1977                    are configured, then add profile */
   1978                 if (map->idinp + 1 == resInfo->profile_r[map->pid]->regs_count) {
   1979                     SOC_IF_ERROR_RETURN(soc_profile_reg_add(unit, 
   1980                         resInfo->profile_r[map->pid], prval[map->pid], 
   1981                         1, &profile_index));
   1982                 }
   1983             } else {
   1984                 sal_memset(entry, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS);
   1985                 soc_mem_field32_set(unit, resInfo->profile_mem, &entry,
   1986                                     resInfo->profile_field, cells[0]);
   1987                 entries[0] = entry;
   1988                 SOC_IF_ERROR_RETURN(soc_profile_mem_add(unit, 
   1989                     resInfo->profile_m, entries, 1, &profile_index));
   1990             }
   1991 
   1992             if (profile_index != -1) {
   1993                 if ((bid == bcmBstStatIdMcast) && _BCM_BST_TH_IS_CPU_QUEUE(hw_index)) {
   1994                     uint64 value;
   1995                     COMPILER_64_ZERO(value);
   1996                     soc_reg64_field32_set(unit, MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILEr,
   1997                         &value, THRESHOLDf, cells[xpe_id]);
   1998                     SOC_IF_ERROR_RETURN(soc_reg_set(unit,
   1999                         MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILE_XPE0r,
   2000                         REG_PORT_ANY, profile_index, value));
   2001                     SOC_IF_ERROR_RETURN(soc_reg_set(unit,
   2002                         MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILE_XPE2r,
   2003                         REG_PORT_ANY, profile_index, value));
   2004                 }
   2005 
   2006                 if (hw_index >= 0) {
   2007                     /* old profile id */
   2008                     SOC_IF_ERROR_RETURN(        
   2009                        _bst_th_cmn_io_op(unit, BST_OP_GET | BST_OP_THD, 
   2010                                           pipe_id, hw_index, bid, 
   2011                                           resInfo->threshold_mem[pipe_id],
   2012                                           resInfo->threshold_reg[map->tid],
   2013                                           resInfo->threshold_field,
   2014                                           &old_profile_index));
   2015                     /* attach the new profile id */
   2016                     SOC_IF_ERROR_RETURN(        
   2017                         _bst_th_cmn_io_op(unit, BST_OP_SET | BST_OP_THD, 
   2018                                            pipe_id, hw_index, bid, 
   2019                                            resInfo->threshold_mem[pipe_id],
   2020                                            resInfo->threshold_reg[map->tid],
   2021                                            resInfo->threshold_field, 
   2022                                            &profile_index));
   2023                     SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_delete_hw
   2024                         (unit, bid, map->pid, old_profile_index));
   2025                 }
   2026                 if (p_profile) {
   2027                     *p_profile = profile_index;
   2028                 }
   2029             }
   2030         } else {
   2031             SOC_IF_ERROR_RETURN(
   2032                 _bst_th_cmn_io_op(unit, BST_OP_SET | BST_OP_THD, 
   2033                                    pipe_id, hw_index, bid, 
   2034                                    resInfo->threshold_mem[pipe_id],
   2035                                    resInfo->threshold_reg[map->tid],
   2036                                    resInfo->threshold_field,
   2037                                    &cells[xpe_id]));
   2038         }
   2039     }
   2040 
   2041     if (trigger && bst_info->hw_trigger_set) {
   2042         bst_info->hw_trigger_set(unit, bid);
   2043     }
   2044 
   2045     return BCM_E_NONE;
   2046 }
   2047 
   2048 int
   2049 bcm_bst_th_init(int unit)
   2050 {
   2051     _bcm_bst_cmn_unit_info_t *bst_info;
   2052     _bcm_bst_resource_info_t *pres;
   2053     int idx_count, i;
   2054     /* stat count and thd count need not be same.
   2055      * stat_count - Acc Type of stat are Non Dup, hence stat is for all ACC type
   2056      * thd_count - Acc Type of Thd are Dup(except CFAP), hence 1 copy.
   2057      */
   2058     int total_stat_count, total_thd_count;
   2059     soc_mem_t stat_mem = INVALIDm, child_mem = INVALIDm, thd_mem = INVALIDm;
   2060     soc_reg_t stat_reg = INVALIDr, thd_reg = INVALIDr, prof_reg = INVALIDr;
   2061     soc_field_t stat_field = INVALIDf, thd_field = INVALIDf, prof_field = INVALIDf;
   2062     int layer = 0, granularity = 1;
   2063     uint32 rval;
   2064 
   2065     bst_info = _BCM_UNIT_BST_INFO(unit);
   2066     if (!bst_info) {
   2067         return BCM_E_MEMORY;
   2068     }
   2069 
   2070     bst_info->to_cell = _bcm_bst_th_byte_to_cell;
   2071     bst_info->to_byte = _bcm_bst_th_cell_to_byte;
   2072     bst_info->control_set = _bcm_th_bst_control_set;
   2073     bst_info->control_get = _bcm_th_bst_control_get;
   2074     bst_info->intr_to_resources = _bcm_bst_th_intr_to_resources;
   2075     bst_info->hw_stat_snapshot = _bcm_bst_th_sync_hw_snapshot;
   2076     bst_info->hw_stat_clear = _bcm_bst_th_hw_stat_clear;
   2077     bst_info->intr_enable_set = _bcm_bst_th_intr_enable_set;
   2078     bst_info->pre_sync = NULL;
   2079     bst_info->post_sync = NULL;
   2080     bst_info->hw_intr_cb = soc_th_set_hw_intr_cb;
   2081     bst_info->port_to_mmu_inst_map = _bst_th_port_to_mmu_inst_map_get;
   2082     bst_info->bst_cmn_io_op = _bst_th_cmn_io_op;
   2083     bst_info->profile_init = _bst_th_profile_init;
   2084     bst_info->thd_get = _bst_th_cmn_profile_get_hw;
   2085     bst_info->thd_set = _bst_th_cmn_profile_set_hw;;
   2086     bst_info->hw_sbusdma_desc_init = _bcm_bst_th_sbusdma_desc_init;
   2087     bst_info->hw_sbusdma_desc_deinit = _bcm_bst_th_sbusdma_desc_deinit;
   2088     bst_info->hw_sbusdma_desc_sync = _bcm_bst_th_sbusdma_desc_sync;
   2089     bst_info->max_bytes = bst_info->to_byte(unit, TH_BST_THRESHOLD_MAX_HIGH);
   2090 
   2091 #ifdef BCM_TOMAHAWK2_SUPPORT
   2092     /* on TH2, enable HW Clear on Read for HWM mode by default */
   2093     if (SOC_IS_TOMAHAWK2(unit) &&
   2094         soc_property_get(unit, "hw_cor_in_max_use_count", TRUE)) {
   2095         BCM_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval));
   2096         soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval,
   2097                           BST_CLEAR_ON_READ_IN_MAX_USE_COUNT_MODE_ENABLEf, 0x1);
   2098         BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval));
   2099         bst_info->hw_cor_in_max_use_count = 1;
   2100     } else
   2101 #endif
   2102     {
   2103         bst_info->hw_cor_in_max_use_count = 0;
   2104     }
   2105 
   2106     /* DEVICE - Resources begin */
   2107     /* bcmBstStatIdDevice */
   2108     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdDevice);
   2109     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2110     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_DEV);
   2111     pres->num_instance = NUM_XPE(unit);
   2112     idx_count = 1;
   2113     stat_mem = INVALIDm;
   2114     stat_reg = CFAPBSTSTATr;
   2115     stat_field = BST_STATf;
   2116 
   2117     /* Threshold info count and Resource allocation */
   2118     granularity = 1;
   2119     total_thd_count = NUM_XPE(unit) * idx_count; /* per xpe copy */
   2120     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAPBSTTHRSr, BST_THRESHOLDf,
   2121                             granularity);
   2122     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst cfap");
   2123     /* Stat info count and Resource allocation */
   2124     total_stat_count = total_thd_count;
   2125     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2126     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst cfap");
   2127     pres->index_min = 0;
   2128     pres->index_max = total_stat_count - 1;
   2129     /* DEVICE - Resources end */
   2130 
   2131     /* INGRESS - Resources begin */
   2132     /* bcmBstStatIdHeadroomPool */
   2133     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool);
   2134     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2135     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING);
   2136     pres->num_instance = NUM_XPE(unit);
   2137     /* There are 4 HDRM POOL per XPE */
   2138     idx_count = _TH_MMU_NUM_POOL;
   2139     stat_mem = INVALIDm;
   2140     BCM_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval));
   2141     bst_info->track_mode = soc_reg_field_get(unit, MMU_GCFG_MISCCONFIGr,
   2142                                              rval, BST_TRACKING_MODEf);
   2143     /*
   2144      * As Headroom Pool has two different stats resource
   2145      * for tracking current usage count and peak usage count
   2146      * we set up the respective resource accordingly based on
   2147      * BST Tracking Mode
   2148      */
   2149     if (bst_info->track_mode) {
   2150         /* Peak Mode */
   2151         stat_reg = THDI_HDRM_POOL_PEAK_COUNT_HPr;
   2152         stat_field = PEAK_BUFFER_COUNTf;
   2153     } else {
   2154         /* Current Mode */
   2155         stat_reg = THDI_HDRM_POOL_COUNT_HPr;
   2156         stat_field = TOTAL_BUFFER_COUNTf;
   2157     }
   2158 
   2159     /* Disabling the headroom Pool monitoring during init */
   2160     for (layer = 0; layer < NUM_LAYER(unit); layer++) {
   2161         BCM_IF_ERROR_RETURN
   2162             (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, layer, 0, 0x0));
   2163     }
   2164 
   2165     /* Stat info count and Resource allocation */
   2166     total_stat_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */
   2167     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2168     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst ing headroom pool");
   2169     pres->index_min = 0;
   2170     pres->index_max = total_stat_count - 1;
   2171 
   2172 
   2173     /* bcmBstStatIdIngPool */
   2174     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdIngPool);
   2175     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2176     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING);
   2177     pres->num_instance = NUM_XPE(unit);
   2178     idx_count = 4;
   2179     stat_mem = INVALIDm;
   2180     stat_reg = THDI_BST_SP_GLOBAL_SHARED_CNTr;
   2181     stat_field = SP_GLOBAL_SHARED_CNTf;
   2182 
   2183     /* Threshold info count and Resource allocation */
   2184     granularity = 1;
   2185     total_thd_count = NUM_XPE(unit) * idx_count;
   2186     thd_reg = THDI_BST_SP_GLOBAL_SHARED_PROFILEr;
   2187     thd_field = SP_GLOBAL_SHARED_PROFILEf;
   2188     for (i = 0; i < NUM_XPE(unit); i++) {
   2189         _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm, 
   2190             SOC_REG_UNIQUE_ACC(unit, thd_reg)[i], thd_field, granularity, i);
   2191     }
   2192     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst ing pool");
   2193     /* Stat info count and Resource allocation */
   2194     total_stat_count = total_thd_count; /* No per pipe copy */
   2195     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2196     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst ing pool");
   2197     pres->index_min = 0;
   2198     pres->index_max = total_stat_count - 1;
   2199 
   2200     /* bcmBstStatIdPortPool */
   2201     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPortPool);
   2202     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2203     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2204                                      _BCM_BST_CMN_RES_F_PIPED |
   2205                                      _BCM_BST_CMN_RES_F_RES_ING);
   2206     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   2207     pres->num_instance = NUM_XPE(unit);
   2208     stat_mem = THDI_PORT_SP_BSTm;
   2209     stat_reg = INVALIDr;
   2210     stat_field = SP_BST_STAT_PORT_COUNTf;
   2211 
   2212     /* Get the mem attributes(Max idx) from the first child,
   2213      * which could be used for other instances.
   2214      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2215      */
   2216     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2217     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2218 
   2219     /* Threshold info count and Resource allocation */
   2220     granularity = 1;
   2221     total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count;
   2222     thd_mem = THDI_PORT_SP_CONFIGm;
   2223     thd_field = SP_BST_PROFILE_SHAREDf;
   2224     for (i = 0; i < NUM_PIPE(unit); i++) {
   2225         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2226                                   INVALIDr, thd_field, granularity, i);
   2227     }
   2228     prof_reg = THDI_BST_SP_SHARED_PROFILEr;
   2229     prof_field = BST_SP_SHARED_THRESHf;
   2230     for (i = 0; i < NUM_XPE(unit); i++) {
   2231         _BCM_BST_PROFILE_INFO_N(pres, INVALIDm, 
   2232             SOC_REG_UNIQUE_ACC(unit, prof_reg)[i], prof_field, i);
   2233     }
   2234     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst port pool");
   2235     /* Stat info count and Resource allocation */
   2236     total_stat_count = total_thd_count;
   2237     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2238     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst port pool");
   2239     pres->index_min = 0;
   2240     pres->index_max = total_stat_count - 1;
   2241 
   2242     /* bcmBstStatIdPriGroupShared */
   2243     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupShared);
   2244     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2245     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2246                                      _BCM_BST_CMN_RES_F_PIPED |
   2247                                      _BCM_BST_CMN_RES_F_RES_ING);
   2248     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   2249     pres->num_instance = NUM_XPE(unit);
   2250     stat_mem = THDI_PORT_PG_BSTm;
   2251     stat_reg = INVALIDr;
   2252     stat_field = PG_BST_STAT_SHAREDf;
   2253     idx_count = NUM_PORT(unit) * 8;
   2254     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2255     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2256 
   2257     /* Threshold info count and Resource allocation */
   2258     granularity = 1;
   2259     total_thd_count = idx_count * NUM_XPE(unit) * NUM_PIPE(unit);
   2260     thd_mem = THDI_PORT_PG_CONFIGm;
   2261     thd_field = PG_BST_PROFILE_SHAREDf;
   2262     for (i = 0; i < NUM_PIPE(unit); i++) {
   2263         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2264                                   INVALIDr, thd_field, granularity, i);
   2265     }
   2266     prof_reg = THDI_BST_PG_SHARED_PROFILEr;
   2267     prof_field = BST_PG_SHARED_THRESHf;
   2268     for (i = 0; i < NUM_XPE(unit); i++) {
   2269         _BCM_BST_PROFILE_INFO_N(pres, INVALIDm, 
   2270             SOC_REG_UNIQUE_ACC(unit, prof_reg)[i], prof_field, i);
   2271     }
   2272     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst pg");
   2273     /* Stat info count and Resource allocation */
   2274     /* Stat res - THDI_PORT_PG_BST : (Num Ports (32/pipe) * 4 pipes) * 8(PGs) */
   2275     total_stat_count = total_thd_count;
   2276     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2277     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst pg");
   2278     pres->index_min = 0;
   2279     pres->index_max = total_stat_count - 1;
   2280 
   2281     /* bcmBstStatIdPriGroupHeadroom */
   2282     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupHeadroom);
   2283     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2284     pres->num_instance = NUM_XPE(unit);
   2285     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2286                                      _BCM_BST_CMN_RES_F_PIPED |
   2287                                      _BCM_BST_CMN_RES_F_RES_ING);
   2288     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   2289     stat_mem = THDI_PORT_PG_BSTm;
   2290     stat_reg = INVALIDr;
   2291     stat_field = PG_BST_STAT_HDRMf;
   2292     idx_count = NUM_PORT(unit) * 8;
   2293     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2294     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2295 
   2296     /* Threshold info count and Resource allocation */
   2297     granularity = 1;
   2298     total_thd_count = idx_count * NUM_XPE(unit) * NUM_PIPE(unit);
   2299     thd_mem = THDI_PORT_PG_CONFIGm;
   2300     thd_field = PG_BST_PROFILE_HDRMf;
   2301     for (i = 0; i < NUM_PIPE(unit); i++) {
   2302         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2303                                   INVALIDr, thd_field, granularity, i);
   2304     }
   2305     prof_reg = THDI_BST_PG_HDRM_PROFILEr;
   2306     prof_field = BST_PG_HDRM_THRESHf;
   2307     for (i = 0; i < NUM_XPE(unit); i++) {
   2308         _BCM_BST_PROFILE_INFO_N(pres, INVALIDm, 
   2309             SOC_REG_UNIQUE_ACC(unit, prof_reg)[i], prof_field, i);
   2310     }
   2311     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst pg hdrm");
   2312     /* Stat info count and Resource allocation */
   2313     /* Stat res - THDI_PORT_PG_BST : (Num Ports (32/pipe) * 4 pipes) * 8(PGs) */
   2314     total_stat_count = total_thd_count;
   2315     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2316     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst pg hdrm");
   2317     pres->index_min = 0;
   2318     pres->index_max = total_stat_count - 1;
   2319     /* INGRESS - Resources end */
   2320 
   2321     /* EGRESS - Resources begin */
   2322     /* bcmBstStatIdEgrPool */
   2323     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPool);
   2324     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2325     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   2326     pres->num_instance = NUM_XPE(unit);
   2327     idx_count = 4;
   2328     pres->threshold_adj = -1;
   2329     stat_mem = INVALIDm;
   2330     stat_reg = MMU_THDM_DB_POOL_MCUC_BST_STATr;
   2331     stat_field = BST_STATf;
   2332 
   2333     /* Threshold info count and Resource allocation */
   2334     granularity = 1;
   2335     total_thd_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */
   2336     thd_reg = MMU_THDM_DB_POOL_MCUC_BST_THRESHOLDr;
   2337     thd_field = BST_STATf;
   2338     for (i = 0; i < NUM_XPE(unit); i++) {
   2339         _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm, 
   2340             SOC_REG_UNIQUE_ACC(unit, thd_reg)[i], thd_field, granularity, i);
   2341     }
   2342     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst egrpool");
   2343     /* Stat info count and Resource allocation */
   2344     total_stat_count = total_thd_count; /* No per pipe copy */
   2345     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2346     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst egrpool");
   2347     pres->index_min = 0;
   2348     pres->index_max = total_stat_count - 1;
   2349 
   2350     /* bcmBstStatIdEgrMCastPool */
   2351     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrMCastPool);
   2352     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2353     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   2354     pres->num_instance = NUM_XPE(unit);
   2355     idx_count = 4;
   2356     pres->threshold_adj = -1;
   2357     stat_mem = INVALIDm;
   2358     stat_reg = MMU_THDM_DB_POOL_MC_BST_STATr;
   2359     stat_field = BST_STATf;
   2360 
   2361     /* Threshold info count and Resource allocation */
   2362     granularity = 1;
   2363     total_thd_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */
   2364     thd_reg = MMU_THDM_DB_POOL_MC_BST_THRESHOLDr;
   2365     thd_field = BST_STATf;
   2366     for (i = 0; i < NUM_XPE(unit); i++) {
   2367         _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm, 
   2368             SOC_REG_UNIQUE_ACC(unit, thd_reg)[i], thd_field, granularity, i);
   2369     }
   2370     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst egr mcpool");
   2371     /* Stat info count and Resource allocation */
   2372     total_stat_count = total_thd_count; /* No per pipe copy */
   2373     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2374     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst egr mcpool");
   2375     pres->index_min = 0;
   2376     pres->index_max = total_stat_count - 1;
   2377 
   2378     /* bcmBstStatIdMcast */
   2379     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdMcast);
   2380     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2381     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2382                                      _BCM_BST_CMN_RES_F_PIPED |
   2383                                      _BCM_BST_CMN_RES_F_RES_EGR);
   2384     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_CMIC(unit));
   2385     pres->num_instance = NUM_XPE(unit);
   2386     stat_mem = MMU_THDM_DB_QUEUE_BSTm;
   2387     stat_reg = INVALIDr;
   2388     stat_field = Q_COUNTf;
   2389 
   2390     /* Get the mem attributes(Max idx) from the first child,
   2391      * which could be used for other instances.
   2392      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2393      */
   2394     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2395     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2396 
   2397     /* Threshold info count and Resource allocation */
   2398     granularity = 1;
   2399     total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count;
   2400     thd_mem = MMU_THDM_DB_QUEUE_CONFIGm;
   2401     thd_field = BST_THRESHOLD_PROFILEf;
   2402     for (i = 0; i < NUM_PIPE(unit); i++) {
   2403         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2404                                   INVALIDr, thd_field, granularity, i);
   2405     }
   2406     prof_reg = MMU_THDM_DB_QUEUE_MC_BST_THRESHOLD_PROFILEr;
   2407     prof_field = BST_STATf;
   2408     for (i = 0; i < NUM_XPE(unit); i++) {
   2409         _BCM_BST_PROFILE_INFO_N(pres, INVALIDm, 
   2410             SOC_REG_UNIQUE_ACC(unit, prof_reg)[i], prof_field, i);
   2411     }
   2412     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst mcast");
   2413     /* Stat info count and Resource allocation */
   2414     total_stat_count = total_thd_count;
   2415     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2416     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst mcast");
   2417     pres->index_min = 0;
   2418     pres->index_max = total_stat_count - 1;
   2419 
   2420     /* bcmBstStatIdEgrPortPoolSharedMcast */
   2421     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedMcast);
   2422     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2423     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2424                                      _BCM_BST_CMN_RES_F_PIPED |
   2425                                      _BCM_BST_CMN_RES_F_RES_EGR |
   2426                                      _BCM_BST_CMN_RES_F_PORTED);
   2427     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   2428     pres->num_instance = NUM_XPE(unit);
   2429     stat_mem = MMU_THDM_DB_PORTSP_BSTm;
   2430     stat_reg = INVALIDr;
   2431     stat_field = P_COUNTf;
   2432 
   2433     /* Get the mem attributes(Max idx) from the first child,
   2434      * which could be used for other instances.
   2435      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2436      */
   2437     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2438     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2439 
   2440     /* Threshold info count and Resource allocation */
   2441     granularity = 1;
   2442     total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count;
   2443     thd_reg = MMU_THDM_DB_PORTSP_THRESHOLD_PROFILE_SELr;
   2444     thd_field = BST_THRESHOLD_PROFILEf;
   2445     for (i = 0; i < 8; i++) {
   2446         _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm, 
   2447             SOC_REG_UNIQUE_ACC(unit, thd_reg)[i/2], thd_field, granularity, i);
   2448     }
   2449 
   2450     prof_reg = MMU_THDM_DB_PORTSP_BST_THRESHOLDr;
   2451     prof_field = BST_STATf;
   2452     for (i = 0; i < NUM_XPE(unit); i++) {
   2453         _BCM_BST_PROFILE_INFO_N(pres, INVALIDm, 
   2454             SOC_REG_UNIQUE_ACC(unit, prof_reg)[i], prof_field, i);
   2455     }
   2456     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count,
   2457                                      "bst egr port pool shared mcast");
   2458     /* Stat info count and Resource allocation */
   2459     total_stat_count = total_thd_count;
   2460     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2461     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count,
   2462                                 "bst egr port pool shared mcast");
   2463     pres->index_min = 0;
   2464     pres->index_max = total_stat_count - 1;
   2465 
   2466     /* bcmBstStatIdUcast */
   2467     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUcast);
   2468     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2469     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2470                                      _BCM_BST_CMN_RES_F_PIPED |
   2471                                      _BCM_BST_CMN_RES_F_RES_EGR);
   2472     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   2473     pres->num_instance = NUM_XPE(unit);
   2474     stat_mem = MMU_THDU_BST_QUEUEm;
   2475     stat_reg = INVALIDr;
   2476     stat_field = Q_COUNTf;
   2477 
   2478     /* Get the mem attributes(Max idx) from the first child,
   2479      * which could be used for other instances.
   2480      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2481      */
   2482     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2483     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2484 
   2485     /* Threshold info count and Resource allocation */
   2486     granularity = 8; /* UC Queue Thd is 8 cell granularity */
   2487     total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count;
   2488     thd_mem = MMU_THDU_CONFIG_QUEUEm;
   2489     thd_field = Q_WM_MAX_THRESHOLDf;
   2490     for (i = 0; i < NUM_PIPE(unit); i++) {
   2491         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2492                                   INVALIDr, thd_field, granularity, i);
   2493     }
   2494     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QUEUE_BST_THRESHOLDr, BST_STATf);
   2495     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst ucast");
   2496     /* Stat info count and Resource allocation */
   2497     total_stat_count = total_thd_count;
   2498     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2499     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst ucast");
   2500     pres->index_min = 0;
   2501     pres->index_max = total_stat_count - 1;
   2502 
   2503     /* bcmBstStatIdEgrPortPoolSharedUcast */
   2504     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedUcast);
   2505     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2506     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2507                                      _BCM_BST_CMN_RES_F_PIPED |
   2508                                      _BCM_BST_CMN_RES_F_RES_EGR);
   2509     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   2510     pres->num_instance = NUM_XPE(unit);
   2511     stat_mem = MMU_THDU_BST_PORTm;
   2512     stat_reg = INVALIDr;
   2513     stat_field = Q_COUNTf;
   2514 
   2515     /* Get the mem attributes(Max idx) from the first child,
   2516      * which could be used for other instances.
   2517      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2518      */
   2519     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0);
   2520     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2521 
   2522     /* Threshold info count and Resource allocation */
   2523     granularity = 8; /* UC Port Shared Thd is 8 cell granularity */
   2524     total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count;
   2525     thd_mem = MMU_THDU_CONFIG_PORTm;
   2526     thd_field = WM_MAX_THRESHOLDf;
   2527     for (i = 0; i < NUM_PIPE(unit); i++) {
   2528         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2529                                   INVALIDr, thd_field, granularity, i);
   2530     }
   2531     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_PORT_BST_THRESHOLDr, BST_STATf);
   2532     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count,
   2533                                      "bst egr port pool shared ucast");
   2534     /* Stat info count and Resource allocation */
   2535     total_stat_count = total_thd_count;
   2536     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2537     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count,
   2538                                 "bst egr port pool shared ucast");
   2539     pres->index_min = 0;
   2540     pres->index_max = total_stat_count - 1;
   2541 
   2542     /* bcmBstStatIdRQEQueue */
   2543     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEQueue);
   2544     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2545     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   2546     pres->num_instance = NUM_XPE(unit);
   2547     idx_count = 11;
   2548     pres->threshold_adj = -1;
   2549     stat_mem = INVALIDm;
   2550     stat_reg = MMU_THDR_DB_BST_STAT_PRIQr;
   2551     stat_field = BST_STATf;
   2552 
   2553     /* Threshold info count and Resource allocation */
   2554     granularity = 1;
   2555     total_thd_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */
   2556     thd_reg = MMU_THDR_DB_BST_THRESHOLD_PRIQr;
   2557     thd_field = BST_THRf;
   2558     for (i = 0; i < NUM_XPE(unit); i++) {
   2559         _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm,
   2560             SOC_REG_UNIQUE_ACC(unit, thd_reg)[i], thd_field, granularity, i);
   2561     }
   2562     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst RQE queue");
   2563     /* Stat info count and Resource allocation */
   2564     total_stat_count = total_thd_count; /* No per pipe copy */
   2565     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2566     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst RQE queue");
   2567     pres->index_min = 0;
   2568     pres->index_max = total_stat_count - 1;
   2569 
   2570     /* bcmBstStatIdRQEPool */
   2571     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEPool);
   2572     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2573     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   2574     pres->num_instance = NUM_XPE(unit);
   2575     idx_count = 4;
   2576     pres->threshold_adj = -1;
   2577     stat_mem = INVALIDm;
   2578     stat_reg = MMU_THDR_DB_BST_STAT_SPr;
   2579     stat_field = BST_STATf;
   2580 
   2581     /* Threshold info count and Resource allocation */
   2582     granularity = 1;
   2583     total_thd_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */
   2584     thd_reg = MMU_THDR_DB_BST_THRESHOLD_SPr;
   2585     thd_field = BST_THRf;
   2586     for (i = 0; i < NUM_XPE(unit); i++) {
   2587         _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm,
   2588             SOC_REG_UNIQUE_ACC(unit, thd_reg)[i], thd_field, granularity, i);
   2589     }
   2590     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst RQE pool");
   2591     /* Stat info count and Resource allocation */
   2592     total_stat_count = total_thd_count; /* No per pipe copy */
   2593     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2594     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst RQE pool");
   2595     pres->index_min = 0;
   2596     pres->index_max = total_stat_count - 1;
   2597 
   2598     /* bcmBstStatIdUCQueueGroup */
   2599     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUCQueueGroup);
   2600     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   2601     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   2602                                      _BCM_BST_CMN_RES_F_PIPED |
   2603                                      _BCM_BST_CMN_RES_F_RES_EGR |
   2604                                      _BCM_BST_CMN_RES_F_PORTED);
   2605     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   2606     pres->num_instance = NUM_XPE(unit);
   2607     stat_mem = MMU_THDU_BST_QGROUPm;
   2608     stat_reg = INVALIDr;
   2609     stat_field = Q_COUNTf;
   2610 
   2611     thd_mem = MMU_THDU_CONFIG_QGROUPm;
   2612     thd_field = Q_WM_MAX_THRESHOLDf;
   2613     /* Get the mem attributes(Max idx) from the first child,
   2614      * which could be used for other instances.
   2615      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2616      */
   2617     child_mem = SOC_MEM_UNIQUE_ACC_PIPE(unit, thd_mem, 0);
   2618     idx_count = soc_mem_index_max(unit, child_mem) + 1;
   2619 
   2620     /* Threshold info count and Resource allocation */
   2621     granularity = 8; /* UC queue group Thd is 8 cell granularity */
   2622     total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count;
   2623     for (i = 0; i < NUM_PIPE(unit); i++) {
   2624         _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i],
   2625                                   INVALIDr, thd_field, granularity, i);
   2626     }
   2627     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QGROUP_BST_THRESHOLDr,
   2628                           BST_STATf);
   2629     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count,
   2630                                      "bst unicast queue group");
   2631     /* Stat info count and Resource allocation */
   2632     total_stat_count = total_thd_count;
   2633     _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field);
   2634     _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count,
   2635                                 "bst unicast queue group");
   2636     pres->index_min = 0;
   2637     pres->index_max = total_stat_count - 1;
   2638 
   2639     /* EGRESS - Resources end */
   2640 
   2641     return BCM_E_NONE;
   2642 }
   2643 STATIC int
   2644 _bst_th_sbusdma_desc_setup(int unit)
   2645 {
   2646     _bcm_bst_cmn_unit_info_t *bst_info;
   2647     _bcm_bst_resource_info_t *resInfo;
   2648     _bcm_bst_tbl_ctrl_t *tbl_ctrl;
   2649     int blk, bid, pipe, mi, pipe_factor;
   2650     uint8 acc_type;
   2651     soc_mem_t mem, base_mem;
   2652     soc_reg_t reg;
   2653     uint32 size;
   2654     uint8 *buff = NULL;
   2655     _bcm_bst_tbl_desc_t *desc = NULL;
   2656     int stats_per_inst = 0;
   2657     int idx_count = 0;
   2658     int xpe = 0;
   2659     int stat_idx = 0;
   2660     int inst = 0;
   2661 
   2662     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2663         return BCM_E_INIT;
   2664     }
   2665     buff = bst_info->bst_tbl_buf;
   2666     bst_tbl_ctrl[unit] = sal_alloc(bcmBstStatIdMaxCount *
   2667                                       sizeof(_bcm_bst_tbl_ctrl_t *),
   2668                                       "bst_tbl_ctrl_p");
   2669     if (bst_tbl_ctrl[unit] == NULL) {
   2670         return BCM_E_MEMORY;
   2671     }
   2672 
   2673     bst_info->bst_tbl_desc = sal_alloc(bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t),
   2674         "bst_tbl_desc_p");
   2675     if (bst_info->bst_tbl_desc == NULL) {
   2676         return BCM_E_MEMORY;
   2677     }
   2678     sal_memset(bst_info->bst_tbl_desc, 0,  bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t));
   2679     desc = bst_info->bst_tbl_desc;
   2680 
   2681     mi = 0;
   2682     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   2683         resInfo = _BCM_BST_RESOURCE(unit, bid);
   2684         if (resInfo == NULL) {
   2685             return BCM_E_PARAM;
   2686         }
   2687 
   2688         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   2689             continue;
   2690         }
   2691 
   2692         tbl_ctrl = sal_alloc(sizeof(_bcm_bst_tbl_ctrl_t), "bst_tbl_ctrl");
   2693         if (tbl_ctrl == NULL) {
   2694             return BCM_E_MEMORY;
   2695         }
   2696         pipe_factor = 1;
   2697         if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   2698             pipe_factor = NUM_PIPE(unit)/2;
   2699         }
   2700         size = 0;
   2701         tbl_ctrl->tindex = bid;
   2702         tbl_ctrl->entries = resInfo->num_instance * pipe_factor;
   2703         tbl_ctrl->buff = buff;
   2704         tbl_ctrl->size = 0;
   2705         bst_tbl_ctrl[unit][bid] = tbl_ctrl;
   2706 
   2707         base_mem = resInfo->stat_mem[0];
   2708         reg = resInfo->stat_reg[0];
   2709         if (reg != INVALIDr) {
   2710             stats_per_inst = resInfo->num_stat_pp / resInfo->num_instance;
   2711             for (xpe = 0; xpe < resInfo->num_instance; xpe++) {
   2712                 if (stats_per_inst) {
   2713                     inst = xpe ;
   2714                     stat_idx = 0;
   2715                 } else {
   2716                     inst = REG_PORT_ANY;
   2717                     stat_idx = xpe;
   2718                     stats_per_inst = 1;
   2719                 }
   2720                 desc[mi].reg = reg;
   2721                 desc[mi].addr = soc_reg_addr_get(unit, reg, inst, stat_idx,
   2722                     SOC_REG_ADDR_OPTION_NONE, &blk,
   2723                     &acc_type);
   2724                 desc[mi].flags = 0;
   2725                 desc[mi].acc_type = acc_type;
   2726                 desc[mi].blk = blk;
   2727                 desc[mi].width = BYTES2WORDS(soc_reg_bytes(unit, reg));
   2728                 desc[mi].entries= stats_per_inst;
   2729                 desc[mi].shift = 8;
   2730                 size += desc[mi].entries * desc[mi].width * 4;
   2731                 tbl_ctrl->blk = desc[mi].blk;
   2732                 mi++;
   2733             }
   2734         } else if (base_mem != INVALIDm) {
   2735             idx_count = 0;
   2736 
   2737             mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0);
   2738             if (mem == INVALIDm) {
   2739                 return BCM_E_PARAM;
   2740             }
   2741             for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
   2742                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2743                     mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
   2744                     if (mem == INVALIDm) {
   2745                         continue;
   2746                     }
   2747                     idx_count = soc_mem_index_max(unit, mem) + 1;
   2748                     desc[mi].mem = mem;
   2749                     desc[mi].flags = SOC_SBUSDMA_CFG_COUNTER_IS_MEM | SOC_SBUSDMA_CFG_USE_FLAGS;
   2750                     desc[mi].blk = SOC_MEM_BLOCK_ANY(unit, mem);
   2751                     desc[mi].addr = soc_mem_addr_get(unit, mem,
   2752                                                    0, desc[mi].blk, 0, &acc_type);
   2753                     desc[mi].acc_type = acc_type;
   2754                     desc[mi].blk = SOC_BLOCK2SCH(unit, desc[mi].blk);
   2755                     desc[mi].width = soc_mem_entry_words(unit, mem);
   2756                     desc[mi].entries = idx_count;
   2757                     desc[mi].shift = 0;
   2758                     size += desc[mi].entries * desc[mi].width * 4;
   2759                     tbl_ctrl->blk = desc[mi].blk;
   2760                     mi++;
   2761                 }
   2762             }
   2763         }
   2764         buff += size;
   2765         tbl_ctrl->size += size;
   2766     }
   2767 
   2768     return BCM_E_NONE;
   2769 }
   2770 
   2771 STATIC int
   2772 _bcm_bst_th_sbusdma_desc_init(int unit)
   2773 {
   2774     _bcm_bst_cmn_unit_info_t *bst_info;
   2775     _bcm_bst_resource_info_t *resInfo;
   2776     int pipe, bid, mi;
   2777     soc_mem_t mem, base_mem;
   2778     soc_reg_t reg;
   2779     uint32 entries, width, size = 0;
   2780     int xpe = 0;
   2781     int rv = BCM_E_INIT;
   2782     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2783         return BCM_E_INIT;
   2784     }
   2785     mi = 0;
   2786     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   2787         resInfo = _BCM_BST_RESOURCE(unit, bid);
   2788         if (resInfo == NULL) {
   2789             return BCM_E_PARAM;
   2790         }
   2791 
   2792         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   2793             continue;
   2794         }
   2795 
   2796         base_mem = resInfo->stat_mem[0];
   2797         reg = resInfo->stat_reg[0];
   2798         if (reg != INVALIDr) {
   2799             for (xpe = 0; xpe < resInfo->num_instance; xpe++) {
   2800                 entries = resInfo->num_stat_pp / resInfo->num_instance;
   2801                 width = BYTES2WORDS(soc_reg_bytes(unit, reg));
   2802                 size += entries * width * 4;
   2803                 mi++;
   2804             }
   2805         } else if (base_mem != INVALIDm) {
   2806             int idx_count = 0;
   2807 
   2808             mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0);
   2809             if (mem == INVALIDm) {
   2810                 return BCM_E_PARAM;
   2811             }
   2812             for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
   2813                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2814                     mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
   2815                     if (mem == INVALIDm) {
   2816                         continue;
   2817                     }
   2818                     idx_count = soc_mem_index_max(unit, mem) + 1;
   2819                     entries = idx_count;
   2820                     width = soc_mem_entry_words(unit, mem);
   2821                     size += entries * width * 4;
   2822                     mi++;
   2823                 }
   2824             }
   2825         }
   2826     }
   2827     bst_info->bst_tbl_size = size;
   2828     bst_info->bst_tbl_num = mi;
   2829     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2830                 (BSL_META_U(unit,
   2831                             "Total bst tbls: %d, Total size: %d\n"),
   2832                  bcmBstStatIdMaxCount, size));
   2833     bst_tbl_handles[unit] = 0;
   2834     if (bst_info->bst_tbl_buf == NULL) {
   2835         bst_info->bst_tbl_buf = soc_cm_salloc(unit, size, "bst_tbl_buf");
   2836         if (bst_info->bst_tbl_buf == NULL) {
   2837             goto error;
   2838         }
   2839     }
   2840     sal_memset(bst_info->bst_tbl_buf, 0, size);
   2841     rv =_bst_th_sbusdma_desc_setup(unit);
   2842     if (rv != SOC_E_NONE) {
   2843         goto error;
   2844     }
   2845 
   2846     rv = soc_bst_sbusdma_desc_setup(unit);
   2847     if (rv != SOC_E_NONE) {
   2848         goto error;
   2849     }
   2850     return BCM_E_NONE;
   2851 error:
   2852     if (bst_info->bst_tbl_buf) {
   2853         soc_cm_sfree(unit, bst_info->bst_tbl_buf);
   2854         bst_info->bst_tbl_buf = NULL;
   2855     }
   2856     if (bst_info->bst_tbl_desc) {
   2857         sal_free(bst_info->bst_tbl_desc);
   2858         bst_info->bst_tbl_desc = NULL;
   2859     }
   2860     rv = soc_bst_sbusdma_desc_free(unit);
   2861     return rv;
   2862 }
   2863 
   2864 STATIC int
   2865 _bst_th_sw_sbusdma_desc_sync(int unit, int bid)
   2866 {
   2867     _bcm_bst_cmn_unit_info_t *bst_info;
   2868     _bcm_bst_resource_info_t *resInfo;
   2869     _bcm_bst_tbl_ctrl_t *tbl_ctrl;
   2870     int idx, idx_offset, xpe, xpe_offset, pipe, pipe_offset = 0;
   2871     void *pentry;
   2872     uint32 rval, temp_val;
   2873     uint8 *buff = NULL;
   2874     soc_mem_t mem, base_mem;
   2875     soc_reg_t reg;
   2876     uint32 width = 0;
   2877     bcm_gport_t gport = -1;
   2878     bcm_cos_t cosq = -1;
   2879     int port = -1;
   2880 
   2881     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2882         sal_mutex_give(bst_info->bst_reslock);
   2883         return BCM_E_INIT;
   2884     }
   2885     if (!bst_tbl_ctrl[unit][bid]) {
   2886         sal_mutex_give(bst_info->bst_reslock);
   2887         return BCM_E_INIT;
   2888     }
   2889     tbl_ctrl = bst_tbl_ctrl[unit][bid];
   2890     buff = tbl_ctrl->buff;
   2891     resInfo = _BCM_BST_RESOURCE(unit, bid);
   2892     if (resInfo == NULL) {
   2893         sal_mutex_give(bst_info->bst_reslock);
   2894         return BCM_E_PARAM;
   2895     }
   2896 
   2897     base_mem = resInfo->stat_mem[0];
   2898     reg = resInfo->stat_reg[0];
   2899     if (reg != INVALIDr) {
   2900         pipe_offset = 0;
   2901         for (idx = 0; idx < resInfo->num_stat_pp; idx++) {
   2902             rval = 0;
   2903             width = BYTES2WORDS(soc_reg_bytes(unit, reg));
   2904             idx_offset = idx + pipe_offset;
   2905             sal_memcpy(&rval, buff, width * 4);
   2906             temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field);
   2907             if (bst_info->track_mode) {
   2908                 /* BST tracking is in Peak mode.
   2909                  * Hence store the watermark value only.
   2910                  */
   2911                 if (resInfo->p_stat[idx_offset] < temp_val) {
   2912                     resInfo->p_stat[idx_offset] = temp_val;
   2913                 }
   2914             } else {
   2915                 resInfo->p_stat[idx_offset] = temp_val;
   2916             }
   2917             buff = buff + width * 4;
   2918 
   2919             /* Check if there exists threshold for a resource
   2920              * continue if we don't have one */
   2921             if (resInfo->p_threshold == NULL) {
   2922                 continue;
   2923             }
   2924 
   2925             /* coverity[copy_paste_error : FALSE] */
   2926             if (resInfo->p_threshold[idx_offset] &&
   2927                 (resInfo->p_stat[idx_offset] >=
   2928                  (resInfo->p_threshold[idx_offset] * resInfo->threshold_gran)
   2929                 )) {
   2930                 /* Generate SOC EVENT */
   2931                 if (bst_info->handlers.reverse_resolve_index) {
   2932                     /* reverse map the inedx to port/cos pair */
   2933                     bst_info->handlers.reverse_resolve_index(unit, bid,
   2934                                                              port, idx_offset,
   2935                                                              &gport, &cosq);
   2936                     soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
   2937                                        bid, gport, cosq);
   2938                 }
   2939             }
   2940 
   2941         }
   2942     } else if (base_mem != INVALIDm) {
   2943         int max_idx = 0;
   2944         int stats_per_pipe = 0; /* stats per pipe per mem-instance(xpe) */
   2945         int stats_per_inst = 0;
   2946 
   2947         /* Get the mem attributes(Max idx) from the first child,
   2948          * which could be used for other instances.
   2949          * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2950          */
   2951         mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0);
   2952 
   2953         if (mem == INVALIDm) {
   2954             sal_mutex_give(bst_info->bst_reslock);
   2955             return BCM_E_PARAM;
   2956         }
   2957         stats_per_inst = (resInfo->index_max + 1) / resInfo->num_instance;
   2958         stats_per_pipe = stats_per_inst / NUM_PIPE(unit);
   2959         max_idx = soc_mem_index_max(unit, mem);
   2960         for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
   2961             xpe_offset = 0;
   2962             gport = BCM_GPORT_INVALID;
   2963             cosq = -1;
   2964             if (xpe) {
   2965                 xpe_offset = stats_per_inst * xpe;
   2966             }
   2967             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2968                 pipe_offset = 0;
   2969                 if (pipe) {
   2970                     pipe_offset = stats_per_pipe * pipe;
   2971                 }
   2972                 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
   2973                 if (mem == INVALIDm) {
   2974                     continue;
   2975                 }
   2976 
   2977                 for (idx = 0; idx < max_idx; idx++) {
   2978                     if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
   2979                         /*
   2980                          * Reorder sw stat index
   2981                          * HW stat: index 0 - port 0 pool 0
   2982                          *          index 1 - port 1 pool 0
   2983                          *          index 2 - port 2 pool 0
   2984                          *          ...
   2985                          *          index n - port n%34 pool n/34
   2986                          * SW stat: index 0 - port 0 pool 0
   2987                          *          index 1 - port 0 pool 1
   2988                          *          index 2 - port 0 pool 2
   2989                          *          ...
   2990                          *          index n - port n/4 pool n%4
   2991                          */
   2992                         /* coverity[parameter_hidden: FALSE] */
   2993                         int port, pool;
   2994                         port = idx % _TH_MMU_PORTS_PER_PIPE;
   2995                         pool = idx / _TH_MMU_PORTS_PER_PIPE;
   2996                         idx_offset = port * _TH_MMU_NUM_POOL + pool +
   2997                                      pipe_offset + xpe_offset;
   2998                     } else {
   2999                         idx_offset = idx + pipe_offset + xpe_offset;
   3000                     }
   3001                     pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
   3002                                                           buff, idx);
   3003                     temp_val = soc_mem_field32_get(unit, mem, pentry,
   3004                                                    resInfo->stat_field);
   3005                     if (bst_info->track_mode) {
   3006                         /* BST tracking is in Peak mode.
   3007                          * Hence store the watermark value only.
   3008                          */
   3009                         if (resInfo->p_stat[idx_offset] < temp_val) {
   3010                             resInfo->p_stat[idx_offset] = temp_val;
   3011                         }
   3012                     } else {
   3013                         resInfo->p_stat[idx_offset] = temp_val;
   3014                     }
   3015 
   3016                     if (resInfo->p_threshold[idx_offset] &&
   3017                         (resInfo->p_stat[idx_offset] >=
   3018                          (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   3019                         /* Generate SOC EVENT */
   3020                         if (bst_info->handlers.reverse_resolve_index) {
   3021                             /* reverse map the inedx to port/cos pair */
   3022                             bst_info->handlers.reverse_resolve_index(unit, bid,
   3023                                                                      port, idx_offset,
   3024                                                                      &gport, &cosq);
   3025                             soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
   3026                                                bid, gport, cosq);
   3027 
   3028                         }
   3029                     }
   3030                 }
   3031                 buff += tbl_ctrl->size / tbl_ctrl->entries;
   3032             }
   3033         }
   3034     }
   3035 
   3036     return BCM_E_NONE;
   3037 }
   3038 
   3039 
   3040 STATIC int
   3041 _bcm_bst_th_sbusdma_desc_sync(int unit)
   3042 {
   3043     _bcm_bst_cmn_unit_info_t *bst_info;
   3044     _bcm_bst_resource_info_t *resInfo;
   3045     bcm_bst_stat_id_t bid;
   3046     int enable = 0;
   3047 
   3048     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3049         return BCM_E_INIT;
   3050     }
   3051 
   3052     if (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) {
   3053         return BCM_E_NONE;
   3054     }
   3055 
   3056     sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   3057 
   3058     if (bst_info->control_get) {
   3059         bst_info->control_get(unit, bcmSwitchBstEnable, &enable);
   3060     }
   3061 
   3062     if (enable && bst_info->control_set) {
   3063         bst_info->control_set(unit, bcmSwitchBstEnable, 0,
   3064                               _bcmBstThreadOperInternal);
   3065     }
   3066 
   3067     BCM_IF_ERROR_RETURN(soc_bst_hw_sbusdma_desc_sync(unit));
   3068 
   3069     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   3070         resInfo = _BCM_BST_RESOURCE(unit, bid);
   3071         if (resInfo == NULL) {
   3072             return BCM_E_PARAM;
   3073         }
   3074 
   3075         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   3076             continue;
   3077         }
   3078 
   3079         BCM_IF_ERROR_RETURN(_bst_th_sw_sbusdma_desc_sync(unit, bid));
   3080     }
   3081 
   3082     if (enable && bst_info->control_set) {
   3083         bst_info->control_set(unit, bcmSwitchBstEnable, enable,
   3084                               _bcmBstThreadOperInternal);
   3085     }
   3086 
   3087     sal_mutex_give(bst_info->bst_reslock);
   3088     return BCM_E_NONE;
   3089 }
   3090 
   3091 STATIC int
   3092 _bcm_bst_th_sbusdma_desc_deinit(int unit)
   3093 {
   3094     _bcm_bst_cmn_unit_info_t *bst_info;
   3095     int rv = BCM_E_INIT;
   3096 
   3097     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3098         return BCM_E_INIT;
   3099     }
   3100 
   3101     if (bst_info->bst_tbl_buf) {
   3102         soc_cm_sfree(unit, bst_info->bst_tbl_buf);
   3103         bst_info->bst_tbl_buf = NULL;
   3104     }
   3105     if (bst_info->bst_tbl_desc) {
   3106         sal_free(bst_info->bst_tbl_desc);
   3107         bst_info->bst_tbl_desc = NULL;
   3108     }
   3109 
   3110     rv = soc_bst_sbusdma_desc_free(unit);
   3111     if (rv != BCM_E_NONE) {
   3112         return rv;
   3113     }
   3114 
   3115     return BCM_E_NONE;
   3116 }
   3117 
   3118 #endif /* BCM_TOMAHAWK_SUPPORT */
   3119