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

port.c (18910B)


      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 
      8 #include <soc/defs.h>
      9 #include <sal/core/libc.h>
     10 
     11 #if defined(BCM_TRIUMPH3_SUPPORT)
     12 
     13 #include <soc/drv.h>
     14 #include <soc/macutil.h>
     15 #include <bcm/error.h>
     16 #include <bcm_int/esw/port.h>
     17 #include <bcm_int/esw/stack.h>
     18 #include <bcm_int/esw/trident.h>
     19 #include <bcm_int/esw_dispatch.h>
     20 #include <bcm_int/common/lock.h>
     21 
     22 /*
     23  * Function:
     24  *      bcm_tr3_port_esm_eligible_set
     25  * Description:
     26  *      Set a port's ESM lookup eligibility. The port may be a remote port.
     27  * Parameters:
     28  *      unit  - (IN) Device number
     29  *      port  - (IN) Port number
     30  *      value - (IN) TRUE = eligible, FALSE = not eligible.
     31  * Return Value:
     32  *      BCM_E_XXX
     33  */
     34 int
     35 bcm_tr3_port_esm_eligible_set(int unit, bcm_port_t port, int value)
     36 {
     37     bcm_module_t mod_out;
     38     bcm_port_t port_out;
     39     bcm_trunk_t tid_out;
     40     int id_out;
     41     int stm_index;
     42     bcm_module_t my_modid;
     43     int rv = BCM_E_NONE;
     44     source_trunk_map_table_entry_t stm_entry;
     45 
     46     if (!soc_feature(unit, soc_feature_etu_support)) {
     47         return BCM_E_UNAVAIL;
     48     }
     49 
     50     /* Derive index to SOURCE_TRUNK_MAP table based on module ID and port */
     51     if (BCM_GPORT_IS_SET(port)) {
     52         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
     53                     &mod_out, &port_out, &tid_out, &id_out));
     54         if (-1 != tid_out || -1 != id_out) {
     55             return BCM_E_PORT;
     56         }
     57         BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
     58                     mod_out, port_out, &stm_index));
     59     } else {
     60         if (!SOC_PORT_VALID(unit, port)) {
     61             return BCM_E_PORT;
     62         }
     63         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
     64         BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
     65                     my_modid, port, &stm_index));
     66     }
     67 
     68     /* Update ESM fields */
     69     soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm);
     70     rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_index,
     71             &stm_entry); 
     72     if (BCM_FAILURE(rv)) {
     73         soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
     74         return rv;
     75     }
     76 
     77     if (value) {
     78         soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
     79                 ESM_SEARCH_OFFSETf, 1);
     80         soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
     81                 ESM_SEARCH_PRIORITYf, 7);
     82     } else {
     83         soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
     84                 ESM_SEARCH_OFFSETf, 0);
     85         soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
     86                 ESM_SEARCH_PRIORITYf, 0);
     87     }
     88 
     89     rv = WRITE_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ALL, stm_index,
     90             &stm_entry); 
     91     if (BCM_FAILURE(rv)) {
     92         soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
     93         return rv;
     94     }
     95 
     96     soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
     97     return BCM_E_NONE;
     98 }
     99 
    100 /*
    101  * Function:
    102  *      bcm_tr3_port_esm_eligible_get
    103  * Description:
    104  *      Get a port's ESM lookup eligibility. The port may be a remote port.
    105  * Parameters:
    106  *      unit  - (IN) Device number
    107  *      port  - (IN) Port number
    108  *      value - (OUT) TRUE = eligible, FALSE = not eligible.
    109  * Return Value:
    110  *      BCM_E_XXX
    111  */
    112 int
    113 bcm_tr3_port_esm_eligible_get(int unit, bcm_port_t port, int *value)
    114 {
    115     bcm_module_t mod_out;
    116     bcm_port_t port_out;
    117     bcm_trunk_t tid_out;
    118     int id_out;
    119     int stm_index;
    120     bcm_module_t my_modid;
    121     source_trunk_map_table_entry_t stm_entry;
    122 
    123     if (!soc_feature(unit, soc_feature_etu_support)) {
    124         return BCM_E_UNAVAIL;
    125     }
    126 
    127     /* Derive index to SOURCE_TRUNK_MAP table based on module ID and port */
    128     if (BCM_GPORT_IS_SET(port)) {
    129         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
    130                     &mod_out, &port_out, &tid_out, &id_out));
    131         if (-1 != tid_out || -1 != id_out) {
    132             return BCM_E_PORT;
    133         }
    134         BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
    135                     mod_out, port_out, &stm_index));
    136     } else {
    137         if (!SOC_PORT_VALID(unit, port)) {
    138             return BCM_E_PORT;
    139         }
    140         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
    141         BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
    142                     my_modid, port, &stm_index));
    143     }
    144 
    145     /* Get ESM fields */
    146     SOC_IF_ERROR_RETURN(READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY,
    147                 stm_index, &stm_entry)); 
    148     if (soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
    149                 ESM_SEARCH_OFFSETf) &&
    150         soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
    151                 ESM_SEARCH_PRIORITYf)) {
    152         *value = TRUE;
    153     } else {
    154         *value = FALSE;
    155     }
    156 
    157     return BCM_E_NONE;
    158 }
    159 
    160 /*
    161  * Function:
    162  *      bcm_tr3_port_extender_type_set
    163  * Description:
    164  *      Set Port Extender port type.
    165  * Parameters:
    166  *      unit - (IN) Device number
    167  *      port - (IN) Port number
    168  *      value - (IN) Port type 
    169  * Return Value:
    170  *      BCM_E_XXX
    171  */
    172 int
    173 bcm_tr3_port_extender_type_set(int unit, bcm_port_t port, int value)
    174 {
    175     switch (value) {
    176         case BCM_PORT_EXTENDER_TYPE_SWITCH:
    177             BCM_IF_ERROR_RETURN(bcm_td_port_niv_type_set(unit, port,
    178                         BCM_PORT_NIV_TYPE_SWITCH));
    179             break;
    180         case BCM_PORT_EXTENDER_TYPE_UPLINK:
    181             BCM_IF_ERROR_RETURN(bcm_td_port_niv_type_set(unit, port,
    182                         BCM_PORT_NIV_TYPE_UPLINK));
    183             break;
    184         case BCM_PORT_EXTENDER_TYPE_DOWNLINK_ACCESS:
    185             BCM_IF_ERROR_RETURN(bcm_td_port_niv_type_set(unit, port,
    186                         BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS));
    187             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    188                         _BCM_CPU_TABS_ETHER, VNTAG_ACTIONS_IF_NOT_PRESENTf,
    189                         2));
    190             break;
    191         case BCM_PORT_EXTENDER_TYPE_DOWNLINK_TRANSIT:
    192             BCM_IF_ERROR_RETURN(bcm_td_port_niv_type_set(unit, port,
    193                         BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT));
    194             break;
    195         case BCM_PORT_EXTENDER_TYPE_NONE:
    196             BCM_IF_ERROR_RETURN(
    197                 bcm_td_port_niv_type_set(unit, port, BCM_PORT_NIV_TYPE_NONE));
    198             break;
    199         default:
    200             return BCM_E_PARAM;
    201     }
    202 
    203     return BCM_E_NONE;
    204 }
    205 
    206 /*
    207  * Function:
    208  *      bcm_tr3_port_extender_type_get
    209  * Description:
    210  *      Get Port Extender port type.
    211  * Parameters:
    212  *      unit - (IN) Device number
    213  *      port - (IN) Port number
    214  *      value - (IN) Port type 
    215  * Return Value:
    216  *      BCM_E_XXX
    217  */
    218 int
    219 bcm_tr3_port_extender_type_get(int unit, bcm_port_t port, int *value)
    220 {
    221     int type;
    222 
    223     BCM_IF_ERROR_RETURN(bcm_td_port_niv_type_get(unit, port, &type));
    224     switch (type) {
    225         case BCM_PORT_NIV_TYPE_SWITCH:
    226             *value = BCM_PORT_EXTENDER_TYPE_SWITCH;
    227             break;
    228         case BCM_PORT_NIV_TYPE_UPLINK:
    229             *value = BCM_PORT_EXTENDER_TYPE_UPLINK;
    230             break;
    231         case BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS:
    232             *value = BCM_PORT_EXTENDER_TYPE_DOWNLINK_ACCESS;
    233             break;
    234         case BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT:
    235             *value = BCM_PORT_EXTENDER_TYPE_DOWNLINK_TRANSIT;
    236             break;
    237         case BCM_PORT_NIV_TYPE_NONE:
    238             *value = BCM_PORT_EXTENDER_TYPE_NONE;
    239             break;
    240         default:
    241             return BCM_E_INTERNAL;
    242     }
    243 
    244     return BCM_E_NONE;
    245 }
    246 
    247 #if defined(INCLUDE_L3) 
    248 /*
    249  * Function:
    250  *      bcm_tr3_port_etag_pcp_de_source_set
    251  * Description:
    252  *      Set source of ETAG's PCP and DE fields.
    253  * Parameters:
    254  *      unit - (IN) Device number
    255  *      port - (IN) Port number
    256  *      value - (IN) PCP and DE source
    257  * Return Value:
    258  *      BCM_E_XXX
    259  */
    260 int
    261 bcm_tr3_port_etag_pcp_de_source_set(int unit, bcm_port_t port, int value)
    262 {
    263     int source;
    264 
    265     switch (value) {
    266         case BCM_EXTENDER_PCP_DE_SELECT_OUTER_TAG:
    267             source = 0;
    268             break;
    269         case BCM_EXTENDER_PCP_DE_SELECT_INNER_TAG:
    270             source = 1;
    271             break;
    272         case BCM_EXTENDER_PCP_DE_SELECT_DEFAULT:
    273             source = 2;
    274             break;
    275         case BCM_EXTENDER_PCP_DE_SELECT_PHB:
    276             source = 3;
    277             break;
    278         default:
    279             return BCM_E_PARAM;
    280     }
    281 
    282     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
    283                 ETAG_PCP_DE_SOURCEf, source));
    284     if (SOC_MEM_IS_VALID(unit, EGR_ING_PORTm)) {
    285         BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
    286                     ETAG_PCP_DE_SOURCEf, source));
    287     }
    288 
    289     return BCM_E_NONE;
    290 }
    291 
    292 /*
    293  * Function:
    294  *      bcm_tr3_port_etag_pcp_de_source_get
    295  * Description:
    296  *      Get source of ETAG's PCP and DE fields.
    297  * Parameters:
    298  *      unit - (IN) Device number
    299  *      port - (IN) Port number
    300  *      value - (IN) PCP and DE source
    301  * Return Value:
    302  *      BCM_E_XXX
    303  */
    304 int
    305 bcm_tr3_port_etag_pcp_de_source_get(int unit, bcm_port_t port, int *value)
    306 {
    307     int source;
    308 
    309     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port, ETAG_PCP_DE_SOURCEf,
    310                 &source));
    311 
    312     switch (source) {
    313         case 0:
    314             *value = BCM_EXTENDER_PCP_DE_SELECT_OUTER_TAG;
    315             break;
    316         case 1:
    317             *value = BCM_EXTENDER_PCP_DE_SELECT_INNER_TAG;
    318             break;
    319         case 2:
    320             *value = BCM_EXTENDER_PCP_DE_SELECT_DEFAULT;
    321             break;
    322         case 3:
    323             *value = BCM_EXTENDER_PCP_DE_SELECT_PHB;
    324             break;
    325         default:
    326             return BCM_E_INTERNAL;
    327     }
    328 
    329     return BCM_E_NONE;
    330 }
    331 #endif /* INCLUDE_L3 */
    332 
    333 int
    334 bcm_tr3_port_pps_rate_egress_set(int unit, bcm_port_t port,
    335                                 uint32 pps, uint32 burst)
    336 {
    337     uint32 miscval;
    338     uint64 regval;
    339     uint32 refresh_rate, bucketsize, granularity = 3, flags = 0;
    340     int    refresh_bitsize, bucket_bitsize;
    341 
    342     /*
    343      * The procedure followed is first disable the egress metering i.e.
    344      * reset EGRMETERINGCONFIG, then clear the buckets and re-enable the
    345      * egress metering. Finally enable the MISCCONFING,Metering clocking
    346      *
    347      * NOTE: During the period of disabling and re-enabling the Egress metering
    348      * may be in-effective for couple of cycles
    349      */
    350 
    351     /* Disable egress metering for this port */
    352     BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIG_64r(unit, port, &regval));
    353     soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval, REFRESHf, 0);
    354     soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval, THD_SELf, 0);
    355     BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIG_64r(unit, port, regval));
    356 
    357     /* Reset metering bucket. */
    358     BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port, 0));
    359 
    360     /* If pps=0, metering is disabled on this egress port*/
    361     if (pps) {
    362         /* Enable metering for this port */
    363 
    364         BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &miscval));
    365         if (soc_reg_field_get(unit, MISCCONFIGr, miscval, ITU_MODE_SELf)) {
    366             flags |= _BCM_TD_METER_FLAG_NON_LINEAR;
    367         }
    368         flags |= _BCM_TD_METER_FLAG_PACKET_MODE;
    369         refresh_bitsize = soc_reg_field_length(unit, EGRMETERINGCONFIG_64r, REFRESHf);
    370         bucket_bitsize = soc_reg_field_length(unit, EGRMETERINGCONFIG_64r, THD_SELf);
    371         BCM_IF_ERROR_RETURN
    372             (_bcm_td_rate_to_bucket_encoding(unit, pps, burst, flags,
    373                                refresh_bitsize, bucket_bitsize,
    374                                &refresh_rate, &bucketsize, &granularity));
    375 
    376         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval, MODEf, 1);
    377         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval,
    378                                   METER_GRANf, granularity);
    379         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval,
    380                               REFRESHf, refresh_rate);
    381         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval,
    382                               THD_SELf, bucketsize);
    383         BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIG_64r(unit, port, regval));
    384     }
    385 
    386     return BCM_E_NONE;
    387 }
    388 
    389 int
    390 bcm_tr3_port_pps_rate_egress_get(int unit, bcm_port_t port,
    391                                 uint32 *pps, uint32 *burst)
    392 {
    393     uint64 regval; 
    394     uint32 miscval;
    395     uint32 refresh_rate = 0, bucketsize = 0, granularity = 3, flags = 0;
    396 
    397     COMPILER_64_ZERO(regval);
    398 
    399     /* Input parameters check. */
    400     if (!pps || !burst) {
    401         return (BCM_E_PARAM);
    402     }
    403 
    404     BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &miscval));
    405     if (soc_reg_field_get(unit, MISCCONFIGr, miscval, ITU_MODE_SELf)) {
    406         flags |= _BCM_TD_METER_FLAG_NON_LINEAR;
    407     }
    408 
    409     BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIG_64r(unit, port, &regval));
    410 
    411     bucketsize = soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r,
    412                                        regval, THD_SELf);
    413     refresh_rate = soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r, 
    414                                          regval, REFRESHf);
    415     flags |= _BCM_TD_METER_FLAG_PACKET_MODE;
    416 
    417     granularity = soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r,
    418                                             regval, METER_GRANf);
    419     BCM_IF_ERROR_RETURN
    420         (_bcm_td_bucket_encoding_to_rate(unit, refresh_rate, bucketsize,
    421                                          granularity, flags, pps, burst));
    422 
    423     return (BCM_E_NONE);
    424 }
    425 
    426 int
    427 bcm_tr3_port_rate_egress_set(int unit, bcm_port_t port,
    428                              uint32 kbits_sec, uint32 kbits_burst, uint32 mode)
    429 {
    430     uint32 miscval;
    431     uint64 regval;
    432     uint32 refresh_rate, bucketsize, granularity = 3, flags = 0;
    433     int    refresh_bitsize, bucket_bitsize;
    434 
    435     if (mode == _BCM_PORT_RATE_PPS_MODE) {
    436         return bcm_tr3_port_pps_rate_egress_set(
    437                             unit, port, kbits_sec, kbits_burst);
    438     }
    439 
    440     /*
    441      * The procedure followed is first disable the egress metering i.e.
    442      * reset EGRMETERINGCONFIG, then clear the buckets and re-enable the
    443      * egress metering. Finally enable the MISCCONFING,Metering clocking
    444      *
    445      * NOTE: During the period of disabling and re-enabling the Egress metering
    446      * may be in-effective for couple of cycles
    447      */
    448 
    449     /* Disable egress metering for this port */
    450     BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIG_64r(unit, port, &regval));
    451     soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval, REFRESHf, 0);
    452     soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval, THD_SELf, 0);
    453     BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIG_64r(unit, port, regval));
    454 
    455     /* Reset metering bucket. */
    456     BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port, 0));
    457 
    458     /* If kbits_sec=0, metering is disabled on this egress port*/
    459     if (kbits_sec) {
    460         /* Enable metering for this port */
    461 
    462         BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &miscval));
    463         if (soc_reg_field_get(unit, MISCCONFIGr, miscval, ITU_MODE_SELf)) {
    464             flags |= _BCM_TD_METER_FLAG_NON_LINEAR;
    465         }
    466         refresh_bitsize = soc_reg_field_length(unit, EGRMETERINGCONFIG_64r,
    467                                                REFRESHf);
    468         bucket_bitsize = soc_reg_field_length(unit, EGRMETERINGCONFIG_64r,
    469                                               THD_SELf);
    470         BCM_IF_ERROR_RETURN
    471             (_bcm_td_rate_to_bucket_encoding(unit, kbits_sec, kbits_burst, flags,
    472                                refresh_bitsize, bucket_bitsize,
    473                                &refresh_rate, &bucketsize, &granularity));
    474         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval, MODEf, 0);
    475         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval,
    476                                   METER_GRANf, granularity);
    477         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval,
    478                               REFRESHf, refresh_rate);
    479         soc_reg64_field32_set(unit, EGRMETERINGCONFIG_64r, &regval,
    480                               THD_SELf, bucketsize);
    481         BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIG_64r(unit, port, regval));
    482     }
    483 
    484     return BCM_E_NONE;
    485 }
    486 
    487 int
    488 bcm_tr3_port_rate_egress_get(int unit, bcm_port_t port,
    489                         uint32 *kbits_sec, uint32 *kbits_burst, uint32 *mode)
    490 {
    491     uint64 regval;                   /* EGRMETERINGCONFIGr register value. */
    492     uint32 miscval;
    493     uint32 refresh_rate = 0, bucketsize = 0, granularity = 3, flags = 0;
    494 
    495     COMPILER_64_ZERO(regval);
    496 
    497     /* Input parameters check. */
    498     if (!kbits_sec || !kbits_burst) {
    499         return (BCM_E_PARAM);
    500     }
    501 
    502     BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &miscval));
    503     if (soc_reg_field_get(unit, MISCCONFIGr, miscval, ITU_MODE_SELf)) {
    504         flags |= _BCM_TD_METER_FLAG_NON_LINEAR;
    505     }
    506 
    507     BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIG_64r(unit, port, &regval));
    508 
    509     if (1 == soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r, 
    510                                     regval, MODEf)) {
    511         *mode = _BCM_PORT_RATE_PPS_MODE;
    512         return bcm_tr3_port_pps_rate_egress_get(unit, port, 
    513                                             kbits_sec, kbits_burst);
    514     }
    515 
    516     bucketsize = soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r,
    517                                        regval, THD_SELf);
    518     refresh_rate = soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r, 
    519                                          regval, REFRESHf);
    520     granularity = soc_reg64_field32_get(unit, EGRMETERINGCONFIG_64r,
    521                                             regval, METER_GRANf);
    522     BCM_IF_ERROR_RETURN
    523         (_bcm_td_bucket_encoding_to_rate(unit, refresh_rate, bucketsize,
    524                                            granularity, flags,
    525                                            kbits_sec, kbits_burst));
    526 
    527     return (BCM_E_NONE);
    528 }
    529 /* 
    530  * Function: 
    531  * bcm_tr3_cpu_port_drain_cells 
    532  * Purpose: 
    533  * To drain cells on CPU port (no MAC Control Needed) 
    534  * Parameters: 
    535  * unit - (IN) unit number 
    536  * port - (IN) Port 
    537  * Returns: 
    538  * BCM_E_XXX 
    539  */ 
    540   int bcm_tr3_cpu_port_drain_cells(int unit, int port) 
    541   { 
    542    return soc_egress_drain_cells(unit, port, 250000); 
    543   } 
    544  
    545 /*
    546  * Function:
    547  *     _bcm_tr3_port_drain_cells
    548  * Purpose:
    549  *     To drain cells associated to the port.
    550  * Parameters:
    551  *     unit       - (IN) unit number
    552  *     port       - (IN) Port
    553  * Returns:
    554  *     BCM_E_XXX
    555  */
    556 int bcm_tr3_port_drain_cells(int unit, int port)
    557 {
    558     mac_driver_t *macd;
    559     int rv = BCM_E_NONE;
    560 
    561     PORT_LOCK(unit);
    562     if (IS_CPU_PORT(unit, port)) 
    563     { 
    564        rv = bcm_tr3_cpu_port_drain_cells(unit, port); 
    565        PORT_UNLOCK(unit); 
    566        return rv; 
    567     } 
    568     rv = soc_mac_probe(unit, port, &macd);
    569 
    570     if (!BCM_SUCCESS(rv)) {
    571         PORT_UNLOCK(unit);
    572         return rv;
    573     }
    574     /* Drain cells from queue */
    575     rv = MAC_CONTROL_SET(macd, unit, port, SOC_MAC_CONTROL_EGRESS_DRAIN, 1);
    576     PORT_UNLOCK(unit);
    577     return rv;
    578 }
    579 
    580 
    581 #endif /* BCM_TRIUMPH3_SUPPORT */