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

tcb.c (90263B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:    tcb.c
      8  * Purpose: Handle TH2 specific tcb APIs
      9  */
     10 
     11 #include <shared/bsl.h>
     12 #include <bcm/error.h>
     13 #include <soc/drv.h>
     14 #include <bcm/cosq.h>
     15 #include <soc/profile_mem.h>
     16 #include <soc/tomahawk.h>
     17 #include <soc/tomahawk2.h>
     18 
     19 #include <bcm_int/esw_dispatch.h>
     20 #include <bcm_int/esw/virtual.h>
     21 #include <bcm_int/esw/tomahawk.h>
     22 
     23 #if defined (INCLUDE_TCB) && defined (BCM_TCB_SUPPORT)
     24 #include <bcm_int/esw/tcb.h>
     25 #endif
     26 
     27 
     28 #define _BCM_TH2_NUM_UCAST_QUEUE_PER_PORT 10
     29 
     30 #if defined (INCLUDE_TCB) && defined (BCM_TCB_SUPPORT)
     31 
     32 STATIC soc_field_t _bcm_cosq_tcb_threshold_profile_map_fields[] = {
     33     QUEUE_0f,
     34     QUEUE_1f,
     35     QUEUE_2f,
     36     QUEUE_3f,
     37     QUEUE_4f,
     38     QUEUE_5f,
     39     QUEUE_6f,
     40     QUEUE_7f,
     41     QUEUE_8f,
     42     QUEUE_9f
     43 };
     44 
     45 STATIC soc_field_t _bcm_th2_cosq_tcb_freeze_fields[] = {
     46     TCB_FREEZE_XPE_RAf,
     47     TCB_FREEZE_XPE_RBf,
     48     TCB_FREEZE_XPE_SAf,
     49     TCB_FREEZE_XPE_SBf
     50 };
     51 
     52 STATIC int _bcm_th2_cosq_tcb_ucq_offset[] = {0, 708, 0, 708};
     53 STATIC int _bcm_th2_cosq_tcb_ing_port_offset[] = {0, 0, 64, 64};
     54 STATIC int _bcm_th2_cosq_tcb_egr_port_offset[] = {0, 64, 0, 64};
     55 STATIC int _bcm_th2_cosq_tcb_egr_mmu_port_offset[] = {0, 34, 0, 34};
     56 
     57 
     58 STATIC _bcm_cosq_tcb_pipe_port_tab_t _bcm_th2_cosq_tcb_pipe_table[] = {
     59     /* tcb 0*/
     60     {_TCB_PIPE0 | _TCB_PIPE3, {0, 3}, _TCB_PIPE0 | _TCB_PIPE1, {0, 1},
     61      "0,3", "0,1", "1-33,102-134", "1-33,34-66", ""},
     62     /* tcb 1*/
     63     {_TCB_PIPE0 | _TCB_PIPE3, {0, 3}, _TCB_PIPE2 | _TCB_PIPE3, {2, 3},
     64      "0,3", "2,3", "1-33,102-134", "68-100,102-134", ""},
     65     /* tcb 2*/
     66     {_TCB_PIPE1 | _TCB_PIPE2, {1, 2}, _TCB_PIPE0 | _TCB_PIPE1, {0, 1},
     67      "1,2", "0,1", "34-66,68-100", "1-33,34-66", ""},
     68     /* tcb 3*/
     69     {_TCB_PIPE1 | _TCB_PIPE2, {1, 2}, _TCB_PIPE2 | _TCB_PIPE3, {2, 3},
     70      "1,2", "2,3", "34-66,68-100", "68-100,102-134", ""}
     71 };
     72 
     73 STATIC int _bcm_th2_cosq_tcb_ext_frz_offset[] = {0, 2, 1, 3};
     74 
     75 /* Number of COSQs configured for this unit */
     76 #define _TH2_NUM_PROFILE_COS 10
     77 
     78 #define _BCM_TH2_TCB_MAX_NUM    4
     79 #define _BCM_TH2_TCB_PROFILE_MAX_NUM    8
     80 
     81 #define _BCM_TH2_TCB_THRESHOLD_MAX      0xffff
     82 
     83 #define _MMU_CELLS_TO_BYTES(cells, cell_bytes)  cells * cell_bytes
     84 #define _MMU_BYTES_TO_CELLS(bytes, cell_bytes)  (bytes + (cell_bytes - 1)) \
     85                                                 / cell_bytes
     86 
     87 /* 
     88  * timer = (pre_freeze_capture_time * frequency) /10;
     89  * The algorithm above would cause a max deviation of 9 (10-1) 
     90  */
     91 #define _TCB_PRE_FREEZE_CAP_TIME_TO_TIMER(u, _pre_freeze_capture_time) \
     92         (((_pre_freeze_capture_time) * (SOC_INFO(u).frequency)) / _TCB_CAP_TIM_FACTOR)
     93 /*
     94  * pre_freeze_capture_time = (timer * 10) /frequency;
     95  * Adding a max deviation of 9 (10-1), while calculating the pre-freeze capture time
     96  */
     97 #define _TCB_TIMER_TO_PRE_FREEZE_CAP_TIME(u, _timer) \
     98         (((_timer) * _TCB_CAP_TIM_FACTOR + _TCB_CAP_TIM_MAX_DEVIATION) / (SOC_INFO(u).frequency))
     99 
    100 /* 
    101  * timer = (pre_freeze_capture_time * frequency) /10;
    102  * The algorithm above would cause a max deviation of 9 (10-1) 
    103  */
    104 #define _TCB_PRE_FREEZE_CAP_TIME_TO_TIMER(u, _pre_freeze_capture_time) \
    105         (((_pre_freeze_capture_time) * (SOC_INFO(u).frequency)) / _TCB_CAP_TIM_FACTOR)
    106 /*
    107  * pre_freeze_capture_time = (timer * 10) /frequency;
    108  * Adding a max deviation of 9 (10-1), while calculating the pre-freeze capture time
    109  */
    110 #define _TCB_TIMER_TO_PRE_FREEZE_CAP_TIME(u, _timer) \
    111         (((_timer) * _TCB_CAP_TIM_FACTOR + _TCB_CAP_TIM_MAX_DEVIATION) / (SOC_INFO(u).frequency))
    112 
    113 #ifdef BCM_WARM_BOOT_SUPPORT
    114 int
    115 bcm_th2_cosq_tcb_reinit(int unit)
    116 {
    117     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    118     _bcm_cosq_tcb_info_t *tcb_config;
    119     int i, j, k, n, enable, index, start_threshold, stop_threshold;
    120     uint64 rval64;
    121     soc_mem_t profile_mem;
    122     soc_field_t field;
    123 
    124     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    125     TCB_INIT(unit);
    126 
    127     for (i = 0; i < _BCM_TH2_TCB_MAX_NUM; i++) {
    128         SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, i, 0, &rval64));
    129         enable = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TCB_ENABLEf);
    130         if (enable) {
    131             tcb_unit_info->tcb_enabled_bmp |= 1 << i;
    132         }
    133 
    134         profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[i];
    135         tcb_config = tcb_unit_info->tcb_info[i];
    136         SHR_BITSET(tcb_config->profile_bmp, 0);
    137 
    138         for (n = 1; n < _BCM_TH2_TCB_PROFILE_MAX_NUM; n++) {
    139             BCM_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr, i,
    140                                               n, &rval64));
    141             start_threshold = soc_reg_field_get(unit, TCB_THRESHOLD_PROFILEr,
    142                                                 rval64, CAPTURE_START_THRESHOLDf);
    143             stop_threshold = soc_reg_field_get(unit, TCB_THRESHOLD_PROFILEr,
    144                                                rval64, CAPTURE_END_THRESHOLDf);
    145             if (start_threshold != 0 || stop_threshold != 0) {
    146                 SHR_BITSET(tcb_config->profile_bmp, n);
    147             }
    148 
    149         }
    150         for (j = 0; j < soc_mem_index_count(unit, profile_mem); j++) {
    151             BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
    152                                               j, &rval64));
    153             for (k = 0; k < _TH2_NUM_PROFILE_COS; k++) {
    154                 field = _bcm_cosq_tcb_threshold_profile_map_fields[k];
    155                 index = soc_mem_field32_get(unit,TCB_THRESHOLD_PROFILE_MAPm,
    156                                             &rval64, field);
    157                 for (n = 0; n < _BCM_TH2_TCB_PROFILE_MAX_NUM; n++) {
    158                     if (index == n) {
    159                         if(SHR_BITGET(tcb_config->profile_bmp, n)) {
    160                         tcb_config->profile_ref_count[n]++;
    161                         }
    162                     }
    163                 }
    164             }
    165         }
    166     }
    167 
    168     return BCM_E_NONE;
    169 }
    170 #endif
    171 
    172 /*
    173  * Function:
    174  *      _bcm_th2_cosq_tcb_current_phase_get
    175  * Purpose:
    176  *      Get tcb buffer running status.
    177  * Parameters:
    178  *      unit - (IN) BCM device number.
    179  *      buffer_id - (IN) TCB buffer id.
    180  *      status - (OUT) TCB buffer status.
    181  * Returns:
    182  *      BCM_E_XXX
    183  */
    184 STATIC int
    185 _bcm_th2_cosq_tcb_current_phase_get(int unit,
    186                                    bcm_cosq_buffer_id_t buffer_id, int *status)
    187 {
    188     uint32 rval;
    189 
    190     LOG_INFO(BSL_LS_BCM_COSQ,
    191              (BSL_META_U(unit,
    192                          "tcb_current_phase_get: unit %d, buffer_id %d\n"),
    193                          unit, buffer_id));
    194 
    195     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_CURRENT_PHASEr, buffer_id, 0, &rval));
    196     *status = soc_reg_field_get(unit,TCB_CURRENT_PHASEr, rval, CURRENT_PHASEf);
    197 
    198     return BCM_E_NONE;
    199 }
    200 
    201 STATIC int
    202 _bcm_th2_cosq_tcb_intr_enable_set(int unit, int enable)
    203 {
    204     uint32 rval;
    205 
    206     if (SOC_REG_IS_VALID(unit, MMU_XCFG_XPE_CPU_INT_ENr)) {
    207         BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_ENr(unit, &rval));
    208         soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval,
    209                           TCB_FREEZE_INT_ENf, enable);
    210         BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_ENr(unit, rval));
    211     }
    212     return BCM_E_NONE;
    213 }
    214 
    215 STATIC int
    216 _bcm_th2_cosq_tcb_intr_status_reset(int unit)
    217 {
    218     uint32 rval;
    219 
    220     BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, &rval));
    221     soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval,
    222                       TCB_FREEZE_INT_CLRf, 0);
    223     BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, rval));
    224 
    225     return BCM_E_NONE;
    226 }
    227 
    228 STATIC int
    229 _bcm_th2_cosq_tcb_hw_event_cb(int unit)
    230 {
    231     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    232     bcm_cosq_buffer_id_t buffer_id;
    233     int status;
    234 
    235     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    236     if (!tcb_unit_info) {
    237         return 0;
    238     }
    239 
    240     _bcm_th2_cosq_tcb_intr_enable_set(unit, 0);
    241     _bcm_th2_cosq_tcb_intr_status_reset(unit);
    242 
    243     for (buffer_id = 0; buffer_id < _BCM_TH2_TCB_MAX_NUM; buffer_id++)
    244     {
    245         /* Go over the enabled TCB to see which is freezed */
    246         if(tcb_unit_info->tcb_enabled_bmp & (1 << buffer_id)) {
    247             BCM_IF_ERROR_RETURN(
    248                     _bcm_th2_cosq_tcb_current_phase_get(unit, buffer_id, &status));
    249             if (_TCB_FROZEN_PHASE == status) {
    250                 if (tcb_unit_info->tcb_evt_cb) {
    251                     tcb_unit_info->tcb_evt_cb(unit, buffer_id,
    252                                               tcb_unit_info->tcb_evt_user_data);
    253                 }
    254             }
    255         }
    256     }
    257 
    258     _bcm_th2_cosq_tcb_intr_enable_set(unit, 1);
    259     return BCM_E_NONE;
    260 }
    261 
    262 int
    263 soc_th2_tcb_set_hw_intr_cb(int unit)
    264 {
    265 #ifdef BCM_TOMAHAWK2_SUPPORT
    266     BCM_IF_ERROR_RETURN(
    267             soc_th2_set_tcb_callback(unit, &_bcm_th2_cosq_tcb_hw_event_cb));
    268 #endif
    269     return SOC_E_NONE;
    270 }
    271 
    272 STATIC int
    273 _bcm_th2_cosq_tcb_ext_freeze_set(int unit,
    274                                  bcm_cosq_buffer_id_t buffer_id, int enable)
    275 {
    276     uint32 rval;
    277     soc_field_t field;
    278     int idx;
    279 
    280     LOG_INFO(BSL_LS_BCM_COSQ,
    281              (BSL_META_U(unit,
    282                          "tcb_ext_freeze_set: unit %d, buffer_id %d, enable %d\n"),
    283                          unit, buffer_id, enable));
    284 
    285     BCM_IF_ERROR_RETURN(READ_MMU_GCFG_TCB_FREEZEr(unit, &rval));
    286 
    287     if (-1 == buffer_id) {
    288         if (enable) {
    289             for (idx = 0; idx < _BCM_TH2_TCB_MAX_NUM; idx++) {
    290                 field = _bcm_th2_cosq_tcb_freeze_fields[idx];
    291                 soc_reg_field_set(unit, MMU_GCFG_TCB_FREEZEr, &rval, field, 1);
    292             }
    293         } else {
    294             for (idx = 0; idx < _BCM_TH2_TCB_MAX_NUM; idx++) {
    295                 field = _bcm_th2_cosq_tcb_freeze_fields[idx];
    296                 soc_reg_field_set(unit, MMU_GCFG_TCB_FREEZEr, &rval, field, 0);
    297             }
    298         }
    299     } else {
    300         idx = _bcm_th2_cosq_tcb_ext_frz_offset[buffer_id];
    301         field = _bcm_th2_cosq_tcb_freeze_fields[idx];
    302 
    303         if(enable) {
    304             soc_reg_field_set(unit,MMU_GCFG_TCB_FREEZEr, &rval, field, 1);
    305         } else {
    306             soc_reg_field_set(unit,MMU_GCFG_TCB_FREEZEr, &rval, field, 0);
    307         }
    308     }
    309     BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_TCB_FREEZEr(unit, rval));
    310 
    311     return BCM_E_NONE;
    312 }
    313 
    314 
    315 STATIC int
    316 _bcm_th2_cosq_tcb_buffer_ready_clear(int unit, bcm_cosq_buffer_id_t buffer_id)
    317 {
    318     uint32 rval;
    319     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_BUFFER_READYr, buffer_id, 0, &rval));
    320     soc_reg_field_set(unit, TCB_BUFFER_READYr, &rval, BUFFER_READYf, 0);
    321     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, TCB_BUFFER_READYr, buffer_id, 0, rval));
    322 
    323     return BCM_E_NONE;
    324 }
    325 
    326 STATIC int
    327 _bcm_cosq_tcb_is_enabled(int unit, bcm_cosq_buffer_id_t buffer_id)
    328 {
    329      _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    330      int enabled;
    331 
    332      tcb_unit_info = TCB_UNIT_CONTROL(unit);
    333      enabled = tcb_unit_info->tcb_enabled_bmp & (1 << buffer_id);
    334      if (0 == enabled) {
    335          return FALSE;
    336      } else {
    337          return TRUE;
    338      }
    339 }
    340 
    341 
    342 STATIC int
    343 _bcm_th2_cosq_tcb_profile_id_alloc(int unit,
    344                                     bcm_cosq_buffer_id_t buffer_id, int *index)
    345 {
    346     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    347     int i, profile_count;
    348     SHR_BITDCL *bitmap;
    349     _bcm_cosq_tcb_info_t *tcb_info;
    350 
    351     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    352 
    353     tcb_info = tcb_unit_info->tcb_info[buffer_id];
    354     bitmap = tcb_info->profile_bmp;
    355     profile_count = _BCM_TH2_TCB_PROFILE_MAX_NUM;
    356 
    357     for(i = 0; i < profile_count; i++) {
    358         if(!SHR_BITGET(bitmap, i)) {
    359             SHR_BITSET(bitmap, i);
    360             *index = i;
    361             return BCM_E_NONE;
    362         }
    363     }
    364 
    365     LOG_INFO(BSL_LS_BCM_COSQ, (BSL_META_U(unit,
    366                                "No free profile in TCB %d\n"),
    367                                buffer_id));
    368 
    369     return BCM_E_RESOURCE;
    370 }
    371 
    372 
    373 
    374 STATIC int
    375 _bcm_th2_cosq_tcb_buffer_info_get(int unit,
    376                                   bcm_cosq_buffer_id_t buffer_id,
    377                                   int type, int *arg)
    378 {
    379     uint32 rval;
    380 
    381     LOG_INFO(BSL_LS_BCM_COSQ,
    382              (BSL_META_U(unit,
    383                          "tcb_buffer_info_get: unit %d, buffer_id %d, type %d\n"),
    384                          unit, buffer_id, type));
    385 
    386     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_BUFFER_STATUSr, buffer_id, 0, &rval));
    387 
    388     switch(type) {
    389         case _TCB_BUF_STATUS_WRAPPED:
    390             *arg = soc_reg_field_get(unit, TCB_BUFFER_STATUSr, rval,
    391                                      TCB_BUFFER_WRAP_AROUND_FLAGf);
    392             break;
    393         case _TCB_BUF_STATUS_PTR:
    394             *arg = soc_reg_field_get(unit, TCB_BUFFER_STATUSr, rval,
    395                                      TCB_BUFFER_END_PTRf);
    396             break;
    397         case _TCB_BUF_STATUS_EVT_NUM:
    398             *arg = soc_reg_field_get(unit, TCB_BUFFER_STATUSr, rval,
    399                                      EVENT_BUFFER_SIZEf);
    400             break;
    401         case _TCB_BUF_STATUS_0_USED:
    402             *arg = soc_reg_field_get(unit, TCB_BUFFER_STATUSr, rval,
    403                                      TCB_BUFFER_ADDRESS_0_USEDf);
    404             break;
    405         default:
    406             break;
    407     }
    408 
    409     return BCM_E_NONE;
    410 }
    411 
    412 STATIC int
    413 _bcm_th2_cosq_tcb_evt_overflow_count_get(int unit,
    414                                          bcm_cosq_buffer_id_t buffer_id,
    415                                          int *num)
    416 {
    417     uint32 rval;
    418 
    419     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_EVENT_BUFFER_OVERFLOW_COUNTERr,
    420                                       buffer_id, 0, &rval));
    421     *num = soc_reg_field_get(unit, TCB_EVENT_BUFFER_OVERFLOW_COUNTERr,
    422                              rval, OVERFLOW_COUNTERf);
    423 
    424     return BCM_E_NONE;
    425 }
    426 
    427 
    428 STATIC int
    429 _bcm_th2_cosq_tcb_buffer_get_rd_num(int unit,
    430                                     bcm_cosq_buffer_id_t buffer_id, int *num)
    431 {
    432     int wrap_flag, end_idx, add_0_used;
    433 
    434     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    435                             _TCB_BUF_STATUS_WRAPPED, &wrap_flag));
    436     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    437                             _TCB_BUF_STATUS_PTR, &end_idx));
    438     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    439                             _TCB_BUF_STATUS_0_USED, &add_0_used));
    440 
    441     if (0 == add_0_used) {
    442         *num = 0;
    443     } else if (0 == wrap_flag) {
    444         *num = end_idx + 1;
    445     } else {
    446         *num = 1024;
    447     }
    448 
    449     return BCM_E_NONE;
    450 }
    451 
    452 STATIC void
    453 _bcm_th2_cosq_tcb_pkt_order_fix(uint8 *pkt_data)
    454 {
    455     uint32 temp32;
    456     int i;
    457 
    458     for (i = 36; i >= 20; i -= 4) {
    459         temp32 = *(uint32*)(&pkt_data[i]);
    460         *(uint32*)(&pkt_data[i]) = soc_ntohl(*(uint32*)(&pkt_data[36 - i]));
    461         *(uint32*)(&pkt_data[36 - i]) = soc_ntohl(temp32);
    462     }
    463 
    464     return;
    465 }
    466 
    467 int
    468 bcm_th2_cosq_tcb_uc_queue_resolve(int unit, bcm_cosq_buffer_id_t buffer_id, int qnum,
    469                                   bcm_gport_t *uc_gport)
    470 {
    471     int index, pipe, id;
    472     bcm_port_t mmu_port, local_port, phy_port, local_mmu_port;
    473     soc_info_t *si;
    474 
    475     si = &SOC_INFO(unit);
    476 
    477     index = (qnum) < 708 ? 0 : 1;
    478     pipe = _bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_member[index];
    479     id = (qnum - _bcm_th2_cosq_tcb_ucq_offset[pipe]) %
    480           _BCM_TH2_NUM_UCAST_QUEUE_PER_PORT;
    481     local_mmu_port = (qnum - _bcm_th2_cosq_tcb_ucq_offset[pipe]) /
    482                      _BCM_TH2_NUM_UCAST_QUEUE_PER_PORT;
    483     mmu_port = pipe * SOC_TH_MMU_PORT_STRIDE + local_mmu_port;
    484     phy_port = si->port_m2p_mapping[mmu_port];
    485     local_port = si->port_p2l_mapping[phy_port];
    486     BCM_GPORT_UCAST_QUEUE_GROUP_SYSQID_SET(*uc_gport, local_port, id);
    487 
    488     return BCM_E_NONE;
    489 }
    490 
    491 STATIC int
    492 _bcm_th2_cosq_tcb_celldata_read(int unit, bcm_cosq_buffer_id_t buffer_id,
    493                                 int num, bcm_cosq_tcb_buffer_t *record_entries)
    494 {
    495     uint32 mem_wid;
    496     soc_mem_t mem;
    497     mmu_tcb_buffer_cell_data_upper_entry_t *pud;
    498     mmu_tcb_buffer_cell_data_lower_entry_t *pld;
    499     uint8 *tcb_md_buf = NULL;
    500     int i, j = 0, idx, wrapped;
    501 
    502     LOG_INFO(BSL_LS_BCM_COSQ,
    503              (BSL_META_U(unit,
    504                          "tcb_celldata_read: unit %d, buffer_id %d, num %d\n"),
    505                          unit, buffer_id, num));
    506 
    507     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    508                                                      _TCB_BUF_STATUS_PTR, &idx));
    509     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    510                                                      _TCB_BUF_STATUS_WRAPPED,
    511                                                      &wrapped));
    512 
    513     mem_wid = sizeof(uint32) * soc_mem_entry_words(unit,
    514                                                MMU_TCB_BUFFER_CELL_DATA_UPPERm);
    515     mem = SOC_MEM_UNIQUE_ACC(unit, MMU_TCB_BUFFER_CELL_DATA_UPPERm)[buffer_id];
    516 
    517     if (wrapped) {
    518         tcb_md_buf = soc_cm_salloc(unit, mem_wid * _BCM_TCB_RD_MAX_NUM,
    519                                    "tcb cell data upper");
    520         if (tcb_md_buf == NULL) {
    521             return BCM_E_MEMORY;
    522         }
    523 
    524         SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0,
    525                                                _BCM_TCB_RD_MAX_NUM - 1, tcb_md_buf));
    526 
    527         for (i = idx + 1, j = 0; j < num; i++, j++) {
    528             pud = soc_mem_table_idx_to_pointer(unit, MMU_TCB_BUFFER_CELL_DATA_UPPERm,
    529                         mmu_tcb_buffer_cell_data_upper_entry_t *, tcb_md_buf,
    530                         i % _BCM_TCB_RD_MAX_NUM);
    531             soc_MMU_TCB_BUFFER_CELL_DATA_UPPERm_field_get(unit, (uint32*)pud,
    532                         CBIDATAf, (uint32*)(record_entries[j].buf_data));
    533             _bcm_th2_cosq_tcb_pkt_order_fix(record_entries[j].buf_data);
    534         }
    535     } else {
    536         tcb_md_buf = soc_cm_salloc(unit, mem_wid * num, "tcb cell data upper");
    537         if (tcb_md_buf == NULL) {
    538             return BCM_E_MEMORY;
    539         }
    540 
    541         SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0, num - 1,
    542                                                tcb_md_buf));
    543         for(i = 0; i < num; i++) {
    544             pud = soc_mem_table_idx_to_pointer(unit, MMU_TCB_BUFFER_CELL_DATA_UPPERm,
    545                     mmu_tcb_buffer_cell_data_upper_entry_t *, tcb_md_buf, i);
    546             soc_MMU_TCB_BUFFER_CELL_DATA_UPPERm_field_get(unit, pud,
    547                         CBIDATAf, (uint32*)(record_entries[i].buf_data));
    548             _bcm_th2_cosq_tcb_pkt_order_fix(record_entries[i].buf_data);
    549         }
    550     }
    551 
    552     soc_cm_sfree(unit, tcb_md_buf);
    553 
    554     mem_wid = sizeof(uint32) * soc_mem_entry_words(unit,
    555                                                MMU_TCB_BUFFER_CELL_DATA_LOWERm);
    556     mem = SOC_MEM_UNIQUE_ACC(unit, MMU_TCB_BUFFER_CELL_DATA_LOWERm)[buffer_id];
    557 
    558     if (wrapped) {
    559         tcb_md_buf = soc_cm_salloc(unit, mem_wid * _BCM_TCB_RD_MAX_NUM,
    560                                    "tcb metadata");
    561         if (tcb_md_buf == NULL) {
    562             return BCM_E_MEMORY;
    563         }
    564 
    565         SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0,
    566                                                _BCM_TCB_RD_MAX_NUM - 1, tcb_md_buf));
    567 
    568         for (i = idx + 1, j = 0; j < num; i++, j++) {
    569             pld = soc_mem_table_idx_to_pointer(unit, MMU_TCB_BUFFER_CELL_DATA_LOWERm,
    570                         mmu_tcb_buffer_cell_data_lower_entry_t *, tcb_md_buf,
    571                         i % _BCM_TCB_RD_MAX_NUM);
    572             soc_MMU_TCB_BUFFER_CELL_DATA_LOWERm_field_get(unit, pld,
    573                         CBIDATAf, (uint32*)(&(record_entries[j].buf_data[40])));
    574             _bcm_th2_cosq_tcb_pkt_order_fix((uint8*)(&(record_entries[j].buf_data[40])));
    575         }
    576     } else {
    577         tcb_md_buf = soc_cm_salloc(unit, mem_wid * num, "tcb cell data lower");
    578         if (tcb_md_buf == NULL) {
    579             return BCM_E_MEMORY;
    580         }
    581 
    582         SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0, num - 1,
    583                                                tcb_md_buf));
    584         for(i = 0; i < num; i++) {
    585             pld = soc_mem_table_idx_to_pointer(unit, MMU_TCB_BUFFER_CELL_DATA_LOWERm,
    586                     mmu_tcb_buffer_cell_data_lower_entry_t *, tcb_md_buf, i);
    587 
    588             soc_MMU_TCB_BUFFER_CELL_DATA_LOWERm_field_get(unit, pld,
    589                         CBIDATAf, (uint32*)(&(record_entries[i].buf_data[40])));
    590             _bcm_th2_cosq_tcb_pkt_order_fix((uint8*)(&(record_entries[i].buf_data[40])));
    591         }
    592     }
    593 
    594     soc_cm_sfree(unit, tcb_md_buf);
    595     return BCM_E_NONE;
    596 }
    597 
    598 STATIC int
    599 _bcm_th2_cosq_tcb_modport_set(int unit, int gpp, bcm_gport_t *modport)
    600 {
    601     bcm_module_t mod_in, mod_out;
    602     bcm_port_t port_in, port_out;
    603 
    604     port_in = gpp & SOC_MEM_FIF_DGPP_PORT_MASK;
    605     mod_in = (gpp & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >>
    606              SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS;
    607     BCM_IF_ERROR_RETURN
    608         (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
    609                                  mod_in, port_in, &mod_out, &port_out));
    610     BCM_GPORT_MODPORT_SET(*modport, mod_out, port_out);
    611 
    612     return BCM_E_NONE;
    613 }
    614 
    615 STATIC int
    616 _bcm_th2_cosq_tcb_metadata_read(int unit, bcm_cosq_buffer_id_t buffer_id,
    617                                 int num, bcm_cosq_tcb_buffer_t *record_entries)
    618 {
    619     uint32 mem_wid;
    620     soc_mem_t mem;
    621     tcb_buffer_metadata_entry_t *pmd;
    622     uint8 *tcb_md_buf = NULL;
    623     int i, j, idx, wrapped;
    624     int dvp, dgpp, sgpp, src_port, dst_port, qnum, depth, cell_bytes;
    625     bcm_port_t mmu_port, local_port, phy_port;
    626     soc_info_t *si;
    627     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    628     bcm_gport_t ingress_gport, egress_gport, dvp_gport;
    629 
    630     LOG_INFO(BSL_LS_BCM_COSQ,
    631              (BSL_META_U(unit,
    632                          "tcb_metadata_read: unit %d, buffer_id %d, num %d\n"),
    633                          unit, buffer_id, num));
    634 
    635     si = &SOC_INFO(unit);
    636     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    637     cell_bytes = tcb_unit_info->cell_bytes;
    638 
    639     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    640                                                      _TCB_BUF_STATUS_PTR, &idx));
    641     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
    642                                                      _TCB_BUF_STATUS_WRAPPED,
    643                                                      &wrapped));
    644 
    645     mem_wid = sizeof(uint32) * soc_mem_entry_words(unit, TCB_BUFFER_METADATAm);
    646     mem = SOC_MEM_UNIQUE_ACC(unit, TCB_BUFFER_METADATAm)[buffer_id];
    647 
    648     if (wrapped) {
    649         tcb_md_buf = soc_cm_salloc(unit, mem_wid * _BCM_TCB_RD_MAX_NUM,
    650                                    "tcb metadata");
    651         if (tcb_md_buf == NULL) {
    652             return BCM_E_MEMORY;
    653         }
    654 
    655         SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0,
    656                                 _BCM_TCB_RD_MAX_NUM - 1, tcb_md_buf));
    657 
    658         for (i = idx + 1, j = 0; j < num; i++, j++) {
    659             pmd = soc_mem_table_idx_to_pointer(unit, TCB_BUFFER_METADATAm,
    660                         tcb_buffer_metadata_entry_t *, tcb_md_buf,
    661                         i % _BCM_TCB_RD_MAX_NUM);
    662 
    663             soc_TCB_BUFFER_METADATAm_field_get(unit, pmd, TIMESTAMPf,
    664                                        (uint32*)(&(record_entries[j].timestamp)));
    665 
    666             dvp = soc_TCB_EVENT_BUFFERm_field32_get(unit, pmd, DVPf);
    667             _bcm_vp_encode_gport(unit, dvp, &dvp_gport);
    668 
    669             dgpp = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, DGPPf);
    670             _bcm_th2_cosq_tcb_modport_set(unit, dgpp, &egress_gport);
    671 
    672             sgpp = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, SGPP_SVPf);
    673             if (sgpp & _TCB_SGPP_TYPE_MASK) {
    674                 sgpp &= _TCB_SGPP_MASK;
    675                 _bcm_th2_cosq_tcb_modport_set(unit, sgpp, &ingress_gport);
    676             } else {
    677                 sgpp &= _TCB_SGPP_MASK;
    678                 _bcm_vp_encode_gport(unit, sgpp, &ingress_gport);
    679             }
    680 
    681             src_port = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, SRC_PORTf);
    682             if (SOC_IS_TRIDENT3(unit)) {
    683                 mmu_port = src_port;
    684             } else {
    685                 int index, pipe;
    686 
    687                 index = (src_port) < 64 ? 0 : 1;
    688                 pipe = _bcm_th2_cosq_tcb_pipe_table[buffer_id].ipipe_member[index];
    689                 mmu_port = pipe * SOC_TH_MMU_PORT_STRIDE +
    690                           (src_port - _bcm_th2_cosq_tcb_ing_port_offset[pipe]);
    691             }
    692             phy_port = si->port_m2p_mapping[mmu_port];
    693             local_port = si->port_p2l_mapping[phy_port];
    694             BCM_GPORT_LOCAL_SET(record_entries[j].ingress_gport, local_port);
    695 
    696             qnum = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, QNUMf);
    697             BCM_IF_ERROR_RETURN
    698                 (_bcm_cosq_tcb_uc_queue_resolve(unit, buffer_id, qnum,
    699                                                 &record_entries[j].queue));
    700 
    701             dst_port = BCM_GPORT_UCAST_QUEUE_GROUP_SYSPORTID_GET(record_entries[j].queue);
    702             BCM_GPORT_LOCAL_SET(record_entries[j].egress_gport, dst_port);
    703 
    704             depth = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, Q_DEPTHf);
    705             record_entries[j].queue_size = _MMU_CELLS_TO_BYTES(depth, cell_bytes);
    706 
    707             depth = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, SRVPOOL_DEPTHf);
    708             record_entries[j].service_pool_size = _MMU_CELLS_TO_BYTES(depth, cell_bytes);
    709         }
    710     } else {
    711         tcb_md_buf = soc_cm_salloc(unit, mem_wid * num, "tcb metadata");
    712         if (tcb_md_buf == NULL) {
    713             return BCM_E_MEMORY;
    714         }
    715 
    716         SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0,
    717                                                num - 1, tcb_md_buf));
    718         for(i = 0; i < num; i++) {
    719             pmd = soc_mem_table_idx_to_pointer(unit, TCB_BUFFER_METADATAm,
    720                     tcb_buffer_metadata_entry_t *, tcb_md_buf, i);
    721 
    722             soc_TCB_BUFFER_METADATAm_field_get(unit, pmd, TIMESTAMPf,
    723                                        (uint32*)(&(record_entries[i].timestamp)));
    724 
    725             dvp = soc_TCB_EVENT_BUFFERm_field32_get(unit, pmd, DVPf);
    726             _bcm_vp_encode_gport(unit, dvp, &dvp_gport);
    727 
    728             dgpp = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, DGPPf);
    729             _bcm_th2_cosq_tcb_modport_set(unit, dgpp, &egress_gport);
    730 
    731             sgpp = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, SGPP_SVPf);
    732             if (sgpp & _TCB_SGPP_TYPE_MASK) {
    733                 sgpp &= _TCB_SGPP_MASK;
    734                 _bcm_th2_cosq_tcb_modport_set(unit, sgpp, &ingress_gport);
    735             } else {
    736                 sgpp &= _TCB_SGPP_MASK;
    737                 _bcm_vp_encode_gport(unit, sgpp, &ingress_gport);
    738             }
    739 
    740             src_port = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, SRC_PORTf);
    741             if (SOC_IS_TRIDENT3(unit)) {
    742                 mmu_port = src_port;
    743             } else {
    744                 int index, pipe;
    745 
    746                 index = (src_port) < 64 ? 0 : 1;
    747                 pipe = _bcm_th2_cosq_tcb_pipe_table[buffer_id].ipipe_member[index];
    748                 mmu_port = pipe * SOC_TH_MMU_PORT_STRIDE +
    749                           (src_port - _bcm_th2_cosq_tcb_ing_port_offset[pipe]);
    750             }
    751             phy_port = si->port_m2p_mapping[mmu_port];
    752             local_port = si->port_p2l_mapping[phy_port];
    753             BCM_GPORT_LOCAL_SET(record_entries[i].ingress_gport, local_port);
    754 
    755             qnum = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, QNUMf);
    756             BCM_IF_ERROR_RETURN
    757                 (_bcm_cosq_tcb_uc_queue_resolve(unit, buffer_id, qnum,
    758                                                 &record_entries[i].queue));
    759 
    760             dst_port = BCM_GPORT_UCAST_QUEUE_GROUP_SYSPORTID_GET(record_entries[i].queue);
    761             BCM_GPORT_LOCAL_SET(record_entries[i].egress_gport, dst_port);
    762 
    763             depth = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, Q_DEPTHf);
    764             record_entries[i].queue_size = _MMU_CELLS_TO_BYTES(depth, cell_bytes);
    765 
    766             depth = soc_TCB_BUFFER_METADATAm_field32_get(unit, pmd, SRVPOOL_DEPTHf);
    767             record_entries[i].service_pool_size = _MMU_CELLS_TO_BYTES(depth, cell_bytes);
    768         }
    769     }
    770 
    771     soc_cm_sfree(unit, tcb_md_buf);
    772     return BCM_E_NONE;
    773 }
    774 
    775 STATIC int
    776 _bcm_th2_cosq_tcb_event_buffer_read(int unit, bcm_cosq_buffer_id_t buffer_id,
    777                                  int num, bcm_cosq_tcb_event_t *record_entries)
    778 {
    779     uint32 mem_wid;
    780     tcb_event_buffer_entry_t *ped;
    781     uint8 *tcb_evt_buf = NULL;
    782     soc_mem_t mem;
    783     int idx;
    784     int dvp, dgpp, sgpp, src_port, dst_port, qnum;
    785     int drop_reason = 0, drop_vector, depth, cell_bytes;
    786     bcm_port_t mmu_port, local_port, phy_port;
    787     soc_info_t *si;
    788     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    789     bcm_gport_t ingress_gport, egress_gport, dvp_gport;
    790 
    791     LOG_INFO(BSL_LS_BCM_COSQ,
    792              (BSL_META_U(unit,
    793                          "tcb_event_buffer_read: unit %d, buffer_id %d, num %d\n"),
    794                          unit, buffer_id, num));
    795 
    796     si = &SOC_INFO(unit);
    797     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    798     cell_bytes = tcb_unit_info->cell_bytes;
    799 
    800     mem_wid = sizeof(uint32) * soc_mem_entry_words(unit, TCB_EVENT_BUFFERm);
    801 
    802     tcb_evt_buf = soc_cm_salloc(unit, num * mem_wid, "tcb event");
    803 
    804     if (tcb_evt_buf == NULL) {
    805         return BCM_E_MEMORY;
    806     }
    807 
    808     mem = SOC_MEM_UNIQUE_ACC(unit, TCB_EVENT_BUFFERm)[buffer_id];
    809     SOC_IF_ERROR_RETURN(soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 0, num - 1,
    810                                            tcb_evt_buf));
    811 
    812     for (idx = 0; idx < num; idx++) {
    813         ped = soc_mem_table_idx_to_pointer
    814                     (unit, TCB_EVENT_BUFFERm, tcb_event_buffer_entry_t *,
    815                      tcb_evt_buf, idx);
    816 
    817         soc_TCB_EVENT_BUFFERm_field_get(unit, ped, TIMESTAMPf,
    818                                        (uint32*)(&(record_entries[idx].timestamp)));
    819 
    820         dvp = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, DVPf);
    821         _bcm_vp_encode_gport(unit, dvp, &dvp_gport);
    822 
    823         dgpp = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, DGPPf);
    824         _bcm_th2_cosq_tcb_modport_set(unit, dgpp, &egress_gport);
    825 
    826         sgpp = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, SGPP_SVPf);
    827         if (sgpp & _TCB_SGPP_TYPE_MASK) {
    828             sgpp &= _TCB_SGPP_MASK;
    829             _bcm_th2_cosq_tcb_modport_set(unit, sgpp, &ingress_gport);
    830         } else {
    831             sgpp &= _TCB_SGPP_MASK;
    832             _bcm_vp_encode_gport(unit, sgpp, &ingress_gport);
    833         }
    834 
    835         src_port = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, SRC_PORTf);
    836         if (SOC_IS_TRIDENT3(unit)) {
    837             mmu_port = src_port;
    838         } else {
    839             int index, pipe;
    840 
    841             index = (src_port) < 64 ? 0 : 1;
    842             pipe = _bcm_th2_cosq_tcb_pipe_table[buffer_id].ipipe_member[index];
    843             mmu_port = pipe * SOC_TH_MMU_PORT_STRIDE +
    844                       (src_port - _bcm_th2_cosq_tcb_ing_port_offset[pipe]);
    845         }
    846         phy_port = si->port_m2p_mapping[mmu_port];
    847         local_port = si->port_p2l_mapping[phy_port];
    848         BCM_GPORT_LOCAL_SET(record_entries[idx].ingress_gport, local_port);
    849 
    850         qnum = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, QNUMf);
    851         BCM_IF_ERROR_RETURN
    852             (_bcm_cosq_tcb_uc_queue_resolve(unit, buffer_id, qnum,
    853                                             &record_entries[idx].queue));
    854 
    855         dst_port = BCM_GPORT_UCAST_QUEUE_GROUP_SYSPORTID_GET(record_entries[idx].queue);
    856         BCM_GPORT_LOCAL_SET(record_entries[idx].egress_gport, dst_port);
    857 
    858         depth = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, Q_DEPTHf);
    859         record_entries[idx].queue_size = _MMU_CELLS_TO_BYTES(depth, cell_bytes);
    860 
    861         depth = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, SRVPOOL_DEPTHf);
    862         record_entries[idx].service_pool_size = _MMU_CELLS_TO_BYTES(depth, cell_bytes);
    863 
    864         record_entries[idx].color =
    865                 soc_TCB_EVENT_BUFFERm_field32_get(unit, ped, CNGf);
    866 
    867         drop_vector = soc_TCB_EVENT_BUFFERm_field32_get(unit, ped,
    868                                                         DROP_RSN_VECTORf);
    869         if (drop_vector & _TCB_EVENT_DROP_REASON_IADMN_MASK ||
    870             drop_vector & _TCB_EVENT_DROP_REASON_PURGE_MASK) {
    871             drop_reason = 1 << _SHR_TCB_TRACK_IADMN_DROP_SHIFT;
    872         }
    873         if (drop_vector & _TCB_EVENT_DROP_REASON_EADMN_MASK) {
    874             drop_reason |= 1 << _SHR_TCB_TRACK_EADMN_DROP_SHIFT;
    875         }
    876         if (drop_vector & _TCB_EVENT_DROP_REASON_WRED_MASK) {
    877             drop_reason |= 1 << _SHR_TCB_TRACK_WRED_DROP_SHIFT;
    878         }
    879         if (drop_vector & _TCB_EVENT_DROP_REASON_CFAP_MASK) {
    880             drop_reason |= 1 << _SHR_TCB_TRACK_CFAP_DROP_SHIFT;
    881         }
    882         record_entries[idx].drop_reason = drop_reason;
    883     }
    884 
    885     soc_cm_sfree(unit, tcb_evt_buf);
    886 
    887     return BCM_E_NONE;
    888 
    889 }
    890 
    891 
    892 STATIC void
    893 _bcm_th2_cosq_tcb_scope_help(int unit) {
    894 
    895     int i;
    896     _bcm_cosq_tcb_pipe_port_tab_t tab;
    897 
    898     LOG_INFO(BSL_LS_BCM_COSQ,(BSL_META_U(unit,
    899                         "=== Scope Parameter is Invalid ===\n")));
    900     LOG_INFO(BSL_LS_BCM_COSQ,(BSL_META_U(unit,
    901       "buffer_id\tIng_Port_Range\tEgr_Port_Range\tUcq_Range\n")));
    902 
    903     for (i = 0; i < _BCM_TH2_TCB_MAX_NUM; i++) {
    904         tab = _bcm_th2_cosq_tcb_pipe_table[i];
    905         LOG_INFO(BSL_LS_BCM_COSQ,(BSL_META_U(unit,
    906                          "%d\t%s\t%s\t%s\n"),
    907                          i, tab.iport_range, tab.eport_range,
    908                          tab.ucq_range));
    909     }
    910 
    911     return;
    912 }
    913 
    914 /*
    915  * Function:
    916  *      _bcm_th2_cosq_tcb_deinit
    917  * Purpose:
    918  *      Deinitialize all TCB internal structure.
    919  * Parameters:
    920  *      unit - (IN) BCM device number.
    921  * Returns:
    922  *      BCM_E_XXX
    923  */
    924 int
    925 _bcm_th2_cosq_tcb_deinit(int unit)
    926 {
    927     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    928     _bcm_cosq_tcb_info_t *tcb_info;
    929     int i;
    930 
    931     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    932     if (tcb_unit_info == NULL) {
    933         return BCM_E_NONE;
    934     }
    935 
    936     for (i = 0; i < _BCM_TH2_TCB_MAX_NUM; i++) {
    937         if (NULL != tcb_unit_info->tcb_info[i]) {
    938             tcb_info = tcb_unit_info->tcb_info[i];
    939             if (NULL != tcb_info->profile_bmp) {
    940                 sal_free(tcb_info->profile_bmp);
    941                 tcb_info->profile_bmp = NULL;
    942             }
    943             sal_free(tcb_unit_info->tcb_info[i]);
    944             tcb_unit_info->tcb_info[i] = NULL;
    945         }
    946     }
    947 
    948     if (NULL != tcb_unit_info->tcb_evt_cb) {
    949         tcb_unit_info->tcb_evt_cb = NULL;
    950     }
    951 
    952     if (NULL != tcb_unit_info->tcb_evt_user_data) {
    953         tcb_unit_info->tcb_evt_user_data = NULL;
    954     }
    955 
    956     if (NULL != tcb_unit_info->tcb_reslock) {
    957         sal_mutex_destroy(tcb_unit_info->tcb_reslock);
    958         tcb_unit_info->tcb_reslock = NULL;
    959     }
    960 
    961     sal_free(tcb_unit_info);
    962 
    963     TCB_UNIT_CONTROL(unit) = NULL;
    964 
    965     return BCM_E_NONE;
    966 }
    967 
    968 /*
    969  * Function:
    970  *      bcm_th2_cosq_tcb_control_get
    971  * Purpose:
    972  *      Get TCB instance control status.
    973  * Parameters:
    974  *      unit - (IN) BCM device number.
    975  *      buffer_id - (IN) TCB buffer id.
    976  *      type - (IN) Control type
    977  *      arg - (OUT) argument.
    978  * Returns:
    979  *      BCM_E_XXX
    980  */
    981 int
    982 bcm_th2_cosq_tcb_control_get(int unit, bcm_cosq_buffer_id_t buffer_id,
    983                               bcm_cosq_tcb_control_t type, int *arg)
    984 {
    985     int status;
    986 
    987     LOG_INFO(BSL_LS_BCM_COSQ,
    988              (BSL_META_U(unit,
    989                          "tcb_control_get: unit %d, buffer_id %d, type %d\n"),
    990                          unit, buffer_id, type));
    991 
    992     TCB_ID_CHECK(buffer_id);
    993     if (NULL == arg) {
    994         LOG_ERROR(BSL_LS_BCM_COSQ, (BSL_META_U(unit, "arg is null!\n")));
    995         return BCM_E_PARAM;
    996     }
    997 
    998     if (type == bcmCosqTcbControlEnable) {
    999         if (_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   1000             *arg = 1;
   1001         } else {
   1002             *arg = 0;
   1003         }
   1004     } else if (type == bcmCosqTcbControlFreeze) {
   1005         if (!_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   1006             LOG_INFO(BSL_LS_BCM_COSQ,
   1007                      (BSL_META_U(unit,
   1008                                  "tcb buffer %d is not enabled\n"),
   1009                                  buffer_id));
   1010             return BCM_E_DISABLED;
   1011         }
   1012         BCM_IF_ERROR_RETURN(
   1013                 _bcm_th2_cosq_tcb_current_phase_get(unit, buffer_id, &status));
   1014         if (status == _TCB_FROZEN_PHASE) {
   1015             *arg = 1;
   1016         } else {
   1017             *arg = 0;
   1018         }
   1019     } else {
   1020         LOG_ERROR(BSL_LS_BCM_COSQ,
   1021                   (BSL_META_U(unit,
   1022                               "unknown tcb control type %d\n"),
   1023                               type));
   1024         return BCM_E_PARAM;
   1025     }
   1026 
   1027     return BCM_E_NONE;
   1028 }
   1029 
   1030 /*
   1031  * Function:
   1032  *      bcm_th2_cosq_tcb_enable
   1033  * Purpose:
   1034  *      Enable or disable a TCB buffer.
   1035  * Parameters:
   1036  *      unit - (IN) BCM device number.
   1037  *      buffer_id - (IN) TCB buffer id.
   1038  *      enable - (IN) enable or disable.
   1039  * Returns:
   1040  *      BCM_E_XXX
   1041  */
   1042 int
   1043 bcm_th2_cosq_tcb_enable(int unit, bcm_cosq_buffer_id_t buffer_id, int enable)
   1044 {
   1045     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1046     int mask, rv = BCM_E_NONE;
   1047     uint64 rval64;
   1048 
   1049     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1050     TCB_ID_CHECK(buffer_id);
   1051     mask = 1 << buffer_id;
   1052 
   1053     LOG_INFO(BSL_LS_BCM_COSQ,
   1054              (BSL_META_U(unit,
   1055                          "tcb_enable: unit %d, buffer_id %d, enable %d\n"),
   1056                          unit, buffer_id, enable));
   1057 
   1058     if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
   1059         LOG_INFO(BSL_LS_BCM_COSQ,
   1060                  (BSL_META_U(unit,
   1061                              "tcb config of buffer %d is not initialized\n"),
   1062                              buffer_id));
   1063         return BCM_E_DISABLED;
   1064     }
   1065 
   1066     if (enable) {
   1067         if (tcb_unit_info->tcb_enabled_bmp & mask) {
   1068             /* tcb is already enabled */
   1069             rv = BCM_E_BUSY;
   1070         } else { /* enable tcb */
   1071             SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0,
   1072                                               &rval64));
   1073             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TCB_ENABLEf, 1);
   1074             SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0,
   1075                                               rval64));
   1076 
   1077             if (tcb_unit_info->tcb_enabled_bmp == 0) {
   1078                 /* Enable interrupt */
   1079                 BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_intr_enable_set(unit, 1));
   1080             }
   1081             tcb_unit_info->tcb_enabled_bmp |= mask;
   1082         }
   1083     } else {
   1084         if (!(tcb_unit_info->tcb_enabled_bmp & mask)) {
   1085             /* tcb is already disabled */
   1086             rv =  BCM_E_PARAM;
   1087         } else { /* disable tcb */
   1088             BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_ext_freeze_set(unit, buffer_id, 0));
   1089 
   1090             SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0,
   1091                                               &rval64));
   1092             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TCB_ENABLEf, 0);
   1093             SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0,
   1094                                               rval64));
   1095 
   1096             BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_ready_clear(unit, buffer_id));
   1097 
   1098             tcb_unit_info->tcb_enabled_bmp &= ~mask;
   1099             if (tcb_unit_info->tcb_enabled_bmp == 0) {
   1100                 /* Disable interrupt */
   1101                 BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_intr_enable_set(unit, 0));
   1102             }
   1103         }
   1104     }
   1105 
   1106     return rv;
   1107 
   1108 }
   1109 
   1110 /*
   1111  * Function:
   1112  *      bcm_th2_cosq_tcb_freeze
   1113  * Purpose:
   1114  *      External freeze a TCB buffer.
   1115  * Parameters:
   1116  *      unit - (IN) BCM device number.
   1117  *      buffer_id - (IN) TCB buffer id.
   1118  *      enable - (IN) enable or disable.
   1119  * Returns:
   1120  *      BCM_E_XXX
   1121  * Notes:
   1122  *      When buffer_id is -1, this API will freeze all TCB instance at a once.
   1123  */
   1124 int
   1125 bcm_th2_cosq_tcb_freeze(int unit, bcm_cosq_buffer_id_t buffer_id, int enable)
   1126 {
   1127     int i;
   1128 
   1129     LOG_INFO(BSL_LS_BCM_COSQ,
   1130              (BSL_META_U(unit,
   1131                          "tcb_freeze: unit %d, buffer_id %d, enable %d\n"),
   1132                          unit, buffer_id, enable));
   1133 
   1134     if(-1 == buffer_id) {
   1135         int tcb_disable_all = TRUE;
   1136         /* freeze all TCB instance */
   1137         for (i = 0; i < _BCM_TH2_TCB_MAX_NUM; i++) {
   1138             if (!_bcm_cosq_tcb_is_enabled(unit, i)) {
   1139                 continue;
   1140             }
   1141 
   1142             if (enable) {
   1143                 BCM_IF_ERROR_RETURN(
   1144                         _bcm_th2_cosq_tcb_ext_freeze_set(unit, i, 1));
   1145             } else {
   1146                 BCM_IF_ERROR_RETURN(
   1147                         _bcm_th2_cosq_tcb_ext_freeze_set(unit, i, 0));
   1148                 BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_ready_clear(unit, i));
   1149             }
   1150             tcb_disable_all = FALSE;
   1151         }
   1152 
   1153         if (tcb_disable_all) {
   1154             LOG_INFO(BSL_LS_BCM_COSQ,
   1155                      (BSL_META_U(unit,
   1156                                  "all tcb buffer is disabled, can not freeze\n")));
   1157             return BCM_E_DISABLED;
   1158         }
   1159 
   1160     } else {
   1161         TCB_ID_CHECK(buffer_id);
   1162 
   1163         if (!_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   1164             LOG_INFO(BSL_LS_BCM_COSQ,
   1165                      (BSL_META_U(unit,
   1166                                  "tcb buffer %d is disabled, can not freeze\n"),
   1167                                  buffer_id));
   1168             return BCM_E_DISABLED;
   1169         }
   1170 
   1171         if (0 != enable) {
   1172             BCM_IF_ERROR_RETURN(
   1173                     _bcm_th2_cosq_tcb_ext_freeze_set(unit, buffer_id, 1));
   1174         } else {
   1175             BCM_IF_ERROR_RETURN(
   1176                     _bcm_th2_cosq_tcb_ext_freeze_set(unit, buffer_id, 0));
   1177             BCM_IF_ERROR_RETURN(
   1178                     _bcm_th2_cosq_tcb_buffer_ready_clear(unit, buffer_id));
   1179         }
   1180     }
   1181 
   1182     return BCM_E_NONE;
   1183 }
   1184 
   1185 /*
   1186  * Function:
   1187  *      bcm_th2_cosq_tcb_config_set
   1188  * Purpose:
   1189  *      Set TCB instance config attributes.
   1190  * Parameters:
   1191  *      unit - (IN) BCM device number.
   1192  *      buffer_id - (IN) TCB buffer id.
   1193  *      config - (IN) TCB config information
   1194  * Returns:
   1195  *      BCM_E_XXX
   1196  */
   1197 int
   1198 bcm_th2_cosq_tcb_config_set(int unit, bcm_cosq_buffer_id_t buffer_id,
   1199                             bcm_cosq_tcb_config_t *config)
   1200 {
   1201     uint64 rval64 = COMPILER_64_INIT(0,0);
   1202     int timer;
   1203     bcm_port_t local_port;
   1204     bcm_gport_t gport;
   1205     int mmu_port, phy_port, q_num, pipe, arg = 0, cosq, modid, trunk_id;
   1206     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1207     soc_info_t *si;
   1208     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1209 
   1210     LOG_INFO(BSL_LS_BCM_COSQ,
   1211              (BSL_META_U(unit,
   1212                          "tcb_config_set: unit %d, buffer_id %d\n"),
   1213                          unit, buffer_id));
   1214 
   1215     TCB_ID_CHECK(buffer_id);
   1216     if (NULL == config) {
   1217         LOG_ERROR(BSL_LS_BCM_COSQ,
   1218                   (BSL_META_U(unit, "config is null!\n")));
   1219         return BCM_E_PARAM;
   1220     }
   1221 
   1222     if (_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   1223         /* tcb can only be configured in idle state */
   1224         LOG_INFO(BSL_LS_BCM_COSQ,
   1225                  (BSL_META_U(unit,
   1226                              "tcb buffer %d is enabled\n"),
   1227                              buffer_id));
   1228         return BCM_E_BUSY;
   1229     }
   1230 
   1231     gport = config->gport;
   1232     si = &SOC_INFO(unit);
   1233 
   1234     /* Reset default value */
   1235     if ((config->scope_type == bcmCosqTcbScopeMaxCount) &&
   1236         (config->gport == BCM_GPORT_INVALID) &&
   1237         (config->cosq == -1) &&
   1238         (config->trigger_reason == (BCM_COSQ_TCB_INGRESS_ADMIN_DROP |
   1239                                     BCM_COSQ_TCB_EGRESS_ADMIN_DROP  |
   1240                                     BCM_COSQ_TCB_CFAP_DROP          |
   1241                                     BCM_COSQ_TCB_WRED_DROP)) &&
   1242         (config->pre_freeze_capture_num == _TCB_CAP_NUM_DEFAULT) &&
   1243         (config->pre_freeze_capture_time ==
   1244             _TCB_TIMER_TO_PRE_FREEZE_CAP_TIME(unit, _TCB_CAP_TIM_DEFAULT)) &&
   1245         (config->pre_sample_probability == _TCB_PRE_SAMP_RATE_DEFAULT + 1) &&
   1246         (config->post_sample_probability == _TCB_POST_SAMP_RATE_DEFAULT + 1)) {
   1247 
   1248         SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, rval64));
   1249         /* update TCB instance status */
   1250         if ((tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
   1251             tcb_unit_info->tcb_config_init_bmp &= ~(1 << buffer_id);
   1252         }
   1253         return BCM_E_NONE;
   1254     }
   1255 
   1256     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, &rval64));
   1257 
   1258     switch(config->scope_type) {
   1259         case bcmCosqTcbScopeUcastQueue:
   1260             if (!BCM_GPORT_IS_SET(gport)) {
   1261                 LOG_INFO(BSL_LS_BCM_COSQ,
   1262                          (BSL_META_U(unit,
   1263                                      "tcb config set, gport 0x%x is illegal\n"),
   1264                                      gport));
   1265                 return BCM_E_PARAM;
   1266             }
   1267             if (!BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1268                 LOG_INFO(BSL_LS_BCM_COSQ,
   1269                          (BSL_META_U(unit,
   1270                                      "tcb config set, gport 0x%x is illegal\n"),
   1271                                      gport));
   1272                 return BCM_E_PARAM;
   1273             }
   1274 
   1275             BCM_IF_ERROR_RETURN(_bcm_th_cosq_index_resolve(unit, gport, 0,
   1276                                     _BCM_TH_COSQ_INDEX_STYLE_UCAST_QUEUE, NULL,
   1277                                     &cosq, NULL));
   1278             BCM_IF_ERROR_RETURN(_bcm_th_cosq_port_resolve(unit, gport, &modid,
   1279                                     &local_port, &trunk_id, NULL, NULL));
   1280 
   1281             SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1282             if(!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_bmp),
   1283                            pipe)) {
   1284                 _bcm_th2_cosq_tcb_scope_help(unit);
   1285                 return BCM_E_PARAM;
   1286             }
   1287 
   1288             q_num = cosq + _bcm_th2_cosq_tcb_ucq_offset[pipe];
   1289 
   1290             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
   1291                                   _TCB_SCOPE_UCQ);
   1292             arg = q_num;
   1293             break;
   1294         case bcmCosqTcbScopeIngressPort:
   1295             if (BCM_GPORT_IS_SET(gport)){
   1296                 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport,
   1297                                                            &local_port));
   1298             } else if (SOC_PORT_VALID(unit, gport)) {
   1299                 local_port = gport;
   1300             } else {
   1301                 LOG_INFO(BSL_LS_BCM_COSQ,
   1302                          (BSL_META_U(unit,
   1303                                      "tcb config set, gport 0x%x is illegal\n"),
   1304                                      gport));
   1305                 return BCM_E_PORT;
   1306             }
   1307 
   1308             if (IS_CPU_PORT(unit, local_port) || IS_LB_PORT(unit, local_port)) {
   1309                 LOG_INFO(BSL_LS_BCM_COSQ,
   1310                          (BSL_META_U(unit,
   1311                                      "tcb config set, gport 0x%x is illegal\n"),
   1312                                      gport));
   1313                 return BCM_E_PORT;
   1314             }
   1315 
   1316             phy_port = si->port_l2p_mapping[local_port];
   1317             mmu_port = si->port_p2m_mapping[phy_port];
   1318             pipe = si->port_pipe[local_port];
   1319             if(!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].ipipe_bmp), pipe)) {
   1320                 _bcm_th2_cosq_tcb_scope_help(unit);
   1321                 return BCM_E_PARAM;
   1322             }
   1323 
   1324             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
   1325                               _TCB_SCOPE_ING_PORT);
   1326             arg = mmu_port % SOC_TH_MMU_PORT_STRIDE +
   1327                           _bcm_th2_cosq_tcb_ing_port_offset[pipe];
   1328             break;
   1329         case bcmCosqTcbScopeEgressPort:
   1330             if (BCM_GPORT_IS_SET(gport)){
   1331                 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport,
   1332                                                            &local_port));
   1333             } else if (SOC_PORT_VALID(unit, gport)) {
   1334                 local_port = gport;
   1335             } else {
   1336                 LOG_INFO(BSL_LS_BCM_COSQ,
   1337                          (BSL_META_U(unit,
   1338                                      "tcb config set, gport 0x%x is illegal\n"),
   1339                                      gport));
   1340                 return BCM_E_PORT;
   1341             }
   1342 
   1343             if (IS_CPU_PORT(unit, local_port) || IS_LB_PORT(unit, local_port)) {
   1344                 LOG_INFO(BSL_LS_BCM_COSQ,
   1345                          (BSL_META_U(unit,
   1346                                      "tcb config set, gport 0x%x is illegal\n"),
   1347                                      gport));
   1348                 return BCM_E_PORT;
   1349             }
   1350 
   1351             phy_port = si->port_l2p_mapping[local_port];
   1352             mmu_port = si->port_p2m_mapping[phy_port];
   1353             pipe = si->port_pipe[local_port];
   1354             if(!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_bmp), pipe)) {
   1355                 _bcm_th2_cosq_tcb_scope_help(unit);
   1356                 return BCM_E_PARAM;
   1357             }
   1358 
   1359             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
   1360                                   _TCB_SCOPE_EGR_PORT);
   1361             arg = mmu_port % SOC_TH_MMU_PORT_STRIDE + _bcm_th2_cosq_tcb_egr_port_offset[pipe];
   1362             break;
   1363         case bcmCosqTcbScopeIngressPipe:
   1364             if (!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].ipipe_bmp), config->pipe_id)) {
   1365                 _bcm_th2_cosq_tcb_scope_help(unit);
   1366                 return BCM_E_PARAM;
   1367             }
   1368             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
   1369                                   _TCB_SCOPE_ING_PIPE);
   1370             arg = config->pipe_id;
   1371             break;
   1372         case bcmCosqTcbScopeEgressPipe:
   1373             if (!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_bmp), config->pipe_id)) {
   1374                 _bcm_th2_cosq_tcb_scope_help(unit);
   1375                 return BCM_E_PARAM;
   1376             }
   1377             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
   1378                                   _TCB_SCOPE_EGR_PIPE);
   1379             arg = config->pipe_id;
   1380             break;
   1381         default:
   1382             LOG_INFO(BSL_LS_BCM_COSQ,
   1383                      (BSL_META_U(unit,
   1384                                  "tcb config set, scope type %d is illegal\n"),
   1385                                  config->scope_type));
   1386             return BCM_E_PARAM;
   1387     }
   1388 
   1389     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITYf, arg);
   1390 
   1391     if (config->trigger_reason > _TCB_TRIGGER_MAX) {
   1392         LOG_INFO(BSL_LS_BCM_COSQ,
   1393                  (BSL_META_U(unit,
   1394                              "tcb config set, trigger reason %d is illegal\n"),
   1395                              config->trigger_reason));
   1396         return BCM_E_PARAM;
   1397     }
   1398     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_IADMN_DROPf,
   1399                       (config->trigger_reason & BCM_COSQ_TCB_INGRESS_ADMIN_DROP) ? 1:0);
   1400     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_EADMN_DROPf,
   1401                       (config->trigger_reason & BCM_COSQ_TCB_EGRESS_ADMIN_DROP) ? 1:0);
   1402     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_CFAP_DROPf,
   1403                       (config->trigger_reason & BCM_COSQ_TCB_CFAP_DROP) ? 1:0);
   1404     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_WRED_DROPf,
   1405                       (config->trigger_reason & BCM_COSQ_TCB_WRED_DROP) ? 1:0);
   1406 
   1407     /* rev_counter valid range is 2 - 1024 */
   1408     if ((config->pre_freeze_capture_num < _TCB_CAP_NUM_MIN) ||
   1409         (config->pre_freeze_capture_num > _TCB_CAP_NUM_MAX)) {
   1410         LOG_INFO(BSL_LS_BCM_COSQ,
   1411                  (BSL_META_U(unit,
   1412                              "tcb config set, pre freeze capture %d is illegal\n"),
   1413                              config->pre_freeze_capture_num));
   1414         return BCM_E_PARAM;
   1415     }
   1416     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, REV_COUNTERf,
   1417                           config->pre_freeze_capture_num);
   1418 
   1419     /* WD_TIMER_PRESET is a counter of clock cycles * 10, a value 1 means 10 clock cycles */
   1420     timer = _TCB_PRE_FREEZE_CAP_TIME_TO_TIMER(unit, config->pre_freeze_capture_time);
   1421     if (timer > _TCB_CAP_TIM_MAX) {
   1422         LOG_INFO(BSL_LS_BCM_COSQ,
   1423                  (BSL_META_U(unit,
   1424                              "tcb config set, pre freeze capture time %d is illegal\n"),
   1425                              config->pre_freeze_capture_time));
   1426         return BCM_E_PARAM;
   1427     }
   1428     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, WD_TIMER_PRESETf,
   1429                           timer);
   1430 
   1431     if (config->post_sample_probability > _TCB_POST_SAMP_RATE_MAX ||
   1432         config->post_sample_probability <= 0) {
   1433         LOG_INFO(BSL_LS_BCM_COSQ,
   1434                  (BSL_META_U(unit,
   1435                              "tcb config set, post sample probability %d is illegal\n"),
   1436                              config->post_sample_probability));
   1437         return BCM_E_PARAM;
   1438     }
   1439     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, POST_TRIGGER_SAMPLE_RATEf,
   1440                           config->post_sample_probability - 1);
   1441 
   1442     if (config->pre_sample_probability > _TCB_PRE_SAMP_RATE_MAX ||
   1443         config->pre_sample_probability <= 0) {
   1444         LOG_INFO(BSL_LS_BCM_COSQ,
   1445                  (BSL_META_U(unit,
   1446                              "tcb config set, pre sample probability %d is illegal\n"),
   1447                              config->pre_sample_probability));
   1448         return BCM_E_PARAM;
   1449     }
   1450     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, PRE_TRIGGER_SAMPLE_RATEf,
   1451                           config->pre_sample_probability - 1);
   1452 
   1453     SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, rval64));
   1454 
   1455     /* update TCB instance status */
   1456     if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
   1457         tcb_unit_info->tcb_config_init_bmp |= (1 << buffer_id);
   1458     }
   1459     return BCM_E_NONE;
   1460 }
   1461 
   1462 /*
   1463  * Function:
   1464  *      bcm_th2_cosq_tcb_config_get
   1465  * Purpose:
   1466  *      Get TCB instance control status.
   1467  * Parameters:
   1468  *      unit - (IN) BCM device number.
   1469  *      buffer_id - (IN) TCB buffer id.
   1470  *      config - (OUT) TCB config information
   1471  * Returns:
   1472  *      BCM_E_XXX
   1473  */
   1474 int
   1475 bcm_th2_cosq_tcb_config_get(int unit, bcm_cosq_buffer_id_t buffer_id,
   1476                                     bcm_cosq_tcb_config_t *config)
   1477 {
   1478     uint64 rval64;
   1479     uint32 trigger, timer;
   1480     int type, entity_num, index, pipe,  propability;
   1481     bcm_port_t mmu_port, phy_port, local_port;
   1482     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1483     soc_info_t *si;
   1484     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1485 
   1486     LOG_INFO(BSL_LS_BCM_COSQ,
   1487              (BSL_META_U(unit,
   1488                          "tcb_config_get: unit %d, buffer_id %d\n"),
   1489                          unit, buffer_id));
   1490 
   1491     TCB_ID_CHECK(buffer_id);
   1492     if (NULL == config) {
   1493         LOG_ERROR(BSL_LS_BCM_COSQ,
   1494                   (BSL_META_U(unit, "config is null!\n")));
   1495         return BCM_E_PARAM;
   1496     }
   1497 
   1498     si = &SOC_INFO(unit);
   1499 
   1500     /* check TCB instance status */
   1501     if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
   1502         config->scope_type = bcmCosqTcbScopeMaxCount;
   1503         config->gport = BCM_GPORT_INVALID;
   1504         config->cosq = -1;
   1505         config->trigger_reason = BCM_COSQ_TCB_INGRESS_ADMIN_DROP |
   1506                                  BCM_COSQ_TCB_EGRESS_ADMIN_DROP  |
   1507                                  BCM_COSQ_TCB_CFAP_DROP          |
   1508                                  BCM_COSQ_TCB_WRED_DROP;
   1509         config->pre_freeze_capture_num = _TCB_CAP_NUM_DEFAULT;
   1510         config->pre_freeze_capture_time =
   1511                 _TCB_TIMER_TO_PRE_FREEZE_CAP_TIME(unit, _TCB_CAP_TIM_DEFAULT);
   1512         config->pre_sample_probability = _TCB_PRE_SAMP_RATE_DEFAULT + 1;
   1513         config->post_sample_probability = _TCB_POST_SAMP_RATE_DEFAULT + 1;
   1514 
   1515         return BCM_E_NONE;
   1516     }
   1517 
   1518     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, &rval64));
   1519 
   1520     type = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, SCOPE_ENTITY_TYPEf);
   1521 
   1522     switch(type) {
   1523         case _TCB_SCOPE_UCQ:
   1524             config->scope_type = bcmCosqTcbScopeUcastQueue;
   1525             entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
   1526                                                SCOPE_ENTITYf);
   1527             BCM_IF_ERROR_RETURN
   1528                 (_bcm_cosq_tcb_uc_queue_resolve(unit, buffer_id, entity_num,
   1529                                                 &config->gport));
   1530             break;
   1531         case _TCB_SCOPE_ING_PORT:
   1532             config->scope_type = bcmCosqTcbScopeIngressPort;
   1533             entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
   1534                                                SCOPE_ENTITYf);
   1535             index = (entity_num) < 64 ? 0 : 1;
   1536             pipe = _bcm_th2_cosq_tcb_pipe_table[buffer_id].ipipe_member[index];
   1537             mmu_port = pipe * SOC_TH_MMU_PORT_STRIDE +
   1538                       (entity_num - _bcm_th2_cosq_tcb_ing_port_offset[pipe]);
   1539             phy_port = si->port_m2p_mapping[mmu_port];
   1540             local_port = si->port_p2l_mapping[phy_port];
   1541             BCM_GPORT_LOCAL_SET(config->gport, local_port);
   1542             break;
   1543         case _TCB_SCOPE_EGR_PORT:
   1544             config->scope_type = bcmCosqTcbScopeEgressPort;
   1545             entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
   1546                                                SCOPE_ENTITYf);
   1547             index = (entity_num < 64) ? 0 : 1;
   1548             pipe = _bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_member[index];
   1549             mmu_port = pipe * SOC_TH_MMU_PORT_STRIDE +
   1550                       (entity_num - _bcm_th2_cosq_tcb_egr_port_offset[pipe]);
   1551             phy_port = si->port_m2p_mapping[mmu_port];
   1552             local_port = si->port_p2l_mapping[phy_port];
   1553             BCM_GPORT_LOCAL_SET(config->gport, local_port);
   1554             break;
   1555         case _TCB_SCOPE_ING_PIPE:
   1556             config->scope_type = bcmCosqTcbScopeIngressPipe;
   1557             config->pipe_id = soc_reg64_field32_get(
   1558                 unit, TCB_CONFIGr, rval64, SCOPE_ENTITYf);
   1559             break;
   1560         case _TCB_SCOPE_EGR_PIPE:
   1561             config->scope_type = bcmCosqTcbScopeEgressPipe;
   1562             config->pipe_id = soc_reg64_field32_get(
   1563                 unit, TCB_CONFIGr, rval64, SCOPE_ENTITYf);
   1564             break;
   1565         default:
   1566             LOG_ERROR(BSL_LS_BCM_COSQ,
   1567                       (BSL_META_U(unit,
   1568                                   "scope type %d is illegal\n"),
   1569                                   type));
   1570             return BCM_E_PARAM;
   1571     }
   1572 
   1573     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_IADMN_DROPf);
   1574     config->trigger_reason = trigger << _SHR_TCB_TRACK_IADMN_DROP_SHIFT;
   1575     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_EADMN_DROPf);
   1576     config->trigger_reason |= trigger << _SHR_TCB_TRACK_EADMN_DROP_SHIFT;
   1577     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_CFAP_DROPf);
   1578     config->trigger_reason |= trigger << _SHR_TCB_TRACK_CFAP_DROP_SHIFT;
   1579     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_WRED_DROPf);
   1580     config->trigger_reason |= trigger << _SHR_TCB_TRACK_WRED_DROP_SHIFT;
   1581 
   1582     config->pre_freeze_capture_num = soc_reg64_field32_get(unit, TCB_CONFIGr,
   1583                                                            rval64, REV_COUNTERf);
   1584     timer = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
   1585                                                 WD_TIMER_PRESETf);
   1586     config->pre_freeze_capture_time =
   1587                                 _TCB_TIMER_TO_PRE_FREEZE_CAP_TIME(unit, timer);
   1588     propability = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
   1589                                         PRE_TRIGGER_SAMPLE_RATEf);
   1590     config->pre_sample_probability = propability + 1;
   1591     propability = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
   1592                                         POST_TRIGGER_SAMPLE_RATEf);
   1593     config->post_sample_probability = propability + 1;
   1594 
   1595     return BCM_E_NONE;
   1596 
   1597 }
   1598 
   1599 /*
   1600  * Function:
   1601  *      bcm_th2_cosq_tcb_gport_threshold_mapping_set
   1602  * Purpose:
   1603  *      Set threshold profile for a UCQ or a port.
   1604  * Parameters:
   1605  *      unit - (IN) unit number
   1606  *      gport - (IN) Ucq or a port
   1607  *      cosq  - (IN) Reserved field
   1608  *      buffer_id - (IN) TCB buffer id.
   1609  *      index - (IN) Threshold profile index
   1610  * Returns:
   1611  *      BCM_E_XXX
   1612  * Notes:
   1613  *      When gport is a port, SDK will attach all Ucqs in this port to one threshold profile.
   1614  */
   1615 int
   1616 bcm_th2_cosq_tcb_gport_threshold_mapping_set(int unit,
   1617                                       bcm_gport_t gport, bcm_cos_queue_t cosq,
   1618                                       bcm_cosq_buffer_id_t buffer_id,
   1619                                       int index)
   1620 {
   1621     soc_mem_t profile_mem;
   1622     soc_field_t field;
   1623     bcm_port_t local_port;
   1624     int mmu_port, phy_port, pipe, i, port_index, old_profile;
   1625     bcm_cos_t cos;
   1626     soc_info_t *si;
   1627     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1628     _bcm_cosq_tcb_info_t *tcb_config;
   1629     uint32 entry[SOC_MAX_MEM_WORDS];
   1630 
   1631     si = &SOC_INFO(unit);
   1632     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1633     TCB_ID_CHECK(buffer_id);
   1634 
   1635     LOG_INFO(BSL_LS_BCM_COSQ,
   1636              (BSL_META_U(unit,
   1637                          "tcb_threshold_mapping_set: unit %d, gport 0x%x, "
   1638                          "cosq %d, buffer_id %d, index %d\n"),
   1639                          unit, gport, cosq, buffer_id, index));
   1640 
   1641     if (_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   1642         /* tcb can only be configured in idle state */
   1643         LOG_INFO(BSL_LS_BCM_COSQ,
   1644                  (BSL_META_U(unit,
   1645                              "tcb buffer %d is enabled\n"),
   1646                              buffer_id));
   1647         return BCM_E_BUSY;
   1648     }
   1649 
   1650     tcb_config = tcb_unit_info->tcb_info[buffer_id];
   1651     profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
   1652 
   1653     if (BCM_GPORT_IS_SET(gport)) {
   1654         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1655             BCM_IF_ERROR_RETURN(_bcm_th_cosq_index_resolve(unit, gport, 0,
   1656                                     _BCM_TH_COSQ_INDEX_STYLE_COS, &local_port,
   1657                                     &cos, NULL));
   1658         } else if (BCM_GPORT_IS_LOCAL(gport) || BCM_GPORT_IS_MODPORT(gport)) {
   1659             BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
   1660             cos = -1;
   1661         } else {
   1662             LOG_INFO(BSL_LS_BCM_COSQ,
   1663                      (BSL_META_U(unit,
   1664                                  "tcb_threshold_mapping_set, gport 0x%x is illegal\n"),
   1665                                  gport));
   1666             return BCM_E_PARAM;
   1667         }
   1668     } else {
   1669         local_port = gport;
   1670         cos = -1;
   1671     }
   1672 
   1673     if (!SOC_PORT_VALID(unit, local_port) || IS_CPU_PORT(unit, local_port) ||
   1674         IS_LB_PORT(unit, local_port)) {
   1675         LOG_INFO(BSL_LS_BCM_COSQ,
   1676                  (BSL_META_U(unit,
   1677                              "tcb_threshold_mapping_set, gport 0x%x is illegal\n"),
   1678                              gport));
   1679         return BCM_E_PORT;
   1680     }
   1681 
   1682     phy_port = si->port_l2p_mapping[local_port];
   1683     mmu_port = si->port_p2m_mapping[phy_port];
   1684     pipe = si->port_pipe[local_port];
   1685     port_index = mmu_port % SOC_TH_MMU_PORT_STRIDE +
   1686                           _bcm_th2_cosq_tcb_egr_mmu_port_offset[pipe];
   1687 
   1688     if(!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_bmp), pipe)) {
   1689         _bcm_th2_cosq_tcb_scope_help(unit);
   1690         return BCM_E_PARAM;
   1691     }
   1692 
   1693     if (!SHR_BITGET(tcb_config->profile_bmp, index)) {
   1694         LOG_ERROR(BSL_LS_BCM_COSQ,
   1695                   (BSL_META_U(unit,
   1696                               "profile %d is illegal\n"),
   1697                               index));
   1698         return BCM_E_NOT_FOUND;
   1699     }
   1700 
   1701     if (-1 == cos) {
   1702         BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
   1703                                           port_index, entry));
   1704         for (i = 0; i < _TH2_NUM_PROFILE_COS; i++) {
   1705             field = _bcm_cosq_tcb_threshold_profile_map_fields[i];
   1706             old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm,
   1707                                               entry, field);
   1708             tcb_config->profile_ref_count[old_profile]--;
   1709             soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm, entry, field,
   1710                                 index);
   1711             tcb_config->profile_ref_count[index]++;
   1712         }
   1713         BCM_IF_ERROR_RETURN (soc_mem_write(unit, profile_mem, MEM_BLOCK_ALL,
   1714                                            port_index, entry));
   1715     } else {
   1716         field = _bcm_cosq_tcb_threshold_profile_map_fields[cos];
   1717         BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
   1718                                           port_index, entry));
   1719         old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm,
   1720                                           entry, field);
   1721         tcb_config->profile_ref_count[old_profile]--;
   1722 
   1723         soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm, entry,
   1724                             field, index);
   1725         tcb_config->profile_ref_count[index]++;
   1726         BCM_IF_ERROR_RETURN (soc_mem_write(unit, profile_mem, MEM_BLOCK_ALL,
   1727                                            port_index, entry));
   1728     }
   1729 
   1730     return BCM_E_NONE;
   1731 }
   1732 
   1733 /*
   1734  * Function:
   1735  *      bcm_th2_cosq_tcb_gport_threshold_mapping_get
   1736  * Purpose:
   1737  *      Set threshold profile for a UCQ or a port.
   1738  * Parameters:
   1739  *      unit - (IN) unit number
   1740  *      gport - (IN) Ucq or a port
   1741  *      cosq  - (IN) Reserved field
   1742  *      buffer_id - (IN) TCB buffer id.
   1743  *      index - (OUT) Threshold profile index
   1744  * Returns:
   1745  *      BCM_E_XXX
   1746  * Notes:
   1747  *      When gport is a port, SDK will return the threshold profile index of the first Ucq in this
   1748  *      port.
   1749  */
   1750 int
   1751 bcm_th2_cosq_tcb_gport_threshold_mapping_get(int unit,
   1752                                      bcm_gport_t gport, bcm_cos_queue_t cosq,
   1753                                      bcm_cosq_buffer_id_t buffer_id, int *index)
   1754 {
   1755     soc_mem_t profile_mem;
   1756     soc_field_t field;
   1757     bcm_port_t local_port;
   1758     int mmu_port, phy_port, pipe, port_index, cos;
   1759     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1760     _bcm_cosq_tcb_info_t *tcb_config;
   1761     soc_info_t *si;
   1762     uint32 entry[SOC_MAX_MEM_WORDS];
   1763 
   1764     LOG_INFO(BSL_LS_BCM_COSQ,
   1765              (BSL_META_U(unit,
   1766                          "tcb_threshold_mapping_get: unit %d, gport 0x%x, "
   1767                          "cosq %d, buffer_id %d\n"),
   1768                          unit, gport, cosq, buffer_id));
   1769 
   1770     TCB_ID_CHECK(buffer_id);
   1771     if (NULL == index) {
   1772         LOG_ERROR(BSL_LS_BCM_COSQ,
   1773                   (BSL_META_U(unit, "index is null!\n")));
   1774         return BCM_E_PARAM;
   1775     }
   1776 
   1777     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1778     si = &SOC_INFO(unit);
   1779 
   1780     profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
   1781 
   1782     if (BCM_GPORT_IS_SET(gport)) {
   1783         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1784             BCM_IF_ERROR_RETURN(_bcm_th_cosq_index_resolve(unit, gport, 0,
   1785                                     _BCM_TH_COSQ_INDEX_STYLE_COS, &local_port,
   1786                                     &cos, NULL));
   1787         } else if (BCM_GPORT_IS_LOCAL(gport) || BCM_GPORT_IS_MODPORT(gport)) {
   1788             BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
   1789             cos = 0;
   1790         } else {
   1791             LOG_INFO(BSL_LS_BCM_COSQ,
   1792                      (BSL_META_U(unit,
   1793                                  "tcb_threshold_mapping_get, gport 0x%x is illegal\n"),
   1794                                  gport));
   1795             return BCM_E_PARAM;
   1796         }
   1797     } else {
   1798         local_port = gport;
   1799         cos = 0;
   1800     }
   1801 
   1802     if (!SOC_PORT_VALID(unit, local_port) || IS_CPU_PORT(unit, local_port) ||
   1803         IS_LB_PORT(unit, local_port)) {
   1804         LOG_INFO(BSL_LS_BCM_COSQ,
   1805                  (BSL_META_U(unit,
   1806                              "tcb_threshold_mapping_get, gport 0x%x is illegal\n"),
   1807                              gport));
   1808         return BCM_E_PORT;
   1809     }
   1810 
   1811     phy_port = si->port_l2p_mapping[local_port];
   1812     mmu_port = si->port_p2m_mapping[phy_port];
   1813     pipe = si->port_pipe[local_port];
   1814     port_index = mmu_port % SOC_TH_MMU_PORT_STRIDE +
   1815                           _bcm_th2_cosq_tcb_egr_mmu_port_offset[pipe];
   1816 
   1817     if(!SHR_BITGET(&(_bcm_th2_cosq_tcb_pipe_table[buffer_id].epipe_bmp), pipe)) {
   1818         _bcm_th2_cosq_tcb_scope_help(unit);
   1819         return BCM_E_PARAM;
   1820     }
   1821 
   1822     BCM_IF_ERROR_RETURN(soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
   1823                                      port_index, entry));
   1824 
   1825     field = _bcm_cosq_tcb_threshold_profile_map_fields[cos];
   1826     *index = soc_mem_field32_get(unit,TCB_THRESHOLD_PROFILE_MAPm, entry, field);
   1827 
   1828     tcb_config = tcb_unit_info->tcb_info[buffer_id];
   1829     if (!SHR_BITGET(tcb_config->profile_bmp, *index)) {
   1830         LOG_ERROR(BSL_LS_BCM_COSQ,
   1831                   (BSL_META_U(unit,
   1832                               "profile %d is illegal\n"),
   1833                               *index));
   1834         return BCM_E_NOT_FOUND;
   1835     }
   1836 
   1837     return BCM_E_NONE;
   1838 
   1839 }
   1840 
   1841 /*
   1842  * Function:
   1843  *      bcm_th2_cosq_tcb_threshold_profile_create
   1844  * Purpose:
   1845  *      Create a threshold profile for a specified TCB buffer.
   1846  * Parameters:
   1847  *      unit - (IN) BCM device number.
   1848  *      flags - (IN) BCM_COSQ_TCB_THRESHOLD_PROFILE_WITH_ID: Index arg is given
   1849  *                       BCM_COSQ_TCB_THRESHOLD_PROFILE_REPLACE: Replace existing profile
   1850  *      buffer_id - (IN) TCB buffer id.
   1851  *      threshold - (IN) Threshold profile
   1852  *      index - (INOUT) profile index
   1853  * Returns:
   1854  *      BCM_E_XXX
   1855  * Notes:
   1856  *      If user do not specify index, SDK will alloc a profile index and return to user.
   1857  *      With BCM_COSQ_TCB_THRESHOLD_PROFILE_REPLACE flag user could directly update a
   1858  *      existing threshold profile to new values.
   1859  */
   1860 int
   1861 bcm_th2_cosq_tcb_threshold_profile_create(int unit, int flags,
   1862                                      bcm_cosq_buffer_id_t buffer_id,
   1863                                      bcm_cosq_tcb_threshold_profile_t *threshold,
   1864                                      int *index)
   1865 {
   1866     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1867     _bcm_cosq_tcb_info_t *tcb_config;
   1868 
   1869     uint64 rval64;
   1870     int start_threshold, stop_threshold, i, start_cell, stop_cell, cell_bytes, threshold_max;
   1871 
   1872     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1873     TCB_ID_CHECK(buffer_id);
   1874     cell_bytes = tcb_unit_info->cell_bytes;
   1875     threshold_max = tcb_unit_info->threshold_max;
   1876 
   1877     LOG_INFO(BSL_LS_BCM_COSQ,
   1878              (BSL_META_U(unit,
   1879                          "tcb_threshold_profile_create: unit %d, "
   1880                          "flags %d, buffer_id %d\n"),
   1881                          unit, flags, buffer_id));
   1882 
   1883     if (_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   1884         /* tcb can only be configured in idle state */
   1885         LOG_INFO(BSL_LS_BCM_COSQ,
   1886                  (BSL_META_U(unit,
   1887                              "tcb buffer %d is enabled\n"),
   1888                              buffer_id));
   1889         return BCM_E_BUSY;
   1890     }
   1891 
   1892     if (NULL == threshold || NULL == index) {
   1893         LOG_ERROR(BSL_LS_BCM_COSQ,
   1894                   (BSL_META_U(unit, "threshold or index is null!\n")));
   1895         return BCM_E_PARAM;
   1896     }
   1897 
   1898     start_threshold = _MMU_BYTES_TO_CELLS(threshold->start_threshold_bytes,
   1899                                               cell_bytes);
   1900     stop_threshold = _MMU_BYTES_TO_CELLS(threshold->stop_threshold_bytes,
   1901                                              cell_bytes);
   1902     if (start_threshold> threshold_max || start_threshold <= 0 ||
   1903         stop_threshold > threshold_max || stop_threshold <= 0 ||
   1904         start_threshold <= stop_threshold) {
   1905         /* start_threshold should be higher than stop_threshold */
   1906         LOG_INFO(BSL_LS_BCM_COSQ,
   1907                  (BSL_META_U(unit,
   1908                              "tcb profile create: start threshold %d or "
   1909                              "stop threshold %d is illegal.\n"),
   1910                              start_threshold, stop_threshold));
   1911         return BCM_E_PARAM;
   1912     }
   1913 
   1914     if (flags & BCM_COSQ_TCB_THRESHOLD_PROFILE_REPLACE) {
   1915         if (!(flags & BCM_COSQ_TCB_THRESHOLD_PROFILE_WITH_ID)) {
   1916             LOG_INFO(BSL_LS_BCM_COSQ,
   1917                      (BSL_META_U(unit,
   1918                                  "tcb profile create: flags %d is illegal.\n"),
   1919                                  flags));
   1920             return BCM_E_PARAM;
   1921         }
   1922         if (*index >= _BCM_TH2_TCB_PROFILE_MAX_NUM || *index <= 0) {
   1923             LOG_INFO(BSL_LS_BCM_COSQ,
   1924                      (BSL_META_U(unit,
   1925                                  "tcb profile create: index %d is illegal.\n"),
   1926                                  *index));
   1927             return BCM_E_PARAM;
   1928         }
   1929 
   1930         tcb_config = tcb_unit_info->tcb_info[buffer_id];
   1931         if (!SHR_BITGET(tcb_config->profile_bmp, *index))
   1932         {
   1933             LOG_ERROR(BSL_LS_BCM_COSQ,
   1934                       (BSL_META_U(unit, "index %d is illegal.\n"),
   1935                                   *index));
   1936             return BCM_E_NOT_FOUND;
   1937         }
   1938     } else if (flags & BCM_COSQ_TCB_THRESHOLD_PROFILE_WITH_ID) {
   1939         if (*index >= _BCM_TH2_TCB_PROFILE_MAX_NUM || *index <= 0) {
   1940             LOG_ERROR(BSL_LS_BCM_COSQ,
   1941                       (BSL_META_U(unit, "index %d is illegal.\n"),
   1942                                   *index));
   1943             return BCM_E_PARAM;
   1944         }
   1945 
   1946         tcb_config = tcb_unit_info->tcb_info[buffer_id];
   1947         if (SHR_BITGET(tcb_config->profile_bmp, *index))
   1948         {
   1949             LOG_ERROR(BSL_LS_BCM_COSQ,
   1950                       (BSL_META_U(unit, "index %d is illegal.\n"),
   1951                                   *index));
   1952             return BCM_E_EXISTS;
   1953         }
   1954         SHR_BITSET(tcb_config->profile_bmp, *index);
   1955 
   1956     } else {/* allocate new profile*/
   1957         for (i = 0; i < _BCM_TH2_TCB_PROFILE_MAX_NUM; i++) {
   1958             BCM_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr,
   1959                                               buffer_id, i, &rval64));
   1960             start_cell = soc_reg64_field_get(unit, TCB_THRESHOLD_PROFILEr, rval64,
   1961                                            CAPTURE_START_THRESHOLDf);
   1962             stop_cell = soc_reg64_field_get(unit, TCB_THRESHOLD_PROFILEr, rval64,
   1963                                           CAPTURE_END_THRESHOLDf);
   1964             if (start_threshold == start_cell && stop_threshold == stop_cell) {
   1965                 *index = i;
   1966                 return BCM_E_NONE;
   1967             }
   1968         }
   1969         BCM_IF_ERROR_RETURN(
   1970                 _bcm_th2_cosq_tcb_profile_id_alloc(unit, buffer_id, index));
   1971     }
   1972 
   1973     BCM_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr, buffer_id,
   1974                                       *index, &rval64));
   1975     soc_reg64_field_set(unit, TCB_THRESHOLD_PROFILEr, &rval64,
   1976                         CAPTURE_START_THRESHOLDf, start_threshold);
   1977     soc_reg64_field_set(unit, TCB_THRESHOLD_PROFILEr, &rval64,
   1978                         CAPTURE_END_THRESHOLDf, stop_threshold);
   1979 
   1980     soc_reg64_set(unit, TCB_THRESHOLD_PROFILEr, buffer_id, *index, rval64);
   1981 
   1982     return BCM_E_NONE;
   1983 }
   1984 
   1985 /*
   1986  * Function:
   1987  *      bcm_th2_cosq_tcb_threshold_profile_get
   1988  * Purpose:
   1989  *      Get a threshold profile for a specified TCB buffer.
   1990  * Parameters:
   1991  *      unit - (IN) BCM device number.
   1992  *      buffer_id - (IN) TCB buffer id.
   1993  *      index - (IN) profile index
   1994  *      threshold - (OUT) Threshold profile
   1995  * Returns:
   1996  *      BCM_E_XXX
   1997  */
   1998 int
   1999 bcm_th2_cosq_tcb_threshold_profile_get(int unit,
   2000                               bcm_cosq_buffer_id_t buffer_id, int index,
   2001                               bcm_cosq_tcb_threshold_profile_t *threshold)
   2002 {
   2003     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   2004     _bcm_cosq_tcb_info_t *tcb_config;
   2005 
   2006     uint64 rval64;
   2007     int cells, cell_bytes;
   2008 
   2009     LOG_INFO(BSL_LS_BCM_COSQ,
   2010              (BSL_META_U(unit,
   2011                          "tcb_threshold_profile_get: unit %d, "
   2012                          "buffer_id %d index %d\n"),
   2013                          unit, buffer_id, index));
   2014 
   2015     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   2016     TCB_ID_CHECK(buffer_id);
   2017     cell_bytes = tcb_unit_info->cell_bytes;
   2018 
   2019     if (index >= _BCM_TH2_TCB_PROFILE_MAX_NUM || index <= 0) {
   2020         LOG_ERROR(BSL_LS_BCM_COSQ,
   2021                   (BSL_META_U(unit, "index %d is illegal.\n"), index));
   2022         return BCM_E_PARAM;
   2023     }
   2024 
   2025     if (NULL == threshold) {
   2026         LOG_ERROR(BSL_LS_BCM_COSQ,
   2027                   (BSL_META_U(unit, "threshold is null!\n")));
   2028         return BCM_E_PARAM;
   2029     }
   2030 
   2031     tcb_config = tcb_unit_info->tcb_info[buffer_id];
   2032     if (!SHR_BITGET(tcb_config->profile_bmp, index))
   2033     {
   2034         LOG_ERROR(BSL_LS_BCM_COSQ,
   2035                   (BSL_META_U(unit, "index %d is illegal.\n"), index));
   2036         return BCM_E_NOT_FOUND;
   2037     }
   2038 
   2039     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr, buffer_id,
   2040                                       index, &rval64));
   2041     cells = soc_reg64_field_get(unit, TCB_THRESHOLD_PROFILEr, rval64,
   2042                               CAPTURE_START_THRESHOLDf);
   2043     threshold->start_threshold_bytes = _MMU_CELLS_TO_BYTES(cells, cell_bytes);
   2044     cells = soc_reg64_field_get(unit, TCB_THRESHOLD_PROFILEr, rval64,
   2045                               CAPTURE_END_THRESHOLDf);
   2046     threshold->stop_threshold_bytes = _MMU_CELLS_TO_BYTES(cells, cell_bytes);
   2047 
   2048     return BCM_E_NONE;
   2049 }
   2050 
   2051 /*
   2052  * Function:
   2053  *      bcm_th2_cosq_tcb_threshold_profile_destroy
   2054  * Purpose:
   2055  *      Destory a existing threshold profile for a specified TCB buffer.
   2056  * Parameters:
   2057  *      unit - (IN) BCM device number.
   2058  *      buffer_id - (IN) TCB buffer id.
   2059  *      index - (IN) profile index
   2060  * Returns:
   2061  *      BCM_E_XXX
   2062  */
   2063 int
   2064 bcm_th2_cosq_tcb_threshold_profile_destroy(int unit,
   2065                                              bcm_cosq_buffer_id_t buffer_id,
   2066                                              int index)
   2067 {
   2068     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   2069     _bcm_cosq_tcb_info_t *tcb_config;
   2070     uint64 rval64;
   2071     soc_mem_t profile_mem;
   2072     soc_field_t field;
   2073     int num_entries, mem_wsz;
   2074     int i, j, index_min, index_max;
   2075     int old_profile;
   2076     void *pentry;
   2077     char *dmabuf;
   2078 
   2079     LOG_INFO(BSL_LS_BCM_COSQ,
   2080              (BSL_META_U(unit,
   2081                          "tcb_threshold_profile_destroy: unit %d, "
   2082                          "buffer_id %d index %d\n"),
   2083                          unit, buffer_id, index));
   2084 
   2085     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   2086     TCB_ID_CHECK(buffer_id);
   2087 
   2088     if (_bcm_cosq_tcb_is_enabled(unit, buffer_id)) {
   2089         /* tcb can only be configured in idle state */
   2090         LOG_INFO(BSL_LS_BCM_COSQ,
   2091                  (BSL_META_U(unit,
   2092                              "tcb buffer %d is enabled\n"),
   2093                              buffer_id));
   2094         return BCM_E_BUSY;
   2095     }
   2096 
   2097     if (index >= _BCM_TH2_TCB_PROFILE_MAX_NUM || index <= 0) {
   2098         LOG_ERROR(BSL_LS_BCM_COSQ,
   2099                   (BSL_META_U(unit, "index %d is illegal.\n"), index));
   2100         return BCM_E_PARAM;
   2101     }
   2102 
   2103     tcb_config = tcb_unit_info->tcb_info[buffer_id];
   2104     if (!SHR_BITGET(tcb_config->profile_bmp, index))
   2105     {
   2106         LOG_ERROR(BSL_LS_BCM_COSQ,
   2107                   (BSL_META_U(unit, "index %d is illegal.\n"), index));
   2108         return BCM_E_NOT_FOUND;
   2109     }
   2110 
   2111     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr, buffer_id,
   2112                                       index, &rval64));
   2113     soc_reg64_field_set(unit, TCB_THRESHOLD_PROFILEr, &rval64,
   2114                         CAPTURE_START_THRESHOLDf, 0);
   2115     soc_reg64_field_set(unit, TCB_THRESHOLD_PROFILEr, &rval64,
   2116                         CAPTURE_END_THRESHOLDf, 0);
   2117     soc_reg64_set(unit, TCB_THRESHOLD_PROFILEr, buffer_id, index, rval64);
   2118 
   2119     /* Reset profile map table */
   2120     profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
   2121     num_entries = soc_mem_index_count(unit, profile_mem);
   2122     index_min = soc_mem_index_min(unit, profile_mem);
   2123     index_max = soc_mem_index_max(unit, profile_mem);
   2124     mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, profile_mem);
   2125 
   2126     dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "tcb profile");
   2127     if (dmabuf == NULL) {
   2128         return BCM_E_MEMORY;
   2129     }
   2130 
   2131     if (soc_mem_read_range(unit, profile_mem, MEM_BLOCK_ALL,
   2132                            index_min, index_max, dmabuf)) {
   2133         soc_cm_sfree(unit, dmabuf);
   2134         return BCM_E_INTERNAL;
   2135     }
   2136 
   2137     for (i = index_min; i <= index_max; i++) {
   2138         pentry = soc_mem_table_idx_to_pointer(unit, profile_mem, void*, dmabuf, i);
   2139         for (j = 0; j < _TH2_NUM_PROFILE_COS;j++) {
   2140             field = _bcm_cosq_tcb_threshold_profile_map_fields[j];
   2141             old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm,
   2142                                               pentry, field);
   2143             if (old_profile == index) {
   2144                 tcb_config->profile_ref_count[index]--;
   2145                 soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm,
   2146                                     pentry, field, 0);
   2147                 tcb_config->profile_ref_count[0]++;
   2148             }
   2149         }
   2150     }
   2151 
   2152     if (soc_mem_write_range(unit, profile_mem, MEM_BLOCK_ALL,
   2153                             index_min, index_max, dmabuf)) {
   2154         soc_cm_sfree(unit, dmabuf);
   2155         return BCM_E_INTERNAL;
   2156     }
   2157 
   2158     if (tcb_config->profile_ref_count[index] != 0) {
   2159         LOG_ERROR(BSL_LS_BCM_COSQ, (BSL_META_U(unit,
   2160                                     "TCB buffer %d profile %d ref_count %d != 0\n"),
   2161                                     buffer_id, index,
   2162                                     tcb_config->profile_ref_count[index]));
   2163     }
   2164 
   2165     SHR_BITCLR(tcb_config->profile_bmp, index);
   2166     soc_cm_sfree(unit, dmabuf);
   2167 
   2168     return BCM_E_NONE;
   2169 }
   2170 
   2171 /*
   2172  * Function:
   2173  *      bcm_th2_cosq_tcb_init
   2174  * Purpose:
   2175  *      Initialize (clear) all TCB internal structure.
   2176  * Parameters:
   2177  *      unit - (IN) BCM device number.
   2178  * Returns:
   2179  *      BCM_E_XXX
   2180  */
   2181 int
   2182 bcm_th2_cosq_tcb_init(int unit)
   2183 {
   2184     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   2185     _bcm_cosq_tcb_info_t *tcb_info;
   2186     bcm_cosq_buffer_id_t buffer_id = 0;
   2187     soc_mem_t profile_mem;
   2188 
   2189     (void)_bcm_th2_cosq_tcb_deinit(unit);
   2190 
   2191     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   2192     if (NULL == tcb_unit_info) {
   2193         tcb_unit_info = sal_alloc(sizeof(_bcm_cosq_tcb_unit_ctrl_t), "tcb_dev_info");
   2194         if (!tcb_unit_info) {
   2195             return BCM_E_MEMORY;
   2196         }
   2197     }
   2198 
   2199     sal_memset(tcb_unit_info, 0, sizeof(_bcm_cosq_tcb_unit_ctrl_t));
   2200 
   2201     TCB_UNIT_CONTROL(unit) = tcb_unit_info;
   2202 
   2203     tcb_unit_info->tcb_num = _BCM_TH2_TCB_MAX_NUM;
   2204     tcb_unit_info->cell_bytes = _TH_MMU_BYTES_PER_CELL;
   2205     tcb_unit_info->threshold_max = _BCM_TH2_TCB_THRESHOLD_MAX;
   2206 
   2207     /* Create protection mutex. */
   2208     if (tcb_unit_info->tcb_reslock == NULL) {
   2209         tcb_unit_info->tcb_reslock = sal_mutex_create("tcb_resource_lock");
   2210     }
   2211 
   2212     if (tcb_unit_info->tcb_reslock == NULL) {
   2213         (void)_bcm_th2_cosq_tcb_deinit(unit);
   2214         return BCM_E_MEMORY;
   2215     }
   2216 
   2217     for (buffer_id = 0; buffer_id < _BCM_TH2_TCB_MAX_NUM; buffer_id++) {
   2218         tcb_unit_info->tcb_info[buffer_id] =
   2219                 sal_alloc(sizeof(_bcm_cosq_tcb_info_t), "tcb info");
   2220         if (NULL == tcb_unit_info->tcb_info[buffer_id]) {
   2221             (void)_bcm_th2_cosq_tcb_deinit(unit);
   2222             return BCM_E_MEMORY;
   2223         }
   2224 
   2225         sal_memset(tcb_unit_info->tcb_info[buffer_id], 0, sizeof(_bcm_cosq_tcb_info_t));
   2226 
   2227         tcb_info = tcb_unit_info->tcb_info[buffer_id];
   2228         tcb_info->profile_bmp =
   2229                 sal_alloc(SHR_BITALLOCSIZE(_BCM_TH2_TCB_PROFILE_MAX_NUM),
   2230                           "profile_bitmap");
   2231         if (NULL == tcb_info->profile_bmp) {
   2232             (void)_bcm_th2_cosq_tcb_deinit(unit);
   2233             return BCM_E_MEMORY;
   2234         }
   2235         sal_memset(tcb_info->profile_bmp, 0,
   2236                    SHR_BITALLOCSIZE(_BCM_TH2_TCB_PROFILE_MAX_NUM));
   2237     }
   2238 
   2239     if (!SOC_WARM_BOOT(unit)) {
   2240         for (buffer_id = 0; buffer_id < _BCM_TH2_TCB_MAX_NUM; buffer_id++) {
   2241             SHR_BITSET(tcb_info->profile_bmp, 0);
   2242             profile_mem =
   2243                 SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
   2244             tcb_info = tcb_unit_info->tcb_info[buffer_id];
   2245             tcb_info->profile_ref_count[0] =
   2246                     soc_mem_index_count(unit, profile_mem) * 10;
   2247         }
   2248     }
   2249 
   2250     soc_th2_tcb_set_hw_intr_cb(unit);
   2251 
   2252     return BCM_E_NONE;
   2253 }
   2254 
   2255 
   2256 /*
   2257  * Function:
   2258  *      bcm_th2_cosq_tcb_buffer_multi_get
   2259  * Purpose:
   2260  *      Get packet records in a specified TCB buffer.
   2261  * Parameters:
   2262  *      unit - (IN) BCM device number.
   2263  *      buffer_id - (IN) buffer id
   2264  *      array_max - (IN) Number of entries to be retrieved
   2265  *      buffer_array - (OUT) Pakcet record array
   2266  *      array_count - (OUT) Number of packet records returned in buffer_array
   2267  * Returns:
   2268  *      BCM_E_XXX
   2269  * Notes:
   2270  *      When array_max is 0, buffer_array is NULL, array_count will return actural packet record
   2271  *      count in the TCB buffer.
   2272  */
   2273 int
   2274 bcm_th2_cosq_tcb_buffer_multi_get(int unit,
   2275                           bcm_cosq_buffer_id_t buffer_id, int count,
   2276                           bcm_cosq_tcb_buffer_t *entries, int *num)
   2277 {
   2278     int i_count = 0, status;
   2279 
   2280     LOG_INFO(BSL_LS_BCM_COSQ,
   2281              (BSL_META_U(unit,
   2282                          "tcb_buffer_multi_get: unit %d, buffer_id %d, count %d\n"),
   2283                          unit, buffer_id, count));
   2284 
   2285     TCB_ID_CHECK(buffer_id);
   2286 
   2287     if (count < 0) {
   2288         LOG_ERROR(BSL_LS_BCM_COSQ,
   2289                   (BSL_META_U(unit, "count %d is illegal\n"), count));
   2290         return BCM_E_PARAM;
   2291     }
   2292 
   2293     if((count > 0) && (NULL == entries)) {
   2294         LOG_ERROR(BSL_LS_BCM_COSQ,
   2295                   (BSL_META_U(unit, "entries is null\n")));
   2296         return BCM_E_PARAM;
   2297     }
   2298 
   2299     if (NULL == num) {
   2300         LOG_ERROR(BSL_LS_BCM_COSQ,
   2301                   (BSL_META_U(unit, "num is null\n")));
   2302         return BCM_E_PARAM;
   2303     }
   2304 
   2305     /* event buffer can only be read in freeze status */
   2306     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_current_phase_get(unit, buffer_id, &status));
   2307     if (_TCB_FROZEN_PHASE != status) {
   2308         LOG_ERROR(BSL_LS_BCM_COSQ,
   2309                   (BSL_META_U(unit,
   2310                               "tcb buffer can only be read in freeze status "
   2311                               "current status %d\n"),
   2312                               status));
   2313         return BCM_E_BUSY;
   2314     }
   2315 
   2316     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_get_rd_num(unit, buffer_id, num));
   2317 
   2318     if((0 == *num) || (0 == count)) {
   2319         return BCM_E_NONE;
   2320     }
   2321 
   2322     if(count < *num) {
   2323         i_count = count;
   2324         *num = count;
   2325     } else {
   2326         i_count = *num;
   2327     }
   2328     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_metadata_read(unit, buffer_id, i_count,
   2329                                                    entries));
   2330     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_celldata_read(unit, buffer_id, i_count,
   2331                                                    entries));
   2332 
   2333     return BCM_E_NONE;
   2334 }
   2335 
   2336 /*
   2337  * Function:
   2338  *      bcm_th2_cosq_tcb_event_multi_get
   2339  * Purpose:
   2340  *      Get drop event records in a specified TCB buffer.
   2341  * Parameters:
   2342  *      unit - (IN) BCM device number.
   2343  *      buffer_id - (IN) buffer id
   2344  *      array_max - (IN) Number of entries to be retrieved
   2345  *      event_array - (OUT) Drop event record array
   2346  *      array_count - (OUT) Number of drop event records returned in event_array
   2347  *      overflow_count - (OUT) Drop event count exceed the event buffer.
   2348  * Returns:
   2349  *      BCM_E_XXX
   2350  * Notes:
   2351  *      When array_max is 0, event_array is NULL, array_count will return actural drop event
   2352  *      record count in the TCB buffer.
   2353  */
   2354 int
   2355 bcm_th2_cosq_tcb_event_multi_get(int unit,
   2356                             bcm_cosq_buffer_id_t buffer_id, int count,
   2357                             bcm_cosq_tcb_event_t *entries, int *num,
   2358                             int *overflow_num)
   2359 {
   2360     int i_count = 0;
   2361     int status;
   2362 
   2363     LOG_INFO(BSL_LS_BCM_COSQ,
   2364              (BSL_META_U(unit,
   2365                          "tcb_event_multi_get: unit %d, buffer_id %d, count %d\n"),
   2366                          unit, buffer_id, count));
   2367 
   2368     TCB_ID_CHECK(buffer_id);
   2369 
   2370     if (count < 0) {
   2371         LOG_ERROR(BSL_LS_BCM_COSQ,
   2372                   (BSL_META_U(unit, "count %d is illegal\n"), count));
   2373         return BCM_E_PARAM;
   2374     }
   2375 
   2376     if((count > 0) && (NULL == entries)) {
   2377         LOG_ERROR(BSL_LS_BCM_COSQ,
   2378                   (BSL_META_U(unit, "entries is null\n")));
   2379         return BCM_E_PARAM;
   2380     }
   2381 
   2382     if (NULL == num) {
   2383         LOG_ERROR(BSL_LS_BCM_COSQ,
   2384                   (BSL_META_U(unit, "num is null\n")));
   2385         return BCM_E_PARAM;
   2386     }
   2387 
   2388     if (NULL == overflow_num) {
   2389         LOG_ERROR(BSL_LS_BCM_COSQ,
   2390                   (BSL_META_U(unit, "overflow is null\n")));
   2391         return BCM_E_PARAM;
   2392     }
   2393 
   2394     /* event buffer can only be read in freeze status */
   2395     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_current_phase_get(unit, buffer_id, &status));
   2396     if (_TCB_FROZEN_PHASE != status) {
   2397         LOG_ERROR(BSL_LS_BCM_COSQ,
   2398                   (BSL_META_U(unit,
   2399                               "event buffer can only be read in freeze status "
   2400                               "current status %d\n"),
   2401                               status));
   2402         return BCM_E_BUSY;
   2403     }
   2404 
   2405     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_buffer_info_get(unit, buffer_id,
   2406                                                      _TCB_BUF_STATUS_EVT_NUM, num));
   2407     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_evt_overflow_count_get(unit, buffer_id,
   2408                                                             overflow_num));
   2409 
   2410     if ((0 == *num) || (0 == count)) {
   2411         return BCM_E_NONE;
   2412     }
   2413 
   2414     if (count < *num) {
   2415         i_count = count;
   2416         *num = count;
   2417     } else {
   2418         i_count = *num;
   2419     }
   2420     BCM_IF_ERROR_RETURN(_bcm_th2_cosq_tcb_event_buffer_read(unit, buffer_id,
   2421                                                             i_count, entries));
   2422 
   2423     return BCM_E_NONE;
   2424 }
   2425 
   2426 #ifndef BCM_SW_STATE_DUMP_DISABLE
   2427 /*
   2428  * Function:
   2429  *     bcm_th2_cosq_tcb_sw_dump
   2430  * Purpose:
   2431  *     Displays TCB threshold information maintained by software.
   2432  * Parameters:
   2433  *     unit - Device unit number
   2434  * Returns:
   2435  *     None
   2436  */
   2437 void
   2438 bcm_th2_cosq_tcb_sw_dump(int unit)
   2439 {
   2440     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   2441     _bcm_cosq_tcb_info_t *tcb_config;
   2442     int i, j;
   2443 
   2444     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   2445     if (tcb_unit_info == NULL) {
   2446         LOG_CLI((BSL_META_U(unit,
   2447                      "ERROR: TCB module not initialized on Unit:%d \n"), unit));
   2448         return;
   2449     }
   2450 
   2451     for (i = 0; i < tcb_unit_info->tcb_num; i++) {
   2452         LOG_CLI((BSL_META_U(unit,
   2453                             "TCB profile info: TCB buffer %d \n"), i));
   2454         tcb_config = tcb_unit_info->tcb_info[i];
   2455         for (j = 0; j < _BCM_TH2_TCB_PROFILE_MAX_NUM; j++) {
   2456             if (SHR_BITGET(tcb_config->profile_bmp, j)) {
   2457                 LOG_CLI((BSL_META_U(unit,
   2458                             " profile:%d   ref_count:%d \n"),
   2459                             j, tcb_config->profile_ref_count[j]));
   2460             }
   2461         }
   2462     }
   2463 
   2464     return;
   2465 }
   2466 #endif /* BCM_SW_STATE_DUMP_DISABLE */
   2467 
   2468 #endif /* INCLUDE_TCB && BCM_TCB_SUPPORT */
   2469