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


      1 /*
      2  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3  * 
      4  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5  */
      6 
      7 #include <bcm/cosq.h>
      8 
      9 #include <bcm_int/esw_dispatch.h>
     10 #include <bcm_int/esw/trident3.h>
     11 
     12 #include <soc/trident3.h>
     13 
     14 #if defined (INCLUDE_TCB) && defined (BCM_TCB_SUPPORT)
     15 #include <bcm_int/esw/tcb.h>
     16 
     17 #define _BCM_TD3_TCB_MAX_NUM    1
     18 #define _BCM_TD3_TCB_PROFILE_MAX_NUM    8
     19 #define _BCM_TD3_TCB_THRESHOLD_MAX      0x3ffff
     20 
     21 #define _BCM_TD3_NUM_UCAST_QUEUE_PER_PORT 10
     22 
     23 #define _TD3_NUM_PROFILE_COS 10
     24 
     25 #define _TD3_TCB_UCQ_SCOPE_PIPE_OFFSET 10
     26 #define _TD3_TCB_UCQ_SCOPE_QUEUE_MASK  0x3ff
     27 #define _TD3_TCB_PORT_SCOPE_PIPE_OFFSET 7
     28 #define _TD3_TCB_PORT_SCOPE_PORT_MASK   0x7f
     29 
     30 STATIC soc_field_t _bcm_td3_cosq_tcb_threshold_profile_map_fields[] = {
     31     QUEUE_0f,
     32     QUEUE_1f,
     33     QUEUE_2f,
     34     QUEUE_3f,
     35     QUEUE_4f,
     36     QUEUE_5f,
     37     QUEUE_6f,
     38     QUEUE_7f,
     39     QUEUE_8f,
     40     QUEUE_9f
     41 };
     42 
     43 
     44 STATIC int
     45 _bcm_td3_cosq_tcb_intr_enable_set(int unit, int enable)
     46 {
     47     uint32 rval;
     48 
     49     if (SOC_REG_IS_VALID(unit, MMU_XCFG_XPE_CPU_INT_ENr)) {
     50         BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_ENr(unit, &rval));
     51         soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval,
     52                           TCB_FREEZE_INT_ENf, enable);
     53         BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_ENr(unit, rval));
     54     }
     55     return BCM_E_NONE;
     56 }
     57 
     58 STATIC int
     59 _bcm_td3_cosq_tcb_intr_status_reset(int unit)
     60 {
     61     uint32 rval;
     62 
     63     BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, &rval));
     64     soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval,
     65                       TCB_FREEZE_INT_CLRf, 0);
     66     BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, rval));
     67 
     68     return BCM_E_NONE;
     69 }
     70 
     71 /*
     72  * Function:
     73  *      _bcm_td3_cosq_tcb_current_phase_get
     74  * Purpose:
     75  *      Get tcb buffer running status.
     76  * Parameters:
     77  *      unit - (IN) BCM device number.
     78  *      buffer_id - (IN) TCB buffer id.
     79  *      status - (OUT) TCB buffer status.
     80  * Returns:
     81  *      BCM_E_XXX
     82  */
     83 STATIC int
     84 _bcm_td3_cosq_tcb_current_phase_get(int unit, int *status)
     85 {
     86     uint32 rval;
     87 
     88     LOG_INFO(BSL_LS_BCM_COSQ,
     89              (BSL_META_U(unit,
     90                          "tcb_current_phase_get: unit %d, buffer_id 0\n"),
     91                          unit));
     92 
     93     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_CURRENT_PHASEr, 0, 0, &rval));
     94     *status = soc_reg_field_get(unit,TCB_CURRENT_PHASEr, rval, CURRENT_PHASEf);
     95 
     96     return BCM_E_NONE;
     97 }
     98 
     99 STATIC int
    100 _bcm_td3_cosq_tcb_hw_event_cb(int unit)
    101 {
    102     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    103     bcm_cosq_buffer_id_t buffer_id;
    104     int status;
    105 
    106     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    107     if (!tcb_unit_info) {
    108         return 0;
    109     }
    110 
    111     _bcm_td3_cosq_tcb_intr_enable_set(unit, 0);
    112     _bcm_td3_cosq_tcb_intr_status_reset(unit);
    113 
    114     buffer_id = 0;
    115     /* Go over the enabled TCB to see which is freezed */
    116     if(tcb_unit_info->tcb_enabled_bmp & (1 << buffer_id)) {
    117         BCM_IF_ERROR_RETURN(
    118                 _bcm_td3_cosq_tcb_current_phase_get(unit, &status));
    119         if (_TCB_FROZEN_PHASE == status) {
    120             if (tcb_unit_info->tcb_evt_cb) {
    121                 tcb_unit_info->tcb_evt_cb(unit, buffer_id,
    122                                           tcb_unit_info->tcb_evt_user_data);
    123             }
    124         }
    125     }
    126 
    127     _bcm_td3_cosq_tcb_intr_enable_set(unit, 1);
    128     return BCM_E_NONE;
    129 }
    130 
    131 int
    132 soc_td3_tcb_set_hw_intr_cb(int unit)
    133 {
    134     BCM_IF_ERROR_RETURN(
    135             soc_td3_set_tcb_callback(unit, &_bcm_td3_cosq_tcb_hw_event_cb));
    136     return SOC_E_NONE;
    137 }
    138 
    139 STATIC int
    140 _bcm_td3_cosq_tcb_buffer_ready_clear(int unit, bcm_cosq_buffer_id_t buffer_id)
    141 {
    142     uint32 rval;
    143     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_BUFFER_READYr, buffer_id, 0, &rval));
    144     soc_reg_field_set(unit, TCB_BUFFER_READYr, &rval, BUFFER_READYf, 0);
    145     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, TCB_BUFFER_READYr, buffer_id, 0, rval));
    146 
    147     return BCM_E_NONE;
    148 }
    149 
    150 STATIC int
    151 _bcm_td3_cosq_tcb_ext_freeze_set(int unit,
    152                                  bcm_cosq_buffer_id_t buffer_id, int enable)
    153 {
    154     uint32 rval;
    155 
    156     LOG_INFO(BSL_LS_BCM_COSQ,
    157              (BSL_META_U(unit,
    158                          "tcb_ext_freeze_set: unit %d, buffer_id %d, enable %d\n"),
    159                          unit, buffer_id, enable));
    160 
    161     BCM_IF_ERROR_RETURN(READ_MMU_GCFG_TCB_FREEZEr(unit, &rval));
    162 
    163     if(enable) {
    164         soc_reg_field_set(unit,MMU_GCFG_TCB_FREEZEr, &rval, TCB_FREEZE_XPEf, 1);
    165     } else {
    166         soc_reg_field_set(unit,MMU_GCFG_TCB_FREEZEr, &rval, TCB_FREEZE_XPEf, 0);
    167     }
    168 
    169     BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_TCB_FREEZEr(unit, rval));
    170 
    171     return BCM_E_NONE;
    172 }
    173 
    174 int
    175 bcm_td3_cosq_tcb_uc_queue_resolve(int unit, bcm_cosq_buffer_id_t buffer_id, int queue,
    176                                   bcm_gport_t *uc_gport)
    177 {
    178     int pipe, id;
    179     bcm_port_t mmu_port, local_port, phy_port, local_mmu_port;
    180     soc_info_t *si;
    181 
    182     si = &SOC_INFO(unit);
    183 
    184     pipe = queue >> _TD3_TCB_UCQ_SCOPE_PIPE_OFFSET;
    185     id = (queue & _TD3_TCB_UCQ_SCOPE_QUEUE_MASK) %
    186          _BCM_TD3_NUM_UCAST_QUEUE_PER_PORT;
    187     local_mmu_port = (queue & _TD3_TCB_UCQ_SCOPE_QUEUE_MASK) /
    188                      _BCM_TD3_NUM_UCAST_QUEUE_PER_PORT;
    189     mmu_port = pipe * (SOC_TD3_MMU_PORT_STRIDE + 1) + local_mmu_port;
    190     phy_port = si->port_m2p_mapping[mmu_port];
    191     local_port = si->port_p2l_mapping[phy_port];
    192     BCM_GPORT_UCAST_QUEUE_GROUP_SYSQID_SET(*uc_gport, local_port, id);
    193 
    194     return BCM_E_NONE;
    195 }
    196 
    197 /*
    198  * Function:
    199  *      bcm_td3_cosq_tcb_enable
    200  * Purpose:
    201  *      Enable or disable a TCB buffer.
    202  * Parameters:
    203  *      unit - (IN) BCM device number.
    204  *      buffer_id - (IN) TCB buffer id.
    205  *      enable - (IN) enable or disable.
    206  * Returns:
    207  *      BCM_E_XXX
    208  */
    209 int
    210 bcm_td3_cosq_tcb_enable(int unit, bcm_cosq_buffer_id_t buffer_id, int enable)
    211 {
    212     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    213     int mask, rv = BCM_E_NONE;
    214     uint64 rval64;
    215 
    216     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    217     TCB_ID_CHECK(buffer_id);
    218     mask = 1;
    219 
    220     LOG_INFO(BSL_LS_BCM_COSQ,
    221              (BSL_META_U(unit,
    222                          "tcb_enable: unit %d, buffer_id %d, enable %d\n"),
    223                          unit, buffer_id, enable));
    224 
    225     if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
    226         LOG_INFO(BSL_LS_BCM_COSQ,
    227                  (BSL_META_U(unit,
    228                              "tcb config of buffer %d is not initialized\n"),
    229                              buffer_id));
    230         return BCM_E_DISABLED;
    231     }
    232 
    233     if (enable) {
    234         if (tcb_unit_info->tcb_enabled_bmp & mask) {
    235             /* tcb is already enabled */
    236             rv = BCM_E_BUSY;
    237         } else { /* enable tcb */
    238             SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0,
    239                                               &rval64));
    240             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TCB_ENABLEf, 1);
    241             SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0,
    242                                               rval64));
    243 
    244             if (tcb_unit_info->tcb_enabled_bmp == 0) {
    245                 /* Enable interrupt */
    246                 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_intr_enable_set(unit, 1));
    247             }
    248             tcb_unit_info->tcb_enabled_bmp |= mask;
    249         }
    250     } else {
    251         if (!(tcb_unit_info->tcb_enabled_bmp & mask)) {
    252             /* tcb is already disabled */
    253             rv =  BCM_E_PARAM;
    254         } else { /* disable tcb */
    255             BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_ext_freeze_set(unit, buffer_id, 0));
    256 
    257             SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0,
    258                                               &rval64));
    259             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TCB_ENABLEf, 0);
    260             SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0,
    261                                               rval64));
    262 
    263             BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_buffer_ready_clear(unit, buffer_id));
    264 
    265             tcb_unit_info->tcb_enabled_bmp &= ~mask;
    266             if (tcb_unit_info->tcb_enabled_bmp == 0) {
    267                 /* Disable interrupt */
    268                 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_intr_enable_set(unit, 0));
    269             }
    270         }
    271     }
    272 
    273     return rv;
    274 
    275 }
    276 
    277 /*
    278  * Function:
    279  *      bcm_td3_cosq_tcb_freeze
    280  * Purpose:
    281  *      External freeze a TCB buffer.
    282  * Parameters:
    283  *      unit - (IN) BCM device number.
    284  *      buffer_id - (IN) TCB buffer id.
    285  *      enable - (IN) enable or disable.
    286  * Returns:
    287  *      BCM_E_XXX
    288  */
    289 int
    290 bcm_td3_cosq_tcb_freeze(int unit, bcm_cosq_buffer_id_t buffer_id, int enable)
    291 {
    292     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    293     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    294 
    295     LOG_INFO(BSL_LS_BCM_COSQ,
    296              (BSL_META_U(unit,
    297                          "tcb_freeze: unit %d, buffer_id %d, enable %d\n"),
    298                          unit, buffer_id, enable));
    299 
    300     if (buffer_id == -1) {
    301         buffer_id = 0;
    302     }
    303 
    304     TCB_ID_CHECK(buffer_id);
    305 
    306     if (!tcb_unit_info->tcb_enabled_bmp) {
    307         LOG_INFO(BSL_LS_BCM_COSQ,
    308                  (BSL_META_U(unit,
    309                              "tcb buffer %d is disabled, can not freeze\n"),
    310                              buffer_id));
    311         return BCM_E_DISABLED;
    312     }
    313 
    314     if (0 != enable) {
    315         BCM_IF_ERROR_RETURN(
    316                 _bcm_td3_cosq_tcb_ext_freeze_set(unit, buffer_id, 1));
    317     } else {
    318         BCM_IF_ERROR_RETURN(
    319                 _bcm_td3_cosq_tcb_ext_freeze_set(unit, buffer_id, 0));
    320         BCM_IF_ERROR_RETURN(
    321                 _bcm_td3_cosq_tcb_buffer_ready_clear(unit, buffer_id));
    322     }
    323 
    324     return BCM_E_NONE;
    325 }
    326 
    327 /*
    328  * Function:
    329  *      _bcm_td3_cosq_tcb_deinit
    330  * Purpose:
    331  *      Deinitialize all TCB internal structure.
    332  * Parameters:
    333  *      unit - (IN) BCM device number.
    334  * Returns:
    335  *      BCM_E_XXX
    336  */
    337 int
    338 _bcm_td3_cosq_tcb_deinit(int unit)
    339 {
    340     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    341     _bcm_cosq_tcb_info_t *tcb_info;
    342     int i = 0;
    343 
    344     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    345     if (tcb_unit_info == NULL) {
    346         return BCM_E_NONE;
    347     }
    348 
    349     if (NULL != tcb_unit_info->tcb_info[i]) {
    350         tcb_info = tcb_unit_info->tcb_info[i];
    351         if (NULL != tcb_info->profile_bmp) {
    352             sal_free(tcb_info->profile_bmp);
    353             tcb_info->profile_bmp = NULL;
    354         }
    355         sal_free(tcb_unit_info->tcb_info[i]);
    356         tcb_unit_info->tcb_info[i] = NULL;
    357     }
    358 
    359     if (NULL != tcb_unit_info->tcb_evt_cb) {
    360         tcb_unit_info->tcb_evt_cb = NULL;
    361     }
    362 
    363     if (NULL != tcb_unit_info->tcb_evt_user_data) {
    364         tcb_unit_info->tcb_evt_user_data = NULL;
    365     }
    366 
    367     if (NULL != tcb_unit_info->tcb_reslock) {
    368         sal_mutex_destroy(tcb_unit_info->tcb_reslock);
    369         tcb_unit_info->tcb_reslock = NULL;
    370     }
    371 
    372     sal_free(tcb_unit_info);
    373 
    374     TCB_UNIT_CONTROL(unit) = NULL;
    375 
    376     return BCM_E_NONE;
    377 }
    378 
    379 /*
    380  * Function:
    381  *      bcm_td3_cosq_tcb_config_get
    382  * Purpose:
    383  *      Get TCB instance control status.
    384  * Parameters:
    385  *      unit - (IN) BCM device number.
    386  *      buffer_id - (IN) TCB buffer id.
    387  *      config - (OUT) TCB config information
    388  * Returns:
    389  *      BCM_E_XXX
    390  */
    391 int
    392 bcm_td3_cosq_tcb_config_get(int unit, bcm_cosq_buffer_id_t buffer_id,
    393                                     bcm_cosq_tcb_config_t *config)
    394 {
    395     uint64 rval64;
    396     uint32 trigger, timer;
    397     int type, entity_num, propability;
    398     bcm_port_t mmu_port, local_port, phy_port;
    399     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    400     soc_info_t *si;
    401     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    402 
    403     LOG_INFO(BSL_LS_BCM_COSQ,
    404              (BSL_META_U(unit,
    405                          "tcb_config_get: unit %d, buffer_id %d\n"),
    406                          unit, buffer_id));
    407 
    408     TCB_ID_CHECK(buffer_id);
    409     if (NULL == config) {
    410         LOG_ERROR(BSL_LS_BCM_COSQ,
    411                   (BSL_META_U(unit, "config is null!\n")));
    412         return BCM_E_PARAM;
    413     }
    414 
    415     si = &SOC_INFO(unit);
    416 
    417     /* check TCB instance status */
    418     if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
    419         config->scope_type = bcmCosqTcbScopeMaxCount;
    420         config->gport = BCM_GPORT_INVALID;
    421         config->cosq = -1;
    422         config->trigger_reason = BCM_COSQ_TCB_INGRESS_ADMIN_DROP |
    423                                  BCM_COSQ_TCB_EGRESS_ADMIN_DROP  |
    424                                  BCM_COSQ_TCB_CFAP_DROP          |
    425                                  BCM_COSQ_TCB_WRED_DROP;
    426         config->pre_freeze_capture_num = _TCB_CAP_NUM_DEFAULT;
    427         config->pre_freeze_capture_time = _TCB_CAP_TIM_DEFAULT * 10 / si->frequency;
    428         config->pre_sample_probability = _TCB_PRE_SAMP_RATE_DEFAULT + 1;
    429         config->post_sample_probability = _TCB_POST_SAMP_RATE_DEFAULT + 1;
    430 
    431         return BCM_E_NONE;
    432     }
    433 
    434     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, &rval64));
    435 
    436     type = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, SCOPE_ENTITY_TYPEf);
    437 
    438     switch(type) {
    439         case _TCB_SCOPE_UCQ:
    440             config->scope_type = bcmCosqTcbScopeUcastQueue;
    441             entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
    442                                                SCOPE_ENTITYf);
    443             BCM_IF_ERROR_RETURN
    444                 (_bcm_cosq_tcb_uc_queue_resolve(unit, buffer_id, entity_num,
    445                                                 &config->gport));
    446             break;
    447         case _TCB_SCOPE_ING_PORT:
    448             config->scope_type = bcmCosqTcbScopeIngressPort;
    449             entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
    450                                                SCOPE_ENTITYf);
    451             mmu_port = entity_num;
    452             phy_port = si->port_m2p_mapping[mmu_port];
    453             local_port = si->port_p2l_mapping[phy_port];
    454             BCM_GPORT_LOCAL_SET(config->gport, local_port);
    455             break;
    456         case _TCB_SCOPE_EGR_PORT:
    457             config->scope_type = bcmCosqTcbScopeEgressPort;
    458             entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
    459                                                SCOPE_ENTITYf);
    460             mmu_port = entity_num;
    461             phy_port = si->port_m2p_mapping[mmu_port];
    462             local_port = si->port_p2l_mapping[phy_port];
    463             BCM_GPORT_LOCAL_SET(config->gport, local_port);
    464             break;
    465         case _TCB_SCOPE_ING_PIPE:
    466             config->scope_type = bcmCosqTcbScopeIngressPipe;
    467             config->pipe_id = soc_reg64_field32_get(
    468                 unit, TCB_CONFIGr, rval64, SCOPE_ENTITYf);
    469             break;
    470         case _TCB_SCOPE_EGR_PIPE:
    471             config->scope_type = bcmCosqTcbScopeEgressPipe;
    472             config->pipe_id = soc_reg64_field32_get(
    473                 unit, TCB_CONFIGr, rval64, SCOPE_ENTITYf);
    474             break;
    475         default:
    476             LOG_ERROR(BSL_LS_BCM_COSQ,
    477                       (BSL_META_U(unit,
    478                                   "scope type %d is illegal\n"),
    479                                   type));
    480             return BCM_E_PARAM;
    481     }
    482 
    483     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_IADMN_DROPf);
    484     config->trigger_reason = trigger << _SHR_TCB_TRACK_IADMN_DROP_SHIFT;
    485     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_EADMN_DROPf);
    486     config->trigger_reason |= trigger << _SHR_TCB_TRACK_EADMN_DROP_SHIFT;
    487     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_CFAP_DROPf);
    488     config->trigger_reason |= trigger << _SHR_TCB_TRACK_CFAP_DROP_SHIFT;
    489     trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_WRED_DROPf);
    490     config->trigger_reason |= trigger << _SHR_TCB_TRACK_WRED_DROP_SHIFT;
    491 
    492     config->pre_freeze_capture_num = soc_reg64_field32_get(unit, TCB_CONFIGr,
    493                                                            rval64, REV_COUNTERf);
    494     timer = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
    495                                                 WD_TIMER_PRESETf);
    496     config->pre_freeze_capture_time =  timer * 10 / si->frequency;
    497     propability = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
    498                                         PRE_TRIGGER_SAMPLE_RATEf);
    499     config->pre_sample_probability = propability + 1;
    500     propability = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64,
    501                                         POST_TRIGGER_SAMPLE_RATEf);
    502     config->post_sample_probability = propability + 1;
    503 
    504     return BCM_E_NONE;
    505 
    506 }
    507 
    508 /*
    509  * Function:
    510  *      bcm_td3_cosq_tcb_config_set
    511  * Purpose:
    512  *      Set TCB instance config attributes.
    513  * Parameters:
    514  *      unit - (IN) BCM device number.
    515  *      buffer_id - (IN) TCB buffer id.
    516  *      config - (IN) TCB config information
    517  * Returns:
    518  *      BCM_E_XXX
    519  */
    520 int
    521 bcm_td3_cosq_tcb_config_set(int unit, bcm_cosq_buffer_id_t buffer_id,
    522                             bcm_cosq_tcb_config_t *config)
    523 {
    524     uint64 rval64 = COMPILER_64_INIT(0,0);
    525     int timer;
    526     bcm_port_t local_port;
    527     bcm_gport_t gport;
    528     int mmu_port, phy_port, q_num, pipe, arg = 0, cosq, modid, trunk_id;
    529     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    530     soc_info_t *si;
    531     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    532 
    533     LOG_INFO(BSL_LS_BCM_COSQ,
    534              (BSL_META_U(unit,
    535                          "tcb_config_set: unit %d, buffer_id %d\n"),
    536                          unit, buffer_id));
    537 
    538     TCB_ID_CHECK(buffer_id);
    539     if (NULL == config) {
    540         LOG_ERROR(BSL_LS_BCM_COSQ,
    541                   (BSL_META_U(unit, "config is null!\n")));
    542         return BCM_E_PARAM;
    543     }
    544 
    545     if (tcb_unit_info->tcb_enabled_bmp) {
    546         /* tcb can only be configured in idle state */
    547         LOG_INFO(BSL_LS_BCM_COSQ,
    548                  (BSL_META_U(unit,
    549                              "tcb buffer %d is enabled\n"),
    550                              buffer_id));
    551         return BCM_E_BUSY;
    552     }
    553 
    554     gport = config->gport;
    555     si = &SOC_INFO(unit);
    556 
    557     /* Reset default value */
    558     if ((config->scope_type == bcmCosqTcbScopeMaxCount) &&
    559         (config->gport == BCM_GPORT_INVALID) &&
    560         (config->cosq == -1) &&
    561         (config->trigger_reason == (BCM_COSQ_TCB_INGRESS_ADMIN_DROP |
    562                                     BCM_COSQ_TCB_EGRESS_ADMIN_DROP  |
    563                                     BCM_COSQ_TCB_CFAP_DROP          |
    564                                     BCM_COSQ_TCB_WRED_DROP)) &&
    565         (config->pre_freeze_capture_num == _TCB_CAP_NUM_DEFAULT) &&
    566         (config->pre_freeze_capture_time ==
    567                                 _TCB_CAP_TIM_DEFAULT * 10 / si->frequency) &&
    568         (config->pre_sample_probability == _TCB_PRE_SAMP_RATE_DEFAULT + 1) &&
    569         (config->post_sample_probability == _TCB_POST_SAMP_RATE_DEFAULT + 1)) {
    570 
    571         SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, rval64));
    572         /* update TCB instance status */
    573         if ((tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
    574             tcb_unit_info->tcb_config_init_bmp &= ~(1 << buffer_id);
    575         }
    576         return BCM_E_NONE;
    577     }
    578 
    579     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, &rval64));
    580 
    581     switch(config->scope_type) {
    582         case bcmCosqTcbScopeUcastQueue:
    583             if (!BCM_GPORT_IS_SET(gport)) {
    584                 LOG_INFO(BSL_LS_BCM_COSQ,
    585                          (BSL_META_U(unit,
    586                                      "tcb config set, gport 0x%x is illegal\n"),
    587                                      gport));
    588                 return BCM_E_PARAM;
    589             }
    590             if (!BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    591                 LOG_INFO(BSL_LS_BCM_COSQ,
    592                          (BSL_META_U(unit,
    593                                      "tcb config set, gport 0x%x is illegal\n"),
    594                                      gport));
    595                 return BCM_E_PARAM;
    596             }
    597 
    598             BCM_IF_ERROR_RETURN(_bcm_td3_cosq_index_resolve(unit, gport, 0,
    599                                     _BCM_TD3_COSQ_INDEX_STYLE_UCAST_QUEUE, NULL,
    600                                     &cosq, NULL));
    601             BCM_IF_ERROR_RETURN(_bcm_td3_cosq_port_resolve(unit, gport, &modid,
    602                                     &local_port, &trunk_id, NULL, NULL));
    603 
    604             SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
    605 
    606             q_num = (pipe << _TD3_TCB_UCQ_SCOPE_PIPE_OFFSET) + cosq;
    607 
    608             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
    609                                   _TCB_SCOPE_UCQ);
    610             arg = q_num;
    611             break;
    612         case bcmCosqTcbScopeIngressPort:
    613             if (BCM_GPORT_IS_SET(gport)){
    614                 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport,
    615                                                            &local_port));
    616             } else if (SOC_PORT_VALID(unit, gport)) {
    617                 local_port = gport;
    618             } else {
    619                 LOG_INFO(BSL_LS_BCM_COSQ,
    620                          (BSL_META_U(unit,
    621                                      "tcb config set, gport 0x%x is illegal\n"),
    622                                      gport));
    623                 return BCM_E_PORT;
    624             }
    625 
    626             if (IS_CPU_PORT(unit, local_port) || IS_LB_PORT(unit, local_port)) {
    627                 LOG_INFO(BSL_LS_BCM_COSQ,
    628                          (BSL_META_U(unit,
    629                                      "tcb config set, gport 0x%x is illegal\n"),
    630                                      gport));
    631                 return BCM_E_PORT;
    632             }
    633 
    634             phy_port = si->port_l2p_mapping[local_port];
    635             mmu_port = si->port_p2m_mapping[phy_port];
    636 
    637             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
    638                               _TCB_SCOPE_ING_PORT);
    639             arg = mmu_port;
    640             break;
    641         case bcmCosqTcbScopeEgressPort:
    642             if (BCM_GPORT_IS_SET(gport)){
    643                 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport,
    644                                                            &local_port));
    645             } else if (SOC_PORT_VALID(unit, gport)) {
    646                 local_port = gport;
    647             } else {
    648                 LOG_INFO(BSL_LS_BCM_COSQ,
    649                          (BSL_META_U(unit,
    650                                      "tcb config set, gport 0x%x is illegal\n"),
    651                                      gport));
    652                 return BCM_E_PORT;
    653             }
    654 
    655             if (IS_CPU_PORT(unit, local_port) || IS_LB_PORT(unit, local_port)) {
    656                 LOG_INFO(BSL_LS_BCM_COSQ,
    657                          (BSL_META_U(unit,
    658                                      "tcb config set, gport 0x%x is illegal\n"),
    659                                      gport));
    660                 return BCM_E_PORT;
    661             }
    662 
    663             phy_port = si->port_l2p_mapping[local_port];
    664             mmu_port = si->port_p2m_mapping[phy_port];
    665 
    666             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
    667                                   _TCB_SCOPE_EGR_PORT);
    668             arg = mmu_port;
    669             break;
    670         case bcmCosqTcbScopeIngressPipe:
    671             if ((config->pipe_id < 0) || (config->pipe_id >= si->num_pipe)) {
    672                 return BCM_E_PARAM;
    673             }
    674             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
    675                                   _TCB_SCOPE_ING_PIPE);
    676             arg = config->pipe_id;
    677             break;
    678         case bcmCosqTcbScopeEgressPipe:
    679             if ((config->pipe_id < 0) || (config->pipe_id >= si->num_pipe)) {
    680                 return BCM_E_PARAM;
    681             }
    682             soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf,
    683                                   _TCB_SCOPE_EGR_PIPE);
    684             arg = config->pipe_id;
    685             break;
    686         default:
    687             LOG_INFO(BSL_LS_BCM_COSQ,
    688                      (BSL_META_U(unit,
    689                                  "tcb config set, scope type %d is illegal\n"),
    690                                  config->scope_type));
    691             return BCM_E_PARAM;
    692     }
    693 
    694     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITYf, arg);
    695 
    696     if (config->trigger_reason > _TCB_TRIGGER_MAX) {
    697         LOG_INFO(BSL_LS_BCM_COSQ,
    698                  (BSL_META_U(unit,
    699                              "tcb config set, trigger reason %d is illegal\n"),
    700                              config->trigger_reason));
    701         return BCM_E_PARAM;
    702     }
    703     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_IADMN_DROPf,
    704                       (config->trigger_reason & BCM_COSQ_TCB_INGRESS_ADMIN_DROP) ? 1:0);
    705     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_EADMN_DROPf,
    706                       (config->trigger_reason & BCM_COSQ_TCB_EGRESS_ADMIN_DROP) ? 1:0);
    707     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_CFAP_DROPf,
    708                       (config->trigger_reason & BCM_COSQ_TCB_CFAP_DROP) ? 1:0);
    709     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_WRED_DROPf,
    710                       (config->trigger_reason & BCM_COSQ_TCB_WRED_DROP) ? 1:0);
    711 
    712     /* rev_counter valid range is 2 - 1024 */
    713     if ((config->pre_freeze_capture_num < _TCB_CAP_NUM_MIN) ||
    714         (config->pre_freeze_capture_num > _TCB_CAP_NUM_MAX)) {
    715         LOG_INFO(BSL_LS_BCM_COSQ,
    716                  (BSL_META_U(unit,
    717                              "tcb config set, pre freeze capture %d is illegal\n"),
    718                              config->pre_freeze_capture_num));
    719         return BCM_E_PARAM;
    720     }
    721     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, REV_COUNTERf,
    722                           config->pre_freeze_capture_num);
    723 
    724     /* WD_TIMER_PRESET is a counter of clock cycles * 10, a value 1 means 10 clock cycles */
    725     timer = (config->pre_freeze_capture_time) * (si->frequency) / 10;
    726     if (timer > _TCB_CAP_TIM_MAX) {
    727         LOG_INFO(BSL_LS_BCM_COSQ,
    728                  (BSL_META_U(unit,
    729                              "tcb config set, pre freeze capture time %d is illegal\n"),
    730                              config->pre_freeze_capture_time));
    731         return BCM_E_PARAM;
    732     }
    733     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, WD_TIMER_PRESETf,
    734                           timer);
    735 
    736     if (config->post_sample_probability > _TCB_POST_SAMP_RATE_MAX ||
    737         config->post_sample_probability <= 0) {
    738         LOG_INFO(BSL_LS_BCM_COSQ,
    739                  (BSL_META_U(unit,
    740                              "tcb config set, post sample probability %d is illegal\n"),
    741                              config->post_sample_probability));
    742         return BCM_E_PARAM;
    743     }
    744     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, POST_TRIGGER_SAMPLE_RATEf,
    745                           config->post_sample_probability - 1);
    746 
    747     if (config->pre_sample_probability > _TCB_PRE_SAMP_RATE_MAX ||
    748         config->pre_sample_probability <= 0) {
    749         LOG_INFO(BSL_LS_BCM_COSQ,
    750                  (BSL_META_U(unit,
    751                              "tcb config set, pre sample probability %d is illegal\n"),
    752                              config->pre_sample_probability));
    753         return BCM_E_PARAM;
    754     }
    755     soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, PRE_TRIGGER_SAMPLE_RATEf,
    756                           config->pre_sample_probability - 1);
    757 
    758     SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, rval64));
    759 
    760     /* update TCB instance status */
    761     if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) {
    762         tcb_unit_info->tcb_config_init_bmp |= (1 << buffer_id);
    763     }
    764     return BCM_E_NONE;
    765 }
    766 
    767 /*
    768  * Function:
    769  *      bcm_td3_cosq_tcb_gport_threshold_mapping_set
    770  * Purpose:
    771  *      Set threshold profile for a UCQ or a port.
    772  * Parameters:
    773  *      unit - (IN) unit number
    774  *      gport - (IN) Ucq or a port
    775  *      cosq  - (IN) Reserved field
    776  *      buffer_id - (IN) TCB buffer id.
    777  *      index - (IN) Threshold profile index
    778  * Returns:
    779  *      BCM_E_XXX
    780  * Notes:
    781  *      When gport is a port, SDK will attach all Ucqs in this port to one threshold profile.
    782  */
    783 int
    784 bcm_td3_cosq_tcb_gport_threshold_mapping_set(int unit,
    785                                       bcm_gport_t gport, bcm_cos_queue_t cosq,
    786                                       bcm_cosq_buffer_id_t buffer_id,
    787                                       int index)
    788 {
    789     soc_mem_t profile_mem;
    790     soc_field_t field;
    791     bcm_port_t local_port;
    792     int mmu_port, phy_port, pipe, i, port_index, old_profile;
    793     bcm_cos_t cos;
    794     soc_info_t *si;
    795     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    796     _bcm_cosq_tcb_info_t *tcb_config;
    797     uint32 entry[SOC_MAX_MEM_WORDS];
    798 
    799     si = &SOC_INFO(unit);
    800     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    801     TCB_ID_CHECK(buffer_id);
    802 
    803     LOG_INFO(BSL_LS_BCM_COSQ,
    804              (BSL_META_U(unit,
    805                          "tcb_threshold_mapping_set: unit %d, gport 0x%x, "
    806                          "cosq %d, buffer_id %d, index %d\n"),
    807                          unit, gport, cosq, buffer_id, index));
    808 
    809     if (tcb_unit_info->tcb_enabled_bmp) {
    810         /* tcb can only be configured in idle state */
    811         LOG_INFO(BSL_LS_BCM_COSQ,
    812                  (BSL_META_U(unit,
    813                              "tcb buffer %d is enabled\n"),
    814                              buffer_id));
    815         return BCM_E_BUSY;
    816     }
    817 
    818     tcb_config = tcb_unit_info->tcb_info[buffer_id];
    819     profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
    820 
    821     if (BCM_GPORT_IS_SET(gport)) {
    822         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    823             BCM_IF_ERROR_RETURN(_bcm_td3_cosq_index_resolve(unit, gport, 0,
    824                                     _BCM_TD3_COSQ_INDEX_STYLE_COS, &local_port,
    825                                     &cos, NULL));
    826         } else if (BCM_GPORT_IS_LOCAL(gport)) {
    827             local_port = BCM_GPORT_LOCAL_GET(gport);
    828             cos = -1;
    829         } else {
    830             LOG_INFO(BSL_LS_BCM_COSQ,
    831                      (BSL_META_U(unit,
    832                                  "tcb_threshold_mapping_set, gport 0x%x is illegal\n"),
    833                                  gport));
    834             return BCM_E_PARAM;
    835         }
    836     } else {
    837         local_port = gport;
    838         cos = -1;
    839     }
    840 
    841     if (!SOC_PORT_VALID(unit, local_port) || IS_CPU_PORT(unit, local_port) ||
    842         IS_LB_PORT(unit, local_port)) {
    843         LOG_INFO(BSL_LS_BCM_COSQ,
    844                  (BSL_META_U(unit,
    845                              "tcb_threshold_mapping_set, gport 0x%x is illegal\n"),
    846                              gport));
    847         return BCM_E_PORT;
    848     }
    849 
    850     phy_port = si->port_l2p_mapping[local_port];
    851     mmu_port = si->port_p2m_mapping[phy_port];
    852     pipe = si->port_pipe[local_port];
    853     port_index = mmu_port % 66 + pipe * 66;
    854 
    855 
    856     if (!SHR_BITGET(tcb_config->profile_bmp, index)) {
    857         LOG_ERROR(BSL_LS_BCM_COSQ,
    858                   (BSL_META_U(unit,
    859                               "profile %d is illegal\n"),
    860                               index));
    861         return BCM_E_NOT_FOUND;
    862     }
    863 
    864     if (-1 == cos) {
    865         BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
    866                                           port_index, entry));
    867         for (i = 0; i < _TD3_NUM_PROFILE_COS; i++) {
    868             field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[i];
    869             old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm,
    870                                               entry, field);
    871             tcb_config->profile_ref_count[old_profile]--;
    872             soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm, entry, field,
    873                                 index);
    874             tcb_config->profile_ref_count[index]++;
    875         }
    876         BCM_IF_ERROR_RETURN (soc_mem_write(unit, profile_mem, MEM_BLOCK_ALL,
    877                                            port_index, entry));
    878     } else {
    879         field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[cos];
    880         BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
    881                                           port_index, entry));
    882         old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm,
    883                                           entry, field);
    884         tcb_config->profile_ref_count[old_profile]--;
    885 
    886         soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm, entry,
    887                             field, index);
    888         tcb_config->profile_ref_count[index]++;
    889         BCM_IF_ERROR_RETURN (soc_mem_write(unit, profile_mem, MEM_BLOCK_ALL,
    890                                            port_index, entry));
    891     }
    892 
    893     return BCM_E_NONE;
    894 }
    895 
    896 /*
    897  * Function:
    898  *      bcm_td3_cosq_tcb_gport_threshold_mapping_get
    899  * Purpose:
    900  *      Set threshold profile for a UCQ or a port.
    901  * Parameters:
    902  *      unit - (IN) unit number
    903  *      gport - (IN) Ucq or a port
    904  *      cosq  - (IN) Reserved field
    905  *      buffer_id - (IN) TCB buffer id.
    906  *      index - (OUT) Threshold profile index
    907  * Returns:
    908  *      BCM_E_XXX
    909  * Notes:
    910  *      When gport is a port, SDK will return the threshold profile index of the first Ucq in this
    911  *      port.
    912  */
    913 int
    914 bcm_td3_cosq_tcb_gport_threshold_mapping_get(int unit,
    915                                      bcm_gport_t gport, bcm_cos_queue_t cosq,
    916                                      bcm_cosq_buffer_id_t buffer_id, int *index)
    917 {
    918     soc_mem_t profile_mem;
    919     soc_field_t field;
    920     bcm_port_t local_port;
    921     int mmu_port, phy_port, pipe, port_index, cos;
    922     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
    923     _bcm_cosq_tcb_info_t *tcb_config;
    924     soc_info_t *si;
    925     uint32 entry[SOC_MAX_MEM_WORDS];
    926 
    927     LOG_INFO(BSL_LS_BCM_COSQ,
    928              (BSL_META_U(unit,
    929                          "tcb_threshold_mapping_get: unit %d, gport 0x%x, "
    930                          "cosq %d, buffer_id %d\n"),
    931                          unit, gport, cosq, buffer_id));
    932 
    933     TCB_ID_CHECK(buffer_id);
    934     if (NULL == index) {
    935         LOG_ERROR(BSL_LS_BCM_COSQ,
    936                   (BSL_META_U(unit, "index is null!\n")));
    937         return BCM_E_PARAM;
    938     }
    939 
    940     tcb_unit_info = TCB_UNIT_CONTROL(unit);
    941     si = &SOC_INFO(unit);
    942 
    943     profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
    944 
    945     if (BCM_GPORT_IS_SET(gport)) {
    946         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    947             BCM_IF_ERROR_RETURN(_bcm_td3_cosq_index_resolve(unit, gport, 0,
    948                                     _BCM_TD3_COSQ_INDEX_STYLE_COS, &local_port,
    949                                     &cos, NULL));
    950         } else if (BCM_GPORT_IS_LOCAL(gport)) {
    951             local_port = BCM_GPORT_LOCAL_GET(gport);
    952             cos = 0;
    953         } else {
    954             LOG_INFO(BSL_LS_BCM_COSQ,
    955                      (BSL_META_U(unit,
    956                                  "tcb_threshold_mapping_get, gport 0x%x is illegal\n"),
    957                                  gport));
    958             return BCM_E_PARAM;
    959         }
    960     } else {
    961         local_port = gport;
    962         cos = 0;
    963     }
    964 
    965     if (!SOC_PORT_VALID(unit, local_port) || IS_CPU_PORT(unit, local_port) ||
    966         IS_LB_PORT(unit, local_port)) {
    967         LOG_INFO(BSL_LS_BCM_COSQ,
    968                  (BSL_META_U(unit,
    969                              "tcb_threshold_mapping_get, gport 0x%x is illegal\n"),
    970                              gport));
    971         return BCM_E_PORT;
    972     }
    973 
    974     phy_port = si->port_l2p_mapping[local_port];
    975     mmu_port = si->port_p2m_mapping[phy_port];
    976     pipe = si->port_pipe[local_port];
    977     port_index = mmu_port % 66 + pipe * 66;
    978 
    979     BCM_IF_ERROR_RETURN(soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
    980                                      port_index, entry));
    981 
    982     field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[cos];
    983     *index = soc_mem_field32_get(unit,TCB_THRESHOLD_PROFILE_MAPm, entry, field);
    984 
    985     tcb_config = tcb_unit_info->tcb_info[buffer_id];
    986     if (!SHR_BITGET(tcb_config->profile_bmp, *index)) {
    987         LOG_ERROR(BSL_LS_BCM_COSQ,
    988                   (BSL_META_U(unit,
    989                               "profile %d is illegal\n"),
    990                               *index));
    991         return BCM_E_NOT_FOUND;
    992     }
    993 
    994     return BCM_E_NONE;
    995 
    996 }
    997 
    998 #ifdef BCM_WARM_BOOT_SUPPORT
    999 int
   1000 bcm_td3_cosq_tcb_reinit(int unit)
   1001 {
   1002     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1003     _bcm_cosq_tcb_info_t *tcb_config;
   1004     int i = 0, j, k, n, enable, index, start_threshold, stop_threshold;
   1005     uint64 rval64;
   1006     soc_mem_t profile_mem;
   1007     soc_field_t field;
   1008 
   1009     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1010     TCB_INIT(unit);
   1011 
   1012     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, i, 0, &rval64));
   1013     enable = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TCB_ENABLEf);
   1014     if (enable) {
   1015         tcb_unit_info->tcb_enabled_bmp |= 1 << i;
   1016     }
   1017 
   1018     profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[i];
   1019     tcb_config = tcb_unit_info->tcb_info[i];
   1020     SHR_BITSET(tcb_config->profile_bmp, 0);
   1021 
   1022     for (n = 1; n < _BCM_TD3_TCB_PROFILE_MAX_NUM; n++) {
   1023         BCM_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr, i,
   1024                                           n, &rval64));
   1025         start_threshold = soc_reg_field_get(unit, TCB_THRESHOLD_PROFILEr,
   1026                                             rval64, CAPTURE_START_THRESHOLDf);
   1027         stop_threshold = soc_reg_field_get(unit, TCB_THRESHOLD_PROFILEr,
   1028                                            rval64, CAPTURE_END_THRESHOLDf);
   1029         if (start_threshold != 0 || stop_threshold != 0) {
   1030             SHR_BITSET(tcb_config->profile_bmp, n);
   1031         }
   1032 
   1033     }
   1034     for (j = 0; j < soc_mem_index_count(unit, profile_mem); j++) {
   1035         BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY,
   1036                                           j, &rval64));
   1037         for (k = 0; k < _TD3_NUM_PROFILE_COS; k++) {
   1038             field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[k];
   1039             index = soc_mem_field32_get(unit,TCB_THRESHOLD_PROFILE_MAPm,
   1040                                         &rval64, field);
   1041             for (n = 0; n < _BCM_TD3_TCB_PROFILE_MAX_NUM; n++) {
   1042                 if (index == n) {
   1043                     if(SHR_BITGET(tcb_config->profile_bmp, n)) {
   1044                     tcb_config->profile_ref_count[n]++;
   1045                     }
   1046                 }
   1047             }
   1048         }
   1049     }
   1050 
   1051     return BCM_E_NONE;
   1052 }
   1053 #endif
   1054 
   1055 /*
   1056  * Function:
   1057  *      bcm_td3_cosq_tcb_init
   1058  * Purpose:
   1059  *      Initialize (clear) all TCB internal structure.
   1060  * Parameters:
   1061  *      unit - (IN) BCM device number.
   1062  * Returns:
   1063  *      BCM_E_XXX
   1064  */
   1065 int
   1066 bcm_td3_cosq_tcb_init(int unit)
   1067 {
   1068     _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info;
   1069     _bcm_cosq_tcb_info_t *tcb_info;
   1070     bcm_cosq_buffer_id_t buffer_id = 0;
   1071     soc_mem_t profile_mem;
   1072 
   1073     (void)_bcm_td3_cosq_tcb_deinit(unit);
   1074 
   1075     tcb_unit_info = TCB_UNIT_CONTROL(unit);
   1076     if (NULL == tcb_unit_info) {
   1077         tcb_unit_info = sal_alloc(sizeof(_bcm_cosq_tcb_unit_ctrl_t), "tcb_dev_info");
   1078         if (!tcb_unit_info) {
   1079             return BCM_E_MEMORY;
   1080         }
   1081     }
   1082 
   1083     sal_memset(tcb_unit_info, 0, sizeof(_bcm_cosq_tcb_unit_ctrl_t));
   1084 
   1085     TCB_UNIT_CONTROL(unit) = tcb_unit_info;
   1086 
   1087     tcb_unit_info->tcb_num = _BCM_TD3_TCB_MAX_NUM;
   1088     tcb_unit_info->cell_bytes = _TD3_MMU_BYTES_PER_CELL;
   1089     tcb_unit_info->threshold_max = _BCM_TD3_TCB_THRESHOLD_MAX;
   1090 
   1091     /* Create protection mutex. */
   1092     if (tcb_unit_info->tcb_reslock == NULL) {
   1093         tcb_unit_info->tcb_reslock = sal_mutex_create("tcb_resource_lock");
   1094     }
   1095 
   1096     if (tcb_unit_info->tcb_reslock == NULL) {
   1097         (void)_bcm_td3_cosq_tcb_deinit(unit);
   1098         return BCM_E_MEMORY;
   1099     }
   1100 
   1101     tcb_unit_info->tcb_info[buffer_id] =
   1102             sal_alloc(sizeof(_bcm_cosq_tcb_info_t), "tcb info");
   1103     if (NULL == tcb_unit_info->tcb_info[buffer_id]) {
   1104         (void)_bcm_td3_cosq_tcb_deinit(unit);
   1105         return BCM_E_MEMORY;
   1106     }
   1107 
   1108     sal_memset(tcb_unit_info->tcb_info[buffer_id], 0, sizeof(_bcm_cosq_tcb_info_t));
   1109 
   1110     tcb_info = tcb_unit_info->tcb_info[buffer_id];
   1111     tcb_info->profile_bmp =
   1112             sal_alloc(SHR_BITALLOCSIZE(_BCM_TD3_TCB_PROFILE_MAX_NUM),
   1113                       "profile_bitmap");
   1114     if (NULL == tcb_info->profile_bmp) {
   1115         (void)_bcm_td3_cosq_tcb_deinit(unit);
   1116         return BCM_E_MEMORY;
   1117     }
   1118     sal_memset(tcb_info->profile_bmp, 0,
   1119                SHR_BITALLOCSIZE(_BCM_TD3_TCB_PROFILE_MAX_NUM));
   1120 
   1121     if (!SOC_WARM_BOOT(unit)) {
   1122         SHR_BITSET(tcb_info->profile_bmp, 0);
   1123         profile_mem =
   1124             SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id];
   1125         tcb_info = tcb_unit_info->tcb_info[buffer_id];
   1126         tcb_info->profile_ref_count[0] =
   1127                     soc_mem_index_count(unit, profile_mem) * 10;
   1128     }
   1129 
   1130     soc_td3_tcb_set_hw_intr_cb(unit);
   1131 
   1132     return BCM_E_NONE;
   1133 }
   1134 
   1135 #endif /* INCLUDE_TCB && BCM_TCB_SUPPORT */