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

rate.c (75197B)


      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  * Rate - Broadcom StrataSwitch Rate Limiting API.
      8  */
      9 
     10 #include <soc/drv.h>
     11 
     12 #include <soc/mem.h>
     13 #include <soc/register.h>
     14 #include <soc/memory.h>
     15 #include <soc/drv.h>
     16 
     17 #include <bcm/rate.h>
     18 #include <bcm/error.h>
     19 
     20 #include <bcm_int/esw_dispatch.h> 
     21 
     22 #include <bcm_int/esw/rate.h> 
     23 
     24 #define TOKEN_BUCKET_SIZE       64      /* Size of one token bucket in kbits */
     25 #define METERING_TOKEN_MAX      0x7FFFF  /* Max number of supported tokens */
     26 #define METER_BUCKETSIZE_MAX    12
     27 #define BITSINBYTE              8
     28 #define KBYTES                  (1024)
     29 #define MBYTES                  (1024) * KBYTES
     30 #define KBITS_IN_API            1000
     31 
     32 #ifdef BCM_TRX_SUPPORT
     33 #define _BCM_TRX_RATE_BCAST_INDEX         0
     34 #define _BCM_TRX_RATE_MCAST_INDEX         1
     35 #define _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX 2
     36 #define _BCM_TRX_RATE_DLF_INDEX           3
     37 
     38 #define _BCM_TRX_RATE_BCAST_INDEX_GET(unit, index) \
     39 { \
     40     if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {\
     41         index = soc_property_get(unit, spn_BCM_RATE_BCAST_INDEX, _BCM_TRX_RATE_BCAST_INDEX); \
     42         if (index > 3) { \
     43             index = _BCM_TRX_RATE_BCAST_INDEX; \
     44         } \
     45     } else { \
     46         index = _BCM_TRX_RATE_BCAST_INDEX; \
     47     } \
     48 } \
     49 
     50 #define _BCM_TRX_RATE_MCAST_INDEX_GET(unit, index) \
     51 { \
     52     if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {\
     53         index = soc_property_get(unit, spn_BCM_RATE_MCAST_INDEX, _BCM_TRX_RATE_MCAST_INDEX); \
     54         if (index > 3) { \
     55             index = _BCM_TRX_RATE_MCAST_INDEX; \
     56         } \
     57     } else { \
     58         index = _BCM_TRX_RATE_MCAST_INDEX; \
     59     } \
     60 } \
     61 
     62 #define _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX_GET(unit, index) \
     63 { \
     64     if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {\
     65         index = soc_property_get(unit, spn_BCM_RATE_UNKNOWN_MCAST_INDEX, _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX); \
     66         if (index > 3) { \
     67             index = _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX; \
     68         } \
     69     } else { \
     70         index = _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX; \
     71     } \
     72 } \
     73 
     74 #define _BCM_TRX_RATE_DLF_INDEX_GET(unit, index) \
     75 { \
     76     if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {\
     77         index = soc_property_get(unit, spn_BCM_RATE_DLF_INDEX, _BCM_TRX_RATE_DLF_INDEX); \
     78         if (index > 3) { \
     79             index = _BCM_TRX_RATE_DLF_INDEX; \
     80         } \
     81     } else { \
     82         index = _BCM_TRX_RATE_DLF_INDEX; \
     83     } \
     84 } \
     85 
     86 #define _BCM_TRX_RATE_BYTE_MODE         1
     87 #define _BCM_TRX_RATE_PKT_MODE          0
     88 
     89 #define _BCM_TRX_REFRESH_TO_RPS         64      /* see inline comments */
     90 #define _BCM_TRX_RATE_MAX_REFRESH_COUNT 0x7ffff
     91 #define _BCM_TRX_RATE_DFT_PKT_BUCKETSZ  7       /* max allow */
     92 
     93 #define _BCM_TR3_REFRESH_TO_RPS         64
     94 #define _BCM_TR3_RATE_MAX_REFRESH_COUNT 0x1fffff
     95 
     96 /* Definition for Hurricane3 :
     97  * - FP_STORM_CONTROL_METERSm.REFRESHCOUNTf extended to 20 bits.
     98  *   (to support max port speed upto 42G)
     99  */
    100 #define _BCM_HR3_RATE_MAX_REFRESH_COUNT 0xfffff 
    101 #endif /* BCM_TRX_SUPPORTED */
    102 
    103 #if defined(BCM_BANDWIDTH_RATE_METER)
    104 
    105 static uint32 kbits_2_bucket_size[METER_BUCKETSIZE_MAX + 1] = {
    106       4 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 4 Kbytes bucket size */
    107       8 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 8 Kbytes bucket size */
    108      16 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 16 Kbytes bucket size */
    109      32 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 32 Kbytes bucket size */
    110      64 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 64 Kbytes bucket size */
    111     128 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 128 Kbytes bucket size */
    112     256 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 256 Kbytes bucket size */
    113     512 * KBYTES * BITSINBYTE / KBITS_IN_API,   /* 512 Kbytes bucket size */
    114       1 * MBYTES * BITSINBYTE / KBITS_IN_API,   /* 1 Mbytes bucket size */
    115       2 * MBYTES * BITSINBYTE / KBITS_IN_API,   /* 2 Mbytes bucket size */
    116       4 * MBYTES * BITSINBYTE / KBITS_IN_API,   /* 4 Mbytes bucket size */
    117       8 * MBYTES * BITSINBYTE / KBITS_IN_API,   /* 8 Mbytes bucket size */
    118      16 * MBYTES * BITSINBYTE / KBITS_IN_API    /* 16 Mbytes bucket size */
    119 };
    120 
    121 /*
    122  * Function:
    123  *      _bcm_kbits_to_bucket_size
    124  * Purpose:
    125  *      Translate kbits burst value into bucket size
    126  * Parameters:
    127  *      kbits_burst - Value to translate
    128  *      
    129  * Returns:
    130  *      Programable value 
    131  */
    132 STATIC int 
    133 _bcm_kbits_to_bucket_size(uint32 kbits_burst)
    134 {
    135     int bckt_sz; 
    136 
    137     for (bckt_sz = 0; bckt_sz <= METER_BUCKETSIZE_MAX; bckt_sz++) {
    138         if (kbits_burst <= kbits_2_bucket_size[bckt_sz]) {
    139             break;
    140         }
    141     }
    142     if (bckt_sz > METER_BUCKETSIZE_MAX) {
    143         bckt_sz = METER_BUCKETSIZE_MAX;
    144     }
    145 
    146     return bckt_sz;
    147 }
    148 
    149 /*
    150  * Function:
    151  *      _bcm_bucket_size_to_kbits
    152  * Purpose:
    153  *      Translate bucket_size into kbits burst
    154  * Parameters:
    155  *      kbits_burst - Value to translate
    156  *      
    157  * Returns:
    158  *      Programable value 
    159  */
    160 STATIC uint32
    161 _bcm_bucket_size_to_kbits(uint32 bucket_size)
    162 {
    163     assert(bucket_size <= METER_BUCKETSIZE_MAX);
    164 
    165     return(kbits_2_bucket_size[bucket_size]);
    166 }
    167 #endif /* BCM_BANDWIDTH_RATE_METER */
    168 /*
    169  * Function:
    170  *      _bcm_rate_bw_set
    171  * Purpose:
    172  *      Helper function to bcm_esw_rate_bandwidth_set
    173  * Parameters:
    174  *      unit        - BCM unit
    175  *      port        - port number
    176  *      mem         - Memory to program
    177  *      refresh -   value to configure refresh count with
    178  *      bucket_size - value to configure bucket size with
    179  *      
    180  * Returns:
    181  *      Programable value 
    182  */
    183 #if defined(BCM_BANDWIDTH_RATE_METER)
    184 STATIC int
    185 _bcm_rate_bw_set(int unit, int port, uint32 mem, uint32 refresh, 
    186                  int bucket_size)
    187 {
    188     fp_sc_meter_table_entry_t   entryMeter;
    189 
    190     soc_mem_field32_set(unit, mem, &entryMeter, BUCKETSIZEf, bucket_size);
    191     soc_mem_field32_set(unit, mem, &entryMeter, REFRESHCOUNTf, refresh);
    192     soc_mem_field32_set(unit, mem, &entryMeter, BUCKETCOUNTf, 0);
    193 
    194     soc_mem_write(unit, mem, MEM_BLOCK_ALL,port, &entryMeter);
    195 
    196     return BCM_E_NONE;
    197 }
    198 
    199 /*
    200  * Function:
    201  *      _bcm_rate_bw_get
    202  * Purpose:
    203  *      Helper function to bcm_esw_rate_bandwidth_get
    204  * Parameters:
    205  *      unit        - BCM unit
    206  *      port        - BCM port 
    207  *      mem         - Memory to read 
    208  *      kbits_sec   - Rate in kilobits (1000 bits) per second.
    209  *      kbits_burst - Maximum burst size in kilobits(1000 bits)
    210  *      
    211  * Returns:
    212  *      Programable value 
    213  */
    214 STATIC int
    215 _bcm_rate_bw_get(int unit, int port, uint32 mem, 
    216                  uint32 *kbits_sec, uint32 *kbits_burst) 
    217 {
    218 
    219     fp_sc_meter_table_entry_t   entryMeter;
    220     uint32                      bucket_size;
    221 
    222     BCM_IF_ERROR_RETURN(
    223         soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &entryMeter));
    224 
    225     *kbits_sec = TOKEN_BUCKET_SIZE * 
    226         soc_mem_field32_get(unit, mem, &entryMeter, REFRESHCOUNTf);
    227     bucket_size = soc_mem_field32_get(unit, mem, &entryMeter, BUCKETSIZEf);
    228     *kbits_burst = _bcm_bucket_size_to_kbits(bucket_size);
    229 
    230     return BCM_E_NONE;
    231 }
    232 #endif
    233 
    234 #ifdef BCM_TRX_SUPPORT
    235 /*  
    236  * Like most other switching chips, Triumph and Scorpion provide meters 
    237  * to control Brocast/Multicast/DLF packet storm. And similar to Raptor, 
    238  * they allow the byte-mode or packet-mode meters. However, unlike Raptor,
    239  * both modes in Triumph and Scorpion can not be mixed for a given port.
    240  * Triumph and Scorpion supports a set of 4 meters per ingress port. 
    241  * By default, if metering enabled, Broadcast packets select the 0th meter,
    242  * known Muliticast packets (including L2MC and IPMC packets) select 1st 
    243  * meter, unknown Multicast packets (including L2MC and IPMC packets) select
    244  * 2nd meter, and DLF packets select 3rd meter. If one ingress port want to
    245  * change the metering mode, it shall first turn off all meters enabled with
    246  * existing metering mode, and then program the new mode. Different metering 
    247  * mode in different ports are allowed. 
    248  */
    249 
    250 /* Verify the meter mode per port */
    251 STATIC int 
    252 _bcm_trx_rate_modeset_verify(int unit, int port, int mode)
    253 {
    254     uint32 ctrlMeter;
    255     int  byte_mode;
    256 
    257     SOC_IF_ERROR_RETURN
    258         (READ_STORM_CONTROL_METER_CONFIGr(unit, port, &ctrlMeter));
    259     byte_mode = soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    260                                   BYTE_MODEf);
    261     if (byte_mode != mode) {
    262 
    263         /* Check whether any meter is enabled */
    264         if (SOC_IS_SHADOW(unit)) {
    265             if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    266                                   BCAST_ENABLEf) ||
    267                 soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    268                                   MC_ENABLEf)) {
    269                 return BCM_E_RESOURCE;
    270             }
    271         } else {
    272             if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    273                                   BCAST_ENABLEf) || 
    274                 soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    275                                   DLFBC_ENABLEf) ||
    276                 soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    277                                   KNOWN_L2MC_ENABLEf) ||
    278                 soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    279                                   UNKNOWN_L2MC_ENABLEf) ||
    280                 soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    281                                   KNOWN_IPMC_ENABLEf) ||
    282                 soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
    283                                   UNKNOWN_IPMC_ENABLEf)) {
    284                 return BCM_E_RESOURCE;
    285             }
    286         }
    287     } 
    288 
    289     return BCM_E_NONE;
    290 }
    291 
    292 /* Table of Kbits to BucketSize */
    293 static uint32 
    294 _bcm_trx_rate_bucketSz_map [] = {
    295     ((4   * KBYTES * BITSINBYTE) / KBITS_IN_API),
    296     ((16  * KBYTES * BITSINBYTE) / KBITS_IN_API),
    297     ((64  * KBYTES * BITSINBYTE) / KBITS_IN_API),
    298     ((256 * KBYTES * BITSINBYTE) / KBITS_IN_API),
    299     ((1   * MBYTES * BITSINBYTE) / KBITS_IN_API),
    300     ((4   * MBYTES * BITSINBYTE) / KBITS_IN_API),
    301     ((8   * MBYTES * BITSINBYTE) / KBITS_IN_API),
    302     ((16  * MBYTES * BITSINBYTE) / KBITS_IN_API)
    303 };   
    304 
    305 /* Kbit_to_bucketSz conversion */
    306 STATIC int
    307 _bcm_trx_rate_kbit_to_bucketsz(uint32 kbits)
    308 {
    309     int ix;
    310 
    311     for (ix = 0; ix < COUNTOF(_bcm_trx_rate_bucketSz_map); ix++) {
    312         if (kbits <= _bcm_trx_rate_bucketSz_map[ix]) {
    313             return ix;
    314         }
    315     }
    316 
    317     return (-1);
    318 }
    319 
    320 /* Program the FP_STORM_CONTROL_METERS */
    321 STATIC int
    322 _bcm_trx_rate_meter_rate_set(int unit, int port, int index, 
    323                              int bucketSz, uint32 refreshCnt)
    324 {
    325     fp_storm_control_meters_entry_t  entryMeter;
    326     int entryNum;
    327     soc_mem_t mem;
    328     int storm_control_ptr = 0;
    329     port_tab_entry_t ptab;
    330 
    331     /* Table name change fot TH style IFP devices */
    332     if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports) ||
    333         SOC_IS_TOMAHAWKX(unit)) {
    334         mem = IFP_STORM_CONTROL_METERSm;
    335     } else {
    336         mem = FP_STORM_CONTROL_METERSm;
    337     }
    338 #ifdef BCM_TRIDENT_SUPPORT
    339     if (SOC_IS_TD_TT(unit) && 
    340         SOC_MEM_IS_VALID(unit, FP_STORM_CONTROL_METERS_Xm)) {
    341         if (SOC_PBMP_MEMBER(SOC_INFO(unit).xpipe_pbm, port)) {
    342             mem = FP_STORM_CONTROL_METERS_Xm;
    343         } else {
    344             mem = FP_STORM_CONTROL_METERS_Ym;
    345         }
    346     }
    347 #endif /* BCM_TRIDENT_SUPPORT */
    348 
    349     /* program the FP_STORM_CONTROL_METERS table */
    350     sal_memset(&entryMeter, 0x0, sizeof(entryMeter));
    351     soc_mem_field32_set(unit, mem, &entryMeter, BUCKETSIZEf, bucketSz);
    352     soc_mem_field32_set(unit, mem, &entryMeter, REFRESHCOUNTf, refreshCnt);
    353     soc_mem_field32_set(unit, mem, &entryMeter, BUCKETCOUNTf, 0);
    354 
    355     if (soc_mem_field_valid (unit, PORT_TABm, STORM_CONTROL_PTRf)) {
    356         BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm,
    357                                     MEM_BLOCK_ANY, port, &ptab));
    358         storm_control_ptr = soc_PORT_TABm_field32_get(unit, &ptab,
    359                                                     STORM_CONTROL_PTRf);
    360         entryNum = (storm_control_ptr << 2) + index;
    361     } else {
    362         entryNum = (port << 2) + index;
    363     }
    364     BCM_IF_ERROR_RETURN
    365         (soc_mem_write(unit, mem, MEM_BLOCK_ALL, entryNum, &entryMeter));
    366 
    367     return BCM_E_NONE;
    368 }
    369 
    370 STATIC int
    371 _bcm_trx_tokens_to_bucket_size(int unit, uint32 tokens, uint32 quantum)
    372 {
    373     static uint32 _bcm_trx_tokens_to_bucket_map[] = {
    374         64*KBYTES, 256*KBYTES, 1*MBYTES, 4*MBYTES, 16*MBYTES, 64*MBYTES,
    375         128*MBYTES, 256*MBYTES
    376     };
    377     uint32 value;
    378     int i, c = COUNTOF(_bcm_trx_tokens_to_bucket_map);
    379 
    380     /* For TR3 the mapping values are reduced by 1/8 */    
    381     for (i = 0; i < c; i++) {
    382         value = _bcm_trx_tokens_to_bucket_map[i];
    383         if ((SOC_IS_TRIUMPH(unit)) || (SOC_IS_TRIUMPH2(unit))) {
    384             value /= 16;
    385         }
    386         if (SOC_IS_TRIUMPH3(unit)) {
    387             value /= 8;
    388         }
    389         if (value >= tokens) {
    390 #if defined(BCM_TRIUMPH3_SUPPORT)
    391             /* For TR3 the min burst size(in packets) is 1 packet */
    392             /* Each packet consumes 2 * PACKET_QUANTUM tokens */
    393             if ((value / (2 * quantum)) >= 1)
    394 #endif
    395             {
    396                 break;
    397             }
    398         }
    399     }
    400     return (i == c) ? i-1 : i;
    401 }
    402 
    403 STATIC int
    404 _bcm_trx_rate_meter_rate_get(int unit, int port, int mode, int index, 
    405                              uint32 *pRps, uint32 *pBrs);
    406 
    407 /* Set the metering mode */
    408 STATIC int 
    409 _bcm_trx_rate_meter_portmode_set(int unit, int port, int mode,
    410                                  uint32 flags, uint32 fmask, 
    411                                  int rps, int brs)
    412 {
    413     soc_field_t field;
    414     uint32 ctrlMeter;
    415     int    allDisable = 0;
    416     int    bitSet;
    417     int    byte_mode;
    418     int    bucketSz;
    419     uint32 bcast_rate, mcast_rate, unknown_mcast_rate, dlf_rate, max_rate;
    420     uint32 min_rate = 0;
    421     uint32 burst, burst_tokens;
    422     uint32 refreshCnt, updated_refresh_cnt;
    423     uint32 deltaRps = 0;
    424     uint32 max_quantum = 4000;
    425     uint32 max_refresh_count = _BCM_TRX_RATE_MAX_REFRESH_COUNT;
    426     uint32 quantum = 125, old_quantum = 0;
    427     uint64 rps_temp;
    428     uint32 bcast_index = _BCM_TRX_RATE_BCAST_INDEX;
    429     uint32 mcast_index = _BCM_TRX_RATE_MCAST_INDEX;
    430     uint32 unknown_mcast_index = _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX;
    431     uint32 dlf_index = _BCM_TRX_RATE_DLF_INDEX;
    432 
    433     if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {
    434         _BCM_TRX_RATE_BCAST_INDEX_GET(unit, bcast_index);
    435         _BCM_TRX_RATE_MCAST_INDEX_GET(unit, mcast_index);
    436         _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX_GET(unit, unknown_mcast_index);
    437         _BCM_TRX_RATE_DLF_INDEX_GET(unit, dlf_index);
    438     }
    439 
    440     SOC_IF_ERROR_RETURN
    441         (READ_STORM_CONTROL_METER_CONFIGr(unit, port, &ctrlMeter));
    442 
    443     byte_mode = soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, 
    444                                   ctrlMeter, BYTE_MODEf);
    445 
    446 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
    447     defined(BCM_HURRICANE3_SUPPORT)
    448     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
    449         max_refresh_count = _BCM_TR3_RATE_MAX_REFRESH_COUNT;
    450         max_quantum = 256000;
    451     } else if (SOC_IS_HURRICANE3(unit)||SOC_IS_GREYHOUND2(unit)){
    452         /* only max_refresh_count need be override. */
    453         max_refresh_count = _BCM_HR3_RATE_MAX_REFRESH_COUNT;
    454     }
    455 #endif /* TRIUMPH3 || TRIDENT2 || HURRICANE3 */
    456 
    457     /* Min rate is calculated using the equation given in comments in
    458      * below paragraphs for different devices. To compute the min value use
    459      * refreshCnt=1 and max value for the PACKET QUANTUM.
    460      */
    461 #if defined(BCM_TRIDENT2_SUPPORT)
    462     if (SOC_IS_TD2_TT2(unit)) {
    463 	min_rate = 1 * (256000 / max_quantum) / 2;  /* min_refresh_count=1 */
    464     } else
    465 #endif /* BCM_TRIDENT2_SUPPORT */
    466     {
    467 	min_rate = 1 * (8000 / max_quantum);  /* min_refresh_count=1 */
    468     }
    469 
    470     /* rps value 0 is used to reset the meter */
    471     if (rps && (rps < min_rate)) {
    472 	return BCM_E_PARAM;
    473     }
    474 
    475     old_quantum = 0;
    476     bcast_rate = 0;
    477     mcast_rate = 0;
    478     unknown_mcast_rate = 0;
    479     dlf_rate = 0;
    480     if (mode == _BCM_TRX_RATE_PKT_MODE) {
    481         max_rate = rps;
    482         if (mode == byte_mode) {
    483             old_quantum = soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
    484                                             ctrlMeter, PACKET_QUANTUMf);
    485             if (!(fmask & BCM_RATE_BCAST) 
    486                 && soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, 
    487                 ctrlMeter, BCAST_ENABLEf)) {
    488                 _bcm_trx_rate_meter_rate_get(unit, port, mode,
    489                                              bcast_index,
    490                                              &bcast_rate, &burst);
    491                 if (max_rate < bcast_rate) {
    492                     max_rate = bcast_rate;
    493                 }
    494             }
    495 
    496             if (SOC_IS_SHADOW(unit)) {
    497                 field = MC_ENABLEf;
    498             } else {
    499                 field = KNOWN_L2MC_ENABLEf;
    500             }
    501             if (!(fmask & (BCM_RATE_MCAST | BCM_RATE_KNOWN_MCAST)) 
    502                 && soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, 
    503                 ctrlMeter, field)) {
    504                 _bcm_trx_rate_meter_rate_get(unit, port, mode,
    505                                              mcast_index,
    506                                              &mcast_rate, &burst);
    507                 if (max_rate < mcast_rate) {
    508                     max_rate = mcast_rate;
    509                 }
    510             }
    511             if (!SOC_IS_SHADOW(unit)) {
    512                 if (!(fmask & (BCM_RATE_MCAST | BCM_RATE_UNKNOWN_MCAST)) 
    513                     && soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
    514                     ctrlMeter, UNKNOWN_L2MC_ENABLEf)) {
    515                     _bcm_trx_rate_meter_rate_get
    516                         (unit, port, mode, unknown_mcast_index,
    517                          &unknown_mcast_rate, &burst);
    518                     if (max_rate < unknown_mcast_rate) {
    519                         max_rate = unknown_mcast_rate;
    520                     }
    521                 }
    522                 if (!(fmask & BCM_RATE_DLF)
    523                     && soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
    524                                       ctrlMeter, DLFBC_ENABLEf)) {
    525                     _bcm_trx_rate_meter_rate_get(unit, port, mode,
    526                                                  dlf_index,
    527                                                  &dlf_rate, &burst);
    528                     if (max_rate < dlf_rate) {
    529                         max_rate = dlf_rate;
    530                     }
    531                 }
    532             }
    533         }
    534 
    535         /*
    536          * Triumph3:
    537          *
    538          * Each meter is refreshed 16000 times/sec;
    539          * Each refresh will add refreshCnt tokens;
    540          * Each packet consumes 2 * PACKET_QUANTUM tokens;
    541          * refreshCnt = (rps * PACKET_QUANTUM * 2) / 16000;
    542          *            = rps * PACKET_QUANTUM / 8000;
    543          *
    544          * Trident2:
    545          * Each meter is refreshed 64000 times/sec;
    546          * Each refresh will add (refreshCnt * 2) tokens;
    547          * Each packet consumes PACKET_QUANTUM tokens;
    548          * refreshCnt = (rps * PACKET_QUANTUM ) / (64000 * 2);
    549          *            = rps * PACKET_QUANTUM / 128000;
    550          *
    551          * Other TRX devices:
    552          *
    553          * Each meter is refreshed 64000 times/sec;
    554          * Each refresh will add (refreshCnt * 2) tokens;
    555          * Each packet consumes (PACKET_QUANTUM * 16) tokens;
    556          * refreshCnt = rps * PACKET_QUANTUM * 16 / (64000 * 2);
    557          *            = rps * PACKET_QUANTUM / 8000;
    558          *
    559          * pick quantum which is a factor of 8000 to reduce error
    560          */
    561         for (quantum = max_quantum; quantum >= 125; quantum >>= 1) {
    562 #if defined(BCM_TRIDENT2_SUPPORT)
    563             if (SOC_IS_TD2_TT2(unit)) {
    564                 if (max_rate <= max_refresh_count * (256000 / quantum) / 2) {
    565                     break;
    566                 }
    567             } else
    568 #endif /* BCM_TRIDENT2_SUPPORT */
    569             {
    570                 if (max_rate <= max_refresh_count * (8000 / quantum)) {
    571                     break;
    572                 }
    573             }
    574         }
    575         if (quantum < 125) {
    576             for (quantum = 80; quantum >= 5; quantum >>= 1) {
    577 #if defined(BCM_TRIDENT2_SUPPORT)
    578                 if (SOC_IS_TD2_TT2(unit)) {
    579                     if (max_rate <= max_refresh_count * (128000 / quantum)) {
    580                         break;
    581                     }
    582                 } else
    583 #endif /* BCM_TRIDENT2_SUPPORT */
    584                 {
    585                     if (max_rate <= max_refresh_count * (8000 / quantum)) {
    586                         break;
    587                     }
    588                 }
    589             }
    590             if (quantum < 5) {
    591                 return BCM_E_PARAM;
    592             }
    593         }
    594 
    595 #if defined(BCM_TRIDENT2_SUPPORT)
    596         if (SOC_IS_TD2_TT2(unit)) {
    597             if (quantum <= 128000) {
    598                 refreshCnt = rps / (128000 / quantum);
    599             } else {
    600                 refreshCnt = rps * (quantum / 128000);
    601             }
    602         } else
    603 #endif /* BCM_TRIDENT2_SUPPORT */
    604         {
    605            /* The refreshCnt at this point is the converted value of requested pps, */
    606            /* rouded off to nearest lower value. Choosen quantum would accomodate   */
    607            /* the requested pps. Compute deltaRps which is the difference between   */
    608            /* requested pps and computed pps with refreshCnt. If deltaRps is more   */
    609            /* than 0, then increment the refreshCnt by one, so that configured pps  */
    610            /* is more than requested pps.                                           */
    611 
    612             if (quantum <= 8000) {
    613                 refreshCnt = rps / (8000 / quantum);
    614                 deltaRps = rps - (refreshCnt * (8000 / quantum));
    615                 if (deltaRps) {
    616                     refreshCnt++ ;
    617                 }
    618                 rps += refreshCnt * (8000 / quantum);
    619             } else {
    620                 refreshCnt = rps * (quantum / 8000);
    621                 deltaRps = rps - (refreshCnt / (quantum / 8000));
    622                 if (deltaRps) {
    623                     refreshCnt++ ;
    624                 }
    625                 rps += refreshCnt / (quantum / 8000);
    626             }
    627         }
    628         /*
    629          * Triumph3:
    630          * burst size (in tokens) = rps * (62.5us/1000000) * 2 * packet_quantum;
    631          *                        = rps * 2 * packet_quantum / 16000;
    632          *                        = rps * packet_quantum / 8000;
    633          *
    634          * Other TRX devices:
    635          *
    636          * burst size (in tokens) = rps * (15.625us/1000000) * 16 * packet_quantum;
    637          *                        = rps * 16 * packet_quantum / 64000;
    638          *                        = rps * packet_quantum / 4000;
    639          *
    640          * Choose smallest bucket size that can support the burst size.
    641          */
    642         COMPILER_64_SET(rps_temp, 0, rps);
    643         COMPILER_64_UMUL_32(rps_temp, quantum); 
    644         if (SOC_IS_TRIUMPH3(unit)) {
    645             if (SOC_FAILURE(soc_esw_div64(rps_temp,8000,&burst_tokens))){
    646                 return SOC_E_INTERNAL;
    647             }
    648         } else {
    649             if (SOC_FAILURE(soc_esw_div64(rps_temp,4000,&burst_tokens))) {
    650                 return SOC_E_INTERNAL;
    651             }
    652         }
    653         if (brs != -1) {
    654             bucketSz = _bcm_trx_rate_kbit_to_bucketsz(brs);
    655         } else {
    656             bucketSz = _bcm_trx_tokens_to_bucket_size(unit, burst_tokens, quantum);
    657         }
    658     } else {
    659         /*
    660          * Triumph3:
    661          *
    662          * Each meter is refreshed 8000 times/sec;
    663          * Each refresh will add refreshCnt tokens;
    664          * Each token represents 8 bit data.
    665          * rps = (refreshCnt * 8000 * 8) / (KBITS_IN_API) ->
    666          * rps = refreshCnt * 64;
    667          *
    668          * Other TRX devices:
    669          *
    670          * Each meter is refreshed 64000 times/sec;
    671          * Each refresh will add 2 * refreshCnt tokens;
    672          * Each token represents 0.5 bit data.
    673          * rps = ((refreshCnt * 2 * 64000) / 2) / (KBITS_IN_API) ->
    674          * rps = refreshCnt * 64;
    675          */
    676         refreshCnt = rps / _BCM_TRX_REFRESH_TO_RPS;
    677 
    678 #if defined(BCM_METROLITE_SUPPORT) || defined(BCM_SABER2_SUPPORT)
    679         if (SOC_IS_METROLITE(unit) || SOC_IS_SABER2(unit)) {
    680          /* For Metrolite and Saber2 rps = refreshCnt * 64*2 */;
    681             refreshCnt = rps / (2*_BCM_TRX_REFRESH_TO_RPS);
    682         }
    683 #endif
    684         /* brs is in unit of Kbits */
    685         bucketSz = _bcm_trx_rate_kbit_to_bucketsz(brs);
    686         if (bucketSz == -1) {
    687             return BCM_E_PARAM;
    688         }
    689     }
    690 
    691     if (refreshCnt == 0 && rps != 0) {
    692         /* Use minimum value unless rps is zero */
    693         refreshCnt = 1;
    694     } else if (refreshCnt > max_refresh_count) {
    695         return BCM_E_PARAM;
    696     }
    697 
    698     if (byte_mode != mode) {
    699         /* if metering mode is changed, disable the storm control first */
    700         soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    701                           BCAST_ENABLEf, 0);
    702         if (SOC_IS_SHADOW(unit)) {
    703             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    704                           MC_ENABLEf, 0);
    705         } else {
    706             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    707                               DLFBC_ENABLEf, 0);
    708             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    709                               KNOWN_L2MC_ENABLEf, 0);
    710             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    711                               UNKNOWN_L2MC_ENABLEf, 0);
    712             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    713                               KNOWN_IPMC_ENABLEf, 0);
    714             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    715                               UNKNOWN_IPMC_ENABLEf, 0);
    716         }
    717 
    718         allDisable = 1;
    719         /* program new metering mode */
    720         soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    721                           BYTE_MODEf, mode);
    722         SOC_IF_ERROR_RETURN
    723             (WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, ctrlMeter));
    724     }
    725 
    726     /* enable/disable BCAST counting */
    727     if (fmask & BCM_RATE_BCAST) {
    728         bitSet = 0;
    729         if (flags & BCM_RATE_BCAST) {
    730             _bcm_trx_rate_meter_rate_set(unit, port, 
    731                                          bcast_index,
    732                                          bucketSz, refreshCnt);
    733             bitSet = 1;
    734         }
    735         if (bitSet || !allDisable) {
    736             soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    737                               BCAST_ENABLEf, bitSet);
    738         }
    739     } else if (mode == _BCM_TRX_RATE_PKT_MODE && bcast_rate != 0 &&
    740                quantum != old_quantum) {
    741 #if defined(BCM_TRIDENT2_SUPPORT)
    742         if (SOC_IS_TD2_TT2(unit)) {
    743             if (quantum <= 128000) {
    744                 updated_refresh_cnt = bcast_rate / (128000 / quantum);
    745             } else {
    746                 updated_refresh_cnt = bcast_rate * (quantum / 128000);
    747             }
    748         } else
    749 #endif /* BCM_TRIDENT2_SUPPORT */
    750         {
    751             if (quantum <= 8000) {
    752                 updated_refresh_cnt = bcast_rate / (8000 / quantum);
    753                 deltaRps = bcast_rate - (updated_refresh_cnt * (8000 / quantum));
    754             } else {
    755                 updated_refresh_cnt = bcast_rate * (quantum / 8000);
    756                 deltaRps = bcast_rate - (updated_refresh_cnt / (quantum / 8000));
    757             }
    758             if (deltaRps) {
    759                 updated_refresh_cnt++ ;
    760             }
    761         }
    762 
    763         /* Use minimum value */
    764         if (updated_refresh_cnt == 0) {
    765            updated_refresh_cnt = 1;
    766         }
    767 
    768         _bcm_trx_rate_meter_rate_set(unit, port, bcast_index,
    769                                      bucketSz, updated_refresh_cnt);
    770     }
    771 
    772     /* enable/disable known MCAST counting */
    773     if (fmask & (BCM_RATE_MCAST | BCM_RATE_KNOWN_MCAST)) {
    774         bitSet = 0;
    775         if (flags & (BCM_RATE_MCAST | BCM_RATE_KNOWN_MCAST)) {
    776             _bcm_trx_rate_meter_rate_set(unit, port, 
    777                                          mcast_index,
    778                                          bucketSz, refreshCnt);
    779             bitSet = 1;
    780         }
    781         if (bitSet || !allDisable) { 
    782             if (SOC_IS_SHADOW(unit)) {
    783                 soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr,
    784                                   &ctrlMeter, MC_ENABLEf, bitSet);
    785             } else {
    786                 soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr,
    787                                   &ctrlMeter, KNOWN_L2MC_ENABLEf, bitSet);
    788                 soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr,
    789                                   &ctrlMeter, KNOWN_IPMC_ENABLEf, bitSet);
    790             }
    791         }
    792     } else if (mode == _BCM_TRX_RATE_PKT_MODE && mcast_rate != 0 &&
    793                quantum != old_quantum) {
    794 #if defined(BCM_TRIDENT2_SUPPORT)
    795         if (SOC_IS_TD2_TT2(unit)) {
    796             if (quantum <= 128000) {
    797                 updated_refresh_cnt = mcast_rate / (128000 / quantum);
    798             } else {
    799                 updated_refresh_cnt = mcast_rate * (quantum / 128000);
    800             }
    801         } else
    802 #endif /* BCM_TRIDENT2_SUPPORT */
    803         {
    804             if (quantum <= 8000) {
    805                 updated_refresh_cnt = mcast_rate / (8000 / quantum);
    806                 deltaRps = mcast_rate - (updated_refresh_cnt * (8000 / quantum));
    807             } else {
    808                 updated_refresh_cnt = mcast_rate * (quantum / 8000);
    809                 deltaRps = mcast_rate - (updated_refresh_cnt / (quantum / 8000));
    810             }
    811             if (deltaRps) {
    812                 updated_refresh_cnt++ ;
    813             }
    814         }
    815 
    816         /* Use minimum value */
    817         if (updated_refresh_cnt == 0) {
    818            updated_refresh_cnt = 1;
    819         }
    820 
    821         _bcm_trx_rate_meter_rate_set(unit, port, mcast_index,
    822                                      bucketSz, updated_refresh_cnt);
    823     }
    824 
    825     /* enable/disable unknown MCAST counting */
    826     if (!SOC_IS_SHADOW(unit)) {
    827         if (fmask & (BCM_RATE_MCAST | BCM_RATE_UNKNOWN_MCAST)) {
    828             bitSet = 0;
    829             if (flags & (BCM_RATE_MCAST | BCM_RATE_UNKNOWN_MCAST)) {
    830                 _bcm_trx_rate_meter_rate_set
    831                     (unit, port, unknown_mcast_index, bucketSz,
    832                      refreshCnt);
    833                 bitSet = 1;
    834             }
    835             if (bitSet || !allDisable) { 
    836                 soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr,
    837                                   &ctrlMeter, UNKNOWN_L2MC_ENABLEf, bitSet);
    838                 soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr,
    839                                   &ctrlMeter, UNKNOWN_IPMC_ENABLEf, bitSet);
    840             }
    841         } else if (mode == _BCM_TRX_RATE_PKT_MODE && unknown_mcast_rate != 0 &&
    842                    quantum != old_quantum) {
    843 #if defined(BCM_TRIDENT2_SUPPORT)
    844             if (SOC_IS_TD2_TT2(unit)) {
    845                 if (quantum <= 128000) {
    846                     updated_refresh_cnt = unknown_mcast_rate / (128000 / quantum);
    847                 } else {
    848                     updated_refresh_cnt = unknown_mcast_rate * (quantum / 128000);
    849                 }
    850             } else
    851 #endif /* BCM_TRIDENT2_SUPPORT */
    852             {
    853                 if (quantum <= 8000) {
    854                     updated_refresh_cnt = unknown_mcast_rate / (8000 / quantum);
    855                     deltaRps = unknown_mcast_rate - (updated_refresh_cnt * (8000 / quantum));
    856                 } else {
    857                     updated_refresh_cnt = unknown_mcast_rate * (quantum / 8000);
    858                     deltaRps = unknown_mcast_rate - (updated_refresh_cnt / (quantum / 8000));
    859                 }
    860                 if (deltaRps) {
    861                     updated_refresh_cnt++ ;
    862                 }
    863             }
    864             _bcm_trx_rate_meter_rate_set(unit, port,
    865                                          unknown_mcast_index,
    866                                          bucketSz, updated_refresh_cnt);
    867         }
    868 
    869         /* enable/disable DLF counting */
    870         if (fmask & BCM_RATE_DLF) {
    871             bitSet = 0;
    872             if (flags & BCM_RATE_DLF) {
    873                 _bcm_trx_rate_meter_rate_set(unit, port, 
    874                                              dlf_index, bucketSz,
    875                                              refreshCnt);
    876                 bitSet = 1;
    877             }
    878             if (bitSet || !allDisable) {
    879                 soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr,
    880                                   &ctrlMeter, DLFBC_ENABLEf, bitSet);
    881             }
    882         } else if (mode == _BCM_TRX_RATE_PKT_MODE && dlf_rate != 0 &&
    883                    quantum != old_quantum) {
    884 #if defined(BCM_TRIDENT2_SUPPORT)
    885             if (SOC_IS_TD2_TT2(unit)) {
    886                 if (quantum <= 128000) {
    887                     updated_refresh_cnt = dlf_rate / (128000 / quantum);
    888                 } else {
    889                     updated_refresh_cnt = dlf_rate * (quantum / 128000);
    890                 }
    891             } else
    892 #endif /* BCM_TRIDENT2_SUPPORT */
    893             {
    894                 if (quantum <= 8000) {
    895                     updated_refresh_cnt = dlf_rate / (8000 / quantum);
    896                     deltaRps = dlf_rate - (updated_refresh_cnt * (8000 / quantum));
    897                 } else {
    898                     updated_refresh_cnt = dlf_rate * (quantum / 8000);
    899                     deltaRps = dlf_rate - (updated_refresh_cnt / (quantum / 8000));
    900                 }
    901                 if (deltaRps) {
    902                     updated_refresh_cnt++ ;
    903                 }
    904             }
    905 
    906             /* Use minimum value */
    907             if (updated_refresh_cnt == 0) {
    908                updated_refresh_cnt = 1;
    909             }
    910 
    911             _bcm_trx_rate_meter_rate_set(unit, port, dlf_index,
    912                                          bucketSz, updated_refresh_cnt);
    913         }
    914     }
    915 
    916     /* Set PACKET_QUANTUM for optimal precision */ 
    917     if (mode == _BCM_TRX_RATE_PKT_MODE) {
    918         soc_reg_field_set(unit, STORM_CONTROL_METER_CONFIGr, &ctrlMeter,
    919                           PACKET_QUANTUMf, quantum);
    920     }
    921 
    922     /* write to registers */
    923     SOC_IF_ERROR_RETURN
    924         (WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, ctrlMeter));
    925 
    926     return BCM_E_NONE;
    927 }
    928 
    929 /*
    930  * Function:
    931  *      _bcm_trx_rate_set
    932  * Description:
    933  *      Triumph and Scopiton specific implementation for
    934  *      bcm_rate_xxx_set APIs
    935  * Parameters:
    936  *      unit  -  unit
    937  *      port  -  port number
    938  *      mode  -  packet- or byte-based mode
    939  *      flags -  flags for packet type
    940  *      fmask -  flags mask for <flags> valid bits
    941  *      rps   -  rate per second (pkt/sec for packet-based mode
    942  *                                Kbits/sec for byte-based mode)
    943  *      brs   -  burst size number (ignored in packet-based mode,
    944  *                                  Kbits/sec for byte-based mode)  
    945  *          
    946  * Return:
    947  *      BCM_E_XXX
    948  */
    949 STATIC int
    950 _bcm_trx_rate_set(int unit, int port, int mode, uint32 flags, 
    951                   uint32 fmask, uint32 rps, uint32 brs)
    952 {
    953     if (!soc_feature(unit,soc_feature_storm_control)) {
    954         return BCM_E_UNAVAIL;
    955     }
    956 
    957     if (port != -1 && !SOC_PORT_VALID(unit, port)) {
    958         return BCM_E_PORT;
    959     }
    960 
    961     if (!(fmask & BCM_RATE_ALL)) {
    962         return BCM_E_PARAM;
    963     }
    964 
    965     /* Verify the configured mode is available */
    966     if (port == -1) { /* All ports */
    967         PBMP_ALL_ITER(unit, port) {
    968             if (IS_LB_PORT(unit, port) || !SOC_PORT_VALID(unit, port)) {
    969                 continue;
    970             }
    971             BCM_IF_ERROR_RETURN
    972                 (_bcm_trx_rate_modeset_verify(unit, port, mode));
    973         } 
    974         PBMP_ALL_ITER(unit, port) {
    975             if (IS_LB_PORT(unit, port) || !SOC_PORT_VALID(unit, port)) {
    976                 continue;
    977             }
    978             BCM_IF_ERROR_RETURN
    979                 (_bcm_trx_rate_meter_portmode_set(unit, port, mode, flags,
    980                                                   fmask, rps, brs));
    981         }
    982     } else {
    983         BCM_IF_ERROR_RETURN
    984             (_bcm_trx_rate_modeset_verify(unit, port, mode));
    985 
    986         BCM_IF_ERROR_RETURN
    987             (_bcm_trx_rate_meter_portmode_set(unit, port, mode, flags,
    988                                               fmask, rps, brs));
    989     }          
    990     return BCM_E_NONE;
    991 }
    992 
    993 STATIC int
    994 _bcm_trx_rate_meter_rate_get(int unit, int port, int mode, int index, 
    995                              uint32 *pRps, uint32 *pBrs)
    996 {
    997     uint32 ctrlMeter;
    998     fp_storm_control_meters_entry_t entryMeter;
    999     int    entryNum;
   1000     uint32 bucketSz;
   1001     uint32 refreshCnt;
   1002     uint32 quantum;
   1003     soc_mem_t mem;
   1004 
   1005     /* Table name change fot TH style IFP devices */
   1006     if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports) ||
   1007         SOC_IS_TOMAHAWKX(unit)) {
   1008         mem = IFP_STORM_CONTROL_METERSm;
   1009     } else {
   1010         mem = FP_STORM_CONTROL_METERSm;
   1011     }
   1012 #ifdef BCM_TRIDENT_SUPPORT
   1013     if (SOC_IS_TD_TT(unit) && 
   1014         SOC_MEM_IS_VALID(unit, FP_STORM_CONTROL_METERS_Xm)) {
   1015         if (SOC_PBMP_MEMBER(SOC_INFO(unit).xpipe_pbm, port)) {
   1016             mem = FP_STORM_CONTROL_METERS_Xm;
   1017         } else {
   1018             mem = FP_STORM_CONTROL_METERS_Ym;
   1019         }
   1020     }
   1021 #endif /* BCM_TRIDENT_SUPPORT */
   1022 
   1023     entryNum = (port << 2) + index;
   1024     BCM_IF_ERROR_RETURN
   1025         (soc_mem_read(unit, mem, MEM_BLOCK_ANY, entryNum, &entryMeter));
   1026 
   1027     refreshCnt = soc_mem_field32_get(unit, mem, &entryMeter, REFRESHCOUNTf);
   1028     bucketSz   = soc_mem_field32_get(unit, mem, &entryMeter, BUCKETSIZEf);
   1029     if (mode == _BCM_TRX_RATE_PKT_MODE) {
   1030         SOC_IF_ERROR_RETURN
   1031             (READ_STORM_CONTROL_METER_CONFIGr(unit, port, &ctrlMeter));
   1032         quantum = soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
   1033                                     ctrlMeter, PACKET_QUANTUMf);
   1034 
   1035         /* Please refer to calculations in _bcm_trx_rate_meter_portmode_set */
   1036 #if defined(BCM_TRIDENT2_SUPPORT)
   1037         if (SOC_IS_TD2_TT2(unit)) {
   1038             if (quantum <= 128000) {
   1039                 *pRps = refreshCnt * (128000 / quantum);
   1040             } else {
   1041                 *pRps = refreshCnt / (quantum / 128000);
   1042             }
   1043         } else 
   1044 #endif /* BCM_TRIDENT2_SUPPORT */
   1045         {
   1046             if (quantum <= 8000) {
   1047             {
   1048                 *pRps = refreshCnt * (8000 / quantum);
   1049             }
   1050             } else {
   1051                 *pRps = refreshCnt / (quantum / 8000);
   1052             }
   1053         }
   1054         *pBrs = _bcm_trx_rate_bucketSz_map[bucketSz];
   1055     } else if (mode == _BCM_TRX_RATE_BYTE_MODE) {
   1056 
   1057         /* Please refer to calculations in _bcm_trx_rate_meter_portmode_set */
   1058         *pRps = refreshCnt * _BCM_TRX_REFRESH_TO_RPS; 
   1059 #if defined(BCM_METROLITE_SUPPORT) || defined(BCM_SABER2_SUPPORT)
   1060         if (SOC_IS_METROLITE(unit) || SOC_IS_SABER2(unit)) {
   1061          /* For Metrolite and Saber2 rps = refreshCnt * 64*2 */;
   1062          *pRps = refreshCnt * (2*_BCM_TRX_REFRESH_TO_RPS);
   1063         }
   1064 #endif
   1065         *pBrs = _bcm_trx_rate_bucketSz_map[bucketSz]; 
   1066 
   1067     } else 
   1068         return BCM_E_PARAM;
   1069     
   1070     return BCM_E_NONE;
   1071 }
   1072 
   1073 STATIC int
   1074 _bcm_trx_rate_get(int unit, int port, int mode, int *pFlags,
   1075                   uint32 fmask, uint32 *pRps, int *psRps, uint32 *pBrs)
   1076 {
   1077     uint32 ctrlMeter;
   1078     int    byte_mode;
   1079     uint32 pktType = 0;
   1080     uint32 rate    = 0;
   1081     uint32 burstSz = 0;
   1082     uint32 bcast_index = _BCM_TRX_RATE_BCAST_INDEX;
   1083     uint32 mcast_index = _BCM_TRX_RATE_MCAST_INDEX;
   1084     uint32 unknown_mcast_index = _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX;
   1085     uint32 dlf_index = _BCM_TRX_RATE_DLF_INDEX;
   1086 
   1087     if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {
   1088         _BCM_TRX_RATE_BCAST_INDEX_GET(unit, bcast_index);
   1089         _BCM_TRX_RATE_MCAST_INDEX_GET(unit, mcast_index);
   1090         _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX_GET(unit, unknown_mcast_index);
   1091         _BCM_TRX_RATE_DLF_INDEX_GET(unit, dlf_index);
   1092     }
   1093 
   1094     if (!soc_feature(unit,soc_feature_storm_control)) {
   1095         if (pFlags != NULL) {
   1096             *pFlags = pktType;
   1097         }
   1098         return BCM_E_UNAVAIL;
   1099     }
   1100 
   1101     if (!SOC_PORT_VALID(unit, port)) {
   1102         return BCM_E_PORT;
   1103     }
   1104     assert ((mode == _BCM_TRX_RATE_PKT_MODE) ||
   1105             (mode == _BCM_TRX_RATE_BYTE_MODE));
   1106 
   1107     SOC_IF_ERROR_RETURN
   1108         (READ_STORM_CONTROL_METER_CONFIGr(unit, port, &ctrlMeter));
   1109     byte_mode = soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1110                                   BYTE_MODEf);
   1111     if (byte_mode == mode) {
   1112         if (fmask & BCM_RATE_BCAST) {
   1113             if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1114                                   BCAST_ENABLEf)) {            
   1115                 pktType |= BCM_RATE_BCAST;
   1116                 _bcm_trx_rate_meter_rate_get(unit, port, mode,
   1117                                              bcast_index, &rate,
   1118                                              &burstSz);
   1119             }  
   1120         }
   1121         if (fmask & BCM_RATE_MCAST) {
   1122             if (SOC_IS_SHADOW(unit)) {
   1123                 if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
   1124                                        ctrlMeter, MC_ENABLEf)) {
   1125                     pktType |= BCM_RATE_MCAST;
   1126                     _bcm_trx_rate_meter_rate_get (unit, port, mode,
   1127                                                   mcast_index,
   1128                                                   &rate, &burstSz);
   1129                 }
   1130             } else {
   1131                 if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
   1132                                       ctrlMeter, KNOWN_L2MC_ENABLEf) || 
   1133                     soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
   1134                                       ctrlMeter, UNKNOWN_L2MC_ENABLEf) ||
   1135                     soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
   1136                                       ctrlMeter, KNOWN_IPMC_ENABLEf) ||
   1137                     soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr,
   1138                                       ctrlMeter, UNKNOWN_IPMC_ENABLEf)) {
   1139                     pktType |= BCM_RATE_MCAST;
   1140                     _bcm_trx_rate_meter_rate_get(unit, port, mode,
   1141                                                  mcast_index,
   1142                                                  &rate, &burstSz);
   1143                 }
   1144             }
   1145         }
   1146         if (!SOC_IS_SHADOW(unit)) {
   1147             if (fmask & BCM_RATE_KNOWN_MCAST) {
   1148                 if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1149                                       KNOWN_L2MC_ENABLEf) ||
   1150                     soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1151                                       KNOWN_IPMC_ENABLEf)) {
   1152                     pktType |= BCM_RATE_KNOWN_MCAST;
   1153                     _bcm_trx_rate_meter_rate_get(unit, port, mode,
   1154                                                  mcast_index,
   1155                                                  &rate, &burstSz);
   1156                 }
   1157             }
   1158             if (fmask & BCM_RATE_UNKNOWN_MCAST) {
   1159                 if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1160                                       UNKNOWN_L2MC_ENABLEf) ||
   1161                     soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1162                                       UNKNOWN_IPMC_ENABLEf)) {
   1163                     pktType |= BCM_RATE_UNKNOWN_MCAST;
   1164                     _bcm_trx_rate_meter_rate_get(unit, port, mode,
   1165                                                  unknown_mcast_index,
   1166                                                  &rate, &burstSz);
   1167                 }
   1168             }
   1169             if (fmask & BCM_RATE_DLF) {
   1170                 if (soc_reg_field_get(unit, STORM_CONTROL_METER_CONFIGr, ctrlMeter,
   1171                                       DLFBC_ENABLEf)) {
   1172                     pktType |= BCM_RATE_DLF;
   1173                     _bcm_trx_rate_meter_rate_get(unit, port, mode,
   1174                                                  dlf_index, &rate,
   1175                                                  &burstSz);
   1176                 }
   1177             }
   1178         }
   1179     }
   1180 
   1181     if (pFlags != NULL) {
   1182         *pFlags = pktType;
   1183     }
   1184     if (pRps != NULL) {
   1185         /* To accommodate uint32 pointers in API */
   1186         *pRps = rate;
   1187     }
   1188     if (psRps != NULL) {
   1189         /* To accommodate int pointers in API */
   1190         *psRps = rate;
   1191     }
   1192     if (pBrs != NULL) {
   1193         *pBrs = burstSz;
   1194     }
   1195 
   1196     return BCM_E_NONE;
   1197 }
   1198 #endif /* BCM_TRX_SUPPORT */
   1199 
   1200 /*
   1201  * Function:
   1202  *      _bcm_esw_rate_hw_clear
   1203  * Description:
   1204  *      Clear all registers and memories that related to rate limiting 
   1205  * Parameters:
   1206  *      unit - unit number
   1207  * Returns:
   1208  *      BCM_E_XXX
   1209  */
   1210 STATIC int
   1211 _bcm_esw_rate_hw_clear(int unit)
   1212 {
   1213     uint32 rval = 0;
   1214     bcm_port_t  port;
   1215     int         i;
   1216     soc_reg_t   reg;
   1217     soc_mem_t   _bcm_esw_rate_mems[] = {
   1218         FP_SC_BCAST_METER_TABLEm,
   1219         FP_SC_MCAST_METER_TABLEm,
   1220         FP_SC_DLF_METER_TABLEm,
   1221         FP_STORM_CONTROL_METERSm
   1222     };
   1223     soc_reg_t   _bcm_esw_rate_regs[] = {
   1224         SC_BYTE_METER_CONFIGr,
   1225         BCAST_STORM_CONTROLr,
   1226         DLFBC_STORM_CONTROLr,
   1227         MCAST_STORM_CONTROLr,
   1228         STORM_CONTROL_METER_CONFIGr
   1229     };
   1230 
   1231 #ifdef BCM_TRX_SUPPORT
   1232     uint32 bcast_index = _BCM_TRX_RATE_BCAST_INDEX;
   1233     uint32 mcast_index = _BCM_TRX_RATE_MCAST_INDEX;
   1234     uint32 unknown_mcast_index = _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX;
   1235     uint32 dlf_index = _BCM_TRX_RATE_DLF_INDEX;
   1236     uint32 mapping = 0, old_mapping =  0;
   1237 #endif /* BCM_TRX_SUPPORT */
   1238 
   1239     if (SOC_WARM_BOOT(unit)) {
   1240         return BCM_E_NONE;
   1241     }
   1242 
   1243     /* Registers initialization */      
   1244     for (i = 0; i < COUNTOF(_bcm_esw_rate_regs); i++) {
   1245         if (SOC_REG_IS_VALID(unit, _bcm_esw_rate_regs[i])) {
   1246             PBMP_PORT_ITER(unit, port) {
   1247                 reg = _bcm_esw_rate_regs[i];
   1248                 SOC_IF_ERROR_RETURN
   1249                     (soc_reg32_set(unit, reg, port, 0, rval));
   1250                 /* special case handling */
   1251                 if (STORM_CONTROL_METER_CONFIGr == _bcm_esw_rate_regs[i]) {
   1252                     soc_field_t fields[] = {PACKET_QUANTUMf, BYTE_MODEf};
   1253                     uint32      values[] = {0x100, 1};
   1254 
   1255                     BCM_IF_ERROR_RETURN(
   1256                         soc_reg_fields32_modify(unit,  
   1257                                                 STORM_CONTROL_METER_CONFIGr, 
   1258                                                 port, COUNTOF(fields), 
   1259                                                 fields, values));
   1260                 }
   1261             }
   1262         }
   1263     }
   1264 
   1265 #ifdef BCM_TRX_SUPPORT
   1266     if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
   1267         /* 
   1268          * Set the per-chip STORM_CONTROL_METER_MAPPING register for now:
   1269          * offset 0 meter - BCAST 
   1270          * offset 1 meter - known MCAST (including l2MC and IPMC)
   1271          * offset 2 meter - unknown MCAST (including L2MC and IPMC)
   1272          * offset 3 meter - DLF
   1273          */
   1274 
   1275         if (soc_feature(unit, soc_feature_configurable_storm_control_meter_mapping)) {
   1276             _BCM_TRX_RATE_BCAST_INDEX_GET(unit, bcast_index);
   1277             _BCM_TRX_RATE_MCAST_INDEX_GET(unit, mcast_index);
   1278             _BCM_TRX_RATE_UNKNOWN_MCAST_INDEX_GET(unit, unknown_mcast_index);
   1279             _BCM_TRX_RATE_DLF_INDEX_GET(unit, dlf_index);
   1280         }
   1281 
   1282         (READ_STORM_CONTROL_METER_MAPPINGr(unit, &old_mapping));
   1283         mapping = old_mapping;
   1284         soc_reg_field_set(unit, STORM_CONTROL_METER_MAPPINGr,
   1285                 &mapping, BCAST_METER_INDEXf, bcast_index);
   1286         soc_reg_field_set(unit, STORM_CONTROL_METER_MAPPINGr,
   1287                 &mapping, KNOWN_L2MC_METER_INDEXf, mcast_index);
   1288         soc_reg_field_set(unit, STORM_CONTROL_METER_MAPPINGr,
   1289                 &mapping, UNKNOWN_L2MC_METER_INDEXf, unknown_mcast_index);
   1290         soc_reg_field_set(unit, STORM_CONTROL_METER_MAPPINGr,
   1291                 &mapping, KNOWN_IPMC_METER_INDEXf, mcast_index);
   1292         soc_reg_field_set(unit, STORM_CONTROL_METER_MAPPINGr,
   1293                 &mapping, UNKNOWN_IPMC_METER_INDEXf, unknown_mcast_index);
   1294         soc_reg_field_set(unit, STORM_CONTROL_METER_MAPPINGr,
   1295                 &mapping, DLFBC_METER_INDEXf, dlf_index);
   1296         if (old_mapping != mapping) {
   1297             SOC_IF_ERROR_RETURN
   1298                 (WRITE_STORM_CONTROL_METER_MAPPINGr(unit, mapping));
   1299         }
   1300 
   1301     }
   1302 #endif /* BCM_TRX_SUPPORT */
   1303 
   1304     /* Memories initialization */
   1305     for (i = 0; i < COUNTOF(_bcm_esw_rate_mems); i++) {
   1306         if (SOC_MEM_IS_VALID(unit, _bcm_esw_rate_mems[i])) {
   1307             BCM_IF_ERROR_RETURN(
   1308                 soc_mem_clear(unit, _bcm_esw_rate_mems[i], COPYNO_ALL, TRUE));
   1309         }
   1310     }
   1311     
   1312     if (SOC_MEM_IS_VALID(unit, IFP_STORM_CONTROL_METERSm)) {
   1313             BCM_IF_ERROR_RETURN(
   1314                 soc_mem_clear(unit, IFP_STORM_CONTROL_METERSm, 
   1315                                            COPYNO_ALL, TRUE));
   1316     }
   1317 
   1318     return (BCM_E_NONE);
   1319 }
   1320 
   1321 /*
   1322  * Function:
   1323  *      _bcm_esw_rate_init
   1324  * Description:
   1325  *      Initialize the rate module
   1326  * Parameters:
   1327  *      unit - unit number
   1328  * Returns:
   1329  *      BCM_E_XXX
   1330  */
   1331 int 
   1332 _bcm_esw_rate_init(int unit)
   1333 {
   1334     if(SOC_IS_RCPU_ONLY(unit)) {
   1335         return BCM_E_NONE;
   1336     }
   1337 
   1338     /* Currently no SW structure required for rate module so only clear HW */
   1339     return _bcm_esw_rate_hw_clear(unit);
   1340 }
   1341 
   1342 /*
   1343  * Function:
   1344  *      bcm_rate_type_set
   1345  * Description:
   1346  *      Front end to bcm_*cast_rate_set functions.
   1347  *      Uses a single data structure to write into
   1348  *      all the 3 rate control registers
   1349  * Parameters:
   1350  *      unit - unit number
   1351  *      rl - data structure containing info to be written to the
   1352  *           rate control registers
   1353  * Returns:
   1354  *      BCM_E_XXX
   1355  */
   1356 int
   1357 bcm_esw_rate_type_set(int unit, bcm_rate_limit_t *rl)
   1358 {
   1359     int port;
   1360 
   1361     PBMP_E_ITER(unit, port) {
   1362         BCM_IF_ERROR_RETURN
   1363             (bcm_esw_rate_bcast_set(unit, rl->br_bcast_rate, rl->flags, port));
   1364         BCM_IF_ERROR_RETURN
   1365             (bcm_esw_rate_mcast_set(unit, rl->br_mcast_rate, rl->flags, port));
   1366         BCM_IF_ERROR_RETURN
   1367             (bcm_esw_rate_dlfbc_set(unit, rl->br_dlfbc_rate, rl->flags, port));
   1368     }
   1369 
   1370     return BCM_E_NONE;
   1371 }
   1372 
   1373 /*
   1374  * Function:
   1375  *      bcm_rate_set
   1376  * Description:
   1377  *      Configure rate limit and on/off state of
   1378  *      DLF, MCAST, and BCAST limiting
   1379  * Parameters:
   1380  *      unit - StrataSwitch PCI device unit number
   1381  *      pps - Rate limit value in packets/second
   1382  *      flags - Bitmask with one or more of BCM_RATE_*
   1383  * Returns:
   1384  *      BCM_E_NONE - Success.
   1385  *      BCM_E_INTERNAL - Chip access failure.
   1386  * Notes:
   1387  *      StrataSwitch supports only one rate limit for all 3 types.
   1388  */
   1389 
   1390 int
   1391 bcm_esw_rate_set(int unit, int pps, int flags)
   1392 {
   1393 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1394 #ifdef BCM_TRX_SUPPORT
   1395     if (SOC_IS_TRX(unit)) {
   1396         uint32 fmask;
   1397         fmask = BCM_RATE_DLF | BCM_RATE_MCAST | BCM_RATE_BCAST;
   1398         if (SOC_IS_SHADOW(unit)) {
   1399             if (flags & BCM_RATE_DLF) {
   1400                 return BCM_E_UNAVAIL;
   1401             }
   1402         }
   1403         return (_bcm_trx_rate_set(unit, -1, _BCM_TRX_RATE_PKT_MODE, 
   1404                                   flags, fmask, (uint32)pps, -1)); 
   1405     }
   1406 #endif /* BCM_TRX_SUPPORT */
   1407 
   1408     if (SOC_IS_XGS3_SWITCH(unit)) {
   1409         uint32 rate;
   1410         int port;
   1411         int enable = 0;
   1412         PBMP_ALL_ITER(unit, port) {
   1413             rate = 0;
   1414             enable = (flags & BCM_RATE_MCAST) ? 1 : 0;
   1415             soc_reg_field_set(unit, MCAST_STORM_CONTROLr,
   1416                               &rate, ENABLEf, enable);
   1417             soc_reg_field_set(unit, MCAST_STORM_CONTROLr,
   1418                               &rate, THRESHOLDf, pps);
   1419             SOC_IF_ERROR_RETURN
   1420                 (WRITE_MCAST_STORM_CONTROLr(unit, port, rate));
   1421 
   1422             rate = 0;
   1423             enable = (flags & BCM_RATE_BCAST) ? 1 : 0;
   1424             soc_reg_field_set(unit, BCAST_STORM_CONTROLr,
   1425                               &rate, ENABLEf, enable);
   1426             soc_reg_field_set(unit, BCAST_STORM_CONTROLr,
   1427                               &rate, THRESHOLDf, pps);
   1428             SOC_IF_ERROR_RETURN
   1429                 (WRITE_BCAST_STORM_CONTROLr(unit, port, rate));
   1430 
   1431             rate = 0;
   1432             enable = (flags & BCM_RATE_DLF) ? 1 : 0;
   1433             soc_reg_field_set(unit, DLFBC_STORM_CONTROLr,
   1434                               &rate, ENABLEf, enable);
   1435             soc_reg_field_set(unit, DLFBC_STORM_CONTROLr,
   1436                               &rate, THRESHOLDf, pps);
   1437             SOC_IF_ERROR_RETURN
   1438                 (WRITE_DLFBC_STORM_CONTROLr(unit, port, rate));
   1439         }
   1440         return BCM_E_NONE;
   1441     }
   1442 #endif
   1443 
   1444     return BCM_E_UNAVAIL;
   1445 }
   1446 
   1447 /*
   1448  * Function:
   1449  *      bcm_rate_mcast_set
   1450  * Description:
   1451  *      Configure rate limit for MCAST packets for the given port
   1452  * Parameters:
   1453  *      unit - StrataSwitch PCI device unit number
   1454  *      pps - Rate limit value in packets/second
   1455  *      flags - Bitmask with one or more of BCM_RATE_*
   1456  *      port - Port number for which MCAST limit needs to be set
   1457  * Returns:
   1458  *      BCM_E_NONE - Success.
   1459  *      BCM_E_UNAVAIL - Not supported.
   1460  * Notes:
   1461  *      Individually setting MCAST limit is supported only on 5690 and later.
   1462  */
   1463 
   1464 int
   1465 bcm_esw_rate_mcast_set(int unit, int pps, int flags, int port)
   1466 {
   1467     if (BCM_GPORT_IS_SET(port)) {
   1468         BCM_IF_ERROR_RETURN(
   1469             bcm_esw_port_local_get(unit, port, &port));
   1470     }
   1471     if (!SOC_PORT_VALID(unit, port)) {
   1472         return BCM_E_PORT;
   1473     }
   1474 
   1475 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1476 #ifdef BCM_TRX_SUPPORT
   1477     if (SOC_IS_TRX(unit)) {
   1478         return (_bcm_trx_rate_set(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1479                                   flags, BCM_RATE_MCAST, (uint32)pps, -1)); 
   1480     }
   1481 #endif /* BCM_TRX_SUPPORT */
   1482 
   1483     if (SOC_IS_XGS3_SWITCH(unit)) {
   1484         uint32 rate = 0;
   1485         int enable, threshold = pps;
   1486         enable = (flags & BCM_RATE_MCAST) ? 1 : 0;
   1487         soc_reg_field_set(unit, MCAST_STORM_CONTROLr,
   1488                           &rate, ENABLEf, enable);
   1489         soc_reg_field_set(unit, MCAST_STORM_CONTROLr,
   1490                           &rate, THRESHOLDf, threshold);
   1491         SOC_IF_ERROR_RETURN(WRITE_MCAST_STORM_CONTROLr(unit, port, rate));
   1492         return BCM_E_NONE;
   1493     }
   1494 #endif
   1495 
   1496     return BCM_E_UNAVAIL;
   1497 }
   1498 
   1499 /*
   1500  * Function:
   1501  *      bcm_rate_bcast_set
   1502  * Description:
   1503  *      Configure rate limit for BCAST packets
   1504  * Parameters:
   1505  *      unit - StrataSwitch PCI device unit number
   1506  *      pps - Rate limit value in packets/second
   1507  *      flags - Bitmask with one or more of BCM_RATE_*
   1508  *      port - Port number for which BCAST limit needs to be set
   1509  * Returns:
   1510  *      BCM_E_NONE - Success.
   1511  *      BCM_E_UNAVAIL - Not supported.
   1512  * Notes:
   1513  *      Individually setting BCAST limit is supported only on 5690 and later.
   1514  */
   1515 
   1516 int
   1517 bcm_esw_rate_bcast_set(int unit, int pps, int flags, int port)
   1518 {
   1519     if (BCM_GPORT_IS_SET(port)) {
   1520         BCM_IF_ERROR_RETURN(
   1521             bcm_esw_port_local_get(unit, port, &port));
   1522     }
   1523     if (!SOC_PORT_VALID(unit, port)) {
   1524         return BCM_E_PORT;
   1525     }
   1526 
   1527 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1528 #ifdef BCM_TRX_SUPPORT
   1529     if (SOC_IS_TRX(unit)) {
   1530         return (_bcm_trx_rate_set(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1531                                   flags, BCM_RATE_BCAST, (uint32)pps, -1)); 
   1532     }
   1533 #endif /* BCM_TRX_SUPPORT */
   1534 
   1535     if (SOC_IS_XGS3_SWITCH(unit)) {
   1536         uint32 rate = 0;
   1537         int enable, threshold = pps;
   1538         enable = (flags & BCM_RATE_BCAST) ? 1 : 0;
   1539         soc_reg_field_set(unit, BCAST_STORM_CONTROLr,
   1540                           &rate, ENABLEf, enable);
   1541         soc_reg_field_set(unit, BCAST_STORM_CONTROLr,
   1542                           &rate, THRESHOLDf, threshold);
   1543         SOC_IF_ERROR_RETURN(WRITE_BCAST_STORM_CONTROLr(unit, port, rate));
   1544         return BCM_E_NONE;
   1545     }
   1546 #endif
   1547 
   1548     return BCM_E_UNAVAIL;
   1549 }
   1550 
   1551 /*
   1552  * Function:
   1553  *      bcm_rate_dlfbc_set
   1554  * Description:
   1555  *      Configure rate limit for DLFBC packets
   1556  * Parameters:
   1557  *      unit - StrataSwitch PCI device unit number
   1558  *      pps - Rate limit value in packets/second
   1559  *      flags - Bitmask with one or more of BCM_RATE_*
   1560  *      port - Port number for which DLFBC limit needs to be set
   1561  * Returns:
   1562  *      BCM_E_NONE - Success.
   1563  *      BCM_E_UNAVAIL - Not supported.
   1564  * Notes:
   1565  *      DLFBC: Destination Lookup Failure Broadcast
   1566  *      Individually setting DLFBC limit is supported only on 5690 and later.
   1567  */
   1568 
   1569 int
   1570 bcm_esw_rate_dlfbc_set(int unit, int pps, int flags, int port)
   1571 {
   1572     if (BCM_GPORT_IS_SET(port)) {
   1573         BCM_IF_ERROR_RETURN(
   1574             bcm_esw_port_local_get(unit, port, &port));
   1575     }
   1576     if (!SOC_PORT_VALID(unit, port)) {
   1577         return BCM_E_PORT;
   1578     }
   1579 
   1580 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1581 #ifdef BCM_TRX_SUPPORT
   1582     if (SOC_IS_TRX(unit)) {
   1583         return (_bcm_trx_rate_set(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1584                                   flags, BCM_RATE_DLF, (uint32)pps, -1)); 
   1585     }
   1586 #endif /* BCM_TRX_SUPPORT */
   1587 
   1588     if (SOC_IS_XGS3_SWITCH(unit)) {
   1589         uint32 rate = 0;
   1590         int enable, threshold = pps;
   1591         enable = (flags & BCM_RATE_DLF) ? 1 : 0;
   1592         soc_reg_field_set(unit, DLFBC_STORM_CONTROLr,
   1593                           &rate, ENABLEf, enable);
   1594         soc_reg_field_set(unit, DLFBC_STORM_CONTROLr,
   1595                           &rate, THRESHOLDf, threshold);
   1596         SOC_IF_ERROR_RETURN(WRITE_DLFBC_STORM_CONTROLr(unit, port, rate));
   1597         return BCM_E_NONE;
   1598     }
   1599 #endif
   1600 
   1601     return BCM_E_UNAVAIL;
   1602 }
   1603 
   1604 /*
   1605  * Function:
   1606  *      bcm_rate_mcast_get
   1607  * Description:
   1608  *      Get rate limit for MCAST packets
   1609  * Parameters:
   1610  *      unit - StrataSwitch PCI device unit number
   1611  *      pps - (OUT) Rate limit value in packets/second
   1612  *      flags - (OUT) Bitmask with one or more of BCM_RATE_*
   1613  *      port - Port number for which MCAST limit is requested
   1614  * Returns:
   1615  *      BCM_E_XXX
   1616  */
   1617 
   1618 int
   1619 bcm_esw_rate_mcast_get(int unit, int *pps, int *flags, int port)
   1620 {
   1621     if (BCM_GPORT_IS_SET(port)) {
   1622         BCM_IF_ERROR_RETURN(
   1623             bcm_esw_port_local_get(unit, port, &port));
   1624     }
   1625     if (!SOC_PORT_VALID(unit, port)) {
   1626         return BCM_E_PORT;
   1627     }
   1628 
   1629     /* Check for Storm Control feature */
   1630     if (!soc_feature(unit,soc_feature_storm_control)) {
   1631         return BCM_E_UNAVAIL;
   1632     }
   1633 
   1634 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1635 #ifdef BCM_TRX_SUPPORT
   1636     if (SOC_IS_TRX(unit)) {
   1637         return _bcm_trx_rate_get(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1638                                  flags, BCM_RATE_MCAST, NULL, pps, NULL);
   1639     }
   1640 #endif /* BCM_TRX_SUPPORT */
   1641 
   1642     if (SOC_IS_XGS3_SWITCH(unit)) {
   1643         uint32 rate;
   1644 
   1645         SOC_IF_ERROR_RETURN(READ_MCAST_STORM_CONTROLr(unit, port, &rate));
   1646         *flags = 0;
   1647         *pps = 0;
   1648         if (soc_reg_field_get(unit, MCAST_STORM_CONTROLr, rate, ENABLEf)) {
   1649             *flags |= BCM_RATE_MCAST;
   1650             *pps = soc_reg_field_get(unit, MCAST_STORM_CONTROLr,
   1651                                      rate, THRESHOLDf);
   1652         } 
   1653         return BCM_E_NONE;
   1654     }
   1655 #endif
   1656 
   1657     return bcm_esw_rate_get(unit, pps, flags);
   1658 }
   1659 
   1660 /*
   1661  * Function:
   1662  *      bcm_rate_dlfbc_get
   1663  * Description:
   1664  *      Get rate limit for DLFBC packets
   1665  * Parameters:
   1666  *      unit - StrataSwitch PCI device unit number
   1667  *      pps - (OUT) Rate limit value in packets/second
   1668  *      flags - (OUT) Bitmask with one or more of BCM_RATE_*
   1669  *      port - Port number for which DLFBC limit is requested
   1670  * Returns:
   1671  *      BCM_E_XXX
   1672  * Notes:
   1673  *      DLFBC: Destination Lookup Failure Broadcast
   1674  */
   1675 
   1676 int
   1677 bcm_esw_rate_dlfbc_get(int unit, int *pps, int *flags, int port)
   1678 {
   1679     if (BCM_GPORT_IS_SET(port)) {
   1680         BCM_IF_ERROR_RETURN(
   1681             bcm_esw_port_local_get(unit, port, &port));
   1682     }
   1683     if (!SOC_PORT_VALID(unit, port)) {
   1684         return BCM_E_PORT;
   1685     }
   1686 
   1687     /* Check for Storm Control feature */
   1688     if (!soc_feature(unit,soc_feature_storm_control)) {
   1689         return BCM_E_UNAVAIL;
   1690     }
   1691 
   1692 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1693 #ifdef BCM_TRX_SUPPORT
   1694     if (SOC_IS_TRX(unit)) {
   1695         return _bcm_trx_rate_get(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1696                                  flags, BCM_RATE_DLF, NULL, pps, NULL);
   1697     }
   1698 #endif /* BCM_TRX_SUPPORT */
   1699     if (SOC_IS_XGS3_SWITCH(unit)) {
   1700         uint32 rate;
   1701 
   1702         SOC_IF_ERROR_RETURN(READ_DLFBC_STORM_CONTROLr(unit, port, &rate));
   1703  
   1704         *flags = 0;
   1705         *pps = 0;
   1706         if (soc_reg_field_get(unit, DLFBC_STORM_CONTROLr, rate, ENABLEf)) {
   1707             *flags |= BCM_RATE_DLF;
   1708             *pps = soc_reg_field_get(unit, DLFBC_STORM_CONTROLr,
   1709                                      rate, THRESHOLDf);
   1710         }
   1711         return BCM_E_NONE;
   1712     }
   1713 #endif
   1714 
   1715     return bcm_esw_rate_get(unit, pps, flags);
   1716 }
   1717 
   1718 /*
   1719  * Function:
   1720  *      bcm_rate_bcast_get
   1721  * Description:
   1722  *      Get rate limit for BCAST packets
   1723  * Parameters:
   1724  *      unit - StrataSwitch PCI device unit number
   1725  *      pps - (OUT) Rate limit value in packets/second
   1726  *      flags - (OUT) Bitmask with one or more of BCM_RATE_*
   1727  *      port - Port number for which BCAST limit is requested
   1728  * Returns:
   1729  *      BCM_E_XXX
   1730  */
   1731 
   1732 int
   1733 bcm_esw_rate_bcast_get(int unit, int *pps, int *flags, int port)
   1734 {
   1735     if (BCM_GPORT_IS_SET(port)) {
   1736         BCM_IF_ERROR_RETURN(
   1737             bcm_esw_port_local_get(unit, port, &port));
   1738     }
   1739     if (!SOC_PORT_VALID(unit, port)) {
   1740         return BCM_E_PORT;
   1741     }
   1742 
   1743     /* Check for Storm Control feature */
   1744     if (!soc_feature(unit,soc_feature_storm_control)) {
   1745         return BCM_E_UNAVAIL;
   1746     }
   1747 
   1748 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1749 #ifdef BCM_TRX_SUPPORT
   1750     if (SOC_IS_TRX(unit)) {
   1751         return _bcm_trx_rate_get(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1752                                  flags, BCM_RATE_BCAST, NULL, pps, NULL);
   1753     }
   1754 #endif /* BCM_TRX_SUPPORT */
   1755     if (SOC_IS_XGS3_SWITCH(unit)) {
   1756         uint32 rate;
   1757 
   1758         SOC_IF_ERROR_RETURN(READ_BCAST_STORM_CONTROLr(unit, port, &rate));
   1759         *flags = 0;
   1760         *pps = 0;
   1761         if (soc_reg_field_get(unit, BCAST_STORM_CONTROLr, rate, ENABLEf)) {
   1762             *flags |= BCM_RATE_BCAST;
   1763             *pps = soc_reg_field_get(unit, BCAST_STORM_CONTROLr,
   1764                                      rate, THRESHOLDf);
   1765         }
   1766         return BCM_E_NONE;
   1767     }
   1768 #endif
   1769 
   1770     return bcm_esw_rate_get(unit, pps, flags);
   1771 }
   1772 
   1773 /*
   1774  * Function:
   1775  *      bcm_rate_type_get
   1776  * Description:
   1777  *      Front end to bcm_*cast_rate_get functions.
   1778  *      Uses a single data structure to read from
   1779  *      all the 3 rate control registers
   1780  * Parameters:
   1781  *      unit - unit number
   1782  *      rl - (OUT) data structure containing info to be acquired from the
   1783  *           rate control registers
   1784  * Returns:
   1785  *      BCM_E_XXX
   1786  */
   1787 
   1788 int
   1789 bcm_esw_rate_type_get(int unit, bcm_rate_limit_t *rl)
   1790 {
   1791     int port;
   1792     int flags = 0;
   1793 
   1794     bcm_rate_limit_t_init(rl);
   1795 
   1796     /* get first enabled ethernet port */
   1797     PBMP_E_ITER(unit, port) {
   1798         BCM_IF_ERROR_RETURN
   1799             (bcm_esw_rate_bcast_get(unit, &rl->br_bcast_rate, &flags, port));
   1800         rl->flags |= flags;
   1801         BCM_IF_ERROR_RETURN
   1802             (bcm_esw_rate_mcast_get(unit, &rl->br_mcast_rate, &flags, port));
   1803         rl->flags |= flags;
   1804         BCM_IF_ERROR_RETURN
   1805             (bcm_esw_rate_dlfbc_get(unit, &rl->br_dlfbc_rate, &flags, port));
   1806         rl->flags |= flags;
   1807         break;
   1808     }
   1809 
   1810     return BCM_E_NONE;
   1811 }
   1812 
   1813 /*
   1814  * Function:
   1815  *      bcm_rate_get
   1816  * Description:
   1817  *      Get rate limit and on/off state of
   1818  *      DLF, MCAST, and BCAST limiting
   1819  * Parameters:
   1820  *      unit - StrataSwitch PCI device unit number
   1821  *      pps - (OUT) Place to store returned rate limit value
   1822  *      flags - (OUT) Place to store returned flag bitmask with
   1823  *              one or more of BCM_RATE_*
   1824  * Returns:
   1825  *      BCM_E_NONE - Success.
   1826  *      BCM_E_INTERNAL - Chip access failure.
   1827  * Notes:
   1828  *      Actually returns the rate for BCAST only, but assumes the
   1829  *      bcm_rate_set call was used so DLF, MCAST and BCAST should be equal.
   1830  */
   1831 
   1832 int
   1833 bcm_esw_rate_get(int unit, int *pps, int *flags)
   1834 {
   1835 #ifdef BCM_XGS3_SWITCH_SUPPORT
   1836     if (SOC_IS_XGS3_SWITCH(unit)) {
   1837         uint32 rate;
   1838         int port;
   1839         PBMP_ALL_ITER(unit, port) {
   1840             break;
   1841         }
   1842 #ifdef BCM_TRX_SUPPORT
   1843         if (SOC_IS_TRX(unit)) {
   1844             uint32 fmask;
   1845             fmask = BCM_RATE_DLF | BCM_RATE_MCAST | BCM_RATE_BCAST;
   1846             return _bcm_trx_rate_get(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   1847                                      flags, fmask, NULL, pps, NULL);
   1848         }
   1849 #endif /* BCM_TRX_SUPPORT */
   1850 
   1851         *flags = 0;
   1852         SOC_IF_ERROR_RETURN(READ_BCAST_STORM_CONTROLr(unit, port, &rate));
   1853         if (soc_reg_field_get(unit, BCAST_STORM_CONTROLr, rate, ENABLEf)) {
   1854             *pps = soc_reg_field_get(unit, BCAST_STORM_CONTROLr, rate,
   1855                                      THRESHOLDf);
   1856             *flags |= BCM_RATE_BCAST;
   1857         }
   1858         SOC_IF_ERROR_RETURN(READ_MCAST_STORM_CONTROLr(unit, port, &rate));
   1859         if (soc_reg_field_get(unit, MCAST_STORM_CONTROLr, rate, ENABLEf)) {
   1860             *pps = soc_reg_field_get(unit, MCAST_STORM_CONTROLr, rate,
   1861                                      THRESHOLDf);
   1862             *flags |= BCM_RATE_MCAST;
   1863         }
   1864         SOC_IF_ERROR_RETURN(READ_DLFBC_STORM_CONTROLr(unit, port, &rate));
   1865         if (soc_reg_field_get(unit, DLFBC_STORM_CONTROLr, rate, ENABLEf)) {
   1866             *pps = soc_reg_field_get(unit, DLFBC_STORM_CONTROLr, rate,
   1867                                      THRESHOLDf);
   1868             *flags |= BCM_RATE_DLF;
   1869         }
   1870         return BCM_E_NONE;
   1871     }
   1872 #endif
   1873 
   1874     return BCM_E_UNAVAIL;
   1875 }
   1876 
   1877 
   1878 /*
   1879  * Function:
   1880  *      bcm_esw_rate_bandwidth_get
   1881  * Description:
   1882  *      Get rate bandwidth limiting parameters
   1883  * Parameters:
   1884  *      unit - Device number
   1885  *      port - Port number
   1886  *      flags - Bitmask with one of the following:
   1887  *              BCM_RATE_BCAST
   1888  *              BCM_RATE_MCAST
   1889  *              BCM_RATE_DLF
   1890  *              BCM_RATE_MODE_PACKETS: pps vs bps mode.
   1891  *      kbits_sec - Rate in kilobits (1000 bits) per second.
   1892  *                  Rate of 0 disabled rate limiting.
   1893  *      kbits_burst - Maximum burst size in kilobits(1000 bits)
   1894  * Returns:
   1895  *      BCM_E_NONE - Success.
   1896  *      BCM_E_UNAVAIL - Not supported
   1897  *      BCM_E_XXX - Error.
   1898  */
   1899 
   1900 int 
   1901 bcm_esw_rate_bandwidth_get(int unit, bcm_port_t port, int flags, 
   1902                            uint32 *kbits_sec, uint32 *kbits_burst)
   1903 {
   1904 #ifdef BCM_TRX_SUPPORT
   1905     int mode;
   1906 #endif /* BCM_TRX_SUPPORT */
   1907 
   1908     if (BCM_GPORT_IS_SET(port)) {
   1909         BCM_IF_ERROR_RETURN(
   1910             bcm_esw_port_local_get(unit, port, &port));
   1911     }
   1912 #ifdef BCM_TRX_SUPPORT
   1913     if (SOC_IS_TRX(unit)) {
   1914         mode = ((flags & BCM_RATE_MODE_PACKETS) ?
   1915                 _BCM_TRX_RATE_PKT_MODE : _BCM_TRX_RATE_BYTE_MODE);
   1916         flags &= ~BCM_RATE_MODE_PACKETS;
   1917         return _bcm_trx_rate_get(unit, port, mode, 
   1918                                  NULL, flags, kbits_sec, NULL,
   1919                                  kbits_burst);
   1920     } 
   1921 #endif /* BCM_TRX_SUPPORT */
   1922 
   1923 #if defined(BCM_BANDWIDTH_RATE_METER)
   1924     if (soc_feature(unit,soc_feature_storm_control)) {
   1925         uint32  enable_entry;
   1926 
   1927         if (!SOC_PORT_VALID(unit, port)) {
   1928             return BCM_E_PORT;
   1929         }
   1930 
   1931         *kbits_sec = *kbits_burst = 0;
   1932         BCM_IF_ERROR_RETURN(
   1933             READ_SC_BYTE_METER_CONFIGr(unit, port, &enable_entry));
   1934 
   1935         if (flags & BCM_RATE_BCAST) {
   1936             if (soc_reg_field_get(unit, SC_BYTE_METER_CONFIGr, enable_entry,
   1937                                   BCAST_ENABLEf)) {
   1938                 _bcm_rate_bw_get(unit, port, FP_SC_BCAST_METER_TABLEm, 
   1939                                  kbits_sec, kbits_burst);
   1940             }
   1941         } else if (flags & BCM_RATE_MCAST) {
   1942             if (soc_reg_field_get(unit, SC_BYTE_METER_CONFIGr, enable_entry,
   1943                                   MCAST_ENABLEf)) {
   1944                 _bcm_rate_bw_get(unit, port, FP_SC_MCAST_METER_TABLEm, 
   1945                                  kbits_sec, kbits_burst);
   1946             }
   1947         } else if (flags & BCM_RATE_DLF) {
   1948             if (!SOC_IS_SHADOW(unit)) {
   1949                 if (soc_reg_field_get(unit, SC_BYTE_METER_CONFIGr, enable_entry,
   1950                                       DLFBC_ENABLEf)) {
   1951                     _bcm_rate_bw_get(unit, port, FP_SC_DLF_METER_TABLEm,
   1952                                      kbits_sec, kbits_burst);
   1953                 }
   1954             }
   1955         }
   1956 
   1957         return BCM_E_NONE;
   1958     }
   1959 #endif
   1960     return BCM_E_UNAVAIL;
   1961 }
   1962 
   1963 /*
   1964  * Function:
   1965  *      bcm_esw_rate_bandwidth_set
   1966  * Description:
   1967  *      Set rate bandwidth limiting parameters
   1968  * Parameters:
   1969  *      unit - Device number
   1970  *      port - Port number
   1971  *      flags - Bitmask with one of the following:
   1972  *              BCM_RATE_BCAST
   1973  *              BCM_RATE_MCAST
   1974  *              BCM_RATE_DLF
   1975  *              BCM_RATE_MODE_PACKETS: pps vs bps mode.
   1976  *      kbits_sec - Rate in kilobits (1000 bits) per second.
   1977  *                  Rate of 0 disables rate limiting.
   1978  *      kbits_burst - Maximum burst size in kilobits(1000 bits)
   1979  * Returns:
   1980  *      BCM_E_NONE - Success.
   1981  *      BCM_E_UNAVAIL - Not supported
   1982  *      BCM_E_XXX - Error.
   1983  */
   1984 
   1985 int 
   1986 bcm_esw_rate_bandwidth_set(int unit, bcm_port_t port, int flags, 
   1987                            uint32 kbits_sec, uint32 kbits_burst)
   1988 {
   1989 #ifdef BCM_TRX_SUPPORT
   1990     int mode;
   1991 #endif /* BCM_TRX_SUPPORT */
   1992 
   1993     if (BCM_GPORT_IS_SET(port)) {
   1994         BCM_IF_ERROR_RETURN(
   1995             bcm_esw_port_local_get(unit, port, &port));
   1996     }
   1997 #ifdef BCM_TRX_SUPPORT
   1998     if (SOC_IS_TRX(unit)) {
   1999         uint32 fmask;
   2000         mode = ((flags & BCM_RATE_MODE_PACKETS) ?
   2001                 _BCM_TRX_RATE_PKT_MODE : _BCM_TRX_RATE_BYTE_MODE);
   2002         flags &= ~BCM_RATE_MODE_PACKETS;
   2003         fmask = flags;
   2004 
   2005         if (kbits_sec == BCM_RATE_DISABLE) { /* disable storm control */
   2006             flags = 0;
   2007         }
   2008         if (kbits_sec == BCM_RATE_BLOCK) {
   2009             kbits_sec = 0;
   2010             kbits_burst = 0;
   2011         }
   2012         return (_bcm_trx_rate_set(unit, port, mode, 
   2013                                   flags, fmask, kbits_sec, kbits_burst)); 
   2014     } 
   2015 #endif /* BCM_TRX_SUPPORT */
   2016 
   2017 #if defined(BCM_BANDWIDTH_RATE_METER)
   2018 
   2019     if (soc_feature(unit,soc_feature_storm_control)) {
   2020         uint32      enable_entry, old_entry;
   2021         uint32      refresh;
   2022 
   2023         if (!SOC_PORT_VALID(unit, port)) {
   2024             return BCM_E_PORT;
   2025         }
   2026         if (kbits_sec > METERING_TOKEN_MAX * TOKEN_BUCKET_SIZE) {
   2027             return BCM_E_PARAM;
   2028         }
   2029         if (kbits_burst > kbits_2_bucket_size[METER_BUCKETSIZE_MAX]) {
   2030             return BCM_E_PARAM;
   2031         }
   2032 
   2033         if (!(flags & BCM_RATE_ALL)) {
   2034             return BCM_E_PARAM;
   2035         }
   2036 
   2037         /*    coverity[equality_cond]    */
   2038         if (!kbits_sec || !kbits_burst) { 
   2039             /* metering is disabled on port - program tables to max values */
   2040             BCM_IF_ERROR_RETURN(
   2041                 READ_SC_BYTE_METER_CONFIGr(unit, port, &enable_entry));
   2042             
   2043             old_entry = enable_entry;
   2044             if (flags & BCM_RATE_BCAST) {
   2045                 soc_reg_field_set(unit, SC_BYTE_METER_CONFIGr, &enable_entry,
   2046                                   BCAST_ENABLEf, 0);
   2047 
   2048                 _bcm_rate_bw_set(unit, port, FP_SC_BCAST_METER_TABLEm, 
   2049                                  METERING_TOKEN_MAX, METER_BUCKETSIZE_MAX); 
   2050             }
   2051             if (flags & BCM_RATE_MCAST) {
   2052                 soc_reg_field_set(unit, SC_BYTE_METER_CONFIGr, &enable_entry,
   2053                                   MCAST_ENABLEf, 0);
   2054 
   2055                 _bcm_rate_bw_set(unit, port, FP_SC_MCAST_METER_TABLEm, 
   2056                                  METERING_TOKEN_MAX, METER_BUCKETSIZE_MAX); 
   2057             }
   2058             if (flags & BCM_RATE_DLF) {
   2059                 if (!SOC_IS_SHADOW(unit)) {
   2060                     soc_reg_field_set(unit, SC_BYTE_METER_CONFIGr, &enable_entry,
   2061                                       DLFBC_ENABLEf, 0);
   2062                     _bcm_rate_bw_set(unit, port, FP_SC_DLF_METER_TABLEm, 
   2063                                      METERING_TOKEN_MAX, METER_BUCKETSIZE_MAX); 
   2064                 }
   2065             }
   2066             if (old_entry != enable_entry) {
   2067                 BCM_IF_ERROR_RETURN(
   2068                     WRITE_SC_BYTE_METER_CONFIGr(unit, port, enable_entry));
   2069             }
   2070 
   2071             return BCM_E_NONE; 
   2072         }
   2073 
   2074         refresh = (kbits_sec + TOKEN_BUCKET_SIZE - 1) / TOKEN_BUCKET_SIZE ;
   2075         if ( refresh >= METERING_TOKEN_MAX){
   2076             refresh = METERING_TOKEN_MAX; 
   2077         }
   2078 
   2079         BCM_IF_ERROR_RETURN(
   2080             READ_SC_BYTE_METER_CONFIGr(unit, port, &enable_entry));
   2081 
   2082         old_entry = enable_entry;
   2083 
   2084         if (flags & BCM_RATE_BCAST) {
   2085             soc_reg_field_set(unit, SC_BYTE_METER_CONFIGr, &enable_entry,
   2086                               BCAST_ENABLEf, 1);
   2087 
   2088             _bcm_rate_bw_set(unit, port, FP_SC_BCAST_METER_TABLEm, refresh, 
   2089                              _bcm_kbits_to_bucket_size(kbits_burst)); 
   2090         }
   2091         if (flags & BCM_RATE_MCAST) {
   2092             soc_reg_field_set(unit, SC_BYTE_METER_CONFIGr, &enable_entry,
   2093                               MCAST_ENABLEf, 1);
   2094 
   2095             _bcm_rate_bw_set(unit, port, FP_SC_MCAST_METER_TABLEm, refresh, 
   2096                              _bcm_kbits_to_bucket_size(kbits_burst)); 
   2097         }
   2098         if (flags & BCM_RATE_DLF) {
   2099             if (!SOC_IS_SHADOW(unit)) {
   2100                 soc_reg_field_set(unit, SC_BYTE_METER_CONFIGr, &enable_entry,
   2101                               DLFBC_ENABLEf, 1);
   2102 
   2103                 _bcm_rate_bw_set(unit, port, FP_SC_DLF_METER_TABLEm, refresh, 
   2104                                  _bcm_kbits_to_bucket_size(kbits_burst)); 
   2105             }
   2106         }
   2107         if (old_entry != enable_entry) {
   2108             BCM_IF_ERROR_RETURN(
   2109                 WRITE_SC_BYTE_METER_CONFIGr(unit, port, enable_entry));
   2110         }
   2111 
   2112         return BCM_E_NONE;
   2113     }
   2114 #endif
   2115 
   2116     return BCM_E_UNAVAIL;
   2117 }
   2118 
   2119 /*
   2120  * Function:
   2121  *      bcm_esw_rate_packet_get
   2122  * Description:
   2123  *      Get rate packet limiting parameters
   2124  * Parameters:
   2125  *      unit      - Device number
   2126  *      pkt_rate  - packet rate information
   2127  * Returns:
   2128  *      BCM_E_NONE    - Success.
   2129  *      BCM_E_UNAVAIL - Not supported
   2130  *      BCM_E_XXX     - Error.
   2131  */
   2132 
   2133 int 
   2134 bcm_esw_rate_packet_get(int unit, bcm_port_t port, bcm_rate_packet_t *pkt_rate)
   2135 {
   2136     if (BCM_GPORT_IS_SET(port)) {
   2137         BCM_IF_ERROR_RETURN(
   2138             bcm_esw_port_local_get(unit, port, &port));
   2139     }
   2140     if (!SOC_PORT_VALID(unit, port)) {
   2141         return BCM_E_PORT;
   2142     }
   2143 
   2144 #ifdef BCM_TRX_SUPPORT
   2145     if (SOC_IS_TRX(unit)) {
   2146         return _bcm_trx_rate_get(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   2147                                  (int *)&pkt_rate->flags, pkt_rate->flags, NULL, 
   2148                                  &pkt_rate->pps, (uint32 *)(&pkt_rate->kbits_burst));
   2149     }
   2150 #endif /* BCM_TRX_SUPPORT */
   2151 
   2152     return BCM_E_UNAVAIL;
   2153 }
   2154 
   2155 /*
   2156  * Function:
   2157  *      bcm_esw_rate_packet_set
   2158  * Description:
   2159  *      Set rate packet limiting parameters
   2160  * Parameters:
   2161  *      unit      - Device number
   2162  *      pkt_rate  - packet rate information
   2163  * Returns:
   2164  *      BCM_E_NONE    - Success.
   2165  *      BCM_E_UNAVAIL - Not supported
   2166  *      BCM_E_XXX     - Error.
   2167  */
   2168 
   2169 int 
   2170 bcm_esw_rate_packet_set(int unit, bcm_port_t port, bcm_rate_packet_t *pkt_rate)
   2171 {
   2172     if (BCM_GPORT_IS_SET(port)) {
   2173         BCM_IF_ERROR_RETURN(
   2174             bcm_esw_port_local_get(unit, port, &port));
   2175     }
   2176     if (!SOC_PORT_VALID(unit, port)) {
   2177         return BCM_E_PORT;
   2178     }
   2179 
   2180 #ifdef BCM_TRX_SUPPORT
   2181     if (SOC_IS_TRX(unit)) {
   2182         return (_bcm_trx_rate_set(unit, port, _BCM_TRX_RATE_PKT_MODE, 
   2183                                   pkt_rate->flags, pkt_rate->flags, pkt_rate->pps, 
   2184                                   (uint32)(pkt_rate->kbits_burst))); 
   2185     }
   2186 #endif /* BCM_TRX_SUPPORT */
   2187     return BCM_E_UNAVAIL;
   2188 }
   2189 
   2190 
   2191