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