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 */