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 (153804B)


      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
      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 
     25 #include <bcm/cosq.h>
     26 #include <bcm/switch.h>
     27 #include <bcm_int/bst.h>
     28 
     29 #if defined(BCM_TRIUMPH3_SUPPORT)
     30 #include <soc/triumph3.h>
     31 #endif
     32 
     33 #if defined(BCM_APACHE_SUPPORT)
     34 #include <soc/apache.h>
     35 #endif
     36 #if defined(BCM_MONTEREY_SUPPORT)
     37 #include <soc/monterey.h>
     38 #endif
     39 
     40 #if defined(BCM_TRIDENT2_SUPPORT)
     41 #include <soc/trident2.h>
     42 #endif
     43 
     44 _bcm_bst_cmn_unit_info_t *_bcm_bst_unit_info[BCM_MAX_NUM_UNITS];
     45 sbusdma_desc_handle_t bst_tbl_handles[BCM_MAX_NUM_UNITS] = {0};
     46 _bcm_bst_tbl_ctrl_t **bst_tbl_ctrl[BCM_MAX_NUM_UNITS] = {NULL};
     47 
     48 #define _BCM_AP_BST_MIN_THRESHOLD_CELLS 18
     49 
     50 #if defined(BCM_TRIUMPH3_SUPPORT)
     51 STATIC int _bcm_bst_hw_stat_sync(int unit, _bcm_bst_resource_info_t *resInfo, 
     52                                  bcm_bst_stat_id_t bid, int port, int index);
     53 #endif
     54 
     55 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
     56 STATIC int _bcm_bst_td2_sbusdma_desc_sync(int unit);
     57 STATIC int _bcm_bst_td2_sbusdma_desc_init(int unit);
     58 STATIC int _bcm_bst_td2_sbusdma_desc_deinit(int unit);
     59 #endif
     60 
     61 #if defined(BCM_TRIUMPH3_SUPPORT)
     62 STATIC int _bcm_bst_sw_stat_clear(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
     63                                   bcm_bst_stat_id_t bid);
     64 #endif
     65 STATIC int _bcm_bst_cmn_profile_set_hw(int unit, int pipe, int xpe, int hw_index, 
     66                                        bcm_bst_stat_id_t bid,
     67                                        bcm_cosq_bst_profile_t *profile, 
     68                                        uint32 *p_profile);
     69 STATIC int _bcm_bst_cmn_io_op(int unit, int op, int pipe, int hw_index,
     70                               bcm_bst_stat_id_t bid, soc_mem_t mem,
     71                               soc_reg_t reg, soc_field_t field, uint32 *resval);
     72 
     73 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
     74     defined(BCM_APACHE_SUPPORT)
     75 STATIC int
     76 _bcm_bst_check_intr_status(int unit, bcm_bst_stat_id_t bid);
     77 #endif
     78 
     79 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
     80     defined(BCM_APACHE_SUPPORT)
     81 STATIC int
     82 _bcm_bst_tr3_byte_to_cell(int unit, uint32 bytes)
     83 {
     84     return (bytes + (208 - 1))/208;
     85 }
     86 
     87 STATIC int
     88 _bcm_bst_tr3_cell_to_byte(int unit, uint32 cells)
     89 {
     90     return cells * 208;
     91 }
     92 #endif
     93 
     94 #if defined(BCM_TRIUMPH3_SUPPORT)
     95 STATIC int
     96 _bcm_tr3_bst_control_set(int unit, bcm_switch_control_t type, int arg,
     97                          _bcm_bst_thread_oper_t operation)
     98 {
     99     uint32 rval,fval=0,  i;
    100     _bcm_bst_cmn_unit_info_t *bst_info;
    101     uint32 sval[3] = {0};
    102     soc_field_t fld[3] = {BST_HW_SNAPSHOT_EN_THDOf,
    103                         BST_HW_SNAPSHOT_EN_THDIf,
    104                         BST_HW_SNAPSHOT_EN_CFAPf};
    105 
    106     bst_info = _BCM_UNIT_BST_INFO(unit);
    107 
    108     switch (type) {
    109     case bcmSwitchBstEnable:
    110 
    111         fval = arg; 
    112         BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
    113         soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 
    114                           BST_TRACK_EN_THDOf, fval);
    115         soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 
    116                           BST_TRACK_EN_THDIf, fval);
    117         soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 
    118                           BST_TRACK_EN_CFAPf, fval);
    119         BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval));
    120 
    121 
    122         BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
    123         soc_reg_field_set(unit, MISCCONFIGr, &rval, BST_TRACKING_MODEf, 1);
    124         BCM_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
    125 
    126         if (operation == _bcmBstThreadOperExternal) {
    127             if (fval) {
    128                 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit));
    129             } else {
    130                 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit));
    131             }
    132         } else {
    133             _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, fval ? TRUE : FALSE);
    134         }
    135         break;
    136     case bcmSwitchBstTrackingMode:
    137         BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
    138         soc_reg_field_set(unit, MISCCONFIGr, &rval, BST_TRACKING_MODEf, (arg ? 1 : 0));
    139         BCM_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
    140         bst_info->track_mode = arg ? 1 : 0;
    141         break;
    142 
    143     case bcmSwitchBstSnapshotEnable:
    144          for (i = _BCM_BST_SNAPSHOT_THDO; i < _BCM_BST_SNAPSHOT_COUNT; i++) {
    145             if (arg & (0x1 << i)) {
    146                 sval[i] = 1;
    147             } else {
    148                 sval[i] = 0;
    149             }
    150 
    151             BCM_IF_ERROR_RETURN(READ_BST_TRACKING_CONFIGr(unit, &rval));
    152             soc_reg_field_set(unit, BST_TRACKING_CONFIGr, &rval, fld[i], sval[i]);
    153             BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_CONFIGr(unit, rval));
    154         }
    155         bst_info->snapshot_mode = arg;
    156 
    157        break;
    158     default:
    159         return BCM_E_UNAVAIL;
    160     }
    161 
    162     return BCM_E_NONE;
    163 }
    164 
    165 STATIC int
    166 _bcm_tr3_bst_control_get(int unit, bcm_switch_control_t type, int *arg)
    167 {
    168     uint32 rval;
    169     _bcm_bst_cmn_unit_info_t *bst_info;
    170     bst_info = _BCM_UNIT_BST_INFO(unit);
    171 
    172 
    173     switch (type) {
    174     case bcmSwitchBstEnable:
    175         BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
    176         *arg = soc_reg_field_get(unit,BST_TRACKING_ENABLEr, rval, 
    177                                  BST_TRACK_EN_THDOf);
    178         break;
    179     case bcmSwitchBstTrackingMode:
    180         BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
    181         *arg = soc_reg_field_get(unit, MISCCONFIGr, rval, BST_TRACKING_MODEf);        
    182         break;
    183 
    184     case bcmSwitchBstSnapshotEnable:
    185         *arg = bst_info->snapshot_mode; 
    186         break;
    187 
    188     default:
    189         return BCM_E_UNAVAIL;
    190     }
    191     return BCM_E_NONE;
    192 }
    193 
    194 STATIC int
    195 _bcm_bst_triumph3_intr_to_resources(int unit, uint32 *flags)
    196 {
    197     uint32 flags_tr = 0, fval, rval;
    198     uint64 rval64;
    199     int index = -1;
    200     bcm_bst_stat_id_t bid = bcmBstStatIdMaxCount;
    201     soc_field_t fld;
    202    
    203     fld = INVALIDf;
    204 
    205     BCM_IF_ERROR_RETURN(READ_THDO_BST_STATr(unit, &rval64));
    206     if ((fval = soc_reg64_field32_get(unit, THDO_BST_STATr, 
    207                               rval64, BST_STAT_TRIGGERED_TYPEf))) {
    208 
    209         if (fval & 0x1) {
    210             bid = bcmBstStatIdUcast;
    211             fld = UC_Q_BST_STAT_IDf;
    212         } else if (fval & 0x8) {
    213             bid = bcmBstStatIdEgrPool;
    214             fld = SP_MC_BST_STAT_IDf;
    215         }
    216         
    217         index = soc_reg64_field32_get(unit, THDO_BST_STATr, rval64, fld);
    218     }
    219 
    220     BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUSr(unit, &rval64));
    221 
    222     if (soc_reg64_field32_get(unit, THDI_BST_TRIGGER_STATUSr, 
    223                               rval64, TRIGGER_TYPEf)) {
    224 
    225         index = soc_reg64_field32_get(unit, THDI_BST_TRIGGER_STATUSr, 
    226                                       rval64, PG_SHARED_TRIGGER_IDf);
    227 
    228         fval = soc_reg64_field32_get(unit, THDI_BST_TRIGGER_STATUSr, rval64, 
    229                                         TRIGGER_TYPEf);
    230         if (fval & 0x1) {
    231             bid = bcmBstStatIdPriGroupShared;
    232         }
    233 
    234         if (fval & 0x2) {
    235             bid = bcmBstStatIdPriGroupHeadroom;
    236         }
    237 
    238         if (fval & 0x4) {
    239             bid = bcmBstStatIdPortPool;
    240         }
    241 
    242         if (fval & 0x8) {
    243             bid = bcmBstStatIdIngPool;
    244         }
    245     }
    246 
    247     if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) {
    248         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64));
    249         (void)soc_reg64_field32_get(unit, MEM_FAIL_INT_EN_64r,
    250                                     rval64, BST_CFAP_INT_ENf);
    251         index = 0;
    252         bid = bcmBstStatIdDevice;
    253     } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) {
    254         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
    255         (void)soc_reg_field_get(unit, MEM_FAIL_INT_ENr, rval,
    256                               BST_CFAP_INT_ENf);
    257         index = 0;
    258         bid = bcmBstStatIdDevice;
    259     }
    260 
    261     if (bid == bcmBstStatIdMaxCount) {
    262         return BCM_E_NONE;
    263     }
    264 
    265     BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
    266     if (soc_reg_field_get(unit, MISCCONFIGr, rval, BST_TRACKING_MODEf)) {
    267         _bcm_bst_sync_hw_trigger(unit, bid, -1, index);
    268     } else {
    269         _bcm_bst_sync_hw_snapshot(unit, bid, -1, index);
    270     }
    271 
    272     *flags = flags_tr;
    273 
    274     return BCM_E_NONE;
    275 }
    276 
    277 STATIC int
    278 soc_tr3_set_hw_intr_cb(int unit)
    279 {
    280     BCM_IF_ERROR_RETURN(soc_tr3_set_bst_callback(unit, &_bcm_bst_hw_event_cb));
    281     return SOC_E_NONE;
    282 }
    283 
    284 STATIC int 
    285 _bcm_bst_triumph3_init(int unit)
    286 {
    287     _bcm_bst_cmn_unit_info_t *bst_info;
    288     _bcm_bst_resource_info_t *pres;
    289     
    290     bst_info = _BCM_UNIT_BST_INFO(unit);
    291 
    292     bst_info->max_bytes = 0x500000;
    293     bst_info->to_cell = _bcm_bst_tr3_byte_to_cell;
    294     bst_info->to_byte = _bcm_bst_tr3_cell_to_byte;
    295     bst_info->control_set = _bcm_tr3_bst_control_set;
    296     bst_info->control_get = _bcm_tr3_bst_control_get;
    297     bst_info->intr_to_resources = _bcm_bst_triumph3_intr_to_resources;
    298     bst_info->hw_trigger_set = NULL;
    299     bst_info->hw_trigger_reset = NULL;
    300     bst_info->hw_intr_cb = soc_tr3_set_hw_intr_cb;
    301     bst_info->intr_enable_set = _bst_intr_enable_set;
    302     bst_info->hw_stat_snapshot = _bcm_bst_sync_hw_snapshot;
    303     bst_info->hw_stat_clear = _bcm_bst_hw_stat_clear;
    304     bst_info->pre_sync = NULL;
    305     bst_info->post_sync = NULL;
    306 
    307     /* bcmBstStatIdDevice */
    308     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdDevice);
    309     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    310     pres->index_min = pres->index_max = 0;
    311     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_DEV);
    312     _BCM_BST_STAT_INFO(pres, INVALIDm, CFAPBSTSTATr, BST_STATf);
    313     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAPBSTTHRSr, BST_THRESHOLDf, 1);
    314     _BCM_BST_RESOURCE_STAT_INIT(pres, 1, "bst cfap");
    315     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 1, "bst cfap");
    316 
    317     /* bcmBstStatIdEgrPool */
    318     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPool);
    319     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    320     pres->index_min = 0;
    321     pres->index_max = 3;
    322     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
    323     _BCM_BST_STAT_INFO(pres, INVALIDm, OP_MCUC_SP_BST_STATr, BST_STATf);
    324     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
    325                             OP_MCUC_SP_BST_THRESHOLDr, BST_THRESHOLDf, 1);
    326     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egrpool");
    327     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egrpool");
    328 
    329     /* bcmBstStatIdEgrMCastPool */
    330     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrMCastPool);
    331     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    332     pres->index_min = 0;
    333     pres->index_max = 3;
    334     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
    335     _BCM_BST_STAT_INFO(pres, INVALIDm, OP_MC_SP_BST_STATr, BST_STATf);
    336     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
    337                             OP_MC_SP_BST_THRESHOLDr, BST_THRESHOLDf, 1);
    338     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egr mcpool");
    339      _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egr mcpool");
    340 
    341     /* bcmBstStatIdIngPool */
    342     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdIngPool);
    343     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    344     pres->index_min = 0;
    345     pres->index_max = 3;
    346     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING);
    347     _BCM_BST_STAT_INFO(pres, INVALIDm, THDI_BST_SHADOW_SPr, BST_STATf);
    348     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
    349                             THDI_BST_PROFILE_THRESH_SPr, BST_THRESHOLDf, 1);
    350     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst ing pool");
    351     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst ing pool");
    352 
    353     /* bcmBstStatIdPortPool */
    354     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPortPool);
    355     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    356     pres->index_min = 0;
    357     pres->index_max = soc_mem_index_max(unit, THDI_PORT_SP_BSTm);
    358 
    359     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
    360                                      _BCM_BST_CMN_RES_F_RES_ING);
    361 
    362     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
    363 
    364     _BCM_BST_THRESHOLD_INFO(pres, THDI_PORT_SP_CONFIGm, 
    365                             INVALIDr, BST_THRESHOLD_PROFILEf, 1);
    366 
    367     _BCM_BST_PROFILE_INFO(pres, INVALIDm, 
    368                   THDI_BST_PROFILE_THRESH_PORT_SHAREDr, BST_THRESHOLDf);
    369 
    370     _BCM_BST_STAT_INFO(pres, THDI_PORT_SP_BSTm, INVALIDr, BST_STATf);
    371 
    372     _BCM_BST_RESOURCE_STAT_INIT(pres, 
    373                soc_mem_index_count(unit, THDI_PORT_SP_BSTm), "bst port pool");
    374     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres,
    375                soc_mem_index_count(unit, THDI_PORT_SP_BSTm), "bst port pool");
    376 
    377     /* bcmBstStatIdPriGroupShared */
    378     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupShared);
    379     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    380     pres->index_min = 0;
    381     pres->index_max = (63 * 8) - 1;
    382     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
    383                                      _BCM_BST_CMN_RES_F_RES_ING);
    384     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
    385     _BCM_BST_THRESHOLD_INFO(pres, THDI_PORT_PG_CONFIGm, INVALIDr, 
    386                           PG_BST_PROFILE_SHAREDf, 1);
    387     _BCM_BST_PROFILE_INFO(pres, INVALIDm, 
    388                             THDI_BST_PROFILE_THRESH_PG_SHAREDr, 
    389                             BST_THRESHOLD_SHAREDf);
    390     _BCM_BST_STAT_INFO(pres, THDI_PORT_PG_BSTm, INVALIDr, PG_BST_STAT_SHAREDf);
    391     _BCM_BST_RESOURCE_STAT_INIT(pres, 63 * 8, "bst pg");
    392     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 63 * 8, "bst pg");
    393 
    394     /* bcmBstStatIdPriGroupHeadroom */
    395     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupHeadroom);
    396     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    397     pres->index_min = 0;
    398     pres->index_max = (63 * 8) - 1;
    399     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 
    400                                      _BCM_BST_CMN_RES_F_RES_ING);
    401     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
    402     _BCM_BST_THRESHOLD_INFO(pres, THDI_PORT_PG_CONFIGm, INVALIDr,
    403                             PG_BST_PROFILE_HDRMf, 1);
    404     _BCM_BST_PROFILE_INFO(pres, INVALIDm, 
    405                             THDI_BST_PROFILE_THRESH_PG_HDRMr, 
    406                             BST_THRESHOLD_HDRMf);
    407     _BCM_BST_STAT_INFO(pres, THDI_PORT_PG_BSTm, INVALIDr, BST_STAT_HDRMf);
    408     _BCM_BST_RESOURCE_STAT_INIT(pres, 63 * 8, "bst pg hdrm");
    409     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 63 * 8, "bst pg");
    410 
    411     /* bcmBstStatIdMcast */
    412     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdMcast);
    413     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    414     pres->index_min = 0;
    415     pres->index_max = 47;
    416     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
    417                                      _BCM_BST_CMN_RES_F_RES_EGR);
    418     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_CMIC(unit));
    419     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
    420                           OP_CPU_QUEUE_BST_THRESHOLDr, BST_PROFILEf, 1);
    421     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_CPU_QUEUE_BST_THRESHOLD_PROFILEr, 
    422                              THRESHOLDf);
    423     _BCM_BST_STAT_INFO(pres, INVALIDm, OP_CPU_QUEUE_BST_STATr, BST_STATf);
    424     _BCM_BST_RESOURCE_STAT_INIT(pres, 48, "bst mcast");
    425     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 48, "bst mcast");
    426 
    427     /* bcmBstStatIdUcast */
    428     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUcast);
    429     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
    430     pres->index_min = 0;
    431     pres->index_max = soc_mem_index_max(unit, MMU_THDO_BST_QUEUEm);
    432     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
    433                                      _BCM_BST_CMN_RES_F_RES_EGR);
    434     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
    435     _BCM_BST_THRESHOLD_INFO(pres, MMU_THDO_CONFIG_QUEUEm, INVALIDr, 
    436                           BST_THRESHOLD_PROFILEf, 8);
    437     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QUEUE_BST_THRESHOLDr, 
    438                              BST_THRESHOLDf);
    439     _BCM_BST_STAT_INFO(pres, MMU_THDO_BST_QUEUEm, INVALIDr, BST_STATf);
    440     _BCM_BST_RESOURCE_STAT_INIT(pres, 
    441                  soc_mem_index_count(unit, MMU_THDO_BST_QUEUEm), "bst ucast");
    442     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres,
    443                  soc_mem_index_count(unit, MMU_THDO_BST_QUEUEm), "bst ucast");
    444 
    445     return BCM_E_NONE;
    446 }
    447 
    448 #endif /* BCM_TRIUMPH3_SUPPORT */
    449 
    450 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
    451 
    452 STATIC int _bcm_td2_bst_sync_thread_restore(int unit)
    453 {
    454     _bcm_bst_cmn_unit_info_t *bst_info;
    455     int enable;
    456 
    457     bst_info = _BCM_UNIT_BST_INFO(unit);
    458     if (bst_info->control_get) {
    459         bst_info->control_get(unit, bcmSwitchBstEnable, &enable);
    460         if (enable) {
    461             return TRUE;
    462         }
    463     }
    464 
    465     return FALSE;
    466 }
    467 
    468 STATIC int _bcm_td2_bst_info_restore(int unit)
    469 {
    470     _bcm_bst_cmn_unit_info_t *bst_info;
    471     uint32 rval;
    472 
    473     bst_info = _BCM_UNIT_BST_INFO(unit);
    474 
    475     BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
    476     bst_info->track_mode = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval,
    477                              BST_TRACK_EN_THDOf);
    478 
    479     BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval));
    480     bst_info->snapshot_mode = soc_reg_field_get(unit, BST_HW_SNAPSHOT_ENr, rval,
    481                              BST_HW_SNAPSHOT_EN_THDOf);
    482 
    483     return BCM_E_NONE;
    484 }
    485 
    486 STATIC int _bcm_td2_bst_resource_threshold_restore(int unit)
    487 {
    488     _bcm_bst_resource_info_t *resInfo;
    489     int hw_index, pipe, ipipe, index_max = 0;
    490     bcm_bst_stat_id_t bid;
    491     uint32 cells;
    492     uint32 profile_index;
    493     int pipe_offset;
    494     int pipe_factor = 1;
    495 
    496     pipe_factor = NUM_PIPE(unit);
    497 
    498     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
    499         resInfo = _BCM_BST_RESOURCE(unit, bid);
    500 
    501         if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
    502             index_max = resInfo->index_max / NUM_PIPE(unit);
    503         }
    504         else {
    505             index_max = resInfo->index_max;
    506         }
    507 
    508         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    509             pipe_offset = 0;
    510             if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
    511                 if (pipe) {
    512                     pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor);
    513                 }
    514                 ipipe = pipe;
    515             } else {
    516                 if (pipe) {
    517                     continue;
    518                 }
    519                 ipipe = pipe;
    520             }
    521 
    522             for (hw_index = resInfo->index_min; hw_index < index_max; hw_index++) {
    523                 if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
    524                     SOC_IF_ERROR_RETURN(
    525                        _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD,
    526                                           ipipe, hw_index, bid,
    527                                           resInfo->threshold_mem[ipipe],
    528                                           resInfo->threshold_reg[ipipe],
    529                                           resInfo->threshold_field,
    530                                           &profile_index));
    531 
    532                     SOC_IF_ERROR_RETURN(
    533                        _bcm_bst_cmn_io_op(unit, BST_OP_GET,
    534                                           ipipe, profile_index, bid,
    535                                           resInfo->profile_mem,
    536                                           resInfo->profile_reg[0],
    537                                           resInfo->profile_field,
    538                                           &cells));
    539                 } else {
    540                     SOC_IF_ERROR_RETURN(
    541                        _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD,
    542                                           ipipe, hw_index, bid,
    543                                           resInfo->threshold_mem[ipipe],
    544                                           resInfo->threshold_reg[ipipe],
    545                                           resInfo->threshold_field,
    546                                           &cells));
    547                 }
    548 
    549                 resInfo->p_threshold[hw_index + pipe_offset] = cells;
    550             }
    551         }
    552     }
    553 
    554     return BCM_E_NONE;
    555 }
    556 
    557 STATIC int
    558 _bcm_td2_bst_threshold_maximum_set(int unit, _bcm_bst_cmn_unit_info_t *bst_info,
    559                                                  uint32 enable)
    560 {
    561     int hw_index, pipe, cells;
    562     uint32 bid_index, index_max;
    563     _bcm_bst_resource_info_t *resInfo;
    564     bcm_cosq_bst_profile_t profile;
    565     int pipe_offset;
    566     int pipe_factor = 1;
    567     uint32 threshold_max = BST_THRESHOLD_MAX_HIGH;
    568 
    569     /* Need to set bst threshold to max high when bst_trac_en is disabled. 
    570        Only add bst id if relative bst id is set.
    571        Registers listed below are exposed to add with related BST ID in the future
    572        MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILE 
    573        MMU_THDM_DB_PORTSP_BST_THRESHOLD 
    574        MMU_THDM_MCQE_CPUQUEUE_BST_THRESHOLD_PROFILE 
    575        MMU_THDM_MCQE_POOL_MC_BST_THRESHOLD 
    576        MMU_THDM_MCQE_QUEUE_MC_BST_THRESHOLD_PROFILE 
    577        MMU_THDM_MCQE_PORTSP_BST_THRESHOLD
    578        */    
    579     bcm_bst_stat_id_t bst_threshold_id[] = {bcmBstStatIdEgrPool, 
    580                                             bcmBstStatIdEgrMCastPool, 
    581                                             bcmBstStatIdMcast};   
    582 
    583     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) {
    584         for (bid_index = 0;
    585              bid_index < (sizeof(bst_threshold_id)/sizeof(bcm_bst_stat_id_t));
    586              bid_index++) {
    587             sal_memset(&profile, 0, sizeof(bcm_cosq_bst_profile_t));                
    588             resInfo = _BCM_BST_RESOURCE(unit, bst_threshold_id[bid_index]);
    589             if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
    590                 continue;
    591             }
    592 
    593             if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
    594                 index_max = resInfo->index_max / NUM_PIPE(unit) - 1;
    595             }
    596             else {
    597                 index_max = resInfo->index_max;
    598             }
    599 
    600             for (hw_index = resInfo->index_min; hw_index <= index_max ; hw_index++) {
    601                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    602                     pipe_offset = 0;
    603                     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
    604                         pipe_factor = NUM_PIPE(unit);
    605                         if (pipe) {
    606                             pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor);
    607                         }
    608                     } 
    609 
    610                     if(resInfo->p_threshold[hw_index + pipe_offset] != threshold_max) {
    611                         if(enable == 1) {
    612                             cells = resInfo->p_threshold[hw_index + pipe_offset];
    613                             if(cells != 0) {
    614                                 /* Taking granularity into count */
    615                                 if(resInfo->threshold_gran != 0) {
    616                                     cells = cells * resInfo->threshold_gran - resInfo->threshold_adj;
    617                                 } else {
    618                                     cells -= resInfo->threshold_adj;
    619                                 }
    620 
    621                                 profile.byte = bst_info->to_byte(unit, cells);
    622                                 
    623                                 SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw
    624                                     (unit, pipe, BCM_BST_DUP_XPE, hw_index,
    625                                         bst_threshold_id[bid_index], &profile, NULL));
    626                             }
    627                         } else {
    628                             profile.byte = BST_THRESHOLD_INVALID;
    629                             SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw
    630                                 (unit, pipe, BCM_BST_DUP_XPE, hw_index,
    631                                     bst_threshold_id[bid_index], &profile, NULL));
    632 
    633                         } 
    634                     }
    635                 }
    636             }
    637         }
    638     }
    639 
    640     return BCM_E_NONE;
    641 }
    642 
    643 STATIC int
    644 _bcm_td2_bst_control_set(int unit, bcm_switch_control_t type, int arg,
    645                          _bcm_bst_thread_oper_t operation)
    646 {
    647     uint32 i, rval, fval;
    648     uint32 sval[3] = {0};
    649     _bcm_bst_cmn_unit_info_t *bst_info;
    650     soc_field_t fld[6] = {BST_HW_SNAPSHOT_EN_THDOf, 
    651                         ACTION_EN_THDOf,
    652                         BST_HW_SNAPSHOT_EN_THDIf, 
    653                         ACTION_EN_THDIf,
    654                         BST_HW_SNAPSHOT_EN_CFAPf, 
    655                         ACTION_CFAPf};  
    656 
    657     bst_info = _BCM_UNIT_BST_INFO(unit);
    658 
    659     switch (type) {
    660     case bcmSwitchBstEnable:
    661 
    662         BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
    663 
    664         fval = !!arg;
    665         soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 
    666                           BST_TRACK_EN_THDOf, fval);
    667         soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 
    668                           BST_TRACK_EN_THDIf, fval);
    669         soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 
    670                           BST_TRACK_EN_CFAPf, fval);
    671 
    672         BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval));
    673 
    674         if (operation == _bcmBstThreadOperExternal) {          
    675             BCM_IF_ERROR_RETURN(_bcm_td2_bst_threshold_maximum_set(unit, bst_info, fval));  
    676             
    677             if (fval) {
    678                 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit));
    679             } else {
    680                 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit));
    681             }
    682         } else {
    683             _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, fval ? TRUE : FALSE);
    684         }
    685         
    686         break;
    687     case bcmSwitchBstTrackingMode:
    688         BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
    689         soc_reg_field_set(unit, MISCCONFIGr, &rval, BST_TRACKING_MODEf, arg);
    690         BCM_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
    691         bst_info->track_mode = arg ? 1 : 0;
    692         break;
    693     case bcmSwitchBstSnapshotEnable:
    694         for (i = _BCM_BST_SNAPSHOT_THDO; i < _BCM_BST_SNAPSHOT_COUNT; i++) {
    695             if (arg & (0x1 << i)) {
    696                 sval[i] = 1;
    697             } else {
    698                 sval[i] = 0;
    699             }
    700 
    701             BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval));
    702             soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, fld[i*2], sval[i]);
    703             BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval));
    704 
    705             BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval));
    706             soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, fld[i*2+1], sval[i]);
    707             BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval));            
    708         }
    709         bst_info->snapshot_mode = arg;
    710 
    711         break;
    712     default:
    713         return BCM_E_UNAVAIL;
    714     }
    715     return BCM_E_NONE;
    716 }
    717 
    718 STATIC int
    719 _bcm_td2_bst_control_get(int unit, bcm_switch_control_t type, int *arg)
    720 {
    721     uint32 rval;
    722     _bcm_bst_cmn_unit_info_t *bst_info;
    723     bst_info = _BCM_UNIT_BST_INFO(unit);
    724 
    725     switch (type) {
    726     case bcmSwitchBstEnable:
    727         BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
    728         *arg = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, 
    729                                  BST_TRACK_EN_THDOf);
    730         break;
    731     case bcmSwitchBstTrackingMode:
    732         *arg = bst_info->track_mode;
    733         break;
    734     case bcmSwitchBstSnapshotEnable:
    735         *arg = bst_info->snapshot_mode;
    736         break;
    737     default:
    738         return BCM_E_UNAVAIL;
    739     }
    740     return BCM_E_NONE;
    741 }
    742 
    743 STATIC int
    744 _bcm_bst_td2_intr_to_resources(int unit, uint32 *flags)
    745 {
    746     uint32 flags_tr = 0;
    747     uint32 fval, fval_pipe[SOC_MAX_NUM_PIPES];
    748     uint32 rval, rval_dev, rval_pipe[SOC_MAX_NUM_PIPES], rval_status;
    749     uint32 rval_rqe;
    750     uint64 rval_uc, rval_db, rval_mcqe, rval64, rval64_zero;
    751     int index[_bcmResourceMaxCount][SOC_MAX_NUM_PIPES], res_ct = 0;
    752     bcm_bst_stat_id_t bid[_bcmResourceMaxCount] = {-1};
    753     int pipe = 0, pos = 0;
    754     int bid_mcast = 0;
    755     soc_field_t fld[SOC_MAX_NUM_PIPES];
    756     soc_reg_t reg[SOC_MAX_NUM_PIPES];
    757     _bcm_bst_cmn_unit_info_t *bst_info;
    758     bst_info = _BCM_UNIT_BST_INFO(unit);
    759 
    760     for (pipe = 0; pipe < NUM_PIPE(unit) ; pipe++) {
    761         fval_pipe[pipe] = 0;
    762         rval_pipe[pipe] = 0;
    763         fld[pipe] = INVALIDf;
    764         reg[pipe] = INVALIDr;
    765         for (pos = 0; pos < _bcmResourceMaxCount; pos++) {
    766             index[pos][pipe] = -1;
    767         }
    768     }
    769 
    770     if (bst_info->intr_enable_set) {
    771         bst_info->intr_enable_set(unit, 0);
    772     }
    773 
    774     if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) {
    775         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64));
    776     } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) {
    777         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval_status));
    778     }
    779 
    780     _bst_intr_status_reset(unit);
    781 
    782     BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
    783     BCM_IF_ERROR_RETURN(READ_THDU_BST_STATr(unit, &rval_uc));
    784     BCM_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_BST_STATr(unit, &rval_db));
    785     BCM_IF_ERROR_RETURN(READ_MMU_THDM_MCQE_DEVICE_BST_STATr(unit, &rval_mcqe));
    786     BCM_IF_ERROR_RETURN(READ_MMU_THDR_DB_BST_STATr(unit, &rval_rqe));
    787 
    788     /* bcmBstStatIdEgrPool */
    789     fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, 
    790                                  rval_db, BST_STAT_TRIGGERED_TYPEf);
    791     if (fval) {
    792         reg[0] = MMU_THDM_DB_DEVICE_BST_STATr;
    793         /* Check all triggered types. */
    794         for (pos = 0; pos < 5; pos++) {
    795             if (!(fval & (1U << pos))) {
    796                 continue;
    797             }
    798             switch (fval & (1U << pos)) {
    799                 case 0x1:
    800                     bid[res_ct] = bcmBstStatIdEgrPool;
    801                     fld[0] = MCUC_SP_BST_STAT_IDf;
    802                     break;
    803                 case 0x2:
    804                     bid[res_ct] = bcmBstStatIdEgrMCastPool;
    805                     fld[0] = MC_SP_BST_STAT_IDf;
    806                     break;
    807                 case 0x4:
    808                     bid[res_ct] = bcmBstStatIdMcast;
    809                     fld[0] = MC_Q_BST_STAT_IDf;
    810                     bid_mcast = 1;
    811                     break;
    812                 case 0x8:
    813                     if (!bid_mcast) {
    814                         bid[res_ct] = bcmBstStatIdMcast;
    815                         fld[0] = MC_CPU_Q_BST_STAT_IDf;
    816                     } else {
    817                         fld[0] = INVALIDf;
    818                     }
    819                     break;
    820                 case 0x10:
    821                     bid[res_ct] = bcmBstStatIdEgrPortPoolSharedMcast;
    822                     fld[0] = MC_PORTSP_BST_STAT_IDf;
    823                     break;
    824                 default:
    825                     fld[0] = INVALIDf;
    826             }
    827             if (fld[0] != INVALIDf) {
    828                 index[res_ct++][0] = soc_reg64_field32_get(unit, reg[0], rval_db, fld[0]);
    829             }
    830         }
    831         COMPILER_64_ZERO(rval64_zero);
    832         BCM_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_BST_STATr(unit, rval64_zero));
    833     }
    834     
    835 #if defined(BCM_APACHE_SUPPORT)
    836     if (SOC_IS_APACHE(unit)) {
    837         /* bcmBstStatIdDevice */
    838         BCM_IF_ERROR_RETURN(READ_CFAP_BST_THRSr(unit, &rval_dev));
    839         if (soc_reg_field_get(unit, CFAP_BST_THRSr, rval_dev, BST_THRESHOLDf)) {
    840             if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) {
    841                 if (soc_reg64_field32_get(unit, MEM_FAIL_INT_EN_64r,
    842                         rval64, BST_CFAP_INT_ENf)) {
    843                     index[res_ct][0] = 0;
    844                     bid[res_ct++] = bcmBstStatIdDevice;
    845                 }
    846             } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) {
    847                 /* CFAP : Device resource. 
    848                 * Check Intr Status reg if Stats > Thd.
    849                 */
    850                 reg[0] = MEM_FAIL_INT_STATr;
    851                 if (soc_reg_field_get(unit, reg[0], rval_status, BST_CFAP_INTf)) {
    852                     index[res_ct][0] = 0;
    853                     bid[res_ct++] = bcmBstStatIdDevice;
    854                 }
    855             }
    856         }
    857     } else 
    858 #endif
    859     {
    860         /* bcmBstStatIdDevice */
    861         BCM_IF_ERROR_RETURN(READ_CFAPBSTTHRSr(unit, &rval_dev));
    862         if (soc_reg_field_get(unit, CFAPBSTTHRSr, rval_dev, BST_THRESHOLDf)) {
    863             if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) {
    864                 if (soc_reg64_field32_get(unit, MEM_FAIL_INT_EN_64r,
    865                         rval64, BST_CFAP_INT_ENf)) {
    866                     index[res_ct][0] = 0;
    867                     bid[res_ct++] = bcmBstStatIdDevice;
    868                 }
    869             } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) {
    870                 /* CFAP : Device resource. 
    871                 * Check Intr Status reg if Stats > Thd.
    872                 */
    873                 reg[0] = MEM_FAIL_INT_STATr;
    874                 if (soc_reg_field_get(unit, reg[0], rval_status, BST_CFAP_INTf)) {
    875                     index[res_ct][0] = 0;
    876                     bid[res_ct++] = bcmBstStatIdDevice;
    877                 }
    878             }
    879         }
    880     }
    881 
    882 #if defined(BCM_APACHE_SUPPORT)
    883     if (SOC_IS_APACHE(unit)) {
    884         /* Ingress based Status/Triggers */
    885         BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, &rval_pipe[0]));
    886         reg[0] = THDI_BST_TRIGGER_STATUS_PIPEXr;
    887 
    888         /* bcmBstStatIdIngPool */
    889         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
    890                                         rval_pipe[0], POOL_SHARED_TRIGGERf);
    891         if (fval_pipe[0]) {
    892             fld[0] = POOL_SHARED_TRIGGER_STATUSf;
    893 
    894             if (!fval) {
    895                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    896                     if (!fval_pipe[pipe]) {
    897                         continue;
    898                     }
    899                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[0]);
    900                 }
    901             }
    902             bid[res_ct++] = bcmBstStatIdIngPool;
    903         }
    904 
    905         /* bcmBstStatIdPortPool */
    906         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
    907                                         rval_pipe[0], SP_SHARED_TRIGGER_PIPEXf);
    908         if (fval_pipe[0]) {
    909             fld[0] = SP_SHARED_TRIGGER_STATUS_PIPEXf;
    910 
    911             if (!fval) {
    912                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    913                     if (!fval_pipe[pipe]) {
    914                         continue;
    915                     }
    916                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]);
    917                 }
    918             }
    919             bid[res_ct++] = bcmBstStatIdPortPool;
    920         }
    921 
    922         /* bcmBstStatIdPriGroupShared */
    923         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
    924                                         rval_pipe[0], PG_SHARED_TRIGGER_PIPEXf);
    925         if (fval_pipe[0]) {
    926             fld[0] = PG_SHARED_TRIGGER_STATUS_PIPEXf;
    927 
    928             if (!fval) {
    929                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    930                     if (!fval_pipe[pipe]) {
    931                         continue;
    932                     }
    933                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]);
    934                 }
    935             }
    936             bid[res_ct++] = bcmBstStatIdPriGroupShared;
    937         }
    938 
    939         /* bcmBstStatIdPriGroupHeadroom */
    940         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
    941                                         rval_pipe[0], PG_HDRM_TRIGGER_PIPEXf);
    942         if (fval_pipe[0]) {
    943             fld[0] = PG_HDRM_TRIGGER_STATUS_PIPEXf;
    944 
    945             if (!fval) {
    946                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    947                     if (!fval_pipe[pipe]) {
    948                         continue;
    949                     }
    950                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]);
    951                 }
    952             }
    953             bid[res_ct++] = bcmBstStatIdPriGroupHeadroom;
    954         }
    955         BCM_IF_ERROR_RETURN(WRITE_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, 0));
    956     } else 
    957 #endif
    958     {
    959         /* Ingress based Status/Triggers */
    960         BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, &rval_pipe[0]));
    961         BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr(unit, &rval_pipe[1]));
    962         reg[0] = THDI_BST_TRIGGER_STATUS_PIPEXr;
    963         reg[1] = THDI_BST_TRIGGER_STATUS_PIPEYr;
    964 
    965         /* bcmBstStatIdIngPool */
    966         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
    967                                         rval_pipe[0], POOL_SHARED_TRIGGERf);
    968         fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 
    969                                         rval_pipe[1], POOL_SHARED_TRIGGERf);
    970         if (fval_pipe[0] || fval_pipe[1]) {
    971             fld[0] = POOL_SHARED_TRIGGER_STATUSf;
    972 
    973             if (!fval) {
    974                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    975                     if (!fval_pipe[pipe]) {
    976                         continue;
    977                     }
    978                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[0]);
    979                 }
    980             }
    981             bid[res_ct++] = bcmBstStatIdIngPool;
    982         }
    983 
    984         /* bcmBstStatIdPortPool */
    985         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
    986                                         rval_pipe[0], SP_SHARED_TRIGGER_PIPEXf);
    987         fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 
    988                                         rval_pipe[1], SP_SHARED_TRIGGER_PIPEYf);
    989         if (fval_pipe[0] || fval_pipe[1]) {
    990             fld[0] = SP_SHARED_TRIGGER_STATUS_PIPEXf;
    991             fld[1] = SP_SHARED_TRIGGER_STATUS_PIPEYf;
    992 
    993             if (!fval) {
    994                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    995                     if (!fval_pipe[pipe]) {
    996                         continue;
    997                     }
    998                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]);
    999                 }
   1000             }
   1001             bid[res_ct++] = bcmBstStatIdPortPool;
   1002         }
   1003 
   1004         /* bcmBstStatIdPriGroupShared */
   1005         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
   1006                                         rval_pipe[0], PG_SHARED_TRIGGER_PIPEXf);
   1007         fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 
   1008                                         rval_pipe[1], PG_SHARED_TRIGGER_PIPEYf);
   1009         if (fval_pipe[0] || fval_pipe[1]) {
   1010             fld[0] = PG_SHARED_TRIGGER_STATUS_PIPEXf;
   1011             fld[1] = PG_SHARED_TRIGGER_STATUS_PIPEYf;
   1012 
   1013             if (!fval) {
   1014                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1015                     if (!fval_pipe[pipe]) {
   1016                         continue;
   1017                     }
   1018                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]);
   1019                 }
   1020             }
   1021             bid[res_ct++] = bcmBstStatIdPriGroupShared;
   1022         }
   1023 
   1024         /* bcmBstStatIdPriGroupHeadroom */
   1025         fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 
   1026                                         rval_pipe[0], PG_HDRM_TRIGGER_PIPEXf);
   1027         fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 
   1028                                         rval_pipe[1], PG_HDRM_TRIGGER_PIPEYf);
   1029         if (fval_pipe[0] || fval_pipe[1]) {
   1030             fld[0] = PG_HDRM_TRIGGER_STATUS_PIPEXf;
   1031             fld[1] = PG_HDRM_TRIGGER_STATUS_PIPEYf;
   1032 
   1033             if (!fval) {
   1034                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1035                     if (!fval_pipe[pipe]) {
   1036                         continue;
   1037                     }
   1038                     index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]);
   1039                 }
   1040             }
   1041             bid[res_ct++] = bcmBstStatIdPriGroupHeadroom;
   1042         }
   1043         BCM_IF_ERROR_RETURN(WRITE_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, 0));
   1044         BCM_IF_ERROR_RETURN(WRITE_THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr(unit, 0));
   1045     }
   1046 
   1047     /* bcmBstStatIdUcast */
   1048     if ((fval = soc_reg64_field32_get(unit, THDU_BST_STATr,
   1049                               rval_uc, BST_STAT_TRIGGERED_TYPEf))) {
   1050         if (fval & 0x1) {
   1051             fld[0] = UC_Q_BST_STAT_IDf;
   1052             index[res_ct][0] = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc, fld[0]);
   1053             if (index[res_ct][0] >= 2048) {
   1054                 index[res_ct][1] = index[res_ct][0] - 2048 + 1480;
   1055                 index[res_ct][0] = -1;
   1056             }
   1057             bid[res_ct++] = bcmBstStatIdUcast;
   1058         }
   1059         if (fval & 0x2) {
   1060             fld[0] = UC_QGROUP_BST_STAT_IDf;
   1061             index[res_ct][0] = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc,
   1062                                              fld[0]);
   1063             if (NUM_PIPE(unit) > 1) {
   1064                 if (index[res_ct][0] >= 128) {
   1065                     index[res_ct][1] = index[res_ct][0] - 128;
   1066                     index[res_ct][0] = -1;
   1067                 }
   1068             }
   1069             bid[res_ct++] = bcmBstStatIdUCQueueGroup;
   1070         }
   1071         if (fval & 0x4) {
   1072             fld[0] = UC_PORT_SP_BST_STAT_IDf;
   1073             index[res_ct][0] = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc,
   1074                                              fld[0]);
   1075             if (NUM_PIPE(unit) > 1) {
   1076                 if (index[res_ct][0] >= 256) {
   1077                     index[res_ct][1] = index[res_ct][0] - 256;
   1078                     index[res_ct][0] = -1;
   1079                 }
   1080             }
   1081             bid[res_ct++] = bcmBstStatIdEgrPortPoolSharedUcast;
   1082         }
   1083 
   1084         COMPILER_64_ZERO(rval64_zero);
   1085         BCM_IF_ERROR_RETURN(WRITE_THDU_BST_STATr(unit, rval64_zero));
   1086     }
   1087 
   1088     /* THDR Status/Triggers */
   1089     reg[0] = MMU_THDR_DB_BST_STATr;
   1090     fval = soc_reg_field_get(unit, reg[0], rval_rqe,
   1091                             PRIQ_TRIGGEREDf);
   1092     if (fval & 0x1) {
   1093         fld[0] = PRIQ_IDf;
   1094         index[res_ct][0] = soc_reg_field_get(unit, reg[0], rval_rqe,
   1095                                          fld[0]);
   1096         bid[res_ct++] = bcmBstStatIdRQEQueue;
   1097     }
   1098 
   1099     fval = soc_reg_field_get(unit, reg[0], rval_rqe,
   1100                             SP_TRIGGEREDf);
   1101     if (fval & 0x1) {
   1102         fld[0] = SP_IDf;
   1103         index[res_ct][0] = soc_reg_field_get(unit, reg[0], rval_rqe,
   1104                                          fld[0]);
   1105         bid[res_ct++] = bcmBstStatIdRQEPool;
   1106     }
   1107 
   1108     COMPILER_64_ZERO(rval64_zero);
   1109     /*BCM_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_BST_STATr(unit, rval64_zero));*/
   1110     BCM_IF_ERROR_RETURN(soc_reg_set(unit, MMU_THDR_DB_BST_STATr, REG_PORT_ANY,
   1111                 0, rval64_zero));
   1112 
   1113     if (res_ct == 0) {
   1114         /* No resource to fetch */
   1115         if (bst_info->intr_enable_set) {
   1116             bst_info->intr_enable_set(unit, 1);
   1117         }
   1118         return BCM_E_NONE;
   1119     }
   1120 
   1121     for (pos = 0; pos < res_ct; pos++) {
   1122         if (index[pos][0] != -1) {
   1123             _bcm_bst_sync_hw_snapshot(unit, bid[pos], -1, index[pos][0]);
   1124         } else {
   1125             _bcm_bst_sync_hw_snapshot(unit, bid[pos], -2, index[pos][1]);
   1126         }
   1127     }
   1128 
   1129     *flags = flags_tr;
   1130     if (bst_info->intr_enable_set) {
   1131         bst_info->intr_enable_set(unit, 1);
   1132     }
   1133     return BCM_E_NONE;
   1134 }
   1135 
   1136 STATIC int 
   1137 _bcm_bst_td2_hw_trigger_set(int unit, bcm_bst_stat_id_t bid)
   1138 {
   1139     uint32 rval;
   1140     _bcm_bst_resource_info_t *resInfo;
   1141     soc_field_t fld[2] = { INVALIDf, INVALIDf };
   1142 
   1143     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1144     if (resInfo == NULL) {
   1145         return BCM_E_PARAM;
   1146     }
   1147 
   1148     if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) {
   1149         fld[0] = BST_HW_SNAPSHOT_EN_CFAPf;
   1150         fld[1] = ACTION_CFAPf;
   1151     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) {
   1152         fld[0] = BST_HW_SNAPSHOT_EN_THDIf;
   1153         fld[1] = ACTION_EN_THDIf;
   1154     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) {
   1155         fld[0] = BST_HW_SNAPSHOT_EN_THDOf;
   1156         fld[1] = ACTION_EN_THDOf;
   1157     } else {
   1158         return BCM_E_PARAM;
   1159     }
   1160     
   1161     BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval));
   1162     soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, fld[0], 1);
   1163     BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval));
   1164 
   1165     BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval));
   1166     soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, fld[1], 1);
   1167     BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval));
   1168     return BCM_E_NONE;
   1169 }
   1170 
   1171 STATIC int 
   1172 _bcm_bst_td2_hw_trigger_reset(int unit, bcm_bst_stat_id_t bid)
   1173 {
   1174     uint32 rval;
   1175     _bcm_bst_resource_info_t *resInfo;
   1176     soc_field_t fld[2] = { INVALIDf, INVALIDf };
   1177 
   1178     if (bid != -1) {
   1179         resInfo = _BCM_BST_RESOURCE(unit, bid);
   1180         if (resInfo == NULL) {
   1181             return BCM_E_PARAM;
   1182         }
   1183 
   1184         if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) {
   1185             fld[0] = BST_HW_SNAPSHOT_EN_CFAPf;
   1186             fld[1] = ACTION_CFAPf;
   1187         } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) {
   1188             fld[0] = BST_HW_SNAPSHOT_EN_THDIf;
   1189             fld[1] = ACTION_EN_THDIf;
   1190         } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) {
   1191             fld[0] = BST_HW_SNAPSHOT_EN_THDOf;
   1192             fld[1] = ACTION_EN_THDOf;
   1193         } else {
   1194             return BCM_E_PARAM;
   1195         }
   1196     
   1197         BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval));
   1198         soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, fld[0], 0);
   1199         BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval));
   1200 
   1201         BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval));
   1202         soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, fld[1], 0);
   1203         BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval));
   1204     } else {
   1205         /* Reset for all Resources */
   1206         BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval));
   1207         soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, BST_HW_SNAPSHOT_EN_CFAPf, 0);
   1208         soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, BST_HW_SNAPSHOT_EN_THDIf, 0);
   1209         soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, BST_HW_SNAPSHOT_EN_THDOf, 0);
   1210         BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval));
   1211 
   1212         BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval));
   1213         soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, ACTION_CFAPf, 0);
   1214         soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, ACTION_EN_THDIf, 0);
   1215         soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, ACTION_EN_THDOf, 0);
   1216         BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval));
   1217     }
   1218     return BCM_E_NONE;
   1219 }
   1220 
   1221 STATIC int
   1222 soc_td2_set_hw_intr_cb(int unit)
   1223 {
   1224 #if defined(BCM_MONTEREY_SUPPORT)
   1225     if (SOC_IS_MONTEREY(unit)) {
   1226         BCM_IF_ERROR_RETURN(soc_monterey_set_bst_callback(unit, &_bcm_bst_hw_event_cb));
   1227         return SOC_E_NONE;
   1228     }
   1229 #endif
   1230 #if defined(BCM_APACHE_SUPPORT)
   1231     if (SOC_IS_APACHE(unit)) {
   1232         BCM_IF_ERROR_RETURN(soc_apache_set_bst_callback(unit, &_bcm_bst_hw_event_cb));
   1233         return SOC_E_NONE;
   1234     }
   1235 #endif
   1236     BCM_IF_ERROR_RETURN(soc_td2_set_bst_callback(unit, &_bcm_bst_hw_event_cb));
   1237     return SOC_E_NONE;
   1238 }
   1239 
   1240 int
   1241 _bcm_bst_td2_intr_check(int unit)
   1242 {
   1243     _bcm_bst_cmn_unit_info_t *bst_info;
   1244     _bcm_bst_resource_info_t *resInfo;
   1245     int num_entries, mem_wsz, port;
   1246     int idx, idx_offset, rv, pipe, pipe_offset = 0;
   1247     void *pentry;
   1248     char *dmabuf;
   1249     uint32 rval, temp_val;
   1250     soc_mem_t mem;
   1251     soc_reg_t reg;
   1252     bcm_bst_stat_id_t bid = bcmBstStatIdMaxCount;
   1253 
   1254     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   1255         return BCM_E_INIT;
   1256     }
   1257 
   1258     /* bcmBstStatIdHeadroomPool is used for Tomahawk*/
   1259     for(bid = _BCM_BST_RESOURCE_MIN; bid < bcmBstStatIdMaxCount; bid++)
   1260     {
   1261         /* bcmBstStatIdHeadroomPool is not supported for TD2/TD2+...*/
   1262         if (bid == bcmBstStatIdHeadroomPool) {
   1263             continue;
   1264         }
   1265 
   1266         /* sync all the stats */
   1267         resInfo = _BCM_BST_RESOURCE(unit, bid);
   1268         if (resInfo == NULL) {
   1269             return BCM_E_PARAM;
   1270         }
   1271 
   1272         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1273             bcm_gport_t gport = -1;
   1274             bcm_cos_t cosq = -1;
   1275             mem = resInfo->stat_mem[pipe];
   1276             reg = resInfo->stat_reg[pipe];
   1277             pipe_offset = 0;
   1278 
   1279             if (pipe) {
   1280                 pipe_offset = (resInfo->index_max / NUM_PIPE(unit)) * pipe;
   1281             }
   1282 
   1283             if (pipe == 1) {
   1284                 port = -2;
   1285             } else {
   1286                 port = -1;
   1287             }
   1288 
   1289             if (mem != INVALIDm) {
   1290                 num_entries = soc_mem_index_count(unit, mem);
   1291                 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem);
   1292 
   1293                 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf");
   1294                 if (dmabuf == NULL) {
   1295                     return BCM_E_MEMORY;
   1296                 }
   1297 
   1298                 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL,
   1299                                         soc_mem_index_min(unit, mem),
   1300                                         soc_mem_index_max(unit, mem),
   1301                                         dmabuf)) {
   1302                     soc_cm_sfree(unit, dmabuf);
   1303                     return BCM_E_INTERNAL;
   1304                 }
   1305 
   1306                 for (idx = 0; idx < (resInfo->num_stat_pp / NUM_PIPE(unit)); idx++) {
   1307                     idx_offset = idx + pipe_offset;
   1308                     pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
   1309                                                           dmabuf, idx);
   1310                     temp_val = soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field);
   1311                     if (bst_info->track_mode) {
   1312                         if (resInfo->p_stat[idx_offset] < temp_val) {
   1313                             resInfo->p_stat[idx_offset] = temp_val;
   1314                         }
   1315                     } else {
   1316                         resInfo->p_stat[idx_offset] = temp_val;
   1317                     }
   1318 
   1319                     if (resInfo->p_threshold[idx_offset] &&
   1320                         (resInfo->p_stat[idx_offset] >=
   1321                          (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   1322                          LOG_WARN(BSL_LS_SOC_COMMON,
   1323                           (BSL_META_U(unit,
   1324                                       "unit %d %s %d mem %s bid %d port %d idx %d threshold %d stat %d!!\n"),
   1325                                       unit, __FUNCTION__, __LINE__, SOC_MEM_NAME(unit, mem), bid, port, idx_offset,
   1326                                       resInfo->p_threshold[idx_offset], resInfo->p_stat[idx_offset]));
   1327                         /* Generate SOC EVENT */
   1328                         if (bst_info->handlers.reverse_resolve_index) {
   1329                             /* reverse map the inedx to port/cos pair */
   1330                             bst_info->handlers.reverse_resolve_index(unit, bid,
   1331                                                                      port, idx_offset,
   1332                                                                      &gport, &cosq);
   1333                             soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
   1334                                                bid, gport, cosq);
   1335 
   1336                         }
   1337                     }
   1338                 }
   1339                 soc_cm_sfree(unit, dmabuf);
   1340             } else if (reg != INVALIDr) {
   1341                 for (idx = 0; idx < resInfo->num_stat_pp; idx++) {
   1342                     idx_offset = idx + pipe_offset;
   1343                     rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval);
   1344                     if (rv) {
   1345                         return BCM_E_INTERNAL;
   1346                     }
   1347                     temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field);
   1348                     if (bst_info->track_mode) {
   1349                         if (resInfo->p_stat[idx_offset] < temp_val) {
   1350                             resInfo->p_stat[idx_offset] = temp_val;
   1351                         }
   1352                     } else {
   1353                         resInfo->p_stat[idx_offset] = temp_val;
   1354                     }
   1355 
   1356                     if (resInfo->p_threshold[idx_offset] &&
   1357                         (resInfo->p_stat[idx_offset] >=
   1358                          (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   1359                          LOG_WARN(BSL_LS_SOC_COMMON,
   1360                           (BSL_META_U(unit,
   1361                                       "unit %d %s %d reg %s bid %d port %d pipe %d idx %d threshold %d stat %d!!\n"),
   1362                                       unit, __FUNCTION__, __LINE__, SOC_REG_NAME(unit, reg), bid, port, pipe, idx_offset,
   1363                                       resInfo->p_threshold[idx_offset], resInfo->p_stat[idx_offset]));
   1364                         /* Generate SOC EVENT */
   1365                         if (bst_info->handlers.reverse_resolve_index) {
   1366                             /* reverse map the inedx to port/cos pair */
   1367                             bst_info->handlers.reverse_resolve_index(unit, bid,
   1368                                                                      port, idx_offset,
   1369                                                                      &gport, &cosq);
   1370                             soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
   1371                                                bid, gport, cosq);
   1372                         }
   1373                     }
   1374                 }
   1375             }
   1376         }
   1377     }
   1378     return BCM_E_NONE;
   1379 }
   1380 
   1381 STATIC int
   1382 soc_td2_intr_check_cb_register(int unit)
   1383 {
   1384     BCM_IF_ERROR_RETURN(soc_td2_set_bst_intr_check_callback(unit, &_bcm_bst_td2_intr_check));
   1385     return SOC_E_NONE;
   1386 }
   1387 
   1388 STATIC int
   1389 _bcm_td2_pre_sync(int unit, bcm_bst_stat_id_t bid, int *sync_val)
   1390 {
   1391     soc_field_t field = INVALIDf;
   1392     _bcm_bst_resource_info_t *resInfo;
   1393     uint32 rval;
   1394 
   1395     if ((bid < 0) || (bid >= bcmBstStatIdMaxCount)) {
   1396         return BCM_E_INTERNAL;
   1397     }
   1398     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1399 
   1400     if (resInfo == NULL) {
   1401         return BCM_E_INTERNAL;
   1402     }
   1403 
   1404     if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) {
   1405         field = BST_TRACK_EN_CFAPf;
   1406     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) {
   1407         field = BST_TRACK_EN_THDIf;
   1408     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) {
   1409         field = BST_TRACK_EN_THDOf;
   1410     } else {
   1411         return BCM_E_PARAM;
   1412     }
   1413 
   1414     BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
   1415     *sync_val = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, 
   1416                                 field);
   1417     soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, field, 0);
   1418     BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval));
   1419 
   1420     return SOC_E_NONE;
   1421 }
   1422 
   1423 STATIC int
   1424 _bcm_td2_post_sync(int unit, bcm_bst_stat_id_t bid, int sync_val)
   1425 {
   1426     soc_field_t field = INVALIDf;
   1427     _bcm_bst_resource_info_t *resInfo;
   1428     uint32 rval;
   1429 
   1430     if ((bid < 0) || (bid >= bcmBstStatIdMaxCount)) {
   1431         return BCM_E_INTERNAL;
   1432     }
   1433     resInfo = _BCM_BST_RESOURCE(unit, bid);
   1434 
   1435     if (resInfo == NULL) {
   1436         return BCM_E_INTERNAL;
   1437     }
   1438 
   1439     if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) {
   1440         field = BST_TRACK_EN_CFAPf;
   1441     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) {
   1442         field = BST_TRACK_EN_THDIf;
   1443     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) {
   1444         field = BST_TRACK_EN_THDOf;
   1445     } else {
   1446         return BCM_E_PARAM;
   1447     }
   1448 
   1449     BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval));
   1450     soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, field, sync_val);
   1451     BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval));
   1452 
   1453     return SOC_E_NONE;
   1454 }
   1455 
   1456 STATIC int 
   1457 _bcm_bst_td2_init(int unit)
   1458 {
   1459     _bcm_bst_cmn_unit_info_t *bst_info;
   1460     _bcm_bst_resource_info_t *pres;
   1461     int td2_3320 = 0;
   1462     int idx_count = 0;
   1463 
   1464     td2_3320 = soc_feature(unit, soc_feature_min_resume_limit_1);
   1465     
   1466     bst_info = _BCM_UNIT_BST_INFO(unit);
   1467 
   1468     bst_info->to_cell = _bcm_bst_tr3_byte_to_cell;
   1469     bst_info->to_byte = _bcm_bst_tr3_cell_to_byte;
   1470     bst_info->control_set = _bcm_td2_bst_control_set;
   1471     bst_info->control_get = _bcm_td2_bst_control_get;
   1472     bst_info->intr_to_resources = _bcm_bst_td2_intr_to_resources;
   1473     bst_info->hw_trigger_set = _bcm_bst_td2_hw_trigger_set;
   1474     bst_info->hw_trigger_reset = _bcm_bst_td2_hw_trigger_reset;
   1475     bst_info->hw_intr_cb = soc_td2_set_hw_intr_cb;
   1476     bst_info->intr_enable_set = _bst_intr_enable_set;
   1477     bst_info->pre_sync = _bcm_td2_pre_sync;
   1478     bst_info->post_sync = _bcm_td2_post_sync;
   1479     bst_info->hw_stat_snapshot = _bcm_bst_sync_hw_snapshot;
   1480     bst_info->hw_stat_clear = _bcm_bst_hw_stat_clear;
   1481     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
   1482         bst_info->hw_sbusdma_desc_init = _bcm_bst_td2_sbusdma_desc_init;
   1483         bst_info->hw_sbusdma_desc_deinit = _bcm_bst_td2_sbusdma_desc_deinit;
   1484         bst_info->hw_sbusdma_desc_sync = _bcm_bst_td2_sbusdma_desc_sync;
   1485     }
   1486     if(soc_property_get(unit, spn_PROFILE_PG_1HDRM_8SHARED, 1)) {
   1487         bst_info->mode = 1 ;
   1488     } else {
   1489         bst_info->mode = 0;
   1490     }
   1491     bst_info->max_bytes = bst_info->to_byte(unit, BST_THRESHOLD_MAX_HIGH);
   1492 
   1493     /* Register a callback for soc to do bst interrupt check during mmu ser processing*/
   1494     soc_td2_intr_check_cb_register(unit);
   1495 
   1496     /* bcmBstStatIdDevice */
   1497     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdDevice);
   1498     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1499     pres->index_min = 0;
   1500     pres->index_max = 0;
   1501     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_DEV);
   1502 #if defined(BCM_APACHE_SUPPORT)
   1503     if (SOC_IS_APACHE(unit)) {
   1504         _BCM_BST_STAT_INFO(pres, INVALIDm, CFAP_BST_STATr, BST_STATf);
   1505         _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAP_BST_THRSr, BST_THRESHOLDf, 1);
   1506     } else 
   1507 #endif
   1508     {
   1509         _BCM_BST_STAT_INFO(pres, INVALIDm, CFAPBSTSTATr, BST_STATf);
   1510         _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAPBSTTHRSr, BST_THRESHOLDf, 1);
   1511     }
   1512     _BCM_BST_RESOURCE_STAT_INIT(pres, 1, "bst cfap");
   1513     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 1, "bst cfap");
   1514 
   1515     /* bcmBstStatIdEgrPool */
   1516     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPool);
   1517     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1518     pres->index_min = 0;
   1519     pres->index_max = 3;
   1520     pres->threshold_adj = td2_3320 ? -1 : 0;
   1521     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   1522     _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDM_DB_POOL_MCUC_BST_STATr, BST_STATf);
   1523     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
   1524                             MMU_THDM_DB_POOL_MCUC_BST_THRESHOLDr, BST_STATf, 1);
   1525     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egrpool");
   1526     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egrpool");
   1527 
   1528     /* bcmBstStatIdEgrMCastPool */
   1529     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrMCastPool);
   1530     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1531     pres->index_min = 0;
   1532     pres->index_max = 3;
   1533     pres->threshold_adj = td2_3320 ? -1 : 0;
   1534     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   1535     _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDM_DB_POOL_MC_BST_STATr, BST_STATf);
   1536     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
   1537                             MMU_THDM_DB_POOL_MC_BST_THRESHOLDr, BST_STATf, 1);
   1538     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egr mcpool");
   1539     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egr mcpool");
   1540 
   1541     /* bcmBstStatIdIngPool */
   1542     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdIngPool);
   1543     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1544     pres->index_min = 0;
   1545     pres->index_max = 3;
   1546     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING);
   1547     _BCM_BST_STAT_INFO(pres, INVALIDm, THDI_BST_SP_GLOBAL_SHARED_CNTr, 
   1548                         SP_GLOBAL_SHARED_CNTf);
   1549 
   1550     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 
   1551             THDI_BST_SP_GLOBAL_SHARED_PROFILEr, SP_GLOBAL_SHARED_PROFILEf, 1);
   1552 
   1553     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst ing pool");
   1554     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst ing pool");
   1555 
   1556     /* bcmBstStatIdPortPool */
   1557     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPortPool);
   1558     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1559     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1560                                      _BCM_BST_CMN_RES_F_PIPED |
   1561                                      _BCM_BST_CMN_RES_F_RES_ING);
   1562     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   1563 
   1564     _BCM_BST_THRESHOLD_INFO2(pres, THDI_PORT_SP_CONFIG_Xm, 
   1565             THDI_PORT_SP_CONFIG_Ym, INVALIDr, INVALIDr, SP_BST_PROFILE_SHAREDf, 1);
   1566 
   1567     _BCM_BST_PROFILE_INFO(pres, INVALIDm, THDI_BST_SP_SHARED_PROFILEr, 
   1568                           BST_SP_SHARED_THRESHf);
   1569 
   1570     _BCM_BST_STAT_INFO2(pres, THDI_PORT_SP_BST_Xm, THDI_PORT_SP_BST_Ym, 
   1571                         INVALIDr, INVALIDr, SP_BST_STAT_PORT_COUNTf);
   1572 
   1573     _BCM_BST_RESOURCE_STAT_INIT(pres, 
   1574                 soc_mem_index_count(unit, THDI_PORT_SP_BST_Xm) * NUM_PIPE(unit),
   1575                 "bst port pool");
   1576     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 
   1577                 soc_mem_index_count(unit, THDI_PORT_SP_BST_Xm) * NUM_PIPE(unit),
   1578                 "bst port pool");
   1579     pres->index_min = 0;
   1580     pres->index_max = soc_mem_index_count(unit, THDI_PORT_SP_BST_Xm) *
   1581                       NUM_PIPE(unit);
   1582 
   1583     /* bcmBstStatIdPriGroupShared */
   1584     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupShared);
   1585     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1586 
   1587     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1588                                      _BCM_BST_CMN_RES_F_PIPED |
   1589                                      _BCM_BST_CMN_RES_F_RES_ING);
   1590 
   1591     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   1592 
   1593     _BCM_BST_THRESHOLD_INFO2(pres, THDI_PORT_PG_CONFIG_Xm, 
   1594           THDI_PORT_PG_CONFIG_Ym, INVALIDr, INVALIDr, PG_BST_PROFILE_SHAREDf, 1);
   1595 
   1596     _BCM_BST_PROFILE_INFO(pres, INVALIDm, 
   1597                           THDI_BST_PG_SHARED_PROFILEr, BST_PG_SHARED_THRESHf);
   1598 
   1599     _BCM_BST_STAT_INFO2(pres, THDI_PORT_PG_BST_Xm, THDI_PORT_PG_BST_Ym,
   1600                         INVALIDr, INVALIDr, PG_BST_STAT_SHAREDf);
   1601 
   1602 #if defined(BCM_APACHE_SUPPORT)
   1603 #if defined(BCM_MONTEREY_SUPPORT)
   1604     if (SOC_IS_MONTEREY(unit)) {
   1605         /* Stat res -THDI_PORT_PG_BST_X : 68 (ports) * 8 (PGs) */
   1606         _BCM_BST_RESOURCE_STAT_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg");
   1607         _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg");
   1608         pres->index_min = 0;
   1609         pres->index_max = (68 * 8) * NUM_PIPE(unit);
   1610     } else
   1611 #endif
   1612     if (SOC_IS_APACHE(unit)) {
   1613         /* Stat res - THDI_PORT_PG_BST_X/_Y : 75(Ports) * 8(PGs) * 1(pipes) */
   1614         _BCM_BST_RESOURCE_STAT_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg");
   1615         _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg");
   1616         pres->index_min = 0;
   1617         pres->index_max = (75 * 8) * NUM_PIPE(unit);
   1618     } else 
   1619 #endif
   1620     {
   1621         /* Stat res - THDI_PORT_PG_BST_X/_Y : 53(Ports) * 8(PGs) * 2(pipes) */
   1622         _BCM_BST_RESOURCE_STAT_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg");
   1623         _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg");
   1624         pres->index_min = 0;
   1625         pres->index_max = (53 * 8) * NUM_PIPE(unit);
   1626     }
   1627 
   1628     /* bcmBstStatIdPriGroupHeadroom */
   1629     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupHeadroom);
   1630     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1631     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1632                                      _BCM_BST_CMN_RES_F_PIPED |
   1633                                      _BCM_BST_CMN_RES_F_RES_ING);
   1634 
   1635     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit));
   1636 
   1637     _BCM_BST_PROFILE_INFO(pres, INVALIDm, THDI_BST_PG_HDRM_PROFILEr,
   1638                           BST_PG_HDRM_THRESHf);
   1639 
   1640     _BCM_BST_THRESHOLD_INFO2(pres, THDI_PORT_PG_CONFIG_Xm,
   1641         THDI_PORT_PG_CONFIG_Ym, INVALIDr, INVALIDr, PG_BST_PROFILE_HDRMf, 1);
   1642 
   1643     _BCM_BST_STAT_INFO2(pres, THDI_PORT_PG_BST_Xm, THDI_PORT_PG_BST_Ym,
   1644                         INVALIDr, INVALIDr, PG_BST_STAT_HDRMf);
   1645 
   1646 #if defined(BCM_APACHE_SUPPORT)
   1647 #if defined(BCM_MONTEREY_SUPPORT)
   1648     if (SOC_IS_MONTEREY(unit)) {
   1649         /* Stat res -THDI_PORT_PG_BST_X : 68 (ports) * 8 (PGs) */
   1650         _BCM_BST_RESOURCE_STAT_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg hdrm");
   1651         _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg hdrm");
   1652         pres->index_min = 0;
   1653         pres->index_max = (68 * 8) * NUM_PIPE(unit);
   1654     } else
   1655 #endif
   1656     if (SOC_IS_APACHE(unit)) {
   1657         /* Stat res - THDI_PORT_PG_BST_X/_Y : 75(Ports) * 8(PGs) * 2(pipes) */
   1658         _BCM_BST_RESOURCE_STAT_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg hdrm");
   1659         _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg hdrm");
   1660         pres->index_min = 0;
   1661         pres->index_max = (75 * 8) * NUM_PIPE(unit);
   1662     } else 
   1663 #endif
   1664     {
   1665         /* Stat res - THDI_PORT_PG_BST_X/_Y : 53(Ports) * 8(PGs) * 2(pipes) */
   1666         _BCM_BST_RESOURCE_STAT_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg hdrm");
   1667         _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg hdrm");
   1668         pres->index_min = 0;
   1669         pres->index_max = (53 * 8) * NUM_PIPE(unit);
   1670     }
   1671 
   1672     /* bcmBstStatIdMcast */
   1673     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdMcast);
   1674     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1675     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1676                                      _BCM_BST_CMN_RES_F_PIPED |
   1677                                      _BCM_BST_CMN_RES_F_RES_EGR);
   1678     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_CMIC(unit));
   1679     _BCM_BST_PROFILE_INFO(pres, INVALIDm, 
   1680                    MMU_THDM_DB_QUEUE_MC_BST_THRESHOLD_PROFILEr, BST_STATf);
   1681 
   1682     _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDM_DB_QUEUE_CONFIG_0m, 
   1683                              MMU_THDM_DB_QUEUE_CONFIG_1m, INVALIDr, INVALIDr,
   1684                              BST_THRESHOLD_PROFILEf, 1);
   1685 
   1686     idx_count = soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_BST_0m);
   1687     _BCM_BST_STAT_INFO2(pres, MMU_THDM_DB_QUEUE_BST_0m, MMU_THDM_DB_QUEUE_BST_1m,
   1688                         INVALIDr, INVALIDr, DATAf);
   1689     _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit),
   1690                 "bst mcast");
   1691     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit),
   1692                 "bst mcast");
   1693     pres->index_min = 0;
   1694     pres->index_max = idx_count * NUM_PIPE(unit);
   1695 
   1696     /* bcmBstStatIdUcast */
   1697     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUcast);
   1698     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1699     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 
   1700                                      _BCM_BST_CMN_RES_F_PIPED |
   1701                                      _BCM_BST_CMN_RES_F_RES_EGR);
   1702 
   1703     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   1704 
   1705     _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDU_XPIPE_CONFIG_QUEUEm, 
   1706         MMU_THDU_YPIPE_CONFIG_QUEUEm, INVALIDr, INVALIDr, Q_WM_MAX_THRESHOLDf, 8);
   1707 
   1708     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QUEUE_BST_THRESHOLDr, BST_STATf);
   1709 
   1710     _BCM_BST_STAT_INFO2(pres, MMU_THDU_XPIPE_BST_QUEUEm, 
   1711                 MMU_THDU_YPIPE_BST_QUEUEm, INVALIDr, INVALIDr, DATAf);
   1712 
   1713     idx_count = soc_mem_index_count(unit, MMU_THDU_XPIPE_BST_QUEUEm) - 1;
   1714     _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit),
   1715                 "bst ucast");
   1716     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit),
   1717                 "bst ucast"); 
   1718     pres->index_min = 0;
   1719     pres->index_max = idx_count * NUM_PIPE(unit);
   1720 
   1721     /* bcmBstStatIdEgrPortPoolSharedUcast */
   1722     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedUcast);
   1723     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1724     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1725                                      _BCM_BST_CMN_RES_F_PIPED |
   1726                                      _BCM_BST_CMN_RES_F_RES_EGR);
   1727 
   1728     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   1729 
   1730     _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDU_XPIPE_CONFIG_PORTm,
   1731             MMU_THDU_YPIPE_CONFIG_PORTm, INVALIDr, INVALIDr, WM_MAX_THRESHOLDf,
   1732             8);
   1733 
   1734     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_PORT_BST_THRESHOLDr, BST_STATf);
   1735 
   1736     _BCM_BST_STAT_INFO2(pres, MMU_THDU_XPIPE_BST_PORTm,
   1737             MMU_THDU_YPIPE_BST_PORTm, INVALIDr, INVALIDr, DATAf);
   1738     idx_count = soc_mem_index_count(unit, MMU_THDU_XPIPE_BST_PORTm);
   1739     _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit),
   1740                                 "bst egr port pool shared ucast");
   1741     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit),
   1742                                      "bst egr port pool shared ucast");
   1743     pres->index_min = 0;
   1744     pres->index_max = idx_count * NUM_PIPE(unit);
   1745 
   1746     /* bcmBstStatIdEgrPortPoolSharedMcast */
   1747     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedMcast);
   1748     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1749     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1750                                      _BCM_BST_CMN_RES_F_PIPED |
   1751                                      _BCM_BST_CMN_RES_F_RES_EGR |
   1752                                      _BCM_BST_CMN_RES_F_PORTED);
   1753 
   1754     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   1755 
   1756     _BCM_BST_THRESHOLD_INFO2(pres, INVALIDm, INVALIDm,
   1757                              MMU_THDM_DB_PORTSP_THRESHOLD_PROFILE_SELr,
   1758                              MMU_THDM_DB_PORTSP_THRESHOLD_PROFILE_SELr,
   1759                              BST_THRESHOLD_PROFILEf, 1);
   1760 
   1761     _BCM_BST_PROFILE_INFO(pres, INVALIDm,MMU_THDM_DB_PORTSP_BST_THRESHOLDr,
   1762                           BST_STATf);
   1763 
   1764     _BCM_BST_STAT_INFO2(pres, MMU_THDM_DB_PORTSP_BST_0m,
   1765                         MMU_THDM_DB_PORTSP_BST_1m, INVALIDr, INVALIDr, DATAf);
   1766     idx_count = soc_mem_index_count(unit, MMU_THDM_DB_PORTSP_BST_0m);
   1767     _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit),
   1768                                 "bst egr port pool shared mcast");
   1769     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit),
   1770                                      "bst egr port pool shared mcast");
   1771     pres->index_min = 0;
   1772     pres->index_max = idx_count * NUM_PIPE(unit);
   1773 
   1774     /* bcmBstStatIdRQEQueue */
   1775     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEQueue);
   1776     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1777     pres->index_min = 0;
   1778     pres->index_max = 10;
   1779     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   1780     _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDR_DB_BST_STAT_PRIQr, BST_STATf);
   1781     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm,
   1782                             MMU_THDR_DB_BST_THRESHOLD_PRIQr, BST_THRf, 1);
   1783     _BCM_BST_RESOURCE_STAT_INIT(pres, 11, "bst RQE queue");
   1784     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 11, "bst RQE queue");
   1785 
   1786     /* bcmBstStatIdRQEPool */
   1787     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEPool);
   1788     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1789     pres->index_min = 0;
   1790     pres->index_max = 3;
   1791     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR);
   1792     _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDR_DB_BST_STAT_SPr, BST_STATf);
   1793     _BCM_BST_THRESHOLD_INFO(pres, INVALIDm,
   1794                             MMU_THDR_DB_BST_THRESHOLD_SPr, BST_THRf, 1);
   1795     _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst RQE pool");
   1796     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst RQE pool");
   1797 
   1798     /* bcmBstStatIdUCQueueGroup */
   1799     pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUCQueueGroup);
   1800     _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres);
   1801     _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID |
   1802                                      _BCM_BST_CMN_RES_F_PIPED |
   1803                                      _BCM_BST_CMN_RES_F_RES_EGR |
   1804                                      _BCM_BST_CMN_RES_F_PORTED);
   1805     _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit));
   1806 
   1807     _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDU_XPIPE_CONFIG_QGROUPm,
   1808         MMU_THDU_YPIPE_CONFIG_QGROUPm, INVALIDr, INVALIDr, Q_WM_MAX_THRESHOLDf, 8);
   1809 
   1810     _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QGROUP_BST_THRESHOLDr, BST_STATf);
   1811 
   1812     _BCM_BST_STAT_INFO2(pres, MMU_THDU_XPIPE_BST_QGROUPm,
   1813                 MMU_THDU_YPIPE_BST_QGROUPm, INVALIDr, INVALIDr, DATAf);
   1814 
   1815     idx_count = soc_mem_index_count(unit, MMU_THDU_XPIPE_BST_QGROUPm);
   1816     _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit),
   1817                 "bst unicast queue group");
   1818     _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit),
   1819                 "bst unicast queue group");
   1820     pres->index_min = 0;
   1821     pres->index_max = idx_count * NUM_PIPE(unit);
   1822 
   1823     return BCM_E_NONE;
   1824 }
   1825 
   1826 #endif /* BCM_TRIDENT2_SUPPORT || BCM_APACHE_SUPPORT*/
   1827 
   1828 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   1829     defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   1830 STATIC int
   1831 _bcm_bst_sync_thread_ok_to_run(int unit)
   1832 {
   1833     _bcm_bst_cmn_unit_info_t *bst_info;
   1834 
   1835     bst_info = _BCM_UNIT_BST_INFO(unit);
   1836 
   1837     if ((bst_info == NULL) || (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) ||
   1838         (bst_info->interval <= 0)) {
   1839         return FALSE;
   1840     }
   1841 
   1842     return TRUE;
   1843 }
   1844 
   1845 int
   1846 _bst_intr_enable_set(int unit, int enable)
   1847 {
   1848     uint64 rval64;
   1849     uint32 rval;
   1850 
   1851     if (!soc_property_get(unit, spn_POLLED_IRQ_MODE, 0)) {
   1852         if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) {
   1853             BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_EN_64r(unit, &rval64));
   1854             soc_reg64_field32_set(unit, MEM_FAIL_INT_EN_64r, &rval64,
   1855                                   BST_THDO_INT_ENf, enable);
   1856             soc_reg64_field32_set(unit, MEM_FAIL_INT_EN_64r, &rval64,
   1857                                   BST_THDI_INT_ENf, enable);
   1858             soc_reg64_field32_set(unit, MEM_FAIL_INT_EN_64r, &rval64,
   1859                                   BST_CFAP_INT_ENf, enable);
   1860             BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_EN_64r(unit, rval64));
   1861         } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) {
   1862             if (!soc_property_get(unit, spn_POLLED_IRQ_MODE, 0)) {
   1863                 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_ENr(unit, &rval));
   1864                 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval,
   1865                                   BST_THDO_INT_ENf, enable);
   1866                 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval,
   1867                                   BST_THDI_INT_ENf, enable);
   1868                 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval,
   1869                                   BST_CFAP_INT_ENf, enable);
   1870                 BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_ENr(unit, rval));
   1871             }
   1872         }
   1873     }
   1874     return 0;
   1875 }
   1876 
   1877 int
   1878 _bst_intr_status_reset(int unit)
   1879 {
   1880     uint32 rval;
   1881     uint64 rval64;
   1882 
   1883     if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_STAT_64r)) {
   1884         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64));
   1885         soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r,
   1886                               &rval64, BST_CFAP_INTf, 0);
   1887         soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r,
   1888                               &rval64, BST_THDO_INTf, 0);
   1889         soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r,
   1890                               &rval64, BST_THDI_INTf, 0);
   1891         BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STAT_64r(unit, rval64));
   1892     } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_STATr)) {
   1893         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   1894         soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval,
   1895                           BST_CFAP_INTf, 0);
   1896         soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval,
   1897                           BST_THDO_INTf, 0);
   1898         soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval,
   1899                           BST_THDI_INTf, 0);
   1900         BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, rval));
   1901     }
   1902 
   1903     return BCM_E_NONE;
   1904 }
   1905 
   1906 int
   1907 _bcm_bst_hw_event_cb(int unit)
   1908 {
   1909     
   1910     _bcm_bst_cmn_unit_info_t *bst_info;
   1911     bst_info = _BCM_UNIT_BST_INFO(unit);
   1912 
   1913     if ((!bst_info) || (bst_info->bst_trigger == NULL)) {
   1914         return 0;
   1915     }
   1916     if (bst_info->intr_enable_set) {
   1917         bst_info->intr_enable_set(unit, 0);
   1918     }
   1919     sal_sem_give(bst_info->bst_trigger);
   1920     return 0;
   1921 }
   1922 
   1923 STATIC void
   1924 _bcm_bst_sync_thread(void *cookie)
   1925 {
   1926     int unit;
   1927     uint32 res_flags = 0;
   1928     _bcm_bst_cmn_unit_info_t *bst_info;
   1929 
   1930     unit = PTR_TO_INT(cookie);
   1931 
   1932     bst_info = _BCM_UNIT_BST_INFO(unit);
   1933     if (!bst_info) {
   1934         sal_thread_exit(0);
   1935         return;
   1936     }
   1937 
   1938     if (bst_info->hw_intr_cb) {
   1939         bst_info->hw_intr_cb(unit);
   1940     }
   1941 
   1942     if (bst_info->intr_enable_set) {
   1943         bst_info->intr_enable_set(unit, 1);
   1944     }
   1945 
   1946     /* When Thread VALID flag is disabled, loop should break,
   1947      * thread must exit.
   1948      */
   1949     while (_bcm_bst_sync_thread_ok_to_run(unit) == TRUE) {
   1950         /* When Thread ENABLE flag is disabled, thread operations are paused
   1951          * until ENABLE flag is enabled.
   1952          */
   1953         if (_BCM_BST_SYNC_ENABLED(bst_info) == TRUE) {
   1954             if (bst_info->bst_trigger) {
   1955 
   1956                 /*
   1957                 _bst_intr_enable_set(unit, 1);
   1958                 */
   1959 
   1960                 if (sal_sem_take(bst_info->bst_trigger, bst_info->interval) < 0) {
   1961                     if (bst_info->interval <= 0) {
   1962                         break;
   1963                     }
   1964                     continue;
   1965                 }
   1966             } else {
   1967                 sal_usleep(bst_info->interval);
   1968             }
   1969 
   1970             if (bst_info->interval <= 0) {
   1971                 break;
   1972             }
   1973 
   1974             res_flags = 0;
   1975             if (bst_info->intr_to_resources) {
   1976                 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   1977                 bst_info->intr_to_resources(unit, &res_flags);
   1978                 sal_mutex_give(bst_info->bst_reslock);
   1979             }
   1980         } else {
   1981             sal_usleep(bst_info->interval);
   1982         }
   1983     }
   1984 
   1985     if (bst_info->intr_enable_set) {
   1986         bst_info->intr_enable_set(unit, 0);
   1987     }
   1988     bst_info->sync_flags &= ~_BCM_BST_SYNC_F_ENABLE;
   1989     bst_info->sync_flags &= ~_BCM_BST_SYNC_F_THREAD_VALID;
   1990 
   1991     sal_sem_give(bst_info->bst_thread);
   1992     sal_thread_exit(0);
   1993     return;
   1994 }
   1995 
   1996 int 
   1997 _bcm_bst_sync_thread_start(int unit)
   1998 {
   1999     _bcm_bst_cmn_unit_info_t *bst_info;
   2000     int rv = BCM_E_NONE;
   2001 
   2002     bst_info = _BCM_UNIT_BST_INFO(unit);
   2003     if (!bst_info) {
   2004         return BCM_E_INIT;
   2005     }
   2006 
   2007     if (_BCM_BST_SYNC_THREAD_VALID(bst_info)) {
   2008         return BCM_E_NONE;
   2009     }
   2010 
   2011     if (bst_info->hw_sbusdma_desc_init) {
   2012         rv = bst_info->hw_sbusdma_desc_init(unit);
   2013         if (BCM_FAILURE(rv)) {
   2014             BCM_IF_ERROR_RETURN(bst_info->hw_sbusdma_desc_deinit(unit));
   2015             LOG_ERROR(BSL_LS_SOC_COMMON,
   2016                      (BSL_META_U(unit, "hw_sbusdma_desc_init failed rv = %d\n"), rv));
   2017             return BCM_E_INIT;
   2018         }
   2019     }
   2020 
   2021     bst_info->sync_flags |= _BCM_BST_SYNC_F_THREAD_VALID;
   2022     bst_info->interval = 1000000;
   2023     bst_info->bst_thread_id = sal_thread_create("bcm_bst_sync_thread",
   2024                                                 SAL_THREAD_STKSZ,
   2025                                                 soc_property_get(unit, spn_BST_SYNC_THREAD_PRI, 50),
   2026                                                 _bcm_bst_sync_thread, 
   2027                                                 INT_TO_PTR(unit));
   2028 
   2029     _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, TRUE);
   2030     return rv;
   2031 }
   2032 
   2033 int 
   2034 _bcm_bst_sync_thread_stop(int unit)
   2035 {
   2036     _bcm_bst_cmn_unit_info_t *bst_info;
   2037 
   2038     bst_info = _BCM_UNIT_BST_INFO(unit);
   2039     if (!bst_info) {
   2040         return BCM_E_INIT;
   2041     }
   2042 
   2043     if (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) {
   2044         return BCM_E_NONE;
   2045     }
   2046 
   2047     bst_info->sync_flags &= ~_BCM_BST_SYNC_F_ENABLE;
   2048     bst_info->sync_flags &= ~_BCM_BST_SYNC_F_THREAD_VALID;
   2049 
   2050     if (bst_info->bst_trigger) {
   2051         sal_sem_give(bst_info->bst_trigger);
   2052     }
   2053 
   2054     /* If thread already running wait for it to be done before stopping */
   2055     (void)sal_sem_take(bst_info->bst_thread, sal_sem_FOREVER);
   2056 
   2057     if (bst_info->hw_sbusdma_desc_deinit) {
   2058         BCM_IF_ERROR_RETURN(bst_info->hw_sbusdma_desc_deinit(unit));
   2059     }
   2060 
   2061     return BCM_E_NONE;    
   2062 }
   2063 
   2064 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   2065     defined(BCM_APACHE_SUPPORT)
   2066 STATIC int
   2067 _bcm_bst_check_intr_status(int unit, bcm_bst_stat_id_t bid)
   2068 {
   2069     soc_field_t fld = INVALIDf;
   2070     _bcm_bst_resource_info_t *resInfo;
   2071     uint64 rval64;
   2072     uint32 rval;
   2073     uint32 fval = 0;
   2074 
   2075     resInfo = _BCM_BST_RESOURCE(unit, bid);
   2076 
   2077     if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) {
   2078         fld = BST_CFAP_INTf;
   2079     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) {
   2080         fld = BST_THDI_INTf;
   2081     } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) {
   2082         fld = BST_THDO_INTf;
   2083     }
   2084     
   2085     if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) {
   2086         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64));
   2087         fval = soc_reg64_field32_get(unit, MEM_FAIL_INT_STAT_64r,
   2088                                     rval64, fld);
   2089     } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) {
   2090         BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   2091         fval = soc_reg_field_get(unit, MEM_FAIL_INT_STATr, rval,
   2092                                 fld);
   2093     }
   2094     return fval;
   2095 }
   2096 #endif
   2097 #endif
   2098 
   2099 int
   2100 _bcm_bst_cmn_profile_delete_hw(int unit, bcm_bst_stat_id_t bid, 
   2101                                int id, int profile_index)
   2102 {
   2103     _bcm_bst_resource_info_t *resInfo;
   2104     
   2105     resInfo = _BCM_BST_RESOURCE(unit, bid);
   2106 
   2107     if (resInfo->profile_r[id]) {
   2108         SOC_IF_ERROR_RETURN
   2109             (soc_profile_reg_delete(unit, resInfo->profile_r[id], profile_index));
   2110     } else if (resInfo->profile_m) {
   2111         SOC_IF_ERROR_RETURN
   2112             (soc_profile_mem_delete(unit, resInfo->profile_m, profile_index));
   2113     } else {
   2114         return BCM_E_INIT;
   2115     }
   2116     
   2117     return BCM_E_NONE;
   2118 }
   2119 
   2120 STATIC int
   2121 _bcm_bst_default_profile_init(int unit)
   2122 {
   2123     _bcm_bst_cmn_unit_info_t *bst_info;
   2124     _bcm_bst_resource_info_t *resInfo;
   2125     int ei, pipe, index_max = 0;
   2126     bcm_bst_stat_id_t bid;
   2127     int entry_size;
   2128     bcm_cosq_bst_profile_t profile;
   2129     int i, wb = 0;
   2130     uint32 profile_index;
   2131 
   2132     wb = SOC_WARM_BOOT(unit) ? 1 : 0;
   2133 
   2134     bst_info = _BCM_UNIT_BST_INFO(unit);
   2135 
   2136     if (bst_info->profile_init) {
   2137         return bst_info->profile_init(unit);
   2138     }
   2139 
   2140     _BCM_BST_RESOURCE_ITER(bst_info, bid) {
   2141         resInfo = _BCM_BST_RESOURCE(unit, bid);
   2142 
   2143         if ((resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) == 0) {
   2144             continue;
   2145         }
   2146     
   2147         for (i = 0; i < _BCM_MAX_PROFILES; i ++) {
   2148             resInfo->profile_r[i] = NULL;
   2149         }
   2150         resInfo->profile_m = NULL;
   2151         if (resInfo->profile_mem != INVALIDm) {
   2152             soc_profile_mem_t_init(&resInfo->iprofile_m);
   2153             entry_size = soc_mem_entry_bytes(unit, resInfo->profile_mem);
   2154             SOC_IF_ERROR_RETURN(
   2155                 soc_profile_mem_create(unit, &resInfo->profile_mem, 
   2156                                    &entry_size, 1, &resInfo->iprofile_m));
   2157             resInfo->profile_m = &resInfo->iprofile_m;
   2158         } else if (resInfo->profile_reg[0] != INVALIDr) {
   2159             soc_profile_reg_t_init(&resInfo->iprofile_r[0]);
   2160             SOC_IF_ERROR_RETURN
   2161                 (soc_profile_reg_create(unit, &resInfo->profile_reg[0], 
   2162                                         1, &resInfo->iprofile_r[0]));
   2163             resInfo->profile_r[0] = &resInfo->iprofile_r[0];
   2164         }
   2165     }
   2166 
   2167     /* create default profiles. */
   2168     _BCM_BST_RESOURCE_ITER(bst_info, bid) {
   2169         profile.byte = bst_info->max_bytes;
   2170         resInfo = _BCM_BST_RESOURCE(unit, bid);
   2171         if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
   2172 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2173             if (SOC_IS_TD2_TT2(unit)) {
   2174                 if (resInfo->threshold_gran != 0) {
   2175                     profile.byte = bst_info->to_byte(unit,
   2176                         BST_THRESHOLD_MAX_HIGH - (resInfo->threshold_gran - 1));
   2177                 }
   2178             }
   2179 #endif
   2180             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2181                 if ((resInfo->threshold_mem[pipe] == INVALIDm) && 
   2182                     (resInfo->threshold_reg[pipe] == INVALIDr)) {
   2183                     continue;
   2184                 }
   2185                 
   2186                 if (!wb) {
   2187                     SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw(unit, pipe, 
   2188                         BCM_BST_DUP_XPE, -1, bid, &profile, &profile_index));
   2189                 }
   2190                 if (SOC_IS_TOMAHAWKX(unit)) {
   2191                     /* TH has 4 MMU instances unlike previous devices
   2192                        where MMU instance is 1 */
   2193                     index_max = resInfo->index_max / (NUM_PIPE(unit) *
   2194                                 resInfo->num_instance);
   2195                 } else {
   2196                     index_max = resInfo->index_max / NUM_PIPE(unit);
   2197                 }
   2198                 for (ei = resInfo->index_min; ei < index_max; ei++) {
   2199                     if (wb) {
   2200                         SOC_IF_ERROR_RETURN(
   2201                            _bcm_bst_cmn_io_op(unit,
   2202                                               BST_OP_GET | BST_OP_THD,
   2203                                               pipe, ei, bid,
   2204                                               resInfo->threshold_mem[pipe],
   2205                                               resInfo->threshold_reg[pipe],
   2206                                               resInfo->threshold_field,
   2207                                               &profile_index));
   2208                     }
   2209 
   2210 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2211                     if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) &&
   2212                         !SOC_IS_TRIDENT3X(unit)) {
   2213                         if (((bid == bcmBstStatIdPriGroupHeadroom) && 
   2214                              (bst_info->mode == 1)) ||
   2215                              ((bid == bcmBstStatIdPriGroupShared) && 
   2216                               (bst_info->mode == 0))) {
   2217                             break;
   2218                         }
   2219                     }
   2220 #endif
   2221                     if (resInfo->profile_r[0]) {
   2222                         BCM_IF_ERROR_RETURN(soc_profile_reg_reference(unit,
   2223                                resInfo->profile_r[0], profile_index, 1));
   2224                     } else if (resInfo->profile_m) {
   2225                         BCM_IF_ERROR_RETURN(soc_profile_mem_reference(unit,
   2226                                resInfo->profile_m, profile_index, 1));
   2227                     }
   2228                 }
   2229             }
   2230         } 
   2231     }
   2232     
   2233 #if defined(BCM_TRIDENT2_SUPPORT)
   2234     if (SOC_IS_TRIDENT2(unit)) {
   2235         /* Set default threshold for bcmBstStatIdDevice and bcmBstStatIdIngPool
   2236          * from zero to max to avoid unexpected trigger.
   2237          */
   2238         int pool_num = 4;
   2239         bcm_cosq_bst_profile_t_init(&profile);
   2240         profile.byte = bst_info->max_bytes;
   2241         for (ei = 0; ei < pool_num; ei++) {
   2242             SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw
   2243                 (unit, -1, BCM_BST_DUP_XPE, ei, 
   2244                     bcmBstStatIdIngPool, &profile, NULL));
   2245         }
   2246         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CFAPBSTTHRSr,
   2247                                         REG_PORT_ANY, BST_THRESHOLDf,
   2248                                         BST_THRESHOLD_MAX_HIGH));
   2249     }
   2250 #endif
   2251 
   2252     return BCM_E_NONE;
   2253 }
   2254 
   2255 int _bcm_bst_attach(int unit, _bcm_bst_device_handlers_t *cbs)
   2256 {
   2257     _bcm_bst_cmn_unit_info_t *bst_info;
   2258 
   2259     (void)_bcm_bst_detach(unit);
   2260 
   2261     bst_info = _BCM_UNIT_BST_INFO(unit);
   2262 
   2263     if (NULL == bst_info) {
   2264         bst_info = sal_alloc(sizeof(_bcm_bst_cmn_unit_info_t), "bst_dev_info");
   2265         if (!bst_info) {
   2266             return BCM_E_MEMORY;
   2267         }
   2268     }
   2269 
   2270     sal_memset(bst_info, 0, sizeof(_bcm_bst_cmn_unit_info_t));
   2271 
   2272     if (cbs) {
   2273         sal_memcpy(&bst_info->handlers, cbs, sizeof(_bcm_bst_device_handlers_t));
   2274     }
   2275 
   2276     _BCM_UNIT_BST_INFO(unit) = bst_info;
   2277 
   2278      if (bst_info->bst_trigger == NULL) {
   2279         bst_info->bst_trigger = sal_sem_create("bst_trigger", sal_sem_BINARY, 0);
   2280     }
   2281 
   2282     if (bst_info->bst_trigger == NULL) {
   2283         (void)_bcm_bst_detach(unit);
   2284         return BCM_E_MEMORY;
   2285     }
   2286 
   2287     if (bst_info->bst_thread == NULL) {
   2288         bst_info->bst_thread = sal_sem_create("bst_thread", sal_sem_BINARY, 0);
   2289     }
   2290 
   2291     if (bst_info->bst_thread == NULL) {
   2292         (void)_bcm_bst_detach(unit);
   2293         return BCM_E_MEMORY;
   2294     }
   2295 
   2296     /* Create protection mutex. */
   2297     if (bst_info->bst_reslock == NULL) {
   2298         bst_info->bst_reslock = sal_mutex_create("bst_resource_lock");
   2299     }
   2300     
   2301     if (bst_info->bst_reslock == NULL) {
   2302         (void)_bcm_bst_detach(unit);
   2303         return BCM_E_MEMORY;
   2304     }
   2305 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2306     if (SOC_IS_TOMAHAWK3(unit)) {
   2307         SOC_IF_ERROR_RETURN(bcm_bst_th3_init(unit));
   2308     } else
   2309 #endif
   2310 #if defined(BCM_TOMAHAWK_SUPPORT)
   2311     if (SOC_IS_TOMAHAWKX(unit)) {
   2312         SOC_IF_ERROR_RETURN(bcm_bst_th_init(unit));
   2313     } else
   2314 #endif
   2315 #if defined(BCM_HELIX5_SUPPORT)
   2316     if (SOC_IS_HELIX5(unit)) {
   2317         SOC_IF_ERROR_RETURN(bcm_bst_hx5_init(unit));
   2318     } else
   2319 #endif
   2320 #if defined(BCM_TRIDENT3_SUPPORT)
   2321     if (SOC_IS_TRIDENT3X(unit)) {
   2322         SOC_IF_ERROR_RETURN(bcm_bst_td3_init(unit));
   2323     } else
   2324 #endif
   2325 #if defined(BCM_TRIUMPH3_SUPPORT)
   2326     if (SOC_IS_TRIUMPH3(unit)) {
   2327         SOC_IF_ERROR_RETURN(_bcm_bst_triumph3_init(unit));
   2328     } else
   2329 #endif
   2330 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2331     if (SOC_IS_TD2_TT2(unit)) {
   2332         SOC_IF_ERROR_RETURN(_bcm_bst_td2_init(unit));
   2333     } else
   2334 #endif
   2335     {
   2336         return BCM_E_UNAVAIL;
   2337     }
   2338 
   2339     /* setup default profile. default profile is the max limit
   2340      * of the buffer sizes and is equivalent of being disabled.
   2341      */
   2342 
   2343     SOC_IF_ERROR_RETURN(_bcm_bst_default_profile_init(unit));
   2344 
   2345 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2346     if (SOC_WARM_BOOT(unit) && (SOC_IS_TRIDENT2(unit) || 
   2347         SOC_IS_APACHE(unit))) {
   2348         BCM_IF_ERROR_RETURN(_bcm_td2_bst_info_restore(unit));
   2349         BCM_IF_ERROR_RETURN(_bcm_td2_bst_resource_threshold_restore(unit));
   2350         if (_bcm_td2_bst_sync_thread_restore(unit) == TRUE) {
   2351             BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit));
   2352         }
   2353     } else
   2354 #endif
   2355     {
   2356         /* Initialize the trigger and Snapshot regs */
   2357         if (bst_info->hw_trigger_reset) {
   2358             bst_info->hw_trigger_reset(unit, -1);
   2359         }
   2360     }
   2361 
   2362     return BCM_E_NONE;
   2363 }
   2364 
   2365 int _bcm_bst_detach(int unit)
   2366 {
   2367     _bcm_bst_cmn_unit_info_t *bst_info;
   2368     _bcm_bst_resource_info_t *resInfo;
   2369     bcm_bst_stat_id_t bid;
   2370     int i;
   2371 
   2372     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2373         return BCM_E_NONE;
   2374     }
   2375 
   2376 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   2377     defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \
   2378     defined(BCM_APACHE_SUPPORT)
   2379     BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit));
   2380 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_TRIDENT2_SUPPORT || BCM_TOMAHAWK_SUPPORT
   2381         * BCM_TRIDENT3_SUPPORT || BCM_APACHE_SUPPORT
   2382         */
   2383 
   2384     _BCM_BST_RESOURCE_ITER(bst_info, bid) {
   2385         resInfo = _BCM_BST_RESOURCE(unit, bid);
   2386         if (resInfo->p_stat) {
   2387             sal_free(resInfo->p_stat);
   2388             resInfo->p_stat = NULL;
   2389         }
   2390         if (resInfo->p_threshold) {
   2391             sal_free(resInfo->p_threshold);
   2392             resInfo->p_threshold = NULL;
   2393         }
   2394         soc_profile_mem_destroy(unit, &resInfo->iprofile_m);
   2395         for (i = 0; i < _BCM_MAX_PROFILES; i++) {
   2396             soc_profile_reg_destroy(unit, &resInfo->iprofile_r[i]);
   2397             resInfo->profile_r[i] = NULL;
   2398         }
   2399         resInfo->profile_m = NULL;
   2400     }
   2401 
   2402     sal_sem_destroy(bst_info->bst_trigger);
   2403     sal_sem_destroy(bst_info->bst_thread);
   2404     sal_mutex_destroy(bst_info->bst_reslock);
   2405     bst_info->bst_trigger = NULL;
   2406     bst_info->bst_thread = NULL;
   2407     bst_info->bst_reslock = NULL;
   2408 
   2409     sal_free(bst_info);
   2410 
   2411     _BCM_UNIT_BST_INFO(unit) = NULL;
   2412 
   2413     return BCM_E_NONE;
   2414 }
   2415 
   2416 int _bst_thd_reg_index_get(int unit, bcm_bst_stat_id_t bid, int pipe,
   2417                            int hw_index, int *inst, int *index)
   2418 {
   2419     if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
   2420         int phy_port, mmu_port, mmu_port_base;
   2421         soc_info_t *si = &SOC_INFO(unit);
   2422 
   2423         mmu_port_base = 64 * pipe;
   2424         mmu_port = hw_index / 4;
   2425         phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base];
   2426         *inst = si->port_p2l_mapping[phy_port];
   2427         *index = hw_index % 4;
   2428     }
   2429 
   2430     return BCM_E_NONE;
   2431 }
   2432 
   2433 STATIC int
   2434 _bcm_bst_cmn_io_op(int unit, int op, int pipe, int hw_index,
   2435                    bcm_bst_stat_id_t bid, soc_mem_t mem, soc_reg_t reg,
   2436                    soc_field_t field, uint32 *resval)
   2437 {
   2438     uint32 entry[SOC_MAX_MEM_WORDS], rval;
   2439     int port = REG_PORT_ANY, reg_index = hw_index;
   2440     _bcm_bst_resource_info_t *resInfo;
   2441 #if defined(BCM_TOMAHAWK_SUPPORT)
   2442     _bcm_bst_cmn_unit_info_t *bst_info = NULL;
   2443 #endif
   2444 
   2445 #if defined(BCM_TOMAHAWK_SUPPORT)
   2446     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   2447         if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2448             return BCM_E_INIT;
   2449         }
   2450 
   2451         return bst_info->bst_cmn_io_op(unit, op, pipe, hw_index, bid,
   2452                                        mem, reg, field, resval);
   2453     }
   2454 #endif
   2455   resInfo = _BCM_BST_RESOURCE(unit, bid);
   2456   if ((resInfo->flags & _BCM_BST_CMN_RES_F_PORTED) &&
   2457      (op & BST_OP_THD)) {
   2458       BCM_IF_ERROR_RETURN(
   2459        _bst_thd_reg_index_get(unit, bid, pipe, hw_index,
   2460                                  &port, &reg_index));
   2461       if ((bid == bcmBstStatIdEgrPortPoolSharedMcast) && (port == -1)) {
   2462            port = REG_PORT_ANY;
   2463       }
   2464   }
   2465 
   2466     if (mem != INVALIDm) {
   2467         SOC_IF_ERROR_RETURN(
   2468             soc_mem_read(unit, mem, MEM_BLOCK_ALL, reg_index, entry));
   2469         if (op & BST_OP_GET) {
   2470             *resval = soc_mem_field32_get(unit, mem, entry, field);
   2471         } else if (op & BST_OP_SET) {
   2472             soc_mem_field32_set(unit, mem, entry, field, *resval);
   2473             SOC_IF_ERROR_RETURN(
   2474                 soc_mem_write(unit, mem, MEM_BLOCK_ALL, reg_index, entry));
   2475         }
   2476     } else if (reg != INVALIDr) {
   2477         SOC_IF_ERROR_RETURN(
   2478             soc_reg32_get(unit, reg, port, reg_index, &rval));
   2479         if (op & BST_OP_GET) {
   2480             *resval = soc_reg_field_get(unit, reg, rval, field);
   2481         } else if (op & BST_OP_SET) {
   2482             if (*resval >= (1 << soc_reg_field_length(unit, reg, field))) {
   2483                 return BCM_E_PARAM;
   2484             }
   2485             soc_reg_field_set(unit, reg, &rval, field, *resval);
   2486             SOC_IF_ERROR_RETURN(
   2487                 soc_reg32_set(unit, reg, port, reg_index, rval));
   2488         }
   2489     }
   2490 
   2491     return BCM_E_NONE;
   2492 }
   2493 
   2494 STATIC int 
   2495 _bcm_bst_cmn_profile_set_hw(int unit, int pipe, int xpe, int hw_index, 
   2496                             bcm_bst_stat_id_t bid,
   2497                             bcm_cosq_bst_profile_t *profile, 
   2498                             uint32 *p_profile)
   2499 {
   2500     uint32 cells;
   2501     _bcm_bst_cmn_unit_info_t *bst_info;
   2502     _bcm_bst_resource_info_t *resInfo;
   2503     uint32 profile_index = 0xffffffff, old_profile_index = 0xffffffff;
   2504     uint32 entry[SOC_MAX_MEM_WORDS];
   2505     uint64 rval, *rvals[1];
   2506     void *entries[1];
   2507     int pipe_factor = 1, pipe_offset = 0;
   2508 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2509     _bcm_bst_resource_info_t *resInfo1 = NULL;
   2510     int index = 0 , num_entries = 0;
   2511     int start_idx = 0;
   2512 #endif
   2513 
   2514     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2515         return BCM_E_INIT;
   2516     }
   2517 
   2518     if ((bid >= bcmBstStatIdMaxCount) || (profile == NULL)) {
   2519         return BCM_E_PARAM;
   2520     }
   2521 
   2522     if (p_profile) {
   2523         *p_profile = -1;
   2524     }
   2525 
   2526     resInfo = _BCM_BST_RESOURCE(unit, bid);
   2527 
   2528     if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   2529         return BCM_E_UNAVAIL;
   2530     }
   2531 
   2532     if (bst_info->thd_set) {
   2533         return bst_info->thd_set(unit, pipe, xpe, hw_index, bid, 
   2534             profile, p_profile);
   2535     }
   2536 
   2537     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   2538         pipe_factor = NUM_PIPE(unit);
   2539         if (pipe) {
   2540             if (resInfo->num_instance > 1) {
   2541                 pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor /
   2542                                       resInfo->num_instance);
   2543             } else {
   2544                 pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor);
   2545             }
   2546         }
   2547     } else {
   2548         pipe = 0;
   2549     }
   2550 
   2551     /* Taking granularity into count */
   2552     if (resInfo->threshold_gran != 0) {
   2553         cells = (bst_info->to_cell(unit, profile->byte) +
   2554                 resInfo->threshold_adj + resInfo->threshold_gran - 1) /
   2555                 resInfo->threshold_gran;
   2556     } else {
   2557         cells = bst_info->to_cell(unit, profile->byte) + resInfo->threshold_adj;
   2558     }
   2559 
   2560 #if defined(BCM_APACHE_SUPPORT)
   2561     if (SOC_IS_APACHE(unit)) {
   2562         if ((bid == bcmBstStatIdDevice) && (cells < _BCM_AP_BST_MIN_THRESHOLD_CELLS)) {
   2563             cells = _BCM_AP_BST_MIN_THRESHOLD_CELLS;
   2564         }
   2565     }
   2566 #endif
   2567 
   2568 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2569     if (SOC_IS_TD2_TT2(unit)) {
   2570         if (hw_index >= 0) {
   2571             if (BST_THRESHOLD_INVALID == profile->byte) {
   2572                 cells = BST_THRESHOLD_MAX_HIGH;
   2573             } else {
   2574                 resInfo->p_threshold[hw_index + pipe_offset] = cells;
   2575             }
   2576         }
   2577     } else
   2578 #endif
   2579     {
   2580         if (hw_index >= 0) {
   2581             resInfo->p_threshold[hw_index + pipe_offset] = cells;
   2582         }
   2583     }
   2584 
   2585     if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
   2586         if (hw_index >= 0) {
   2587             SOC_IF_ERROR_RETURN(
   2588                _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD,
   2589                                   pipe, hw_index, bid,
   2590                                   resInfo->threshold_mem[pipe],
   2591                                   resInfo->threshold_reg[pipe],
   2592                                   resInfo->threshold_field,
   2593                                   &old_profile_index));
   2594         }
   2595 
   2596         if (resInfo->profile_r[0]) {
   2597             COMPILER_64_ZERO(rval);
   2598             soc_reg64_field32_set(unit, resInfo->profile_reg[0], &rval, 
   2599                               resInfo->profile_field, cells);
   2600             rvals[0] = &rval;
   2601 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2602             if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) &&
   2603                 !SOC_IS_TRIDENT3X(unit)) {
   2604                 if (((bid == bcmBstStatIdPriGroupHeadroom) &&
   2605                      (bst_info->mode == 1) ) ||
   2606                     ((bid == bcmBstStatIdPriGroupShared) && 
   2607                      (bst_info->mode == 0))) {
   2608                     num_entries = SOC_REG_NUMELS(unit,
   2609                             resInfo->profile_reg[0]);
   2610                     /*
   2611                      * start_idx is 0 only in case hw_index = -1
   2612                      */
   2613                     start_idx = hw_index < 0 ? 0: 1 ;
   2614                     for( index = start_idx; 
   2615                             index < num_entries ; index++ ) {
   2616                         /* Insert the new entries into profile table */
   2617                         SOC_IF_ERROR_RETURN(soc_reg_set(unit, 
   2618                                     resInfo->profile_reg[0], REG_PORT_ANY,
   2619                                     index, 
   2620                                     rval));
   2621                     }
   2622                     if ( hw_index >= 0) {
   2623                         old_profile_index = profile_index = 0xffffffff ;
   2624                     } else {
   2625                         profile_index = 0 ;
   2626                     }
   2627                 }  else {
   2628                     SOC_IF_ERROR_RETURN(soc_profile_reg_add(unit,
   2629                                 resInfo->profile_r[0],
   2630                                 rvals, 1,
   2631                                 &profile_index));
   2632                 }
   2633             } else
   2634 #endif
   2635             {
   2636                 SOC_IF_ERROR_RETURN(soc_profile_reg_add(unit,
   2637                             resInfo->profile_r[0],
   2638                             rvals, 1,
   2639                             &profile_index));
   2640 
   2641             }
   2642         } else if (resInfo->profile_m) {
   2643             sal_memset(entry, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS);
   2644             soc_mem_field32_set(unit, resInfo->profile_mem, &entry,
   2645                                 resInfo->profile_field, cells);
   2646             entries[0] = entry;
   2647             SOC_IF_ERROR_RETURN(soc_profile_mem_add(unit,
   2648                                                     resInfo->profile_m,
   2649                                                     entries, 1,
   2650                                                     &profile_index));
   2651         }
   2652 
   2653         /* attach the profile id for the resource */
   2654         if (profile_index != 0xffffffff) {
   2655 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2656             if ((SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit)
   2657                 || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit))
   2658                 && (bid == bcmBstStatIdMcast)) {
   2659                 uint32 value = 0;
   2660                 soc_reg_field_set(unit, MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILEr,
   2661                     &value, THRESHOLDf, cells);
   2662                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit,
   2663                     MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILEr,
   2664                     REG_PORT_ANY, profile_index, value));
   2665             }
   2666 #endif /* BCM_TRIDENT2_SUPPORT */
   2667 
   2668             if (hw_index >= 0) {
   2669 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2670                 if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) &&
   2671                     !SOC_IS_TRIDENT3X(unit)) {
   2672                     if (((bid == bcmBstStatIdPriGroupHeadroom) &&
   2673                          (bst_info->mode == 0)) ||
   2674                         ((bid == bcmBstStatIdPriGroupShared) &&
   2675                          (bst_info->mode == 1))) {
   2676                         if ( bid == bcmBstStatIdPriGroupShared ) {
   2677                             resInfo1 = _BCM_BST_RESOURCE(unit,
   2678                                     bcmBstStatIdPriGroupHeadroom);
   2679                             if (!_BCM_BST_RESOURCE_VALID(resInfo1)) {
   2680                                 return BCM_E_UNAVAIL;
   2681                             }
   2682                         } else if ( bid == bcmBstStatIdPriGroupHeadroom) {
   2683                             resInfo1 = _BCM_BST_RESOURCE(unit,
   2684                                     bcmBstStatIdPriGroupShared);
   2685                             if (!_BCM_BST_RESOURCE_VALID(resInfo1)) {
   2686                                 return BCM_E_UNAVAIL;
   2687                             }
   2688                         }
   2689                         SOC_IF_ERROR_RETURN(
   2690                             _bcm_bst_cmn_io_op(unit,
   2691                                                BST_OP_SET | BST_OP_THD,
   2692                                                pipe, hw_index, bid,
   2693                                                resInfo1->threshold_mem[pipe],
   2694                                                resInfo1->threshold_reg[pipe],
   2695                                                resInfo1->threshold_field,
   2696                                                &profile_index));
   2697 
   2698                     }
   2699                 }
   2700 #endif
   2701                 SOC_IF_ERROR_RETURN(
   2702                     _bcm_bst_cmn_io_op(unit, BST_OP_SET | BST_OP_THD,
   2703                                        pipe, hw_index, bid,
   2704                                        resInfo->threshold_mem[pipe],
   2705                                        resInfo->threshold_reg[pipe],
   2706                                        resInfo->threshold_field,
   2707                                        &profile_index));
   2708             }
   2709             if (p_profile) {
   2710                 *p_profile = profile_index;
   2711             }
   2712         }
   2713 
   2714         if (old_profile_index != 0xffffffff) {
   2715             SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_delete_hw(unit, bid,
   2716                                                     0, old_profile_index));
   2717         }
   2718     } else {
   2719         SOC_IF_ERROR_RETURN(
   2720             _bcm_bst_cmn_io_op(unit, BST_OP_SET | BST_OP_THD,
   2721                                pipe, hw_index, bid,
   2722                                resInfo->threshold_mem[pipe],
   2723                                resInfo->threshold_reg[pipe],
   2724                                resInfo->threshold_field,
   2725                                &cells));
   2726     }
   2727 
   2728 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   2729     if (SOC_IS_TD2_TT2(unit)) {
   2730         if (bst_info->hw_trigger_set && cells && (BST_THRESHOLD_MAX_HIGH != cells)) {
   2731             bst_info->hw_trigger_set(unit, bid);
   2732         }
   2733     } else
   2734 #endif
   2735     {
   2736         if (bst_info->hw_trigger_set && cells) {
   2737             bst_info->hw_trigger_set(unit, bid);
   2738         }
   2739     }
   2740     return BCM_E_NONE;
   2741 }
   2742 
   2743 STATIC int 
   2744 _bcm_bst_cmn_profile_get_hw(int unit, int pipe, int xpe, int hw_index, 
   2745                             bcm_bst_stat_id_t bid, 
   2746                             bcm_cosq_bst_profile_t *profile)
   2747 {
   2748     _bcm_bst_cmn_unit_info_t *bst_info;
   2749     _bcm_bst_resource_info_t *resInfo;
   2750     uint32 profile_index;
   2751     uint32 cells;
   2752 
   2753     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2754         return BCM_E_INIT;
   2755     }
   2756 
   2757     if ((bid >= bcmBstStatIdMaxCount) || (profile == NULL)) {
   2758         return BCM_E_PARAM;
   2759     }
   2760 
   2761     resInfo = _BCM_BST_RESOURCE(unit, bid);
   2762 
   2763     if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   2764         return BCM_E_UNAVAIL;
   2765     }
   2766 
   2767     if (bst_info->thd_get) {
   2768         return bst_info->thd_get(unit, pipe, xpe, hw_index, bid, profile);
   2769     }
   2770 
   2771     if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) {
   2772         /* Dont use Pipe info, if the resource is Not Pipe specific */
   2773         pipe = 0;
   2774     }
   2775     /* attach the profile id for the resource */
   2776     if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) {
   2777         SOC_IF_ERROR_RETURN(
   2778            _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD,
   2779                               pipe, hw_index, bid,
   2780                               resInfo->threshold_mem[pipe],
   2781                               resInfo->threshold_reg[pipe],
   2782                               resInfo->threshold_field,
   2783                               &profile_index));
   2784 
   2785         SOC_IF_ERROR_RETURN(
   2786            _bcm_bst_cmn_io_op(unit, BST_OP_GET,
   2787                               pipe, profile_index, bid,
   2788                               resInfo->profile_mem,
   2789                               resInfo->profile_reg[0],
   2790                               resInfo->profile_field,
   2791                               &cells));
   2792     } else {
   2793         SOC_IF_ERROR_RETURN(
   2794            _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD,
   2795                               pipe, hw_index, bid,
   2796                               resInfo->threshold_mem[pipe],
   2797                               resInfo->threshold_reg[pipe],
   2798                               resInfo->threshold_field,
   2799                               &cells));
   2800     }
   2801 
   2802     /* Taking granularity into count */
   2803     if (resInfo->threshold_gran != 0) {
   2804         cells = cells * resInfo->threshold_gran - resInfo->threshold_adj;
   2805     } else {
   2806         cells -= resInfo->threshold_adj;
   2807     }
   2808 
   2809     profile->byte = bst_info->to_byte(unit, cells);
   2810 
   2811     return BCM_E_NONE;
   2812 }
   2813 
   2814 typedef enum _bcm_bst_cmn_op_e {
   2815     _BcmBstProfileGet = 0,
   2816     _BcmBstProfileSet
   2817 } _bcm_bst_cmn_op_t;
   2818 
   2819 
   2820 STATIC int
   2821 _bcm_bst_cmn_profile_op(int unit, _bcm_bst_cmn_op_t op,
   2822                         bcm_gport_t gport, bcm_cos_queue_t cosq, int xpe,
   2823                         bcm_bst_stat_id_t bid, bcm_cosq_bst_profile_t *profile)
   2824 {
   2825     _bcm_bst_cmn_unit_info_t *bst_info;
   2826     _bcm_bst_cb_ret_t rv;
   2827     void *cb_data = NULL; 
   2828     int bcm_rv, ii, rcb = 0, pipe;
   2829     int start_hw_index = 0, end_hw_index = 0;
   2830     _bcm_bst_resource_info_t *resInfo;
   2831 
   2832     /* Parameter check */
   2833     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   2834         return BCM_E_PARAM;
   2835     }
   2836 
   2837     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2838         return BCM_E_INIT;
   2839     }
   2840 
   2841     resInfo = _BCM_BST_RESOURCE(unit, bid);
   2842     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   2843         return BCM_E_PARAM;
   2844     }
   2845 
   2846     if (profile == NULL) {
   2847         return BCM_E_PARAM;
   2848     }
   2849 
   2850     if (bst_info->handlers.resolve_index == NULL) {
   2851         return BCM_E_UNAVAIL;
   2852     }
   2853 
   2854     do {
   2855         rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe, 
   2856                     &start_hw_index, &end_hw_index, &rcb, &cb_data, &bcm_rv);
   2857         if (bcm_rv) {
   2858             return bcm_rv;
   2859         }
   2860 
   2861         if (op == _BcmBstProfileGet) {
   2862             end_hw_index = start_hw_index;
   2863         }
   2864 
   2865         for (ii = start_hw_index; ii <= end_hw_index; ii++) {
   2866             if (op == _BcmBstProfileGet) {
   2867                 SOC_IF_ERROR_RETURN(
   2868                     _bcm_bst_cmn_profile_get_hw(unit, pipe, xpe, ii, bid, profile));
   2869             } else {
   2870                 SOC_IF_ERROR_RETURN(
   2871                     _bcm_bst_cmn_profile_set_hw(unit, pipe, xpe, ii, bid, profile, NULL));
   2872             }
   2873         }
   2874 
   2875         if (op == _BcmBstProfileGet) {
   2876             return BCM_E_NONE;
   2877         }
   2878 
   2879     } while (rv == _BCM_BST_RV_RETRY);
   2880 
   2881     return BCM_E_NONE;
   2882 }
   2883 
   2884 int
   2885 _bcm_bst_cmn_profile_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   2886                          int xpe, bcm_bst_stat_id_t bid, 
   2887                          bcm_cosq_bst_profile_t *profile)
   2888 {
   2889     BCM_IF_ERROR_RETURN(
   2890         _bcm_bst_cmn_profile_op(unit, _BcmBstProfileSet, gport, cosq, xpe, 
   2891                                 bid, profile));
   2892     return BCM_E_NONE;
   2893 }
   2894 
   2895 int
   2896 _bcm_bst_cmn_profile_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   2897                          int xpe, bcm_bst_stat_id_t bid, 
   2898                          bcm_cosq_bst_profile_t *profile)
   2899 {
   2900     BCM_IF_ERROR_RETURN(
   2901         _bcm_bst_cmn_profile_op(unit, _BcmBstProfileGet, gport, cosq, xpe, 
   2902                                 bid, profile));
   2903 
   2904     return BCM_E_NONE;
   2905 }
   2906 
   2907 int
   2908 _bcm_bst_cmn_stat_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   2909                       bcm_cosq_buffer_id_t buffer_id, bcm_bst_stat_id_t bid,
   2910                       uint32 options, uint64 *pvalue)
   2911 {
   2912     _bcm_bst_cmn_unit_info_t *bst_info;
   2913     _bcm_bst_resource_info_t *resInfo;
   2914     _bcm_bst_cb_ret_t rv;
   2915     void *cb_data = NULL; 
   2916     int bcm_rv, rcb = 0, ii, inst, entries_per_inst;
   2917     int start_hw_index = 0, end_hw_index = 0, pipe_offset = 0, pipe;
   2918 
   2919     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   2920         return BCM_E_PARAM;
   2921     }
   2922 
   2923     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   2924         return BCM_E_INIT;
   2925     }
   2926 
   2927     if (bst_info->handlers.resolve_index == NULL) {
   2928         return BCM_E_UNAVAIL;
   2929     }
   2930     COMPILER_64_ZERO(*pvalue);
   2931 
   2932     do {
   2933         rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe, 
   2934                     &start_hw_index, &end_hw_index, &rcb, &cb_data, &bcm_rv);
   2935         if (bcm_rv) {
   2936             return bcm_rv;
   2937         }
   2938 
   2939         resInfo = _BCM_BST_RESOURCE(unit, bid);
   2940         if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   2941             return BCM_E_PARAM;
   2942         }
   2943 
   2944         if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) {
   2945             pipe = 0;
   2946         }
   2947 
   2948         if (resInfo->num_instance > 1) {
   2949             uint32 mmu_inst_map = 0;
   2950             if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) {
   2951                 /* Dont use Pipe info, if the resource is Not Pipe specific */
   2952                 pipe = 0;
   2953             }
   2954             pipe_offset = pipe * (((resInfo->index_max + 1) / NUM_PIPE(unit)) /
   2955                                   resInfo->num_instance);
   2956             entries_per_inst = (resInfo->index_max + 1) / resInfo->num_instance;
   2957             if (bst_info->port_to_mmu_inst_map) {
   2958                 (void)bst_info->port_to_mmu_inst_map(unit, bid, gport,
   2959                                                      &mmu_inst_map);
   2960             }
   2961             /* When a resource has more than one instance, find the max value
   2962              * of all applicable instances and return the Max value.
   2963              */
   2964             for (ii = start_hw_index; ii <= end_hw_index; ii++) {
   2965                 int temp_stat = 0, max_stat = 0;
   2966                 if (buffer_id < 0 || buffer_id >= NUM_XPE(unit)) {
   2967                     for (inst = 0; inst < resInfo->num_instance; inst++) {
   2968                         if (mmu_inst_map & (1 << inst)) {
   2969                             temp_stat = resInfo->p_stat[pipe_offset + ii +
   2970                                                         (inst * entries_per_inst)];
   2971                             if (temp_stat > max_stat) {
   2972                                 max_stat = temp_stat;
   2973                             }
   2974                         }
   2975                     }
   2976                 } else {
   2977                     max_stat = resInfo->p_stat[pipe_offset + ii +
   2978                                                (buffer_id * entries_per_inst)];
   2979                 }
   2980                 COMPILER_64_ADD_32(*pvalue, max_stat);
   2981             }
   2982         } else {
   2983             if ((resInfo->stat_mem[pipe] != INVALIDm) || 
   2984                 (resInfo->stat_reg[pipe] != INVALIDr)) {
   2985                 pipe_offset = ((resInfo->index_max + 1) / NUM_PIPE(unit)) * pipe;
   2986             }
   2987 
   2988             for (ii = start_hw_index; ii <= end_hw_index; ii++) {
   2989                 COMPILER_64_ADD_32(*pvalue, resInfo->p_stat[ii + pipe_offset]);
   2990             }
   2991         }
   2992     } while (rv == _BCM_BST_RV_RETRY);
   2993 
   2994     bcm_rv = BCM_E_NONE;
   2995 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   2996     defined(BCM_APACHE_SUPPORT)
   2997     if (options & BCM_COSQ_STAT_CLEAR) {
   2998         int need_hw_stat_clear = 1;
   2999         sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   3000         if ((bst_info->track_mode == 1) &&
   3001             (bst_info->hw_cor_in_max_use_count == 1)) {
   3002             /* no need hw stat clear */
   3003             need_hw_stat_clear = 0;
   3004         }
   3005         if (bst_info->hw_stat_clear && (need_hw_stat_clear == 1)) {
   3006             (void)bst_info->hw_stat_clear(unit, resInfo, bid,
   3007                                           gport, start_hw_index);
   3008         }
   3009         bcm_rv = _bcm_bst_sw_stat_clear(unit, gport, cosq, bid);
   3010         sal_mutex_give(bst_info->bst_reslock);
   3011     }
   3012 
   3013     if (_bcm_bst_check_intr_status(unit, bid)) {
   3014         if (bst_info->intr_enable_set) {
   3015             bst_info->intr_enable_set(unit, 1);
   3016         }
   3017         _bst_intr_status_reset(unit);
   3018     }
   3019 #endif
   3020 
   3021     return bcm_rv;
   3022 }
   3023 
   3024 int _bcm_bst_cmn_stat_multi_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   3025             uint32 options, int max_values, bcm_bst_stat_id_t *id_list, uint64 *values)
   3026 {
   3027     int i;
   3028 
   3029     for (i = 0; i < max_values; i++) {
   3030         BCM_IF_ERROR_RETURN(_bcm_bst_cmn_stat_get(unit, gport, cosq, -1, id_list[i], 
   3031                             options, &values[i]));
   3032     }
   3033     
   3034     return BCM_E_NONE;
   3035 }
   3036 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
   3037     defined(BCM_APACHE_SUPPORT)
   3038 int _bcm_bst_cmn_stat_clear(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 
   3039                             bcm_bst_stat_id_t bid)
   3040 {
   3041     _bcm_bst_cmn_unit_info_t *bst_info;
   3042     _bcm_bst_resource_info_t *resInfo;
   3043     int bcm_rv = BCM_E_NONE;
   3044     _bcm_bst_cb_ret_t rv;
   3045     void *cb_data = NULL;
   3046     int rcb = 0;
   3047     int start_hw_index = 0, end_hw_index = 0, pipe;
   3048 
   3049     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   3050         return BCM_E_PARAM;
   3051     }
   3052    
   3053     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3054         return BCM_E_INIT;
   3055     }
   3056 
   3057     if (bst_info->handlers.resolve_index == NULL) {
   3058         return BCM_E_UNAVAIL;
   3059     }    
   3060 
   3061     /* sync all the stats */
   3062     resInfo = _BCM_BST_RESOURCE(unit, bid);
   3063     if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   3064         return BCM_E_PARAM;
   3065     }
   3066 
   3067     sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   3068     if (bst_info->hw_stat_clear) {
   3069         if (gport == -1) {
   3070             /* Clear all stat counters */
   3071             (void)bst_info->hw_stat_clear(unit, resInfo, bid, -1, -1);
   3072         } else {
   3073             /* Clear stat counter for given port, cos */
   3074             rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe,
   3075                                 &start_hw_index, &end_hw_index, &rcb,
   3076                                 &cb_data, &bcm_rv);
   3077             if (rv != _BCM_BST_RV_ERROR) {
   3078                 (void)bst_info->hw_stat_clear(unit, resInfo, bid, gport,
   3079                                               start_hw_index);
   3080             }
   3081         }
   3082     }
   3083 
   3084     if (gport == -1) {
   3085         bcm_port_t local_port;
   3086         PBMP_PORT_ITER(unit, local_port) {
   3087             bcm_rv = _bcm_bst_sw_stat_clear(unit, local_port, cosq, bid);
   3088             if (BCM_FAILURE(bcm_rv)) {
   3089                 break;
   3090             }
   3091         }
   3092     } else {
   3093         bcm_rv = _bcm_bst_sw_stat_clear(unit, gport, cosq, bid);
   3094     }
   3095     sal_mutex_give(bst_info->bst_reslock);
   3096 
   3097     return bcm_rv;
   3098 
   3099 }
   3100 #endif
   3101 int
   3102 _bcm_bst_cmn_stat_sync(int unit, bcm_bst_stat_id_t bid)
   3103 {
   3104     int rv = BCM_E_NONE;
   3105     _bcm_bst_cmn_unit_info_t *bst_info;
   3106     _bcm_bst_resource_info_t *resInfo;
   3107 
   3108     if (((bid < 0) && (bid != bcmBstStatIdInvalid)) ||
   3109         (bid >= bcmBstStatIdMaxCount)) {
   3110         return BCM_E_PARAM;
   3111     }
   3112 
   3113     bst_info = _BCM_UNIT_BST_INFO(unit);
   3114     if (!bst_info) {
   3115         return BCM_E_MEMORY;
   3116     }
   3117     if (bid == bcmBstStatIdInvalid) {
   3118         if (bst_info->hw_sbusdma_desc_sync) {
   3119             rv = bst_info->hw_sbusdma_desc_sync(unit);
   3120         } else {
   3121             return BCM_E_PARAM;
   3122         }
   3123     } else {
   3124 #ifdef BCM_TOMAHAWK3_SUPPORT
   3125         if (SOC_IS_TOMAHAWK3(unit)) {
   3126             if (bid == bcmBstStatIdUcast || bid == bcmBstStatIdMcast) {
   3127                 bid = bcmBstStatIdQueueTotal;
   3128             }
   3129         }
   3130 #endif
   3131         resInfo = _BCM_BST_RESOURCE(unit, bid);
   3132         if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) {
   3133             return BCM_E_PARAM;
   3134         }
   3135 
   3136         sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   3137     if (bst_info->hw_stat_snapshot) {
   3138         rv = bst_info->hw_stat_snapshot(unit, bid, -1, -1);
   3139     }
   3140         sal_mutex_give(bst_info->bst_reslock);
   3141     }
   3142 
   3143     return rv;
   3144 }
   3145 
   3146 int _bcm_bst_cmn_control_set(int unit, bcm_switch_control_t type, int arg)
   3147 {
   3148     _bcm_bst_cmn_unit_info_t *bst_info;
   3149    
   3150     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3151         return BCM_E_INIT;
   3152     }
   3153 
   3154     if (bst_info->control_set == NULL) {
   3155         return BCM_E_UNAVAIL;
   3156     }
   3157 
   3158     BCM_IF_ERROR_RETURN
   3159         (bst_info->control_set(unit, type, arg, _bcmBstThreadOperExternal));
   3160 
   3161     return BCM_E_NONE;
   3162 }
   3163 
   3164 int _bcm_bst_cmn_control_get(int unit, bcm_switch_control_t type, int *arg)
   3165 {
   3166     _bcm_bst_cmn_unit_info_t *bst_info;
   3167    
   3168     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3169         return BCM_E_INIT;
   3170     }
   3171 
   3172     if (bst_info->control_get == NULL) {
   3173         return BCM_E_UNAVAIL;
   3174     }
   3175 
   3176     return bst_info->control_get(unit, type, arg);
   3177 }
   3178 
   3179 #if defined(BCM_TRIUMPH3_SUPPORT)
   3180 
   3181 STATIC int
   3182 _bcm_bst_hw_stat_sync(int unit, _bcm_bst_resource_info_t *resInfo, 
   3183                     bcm_bst_stat_id_t bid, int port, int index)
   3184 {
   3185     _bcm_bst_cmn_unit_info_t *bst_info;
   3186     int rv, pipe;
   3187     uint32 rval;
   3188     soc_mem_t mem;
   3189     soc_reg_t reg;
   3190     int min_hw_idx, max_hw_idx, idx;
   3191     int pipe_factor = 1, pipe_offset = 0;
   3192     int num_entries, mem_wsz;
   3193     void *pentry;
   3194     char *dmabuf;
   3195     int sync_val = 0;    
   3196 
   3197     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   3198         return BCM_E_PARAM;
   3199     }
   3200    
   3201     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3202         return BCM_E_INIT;
   3203     }
   3204 
   3205     if (bst_info->pre_sync) {
   3206         bst_info->pre_sync(unit, bid, &sync_val);
   3207     }
   3208 
   3209     /* sync all the stats */
   3210     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   3211         pipe_factor = NUM_PIPE(unit);
   3212     }
   3213     if (index == -1) {
   3214         min_hw_idx = resInfo->index_min;
   3215         max_hw_idx = resInfo->index_max / pipe_factor;
   3216     } else {
   3217         min_hw_idx = max_hw_idx = index;
   3218     }
   3219 
   3220     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3221         if ((mem = resInfo->stat_mem[pipe]) != INVALIDm) {
   3222             num_entries = soc_mem_index_count(unit, mem);
   3223             mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem);
   3224 
   3225             dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf");
   3226             if (dmabuf == NULL) {
   3227                 return BCM_E_MEMORY;
   3228             }
   3229 
   3230             if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL,
   3231                                     soc_mem_index_min(unit, mem), 
   3232                                     soc_mem_index_max(unit, mem), 
   3233                                     dmabuf)) {
   3234                 soc_cm_sfree(unit, dmabuf);
   3235                 return BCM_E_INTERNAL;
   3236             }
   3237 
   3238             for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
   3239                 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
   3240                                                       dmabuf, idx);
   3241                 resInfo->p_stat[idx + pipe_offset] = 
   3242                     soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field);
   3243             }
   3244 
   3245             soc_cm_sfree(unit, dmabuf);
   3246         } else if (resInfo->profile_r[0]) {
   3247             pipe_offset += max_hw_idx;
   3248         } else if ((reg = resInfo->stat_reg[pipe]) != INVALIDr) {
   3249             for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
   3250                 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval);
   3251                 if (rv) {
   3252                     return BCM_E_INTERNAL;
   3253                 }
   3254                 resInfo->p_stat[idx] = soc_reg_field_get(unit, reg, 
   3255                                               rval, resInfo->stat_field);
   3256             }
   3257         } /* if valid reg */
   3258     } /* for each pipe */
   3259     
   3260     if (bst_info->post_sync) {
   3261         bst_info->post_sync(unit, bid, sync_val);
   3262     }
   3263 
   3264     return BCM_E_NONE;
   3265 }
   3266 
   3267 STATIC int
   3268 _bcm_bst_sw_stat_clear(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   3269                        bcm_bst_stat_id_t bid)
   3270 {
   3271     _bcm_bst_cmn_unit_info_t *bst_info;
   3272     _bcm_bst_resource_info_t *resInfo;
   3273     _bcm_bst_cb_ret_t rv;
   3274     void *cb_data = NULL;
   3275     int bcm_rv, rcb = 0, index;
   3276     int start_hw_index = 0, end_hw_index = 0, pipe_offset = 0, pipe;
   3277 
   3278     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   3279         return BCM_E_PARAM;
   3280     }
   3281 
   3282     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3283         return BCM_E_INIT;
   3284     }
   3285 
   3286     if (bst_info->handlers.resolve_index == NULL) {
   3287         return BCM_E_UNAVAIL;
   3288     }
   3289 
   3290     do {
   3291         rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe,
   3292                     &start_hw_index, &end_hw_index, &rcb, &cb_data, &bcm_rv);
   3293         if (bcm_rv) {
   3294             return bcm_rv;
   3295         }
   3296 
   3297         resInfo = _BCM_BST_RESOURCE(unit, bid);
   3298         if (resInfo == NULL) {
   3299             return BCM_E_PARAM;
   3300         }
   3301 
   3302         if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) {
   3303             pipe = 0;
   3304         }
   3305 
   3306         if (resInfo->num_instance > 1) {
   3307             uint32 mmu_inst_map = 0;
   3308             int entries_per_inst, inst_offset, inst;
   3309             if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) {
   3310                 /* Dont use Pipe info, if the resource is Not Pipe specific */
   3311                 pipe = 0;
   3312             }
   3313             pipe_offset = pipe * (((resInfo->index_max + 1) / NUM_PIPE(unit)) /
   3314                                   resInfo->num_instance);
   3315             entries_per_inst = (resInfo->index_max + 1) / resInfo->num_instance;
   3316             if (bst_info->port_to_mmu_inst_map) {
   3317                 (void)bst_info->port_to_mmu_inst_map(unit, bid, gport,
   3318                                                      &mmu_inst_map);
   3319             }
   3320             /* When a resource has more than one instance, clear all
   3321              * applicable instances.
   3322              */
   3323             for (index = start_hw_index; index <= end_hw_index; index++) {
   3324                 for (inst = 0; inst < resInfo->num_instance; inst++) {
   3325                     if (mmu_inst_map & (1 << inst)) {
   3326                         inst_offset = inst * entries_per_inst;
   3327                         resInfo->p_stat[pipe_offset + index + inst_offset] = 0;
   3328                     }
   3329                 }
   3330             }
   3331         } else {
   3332             if ((resInfo->stat_mem[pipe] != INVALIDm) || 
   3333                 (resInfo->stat_reg[pipe] != INVALIDr)) {
   3334                 pipe_offset = ((resInfo->index_max + 1) / NUM_PIPE(unit)) * pipe;
   3335             }
   3336 
   3337             for (index = start_hw_index; index <= end_hw_index; index++) {
   3338                 resInfo->p_stat[index + pipe_offset] = 0;
   3339             }
   3340         }
   3341     } while (rv == _BCM_BST_RV_RETRY);
   3342 
   3343     return BCM_E_NONE;
   3344 }
   3345 
   3346 int
   3347 _bcm_bst_hw_stat_clear(int unit, _bcm_bst_resource_info_t *resInfo, 
   3348                     bcm_bst_stat_id_t bid, int port, int index)
   3349 {
   3350     _bcm_bst_cmn_unit_info_t *bst_info;
   3351     int rv, pipe;
   3352     uint32 rval;
   3353     soc_mem_t mem;
   3354     soc_reg_t reg;
   3355     int min_hw_idx, max_hw_idx, idx;
   3356     int pipe_factor = 1, pipe_offset = 0;
   3357     int num_entries, mem_wsz;
   3358     void *pentry;
   3359     char *dmabuf;
   3360     int enable = 0;
   3361     int sync_val = 0;    
   3362 
   3363     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   3364         return BCM_E_PARAM;
   3365     }
   3366     
   3367     /* The bcmBstStatIdIngPool stat register THDI_BST_SP_GLOBAL_SHARED_CNT 
   3368        is a readonly register */
   3369     if (SOC_IS_TRIDENT2(unit)) {
   3370     if (bid == bcmBstStatIdIngPool && 
   3371         resInfo->stat_reg[0] == THDI_BST_SP_GLOBAL_SHARED_CNTr) {
   3372         return BCM_E_PARAM;
   3373     }
   3374     }
   3375    
   3376     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3377         return BCM_E_INIT;
   3378     }
   3379 
   3380     if (bst_info->pre_sync) {
   3381         bst_info->pre_sync(unit, bid, &sync_val);
   3382     }
   3383 
   3384     /* sync all the stats */
   3385     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   3386         pipe_factor = NUM_PIPE(unit);
   3387     }
   3388     if (index == -1) {
   3389         min_hw_idx = resInfo->index_min;
   3390         max_hw_idx = resInfo->index_max / pipe_factor;
   3391     } else {
   3392         min_hw_idx = max_hw_idx = index;
   3393     }
   3394 
   3395     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3396         if ((mem = resInfo->stat_mem[pipe]) != INVALIDm) {
   3397             if (index == -1) {
   3398                 BCM_IF_ERROR_RETURN(soc_mem_clear(unit, mem, COPYNO_ALL, TRUE));
   3399                 continue;
   3400             }
   3401 
   3402             num_entries = soc_mem_index_count(unit, mem);
   3403             mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem);            
   3404 
   3405             dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf");
   3406             if (dmabuf == NULL) {
   3407                 return BCM_E_MEMORY;
   3408             }
   3409 
   3410             if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL,
   3411                                     soc_mem_index_min(unit, mem), 
   3412                                     soc_mem_index_max(unit, mem), 
   3413                                     dmabuf)) {
   3414                 soc_cm_sfree(unit, dmabuf);
   3415                 return BCM_E_INTERNAL;
   3416             }
   3417 
   3418             /* Clear stat counter if requested */
   3419             for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
   3420                 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
   3421                                                       dmabuf, idx); 
   3422                 soc_mem_field32_set(unit, mem, pentry, resInfo->stat_field, 0);
   3423             }
   3424             
   3425             if (soc_mem_write_range(unit, mem, MEM_BLOCK_ALL,
   3426                                     soc_mem_index_min(unit, mem), 
   3427                                     soc_mem_index_max(unit, mem), 
   3428                                     dmabuf)) {
   3429                 soc_cm_sfree(unit, dmabuf);
   3430                 return BCM_E_INTERNAL;
   3431             } 
   3432             
   3433             soc_cm_sfree(unit, dmabuf);
   3434         } else if (resInfo->profile_r[0]) {
   3435             pipe_offset += max_hw_idx;
   3436         } else if ((reg = resInfo->stat_reg[pipe]) != INVALIDr) {
   3437             for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
   3438                 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval);
   3439                 if (rv) {
   3440                     return BCM_E_INTERNAL;
   3441                 }
   3442             }
   3443 
   3444             /* Clear stat counters */
   3445             if (bst_info->control_get) {
   3446                 bst_info->control_get(unit, bcmSwitchBstEnable, &enable);
   3447             }
   3448             if (enable && bst_info->control_set) {
   3449                 bst_info->control_set(unit, bcmSwitchBstEnable, 0,
   3450                                       _bcmBstThreadOperInternal);
   3451             }                
   3452 
   3453             for (idx = min_hw_idx; idx <= max_hw_idx; idx++) {
   3454                 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval);
   3455                 if (rv) {
   3456                     return BCM_E_INTERNAL;
   3457                 }                
   3458                 soc_reg_field_set(unit, reg, &rval, resInfo->stat_field, 0);
   3459                 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   3460             }
   3461 
   3462             if (enable && bst_info->control_set) {
   3463                 bst_info->control_set(unit, bcmSwitchBstEnable, enable,
   3464                                       _bcmBstThreadOperInternal);
   3465             }
   3466 
   3467         } /* if valid reg */
   3468     } /* for each pipe */
   3469     
   3470     if (bst_info->post_sync) {
   3471         bst_info->post_sync(unit, bid, sync_val);
   3472     }
   3473 
   3474     return BCM_E_NONE;
   3475 }
   3476 
   3477 int
   3478 _bcm_bst_sync_hw_trigger(int unit, bcm_bst_stat_id_t bid, int port, int index)
   3479 {
   3480     _bcm_bst_cmn_unit_info_t *bst_info;
   3481     _bcm_bst_resource_info_t *resInfo;
   3482     bcm_gport_t gport;
   3483     bcm_cos_t cosq;
   3484 
   3485     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   3486         return BCM_E_PARAM;
   3487     }
   3488     
   3489     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3490         return BCM_E_INIT;
   3491     }
   3492     
   3493     /* sync all the stats */
   3494     resInfo = _BCM_BST_RESOURCE(unit, bid);
   3495     if (resInfo == NULL) {
   3496         return BCM_E_PARAM;
   3497     }
   3498 
   3499     BCM_IF_ERROR_RETURN(_bcm_bst_hw_stat_sync(unit, resInfo, bid, port, index));
   3500 
   3501     if (bst_info->handlers.reverse_resolve_index) {
   3502         /* reverse map the inedx to port/cos pair */
   3503         bst_info->handlers.reverse_resolve_index(unit, bid, port, index, &gport, &cosq);
   3504     
   3505         soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 
   3506                            bid, gport, cosq);
   3507     }
   3508 
   3509     return BCM_E_NONE;
   3510 }
   3511 
   3512 int
   3513 _bcm_bst_sync_hw_snapshot(int unit, bcm_bst_stat_id_t bid, int port, int index)
   3514 {
   3515     _bcm_bst_cmn_unit_info_t *bst_info;
   3516     _bcm_bst_resource_info_t *resInfo;
   3517     int num_entries, mem_wsz;
   3518     int idx, idx_offset = 0, rv, pipe, pipe_offset = 0;
   3519     void *pentry;
   3520     char *dmabuf;
   3521     uint32 rval, temp_val;
   3522     soc_mem_t mem;
   3523     soc_reg_t reg;
   3524     int sync_val = 0;
   3525 
   3526     if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) {
   3527         return BCM_E_PARAM;
   3528     }
   3529    
   3530     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3531         return BCM_E_INIT;
   3532     }
   3533 
   3534     if (bst_info->pre_sync) {
   3535         bst_info->pre_sync(unit, bid, &sync_val);
   3536     }
   3537 
   3538     /* sync all the stats */
   3539     resInfo = _BCM_BST_RESOURCE(unit, bid);
   3540     if (resInfo == NULL) {
   3541         return BCM_E_PARAM;
   3542     }
   3543 
   3544     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3545         bcm_gport_t gport = -1;
   3546         bcm_cos_t cosq = -1;
   3547         mem = resInfo->stat_mem[pipe];
   3548         reg = resInfo->stat_reg[pipe];
   3549         pipe_offset = 0;
   3550 
   3551         if (pipe) {
   3552             pipe_offset = (resInfo->index_max / NUM_PIPE(unit)) * pipe;
   3553         }
   3554         if (mem != INVALIDm) {
   3555             num_entries = soc_mem_index_count(unit, mem);
   3556             mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem);
   3557 
   3558             dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf");
   3559             if (dmabuf == NULL) {
   3560                 return BCM_E_MEMORY;
   3561             }
   3562 
   3563             if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL,
   3564                                     soc_mem_index_min(unit, mem), 
   3565                                     soc_mem_index_max(unit, mem), 
   3566                                     dmabuf)) {
   3567                 soc_cm_sfree(unit, dmabuf);
   3568                 return BCM_E_INTERNAL;
   3569             }
   3570 
   3571             for (idx = 0; idx < (resInfo->num_stat_pp / NUM_PIPE(unit)); idx++) {
   3572 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   3573                 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) {
   3574                     /*
   3575                      * Reorder sw stat index
   3576                      * HW stat: index 0 - port 0 pool 0
   3577                      *          index 1 - port 1 pool 0
   3578                      *          index 2 - port 2 pool 0
   3579                      *          ...
   3580                      *          index n - port n%34 pool n/34
   3581                      * SW stat: index 0 - port 0 pool 0
   3582                      *          index 1 - port 0 pool 1
   3583                      *          index 2 - port 0 pool 2
   3584                      *          ...
   3585                      *          index n - port n/4 pool n%4
   3586                      */
   3587                     int port_tmp = 0, pool = 0;
   3588 #if defined(BCM_MONTEREY_SUPPORT)
   3589                     if (SOC_IS_MONTEREY(unit)) {
   3590                         port_tmp = idx % SOC_MONTEREY_NUM_MMU_PORTS_PER_PIPE;
   3591                         pool = idx / SOC_MONTEREY_NUM_MMU_PORTS_PER_PIPE;
   3592                     } else
   3593 #endif
   3594 #if defined(BCM_APACHE_SUPPORT)
   3595                     if (SOC_IS_APACHE(unit)) {
   3596                         port_tmp = idx % (SOC_APACHE_NUM_MMU_PORTS_PER_PIPE - 1);
   3597                         pool = idx / (SOC_APACHE_NUM_MMU_PORTS_PER_PIPE - 1);
   3598                     } else
   3599 #endif
   3600 #if defined(BCM_TRIDENT2_SUPPORT)
   3601                     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit) ||
   3602                         SOC_IS_TD2P_TT2P(unit)) {
   3603                         port_tmp = idx % _TD2_MMU_PORTS_PER_PIPE;
   3604                         pool = idx / _TD2_MMU_PORTS_PER_PIPE;
   3605                         if (pipe) {
   3606                             /* TD2 uses specific port value to pass pipe info */
   3607                             port = -2;
   3608                         }
   3609                     } else
   3610 #endif
   3611                     {
   3612                         soc_cm_sfree(unit, dmabuf);
   3613                         return BCM_E_UNAVAIL;
   3614                     }
   3615                     idx_offset = port_tmp * 4 + pool + pipe_offset;
   3616                 } else
   3617 #endif /* BCM_TRIDENT2_SUPPORT || BCM_APACHE_SUPPORT */
   3618                 {
   3619                     idx_offset = idx + pipe_offset;
   3620                 }
   3621                 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
   3622                                                       dmabuf, idx);
   3623                 temp_val = soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field);
   3624                 if (bst_info->track_mode) {
   3625                     if (resInfo->p_stat[idx_offset] < temp_val) {
   3626                         resInfo->p_stat[idx_offset] = temp_val;
   3627                     }
   3628                 } else {
   3629                     resInfo->p_stat[idx_offset] = temp_val;
   3630                 }
   3631 
   3632                 if (resInfo->p_threshold[idx_offset] &&
   3633                     (resInfo->p_stat[idx_offset] >= 
   3634                      (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   3635                     /* Generate SOC EVENT */
   3636                     if (bst_info->handlers.reverse_resolve_index) {
   3637                         /* reverse map the inedx to port/cos pair */
   3638                         bst_info->handlers.reverse_resolve_index(unit, bid, 
   3639                                                                  port, idx_offset,
   3640                                                                  &gport, &cosq);
   3641                         soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 
   3642                                            bid, gport, cosq);
   3643 
   3644                     }
   3645                 }
   3646             }
   3647             soc_cm_sfree(unit, dmabuf);
   3648         } else if (reg != INVALIDr) {
   3649             for (idx = 0; idx < resInfo->num_stat_pp; idx++) {
   3650                 idx_offset = idx + pipe_offset;
   3651                 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval);
   3652                 if (rv) {
   3653                     return BCM_E_INTERNAL;
   3654                 }
   3655                 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field);
   3656                 if (bst_info->track_mode) {
   3657                     if (resInfo->p_stat[idx_offset] < temp_val) {
   3658                         resInfo->p_stat[idx_offset] = temp_val;
   3659                     }
   3660                 } else {
   3661                     resInfo->p_stat[idx_offset] = temp_val;
   3662                 }
   3663 
   3664                 if (resInfo->p_threshold[idx_offset] &&
   3665                     (resInfo->p_stat[idx_offset] >= 
   3666                      (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   3667                     /* Generate SOC EVENT */
   3668                     if (bst_info->handlers.reverse_resolve_index) {
   3669                         /* reverse map the inedx to port/cos pair */
   3670                         bst_info->handlers.reverse_resolve_index(unit, bid, 
   3671                                                                  port, idx_offset,
   3672                                                                  &gport, &cosq);
   3673                         soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 
   3674                                            bid, gport, cosq);
   3675 
   3676                     }
   3677 
   3678                 }
   3679             }
   3680         }
   3681     }
   3682     
   3683     if (bst_info->post_sync) {
   3684         bst_info->post_sync(unit, bid, sync_val);
   3685     }
   3686     
   3687     return BCM_E_NONE;
   3688 }
   3689 #endif
   3690 
   3691 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   3692 STATIC int
   3693 _bst_td2_sbusdma_desc_setup(int unit)
   3694 {
   3695     _bcm_bst_cmn_unit_info_t *bst_info;
   3696     _bcm_bst_resource_info_t *resInfo;
   3697     _bcm_bst_tbl_ctrl_t *tbl_ctrl;
   3698     int blk, bid, pipe, mi, pipe_factor;
   3699     uint8 acc_type;
   3700     soc_mem_t mem;
   3701     soc_reg_t reg;
   3702     soc_reg_info_t *regp;
   3703     uint32 size;
   3704     uint8 *buff = NULL;
   3705     _bcm_bst_tbl_desc_t *desc = NULL;
   3706 
   3707     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3708         return BCM_E_INIT;
   3709     }
   3710     buff = bst_info->bst_tbl_buf;
   3711     bst_tbl_ctrl[unit] = sal_alloc(bcmBstStatIdMaxCount *
   3712                                       sizeof(_bcm_bst_tbl_ctrl_t *),
   3713                                       "bst_tbl_ctrl_p");
   3714     if (bst_tbl_ctrl[unit] == NULL) {
   3715         return BCM_E_MEMORY;
   3716     }
   3717 
   3718     bst_info->bst_tbl_desc = sal_alloc(bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t),
   3719         "bst_tbl_desc_p");
   3720     if (bst_info->bst_tbl_desc == NULL) {
   3721         return BCM_E_MEMORY;
   3722     }
   3723     sal_memset(bst_info->bst_tbl_desc, 0,  bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t));
   3724     desc = bst_info->bst_tbl_desc;
   3725 
   3726     mi = 0;
   3727     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   3728         resInfo = _BCM_BST_RESOURCE(unit, bid);
   3729         if (resInfo == NULL) {
   3730             return BCM_E_PARAM;
   3731         }
   3732 
   3733         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   3734             continue;
   3735         }
   3736 
   3737         tbl_ctrl = sal_alloc(sizeof(_bcm_bst_tbl_ctrl_t), "bst_tbl_ctrl");
   3738         if (tbl_ctrl == NULL) {
   3739             return BCM_E_MEMORY;
   3740         }
   3741         pipe_factor = 1;
   3742         if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   3743             pipe_factor = NUM_PIPE(unit);
   3744         }
   3745         size = 0;
   3746         tbl_ctrl->tindex = bid;
   3747         tbl_ctrl->entries = pipe_factor;
   3748         tbl_ctrl->buff = buff;
   3749         tbl_ctrl->size = 0;
   3750         bst_tbl_ctrl[unit][bid] = tbl_ctrl;
   3751         for (pipe = 0; pipe < pipe_factor; pipe++) {
   3752             mem = resInfo->stat_mem[pipe];
   3753             reg = resInfo->stat_reg[pipe];
   3754             if (mem != INVALIDm) {
   3755                 desc[mi].mem = mem;
   3756                 desc[mi].flags = SOC_SBUSDMA_CFG_COUNTER_IS_MEM | SOC_SBUSDMA_CFG_USE_FLAGS;
   3757                 desc[mi].blk = SOC_MEM_BLOCK_ANY(unit, mem);
   3758                 desc[mi].addr = soc_mem_addr_get(unit, mem,
   3759                                                0, desc[mi].blk, 0, &acc_type);
   3760                 desc[mi].acc_type = acc_type;
   3761                 desc[mi].blk = SOC_BLOCK2SCH(unit, desc[mi].blk);
   3762                 desc[mi].width = soc_mem_entry_words(unit, mem);
   3763                 desc[mi].entries = resInfo->num_stat_pp / pipe_factor;
   3764                 desc[mi].shift = 0;
   3765                 size += desc[mi].entries * desc[mi].width * 4;
   3766                 tbl_ctrl->blk = desc[mi].blk;
   3767                 mi++;
   3768             }else if (reg != INVALIDr) {
   3769                 regp = SOC_REG_PTR(unit, reg);
   3770                 desc[mi].reg= reg;
   3771                 desc[mi].addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   3772                     SOC_REG_ADDR_OPTION_NONE, &blk,
   3773                     &acc_type);
   3774                 desc[mi].flags = 0;
   3775                 desc[mi].acc_type = acc_type;
   3776                 desc[mi].blk = blk;
   3777                 desc[mi].width = BYTES2WORDS(soc_reg_bytes(unit, reg)) * regp->nFields;
   3778                 desc[mi].entries = resInfo->num_stat_pp / pipe_factor;
   3779                 desc[mi].shift = 8;
   3780                 size += desc[mi].entries * desc[mi].width * 4;
   3781                 tbl_ctrl->blk = desc[mi].blk;
   3782                 mi++;
   3783             }
   3784         }
   3785         buff += size;
   3786         tbl_ctrl->size += size;
   3787     }
   3788 
   3789     return BCM_E_NONE;
   3790 }
   3791 
   3792 STATIC int
   3793 _bcm_bst_td2_sbusdma_desc_init(int unit)
   3794 {
   3795     _bcm_bst_cmn_unit_info_t *bst_info;
   3796     _bcm_bst_resource_info_t *resInfo;
   3797     int pipe, bid, mi, pipe_factor;
   3798     soc_mem_t mem;
   3799     soc_reg_t reg;
   3800     soc_reg_info_t *regp;
   3801     uint32 entries, width, size = 0;
   3802     int rv = BCM_E_INIT;
   3803     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3804         return BCM_E_INIT;
   3805     }
   3806     mi = 0;
   3807     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   3808         resInfo = _BCM_BST_RESOURCE(unit, bid);
   3809         if (resInfo == NULL) {
   3810             return BCM_E_PARAM;
   3811         }
   3812 
   3813         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   3814             continue;
   3815         }
   3816 
   3817         pipe_factor = 1;
   3818         if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   3819             pipe_factor = NUM_PIPE(unit);
   3820         }
   3821         for (pipe = 0; pipe < pipe_factor; pipe++) {
   3822             mem = resInfo->stat_mem[pipe];
   3823             reg = resInfo->stat_reg[pipe];
   3824             if (mem != INVALIDm) {
   3825                 entries = resInfo->num_stat_pp / pipe_factor;
   3826                 width = soc_mem_entry_words(unit, mem);
   3827                 size += entries * width * 4;
   3828                 mi++;
   3829             } else if (reg != INVALIDr) {
   3830                 regp = SOC_REG_PTR(unit, reg);
   3831                 entries = resInfo->num_stat_pp;
   3832                 width = BYTES2WORDS(soc_reg_bytes(unit, reg)) * regp->nFields;
   3833                 size += entries * width * 4;
   3834                 mi++;
   3835             }
   3836         }
   3837     }
   3838     bst_info->bst_tbl_size = size;
   3839     bst_info->bst_tbl_num = mi;
   3840     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3841                 (BSL_META_U(unit,
   3842                             "Total bst tbls: %d, Total size: %d\n"),
   3843                  bcmBstStatIdMaxCount, size));
   3844     bst_tbl_handles[unit] = 0;
   3845     if (bst_info->bst_tbl_buf == NULL) {
   3846         bst_info->bst_tbl_buf = soc_cm_salloc(unit, size, "bst_tbl_buf");
   3847         if (bst_info->bst_tbl_buf == NULL) {
   3848             goto error;
   3849         }
   3850     }
   3851     sal_memset(bst_info->bst_tbl_buf, 0, size);
   3852     rv =_bst_td2_sbusdma_desc_setup(unit);
   3853     if (rv != SOC_E_NONE) {
   3854         goto error;
   3855     }
   3856 
   3857     rv = soc_bst_sbusdma_desc_setup(unit);
   3858     if (rv != SOC_E_NONE) {
   3859         goto error;
   3860     }
   3861     return BCM_E_NONE;
   3862 error:
   3863     if (bst_info->bst_tbl_buf) {
   3864         soc_cm_sfree(unit, bst_info->bst_tbl_buf);
   3865         bst_info->bst_tbl_buf = NULL;
   3866     }
   3867     if (bst_info->bst_tbl_desc) {
   3868         sal_free(bst_info->bst_tbl_desc);
   3869         bst_info->bst_tbl_desc = NULL;
   3870     }
   3871     rv = soc_bst_sbusdma_desc_free(unit);
   3872     return rv;
   3873 }
   3874 
   3875 STATIC int
   3876 _bst_td2_sw_sbusdma_desc_sync(int unit, int bid)
   3877 {
   3878     _bcm_bst_cmn_unit_info_t *bst_info;
   3879     _bcm_bst_resource_info_t *resInfo;
   3880     _bcm_bst_tbl_ctrl_t *tbl_ctrl;
   3881     int idx, idx_offset, pipe, pipe_offset = 0;
   3882     void *pentry;
   3883     uint32 rval, temp_val;
   3884     uint8 *buff = NULL;
   3885     soc_mem_t mem;
   3886     soc_reg_t reg;
   3887     uint32 width = 0;
   3888     int pipe_factor;
   3889     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3890         sal_mutex_give(bst_info->bst_reslock);
   3891         return BCM_E_INIT;
   3892     }
   3893     if (!bst_tbl_ctrl[unit][bid]) {
   3894         sal_mutex_give(bst_info->bst_reslock);
   3895         return BCM_E_INIT;
   3896     }
   3897     tbl_ctrl = bst_tbl_ctrl[unit][bid];
   3898     buff = tbl_ctrl->buff;
   3899     resInfo = _BCM_BST_RESOURCE(unit, bid);
   3900     if (resInfo == NULL) {
   3901         sal_mutex_give(bst_info->bst_reslock);
   3902         return BCM_E_PARAM;
   3903     }
   3904     pipe_factor = 1;
   3905     if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) {
   3906         pipe_factor = NUM_PIPE(unit);
   3907     }
   3908     for (pipe = 0; pipe < pipe_factor; pipe++) {
   3909         bcm_gport_t gport = -1;
   3910         bcm_cos_t cosq = -1;
   3911         mem = resInfo->stat_mem[pipe];
   3912         reg = resInfo->stat_reg[pipe];
   3913         pipe_offset = 0;
   3914         if (pipe) {
   3915             pipe_offset = (resInfo->index_max / NUM_PIPE(unit)) * pipe;
   3916         }
   3917         if (mem != INVALIDm) {
   3918             for (idx = 0; idx < (resInfo->num_stat_pp / NUM_PIPE(unit)); idx++) {
   3919                 idx_offset = idx + pipe_offset;
   3920                 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*,
   3921                                                       buff, idx);
   3922                 temp_val = soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field);
   3923                 if (bst_info->track_mode) {
   3924                     if (resInfo->p_stat[idx_offset] < temp_val) {
   3925                         resInfo->p_stat[idx_offset] = temp_val;
   3926                     }
   3927                 } else {
   3928                     resInfo->p_stat[idx_offset] = temp_val;
   3929                 }
   3930                 if (resInfo->p_threshold[idx_offset] &&
   3931                     (resInfo->p_stat[idx_offset] >=
   3932                      (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   3933                     /* Generate SOC EVENT */
   3934                     if (bst_info->handlers.reverse_resolve_index) {
   3935                         /* reverse map the inedx to port/cos pair */
   3936                         bst_info->handlers.reverse_resolve_index(unit, bid,
   3937                                                                  -1, idx_offset,
   3938                                                                  &gport, &cosq);
   3939                         soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
   3940                                            bid, gport, cosq);
   3941                     }
   3942                 }
   3943             }
   3944             buff += tbl_ctrl->size / pipe_factor;
   3945         } else if (reg != INVALIDr) {
   3946             for (idx = 0; idx < resInfo->num_stat_pp; idx++) {
   3947                 width = BYTES2WORDS(soc_reg_bytes(unit, reg));
   3948                 idx_offset = idx + pipe_offset;
   3949 
   3950                 sal_memcpy(&rval, buff, width * 4);
   3951                 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field);
   3952                 if (bst_info->track_mode) {
   3953                     if (resInfo->p_stat[idx_offset] < temp_val) {
   3954                         resInfo->p_stat[idx_offset] = temp_val;
   3955                     }
   3956                 } else {
   3957                     resInfo->p_stat[idx_offset] = temp_val;
   3958                 }
   3959                 buff = buff + width * 4;
   3960 
   3961                 if (resInfo->p_threshold[idx_offset] &&
   3962                     (resInfo->p_stat[idx_offset] >=
   3963                      (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) {
   3964                     /* Generate SOC EVENT */
   3965                     if (bst_info->handlers.reverse_resolve_index) {
   3966                         /* reverse map the inedx to port/cos pair */
   3967                         bst_info->handlers.reverse_resolve_index(unit, bid,
   3968                                                                  -1, idx_offset,
   3969                                                                  &gport, &cosq);
   3970                         soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER,
   3971                                            bid, gport, cosq);
   3972                     }
   3973                 }
   3974             }
   3975         }
   3976     }
   3977 
   3978     return BCM_E_NONE;
   3979 }
   3980 
   3981 STATIC int
   3982 _bcm_bst_td2_sbusdma_desc_sync(int unit)
   3983 {
   3984     _bcm_bst_cmn_unit_info_t *bst_info;
   3985     _bcm_bst_resource_info_t *resInfo;
   3986     bcm_bst_stat_id_t bid;
   3987     int enable = 0;
   3988 
   3989     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   3990         return BCM_E_INIT;
   3991     }
   3992 
   3993     if (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) {
   3994         return BCM_E_NONE;
   3995     }
   3996 
   3997     sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER);
   3998 
   3999     if (bst_info->control_get) {
   4000         bst_info->control_get(unit, bcmSwitchBstEnable, &enable);
   4001     }
   4002 
   4003     if (enable && bst_info->control_set) {
   4004         bst_info->control_set(unit, bcmSwitchBstEnable, 0,
   4005                               _bcmBstThreadOperInternal);
   4006     }
   4007 
   4008     BCM_IF_ERROR_RETURN(soc_bst_hw_sbusdma_desc_sync(unit));
   4009 
   4010     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   4011         resInfo = _BCM_BST_RESOURCE(unit, bid);
   4012         if (resInfo == NULL) {
   4013             return BCM_E_PARAM;
   4014         }
   4015 
   4016         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   4017             continue;
   4018         }
   4019 
   4020         BCM_IF_ERROR_RETURN(_bst_td2_sw_sbusdma_desc_sync(unit, bid));
   4021     }
   4022 
   4023     if (enable && bst_info->control_set) {
   4024         bst_info->control_set(unit, bcmSwitchBstEnable, enable,
   4025                               _bcmBstThreadOperInternal);
   4026     }
   4027 
   4028     sal_mutex_give(bst_info->bst_reslock);
   4029     return BCM_E_NONE;
   4030 }
   4031 
   4032 STATIC int
   4033 _bcm_bst_td2_sbusdma_desc_deinit(int unit)
   4034 {
   4035     _bcm_bst_cmn_unit_info_t *bst_info;
   4036     int rv = BCM_E_INIT;
   4037 
   4038     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   4039         return BCM_E_INIT;
   4040     }
   4041 
   4042     if (bst_info->bst_tbl_buf) {
   4043         soc_cm_sfree(unit, bst_info->bst_tbl_buf);
   4044         bst_info->bst_tbl_buf = NULL;
   4045     }
   4046     if (bst_info->bst_tbl_desc) {
   4047         sal_free(bst_info->bst_tbl_desc);
   4048         bst_info->bst_tbl_desc = NULL;
   4049     }
   4050 
   4051     rv = soc_bst_sbusdma_desc_free(unit);
   4052     if (rv != BCM_E_NONE) {
   4053         return rv;
   4054     }
   4055 
   4056     return BCM_E_NONE;
   4057 }
   4058 #endif
   4059 
   4060 STATIC void
   4061 soc_sbusdma_bst_cb(int unit, int status, sbusdma_desc_handle_t handle, void *data)
   4062 {
   4063     _bcm_bst_tbl_ctrl_t *tbl_ctrl = bst_tbl_ctrl[unit][PTR_TO_INT(data)];
   4064     if (status != SOC_E_NONE) {
   4065         LOG_ERROR(BSL_LS_SOC_COMMON,
   4066                   (BSL_META_U(unit,
   4067                               "bst sbusdma failed: blk: %d, bid: %d, entries: %d, size: %d.\n"),
   4068                    tbl_ctrl->blk, tbl_ctrl->tindex, tbl_ctrl->entries, tbl_ctrl->size));
   4069     }
   4070 }
   4071 
   4072 int
   4073 soc_bst_sbusdma_desc_setup(int unit)
   4074 {
   4075     _bcm_bst_cmn_unit_info_t *bst_info;
   4076     int mi;
   4077     uint8 *buff = NULL;
   4078     soc_sbusdma_desc_ctrl_t ctrl = {0};
   4079     soc_sbusdma_desc_cfg_t *cfg = NULL;
   4080     _bcm_bst_tbl_desc_t *desc = NULL;
   4081     int rv = BCM_E_INIT;
   4082     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   4083         return BCM_E_INIT;
   4084     }
   4085     buff = bst_info->bst_tbl_buf;
   4086     desc = bst_info->bst_tbl_desc;
   4087 
   4088     ctrl.flags = SOC_SBUSDMA_CFG_USE_FLAGS;
   4089     ctrl.pc = NULL;
   4090     ctrl.pc_data = NULL;
   4091     ctrl.cfg_count = bst_info->bst_tbl_num;
   4092     ctrl.buff = buff;
   4093     ctrl.cb = soc_sbusdma_bst_cb;
   4094     ctrl.data = INT_TO_PTR(bcmBstStatIdDevice);
   4095 #define BST_TBLS "BST TBLS"
   4096     sal_strncpy(ctrl.name, BST_TBLS, sizeof(BST_TBLS));
   4097     cfg = sal_alloc(bst_info->bst_tbl_num * sizeof(soc_sbusdma_desc_cfg_t),
   4098         "bst_sbusdma_desc_cfg");
   4099     if (cfg == NULL) {
   4100         return BCM_E_MEMORY;
   4101     }
   4102     sal_memset(cfg, 0,  bst_info->bst_tbl_num * sizeof(soc_sbusdma_desc_cfg_t));
   4103     mi = 0;
   4104     for (mi = 0; mi < bst_info->bst_tbl_num; mi++) {
   4105         cfg[mi].addr = desc[mi].addr;
   4106         cfg[mi].flags = desc[mi].flags;
   4107         cfg[mi].acc_type = desc[mi].acc_type;
   4108         cfg[mi].blk = desc[mi].blk;
   4109         cfg[mi].width = desc[mi].width;
   4110         cfg[mi].count = desc[mi].entries;
   4111         cfg[mi].addr_shift = desc[mi].shift;
   4112 #ifdef BCM_TOMAHAWK3_SUPPORT
   4113         if (SOC_IS_TOMAHAWK3(unit)) {
   4114              cfg[mi].flags |= SOC_SBUSDMA_CFG_MOR;
   4115         }
   4116 #endif
   4117 
   4118     }
   4119     rv = soc_sbusdma_desc_create(unit, &ctrl, cfg,
   4120                      &bst_tbl_handles[unit]);
   4121     sal_free(cfg);
   4122     if (rv != SOC_E_NONE) {
   4123         LOG_ERROR(BSL_LS_SOC_COMMON,
   4124                   (BSL_META_U(unit,
   4125                               "bst sbusdma desc creation error!\n")));
   4126         return rv;
   4127     }
   4128     return BCM_E_NONE;
   4129 }
   4130 
   4131 int
   4132 soc_bst_sbusdma_desc_free(int unit)
   4133 {
   4134     int bid;
   4135     _bcm_bst_resource_info_t *resInfo;
   4136     int rv = BCM_E_INIT;
   4137     if (bst_tbl_handles[unit]) {
   4138         do {
   4139             rv = soc_sbusdma_desc_delete(unit, bst_tbl_handles[unit]);
   4140             if (rv == SOC_E_BUSY) {
   4141                 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10);
   4142             }
   4143         } while (rv == SOC_E_BUSY);
   4144         if (rv != SOC_E_NONE) {
   4145             LOG_ERROR(BSL_LS_SOC_COMMON,
   4146                       (BSL_META_U(unit,
   4147                                   "bst sbusdma desc delete error!\n")));
   4148             return rv;
   4149         }
   4150 
   4151         bst_tbl_handles[unit] = 0;
   4152     }
   4153 
   4154     for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) {
   4155         resInfo = _BCM_BST_RESOURCE(unit, bid);
   4156         if (resInfo == NULL) {
   4157             return BCM_E_PARAM;
   4158         }
   4159 
   4160         if (!_BCM_BST_RESOURCE_VALID(resInfo)) {
   4161             continue;
   4162         }
   4163 
   4164         if (bst_tbl_ctrl[unit][bid]) {
   4165             sal_free(bst_tbl_ctrl[unit][bid]);
   4166             bst_tbl_ctrl[unit][bid] = NULL;
   4167         }
   4168     }
   4169     if (bst_tbl_ctrl[unit]) {
   4170         sal_free(bst_tbl_ctrl[unit]);
   4171         bst_tbl_ctrl[unit] = NULL;
   4172     }
   4173 
   4174     return BCM_E_NONE;
   4175 }
   4176 int
   4177 soc_bst_hw_sbusdma_desc_sync(int unit)
   4178 {
   4179     sbusdma_desc_handle_t desc_handle;
   4180     soc_timeout_t to;
   4181     sal_usecs_t dma_timeout = 1000000;
   4182     sal_usecs_t stime, etime;
   4183     _bcm_bst_cmn_unit_info_t *bst_info;
   4184     int rv = BCM_E_INIT;
   4185     if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) {
   4186         return BCM_E_INIT;
   4187     }
   4188     if (!bst_tbl_ctrl[unit]) {
   4189         return BCM_E_INIT;
   4190     }
   4191     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   4192                 (BSL_META_U(unit, "bst start sync.\n")));
   4193     desc_handle = bst_tbl_handles[unit];
   4194     if (bst_info->bst_tbl_buf && desc_handle) {
   4195         soc_timeout_init(&to, 2 * dma_timeout, 0);
   4196         do {
   4197             stime = sal_time_usecs();
   4198             rv = soc_sbusdma_desc_start(unit, desc_handle);
   4199             if (rv == SOC_E_NONE) {
   4200                 break;
   4201             } else if (rv == SOC_E_BUSY) {
   4202                 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10);
   4203             } else {
   4204                 sal_mutex_give(bst_info->bst_reslock);
   4205                 return SOC_E_INTERNAL;
   4206             }
   4207             if (soc_timeout_check(&to)) {
   4208                 LOG_WARN(BSL_LS_SOC_COMMON,
   4209                          (BSL_META_U(unit,
   4210                                      "bst start dma timeout\n")));
   4211                 sal_mutex_give(bst_info->bst_reslock);
   4212                 return SOC_E_TIMEOUT;
   4213             }
   4214         } while (rv == SOC_E_BUSY);
   4215         etime = sal_time_usecs();
   4216         LOG_INFO(BSL_LS_SOC_MMU,
   4217                  (BSL_META_U(unit,
   4218                              "soc_bst_hw_sbusdma_desc_sync: unit=%d bst sync done in %d usec\n"),
   4219                   unit,
   4220                   SAL_USECS_SUB(etime, stime)));
   4221     }
   4222     return BCM_E_NONE;
   4223 }
   4224