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


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