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


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