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

meter.c (13485B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File: 	meter.c
      8  * Purpose: 	tomahawk3 placeholder for metering, FP metering.
      9  */
     10 
     11 #include <soc/defs.h>
     12 #if defined(BCM_TOMAHAWK3_SUPPORT)
     13 
     14 #include <sal/core/libc.h>
     15 #include <bcm_int/esw/tomahawk3.h>
     16 
     17 #define TH3_METER_GRANULARITY_DEFAULT      3
     18 #define TH3_METER_GRANULARITY_NUM          8
     19 #define TH3_METER_KBITS_SEC_QUANTUM_MIN    32        /* 32000 bits/second */
     20 #define TH3_METER_BITS_BURST_MIN           (256 * 8) /* 256 bytes */
     21 #define TH3_METER_PACKET_SEC_QUANTUM_MIN   2
     22 #define TH3_METER_MMU_PACKET_BURST_MIN     128       /* 0.128 packet, use 1000x */
     23 #define TH3_METER_FP_PACKET_BURST_MIN      512       /* 0.512 packet, use 1000x */
     24 #define TH3_METER_PACKET_BURST_DIVISOR      1000    /* use 1000x for calculation */
     25 #define TH3_METER_NL_SEGMENT_GRANULARITY    256
     26 #define TH3_METER_NL_BUCKET_POWER_SHIFT     8
     27 #define TH3_METER_NL_BUCKET_RANGE_NUM       16
     28 #define TH3_METER_NL_BUCKET_SEGMENT_MASK    0xff
     29 #define TH3_METER_NL_BUCKET_POWER_MASK      0xf
     30 #define TH3_METER_NL_BUCKET_MAC_ENCODE_MAX  0xff80 /* (2 ** 0xf) * (1 + 0xff/256) */
     31 
     32 STATIC void
     33 _bcm_th3_granularity_params(int unit, int granularity, uint32 flags,
     34                            uint32 *rate_unit_size, uint32 *burst_unit_size)
     35 {
     36     uint32 gran_multiple;
     37     static const uint32 fp_pkt_mode_gran_multiple[] = {
     38         1, 2, 4, 8, 16, 64, 256, 1024
     39     };
     40     static const uint32 mmu_pkt_mode_gran_multiple[] = {
     41         1, 2, 4, 16, 64, 256, 1024, 4096
     42     };
     43 
     44     if (flags & _BCM_TH3_METER_FLAG_PACKET_MODE) {
     45         if (flags &_BCM_TH3_METER_FLAG_FP_POLICER) {
     46             gran_multiple = fp_pkt_mode_gran_multiple[granularity];
     47             *burst_unit_size = TH3_METER_FP_PACKET_BURST_MIN * gran_multiple;
     48         } else {
     49             gran_multiple = mmu_pkt_mode_gran_multiple[granularity];
     50             *burst_unit_size = TH3_METER_MMU_PACKET_BURST_MIN * gran_multiple;
     51         }
     52         *rate_unit_size = TH3_METER_PACKET_SEC_QUANTUM_MIN * gran_multiple;
     53     } else {
     54         gran_multiple = 1 << granularity;
     55         *rate_unit_size = TH3_METER_KBITS_SEC_QUANTUM_MIN * gran_multiple;
     56         *burst_unit_size = TH3_METER_BITS_BURST_MIN * gran_multiple;
     57     }
     58 }
     59 
     60 /*
     61  * Function:
     62  *	_bcm_th3_rate_to_bucket_encoding
     63  * Description:
     64  *      Routine that converts desired burst size into leaky bucketsize
     65  *      register value.
     66  * Parameters:
     67  *      rate_quantum - Desired rate of ongoing traffic
     68  *      burst_quantum - Desired size of maximum burst traffic
     69  *      flags - paramters indicating capabilities and configuration of meter
     70  *      refresh_bitsize - number of bits for the refresh rate field
     71  *      bucket_max_bitsize - number of bits for the bucket max field
     72  *      refresh_rate - (OUT) calculated value for the refresh rate field
     73  *      bucket_max - (OUT) calculated value for the bucket max field
     74  *      granularity - (OUT) calculated value for the granularity field
     75  * Returns:
     76  *	BCM_E_*
     77  * Notes:
     78  *
     79  * bandwidth(byte) mode
     80  * RI = 1.024 MHz
     81  * Refresh min = RI * token_size * 8 * 1(min 17 bits wide number)
     82  * Refresh max = RI * token_size * 8 * 0x1ffff(max 17bits wide number)
     83  * Burst size (Linear) = thd_sel * 64K * Token size
     84  * Burst size (Linear) min = 1 * 64K * 1/256
     85  * Burst size (Linear) max = 4096 * 64K * 1/256
     86  * Burst size (ITU mode) = 2^thd_sel[11:8] *(1+thd[7:0]/256) * 64K * Token size
     87  * Burst size (ITU mode) min = 1 * 64K * 1/256
     88  * Burst size (ITU mode) max = 4096 * 64K * 1/256
     89  * gran  refresh      refresh            bucket-size-granularity
     90  *       byte/refresh kbit/second        bits
     91  *                     min <-> max         base <-> max
     92  *                                                  (linear)   / (ITU mode)
     93  * 0     1/256          32 <-> 4194304     2048 <-> 0x3ffc00   / 0x7fc0000
     94  * 1     1/128          64 <-> 8388608     4096 <-> 0x7ff800   / 0xff80000
     95  * 2     1/64          128 <-> 16777216    8192 <-> 0xfff000   / 0x1ff00000
     96  * 3     1/32          256 <-> 33554432   16384 <-> 0x1ffe000  / 0x3fe00000
     97  * 4     1/16          512 <-> 67108864   32768 <-> 0x3ffc000  / 0x7fc00000
     98  * 5     1/8          1024 <-> 134217728   65536 <-> 0x7ff8000  / 0xff800000
     99  * 6     1/4          2048 <-> 268435456 131072 <-> 0xfff0000  / 0x1ff000000
    100  * 7     1/2          4096 <-> 536870912 262144 <-> 0x1ffe0000 / 0x3fe000000
    101  * (max value is based on 17-bit refresh setting and 12-bit burst setting)
    102  *
    103  * packet-shaping mode (for tomahawk3 mmu)
    104  * gran  refresh        refresh           bucket-size-granularity
    105  *       packet/refresh packet/second     packet
    106  *                      min <-> max          base <-> max
    107  *                                          (linear) / (ITU mode)
    108  * 0     1/512000         2 <-> 0x3ff70     0.128 <-> 0x20c    / 0x20b4
    109  * 1     1/256000         4 <-> 0x3ffff     0.256 <-> 0x418    / 0x4168
    110  * 2     1/128000         8 <-> 0x7fffe     0.512 <-> 0x830    / 0x82d0
    111  * 3     1/32000         32 <-> 0xffffc     2.048 <-> 0x1061   / 0x105a1
    112  * 4     1/8000         128 <-> 0x1ffff8    8.192 <-> 0x20c2   / 0x20b43
    113  * 5     1/2000         512 <-> 0x3ffff0    32.768 <-> 0x4185   / 0x41687
    114  * 6     1/500         2048 <-> 0xffffc0   131.072 <-> 0x10614  / 0x105a1c
    115  * 7     1/125         8192 <-> 0x3ffff00  524.288 <-> 0x41851  / 0x416872
    116  *
    117  * packet-policing mode (for tomahawk3 fp)
    118  * gran  refresh        refresh           bucket-size-granularity
    119  *       packet/refresh packet/second     packet
    120  *                      min <-> max          base <-> max
    121  *                                                    (linear) / (ITU mode)
    122  * 0     1/128000         1 <-> 0x7ffff     0.512 <-> 0x830    / 0x82d0
    123  * 1     1/64000          2 <-> 0xffffe     1.024 <-> 0x1061   / 0x105a1
    124  * 2     1/32000          4 <-> 0x1ffffc    2.048 <-> 0x20c2   / 0x20b43
    125  * 3     1/16000          8 <-> 0x3ffff8    4.096 <-> 0x4185   / 0x41687
    126  * 4     1/8000          16 <-> 0x7ffff0    8.192 <-> 0x830a   / 0x82d0e
    127  * 5     1/2000          64 <-> 0xffffe0   32.768 <-> 0x20c28  / 0x20b438
    128  * 6     1/500          256 <-> 0x1ffffc0 131.072 <-> 0x830a0  / 0x82d0e0
    129  * 7     1/125         1024 <-> 0xffffe00 524.288 <-> 0x20c28e / 0x20b4394
    130  */
    131 int
    132 _bcm_th3_rate_to_bucket_encoding(int unit, uint32 rate_quantum,
    133                                 uint32 burst_quantum, uint32 flags,
    134                                 int refresh_bitsize, int bucket_max_bitsize,
    135                                 uint32 *refresh_rate, uint32 *bucketsize,
    136                                 uint32 *granularity)
    137 {
    138     int gran, gran_min, gran_max;
    139     uint32 i;
    140     uint32 burst, encoding, buckettop, bucket_segment_size;
    141     uint32 refresh_mask = 0;
    142     uint32 bucket_mask = 0;
    143     uint32 refresh_max = 0;
    144     uint32 bucket_max = 0;
    145     uint32 rate_unit_size = 0;
    146     uint32 burst_unit_size = 0;
    147 
    148     if ((refresh_rate == NULL) || (bucketsize == NULL)) {
    149         return BCM_E_INTERNAL;
    150     }
    151 
    152     if ((burst_quantum == 0) &&
    153         (!(flags & _BCM_TH3_METER_FLAG_FP_POLICER) && (rate_quantum == 0))) {
    154         /* Disabled */
    155         *refresh_rate = 0;
    156         *bucketsize = 0;
    157         *granularity = TH3_METER_GRANULARITY_DEFAULT;
    158         return BCM_E_NONE;
    159     }
    160 
    161     refresh_mask = 0xffffffff >> (32 - refresh_bitsize);
    162     bucket_mask = 0xffffffff >> (32 - bucket_max_bitsize);
    163     if (flags & _BCM_TH3_METER_FLAG_PACKET_MODE) {
    164         /* Minimum packet burst is .512 packet.  We'll work in integers. */
    165         burst = burst_quantum * TH3_METER_PACKET_BURST_DIVISOR;
    166     } else {
    167         if (burst_quantum > (0xffffffff / 1000)) {
    168             burst = 0xffffffff;
    169         } else {
    170             burst = burst_quantum * 1000;
    171         }
    172     }
    173 
    174     gran_min = 0;
    175     gran_max = TH3_METER_GRANULARITY_NUM - 1;
    176 
    177     for (gran = gran_min; gran <= gran_max; gran++) {
    178         _bcm_th3_granularity_params(unit, gran, flags, &rate_unit_size,
    179                                    &burst_unit_size);
    180         refresh_max = refresh_mask * rate_unit_size;
    181         if (flags & _BCM_TH3_METER_FLAG_NON_LINEAR) {
    182             bucket_max = TH3_METER_NL_BUCKET_MAC_ENCODE_MAX * burst_unit_size;
    183         } else {
    184             bucket_max = (bucket_mask + 1) * burst_unit_size;
    185         }
    186 
    187         if ((rate_quantum <= refresh_max) && (burst <= bucket_max)) {
    188             break;
    189         }
    190     }
    191 
    192     if (gran > gran_max) {
    193         /* Saturate! */
    194         gran = gran_max;
    195         if (rate_quantum > refresh_max) {
    196             rate_quantum = refresh_max;
    197         }
    198         if (burst > bucket_max) {
    199             burst = bucket_max;
    200         }
    201     }
    202 
    203     *granularity = gran;
    204 
    205     if (rate_quantum > (0xffffffff - (rate_unit_size - 1))) {
    206         rate_quantum = 0xffffffff - (rate_unit_size - 1);
    207     }
    208 
    209     *refresh_rate = (rate_quantum + (rate_unit_size - 1)) / rate_unit_size;
    210     if (*refresh_rate > refresh_mask) {
    211         *refresh_rate = refresh_mask;
    212     }
    213 
    214     if (flags & _BCM_TH3_METER_FLAG_NON_LINEAR) {
    215         if (burst <= burst_unit_size) {
    216             *bucketsize = burst ? 1 : 0; /* 0 kbits means disable */
    217         } else {
    218             encoding = bucket_mask;
    219             buckettop = burst_unit_size;
    220             for (i = 0; i < TH3_METER_NL_BUCKET_RANGE_NUM; i++, buckettop *= 2) {
    221                 bucket_segment_size =
    222                     buckettop / TH3_METER_NL_SEGMENT_GRANULARITY;
    223                 if (burst <= (buckettop * 2 - bucket_segment_size) ||
    224                     (buckettop == 0)) {
    225                     if (buckettop == 0) {
    226                         /* Saturate */
    227                         buckettop = 0xffffffff;
    228                     }
    229                     encoding =
    230                         (burst - buckettop + (bucket_segment_size - 1)) /
    231                         bucket_segment_size;
    232                     encoding |= i << TH3_METER_NL_BUCKET_POWER_SHIFT;
    233                     break;
    234                 }
    235             }
    236             *bucketsize = (i < TH3_METER_NL_BUCKET_RANGE_NUM) ? encoding :
    237                 bucket_mask;
    238         }
    239     } else {
    240         encoding = (burst + (burst_unit_size - 1)) / burst_unit_size;
    241         if (encoding > bucket_mask) {
    242             encoding = bucket_mask;
    243         }
    244         *bucketsize = encoding;
    245     }
    246     return BCM_E_NONE;
    247 }
    248 
    249 /*
    250  * Function:
    251  *	_bcm_th3_bucket_encoding_to_rate
    252  * Description:
    253  *      Routine that converts leaky bucketsize
    254  *      register value into its associated burst size.
    255  * Parameters:
    256  *      refresh_rate - refresh rate field
    257  *      bucket_max - bucket max field
    258  *      granularity - granularity field
    259  *      flags - paramters indicating capabilities and configuration of meter
    260  *      rate_quantum - (OUT) Configured rate of ongoing traffic
    261  *      burst_quantum - (OUT) Configured size of maximum burst traffic
    262  * Returns:
    263  *	Max size burst traffic in kbits.
    264  * Notes:
    265  *      None.
    266  */
    267 
    268 uint32
    269 _bcm_th3_bucket_encoding_to_rate(int unit, uint32 refresh_rate,
    270                                 uint32 bucket_max, uint32 granularity,
    271                                 uint32 flags, uint32 *rate_quantum,
    272                                 uint32 *burst_quantum)
    273 {
    274     int gran;
    275     uint32 power, segment, bucketsize;
    276     uint32 rate_unit_size, burst_unit_size;
    277 
    278     if ((rate_quantum == NULL) || (burst_quantum == NULL)) {
    279         return BCM_E_INTERNAL;
    280     }
    281 
    282     gran = granularity;
    283     _bcm_th3_granularity_params(unit, gran, flags, &rate_unit_size,
    284                                &burst_unit_size);
    285 
    286     *rate_quantum = refresh_rate * rate_unit_size;
    287 
    288     if (flags & _BCM_TH3_METER_FLAG_NON_LINEAR) {
    289         if (bucket_max == 0) { /* 0 means disabled */
    290             bucketsize = 0;
    291         } else {
    292             segment = bucket_max & TH3_METER_NL_BUCKET_SEGMENT_MASK;
    293             power = (bucket_max >> TH3_METER_NL_BUCKET_POWER_SHIFT) &
    294                 TH3_METER_NL_BUCKET_POWER_MASK;
    295 
    296             /* Calculate raw bits */
    297             bucketsize = (1 << power) *
    298                 (burst_unit_size / TH3_METER_NL_SEGMENT_GRANULARITY) *
    299                 (TH3_METER_NL_SEGMENT_GRANULARITY + segment);
    300         }
    301     } else {
    302         bucketsize = bucket_max * burst_unit_size;
    303     }
    304 
    305     if (flags & _BCM_TH3_METER_FLAG_PACKET_MODE) {
    306         *burst_quantum = bucketsize / TH3_METER_PACKET_BURST_DIVISOR;
    307     } else {
    308         *burst_quantum = bucketsize / 1000;
    309     }
    310 
    311     return BCM_E_NONE;
    312 }
    313 
    314 uint32 _bcm_th3_default_burst_size(int unit, int port, uint32 kbits_sec)
    315 {
    316     soc_info_t *si = &SOC_INFO(unit);
    317     int proposed1, proposed2, proposed, max_port_speed;
    318     int mtu = 9216, numq;
    319 
    320     max_port_speed = (IS_CPU_PORT(unit,port))? 1000 : si->port_speed_max[port];
    321 
    322     
    323 #ifdef BCM_TOMAHAWK3_SUPPORT
    324     if (SOC_IS_TOMAHAWK3(unit) &&
    325             IS_LB_PORT(unit, port)) {
    326         max_port_speed = 400000;
    327     }
    328 #endif /* BCM_TOMAHAWK3_SUPPORT */
    329     max_port_speed *= 1000;
    330 
    331     if (max_port_speed <= 0) {
    332         return 0;
    333     }
    334 
    335     numq = SOC_TH3_NUM_GP_QUEUES;
    336     if (max_port_speed > kbits_sec) {
    337         proposed1 = (mtu * numq)/(max_port_speed/kbits_sec);
    338     } else {
    339         if (((max_port_speed + kbits_sec - 1)/kbits_sec) == 0) {
    340             return 0;
    341         }
    342         proposed1 = (mtu * numq)/((max_port_speed + kbits_sec - 1)/kbits_sec);
    343     }
    344 
    345     proposed2 = kbits_sec/(8 * 256);
    346 
    347     proposed = (proposed1 > proposed2) ? proposed1 : proposed2;
    348     proposed = (proposed * 8)/1000;
    349     return (proposed > 0) ? proposed : 1;
    350 }
    351 
    352 
    353 #endif  /* BCM_TOMAHAWK3_SUPPORT */